From 2afe5637728c5dcbf6d9aa53f5b390290cc636a5 Mon Sep 17 00:00:00 2001 From: Kate F Date: Fri, 7 Jun 2024 15:52:29 +0100 Subject: [PATCH 01/28] Default to printing endids when no .endleaf callback is present. --- src/libfsm/print/dot.c | 54 +++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/libfsm/print/dot.c b/src/libfsm/print/dot.c index 25f6ea4a7..ab360af2b 100644 --- a/src/libfsm/print/dot.c +++ b/src/libfsm/print/dot.c @@ -37,16 +37,6 @@ singlestate(FILE *f, const struct fsm *fsm, fsm_state_t s) assert(fsm->opt != NULL); assert(s < fsm->statecount); - if (!fsm->opt->anonymous_states) { - fprintf(f, "\t%sS%-2u [ label = <", - fsm->opt->prefix != NULL ? fsm->opt->prefix : "", - s); - - fprintf(f, "%u", s); - - fprintf(f, "> ];\n"); - } - if (!fsm->opt->consolidate_edges) { { struct state_iter jt; @@ -163,18 +153,24 @@ singlestate(FILE *f, const struct fsm *fsm, fsm_state_t s) static int print_dotfrag(FILE *f, const struct fsm *fsm) { - fsm_state_t i; + fsm_state_t s; assert(f != NULL); assert(fsm != NULL); assert(fsm->opt != NULL); - for (i = 0; i < fsm->statecount; i++) { - if (fsm_isend(fsm, i)) { + for (s = 0; s < fsm->statecount; s++) { + if (!fsm_isend(fsm, s)) { + if (!fsm->opt->anonymous_states) { + fprintf(f, "\t%sS%-2u [ label = <%u> ];\n", + fsm->opt->prefix != NULL ? fsm->opt->prefix : "", + s, s); + } + } else { enum fsm_getendids_res res; size_t written; struct fsm_end_ids *ids = NULL; - const size_t count = fsm_getendidcount(fsm, i); + const size_t count = fsm_getendidcount(fsm, s); if (count > 0) { ids = f_malloc(fsm->opt->alloc, sizeof(*ids) + ((count - 1) * sizeof(ids->ids))); @@ -183,7 +179,7 @@ print_dotfrag(FILE *f, const struct fsm *fsm) return -1; } - res = fsm_getendids(fsm, i, count, + res = fsm_getendids(fsm, s, count, ids->ids, &written); if (res == FSM_GETENDIDS_FOUND) { ids->count = (unsigned)written; @@ -193,13 +189,37 @@ print_dotfrag(FILE *f, const struct fsm *fsm) } fprintf(f, "\t%sS%-2u [ shape = doublecircle", - fsm->opt->prefix != NULL ? fsm->opt->prefix : "", i); + fsm->opt->prefix != NULL ? fsm->opt->prefix : "", s); if (fsm->opt->endleaf != NULL) { fprintf(f, ", "); if (-1 == fsm->opt->endleaf(f, ids, fsm->opt->endleaf_opaque)) { return -1; } + } else { + assert(f != NULL); + + fprintf(f, ", "); + + fprintf(f, "label = <"); + + if (!fsm->opt->anonymous_states) { + fprintf(f, "%u", s); + + if (ids->count > 0) { + fprintf(f, "
"); + } + } + + for (size_t i = 0; i < ids->count; i++) { + fprintf(f, "#%u", ids->ids[i]); + + if (i < ids->count - 1) { + fprintf(f, ","); + } + } + + fprintf(f, ">"); } fprintf(f, " ];\n"); @@ -209,7 +229,7 @@ print_dotfrag(FILE *f, const struct fsm *fsm) /* TODO: show example here, unless !opt->comments */ - if (-1 == singlestate(f, fsm, i)) { + if (-1 == singlestate(f, fsm, s)) { return -1; } } From ffea1decb956b0f396405c60a514ea6f049eecac Mon Sep 17 00:00:00 2001 From: Kate F Date: Fri, 7 Jun 2024 16:31:37 +0100 Subject: [PATCH 02/28] Return a set of endids, rather than the state id. --- src/libfsm/print/awk.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/libfsm/print/awk.c b/src/libfsm/print/awk.c index b71ffc307..c7083e6e2 100644 --- a/src/libfsm/print/awk.c +++ b/src/libfsm/print/awk.c @@ -91,6 +91,8 @@ static int print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, enum dfavm_op_end end_bits, const struct ir *ir) { + (void) ir; + if (end_bits == VM_END_FAIL) { fprintf(f, "return -1"); return 0; @@ -101,7 +103,22 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, return -1; } } else { - fprintf(f, "return %td", op->ir_state - ir->states); + size_t i; + + assert(f != NULL); + + /* awk can't return an array */ + fprintf(f, "return \""); + + for (i = 0; i < op->ir_state->end_ids->count; i++) { + fprintf(f, "%u", op->ir_state->end_ids->ids[i]); + + if (i < op->ir_state->end_ids->count - 1) { + fprintf(f, ","); + } + } + + fprintf(f, "\""); } return 0; From f84aa387d96644063d5c429c7819b065e822cca9 Mon Sep 17 00:00:00 2001 From: Kate F Date: Sat, 8 Jun 2024 07:02:14 -0700 Subject: [PATCH 03/28] Naming. I'm keeping "id" free. --- src/libfsm/parser.c | 412 +++++++++++++++++++++--------------------- src/libfsm/parser.sid | 22 +-- 2 files changed, 217 insertions(+), 217 deletions(-) diff --git a/src/libfsm/parser.c b/src/libfsm/parser.c index 19d5664f3..998e9ee75 100644 --- a/src/libfsm/parser.c +++ b/src/libfsm/parser.c @@ -146,13 +146,13 @@ static void p_label(fsm, lex_state, act_state, char *); static void p_items(fsm, lex_state, act_state); +static void p_xend_C_Cend_Hstates(fsm, lex_state, act_state); static void p_xstart(fsm, lex_state, act_state); static void p_xend(fsm, lex_state, act_state); +static void p_xend_C_Cend_Hstate(fsm, lex_state, act_state); static void p_61(fsm, lex_state, act_state); static void p_63(fsm, lex_state, act_state, string *); extern void p_fsm(fsm, lex_state, act_state); -static void p_xend_C_Cend_Hids(fsm, lex_state, act_state); -static void p_xend_C_Cend_Hid(fsm, lex_state, act_state); /* BEGINNING OF STATIC VARIABLES */ @@ -323,7 +323,7 @@ ZL2_items:; { string ZIa; - /* BEGINNING OF INLINE: id */ + /* BEGINNING OF INLINE: ident */ { { switch (CURRENT_TERMINAL) { @@ -345,7 +345,7 @@ ZL2_items:; ADVANCE_LEXER; } } - /* END OF INLINE: id */ + /* END OF INLINE: ident */ p_63 (fsm, lex_state, act_state, &ZIa); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; @@ -370,6 +370,67 @@ ZL1:; return; } +static void +p_xend_C_Cend_Hstates(fsm fsm, lex_state lex_state, act_state act_state) +{ + if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { + return; + } +ZL2_xend_C_Cend_Hstates:; + { + p_xend_C_Cend_Hstate (fsm, lex_state, act_state); + /* BEGINNING OF INLINE: 58 */ + { + switch (CURRENT_TERMINAL) { + case (TOK_COMMA): + { + /* BEGINNING OF INLINE: 59 */ + { + { + switch (CURRENT_TERMINAL) { + case (TOK_COMMA): + break; + default: + goto ZL5; + } + ADVANCE_LEXER; + } + goto ZL4; + ZL5:; + { + /* BEGINNING OF ACTION: err-expected-comma */ + { +#line 362 "src/libfsm/parser.act" + + err_expected(lex_state, "','"); + +#line 408 "src/libfsm/parser.c" + } + /* END OF ACTION: err-expected-comma */ + } + ZL4:; + } + /* END OF INLINE: 59 */ + /* BEGINNING OF INLINE: xend::end-states */ + goto ZL2_xend_C_Cend_Hstates; + /* END OF INLINE: xend::end-states */ + } + /*UNREACHED*/ + case (ERROR_TERMINAL): + RESTORE_LEXER; + goto ZL1; + default: + break; + } + } + /* END OF INLINE: 58 */ + } + return; +ZL1:; + SAVE_LEXER ((ERROR_TERMINAL)); + return; +} + static void p_xstart(fsm fsm, lex_state lex_state, act_state act_state) { @@ -399,14 +460,14 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) err_expected(lex_state, "'start:'"); -#line 403 "src/libfsm/parser.c" +#line 464 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-start */ } ZL2:; } /* END OF INLINE: 50 */ - /* BEGINNING OF INLINE: id */ + /* BEGINNING OF INLINE: ident */ { { switch (CURRENT_TERMINAL) { @@ -418,7 +479,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) /* XXX: don't exit in library code */ ZIn = xstrdup(lex_state->buf.a); -#line 422 "src/libfsm/parser.c" +#line 483 "src/libfsm/parser.c" } /* END OF EXTRACT: IDENT */ break; @@ -428,7 +489,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) ADVANCE_LEXER; } } - /* END OF INLINE: id */ + /* END OF INLINE: ident */ p_61 (fsm, lex_state, act_state); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; @@ -489,7 +550,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) act_state->states.buckets[bucket_id] = new; } -#line 493 "src/libfsm/parser.c" +#line 554 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: mark-start */ @@ -498,7 +559,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) fsm_setstart(fsm, (ZIs)); -#line 502 "src/libfsm/parser.c" +#line 563 "src/libfsm/parser.c" } /* END OF ACTION: mark-start */ /* BEGINNING OF ACTION: free */ @@ -507,7 +568,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) free((ZIn)); -#line 511 "src/libfsm/parser.c" +#line 572 "src/libfsm/parser.c" } /* END OF ACTION: free */ } @@ -549,14 +610,14 @@ p_xend(fsm fsm, lex_state lex_state, act_state act_state) err_expected(lex_state, "'end:'"); -#line 553 "src/libfsm/parser.c" +#line 614 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-end */ } ZL2:; } /* END OF INLINE: 60 */ - p_xend_C_Cend_Hids (fsm, lex_state, act_state); + p_xend_C_Cend_Hstates (fsm, lex_state, act_state); p_61 (fsm, lex_state, act_state); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; @@ -575,6 +636,122 @@ ZL1:; return; } +static void +p_xend_C_Cend_Hstate(fsm fsm, lex_state lex_state, act_state act_state) +{ + if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { + return; + } + { + string ZIn; + state ZIs; + + /* BEGINNING OF INLINE: ident */ + { + { + switch (CURRENT_TERMINAL) { + case (TOK_IDENT): + /* BEGINNING OF EXTRACT: IDENT */ + { +#line 245 "src/libfsm/parser.act" + + /* XXX: don't exit in library code */ + ZIn = xstrdup(lex_state->buf.a); + +#line 662 "src/libfsm/parser.c" + } + /* END OF EXTRACT: IDENT */ + break; + default: + goto ZL1; + } + ADVANCE_LEXER; + } + } + /* END OF INLINE: ident */ + /* BEGINNING OF ACTION: add-state */ + { +#line 252 "src/libfsm/parser.act" + + struct act_statelist *p; + const unsigned hash = hash_of_id((ZIn)); + const unsigned mask = act_state->states.bucket_count - 1; + size_t chain_length = 0; + unsigned bucket_id = hash & mask; + + assert((ZIn) != NULL); + + if (act_state->states.longest_chain_length > MAX_CHAIN_LENGTH) { + grow_state_hash_table(&act_state->states); + bucket_id = hash & (act_state->states.bucket_count - 1); + } + + for (p = act_state->states.buckets[bucket_id]; p != NULL; p = p->next) { + assert(p->id != NULL); + + chain_length++; + + if (0 == strcmp(p->id, (ZIn))) { + (ZIs) = p->state; + break; + } + } + + if (chain_length > act_state->states.longest_chain_length) { + act_state->states.longest_chain_length = chain_length; + } + + if (p == NULL) { + struct act_statelist *new; + + new = malloc(sizeof *new); + if (new == NULL) { + perror("malloc"); + exit(EXIT_FAILURE); + } + + /* XXX: don't exit in library code */ + new->id = xstrdup((ZIn)); + + if (!fsm_addstate(fsm, &(ZIs))) { + perror("fsm_addstate"); + exit(EXIT_FAILURE); + } + + new->state = (ZIs); + + new->next = act_state->states.buckets[bucket_id]; + act_state->states.buckets[bucket_id] = new; + } + +#line 728 "src/libfsm/parser.c" + } + /* END OF ACTION: add-state */ + /* BEGINNING OF ACTION: mark-end */ + { +#line 308 "src/libfsm/parser.act" + + fsm_setend(fsm, (ZIs), 1); + +#line 737 "src/libfsm/parser.c" + } + /* END OF ACTION: mark-end */ + /* BEGINNING OF ACTION: free */ + { +#line 312 "src/libfsm/parser.act" + + free((ZIn)); + +#line 746 "src/libfsm/parser.c" + } + /* END OF ACTION: free */ + } + return; +ZL1:; + SAVE_LEXER ((ERROR_TERMINAL)); + return; +} + static void p_61(fsm fsm, lex_state lex_state, act_state act_state) { @@ -599,7 +776,7 @@ ZL1:; err_expected(lex_state, "';'"); -#line 603 "src/libfsm/parser.c" +#line 780 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-sep */ } @@ -616,7 +793,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) state ZIy; ADVANCE_LEXER; - /* BEGINNING OF INLINE: id */ + /* BEGINNING OF INLINE: ident */ { { switch (CURRENT_TERMINAL) { @@ -628,7 +805,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) /* XXX: don't exit in library code */ ZIb = xstrdup(lex_state->buf.a); -#line 632 "src/libfsm/parser.c" +#line 809 "src/libfsm/parser.c" } /* END OF EXTRACT: IDENT */ break; @@ -638,7 +815,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) ADVANCE_LEXER; } } - /* END OF INLINE: id */ + /* END OF INLINE: ident */ /* BEGINNING OF ACTION: add-state */ { #line 252 "src/libfsm/parser.act" @@ -694,7 +871,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) act_state->states.buckets[bucket_id] = new; } -#line 698 "src/libfsm/parser.c" +#line 875 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: add-state */ @@ -752,7 +929,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) act_state->states.buckets[bucket_id] = new; } -#line 756 "src/libfsm/parser.c" +#line 933 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: free */ @@ -761,7 +938,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) free((*ZIa)); -#line 765 "src/libfsm/parser.c" +#line 942 "src/libfsm/parser.c" } /* END OF ACTION: free */ /* BEGINNING OF ACTION: free */ @@ -770,7 +947,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) free((ZIb)); -#line 774 "src/libfsm/parser.c" +#line 951 "src/libfsm/parser.c" } /* END OF ACTION: free */ /* BEGINNING OF INLINE: 42 */ @@ -788,7 +965,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) exit(EXIT_FAILURE); } -#line 792 "src/libfsm/parser.c" +#line 969 "src/libfsm/parser.c" } /* END OF ACTION: add-edge-any */ } @@ -811,7 +988,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) exit(EXIT_FAILURE); } -#line 815 "src/libfsm/parser.c" +#line 992 "src/libfsm/parser.c" } /* END OF ACTION: add-edge-literal */ } @@ -827,7 +1004,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) exit(EXIT_FAILURE); } -#line 831 "src/libfsm/parser.c" +#line 1008 "src/libfsm/parser.c" } /* END OF ACTION: add-edge-epsilon */ } @@ -842,7 +1019,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) err_expected(lex_state, "transition"); -#line 846 "src/libfsm/parser.c" +#line 1023 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-trans */ } @@ -915,7 +1092,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) act_state->states.buckets[bucket_id] = new; } -#line 919 "src/libfsm/parser.c" +#line 1096 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: free */ @@ -924,7 +1101,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) free((*ZIa)); -#line 928 "src/libfsm/parser.c" +#line 1105 "src/libfsm/parser.c" } /* END OF ACTION: free */ p_61 (fsm, lex_state, act_state); @@ -982,7 +1159,7 @@ p_fsm(fsm fsm, lex_state lex_state, act_state act_state) } } -#line 986 "src/libfsm/parser.c" +#line 1163 "src/libfsm/parser.c" } /* END OF ACTION: free-statelist */ } @@ -996,189 +1173,12 @@ ZL1:; err(lex_state, "Syntax error"); exit(EXIT_FAILURE); -#line 1000 "src/libfsm/parser.c" +#line 1177 "src/libfsm/parser.c" } /* END OF ACTION: err-syntax */ } } -static void -p_xend_C_Cend_Hids(fsm fsm, lex_state lex_state, act_state act_state) -{ - if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { - return; - } -ZL2_xend_C_Cend_Hids:; - { - p_xend_C_Cend_Hid (fsm, lex_state, act_state); - /* BEGINNING OF INLINE: 58 */ - { - switch (CURRENT_TERMINAL) { - case (TOK_COMMA): - { - /* BEGINNING OF INLINE: 59 */ - { - { - switch (CURRENT_TERMINAL) { - case (TOK_COMMA): - break; - default: - goto ZL5; - } - ADVANCE_LEXER; - } - goto ZL4; - ZL5:; - { - /* BEGINNING OF ACTION: err-expected-comma */ - { -#line 362 "src/libfsm/parser.act" - - err_expected(lex_state, "','"); - -#line 1040 "src/libfsm/parser.c" - } - /* END OF ACTION: err-expected-comma */ - } - ZL4:; - } - /* END OF INLINE: 59 */ - /* BEGINNING OF INLINE: xend::end-ids */ - goto ZL2_xend_C_Cend_Hids; - /* END OF INLINE: xend::end-ids */ - } - /*UNREACHED*/ - case (ERROR_TERMINAL): - RESTORE_LEXER; - goto ZL1; - default: - break; - } - } - /* END OF INLINE: 58 */ - } - return; -ZL1:; - SAVE_LEXER ((ERROR_TERMINAL)); - return; -} - -static void -p_xend_C_Cend_Hid(fsm fsm, lex_state lex_state, act_state act_state) -{ - if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { - return; - } - { - string ZIn; - state ZIs; - - /* BEGINNING OF INLINE: id */ - { - { - switch (CURRENT_TERMINAL) { - case (TOK_IDENT): - /* BEGINNING OF EXTRACT: IDENT */ - { -#line 245 "src/libfsm/parser.act" - - /* XXX: don't exit in library code */ - ZIn = xstrdup(lex_state->buf.a); - -#line 1089 "src/libfsm/parser.c" - } - /* END OF EXTRACT: IDENT */ - break; - default: - goto ZL1; - } - ADVANCE_LEXER; - } - } - /* END OF INLINE: id */ - /* BEGINNING OF ACTION: add-state */ - { -#line 252 "src/libfsm/parser.act" - - struct act_statelist *p; - const unsigned hash = hash_of_id((ZIn)); - const unsigned mask = act_state->states.bucket_count - 1; - size_t chain_length = 0; - unsigned bucket_id = hash & mask; - - assert((ZIn) != NULL); - - if (act_state->states.longest_chain_length > MAX_CHAIN_LENGTH) { - grow_state_hash_table(&act_state->states); - bucket_id = hash & (act_state->states.bucket_count - 1); - } - - for (p = act_state->states.buckets[bucket_id]; p != NULL; p = p->next) { - assert(p->id != NULL); - - chain_length++; - - if (0 == strcmp(p->id, (ZIn))) { - (ZIs) = p->state; - break; - } - } - - if (chain_length > act_state->states.longest_chain_length) { - act_state->states.longest_chain_length = chain_length; - } - - if (p == NULL) { - struct act_statelist *new; - - new = malloc(sizeof *new); - if (new == NULL) { - perror("malloc"); - exit(EXIT_FAILURE); - } - - /* XXX: don't exit in library code */ - new->id = xstrdup((ZIn)); - - if (!fsm_addstate(fsm, &(ZIs))) { - perror("fsm_addstate"); - exit(EXIT_FAILURE); - } - - new->state = (ZIs); - - new->next = act_state->states.buckets[bucket_id]; - act_state->states.buckets[bucket_id] = new; - } - -#line 1155 "src/libfsm/parser.c" - } - /* END OF ACTION: add-state */ - /* BEGINNING OF ACTION: mark-end */ - { -#line 308 "src/libfsm/parser.act" - - fsm_setend(fsm, (ZIs), 1); - -#line 1164 "src/libfsm/parser.c" - } - /* END OF ACTION: mark-end */ - /* BEGINNING OF ACTION: free */ - { -#line 312 "src/libfsm/parser.act" - - free((ZIn)); - -#line 1173 "src/libfsm/parser.c" - } - /* END OF ACTION: free */ - } - return; -ZL1:; - SAVE_LEXER ((ERROR_TERMINAL)); - return; -} - /* BEGINNING OF TRAILER */ #line 431 "src/libfsm/parser.act" diff --git a/src/libfsm/parser.sid b/src/libfsm/parser.sid index d1da43b30..32a370312 100644 --- a/src/libfsm/parser.sid +++ b/src/libfsm/parser.sid @@ -64,14 +64,14 @@ LABEL; }; - id: () -> (n :string) = { + ident: () -> (n :string) = { n = IDENT; }; edge = { - a = id; + a = ident; TO; - b = id; + b = ident; x = (a); y = (b); @@ -106,7 +106,7 @@ * its own output. */ decl = { - a = id; + a = ident; ! = (a); @@ -137,7 +137,7 @@ ; }; - n = id; + n = ident; { SEP; @@ -155,8 +155,8 @@ xend [ - end-id = { - n = id; + end-state = { + n = ident; s = (n); (s); @@ -164,8 +164,8 @@ (n); }; - end-ids = { - end-id; + end-states = { + end-state; { { @@ -174,7 +174,7 @@ ; }; - end-ids; + end-states; || $; }; @@ -187,7 +187,7 @@ ; }; - end-ids; + end-states; { SEP; From a7d2e505d5c3dc997f7fb45579c145e2a5c130b0 Mon Sep 17 00:00:00 2001 From: Kate F Date: Mon, 10 Jun 2024 01:46:16 -0700 Subject: [PATCH 04/28] Add syntax for endids in .fsm format. These are optional. I'd expected this to be per state at file scope, but I don't like that the syntax would then allow attempting to attach an id to a non-accepting state. Since we have a block for `end:` already, adding the end ids here means they can't be mixed up. This looks like: ``` ; ./build/bin/re -r pcre -bpl fsm 'ab?c' 'abc*' 0 -> 1 "a"; # e.g. "a" 1 -> 2 "b"; # e.g. "ab" 1 -> 3 "c"; # e.g. "ac" 2 -> 4 "c"; # e.g. "abc" 4 -> 5 "c"; # e.g. "abcc" 5 -> 5 "c"; # e.g. "abcc" start: 0; end: 2 = [0], 3 = [0], 4 = [0, 1], 5 = [0]; ``` --- src/libfsm/lexer.c | 539 ++++++++++++++++++++++++++++++----------- src/libfsm/lexer.h | 6 +- src/libfsm/lexer.lx | 11 + src/libfsm/parser.act | 43 +++- src/libfsm/parser.c | 471 +++++++++++++++++++++++------------ src/libfsm/parser.h | 4 +- src/libfsm/parser.sid | 45 +++- src/libfsm/print/fsm.c | 66 ++++- 8 files changed, 876 insertions(+), 309 deletions(-) diff --git a/src/libfsm/lexer.c b/src/libfsm/lexer.c index 7213bb142..8bd374cec 100644 --- a/src/libfsm/lexer.c +++ b/src/libfsm/lexer.c @@ -12,6 +12,8 @@ static enum lx_token z0(struct lx *lx); static enum lx_token z1(struct lx *lx); static enum lx_token z2(struct lx *lx); static enum lx_token z3(struct lx *lx); +static enum lx_token z4(struct lx *lx); +static enum lx_token z5(struct lx *lx); #if __STDC_VERSION__ >= 199901L inline @@ -180,25 +182,35 @@ z0(struct lx *lx) switch (state) { case S0: /* start */ switch ((unsigned char) c) { - case '\'': state = S2; break; + case '\n': state = S2; break; default: state = S1; break; } break; case S1: /* e.g. "a" */ - lx_ungetc(lx, c); return TOK_CHAR; + lx_ungetc(lx, c); return lx->z(lx); - case S2: /* e.g. "'" */ - lx_ungetc(lx, c); return lx->z = z3, TOK_LABEL; + case S2: /* e.g. "" */ + lx_ungetc(lx, c); return lx->z = z1, lx->z(lx); default: ; /* unreached */ } - if (lx->push != NULL) { - if (-1 == lx->push(lx->buf_opaque, c)) { - return TOK_ERROR; + switch (state) { + case S0: + case S1: + case S2: + break; + + default: + if (lx->push != NULL) { + if (-1 == lx->push(lx->buf_opaque, (char)c)) { + return TOK_ERROR; + } } + break; + } } @@ -206,8 +218,8 @@ z0(struct lx *lx) switch (state) { case NONE: return TOK_EOF; - case S1: return TOK_CHAR; - case S2: return TOK_LABEL; + case S1: return TOK_EOF; + case S2: return TOK_EOF; default: errno = EINVAL; return TOK_ERROR; } } @@ -218,7 +230,7 @@ z1(struct lx *lx) int c; enum { - S0, S1, S2, S3, S4, S5, S6, S7, NONE + S0, S1, S2, S3, S4, S5, NONE } state; assert(lx != NULL); @@ -239,27 +251,29 @@ z1(struct lx *lx) switch (state) { case S0: /* start */ switch ((unsigned char) c) { - case '"': state = S2; break; - case '\\': state = S3; break; - default: state = S1; break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': state = S1; break; + case ',': state = S2; break; + case '#': state = S3; break; + case '\t': + case '\n': + case '\r': + case ' ': state = S4; break; + case ']': state = S5; break; + default: lx->lgetc = NULL; return TOK_UNKNOWN; } break; - case S1: /* e.g. "a" */ - lx_ungetc(lx, c); return TOK_CHAR; - - case S2: /* e.g. "\"" */ - lx_ungetc(lx, c); return lx->z = z3, TOK_LABEL; - - case S3: /* e.g. "\\" */ + case S1: /* e.g. "0" */ switch ((unsigned char) c) { - case '"': - case '\\': - case 'f': - case 'n': - case 'r': - case 't': - case 'v': state = S4; break; case '0': case '1': case '2': @@ -267,17 +281,160 @@ z1(struct lx *lx) case '4': case '5': case '6': - case '7': state = S5; break; - case 'x': state = S6; break; - default: lx_ungetc(lx, c); return TOK_CHAR; + case '7': + case '8': + case '9': break; + default: lx_ungetc(lx, c); return TOK_ENDID; } break; - case S4: /* e.g. "\\f" */ - lx_ungetc(lx, c); return TOK_ESC; + case S2: /* e.g. "," */ + lx_ungetc(lx, c); return TOK_COMMA; - case S5: /* e.g. "\\0" */ + case S3: /* e.g. "#" */ + lx_ungetc(lx, c); return lx->z = z0, lx->z(lx); + + case S4: /* e.g. "\\x09" */ + switch ((unsigned char) c) { + case '\t': + case '\n': + case '\r': + case ' ': break; + default: lx_ungetc(lx, c); return lx->z(lx); + } + break; + + case S5: /* e.g. "]" */ + lx_ungetc(lx, c); return lx->z = z5, TOK_CLOSEENDIDS; + + default: + ; /* unreached */ + } + + switch (state) { + case S3: + case S4: + break; + + default: + if (lx->push != NULL) { + if (-1 == lx->push(lx->buf_opaque, (char)c)) { + return TOK_ERROR; + } + } + break; + + } + } + + lx->lgetc = NULL; + + switch (state) { + case NONE: return TOK_EOF; + case S1: return TOK_ENDID; + case S2: return TOK_COMMA; + case S3: return TOK_EOF; + case S4: return TOK_EOF; + case S5: return TOK_CLOSEENDIDS; + default: errno = EINVAL; return TOK_ERROR; + } +} + +static enum lx_token +z2(struct lx *lx) +{ + int c; + + enum { + S0, S1, S2, NONE + } state; + + assert(lx != NULL); + + if (lx->clear != NULL) { + lx->clear(lx->buf_opaque); + } + + state = NONE; + + lx->start = lx->end; + + while (c = lx_getc(lx), c != EOF) { + if (state == NONE) { + state = S0; + } + + switch (state) { + case S0: /* start */ switch ((unsigned char) c) { + case '\'': state = S2; break; + default: state = S1; break; + } + break; + + case S1: /* e.g. "a" */ + lx_ungetc(lx, c); return TOK_CHAR; + + case S2: /* e.g. "'" */ + lx_ungetc(lx, c); return lx->z = z5, TOK_LABEL; + + default: + ; /* unreached */ + } + + if (lx->push != NULL) { + if (-1 == lx->push(lx->buf_opaque, (char)c)) { + return TOK_ERROR; + } + } + } + + lx->lgetc = NULL; + + switch (state) { + case NONE: return TOK_EOF; + case S1: return TOK_CHAR; + case S2: return TOK_LABEL; + default: errno = EINVAL; return TOK_ERROR; + } +} + +static enum lx_token +z3(struct lx *lx) +{ + int c; + + enum { + S0, S1, S2, S3, S4, S5, S6, S7, NONE + } state; + + assert(lx != NULL); + + if (lx->clear != NULL) { + lx->clear(lx->buf_opaque); + } + + state = NONE; + + lx->start = lx->end; + + while (c = lx_getc(lx), c != EOF) { + if (state == NONE) { + state = S0; + } + + switch (state) { + case S0: /* start */ + switch ((unsigned char) c) { + case '\\': state = S1; break; + case '"': state = S3; break; + default: state = S2; break; + } + break; + + case S1: /* e.g. "\\" */ + switch ((unsigned char) c) { + case 'x': state = S4; break; case '0': case '1': case '2': @@ -285,12 +442,25 @@ z1(struct lx *lx) case '4': case '5': case '6': - case '7': break; - default: lx_ungetc(lx, c); return TOK_OCT; + case '7': state = S5; break; + case '"': + case '\\': + case 'f': + case 'n': + case 'r': + case 't': + case 'v': state = S6; break; + default: lx_ungetc(lx, c); return TOK_CHAR; } break; - case S6: /* e.g. "\\x" */ + case S2: /* e.g. "a" */ + lx_ungetc(lx, c); return TOK_CHAR; + + case S3: /* e.g. "\"" */ + lx_ungetc(lx, c); return lx->z = z5, TOK_LABEL; + + case S4: /* e.g. "\\x" */ switch ((unsigned char) c) { case '0': case '1': @@ -318,6 +488,23 @@ z1(struct lx *lx) } break; + case S5: /* e.g. "\\0" */ + switch ((unsigned char) c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': break; + default: lx_ungetc(lx, c); return TOK_OCT; + } + break; + + case S6: /* e.g. "\\f" */ + lx_ungetc(lx, c); return TOK_ESC; + case S7: /* e.g. "\\xa" */ switch ((unsigned char) c) { case '0': @@ -351,7 +538,7 @@ z1(struct lx *lx) } if (lx->push != NULL) { - if (-1 == lx->push(lx->buf_opaque, c)) { + if (-1 == lx->push(lx->buf_opaque, (char)c)) { return TOK_ERROR; } } @@ -362,17 +549,17 @@ z1(struct lx *lx) switch (state) { case NONE: return TOK_EOF; case S1: return TOK_CHAR; - case S2: return TOK_LABEL; - case S3: return TOK_CHAR; - case S4: return TOK_ESC; + case S2: return TOK_CHAR; + case S3: return TOK_LABEL; case S5: return TOK_OCT; + case S6: return TOK_ESC; case S7: return TOK_HEX; default: errno = EINVAL; return TOK_ERROR; } } static enum lx_token -z2(struct lx *lx) +z4(struct lx *lx) { int c; @@ -407,7 +594,7 @@ z2(struct lx *lx) lx_ungetc(lx, c); return lx->z(lx); case S2: /* e.g. "" */ - lx_ungetc(lx, c); return lx->z = z3, lx->z(lx); + lx_ungetc(lx, c); return lx->z = z5, lx->z(lx); default: ; /* unreached */ @@ -421,7 +608,7 @@ z2(struct lx *lx) default: if (lx->push != NULL) { - if (-1 == lx->push(lx->buf_opaque, c)) { + if (-1 == lx->push(lx->buf_opaque, (char)c)) { return TOK_ERROR; } } @@ -441,14 +628,14 @@ z2(struct lx *lx) } static enum lx_token -z3(struct lx *lx) +z5(struct lx *lx) { int c; enum { S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19, - S20, NONE + S20, S21, S22, NONE } state; assert(lx != NULL); @@ -469,15 +656,14 @@ z3(struct lx *lx) switch (state) { case S0: /* start */ switch ((unsigned char) c) { - case '\t': - case '\n': - case '\r': - case ' ': state = S1; break; - case '"': state = S2; break; - case '#': state = S3; break; - case '\'': state = S4; break; - case ',': state = S5; break; - case '-': state = S6; break; + case ',': state = S1; break; + case ';': state = S2; break; + case '?': state = S3; break; + case '-': state = S4; break; + case '[': state = S5; break; + case '=': state = S6; break; + case 'e': state = S7; break; + case 's': state = S8; break; case '0': case '1': case '2': @@ -538,45 +724,41 @@ z3(struct lx *lx) case 'w': case 'x': case 'y': - case 'z': state = S7; break; - case ';': state = S8; break; - case '?': state = S9; break; - case 'e': state = S10; break; - case 's': state = S11; break; - default: lx->lgetc = NULL; return TOK_UNKNOWN; - } - break; - - case S1: /* e.g. "\\x09" */ - switch ((unsigned char) c) { + case 'z': state = S9; break; + case '\'': state = S10; break; + case '"': state = S11; break; + case '#': state = S12; break; case '\t': case '\n': case '\r': - case ' ': break; - default: lx_ungetc(lx, c); return lx->z(lx); + case ' ': state = S13; break; + default: lx->lgetc = NULL; return TOK_UNKNOWN; } break; - case S2: /* e.g. "\"" */ - lx_ungetc(lx, c); return lx->z = z1, lx->z(lx); - - case S3: /* e.g. "#" */ - lx_ungetc(lx, c); return lx->z = z2, lx->z(lx); + case S1: /* e.g. "," */ + lx_ungetc(lx, c); return TOK_COMMA; - case S4: /* e.g. "'" */ - lx_ungetc(lx, c); return lx->z = z0, lx->z(lx); + case S2: /* e.g. ";" */ + lx_ungetc(lx, c); return TOK_SEP; - case S5: /* e.g. "," */ - lx_ungetc(lx, c); return TOK_COMMA; + case S3: /* e.g. "?" */ + lx_ungetc(lx, c); return TOK_ANY; - case S6: /* e.g. "-" */ + case S4: /* e.g. "-" */ switch ((unsigned char) c) { - case '>': state = S20; break; + case '>': state = S22; break; default: lx->lgetc = NULL; return TOK_UNKNOWN; } break; - case S7: /* e.g. "a" */ + case S5: /* e.g. "[" */ + lx_ungetc(lx, c); return lx->z = z1, TOK_OPENENDIDS; + + case S6: /* e.g. "=" */ + lx_ungetc(lx, c); return TOK_EQUALS; + + case S7: /* e.g. "e" */ switch ((unsigned char) c) { case '0': case '1': @@ -628,7 +810,6 @@ z3(struct lx *lx) case 'k': case 'l': case 'm': - case 'n': case 'o': case 'p': case 'q': @@ -640,18 +821,13 @@ z3(struct lx *lx) case 'w': case 'x': case 'y': - case 'z': break; + case 'z': state = S9; break; + case 'n': state = S19; break; default: lx_ungetc(lx, c); return TOK_IDENT; } break; - case S8: /* e.g. ";" */ - lx_ungetc(lx, c); return TOK_SEP; - - case S9: /* e.g. "?" */ - lx_ungetc(lx, c); return TOK_ANY; - - case S10: /* e.g. "e" */ + case S8: /* e.g. "s" */ switch ((unsigned char) c) { case '0': case '1': @@ -703,24 +879,24 @@ z3(struct lx *lx) case 'k': case 'l': case 'm': + case 'n': case 'o': case 'p': case 'q': case 'r': case 's': - case 't': case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': state = S7; break; - case 'n': state = S17; break; + case 'z': state = S9; break; + case 't': state = S14; break; default: lx_ungetc(lx, c); return TOK_IDENT; } break; - case S11: /* e.g. "s" */ + case S9: /* e.g. "a" */ switch ((unsigned char) c) { case '0': case '1': @@ -778,18 +954,37 @@ z3(struct lx *lx) case 'q': case 'r': case 's': + case 't': case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': state = S7; break; - case 't': state = S12; break; + case 'z': break; default: lx_ungetc(lx, c); return TOK_IDENT; } break; - case S12: /* e.g. "st" */ + case S10: /* e.g. "'" */ + lx_ungetc(lx, c); return lx->z = z2, lx->z(lx); + + case S11: /* e.g. "\"" */ + lx_ungetc(lx, c); return lx->z = z3, lx->z(lx); + + case S12: /* e.g. "#" */ + lx_ungetc(lx, c); return lx->z = z4, lx->z(lx); + + case S13: /* e.g. "\\x09" */ + switch ((unsigned char) c) { + case '\t': + case '\n': + case '\r': + case ' ': break; + default: lx_ungetc(lx, c); return lx->z(lx); + } + break; + + case S14: /* e.g. "st" */ switch ((unsigned char) c) { case '0': case '1': @@ -852,13 +1047,13 @@ z3(struct lx *lx) case 'w': case 'x': case 'y': - case 'z': state = S7; break; - case 'a': state = S13; break; + case 'z': state = S9; break; + case 'a': state = S15; break; default: lx_ungetc(lx, c); return TOK_IDENT; } break; - case S13: /* e.g. "sta" */ + case S15: /* e.g. "sta" */ switch ((unsigned char) c) { case '0': case '1': @@ -921,13 +1116,13 @@ z3(struct lx *lx) case 'w': case 'x': case 'y': - case 'z': state = S7; break; - case 'r': state = S14; break; + case 'z': state = S9; break; + case 'r': state = S16; break; default: lx_ungetc(lx, c); return TOK_IDENT; } break; - case S14: /* e.g. "star" */ + case S16: /* e.g. "star" */ switch ((unsigned char) c) { case '0': case '1': @@ -990,13 +1185,13 @@ z3(struct lx *lx) case 'w': case 'x': case 'y': - case 'z': state = S7; break; - case 't': state = S15; break; + case 'z': state = S9; break; + case 't': state = S17; break; default: lx_ungetc(lx, c); return TOK_IDENT; } break; - case S15: /* e.g. "start" */ + case S17: /* e.g. "start" */ switch ((unsigned char) c) { case '0': case '1': @@ -1060,16 +1255,16 @@ z3(struct lx *lx) case 'w': case 'x': case 'y': - case 'z': state = S7; break; - case ':': state = S16; break; + case 'z': state = S9; break; + case ':': state = S18; break; default: lx_ungetc(lx, c); return TOK_IDENT; } break; - case S16: /* e.g. "start:" */ + case S18: /* e.g. "start:" */ lx_ungetc(lx, c); return TOK_START; - case S17: /* e.g. "en" */ + case S19: /* e.g. "en" */ switch ((unsigned char) c) { case '0': case '1': @@ -1132,13 +1327,13 @@ z3(struct lx *lx) case 'w': case 'x': case 'y': - case 'z': state = S7; break; - case 'd': state = S18; break; + case 'z': state = S9; break; + case 'd': state = S20; break; default: lx_ungetc(lx, c); return TOK_IDENT; } break; - case S18: /* e.g. "end" */ + case S20: /* e.g. "end" */ switch ((unsigned char) c) { case '0': case '1': @@ -1202,16 +1397,16 @@ z3(struct lx *lx) case 'w': case 'x': case 'y': - case 'z': state = S7; break; - case ':': state = S19; break; + case 'z': state = S9; break; + case ':': state = S21; break; default: lx_ungetc(lx, c); return TOK_IDENT; } break; - case S19: /* e.g. "end:" */ + case S21: /* e.g. "end:" */ lx_ungetc(lx, c); return TOK_END; - case S20: /* e.g. "->" */ + case S22: /* e.g. "->" */ lx_ungetc(lx, c); return TOK_TO; default: @@ -1219,15 +1414,15 @@ z3(struct lx *lx) } switch (state) { - case S1: - case S2: - case S3: - case S4: + case S10: + case S11: + case S12: + case S13: break; default: if (lx->push != NULL) { - if (-1 == lx->push(lx->buf_opaque, c)) { + if (-1 == lx->push(lx->buf_opaque, (char)c)) { return TOK_ERROR; } } @@ -1240,25 +1435,27 @@ z3(struct lx *lx) switch (state) { case NONE: return TOK_EOF; - case S1: return TOK_EOF; - case S2: return TOK_EOF; - case S3: return TOK_EOF; - case S4: return TOK_EOF; - case S5: return TOK_COMMA; + case S1: return TOK_COMMA; + case S2: return TOK_SEP; + case S3: return TOK_ANY; + case S5: return TOK_OPENENDIDS; + case S6: return TOK_EQUALS; case S7: return TOK_IDENT; - case S8: return TOK_SEP; - case S9: return TOK_ANY; - case S10: return TOK_IDENT; - case S11: return TOK_IDENT; - case S12: return TOK_IDENT; - case S13: return TOK_IDENT; + case S8: return TOK_IDENT; + case S9: return TOK_IDENT; + case S10: return TOK_EOF; + case S11: return TOK_EOF; + case S12: return TOK_EOF; + case S13: return TOK_EOF; case S14: return TOK_IDENT; case S15: return TOK_IDENT; - case S16: return TOK_START; + case S16: return TOK_IDENT; case S17: return TOK_IDENT; - case S18: return TOK_IDENT; - case S19: return TOK_END; - case S20: return TOK_TO; + case S18: return TOK_START; + case S19: return TOK_IDENT; + case S20: return TOK_IDENT; + case S21: return TOK_END; + case S22: return TOK_TO; default: errno = EINVAL; return TOK_ERROR; } } @@ -1267,10 +1464,14 @@ const char * lx_name(enum lx_token t) { switch (t) { - case TOK_COMMA: return "COMMA"; case TOK_SEP: return "SEP"; case TOK_ANY: return "ANY"; case TOK_TO: return "TO"; + case TOK_ENDID: return "ENDID"; + case TOK_COMMA: return "COMMA"; + case TOK_CLOSEENDIDS: return "CLOSEENDIDS"; + case TOK_OPENENDIDS: return "OPENENDIDS"; + case TOK_EQUALS: return "EQUALS"; case TOK_IDENT: return "IDENT"; case TOK_END: return "END"; case TOK_START: return "START"; @@ -1293,10 +1494,14 @@ lx_example(enum lx_token (*z)(struct lx *), enum lx_token t) if (z == z0) { switch (t) { - case TOK_COMMA: return ""; case TOK_SEP: return ""; case TOK_ANY: return ""; case TOK_TO: return ""; + case TOK_ENDID: return ""; + case TOK_COMMA: return ""; + case TOK_CLOSEENDIDS: return ""; + case TOK_OPENENDIDS: return ""; + case TOK_EQUALS: return ""; case TOK_IDENT: return ""; case TOK_END: return ""; case TOK_START: return ""; @@ -1310,10 +1515,14 @@ lx_example(enum lx_token (*z)(struct lx *), enum lx_token t) } else if (z == z1) { switch (t) { - case TOK_COMMA: return ""; case TOK_SEP: return ""; case TOK_ANY: return ""; case TOK_TO: return ""; + case TOK_ENDID: return ""; + case TOK_COMMA: return ""; + case TOK_CLOSEENDIDS: return ""; + case TOK_OPENENDIDS: return ""; + case TOK_EQUALS: return ""; case TOK_IDENT: return ""; case TOK_END: return ""; case TOK_START: return ""; @@ -1327,10 +1536,14 @@ lx_example(enum lx_token (*z)(struct lx *), enum lx_token t) } else if (z == z2) { switch (t) { - case TOK_COMMA: return ""; case TOK_SEP: return ""; case TOK_ANY: return ""; case TOK_TO: return ""; + case TOK_ENDID: return ""; + case TOK_COMMA: return ""; + case TOK_CLOSEENDIDS: return ""; + case TOK_OPENENDIDS: return ""; + case TOK_EQUALS: return ""; case TOK_IDENT: return ""; case TOK_END: return ""; case TOK_START: return ""; @@ -1344,10 +1557,56 @@ lx_example(enum lx_token (*z)(struct lx *), enum lx_token t) } else if (z == z3) { switch (t) { + case TOK_SEP: return ""; + case TOK_ANY: return ""; + case TOK_TO: return ""; + case TOK_ENDID: return ""; case TOK_COMMA: return ""; + case TOK_CLOSEENDIDS: return ""; + case TOK_OPENENDIDS: return ""; + case TOK_EQUALS: return ""; + case TOK_IDENT: return ""; + case TOK_END: return ""; + case TOK_START: return ""; + case TOK_CHAR: return ""; + case TOK_HEX: return ""; + case TOK_OCT: return ""; + case TOK_ESC: return ""; + case TOK_LABEL: return ""; + default: goto error; + } + } else + if (z == z4) { + switch (t) { case TOK_SEP: return ""; case TOK_ANY: return ""; case TOK_TO: return ""; + case TOK_ENDID: return ""; + case TOK_COMMA: return ""; + case TOK_CLOSEENDIDS: return ""; + case TOK_OPENENDIDS: return ""; + case TOK_EQUALS: return ""; + case TOK_IDENT: return ""; + case TOK_END: return ""; + case TOK_START: return ""; + case TOK_CHAR: return ""; + case TOK_HEX: return ""; + case TOK_OCT: return ""; + case TOK_ESC: return ""; + case TOK_LABEL: return ""; + default: goto error; + } + } else + if (z == z5) { + switch (t) { + case TOK_SEP: return ""; + case TOK_ANY: return ""; + case TOK_TO: return ""; + case TOK_ENDID: return ""; + case TOK_COMMA: return ""; + case TOK_CLOSEENDIDS: return ""; + case TOK_OPENENDIDS: return ""; + case TOK_EQUALS: return ""; case TOK_IDENT: return ""; case TOK_END: return ""; case TOK_START: return ""; @@ -1376,7 +1635,7 @@ lx_init(struct lx *lx) *lx = lx_default; lx->c = EOF; - lx->z = z3; + lx->z = z5; lx->end.byte = 0; lx->end.line = 1; diff --git a/src/libfsm/lexer.h b/src/libfsm/lexer.h index 7848879fc..68e55b612 100644 --- a/src/libfsm/lexer.h +++ b/src/libfsm/lexer.h @@ -4,10 +4,14 @@ #define LX_H enum lx_token { - TOK_COMMA, TOK_SEP, TOK_ANY, TOK_TO, + TOK_ENDID, + TOK_COMMA, + TOK_CLOSEENDIDS, + TOK_OPENENDIDS, + TOK_EQUALS, TOK_IDENT, TOK_END, TOK_START, diff --git a/src/libfsm/lexer.lx b/src/libfsm/lexer.lx index 7aa8cf5bf..0288e1877 100644 --- a/src/libfsm/lexer.lx +++ b/src/libfsm/lexer.lx @@ -31,6 +31,17 @@ /[a-z0-9_]+/i -> $ident; +'=' -> $equals; +'[' -> $openendids .. ']' -> $closeendids { + /[\r\n\t ]+/; + "#" .. "\n"; + + ',' -> $comma; + + # using a lexical zone because $endid overlaps $ident + /[0-9]+/ -> $endid; +} + '->' -> $to; '?' -> $any; ';' -> $sep; diff --git a/src/libfsm/parser.act b/src/libfsm/parser.act index 80ace7fdf..ffae3402a 100644 --- a/src/libfsm/parser.act +++ b/src/libfsm/parser.act @@ -1,5 +1,5 @@ /* - * Copyright 2008-2017 Katherine Flavel + * Copyright 2008-2024 Katherine Flavel * * See LICENCE for the full copyright terms. */ @@ -22,6 +22,7 @@ char -> char; string -> string; state -> state; + endid -> endid; %header% @{ @@ -41,8 +42,9 @@ #include "lexer.h" #include "parser.h" - typedef char * string; - typedef fsm_state_t state; + typedef char * string; + typedef fsm_state_t state; + typedef fsm_end_id_t endid; struct act_statelist { char *id; @@ -194,12 +196,14 @@ if ((u == ULONG_MAX && errno == ERANGE) || u > UCHAR_MAX) { err(lex_state, "octal escape %s out of range: expected \\0..\\%o inclusive", lex_state->buf.a, UCHAR_MAX); + /* XXX: don't exit in library code */ exit(EXIT_FAILURE); } if ((u == ULONG_MAX && errno != 0) || *e != '\0') { err(lex_state, "%s: %s: expected \\0..\\%o inclusive", lex_state->buf.a, strerror(errno), UCHAR_MAX); + /* XXX: don't exit in library code */ exit(EXIT_FAILURE); } @@ -221,12 +225,14 @@ if ((u == ULONG_MAX && errno == ERANGE) || u > UCHAR_MAX) { err(lex_state, "hex escape %s out of range: expected \\x0..\\x%x inclusive", lex_state->buf.a, UCHAR_MAX); + /* XXX: don't exit in library code */ exit(EXIT_FAILURE); } if ((u == ULONG_MAX && errno != 0) || *e != '\0') { err(lex_state, "%s: %s: expected \\x0..\\x%x inclusive", lex_state->buf.a, strerror(errno), UCHAR_MAX); + /* XXX: don't exit in library code */ exit(EXIT_FAILURE); } @@ -245,6 +251,31 @@ @s = xstrdup(lex_state->buf.a); @}; + ENDID: () -> (id :endid) = @{ + unsigned long u; + char *e; + + errno = 0; + + u = strtoul(lex_state->buf.a, &e, 16); + + if ((u == ULONG_MAX && errno == ERANGE) || u > FSM_END_ID_MAX) { + err(lex_state, "end id %s out of range: expected 0..%u inclusive", + lex_state->buf.a, FSM_END_ID_MAX); + /* XXX: don't exit in library code */ + exit(EXIT_FAILURE); + } + + if ((u == ULONG_MAX && errno != 0) || *e != '\0') { + err(lex_state, "%s: %s: expected 0..%u inclusive", + lex_state->buf.a, strerror(errno), FSM_END_ID_MAX); + /* XXX: don't exit in library code */ + exit(EXIT_FAILURE); + } + + @id = (fsm_end_id_t) u; + @}; + %actions% : (n :string) -> (s :state) = @{ @@ -308,6 +339,12 @@ fsm_setend(fsm, @s, 1); @}; + : (s :state, id :endid) -> () = @{ + if (!fsm_setendidstate(fsm, @s, @id)) { + @!; + } + @}; + : (s :string) -> () = @{ free(@s); @}; diff --git a/src/libfsm/parser.c b/src/libfsm/parser.c index 998e9ee75..40e692db4 100644 --- a/src/libfsm/parser.c +++ b/src/libfsm/parser.c @@ -9,7 +9,7 @@ /* BEGINNING OF HEADER */ -#line 151 "src/libfsm/parser.act" +#line 153 "src/libfsm/parser.act" #include @@ -28,8 +28,9 @@ #include "lexer.h" #include "parser.h" - typedef char * string; - typedef fsm_state_t state; + typedef char * string; + typedef fsm_state_t state; + typedef fsm_end_id_t endid; struct act_statelist { char *id; @@ -135,7 +136,7 @@ htab->longest_chain_length = max_chain_length; } -#line 139 "src/libfsm/parser.c" +#line 140 "src/libfsm/parser.c" #ifndef ERROR_TERMINAL @@ -149,10 +150,13 @@ static void p_items(fsm, lex_state, act_state); static void p_xend_C_Cend_Hstates(fsm, lex_state, act_state); static void p_xstart(fsm, lex_state, act_state); static void p_xend(fsm, lex_state, act_state); -static void p_xend_C_Cend_Hstate(fsm, lex_state, act_state); -static void p_61(fsm, lex_state, act_state); -static void p_63(fsm, lex_state, act_state, string *); +static void p_xend_C_Cend_Hstate(fsm, lex_state, act_state, state *); extern void p_fsm(fsm, lex_state, act_state); +static void p_73(fsm, lex_state, act_state); +static void p_75(fsm, lex_state, act_state); +static void p_77(fsm, lex_state, act_state, string *); +static void p_xend_C_Cend_Hids(fsm, lex_state, act_state, state); +static void p_xend_C_Cend_Hid(fsm, lex_state, act_state, state); /* BEGINNING OF STATIC VARIABLES */ @@ -168,21 +172,21 @@ p_label(fsm fsm, lex_state lex_state, act_state act_state, char *ZOc) return; } { - /* BEGINNING OF INLINE: 34 */ + /* BEGINNING OF INLINE: 40 */ { switch (CURRENT_TERMINAL) { case (TOK_CHAR): { /* BEGINNING OF EXTRACT: CHAR */ { -#line 240 "src/libfsm/parser.act" +#line 246 "src/libfsm/parser.act" assert(lex_state->buf.a[0] != '\0'); assert(lex_state->buf.a[1] == '\0'); ZIc = lex_state->buf.a[0]; -#line 186 "src/libfsm/parser.c" +#line 190 "src/libfsm/parser.c" } /* END OF EXTRACT: CHAR */ ADVANCE_LEXER; @@ -192,7 +196,7 @@ p_label(fsm fsm, lex_state lex_state, act_state act_state, char *ZOc) { /* BEGINNING OF EXTRACT: ESC */ { -#line 168 "src/libfsm/parser.act" +#line 170 "src/libfsm/parser.act" assert(0 == strncmp(lex_state->buf.a, "\\", 1)); assert(2 == strlen(lex_state->buf.a)); @@ -210,7 +214,7 @@ p_label(fsm fsm, lex_state lex_state, act_state act_state, char *ZOc) default: break; } -#line 214 "src/libfsm/parser.c" +#line 218 "src/libfsm/parser.c" } /* END OF EXTRACT: ESC */ ADVANCE_LEXER; @@ -220,7 +224,7 @@ p_label(fsm fsm, lex_state lex_state, act_state act_state, char *ZOc) { /* BEGINNING OF EXTRACT: HEX */ { -#line 233 "src/libfsm/parser.act" +#line 239 "src/libfsm/parser.act" unsigned long u; char *e; @@ -236,18 +240,20 @@ p_label(fsm fsm, lex_state lex_state, act_state act_state, char *ZOc) if ((u == ULONG_MAX && errno == ERANGE) || u > UCHAR_MAX) { err(lex_state, "hex escape %s out of range: expected \\x0..\\x%x inclusive", lex_state->buf.a, UCHAR_MAX); + /* XXX: don't exit in library code */ exit(EXIT_FAILURE); } if ((u == ULONG_MAX && errno != 0) || *e != '\0') { err(lex_state, "%s: %s: expected \\x0..\\x%x inclusive", lex_state->buf.a, strerror(errno), UCHAR_MAX); + /* XXX: don't exit in library code */ exit(EXIT_FAILURE); } ZIc = (char) (unsigned char) u; -#line 251 "src/libfsm/parser.c" +#line 257 "src/libfsm/parser.c" } /* END OF EXTRACT: HEX */ ADVANCE_LEXER; @@ -257,7 +263,7 @@ p_label(fsm fsm, lex_state lex_state, act_state act_state, char *ZOc) { /* BEGINNING OF EXTRACT: OCT */ { -#line 206 "src/libfsm/parser.act" +#line 210 "src/libfsm/parser.act" unsigned long u; char *e; @@ -273,18 +279,20 @@ p_label(fsm fsm, lex_state lex_state, act_state act_state, char *ZOc) if ((u == ULONG_MAX && errno == ERANGE) || u > UCHAR_MAX) { err(lex_state, "octal escape %s out of range: expected \\0..\\%o inclusive", lex_state->buf.a, UCHAR_MAX); + /* XXX: don't exit in library code */ exit(EXIT_FAILURE); } if ((u == ULONG_MAX && errno != 0) || *e != '\0') { err(lex_state, "%s: %s: expected \\0..\\%o inclusive", lex_state->buf.a, strerror(errno), UCHAR_MAX); + /* XXX: don't exit in library code */ exit(EXIT_FAILURE); } ZIc = (char) (unsigned char) u; -#line 288 "src/libfsm/parser.c" +#line 296 "src/libfsm/parser.c" } /* END OF EXTRACT: OCT */ ADVANCE_LEXER; @@ -294,7 +302,7 @@ p_label(fsm fsm, lex_state lex_state, act_state act_state, char *ZOc) goto ZL1; } } - /* END OF INLINE: 34 */ + /* END OF INLINE: 40 */ switch (CURRENT_TERMINAL) { case (TOK_LABEL): break; @@ -318,7 +326,7 @@ ZL2_items:; switch (CURRENT_TERMINAL) { case (TOK_IDENT): { - /* BEGINNING OF INLINE: 48 */ + /* BEGINNING OF INLINE: 54 */ { { string ZIa; @@ -330,12 +338,12 @@ ZL2_items:; case (TOK_IDENT): /* BEGINNING OF EXTRACT: IDENT */ { -#line 245 "src/libfsm/parser.act" +#line 251 "src/libfsm/parser.act" /* XXX: don't exit in library code */ ZIa = xstrdup(lex_state->buf.a); -#line 339 "src/libfsm/parser.c" +#line 347 "src/libfsm/parser.c" } /* END OF EXTRACT: IDENT */ break; @@ -346,14 +354,14 @@ ZL2_items:; } } /* END OF INLINE: ident */ - p_63 (fsm, lex_state, act_state, &ZIa); + p_77 (fsm, lex_state, act_state, &ZIa); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; goto ZL1; } } } - /* END OF INLINE: 48 */ + /* END OF INLINE: 54 */ /* BEGINNING OF INLINE: items */ goto ZL2_items; /* END OF INLINE: items */ @@ -378,44 +386,35 @@ p_xend_C_Cend_Hstates(fsm fsm, lex_state lex_state, act_state act_state) } ZL2_xend_C_Cend_Hstates:; { - p_xend_C_Cend_Hstate (fsm, lex_state, act_state); - /* BEGINNING OF INLINE: 58 */ + state ZIs; + + p_xend_C_Cend_Hstate (fsm, lex_state, act_state, &ZIs); + /* BEGINNING OF INLINE: 71 */ { switch (CURRENT_TERMINAL) { - case (TOK_COMMA): + case (TOK_EQUALS): { - /* BEGINNING OF INLINE: 59 */ - { - { - switch (CURRENT_TERMINAL) { - case (TOK_COMMA): - break; - default: - goto ZL5; - } - ADVANCE_LEXER; - } - goto ZL4; - ZL5:; - { - /* BEGINNING OF ACTION: err-expected-comma */ - { -#line 362 "src/libfsm/parser.act" - - err_expected(lex_state, "','"); - -#line 408 "src/libfsm/parser.c" - } - /* END OF ACTION: err-expected-comma */ - } - ZL4:; + ADVANCE_LEXER; + switch (CURRENT_TERMINAL) { + case (TOK_OPENENDIDS): + break; + default: + goto ZL1; } - /* END OF INLINE: 59 */ - /* BEGINNING OF INLINE: xend::end-states */ - goto ZL2_xend_C_Cend_Hstates; - /* END OF INLINE: xend::end-states */ + ADVANCE_LEXER; + p_xend_C_Cend_Hids (fsm, lex_state, act_state, ZIs); + switch (CURRENT_TERMINAL) { + case (TOK_CLOSEENDIDS): + break; + case (ERROR_TERMINAL): + RESTORE_LEXER; + goto ZL1; + default: + goto ZL1; + } + ADVANCE_LEXER; } - /*UNREACHED*/ + break; case (ERROR_TERMINAL): RESTORE_LEXER; goto ZL1; @@ -423,7 +422,28 @@ ZL2_xend_C_Cend_Hstates:; break; } } - /* END OF INLINE: 58 */ + /* END OF INLINE: 71 */ + /* BEGINNING OF INLINE: 72 */ + { + switch (CURRENT_TERMINAL) { + case (TOK_COMMA): + { + p_73 (fsm, lex_state, act_state); + /* BEGINNING OF INLINE: xend::end-states */ + if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { + RESTORE_LEXER; + goto ZL1; + } else { + goto ZL2_xend_C_Cend_Hstates; + } + /* END OF INLINE: xend::end-states */ + } + /*UNREACHED*/ + default: + break; + } + } + /* END OF INLINE: 72 */ } return; ZL1:; @@ -440,7 +460,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) string ZIn; state ZIs; - /* BEGINNING OF INLINE: 50 */ + /* BEGINNING OF INLINE: 56 */ { { switch (CURRENT_TERMINAL) { @@ -456,17 +476,17 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) { /* BEGINNING OF ACTION: err-expected-start */ { -#line 366 "src/libfsm/parser.act" +#line 403 "src/libfsm/parser.act" err_expected(lex_state, "'start:'"); -#line 464 "src/libfsm/parser.c" +#line 484 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-start */ } ZL2:; } - /* END OF INLINE: 50 */ + /* END OF INLINE: 56 */ /* BEGINNING OF INLINE: ident */ { { @@ -474,12 +494,12 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) case (TOK_IDENT): /* BEGINNING OF EXTRACT: IDENT */ { -#line 245 "src/libfsm/parser.act" +#line 251 "src/libfsm/parser.act" /* XXX: don't exit in library code */ ZIn = xstrdup(lex_state->buf.a); -#line 483 "src/libfsm/parser.c" +#line 503 "src/libfsm/parser.c" } /* END OF EXTRACT: IDENT */ break; @@ -490,14 +510,14 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) } } /* END OF INLINE: ident */ - p_61 (fsm, lex_state, act_state); + p_75 (fsm, lex_state, act_state); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; goto ZL1; } /* BEGINNING OF ACTION: add-state */ { -#line 252 "src/libfsm/parser.act" +#line 283 "src/libfsm/parser.act" struct act_statelist *p; const unsigned hash = hash_of_id((ZIn)); @@ -550,25 +570,25 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) act_state->states.buckets[bucket_id] = new; } -#line 554 "src/libfsm/parser.c" +#line 574 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: mark-start */ { -#line 304 "src/libfsm/parser.act" +#line 335 "src/libfsm/parser.act" fsm_setstart(fsm, (ZIs)); -#line 563 "src/libfsm/parser.c" +#line 583 "src/libfsm/parser.c" } /* END OF ACTION: mark-start */ /* BEGINNING OF ACTION: free */ { -#line 312 "src/libfsm/parser.act" +#line 349 "src/libfsm/parser.act" free((ZIn)); -#line 572 "src/libfsm/parser.c" +#line 592 "src/libfsm/parser.c" } /* END OF ACTION: free */ } @@ -590,7 +610,7 @@ p_xend(fsm fsm, lex_state lex_state, act_state act_state) switch (CURRENT_TERMINAL) { case (TOK_END): { - /* BEGINNING OF INLINE: 60 */ + /* BEGINNING OF INLINE: 74 */ { { switch (CURRENT_TERMINAL) { @@ -606,19 +626,19 @@ p_xend(fsm fsm, lex_state lex_state, act_state act_state) { /* BEGINNING OF ACTION: err-expected-end */ { -#line 370 "src/libfsm/parser.act" +#line 407 "src/libfsm/parser.act" err_expected(lex_state, "'end:'"); -#line 614 "src/libfsm/parser.c" +#line 634 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-end */ } ZL2:; } - /* END OF INLINE: 60 */ + /* END OF INLINE: 74 */ p_xend_C_Cend_Hstates (fsm, lex_state, act_state); - p_61 (fsm, lex_state, act_state); + p_75 (fsm, lex_state, act_state); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; goto ZL1; @@ -637,14 +657,15 @@ ZL1:; } static void -p_xend_C_Cend_Hstate(fsm fsm, lex_state lex_state, act_state act_state) +p_xend_C_Cend_Hstate(fsm fsm, lex_state lex_state, act_state act_state, state *ZOs) { + state ZIs; + if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { return; } { string ZIn; - state ZIs; /* BEGINNING OF INLINE: ident */ { @@ -653,12 +674,12 @@ p_xend_C_Cend_Hstate(fsm fsm, lex_state lex_state, act_state act_state) case (TOK_IDENT): /* BEGINNING OF EXTRACT: IDENT */ { -#line 245 "src/libfsm/parser.act" +#line 251 "src/libfsm/parser.act" /* XXX: don't exit in library code */ ZIn = xstrdup(lex_state->buf.a); -#line 662 "src/libfsm/parser.c" +#line 683 "src/libfsm/parser.c" } /* END OF EXTRACT: IDENT */ break; @@ -671,7 +692,7 @@ p_xend_C_Cend_Hstate(fsm fsm, lex_state lex_state, act_state act_state) /* END OF INLINE: ident */ /* BEGINNING OF ACTION: add-state */ { -#line 252 "src/libfsm/parser.act" +#line 283 "src/libfsm/parser.act" struct act_statelist *p; const unsigned hash = hash_of_id((ZIn)); @@ -724,36 +745,125 @@ p_xend_C_Cend_Hstate(fsm fsm, lex_state lex_state, act_state act_state) act_state->states.buckets[bucket_id] = new; } -#line 728 "src/libfsm/parser.c" +#line 749 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: mark-end */ { -#line 308 "src/libfsm/parser.act" +#line 339 "src/libfsm/parser.act" fsm_setend(fsm, (ZIs), 1); -#line 737 "src/libfsm/parser.c" +#line 758 "src/libfsm/parser.c" } /* END OF ACTION: mark-end */ /* BEGINNING OF ACTION: free */ { -#line 312 "src/libfsm/parser.act" +#line 349 "src/libfsm/parser.act" free((ZIn)); -#line 746 "src/libfsm/parser.c" +#line 767 "src/libfsm/parser.c" } /* END OF ACTION: free */ } - return; + goto ZL0; ZL1:; SAVE_LEXER ((ERROR_TERMINAL)); return; +ZL0:; + *ZOs = ZIs; +} + +void +p_fsm(fsm fsm, lex_state lex_state, act_state act_state) +{ + if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { + return; + } + { + p_items (fsm, lex_state, act_state); + p_xstart (fsm, lex_state, act_state); + p_xend (fsm, lex_state, act_state); + switch (CURRENT_TERMINAL) { + case (TOK_EOF): + break; + case (ERROR_TERMINAL): + RESTORE_LEXER; + goto ZL1; + default: + goto ZL1; + } + ADVANCE_LEXER; + /* BEGINNING OF ACTION: free-statelist */ + { +#line 365 "src/libfsm/parser.act" + + struct act_statelist *p; + struct act_statelist *next; + unsigned b_i; /* bucket */ + + for (b_i = 0; b_i < act_state->states.bucket_count; b_i++) { + for (p = act_state->states.buckets[b_i]; p != NULL; p = next) { + next = p->next; + assert(p->id != NULL); + free(p->id); + free(p); + } + } + +#line 816 "src/libfsm/parser.c" + } + /* END OF ACTION: free-statelist */ + } + return; +ZL1:; + { + /* BEGINNING OF ACTION: err-syntax */ + { +#line 412 "src/libfsm/parser.act" + + err(lex_state, "Syntax error"); + exit(EXIT_FAILURE); + +#line 830 "src/libfsm/parser.c" + } + /* END OF ACTION: err-syntax */ + } } static void -p_61(fsm fsm, lex_state lex_state, act_state act_state) +p_73(fsm fsm, lex_state lex_state, act_state act_state) +{ + if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { + return; + } + { + switch (CURRENT_TERMINAL) { + case (TOK_COMMA): + break; + default: + goto ZL1; + } + ADVANCE_LEXER; + } + return; +ZL1:; + { + /* BEGINNING OF ACTION: err-expected-comma */ + { +#line 399 "src/libfsm/parser.act" + + err_expected(lex_state, "','"); + +#line 860 "src/libfsm/parser.c" + } + /* END OF ACTION: err-expected-comma */ + } +} + +static void +p_75(fsm fsm, lex_state lex_state, act_state act_state) { if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { return; @@ -772,18 +882,18 @@ ZL1:; { /* BEGINNING OF ACTION: err-expected-sep */ { -#line 354 "src/libfsm/parser.act" +#line 391 "src/libfsm/parser.act" err_expected(lex_state, "';'"); -#line 780 "src/libfsm/parser.c" +#line 890 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-sep */ } } static void -p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) +p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) { switch (CURRENT_TERMINAL) { case (TOK_TO): @@ -800,12 +910,12 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) case (TOK_IDENT): /* BEGINNING OF EXTRACT: IDENT */ { -#line 245 "src/libfsm/parser.act" +#line 251 "src/libfsm/parser.act" /* XXX: don't exit in library code */ ZIb = xstrdup(lex_state->buf.a); -#line 809 "src/libfsm/parser.c" +#line 919 "src/libfsm/parser.c" } /* END OF EXTRACT: IDENT */ break; @@ -818,7 +928,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) /* END OF INLINE: ident */ /* BEGINNING OF ACTION: add-state */ { -#line 252 "src/libfsm/parser.act" +#line 283 "src/libfsm/parser.act" struct act_statelist *p; const unsigned hash = hash_of_id((*ZIa)); @@ -871,12 +981,12 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) act_state->states.buckets[bucket_id] = new; } -#line 875 "src/libfsm/parser.c" +#line 985 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: add-state */ { -#line 252 "src/libfsm/parser.act" +#line 283 "src/libfsm/parser.act" struct act_statelist *p; const unsigned hash = hash_of_id((ZIb)); @@ -929,28 +1039,28 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) act_state->states.buckets[bucket_id] = new; } -#line 933 "src/libfsm/parser.c" +#line 1043 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: free */ { -#line 312 "src/libfsm/parser.act" +#line 349 "src/libfsm/parser.act" free((*ZIa)); -#line 942 "src/libfsm/parser.c" +#line 1052 "src/libfsm/parser.c" } /* END OF ACTION: free */ /* BEGINNING OF ACTION: free */ { -#line 312 "src/libfsm/parser.act" +#line 349 "src/libfsm/parser.act" free((ZIb)); -#line 951 "src/libfsm/parser.c" +#line 1061 "src/libfsm/parser.c" } /* END OF ACTION: free */ - /* BEGINNING OF INLINE: 42 */ + /* BEGINNING OF INLINE: 48 */ { switch (CURRENT_TERMINAL) { case (TOK_ANY): @@ -958,14 +1068,14 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) ADVANCE_LEXER; /* BEGINNING OF ACTION: add-edge-any */ { -#line 338 "src/libfsm/parser.act" +#line 375 "src/libfsm/parser.act" if (!fsm_addedge_any(fsm, (ZIx), (ZIy))) { perror("fsm_addedge_any"); exit(EXIT_FAILURE); } -#line 969 "src/libfsm/parser.c" +#line 1079 "src/libfsm/parser.c" } /* END OF ACTION: add-edge-any */ } @@ -981,14 +1091,14 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) } /* BEGINNING OF ACTION: add-edge-literal */ { -#line 331 "src/libfsm/parser.act" +#line 368 "src/libfsm/parser.act" if (!fsm_addedge_literal(fsm, (ZIx), (ZIy), (ZIc))) { perror("fsm_addedge_literal"); exit(EXIT_FAILURE); } -#line 992 "src/libfsm/parser.c" +#line 1102 "src/libfsm/parser.c" } /* END OF ACTION: add-edge-literal */ } @@ -997,14 +1107,14 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) { /* BEGINNING OF ACTION: add-edge-epsilon */ { -#line 345 "src/libfsm/parser.act" +#line 382 "src/libfsm/parser.act" if (!fsm_addedge_epsilon(fsm, (ZIx), (ZIy))) { perror("fsm_addedge_epsilon"); exit(EXIT_FAILURE); } -#line 1008 "src/libfsm/parser.c" +#line 1118 "src/libfsm/parser.c" } /* END OF ACTION: add-edge-epsilon */ } @@ -1015,18 +1125,18 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) { /* BEGINNING OF ACTION: err-expected-trans */ { -#line 358 "src/libfsm/parser.act" +#line 395 "src/libfsm/parser.act" err_expected(lex_state, "transition"); -#line 1023 "src/libfsm/parser.c" +#line 1133 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-trans */ } ZL3:; } - /* END OF INLINE: 42 */ - p_61 (fsm, lex_state, act_state); + /* END OF INLINE: 48 */ + p_75 (fsm, lex_state, act_state); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; goto ZL1; @@ -1035,11 +1145,11 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) break; case (TOK_SEP): { - state ZI45; + state ZI51; /* BEGINNING OF ACTION: add-state */ { -#line 252 "src/libfsm/parser.act" +#line 283 "src/libfsm/parser.act" struct act_statelist *p; const unsigned hash = hash_of_id((*ZIa)); @@ -1060,7 +1170,7 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) chain_length++; if (0 == strcmp(p->id, (*ZIa))) { - (ZI45) = p->state; + (ZI51) = p->state; break; } } @@ -1081,30 +1191,30 @@ p_63(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) /* XXX: don't exit in library code */ new->id = xstrdup((*ZIa)); - if (!fsm_addstate(fsm, &(ZI45))) { + if (!fsm_addstate(fsm, &(ZI51))) { perror("fsm_addstate"); exit(EXIT_FAILURE); } - new->state = (ZI45); + new->state = (ZI51); new->next = act_state->states.buckets[bucket_id]; act_state->states.buckets[bucket_id] = new; } -#line 1096 "src/libfsm/parser.c" +#line 1206 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: free */ { -#line 312 "src/libfsm/parser.act" +#line 349 "src/libfsm/parser.act" free((*ZIa)); -#line 1105 "src/libfsm/parser.c" +#line 1215 "src/libfsm/parser.c" } /* END OF ACTION: free */ - p_61 (fsm, lex_state, act_state); + p_75 (fsm, lex_state, act_state); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; goto ZL1; @@ -1122,66 +1232,113 @@ ZL1:; return; } -void -p_fsm(fsm fsm, lex_state lex_state, act_state act_state) +static void +p_xend_C_Cend_Hids(fsm fsm, lex_state lex_state, act_state act_state, state ZIs) { if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { return; } +ZL2_xend_C_Cend_Hids:; { - p_items (fsm, lex_state, act_state); - p_xstart (fsm, lex_state, act_state); - p_xend (fsm, lex_state, act_state); + p_xend_C_Cend_Hid (fsm, lex_state, act_state, ZIs); + /* BEGINNING OF INLINE: 65 */ + { + switch (CURRENT_TERMINAL) { + case (TOK_COMMA): + { + p_73 (fsm, lex_state, act_state); + /* BEGINNING OF INLINE: xend::end-ids */ + if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { + RESTORE_LEXER; + goto ZL1; + } else { + goto ZL2_xend_C_Cend_Hids; + } + /* END OF INLINE: xend::end-ids */ + } + /*UNREACHED*/ + case (ERROR_TERMINAL): + RESTORE_LEXER; + goto ZL1; + default: + break; + } + } + /* END OF INLINE: 65 */ + } + return; +ZL1:; + SAVE_LEXER ((ERROR_TERMINAL)); + return; +} + +static void +p_xend_C_Cend_Hid(fsm fsm, lex_state lex_state, act_state act_state, state ZIs) +{ + if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { + return; + } + { + endid ZIid; + switch (CURRENT_TERMINAL) { - case (TOK_EOF): + case (TOK_ENDID): + /* BEGINNING OF EXTRACT: ENDID */ + { +#line 276 "src/libfsm/parser.act" + + unsigned long u; + char *e; + + errno = 0; + + u = strtoul(lex_state->buf.a, &e, 16); + + if ((u == ULONG_MAX && errno == ERANGE) || u > FSM_END_ID_MAX) { + err(lex_state, "end id %s out of range: expected 0..%u inclusive", + lex_state->buf.a, FSM_END_ID_MAX); + /* XXX: don't exit in library code */ + exit(EXIT_FAILURE); + } + + if ((u == ULONG_MAX && errno != 0) || *e != '\0') { + err(lex_state, "%s: %s: expected 0..%u inclusive", + lex_state->buf.a, strerror(errno), FSM_END_ID_MAX); + /* XXX: don't exit in library code */ + exit(EXIT_FAILURE); + } + + ZIid = (fsm_end_id_t) u; + +#line 1314 "src/libfsm/parser.c" + } + /* END OF EXTRACT: ENDID */ break; - case (ERROR_TERMINAL): - RESTORE_LEXER; - goto ZL1; default: goto ZL1; } ADVANCE_LEXER; - /* BEGINNING OF ACTION: free-statelist */ + /* BEGINNING OF ACTION: mark-end-id */ { -#line 328 "src/libfsm/parser.act" +#line 343 "src/libfsm/parser.act" - struct act_statelist *p; - struct act_statelist *next; - unsigned b_i; /* bucket */ - - for (b_i = 0; b_i < act_state->states.bucket_count; b_i++) { - for (p = act_state->states.buckets[b_i]; p != NULL; p = next) { - next = p->next; - assert(p->id != NULL); - free(p->id); - free(p); - } + if (!fsm_setendidstate(fsm, (ZIs), (ZIid))) { + goto ZL1; } -#line 1163 "src/libfsm/parser.c" +#line 1330 "src/libfsm/parser.c" } - /* END OF ACTION: free-statelist */ + /* END OF ACTION: mark-end-id */ } return; ZL1:; - { - /* BEGINNING OF ACTION: err-syntax */ - { -#line 375 "src/libfsm/parser.act" - - err(lex_state, "Syntax error"); - exit(EXIT_FAILURE); - -#line 1177 "src/libfsm/parser.c" - } - /* END OF ACTION: err-syntax */ - } + SAVE_LEXER ((ERROR_TERMINAL)); + return; } /* BEGINNING OF TRAILER */ -#line 431 "src/libfsm/parser.act" +#line 468 "src/libfsm/parser.act" struct fsm *fsm_parse(FILE *f, const struct fsm_options *opt) { @@ -1236,6 +1393,6 @@ ZL1:; return new; } -#line 1240 "src/libfsm/parser.c" +#line 1397 "src/libfsm/parser.c" /* END OF FILE */ diff --git a/src/libfsm/parser.h b/src/libfsm/parser.h index 70155c504..b4aaba2b8 100644 --- a/src/libfsm/parser.h +++ b/src/libfsm/parser.h @@ -9,7 +9,7 @@ /* BEGINNING OF HEADER */ -#line 160 "src/libfsm/parser.act" +#line 162 "src/libfsm/parser.act" typedef struct lex_state * lex_state; @@ -26,7 +26,7 @@ extern void p_fsm(fsm, lex_state, act_state); /* BEGINNING OF TRAILER */ -#line 432 "src/libfsm/parser.act" +#line 469 "src/libfsm/parser.act" #line 32 "src/libfsm/parser.h" diff --git a/src/libfsm/parser.sid b/src/libfsm/parser.sid index 32a370312..f8d8e78cd 100644 --- a/src/libfsm/parser.sid +++ b/src/libfsm/parser.sid @@ -1,5 +1,5 @@ /* - * Copyright 2008-2017 Katherine Flavel + * Copyright 2008-2024 Katherine Flavel * * See LICENCE for the full copyright terms. */ @@ -9,10 +9,12 @@ char; string; state; + endid; %terminals% IDENT: () -> (:string); + ENDID: () -> (:endid); ESC: () -> (:char); OCT: () -> (:char); @@ -23,6 +25,10 @@ START; END; + OPENENDIDS; + CLOSEENDIDS; + + EQUALS; TO; ANY; SEP; @@ -36,6 +42,7 @@ : (:string) -> (:state); : (:state) -> (); : (:state) -> (); + : (:state, :endid) -> (); : (:string) -> (); ; @@ -155,7 +162,29 @@ xend [ - end-state = { + end-id: (s :state) -> () = { + id = ENDID; + + (s, id); + }; + + end-ids: (s :state) -> () = { + end-id(s); + + { + { + COMMA; + ## + ; + }; + + end-ids(s); + || + $; + }; + }; + + end-state: () -> (s :state) = { n = ident; s = (n); @@ -165,7 +194,17 @@ }; end-states = { - end-state; + s = end-state; + + { + EQUALS; + + OPENENDIDS; + end-ids(s); + CLOSEENDIDS; + || + $; + }; { { diff --git a/src/libfsm/print/fsm.c b/src/libfsm/print/fsm.c index ea41ea757..ae3163abd 100644 --- a/src/libfsm/print/fsm.c +++ b/src/libfsm/print/fsm.c @@ -24,6 +24,19 @@ #include #include +/* TODO: centralise */ +static int +comp_end_id(const void *a, const void *b) +{ + assert(a != NULL); + assert(b != NULL); + + if (* (fsm_end_id_t *) a < * (fsm_end_id_t *) b) { return -1; } + if (* (fsm_end_id_t *) a > * (fsm_end_id_t *) b) { return +1; } + + return 0; +} + /* TODO: centralise */ static int findany(const struct fsm *fsm, fsm_state_t state, fsm_state_t *a) @@ -278,11 +291,58 @@ fsm_print_fsm(FILE *f, const struct fsm *fsm) fprintf(f, "end: "); for (s = 0; s < fsm->statecount; s++) { - if (fsm_isend(fsm, s)) { - end--; + size_t count; + + if (!fsm_isend(fsm, s)) { + continue; + } + + end--; + + fprintf(f, "%u", s); + + count = fsm_getendidcount(fsm, s); + if (count > 0) { + enum fsm_getendids_res res; + fsm_end_id_t *ids; + size_t written; + + ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); + if (ids == NULL) { + return -1; + } + + res = fsm_getendids(fsm, s, count, ids, &written); + switch (res) { + case FSM_GETENDIDS_NOT_FOUND: + case FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE: + assert(!"unreached"); + abort(); + + case FSM_GETENDIDS_FOUND: + break; + } + + assert(written == count); + + qsort(ids, count, sizeof *ids, comp_end_id); + + fprintf(f, " = ["); - fprintf(f, "%u%s", s, end > 0 ? ", " : ";\n"); + for (size_t id = 0; id < count; id++) { + fprintf(f, "%zu", id); + + if (id + 1 < count) { + fprintf(f, ", "); + } + } + + fprintf(f, "]"); + + f_free(fsm->opt->alloc, ids); } + + fprintf(f, "%s", end > 0 ? ", " : ";\n"); } done: From 9ce1fb0210784adfea93a3a99e91737e10ee94e4 Mon Sep 17 00:00:00 2001 From: Kate F Date: Mon, 10 Jun 2024 12:45:35 -0700 Subject: [PATCH 05/28] Missing error handling for the initial token. --- src/libfsm/parser.act | 14 +++++++++++++- src/libfsm/parser.c | 18 +++++++++++++++--- src/libfsm/parser.h | 2 +- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/libfsm/parser.act b/src/libfsm/parser.act index ffae3402a..30caa03bd 100644 --- a/src/libfsm/parser.act +++ b/src/libfsm/parser.act @@ -456,7 +456,19 @@ return NULL; } - ADVANCE_LEXER; /* XXX: what if the first token is unrecognised? */ + ADVANCE_LEXER; + switch (CURRENT_TERMINAL) { + case TOK_UNKNOWN: + /* fallthrough */ + case TOK_ERROR: + /* XXX: don't exit in library code */ + err(lex_state, "Syntax error"); + exit(EXIT_FAILURE); + + default: + break; + } + p_fsm(new, lex_state, act_state); free(act_state_s.states.buckets); diff --git a/src/libfsm/parser.c b/src/libfsm/parser.c index 40e692db4..73d525d25 100644 --- a/src/libfsm/parser.c +++ b/src/libfsm/parser.c @@ -1338,7 +1338,7 @@ ZL1:; /* BEGINNING OF TRAILER */ -#line 468 "src/libfsm/parser.act" +#line 480 "src/libfsm/parser.act" struct fsm *fsm_parse(FILE *f, const struct fsm_options *opt) { @@ -1384,7 +1384,19 @@ ZL1:; return NULL; } - ADVANCE_LEXER; /* XXX: what if the first token is unrecognised? */ + ADVANCE_LEXER; + switch (CURRENT_TERMINAL) { + case TOK_UNKNOWN: + /* fallthrough */ + case TOK_ERROR: + /* XXX: don't exit in library code */ + err(lex_state, "Syntax error"); + exit(EXIT_FAILURE); + + default: + break; + } + p_fsm(new, lex_state, act_state); free(act_state_s.states.buckets); @@ -1393,6 +1405,6 @@ ZL1:; return new; } -#line 1397 "src/libfsm/parser.c" +#line 1409 "src/libfsm/parser.c" /* END OF FILE */ diff --git a/src/libfsm/parser.h b/src/libfsm/parser.h index b4aaba2b8..be8f288ec 100644 --- a/src/libfsm/parser.h +++ b/src/libfsm/parser.h @@ -26,7 +26,7 @@ extern void p_fsm(fsm, lex_state, act_state); /* BEGINNING OF TRAILER */ -#line 469 "src/libfsm/parser.act" +#line 481 "src/libfsm/parser.act" #line 32 "src/libfsm/parser.h" From 0447463aabb9f8c7e90f33df40fef0afd47ca19a Mon Sep 17 00:00:00 2001 From: Kate F Date: Mon, 10 Jun 2024 22:49:29 -0700 Subject: [PATCH 06/28] Allow an empty list of end-ids. --- src/libfsm/parser.c | 111 +++++++++++++++++++++++------------------- src/libfsm/parser.sid | 2 +- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/src/libfsm/parser.c b/src/libfsm/parser.c index 73d525d25..0ae7ee763 100644 --- a/src/libfsm/parser.c +++ b/src/libfsm/parser.c @@ -152,9 +152,9 @@ static void p_xstart(fsm, lex_state, act_state); static void p_xend(fsm, lex_state, act_state); static void p_xend_C_Cend_Hstate(fsm, lex_state, act_state, state *); extern void p_fsm(fsm, lex_state, act_state); -static void p_73(fsm, lex_state, act_state); -static void p_75(fsm, lex_state, act_state); -static void p_77(fsm, lex_state, act_state, string *); +static void p_74(fsm, lex_state, act_state); +static void p_76(fsm, lex_state, act_state); +static void p_78(fsm, lex_state, act_state, string *); static void p_xend_C_Cend_Hids(fsm, lex_state, act_state, state); static void p_xend_C_Cend_Hid(fsm, lex_state, act_state, state); @@ -354,7 +354,7 @@ ZL2_items:; } } /* END OF INLINE: ident */ - p_77 (fsm, lex_state, act_state, &ZIa); + p_78 (fsm, lex_state, act_state, &ZIa); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; goto ZL1; @@ -402,13 +402,26 @@ ZL2_xend_C_Cend_Hstates:; goto ZL1; } ADVANCE_LEXER; - p_xend_C_Cend_Hids (fsm, lex_state, act_state, ZIs); + /* BEGINNING OF INLINE: 72 */ + { + switch (CURRENT_TERMINAL) { + case (TOK_ENDID): + { + p_xend_C_Cend_Hids (fsm, lex_state, act_state, ZIs); + if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { + RESTORE_LEXER; + goto ZL1; + } + } + break; + default: + break; + } + } + /* END OF INLINE: 72 */ switch (CURRENT_TERMINAL) { case (TOK_CLOSEENDIDS): break; - case (ERROR_TERMINAL): - RESTORE_LEXER; - goto ZL1; default: goto ZL1; } @@ -423,12 +436,12 @@ ZL2_xend_C_Cend_Hstates:; } } /* END OF INLINE: 71 */ - /* BEGINNING OF INLINE: 72 */ + /* BEGINNING OF INLINE: 73 */ { switch (CURRENT_TERMINAL) { case (TOK_COMMA): { - p_73 (fsm, lex_state, act_state); + p_74 (fsm, lex_state, act_state); /* BEGINNING OF INLINE: xend::end-states */ if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; @@ -443,7 +456,7 @@ ZL2_xend_C_Cend_Hstates:; break; } } - /* END OF INLINE: 72 */ + /* END OF INLINE: 73 */ } return; ZL1:; @@ -480,7 +493,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) err_expected(lex_state, "'start:'"); -#line 484 "src/libfsm/parser.c" +#line 497 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-start */ } @@ -499,7 +512,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) /* XXX: don't exit in library code */ ZIn = xstrdup(lex_state->buf.a); -#line 503 "src/libfsm/parser.c" +#line 516 "src/libfsm/parser.c" } /* END OF EXTRACT: IDENT */ break; @@ -510,7 +523,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) } } /* END OF INLINE: ident */ - p_75 (fsm, lex_state, act_state); + p_76 (fsm, lex_state, act_state); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; goto ZL1; @@ -570,7 +583,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) act_state->states.buckets[bucket_id] = new; } -#line 574 "src/libfsm/parser.c" +#line 587 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: mark-start */ @@ -579,7 +592,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) fsm_setstart(fsm, (ZIs)); -#line 583 "src/libfsm/parser.c" +#line 596 "src/libfsm/parser.c" } /* END OF ACTION: mark-start */ /* BEGINNING OF ACTION: free */ @@ -588,7 +601,7 @@ p_xstart(fsm fsm, lex_state lex_state, act_state act_state) free((ZIn)); -#line 592 "src/libfsm/parser.c" +#line 605 "src/libfsm/parser.c" } /* END OF ACTION: free */ } @@ -610,7 +623,7 @@ p_xend(fsm fsm, lex_state lex_state, act_state act_state) switch (CURRENT_TERMINAL) { case (TOK_END): { - /* BEGINNING OF INLINE: 74 */ + /* BEGINNING OF INLINE: 75 */ { { switch (CURRENT_TERMINAL) { @@ -630,15 +643,15 @@ p_xend(fsm fsm, lex_state lex_state, act_state act_state) err_expected(lex_state, "'end:'"); -#line 634 "src/libfsm/parser.c" +#line 647 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-end */ } ZL2:; } - /* END OF INLINE: 74 */ + /* END OF INLINE: 75 */ p_xend_C_Cend_Hstates (fsm, lex_state, act_state); - p_75 (fsm, lex_state, act_state); + p_76 (fsm, lex_state, act_state); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; goto ZL1; @@ -679,7 +692,7 @@ p_xend_C_Cend_Hstate(fsm fsm, lex_state lex_state, act_state act_state, state *Z /* XXX: don't exit in library code */ ZIn = xstrdup(lex_state->buf.a); -#line 683 "src/libfsm/parser.c" +#line 696 "src/libfsm/parser.c" } /* END OF EXTRACT: IDENT */ break; @@ -745,7 +758,7 @@ p_xend_C_Cend_Hstate(fsm fsm, lex_state lex_state, act_state act_state, state *Z act_state->states.buckets[bucket_id] = new; } -#line 749 "src/libfsm/parser.c" +#line 762 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: mark-end */ @@ -754,7 +767,7 @@ p_xend_C_Cend_Hstate(fsm fsm, lex_state lex_state, act_state act_state, state *Z fsm_setend(fsm, (ZIs), 1); -#line 758 "src/libfsm/parser.c" +#line 771 "src/libfsm/parser.c" } /* END OF ACTION: mark-end */ /* BEGINNING OF ACTION: free */ @@ -763,7 +776,7 @@ p_xend_C_Cend_Hstate(fsm fsm, lex_state lex_state, act_state act_state, state *Z free((ZIn)); -#line 767 "src/libfsm/parser.c" +#line 780 "src/libfsm/parser.c" } /* END OF ACTION: free */ } @@ -812,7 +825,7 @@ p_fsm(fsm fsm, lex_state lex_state, act_state act_state) } } -#line 816 "src/libfsm/parser.c" +#line 829 "src/libfsm/parser.c" } /* END OF ACTION: free-statelist */ } @@ -826,14 +839,14 @@ ZL1:; err(lex_state, "Syntax error"); exit(EXIT_FAILURE); -#line 830 "src/libfsm/parser.c" +#line 843 "src/libfsm/parser.c" } /* END OF ACTION: err-syntax */ } } static void -p_73(fsm fsm, lex_state lex_state, act_state act_state) +p_74(fsm fsm, lex_state lex_state, act_state act_state) { if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { return; @@ -856,14 +869,14 @@ ZL1:; err_expected(lex_state, "','"); -#line 860 "src/libfsm/parser.c" +#line 873 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-comma */ } } static void -p_75(fsm fsm, lex_state lex_state, act_state act_state) +p_76(fsm fsm, lex_state lex_state, act_state act_state) { if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { return; @@ -886,14 +899,14 @@ ZL1:; err_expected(lex_state, "';'"); -#line 890 "src/libfsm/parser.c" +#line 903 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-sep */ } } static void -p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) +p_78(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) { switch (CURRENT_TERMINAL) { case (TOK_TO): @@ -915,7 +928,7 @@ p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) /* XXX: don't exit in library code */ ZIb = xstrdup(lex_state->buf.a); -#line 919 "src/libfsm/parser.c" +#line 932 "src/libfsm/parser.c" } /* END OF EXTRACT: IDENT */ break; @@ -981,7 +994,7 @@ p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) act_state->states.buckets[bucket_id] = new; } -#line 985 "src/libfsm/parser.c" +#line 998 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: add-state */ @@ -1039,7 +1052,7 @@ p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) act_state->states.buckets[bucket_id] = new; } -#line 1043 "src/libfsm/parser.c" +#line 1056 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: free */ @@ -1048,7 +1061,7 @@ p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) free((*ZIa)); -#line 1052 "src/libfsm/parser.c" +#line 1065 "src/libfsm/parser.c" } /* END OF ACTION: free */ /* BEGINNING OF ACTION: free */ @@ -1057,7 +1070,7 @@ p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) free((ZIb)); -#line 1061 "src/libfsm/parser.c" +#line 1074 "src/libfsm/parser.c" } /* END OF ACTION: free */ /* BEGINNING OF INLINE: 48 */ @@ -1075,7 +1088,7 @@ p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) exit(EXIT_FAILURE); } -#line 1079 "src/libfsm/parser.c" +#line 1092 "src/libfsm/parser.c" } /* END OF ACTION: add-edge-any */ } @@ -1098,7 +1111,7 @@ p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) exit(EXIT_FAILURE); } -#line 1102 "src/libfsm/parser.c" +#line 1115 "src/libfsm/parser.c" } /* END OF ACTION: add-edge-literal */ } @@ -1114,7 +1127,7 @@ p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) exit(EXIT_FAILURE); } -#line 1118 "src/libfsm/parser.c" +#line 1131 "src/libfsm/parser.c" } /* END OF ACTION: add-edge-epsilon */ } @@ -1129,14 +1142,14 @@ p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) err_expected(lex_state, "transition"); -#line 1133 "src/libfsm/parser.c" +#line 1146 "src/libfsm/parser.c" } /* END OF ACTION: err-expected-trans */ } ZL3:; } /* END OF INLINE: 48 */ - p_75 (fsm, lex_state, act_state); + p_76 (fsm, lex_state, act_state); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; goto ZL1; @@ -1202,7 +1215,7 @@ p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) act_state->states.buckets[bucket_id] = new; } -#line 1206 "src/libfsm/parser.c" +#line 1219 "src/libfsm/parser.c" } /* END OF ACTION: add-state */ /* BEGINNING OF ACTION: free */ @@ -1211,10 +1224,10 @@ p_77(fsm fsm, lex_state lex_state, act_state act_state, string *ZIa) free((*ZIa)); -#line 1215 "src/libfsm/parser.c" +#line 1228 "src/libfsm/parser.c" } /* END OF ACTION: free */ - p_75 (fsm, lex_state, act_state); + p_76 (fsm, lex_state, act_state); if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; goto ZL1; @@ -1246,7 +1259,7 @@ ZL2_xend_C_Cend_Hids:; switch (CURRENT_TERMINAL) { case (TOK_COMMA): { - p_73 (fsm, lex_state, act_state); + p_74 (fsm, lex_state, act_state); /* BEGINNING OF INLINE: xend::end-ids */ if ((CURRENT_TERMINAL) == (ERROR_TERMINAL)) { RESTORE_LEXER; @@ -1310,7 +1323,7 @@ p_xend_C_Cend_Hid(fsm fsm, lex_state lex_state, act_state act_state, state ZIs) ZIid = (fsm_end_id_t) u; -#line 1314 "src/libfsm/parser.c" +#line 1327 "src/libfsm/parser.c" } /* END OF EXTRACT: ENDID */ break; @@ -1326,7 +1339,7 @@ p_xend_C_Cend_Hid(fsm fsm, lex_state lex_state, act_state act_state, state ZIs) goto ZL1; } -#line 1330 "src/libfsm/parser.c" +#line 1343 "src/libfsm/parser.c" } /* END OF ACTION: mark-end-id */ } @@ -1405,6 +1418,6 @@ ZL1:; return new; } -#line 1409 "src/libfsm/parser.c" +#line 1422 "src/libfsm/parser.c" /* END OF FILE */ diff --git a/src/libfsm/parser.sid b/src/libfsm/parser.sid index f8d8e78cd..7d22c7420 100644 --- a/src/libfsm/parser.sid +++ b/src/libfsm/parser.sid @@ -200,7 +200,7 @@ EQUALS; OPENENDIDS; - end-ids(s); + { end-ids(s); || $; }; CLOSEENDIDS; || $; From 1d30a1250ee44fa7dc802065c6374e42c415932b Mon Sep 17 00:00:00 2001 From: Kate F Date: Mon, 10 Jun 2024 23:40:23 -0700 Subject: [PATCH 07/28] Bugfix for argv handling for fsm_exec cli usage. Two things here: Firstly I've reworked all this stuff such that we handle filenames, and then any remaining arguments are used to match with fsm_exec. This is what I'd originally intended, but I think it got lost at some point, probably when introducing operators with arity 2. Secondly matching text with fsm_exec now runs regarless of the operation, not just on OP_IDENTITY. I see no reason to limit that. --- src/fsm/main.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/fsm/main.c b/src/fsm/main.c index d6cd1e83c..a255ae8ee 100644 --- a/src/fsm/main.c +++ b/src/fsm/main.c @@ -477,17 +477,14 @@ main(int argc, char *argv[]) struct fsm *q; if ((op & OP_ARITY) == 1) { - if (argc > 1) { - usage(); - exit(EXIT_FAILURE); - } + /* argc < 1 is okay */ q = fsm_parse((argc == 0) ? stdin : xopen(argv[0]), &opt); if (q == NULL) { exit(EXIT_FAILURE); } } else { - if (argc != 2) { + if (argc < 2) { usage(); exit(EXIT_FAILURE); } @@ -610,6 +607,17 @@ main(int argc, char *argv[]) printf("=> total %g ms (avg %g ms)\n", elapsed, elapsed / iterations); } + /* we're done consuming filenames, remaining argv is text to match */ + if ((op & OP_ARITY) == 1) { + if (argc > 0) { + argc -= 1; + argv += 1; + } + } else { + argc -= 2; + argv += 2; + } + /* henceforth, r is $?-convention (0 for success) */ if (fsm == NULL) { @@ -661,14 +669,15 @@ main(int argc, char *argv[]) } } - /* TODO: optional -- to delimit texts as opposed to .fsm filenames */ - if (op == OP_IDENTITY && argc > 0) { + /* match text */ + if (argc > 0) { int i; /* TODO: option to print input texts which match. like grep(1) does. * This is not the same as printing patterns which match (by associating * a pattern to the end state), like lx(1) does */ + /* TODO: optional -- to delimit texts as opposed to .fsm filenames */ for (i = 0; i < argc; i++) { fsm_state_t state; int e; @@ -694,7 +703,7 @@ main(int argc, char *argv[]) continue; } - /* TODO: option to print state number? */ + /* TODO: option to print matching end-ids */ } } From ebdbbbd6b2fb5a9436f0e9538c1940a053223d3b Mon Sep 17 00:00:00 2001 From: Kate F Date: Tue, 11 Jun 2024 00:24:51 -0700 Subject: [PATCH 08/28] Tests for .fsm syntax. The file format is complex enough that I want to cover these explicitly now, rather than relying on coverage through other tests. --- Makefile | 1 + tests/fsm/Makefile | 22 ++++++++++++++++++++++ tests/fsm/in0.fsm | 0 tests/fsm/in1.fsm | 1 + tests/fsm/in10.fsm | 10 ++++++++++ tests/fsm/in11.fsm | 9 +++++++++ tests/fsm/in12.fsm | 9 +++++++++ tests/fsm/in13.fsm | 9 +++++++++ tests/fsm/in14.fsm | 12 ++++++++++++ tests/fsm/in15.fsm | 11 +++++++++++ tests/fsm/in16.fsm | 11 +++++++++++ tests/fsm/in17.fsm | 11 +++++++++++ tests/fsm/in18.fsm | 11 +++++++++++ tests/fsm/in19.fsm | 11 +++++++++++ tests/fsm/in2.fsm | 13 +++++++++++++ tests/fsm/in20.fsm | 11 +++++++++++ tests/fsm/in21.fsm | 11 +++++++++++ tests/fsm/in22.fsm | 11 +++++++++++ tests/fsm/in3.fsm | 9 +++++++++ tests/fsm/in4.fsm | 9 +++++++++ tests/fsm/in5.fsm | 9 +++++++++ tests/fsm/in6.fsm | 8 ++++++++ tests/fsm/in7.fsm | 9 +++++++++ tests/fsm/in8.fsm | 12 ++++++++++++ tests/fsm/in9.fsm | 9 +++++++++ tests/fsm/out0.fsm | 0 tests/fsm/out1.fsm | 0 tests/fsm/out10.err | 1 + tests/fsm/out11.err | 1 + tests/fsm/out12.err | 1 + tests/fsm/out13.err | 1 + tests/fsm/out14.err | 1 + tests/fsm/out15.err | 1 + tests/fsm/out16.fsm | 8 ++++++++ tests/fsm/out17.err | 1 + tests/fsm/out18.err | 1 + tests/fsm/out19.fsm | 8 ++++++++ tests/fsm/out2.fsm | 7 +++++++ tests/fsm/out20.fsm | 8 ++++++++ tests/fsm/out21.err | 1 + tests/fsm/out22.fsm | 9 +++++++++ tests/fsm/out3.err | 1 + tests/fsm/out4.err | 1 + tests/fsm/out5.err | 1 + tests/fsm/out6.fsm | 7 +++++++ tests/fsm/out7.fsm | 7 +++++++ tests/fsm/out8.fsm | 10 ++++++++++ tests/fsm/out9.err | 1 + 48 files changed, 316 insertions(+) create mode 100755 tests/fsm/Makefile create mode 100644 tests/fsm/in0.fsm create mode 100644 tests/fsm/in1.fsm create mode 100644 tests/fsm/in10.fsm create mode 100644 tests/fsm/in11.fsm create mode 100644 tests/fsm/in12.fsm create mode 100644 tests/fsm/in13.fsm create mode 100644 tests/fsm/in14.fsm create mode 100644 tests/fsm/in15.fsm create mode 100644 tests/fsm/in16.fsm create mode 100644 tests/fsm/in17.fsm create mode 100644 tests/fsm/in18.fsm create mode 100644 tests/fsm/in19.fsm create mode 100644 tests/fsm/in2.fsm create mode 100644 tests/fsm/in20.fsm create mode 100644 tests/fsm/in21.fsm create mode 100644 tests/fsm/in22.fsm create mode 100644 tests/fsm/in3.fsm create mode 100644 tests/fsm/in4.fsm create mode 100644 tests/fsm/in5.fsm create mode 100644 tests/fsm/in6.fsm create mode 100644 tests/fsm/in7.fsm create mode 100644 tests/fsm/in8.fsm create mode 100644 tests/fsm/in9.fsm create mode 100644 tests/fsm/out0.fsm create mode 100644 tests/fsm/out1.fsm create mode 100644 tests/fsm/out10.err create mode 100644 tests/fsm/out11.err create mode 100644 tests/fsm/out12.err create mode 100644 tests/fsm/out13.err create mode 100644 tests/fsm/out14.err create mode 100644 tests/fsm/out15.err create mode 100644 tests/fsm/out16.fsm create mode 100644 tests/fsm/out17.err create mode 100644 tests/fsm/out18.err create mode 100644 tests/fsm/out19.fsm create mode 100644 tests/fsm/out2.fsm create mode 100644 tests/fsm/out20.fsm create mode 100644 tests/fsm/out21.err create mode 100644 tests/fsm/out22.fsm create mode 100644 tests/fsm/out3.err create mode 100644 tests/fsm/out4.err create mode 100644 tests/fsm/out5.err create mode 100644 tests/fsm/out6.fsm create mode 100644 tests/fsm/out7.fsm create mode 100644 tests/fsm/out8.fsm create mode 100644 tests/fsm/out9.err diff --git a/Makefile b/Makefile index 499239fd9..3613bc941 100644 --- a/Makefile +++ b/Makefile @@ -117,6 +117,7 @@ SUBDIR += tests/subtract SUBDIR += tests/determinise SUBDIR += tests/endids SUBDIR += tests/epsilons +SUBDIR += tests/fsm SUBDIR += tests/glob SUBDIR += tests/like SUBDIR += tests/literal diff --git a/tests/fsm/Makefile b/tests/fsm/Makefile new file mode 100755 index 000000000..6ac0a2646 --- /dev/null +++ b/tests/fsm/Makefile @@ -0,0 +1,22 @@ +.include "../../share/mk/top.mk" + +TEST.tests/fsm != ls -1 tests/fsm/out*.fsm +TEST_SRCDIR.tests/fsm = tests/fsm +TEST_OUTDIR.tests/fsm = ${BUILD}/tests/fsm + +FSM=${BUILD}/bin/fsm + +.for n in ${TEST.tests/fsm:T:R:C/^out//} + +${TEST_OUTDIR.tests/fsm}/got${n}.fsm: ${TEST_SRCDIR.tests/fsm}/in${n}.fsm + ${FSM} -p ${.ALLSRC:M*.fsm} \ + > $@ + +${TEST_OUTDIR.tests/fsm}/res${n}: \ + ${TEST_SRCDIR.tests/fsm}/out${n}.fsm \ + ${TEST_OUTDIR.tests/fsm}/got${n}.fsm + +FSMTEST_RESULT += ${TEST_OUTDIR.tests/fsm}/res${n} + +.endfor + diff --git a/tests/fsm/in0.fsm b/tests/fsm/in0.fsm new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fsm/in1.fsm b/tests/fsm/in1.fsm new file mode 100644 index 000000000..88d443fec --- /dev/null +++ b/tests/fsm/in1.fsm @@ -0,0 +1 @@ +# just a comment diff --git a/tests/fsm/in10.fsm b/tests/fsm/in10.fsm new file mode 100644 index 000000000..8b044d3bb --- /dev/null +++ b/tests/fsm/in10.fsm @@ -0,0 +1,10 @@ +# +# Copyright 2008-2017 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +# missing seperator +start: a +end: b + diff --git a/tests/fsm/in11.fsm b/tests/fsm/in11.fsm new file mode 100644 index 000000000..bc058b5e2 --- /dev/null +++ b/tests/fsm/in11.fsm @@ -0,0 +1,9 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +# missing comma +end: 1 2 3; + diff --git a/tests/fsm/in12.fsm b/tests/fsm/in12.fsm new file mode 100644 index 000000000..973f98c86 --- /dev/null +++ b/tests/fsm/in12.fsm @@ -0,0 +1,9 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: a; +start: b; + diff --git a/tests/fsm/in13.fsm b/tests/fsm/in13.fsm new file mode 100644 index 000000000..0ce5b760a --- /dev/null +++ b/tests/fsm/in13.fsm @@ -0,0 +1,9 @@ +# +# Copyright 2008-2017 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +end: a; +end: a; + diff --git a/tests/fsm/in14.fsm b/tests/fsm/in14.fsm new file mode 100644 index 000000000..82bd7b25c --- /dev/null +++ b/tests/fsm/in14.fsm @@ -0,0 +1,12 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +# missing semicolon +0 1; + +start: 0; +end: 1; + diff --git a/tests/fsm/in15.fsm b/tests/fsm/in15.fsm new file mode 100644 index 000000000..f0622bf0f --- /dev/null +++ b/tests/fsm/in15.fsm @@ -0,0 +1,11 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: a; + +# missing ] +end: a = [ ; + diff --git a/tests/fsm/in16.fsm b/tests/fsm/in16.fsm new file mode 100644 index 000000000..0e7fcec60 --- /dev/null +++ b/tests/fsm/in16.fsm @@ -0,0 +1,11 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: a; + +# an empty list is okay +end: a = [ ]; + diff --git a/tests/fsm/in17.fsm b/tests/fsm/in17.fsm new file mode 100644 index 000000000..42df382d5 --- /dev/null +++ b/tests/fsm/in17.fsm @@ -0,0 +1,11 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: a; + +# end-id must be numeric +end: a = [ abc ]; + diff --git a/tests/fsm/in18.fsm b/tests/fsm/in18.fsm new file mode 100644 index 000000000..2cccfc2e5 --- /dev/null +++ b/tests/fsm/in18.fsm @@ -0,0 +1,11 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: a; + +# missing end-id +end: a = [ , ]; + diff --git a/tests/fsm/in19.fsm b/tests/fsm/in19.fsm new file mode 100644 index 000000000..f0875ad1f --- /dev/null +++ b/tests/fsm/in19.fsm @@ -0,0 +1,11 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: a; + +# out of order is okay +end: a = [ 999 ]; + diff --git a/tests/fsm/in2.fsm b/tests/fsm/in2.fsm new file mode 100644 index 000000000..345ab6cc7 --- /dev/null +++ b/tests/fsm/in2.fsm @@ -0,0 +1,13 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +# states are named by identifiers +abc; +0; +_x; +_; +abc123; + diff --git a/tests/fsm/in20.fsm b/tests/fsm/in20.fsm new file mode 100644 index 000000000..d025dc47e --- /dev/null +++ b/tests/fsm/in20.fsm @@ -0,0 +1,11 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: a; + +# out of order is okay +end: a = [ 7, 53, 999 ]; + diff --git a/tests/fsm/in21.fsm b/tests/fsm/in21.fsm new file mode 100644 index 000000000..f53082d14 --- /dev/null +++ b/tests/fsm/in21.fsm @@ -0,0 +1,11 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: a; + +# positive integers only +end: a = [ -1 ]; + diff --git a/tests/fsm/in22.fsm b/tests/fsm/in22.fsm new file mode 100644 index 000000000..c376a9d28 --- /dev/null +++ b/tests/fsm/in22.fsm @@ -0,0 +1,11 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +a -> b 'a'; + +start: a; +end: b = [ 7 ]; + diff --git a/tests/fsm/in3.fsm b/tests/fsm/in3.fsm new file mode 100644 index 000000000..b3f86c37b --- /dev/null +++ b/tests/fsm/in3.fsm @@ -0,0 +1,9 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +# not a valid identifier ++; + diff --git a/tests/fsm/in4.fsm b/tests/fsm/in4.fsm new file mode 100644 index 000000000..e1edb77b8 --- /dev/null +++ b/tests/fsm/in4.fsm @@ -0,0 +1,9 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +# syntax error +abc -> + diff --git a/tests/fsm/in5.fsm b/tests/fsm/in5.fsm new file mode 100644 index 000000000..8550f0566 --- /dev/null +++ b/tests/fsm/in5.fsm @@ -0,0 +1,9 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +# syntax error +-> def; + diff --git a/tests/fsm/in6.fsm b/tests/fsm/in6.fsm new file mode 100644 index 000000000..9f6c3c3e8 --- /dev/null +++ b/tests/fsm/in6.fsm @@ -0,0 +1,8 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +x -> y; + diff --git a/tests/fsm/in7.fsm b/tests/fsm/in7.fsm new file mode 100644 index 000000000..09d508a27 --- /dev/null +++ b/tests/fsm/in7.fsm @@ -0,0 +1,9 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +# implicit state +start: x; + diff --git a/tests/fsm/in8.fsm b/tests/fsm/in8.fsm new file mode 100644 index 000000000..7760b6e3c --- /dev/null +++ b/tests/fsm/in8.fsm @@ -0,0 +1,12 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +# explicitly created states +x; +y; + +start: x; + diff --git a/tests/fsm/in9.fsm b/tests/fsm/in9.fsm new file mode 100644 index 000000000..e7cbbcc0d --- /dev/null +++ b/tests/fsm/in9.fsm @@ -0,0 +1,9 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +# missing separator +a b c + diff --git a/tests/fsm/out0.fsm b/tests/fsm/out0.fsm new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fsm/out1.fsm b/tests/fsm/out1.fsm new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fsm/out10.err b/tests/fsm/out10.err new file mode 100644 index 000000000..412679b24 --- /dev/null +++ b/tests/fsm/out10.err @@ -0,0 +1 @@ +9:1: Syntax error: expected ';' diff --git a/tests/fsm/out11.err b/tests/fsm/out11.err new file mode 100644 index 000000000..d5b538786 --- /dev/null +++ b/tests/fsm/out11.err @@ -0,0 +1 @@ +8:8: Syntax error: expected ',' diff --git a/tests/fsm/out12.err b/tests/fsm/out12.err new file mode 100644 index 000000000..ebbbb9d1b --- /dev/null +++ b/tests/fsm/out12.err @@ -0,0 +1 @@ +8:1: Syntax error diff --git a/tests/fsm/out13.err b/tests/fsm/out13.err new file mode 100644 index 000000000..ebbbb9d1b --- /dev/null +++ b/tests/fsm/out13.err @@ -0,0 +1 @@ +8:1: Syntax error diff --git a/tests/fsm/out14.err b/tests/fsm/out14.err new file mode 100644 index 000000000..f7e4f861b --- /dev/null +++ b/tests/fsm/out14.err @@ -0,0 +1 @@ +8:3: Syntax error diff --git a/tests/fsm/out15.err b/tests/fsm/out15.err new file mode 100644 index 000000000..fbca0e9a6 --- /dev/null +++ b/tests/fsm/out15.err @@ -0,0 +1 @@ +10:12: Syntax error diff --git a/tests/fsm/out16.fsm b/tests/fsm/out16.fsm new file mode 100644 index 000000000..49f89e1ca --- /dev/null +++ b/tests/fsm/out16.fsm @@ -0,0 +1,8 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: a; +end: a; diff --git a/tests/fsm/out17.err b/tests/fsm/out17.err new file mode 100644 index 000000000..fbca0e9a6 --- /dev/null +++ b/tests/fsm/out17.err @@ -0,0 +1 @@ +10:12: Syntax error diff --git a/tests/fsm/out18.err b/tests/fsm/out18.err new file mode 100644 index 000000000..fbca0e9a6 --- /dev/null +++ b/tests/fsm/out18.err @@ -0,0 +1 @@ +10:12: Syntax error diff --git a/tests/fsm/out19.fsm b/tests/fsm/out19.fsm new file mode 100644 index 000000000..11c504879 --- /dev/null +++ b/tests/fsm/out19.fsm @@ -0,0 +1,8 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: a; +end: a = [ 0 ]; diff --git a/tests/fsm/out2.fsm b/tests/fsm/out2.fsm new file mode 100644 index 000000000..5e711912e --- /dev/null +++ b/tests/fsm/out2.fsm @@ -0,0 +1,7 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +0; 1; 2; 3; 4; diff --git a/tests/fsm/out20.fsm b/tests/fsm/out20.fsm new file mode 100644 index 000000000..71556c552 --- /dev/null +++ b/tests/fsm/out20.fsm @@ -0,0 +1,8 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: a; +end: a = [ 0, 1, 2 ]; diff --git a/tests/fsm/out21.err b/tests/fsm/out21.err new file mode 100644 index 000000000..fbca0e9a6 --- /dev/null +++ b/tests/fsm/out21.err @@ -0,0 +1 @@ +10:12: Syntax error diff --git a/tests/fsm/out22.fsm b/tests/fsm/out22.fsm new file mode 100644 index 000000000..50f1bb868 --- /dev/null +++ b/tests/fsm/out22.fsm @@ -0,0 +1,9 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +0 -> 1 'a'; +start: 0; +end: 1 = [ 0 ]; diff --git a/tests/fsm/out3.err b/tests/fsm/out3.err new file mode 100644 index 000000000..ebbbb9d1b --- /dev/null +++ b/tests/fsm/out3.err @@ -0,0 +1 @@ +8:1: Syntax error diff --git a/tests/fsm/out4.err b/tests/fsm/out4.err new file mode 100644 index 000000000..31fa45171 --- /dev/null +++ b/tests/fsm/out4.err @@ -0,0 +1 @@ +8:7: Syntax error diff --git a/tests/fsm/out5.err b/tests/fsm/out5.err new file mode 100644 index 000000000..ebbbb9d1b --- /dev/null +++ b/tests/fsm/out5.err @@ -0,0 +1 @@ +8:1: Syntax error diff --git a/tests/fsm/out6.fsm b/tests/fsm/out6.fsm new file mode 100644 index 000000000..b673566f0 --- /dev/null +++ b/tests/fsm/out6.fsm @@ -0,0 +1,7 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +0 -> 1; diff --git a/tests/fsm/out7.fsm b/tests/fsm/out7.fsm new file mode 100644 index 000000000..3d4653a70 --- /dev/null +++ b/tests/fsm/out7.fsm @@ -0,0 +1,7 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +start: 0; diff --git a/tests/fsm/out8.fsm b/tests/fsm/out8.fsm new file mode 100644 index 000000000..86110f4ba --- /dev/null +++ b/tests/fsm/out8.fsm @@ -0,0 +1,10 @@ +# +# Copyright 2008-2024 Katherine Flavel +# +# See LICENCE for the full copyright terms. +# + +0; +1; + +start: 0; diff --git a/tests/fsm/out9.err b/tests/fsm/out9.err new file mode 100644 index 000000000..f7e4f861b --- /dev/null +++ b/tests/fsm/out9.err @@ -0,0 +1 @@ +8:3: Syntax error From db27a74564b3ab6d522a2acddb53a844fb70e906 Mon Sep 17 00:00:00 2001 From: Kate F Date: Tue, 11 Jun 2024 04:40:38 -0700 Subject: [PATCH 09/28] Wrong type. This should've been done when updating to fsm_state_t. --- src/libfsm/print/api.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libfsm/print/api.c b/src/libfsm/print/api.c index 38e5dfc27..16e787a05 100644 --- a/src/libfsm/print/api.c +++ b/src/libfsm/print/api.c @@ -93,7 +93,7 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) fprintf(f, "\n"); fprintf(f, "int\n"); - fprintf(f, "%sfsm(struct fsm *fsm, struct fsm_state *x, struct fsm_state *y)\n", + fprintf(f, "%sfsm(struct fsm *fsm, fsm_state_t *x, fsm_state_t *y)\n", fsm->opt->prefix != NULL ? fsm->opt->prefix : ""); fprintf(f, "{\n"); @@ -103,16 +103,20 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) fprintf(f, "\tsize_t i;\n"); fprintf(f, "\n"); + fprintf(f, "\tassert(x != NULL);\n"); + fprintf(f, "\tassert(y != NULL);\n"); + fprintf(f, "\n"); + fprintf(f, "\tfor (i = 0; i < %zu; i++) {\n", fsm->statecount); fprintf(f, "\t\tif (i == %u) {\n", start); - fprintf(f, "\t\t\ts[%u] = x;\n", start); + fprintf(f, "\t\t\ts[%u] = *x;\n", start); fprintf(f, "\t\t\tcontinue;\n"); fprintf(f, "\t\t}\n"); fprintf(f, "\n"); fprintf(f, "\t\tif (i == %u) {\n", end); - fprintf(f, "\t\t\ts[%u] = y;\n", end); + fprintf(f, "\t\t\ts[%u] = *y;\n", end); fprintf(f, "\t\t\tcontinue;\n"); fprintf(f, "\t\t}\n"); fprintf(f, "\n"); From 26b9d25333193a3ee23a67063d24d5352c33e4da Mon Sep 17 00:00:00 2001 From: Kate F Date: Tue, 11 Jun 2024 07:43:17 -0700 Subject: [PATCH 10/28] Printing for endids. This is never actually reached, because fsm_collate() doesn't handle end IDs. --- src/libfsm/print/api.c | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/libfsm/print/api.c b/src/libfsm/print/api.c index 16e787a05..33da6191a 100644 --- a/src/libfsm/print/api.c +++ b/src/libfsm/print/api.c @@ -27,6 +27,19 @@ #include #include +/* TODO: centralise */ +static int +comp_end_id(const void *a, const void *b) +{ + assert(a != NULL); + assert(b != NULL); + + if (* (fsm_end_id_t *) a < * (fsm_end_id_t *) b) { return -1; } + if (* (fsm_end_id_t *) a > * (fsm_end_id_t *) b) { return +1; } + + return 0; +} + static int rangeclass(unsigned char x, unsigned char y) { @@ -90,6 +103,7 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) fprintf(f, "\n"); fprintf(f, "#include \n"); + fprintf(f, "#include \n"); fprintf(f, "\n"); fprintf(f, "int\n"); @@ -128,6 +142,47 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) fprintf(f, "\t}\n"); fprintf(f, "\n"); + { + size_t count; + + count = fsm_getendidcount(fsm, end); + if (count > 0) { + enum fsm_getendids_res res; + fsm_end_id_t *ids; + size_t written; + + ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); + if (ids == NULL) { + /* XXX */ + goto error; + } + + res = fsm_getendids(fsm, end, count, ids, &written); + switch (res) { + case FSM_GETENDIDS_NOT_FOUND: + case FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE: + assert(!"unreached"); + abort(); + + case FSM_GETENDIDS_FOUND: + break; + } + + assert(written == count); + + qsort(ids, count, sizeof *ids, comp_end_id); + + fprintf(f, "\tif (fsm_isend(fsm, s[%u])) {\n", end); + for (size_t id = 0; id < count; id++) { + fprintf(f, "\t\tfsm_setendidstate(fsm, s[%u], %zu);\n", end, id); + } + fprintf(f, "\t}\n"); + fprintf(f, "\n"); + + f_free(fsm->opt->alloc, ids); + } + } + a = f_malloc(fsm->opt->alloc, fsm->statecount * sizeof *a); if (a == NULL) { /* XXX */ From 20ac21b674b7faafbaf835d65369386adcf99b37 Mon Sep 17 00:00:00 2001 From: Kate F Date: Tue, 11 Jun 2024 11:54:53 -0700 Subject: [PATCH 11/28] Printing for endids. --- src/libfsm/print/irdot.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libfsm/print/irdot.c b/src/libfsm/print/irdot.c index 206a42e5e..d388aa88e 100644 --- a/src/libfsm/print/irdot.c +++ b/src/libfsm/print/irdot.c @@ -191,6 +191,20 @@ print_cs(FILE *f, const struct fsm_options *opt, fprintf(f, "\t\t S%u%s\n", ir_indexof(ir, cs), strategy_name(cs->strategy)); + if (cs->isend && cs->end_ids != NULL) { + fprintf(f, "\t\t end id"); + + for (size_t i = 0; i < cs->end_ids->count; i++) { + fprintf(f, "#%u", cs->end_ids->ids[i]); + + if (i < cs->end_ids->count - 1) { + fprintf(f, " "); + } + } + + fprintf(f, "\n"); + } + if (cs->example != NULL) { fprintf(f, "\t\t example"); escputs(f, opt, dot_escputc_html, cs->example); From 8edcc074d50ee977b3a23c2163c650ae387b48f5 Mon Sep 17 00:00:00 2001 From: Kate F Date: Tue, 11 Jun 2024 12:01:00 -0700 Subject: [PATCH 12/28] Printing for endids. --- src/libfsm/print/irjson.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libfsm/print/irjson.c b/src/libfsm/print/irjson.c index 173bef0df..a1e154942 100644 --- a/src/libfsm/print/irjson.c +++ b/src/libfsm/print/irjson.c @@ -123,6 +123,18 @@ print_cs(FILE *f, const struct fsm_options *opt, fprintf(f, "\t\t{\n"); fprintf(f, "\t\t\t\"end\": %s,\n", cs->isend ? "true" : "false"); + if (cs->isend && cs->end_ids != NULL) { + fprintf(f, "\t\t\t\"end_id\": ["); + for (size_t i = 0; i < cs->end_ids->count; i++) { + fprintf(f, "%u", cs->end_ids->ids[i]); + + if (i < cs->end_ids->count - 1) { + fprintf(f, ", "); + } + } + fprintf(f, "],\n"); + } + fprintf(f, "\t\t\t\"strategy\": \"%s\"", strategy_name(cs->strategy)); if (cs->example != NULL || cs->strategy != IR_NONE) { fprintf(f, ","); From 69efe14ad293efca25cb2106ad7585c3160daa1b Mon Sep 17 00:00:00 2001 From: Kate F Date: Tue, 11 Jun 2024 12:39:52 -0700 Subject: [PATCH 13/28] Missing free. --- src/libfsm/print/json.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libfsm/print/json.c b/src/libfsm/print/json.c index 5c3235237..9a878825c 100644 --- a/src/libfsm/print/json.c +++ b/src/libfsm/print/json.c @@ -184,6 +184,8 @@ singlestate(FILE *f, const struct fsm *fsm, fsm_state_t s, int *notfirst) print_edge_bitmap(f, notfirst, fsm->opt, s, e.state, &bm); } + state_set_free(unique); + /* * Special edges are not consolidated above */ From 2b4821e7e1933e06818c1d9b154162c981b5a98e Mon Sep 17 00:00:00 2001 From: Kate F Date: Tue, 11 Jun 2024 13:56:25 -0700 Subject: [PATCH 14/28] Printing for endids. --- src/libfsm/print/vmdot.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libfsm/print/vmdot.c b/src/libfsm/print/vmdot.c index 101934f17..775714798 100644 --- a/src/libfsm/print/vmdot.c +++ b/src/libfsm/print/vmdot.c @@ -97,6 +97,18 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, } } else { fprintf(f, "ret %td", op->ir_state - ir->states); + + if (op->ir_state->end_ids != NULL) { + fprintf(f, " / "); + + for (size_t i = 0; i < op->ir_state->end_ids->count; i++) { + fprintf(f, "#%u", op->ir_state->end_ids->ids[i]); + + if (i < op->ir_state->end_ids->count - 1) { + fprintf(f, " "); + } + } + } } return 0; From e07f66e9f4a322efbb9069e87cc2e026fdadc7b4 Mon Sep 17 00:00:00 2001 From: Kate F Date: Tue, 11 Jun 2024 16:45:32 -0700 Subject: [PATCH 15/28] No need for the wrapper functions here. --- include/fsm/fsm.h | 4 +-- src/libfsm/clone.c | 4 +-- src/libfsm/endids.c | 22 ++------------ src/libfsm/endids.h | 9 ------ src/libfsm/epsilons.c | 4 +-- src/libfsm/libfsm.syms | 4 +-- src/libfsm/minimise.c | 4 +-- src/libfsm/minimise_test_oracle.c | 6 ++-- src/libfsm/print/api.c | 4 +-- src/libfsm/print/dot.c | 4 +-- src/libfsm/print/fsm.c | 4 +-- src/libfsm/print/ir.c | 4 +-- src/libfsm/print/json.c | 4 +-- src/libfsm/walk2.c | 8 ++--- src/lx/ast.c | 4 +-- src/re/main.c | 2 +- tests/capture/captest.c | 8 ++--- tests/capture/capture4.c | 2 +- tests/endids/endids0.c | 4 +-- tests/endids/endids0_many_endids.c | 8 ++--- tests/endids/endids1_determinise.c | 4 +-- .../endids/endids1_determinise_and_minimise.c | 4 +-- tests/endids/endids2_union.c | 16 +++++----- tests/endids/endids2_union_many_endids.c | 22 +++++++------- tests/endids/endids4.c | 18 +++++------ tests/endids/endids5.c | 20 ++++++------- tests/endids/endids6.c | 30 +++++++++---------- tests/endids/endids7.c | 26 ++++++++-------- tests/endids/endids7_with_duplicates.c | 26 ++++++++-------- tests/endids/endids8.c | 14 ++++----- tests/endids/endids9.c | 14 ++++----- tests/endids/utils.c | 16 +++++----- tests/gen/gtest.c | 4 +-- tests/re_strings/testutil.c | 2 +- 34 files changed, 149 insertions(+), 180 deletions(-) diff --git a/include/fsm/fsm.h b/include/fsm/fsm.h index 2fea117cd..81c472d3e 100644 --- a/include/fsm/fsm.h +++ b/include/fsm/fsm.h @@ -238,13 +238,13 @@ enum fsm_getendids_res { FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE = -1 }; enum fsm_getendids_res -fsm_getendids(const struct fsm *fsm, fsm_state_t end_state, +fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, size_t id_buf_count, fsm_end_id_t *id_buf, size_t *ids_written); /* Get the number of end IDs associated with an end state. */ size_t -fsm_getendidcount(const struct fsm *fsm, fsm_state_t end_state); +fsm_endid_count(const struct fsm *fsm, fsm_state_t end_state); /* Callback function to remap the end ids of a state. This function can * remap to fewer end ids, but cannot add additional end ids, and cannot diff --git a/src/libfsm/clone.c b/src/libfsm/clone.c index 78511b12c..587976e94 100644 --- a/src/libfsm/clone.c +++ b/src/libfsm/clone.c @@ -127,15 +127,13 @@ static int copy_end_ids_cb(fsm_state_t state, const fsm_end_id_t id, void *opaque) { struct copy_end_ids_env *env = opaque; - enum fsm_endid_set_res sres; assert(env->tag == 'c'); #if LOG_CLONE_ENDIDS fprintf(stderr, "clone[%d] <- %d\n", state, id); #endif - sres = fsm_endid_set(env->dst, state, id); - if (sres == FSM_ENDID_SET_ERROR_ALLOC_FAIL) { + if (!fsm_setendidstate(env->dst, state, id)) { env->ok = 0; return 0; } diff --git a/src/libfsm/endids.c b/src/libfsm/endids.c index 1fc98ae68..b2c1eeadf 100644 --- a/src/libfsm/endids.c +++ b/src/libfsm/endids.c @@ -69,13 +69,11 @@ fsm_setendid(struct fsm *fsm, fsm_end_id_t id) /* for every end state */ for (i = 0; i < fsm->statecount; i++) { if (fsm_isend(fsm, i)) { - enum fsm_endid_set_res sres; #if LOG_ENDIDS > 3 fprintf(stderr, "fsm_setendid: setting id %u on state %d\n", id, i); #endif - sres = fsm_endid_set(fsm, i, id); - if (sres == FSM_ENDID_SET_ERROR_ALLOC_FAIL) { + if (!fsm_setendidstate(fsm, i, id)) { return 0; } } @@ -94,21 +92,6 @@ fsm_setendidstate(struct fsm *fsm, fsm_state_t end_state, fsm_end_id_t id) return 1; } -enum fsm_getendids_res -fsm_getendids(const struct fsm *fsm, fsm_state_t end_state, - size_t id_buf_count, fsm_end_id_t *id_buf, - size_t *ids_written) -{ - return fsm_endid_get(fsm, end_state, - id_buf_count, id_buf, ids_written); -} - -size_t -fsm_getendidcount(const struct fsm *fsm, fsm_state_t end_state) -{ - return fsm_endid_count(fsm, end_state); -} - int fsm_endid_init(struct fsm *fsm) { @@ -796,8 +779,7 @@ carry_iter_cb(fsm_state_t state, fsm_end_id_t id, void *opaque) (void)state; - sres = fsm_endid_set(env->dst, env->dst_state, id); - if (sres == FSM_ENDID_SET_ERROR_ALLOC_FAIL) { + if (!fsm_setendidstate(env->dst, env->dst_state, id)) { env->ok = 0; return 0; } diff --git a/src/libfsm/endids.h b/src/libfsm/endids.h index 6c46567b3..c4b3184b5 100644 --- a/src/libfsm/endids.h +++ b/src/libfsm/endids.h @@ -45,15 +45,6 @@ enum fsm_endid_set_res fsm_endid_set_bulk(struct fsm *fsm, fsm_state_t state, size_t num_ids, const fsm_end_id_t *ids, enum fsm_endid_bulk_op op); -size_t -fsm_endid_count(const struct fsm *fsm, - fsm_state_t state); - -enum fsm_getendids_res -fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, - size_t id_buf_count, fsm_end_id_t *id_buf, - size_t *ids_written); - int fsm_endid_carry(const struct fsm *src_fsm, const struct state_set *src_set, struct fsm *dst_fsm, fsm_state_t dst_state); diff --git a/src/libfsm/epsilons.c b/src/libfsm/epsilons.c index e87d9d974..82dd6cfa4 100644 --- a/src/libfsm/epsilons.c +++ b/src/libfsm/epsilons.c @@ -405,9 +405,7 @@ carry_endids(struct fsm *fsm, struct state_set *states, /* add them */ for (i = 0; i < env.count; i++) { - enum fsm_endid_set_res sres; - sres = fsm_endid_set(fsm, dst_state, env.ids[i]); - if (sres == FSM_ENDID_SET_ERROR_ALLOC_FAIL) { + if (!fsm_setendidstate(fsm, dst_state, env.ids[i])) { env.ok = 0; goto cleanup; } diff --git a/src/libfsm/libfsm.syms b/src/libfsm/libfsm.syms index 6e1f72dbe..0e40ae884 100644 --- a/src/libfsm/libfsm.syms +++ b/src/libfsm/libfsm.syms @@ -86,8 +86,8 @@ fsm_setstart fsm_getstart fsm_setend -fsm_getendidcount -fsm_getendids +fsm_endid_count +fsm_endid_get fsm_setendid fsm_mapendids fsm_increndids diff --git a/src/libfsm/minimise.c b/src/libfsm/minimise.c index 94dfdf80b..294615292 100644 --- a/src/libfsm/minimise.c +++ b/src/libfsm/minimise.c @@ -951,7 +951,7 @@ static int collect_end_ids(const struct fsm *fsm, fsm_state_t s, struct end_metadata_end *e) { - e->count = fsm_getendidcount(fsm, s); + e->count = fsm_endid_count(fsm, s); if (e->count > 0) { e->ids = f_malloc(fsm->opt->alloc, @@ -961,7 +961,7 @@ collect_end_ids(const struct fsm *fsm, fsm_state_t s, } size_t written; - enum fsm_getendids_res res = fsm_getendids(fsm, s, + enum fsm_getendids_res res = fsm_endid_get(fsm, s, e->count, e->ids, &written); assert(res == FSM_GETENDIDS_FOUND); assert(written == e->count); diff --git a/src/libfsm/minimise_test_oracle.c b/src/libfsm/minimise_test_oracle.c index 9045ce67b..388cc3634 100644 --- a/src/libfsm/minimise_test_oracle.c +++ b/src/libfsm/minimise_test_oracle.c @@ -143,7 +143,7 @@ fsm_minimise_test_oracle(const struct fsm *fsm) * This includes the dead state. */ for (size_t i = 0; i < table_states; i++) { if (i < state_count && fsm_isend(fsm, i)) { - const size_t count = fsm_getendidcount(fsm, i); + const size_t count = fsm_endid_count(fsm, i); if (count > max_endid_count) { max_endid_count = count; } @@ -177,7 +177,7 @@ fsm_minimise_test_oracle(const struct fsm *fsm) for (size_t i = 0; i < state_count; i++) { if (fsm_isend(fsm, i)) { size_t written_a; - enum fsm_getendids_res eres = fsm_getendids(fsm, i, + enum fsm_getendids_res eres = fsm_endid_get(fsm, i, max_endid_count, endid_buf_a, &written_a); assert(eres != FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE); if (eres == FSM_GETENDIDS_NOT_FOUND) { @@ -188,7 +188,7 @@ fsm_minimise_test_oracle(const struct fsm *fsm) /* note: skipping eg 0 here since that's the empty set */ for (size_t eg_i = 1; eg_i < endid_group_count; eg_i++) { size_t written_b; - eres = fsm_getendids(fsm, endid_group_leaders[eg_i], + eres = fsm_endid_get(fsm, endid_group_leaders[eg_i], max_endid_count, endid_buf_b, &written_b); assert(eres != FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE); if (written_b != written_a) { continue; } diff --git a/src/libfsm/print/api.c b/src/libfsm/print/api.c index 33da6191a..dab9cc4df 100644 --- a/src/libfsm/print/api.c +++ b/src/libfsm/print/api.c @@ -145,7 +145,7 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) { size_t count; - count = fsm_getendidcount(fsm, end); + count = fsm_endid_count(fsm, end); if (count > 0) { enum fsm_getendids_res res; fsm_end_id_t *ids; @@ -157,7 +157,7 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) goto error; } - res = fsm_getendids(fsm, end, count, ids, &written); + res = fsm_endid_get(fsm, end, count, ids, &written); switch (res) { case FSM_GETENDIDS_NOT_FOUND: case FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE: diff --git a/src/libfsm/print/dot.c b/src/libfsm/print/dot.c index ab360af2b..518009dd3 100644 --- a/src/libfsm/print/dot.c +++ b/src/libfsm/print/dot.c @@ -170,7 +170,7 @@ print_dotfrag(FILE *f, const struct fsm *fsm) enum fsm_getendids_res res; size_t written; struct fsm_end_ids *ids = NULL; - const size_t count = fsm_getendidcount(fsm, s); + const size_t count = fsm_endid_count(fsm, s); if (count > 0) { ids = f_malloc(fsm->opt->alloc, sizeof(*ids) + ((count - 1) * sizeof(ids->ids))); @@ -179,7 +179,7 @@ print_dotfrag(FILE *f, const struct fsm *fsm) return -1; } - res = fsm_getendids(fsm, s, count, + res = fsm_endid_get(fsm, s, count, ids->ids, &written); if (res == FSM_GETENDIDS_FOUND) { ids->count = (unsigned)written; diff --git a/src/libfsm/print/fsm.c b/src/libfsm/print/fsm.c index ae3163abd..928c6f83a 100644 --- a/src/libfsm/print/fsm.c +++ b/src/libfsm/print/fsm.c @@ -301,7 +301,7 @@ fsm_print_fsm(FILE *f, const struct fsm *fsm) fprintf(f, "%u", s); - count = fsm_getendidcount(fsm, s); + count = fsm_endid_count(fsm, s); if (count > 0) { enum fsm_getendids_res res; fsm_end_id_t *ids; @@ -312,7 +312,7 @@ fsm_print_fsm(FILE *f, const struct fsm *fsm) return -1; } - res = fsm_getendids(fsm, s, count, ids, &written); + res = fsm_endid_get(fsm, s, count, ids, &written); switch (res) { case FSM_GETENDIDS_NOT_FOUND: case FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE: diff --git a/src/libfsm/print/ir.c b/src/libfsm/print/ir.c index 3a7aee222..7c53e3846 100644 --- a/src/libfsm/print/ir.c +++ b/src/libfsm/print/ir.c @@ -471,14 +471,14 @@ make_ir(const struct fsm *fsm) if (fsm_isend(fsm, i)) { enum fsm_getendids_res res; size_t written; - const size_t count = fsm_getendidcount(fsm, i); + const size_t count = fsm_endid_count(fsm, i); struct fsm_end_ids *ids = f_malloc(fsm->opt->alloc, sizeof(*ids) + (count == 0 ? 0 : (count - 1) * sizeof(ids->ids[0]))); if (ids == NULL) { goto error; } - res = fsm_getendids(fsm, i, count, + res = fsm_endid_get(fsm, i, count, ids->ids, &written); if (res == FSM_GETENDIDS_FOUND) { ids->count = (unsigned)written; diff --git a/src/libfsm/print/json.c b/src/libfsm/print/json.c index 9a878825c..69615d287 100644 --- a/src/libfsm/print/json.c +++ b/src/libfsm/print/json.c @@ -249,12 +249,12 @@ fsm_print_json(FILE *f, const struct fsm *fsm) if (fsm_isend(fsm, i)) { enum fsm_getendids_res res; size_t written; - const size_t count = fsm_getendidcount(fsm, i); + const size_t count = fsm_endid_count(fsm, i); struct fsm_end_ids *ids = f_malloc(fsm->opt->alloc, sizeof(*ids) + ((count - 1) * sizeof(ids->ids[0]))); assert(ids != NULL); - res = fsm_getendids(fsm, i, count, + res = fsm_endid_get(fsm, i, count, ids->ids, &written); if (res == FSM_GETENDIDS_FOUND) { ids->count = (unsigned)written; diff --git a/src/libfsm/walk2.c b/src/libfsm/walk2.c index c321db678..b21883abd 100644 --- a/src/libfsm/walk2.c +++ b/src/libfsm/walk2.c @@ -266,11 +266,11 @@ fsm_walk2_tuple_new(struct fsm_walk2_data *data, size_t num_a_endids = 0, num_b_endids = 0, total_num_endids; if (fsm_a != NULL && fsm_isend(fsm_a,a)) { - num_a_endids = fsm_getendidcount(fsm_a, a); + num_a_endids = fsm_endid_count(fsm_a, a); } if (fsm_b != NULL && fsm_isend(fsm_b,b)) { - num_b_endids = fsm_getendidcount(fsm_b, b); + num_b_endids = fsm_endid_count(fsm_b, b); } total_num_endids = num_a_endids + num_b_endids; @@ -286,7 +286,7 @@ fsm_walk2_tuple_new(struct fsm_walk2_data *data, if (num_a_endids > 0) { size_t nwritten = 0; - ret = fsm_getendids(fsm_a, a, num_a_endids, &endids[0], &nwritten); + ret = fsm_endid_get(fsm_a, a, num_a_endids, &endids[0], &nwritten); if (ret != FSM_GETENDIDS_FOUND || nwritten != num_a_endids) { free(endids); @@ -297,7 +297,7 @@ fsm_walk2_tuple_new(struct fsm_walk2_data *data, if (num_b_endids > 0) { size_t nwritten = 0; - ret = fsm_getendids(fsm_b, b, num_b_endids, &endids[num_a_endids], &nwritten); + ret = fsm_endid_get(fsm_b, b, num_b_endids, &endids[num_a_endids], &nwritten); if (ret != FSM_GETENDIDS_FOUND || nwritten != num_b_endids) { free(endids); diff --git a/src/lx/ast.c b/src/lx/ast.c index 75754f58d..4d088cd75 100644 --- a/src/lx/ast.c +++ b/src/lx/ast.c @@ -241,7 +241,7 @@ ast_getendmapping(const struct fsm *fsm, fsm_state_t s) size_t written; struct ast_mapping *m; - id_count = fsm_getendidcount(fsm, s); + id_count = fsm_endid_count(fsm, s); if (id_count > ID_STACK_BUF_COUNT) { id_buf_dynamic = malloc(id_count * sizeof(id_buf_dynamic[0])); if (id_buf_dynamic == NULL) { @@ -249,7 +249,7 @@ ast_getendmapping(const struct fsm *fsm, fsm_state_t s) } } - res = fsm_getendids(fsm, + res = fsm_endid_get(fsm, s, id_count, id_buf_dynamic == NULL ? id_buf : id_buf_dynamic, &written); diff --git a/src/re/main.c b/src/re/main.c index 77f147518..592e368c7 100644 --- a/src/re/main.c +++ b/src/re/main.c @@ -294,7 +294,7 @@ find_first_match_for_end_state(const struct fsm *dfa, fsm_state_t s) return NULL; } - res = fsm_getendids(dfa, s, MAX_END_IDS, + res = fsm_endid_get(dfa, s, MAX_END_IDS, end_id_buf, &end_ids_written); if (res == FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE) { fprintf(stderr, "Error: Multiple end IDs\n"); diff --git a/tests/capture/captest.c b/tests/capture/captest.c index dc66f81d4..b2bc1243f 100644 --- a/tests/capture/captest.c +++ b/tests/capture/captest.c @@ -92,11 +92,11 @@ captest_run_single(const struct captest_single_fsm_test_info *info) fsm_end_id_t id_buf[1] = { ~0 }; enum fsm_getendids_res gres; size_t written; - if (1 != fsm_getendidcount(fsm, end)) { + if (1 != fsm_endid_count(fsm, end)) { FAIL("did not have exactly one end ID"); } - gres = fsm_getendids(fsm, end, 1, id_buf, &written); + gres = fsm_endid_get(fsm, end, 1, id_buf, &written); if (gres != FSM_GETENDIDS_FOUND) { FAIL("failed to get end IDs"); } @@ -190,12 +190,12 @@ captest_check_single_end_id(const struct fsm *fsm, fsm_state_t end_state, msg = &unused; } - if (1 != fsm_getendidcount(fsm, end_state)) { + if (1 != fsm_endid_count(fsm, end_state)) { *msg = "did not have exactly one end ID"; return 0; } - gres = fsm_getendids(fsm, end_state, 1, id_buf, &written); + gres = fsm_endid_get(fsm, end_state, 1, id_buf, &written); if (gres != FSM_GETENDIDS_FOUND) { *msg = "failed to get end IDs"; return 0; diff --git a/tests/capture/capture4.c b/tests/capture/capture4.c index 170cbe8b0..1759afb05 100644 --- a/tests/capture/capture4.c +++ b/tests/capture/capture4.c @@ -223,7 +223,7 @@ check(const struct fsm *fsm, const char *string, enum fsm_getendids_res gres; fsm_end_id_t id_buf[2]; size_t written; - gres = fsm_getendids(fsm, end, 2, id_buf, &written); + gres = fsm_endid_get(fsm, end, 2, id_buf, &written); if (gres != FSM_GETENDIDS_FOUND) { assert(!"fsm_getendids failed"); } diff --git a/tests/endids/endids0.c b/tests/endids/endids0.c index f101f0cc6..4dd4b4ebe 100644 --- a/tests/endids/endids0.c +++ b/tests/endids/endids0.c @@ -47,10 +47,10 @@ int main(void) size_t nwritten; enum fsm_getendids_res ret; - assert( fsm_getendidcount(fsm, state_ind) == 1); + assert( fsm_endid_count(fsm, state_ind) == 1); nwritten = 0; - ret = fsm_getendids( + ret = fsm_endid_get( fsm, state_ind, 1, diff --git a/tests/endids/endids0_many_endids.c b/tests/endids/endids0_many_endids.c index cd5230855..834702bdc 100644 --- a/tests/endids/endids0_many_endids.c +++ b/tests/endids/endids0_many_endids.c @@ -69,7 +69,7 @@ int main(void) assert(end_state < nstates); - assert(fsm_getendidcount(fsm, end_state) == sizeof all_end_ids / sizeof all_end_ids[0]); + assert(fsm_endid_count(fsm, end_state) == sizeof all_end_ids / sizeof all_end_ids[0]); for (i=0; i < sizeof all_end_ids / sizeof all_end_ids[0]; i++) { /* add duplicate end ids */ ret = fsm_setendid(fsm, all_end_ids[i]); @@ -78,7 +78,7 @@ int main(void) assert(ret == 1); /* but it shouldn't add a duplicate id */ - assert(fsm_getendidcount(fsm, end_state) == sizeof all_end_ids / sizeof all_end_ids[0]); + assert(fsm_endid_count(fsm, end_state) == sizeof all_end_ids / sizeof all_end_ids[0]); } nend = 0; @@ -90,10 +90,10 @@ int main(void) memset(&endids[0], 0, sizeof endids); - assert(fsm_getendidcount(fsm, state_ind) == sizeof all_end_ids / sizeof all_end_ids[0]); + assert(fsm_endid_count(fsm, state_ind) == sizeof all_end_ids / sizeof all_end_ids[0]); nwritten = 0; - ret = fsm_getendids( + ret = fsm_endid_get( fsm, state_ind, sizeof endids/sizeof endids[0], diff --git a/tests/endids/endids1_determinise.c b/tests/endids/endids1_determinise.c index 956e0ee33..75a89db0d 100644 --- a/tests/endids/endids1_determinise.c +++ b/tests/endids/endids1_determinise.c @@ -43,10 +43,10 @@ int main(void) size_t nwritten; enum fsm_getendids_res ret; - assert( fsm_getendidcount(fsm, state_ind) == 1); + assert( fsm_endid_count(fsm, state_ind) == 1); nwritten = 0; - ret = fsm_getendids( + ret = fsm_endid_get( fsm, state_ind, 1, diff --git a/tests/endids/endids1_determinise_and_minimise.c b/tests/endids/endids1_determinise_and_minimise.c index 4619af4a8..d8df93543 100644 --- a/tests/endids/endids1_determinise_and_minimise.c +++ b/tests/endids/endids1_determinise_and_minimise.c @@ -48,10 +48,10 @@ int main(void) size_t nwritten; enum fsm_getendids_res ret; - assert( fsm_getendidcount(fsm, state_ind) == 1); + assert( fsm_endid_count(fsm, state_ind) == 1); nwritten = 0; - ret = fsm_getendids( + ret = fsm_endid_get( fsm, state_ind, 1, diff --git a/tests/endids/endids2_union.c b/tests/endids/endids2_union.c index d65ef17e8..a81bce01c 100644 --- a/tests/endids/endids2_union.c +++ b/tests/endids/endids2_union.c @@ -56,16 +56,16 @@ int main(void) if (fsm_isend(comb, state_ind)) { fsm_end_id_t endids[2] = {0,0}; size_t nwritten; - size_t num_endids; + size_t count; enum fsm_getendids_res ret; nwritten = 0; - num_endids = fsm_getendidcount(comb, state_ind); - // fprintf(stderr, "state %u, num_endids = %zu\n", state_ind, num_endids); + count = fsm_endid_count(comb, state_ind); + // fprintf(stderr, "state %u, count = %zu\n", state_ind, count); - assert( num_endids > 0 && num_endids <= 2); + assert( count > 0 && count <= 2); - ret = fsm_getendids( + ret = fsm_endid_get( comb, state_ind, 2, @@ -73,7 +73,7 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); if (nwritten == 1) { assert(endids[0] == 1 || endids[0] == 2); @@ -111,7 +111,7 @@ int main(void) static const struct { const char *s; int should_match; - size_t num_endids; + size_t count; fsm_end_id_t endid[2]; } matches[] = { { "abc" , 1, 1, { 1, 0 } }, @@ -160,7 +160,7 @@ int main(void) assert( ret == 1 ); assert( end_ids != NULL ); - assert( num_end_ids == matches[i].num_endids ); + assert( num_end_ids == matches[i].count ); qsort(&end_ids[0], num_end_ids, sizeof end_ids[0], cmp_endids); diff --git a/tests/endids/endids2_union_many_endids.c b/tests/endids/endids2_union_many_endids.c index 46f2a189e..d7beb8777 100644 --- a/tests/endids/endids2_union_many_endids.c +++ b/tests/endids/endids2_union_many_endids.c @@ -183,17 +183,17 @@ int main(void) if (fsm_isend(fsm, state_ind)) { int tested_pattern[NUM_PATTERNS]; fsm_end_id_t endids[NUM_ENDIDS_TOTAL]; - size_t nwritten, num_endids, j; + size_t nwritten, count, j; enum fsm_getendids_res ret; memset(&endids[0], 0, sizeof endids); nwritten = 0; - num_endids = fsm_getendidcount(fsm, state_ind); + count = fsm_endid_count(fsm, state_ind); - assert(num_endids > 0 && num_endids <= sizeof endids/sizeof endids[0]); + assert(count > 0 && count <= sizeof endids/sizeof endids[0]); - ret = fsm_getendids( + ret = fsm_endid_get( fsm, state_ind, sizeof endids/sizeof endids[0], @@ -201,11 +201,11 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); memset(&tested_pattern[0], 0, sizeof tested_pattern); - for (j=0; j < num_endids; j++) { + for (j=0; j < count; j++) { size_t k, pattern_index; pattern_index = (endids[j] - 1)/NUM_ENDIDS_PER_PATTERN; @@ -250,17 +250,17 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[NUM_ENDIDS_TOTAL]; - size_t nwritten, num_endids; + size_t nwritten, count; enum fsm_getendids_res ret; memset(&endids[0], 0, sizeof endids); nwritten = 0; - num_endids = fsm_getendidcount(fsm, state_ind); + count = fsm_endid_count(fsm, state_ind); - assert(num_endids <= NUM_ENDIDS_TOTAL); + assert(count <= NUM_ENDIDS_TOTAL); - ret = fsm_getendids( + ret = fsm_endid_get( fsm, state_ind, sizeof endids/sizeof endids[0], @@ -268,7 +268,7 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); } } diff --git a/tests/endids/endids4.c b/tests/endids/endids4.c index c8f312663..c4b7da823 100644 --- a/tests/endids/endids4.c +++ b/tests/endids/endids4.c @@ -68,17 +68,17 @@ int main(void) if (fsm_isend(comb, state_ind)) { fsm_end_id_t endids[2] = {0,0}; size_t nwritten; - size_t num_endids; + size_t count; enum fsm_getendids_res ret; nwritten = 0; - num_endids = fsm_getendidcount(comb, state_ind); + count = fsm_endid_count(comb, state_ind); - printf("state %u num_endids = %zu\n", state_ind, num_endids); + printf("state %u count = %zu\n", state_ind, count); - assert(num_endids == 2); + assert(count == 2); - ret = fsm_getendids( + ret = fsm_endid_get( comb, state_ind, 2, @@ -86,9 +86,9 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); - qsort(&endids[0], num_endids, sizeof endids[0], cmp_endids); + qsort(&endids[0], count, sizeof endids[0], cmp_endids); assert(endids[0] == 1 && endids[1] == 2); } } @@ -102,7 +102,7 @@ int main(void) static const struct { const char *s; int should_match; - size_t num_endids; + size_t count; fsm_end_id_t endid[2]; } matches[] = { { "abc" , 0, 0, { 0, 0 } }, @@ -151,7 +151,7 @@ int main(void) assert( ret == 1 ); assert( end_ids != NULL ); - assert( num_end_ids == matches[i].num_endids ); + assert( num_end_ids == matches[i].count ); qsort(&end_ids[0], num_end_ids, sizeof end_ids[0], cmp_endids); diff --git a/tests/endids/endids5.c b/tests/endids/endids5.c index f6220115a..91e39b5eb 100644 --- a/tests/endids/endids5.c +++ b/tests/endids/endids5.c @@ -69,17 +69,17 @@ int main(void) if (fsm_isend(comb, state_ind)) { fsm_end_id_t endids[2] = {0,0}; size_t nwritten; - size_t num_endids; + size_t count; enum fsm_getendids_res ret; nwritten = 0; - num_endids = fsm_getendidcount(comb, state_ind); + count = fsm_endid_count(comb, state_ind); - printf("state %u num_endids = %zu\n", state_ind, num_endids); + printf("state %u count = %zu\n", state_ind, count); - assert(num_endids == 1); + assert(count == 1); - ret = fsm_getendids( + ret = fsm_endid_get( comb, state_ind, 2, @@ -87,7 +87,7 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); assert(endids[0] == 1); } @@ -102,7 +102,7 @@ int main(void) static const struct { const char *s; int should_match; - size_t num_endids; + size_t count; fsm_end_id_t endid[2]; } matches[] = { { "abc" , 1, 1, { 1, 0 } }, @@ -145,8 +145,8 @@ int main(void) num_end_ids = 0; ret = match_string(comb, matches[i].s, NULL, &end_ids, &num_end_ids); - printf("match %zu, \"%s\", should_match=%d, num_endids=%zu, endids={ %u, %u }\n", - i, matches[i].s, matches[i].should_match, matches[i].num_endids, + printf("match %zu, \"%s\", should_match=%d, count=%zu, endids={ %u, %u }\n", + i, matches[i].s, matches[i].should_match, matches[i].count, (unsigned)matches[i].endid[0], (unsigned)matches[i].endid[1]); if (matches[i].should_match) { @@ -155,7 +155,7 @@ int main(void) assert( ret == 1 ); assert( end_ids != NULL ); - assert( num_end_ids == matches[i].num_endids ); + assert( num_end_ids == matches[i].count ); qsort(&end_ids[0], num_end_ids, sizeof end_ids[0], cmp_endids); diff --git a/tests/endids/endids6.c b/tests/endids/endids6.c index ca089d0f1..2179d0a03 100644 --- a/tests/endids/endids6.c +++ b/tests/endids/endids6.c @@ -19,7 +19,7 @@ struct state_info { fsm_state_t state; - unsigned num_endids; + unsigned count; fsm_end_id_t endids[2]; }; @@ -93,15 +93,15 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[2] = {0,0}; size_t nwritten; - size_t num_endids; + size_t count; enum fsm_getendids_res ret; nwritten = 0; - num_endids = fsm_getendidcount(fsm, state_ind); + count = fsm_endid_count(fsm, state_ind); - assert( num_endids > 0 && num_endids <= 2); + assert( count > 0 && count <= 2); - ret = fsm_getendids( + ret = fsm_endid_get( fsm, state_ind, sizeof endids / sizeof endids[0], @@ -109,10 +109,10 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); info[ninfo].state = state_ind; - info[ninfo].num_endids = nwritten; + info[ninfo].count = nwritten; if (nwritten == 1) { assert(endids[0] == 1 || endids[0] == 2); @@ -137,18 +137,18 @@ int main(void) for (state_ind = 0, info_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[2] = {0,0}; - size_t nwritten, num_endids, ind; + size_t nwritten, count, ind; enum fsm_getendids_res ret; assert( state_ind == info[info_ind].state ); nwritten = 0; - num_endids = fsm_getendidcount(fsm, state_ind); + count = fsm_endid_count(fsm, state_ind); - assert(num_endids > 0 && num_endids <= 2); + assert(count > 0 && count <= 2); - assert( num_endids == info[info_ind].num_endids ); - ret = fsm_getendids( + assert( count == info[info_ind].count ); + ret = fsm_endid_get( fsm, state_ind, sizeof endids / sizeof endids[0], @@ -156,13 +156,13 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); if (nwritten > 1) { - qsort(&endids[0], num_endids, sizeof endids[0], cmp_endids); + qsort(&endids[0], count, sizeof endids[0], cmp_endids); } - for (ind=0; ind < num_endids; ind++) { + for (ind=0; ind < count; ind++) { fsm_end_id_t expected = info[info_ind].endids[ind]; switch (info[info_ind].endids[ind]) { case 1: expected = 512; break; diff --git a/tests/endids/endids7.c b/tests/endids/endids7.c index cc68d02c0..c695136cc 100644 --- a/tests/endids/endids7.c +++ b/tests/endids/endids7.c @@ -19,7 +19,7 @@ struct state_info { fsm_state_t state; - unsigned num_endids; + unsigned count; fsm_end_id_t endids[2]; }; @@ -105,15 +105,15 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[2] = {0,0}; size_t nwritten; - size_t num_endids; + size_t count; enum fsm_getendids_res ret; nwritten = 0; - num_endids = fsm_getendidcount(fsm, state_ind); + count = fsm_endid_count(fsm, state_ind); - assert( num_endids > 0 && num_endids <= 2); + assert( count > 0 && count <= 2); - ret = fsm_getendids( + ret = fsm_endid_get( fsm, state_ind, sizeof endids / sizeof endids[0], @@ -121,10 +121,10 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); info[ninfo].state = state_ind; - info[ninfo].num_endids = nwritten; + info[ninfo].count = nwritten; if (nwritten == 1) { assert(endids[0] == 1 || endids[0] == 2); @@ -150,16 +150,16 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endid = 0; fsm_end_id_t expected; - size_t nwritten, num_endids; + size_t nwritten, count; enum fsm_getendids_res ret; assert( state_ind == info[info_ind].state ); nwritten = 0; - num_endids = fsm_getendidcount(fsm, state_ind); + count = fsm_endid_count(fsm, state_ind); - assert(num_endids == 1); - ret = fsm_getendids( + assert(count == 1); + ret = fsm_endid_get( fsm, state_ind, 1, @@ -167,9 +167,9 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); - if (info[info_ind].num_endids == 2) { + if (info[info_ind].count == 2) { expected = 3; } else if (info[info_ind].endids[0] == 1) { expected = 7; diff --git a/tests/endids/endids7_with_duplicates.c b/tests/endids/endids7_with_duplicates.c index b554f7cb6..3da80d9bc 100644 --- a/tests/endids/endids7_with_duplicates.c +++ b/tests/endids/endids7_with_duplicates.c @@ -19,7 +19,7 @@ struct state_info { fsm_state_t state; - unsigned num_endids; + unsigned count; fsm_end_id_t endids[2]; }; @@ -109,15 +109,15 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[2] = {0,0}; size_t nwritten; - size_t num_endids; + size_t count; enum fsm_getendids_res ret; nwritten = 0; - num_endids = fsm_getendidcount(fsm, state_ind); + count = fsm_endid_count(fsm, state_ind); - assert( num_endids > 0 && num_endids <= 2); + assert( count > 0 && count <= 2); - ret = fsm_getendids( + ret = fsm_endid_get( fsm, state_ind, sizeof endids / sizeof endids[0], @@ -125,10 +125,10 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); info[ninfo].state = state_ind; - info[ninfo].num_endids = nwritten; + info[ninfo].count = nwritten; if (nwritten == 1) { assert(endids[0] == 1 || endids[0] == 2); @@ -154,16 +154,16 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endid = 0; fsm_end_id_t expected; - size_t nwritten, num_endids; + size_t nwritten, count; enum fsm_getendids_res ret; assert( state_ind == info[info_ind].state ); nwritten = 0; - num_endids = fsm_getendidcount(fsm, state_ind); + count = fsm_endid_count(fsm, state_ind); - assert(num_endids == 1); - ret = fsm_getendids( + assert(count == 1); + ret = fsm_endid_get( fsm, state_ind, 1, @@ -171,9 +171,9 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); - if (info[info_ind].num_endids == 2) { + if (info[info_ind].count == 2) { expected = 3; } else if (info[info_ind].endids[0] == 1) { expected = 7; diff --git a/tests/endids/endids8.c b/tests/endids/endids8.c index e413e71e7..0be5c244d 100644 --- a/tests/endids/endids8.c +++ b/tests/endids/endids8.c @@ -74,17 +74,17 @@ int main(void) if (fsm_isend(comb, state_ind)) { fsm_end_id_t endids[3] = {0,0,0}; size_t nwritten; - size_t num_endids; + size_t count; enum fsm_getendids_res ret; nwritten = 0; - num_endids = fsm_getendidcount(comb, state_ind); + count = fsm_endid_count(comb, state_ind); - printf("state %u num_endids = %zu\n", state_ind, num_endids); + printf("state %u count = %zu\n", state_ind, count); - assert(num_endids == 3); + assert(count == 3); - ret = fsm_getendids( + ret = fsm_endid_get( comb, state_ind, sizeof endids / sizeof endids[0], @@ -92,9 +92,9 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); - qsort(&endids[0], num_endids, sizeof endids[0], cmp_endids); + qsort(&endids[0], count, sizeof endids[0], cmp_endids); assert(endids[0] == 1 && endids[1] == 2 && endids[2] == 4); } } diff --git a/tests/endids/endids9.c b/tests/endids/endids9.c index de3f28644..c6c467328 100644 --- a/tests/endids/endids9.c +++ b/tests/endids/endids9.c @@ -19,7 +19,7 @@ struct state_info { fsm_state_t state; - unsigned num_endids; + unsigned count; fsm_end_id_t endids[2]; }; @@ -73,15 +73,15 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[2] = {0,0}; size_t nwritten; - size_t num_endids; + size_t count; enum fsm_getendids_res ret; nwritten = 0; - num_endids = fsm_getendidcount(fsm, state_ind); + count = fsm_endid_count(fsm, state_ind); - assert( num_endids > 0 && num_endids <= 2); + assert( count > 0 && count <= 2); - ret = fsm_getendids( + ret = fsm_endid_get( fsm, state_ind, sizeof endids / sizeof endids[0], @@ -89,10 +89,10 @@ int main(void) &nwritten); assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == num_endids); + assert(nwritten == count); info[ninfo].state = state_ind; - info[ninfo].num_endids = nwritten; + info[ninfo].count = nwritten; if (nwritten == 1) { assert(endids[0] == 11 || endids[0] == 12); diff --git a/tests/endids/utils.c b/tests/endids/utils.c index 79777e825..b6dd23042 100644 --- a/tests/endids/utils.c +++ b/tests/endids/utils.c @@ -4,30 +4,30 @@ #include int -match_string(const struct fsm *fsm, const char *s, fsm_state_t *end_ptr, fsm_end_id_t **endids_ptr, size_t *num_endids_ptr) +match_string(const struct fsm *fsm, const char *s, fsm_state_t *end_ptr, fsm_end_id_t **endids_ptr, size_t *count_ptr) { fsm_state_t end = 0; int ret; ret = fsm_exec(fsm, fsm_sgetc, &s, &end, NULL); if (ret == 1) { - size_t num_endids; + size_t count; if (end_ptr != NULL) { *end_ptr = end; } - num_endids = fsm_getendidcount(fsm, end); - if (num_endids > 0) { + count = fsm_endid_count(fsm, end); + if (count > 0) { enum fsm_getendids_res ret; size_t nwritten = 0; - fsm_end_id_t *endids = calloc(num_endids, sizeof *endids); + fsm_end_id_t *endids = calloc(count, sizeof *endids); if (endids == NULL) { return -1; } - ret = fsm_getendids(fsm, end, num_endids, endids, &nwritten); + ret = fsm_endid_get(fsm, end, count, endids, &nwritten); if (ret != FSM_GETENDIDS_FOUND) { free(endids); errno = (ret == FSM_GETENDIDS_NOT_FOUND) ? EINVAL : ENOMEM; @@ -36,8 +36,8 @@ match_string(const struct fsm *fsm, const char *s, fsm_state_t *end_ptr, fsm_end if (endids_ptr != NULL) { *endids_ptr = endids; - if (num_endids_ptr != NULL) { - *num_endids_ptr = num_endids; + if (count_ptr != NULL) { + *count_ptr = count; } } else { free(endids); diff --git a/tests/gen/gtest.c b/tests/gen/gtest.c index 140407943..c99b2eeac 100644 --- a/tests/gen/gtest.c +++ b/tests/gen/gtest.c @@ -60,12 +60,12 @@ gtest_matches_cb(const struct fsm *fsm, #define ID_BUF_COUNT 1 fsm_end_id_t id_buf[ID_BUF_COUNT]; size_t written; - enum fsm_getendids_res gres = fsm_getendids(fsm, + enum fsm_getendids_res gres = fsm_endid_get(fsm, end_state, ID_BUF_COUNT, id_buf, &written); if (gres != FSM_GETENDIDS_FOUND) { fprintf(stderr, - "ERROR: fsm_getendids: returned %d\n", + "ERROR: fsm_endid_get: returned %d\n", gres); return FSM_GENERATE_MATCHES_CB_RES_HALT; } diff --git a/tests/re_strings/testutil.c b/tests/re_strings/testutil.c index 4f4678b0d..5b366c0ce 100644 --- a/tests/re_strings/testutil.c +++ b/tests/re_strings/testutil.c @@ -48,7 +48,7 @@ run_test(const char **strings) assert(res > 0); /* match */ size_t written; - enum fsm_getendids_res eres = fsm_getendids(fsm, end, + enum fsm_getendids_res eres = fsm_endid_get(fsm, end, MAX_INPUTS, id_buf, &written); assert(eres == FSM_GETENDIDS_FOUND); bool found = false; From ed4709c74e55590b5c25943aabb3dede39308447 Mon Sep 17 00:00:00 2001 From: Kate F Date: Wed, 12 Jun 2024 02:42:48 -0700 Subject: [PATCH 16/28] No need for the tri-state enum here. I don't see any reason callers of fsm_endid_get() would want to fetch into a fixed-size buffer of fewer elements than the number of endids an end state has. In all cases the caller can fsm_endid_count() to find out. --- include/fsm/fsm.h | 9 +--- src/libfsm/endids.c | 11 +++-- src/libfsm/minimise.c | 41 ++++++++--------- src/libfsm/minimise_test_oracle.c | 7 ++- src/libfsm/print/api.c | 13 +----- src/libfsm/print/dot.c | 10 ++--- src/libfsm/print/fsm.c | 13 +----- src/libfsm/print/ir.c | 5 +-- src/libfsm/print/json.c | 5 +-- src/libfsm/walk2.c | 24 ++++------ src/lx/ast.c | 12 +---- src/re/main.c | 44 +++++++++---------- tests/capture/captest.c | 8 ++-- tests/capture/capture4.c | 5 ++- tests/endids/endids0.c | 10 ++--- tests/endids/endids0_many_endids.c | 10 ++--- tests/endids/endids1_determinise.c | 8 ++-- .../endids/endids1_determinise_and_minimise.c | 12 ++--- tests/endids/endids2_union.c | 4 +- tests/endids/endids2_union_many_endids.c | 8 ++-- tests/endids/endids4.c | 8 ++-- tests/endids/endids5.c | 6 +-- tests/endids/endids6.c | 8 ++-- tests/endids/endids7.c | 8 ++-- tests/endids/endids7_with_duplicates.c | 8 ++-- tests/endids/endids8.c | 8 ++-- tests/endids/endids9.c | 4 +- tests/endids/utils.c | 6 +-- tests/gen/gtest.c | 4 +- tests/re_strings/testutil.c | 4 +- 30 files changed, 139 insertions(+), 184 deletions(-) diff --git a/include/fsm/fsm.h b/include/fsm/fsm.h index 81c472d3e..484541735 100644 --- a/include/fsm/fsm.h +++ b/include/fsm/fsm.h @@ -228,16 +228,11 @@ fsm_setendidstate(struct fsm *fsm, fsm_state_t end_state, fsm_end_id_t id); * If id_buf has enough cells to store all the end IDs (according * to id_buf_count) then they are written into id_buf[] and * *ids_written is set to the number of IDs. The end IDs in the - * buffer may appear in any order, but should not have duplicates. + * buffer may appear in any order, but will not have duplicates. * * Returns 0 if there is not enough space in id_buf for the * end IDs, or 1 if zero or more end IDs were returned. */ -enum fsm_getendids_res { - FSM_GETENDIDS_NOT_FOUND, - FSM_GETENDIDS_FOUND, - FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE = -1 -}; -enum fsm_getendids_res +int fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, size_t id_buf_count, fsm_end_id_t *id_buf, size_t *ids_written); diff --git a/src/libfsm/endids.c b/src/libfsm/endids.c index b2c1eeadf..80fcbfd8d 100644 --- a/src/libfsm/endids.c +++ b/src/libfsm/endids.c @@ -691,7 +691,7 @@ fsm_endid_count(const struct fsm *fsm, return 0; } -enum fsm_getendids_res +int fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, size_t id_buf_count, fsm_end_id_t *id_buf, size_t *ids_written) @@ -732,14 +732,14 @@ fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, fprintf(stderr, "fsm_endid_get: not found\n"); #endif *ids_written = 0; /* not found */ - return FSM_GETENDIDS_NOT_FOUND; + return 0; } else if (b->state == end_state) { size_t id_i; if (b->ids->count > id_buf_count) { #if LOG_ENDIDS > 2 fprintf(stderr, "fsm_endid_get: insufficient space\n"); #endif - return FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE; + return 0; /* insufficient space */ } for (id_i = 0; id_i < b->ids->count; id_i++) { #if LOG_ENDIDS > 2 @@ -750,7 +750,7 @@ fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, /* todo: could sort them here, if it matters. */ *ids_written = b->ids->count; - return FSM_GETENDIDS_FOUND; + return 1; } else { /* collision */ #if LOG_ENDIDS > 4 fprintf(stderr, "fsm_endid_get: collision\n"); @@ -760,7 +760,7 @@ fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, } assert(!"unreachable"); - return FSM_GETENDIDS_NOT_FOUND; + return 0; } struct carry_env { @@ -773,7 +773,6 @@ struct carry_env { static int carry_iter_cb(fsm_state_t state, fsm_end_id_t id, void *opaque) { - enum fsm_endid_set_res sres; struct carry_env *env = opaque; assert(env->tag == 'C'); diff --git a/src/libfsm/minimise.c b/src/libfsm/minimise.c index 294615292..a55de5d61 100644 --- a/src/libfsm/minimise.c +++ b/src/libfsm/minimise.c @@ -952,32 +952,33 @@ collect_end_ids(const struct fsm *fsm, fsm_state_t s, struct end_metadata_end *e) { e->count = fsm_endid_count(fsm, s); + if (e->count == 0) { + return 1; + } - if (e->count > 0) { - e->ids = f_malloc(fsm->opt->alloc, - e->count * sizeof(e->ids[0])); - if (e->ids == NULL) { - return 0; - } + e->ids = f_malloc(fsm->opt->alloc, + e->count * sizeof(e->ids[0])); + if (e->ids == NULL) { + return 0; + } - size_t written; - enum fsm_getendids_res res = fsm_endid_get(fsm, s, - e->count, e->ids, &written); - assert(res == FSM_GETENDIDS_FOUND); - assert(written == e->count); + size_t written; + int res = fsm_endid_get(fsm, s, e->count, e->ids, &written); + assert(res == 1); + assert(written == e->count); - /* sort, to make comparison easier later */ - qsort(e->ids, e->count, - sizeof(e->ids[0]), cmp_end_ids); + /* sort, to make comparison easier later */ + qsort(e->ids, e->count, + sizeof(e->ids[0]), cmp_end_ids); #if LOG_ECS - fprintf(stderr, "%d:", s); - for (size_t i = 0; i < written; i++) { - fprintf(stderr, " %u", e->ids[i]); - } - fprintf(stderr, "\n"); -#endif + fprintf(stderr, "%d:", s); + for (size_t i = 0; i < written; i++) { + fprintf(stderr, " %u", e->ids[i]); } + fprintf(stderr, "\n"); +#endif + return 1; } diff --git a/src/libfsm/minimise_test_oracle.c b/src/libfsm/minimise_test_oracle.c index 388cc3634..70209f865 100644 --- a/src/libfsm/minimise_test_oracle.c +++ b/src/libfsm/minimise_test_oracle.c @@ -177,10 +177,9 @@ fsm_minimise_test_oracle(const struct fsm *fsm) for (size_t i = 0; i < state_count; i++) { if (fsm_isend(fsm, i)) { size_t written_a; - enum fsm_getendids_res eres = fsm_endid_get(fsm, i, + int eres = fsm_endid_get(fsm, i, max_endid_count, endid_buf_a, &written_a); - assert(eres != FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE); - if (eres == FSM_GETENDIDS_NOT_FOUND) { + if (eres == 0) { assert(written_a == 0); } else { assert(written_a > 0); @@ -190,7 +189,7 @@ fsm_minimise_test_oracle(const struct fsm *fsm) size_t written_b; eres = fsm_endid_get(fsm, endid_group_leaders[eg_i], max_endid_count, endid_buf_b, &written_b); - assert(eres != FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE); + assert(eres != 0); if (written_b != written_a) { continue; } if (0 == memcmp(endid_buf_a, endid_buf_b, written_a * sizeof(endid_buf_a[0]))) { found = true; diff --git a/src/libfsm/print/api.c b/src/libfsm/print/api.c index dab9cc4df..69bf76eed 100644 --- a/src/libfsm/print/api.c +++ b/src/libfsm/print/api.c @@ -147,9 +147,9 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) count = fsm_endid_count(fsm, end); if (count > 0) { - enum fsm_getendids_res res; fsm_end_id_t *ids; size_t written; + int res; ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); if (ids == NULL) { @@ -158,16 +158,7 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) } res = fsm_endid_get(fsm, end, count, ids, &written); - switch (res) { - case FSM_GETENDIDS_NOT_FOUND: - case FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE: - assert(!"unreached"); - abort(); - - case FSM_GETENDIDS_FOUND: - break; - } - + assert(res == 1); assert(written == count); qsort(ids, count, sizeof *ids, comp_end_id); diff --git a/src/libfsm/print/dot.c b/src/libfsm/print/dot.c index 518009dd3..1f070b382 100644 --- a/src/libfsm/print/dot.c +++ b/src/libfsm/print/dot.c @@ -167,11 +167,12 @@ print_dotfrag(FILE *f, const struct fsm *fsm) s, s); } } else { - enum fsm_getendids_res res; size_t written; struct fsm_end_ids *ids = NULL; const size_t count = fsm_endid_count(fsm, s); if (count > 0) { + int res; + ids = f_malloc(fsm->opt->alloc, sizeof(*ids) + ((count - 1) * sizeof(ids->ids))); assert(ids != NULL); @@ -179,12 +180,9 @@ print_dotfrag(FILE *f, const struct fsm *fsm) return -1; } - res = fsm_endid_get(fsm, s, count, - ids->ids, &written); - if (res == FSM_GETENDIDS_FOUND) { + res = fsm_endid_get(fsm, s, count, ids->ids, &written); + if (res == 1) { ids->count = (unsigned)written; - } else { - assert(res == FSM_GETENDIDS_NOT_FOUND); } } diff --git a/src/libfsm/print/fsm.c b/src/libfsm/print/fsm.c index 928c6f83a..762bb1c30 100644 --- a/src/libfsm/print/fsm.c +++ b/src/libfsm/print/fsm.c @@ -303,9 +303,9 @@ fsm_print_fsm(FILE *f, const struct fsm *fsm) count = fsm_endid_count(fsm, s); if (count > 0) { - enum fsm_getendids_res res; fsm_end_id_t *ids; size_t written; + int res; ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); if (ids == NULL) { @@ -313,16 +313,7 @@ fsm_print_fsm(FILE *f, const struct fsm *fsm) } res = fsm_endid_get(fsm, s, count, ids, &written); - switch (res) { - case FSM_GETENDIDS_NOT_FOUND: - case FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE: - assert(!"unreached"); - abort(); - - case FSM_GETENDIDS_FOUND: - break; - } - + assert(res == 1); assert(written == count); qsort(ids, count, sizeof *ids, comp_end_id); diff --git a/src/libfsm/print/ir.c b/src/libfsm/print/ir.c index 7c53e3846..96e2f304e 100644 --- a/src/libfsm/print/ir.c +++ b/src/libfsm/print/ir.c @@ -469,7 +469,7 @@ make_ir(const struct fsm *fsm) ir->states[i].isend = fsm_isend(fsm, i); ir->states[i].end_ids = NULL; if (fsm_isend(fsm, i)) { - enum fsm_getendids_res res; + int res; size_t written; const size_t count = fsm_endid_count(fsm, i); struct fsm_end_ids *ids = f_malloc(fsm->opt->alloc, @@ -480,11 +480,10 @@ make_ir(const struct fsm *fsm) res = fsm_endid_get(fsm, i, count, ids->ids, &written); - if (res == FSM_GETENDIDS_FOUND) { + if (res == 1) { ids->count = (unsigned)written; ir->states[i].end_ids = ids; } else { - assert(res == FSM_GETENDIDS_NOT_FOUND); f_free(fsm->opt->alloc, ids); } } diff --git a/src/libfsm/print/json.c b/src/libfsm/print/json.c index 69615d287..e76da56e3 100644 --- a/src/libfsm/print/json.c +++ b/src/libfsm/print/json.c @@ -247,7 +247,7 @@ fsm_print_json(FILE *f, const struct fsm *fsm) fprintf(f, " \"endleaf\": [ "); for (i = 0; i < fsm->statecount; i++) { if (fsm_isend(fsm, i)) { - enum fsm_getendids_res res; + int res; size_t written; const size_t count = fsm_endid_count(fsm, i); struct fsm_end_ids *ids = f_malloc(fsm->opt->alloc, @@ -256,10 +256,9 @@ fsm_print_json(FILE *f, const struct fsm *fsm) res = fsm_endid_get(fsm, i, count, ids->ids, &written); - if (res == FSM_GETENDIDS_FOUND) { + if (res == 1) { ids->count = (unsigned)written; } else { - assert(res == FSM_GETENDIDS_NOT_FOUND); ids->count = 0; } diff --git a/src/libfsm/walk2.c b/src/libfsm/walk2.c index b21883abd..d57407d23 100644 --- a/src/libfsm/walk2.c +++ b/src/libfsm/walk2.c @@ -276,8 +276,8 @@ fsm_walk2_tuple_new(struct fsm_walk2_data *data, total_num_endids = num_a_endids + num_b_endids; if (total_num_endids > 0) { - fsm_end_id_t *endids= NULL; - enum fsm_getendids_res ret; + fsm_end_id_t *endids; + int ret; endids = calloc(total_num_endids, sizeof endids[0]); if (endids == NULL) { @@ -286,24 +286,16 @@ fsm_walk2_tuple_new(struct fsm_walk2_data *data, if (num_a_endids > 0) { size_t nwritten = 0; - ret = fsm_endid_get(fsm_a, a, num_a_endids, &endids[0], &nwritten); - - if (ret != FSM_GETENDIDS_FOUND || nwritten != num_a_endids) { - free(endids); - errno = (ret != FSM_GETENDIDS_FOUND) ? ENOENT : EINVAL; - return NULL; - } + ret = fsm_endid_get(fsm_a, a, num_a_endids, endids, &nwritten); + assert(ret == 1); + assert(nwritten == num_a_endids); } if (num_b_endids > 0) { size_t nwritten = 0; - ret = fsm_endid_get(fsm_b, b, num_b_endids, &endids[num_a_endids], &nwritten); - - if (ret != FSM_GETENDIDS_FOUND || nwritten != num_b_endids) { - free(endids); - errno = (ret != FSM_GETENDIDS_FOUND) ? ENOENT : EINVAL; - return NULL; - } + ret = fsm_endid_get(fsm_b, b, num_b_endids, endids + num_a_endids, &nwritten); + assert(ret == 1); + assert(nwritten == num_b_endids); } { diff --git a/src/lx/ast.c b/src/lx/ast.c index 4d088cd75..50d780855 100644 --- a/src/lx/ast.c +++ b/src/lx/ast.c @@ -237,9 +237,9 @@ ast_getendmapping(const struct fsm *fsm, fsm_state_t s) size_t id_count; fsm_end_id_t *id_buf_dynamic = NULL; fsm_end_id_t id_buf[ID_STACK_BUF_COUNT]; - enum fsm_getendids_res res; size_t written; struct ast_mapping *m; + int res; id_count = fsm_endid_count(fsm, s); if (id_count > ID_STACK_BUF_COUNT) { @@ -253,18 +253,10 @@ ast_getendmapping(const struct fsm *fsm, fsm_state_t s) s, id_count, id_buf_dynamic == NULL ? id_buf : id_buf_dynamic, &written); - if (res == FSM_GETENDIDS_NOT_FOUND) { - if (id_buf_dynamic != NULL) { - free(id_buf_dynamic); - } - return NULL; - } /* Should always have an appropriately sized buffer, * or fail to allocate above */ - assert(res != FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE); - - assert(res == FSM_GETENDIDS_FOUND); + assert(res == 1); assert(written == id_count); assert(written > 0); diff --git a/src/re/main.c b/src/re/main.c index 592e368c7..895b832ea 100644 --- a/src/re/main.c +++ b/src/re/main.c @@ -30,6 +30,8 @@ #include +#include + #include "libfsm/internal.h" /* XXX */ #include "libre/print.h" /* XXX */ #include "libre/class.h" /* XXX */ @@ -285,28 +287,31 @@ find_match_with_id(fsm_end_id_t id) static struct match * find_first_match_for_end_state(const struct fsm *dfa, fsm_state_t s) { -#define MAX_END_IDS 8 /* FIXME: what is reasonable here? */ - fsm_end_id_t end_id_buf[MAX_END_IDS]; - size_t end_ids_written; - enum fsm_getendids_res res; + fsm_end_id_t *ids, id; + size_t count; + size_t nwritten; + int res; if (!fsm_isend(dfa, s)) { return NULL; } - res = fsm_endid_get(dfa, s, MAX_END_IDS, - end_id_buf, &end_ids_written); - if (res == FSM_GETENDIDS_ERROR_INSUFFICIENT_SPACE) { - fprintf(stderr, "Error: Multiple end IDs\n"); - return NULL; - } else if (res == FSM_GETENDIDS_NOT_FOUND) { + count = fsm_endid_count(dfa, s); + if (count == 0) { return NULL; - } else { - assert(res == FSM_GETENDIDS_FOUND); - /* continues below */ } - return find_match_with_id(end_id_buf[0]); + ids = xmalloc(count * sizeof *ids); + + res = fsm_endid_get(dfa, s, count, ids, &nwritten); + assert(res == 1); + assert(nwritten == count); + + id = ids[0]; + + free(ids); + + return find_match_with_id(id); } static struct match * @@ -337,10 +342,7 @@ addmatch(struct match **head, int i, const char *s) } } - new = malloc(sizeof *new); - if (new == NULL) { - return NULL; - } + new = xmalloc(sizeof *new); new->i = i; new->s = s; @@ -360,11 +362,7 @@ add_matches_list(struct match *head) return; } - new = malloc(sizeof *new); - if (new == NULL) { - perror("allocating matches list"); - abort(); - } + new = xmalloc(sizeof *new); new->next = all_matches; new->head = head; diff --git a/tests/capture/captest.c b/tests/capture/captest.c index b2bc1243f..5a6384686 100644 --- a/tests/capture/captest.c +++ b/tests/capture/captest.c @@ -90,14 +90,14 @@ captest_run_single(const struct captest_single_fsm_test_info *info) { fsm_end_id_t id_buf[1] = { ~0 }; - enum fsm_getendids_res gres; + int gres; size_t written; if (1 != fsm_endid_count(fsm, end)) { FAIL("did not have exactly one end ID"); } gres = fsm_endid_get(fsm, end, 1, id_buf, &written); - if (gres != FSM_GETENDIDS_FOUND) { + if (gres != 1) { FAIL("failed to get end IDs"); } @@ -182,7 +182,7 @@ captest_check_single_end_id(const struct fsm *fsm, fsm_state_t end_state, unsigned expected_end_id, const char **msg) { fsm_end_id_t id_buf[1] = { ~0 }; - enum fsm_getendids_res gres; + int gres; size_t written; const char *unused; @@ -196,7 +196,7 @@ captest_check_single_end_id(const struct fsm *fsm, fsm_state_t end_state, } gres = fsm_endid_get(fsm, end_state, 1, id_buf, &written); - if (gres != FSM_GETENDIDS_FOUND) { + if (gres != 1) { *msg = "failed to get end IDs"; return 0; } diff --git a/tests/capture/capture4.c b/tests/capture/capture4.c index 1759afb05..4394b637f 100644 --- a/tests/capture/capture4.c +++ b/tests/capture/capture4.c @@ -220,11 +220,12 @@ check(const struct fsm *fsm, const char *string, assert(captures[cb_b].pos[1] == pb_1); { - enum fsm_getendids_res gres; + int gres; fsm_end_id_t id_buf[2]; size_t written; + gres = fsm_endid_get(fsm, end, 2, id_buf, &written); - if (gres != FSM_GETENDIDS_FOUND) { + if (gres != 1) { assert(!"fsm_getendids failed"); } diff --git a/tests/endids/endids0.c b/tests/endids/endids0.c index 4dd4b4ebe..69df62775 100644 --- a/tests/endids/endids0.c +++ b/tests/endids/endids0.c @@ -45,11 +45,11 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endid = 0; size_t nwritten; - enum fsm_getendids_res ret; + int ret; assert( fsm_endid_count(fsm, state_ind) == 1); - nwritten = 0; + nwritten = 0; ret = fsm_endid_get( fsm, state_ind, @@ -57,9 +57,9 @@ int main(void) &endid, &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == 1); - assert( endid == 1 ); + assert(ret == 1); + assert(nwritten == 1); + assert(endid == 1); nend++; } diff --git a/tests/endids/endids0_many_endids.c b/tests/endids/endids0_many_endids.c index 834702bdc..f451b9acc 100644 --- a/tests/endids/endids0_many_endids.c +++ b/tests/endids/endids0_many_endids.c @@ -86,7 +86,7 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[sizeof all_end_ids / sizeof all_end_ids[0]]; size_t i, nwritten; - enum fsm_getendids_res ret; + int ret; memset(&endids[0], 0, sizeof endids); @@ -100,11 +100,11 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == sizeof all_end_ids / sizeof all_end_ids[0]); + assert(ret == 1); + assert(nwritten == sizeof all_end_ids / sizeof all_end_ids[0]); - /* sort endids and compare */ - qsort(&endids[0], nwritten, sizeof endids[0], cmp_endids); + /* sort endids and compare */ + qsort(&endids[0], nwritten, sizeof endids[0], cmp_endids); for (i=0; i < nwritten; i++) { assert(endids[i] == sorted_all_end_ids[i]); } diff --git a/tests/endids/endids1_determinise.c b/tests/endids/endids1_determinise.c index 75a89db0d..5d61e1db4 100644 --- a/tests/endids/endids1_determinise.c +++ b/tests/endids/endids1_determinise.c @@ -41,7 +41,7 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endid = 0; size_t nwritten; - enum fsm_getendids_res ret; + int ret; assert( fsm_endid_count(fsm, state_ind) == 1); @@ -53,9 +53,9 @@ int main(void) &endid, &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == 1); - assert( endid == 1 ); + assert(ret == 1); + assert(nwritten == 1); + assert( endid == 1 ); } } diff --git a/tests/endids/endids1_determinise_and_minimise.c b/tests/endids/endids1_determinise_and_minimise.c index d8df93543..91adf3f44 100644 --- a/tests/endids/endids1_determinise_and_minimise.c +++ b/tests/endids/endids1_determinise_and_minimise.c @@ -46,11 +46,11 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endid = 0; size_t nwritten; - enum fsm_getendids_res ret; + int ret; - assert( fsm_endid_count(fsm, state_ind) == 1); + assert(fsm_endid_count(fsm, state_ind) == 1); - nwritten = 0; + nwritten = 0; ret = fsm_endid_get( fsm, state_ind, @@ -58,9 +58,9 @@ int main(void) &endid, &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); - assert(nwritten == 1); - assert( endid == 1 ); + assert(ret == 1); + assert(nwritten == 1); + assert( endid == 1 ); } } diff --git a/tests/endids/endids2_union.c b/tests/endids/endids2_union.c index a81bce01c..905c4b324 100644 --- a/tests/endids/endids2_union.c +++ b/tests/endids/endids2_union.c @@ -57,7 +57,7 @@ int main(void) fsm_end_id_t endids[2] = {0,0}; size_t nwritten; size_t count; - enum fsm_getendids_res ret; + int ret; nwritten = 0; count = fsm_endid_count(comb, state_ind); @@ -72,7 +72,7 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); if (nwritten == 1) { diff --git a/tests/endids/endids2_union_many_endids.c b/tests/endids/endids2_union_many_endids.c index d7beb8777..e292be47b 100644 --- a/tests/endids/endids2_union_many_endids.c +++ b/tests/endids/endids2_union_many_endids.c @@ -184,7 +184,7 @@ int main(void) int tested_pattern[NUM_PATTERNS]; fsm_end_id_t endids[NUM_ENDIDS_TOTAL]; size_t nwritten, count, j; - enum fsm_getendids_res ret; + int ret; memset(&endids[0], 0, sizeof endids); @@ -200,7 +200,7 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); memset(&tested_pattern[0], 0, sizeof tested_pattern); @@ -251,7 +251,7 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[NUM_ENDIDS_TOTAL]; size_t nwritten, count; - enum fsm_getendids_res ret; + int ret; memset(&endids[0], 0, sizeof endids); @@ -267,7 +267,7 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); } } diff --git a/tests/endids/endids4.c b/tests/endids/endids4.c index c4b7da823..1b022aad4 100644 --- a/tests/endids/endids4.c +++ b/tests/endids/endids4.c @@ -69,7 +69,7 @@ int main(void) fsm_end_id_t endids[2] = {0,0}; size_t nwritten; size_t count; - enum fsm_getendids_res ret; + int ret; nwritten = 0; count = fsm_endid_count(comb, state_ind); @@ -85,11 +85,11 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); - qsort(&endids[0], count, sizeof endids[0], cmp_endids); - assert(endids[0] == 1 && endids[1] == 2); + qsort(&endids[0], count, sizeof endids[0], cmp_endids); + assert(endids[0] == 1 && endids[1] == 2); } } diff --git a/tests/endids/endids5.c b/tests/endids/endids5.c index 91e39b5eb..3639ab0ac 100644 --- a/tests/endids/endids5.c +++ b/tests/endids/endids5.c @@ -70,7 +70,7 @@ int main(void) fsm_end_id_t endids[2] = {0,0}; size_t nwritten; size_t count; - enum fsm_getendids_res ret; + int ret; nwritten = 0; count = fsm_endid_count(comb, state_ind); @@ -86,10 +86,10 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); - assert(endids[0] == 1); + assert(endids[0] == 1); } } diff --git a/tests/endids/endids6.c b/tests/endids/endids6.c index 2179d0a03..657a314dc 100644 --- a/tests/endids/endids6.c +++ b/tests/endids/endids6.c @@ -94,7 +94,7 @@ int main(void) fsm_end_id_t endids[2] = {0,0}; size_t nwritten; size_t count; - enum fsm_getendids_res ret; + int ret; nwritten = 0; count = fsm_endid_count(fsm, state_ind); @@ -108,7 +108,7 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); info[ninfo].state = state_ind; @@ -138,7 +138,7 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[2] = {0,0}; size_t nwritten, count, ind; - enum fsm_getendids_res ret; + int ret; assert( state_ind == info[info_ind].state ); @@ -155,7 +155,7 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); if (nwritten > 1) { diff --git a/tests/endids/endids7.c b/tests/endids/endids7.c index c695136cc..488e1e3e0 100644 --- a/tests/endids/endids7.c +++ b/tests/endids/endids7.c @@ -106,7 +106,7 @@ int main(void) fsm_end_id_t endids[2] = {0,0}; size_t nwritten; size_t count; - enum fsm_getendids_res ret; + int ret; nwritten = 0; count = fsm_endid_count(fsm, state_ind); @@ -120,7 +120,7 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); info[ninfo].state = state_ind; @@ -151,7 +151,7 @@ int main(void) fsm_end_id_t endid = 0; fsm_end_id_t expected; size_t nwritten, count; - enum fsm_getendids_res ret; + int ret; assert( state_ind == info[info_ind].state ); @@ -166,7 +166,7 @@ int main(void) &endid, &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); if (info[info_ind].count == 2) { diff --git a/tests/endids/endids7_with_duplicates.c b/tests/endids/endids7_with_duplicates.c index 3da80d9bc..b4d0701d3 100644 --- a/tests/endids/endids7_with_duplicates.c +++ b/tests/endids/endids7_with_duplicates.c @@ -110,7 +110,7 @@ int main(void) fsm_end_id_t endids[2] = {0,0}; size_t nwritten; size_t count; - enum fsm_getendids_res ret; + int ret; nwritten = 0; count = fsm_endid_count(fsm, state_ind); @@ -124,7 +124,7 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); info[ninfo].state = state_ind; @@ -155,7 +155,7 @@ int main(void) fsm_end_id_t endid = 0; fsm_end_id_t expected; size_t nwritten, count; - enum fsm_getendids_res ret; + int ret; assert( state_ind == info[info_ind].state ); @@ -170,7 +170,7 @@ int main(void) &endid, &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); if (info[info_ind].count == 2) { diff --git a/tests/endids/endids8.c b/tests/endids/endids8.c index 0be5c244d..0ef6e024b 100644 --- a/tests/endids/endids8.c +++ b/tests/endids/endids8.c @@ -75,7 +75,7 @@ int main(void) fsm_end_id_t endids[3] = {0,0,0}; size_t nwritten; size_t count; - enum fsm_getendids_res ret; + int ret; nwritten = 0; count = fsm_endid_count(comb, state_ind); @@ -91,11 +91,11 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); - qsort(&endids[0], count, sizeof endids[0], cmp_endids); - assert(endids[0] == 1 && endids[1] == 2 && endids[2] == 4); + qsort(&endids[0], count, sizeof endids[0], cmp_endids); + assert(endids[0] == 1 && endids[1] == 2 && endids[2] == 4); } } diff --git a/tests/endids/endids9.c b/tests/endids/endids9.c index c6c467328..ef15efe13 100644 --- a/tests/endids/endids9.c +++ b/tests/endids/endids9.c @@ -74,7 +74,7 @@ int main(void) fsm_end_id_t endids[2] = {0,0}; size_t nwritten; size_t count; - enum fsm_getendids_res ret; + int ret; nwritten = 0; count = fsm_endid_count(fsm, state_ind); @@ -88,7 +88,7 @@ int main(void) &endids[0], &nwritten); - assert(ret == FSM_GETENDIDS_FOUND); + assert(ret == 1); assert(nwritten == count); info[ninfo].state = state_ind; diff --git a/tests/endids/utils.c b/tests/endids/utils.c index b6dd23042..7457fc70e 100644 --- a/tests/endids/utils.c +++ b/tests/endids/utils.c @@ -19,7 +19,7 @@ match_string(const struct fsm *fsm, const char *s, fsm_state_t *end_ptr, fsm_end count = fsm_endid_count(fsm, end); if (count > 0) { - enum fsm_getendids_res ret; + int ret; size_t nwritten = 0; fsm_end_id_t *endids = calloc(count, sizeof *endids); @@ -28,9 +28,9 @@ match_string(const struct fsm *fsm, const char *s, fsm_state_t *end_ptr, fsm_end } ret = fsm_endid_get(fsm, end, count, endids, &nwritten); - if (ret != FSM_GETENDIDS_FOUND) { + if (ret == 0) { free(endids); - errno = (ret == FSM_GETENDIDS_NOT_FOUND) ? EINVAL : ENOMEM; + errno = EINVAL; return -1; } diff --git a/tests/gen/gtest.c b/tests/gen/gtest.c index c99b2eeac..aff46ba3a 100644 --- a/tests/gen/gtest.c +++ b/tests/gen/gtest.c @@ -60,10 +60,10 @@ gtest_matches_cb(const struct fsm *fsm, #define ID_BUF_COUNT 1 fsm_end_id_t id_buf[ID_BUF_COUNT]; size_t written; - enum fsm_getendids_res gres = fsm_endid_get(fsm, + int gres = fsm_endid_get(fsm, end_state, ID_BUF_COUNT, id_buf, &written); - if (gres != FSM_GETENDIDS_FOUND) { + if (gres != 1) { fprintf(stderr, "ERROR: fsm_endid_get: returned %d\n", gres); diff --git a/tests/re_strings/testutil.c b/tests/re_strings/testutil.c index 5b366c0ce..197415492 100644 --- a/tests/re_strings/testutil.c +++ b/tests/re_strings/testutil.c @@ -48,9 +48,9 @@ run_test(const char **strings) assert(res > 0); /* match */ size_t written; - enum fsm_getendids_res eres = fsm_endid_get(fsm, end, + int eres = fsm_endid_get(fsm, end, MAX_INPUTS, id_buf, &written); - assert(eres == FSM_GETENDIDS_FOUND); + assert(eres == 1); bool found = false; for (size_t i = 0; i < written; i++) { if (id_buf[i] == id) { From c27a1e44dedbb346e6e26565dc41347304f40de5 Mon Sep 17 00:00:00 2001 From: Kate F Date: Wed, 12 Jun 2024 05:56:33 -0700 Subject: [PATCH 17/28] Missing error handling. --- src/libfsm/print/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libfsm/print/api.c b/src/libfsm/print/api.c index 69bf76eed..4c5b31cc8 100644 --- a/src/libfsm/print/api.c +++ b/src/libfsm/print/api.c @@ -165,7 +165,7 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) fprintf(f, "\tif (fsm_isend(fsm, s[%u])) {\n", end); for (size_t id = 0; id < count; id++) { - fprintf(f, "\t\tfsm_setendidstate(fsm, s[%u], %zu);\n", end, id); + fprintf(f, "\t\tif (!fsm_setendidstate(fsm, s[%u], %zu)) { return 0; }\n", end, id); } fprintf(f, "\t}\n"); fprintf(f, "\n"); From d981fdd0cc35e805894b13edbe32c1974228ecef Mon Sep 17 00:00:00 2001 From: Kate F Date: Wed, 12 Jun 2024 06:28:58 -0700 Subject: [PATCH 18/28] No need for the tri-state enum here. --- include/fsm/fsm.h | 2 +- src/libfsm/clone.c | 2 +- src/libfsm/consolidate.c | 9 ++------ src/libfsm/endids.c | 44 ++++++++++++++++------------------------ src/libfsm/endids.h | 14 ++----------- src/libfsm/epsilons.c | 2 +- src/libfsm/libfsm.syms | 2 +- src/libfsm/merge.c | 9 ++------ src/libfsm/parser.act | 2 +- src/libfsm/parser.c | 2 +- src/libfsm/print/api.c | 2 +- src/libfsm/walk2.c | 28 +++++++++++-------------- src/libre/ac.c | 3 +-- 13 files changed, 43 insertions(+), 78 deletions(-) diff --git a/include/fsm/fsm.h b/include/fsm/fsm.h index 484541735..02f04c951 100644 --- a/include/fsm/fsm.h +++ b/include/fsm/fsm.h @@ -222,7 +222,7 @@ fsm_setendid(struct fsm *fsm, fsm_end_id_t id); * Returns 1 on success, 0 on error. * */ int -fsm_setendidstate(struct fsm *fsm, fsm_state_t end_state, fsm_end_id_t id); +fsm_endid_set(struct fsm *fsm, fsm_state_t end_state, fsm_end_id_t id); /* Get the end IDs associated with an end state, if any. * If id_buf has enough cells to store all the end IDs (according diff --git a/src/libfsm/clone.c b/src/libfsm/clone.c index 587976e94..69aedaa63 100644 --- a/src/libfsm/clone.c +++ b/src/libfsm/clone.c @@ -133,7 +133,7 @@ copy_end_ids_cb(fsm_state_t state, const fsm_end_id_t id, void *opaque) fprintf(stderr, "clone[%d] <- %d\n", state, id); #endif - if (!fsm_setendidstate(env->dst, state, id)) { + if (!fsm_endid_set(env->dst, state, id)) { env->ok = 0; return 0; } diff --git a/src/libfsm/consolidate.c b/src/libfsm/consolidate.c index 4518d3926..a000a4c7b 100644 --- a/src/libfsm/consolidate.c +++ b/src/libfsm/consolidate.c @@ -231,19 +231,14 @@ static int consolidate_end_ids_cb(fsm_state_t state, const fsm_end_id_t *ids, size_t num_ids, void *opaque) { struct consolidate_end_ids_env *env = opaque; - enum fsm_endid_set_res sres; fsm_state_t s; assert(env->tag == 'C'); assert(state < env->mapping_count); s = env->mapping[state]; - sres = fsm_endid_set_bulk(env->dst, s, num_ids, ids, FSM_ENDID_BULK_APPEND); - if (sres == FSM_ENDID_SET_ERROR_ALLOC_FAIL) { - return 0; - } - - return 1; + return fsm_endid_set_bulk(env->dst, s, + num_ids, ids, FSM_ENDID_BULK_APPEND); } static int diff --git a/src/libfsm/endids.c b/src/libfsm/endids.c index 80fcbfd8d..fb63baf66 100644 --- a/src/libfsm/endids.c +++ b/src/libfsm/endids.c @@ -73,7 +73,7 @@ fsm_setendid(struct fsm *fsm, fsm_end_id_t id) fprintf(stderr, "fsm_setendid: setting id %u on state %d\n", id, i); #endif - if (!fsm_setendidstate(fsm, i, id)) { + if (!fsm_endid_set(fsm, i, id)) { return 0; } } @@ -82,16 +82,6 @@ fsm_setendid(struct fsm *fsm, fsm_end_id_t id) return 1; } -int -fsm_setendidstate(struct fsm *fsm, fsm_state_t end_state, fsm_end_id_t id) -{ - enum fsm_endid_set_res sres = fsm_endid_set(fsm, end_state, id); - if (sres == FSM_ENDID_SET_ERROR_ALLOC_FAIL) { - return 0; - } - return 1; -} - int fsm_endid_init(struct fsm *fsm) { @@ -377,7 +367,7 @@ allocate_ids(const struct fsm *fsm, struct end_info_ids *prev, size_t n) return f_realloc(fsm->opt->alloc, prev, id_alloc_size); } -enum fsm_endid_set_res +int fsm_endid_set(struct fsm *fsm, fsm_state_t state, fsm_end_id_t id) { @@ -389,7 +379,7 @@ fsm_endid_set(struct fsm *fsm, struct endid_info_bucket *b = endid_find_bucket(fsm, state); if (b == NULL) { - return FSM_ENDID_SET_ERROR_ALLOC_FAIL; + return 0; } LOG_2("fsm_endid_set: state %d, bucket %p\n", state, (void *)b); @@ -399,7 +389,7 @@ fsm_endid_set(struct fsm *fsm, ids = allocate_ids(fsm, NULL, DEF_BUCKET_ID_COUNT); if (ids == NULL) { - return FSM_ENDID_SET_ERROR_ALLOC_FAIL; + return 0; } ids->ids[0] = id; @@ -410,7 +400,7 @@ fsm_endid_set(struct fsm *fsm, b->ids = ids; ei->buckets_used++; - return FSM_ENDID_SET_ADDED; + return 1; } else if (b->state == state) { size_t ind; @@ -427,7 +417,7 @@ fsm_endid_set(struct fsm *fsm, nids = allocate_ids(fsm, b->ids, nceil); if (nids == NULL) { - return FSM_ENDID_SET_ERROR_ALLOC_FAIL; /* alloc fail */ + return 0; /* alloc fail */ } nids->ceil = nceil; b->ids = nids; @@ -448,7 +438,7 @@ fsm_endid_set(struct fsm *fsm, } else if (b->ids->ids[ind] == id) { /* already present, our work is done! */ LOG_2("fsm_endid_set: already present, skipping\n"); - return FSM_ENDID_SET_ALREADY_PRESENT; + return 1; } else { /* need to shift items up to make room for id */ memmove(&b->ids->ids[ind+1], &b->ids->ids[ind], @@ -464,10 +454,10 @@ fsm_endid_set(struct fsm *fsm, (void)dump_buckets; DBG_3(dump_buckets("set_dump", ei)); - return FSM_ENDID_SET_ADDED; + return 1; } else { assert(!"unreachable: endid_find_bucket failed"); - return FSM_ENDID_SET_ERROR_ALLOC_FAIL; + return 0; } } @@ -488,7 +478,7 @@ cmp_endids(const void *pa, const void *pb) return 0; } -enum fsm_endid_set_res +int fsm_endid_set_bulk(struct fsm *fsm, fsm_state_t state, size_t num_ids, const fsm_end_id_t *ids, enum fsm_endid_bulk_op op) { @@ -502,7 +492,7 @@ fsm_endid_set_bulk(struct fsm *fsm, b = endid_find_bucket(fsm, state); if (b == NULL) { - return FSM_ENDID_SET_ERROR_ALLOC_FAIL; + return 0; } if (b->state == state) { @@ -525,12 +515,12 @@ fsm_endid_set_bulk(struct fsm *fsm, if (new_ceil < total_count) { /* num_ids is too large? */ - return FSM_ENDID_SET_ERROR_ALLOC_FAIL; + return 0; } new_ids = allocate_ids(fsm, b->ids, new_ceil); if (new_ids == NULL) { - return FSM_ENDID_SET_ERROR_ALLOC_FAIL; + return 0; } b->ids = new_ids; @@ -560,12 +550,12 @@ fsm_endid_set_bulk(struct fsm *fsm, if (n < num_ids) { /* num_ids is too large? */ - return FSM_ENDID_SET_ERROR_ALLOC_FAIL; + return 0; } new_ids = allocate_ids(fsm, NULL, n); if (new_ids == NULL) { - return FSM_ENDID_SET_ERROR_ALLOC_FAIL; + return 0; } memcpy(&new_ids->ids[0], &ids[0], num_ids * sizeof ids[0]); @@ -602,7 +592,7 @@ fsm_endid_set_bulk(struct fsm *fsm, b->ids->count = j; } - return FSM_ENDID_SET_ADDED; + return 1; } int @@ -778,7 +768,7 @@ carry_iter_cb(fsm_state_t state, fsm_end_id_t id, void *opaque) (void)state; - if (!fsm_setendidstate(env->dst, env->dst_state, id)) { + if (!fsm_endid_set(env->dst, env->dst_state, id)) { env->ok = 0; return 0; } diff --git a/src/libfsm/endids.h b/src/libfsm/endids.h index c4b3184b5..a5697f10b 100644 --- a/src/libfsm/endids.h +++ b/src/libfsm/endids.h @@ -10,15 +10,6 @@ fsm_endid_init(struct fsm *fsm); void fsm_endid_free(struct fsm *fsm); -enum fsm_endid_set_res { - FSM_ENDID_SET_ADDED, - FSM_ENDID_SET_ALREADY_PRESENT, - FSM_ENDID_SET_ERROR_ALLOC_FAIL = -1 -}; -enum fsm_endid_set_res -fsm_endid_set(struct fsm *fsm, - fsm_state_t state, fsm_end_id_t id); - /* Sets end ids in a bulk operation. * * Repeatedly calling fsm_endid_set will end up with quadratic behavior. This @@ -34,14 +25,13 @@ fsm_endid_set(struct fsm *fsm, * * The caller maintains ownership of ids, and must free it if needed. * - * Only FSM_ENDID_SET_ADDED and FSM_ENDID_SET_ERROR_ALLOC_FAIL - * are returned. + * Returns 1 on success, 0 on failure. */ enum fsm_endid_bulk_op { FSM_ENDID_BULK_REPLACE = 0, FSM_ENDID_BULK_APPEND = 1, }; -enum fsm_endid_set_res +int fsm_endid_set_bulk(struct fsm *fsm, fsm_state_t state, size_t num_ids, const fsm_end_id_t *ids, enum fsm_endid_bulk_op op); diff --git a/src/libfsm/epsilons.c b/src/libfsm/epsilons.c index 82dd6cfa4..f8bb1d9d3 100644 --- a/src/libfsm/epsilons.c +++ b/src/libfsm/epsilons.c @@ -405,7 +405,7 @@ carry_endids(struct fsm *fsm, struct state_set *states, /* add them */ for (i = 0; i < env.count; i++) { - if (!fsm_setendidstate(fsm, dst_state, env.ids[i])) { + if (!fsm_endid_set(fsm, dst_state, env.ids[i])) { env.ok = 0; goto cleanup; } diff --git a/src/libfsm/libfsm.syms b/src/libfsm/libfsm.syms index 0e40ae884..2801f3703 100644 --- a/src/libfsm/libfsm.syms +++ b/src/libfsm/libfsm.syms @@ -88,10 +88,10 @@ fsm_setend fsm_endid_count fsm_endid_get +fsm_endid_set fsm_setendid fsm_mapendids fsm_increndids -fsm_setendidstate fsm_countedges fsm_countstates diff --git a/src/libfsm/merge.c b/src/libfsm/merge.c index fd4d35ee5..69834a5bd 100644 --- a/src/libfsm/merge.c +++ b/src/libfsm/merge.c @@ -163,7 +163,6 @@ struct copy_end_ids_env { static int copy_end_ids_cb(fsm_state_t state, const fsm_end_id_t *ids, size_t num_ids, void *opaque) { - enum fsm_endid_set_res sres; struct copy_end_ids_env *env = opaque; assert(env->tag == 'M'); @@ -172,12 +171,8 @@ copy_end_ids_cb(fsm_state_t state, const fsm_end_id_t *ids, size_t num_ids, void state + env->base_src, id); #endif - sres = fsm_endid_set_bulk(env->dst, state + env->base_src, num_ids, ids, FSM_ENDID_BULK_REPLACE); - if (sres == FSM_ENDID_SET_ERROR_ALLOC_FAIL) { - return 0; - } - - return 1; + return fsm_endid_set_bulk(env->dst, state + env->base_src, + num_ids, ids, FSM_ENDID_BULK_REPLACE); } static int diff --git a/src/libfsm/parser.act b/src/libfsm/parser.act index 30caa03bd..71ee0a89c 100644 --- a/src/libfsm/parser.act +++ b/src/libfsm/parser.act @@ -340,7 +340,7 @@ @}; : (s :state, id :endid) -> () = @{ - if (!fsm_setendidstate(fsm, @s, @id)) { + if (!fsm_endid_set(fsm, @s, @id)) { @!; } @}; diff --git a/src/libfsm/parser.c b/src/libfsm/parser.c index 0ae7ee763..442449a44 100644 --- a/src/libfsm/parser.c +++ b/src/libfsm/parser.c @@ -1335,7 +1335,7 @@ p_xend_C_Cend_Hid(fsm fsm, lex_state lex_state, act_state act_state, state ZIs) { #line 343 "src/libfsm/parser.act" - if (!fsm_setendidstate(fsm, (ZIs), (ZIid))) { + if (!fsm_endid_set(fsm, (ZIs), (ZIid))) { goto ZL1; } diff --git a/src/libfsm/print/api.c b/src/libfsm/print/api.c index 4c5b31cc8..6b33d045f 100644 --- a/src/libfsm/print/api.c +++ b/src/libfsm/print/api.c @@ -165,7 +165,7 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) fprintf(f, "\tif (fsm_isend(fsm, s[%u])) {\n", end); for (size_t id = 0; id < count; id++) { - fprintf(f, "\t\tif (!fsm_setendidstate(fsm, s[%u], %zu)) { return 0; }\n", end, id); + fprintf(f, "\t\tif (!fsm_endid_set(fsm, s[%u], %zu)) { return 0; }\n", end, id); } fprintf(f, "\t}\n"); fprintf(f, "\n"); diff --git a/src/libfsm/walk2.c b/src/libfsm/walk2.c index d57407d23..9320dbafd 100644 --- a/src/libfsm/walk2.c +++ b/src/libfsm/walk2.c @@ -298,24 +298,20 @@ fsm_walk2_tuple_new(struct fsm_walk2_data *data, assert(nwritten == num_b_endids); } - { - enum fsm_endid_set_res ret; - - ret = fsm_endid_set_bulk( - data->new, - p->comb, - total_num_endids, - &endids[0], - FSM_ENDID_BULK_REPLACE); - if (ret == FSM_ENDID_SET_ERROR_ALLOC_FAIL) { - int errsv = errno; - free(endids); - errno = errsv; - return NULL; - } - } + ret = fsm_endid_set_bulk( + data->new, + p->comb, + total_num_endids, + &endids[0], + FSM_ENDID_BULK_REPLACE); free(endids); + + if (!ret) { + int errsv = errno; + errno = errsv; + return NULL; + } } } diff --git a/src/libre/ac.c b/src/libre/ac.c index efe13df36..e9412602e 100644 --- a/src/libre/ac.c +++ b/src/libre/ac.c @@ -332,8 +332,7 @@ trie_to_fsm_state(struct trie_state *ts, struct fsm *fsm, fsm_state_t state; state_set_reset(ts->endids, &si); while (state_set_next(&si, &state)) { - fsm_end_id_t endid = (fsm_end_id_t)state; - if (!fsm_setendidstate(fsm, st, endid)) { + if (!fsm_endid_set(fsm, st, (fsm_end_id_t) state)) { return 0; } } From 05b246718c2ee56b874a135559b281b2f944e28c Mon Sep 17 00:00:00 2001 From: Kate F Date: Wed, 12 Jun 2024 07:48:09 -0700 Subject: [PATCH 19/28] No need for the static buffer here. --- src/lx/ast.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/lx/ast.c b/src/lx/ast.c index 50d780855..7dd1ad72c 100644 --- a/src/lx/ast.c +++ b/src/lx/ast.c @@ -9,8 +9,10 @@ #include #include #include +#include #include +#include #include @@ -233,42 +235,42 @@ ast_getendmappingbyendid(fsm_end_id_t id) struct ast_mapping * ast_getendmapping(const struct fsm *fsm, fsm_state_t s) { - #define ID_STACK_BUF_COUNT 4 - size_t id_count; - fsm_end_id_t *id_buf_dynamic = NULL; - fsm_end_id_t id_buf[ID_STACK_BUF_COUNT]; - size_t written; + fsm_end_id_t *ids; + size_t count, written; struct ast_mapping *m; int res; - id_count = fsm_endid_count(fsm, s); - if (id_count > ID_STACK_BUF_COUNT) { - id_buf_dynamic = malloc(id_count * sizeof(id_buf_dynamic[0])); - if (id_buf_dynamic == NULL) { - return NULL; - } + if (!fsm_isend(fsm, s)) { + errno = EINVAL; + return NULL; + } + + count = fsm_endid_count(fsm, s); + if (count == 0) { + errno = EINVAL; + return NULL; } - res = fsm_endid_get(fsm, - s, id_count, - id_buf_dynamic == NULL ? id_buf : id_buf_dynamic, - &written); + ids = malloc(count * sizeof *ids); + if (ids == NULL) { + return NULL; + } + + res = fsm_endid_get(fsm, s, count, ids, &written); - /* Should always have an appropriately sized buffer, - * or fail to allocate above */ assert(res == 1); - assert(written == id_count); + assert(written == count); assert(written > 0); - m = ast_getendmappingbyendid(id_buf[0]); + m = ast_getendmappingbyendid(ids[0]); if (LOG()) { fprintf(stderr, "ast_getendmapping: got mapping %p mappings[%d]\n", - (void *)m, id_buf[0]); + (void *) m, ids[0]); } - if (id_buf_dynamic != NULL) { - free(id_buf_dynamic); - } + free(ids); + return m; } + From 1c88c759249471a712eabcd9cf7d8e780605f3ba Mon Sep 17 00:00:00 2001 From: Kate F Date: Fri, 14 Jun 2024 13:03:23 +0100 Subject: [PATCH 20/28] Statements after declarations for generated code. This keeps the generated code C89-compliant. --- src/libfsm/print/c.c | 9 ++++++--- src/libfsm/print/vmc.c | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/libfsm/print/c.c b/src/libfsm/print/c.c index dbca1d3fa..fcc036633 100644 --- a/src/libfsm/print/c.c +++ b/src/libfsm/print/c.c @@ -427,31 +427,34 @@ fsm_print_c_complete(FILE *f, const struct ir *ir, case FSM_IO_GETC: fprintf(f, "(int (*fsm_getc)(void *opaque), void *opaque)\n"); fprintf(f, "{\n"); - fprintf(f, "\t(void)opaque;\n"); if (ir->n > 0) { fprintf(f, "\tint c;\n"); fprintf(f, "\n"); } + fprintf(f, "\t(void) opaque;\n"); + fprintf(f, "\n"); break; case FSM_IO_STR: fprintf(f, "(const char *s, void *opaque)\n"); fprintf(f, "{\n"); - fprintf(f, "\t(void)opaque;\n"); if (ir->n > 0) { fprintf(f, "\tconst char *p;\n"); fprintf(f, "\n"); } + fprintf(f, "\t(void) opaque;\n"); + fprintf(f, "\n"); break; case FSM_IO_PAIR: fprintf(f, "(const char *b, const char *e, void *opaque)\n"); fprintf(f, "{\n"); - fprintf(f, "\t(void)opaque;\n"); if (ir->n > 0) { fprintf(f, "\tconst char *p;\n"); fprintf(f, "\n"); } + fprintf(f, "\t(void) opaque;\n"); + fprintf(f, "\n"); break; } diff --git a/src/libfsm/print/vmc.c b/src/libfsm/print/vmc.c index 911619a7f..1e60a9b50 100644 --- a/src/libfsm/print/vmc.c +++ b/src/libfsm/print/vmc.c @@ -474,13 +474,15 @@ fsm_print_c_complete(FILE *f, const struct ir *ir, const struct fsm_options *opt case FSM_IO_STR: fprintf(f, "(const char *s, void *opaque)\n"); fprintf(f, "{\n"); - fprintf(f, "\t(void)opaque;\n"); + fprintf(f, "\t(void) opaque;\n"); + fprintf(f, "\n"); break; case FSM_IO_PAIR: fprintf(f, "(const char *b, const char *e, void *opaque)\n"); fprintf(f, "{\n"); - fprintf(f, "\t(void)opaque;\n"); + fprintf(f, "\t(void) opaque;\n"); + fprintf(f, "\n"); break; } From 0620f5528f67b889be1d091b60fa56d36b2e08ce Mon Sep 17 00:00:00 2001 From: Kate F Date: Fri, 14 Jun 2024 15:42:38 +0100 Subject: [PATCH 21/28] No need to mark unused here, this opaque pointer is passed to the getc callback. --- src/libfsm/print/c.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libfsm/print/c.c b/src/libfsm/print/c.c index fcc036633..5de4ce4ee 100644 --- a/src/libfsm/print/c.c +++ b/src/libfsm/print/c.c @@ -431,8 +431,6 @@ fsm_print_c_complete(FILE *f, const struct ir *ir, fprintf(f, "\tint c;\n"); fprintf(f, "\n"); } - fprintf(f, "\t(void) opaque;\n"); - fprintf(f, "\n"); break; case FSM_IO_STR: From e577435cddabf684c2b3e1809d179b1124c6b218 Mon Sep 17 00:00:00 2001 From: Kate F Date: Fri, 14 Jun 2024 18:25:27 +0100 Subject: [PATCH 22/28] No need for the `void *opaque` arguments here. If these were neccessary for caller-supplied generated code from the endleaf callbacks, the actual way I'm intending a caller to pass information there, is to output with `opt.fragment` set. Then there's no need to gi via `void *` for any caller state, that can all be exposed as appropriately typed variables in scope for the generated code (or wrapped in a similar function as the non-fragment code, and exposed as appropriately-typed arguments to that function). The existing `void *opaque` here was nothing to do with this, it was actually for the `.getc()` callback. I've renamed it to keep it from getting mixed up. --- src/libfsm/print/c.c | 12 ++++-------- src/libfsm/print/vmc.c | 12 ++++-------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/libfsm/print/c.c b/src/libfsm/print/c.c index 5de4ce4ee..6ae17486c 100644 --- a/src/libfsm/print/c.c +++ b/src/libfsm/print/c.c @@ -377,7 +377,7 @@ fsm_print_c_body(FILE *f, const struct ir *ir, const struct fsm_options *opt) switch (opt->io) { case FSM_IO_GETC: - fprintf(f, "\twhile (c = fsm_getc(opaque), c != EOF) {\n"); + fprintf(f, "\twhile (c = fsm_getc(getc_opaque), c != EOF) {\n"); break; case FSM_IO_STR: @@ -425,7 +425,7 @@ fsm_print_c_complete(FILE *f, const struct ir *ir, switch (opt->io) { case FSM_IO_GETC: - fprintf(f, "(int (*fsm_getc)(void *opaque), void *opaque)\n"); + fprintf(f, "(int (*fsm_getc)(void *getc_opaque), void *getc_opaque)\n"); fprintf(f, "{\n"); if (ir->n > 0) { fprintf(f, "\tint c;\n"); @@ -434,25 +434,21 @@ fsm_print_c_complete(FILE *f, const struct ir *ir, break; case FSM_IO_STR: - fprintf(f, "(const char *s, void *opaque)\n"); + fprintf(f, "(const char *s)\n"); fprintf(f, "{\n"); if (ir->n > 0) { fprintf(f, "\tconst char *p;\n"); fprintf(f, "\n"); } - fprintf(f, "\t(void) opaque;\n"); - fprintf(f, "\n"); break; case FSM_IO_PAIR: - fprintf(f, "(const char *b, const char *e, void *opaque)\n"); + fprintf(f, "(const char *b, const char *e)\n"); fprintf(f, "{\n"); if (ir->n > 0) { fprintf(f, "\tconst char *p;\n"); fprintf(f, "\n"); } - fprintf(f, "\t(void) opaque;\n"); - fprintf(f, "\n"); break; } diff --git a/src/libfsm/print/vmc.c b/src/libfsm/print/vmc.c index 1e60a9b50..da6927acd 100644 --- a/src/libfsm/print/vmc.c +++ b/src/libfsm/print/vmc.c @@ -121,7 +121,7 @@ print_fetch(FILE *f, const struct fsm_options *opt) * Per its API, fsm_getc() is expected to return a positive character * value (as if cast via unsigned char), or EOF. Just like fgetc() does. */ - fprintf(f, "if (c = fsm_getc(opaque), c == EOF) "); + fprintf(f, "if (c = fsm_getc(getc_opaque), c == EOF) "); break; case FSM_IO_STR: @@ -467,22 +467,18 @@ fsm_print_c_complete(FILE *f, const struct ir *ir, const struct fsm_options *opt switch (opt->io) { case FSM_IO_GETC: - fprintf(f, "(int (*fsm_getc)(void *opaque), void *opaque)\n"); + fprintf(f, "(int (*fsm_getc)(void *opaque), void *getc_opaque)\n"); fprintf(f, "{\n"); break; case FSM_IO_STR: - fprintf(f, "(const char *s, void *opaque)\n"); + fprintf(f, "(const char *s)\n"); fprintf(f, "{\n"); - fprintf(f, "\t(void) opaque;\n"); - fprintf(f, "\n"); break; case FSM_IO_PAIR: - fprintf(f, "(const char *b, const char *e, void *opaque)\n"); + fprintf(f, "(const char *b, const char *e)\n"); fprintf(f, "{\n"); - fprintf(f, "\t(void) opaque;\n"); - fprintf(f, "\n"); break; } From 6ec0aef060a27fcfafb7b9b50043c6affee4cd0b Mon Sep 17 00:00:00 2001 From: Kate F Date: Fri, 14 Jun 2024 18:56:24 +0100 Subject: [PATCH 23/28] No need for the end_ids struct here. I'm not removing this for any profound reason, just that fewer kinds of structs help me better see what's happening. --- include/fsm/fsm.h | 6 --- include/fsm/options.h | 4 +- src/libfsm/print/awk.c | 22 ++++++--- src/libfsm/print/c.c | 18 +++++--- src/libfsm/print/dot.c | 29 ++++++------ src/libfsm/print/go.c | 16 +++++-- src/libfsm/print/ir.c | 40 ++++++++++------- src/libfsm/print/ir.h | 5 ++- src/libfsm/print/irdot.c | 8 ++-- src/libfsm/print/irjson.c | 8 ++-- src/libfsm/print/json.c | 25 +++++------ src/libfsm/print/rust.c | 17 +++++-- src/libfsm/print/sh.c | 11 ++++- src/libfsm/print/vmasm.c | 6 ++- src/libfsm/print/vmc.c | 16 +++++-- src/libfsm/print/vmdot.c | 19 +++++--- src/libfsm/print/vmops.c | 11 +++-- src/lx/print/c.c | 8 ++-- src/lx/print/dot.c | 8 ++-- src/re/main.c | 94 +++++++++++++++++++-------------------- 20 files changed, 214 insertions(+), 157 deletions(-) diff --git a/include/fsm/fsm.h b/include/fsm/fsm.h index 02f04c951..ecc7c5937 100644 --- a/include/fsm/fsm.h +++ b/include/fsm/fsm.h @@ -37,12 +37,6 @@ typedef unsigned int fsm_end_id_t; #define FSM_END_ID_MAX UINT_MAX -/* struct used to return a collection of end IDs. */ -struct fsm_end_ids { - unsigned count; - fsm_end_id_t ids[1]; -}; - /* * Create a new FSM. This is to be freed with fsm_free(). A structure allocated * from fsm_new() is expected to be passed as the "fsm" argument to the diff --git a/include/fsm/options.h b/include/fsm/options.h index b4193cc78..759b3b8eb 100644 --- a/include/fsm/options.h +++ b/include/fsm/options.h @@ -65,12 +65,12 @@ struct fsm_options { const char *cp; /* TODO: explain. for C code fragment output */ - int (*leaf)(FILE *, const struct fsm_end_ids *ids, + int (*leaf)(FILE *, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque); void *leaf_opaque; /* TODO: explain. for C code fragment output */ - int (*endleaf)(FILE *, const struct fsm_end_ids *ids, + int (*endleaf)(FILE *, const fsm_end_id_t *ids, size_t count, const void *endleaf_opaque); void *endleaf_opaque; diff --git a/src/libfsm/print/awk.c b/src/libfsm/print/awk.c index c7083e6e2..462a3ab7f 100644 --- a/src/libfsm/print/awk.c +++ b/src/libfsm/print/awk.c @@ -32,13 +32,14 @@ #define START UINT32_MAX static int -leaf(FILE *f, const struct fsm_end_ids *ids, const void *leaf_opaque) +leaf(FILE *f, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque) { assert(f != NULL); assert(leaf_opaque == NULL); (void) leaf_opaque; (void) ids; + (void) count; /* XXX: this should be FSM_UNKNOWN or something non-EOF, * maybe user defined */ @@ -99,7 +100,10 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, } if (opt->endleaf != NULL) { - if (-1 == opt->endleaf(f, op->ir_state->end_ids, opt->endleaf_opaque)) { + if (-1 == opt->endleaf(f, + op->ir_state->endids.ids, op->ir_state->endids.count, + opt->endleaf_opaque)) + { return -1; } } else { @@ -110,10 +114,10 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, /* awk can't return an array */ fprintf(f, "return \""); - for (i = 0; i < op->ir_state->end_ids->count; i++) { - fprintf(f, "%u", op->ir_state->end_ids->ids[i]); + for (i = 0; i < op->ir_state->endids.count; i++) { + fprintf(f, "%u", op->ir_state->endids.ids[i]); - if (i < op->ir_state->end_ids->count - 1) { + if (i < op->ir_state->endids.count - 1) { fprintf(f, ","); } } @@ -142,14 +146,18 @@ print_branch(FILE *f, const struct dfavm_op_ir *op, const char *prefix) static int fsm_print_awkfrag(FILE *f, const struct ir *ir, const struct fsm_options *opt, const char *cp, const char *prefix, - int (*leaf)(FILE *, const struct fsm_end_ids *ids, const void *leaf_opaque), + int (*leaf)(FILE *, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque), const void *leaf_opaque) { static const struct dfavm_assembler_ir zero; struct dfavm_assembler_ir a; struct dfavm_op_ir *op; - static const struct fsm_vm_compile_opts vm_opts = { FSM_VM_COMPILE_DEFAULT_FLAGS, FSM_VM_COMPILE_VM_V1, NULL }; + static const struct fsm_vm_compile_opts vm_opts = { + FSM_VM_COMPILE_DEFAULT_FLAGS, + FSM_VM_COMPILE_VM_V1, + NULL + }; assert(f != NULL); assert(ir != NULL); diff --git a/src/libfsm/print/c.c b/src/libfsm/print/c.c index 6ae17486c..21f15f837 100644 --- a/src/libfsm/print/c.c +++ b/src/libfsm/print/c.c @@ -53,12 +53,13 @@ ir_hasend(const struct ir *ir) } static int -leaf(FILE *f, const struct fsm_end_ids *ids, const void *leaf_opaque) +leaf(FILE *f, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque) { assert(f != NULL); assert(leaf_opaque == NULL); (void) ids; + (void) count; (void) leaf_opaque; /* XXX: this should be FSM_UNKNOWN or something non-EOF, @@ -136,7 +137,7 @@ static int print_singlecase(FILE *f, const struct ir *ir, const struct fsm_options *opt, const char *cp, struct ir_state *cs, - int (*leaf)(FILE *, const struct fsm_end_ids *ids, const void *leaf_opaque), + int (*leaf)(FILE *, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque), const void *leaf_opaque) { assert(ir != NULL); @@ -149,7 +150,7 @@ print_singlecase(FILE *f, const struct ir *ir, const struct fsm_options *opt, switch (cs->strategy) { case IR_NONE: fprintf(f, "\t\t\t"); - if (-1 == leaf(f, cs->end_ids, leaf_opaque)) { + if (-1 == leaf(f, cs->endids.ids, cs->endids.count, leaf_opaque)) { return -1; } fprintf(f, "\n"); @@ -178,7 +179,7 @@ print_singlecase(FILE *f, const struct ir *ir, const struct fsm_options *opt, print_groups(f, opt, ir_indexof(ir, cs), cs->u.partial.groups, cs->u.partial.n); fprintf(f, "\t\t\tdefault: "); - if (-1 == leaf(f, cs->end_ids, leaf_opaque)) { + if (-1 == leaf(f, cs->endids.ids, cs->endids.count, leaf_opaque)) { return -1; } fprintf(f, "\n"); @@ -209,7 +210,7 @@ print_singlecase(FILE *f, const struct ir *ir, const struct fsm_options *opt, print_ranges(f, opt, cs->u.error.error.ranges, cs->u.error.error.n); fprintf(f, " "); - if (-1 == leaf(f, cs->end_ids, leaf_opaque)) { + if (-1 == leaf(f, cs->endids.ids, cs->endids.count, leaf_opaque)) { return -1; } fprintf(f, "\n"); @@ -289,7 +290,10 @@ endstates(FILE *f, const struct fsm_options *opt, const struct ir *ir) fprintf(f, "\tcase S%u: ", i); if (opt->endleaf != NULL) { - if (-1 == opt->endleaf(f, ir->states[i].end_ids, opt->endleaf_opaque)) { + if (-1 == opt->endleaf(f, + ir->states[i].endids.ids, ir->states[i].endids.count, + opt->endleaf_opaque)) + { return -1; } } else { @@ -306,7 +310,7 @@ endstates(FILE *f, const struct fsm_options *opt, const struct ir *ir) int fsm_print_cfrag(FILE *f, const struct ir *ir, const struct fsm_options *opt, const char *cp, - int (*leaf)(FILE *, const struct fsm_end_ids *ids, const void *leaf_opaque), + int (*leaf)(FILE *, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque), const void *leaf_opaque) { unsigned i; diff --git a/src/libfsm/print/dot.c b/src/libfsm/print/dot.c index 1f070b382..459584e63 100644 --- a/src/libfsm/print/dot.c +++ b/src/libfsm/print/dot.c @@ -167,23 +167,22 @@ print_dotfrag(FILE *f, const struct fsm *fsm) s, s); } } else { - size_t written; - struct fsm_end_ids *ids = NULL; - const size_t count = fsm_endid_count(fsm, s); + fsm_end_id_t *ids; + size_t count, written; + + ids = NULL; + count = fsm_endid_count(fsm, s); if (count > 0) { int res; - ids = f_malloc(fsm->opt->alloc, - sizeof(*ids) + ((count - 1) * sizeof(ids->ids))); - assert(ids != NULL); + ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); if (ids == NULL) { return -1; } - res = fsm_endid_get(fsm, s, count, ids->ids, &written); - if (res == 1) { - ids->count = (unsigned)written; - } + res = fsm_endid_get(fsm, s, count, ids, &written); + assert(res == 1); + assert(count == written); } fprintf(f, "\t%sS%-2u [ shape = doublecircle", @@ -191,7 +190,7 @@ print_dotfrag(FILE *f, const struct fsm *fsm) if (fsm->opt->endleaf != NULL) { fprintf(f, ", "); - if (-1 == fsm->opt->endleaf(f, ids, fsm->opt->endleaf_opaque)) { + if (-1 == fsm->opt->endleaf(f, ids, count, fsm->opt->endleaf_opaque)) { return -1; } } else { @@ -204,15 +203,15 @@ print_dotfrag(FILE *f, const struct fsm *fsm) if (!fsm->opt->anonymous_states) { fprintf(f, "%u", s); - if (ids->count > 0) { + if (count > 0) { fprintf(f, "
"); } } - for (size_t i = 0; i < ids->count; i++) { - fprintf(f, "#%u", ids->ids[i]); + for (size_t i = 0; i < count; i++) { + fprintf(f, "#%u", ids[i]); - if (i < ids->count - 1) { + if (i < count - 1) { fprintf(f, ","); } } diff --git a/src/libfsm/print/go.c b/src/libfsm/print/go.c index d0a4edc47..22ed45ef5 100644 --- a/src/libfsm/print/go.c +++ b/src/libfsm/print/go.c @@ -29,12 +29,13 @@ #include "ir.h" static int -leaf(FILE *f, const struct fsm_end_ids *ids, const void *leaf_opaque) +leaf(FILE *f, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque) { assert(f != NULL); assert(leaf_opaque == NULL); (void) ids; + (void) count; (void) leaf_opaque; /* XXX: this should be FSM_UNKNOWN or something non-EOF, @@ -98,7 +99,10 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, } if (opt->endleaf != NULL) { - if (-1 == opt->endleaf(f, op->ir_state->end_ids, opt->endleaf_opaque)) { + if (-1 == opt->endleaf(f, + op->ir_state->endids.ids, op->ir_state->endids.count, + opt->endleaf_opaque)) + { return -1; } } else { @@ -132,14 +136,18 @@ print_fetch(FILE *f, const struct fsm_options *opt) static int fsm_print_gofrag(FILE *f, const struct ir *ir, const struct fsm_options *opt, const char *cp, - int (*leaf)(FILE *, const struct fsm_end_ids *ids, const void *leaf_opaque), + int (*leaf)(FILE *, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque), const void *leaf_opaque) { static const struct dfavm_assembler_ir zero; struct dfavm_assembler_ir a; struct dfavm_op_ir *op; - static const struct fsm_vm_compile_opts vm_opts = { FSM_VM_COMPILE_DEFAULT_FLAGS, FSM_VM_COMPILE_VM_V1, NULL }; + static const struct fsm_vm_compile_opts vm_opts = { + FSM_VM_COMPILE_DEFAULT_FLAGS, + FSM_VM_COMPILE_VM_V1, + NULL + }; assert(f != NULL); assert(ir != NULL); diff --git a/src/libfsm/print/ir.c b/src/libfsm/print/ir.c index 96e2f304e..4af6a8c11 100644 --- a/src/libfsm/print/ir.c +++ b/src/libfsm/print/ir.c @@ -467,25 +467,32 @@ make_ir(const struct fsm *fsm) assert(i < ir->n); ir->states[i].isend = fsm_isend(fsm, i); - ir->states[i].end_ids = NULL; + ir->states[i].endids.ids = NULL; + ir->states[i].endids.count = 0; + if (fsm_isend(fsm, i)) { - int res; - size_t written; - const size_t count = fsm_endid_count(fsm, i); - struct fsm_end_ids *ids = f_malloc(fsm->opt->alloc, - sizeof(*ids) + (count == 0 ? 0 : (count - 1) * sizeof(ids->ids[0]))); - if (ids == NULL) { - goto error; - } + fsm_end_id_t *ids; + size_t count; - res = fsm_endid_get(fsm, i, count, - ids->ids, &written); - if (res == 1) { - ids->count = (unsigned)written; - ir->states[i].end_ids = ids; + count = fsm_endid_count(fsm, i); + if (count == 0) { + ids = NULL; } else { - f_free(fsm->opt->alloc, ids); + int res; + size_t written; + + ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); + if (ids == NULL) { + goto error; + } + + res = fsm_endid_get(fsm, i, count, ids, &written); + assert(res == 1); + assert(count = written); } + + ir->states[i].endids.ids = ids; + ir->states[i].endids.count = count; } if (make_state(fsm, i, &ir->states[i]) == -1) { @@ -592,8 +599,7 @@ free_ir(const struct fsm *fsm, struct ir *ir) for (i = 0; i < ir->n; i++) { f_free(fsm->opt->alloc, (void *) ir->states[i].example); - - f_free(fsm->opt->alloc, (void *) ir->states[i].end_ids); + f_free(fsm->opt->alloc, (void *) ir->states[i].endids.ids); switch (ir->states[i].strategy) { case IR_TABLE: diff --git a/src/libfsm/print/ir.h b/src/libfsm/print/ir.h index f9f5c40c3..05ad758e7 100644 --- a/src/libfsm/print/ir.h +++ b/src/libfsm/print/ir.h @@ -53,7 +53,10 @@ struct ir_state { const char *example; unsigned int isend:1; - struct fsm_end_ids *end_ids; /* NULL -> 0 */ + struct { + fsm_end_id_t *ids; /* NULL -> 0 */ + size_t count; + } endids; enum ir_strategy strategy; union { diff --git a/src/libfsm/print/irdot.c b/src/libfsm/print/irdot.c index d388aa88e..039b9d568 100644 --- a/src/libfsm/print/irdot.c +++ b/src/libfsm/print/irdot.c @@ -191,13 +191,13 @@ print_cs(FILE *f, const struct fsm_options *opt, fprintf(f, "\t\t S%u%s\n", ir_indexof(ir, cs), strategy_name(cs->strategy)); - if (cs->isend && cs->end_ids != NULL) { + if (cs->isend && cs->endids.count > 0) { fprintf(f, "\t\t end id"); - for (size_t i = 0; i < cs->end_ids->count; i++) { - fprintf(f, "#%u", cs->end_ids->ids[i]); + for (size_t i = 0; i < cs->endids.count; i++) { + fprintf(f, "#%u", cs->endids.ids[i]); - if (i < cs->end_ids->count - 1) { + if (i < cs->endids.count - 1) { fprintf(f, " "); } } diff --git a/src/libfsm/print/irjson.c b/src/libfsm/print/irjson.c index a1e154942..0de7459ae 100644 --- a/src/libfsm/print/irjson.c +++ b/src/libfsm/print/irjson.c @@ -123,12 +123,12 @@ print_cs(FILE *f, const struct fsm_options *opt, fprintf(f, "\t\t{\n"); fprintf(f, "\t\t\t\"end\": %s,\n", cs->isend ? "true" : "false"); - if (cs->isend && cs->end_ids != NULL) { + if (cs->isend && cs->endids.count > 0) { fprintf(f, "\t\t\t\"end_id\": ["); - for (size_t i = 0; i < cs->end_ids->count; i++) { - fprintf(f, "%u", cs->end_ids->ids[i]); + for (size_t i = 0; i < cs->endids.count; i++) { + fprintf(f, "%u", cs->endids.ids[i]); - if (i < cs->end_ids->count - 1) { + if (i < cs->endids.count - 1) { fprintf(f, ", "); } } diff --git a/src/libfsm/print/json.c b/src/libfsm/print/json.c index e76da56e3..8eb1a32e8 100644 --- a/src/libfsm/print/json.c +++ b/src/libfsm/print/json.c @@ -247,28 +247,27 @@ fsm_print_json(FILE *f, const struct fsm *fsm) fprintf(f, " \"endleaf\": [ "); for (i = 0; i < fsm->statecount; i++) { if (fsm_isend(fsm, i)) { + fsm_end_id_t *ids; + size_t count, written; int res; - size_t written; - const size_t count = fsm_endid_count(fsm, i); - struct fsm_end_ids *ids = f_malloc(fsm->opt->alloc, - sizeof(*ids) + ((count - 1) * sizeof(ids->ids[0]))); - assert(ids != NULL); - - res = fsm_endid_get(fsm, i, count, - ids->ids, &written); - if (res == 1) { - ids->count = (unsigned)written; - } else { - ids->count = 0; + + count = fsm_endid_count(fsm, i); + + ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); + if (ids == NULL) { + return -1; } + res = fsm_endid_get(fsm, i, count, ids, &written); + assert(res == 1); + if (notfirst) { fprintf(f, ", "); } fprintf(f, "{ %u, ", i); - fsm->opt->endleaf(f, ids, fsm->opt->endleaf_opaque); + fsm->opt->endleaf(f, ids, count, fsm->opt->endleaf_opaque); fprintf(f, " }"); diff --git a/src/libfsm/print/rust.c b/src/libfsm/print/rust.c index e249c6aad..af2b0f302 100644 --- a/src/libfsm/print/rust.c +++ b/src/libfsm/print/rust.c @@ -32,12 +32,13 @@ #define START UINT32_MAX static int -leaf(FILE *f, const struct fsm_end_ids *ids, const void *leaf_opaque) +leaf(FILE *f, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque) { assert(f != NULL); assert(leaf_opaque == NULL); (void) ids; + (void) count; (void) leaf_opaque; /* XXX: this should be FSM_UNKNOWN or something non-EOF, @@ -109,7 +110,10 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, } if (opt->endleaf != NULL) { - if (-1 == opt->endleaf(f, op->ir_state->end_ids, opt->endleaf_opaque)) { + if (-1 == opt->endleaf(f, + op->ir_state->endids.ids, op->ir_state->endids.count, + opt->endleaf_opaque)) + { return -1; } } else { @@ -144,7 +148,7 @@ static int fsm_print_rustfrag(FILE *f, const struct dfavm_assembler_ir *a, const struct ir *ir, const struct fsm_options *opt, const char *cp, - int (*leaf)(FILE *, const struct fsm_end_ids *ids, const void *leaf_opaque), + int (*leaf)(FILE *, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque), const void *leaf_opaque) { struct dfavm_op_ir *op; @@ -362,9 +366,14 @@ fsm_print_rust_complete(FILE *f, const struct ir *ir, const struct fsm_options *opt, const char *prefix, const char *cp) { static const struct dfavm_assembler_ir zero; - static const struct fsm_vm_compile_opts vm_opts = { FSM_VM_COMPILE_DEFAULT_FLAGS, FSM_VM_COMPILE_VM_V1, NULL }; struct dfavm_assembler_ir a; + static const struct fsm_vm_compile_opts vm_opts = { + FSM_VM_COMPILE_DEFAULT_FLAGS, + FSM_VM_COMPILE_VM_V1, + NULL + }; + assert(f != NULL); assert(ir != NULL); assert(opt != NULL); diff --git a/src/libfsm/print/sh.c b/src/libfsm/print/sh.c index 7b6bee8d2..04e84663e 100644 --- a/src/libfsm/print/sh.c +++ b/src/libfsm/print/sh.c @@ -127,7 +127,10 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, } if (opt->endleaf != NULL) { - if (-1 == opt->endleaf(f, op->ir_state->end_ids, opt->endleaf_opaque)) { + if (-1 == opt->endleaf(f, + op->ir_state->endids.ids, op->ir_state->endids.count, + opt->endleaf_opaque)) + { return -1; } } else { @@ -156,7 +159,11 @@ fsm_print_shfrag(FILE *f, const struct ir *ir, const struct fsm_options *opt) struct dfavm_assembler_ir a; struct dfavm_op_ir *op; - static const struct fsm_vm_compile_opts vm_opts = { FSM_VM_COMPILE_DEFAULT_FLAGS, FSM_VM_COMPILE_VM_V1, NULL }; + static const struct fsm_vm_compile_opts vm_opts = { + FSM_VM_COMPILE_DEFAULT_FLAGS, + FSM_VM_COMPILE_VM_V1, + NULL + }; assert(f != NULL); assert(ir != NULL); diff --git a/src/libfsm/print/vmasm.c b/src/libfsm/print/vmasm.c index 8e3085b86..0c81bbf09 100644 --- a/src/libfsm/print/vmasm.c +++ b/src/libfsm/print/vmasm.c @@ -372,7 +372,11 @@ print_vmasm_encoding(FILE *f, const struct fsm *fsm, enum asm_dialect dialect) static const struct dfavm_assembler_ir zero; struct dfavm_assembler_ir a; - static const struct fsm_vm_compile_opts vm_opts = { FSM_VM_COMPILE_DEFAULT_FLAGS, FSM_VM_COMPILE_VM_V1, NULL }; + static const struct fsm_vm_compile_opts vm_opts = { + FSM_VM_COMPILE_DEFAULT_FLAGS, + FSM_VM_COMPILE_VM_V1, + NULL + }; assert(f != NULL); assert(fsm != NULL); diff --git a/src/libfsm/print/vmc.c b/src/libfsm/print/vmc.c index da6927acd..f94cee60d 100644 --- a/src/libfsm/print/vmc.c +++ b/src/libfsm/print/vmc.c @@ -29,12 +29,13 @@ #include "ir.h" static int -leaf(FILE *f, const struct fsm_end_ids *ids, const void *leaf_opaque) +leaf(FILE *f, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque) { assert(f != NULL); assert(leaf_opaque == NULL); (void) ids; + (void) count; (void) leaf_opaque; /* XXX: this should be FSM_UNKNOWN or something non-EOF, @@ -96,7 +97,10 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, } if (opt->endleaf != NULL) { - if (-1 == opt->endleaf(f, op->ir_state->end_ids, opt->endleaf_opaque)) { + if (-1 == opt->endleaf(f, + op->ir_state->endids.ids, op->ir_state->endids.count, + opt->endleaf_opaque)) + { return -1; } } else { @@ -279,14 +283,18 @@ walk_sequence(struct dfavm_op_ir *op, static int fsm_print_cfrag(FILE *f, const struct ir *ir, const struct fsm_options *opt, const char *cp, - int (*leaf)(FILE *, const struct fsm_end_ids *ids, const void *leaf_opaque), + int (*leaf)(FILE *, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque), const void *leaf_opaque) { static const struct dfavm_assembler_ir zero; struct dfavm_assembler_ir a; struct dfavm_op_ir *op; - static const struct fsm_vm_compile_opts vm_opts = { FSM_VM_COMPILE_DEFAULT_FLAGS, FSM_VM_COMPILE_VM_V1, NULL }; + static const struct fsm_vm_compile_opts vm_opts = { + FSM_VM_COMPILE_DEFAULT_FLAGS, + FSM_VM_COMPILE_VM_V1, + NULL + }; assert(f != NULL); assert(ir != NULL); diff --git a/src/libfsm/print/vmdot.c b/src/libfsm/print/vmdot.c index 775714798..bdcb2e3de 100644 --- a/src/libfsm/print/vmdot.c +++ b/src/libfsm/print/vmdot.c @@ -92,19 +92,22 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, } if (opt->endleaf != NULL) { - if (-1 == opt->endleaf(f, op->ir_state->end_ids, opt->endleaf_opaque)) { + if (-1 == opt->endleaf(f, + op->ir_state->endids.ids, op->ir_state->endids.count, + opt->endleaf_opaque)) + { return -1; } } else { fprintf(f, "ret %td", op->ir_state - ir->states); - if (op->ir_state->end_ids != NULL) { + if (op->ir_state->endids.count > 0) { fprintf(f, " / "); - for (size_t i = 0; i < op->ir_state->end_ids->count; i++) { - fprintf(f, "#%u", op->ir_state->end_ids->ids[i]); + for (size_t i = 0; i < op->ir_state->endids.count; i++) { + fprintf(f, "#%u", op->ir_state->endids.ids[i]); - if (i < op->ir_state->end_ids->count - 1) { + if (i < op->ir_state->endids.count - 1) { fprintf(f, " "); } } @@ -300,7 +303,11 @@ fsm_print_vmdotfrag(FILE *f, const struct ir *ir, const struct fsm_options *opt) static const struct dfavm_assembler_ir zero; struct dfavm_assembler_ir a; - static const struct fsm_vm_compile_opts vm_opts = { FSM_VM_COMPILE_DEFAULT_FLAGS, FSM_VM_COMPILE_VM_V1, NULL }; + static const struct fsm_vm_compile_opts vm_opts = { + FSM_VM_COMPILE_DEFAULT_FLAGS, + FSM_VM_COMPILE_VM_V1, + NULL + }; assert(f != NULL); assert(ir != NULL); diff --git a/src/libfsm/print/vmops.c b/src/libfsm/print/vmops.c index 7804d3cd9..976b47b00 100644 --- a/src/libfsm/print/vmops.c +++ b/src/libfsm/print/vmops.c @@ -35,12 +35,13 @@ enum vmops_dialect { }; static int -leaf(FILE *f, const struct fsm_end_ids *ids, const void *leaf_opaque) +leaf(FILE *f, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque) { assert(f != NULL); assert(leaf_opaque == NULL); (void) ids; + (void) count; (void) leaf_opaque; /* XXX: this should be FSM_UNKNOWN or something non-EOF, @@ -137,14 +138,18 @@ print_fetch(FILE *f, const struct fsm_options *opt, const char *prefix) /* TODO: eventually to be non-static */ static int fsm_print_vmopsfrag(FILE *f, const struct ir *ir, const struct fsm_options *opt, const char *prefix, - int (*leaf)(FILE *, const struct fsm_end_ids *ids, const void *leaf_opaque), + int (*leaf)(FILE *, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque), const void *leaf_opaque) { static const struct dfavm_assembler_ir zero; struct dfavm_assembler_ir a; struct dfavm_op_ir *op; - static const struct fsm_vm_compile_opts vm_opts = { FSM_VM_COMPILE_DEFAULT_FLAGS, FSM_VM_COMPILE_VM_V1, NULL }; + static const struct fsm_vm_compile_opts vm_opts = { + FSM_VM_COMPILE_DEFAULT_FLAGS, + FSM_VM_COMPILE_VM_V1, + NULL + }; assert(f != NULL); assert(ir != NULL); diff --git a/src/lx/print/c.c b/src/lx/print/c.c index 6308ba0c1..a8ae67eec 100644 --- a/src/lx/print/c.c +++ b/src/lx/print/c.c @@ -29,7 +29,7 @@ int fsm_print_cfrag(FILE *f, const struct ir *ir, const struct fsm_options *opt, const char *cp, - int (*leaf)(FILE *, const struct fsm_end_ids *ids, const void *leaf_opaque), + int (*leaf)(FILE *, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque), const void *opaque); static int @@ -138,7 +138,7 @@ shortest_example(const struct fsm *fsm, const struct ast_token *token, } static int -leaf(FILE *f, const struct fsm_end_ids *ids, const void *leaf_opaque) +leaf(FILE *f, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque) { const struct ast *ast; const struct ast_mapping *m; @@ -150,8 +150,8 @@ leaf(FILE *f, const struct fsm_end_ids *ids, const void *leaf_opaque) if (ids == NULL) { m = NULL; } else { - assert(ids->count > 0); - m = ast_getendmappingbyendid(ids->ids[0]); + assert(count > 0); + m = ast_getendmappingbyendid(ids[0]); } if (m == NULL) { diff --git a/src/lx/print/dot.c b/src/lx/print/dot.c index 4904c246c..5ad9d6212 100644 --- a/src/lx/print/dot.c +++ b/src/lx/print/dot.c @@ -65,7 +65,7 @@ mapping(FILE *f, const struct ast_mapping *m, const struct ast *ast) } static int -endleaf_dot(FILE *f, const struct fsm_end_ids *end_ids, +endleaf_dot(FILE *f, const fsm_end_id_t *ids, size_t count, const void *endleaf_opaque) { const struct ast_mapping *m; @@ -74,9 +74,9 @@ endleaf_dot(FILE *f, const struct fsm_end_ids *end_ids, assert(f != NULL); assert(endleaf_opaque != NULL); - (void)end_ids; /* TODO */ - assert(end_ids->count > 0); - m = ast_getendmappingbyendid(end_ids->ids[0]); + assert(ids != NULL); + assert(count > 0); + m = ast_getendmappingbyendid(ids[0]); ast = endleaf_opaque; diff --git a/src/re/main.c b/src/re/main.c index 895b832ea..9c54faa99 100644 --- a/src/re/main.c +++ b/src/re/main.c @@ -51,7 +51,7 @@ */ struct match { - fsm_end_id_t i; + fsm_end_id_t id; const char *s; struct match *next; }; @@ -276,7 +276,7 @@ find_match_with_id(fsm_end_id_t id) struct matches_list *res = all_matches; while (res != NULL) { struct match *m = res->head; - if (m->i == id) { + if (m->id == id) { return m; } res = res->next; @@ -315,14 +315,14 @@ find_first_match_for_end_state(const struct fsm *dfa, fsm_state_t s) } static struct match * -addmatch(struct match **head, int i, const char *s) +addmatch(struct match **head, fsm_end_id_t id, const char *s) { struct match *new; assert(head != NULL); assert(s != NULL); - if ((1U << i) > INT_MAX) { + if ((1U << id) > INT_MAX) { fprintf(stderr, "Too many patterns for int bitmap\n"); exit(EXIT_FAILURE); } @@ -344,7 +344,7 @@ addmatch(struct match **head, int i, const char *s) new = xmalloc(sizeof *new); - new->i = i; + new->id = id; new->s = s; new->next = *head; @@ -414,12 +414,13 @@ printexample(FILE *f, const struct fsm *fsm, fsm_state_t state) } static int -endleaf_c(FILE *f, const struct fsm_end_ids *end_ids, - const void *endleaf_opaque) +endleaf_c(FILE *f, + const fsm_end_id_t *ids, size_t count, + const void *endleaf_opaque) { const struct match *m; - int n; - size_t i, end_ids_count; + unsigned n; + size_t i; assert(endleaf_opaque == NULL); @@ -428,11 +429,9 @@ endleaf_c(FILE *f, const struct fsm_end_ids *end_ids, n = 0; - end_ids_count = (end_ids == NULL ? 0 : end_ids->count); - - for (i = 0; i < end_ids_count; i++) { - for (m = find_match_with_id(end_ids->ids[i]); m != NULL; m = m->next) { - n |= 1 << m->i; + for (i = 0; i < count; i++) { + for (m = find_match_with_id(ids[i]); m != NULL; m = m->next) { + n |= 1U << m->id; } } @@ -440,11 +439,11 @@ endleaf_c(FILE *f, const struct fsm_end_ids *end_ids, fprintf(f, " /* "); - for (i = 0; i < end_ids_count; i++) { - for (m = find_match_with_id(end_ids->ids[i]); m != NULL; m = m->next) { + for (i = 0; i < count; i++) { + for (m = find_match_with_id(ids[i]); m != NULL; m = m->next) { fprintf(f, "\"%s\"", m->s); /* XXX: escape string (and comment) */ - if (m->next != NULL || i < end_ids_count - 1) { + if (m->next != NULL || i < count - 1) { fprintf(f, ", "); } } @@ -456,12 +455,13 @@ endleaf_c(FILE *f, const struct fsm_end_ids *end_ids, } static int -endleaf_rust(FILE *f, const struct fsm_end_ids *end_ids, - const void *endleaf_opaque) +endleaf_rust(FILE *f, + const fsm_end_id_t *ids, size_t count, + const void *endleaf_opaque) { const struct match *m; - int n; - size_t i, end_ids_count; + unsigned n; + size_t i; assert(endleaf_opaque == NULL); @@ -470,11 +470,9 @@ endleaf_rust(FILE *f, const struct fsm_end_ids *end_ids, n = 0; - end_ids_count = (end_ids == NULL ? 0 : end_ids->count); - - for (i = 0; i < end_ids_count; i++) { - for (m = find_match_with_id(end_ids->ids[i]); m != NULL; m = m->next) { - n |= 1 << m->i; + for (i = 0; i < count; i++) { + for (m = find_match_with_id(ids[i]); m != NULL; m = m->next) { + n |= 1U << m->id; } } @@ -482,11 +480,11 @@ endleaf_rust(FILE *f, const struct fsm_end_ids *end_ids, fprintf(f, " /* "); - for (i = 0; i < end_ids_count; i++) { - for (m = find_match_with_id(end_ids->ids[i]); m != NULL; m = m->next) { + for (i = 0; i < count; i++) { + for (m = find_match_with_id(ids[i]); m != NULL; m = m->next) { fprintf(f, "\"%s\"", m->s); /* XXX: escape string (and comment) */ - if (m->next != NULL || i < end_ids_count - 1) { + if (m->next != NULL || i < count - 1) { fprintf(f, ", "); } } @@ -498,11 +496,12 @@ endleaf_rust(FILE *f, const struct fsm_end_ids *end_ids, } static int -endleaf_dot(FILE *f, const struct fsm_end_ids *end_ids, - const void *endleaf_opaque) +endleaf_dot(FILE *f, + const fsm_end_id_t *ids, size_t count, + const void *endleaf_opaque) { const struct match *m; - size_t i, end_ids_count; + size_t i; assert(f != NULL); assert(endleaf_opaque == NULL); @@ -511,13 +510,11 @@ endleaf_dot(FILE *f, const struct fsm_end_ids *end_ids, fprintf(f, "label = <"); - end_ids_count = (end_ids == NULL ? 0 : end_ids->count); - - for (i = 0; i < end_ids_count; i++) { - for (m = find_match_with_id(end_ids->ids[i]); m != NULL; m = m->next) { - fprintf(f, "#%u", m->i); + for (i = 0; i < count; i++) { + for (m = find_match_with_id(ids[i]); m != NULL; m = m->next) { + fprintf(f, "#%u", m->id); - if (m->next != NULL || i < end_ids_count - 1) { + if (m->next != NULL || i < count - 1) { fprintf(f, ","); } } @@ -531,11 +528,11 @@ endleaf_dot(FILE *f, const struct fsm_end_ids *end_ids, #if 0 fprintf(f, " # "); - for (i = 0; i < end_ids_count; i++) { - for (m = find_match_with_id(end_ids->ids[i]); m != NULL; m = m->next) { + for (i = 0; i < count; i++) { + for (m = find_match_with_id(ids[i]); m != NULL; m = m->next) { fprintf(f, "\"%s\"", m->s); /* XXX: escape string (and comment) */ - if (m->next != NULL || i < end_ids_count - 1) { + if (m->next != NULL || i < count - 1) { fprintf(f, ", "); } } @@ -548,11 +545,12 @@ endleaf_dot(FILE *f, const struct fsm_end_ids *end_ids, } static int -endleaf_json(FILE *f, const struct fsm_end_ids *end_ids, - const void *endleaf_opaque) +endleaf_json(FILE *f, + const fsm_end_id_t *ids, size_t count, + const void *endleaf_opaque) { const struct match *m; - size_t i, end_ids_count; + size_t i; assert(f != NULL); assert(endleaf_opaque == NULL); @@ -561,11 +559,9 @@ endleaf_json(FILE *f, const struct fsm_end_ids *end_ids, fprintf(f, "[ "); - end_ids_count = (end_ids == NULL ? 0 : end_ids->count); - - for (i = 0; i < end_ids_count; i++) { - for (m = find_match_with_id(end_ids->ids[i]); m != NULL; m = m->next) { - fprintf(f, "%u", m->i); + for (i = 0; i < count; i++) { + for (m = find_match_with_id(ids[i]); m != NULL; m = m->next) { + fprintf(f, "%u", m->id); if (m->next != NULL) { fprintf(f, ", "); From 1e5cf21b148db89816dad710b1c2d53c6688c40b Mon Sep 17 00:00:00 2001 From: Kate F Date: Sat, 15 Jun 2024 00:19:27 +0100 Subject: [PATCH 24/28] Normalization; attempting to get consistency around endleaf handling. --- include/fsm/options.h | 3 +++ src/libfsm/print/api.c | 2 ++ src/libfsm/print/c.c | 2 ++ src/libfsm/print/dot.c | 44 ++++++++++++++++++----------------- src/libfsm/print/fsm.c | 17 +++++++++++--- src/libfsm/print/go.c | 7 +++++- src/libfsm/print/irdot.c | 21 +++++++++++++++-- src/libfsm/print/irjson.c | 20 ++++++++++++++-- src/libfsm/print/json.c | 48 +++++++++++++++++++++++---------------- src/libfsm/print/vmasm.c | 11 +++++++++ src/libfsm/print/vmops.c | 19 ++++++++++++---- 11 files changed, 141 insertions(+), 53 deletions(-) diff --git a/include/fsm/options.h b/include/fsm/options.h index 759b3b8eb..e66c16b71 100644 --- a/include/fsm/options.h +++ b/include/fsm/options.h @@ -70,6 +70,9 @@ struct fsm_options { void *leaf_opaque; /* TODO: explain. for C code fragment output */ + /* Placement in the output stream depends on the format. + * This replaces an entire "return xyz;" statement for C-like formats, + * but appends extra information for others. */ int (*endleaf)(FILE *, const fsm_end_id_t *ids, size_t count, const void *endleaf_opaque); void *endleaf_opaque; diff --git a/src/libfsm/print/api.c b/src/libfsm/print/api.c index 6b33d045f..54f39fc09 100644 --- a/src/libfsm/print/api.c +++ b/src/libfsm/print/api.c @@ -142,6 +142,8 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) fprintf(f, "\t}\n"); fprintf(f, "\n"); + /* endleaf() doesn't make sense for this format */ + { size_t count; diff --git a/src/libfsm/print/c.c b/src/libfsm/print/c.c index 21f15f837..00e71adb1 100644 --- a/src/libfsm/print/c.c +++ b/src/libfsm/print/c.c @@ -289,6 +289,7 @@ endstates(FILE *f, const struct fsm_options *opt, const struct ir *ir) } fprintf(f, "\tcase S%u: ", i); + if (opt->endleaf != NULL) { if (-1 == opt->endleaf(f, ir->states[i].endids.ids, ir->states[i].endids.count, @@ -299,6 +300,7 @@ endstates(FILE *f, const struct fsm_options *opt, const struct ir *ir) } else { fprintf(f, "return %u;", i); } + fprintf(f, "\n"); } fprintf(f, "\tdefault: return -1; /* unexpected EOT */\n"); diff --git a/src/libfsm/print/dot.c b/src/libfsm/print/dot.c index 459584e63..e64edbb49 100644 --- a/src/libfsm/print/dot.c +++ b/src/libfsm/print/dot.c @@ -188,37 +188,39 @@ print_dotfrag(FILE *f, const struct fsm *fsm) fprintf(f, "\t%sS%-2u [ shape = doublecircle", fsm->opt->prefix != NULL ? fsm->opt->prefix : "", s); - if (fsm->opt->endleaf != NULL) { - fprintf(f, ", "); - if (-1 == fsm->opt->endleaf(f, ids, count, fsm->opt->endleaf_opaque)) { - return -1; - } - } else { - assert(f != NULL); + assert(f != NULL); - fprintf(f, ", "); + fprintf(f, ", "); - fprintf(f, "label = <"); + fprintf(f, "label = <"); - if (!fsm->opt->anonymous_states) { - fprintf(f, "%u", s); + if (fsm->opt->endleaf != NULL) { + if (-1 == fsm->opt->endleaf(f, + ids, count, + fsm->opt->endleaf_opaque)) + { + return -1; + } + } else if (!fsm->opt->anonymous_states) { + fprintf(f, "%u", s); + } - if (count > 0) { - fprintf(f, "
"); - } + if (fsm->opt->endleaf != NULL || !fsm->opt->anonymous_states) { + if (count > 0) { + fprintf(f, "
"); } + } - for (size_t i = 0; i < count; i++) { - fprintf(f, "#%u", ids[i]); + for (size_t i = 0; i < count; i++) { + fprintf(f, "#%u", ids[i]); - if (i < count - 1) { - fprintf(f, ","); - } + if (i < count - 1) { + fprintf(f, ","); } - - fprintf(f, ">"); } + fprintf(f, ">"); + fprintf(f, " ];\n"); f_free(fsm->opt->alloc, ids); diff --git a/src/libfsm/print/fsm.c b/src/libfsm/print/fsm.c index 762bb1c30..2de984445 100644 --- a/src/libfsm/print/fsm.c +++ b/src/libfsm/print/fsm.c @@ -291,6 +291,7 @@ fsm_print_fsm(FILE *f, const struct fsm *fsm) fprintf(f, "end: "); for (s = 0; s < fsm->statecount; s++) { + fsm_end_id_t *ids; size_t count; if (!fsm_isend(fsm, s)) { @@ -299,11 +300,8 @@ fsm_print_fsm(FILE *f, const struct fsm *fsm) end--; - fprintf(f, "%u", s); - count = fsm_endid_count(fsm, s); if (count > 0) { - fsm_end_id_t *ids; size_t written; int res; @@ -315,7 +313,20 @@ fsm_print_fsm(FILE *f, const struct fsm *fsm) res = fsm_endid_get(fsm, s, count, ids, &written); assert(res == 1); assert(written == count); + } + if (fsm->opt->endleaf != NULL) { + if (-1 == fsm->opt->endleaf(f, + ids, count, + fsm->opt->endleaf_opaque)) + { + return -1; + } + } else { + fprintf(f, "%u", s); + } + + if (count > 0) { qsort(ids, count, sizeof *ids, comp_end_id); fprintf(f, " = ["); diff --git a/src/libfsm/print/go.c b/src/libfsm/print/go.c index 22ed45ef5..7b3616f9d 100644 --- a/src/libfsm/print/go.c +++ b/src/libfsm/print/go.c @@ -98,6 +98,9 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, return 0; } + fprintf(f, "{\n"); + fprintf(f, "\t\t"); + if (opt->endleaf != NULL) { if (-1 == opt->endleaf(f, op->ir_state->endids.ids, op->ir_state->endids.count, @@ -106,9 +109,11 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, return -1; } } else { - fprintf(f, "{\n\t\treturn %td\n\t}\n", op->ir_state - ir->states); + fprintf(f, "return %td", op->ir_state - ir->states); } + fprintf(f, "\n\t}\n"); + return 0; } diff --git a/src/libfsm/print/irdot.c b/src/libfsm/print/irdot.c index 039b9d568..8e91029ca 100644 --- a/src/libfsm/print/irdot.c +++ b/src/libfsm/print/irdot.c @@ -173,7 +173,7 @@ print_grouplinks(FILE *f, unsigned self, } } -static void +static int print_cs(FILE *f, const struct fsm_options *opt, const struct ir *ir, const struct ir_state *cs) { @@ -188,6 +188,7 @@ print_cs(FILE *f, const struct fsm_options *opt, fprintf(f, "\tcs%u [ label =\n", ir_indexof(ir, cs)); fprintf(f, "\t\t<\n"); + fprintf(f, "\t\t \n", ir_indexof(ir, cs), strategy_name(cs->strategy)); @@ -213,6 +214,18 @@ print_cs(FILE *f, const struct fsm_options *opt, /* TODO: leaf callback for dot output */ + /* showing endleaf in addition to existing content */ + if (cs->isend && opt->endleaf != NULL) { + fprintf(f, "\t\t \n"); + } + switch (cs->strategy) { case IR_NONE: break; @@ -304,6 +317,8 @@ print_cs(FILE *f, const struct fsm_options *opt, default: ; } + + return 0; } int @@ -334,7 +349,9 @@ fsm_print_ir(FILE *f, const struct fsm *fsm) } for (i = 0; i < ir->n; i++) { - print_cs(f, fsm->opt, ir, &ir->states[i]); + if (-1 == print_cs(f, fsm->opt, ir, &ir->states[i])) { + return -1; + } } fprintf(f, "}\n"); diff --git a/src/libfsm/print/irjson.c b/src/libfsm/print/irjson.c index 0de7459ae..189d4b571 100644 --- a/src/libfsm/print/irjson.c +++ b/src/libfsm/print/irjson.c @@ -112,7 +112,7 @@ print_groups(FILE *f, const struct fsm_options *opt, fprintf(f, "\t\t\t]\n"); } -static void +static int print_cs(FILE *f, const struct fsm_options *opt, const struct ir_state *cs) { @@ -135,6 +135,18 @@ print_cs(FILE *f, const struct fsm_options *opt, fprintf(f, "],\n"); } + /* showing endleaf in addition to existing content */ + if (cs->isend && opt->endleaf != NULL) { + fprintf(f, "\t\t\t\"endleaf\": "); + if (-1 == opt->endleaf(f, + cs->endids.ids, cs->endids.count, + opt->endleaf_opaque)) + { + return -1; + } + fprintf(f, ",\n"); + } + fprintf(f, "\t\t\t\"strategy\": \"%s\"", strategy_name(cs->strategy)); if (cs->example != NULL || cs->strategy != IR_NONE) { fprintf(f, ","); @@ -195,6 +207,8 @@ print_cs(FILE *f, const struct fsm_options *opt, } fprintf(f, "\t\t}"); + + return 0; } int @@ -217,7 +231,9 @@ fsm_print_irjson(FILE *f, const struct fsm *fsm) fprintf(f, "\t\"states\": [\n"); for (i = 0; i < ir->n; i++) { - print_cs(f, fsm->opt, &ir->states[i]); + if (-1 == print_cs(f, fsm->opt, &ir->states[i])) { + return -1; + } if (i + 1 < ir->n) { fprintf(f, ","); diff --git a/src/libfsm/print/json.c b/src/libfsm/print/json.c index 8eb1a32e8..49f751778 100644 --- a/src/libfsm/print/json.c +++ b/src/libfsm/print/json.c @@ -239,6 +239,7 @@ fsm_print_json(FILE *f, const struct fsm *fsm) fprintf(f, " ],\n"); } + /* showing endleaf in addition to existing content */ if (fsm->opt->endleaf != NULL) { int notfirst; @@ -246,35 +247,42 @@ fsm_print_json(FILE *f, const struct fsm *fsm) fprintf(f, " \"endleaf\": [ "); for (i = 0; i < fsm->statecount; i++) { - if (fsm_isend(fsm, i)) { - fsm_end_id_t *ids; - size_t count, written; - int res; + fsm_end_id_t *ids; + size_t count, written; + int res; - count = fsm_endid_count(fsm, i); + if (!fsm_isend(fsm, i)) { + continue; + } - ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); - if (ids == NULL) { - return -1; - } + count = fsm_endid_count(fsm, i); - res = fsm_endid_get(fsm, i, count, ids, &written); - assert(res == 1); + ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); + if (ids == NULL) { + return -1; + } - if (notfirst) { - fprintf(f, ", "); - } + res = fsm_endid_get(fsm, i, count, ids, &written); + assert(res == 1); - fprintf(f, "{ %u, ", i); + if (notfirst) { + fprintf(f, ", "); + } - fsm->opt->endleaf(f, ids, count, fsm->opt->endleaf_opaque); + fprintf(f, "{ %u, ", i); - fprintf(f, " }"); + if (-1 == fsm->opt->endleaf(f, + ids, count, + fsm->opt->endleaf_opaque)) + { + return -1; + } - f_free(fsm->opt->alloc, ids); + fprintf(f, " }"); - notfirst = 1; - } + f_free(fsm->opt->alloc, ids); + + notfirst = 1; } fprintf(f, " ],\n"); } diff --git a/src/libfsm/print/vmasm.c b/src/libfsm/print/vmasm.c index 0c81bbf09..046610c44 100644 --- a/src/libfsm/print/vmasm.c +++ b/src/libfsm/print/vmasm.c @@ -171,7 +171,18 @@ print_asm_amd64(FILE *f, const char *prefix, break; } + + /* endleaf in addition to existing instructions */ + if (opt->endleaf != NULL) { + if (-1 == opt->endleaf(f, + op->ir_state->endids.ids, op->ir_state->endids.count, + opt->endleaf_opaque)) + { + return -1; + } + } } else { + /* TODO: we don't have a way to override the -1 (or its API) */ switch (dialect) { case AMD64_ATT: fprintf(f, "\tmovl $-1, %%%s\n", ret_reg); diff --git a/src/libfsm/print/vmops.c b/src/libfsm/print/vmops.c index 976b47b00..11972ffa5 100644 --- a/src/libfsm/print/vmops.c +++ b/src/libfsm/print/vmops.c @@ -98,7 +98,7 @@ print_cond(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, } static int -print_end(FILE *f, const struct dfavm_op_ir *op, const char *prefix, +print_end(FILE *f, const struct dfavm_op_ir *op, const struct fsm_options *opt, const char *prefix, enum dfavm_op_end end_bits, const struct ir *ir) { if (end_bits == VM_END_FAIL) { @@ -106,7 +106,18 @@ print_end(FILE *f, const struct dfavm_op_ir *op, const char *prefix, return 0; } - fprintf(f, "%sactionRET, %td},\n", prefix, op->ir_state - ir->states); + if (opt->endleaf != NULL) { + if (-1 == opt->endleaf(f, + op->ir_state->endids.ids, op->ir_state->endids.count, + opt->endleaf_opaque)) + { + return -1; + } + } else { + fprintf(f, "%sactionRET, %td", prefix, op->ir_state - ir->states); + } + + fprintf(f, "},\n"); return 0; } @@ -177,7 +188,7 @@ fsm_print_vmopsfrag(FILE *f, const struct ir *ir, const struct fsm_options *opt, if (-1 == print_cond(f, op, opt, prefix)) { return -1; } - if (-1 == print_end(f, op, prefix, op->u.stop.end_bits, ir)) { + if (-1 == print_end(f, op, opt, prefix, op->u.stop.end_bits, ir)) { return -1; } break; @@ -186,7 +197,7 @@ fsm_print_vmopsfrag(FILE *f, const struct ir *ir, const struct fsm_options *opt, if (-1 == print_fetch(f, opt, prefix)) { return -1; } - if (-1 == print_end(f, op, prefix, op->u.fetch.end_bits, ir)) { + if (-1 == print_end(f, op, opt, prefix, op->u.fetch.end_bits, ir)) { return -1; } break; From f7bcbdda56d25cda5605e7559353538ea86e8c5b Mon Sep 17 00:00:00 2001 From: Kate F Date: Sat, 15 Jun 2024 14:04:34 +0100 Subject: [PATCH 25/28] Remove dependencies on *nwritten, fsm_endid_count() beforehand instead. --- src/libfsm/minimise_test_oracle.c | 73 ++++++++++++++++++------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/src/libfsm/minimise_test_oracle.c b/src/libfsm/minimise_test_oracle.c index 70209f865..99b22025c 100644 --- a/src/libfsm/minimise_test_oracle.c +++ b/src/libfsm/minimise_test_oracle.c @@ -175,39 +175,50 @@ fsm_minimise_test_oracle(const struct fsm *fsm) * any of the other end states. If so, assign it to the same endid * group, otherwise assign a new one and mark it as the leader. */ for (size_t i = 0; i < state_count; i++) { - if (fsm_isend(fsm, i)) { - size_t written_a; - int eres = fsm_endid_get(fsm, i, - max_endid_count, endid_buf_a, &written_a); - if (eres == 0) { - assert(written_a == 0); - } else { - assert(written_a > 0); - bool found = false; - /* note: skipping eg 0 here since that's the empty set */ - for (size_t eg_i = 1; eg_i < endid_group_count; eg_i++) { - size_t written_b; - eres = fsm_endid_get(fsm, endid_group_leaders[eg_i], - max_endid_count, endid_buf_b, &written_b); - assert(eres != 0); - if (written_b != written_a) { continue; } - if (0 == memcmp(endid_buf_a, endid_buf_b, written_a * sizeof(endid_buf_a[0]))) { - found = true; - endid_group_assignments[i] = eg_i; - break; - } else { - continue; - } - } + if (!fsm_isend(fsm, i)) { + endid_group_assignments[i] = 0; /* none */ + continue; + } - if (!found) { - endid_group_assignments[i] = endid_group_count; - endid_group_leaders[endid_group_count] = i; - endid_group_count++; - } + size_t count_a = fsm_endid_count(fsm, i); + assert(count_a <= max_endid_count); + if (count_a == 0) { + continue; + } + + size_t written_a; + int eres = fsm_endid_get(fsm, i, + count_a, endid_buf_a, &written_a); + assert(eres == 1); + assert(written_a > 0); + + bool found = false; + /* note: skipping eg 0 here since that's the empty set */ + for (size_t eg_i = 1; eg_i < endid_group_count; eg_i++) { + size_t written_b; + size_t count_b = fsm_endid_count(fsm, endid_group_leaders[eg_i]); + if (count_b != count_a) { + continue; } - } else { - endid_group_assignments[i] = 0; /* none */ + + assert(count_b > 0); + assert(count_b <= max_endid_count); + eres = fsm_endid_get(fsm, endid_group_leaders[eg_i], + count_b, endid_buf_b, &written_b); + assert(eres == 1); + assert(written_b == count_b); + + if (0 == memcmp(endid_buf_a, endid_buf_b, count_a * sizeof(endid_buf_a[0]))) { + found = true; + endid_group_assignments[i] = eg_i; + break; + } + } + + if (!found) { + endid_group_assignments[i] = endid_group_count; + endid_group_leaders[endid_group_count] = i; + endid_group_count++; } } From 6b2426db38799e999e646031be125db3727388a0 Mon Sep 17 00:00:00 2001 From: Kate F Date: Sat, 15 Jun 2024 18:13:19 +0100 Subject: [PATCH 26/28] No need for the *nwritten parameter. Now this is always equivalent to the count passed in, when the return status is 1. And the return status is always 1 when the count is enough. In all situations we know the count is enough. --- include/fsm/fsm.h | 9 ++++---- src/libfsm/endids.c | 11 ++------- src/libfsm/minimise.c | 4 +--- src/libfsm/minimise_test_oracle.c | 8 ++----- src/libfsm/print/api.c | 4 +--- src/libfsm/print/dot.c | 5 ++-- src/libfsm/print/fsm.c | 4 +--- src/libfsm/print/ir.c | 4 +--- src/libfsm/print/json.c | 4 ++-- src/libfsm/walk2.c | 8 ++----- src/lx/ast.c | 7 ++---- src/re/main.c | 4 +--- tests/capture/captest.c | 6 ++--- tests/capture/capture4.c | 7 +++--- tests/endids/endids0.c | 6 +---- tests/endids/endids0_many_endids.c | 15 ++++++------ tests/endids/endids1_determinise.c | 6 +---- .../endids/endids1_determinise_and_minimise.c | 6 +---- tests/endids/endids2_union.c | 10 +++----- tests/endids/endids2_union_many_endids.c | 14 ++++------- tests/endids/endids4.c | 6 +---- tests/endids/endids5.c | 6 +---- tests/endids/endids6.c | 23 +++++++------------ tests/endids/endids7.c | 21 ++++++----------- tests/endids/endids7_with_duplicates.c | 21 ++++++----------- tests/endids/endids8.c | 6 +---- tests/endids/endids9.c | 14 ++++------- tests/endids/utils.c | 3 +-- tests/gen/gtest.c | 5 ++-- tests/re_strings/testutil.c | 5 ++-- 30 files changed, 78 insertions(+), 174 deletions(-) diff --git a/include/fsm/fsm.h b/include/fsm/fsm.h index ecc7c5937..00e9cf095 100644 --- a/include/fsm/fsm.h +++ b/include/fsm/fsm.h @@ -220,16 +220,15 @@ fsm_endid_set(struct fsm *fsm, fsm_state_t end_state, fsm_end_id_t id); /* Get the end IDs associated with an end state, if any. * If id_buf has enough cells to store all the end IDs (according - * to id_buf_count) then they are written into id_buf[] and - * *ids_written is set to the number of IDs. The end IDs in the - * buffer may appear in any order, but will not have duplicates. + * to id_buf_count) then they are written into id_buf[]. + * The end IDs in the buffer may appear in any order, + * but will not have duplicates. * * Returns 0 if there is not enough space in id_buf for the * end IDs, or 1 if zero or more end IDs were returned. */ int fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, - size_t id_buf_count, fsm_end_id_t *id_buf, - size_t *ids_written); + size_t id_buf_count, fsm_end_id_t *id_buf); /* Get the number of end IDs associated with an end state. */ size_t diff --git a/src/libfsm/endids.c b/src/libfsm/endids.c index fb63baf66..df87da617 100644 --- a/src/libfsm/endids.c +++ b/src/libfsm/endids.c @@ -683,24 +683,19 @@ fsm_endid_count(const struct fsm *fsm, int fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, - size_t id_buf_count, fsm_end_id_t *id_buf, - size_t *ids_written) + size_t id_buf_count, fsm_end_id_t *id_buf) { size_t i; - size_t written = 0; const struct endid_info *ei = NULL; uint64_t hash = hash_id(end_state); uint64_t mask; - (void)written; - assert(fsm != NULL); ei = fsm->endid_info; assert(ei != NULL); assert(id_buf != NULL); - assert(ids_written != NULL); mask = ei->bucket_count - 1; /* bucket count is a power of 2 */ @@ -721,8 +716,7 @@ fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, #if LOG_ENDIDS > 2 fprintf(stderr, "fsm_endid_get: not found\n"); #endif - *ids_written = 0; /* not found */ - return 0; + return 0; /* not found */ } else if (b->state == end_state) { size_t id_i; if (b->ids->count > id_buf_count) { @@ -739,7 +733,6 @@ fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, } /* todo: could sort them here, if it matters. */ - *ids_written = b->ids->count; return 1; } else { /* collision */ #if LOG_ENDIDS > 4 diff --git a/src/libfsm/minimise.c b/src/libfsm/minimise.c index a55de5d61..8100e22da 100644 --- a/src/libfsm/minimise.c +++ b/src/libfsm/minimise.c @@ -962,10 +962,8 @@ collect_end_ids(const struct fsm *fsm, fsm_state_t s, return 0; } - size_t written; - int res = fsm_endid_get(fsm, s, e->count, e->ids, &written); + int res = fsm_endid_get(fsm, s, e->count, e->ids); assert(res == 1); - assert(written == e->count); /* sort, to make comparison easier later */ qsort(e->ids, e->count, diff --git a/src/libfsm/minimise_test_oracle.c b/src/libfsm/minimise_test_oracle.c index 99b22025c..cc4d9efac 100644 --- a/src/libfsm/minimise_test_oracle.c +++ b/src/libfsm/minimise_test_oracle.c @@ -186,16 +186,13 @@ fsm_minimise_test_oracle(const struct fsm *fsm) continue; } - size_t written_a; int eres = fsm_endid_get(fsm, i, - count_a, endid_buf_a, &written_a); + count_a, endid_buf_a); assert(eres == 1); - assert(written_a > 0); bool found = false; /* note: skipping eg 0 here since that's the empty set */ for (size_t eg_i = 1; eg_i < endid_group_count; eg_i++) { - size_t written_b; size_t count_b = fsm_endid_count(fsm, endid_group_leaders[eg_i]); if (count_b != count_a) { continue; @@ -204,9 +201,8 @@ fsm_minimise_test_oracle(const struct fsm *fsm) assert(count_b > 0); assert(count_b <= max_endid_count); eres = fsm_endid_get(fsm, endid_group_leaders[eg_i], - count_b, endid_buf_b, &written_b); + count_b, endid_buf_b); assert(eres == 1); - assert(written_b == count_b); if (0 == memcmp(endid_buf_a, endid_buf_b, count_a * sizeof(endid_buf_a[0]))) { found = true; diff --git a/src/libfsm/print/api.c b/src/libfsm/print/api.c index 54f39fc09..7a0a9ffa5 100644 --- a/src/libfsm/print/api.c +++ b/src/libfsm/print/api.c @@ -150,7 +150,6 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) count = fsm_endid_count(fsm, end); if (count > 0) { fsm_end_id_t *ids; - size_t written; int res; ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); @@ -159,9 +158,8 @@ fsm_print_api(FILE *f, const struct fsm *fsm_orig) goto error; } - res = fsm_endid_get(fsm, end, count, ids, &written); + res = fsm_endid_get(fsm, end, count, ids); assert(res == 1); - assert(written == count); qsort(ids, count, sizeof *ids, comp_end_id); diff --git a/src/libfsm/print/dot.c b/src/libfsm/print/dot.c index e64edbb49..54d151a96 100644 --- a/src/libfsm/print/dot.c +++ b/src/libfsm/print/dot.c @@ -168,7 +168,7 @@ print_dotfrag(FILE *f, const struct fsm *fsm) } } else { fsm_end_id_t *ids; - size_t count, written; + size_t count; ids = NULL; count = fsm_endid_count(fsm, s); @@ -180,9 +180,8 @@ print_dotfrag(FILE *f, const struct fsm *fsm) return -1; } - res = fsm_endid_get(fsm, s, count, ids, &written); + res = fsm_endid_get(fsm, s, count, ids); assert(res == 1); - assert(count == written); } fprintf(f, "\t%sS%-2u [ shape = doublecircle", diff --git a/src/libfsm/print/fsm.c b/src/libfsm/print/fsm.c index 2de984445..46bc428ff 100644 --- a/src/libfsm/print/fsm.c +++ b/src/libfsm/print/fsm.c @@ -302,7 +302,6 @@ fsm_print_fsm(FILE *f, const struct fsm *fsm) count = fsm_endid_count(fsm, s); if (count > 0) { - size_t written; int res; ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); @@ -310,9 +309,8 @@ fsm_print_fsm(FILE *f, const struct fsm *fsm) return -1; } - res = fsm_endid_get(fsm, s, count, ids, &written); + res = fsm_endid_get(fsm, s, count, ids); assert(res == 1); - assert(written == count); } if (fsm->opt->endleaf != NULL) { diff --git a/src/libfsm/print/ir.c b/src/libfsm/print/ir.c index 4af6a8c11..f23ce238a 100644 --- a/src/libfsm/print/ir.c +++ b/src/libfsm/print/ir.c @@ -479,16 +479,14 @@ make_ir(const struct fsm *fsm) ids = NULL; } else { int res; - size_t written; ids = f_malloc(fsm->opt->alloc, count * sizeof *ids); if (ids == NULL) { goto error; } - res = fsm_endid_get(fsm, i, count, ids, &written); + res = fsm_endid_get(fsm, i, count, ids); assert(res == 1); - assert(count = written); } ir->states[i].endids.ids = ids; diff --git a/src/libfsm/print/json.c b/src/libfsm/print/json.c index 49f751778..11c7a5f24 100644 --- a/src/libfsm/print/json.c +++ b/src/libfsm/print/json.c @@ -248,7 +248,7 @@ fsm_print_json(FILE *f, const struct fsm *fsm) fprintf(f, " \"endleaf\": [ "); for (i = 0; i < fsm->statecount; i++) { fsm_end_id_t *ids; - size_t count, written; + size_t count; int res; if (!fsm_isend(fsm, i)) { @@ -262,7 +262,7 @@ fsm_print_json(FILE *f, const struct fsm *fsm) return -1; } - res = fsm_endid_get(fsm, i, count, ids, &written); + res = fsm_endid_get(fsm, i, count, ids); assert(res == 1); if (notfirst) { diff --git a/src/libfsm/walk2.c b/src/libfsm/walk2.c index 9320dbafd..20580dd60 100644 --- a/src/libfsm/walk2.c +++ b/src/libfsm/walk2.c @@ -285,17 +285,13 @@ fsm_walk2_tuple_new(struct fsm_walk2_data *data, } if (num_a_endids > 0) { - size_t nwritten = 0; - ret = fsm_endid_get(fsm_a, a, num_a_endids, endids, &nwritten); + ret = fsm_endid_get(fsm_a, a, num_a_endids, endids); assert(ret == 1); - assert(nwritten == num_a_endids); } if (num_b_endids > 0) { - size_t nwritten = 0; - ret = fsm_endid_get(fsm_b, b, num_b_endids, endids + num_a_endids, &nwritten); + ret = fsm_endid_get(fsm_b, b, num_b_endids, endids + num_a_endids); assert(ret == 1); - assert(nwritten == num_b_endids); } ret = fsm_endid_set_bulk( diff --git a/src/lx/ast.c b/src/lx/ast.c index 7dd1ad72c..5852c7055 100644 --- a/src/lx/ast.c +++ b/src/lx/ast.c @@ -236,7 +236,7 @@ struct ast_mapping * ast_getendmapping(const struct fsm *fsm, fsm_state_t s) { fsm_end_id_t *ids; - size_t count, written; + size_t count; struct ast_mapping *m; int res; @@ -256,11 +256,8 @@ ast_getendmapping(const struct fsm *fsm, fsm_state_t s) return NULL; } - res = fsm_endid_get(fsm, s, count, ids, &written); - + res = fsm_endid_get(fsm, s, count, ids); assert(res == 1); - assert(written == count); - assert(written > 0); m = ast_getendmappingbyendid(ids[0]); diff --git a/src/re/main.c b/src/re/main.c index 9c54faa99..ea2c68ae8 100644 --- a/src/re/main.c +++ b/src/re/main.c @@ -289,7 +289,6 @@ find_first_match_for_end_state(const struct fsm *dfa, fsm_state_t s) { fsm_end_id_t *ids, id; size_t count; - size_t nwritten; int res; if (!fsm_isend(dfa, s)) { @@ -303,9 +302,8 @@ find_first_match_for_end_state(const struct fsm *dfa, fsm_state_t s) ids = xmalloc(count * sizeof *ids); - res = fsm_endid_get(dfa, s, count, ids, &nwritten); + res = fsm_endid_get(dfa, s, count, ids); assert(res == 1); - assert(nwritten == count); id = ids[0]; diff --git a/tests/capture/captest.c b/tests/capture/captest.c index 5a6384686..b882043a8 100644 --- a/tests/capture/captest.c +++ b/tests/capture/captest.c @@ -91,12 +91,11 @@ captest_run_single(const struct captest_single_fsm_test_info *info) { fsm_end_id_t id_buf[1] = { ~0 }; int gres; - size_t written; if (1 != fsm_endid_count(fsm, end)) { FAIL("did not have exactly one end ID"); } - gres = fsm_endid_get(fsm, end, 1, id_buf, &written); + gres = fsm_endid_get(fsm, end, 1, id_buf); if (gres != 1) { FAIL("failed to get end IDs"); } @@ -183,7 +182,6 @@ captest_check_single_end_id(const struct fsm *fsm, fsm_state_t end_state, { fsm_end_id_t id_buf[1] = { ~0 }; int gres; - size_t written; const char *unused; if (msg == NULL) { @@ -195,7 +193,7 @@ captest_check_single_end_id(const struct fsm *fsm, fsm_state_t end_state, return 0; } - gres = fsm_endid_get(fsm, end_state, 1, id_buf, &written); + gres = fsm_endid_get(fsm, end_state, 1, id_buf); if (gres != 1) { *msg = "failed to get end IDs"; return 0; diff --git a/tests/capture/capture4.c b/tests/capture/capture4.c index 4394b637f..0d9685358 100644 --- a/tests/capture/capture4.c +++ b/tests/capture/capture4.c @@ -222,18 +222,17 @@ check(const struct fsm *fsm, const char *string, { int gres; fsm_end_id_t id_buf[2]; - size_t written; - gres = fsm_endid_get(fsm, end, 2, id_buf, &written); + gres = fsm_endid_get(fsm, end, 2, id_buf); if (gres != 1) { assert(!"fsm_getendids failed"); } if (expected_ends == 0x2) { - assert(written == 1); + assert(fsm_endid_count(fsm, end) == 1); assert(id_buf[0] == 1); } else if (expected_ends == 0x3) { - assert(written == 2); + assert(fsm_endid_count(fsm, end) == 2); assert(id_buf[0] == 0); assert(id_buf[1] == 1); } else { diff --git a/tests/endids/endids0.c b/tests/endids/endids0.c index 69df62775..2bbe6a237 100644 --- a/tests/endids/endids0.c +++ b/tests/endids/endids0.c @@ -44,21 +44,17 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endid = 0; - size_t nwritten; int ret; assert( fsm_endid_count(fsm, state_ind) == 1); - nwritten = 0; ret = fsm_endid_get( fsm, state_ind, 1, - &endid, - &nwritten); + &endid); assert(ret == 1); - assert(nwritten == 1); assert(endid == 1); nend++; diff --git a/tests/endids/endids0_many_endids.c b/tests/endids/endids0_many_endids.c index f451b9acc..62f52e1a2 100644 --- a/tests/endids/endids0_many_endids.c +++ b/tests/endids/endids0_many_endids.c @@ -85,27 +85,26 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[sizeof all_end_ids / sizeof all_end_ids[0]]; - size_t i, nwritten; + size_t i; int ret; memset(&endids[0], 0, sizeof endids); assert(fsm_endid_count(fsm, state_ind) == sizeof all_end_ids / sizeof all_end_ids[0]); - nwritten = 0; ret = fsm_endid_get( fsm, state_ind, - sizeof endids/sizeof endids[0], - &endids[0], - &nwritten); + sizeof endids / sizeof endids[0], + &endids[0]); assert(ret == 1); - assert(nwritten == sizeof all_end_ids / sizeof all_end_ids[0]); /* sort endids and compare */ - qsort(&endids[0], nwritten, sizeof endids[0], cmp_endids); - for (i=0; i < nwritten; i++) { + qsort(&endids[0], + sizeof endids / sizeof endids[0], sizeof endids[0], + cmp_endids); + for (i=0; i < fsm_endid_count(fsm, state_ind); i++) { assert(endids[i] == sorted_all_end_ids[i]); } diff --git a/tests/endids/endids1_determinise.c b/tests/endids/endids1_determinise.c index 5d61e1db4..3ce6f6b0f 100644 --- a/tests/endids/endids1_determinise.c +++ b/tests/endids/endids1_determinise.c @@ -40,21 +40,17 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endid = 0; - size_t nwritten; int ret; assert( fsm_endid_count(fsm, state_ind) == 1); - nwritten = 0; ret = fsm_endid_get( fsm, state_ind, 1, - &endid, - &nwritten); + &endid); assert(ret == 1); - assert(nwritten == 1); assert( endid == 1 ); } } diff --git a/tests/endids/endids1_determinise_and_minimise.c b/tests/endids/endids1_determinise_and_minimise.c index 91adf3f44..a62d7979b 100644 --- a/tests/endids/endids1_determinise_and_minimise.c +++ b/tests/endids/endids1_determinise_and_minimise.c @@ -45,21 +45,17 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endid = 0; - size_t nwritten; int ret; assert(fsm_endid_count(fsm, state_ind) == 1); - nwritten = 0; ret = fsm_endid_get( fsm, state_ind, 1, - &endid, - &nwritten); + &endid); assert(ret == 1); - assert(nwritten == 1); assert( endid == 1 ); } } diff --git a/tests/endids/endids2_union.c b/tests/endids/endids2_union.c index 905c4b324..e939c5474 100644 --- a/tests/endids/endids2_union.c +++ b/tests/endids/endids2_union.c @@ -55,11 +55,9 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(comb, state_ind)) { fsm_end_id_t endids[2] = {0,0}; - size_t nwritten; size_t count; int ret; - nwritten = 0; count = fsm_endid_count(comb, state_ind); // fprintf(stderr, "state %u, count = %zu\n", state_ind, count); @@ -69,18 +67,16 @@ int main(void) comb, state_ind, 2, - &endids[0], - &nwritten); + &endids[0]); assert(ret == 1); - assert(nwritten == count); - if (nwritten == 1) { + if (count == 1) { assert(endids[0] == 1 || endids[0] == 2); has_endid_1 = has_endid_1 || (endids[0] == 1); has_endid_2 = has_endid_2 || (endids[0] == 2); - } else if (nwritten == 2) { + } else if (count == 2) { assert((endids[0] == 1 && endids[1] == 2) || (endids[0] == 2 && endids[1] == 1)); diff --git a/tests/endids/endids2_union_many_endids.c b/tests/endids/endids2_union_many_endids.c index e292be47b..830421e66 100644 --- a/tests/endids/endids2_union_many_endids.c +++ b/tests/endids/endids2_union_many_endids.c @@ -183,12 +183,11 @@ int main(void) if (fsm_isend(fsm, state_ind)) { int tested_pattern[NUM_PATTERNS]; fsm_end_id_t endids[NUM_ENDIDS_TOTAL]; - size_t nwritten, count, j; + size_t count, j; int ret; memset(&endids[0], 0, sizeof endids); - nwritten = 0; count = fsm_endid_count(fsm, state_ind); assert(count > 0 && count <= sizeof endids/sizeof endids[0]); @@ -197,11 +196,9 @@ int main(void) fsm, state_ind, sizeof endids/sizeof endids[0], - &endids[0], - &nwritten); + &endids[0]); assert(ret == 1); - assert(nwritten == count); memset(&tested_pattern[0], 0, sizeof tested_pattern); @@ -250,12 +247,11 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[NUM_ENDIDS_TOTAL]; - size_t nwritten, count; + size_t count; int ret; memset(&endids[0], 0, sizeof endids); - nwritten = 0; count = fsm_endid_count(fsm, state_ind); assert(count <= NUM_ENDIDS_TOTAL); @@ -264,11 +260,9 @@ int main(void) fsm, state_ind, sizeof endids/sizeof endids[0], - &endids[0], - &nwritten); + &endids[0]); assert(ret == 1); - assert(nwritten == count); } } diff --git a/tests/endids/endids4.c b/tests/endids/endids4.c index 1b022aad4..64838cc83 100644 --- a/tests/endids/endids4.c +++ b/tests/endids/endids4.c @@ -67,11 +67,9 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(comb, state_ind)) { fsm_end_id_t endids[2] = {0,0}; - size_t nwritten; size_t count; int ret; - nwritten = 0; count = fsm_endid_count(comb, state_ind); printf("state %u count = %zu\n", state_ind, count); @@ -82,11 +80,9 @@ int main(void) comb, state_ind, 2, - &endids[0], - &nwritten); + &endids[0]); assert(ret == 1); - assert(nwritten == count); qsort(&endids[0], count, sizeof endids[0], cmp_endids); assert(endids[0] == 1 && endids[1] == 2); diff --git a/tests/endids/endids5.c b/tests/endids/endids5.c index 3639ab0ac..2fce9ea92 100644 --- a/tests/endids/endids5.c +++ b/tests/endids/endids5.c @@ -68,11 +68,9 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(comb, state_ind)) { fsm_end_id_t endids[2] = {0,0}; - size_t nwritten; size_t count; int ret; - nwritten = 0; count = fsm_endid_count(comb, state_ind); printf("state %u count = %zu\n", state_ind, count); @@ -83,11 +81,9 @@ int main(void) comb, state_ind, 2, - &endids[0], - &nwritten); + &endids[0]); assert(ret == 1); - assert(nwritten == count); assert(endids[0] == 1); } diff --git a/tests/endids/endids6.c b/tests/endids/endids6.c index 657a314dc..77976991c 100644 --- a/tests/endids/endids6.c +++ b/tests/endids/endids6.c @@ -92,11 +92,9 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[2] = {0,0}; - size_t nwritten; size_t count; int ret; - nwritten = 0; count = fsm_endid_count(fsm, state_ind); assert( count > 0 && count <= 2); @@ -105,20 +103,18 @@ int main(void) fsm, state_ind, sizeof endids / sizeof endids[0], - &endids[0], - &nwritten); + &endids[0]); assert(ret == 1); - assert(nwritten == count); info[ninfo].state = state_ind; - info[ninfo].count = nwritten; + info[ninfo].count = count; - if (nwritten == 1) { + if (count == 1) { assert(endids[0] == 1 || endids[0] == 2); info[ninfo].endids[0] = endids[0]; - } else if (nwritten == 2) { - qsort(&endids[0], nwritten, sizeof endids[0], cmp_endids); + } else if (count == 2) { + qsort(&endids[0], count, sizeof endids[0], cmp_endids); assert(endids[0] == 1 && endids[1] == 2); info[ninfo].endids[0] = endids[0]; info[ninfo].endids[1] = endids[1]; @@ -137,12 +133,11 @@ int main(void) for (state_ind = 0, info_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[2] = {0,0}; - size_t nwritten, count, ind; + size_t count, ind; int ret; assert( state_ind == info[info_ind].state ); - nwritten = 0; count = fsm_endid_count(fsm, state_ind); assert(count > 0 && count <= 2); @@ -152,13 +147,11 @@ int main(void) fsm, state_ind, sizeof endids / sizeof endids[0], - &endids[0], - &nwritten); + &endids[0]); assert(ret == 1); - assert(nwritten == count); - if (nwritten > 1) { + if (count > 1) { qsort(&endids[0], count, sizeof endids[0], cmp_endids); } diff --git a/tests/endids/endids7.c b/tests/endids/endids7.c index 488e1e3e0..451cf342a 100644 --- a/tests/endids/endids7.c +++ b/tests/endids/endids7.c @@ -104,11 +104,9 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[2] = {0,0}; - size_t nwritten; size_t count; int ret; - nwritten = 0; count = fsm_endid_count(fsm, state_ind); assert( count > 0 && count <= 2); @@ -117,20 +115,18 @@ int main(void) fsm, state_ind, sizeof endids / sizeof endids[0], - &endids[0], - &nwritten); + &endids[0]); assert(ret == 1); - assert(nwritten == count); info[ninfo].state = state_ind; - info[ninfo].count = nwritten; + info[ninfo].count = count; - if (nwritten == 1) { + if (count == 1) { assert(endids[0] == 1 || endids[0] == 2); info[ninfo].endids[0] = endids[0]; - } else if (nwritten == 2) { - qsort(&endids[0], nwritten, sizeof endids[0], cmp_endids); + } else if (count == 2) { + qsort(&endids[0], count, sizeof endids[0], cmp_endids); assert(endids[0] == 1 && endids[1] == 2); info[ninfo].endids[0] = endids[0]; info[ninfo].endids[1] = endids[1]; @@ -150,12 +146,11 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endid = 0; fsm_end_id_t expected; - size_t nwritten, count; + size_t count; int ret; assert( state_ind == info[info_ind].state ); - nwritten = 0; count = fsm_endid_count(fsm, state_ind); assert(count == 1); @@ -163,11 +158,9 @@ int main(void) fsm, state_ind, 1, - &endid, - &nwritten); + &endid); assert(ret == 1); - assert(nwritten == count); if (info[info_ind].count == 2) { expected = 3; diff --git a/tests/endids/endids7_with_duplicates.c b/tests/endids/endids7_with_duplicates.c index b4d0701d3..40acaac8b 100644 --- a/tests/endids/endids7_with_duplicates.c +++ b/tests/endids/endids7_with_duplicates.c @@ -108,11 +108,9 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[2] = {0,0}; - size_t nwritten; size_t count; int ret; - nwritten = 0; count = fsm_endid_count(fsm, state_ind); assert( count > 0 && count <= 2); @@ -121,20 +119,18 @@ int main(void) fsm, state_ind, sizeof endids / sizeof endids[0], - &endids[0], - &nwritten); + &endids[0]); assert(ret == 1); - assert(nwritten == count); info[ninfo].state = state_ind; - info[ninfo].count = nwritten; + info[ninfo].count = count; - if (nwritten == 1) { + if (count == 1) { assert(endids[0] == 1 || endids[0] == 2); info[ninfo].endids[0] = endids[0]; - } else if (nwritten == 2) { - qsort(&endids[0], nwritten, sizeof endids[0], cmp_endids); + } else if (count == 2) { + qsort(&endids[0], count, sizeof endids[0], cmp_endids); assert(endids[0] == 1 && endids[1] == 2); info[ninfo].endids[0] = endids[0]; info[ninfo].endids[1] = endids[1]; @@ -154,12 +150,11 @@ int main(void) if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endid = 0; fsm_end_id_t expected; - size_t nwritten, count; + size_t count; int ret; assert( state_ind == info[info_ind].state ); - nwritten = 0; count = fsm_endid_count(fsm, state_ind); assert(count == 1); @@ -167,11 +162,9 @@ int main(void) fsm, state_ind, 1, - &endid, - &nwritten); + &endid); assert(ret == 1); - assert(nwritten == count); if (info[info_ind].count == 2) { expected = 3; diff --git a/tests/endids/endids8.c b/tests/endids/endids8.c index 0ef6e024b..dedd750b0 100644 --- a/tests/endids/endids8.c +++ b/tests/endids/endids8.c @@ -73,11 +73,9 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(comb, state_ind)) { fsm_end_id_t endids[3] = {0,0,0}; - size_t nwritten; size_t count; int ret; - nwritten = 0; count = fsm_endid_count(comb, state_ind); printf("state %u count = %zu\n", state_ind, count); @@ -88,11 +86,9 @@ int main(void) comb, state_ind, sizeof endids / sizeof endids[0], - &endids[0], - &nwritten); + &endids[0]); assert(ret == 1); - assert(nwritten == count); qsort(&endids[0], count, sizeof endids[0], cmp_endids); assert(endids[0] == 1 && endids[1] == 2 && endids[2] == 4); diff --git a/tests/endids/endids9.c b/tests/endids/endids9.c index ef15efe13..38328f5a4 100644 --- a/tests/endids/endids9.c +++ b/tests/endids/endids9.c @@ -72,11 +72,9 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { fsm_end_id_t endids[2] = {0,0}; - size_t nwritten; size_t count; int ret; - nwritten = 0; count = fsm_endid_count(fsm, state_ind); assert( count > 0 && count <= 2); @@ -85,20 +83,18 @@ int main(void) fsm, state_ind, sizeof endids / sizeof endids[0], - &endids[0], - &nwritten); + &endids[0]); assert(ret == 1); - assert(nwritten == count); info[ninfo].state = state_ind; - info[ninfo].count = nwritten; + info[ninfo].count = count; - if (nwritten == 1) { + if (count == 1) { assert(endids[0] == 11 || endids[0] == 12); info[ninfo].endids[0] = endids[0]; - } else if (nwritten == 2) { - qsort(&endids[0], nwritten, sizeof endids[0], cmp_endids); + } else if (count == 2) { + qsort(&endids[0], count, sizeof endids[0], cmp_endids); assert(endids[0] == 11 && endids[1] == 12); info[ninfo].endids[0] = endids[0]; info[ninfo].endids[1] = endids[1]; diff --git a/tests/endids/utils.c b/tests/endids/utils.c index 7457fc70e..a5d96f020 100644 --- a/tests/endids/utils.c +++ b/tests/endids/utils.c @@ -20,14 +20,13 @@ match_string(const struct fsm *fsm, const char *s, fsm_state_t *end_ptr, fsm_end count = fsm_endid_count(fsm, end); if (count > 0) { int ret; - size_t nwritten = 0; fsm_end_id_t *endids = calloc(count, sizeof *endids); if (endids == NULL) { return -1; } - ret = fsm_endid_get(fsm, end, count, endids, &nwritten); + ret = fsm_endid_get(fsm, end, count, endids); if (ret == 0) { free(endids); errno = EINVAL; diff --git a/tests/gen/gtest.c b/tests/gen/gtest.c index aff46ba3a..53fc89602 100644 --- a/tests/gen/gtest.c +++ b/tests/gen/gtest.c @@ -59,9 +59,8 @@ gtest_matches_cb(const struct fsm *fsm, #define ID_BUF_COUNT 1 fsm_end_id_t id_buf[ID_BUF_COUNT]; - size_t written; int gres = fsm_endid_get(fsm, - end_state, ID_BUF_COUNT, id_buf, &written); + end_state, ID_BUF_COUNT, id_buf); if (gres != 1) { fprintf(stderr, @@ -70,7 +69,7 @@ gtest_matches_cb(const struct fsm *fsm, return FSM_GENERATE_MATCHES_CB_RES_HALT; } - if (written != 1 || id_buf[0] != m_i) { + if (fsm_endid_count(fsm, end_state) != 1 || id_buf[0] != m_i) { fprintf(stderr, "ERROR: endid mismatch, expected %zu, got %u\n", m_i, id_buf[0]); return FSM_GENERATE_MATCHES_CB_RES_HALT; diff --git a/tests/re_strings/testutil.c b/tests/re_strings/testutil.c index 197415492..59d972512 100644 --- a/tests/re_strings/testutil.c +++ b/tests/re_strings/testutil.c @@ -47,12 +47,11 @@ run_test(const char **strings) const int res = fsm_exec(fsm, fsm_sgetc, string, &end, NULL); assert(res > 0); /* match */ - size_t written; int eres = fsm_endid_get(fsm, end, - MAX_INPUTS, id_buf, &written); + MAX_INPUTS, id_buf); assert(eres == 1); bool found = false; - for (size_t i = 0; i < written; i++) { + for (size_t i = 0; i < fsm_endid_count(fsm, end); i++) { if (id_buf[i] == id) { found = true; break; From 99fa19cc6b047fe13d5600d2377169e9c18d6d6c Mon Sep 17 00:00:00 2001 From: Kate F Date: Sat, 15 Jun 2024 21:10:25 +0100 Subject: [PATCH 27/28] Getting 0 end IDs is not an error. --- include/fsm/fsm.h | 12 ++++++++++-- src/libfsm/endids.c | 6 ++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/fsm/fsm.h b/include/fsm/fsm.h index 00e9cf095..269ee5c87 100644 --- a/include/fsm/fsm.h +++ b/include/fsm/fsm.h @@ -219,11 +219,19 @@ int fsm_endid_set(struct fsm *fsm, fsm_state_t end_state, fsm_end_id_t id); /* Get the end IDs associated with an end state, if any. - * If id_buf has enough cells to store all the end IDs (according - * to id_buf_count) then they are written into id_buf[]. + * id_buf is expected to have enough cells (according to id_buf_count) + * to store all the end IDs. You can find this with fsm_endid_count(). + * * The end IDs in the buffer may appear in any order, * but will not have duplicates. * + * A state with no end IDs set is considered equivalent to a state + * that has the empty set, this API does not distinguish these cases. + * This is not an error. + * + * It is an error to attempt to get end IDs associated with a state + * that is not marked as an end state. + * * Returns 0 if there is not enough space in id_buf for the * end IDs, or 1 if zero or more end IDs were returned. */ int diff --git a/src/libfsm/endids.c b/src/libfsm/endids.c index df87da617..135392a74 100644 --- a/src/libfsm/endids.c +++ b/src/libfsm/endids.c @@ -716,8 +716,10 @@ fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, #if LOG_ENDIDS > 2 fprintf(stderr, "fsm_endid_get: not found\n"); #endif - return 0; /* not found */ - } else if (b->state == end_state) { + return 1; /* not an error */ + } + + if (b->state == end_state) { size_t id_i; if (b->ids->count > id_buf_count) { #if LOG_ENDIDS > 2 From f663cd4274d0ebb7235d358aca483696599551c2 Mon Sep 17 00:00:00 2001 From: Kate F Date: Sun, 16 Jun 2024 22:38:44 +0100 Subject: [PATCH 28/28] Naming; ids[] for endids. --- src/libfsm/endids.c | 8 +-- src/libfsm/minimise_test_oracle.c | 26 ++++----- src/libfsm/walk2.c | 39 ++++++++------ tests/capture/captest.c | 12 ++--- tests/capture/capture4.c | 10 ++-- tests/endids/endids0.c | 30 +++++------ tests/endids/endids0_many_endids.c | 54 +++++++++---------- tests/endids/endids1_determinise.c | 24 ++++----- .../endids/endids1_determinise_and_minimise.c | 24 ++++----- tests/endids/endids2_union.c | 26 ++++----- tests/endids/endids2_union_many_endids.c | 34 ++++++------ tests/endids/endids4.c | 26 ++++----- tests/endids/endids5.c | 26 ++++----- tests/endids/endids6.c | 54 +++++++++---------- tests/endids/endids7.c | 50 ++++++++--------- tests/endids/endids7_with_duplicates.c | 42 +++++++-------- tests/endids/endids8.c | 14 ++--- tests/endids/endids9.c | 20 +++---- tests/endids/utils.c | 16 +++--- tests/gen/gtest.c | 8 +-- tests/re_strings/testutil.c | 6 +-- 21 files changed, 279 insertions(+), 270 deletions(-) diff --git a/src/libfsm/endids.c b/src/libfsm/endids.c index 135392a74..66860e88a 100644 --- a/src/libfsm/endids.c +++ b/src/libfsm/endids.c @@ -683,7 +683,7 @@ fsm_endid_count(const struct fsm *fsm, int fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, - size_t id_buf_count, fsm_end_id_t *id_buf) + size_t count, fsm_end_id_t *ids) { size_t i; const struct endid_info *ei = NULL; @@ -695,7 +695,7 @@ fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, ei = fsm->endid_info; assert(ei != NULL); - assert(id_buf != NULL); + assert(ids != NULL); mask = ei->bucket_count - 1; /* bucket count is a power of 2 */ @@ -721,7 +721,7 @@ fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, if (b->state == end_state) { size_t id_i; - if (b->ids->count > id_buf_count) { + if (b->ids->count > count) { #if LOG_ENDIDS > 2 fprintf(stderr, "fsm_endid_get: insufficient space\n"); #endif @@ -731,7 +731,7 @@ fsm_endid_get(const struct fsm *fsm, fsm_state_t end_state, #if LOG_ENDIDS > 2 fprintf(stderr, "fsm_endid_get: writing id[%zu]: %d\n", id_i, b->ids->ids[id_i]); #endif - id_buf[id_i] = b->ids->ids[id_i]; + ids[id_i] = b->ids->ids[id_i]; } /* todo: could sort them here, if it matters. */ diff --git a/src/libfsm/minimise_test_oracle.c b/src/libfsm/minimise_test_oracle.c index cc4d9efac..6cd1848c4 100644 --- a/src/libfsm/minimise_test_oracle.c +++ b/src/libfsm/minimise_test_oracle.c @@ -113,8 +113,8 @@ fsm_minimise_test_oracle(const struct fsm *fsm) unsigned *endid_group_assignments = NULL; size_t endid_group_count = 1; /* group 0 is the empty set */ unsigned *endid_group_leaders = NULL; - fsm_end_id_t *endid_buf_a = NULL; - fsm_end_id_t *endid_buf_b = NULL; + fsm_end_id_t *ids_a = NULL; + fsm_end_id_t *ids_b = NULL; table = calloc(row_words * table_states, sizeof(table[0])); if (table == NULL) { goto cleanup; } @@ -165,10 +165,10 @@ fsm_minimise_test_oracle(const struct fsm *fsm) } } - endid_buf_a = malloc(max_endid_count * sizeof(endid_buf_a[0])); - if (endid_buf_a == NULL) { goto cleanup; } - endid_buf_b = malloc(max_endid_count * sizeof(endid_buf_b[0])); - if (endid_buf_b == NULL) { goto cleanup; } + ids_a = malloc(max_endid_count * sizeof(ids_a[0])); + if (ids_a == NULL) { goto cleanup; } + ids_b = malloc(max_endid_count * sizeof(ids_b[0])); + if (ids_b == NULL) { goto cleanup; } /* For every end state, check if it has endids. If not, assign it * to endid group 0 (none). Otherwise, check if its endids match @@ -187,7 +187,7 @@ fsm_minimise_test_oracle(const struct fsm *fsm) } int eres = fsm_endid_get(fsm, i, - count_a, endid_buf_a); + count_a, ids_a); assert(eres == 1); bool found = false; @@ -201,10 +201,10 @@ fsm_minimise_test_oracle(const struct fsm *fsm) assert(count_b > 0); assert(count_b <= max_endid_count); eres = fsm_endid_get(fsm, endid_group_leaders[eg_i], - count_b, endid_buf_b); + count_b, ids_b); assert(eres == 1); - if (0 == memcmp(endid_buf_a, endid_buf_b, count_a * sizeof(endid_buf_a[0]))) { + if (0 == memcmp(ids_a, ids_b, count_a * sizeof(ids_a[0]))) { found = true; endid_group_assignments[i] = eg_i; break; @@ -361,8 +361,8 @@ fsm_minimise_test_oracle(const struct fsm *fsm) free(mapping); free(endid_group_assignments); free(endid_group_leaders); - free(endid_buf_a); - free(endid_buf_b); + free(ids_a); + free(ids_b); return res; @@ -372,8 +372,8 @@ fsm_minimise_test_oracle(const struct fsm *fsm) if (mapping != NULL) { free(mapping); } if (endid_group_assignments != NULL) { free(endid_group_assignments); } if (endid_group_leaders != NULL) { free(endid_group_leaders); } - if (endid_buf_a != NULL) { free(endid_buf_a); } - if (endid_buf_b != NULL) { free(endid_buf_b); } + if (ids_a != NULL) { free(ids_a); } + if (ids_b != NULL) { free(ids_b); } if (res != NULL) { fsm_free(res); } return NULL; } diff --git a/src/libfsm/walk2.c b/src/libfsm/walk2.c index 20580dd60..afd8107ca 100644 --- a/src/libfsm/walk2.c +++ b/src/libfsm/walk2.c @@ -263,45 +263,54 @@ fsm_walk2_tuple_new(struct fsm_walk2_data *data, } if (is_end) { - size_t num_a_endids = 0, num_b_endids = 0, total_num_endids; + size_t count_a = 0, count_b = 0, count_total; if (fsm_a != NULL && fsm_isend(fsm_a,a)) { - num_a_endids = fsm_endid_count(fsm_a, a); + count_a = fsm_endid_count(fsm_a, a); } if (fsm_b != NULL && fsm_isend(fsm_b,b)) { - num_b_endids = fsm_endid_count(fsm_b, b); + count_b = fsm_endid_count(fsm_b, b); } - total_num_endids = num_a_endids + num_b_endids; + count_total = count_a + count_b; - if (total_num_endids > 0) { - fsm_end_id_t *endids; + if (count_total > 0) { + const struct fsm_alloc *alloc; + fsm_end_id_t *ids; int ret; - endids = calloc(total_num_endids, sizeof endids[0]); - if (endids == NULL) { + if (fsm_a != NULL) { + alloc = fsm_a->opt->alloc; + } else if (fsm_b != NULL) { + alloc = fsm_b->opt->alloc; + } else { + assert(!"unreached"); + } + + ids = f_malloc(alloc, count_total * sizeof *ids); + if (ids == NULL) { return NULL; } - if (num_a_endids > 0) { - ret = fsm_endid_get(fsm_a, a, num_a_endids, endids); + if (count_a > 0) { + ret = fsm_endid_get(fsm_a, a, count_a, ids); assert(ret == 1); } - if (num_b_endids > 0) { - ret = fsm_endid_get(fsm_b, b, num_b_endids, endids + num_a_endids); + if (count_b > 0) { + ret = fsm_endid_get(fsm_b, b, count_b, ids + count_a); assert(ret == 1); } ret = fsm_endid_set_bulk( data->new, p->comb, - total_num_endids, - &endids[0], + count_total, + &ids[0], FSM_ENDID_BULK_REPLACE); - free(endids); + f_free(alloc, ids); if (!ret) { int errsv = errno; diff --git a/tests/capture/captest.c b/tests/capture/captest.c index b882043a8..d1b5c510a 100644 --- a/tests/capture/captest.c +++ b/tests/capture/captest.c @@ -89,18 +89,18 @@ captest_run_single(const struct captest_single_fsm_test_info *info) if (end != strlen(info->string)) { FAIL("exec end pos"); } { - fsm_end_id_t id_buf[1] = { ~0 }; + fsm_end_id_t ids[1] = { ~0 }; int gres; if (1 != fsm_endid_count(fsm, end)) { FAIL("did not have exactly one end ID"); } - gres = fsm_endid_get(fsm, end, 1, id_buf); + gres = fsm_endid_get(fsm, end, 1, ids); if (gres != 1) { FAIL("failed to get end IDs"); } - if (0 != id_buf[0]) { + if (0 != ids[0]) { FAIL("failed to get end ID of 0"); } } @@ -180,7 +180,7 @@ int captest_check_single_end_id(const struct fsm *fsm, fsm_state_t end_state, unsigned expected_end_id, const char **msg) { - fsm_end_id_t id_buf[1] = { ~0 }; + fsm_end_id_t ids[1] = { ~0 }; int gres; const char *unused; @@ -193,13 +193,13 @@ captest_check_single_end_id(const struct fsm *fsm, fsm_state_t end_state, return 0; } - gres = fsm_endid_get(fsm, end_state, 1, id_buf); + gres = fsm_endid_get(fsm, end_state, 1, ids); if (gres != 1) { *msg = "failed to get end IDs"; return 0; } - if (expected_end_id != id_buf[0]) { + if (expected_end_id != ids[0]) { *msg = "failed to get expected end ID"; return 0; } diff --git a/tests/capture/capture4.c b/tests/capture/capture4.c index 0d9685358..313086c97 100644 --- a/tests/capture/capture4.c +++ b/tests/capture/capture4.c @@ -221,20 +221,20 @@ check(const struct fsm *fsm, const char *string, { int gres; - fsm_end_id_t id_buf[2]; + fsm_end_id_t ids[2]; - gres = fsm_endid_get(fsm, end, 2, id_buf); + gres = fsm_endid_get(fsm, end, 2, ids); if (gres != 1) { assert(!"fsm_getendids failed"); } if (expected_ends == 0x2) { assert(fsm_endid_count(fsm, end) == 1); - assert(id_buf[0] == 1); + assert(ids[0] == 1); } else if (expected_ends == 0x3) { assert(fsm_endid_count(fsm, end) == 2); - assert(id_buf[0] == 0); - assert(id_buf[1] == 1); + assert(ids[0] == 0); + assert(ids[1] == 1); } else { assert(!"test not handled"); } diff --git a/tests/endids/endids0.c b/tests/endids/endids0.c index 2bbe6a237..c9117c0b0 100644 --- a/tests/endids/endids0.c +++ b/tests/endids/endids0.c @@ -43,7 +43,7 @@ int main(void) // memset(all_endids, 0, sizeof all_endids); for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { - fsm_end_id_t endid = 0; + fsm_end_id_t id = 0; int ret; assert( fsm_endid_count(fsm, state_ind) == 1); @@ -52,10 +52,10 @@ int main(void) fsm, state_ind, 1, - &endid); + &id); assert(ret == 1); - assert(endid == 1); + assert(id == 1); nend++; } @@ -84,26 +84,26 @@ int main(void) }; for (i=0; i < sizeof matches / sizeof matches[0]; i++) { - fsm_end_id_t *end_ids; - size_t num_end_ids; + fsm_end_id_t *ids; + size_t count; - end_ids = NULL; - num_end_ids = 0; - ret = match_string(fsm, matches[i].s, NULL, &end_ids, &num_end_ids); + ids = NULL; + count = 0; + ret = match_string(fsm, matches[i].s, NULL, &ids, &count); if (matches[i].should_match) { assert( ret == 1 ); - assert( end_ids != NULL ); - assert( end_ids[0] = 1 ); - assert( num_end_ids == 1 ); - assert( end_ids[0] = matches[i].endid ); + assert( ids != NULL ); + assert( ids[0] = 1 ); + assert( count == 1 ); + assert( ids[0] = matches[i].endid ); } else { assert( ret == 0 ); - assert( end_ids == NULL ); - assert( num_end_ids == 0 ); + assert( ids == NULL ); + assert( count == 0 ); } - free(end_ids); + free(ids); } } diff --git a/tests/endids/endids0_many_endids.c b/tests/endids/endids0_many_endids.c index 62f52e1a2..0af45112b 100644 --- a/tests/endids/endids0_many_endids.c +++ b/tests/endids/endids0_many_endids.c @@ -39,18 +39,18 @@ int main(void) * * 17 endids. This should force the array of end ids to resize. */ - static const fsm_end_id_t all_end_ids[17] = { + static const fsm_end_id_t all_ids[17] = { 4, 17, 6, 18, 2, 63, 14, 62, 3, 37, 46, 7, 9, 72, 67, 36, 1, }; - static const fsm_end_id_t sorted_all_end_ids[17] = { + static const fsm_end_id_t sorted_all_ids[17] = { 1, 2, 3, 4, 6, 7, 9, 14, 17, 18, 36, 37, 46, 62, 63, 67, 72, }; - for (size_t i=0; i < sizeof all_end_ids / sizeof all_end_ids[0]; i++) { - ret = fsm_setendid(fsm, all_end_ids[i]); + for (size_t i=0; i < sizeof all_ids / sizeof all_ids[0]; i++) { + ret = fsm_setendid(fsm, all_ids[i]); assert(ret == 1); } @@ -69,28 +69,28 @@ int main(void) assert(end_state < nstates); - assert(fsm_endid_count(fsm, end_state) == sizeof all_end_ids / sizeof all_end_ids[0]); - for (i=0; i < sizeof all_end_ids / sizeof all_end_ids[0]; i++) { + assert(fsm_endid_count(fsm, end_state) == sizeof all_ids / sizeof all_ids[0]); + for (i=0; i < sizeof all_ids / sizeof all_ids[0]; i++) { /* add duplicate end ids */ - ret = fsm_setendid(fsm, all_end_ids[i]); + ret = fsm_setendid(fsm, all_ids[i]); /* fsm_setendid should succeed */ assert(ret == 1); /* but it shouldn't add a duplicate id */ - assert(fsm_endid_count(fsm, end_state) == sizeof all_end_ids / sizeof all_end_ids[0]); + assert(fsm_endid_count(fsm, end_state) == sizeof all_ids / sizeof all_ids[0]); } nend = 0; for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { - fsm_end_id_t endids[sizeof all_end_ids / sizeof all_end_ids[0]]; + fsm_end_id_t endids[sizeof all_ids / sizeof all_ids[0]]; size_t i; int ret; memset(&endids[0], 0, sizeof endids); - assert(fsm_endid_count(fsm, state_ind) == sizeof all_end_ids / sizeof all_end_ids[0]); + assert(fsm_endid_count(fsm, state_ind) == sizeof all_ids / sizeof all_ids[0]); ret = fsm_endid_get( fsm, @@ -105,13 +105,13 @@ int main(void) sizeof endids / sizeof endids[0], sizeof endids[0], cmp_endids); for (i=0; i < fsm_endid_count(fsm, state_ind); i++) { - assert(endids[i] == sorted_all_end_ids[i]); + assert(endids[i] == sorted_all_ids[i]); } #if 0 /* endids should be sorted */ for (i=0; i < nwritten; i++) { - assert(endids[i] == sorted_all_end_ids[i]); + assert(endids[i] == sorted_all_ids[i]); } #endif /* 0 */ @@ -141,38 +141,38 @@ int main(void) }; for (i=0; i < sizeof matches / sizeof matches[0]; i++) { - fsm_end_id_t *end_ids; - size_t num_end_ids; + fsm_end_id_t *ids; + size_t count; - end_ids = NULL; - num_end_ids = 0; - ret = match_string(fsm, matches[i].s, NULL, &end_ids, &num_end_ids); + ids = NULL; + count = 0; + ret = match_string(fsm, matches[i].s, NULL, &ids, &count); if (matches[i].should_match) { size_t j; assert( ret == 1 ); - assert( end_ids != NULL ); - assert( num_end_ids == sizeof all_end_ids / sizeof all_end_ids[0] ); + assert( ids != NULL ); + assert( count == sizeof all_ids / sizeof all_ids[0] ); #if 0 - assert( end_ids[0] == 1 ); - assert( end_ids[0] == matches[i].endid ); + assert( ids[0] == 1 ); + assert( ids[0] == matches[i].endid ); #endif /* 0 */ /* sort endids and compare */ - qsort(&end_ids[0], num_end_ids, sizeof end_ids[0], cmp_endids); + qsort(&ids[0], count, sizeof ids[0], cmp_endids); - for (j=0; j < num_end_ids; j++) { - assert(end_ids[j] == sorted_all_end_ids[j]); + for (j=0; j < count; j++) { + assert(ids[j] == sorted_all_ids[j]); } } else { assert( ret == 0 ); - assert( end_ids == NULL ); - assert( num_end_ids == 0 ); + assert( ids == NULL ); + assert( count == 0 ); } - free(end_ids); + free(ids); } } diff --git a/tests/endids/endids1_determinise.c b/tests/endids/endids1_determinise.c index 3ce6f6b0f..3860aefca 100644 --- a/tests/endids/endids1_determinise.c +++ b/tests/endids/endids1_determinise.c @@ -75,26 +75,26 @@ int main(void) }; for (i=0; i < sizeof matches / sizeof matches[0]; i++) { - fsm_end_id_t *end_ids; - size_t num_end_ids; + fsm_end_id_t *ids; + size_t count; - end_ids = NULL; - num_end_ids = 0; - ret = match_string(fsm, matches[i].s, NULL, &end_ids, &num_end_ids); + ids = NULL; + count = 0; + ret = match_string(fsm, matches[i].s, NULL, &ids, &count); if (matches[i].should_match) { assert( ret == 1 ); - assert( end_ids != NULL ); - assert( end_ids[0] = 1 ); - assert( num_end_ids == 1 ); - assert( end_ids[0] = matches[i].endid ); + assert( ids != NULL ); + assert( ids[0] = 1 ); + assert( count == 1 ); + assert( ids[0] = matches[i].endid ); } else { assert( ret == 0 ); - assert( end_ids == NULL ); - assert( num_end_ids == 0 ); + assert( ids == NULL ); + assert( count == 0 ); } - free(end_ids); + free(ids); } } diff --git a/tests/endids/endids1_determinise_and_minimise.c b/tests/endids/endids1_determinise_and_minimise.c index a62d7979b..bb0711905 100644 --- a/tests/endids/endids1_determinise_and_minimise.c +++ b/tests/endids/endids1_determinise_and_minimise.c @@ -80,26 +80,26 @@ int main(void) }; for (i=0; i < sizeof matches / sizeof matches[0]; i++) { - fsm_end_id_t *end_ids; - size_t num_end_ids; + fsm_end_id_t *ids; + size_t count; - end_ids = NULL; - num_end_ids = 0; - ret = match_string(fsm, matches[i].s, NULL, &end_ids, &num_end_ids); + ids = NULL; + count = 0; + ret = match_string(fsm, matches[i].s, NULL, &ids, &count); if (matches[i].should_match) { assert( ret == 1 ); - assert( end_ids != NULL ); - assert( end_ids[0] = 1 ); - assert( num_end_ids == 1 ); - assert( end_ids[0] = matches[i].endid ); + assert( ids != NULL ); + assert( ids[0] = 1 ); + assert( count == 1 ); + assert( ids[0] = matches[i].endid ); } else { assert( ret == 0 ); - assert( end_ids == NULL ); - assert( num_end_ids == 0 ); + assert( ids == NULL ); + assert( count == 0 ); } - free(end_ids); + free(ids); } } diff --git a/tests/endids/endids2_union.c b/tests/endids/endids2_union.c index e939c5474..c990e7c95 100644 --- a/tests/endids/endids2_union.c +++ b/tests/endids/endids2_union.c @@ -143,33 +143,33 @@ int main(void) }; for (i=0; i < sizeof matches / sizeof matches[0]; i++) { - fsm_end_id_t *end_ids; - size_t num_end_ids; + fsm_end_id_t *ids; + size_t count; - end_ids = NULL; - num_end_ids = 0; - ret = match_string(comb, matches[i].s, NULL, &end_ids, &num_end_ids); + ids = NULL; + count = 0; + ret = match_string(comb, matches[i].s, NULL, &ids, &count); if (matches[i].should_match) { size_t j; assert( ret == 1 ); - assert( end_ids != NULL ); + assert( ids != NULL ); - assert( num_end_ids == matches[i].count ); + assert( count == matches[i].count ); - qsort(&end_ids[0], num_end_ids, sizeof end_ids[0], cmp_endids); + qsort(&ids[0], count, sizeof ids[0], cmp_endids); - for (j=0; j < num_end_ids; j++) { - assert( end_ids[j] == matches[i].endid[j] ); + for (j=0; j < count; j++) { + assert( ids[j] == matches[i].endid[j] ); } } else { assert( ret == 0 ); - assert( end_ids == NULL ); - assert( num_end_ids == 0 ); + assert( ids == NULL ); + assert( count == 0 ); } - free(end_ids); + free(ids); } } diff --git a/tests/endids/endids2_union_many_endids.c b/tests/endids/endids2_union_many_endids.c index 830421e66..deafcff1e 100644 --- a/tests/endids/endids2_union_many_endids.c +++ b/tests/endids/endids2_union_many_endids.c @@ -121,18 +121,18 @@ size_t generate_examples(struct example_list *l, const struct fsm *fsm, size_t p return (first_index != SIZE_MAX) ? first_index : 0; } -/* test that endids correctly propagate through union, determinise, and minimise */ +/* test that ids correctly propagate through union, determinise, and minimise */ int main(void) { struct fsm *fsm; - fsm_end_id_t all_endids[NUM_PATTERNS]; + fsm_end_id_t all_ids[NUM_PATTERNS]; size_t nstates, state_ind; size_t i; int ret; struct example_list example_list; - memset(all_endids, 0, sizeof all_endids); + memset(all_ids, 0, sizeof all_ids); init_examples(&example_list); @@ -176,27 +176,27 @@ int main(void) ret = fsm_determinise(fsm); assert(ret != 0); - // find end states, make sure we have multiple end states and they each have endids + // find end states, make sure we have multiple end states and they each have ids nstates = fsm_countstates(fsm); for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { int tested_pattern[NUM_PATTERNS]; - fsm_end_id_t endids[NUM_ENDIDS_TOTAL]; + fsm_end_id_t ids[NUM_ENDIDS_TOTAL]; size_t count, j; int ret; - memset(&endids[0], 0, sizeof endids); + memset(&ids[0], 0, sizeof ids); count = fsm_endid_count(fsm, state_ind); - assert(count > 0 && count <= sizeof endids/sizeof endids[0]); + assert(count > 0 && count <= sizeof ids/sizeof ids[0]); ret = fsm_endid_get( fsm, state_ind, - sizeof endids/sizeof endids[0], - &endids[0]); + sizeof ids/sizeof ids[0], + &ids[0]); assert(ret == 1); @@ -205,7 +205,7 @@ int main(void) for (j=0; j < count; j++) { size_t k, pattern_index; - pattern_index = (endids[j] - 1)/NUM_ENDIDS_PER_PATTERN; + pattern_index = (ids[j] - 1)/NUM_ENDIDS_PER_PATTERN; assert(pattern_index < NUM_PATTERNS); if (tested_pattern[pattern_index]) { @@ -224,11 +224,11 @@ int main(void) if (ret) { #if 0 printf("end state %zu (end id %u) matches example \"%s\" from pattern /%s/\n", - state_ind, endids[j], ex->example, patterns[pattern_index]); + state_ind, ids[j], ex->example, patterns[pattern_index]); #endif /* 0 */ } else { printf("end state %zu (end id %u) does NOT match example \"%s\" from pattern /%s/\n", - state_ind, endids[j], ex->example, patterns[pattern_index]); + state_ind, ids[j], ex->example, patterns[pattern_index]); abort(); } } @@ -240,17 +240,17 @@ int main(void) assert(ret != 0); /* fsm_minimise should not collapse all the end states to a - * single end state, because they have distinct endids. */ + * single end state, because they have distinct ids. */ assert( fsm_count(fsm, fsm_isend) > 1); nstates = fsm_countstates(fsm); for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { - fsm_end_id_t endids[NUM_ENDIDS_TOTAL]; + fsm_end_id_t ids[NUM_ENDIDS_TOTAL]; size_t count; int ret; - memset(&endids[0], 0, sizeof endids); + memset(&ids[0], 0, sizeof ids); count = fsm_endid_count(fsm, state_ind); @@ -259,8 +259,8 @@ int main(void) ret = fsm_endid_get( fsm, state_ind, - sizeof endids/sizeof endids[0], - &endids[0]); + sizeof ids/sizeof ids[0], + &ids[0]); assert(ret == 1); } diff --git a/tests/endids/endids4.c b/tests/endids/endids4.c index 64838cc83..80afbcc39 100644 --- a/tests/endids/endids4.c +++ b/tests/endids/endids4.c @@ -134,33 +134,33 @@ int main(void) }; for (i=0; i < sizeof matches / sizeof matches[0]; i++) { - fsm_end_id_t *end_ids; - size_t num_end_ids; + fsm_end_id_t *ids; + size_t count; - end_ids = NULL; - num_end_ids = 0; - ret = match_string(comb, matches[i].s, NULL, &end_ids, &num_end_ids); + ids = NULL; + count = 0; + ret = match_string(comb, matches[i].s, NULL, &ids, &count); if (matches[i].should_match) { size_t j; assert( ret == 1 ); - assert( end_ids != NULL ); + assert( ids != NULL ); - assert( num_end_ids == matches[i].count ); + assert( count == matches[i].count ); - qsort(&end_ids[0], num_end_ids, sizeof end_ids[0], cmp_endids); + qsort(&ids[0], count, sizeof ids[0], cmp_endids); - for (j=0; j < num_end_ids; j++) { - assert( end_ids[j] == matches[i].endid[j] ); + for (j=0; j < count; j++) { + assert( ids[j] == matches[i].endid[j] ); } } else { assert( ret == 0 ); - assert( end_ids == NULL ); - assert( num_end_ids == 0 ); + assert( ids == NULL ); + assert( count == 0 ); } - free(end_ids); + free(ids); } } diff --git a/tests/endids/endids5.c b/tests/endids/endids5.c index 2fce9ea92..d6a713843 100644 --- a/tests/endids/endids5.c +++ b/tests/endids/endids5.c @@ -134,12 +134,12 @@ int main(void) }; for (i=0; i < sizeof matches / sizeof matches[0]; i++) { - fsm_end_id_t *end_ids; - size_t num_end_ids; + fsm_end_id_t *ids; + size_t count; - end_ids = NULL; - num_end_ids = 0; - ret = match_string(comb, matches[i].s, NULL, &end_ids, &num_end_ids); + ids = NULL; + count = 0; + ret = match_string(comb, matches[i].s, NULL, &ids, &count); printf("match %zu, \"%s\", should_match=%d, count=%zu, endids={ %u, %u }\n", i, matches[i].s, matches[i].should_match, matches[i].count, @@ -149,22 +149,22 @@ int main(void) size_t j; assert( ret == 1 ); - assert( end_ids != NULL ); + assert( ids != NULL ); - assert( num_end_ids == matches[i].count ); + assert( count == matches[i].count ); - qsort(&end_ids[0], num_end_ids, sizeof end_ids[0], cmp_endids); + qsort(&ids[0], count, sizeof ids[0], cmp_endids); - for (j=0; j < num_end_ids; j++) { - assert( end_ids[j] == matches[i].endid[j] ); + for (j=0; j < count; j++) { + assert( ids[j] == matches[i].endid[j] ); } } else { assert( ret == 0 ); - assert( end_ids == NULL ); - assert( num_end_ids == 0 ); + assert( ids == NULL ); + assert( count == 0 ); } - free(end_ids); + free(ids); } } diff --git a/tests/endids/endids6.c b/tests/endids/endids6.c index 77976991c..34b261118 100644 --- a/tests/endids/endids6.c +++ b/tests/endids/endids6.c @@ -20,33 +20,33 @@ struct state_info { fsm_state_t state; unsigned count; - fsm_end_id_t endids[2]; + fsm_end_id_t ids[2]; }; /* remap 1 -> 512, 2 -> 1024 */ static int -endid_remap_func(fsm_state_t state, size_t num_ids, fsm_end_id_t *endids, size_t *num_written, void *opaque) +endid_remap_func(fsm_state_t state, size_t count, fsm_end_id_t *ids, size_t *num_written, void *opaque) { size_t i; (void)state; (void)opaque; - assert(endids != NULL); - for (i=0; i < num_ids; i++) { - fsm_end_id_t orig = endids[i]; + assert(ids != NULL); + for (i=0; i < count; i++) { + fsm_end_id_t orig = ids[i]; - switch (endids[i]) { - case 1: endids[i] = 512; break; - case 2: endids[i] = 1024; break; + switch (ids[i]) { + case 1: ids[i] = 512; break; + case 2: ids[i] = 1024; break; default: break; } printf("remap: state %u id %u -> %u\n", - (unsigned)state, (unsigned)orig, (unsigned)endids[i]); + (unsigned)state, (unsigned)orig, (unsigned)ids[i]); } - *num_written = num_ids; + *num_written = count; return 1; } @@ -91,7 +91,7 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { - fsm_end_id_t endids[2] = {0,0}; + fsm_end_id_t ids[2] = {0,0}; size_t count; int ret; @@ -102,8 +102,8 @@ int main(void) ret = fsm_endid_get( fsm, state_ind, - sizeof endids / sizeof endids[0], - &endids[0]); + sizeof ids / sizeof ids[0], + &ids[0]); assert(ret == 1); @@ -111,13 +111,13 @@ int main(void) info[ninfo].count = count; if (count == 1) { - assert(endids[0] == 1 || endids[0] == 2); - info[ninfo].endids[0] = endids[0]; + assert(ids[0] == 1 || ids[0] == 2); + info[ninfo].ids[0] = ids[0]; } else if (count == 2) { - qsort(&endids[0], count, sizeof endids[0], cmp_endids); - assert(endids[0] == 1 && endids[1] == 2); - info[ninfo].endids[0] = endids[0]; - info[ninfo].endids[1] = endids[1]; + qsort(&ids[0], count, sizeof ids[0], cmp_endids); + assert(ids[0] == 1 && ids[1] == 2); + info[ninfo].ids[0] = ids[0]; + info[ninfo].ids[1] = ids[1]; } ninfo++; @@ -132,7 +132,7 @@ int main(void) for (state_ind = 0, info_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { - fsm_end_id_t endids[2] = {0,0}; + fsm_end_id_t ids[2] = {0,0}; size_t count, ind; int ret; @@ -146,18 +146,18 @@ int main(void) ret = fsm_endid_get( fsm, state_ind, - sizeof endids / sizeof endids[0], - &endids[0]); + sizeof ids / sizeof ids[0], + &ids[0]); assert(ret == 1); if (count > 1) { - qsort(&endids[0], count, sizeof endids[0], cmp_endids); + qsort(&ids[0], count, sizeof ids[0], cmp_endids); } for (ind=0; ind < count; ind++) { - fsm_end_id_t expected = info[info_ind].endids[ind]; - switch (info[info_ind].endids[ind]) { + fsm_end_id_t expected = info[info_ind].ids[ind]; + switch (info[info_ind].ids[ind]) { case 1: expected = 512; break; case 2: expected = 1024; break; default: @@ -165,8 +165,8 @@ int main(void) break; } - printf("state %u, id %u, expected %u\n", (unsigned)state_ind, endids[ind], expected); - assert(endids[ind] == expected); + printf("state %u, id %u, expected %u\n", (unsigned)state_ind, ids[ind], expected); + assert(ids[ind] == expected); } info_ind++; diff --git a/tests/endids/endids7.c b/tests/endids/endids7.c index 451cf342a..6508308eb 100644 --- a/tests/endids/endids7.c +++ b/tests/endids/endids7.c @@ -20,40 +20,40 @@ struct state_info { fsm_state_t state; unsigned count; - fsm_end_id_t endids[2]; + fsm_end_id_t ids[2]; }; /* remap 1 -> 7, 2 -> 9, both 1&2 -> 3 */ static int -endid_remap_func(fsm_state_t state, size_t num_ids, fsm_end_id_t *endids, size_t *num_written, void *opaque) +endid_remap_func(fsm_state_t state, size_t num_ids, fsm_end_id_t *ids, size_t *num_written, void *opaque) { (void)state; (void)opaque; - assert(endids != NULL); + assert(ids != NULL); assert(num_ids > 0 && num_ids <= 2); if (num_ids > 1) { - endids[0] = 3; + ids[0] = 3; *num_written = 1; printf("remap: state %u with %zu endids, set to one endid, value %u\n", - (unsigned)state, num_ids, (unsigned)endids[0]); + (unsigned)state, num_ids, (unsigned)ids[0]); return 1; } if (num_ids == 1) { - fsm_end_id_t orig = endids[0]; + fsm_end_id_t orig = ids[0]; - switch (endids[0]) { - case 1: endids[0] = 7; break; - case 2: endids[0] = 9; break; + switch (ids[0]) { + case 1: ids[0] = 7; break; + case 2: ids[0] = 9; break; default: break; } printf("remap: state %u id %u -> %u\n", - (unsigned)state, (unsigned)orig, (unsigned)endids[0]); + (unsigned)state, (unsigned)orig, (unsigned)ids[0]); } *num_written = num_ids; @@ -103,7 +103,7 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { - fsm_end_id_t endids[2] = {0,0}; + fsm_end_id_t ids[2] = {0,0}; size_t count; int ret; @@ -114,8 +114,8 @@ int main(void) ret = fsm_endid_get( fsm, state_ind, - sizeof endids / sizeof endids[0], - &endids[0]); + sizeof ids / sizeof ids[0], + &ids[0]); assert(ret == 1); @@ -123,13 +123,13 @@ int main(void) info[ninfo].count = count; if (count == 1) { - assert(endids[0] == 1 || endids[0] == 2); - info[ninfo].endids[0] = endids[0]; + assert(ids[0] == 1 || ids[0] == 2); + info[ninfo].ids[0] = ids[0]; } else if (count == 2) { - qsort(&endids[0], count, sizeof endids[0], cmp_endids); - assert(endids[0] == 1 && endids[1] == 2); - info[ninfo].endids[0] = endids[0]; - info[ninfo].endids[1] = endids[1]; + qsort(&ids[0], count, sizeof ids[0], cmp_endids); + assert(ids[0] == 1 && ids[1] == 2); + info[ninfo].ids[0] = ids[0]; + info[ninfo].ids[1] = ids[1]; } ninfo++; @@ -144,7 +144,7 @@ int main(void) for (state_ind = 0, info_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { - fsm_end_id_t endid = 0; + fsm_end_id_t id = 0; fsm_end_id_t expected; size_t count; int ret; @@ -158,22 +158,22 @@ int main(void) fsm, state_ind, 1, - &endid); + &id); assert(ret == 1); if (info[info_ind].count == 2) { expected = 3; - } else if (info[info_ind].endids[0] == 1) { + } else if (info[info_ind].ids[0] == 1) { expected = 7; - } else if (info[info_ind].endids[0] == 2) { + } else if (info[info_ind].ids[0] == 2) { expected = 9; } else { assert( ! "unexpected value" ); } - printf("state %u, id %u, expected %u\n", (unsigned)state_ind, endid, expected); - assert(endid == expected);; + printf("state %u, id %u, expected %u\n", (unsigned)state_ind, id, expected); + assert(id == expected);; info_ind++; } diff --git a/tests/endids/endids7_with_duplicates.c b/tests/endids/endids7_with_duplicates.c index 40acaac8b..6b01d5f15 100644 --- a/tests/endids/endids7_with_duplicates.c +++ b/tests/endids/endids7_with_duplicates.c @@ -20,44 +20,44 @@ struct state_info { fsm_state_t state; unsigned count; - fsm_end_id_t endids[2]; + fsm_end_id_t ids[2]; }; /* remap 1 -> 7, 2 -> 9, both 1&2 -> 3,3 */ static int -endid_remap_func(fsm_state_t state, size_t num_ids, fsm_end_id_t *endids, size_t *num_written, void *opaque) +endid_remap_func(fsm_state_t state, size_t num_ids, fsm_end_id_t *ids, size_t *num_written, void *opaque) { (void)state; (void)opaque; - assert(endids != NULL); + assert(ids != NULL); assert(num_ids > 0 && num_ids <= 2); if (num_ids > 1) { size_t i; for (i = 0; i < num_ids; i++) { - endids[i] = 3; + ids[i] = 3; } *num_written = num_ids; printf("remap: state %u with %zu endids, set to %zu endid, value %u\n", - (unsigned)state, num_ids, *num_written, (unsigned)endids[0]); + (unsigned)state, num_ids, *num_written, (unsigned) ids[0]); return 1; } if (num_ids == 1) { - fsm_end_id_t orig = endids[0]; + fsm_end_id_t orig = ids[0]; - switch (endids[0]) { - case 1: endids[0] = 7; break; - case 2: endids[0] = 9; break; + switch (ids[0]) { + case 1: ids[0] = 7; break; + case 2: ids[0] = 9; break; default: break; } printf("remap: state %u id %u -> %u\n", - (unsigned)state, (unsigned)orig, (unsigned)endids[0]); + (unsigned)state, (unsigned)orig, (unsigned) ids[0]); } *num_written = num_ids; @@ -107,7 +107,7 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { - fsm_end_id_t endids[2] = {0,0}; + fsm_end_id_t ids[2] = {0,0}; size_t count; int ret; @@ -118,8 +118,8 @@ int main(void) ret = fsm_endid_get( fsm, state_ind, - sizeof endids / sizeof endids[0], - &endids[0]); + sizeof ids / sizeof ids[0], + &ids[0]); assert(ret == 1); @@ -127,13 +127,13 @@ int main(void) info[ninfo].count = count; if (count == 1) { - assert(endids[0] == 1 || endids[0] == 2); - info[ninfo].endids[0] = endids[0]; + assert(ids[0] == 1 || ids[0] == 2); + info[ninfo].ids[0] = ids[0]; } else if (count == 2) { - qsort(&endids[0], count, sizeof endids[0], cmp_endids); - assert(endids[0] == 1 && endids[1] == 2); - info[ninfo].endids[0] = endids[0]; - info[ninfo].endids[1] = endids[1]; + qsort(&ids[0], count, sizeof ids[0], cmp_endids); + assert(ids[0] == 1 && ids[1] == 2); + info[ninfo].ids[0] = ids[0]; + info[ninfo].ids[1] = ids[1]; } ninfo++; @@ -168,9 +168,9 @@ int main(void) if (info[info_ind].count == 2) { expected = 3; - } else if (info[info_ind].endids[0] == 1) { + } else if (info[info_ind].ids[0] == 1) { expected = 7; - } else if (info[info_ind].endids[0] == 2) { + } else if (info[info_ind].ids[0] == 2) { expected = 9; } else { assert( ! "unexpected value" ); diff --git a/tests/endids/endids8.c b/tests/endids/endids8.c index dedd750b0..86a2b28c8 100644 --- a/tests/endids/endids8.c +++ b/tests/endids/endids8.c @@ -24,7 +24,7 @@ int main(void) const char *s1, *s2; int ret; - fsm_end_id_t all_endids[2]; + fsm_end_id_t all_ids[2]; unsigned nstates, state_ind; s1 = "abc"; fsm1 = re_comp(RE_NATIVE, fsm_sgetc, &s1, NULL, 0, NULL); @@ -69,10 +69,10 @@ int main(void) nstates = fsm_countstates(comb); // all end states should have BOTH endids - memset(all_endids, 0, sizeof all_endids); + memset(all_ids, 0, sizeof all_ids); for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(comb, state_ind)) { - fsm_end_id_t endids[3] = {0,0,0}; + fsm_end_id_t ids[3] = {0,0,0}; size_t count; int ret; @@ -85,13 +85,13 @@ int main(void) ret = fsm_endid_get( comb, state_ind, - sizeof endids / sizeof endids[0], - &endids[0]); + sizeof ids / sizeof ids[0], + &ids[0]); assert(ret == 1); - qsort(&endids[0], count, sizeof endids[0], cmp_endids); - assert(endids[0] == 1 && endids[1] == 2 && endids[2] == 4); + qsort(&ids[0], count, sizeof ids[0], cmp_endids); + assert(ids[0] == 1 && ids[1] == 2 && ids[2] == 4); } } diff --git a/tests/endids/endids9.c b/tests/endids/endids9.c index 38328f5a4..33a872155 100644 --- a/tests/endids/endids9.c +++ b/tests/endids/endids9.c @@ -20,7 +20,7 @@ struct state_info { fsm_state_t state; unsigned count; - fsm_end_id_t endids[2]; + fsm_end_id_t ids[2]; }; /* use fsm_increndids to change the endids before a union/intersection */ @@ -71,7 +71,7 @@ int main(void) for (state_ind = 0; state_ind < nstates; state_ind++) { if (fsm_isend(fsm, state_ind)) { - fsm_end_id_t endids[2] = {0,0}; + fsm_end_id_t ids[2] = {0,0}; size_t count; int ret; @@ -82,8 +82,8 @@ int main(void) ret = fsm_endid_get( fsm, state_ind, - sizeof endids / sizeof endids[0], - &endids[0]); + sizeof ids / sizeof ids[0], + &ids[0]); assert(ret == 1); @@ -91,13 +91,13 @@ int main(void) info[ninfo].count = count; if (count == 1) { - assert(endids[0] == 11 || endids[0] == 12); - info[ninfo].endids[0] = endids[0]; + assert(ids[0] == 11 || ids[0] == 12); + info[ninfo].ids[0] = ids[0]; } else if (count == 2) { - qsort(&endids[0], count, sizeof endids[0], cmp_endids); - assert(endids[0] == 11 && endids[1] == 12); - info[ninfo].endids[0] = endids[0]; - info[ninfo].endids[1] = endids[1]; + qsort(&ids[0], count, sizeof ids[0], cmp_endids); + assert(ids[0] == 11 && ids[1] == 12); + info[ninfo].ids[0] = ids[0]; + info[ninfo].ids[1] = ids[1]; } ninfo++; diff --git a/tests/endids/utils.c b/tests/endids/utils.c index a5d96f020..882df92c4 100644 --- a/tests/endids/utils.c +++ b/tests/endids/utils.c @@ -4,7 +4,7 @@ #include int -match_string(const struct fsm *fsm, const char *s, fsm_state_t *end_ptr, fsm_end_id_t **endids_ptr, size_t *count_ptr) +match_string(const struct fsm *fsm, const char *s, fsm_state_t *end_ptr, fsm_end_id_t **ids_ptr, size_t *count_ptr) { fsm_state_t end = 0; int ret; @@ -21,25 +21,25 @@ match_string(const struct fsm *fsm, const char *s, fsm_state_t *end_ptr, fsm_end if (count > 0) { int ret; - fsm_end_id_t *endids = calloc(count, sizeof *endids); - if (endids == NULL) { + fsm_end_id_t *ids = calloc(count, sizeof *ids); + if (ids == NULL) { return -1; } - ret = fsm_endid_get(fsm, end, count, endids); + ret = fsm_endid_get(fsm, end, count, ids); if (ret == 0) { - free(endids); + free(ids); errno = EINVAL; return -1; } - if (endids_ptr != NULL) { - *endids_ptr = endids; + if (ids_ptr != NULL) { + *ids_ptr = ids; if (count_ptr != NULL) { *count_ptr = count; } } else { - free(endids); + free(ids); } } } diff --git a/tests/gen/gtest.c b/tests/gen/gtest.c index 53fc89602..124c8be1b 100644 --- a/tests/gen/gtest.c +++ b/tests/gen/gtest.c @@ -58,9 +58,9 @@ gtest_matches_cb(const struct fsm *fsm, m->found = true; #define ID_BUF_COUNT 1 - fsm_end_id_t id_buf[ID_BUF_COUNT]; + fsm_end_id_t ids[ID_BUF_COUNT]; int gres = fsm_endid_get(fsm, - end_state, ID_BUF_COUNT, id_buf); + end_state, ID_BUF_COUNT, ids); if (gres != 1) { fprintf(stderr, @@ -69,9 +69,9 @@ gtest_matches_cb(const struct fsm *fsm, return FSM_GENERATE_MATCHES_CB_RES_HALT; } - if (fsm_endid_count(fsm, end_state) != 1 || id_buf[0] != m_i) { + if (fsm_endid_count(fsm, end_state) != 1 || ids[0] != m_i) { fprintf(stderr, "ERROR: endid mismatch, expected %zu, got %u\n", - m_i, id_buf[0]); + m_i, ids[0]); return FSM_GENERATE_MATCHES_CB_RES_HALT; } diff --git a/tests/re_strings/testutil.c b/tests/re_strings/testutil.c index 59d972512..50cc21be0 100644 --- a/tests/re_strings/testutil.c +++ b/tests/re_strings/testutil.c @@ -12,7 +12,7 @@ static struct fsm_options opt; #define MAX_INPUTS 100 -static fsm_end_id_t id_buf[MAX_INPUTS]; +static fsm_end_id_t ids[MAX_INPUTS]; int run_test(const char **strings) @@ -48,11 +48,11 @@ run_test(const char **strings) assert(res > 0); /* match */ int eres = fsm_endid_get(fsm, end, - MAX_INPUTS, id_buf); + MAX_INPUTS, ids); assert(eres == 1); bool found = false; for (size_t i = 0; i < fsm_endid_count(fsm, end); i++) { - if (id_buf[i] == id) { + if (ids[i] == id) { found = true; break; }
S%u%s
"); + if (-1 == opt->endleaf(f, + cs->endids.ids, cs->endids.count, + opt->endleaf_opaque)) + { + return -1; + } + fprintf(f, "