%% options copyright owner = Dirk Krause copyright year = 2011-2014 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 \"%s\" \"%s\" %d", TR_STR(p->name), TR_STR(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 \"%s\" \"%s\"", TR_STR(name), TR_STR(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 %s", TR_PTR(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 %s", TR_PTR(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 %s", TR_PTR(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 \"%s\"", lineno, TR_STR(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 \"%s\" \"%s\"", lineno, TR_STR(line), TR_STR(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 \"%s\" \"%s\"", lineno, TR_STR(line), TR_STR(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 \"%s\"", lineno, TR_STR(line) if((stm) && (line)) { $? ". args ok" lstart = dk3str_c8_start(line, NULL); if(lstart) { $? ". text found \"%s\"", 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=\"%s\"", 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 : */