Skip to content

Commit 4a5ca84

Browse files
committed
Replace FSM_ADVANCE_HOOK macro with optional hooks->advance callback.
1 parent 1e55db8 commit 4a5ca84

File tree

3 files changed

+38
-39
lines changed

3 files changed

+38
-39
lines changed

include/fsm/print.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ struct fsm_hooks {
7878
const struct fsm_state_metadata *state_metadata,
7979
void *lang_opaque, void *hook_opaque);
8080

81+
/* If non-NULL, this will be called to generate code
82+
* in scope immediately after advancing to the
83+
* next character of input. */
84+
int (*advance)(FILE *, const struct fsm_options *opt,
85+
const char *cur_char_var, void *hook_opaque);
86+
8187
int (*comment)(FILE *, const struct fsm_options *opt,
8288
const struct fsm_state_metadata *state_metadata,
8389
void *hook_opaque);

src/libfsm/print/c.c

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -495,30 +495,6 @@ fsm_print_c_body(FILE *f, const struct ir *ir,
495495
* input loop was skipped it would still be NONE. */
496496
fprintf(f, "\tint has_consumed_input = 0;\n");
497497

498-
/* For FSM_IO_STR and FSM_IO_PAIR, define a macro that will be
499-
* called with the new character every time iteration advances.
500-
* This is used by lx's internal bookkeeping to track token
501-
* positions in the input stream. For FSM_IO_GETC, the generated
502-
* getc function handles this directly.
503-
*
504-
* This defaults to a no-op unless defined. */
505-
switch (opt->io) {
506-
case FSM_IO_GETC:
507-
break; /* nothing to do */
508-
509-
case FSM_IO_STR:
510-
fprintf(f, "#ifndef FSM_ADVANCE_HOOK\n");
511-
fprintf(f, "#define FSM_ADVANCE_HOOK(C) /* no-op */ (void)C\n");
512-
fprintf(f, "#endif\n");
513-
break;
514-
515-
case FSM_IO_PAIR:
516-
fprintf(f, "#ifndef FSM_ADVANCE_HOOK\n");
517-
fprintf(f, "#define FSM_ADVANCE_HOOK(C) /* no-op */ (void)C\n");
518-
fprintf(f, "#endif\n");
519-
break;
520-
}
521-
522498
/* enum of states */
523499
print_stateenum(f, ir->n);
524500
fprintf(f, "\n");
@@ -536,13 +512,21 @@ fsm_print_c_body(FILE *f, const struct ir *ir,
536512
case FSM_IO_STR:
537513
fprintf(f, "\tfor (p = s; *p != '\\0'; p++) {\n");
538514
fprintf(f, "\t\thas_consumed_input = 1;\n");
539-
fprintf(f, "\t\tFSM_ADVANCE_HOOK(%s);\n", cp);
515+
if (hooks->advance != NULL) {
516+
if (-1 == hooks->advance(f, opt, cp, hooks->hook_opaque)) {
517+
return -1;
518+
}
519+
}
540520
break;
541521

542522
case FSM_IO_PAIR:
543523
fprintf(f, "\tfor (p = b; p != e; p++) {\n");
544524
fprintf(f, "\t\thas_consumed_input = 1;\n");
545-
fprintf(f, "\t\tFSM_ADVANCE_HOOK(%s);\n", cp);
525+
if (hooks->advance != NULL) {
526+
if (-1 == hooks->advance(f, opt, cp, hooks->hook_opaque)) {
527+
return -1;
528+
}
529+
}
546530
break;
547531
}
548532

src/lx/print/c.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,26 @@ reject_c(FILE *f, const struct fsm_options *opt,
297297
return 0;
298298
}
299299

300+
static int
301+
advance_c(FILE *f, const struct fsm_options *opt, const char *cur_char_var, void *hook_opaque)
302+
{
303+
(void)hook_opaque;
304+
305+
switch (opt->io) {
306+
case FSM_IO_GETC:
307+
break;
308+
309+
case FSM_IO_STR:
310+
case FSM_IO_PAIR:
311+
/* When libfsm's generated code advances a character, update
312+
* lx's token name buffer and position bookkeeping. */
313+
fprintf(f, "\t\tif (!%sadvance_end(lx, %s)) { return %sERROR; }\n",
314+
prefix.api, cur_char_var, prefix.tok);
315+
break;
316+
}
317+
return 0;
318+
}
319+
300320
static void
301321
print_proto(FILE *f, const struct ast *ast, const struct ast_zone *z)
302322
{
@@ -485,8 +505,7 @@ print_io(FILE *f, const struct fsm_options *opt)
485505
fprintf(f, "}\n");
486506
fprintf(f, "\n");
487507

488-
switch (opt->io) {
489-
case FSM_IO_GETC:
508+
if (opt->io == FSM_IO_GETC) {
490509
/* TODO: consider passing char *c, and return int 0/-1 for error */
491510
if (opt->comments) {
492511
fprintf(f, "/* This wrapper manages one character of lookahead/pushback\n");
@@ -536,17 +555,6 @@ print_io(FILE *f, const struct fsm_options *opt)
536555
fprintf(f, "\treturn %sgetc((struct %slx *)getc_opaque);\n", prefix.api, prefix.lx);
537556
fprintf(f, "}\n");
538557
fprintf(f, "\n");
539-
break;
540-
541-
case FSM_IO_PAIR:
542-
case FSM_IO_STR:
543-
/* When libfsm's generated code advances a character, update
544-
* lx's token name buffer and position bookkeeping. */
545-
fprintf(f, "#ifndef FSM_ADVANCE_HOOK\n");
546-
fprintf(f, "#define FSM_ADVANCE_HOOK(C) if (!%sadvance_end(lx, C)) { return %sERROR; }\n", prefix.api, prefix.tok);
547-
fprintf(f, "#endif\n");
548-
fprintf(f, "\n");
549-
break;
550558
}
551559

552560
fprintf(f, "#if __STDC_VERSION__ >= 199901L\n");
@@ -831,6 +839,7 @@ print_zone(FILE *f, const struct ast *ast, const struct ast_zone *z,
831839

832840
hooks.accept = accept_c;
833841
hooks.reject = reject_c;
842+
hooks.advance = advance_c;
834843
hooks.hook_opaque = &hook_env;
835844

836845
fsm_print(f, z->fsm, opt, &hooks, FSM_PRINT_C);

0 commit comments

Comments
 (0)