diff --git a/examples/bm/libfsm.c b/examples/bm/libfsm.c index 80b013d63..a7581bd59 100644 --- a/examples/bm/libfsm.c +++ b/examples/bm/libfsm.c @@ -61,7 +61,7 @@ main(int argc, char *argv[]) opt.io = FSM_IO_STR; p = argv[0]; - fsm = re_comp(RE_PCRE, fsm_sgetc, &p, &opt, flags, &e); + fsm = re_comp(RE_PCRE, fsm_sgetc, &p, NULL, flags, &e); if (fsm == NULL) { re_perror(RE_LITERAL, &e, NULL, s); return 1; @@ -80,7 +80,7 @@ main(int argc, char *argv[]) printf("#include \n"); printf("\n"); - fsm_print(stdout, fsm, FSM_PRINT_C); + fsm_print(stdout, fsm, &opt, NULL, FSM_PRINT_C); printf("int\n"); printf("main(void)\n"); diff --git a/examples/glob/main.c b/examples/glob/main.c index a5af0f317..65703352c 100644 --- a/examples/glob/main.c +++ b/examples/glob/main.c @@ -196,7 +196,7 @@ main(int argc, char *argv[]) } if (!quiet) { - fsm_print(stdout, fsm, FSM_PRINT_FSM); + fsm_print(stdout, fsm, NULL, NULL, FSM_PRINT_FSM); } matched = match(fsm, argv[1]); diff --git a/examples/iprange/main.c b/examples/iprange/main.c index 6ce49993b..ba028351b 100644 --- a/examples/iprange/main.c +++ b/examples/iprange/main.c @@ -88,6 +88,24 @@ RB_GENERATE_STATIC(recmap, record, entry, recmap_cmp) static unsigned nrecords; static struct fsm_options opt; +static struct fsm_hooks hooks; + +static struct record * +find_id(unsigned id) +{ + struct record *r; + + /* XXX: this is a crime, we have a tree. + * we should be able to RB_FIND() */ + RB_FOREACH(r, recmap, &recmap) { + if (r->id == id) { + return r; + } + } + + assert(!"unreached"); + abort(); +} static struct record * get_id(char *rec, size_t reclen) @@ -115,7 +133,7 @@ get_id(char *rec, size_t reclen) r->len = reclen; r->id = nrecords++; - r->fsm = fsm_new(&opt); + r->fsm = fsm_new(NULL); if (r->fsm == NULL) { perror("fsm_new"); exit(-1); @@ -133,7 +151,7 @@ get_id(char *rec, size_t reclen) } fsm_setend(r->fsm, r->end, 1); - for (size_t i = 0; i < sizeof r->regs; i++) { + for (size_t i = 0; i < sizeof r->regs / sizeof *r->regs; i++) { r->regs[i].c = '\0'; r->regs[i].s = fsm_none; } @@ -164,7 +182,7 @@ get_id(char *rec, size_t reclen) static void usage(void) { - fprintf(stderr, "ip2fsm -[46] [-f ] -l fmt\n" + fprintf(stderr, "iprange -[46] [-f ] -l fmt\n" "\t-4\t\tIPv4\n" "\t-6\t\tIPv6\n" "\t-f \tuse as input\n" @@ -378,6 +396,9 @@ handle_line(unsigned char *socts, unsigned char *eocts, unsigned noct, } socts[spos] = eocts[spos]; + + // XXX: not sure about this + break; } else { gen_range(r, noct, spos - 1, socts[spos], 255, socts); @@ -422,45 +443,69 @@ important(unsigned n) } static int -leaf(FILE *f, const fsm_end_id_t *ids, size_t count, const void *leaf_opaque) +conflict(FILE *f, const struct fsm_options *opt, + const fsm_end_id_t *ids, size_t count, + const char *example, void *hook_opaque) { - const struct record *r; + size_t i; - (void) leaf_opaque; + (void) f; + (void) hook_opaque; + (void) opt; - if (count != 1) { - fprintf(f, "endid conflict\n"); - exit(EXIT_FAILURE); - } + fprintf(stderr, "ambiguous matches for "); - r = (const void *) (intptr_t) ids[0]; /* XXX */ + for (i = 0; i < count; i++) { + const struct record *r; - if (r == NULL) { - fprintf(f, "return -1;"); - return 0; + r = (const void *) (intptr_t) ids[i]; /* XXX */ + + fprintf(stderr, "%s", r->rec); + + if (i + 1 < count) { + fprintf(stderr, ", "); + } + } + + if (example != NULL) { + fprintf(stderr, "; for example on input '%s'", example); } - fprintf(f, "return 0x%u; /* %s */", r->id, r->rec); + fprintf(stderr, "\n"); return 0; } static int -endleaf_dot(FILE *f, const fsm_end_id_t *ids, size_t count, const void *endleaf_opaque) +accept_dot(FILE *f, const struct fsm_options *opt, + const fsm_end_id_t *ids, size_t count, + void *lang_opaque, void *hook_opaque) { - const struct record *r; + fsm_state_t s; assert(f != NULL); - assert(endleaf_opaque == NULL); - (void) endleaf_opaque; + (void) hook_opaque; + + s = * (fsm_state_t *) lang_opaque; fprintf(f, "label = <"); + if (!opt->anonymous_states) { + fprintf(f, "%u", s); + + if (count > 0) { + fprintf(f, "
"); + } + } + for (size_t i = 0; i < count; i++) { - r = (const void *) (intptr_t) ids[i]; /* XXX */ + const struct record *r; + + r = find_id(ids[i]); fprintf(f, "%s", r->rec); /* XXX: escape */ + if (i + 1 < count) { fprintf(f, ", "); } @@ -471,6 +516,35 @@ endleaf_dot(FILE *f, const fsm_end_id_t *ids, size_t count, const void *endleaf_ return 0; } +static int +comment_c(FILE *f, const struct fsm_options *opt, + const fsm_end_id_t *ids, size_t count, + void *hook_opaque) +{ + assert(f != NULL); + + (void) opt; + (void) hook_opaque; + + fprintf(f, "/* "); + + for (size_t i = 0; i < count; i++) { + const struct record *r; + + r = find_id(ids[i]); + + fprintf(f, "%s", r->rec); /* XXX: escape */ + + if (i + 1 < count) { + fprintf(f, ", "); + } + } + + fprintf(f, " */\n"); + + return 0; +} + int main(int argc, char **argv) { @@ -481,12 +555,15 @@ main(int argc, char **argv) int oc = 0; int c; + opt.ambig = AMBIG_ERROR; opt.prefix = NULL; opt.always_hex = 1; opt.anonymous_states = 1; opt.consolidate_edges = 1; opt.case_ranges = 1; + hooks.conflict = conflict; + while (c = getopt(argc, argv, "46f:l:Q"), c != -1) { switch (c) { case '4': ipv = IPV4; break; @@ -531,7 +608,7 @@ main(int argc, char **argv) memset(ones, 0xff, sizeof ones); - fsm = fsm_new(&opt); + fsm = fsm_new(NULL); if (fsm == NULL) { perror("fsm_new"); return -1; @@ -634,23 +711,31 @@ main(int argc, char **argv) struct record *r; RB_FOREACH(r, recmap, &recmap) { + struct fsm_combine_info ci; fsm_state_t start; - if (fsm_minimise(r->fsm) == 0) { + if (!fsm_determinise(r->fsm)) { + perror("fsm_determinse"); + exit(-1); + } + + if (!fsm_minimise(r->fsm)) { perror("fsm_minimise"); exit(-1); } - fsm_setendid(r->fsm, (intptr_t) r); /* XXX */ + fsm_setendid(r->fsm, r->id); (void) fsm_getstart(r->fsm, &start); - fsm = fsm_merge(fsm, r->fsm, NULL); + fsm = fsm_merge(fsm, r->fsm, &ci); if (fsm == NULL) { perror("fsm_merge"); exit(-1); } + (void) ci; + if (!fsm_addedge_epsilon(fsm, fsm_start, start)) { perror("fsm_addedge_epsilon"); exit(-1); @@ -676,7 +761,7 @@ main(int argc, char **argv) tstart = time(NULL); } - if (!fsm_determinise(fsm) == 0) { + if (!fsm_determinise(fsm)) { perror("fsm_determinise"); exit(-1); } @@ -687,15 +772,13 @@ main(int argc, char **argv) } if (oc) { - opt.fragment = 1; - opt.cp = "c"; - opt.leaf = leaf; - opt.leaf_opaque = NULL; - fsm_print(stdout, fsm, FSM_PRINT_C); + opt.fragment = 1; + opt.comments = 1; + hooks.comment = comment_c; + fsm_print(stdout, fsm, &opt, &hooks, FSM_PRINT_C); } else if (odot) { - opt.endleaf = endleaf_dot; - opt.endleaf_opaque = NULL; - fsm_print(stdout, fsm, FSM_PRINT_DOT); + hooks.accept = accept_dot; + fsm_print(stdout, fsm, &opt, &hooks, FSM_PRINT_DOT); } } diff --git a/examples/utf8dfa/main.c b/examples/utf8dfa/main.c index d987575b3..811cd76c0 100644 --- a/examples/utf8dfa/main.c +++ b/examples/utf8dfa/main.c @@ -164,7 +164,7 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } - fsm = fsm_new(&opt); + fsm = fsm_new(NULL); if (fsm == NULL) { perror("fsm_new"); exit(1); @@ -215,12 +215,17 @@ main(int argc, char *argv[]) } } + if (!fsm_determinise(fsm)) { + perror("fsm_determinise"); + exit(1); + } + if (!fsm_minimise(fsm)) { perror("fsm_minimise"); exit(1); } - fsm_print(stdout, fsm, lang); + fsm_print(stdout, fsm, NULL, NULL, lang); fsm_free(fsm); diff --git a/examples/words/main.c b/examples/words/main.c index 1fe19ddf1..078848b78 100644 --- a/examples/words/main.c +++ b/examples/words/main.c @@ -86,7 +86,7 @@ int main(int argc, char *argv[]) { exit(EXIT_FAILURE); } } else { - fsm = fsm_new(&opt); + fsm = fsm_new(NULL); if (fsm == NULL) { perror("fsm_new"); return 1; @@ -127,7 +127,7 @@ int main(int argc, char *argv[]) { struct fsm *r; struct fsm_combine_info ci; - r = re_comp(native ? RE_NATIVE : RE_LITERAL, fsm_sgetc, &p, &opt, 0, &e); + r = re_comp(native ? RE_NATIVE : RE_LITERAL, fsm_sgetc, &p, NULL, 0, &e); if (r == NULL) { re_perror(native ? RE_NATIVE : RE_LITERAL, &e, NULL, s); return 1; @@ -168,7 +168,7 @@ int main(int argc, char *argv[]) { } fsm = re_strings_build(g, - &opt, unanchored ? 0 : (RE_STRINGS_ANCHOR_LEFT | RE_STRINGS_ANCHOR_RIGHT)); + NULL, unanchored ? 0 : (RE_STRINGS_ANCHOR_LEFT | RE_STRINGS_ANCHOR_RIGHT)); if (fsm == NULL) { perror("re_strings_builder_build"); exit(EXIT_FAILURE); @@ -211,7 +211,7 @@ int main(int argc, char *argv[]) { + ((long) post.tv_nsec - (long) pre.tv_nsec) / 1000000; } - fsm_print(stdout, fsm, lang); + fsm_print(stdout, fsm, &opt, NULL, lang); if (timing) { printf("construction, reduction, total: %lu, %lu, %lu\n", ms, mt, ms + mt);