From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- support/dktools/dkct-au.ctr | 1688 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1688 insertions(+) create mode 100644 support/dktools/dkct-au.ctr (limited to 'support/dktools/dkct-au.ctr') diff --git a/support/dktools/dkct-au.ctr b/support/dktools/dkct-au.ctr new file mode 100644 index 0000000000..45046c9c5e --- /dev/null +++ b/support/dktools/dkct-au.ctr @@ -0,0 +1,1688 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2011-xxxx +license = bsd + + + +%% module + + +#if DK3_USE_WX +#include "dkwxtrace.h" +#else +#include "dkct.h" +#endif + + +$!trace-include + + + +/** Sort criteria:Sort by state and input. +*/ +#define DKCT_AU_RULE_SORT_STATE_INPUT 1 + +/** Sort criteria: Inverted search order. +*/ +#define DKCT_AU_RULE_SORT_REVERSE 2 + + + +/** Input file section for options. +*/ +#define DKCT_AU_SECTION_OPTIONS 0 + +/** Input file section for states. +*/ +#define DKCT_AU_SECTION_STATES 1 + +/** Input file section for inputs. +*/ +#define DKCT_AU_SECTION_INPUTS 2 + +/** Input file section for outputs. +*/ +#define DKCT_AU_SECTION_OUTPUTS 3 + +/** Input file section for rules. +*/ +#define DKCT_AU_SECTION_RULES 4 + + + +/** Section names. +*/ +static char const * const dkct_au_section_names[] = { +/* 0 */ "options", +/* 1 */ "states", +/* 2 */ "inputs", +/* 3 */ "outputs", +/* 4 */ "rules", +/* 5 */ "option", +/* 6 */ "state", +/* 7 */ "input", +/* 8 */ "output", +/* 9 */ "rule", +NULL +}; + + + +/** Keywords used by the module. +*/ +static char const * const dkct_au_kw8[] = { +/* 0 */ "*", +/* 1 */ "\n", +/* 2 */ " ", +/* 3 */ "#ifndef ", +/* 4 */ "#else\n", +/* 5 */ "#endif\n\n", +/* 6 */ "#define ", +/* 7 */ "#error \"Redefinition of ", +/* 8 */ "\"\n", +/* 9 */ " %d\n", +/* 10 */ " (%d)\n", +/* 11 */ "/** ", +/* 12 */ " */\n", +/* 13 */ "State: ", +/* 14 */ "State machine input: ", +/* 15 */ "State machine output: ", +/* 16 */ "state_machine_%lu", +/* 17 */ "/** @defgroup dkct_state_machine_", +/* 18 */ " The ", +/* 19 */ " state machine. */\n/**@{*/\n\n", +/* 20 */ "/**@}*/\n\n", +/* 21 */ "#ifdef __cplusplus\nextern \"C\" { \n#endif\n\n", +/* 22 */ "#ifdef __cplusplus\n}\n#endif\n\n", +/* 23 */ "/**\tReset ", +/* 24 */ " state machine.\n", +/* 25 */ "\t@param\tst\tPointer to state variable.\n*/\n", +/* 26 */ "void ", +/* 27 */ "_reset(int *st);\n\n", +/* 28 */ "/**\tState machine ", +/* 29 */ " step.\n\t@param\tst\tPointer to state variable.\n", +/* 30 */ "\t@param\tin\tInput.\n\t@return\tTransition output.\n*/\n", +/* 31 */ "_step(int *st, int in);\n\n", +/* 32 */ "static\n", +/* 33 */ "void\n", +/* 34 */ "_reset(int *st)\n{\n if(st) { *st = ", +/* 35 */ "; }\n}\n\n", +/* 36 */ "0", +/* 37 */ "int\n", +/* 38 */ "_step(int *st, int in)\n{\n int back = ", +/* 39 */ ";\n", +/* 40 */ " if(st) {\n int os;\n int nf = 1;\n int ns = ", +/* 41 */ "}\n\n", +/* 42 */ " } else {\n", +/* 43 */ " }\n", +/* 44 */ " if(nf) {\n", +/* 45 */ " }\n", +/* 46 */ " os = *st;\n", +/* 47 */ " switch(os) {\n", +/* 48 */ " case ", +/* 49 */ ": {\n", +/* 50 */ " } break;\n", +/* 51 */ " switch(in) {\n", +/* 52 */ " }\n", +/* 53 */ " case ", +/* 54 */ ": {\n", +/* 55 */ " nf = 0;\n } break;\n", +/* 56 */ "ns = ", +/* 57 */ "os", +/* 58 */ "; back = ", +/* 59 */ ";", +/* 60 */ " if(", +/* 61 */ ") {\n", +/* 62 */ "\n } else {\n", +/* 63 */ " }\n", +/* 64 */ "os == ", +/* 65 */ "in == ", +/* 66 */ "fprintf(", +/* 67 */ ", \"+ ", +/* 68 */ "_step state=%d input=%d\\n\", ((st) ? *st : 0), in);\n", +/* 69 */ ", \"- ", +/* 70 */ ", L\"+ ", +/* 71 */ ", L\"- ", +/* 72 */ "fwprintf(", +/* 73 */ "\". rule: ", +/* 74 */ "\\n\"", /* UNUSED */ +/* 75 */ "_step state=%d output=%d\\n\", ((st) ? *st : 0), back);\n", +/* 76 */ " return back;\n", +/* 77 */ " *st = ns;\n", +NULL +}; + + + +/** Option names. +*/ +static char const * const dkct_au_option_names[] = { +/* 0 */ "name", +/* 1 */ "write-header", +NULL +}; + + + +/** Compare two entries by name. + @param l Left entry. + @param r Right entry. + @param cr Comparison critieria (0=struct/struct, 1=struct/name). + @return Comparison result. +*/ +static +int +dkct_au_entry_compare(void const *l, void const *r, int cr) +{ + int back = 0; + DKCT_STM_ENTRY const *pl; /* Left object pointer. */ + DKCT_STM_ENTRY const *pr; /* Right object pointer. */ + if(l) { + if(r) { + pl = (DKCT_STM_ENTRY const *)l; + pr = (DKCT_STM_ENTRY const *)r; + switch(cr) { + case 1: { + if(pl->name) { + back = dk3str_c8_cmp(pl->name, (char const *)r); + } else { + back = -1; + } + } break; + default: { + if(pl->name) { + if(pr->name) { + back = dk3str_c8_cmp(pl->name, pr->name); + } else { + back = 1; + } + } else { + if(pr->name) { + back = -1; + } + } + } break; + } + } else { + back = 1; + } + } else { + if(r) { + back = -1; + } + } + if(back < -1) back = -1; + if(back > 1) back = 1; + return back; +} + + + +/** Delete entry. + @param p Entry to delete. +*/ +static +void +dkct_au_entry_delete(DKCT_STM_ENTRY *p) +{ + if(p) { $? "= dkct_au_entry_delete \"%!8s\" \"%!8s\" %d", TR_8STR(p->name), TR_8STR(p->comment), p->value + dk3_release(p->name); + dk3_release(p->comment); + p->lineno = 0UL; p->value = 0; p->flag = 0x00; + dk3_delete(p); + } +} + + + +/** Create entry. + @param name Entry name. + @param comment Comment. + @param lineno Line number in source file. + @param value Numeric value (if specified). + @param flag Flag: Use value. + @param app Application structure for diagnostics, may be NULL. + @return Pointer to new entry on success, NULL on error. +*/ +DKCT_STM_ENTRY * +dkct_au_entry_new( + char const *name, + char const *comment, + unsigned long lineno, + int value, + int flag, + dk3_app_t *app +) +{ + DKCT_STM_ENTRY *back = NULL; + $? "+ dkct_au_entry_new \"%!8s\" \"%!8s\"", TR_8STR(name), TR_8STR(comment) + if(name) { + back = dk3_new_app(DKCT_STM_ENTRY,1,app); + if(back) { + back->flag = ((flag)? 0x01 : 0x00); + back->value = value; + back->lineno = lineno; + back->name = dk3str_c8_dup_app(name,app); + back->comment = NULL; + if(back->name) { + if(comment) { + back->comment = dk3str_c8_dup_app(comment,app); + if(!(back->comment)) { + dkct_au_entry_delete(back); + back = NULL; + } + } + } else { + dkct_au_entry_delete(back); + back = NULL; + } + } + } $? "- dkct_au_entry_new PTR=%d", TR_IPTR(back) + return back; +} + + + +/** Compare two rules, either by state+input or by line number. + @param l Left rule. + @param r Right rule. + @param cr Comparison criteria (0=line, + DKCT_AU_RULE_SORT_STATE_INPUT=state+input). + @return Comparison result. +*/ +static +int +dkct_au_rule_compare(void const *l, void const *r, int cr) +{ + int back = 0; + DKCT_STM_RULE const *pl; /* Left rule pointer. */ + DKCT_STM_RULE const *pr; /* Right rule pointer. */ + if(l) { + if(r) { + pl = (DKCT_STM_RULE const *)l; + pr = (DKCT_STM_RULE const *)r; + switch(cr & (~(DKCT_AU_RULE_SORT_REVERSE))) { + case DKCT_AU_RULE_SORT_STATE_INPUT: { + /* + First sort by states. + */ + if(pl->state) { + if(pr->state) { + if((pl->state)->name) { + if((pr->state)->name) { + back = dk3str_c8_cmp((pl->state)->name, (pr->state)->name); + } else { + back = 1; + } + } else { + if((pr->state)->name) { + back = -1; + } + } + } else { + back = 1; + } + } else { + if(pr->state) { + back = -1; + } + } + /* + For equal states sort by input. + */ + if(back == 0) { + if(pl->input) { + if(pr->input) { + if((pl->input)->name) { + if((pr->input)->name) { + back = dk3str_c8_cmp((pl->input)->name, (pr->input)->name); + } else { + back = 1; + } + } else { + if((pr->input)->name) { + back = -1; + } + } + } else { + back = 1; + } + } else { + if(pr->input) { + back = -1; + } + } + } + } break; + default: { + /* + Simply sort by line number. + */ + if(pl->lineno > pr->lineno) { back = 1; } + else { + if(pl->lineno < pr->lineno) { back = -1; } + } + } break; + } + } else { + back = 1; + } + } else { + if(r) { + back = -1; + } + } + if(back < -1) { back = -1; } + if(back > 1) { back = 1; } + if(cr & DKCT_AU_RULE_SORT_REVERSE) { + switch(back) { + case 1: { back = -1; } break; + case -1: { back = 1; } break; + } + } + return back; +} + + + +/** Delete rule. + @param rp Rule to delete. +*/ +void +dkct_au_rule_delete(DKCT_STM_RULE *rp) +{ + if(rp) { $? "= dkct_au_rule_delete" + rp->state = NULL; + rp->input = NULL; + rp->newstate = NULL; + rp->output = NULL; + rp->lineno = 0UL; + dk3_delete(rp); + } +} + + + +/** Create rule. + @param os Old state. + @param in Input. + @param ns New state. + @param out Output. + @param lineno Line number in source file. + @param app Application structure for diagnostics, may be NULL. + @return Pointer to new element on success, NULL on error. +*/ +DKCT_STM_RULE * +dkct_au_rule_new( + DKCT_STM_ENTRY *os, + DKCT_STM_ENTRY *in, + DKCT_STM_ENTRY *ns, + DKCT_STM_ENTRY *out, + unsigned long lineno, + dk3_app_t *app +) +{ + DKCT_STM_RULE *back = NULL; + int ok = 1; /* Flag: No errors occured. */ + $? "+ dkct_au_rule_new" + back = dk3_new_app(DKCT_STM_RULE,1,app); + if(back) { + back->state = os; + back->input = in; + back->newstate = ns; + back->output = out; + back->lineno = lineno; + if(!(ok)) { + dkct_au_rule_delete(back); + back = NULL; + } + } $? "- dkct_au_rule_new PTR=%d", TR_IPTR(back) + return back; +} + + + +/** Delete all rules in a storage. + @param s Storage containing the rules. + @param i Iterator for storage. +*/ +static +void +dkct_au_stm_rules_delete(dk3_sto_t *s, dk3_sto_it_t *i) +{ + DKCT_STM_RULE *r; /* Current rule to delete. */ + $? "+ dkct_au_stm_rules_delete" + if(s) { + if(i) { + dk3sto_it_reset(i); + while((r = (DKCT_STM_RULE *)dk3sto_it_next(i)) != NULL) { + dkct_au_rule_delete(r); + } + dk3sto_it_close(i); + } + dk3sto_close(s); + } $? "- dkct_au_stm_rules_delete" +} + + + +/** Delete all entries in a storage. + @param s Storage containing the entries. + @param i Iterator for storage. +*/ +static +void +dkct_au_stm_entries_delete(dk3_sto_t *s, dk3_sto_it_t *i) +{ + DKCT_STM_ENTRY *e; /* Current entry to delete. */ + $? "+ dkct_au_stm_entries_delete" + if(s) { + if(i) { + dk3sto_it_reset(i); + while((e = (DKCT_STM_ENTRY *)dk3sto_it_next(i)) != NULL) { + dkct_au_entry_delete(e); + } + dk3sto_it_close(i); + } + dk3sto_close(s); + } $? "- dkct_au_stm_entries_delete" +} + + + +/** Delete a state machine description. + @param p State machine to delete. +*/ +void +dkct_au_stm_delete(DKCT_STM *p) +{ + $? "+ dkct_au_stm_delete" + if(p) { + dkct_au_stm_rules_delete(p->s_wildcard, p->i_wildcard); + dkct_au_stm_rules_delete(p->s_exact, p->i_exact); + dkct_au_stm_entries_delete(p->s_states, p->i_states); + dkct_au_stm_entries_delete(p->s_inputs, p->i_inputs); + dkct_au_stm_entries_delete(p->s_outputs, p->i_outputs); + p->s_wildcard = NULL; p->i_wildcard = NULL; + p->s_exact = NULL; p->i_exact = NULL; + p->s_states = NULL; p->i_states = NULL; + p->s_outputs = NULL; p->i_outputs = NULL; + p->s_inputs = NULL; p->i_inputs = NULL; + dk3_release(p->name); + p->lineno = 0UL; + p->wrh = 0; + p->rs = NULL; + p->ds = NULL; + p->dout = NULL; + p->lngr = 0UL; + dk3_delete(p); + } $? "- dkct_au_stm_delete" +} + + + +/** Create new state machine description. + @param lineno Line number in source file. + @param app Application structure for diagnostics, may be NULL. + @return Pointer to new structure on success, NULL on error. +*/ +DKCT_STM * +dkct_au_stm_new(unsigned long lineno, dk3_app_t *app) +{ + DKCT_STM *back = NULL; + int ok = 0; /* Flag: Successfully initialized. */ + $? "+ dkct_au_stm_new %lu", lineno + back = dk3_new_app(DKCT_STM,1,app); + if(back) { + back->s_wildcard = NULL; back->i_wildcard = NULL; + back->s_exact = NULL; back->i_exact = NULL; + back->s_states = NULL; back->i_states = NULL; + back->s_outputs = NULL; back->i_outputs = NULL; + back->s_inputs = NULL; back->i_inputs = NULL; + back->name = NULL; + back->lineno = lineno; + back->wrh = 1; + back->section = DKCT_AU_SECTION_OPTIONS; + back->rs = NULL; + back->ds = NULL; + back->dout = NULL; + back->lngr = 0UL; + back->stmno = 0UL; + back->s_states = dk3sto_open_app(app); + back->s_inputs = dk3sto_open_app(app); + back->s_outputs = dk3sto_open_app(app); + back->s_exact = dk3sto_open_app(app); + back->s_wildcard = dk3sto_open_app(app); + if(back->s_states) { back->i_states = dk3sto_it_open(back->s_states); } + if(back->s_inputs) { back->i_inputs = dk3sto_it_open(back->s_inputs); } + if(back->s_outputs) { back->i_outputs = dk3sto_it_open(back->s_outputs); } + if(back->s_exact) { back->i_exact = dk3sto_it_open(back->s_exact); } + if(back->s_wildcard) { back->i_wildcard= dk3sto_it_open(back->s_wildcard); } + if((back->s_states) && (back->s_inputs) && (back->s_outputs)) { + dk3sto_set_comp(back->s_states, dkct_au_entry_compare, 0); + dk3sto_set_comp(back->s_inputs, dkct_au_entry_compare, 0); + dk3sto_set_comp(back->s_outputs, dkct_au_entry_compare, 0); + if((back->s_exact) && (back->s_wildcard)) { + dk3sto_set_comp( + back->s_exact, dkct_au_rule_compare, DKCT_AU_RULE_SORT_STATE_INPUT + ); + dk3sto_set_comp(back->s_wildcard, dkct_au_rule_compare, 0); + if((back->i_states) && (back->i_inputs) && (back->i_outputs)) { + if((back->i_exact) && (back->i_wildcard)) { + ok = 1; + } + } + } + } + if(!(ok)) { + dkct_au_stm_delete(back); + back = NULL; + } + } $? "- dkct_au_stm_new PTR=%d", TR_IPTR(back) + return back; +} + + + +/** Process one option line. + @param stm State machine description. + @param psrc Source structure. + @param line Text line. + @param lineno Line number of current line. + @return 1 on success, 0 on error. +*/ +static +int +dkct_au_add_option( + DKCT_STM *stm, DKCT_SRC *psrc, char *line, unsigned long lineno +) +{ + int back = 0; + char *p1; /* Key (option name). */ + char *p2; /* Value. */ + int ai; /* Array index of option name. */ + $? "+ dkct_au_add_option %lu \"%!8s\"", lineno, TR_8STR(line) + p1 = dk3str_c8_start(line, NULL); + if(p1) { + p2 = dk3str_c8_chr(p1, '='); + if(p2) { + *(p2++) = '\0'; + p2 = dk3str_c8_start(p2, NULL); + if(p2) { + dk3str_c8_normalize(p1, NULL, '-'); + ai = dk3str_c8_array_index(dkct_au_option_names, p1, 0); + switch(ai) { + case 0: { $? ". name" + if(stm->name) { + /* Warning: Redefinition of name */ + dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 28); + dk3_release(stm->name); + } + stm->name = dk3str_c8_dup_app(p2, psrc->app); + if(stm->name) { + back = 1; + } else { + /* ERROR: Memory */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 29); + } + } break; + case 1: { $? ". write header" + if(dk3str_c8_is_bool(p2)) { + stm->wrh = (dk3str_c8_is_on(p2) ? 1 : 0); + back = 1; + } else { + /* ERROR: Syntax (not boolean)! */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 30); + } + } break; + default: { + dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 10, 11, p1); + } break; + } + } else { + /* ERROR: No value. */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9); + } + } else { + /* Syntax */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9); + } + } + $? "- dkct_au_add_option %d", back + return back; +} + + + +/** Add an entry to storage. + @param stm State machine description. + @param psrc Source structure. + @param line Input line to process. + @param co Comment for entry. + @param lineno Line number of input line. + @param storage Storage for entry. + @param iterator Iterator for storage. + @param tp Entry type (0=state, 1=input, 2=output). + @return 1 on success, 0 on error. + +*/ +static +int +dkct_au_add_entry( + DKCT_STM *stm, + DKCT_SRC *psrc, + char *line, + char *co, + unsigned long lineno, + dk3_sto_t *storage, + dk3_sto_it_t *iterator, + int tp +) +{ + int back = 0; + char *nptr; /* Entry name. */ + char *vptr; /* Value (if any). */ + DKCT_STM_ENTRY *e; /* New entry. */ + DKCT_STM_ENTRY *ep; /* Search result. */ + int i; /* Value (if defined). */ + int f; /* Flag: Value defined. */ + $? "+ dkct_au_add_entry %lu \"%!8s\" \"%!8s\"", lineno, TR_8STR(line), TR_8STR(co) + nptr = vptr = NULL; + i = f = 0; + nptr = dk3str_c8_start(line, NULL); + if(nptr) { + vptr = dk3str_c8_next(nptr, NULL); + back = 1; + if(vptr) { + if(sscanf(vptr, "%d", &i) == 1) { + f = 1; + } else { + back = 0; + /* ERROR: Syntax */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 31); + } + } + if(back) { + back = 0; + e = dkct_au_entry_new( + nptr, co, lineno, i, f, psrc->app + ); + if(e) { + ep = (DKCT_STM_ENTRY *)dk3sto_it_find_like(iterator, (void *)e, 0); + if(ep) { + /* ERROR: Redefinition */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 32); + dkct_au_entry_delete(e); + } else { + if(dk3sto_add(storage, (void *)e)) { + back = 1; + switch(tp) { + case 0: { + /* + First state is reset state. + */ + if(!(stm->rs)) { stm->rs = e; } + /* + First state is general rule next state default. + */ + if(!(stm->ds)) { stm->ds = e; } + } break; + case 2: { + /* + First output is general rule output default. + */ + if(!(stm->dout)) { stm->dout = e; } + } break; + } + } else { + dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); + dkct_au_entry_delete(e); + } + } + } else { + /* ERROR Memory */ + dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); + } + } + } else { + /* ERROR: Syntax */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 33); + } $? "- dkct_au_add_entry %d", back + return back; +} + + + +/** Find named entry in storage. + @param psrc Source structure. + @param sto Storage. + @param ist Storage iterator. + @param name Name of entry to find. + @param ok Pointer to not-found-is-ok variable. + @param t Type (0=state, 1=input, 2=output). + @param lineno Line number. + @return Pointer to found entry on success, NULL on error. +*/ +static +DKCT_STM_ENTRY * +dkct_au_find_entry( + DKCT_SRC *psrc, + dk3_sto_t *sto, + dk3_sto_it_t *ist, + char *name, + unsigned long lineno, + int *ok, + int t +) +{ + DKCT_STM_ENTRY *back = NULL; + if(dk3str_c8_cmp(dkct_au_kw8[0], name) == 0) { + *ok = 1; + } else { + back = (DKCT_STM_ENTRY *)dk3sto_it_find_like(ist, name, 1); + if(!(back)) { + /* Warning: State/input/output undeclared! */ + dkct_to_log_3(psrc, 1, DK3_LL_WARNING, 34, 35, name); + back = dkct_au_entry_new(name, NULL, lineno, 0, 0, psrc->app); + if(back) { + if(!dk3sto_add(sto, (void *)back)) { + dkct_au_entry_delete(back); + back = NULL; + } + } else { + /* ERROR: Failed to create entry! */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 29); + } + } + } + return back; +} + + + +/** Add rule to state machine. + @param stm State machine description. + @param psrc Source structure. + @param line Input line to process. + @param co Comment for rule. + @param lineno Current line number. + @return 1 on success, 0 on error. +*/ +static +int +dkct_au_add_rule( + DKCT_STM *stm, DKCT_SRC *psrc, char *line, char *co, unsigned long lineno +) +{ + int back = 0; + DKCT_STM_RULE tr; /* Test rul. */ + DKCT_STM_RULE *nr; /* New rule. */ + char *p1; /* Old state. */ + char *p2; /* Input. */ + char *p3; /* New state. */ + char *p4; /* Output. */ + DKCT_STM_ENTRY *e1; /* Old state. */ + DKCT_STM_ENTRY *e2; /* Input. */ + DKCT_STM_ENTRY *e3; /* New state. */ + DKCT_STM_ENTRY *e4; /* Output. */ + int ok1; /* Flag: Old state *. */ + int ok2; /* Flag: Input *. */ + int ok3; /* Flag: New state *. */ + int ok4; /* Flag: Output *. */ + int can_add; /* Flag: Rule ok, add. */ + $? "+ dkct_au_add_rule %lu \"%!8s\" \"%!8s\"", lineno, TR_8STR(line), TR_8STR(co) + e1 = e2 = e3 = e4 = NULL; ok1 = ok2 = ok3 = ok4 = 0; + p1 = dk3str_c8_start(line, NULL); + if(p1) { + p2 = dk3str_c8_next(p1, NULL); + if(p2) { + p3 = dk3str_c8_next(p2, NULL); + if(p3) { + p4 = dk3str_c8_next(p3, NULL); + if(p4) { + (void)dk3str_c8_next(p4, NULL); + e1 = dkct_au_find_entry( + psrc, stm->s_states, stm->i_states, p1, lineno, &ok1, 0 + ); + e2 = dkct_au_find_entry( + psrc, stm->s_inputs, stm->i_inputs, p2, lineno, &ok2, 1 + ); + e3 = dkct_au_find_entry( + psrc, stm->s_states, stm->i_states, p3, lineno, &ok3, 0 + ); + e4 = dkct_au_find_entry( + psrc, stm->s_outputs, stm->i_outputs, p4, lineno, &ok4, 2 + ); + if( + ((e1) || (ok1)) && ((e2) || (ok2)) + && ((e3) || (ok3)) && ((e4) || (ok4)) + ) + { + can_add = 1; + tr.state = e1; tr.input = e2; tr.newstate = e3; tr.output = e4; + if((e1) && (e2)) { + DKCT_STM_RULE *xrp; + if((xrp = (DKCT_STM_RULE *)dk3sto_it_find_like( + stm->i_exact, (void *)(&tr), + DKCT_AU_RULE_SORT_STATE_INPUT + ) + ) != NULL + ) + { + char ulbuffer[32]; + sprintf(ulbuffer, "%lu", xrp->lineno); + can_add = 0; + /* ERROR: Conflict! */ + dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 36, 39, ulbuffer); + } + } + if(can_add) { + if((e1) && (e2)) { + nr = dkct_au_rule_new(e1, e2, e3, e4, lineno, psrc->app); + if(nr) { + if(dk3sto_add(stm->s_exact, (void *)nr)) { + back = 1; + } else { + dkct_au_rule_delete(nr); + dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); + } + } else { + /* ERROR: Memory! */ + dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); + } + } else { + if((e1) || (e2)) { + nr = dkct_au_rule_new(e1, e2, e3, e4, lineno, psrc->app); + if(nr) { + if(dk3sto_add(stm->s_wildcard, (void *)nr)) { + back = 1; + } else { + dkct_au_rule_delete(nr); + dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); + } + } else { + /* ERROR: Memory! */ + dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); + } + } else { + back = 1; + if(stm->lngr) { + char buffer[32]; + sprintf(buffer, "%lu", stm->lngr); + /* Warning: General rule redefined! */ + dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 36, 39, buffer); + } + stm->ds = e3; + stm->dout = e4; + stm->lngr = lineno; + } + } + } + } else { + dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29); + } + } else { + dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 33); + } + } else { + dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 33); + } + } else { + dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 33); + } + } + $? "- dkct_au_add_rule %d", back + return back; +} + + + +/** Process one input line. + @param stm State machine description. + @param psrc Source structure. + @param line Line to process. + @param lineno Current line number. + @return 1 on success, 0 on error. +*/ +int +dkct_au_add_line( + DKCT_STM *stm, DKCT_SRC *psrc, char *line, unsigned long lineno +) +{ + int back = 0; + char *lstart; /* Start of input line. */ + char *pc; /* Comment pointer. */ + int ai; /* Array index. */ + $? "+ dkct_au_add_line %lu \"%!8s\"", lineno, TR_8STR(line) + if((stm) && (line)) { $? ". args ok" + lstart = dk3str_c8_start(line, NULL); + if(lstart) { $? ". text found \"%!8s\"", lstart + pc = NULL; + if(*lstart != '#') { $? ". not a comment line" + if(*lstart == '[') { $? ". start of section" + lstart++; + lstart = dk3str_c8_start(lstart, NULL); + if(lstart) { + stm->section = -1; + pc = dk3str_c8_chr(lstart, ']'); + if(pc) { + *pc = '\0'; + dk3str_c8_chomp(lstart, NULL); $? ". lstart=\"%!8s\"", lstart + ai = dk3str_c8_array_index(dkct_au_section_names, lstart, 0); + $? ". ai=%d",ai + switch(ai) { + case 0: case 5: { + stm->section = DKCT_AU_SECTION_OPTIONS; back = 1; + } break; + case 1: case 6: { + stm->section = DKCT_AU_SECTION_STATES; back = 1; + } break; + case 2: case 7: { + stm->section = DKCT_AU_SECTION_INPUTS; back = 1; + } break; + case 3: case 8: { + stm->section = DKCT_AU_SECTION_OUTPUTS; back = 1; + } break; + case 4: case 9: { + stm->section = DKCT_AU_SECTION_RULES; back = 1; + } break; + default: { + dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 99, 100, lstart); + } break; + } + } else { + /* ERROR: Syntax! */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 37); + } + } else { + dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 37); + } + } else { $? ". section contents %d", stm->section + pc = dk3str_c8_chr(lstart, '#'); + if(pc) { *(pc++) = '\0'; pc = dk3str_c8_start(pc, NULL); } + switch(stm->section) { + case DKCT_AU_SECTION_OPTIONS: { $? ". options" + back = dkct_au_add_option(stm, psrc, lstart, lineno); + } break; + case DKCT_AU_SECTION_STATES: { $? ". states" + back = dkct_au_add_entry( + stm, psrc, lstart, pc, lineno, stm->s_states, stm->i_states, 0 + ); + } break; + case DKCT_AU_SECTION_INPUTS: { $? ". inputs" + back = dkct_au_add_entry( + stm, psrc, lstart, pc, lineno, stm->s_inputs, stm->i_inputs, 1 + ); + } break; + case DKCT_AU_SECTION_OUTPUTS: { $? ". outputs" + back = dkct_au_add_entry( + stm, psrc, lstart, pc, lineno, stm->s_outputs, stm->i_outputs, 2 + ); + } break; + case DKCT_AU_SECTION_RULES: { $? ". rules" + back = dkct_au_add_rule(stm, psrc, lstart, pc, lineno); + } break; + } + } + } else { + back = 1; /* comments ok */ + } + } else { + back = 1; /* empty lines ok */ + } + } $? "- dkct_au_add_line %d", back + return back; +} + + + +/** Check whether there is at least one entry in the storage. + @param it Iterator of storage to check. + @return 1 on success, 0 on error (storage empty). +*/ +static +int +dkct_au_stm_entries_check(dk3_sto_it_t *it) +{ + int back = 0; + dk3sto_it_reset(it); + if(dk3sto_it_next(it)) { + back = 1; + } + return back; +} + + + +/** Assign values to state/input/output storage. + @param psrc Source structure. + @param stm State machine to modify. + @param it Iterator for state/input/output storage. + @return 1 on success, 0 on error. +*/ +static +int +dkct_au_set_values(DKCT_SRC *psrc, DKCT_STM *stm, dk3_sto_it_t *it) +{ + int back = 1; + DKCT_STM_ENTRY *ep = NULL; /* Current entry to process. */ + dk3_bf_t *bf = NULL; /* Bit field, used values. */ + int min = 0; /* Minimum value so far. */ + int max = 0; /* Maximum value so far. */ + int valfound = 0; /* Flag: Values specified. */ + int cv = 0; /* Current value. */ + int cc = 0; /* Flag: Continue search. */ + $? "+ dkct_au_set_values" + dk3sto_it_reset(it); + while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) { + if(ep->flag) { $? ". have value %d", ep->value + if(valfound) { $? ". already values found" + if(ep->value < min) min = ep->value; + if(ep->value > max) max = ep->value; + } else { $? ". first value" + min = max = ep->value; + } + valfound = 1; + } else { $? ". no value" + } + } + if(valfound) { $? ". must take care of existing values" + bf = dk3bf_open_app((max - min + 1), psrc->app); + if(bf) { + /* + Find used values. + */ + dk3sto_it_reset(it); + while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) { + if(ep->flag) { + dk3bf_set(bf, (ep->value - min), 1); + } + } + /* + Set missing values. + */ + cv = 0; + dk3sto_it_reset(it); + while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) { + if(!(ep->flag)) { + do { $? ". attempt %d", cv + cc = 0; + if((cv >= min) && (cv <= max)) { + if(dk3bf_get(bf, (cv - min))) { + cc = 1; $? "! already in use" + cv++; + if(cv == 0) { $? "! Numeric overflow" + cc = 0; + back = 0; + /* ERROR: Overflow */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 38); + } + } + } + } while(cc); + cc = 0; + if((cv >= min) && (cv <= max)) { + if(!dk3bf_get(bf, (cv - min))) { + cc = 1; + } + } else { + cc = 1; + } + if(cc) { $? ". can use %d", cv + ep->value = cv++; + if(cv == 0) { $? "! Numeric overflow" + back = 0; + /* ERROR: Overflow */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 38); + } + } + } + } + dk3bf_close(bf); + } else { $? "! failed to allocated bit field" + back = 0; + /* ERROR: Memory */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 29); + } + } else { $? ". no existing values yet" + cv = 0; + dk3sto_it_reset(it); + while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) { + ep->value = cv++; + if(cv == 0) { $? "! numeric overflow" + back = 0; + /* ERROR: Overflow */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 38); + } + } + } $? "- dkct_au_set_values %d", back + return back; +} + + + +int +dkct_au_stm_check(DKCT_SRC *psrc, DKCT_STM *stm) +{ + int back = 0; + int sfound = 0; /* Number of states found. */ + int ifound = 0; /* Number of inputs found. */ + int ofound = 0; /* Number of outputs found. */ + + dk3app_set_source_line(psrc->app, stm->lineno); + sfound = dkct_au_stm_entries_check(stm->i_states); + ifound = dkct_au_stm_entries_check(stm->i_inputs); + ofound = dkct_au_stm_entries_check(stm->i_outputs); + if((sfound) && (ifound) && (ofound)) { + back = 1; + if(!dkct_au_set_values(psrc, stm, stm->i_states)) { back = 0; } + if(!dkct_au_set_values(psrc, stm, stm->i_inputs)) { back = 0; } + if(!dkct_au_set_values(psrc, stm, stm->i_outputs)) { back = 0; } + } else { + if(!(sfound)) { + /* ERROR: No states declared! */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 40); + } + if(!(ifound)) { + /* ERROR: No inputs declared! */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 41); + } + if(!(ofound)) { + /* ERROR: No outputs declared! */ + dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 42); + } + } + return back; +} + + + +/** Write definition for one storage entry. + @param psrc Source structure. + @param stm State machine. + @param ep Entry to write + @param commi Keyword index for "state", "input", or "output". +*/ +static +void +dkct_au_write_one_entry( + DKCT_SRC *psrc, DKCT_STM *stm, DKCT_STM_ENTRY *ep, size_t commi +) +{ + $? "+ dkct_au_write_one_entry" + fputs(dkct_au_kw8[3], psrc->fipo); + fputs(ep->name, psrc->fipo); + fputs(dkct_au_kw8[1], psrc->fipo); + fputs(dkct_au_kw8[11], psrc->fipo); + fputs(dkct_au_kw8[commi], psrc->fipo); + if(ep->comment) { + fputs(ep->comment, psrc->fipo); + } else { + fputs(ep->name, psrc->fipo); + } + fputs(dkct_au_kw8[12], psrc->fipo); + if((psrc->dkcto).lnn) { + psrc->lineno = ep->lineno; + dkct_tr_show_source_line(psrc, 0); + } + fputs(dkct_au_kw8[6], psrc->fipo); + fputs(ep->name, psrc->fipo); + fprintf(psrc->fipo, dkct_au_kw8[(ep->value >= 0) ? 9 : 10], ep->value); + fputs(dkct_au_kw8[4], psrc->fipo); /* else */ + if((psrc->dkcto).lnn) { + psrc->lineno = ep->lineno; + dkct_tr_show_source_line(psrc, 0); + } + fputs(dkct_au_kw8[7], psrc->fipo); + fputs(ep->name, psrc->fipo); + fputs(dkct_au_kw8[8], psrc->fipo); + fputs(dkct_au_kw8[5], psrc->fipo); /* endif */ + $? "- dkct_au_write_one_entry" +} + + + +/** Write all entries of a storage. + @param psrc Source structure. + @param stm State machine. + @param it Storage iterator. + @param commi Keyword index for "state", "input", or "output". +*/ +static +void +dkct_au_write_entry_storage( + DKCT_SRC *psrc, DKCT_STM *stm, dk3_sto_it_t *it, size_t commi +) +{ + DKCT_STM_ENTRY *ep; /* Current entry. */ + $? "+ dkct_au_write_entry_storage" + dk3sto_it_reset(it); + while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) { + dkct_au_write_one_entry(psrc, stm, ep, commi); + } $? "- dkct_au_write_entry_storage" +} + + + +/** Write state machine name to output file. + @param psrc Source structure. + @param stm State machine. +*/ +static +void +dkct_au_write_stm_name(DKCT_SRC *psrc, DKCT_STM *stm) +{ + if(stm->name) { + fputs(stm->name, psrc->fipo); + } else { + fprintf(psrc->fipo, dkct_au_kw8[16], stm->stmno); + } +} + + + +/** Write state/input/output entry definitions. + @param psrc Source structure. + @param stm State machine. +*/ +void +dkct_au_write_entries(DKCT_SRC *psrc, DKCT_STM *stm) +{ + /* + Begin doxygen group + */ + fputs(dkct_au_kw8[17], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[18], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[19], psrc->fipo); + /* + Write the entries + */ + dkct_au_write_entry_storage(psrc, stm, stm->i_states, 13); + dkct_au_write_entry_storage(psrc, stm, stm->i_inputs, 14); + dkct_au_write_entry_storage(psrc, stm, stm->i_outputs, 15); + /* + End doxygen group + */ + fputs(dkct_au_kw8[20], psrc->fipo); +} + + + +void +dkct_au_write_prototypes(DKCT_SRC *psrc, DKCT_STM *stm) +{ + fputs(dkct_au_kw8[21], psrc->fipo); + fputs(dkct_au_kw8[23], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[24], psrc->fipo); + fputs(dkct_au_kw8[25], psrc->fipo); + fputs(dkct_au_kw8[26], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[27], psrc->fipo); + fputs(dkct_au_kw8[28], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[29], psrc->fipo); + fputs(dkct_au_kw8[30], psrc->fipo); + fputs(dkct_au_kw8[37], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[31], psrc->fipo); + fputs(dkct_au_kw8[22], psrc->fipo); +} + + + +/** Write a transition result. + @param psrc Source structure. + @param stm State machine. + @param rp Rule. + @param indent Level of indent. +*/ +static +void +dkct_au_write_transition_result( + DKCT_SRC *psrc, DKCT_STM *stm, DKCT_STM_RULE *rp, int indent +) +{ + int i; /* Number of indent spaces already written. */ + /* DEBUG CODE IF -d */ + for(i = 0; i < indent; i++) { fputc(' ', psrc->fipo); } + fputs(dkct_au_kw8[56], psrc->fipo); + if(rp->newstate) { + fputs((rp->newstate)->name, psrc->fipo); + } else { + fputs(dkct_au_kw8[57], psrc->fipo); + } + fputs(dkct_au_kw8[58], psrc->fipo); + if(rp->output) { + fputs((rp->output)->name, psrc->fipo); + } else { + if(stm->dout) { + fputs((stm->dout)->name, psrc->fipo); + } else { + fputs(dkct_au_kw8[36], psrc->fipo); + } + } + fputs(dkct_au_kw8[59], psrc->fipo); +} + + + +/** Create debug code for entering and leaving the + transition function. + @param psrc Source structure. + @param stm State machine. + @param pos Position (0=invokation, 1=return). +*/ +static +void +dkct_au_debug_transition(DKCT_SRC *psrc, DKCT_STM *stm, int pos) +{ + char const *fnptr; /* Debug output file. */ + + fnptr = dkct_tr_get_kw8(((psrc->dkcto).deb == 2) ? 28 : 29); + fputs(dkct_tr_get_kw8(67), psrc->fipo); + if((psrc->dkcto).win) { + fputs(dkct_tr_get_kw8(21), psrc->fipo); + /* char 16 start */ + psrc->lineno = stm->lineno; + fputs(dkct_tr_get_kw8(61), psrc->fipo); + dkct_tr_show_filename_and_lineno(psrc); + fputs(dkct_tr_get_kw8(35), psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_tr_get_kw8(34), psrc->fipo); + + fputs(dkct_au_kw8[72], psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_au_kw8[(pos == 1) ? 71 : 70], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[(pos == 1) ? 75 : 68], psrc->fipo); + + fputs(dkct_tr_get_kw8(37), psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_tr_get_kw8(34), psrc->fipo); + /* char 16 end */ + fputs(dkct_tr_get_kw8(22), psrc->fipo); + } + /* char 8 start */ + if((psrc->dkcto).deb == 1) { + fputs(dkct_tr_get_kw8(30), psrc->fipo); + } + psrc->lineno = stm->lineno; + fputs(dkct_tr_get_kw8(33), psrc->fipo); + dkct_tr_show_filename_and_lineno(psrc); + fputs(dkct_tr_get_kw8(35), psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_tr_get_kw8(34), psrc->fipo); + + fputs(dkct_au_kw8[66], psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_au_kw8[(pos == 1) ? 69 : 67], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[(pos == 1) ? 75 : 68], psrc->fipo); + + fputs(dkct_tr_get_kw8(37), psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_tr_get_kw8(34), psrc->fipo); + if((psrc->dkcto).deb == 1) { + fputs(dkct_tr_get_kw8(31), psrc->fipo); + } + /* char 8 end */ + if((psrc->dkcto).win) { + fputs(dkct_tr_get_kw8(23), psrc->fipo); + } + fputs(dkct_tr_get_kw8(25), psrc->fipo); +} + + + +/** Write debug output to show the matching rule. + @param psrc Source structure. + @param stm State machine. + @param rp Rule to show. +*/ +static +void +dkct_au_debug_matching_rule( + DKCT_SRC *psrc, DKCT_STM *stm, DKCT_STM_RULE *rp +) +{ + char const *fnptr; /* Debug output file. */ + char const *p1; /* Current state. */ + char const *p2; /* Input. */ + char const *p3; /* Next state. */ + char const *p4; /* Output. */ + + if((psrc->dkcto).deb) { + p1 = p2 = p3 = p4 = dkct_au_kw8[0]; + if(rp) { + if(rp->state) { p1 = (rp->state)->name; } + if(rp->input) { p2 = (rp->input)->name; } + if(rp->newstate) { p3 = (rp->newstate)->name; } + if(rp->output) { p4 = (rp->output)->name; } + } else { + if(stm->ds) { p3 = (stm->ds)->name; } + if(stm->dout) { p4 = (stm->dout)->name; } + } + fnptr = dkct_tr_get_kw8(((psrc->dkcto).deb == 2) ? 28 : 29); + psrc->lineno = stm->lineno; + if(rp) { psrc->lineno = rp->lineno; } + fputs(dkct_tr_get_kw8(67), psrc->fipo); + if((psrc->dkcto).win) { + fputs(dkct_tr_get_kw8(21), psrc->fipo); + /* char 16 start */ + if((psrc->dkcto).deb == 1) { + fputs(dkct_tr_get_kw8(30), psrc->fipo); + } + fputs(dkct_tr_get_kw8(61), psrc->fipo); + dkct_tr_show_filename_and_lineno(psrc); + fputs(dkct_tr_get_kw8(35), psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_tr_get_kw8(34), psrc->fipo); + fputs(dkct_tr_get_kw8(61), psrc->fipo); + fputs(dkct_au_kw8[73], psrc->fipo); + fputs(dkct_au_kw8[2], psrc->fipo); + fputs(p1, psrc->fipo); + fputs(dkct_au_kw8[2], psrc->fipo); + fputs(p2, psrc->fipo); + fputs(dkct_au_kw8[2], psrc->fipo); + fputs(p3, psrc->fipo); + fputs(dkct_au_kw8[2], psrc->fipo); + fputs(p4, psrc->fipo); + fputs(dkct_au_kw8[74], psrc->fipo); + fputs(dkct_tr_get_kw8(35), psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_tr_get_kw8(34), psrc->fipo); + fputs(dkct_tr_get_kw8(37), psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_tr_get_kw8(34), psrc->fipo); + if((psrc->dkcto).deb == 1) { + fputs(dkct_tr_get_kw8(31), psrc->fipo); + } + /* char 16 end */ + fputs(dkct_tr_get_kw8(22), psrc->fipo); + } + /* char 8 start */ + if((psrc->dkcto).deb == 1) { + fputs(dkct_tr_get_kw8(30), psrc->fipo); + } + fputs(dkct_tr_get_kw8(33), psrc->fipo); + dkct_tr_show_filename_and_lineno(psrc); + fputs(dkct_tr_get_kw8(35), psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_tr_get_kw8(34), psrc->fipo); + + fputs(dkct_tr_get_kw8(33), psrc->fipo); + fputs(dkct_au_kw8[73], psrc->fipo); + fputs(dkct_au_kw8[2], psrc->fipo); + fputs(p1, psrc->fipo); + fputs(dkct_au_kw8[2], psrc->fipo); + fputs(p2, psrc->fipo); + fputs(dkct_au_kw8[2], psrc->fipo); + fputs(p3, psrc->fipo); + fputs(dkct_au_kw8[2], psrc->fipo); + fputs(p4, psrc->fipo); + fputs(dkct_au_kw8[74], psrc->fipo); + fputs(dkct_tr_get_kw8(35), psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_tr_get_kw8(34), psrc->fipo); + + fputs(dkct_tr_get_kw8(37), psrc->fipo); + fputs(fnptr, psrc->fipo); + fputs(dkct_tr_get_kw8(34), psrc->fipo); + if((psrc->dkcto).deb == 1) { + fputs(dkct_tr_get_kw8(31), psrc->fipo); + } + + /* char 8 end */ + if((psrc->dkcto).win) { + fputs(dkct_tr_get_kw8(23), psrc->fipo); + } + fputs(dkct_tr_get_kw8(25), psrc->fipo); + } +} + + + +void +dkct_au_write_functions(DKCT_SRC *psrc, DKCT_STM *stm, int f_static) +{ + DKCT_STM_ENTRY *prevstate; /* Current state. */ + DKCT_STM_RULE *rp; /* Rule to process. */ + unsigned long nwildcards; /* Number of wildcards. */ + unsigned long i; /* Current wildcard block to finish. */ + /* + Reset function. + */ + if(f_static) { + fputs(dkct_au_kw8[23], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[24], psrc->fipo); + fputs(dkct_au_kw8[25], psrc->fipo); + fputs(dkct_au_kw8[32], psrc->fipo); + } + fputs(dkct_au_kw8[33], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[34], psrc->fipo); + if(stm->rs) { + fputs((stm->rs)->name, psrc->fipo); + } else { + fputs(dkct_au_kw8[36], psrc->fipo); + } + fputs(dkct_au_kw8[35], psrc->fipo); + /* + Transition function. + */ + if(f_static) { + fputs(dkct_au_kw8[28], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[29], psrc->fipo); + fputs(dkct_au_kw8[30], psrc->fipo); + fputs(dkct_au_kw8[32], psrc->fipo); + } + fputs(dkct_au_kw8[37], psrc->fipo); + dkct_au_write_stm_name(psrc, stm); + fputs(dkct_au_kw8[38], psrc->fipo); + if(stm->dout) { + fputs((stm->dout)->name, psrc->fipo); + } else { + fputs(dkct_au_kw8[36], psrc->fipo); + } + fputs(dkct_au_kw8[39], psrc->fipo); + if((psrc->dkcto).deb) { + /* Debug messages for entering function */ + dkct_au_debug_transition(psrc, stm, 0); + } + fputs(dkct_au_kw8[40], psrc->fipo); + if(stm->ds) { + fputs((stm->ds)->name, psrc->fipo); + } else { + fputs(dkct_au_kw8[36], psrc->fipo); + } + fputs(dkct_au_kw8[39], psrc->fipo); + fputs(dkct_au_kw8[46], psrc->fipo); + /* + Exact rules + */ + prevstate = NULL; + dk3sto_it_reset(stm->i_exact); + while((rp = (DKCT_STM_RULE *)dk3sto_it_next(stm->i_exact)) != NULL) { + if(prevstate) { + if(dk3str_c8_cmp(prevstate->name, (rp->state)->name)) { + fputs(dkct_au_kw8[52], psrc->fipo); + fputs(dkct_au_kw8[50], psrc->fipo); + fputs(dkct_au_kw8[48], psrc->fipo); + fputs((rp->state)->name, psrc->fipo); + fputs(dkct_au_kw8[49], psrc->fipo); + fputs(dkct_au_kw8[51], psrc->fipo); + } else { + } + } else { + fputs(dkct_au_kw8[47], psrc->fipo); + fputs(dkct_au_kw8[48], psrc->fipo); + fputs((rp->state)->name, psrc->fipo); + fputs(dkct_au_kw8[49], psrc->fipo); + fputs(dkct_au_kw8[51], psrc->fipo); + } + prevstate = rp->state; + fputs(dkct_au_kw8[53], psrc->fipo); + fputs((rp->input)->name, psrc->fipo); + fputs(dkct_au_kw8[54], psrc->fipo); + dkct_au_debug_matching_rule(psrc, stm, rp); + dkct_au_write_transition_result(psrc, stm, rp, 12); + fputs(dkct_au_kw8[55], psrc->fipo); + } + if(prevstate) { + fputs(dkct_au_kw8[52], psrc->fipo); + fputs(dkct_au_kw8[50], psrc->fipo); + fputs(dkct_au_kw8[45], psrc->fipo); + } + fputs(dkct_au_kw8[44], psrc->fipo); + /* + Wildcard rules + */ + nwildcards = 0UL; + dk3sto_it_reset(stm->i_wildcard); + while((rp = (DKCT_STM_RULE *)dk3sto_it_next(stm->i_wildcard)) != NULL) { + fputs(dkct_au_kw8[60], psrc->fipo); + if(rp->state) { + fputs(dkct_au_kw8[64], psrc->fipo); + fputs((rp->state)->name, psrc->fipo); + } else { + if(rp->input) { + fputs(dkct_au_kw8[65], psrc->fipo); + fputs((rp->input)->name, psrc->fipo); + } else { + fputs(dkct_au_kw8[36], psrc->fipo); + } + } + fputs(dkct_au_kw8[61], psrc->fipo); + dkct_au_debug_matching_rule(psrc, stm, rp); + dkct_au_write_transition_result(psrc, stm, rp, 6); + fputs(dkct_au_kw8[62], psrc->fipo); + nwildcards++; + } + dkct_au_debug_matching_rule(psrc, stm, NULL); + for(i = 0; i < nwildcards; i++) { + fputs(dkct_au_kw8[63], psrc->fipo); + } + fputs(dkct_au_kw8[45], psrc->fipo); + fputs(dkct_au_kw8[77], psrc->fipo); + fputs(dkct_au_kw8[42], psrc->fipo); + /* DEBUG: Invalid st pointer */ + fputs(dkct_au_kw8[43], psrc->fipo); + if((psrc->dkcto).deb) { + /* Debug messages for entering function */ + dkct_au_debug_transition(psrc, stm, 1); + } + fputs(dkct_au_kw8[76], psrc->fipo); + fputs(dkct_au_kw8[41], psrc->fipo); +} + + + +/* vim: set ai sw=2 : */ + -- cgit v1.2.3