Basic apis' ready

This commit is contained in:
Hizenberg469
2025-01-13 23:52:04 +05:30
parent 4c58e94a4a
commit 8200e46baa
4 changed files with 192 additions and 14 deletions

View File

@@ -3,7 +3,7 @@ CFG ?= debug
# Config specific settings # Config specific settings
ifeq ($(CFG),debug) ifeq ($(CFG),debug)
CFLAGS += -DDEBUG CFLAGS += -g -DDEBUG
else else
CFLAGS += -O3 -DNDEBUG CFLAGS += -O3 -DNDEBUG
endif endif
@@ -22,13 +22,18 @@ endif
rule : dep | inform rule : dep | inform
BUILD_DIR = build/$(CFG) BUILD_DIR=bin/$(CFG)
OBJS_DIR = $(BUILD_DIR)/objs OBJS_DIR=objs/$(CFG)
LIBDIR=lib/${CFG}
SRCDIR=src
#-------------------------------------------------- #--------------------------------------------------
BINARY=$(BUILD_DIR)/fsm APP=$(BUILD_DIR)/app
CODEDIRS=. ./src APP_OBJECT=$(OBJS_DIR)/app.o
FSMLIB_NAME=fsm
FSMLIB=$(LIBDIR)/lib$(FSMLIB_NAME)
CODEDIRS=./src
INCDIRS=. ./include/ # can be list INCDIRS=. ./include/ # can be list
CC=gcc CC=gcc
@@ -36,7 +41,7 @@ OPT=-O0
#generate files that encode make rules for the .h dependencies #generate files that encode make rules for the .h dependencies
DEPFLAGS=-MP -MD DEPFLAGS=-MP -MD
#automatically add the -I onto each include directory #automatically add the -I onto each include directory
CFLAGS=-Wall -Wextra -g $(foreach D,$(INCDIRS),-I$(D)) $(OPT) $(DEPFLAGS) CFLAGS+=-Wall -Wextra $(foreach D,$(INCDIRS),-I$(D)) $(OPT) $(DEPFLAGS)
# for-style iteration (foreach) and regular expression completions (wildcard) # for-style iteration (foreach) and regular expression completions (wildcard)
CFILES=$(foreach D, $(CODEDIRS),$(wildcard $(D)/*.c)) CFILES=$(foreach D, $(CODEDIRS),$(wildcard $(D)/*.c))
@@ -44,18 +49,31 @@ CFILES=$(foreach D, $(CODEDIRS),$(wildcard $(D)/*.c))
OBJECTS=$(patsubst %.c,$(OBJS_DIR)/%.o,$(CFILES)) OBJECTS=$(patsubst %.c,$(OBJS_DIR)/%.o,$(CFILES))
DEPFILES=$(patsubst %.c,$(OBJS_DIR)/%.d,$(CFILES)) DEPFILES=$(patsubst %.c,$(OBJS_DIR)/%.d,$(CFILES))
all: $(BINARY) all: $(FSMLIB) $(APP) | create_dir
$(BINARY): $(OBJECTS) create_dir:
$(CC) -o $@ $^ mkdir -p $(BUILD_DIR)
mkdir -p $(OBJS_DIR)
mkdir -p $(LIBDIR)
$(APP): $(APP_OBJECT) | create_dir
$(CC) -o $@ $^ -L $(LIBDIR) -l$(FSMLIB_NAME)
$(FSMLIB): $(OBJECTS) | create_dir
ar cr $(LIBDIR)/${FSMLIB}.a ${OBJECTS}
# only want the .c file dependency here, thus $< instead of $^. # only want the .c file dependency here, thus $< instead of $^.
# #
%.o:%.c $(OBJS_DIR)/%.o:$(SRCDIR)/%.c | create_dir
$(CC) $(CFLAGS) -c -o $@ $<
$(OBJS_DIR)/%.o:%.c | create_dir
$(CC) $(CFLAGS) -c -o $@ $< $(CC) $(CFLAGS) -c -o $@ $<
clean: clean:
rm -rf $(BINARY) $(OBJECTS) $(DEPFILES) rm -rf $(APP) $(APP_OBJECT) $(OBJECTS) $(DEPFILES)
rm -rf $(BUILD_DIR) $(OBJS_DIR) $(LIBDIR)
# shell commands are a set of keystrokes away # shell commands are a set of keystrokes away
distribute: clean distribute: clean

15
app.c Normal file
View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#include <memory.h>
#include <fsm.h>
int main(){
fsm_t* fsm = create_new_fsm("FSM_1");
state_t* initial_state = create_new_state("q0", FSM_FALSE);
set_fsm_initial_state(fsm, initial_state);
return 0;
}

View File

@@ -1,15 +1,21 @@
#ifndef __FSM__ #ifndef __FSM__
#define __FSM__ #define __FSM__
typedef struct fsm_ fsm_t;
typedef struct state_ state_t;
#define MAX_INP_BUFFER_SIZE 128 /***Constants***/
#define MAX_INP_BUFFER_LEN 128
#define MAX_TRANSITION_TABLE_SIZE 128 #define MAX_TRANSITION_TABLE_SIZE 128
#define MAX_STATE_NAME_SIZE 32 #define MAX_STATE_NAME_SIZE 32
#define MAX_FSM_NAME_SIZE 32 #define MAX_FSM_NAME_SIZE 32
#define MAX_TRANSITION_KEY_SIZE 64 #define MAX_TRANSITION_KEY_SIZE 64
/***Data structures and custom datatypes***/
typedef struct fsm_ fsm_t;
typedef struct state_ state_t;
/*Custom-defined datatype /*Custom-defined datatype
* to define boolean value * to define boolean value
* for FSM*/ * for FSM*/
@@ -67,6 +73,9 @@ struct fsm_{
/*Input data fed by application to parse /*Input data fed by application to parse
* by FSM library*/ * by FSM library*/
char input_buffer[MAX_INP_BUFFER_LEN];
/*Size of input buffer*/
unsigned int input_buffer_size; unsigned int input_buffer_size;
/*Pointer which point to the current input /*Pointer which point to the current input
@@ -74,4 +83,51 @@ struct fsm_{
unsigned int input_buffer_cursor; unsigned int input_buffer_cursor;
}; };
/***Function Prototypes***/
fsm_t*
create_new_fsm(const char *fsm_name);
state_t*
create_new_state(char *state_name,
fsm_bool_t is_final);
void
set_fsm_initial_state(fsm_t *fsm, state_t *state);
tt_entry_t*
create_and_insert_new_tt_entry(tt_t *trans_table,
char *transition_key,
unsigned int sizeof_key,
state_t* next_state);
tt_entry_t*
get_next_empty_tt_entry(tt_t *trans_table);
/**static(hidden) functions***/
static inline fsm_bool_t
is_tt_entry_empty(tt_entry_t *tt_entry){
if(!tt_entry->next_state)
return FSM_TRUE;
return FSM_FALSE;
}
/***Iterators' Macro***/
#define FSM_ITERATE_TRANS_TABLE_BEGIN(tr_table_ptr, tt_entry_ptr) \
do{ \
unsigned int index = 0; \
for( ; index < MAX_TRANSITION_TABLE_SIZE ; index++ ){ \
tt_entry_ptr = &(tr_table_ptr->tt_entry[index]);
#define FSM_ITERATE_TRANS_TABLE_END(tr_table_ptr, tt_entry_ptr) \
} \
}while(0);
#endif #endif

89
src/fsm.c Normal file
View File

@@ -0,0 +1,89 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "fsm.h"
fsm_t*
create_new_fsm(const char* fsm_name)
{
fsm_t *fsm = calloc(1, sizeof(fsm_t));
strncpy(fsm->fsm_name, fsm_name, MAX_FSM_NAME_SIZE - 1 );
fsm->fsm_name[MAX_FSM_NAME_SIZE] = '\0';
return fsm;
}
state_t*
create_new_state(char *state_name,
fsm_bool_t is_final){
assert(state_name);
state_t *state = calloc(1, sizeof(state_t));
strncpy(state->state_name, state_name, MAX_STATE_NAME_SIZE - 1);
state->state_name[MAX_STATE_NAME_SIZE] = '\0';
tt_t *trans_table = &(state->state_trans_table);
tt_entry_t *tt_entry_ptr = NULL;
FSM_ITERATE_TRANS_TABLE_BEGIN(trans_table, tt_entry_ptr){
tt_entry_ptr->next_state = NULL;
}FSM_ITERATE_TRANS_TABLE_END(trans_table, tt_entry_ptr)
state->is_final = is_final;
return state;
}
void
set_fsm_initial_state(fsm_t *fsm, state_t *state){
assert(!fsm->initial_state);
fsm->initial_state = state;
}
tt_entry_t*
get_next_empty_tt_entry(tt_t *trans_table){
tt_entry_t* tt_entry_ptr = NULL;
assert(trans_table);
FSM_ITERATE_TRANS_TABLE_BEGIN(trans_table, tt_entry_ptr){
if( is_tt_entry_empty(tt_entry_ptr) == FSM_TRUE )
break;
}FSM_ITERATE_TRANS_TABLE_END(trans_table, tt_entry_ptr)
if(is_tt_entry_empty(tt_entry_ptr) == FSM_TRUE)
return tt_entry_ptr;
return NULL;
}
tt_entry_t*
create_and_insert_new_tt_entry(tt_t *trans_table,
char *transition_key,
unsigned int sizeof_key,
state_t* next_state){
assert( sizeof transition_key < MAX_TRANSITION_KEY_SIZE);
tt_entry_t *tt_entry_ptr = get_next_empty_tt_entry(trans_table);
if(!tt_entry_ptr){
printf("FATAL : Transition Table is Full\n");
return NULL;
}
memcpy(tt_entry_ptr->transition_key , transition_key, sizeof_key);
tt_entry_ptr->transition_key[sizeof_key] = '\0';
tt_entry_ptr->transition_key_size = sizeof_key;
tt_entry_ptr->next_state = next_state;
return tt_entry_ptr;
}