diff --git a/Makefile b/Makefile index 9fcf4b6..eddc721 100644 --- a/Makefile +++ b/Makefile @@ -1,27 +1,13 @@ #Setting a default configuration if invoked with just "make": -CFG ?= debug +CFG?=debug # Config specific settings ifeq ($(CFG),debug) -CFLAGS += -g -DDEBUG + CFLAGS=-g -DDEBUG else -CFLAGS += -O3 -DNDEBUG + CFLAGS=-O3 -DNDEBUG endif -inform: -ifneq ($(CFG),release) -ifneq ($(CFG),debug) - @echo "Invalid configuration "$(CFG)" specified." - @echo - @echo "Possible choices for configuration are 'CFG=release' and 'CFG=debug'" - @exit 1 -endif -endif - @echo "Configuration "$(CFG) - @echo "--------------------------------------------------" - -rule : dep | inform - BUILD_DIR=bin/$(CFG) OBJS_DIR=objs/$(CFG) LIBDIR=lib/${CFG} @@ -31,25 +17,49 @@ SRCDIR=src APP=$(BUILD_DIR)/app APP_OBJECT=$(OBJS_DIR)/app.o +APP_DEPFILES=$(OBJS_DIR)/app.d FSMLIB_NAME=fsm FSMLIB=$(LIBDIR)/lib$(FSMLIB_NAME) -CODEDIRS=./src -INCDIRS=. ./include/ # can be list +CODEDIRS=src +INCDIRS=./ ./include/ # can be list CC=gcc -OPT=-O0 #generate files that encode make rules for the .h dependencies -DEPFLAGS=-MP -MD +DEPFLAGS=-MMD -MP #automatically add the -I onto each include directory -CFLAGS+=-Wall -Wextra $(foreach D,$(INCDIRS),-I$(D)) $(OPT) $(DEPFLAGS) +CFLAGS+=-Wall -Wextra $(foreach D , $(INCDIRS) , -I$(D)) $(DEPFLAGS) # for-style iteration (foreach) and regular expression completions (wildcard) -CFILES=$(foreach D, $(CODEDIRS),$(wildcard $(D)/*.c)) -# regular expression replacement -OBJECTS=$(patsubst %.c,$(OBJS_DIR)/%.o,$(CFILES)) -DEPFILES=$(patsubst %.c,$(OBJS_DIR)/%.d,$(CFILES)) +CFILES=$(foreach D , $(CODEDIRS) , $(wildcard $(D)/*.c)) -all: $(FSMLIB) $(APP) | create_dir + +#WTF, this below code is f**ked me up. +#didn't change anything but still works. +#WHYYY??? +# regular expression replacement +OBJECTS=$(patsubst $(SRCDIR)/%.c, $(OBJS_DIR)/%.o , $(CFILES)) +DEPFILES=$(patsubst $(SRCDIR)/%.c, $(OBJS_DIR)/%.d , $(CFILES)) +DEPFILES += $(APP_DEPFILES) + +# $(info CFILES: $(CFILES)) +# $(info OBJECTS: $(OBJECTS)) +# $(info DEPFILES: $(DEPFILES)) +# $(info APP_OBJECT: $(APP_OBJECT)) +# $(info APP_DEPFILES: $(APP_DEPFILES)) + +all: create_dir inform $(FSMLIB) $(APP) + +inform: +ifneq ($(CFG),release) +ifneq ($(CFG),debug) + @echo "Invalid configuration $(CFG) specified." + @echo + @echo "Possible choices for configuration are 'CFG=release' and 'CFG=debug'" + @exit 1 +endif +endif + @echo "Configuration $(CFG)" + @echo "--------------------------------------------------" create_dir: mkdir -p $(BUILD_DIR) @@ -57,18 +67,18 @@ create_dir: mkdir -p $(LIBDIR) -$(APP): $(APP_OBJECT) | create_dir - $(CC) -o $@ $^ -L $(LIBDIR) -l$(FSMLIB_NAME) +$(APP): $(APP_OBJECT) $(FSMLIB).a + $(CC) -o $@ $^ -L$(LIBDIR) -l$(FSMLIB_NAME) -$(FSMLIB): $(OBJECTS) | create_dir - ar cr $(LIBDIR)/${FSMLIB}.a ${OBJECTS} +$(FSMLIB): $(OBJECTS) + ar cr $(FSMLIB).a $(OBJECTS) # only want the .c file dependency here, thus $< instead of $^. # -$(OBJS_DIR)/%.o:$(SRCDIR)/%.c | create_dir +$(OBJS_DIR)/%.o: $(SRCDIR)/%.c $(CC) $(CFLAGS) -c -o $@ $< -$(OBJS_DIR)/%.o:%.c | create_dir +$(OBJS_DIR)/%.o: %.c $(CC) $(CFLAGS) -c -o $@ $< clean: diff --git a/app.c b/app.c index 090cadd..1bc3c86 100644 --- a/app.c +++ b/app.c @@ -1,15 +1,140 @@ #include #include -#include +#include +#include "fsm.h" + +#define MAX_FSM_STATE 24 + +#define modify_string(state,num) #state ## #num +#define modify_var(state,num) state ## num + +state_t *fsm_states[MAX_FSM_STATE]; + + +void print_fsm(fsm_t *fsm){ + + printf("FSM name : %s\n", fsm->fsm_name); + printf("States : "); + char state[6]; + for(unsigned int i = 0 ; i < fsm->state_count ; i++ ){ + sprintf(state,"q%1d",i); + printf("%s", state); + + if( i < fsm->state_count - 1 ) + printf(", "); + } + putchar('\n'); + + printf("Alphabets : %s\n", fsm->alphabet); + printf("Initial State : %s\n", fsm->initial_state->state_name); + printf("Final States : %s\n", fsm->final_states); + + printf("Transition Table :\n"); + + printf(" | 1 0 \n"); + printf("------------------------\n"); + + + char state1[6] = {0}; + char state2[6] = {0}; + char state3[6] = {0}; + + tt_t *table_ptr = NULL; + tt_entry_t *entry_ptr = NULL; + for( unsigned int i = 0 ; i < fsm->state_count ; i++ ){ + + strncpy(state1, fsm_states[i]->state_name, + strlen(fsm_states[i]->state_name)); + + table_ptr = &(fsm_states[i]->state_trans_table); + FSM_ITERATE_TRANS_TABLE_BEGIN(table_ptr, entry_ptr){ + + if( is_tt_entry_empty(entry_ptr) == FSM_FALSE ){ + if( strcmp(entry_ptr->transition_key, "1") == 0 ){ + strncpy(state2, entry_ptr->next_state->state_name, + strlen(entry_ptr->next_state->state_name)); + } + else{ + strncpy(state3, entry_ptr->next_state->state_name, + strlen(entry_ptr->next_state->state_name)); + } + } + + }FSM_ITERATE_TRANS_TABLE_END(table_ptr, entry_ptr) + + printf(" %s | %s %s \n", state1, state2, state3); + + } + +} int main(){ - fsm_t* fsm = create_new_fsm("FSM_1"); + fsm_t *fsm = create_new_fsm("FSM_1", "0,1"); - state_t* initial_state = create_new_state("q0", FSM_FALSE); - set_fsm_initial_state(fsm, initial_state); + //States + state_t *q0 = create_new_state("q0", FSM_FALSE, "FSM_1", fsm); + state_t *q1 = create_new_state("q1", FSM_TRUE, "FSM_1", fsm); + state_t *q2 = create_new_state("q2", FSM_TRUE, "FSM_1", fsm); + state_t *q3 = create_new_state("q3", FSM_FALSE, "FSM_1", fsm); + fsm_states[0] = q0; + fsm_states[1] = q1; + fsm_states[2] = q2; + fsm_states[3] = q3; + + set_fsm_initial_state(fsm, q0); + + //State q0 + tt_t *trans_table = &(q0->state_trans_table); + create_and_insert_new_tt_entry(trans_table, + "0", + 1, + q2); + create_and_insert_new_tt_entry(trans_table, + "1", + 1, + q1); + + //State q1 + trans_table = &(q1->state_trans_table); + create_and_insert_new_tt_entry(trans_table, + "0", + 1, + q2); + + create_and_insert_new_tt_entry(trans_table, + "1", + 1, + q3); + + //State q2 + trans_table = &(q2->state_trans_table); + create_and_insert_new_tt_entry(trans_table, + "0", + 1, + q3); + + create_and_insert_new_tt_entry(trans_table, + "1", + 1, + q1); + + //State q3 + trans_table = &(q3->state_trans_table); + create_and_insert_new_tt_entry(trans_table, + "0", + 1, + q3); + + create_and_insert_new_tt_entry(trans_table, + "1", + 1, + q3); + + + print_fsm(fsm); return 0; } \ No newline at end of file diff --git a/bin/debug/.fuse_hidden0000009f00000006 b/bin/debug/.fuse_hidden0000009f00000006 new file mode 100644 index 0000000..8416fbc Binary files /dev/null and b/bin/debug/.fuse_hidden0000009f00000006 differ diff --git a/include/fsm.h b/include/fsm.h index a12782c..9b994e4 100644 --- a/include/fsm.h +++ b/include/fsm.h @@ -9,6 +9,8 @@ #define MAX_STATE_NAME_SIZE 32 #define MAX_FSM_NAME_SIZE 32 #define MAX_TRANSITION_KEY_SIZE 64 +#define MAX_ALP_BUFFER_SIZE 30 +#define MAX_FINAL_STATE 128 /***Data structures and custom datatypes***/ @@ -61,6 +63,9 @@ struct state_{ /*Boolean value to distinguish b/w * accept/final state or vice-versa*/ fsm_bool_t is_final; + + /*FSM which the current state belongs to*/ + char fsm[MAX_FSM_NAME_SIZE]; }; struct fsm_{ @@ -68,6 +73,15 @@ struct fsm_{ /*Initial state of FSM to start with*/ state_t *initial_state; + /*Number of states in FSM*/ + unsigned int state_count; + + /*Set of alphabet*/ + char alphabet[MAX_ALP_BUFFER_SIZE]; + + /*Set of final/accept states*/ + char final_states[MAX_FINAL_STATE]; + /*Name of FSM*/ char fsm_name[MAX_FSM_NAME_SIZE]; @@ -87,18 +101,20 @@ struct fsm_{ /***Function Prototypes***/ fsm_t* -create_new_fsm(const char *fsm_name); +create_new_fsm(const char *fsm_name, const char *inp_alpha); state_t* -create_new_state(char *state_name, - fsm_bool_t is_final); +create_new_state(const char *state_name, + fsm_bool_t is_final, + const char *fsm_name, + fsm_t *fsm); 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, + const char *transition_key, unsigned int sizeof_key, state_t* next_state); @@ -110,7 +126,7 @@ get_next_empty_tt_entry(tt_t *trans_table); static inline fsm_bool_t is_tt_entry_empty(tt_entry_t *tt_entry){ - if(!tt_entry->next_state) + if( tt_entry != NULL && !tt_entry->next_state) return FSM_TRUE; return FSM_FALSE; diff --git a/src/fsm.c b/src/fsm.c index b3e348f..3ef222c 100644 --- a/src/fsm.c +++ b/src/fsm.c @@ -1,29 +1,41 @@ #include #include #include +#include #include "fsm.h" -fsm_t* -create_new_fsm(const char* fsm_name) +fsm_t * +create_new_fsm(const char* fsm_name, const char *inp_alpha) { 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'; + strncpy(fsm->fsm_name, fsm_name, strlen(fsm_name) ); + fsm->fsm_name[strlen(fsm_name)] = '\0'; + fsm->state_count = 0; + + strncpy(fsm->alphabet, inp_alpha, strlen(inp_alpha)); + fsm->alphabet[strlen(inp_alpha)] = '\0'; + + memset(fsm->final_states, 0, 1); + memset(fsm->input_buffer, 0, 1); + fsm->input_buffer_cursor = 0; + fsm->input_buffer_size = 0; return fsm; } -state_t* -create_new_state(char *state_name, - fsm_bool_t is_final){ +state_t * +create_new_state(const char *state_name, + fsm_bool_t is_final, + const char *fsm_name, + fsm_t *fsm){ 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'; + strncpy(state->state_name, state_name, strlen(state_name)); + state->state_name[strlen(state_name)] = '\0'; tt_t *trans_table = &(state->state_trans_table); tt_entry_t *tt_entry_ptr = NULL; @@ -34,6 +46,21 @@ create_new_state(char *state_name, state->is_final = is_final; + char temp_state_name[strlen(state_name)+2]; + strncpy(temp_state_name, state_name, strlen(state_name)); + temp_state_name[strlen(state_name)] = '\0'; + + if(state->is_final == FSM_TRUE){ + strcat(temp_state_name,","); + strcat(fsm->final_states,temp_state_name); + } + // fsm->final_states[strlen(fsm->final_states)+2] = '\0'; + + strncpy(state->fsm, fsm_name, strlen(fsm_name)); + state->fsm[strlen(fsm_name)] = '\0'; + + fsm->state_count++; + return state; } @@ -45,7 +72,7 @@ set_fsm_initial_state(fsm_t *fsm, state_t *state){ } -tt_entry_t* +tt_entry_t * get_next_empty_tt_entry(tt_t *trans_table){ tt_entry_t* tt_entry_ptr = NULL; @@ -64,9 +91,9 @@ get_next_empty_tt_entry(tt_t *trans_table){ return NULL; } -tt_entry_t* +tt_entry_t * create_and_insert_new_tt_entry(tt_t *trans_table, - char *transition_key, + const char *transition_key, unsigned int sizeof_key, state_t* next_state){