#include "rc.h" #include "develop.h" void dump(Node *, int); /* dump a Node * as a tree */ static void dump_1(char *p, Node *n, int indent) { fprint(2, "%s:\n", p); dump(n->u[0].p, indent + 1); } static void dump_2(char *p, Node *n, int indent) { fprint(2, "%s:\n", p); dump(n->u[0].p, indent + 1); if (n->u[1].p != NULL) dump(n->u[1].p, indent + 1); } static void dump_3(char *p, Node *n, int indent) { fprint(2, "%s:\n", p); dump(n->u[0].p, indent + 1); if (n->u[1].p != NULL) dump(n->u[1].p, indent + 1); if (n->u[2].p != NULL) dump(n->u[2].p, indent + 1); } static void dump_s(char *p, Node *n, int indent) { fprint(2, "%s: %S\n", p, n->u[0].s); } static void dump_pipe(char *p, Node *n, int indent) { int ifd = n->u[0].i, ofd = n->u[1].i; fprint(2, "%s %d %d:\n", p, ifd, ofd); dump(n->u[2].p, indent + 1); dump(n->u[3].p, indent + 1); } static char *redir(int op) { switch (op) { case rCreate: return ">"; case rAppend: return ">>"; case rFrom: return "<"; case rHeredoc: return "<<"; case rHerestring: return "<<<"; default: return "?"; } } static void dump_dup(char *p, Node *n, int indent) { fprint(2, "%s %s %d %d:\n", p, redir(n->u[0].i), n->u[1].i, n->u[2].i); } static void dump_redir(char *p, Node *n, int indent) { fprint(2, "%s %s %d:\n", p, redir(n->u[0].i), n->u[1].i); dump(n->u[2].p, indent + 1); } void dump(Node *n, int indent) { int i; if (n == NULL) return; for (i = 0; i < indent; ++i) fprint(2, " "); switch (n->type) { case nAndalso: dump_2("nAndalso", n, indent); break; case nArgs: dump_2("nArgs", n, indent); break; case nAssign: dump_2("nAassign", n, indent); break; case nBackq: dump_1("nBackq", n, indent); break; case nBang: dump_1("nBang", n, indent); break; case nBody: dump_2("nBody", n, indent); break; case nBrace: dump_1("nBrace", n, indent); break; case nCase: dump_1("nCase", n, indent); break; case nCbody: dump_2("nCbody", n, indent); break; case nConcat: dump_2("nConcat", n, indent); break; case nCount: dump_1("nCount", n, indent); break; case nDup: dump_dup("nDup", n, indent); break; case nElse: dump_2("nElse", n, indent); break; case nEpilog: dump_2("nEpilog", n, indent); break; case nFlat: dump_1("nFlat", n, indent); break; case nForin: dump_3("nForin", n, indent); break; case nIf: dump_2("nIf", n, indent); break; case nLappend: dump_2("nLappend", n, indent); break; case nMatch: dump_2("nMatch", n, indent); break; case nNewfn: dump_2("nNewfn", n, indent); break; case nNmpipe: dump_redir("nNowait", n, indent); break; case nNowait: dump_1("nNowait", n, indent); break; case nOrelse: dump_2("nNowait", n, indent); break; case nPipe: dump_pipe("nPipe", n, indent); break; case nPre: dump_2("nPre", n, indent); break; case nRedir: dump_redir("nRedir", n, indent); break; case nRmfn: dump_1("nRmfn", n, indent); break; case nSubshell: dump_1("nSubshell", n, indent); break; case nSwitch: dump_2("nSwitch", n, indent); break; case nVar: dump_1("nVar", n, indent); break; case nVarsub: dump_2("nVarsub", n, indent); break; case nWhile: dump_2("nWhile", n, indent); break; case nWord: dump_s("nWord", n, indent); break; default: fprint(2, "unknown\n"); break; } } void tree_dump(Node *f) { dump(f, 0); } #if 0 bool dollar = f->flags & FMT_altform; Node *n = va_arg(f->args, Node *); if (n == NULL) { fmtprint(f, "()"); return FALSE; } switch (n->type) { case nBang: fmtprint(f, "!%X", n->u[0].p); break; case nCase: fmtprint(f, "case %X", n->u[0].p); break; case nNowait: fmtprint(f, "%X&", n->u[0].p); break; case nRmfn: fmtprint(f, "fn %X", n->u[0].p); break; case nSubshell: fmtprint(f, "@ %X", n->u[0].p); break; case nAndalso: fmtprint(f, "%X&&%X", n->u[0].p, n->u[1].p); break; case nAssign: fmtprint(f, "%X=%X", n->u[0].p, n->u[1].p); break; case nConcat: fmtprint(f, "%X^%X", n->u[0].p, n->u[1].p); break; case nElse: fmtprint(f, "{%X}else %X", n->u[0].p, n->u[1].p); break; case nNewfn: fmtprint(f, "fn %X {%X}", n->u[0].p, n->u[1].p); break; case nIf: fmtprint(f, "if(%X)%X", n->u[0].p, n->u[1].p); break; case nOrelse: fmtprint(f, "%X||%X", n->u[0].p, n->u[1].p); break; case nArgs: fmtprint(f, "nArgs: "); Xconv(n->u[0].p, 4); Xconv(n->u[1].p, 4); break; case nSwitch: fmtprint(f, "switch(%X){%X}", n->u[0].p, n->u[1].p); break; case nMatch: fmtprint(f, "~ %X %X", n->u[0].p, n->u[1].p); break; case nWhile: fmtprint(f, "while(%X)%X", n->u[0].p, n->u[1].p); break; case nForin: fmtprint(f, "for(%X in %X)%X", n->u[0].p, n->u[1].p, n->u[2].p); break; case nVarsub: fmtprint(f, "$%X(%X)", n->u[0].p, n->u[1].p); break; case nWord: fmtprint(f, n->u[2].i && quotep(n->u[0].s, dollar) ? "%#S" : "%S", n->u[0].s); break; case nLappend: { static bool inlist; if (!inlist) { inlist = TRUE; fmtprint(f, "(%X %X)", n->u[0].p, n->u[1].p); inlist = FALSE; } else { fmtprint(f, "%X %X", n->u[0].p, n->u[1].p); } break; } case nCount: case nFlat: case nVar: { char *lp = "", *rp = ""; Node *n0 = n->u[0].p; if (n0->type != nWord) lp = "(", rp = ")"; switch (n->type) { default: panic("this can't happen"); break; case nCount: fmtprint(f, "$#%s%#T%s", lp, n0, rp); break; case nFlat: fmtprint(f, "$^%s%#T%s", lp, n0, rp); break; case nVar: fmtprint(f, "$%s%#T%s", lp, n0, rp); break; } break; } case nDup: if (n->u[2].i != -1) fmtprint(f, "%D[%d=%d]", n->u[0].i, n->u[1].i, n->u[2].i); else fmtprint(f, "%D[%d=]", n->u[0].i, n->u[1].i); break; case nBackq: { Node *n0 = n->u[0].p, *n00; if (n0 != NULL && n0->type == nVar && (n00 = n0->u[0].p) != NULL && n00->type == nWord && streq(n00->u[0].s, "ifs")) fmtprint(f, "`"); else fmtprint(f, "``%X", n0); fmtprint(f, "{%X}", n->u[1].p); break; } case nCbody: case nBody: { Node *n0 = n->u[0].p; if (n0 != NULL) fmtprint(f, "%X", n->u[0].p); if (n->u[1].p != NULL) { if (n0 != NULL && n0->type != nNowait) fmtprint(f, ";"); fmtprint(f, "%X", n->u[1].p); } break; } case nBrace: fmtprint(f, "{%X}", n->u[0].p); if (n->u[1].p != NULL) fmtprint(f, "%X", n->u[1].p); break; case nEpilog: case nPre: fmtprint(f, "%X", n->u[0].p); if (n->u[1].p != NULL) fmtprint(f, " %X", n->u[1].p); break; case nPipe: { int ofd = n->u[0].i, ifd = n->u[1].i; fmtprint(f, "%X|", n->u[2].p); if (ifd != 0) fmtprint(f, "[%d=%d]", ofd, ifd); else if (ofd != 1) fmtprint(f, "[%d]", ofd); fmtprint(f, "%X", n->u[3].p); break; } case nRedir: { int op = n->u[0].i; fmtprint(f, "%D", op); fmtprint(f, "[%d]", n->u[1].i); fmtprint(f, "%X", n->u[2].p); break; } case nNmpipe: { int op = n->u[0].i; fmtprint(f, "%D", op); fmtprint(f, "[%d]", n->u[1].i); fmtprint(f, "{%X}", n->u[2].p); break; } } return FALSE; } #endif