3 #include <string.h> /* for memset() */
9 #define EVT_NO_START_COMMENT 1
10 #define EVT_NO_END_COMMENT 2
11 #define EVT_START_COMMENT 3
12 #define EVT_END_COMMENT 4
14 #define ST_NO_COMMENT 1
17 /* Function prototypes */
18 unsigned int get_evt_key(const fsm_t
*fsm
, char **p
);
19 void print_char(void *data
);
20 void dief(const char *p
);
23 * get_evt_key() works like an "event generator".
24 * It examines the current state of FSM along with
25 * the input we feed it, and then generates an
28 * fsm_process_event() acts as an "event consumer",
29 * handling each one of the previously generated events.
31 unsigned int get_evt_key(const fsm_t
*fsm
, char **p
)
35 /* Get current state of FSM */
36 stkey
= fsm_get_current_state(fsm
);
38 if (stkey
== ST_NO_COMMENT
) {
39 if (**p
== '/' && (*p
)[1] == '*') {
41 return EVT_START_COMMENT
;
45 return EVT_NO_START_COMMENT
;
48 else if (stkey
== ST_COMMENT
) {
49 if (**p
== '*' && (*p
)[1] == '/') {
51 return EVT_END_COMMENT
;
55 return EVT_NO_END_COMMENT
;
59 /* Normally, this would never be reached */
64 void print_char(void *data
)
66 printf("%c", *(char *)data
);
69 int main(int argc
, char *argv
[])
71 char buf
[256]; /* must be big enough, or else beginning of comment might split */
72 state_t
*st_no_comment
;
78 /* Check argument count */
80 fprintf(stderr
, "Usage: %s file.c\n", argv
[0]);
84 /* Open file to parse */
85 if ((fp
= fopen(argv
[1], "r")) == NULL
) {
91 fsm_init(&fsm
, 2<<8, 5, 0);
93 /* Initialize states */
94 if (state_init(&st_no_comment
, 2<<5, 2) == ST_NOMEM
) {
96 dief("state_init(): ST_NOMEM");
98 if (state_init(&st_comment
, 2<<5, 2) == ST_NOMEM
) {
100 state_free(st_no_comment
);
101 dief("state_init(): ST_NOMEM");
104 /* Construct state transition table */
105 if ((state_add_evt(st_no_comment
, EVT_NO_START_COMMENT
, "", print_char
, st_no_comment
) == ST_NOMEM
) ||
106 (state_add_evt(st_no_comment
, EVT_START_COMMENT
, "", NULL
, st_comment
) == ST_NOMEM
) ||
107 (state_add_evt(st_comment
, EVT_NO_END_COMMENT
, "", NULL
, st_comment
) == ST_NOMEM
) ||
108 (state_add_evt(st_comment
, EVT_END_COMMENT
, "", NULL
, st_no_comment
))) {
109 dief("state_add_evt(): ST_NOMEM");
114 fsm_add_state(fsm
, ST_NO_COMMENT
, st_no_comment
);
115 fsm_add_state(fsm
, ST_COMMENT
, st_comment
);
117 /* Set initial state */
118 fsm_set_state(fsm
, ST_NO_COMMENT
);
122 memset(buf
, 0, sizeof buf
);
123 if (fgets(buf
, sizeof buf
, fp
) == NULL
&& !feof(fp
)) {
129 fsm_process_event(fsm
, get_evt_key(fsm
, &p
), p
);
141 void dief(const char *p
)
143 fprintf(stderr
, "error: %s\n", p
);