/* * test main for lut module, usage: a.out [lhs[=rhs]...] */ int main(int argc, char *argv[]) { struct lut *r = NULL; struct lut *dupr = NULL; char *equals; err_init(argv[0]); setbuf(stdout, NULL); for (argv++; *argv; argv++) if ((equals = strchr(*argv, '=')) != NULL) { *equals++ = '\0'; r = lut_add(r, *argv, equals); } else r = lut_add(r, *argv, "NULL"); printf("lut contains:\n"); lut_walk(r, printer, r); dupr = lut_dup(r); lut_free(r, NULL); printf("dup lut contains:\n"); lut_walk(dupr, printer, dupr); lut_free(dupr, NULL); err_done(0); /* NOTREACHED */ return (0); }
/* * lut_walk -- walk the table in lexical order */ void lut_walk(struct lut *root, void (*callback)(const char *lhs, void *rhs, void *arg), void *arg) { if (root) { lut_walk(root->lut_left, callback, arg); (*callback)(root->lut_lhs, root->lut_rhs, arg); lut_walk(root->lut_right, callback, arg); } }
static void ptree_type_pattern(int flags, enum nodetype t, const char *pat) { struct printer_info info; struct node *np; info.flags = flags; info.pat = pat; info.t = t; switch (t) { case T_FAULT: lut_walk(Faults, (lut_cb)byname_printer, (void *)&info); return; case T_UPSET: lut_walk(Upsets, (lut_cb)byname_printer, (void *)&info); return; case T_DEFECT: lut_walk(Defects, (lut_cb)byname_printer, (void *)&info); return; case T_ERROR: lut_walk(Errors, (lut_cb)byname_printer, (void *)&info); return; case T_EREPORT: lut_walk(Ereports, (lut_cb)byname_printer, (void *)&info); return; case T_SERD: lut_walk(SERDs, (lut_cb)byname_printer, (void *)&info); return; case T_STAT: lut_walk(STATs, (lut_cb)byname_printer, (void *)&info); return; case T_ASRU: lut_walk(ASRUs, (lut_cb)byname_printer, (void *)&info); return; case T_FRU: lut_walk(FRUs, (lut_cb)byname_printer, (void *)&info); return; case T_CONFIG: lut_walk(Configs, (lut_cb)byname_printer, (void *)&info); return; case T_PROP: for (np = Props; np; np = np->u.stmt.next) if (name_pattern_match_in_subtree(np->u.stmt.np, pat)) ptree(flags, np, 0, 0); return; case T_MASK: for (np = Masks; np; np = np->u.stmt.next) if (name_pattern_match_in_subtree(np->u.stmt.np, pat)) ptree(flags, np, 0, 0); return; default: ptree(flags, tree_root(NULL), 0, 0); } }
/* * lut_dup -- duplicate a lookup table * * caller is responsible for keeping track of how many tables are keeping * pointers to the void * datum values. */ struct lut * lut_dup(struct lut *root) { struct lut *ret = NULL; lut_walk(root, dooper, &ret); return (ret); }
/* * kw_print -- spew the entire keywords table to stream * * this routine is used to dump the keywords table for debugging. */ void kw_print(FILE *stream) { lut_walk(Keywords, kw_printer, stream); }
void ptree(int flags, struct node *np, int no_iterators, int fileline) { if (np == NULL) return; switch (np->t) { case T_NOTHING: break; case T_NAME: out(flags|O_NONL, "%s", np->u.name.s); if (!no_iterators) { if (np->u.name.cp != NULL) { int num; cp2num(np->u.name.cp, &num); out(flags|O_NONL, "%d", num); } else if (np->u.name.it == IT_HORIZONTAL) { if (np->u.name.child == NULL || (np->u.name.childgen && !Pchildgen)) out(flags|O_NONL, "<>"); else { out(flags|O_NONL, "<"); ptree(flags, np->u.name.child, no_iterators, fileline); out(flags|O_NONL, ">"); } } else if (np->u.name.child && (!np->u.name.childgen || Pchildgen)) { if (np->u.name.it != IT_NONE) out(flags|O_NONL, "["); ptree(flags, np->u.name.child, no_iterators, fileline); if (np->u.name.it != IT_NONE) out(flags|O_NONL, "]"); } } if (np->u.name.next) { ASSERT(np->u.name.next->t == T_NAME); if (np->u.name.it == IT_ENAME) out(flags|O_NONL, "."); else out(flags|O_NONL, "/"); ptree(flags, np->u.name.next, no_iterators, fileline); } break; case T_TIMEVAL: ptree_timeval(flags, &np->u.ull); break; case T_NUM: out(flags|O_NONL, "%llu", np->u.ull); break; case T_QUOTE: out(flags|O_NONL, "\"%s\"", np->u.quote.s); break; case T_GLOBID: out(flags|O_NONL, "$%s", np->u.globid.s); break; case T_FUNC: out(flags|O_NONL, "%s(", np->u.func.s); ptree(flags, np->u.func.arglist, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_NVPAIR: ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "="); ptree(flags, np->u.expr.right, no_iterators, fileline); break; case T_EVENT: ptree(flags, np->u.event.ename, no_iterators, fileline); if (np->u.event.epname) { out(flags|O_NONL, "@"); ptree(flags, np->u.event.epname, no_iterators, fileline); } if (np->u.event.eexprlist) { out(flags|O_NONL, "{"); ptree(flags, np->u.event.eexprlist, no_iterators, fileline); out(flags|O_NONL, "}"); } break; case T_ASSIGN: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "="); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_NOT: out(flags|O_NONL, "("); out(flags|O_NONL, "!"); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_AND: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "&&"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_OR: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "||"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_EQ: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "=="); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_NE: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "!="); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_SUB: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "-"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_ADD: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "+"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_MUL: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "*"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_DIV: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "/"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_MOD: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "%%"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_LT: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "<"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_LE: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "<="); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_GT: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, ">"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_GE: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, ">="); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_BITNOT: out(flags|O_NONL, "("); out(flags|O_NONL, "~"); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_BITAND: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "&"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_BITOR: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "|"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_BITXOR: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "^"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_LSHIFT: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "<<"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_RSHIFT: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, ">>"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_CONDIF: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, "?"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_CONDELSE: out(flags|O_NONL, "("); ptree(flags, np->u.expr.left, no_iterators, fileline); out(flags|O_NONL, ":"); ptree(flags, np->u.expr.right, no_iterators, fileline); out(flags|O_NONL, ")"); break; case T_ARROW: ptree(flags, np->u.arrow.lhs, no_iterators, fileline); if (np->u.arrow.nnp) { out(flags|O_NONL, "("); ptree(flags, np->u.arrow.nnp, no_iterators, fileline); out(flags|O_NONL, ")"); } out(flags|O_NONL, "->"); if (np->u.arrow.knp) { out(flags|O_NONL, "("); ptree(flags, np->u.arrow.knp, no_iterators, fileline); out(flags|O_NONL, ")"); } ptree(flags, np->u.arrow.rhs, no_iterators, fileline); break; case T_LIST: ptree(flags, np->u.expr.left, no_iterators, fileline); if (np->u.expr.left && np->u.expr.right && (np->u.expr.left->t != T_LIST || ! is_stmt(np->u.expr.right))) out(flags|O_NONL, ","); ptree(flags, np->u.expr.right, no_iterators, fileline); break; case T_FAULT: case T_UPSET: case T_DEFECT: case T_ERROR: case T_EREPORT: if (fileline) out(flags, "# %d \"%s\"", np->line, np->file); out(flags|O_NONL, "event "); ptree(flags, np->u.stmt.np, no_iterators, fileline); if (np->u.stmt.nvpairs) { out(flags|O_NONL, " "); ptree(flags, np->u.stmt.nvpairs, no_iterators, fileline); } out(flags, ";"); break; case T_SERD: case T_STAT: if (fileline) out(flags, "# %d \"%s\"", np->line, np->file); out(flags|O_NONL, "engine "); ptree(flags, np->u.stmt.np, no_iterators, fileline); if (np->u.stmt.nvpairs) { out(flags|O_NONL, " "); ptree(flags, np->u.stmt.nvpairs, no_iterators, fileline); } else if (np->u.stmt.lutp) { struct plut_wlk_data pd; pd.flags = flags; pd.first = 0; lut_walk(np->u.stmt.lutp, ptree_plut, &pd); } out(flags, ";"); break; case T_ASRU: if (fileline) out(flags, "# %d \"%s\"", np->line, np->file); out(flags|O_NONL, "asru "); ptree(flags, np->u.stmt.np, no_iterators, fileline); if (np->u.stmt.nvpairs) { out(flags|O_NONL, " "); ptree(flags, np->u.stmt.nvpairs, no_iterators, fileline); } out(flags, ";"); break; case T_FRU: if (fileline) out(flags, "# %d \"%s\"", np->line, np->file); out(flags|O_NONL, "fru "); ptree(flags, np->u.stmt.np, no_iterators, fileline); if (np->u.stmt.nvpairs) { out(flags|O_NONL, " "); ptree(flags, np->u.stmt.nvpairs, no_iterators, fileline); } out(flags, ";"); break; case T_CONFIG: if (fileline) out(flags, "# %d \"%s\"", np->line, np->file); out(flags|O_NONL, "config "); ptree(flags, np->u.stmt.np, no_iterators, fileline); if (np->u.stmt.nvpairs) { out(flags|O_NONL, " "); ptree(flags, np->u.stmt.nvpairs, no_iterators, fileline); } out(flags, ";"); break; case T_PROP: if (fileline) out(flags, "# %d \"%s\"", np->line, np->file); out(flags|O_NONL, "prop "); ptree(flags, np->u.stmt.np, no_iterators, fileline); out(flags, ";"); break; case T_MASK: if (fileline) out(flags, "# %d \"%s\"", np->line, np->file); out(flags|O_NONL, "mask "); ptree(flags, np->u.stmt.np, no_iterators, fileline); out(flags, ";"); break; default: out(O_DIE, "internal error: ptree unexpected nodetype: %d", np->t); /*NOTREACHED*/ } }