Dummy commit to test new ssh key
[eleutheria.git] / fsm / test_rmcom.c
blobb74897a7eec692b19ac77d53d8c87e2e059b226e
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h> /* for memset() */
5 #include "fsm.h"
6 #include "states.h"
7 #include "types.h"
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
15 #define ST_COMMENT 2
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
26 * appropriate event.
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)
33 unsigned int stkey;
35 /* Get current state of FSM */
36 stkey = fsm_get_current_state(fsm);
38 if (stkey == ST_NO_COMMENT) {
39 if (**p == '/' && (*p)[1] == '*') {
40 *p += 2;
41 return EVT_START_COMMENT;
43 else {
44 *p += 1;
45 return EVT_NO_START_COMMENT;
48 else if (stkey == ST_COMMENT) {
49 if (**p == '*' && (*p)[1] == '/') {
50 *p += 2;
51 return EVT_END_COMMENT;
53 else {
54 *p += 1;
55 return EVT_NO_END_COMMENT;
59 /* Normally, this would never be reached */
60 *p += 1;
61 return -1;
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;
73 state_t *st_comment;
74 fsm_t *fsm;
75 FILE *fp;
76 char *p;
78 /* Check argument count */
79 if (argc != 2) {
80 fprintf(stderr, "Usage: %s file.c\n", argv[0]);
81 exit(EXIT_FAILURE);
84 /* Open file to parse */
85 if ((fp = fopen(argv[1], "r")) == NULL) {
86 perror("fopen()");
87 exit(EXIT_FAILURE);
90 /* Initialize fsm */
91 fsm_init(&fsm, 2<<8, 5, 0);
93 /* Initialize states */
94 if (state_init(&st_no_comment, 2<<5, 2) == ST_NOMEM) {
95 fsm_free(fsm);
96 dief("state_init(): ST_NOMEM");
98 if (state_init(&st_comment, 2<<5, 2) == ST_NOMEM) {
99 fsm_free(fsm);
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");
110 fsm_free(fsm);
113 /* Add states */
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);
120 /* Parse file */
121 while (!feof(fp)) {
122 memset(buf, 0, sizeof buf);
123 if (fgets(buf, sizeof buf, fp) == NULL && !feof(fp)) {
124 perror("fgets()");
125 break;
127 p = buf;
128 while (*p != '\0')
129 fsm_process_event(fsm, get_evt_key(fsm, &p), p);
132 /* Free memory */
133 fsm_free(fsm);
135 /* Close file */
136 (void)fclose(fp);
138 return EXIT_SUCCESS;
141 void dief(const char *p)
143 fprintf(stderr, "error: %s\n", p);
144 exit(EXIT_FAILURE);