summaryrefslogtreecommitdiff
path: root/support/dktools/dkct-au.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dkct-au.ctr
Initial commit
Diffstat (limited to 'support/dktools/dkct-au.ctr')
-rw-r--r--support/dktools/dkct-au.ctr1688
1 files changed, 1688 insertions, 0 deletions
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 : */
+