develop.c (7303B)
1 #include "rc.h" 2 3 #include "develop.h" 4 5 void dump(Node *, int); 6 7 /* dump a Node * as a tree */ 8 9 static void dump_1(char *p, Node *n, int indent) { 10 fprint(2, "%s:\n", p); 11 dump(n->u[0].p, indent + 1); 12 } 13 14 static void dump_2(char *p, Node *n, int indent) { 15 fprint(2, "%s:\n", p); 16 dump(n->u[0].p, indent + 1); 17 if (n->u[1].p != NULL) 18 dump(n->u[1].p, indent + 1); 19 } 20 21 static void dump_3(char *p, Node *n, int indent) { 22 fprint(2, "%s:\n", p); 23 dump(n->u[0].p, indent + 1); 24 if (n->u[1].p != NULL) 25 dump(n->u[1].p, indent + 1); 26 if (n->u[2].p != NULL) 27 dump(n->u[2].p, indent + 1); 28 } 29 30 static void dump_s(char *p, Node *n, int indent) { 31 fprint(2, "%s: %S\n", p, n->u[0].s); 32 } 33 34 static void dump_pipe(char *p, Node *n, int indent) { 35 int ifd = n->u[0].i, ofd = n->u[1].i; 36 fprint(2, "%s %d %d:\n", p, ifd, ofd); 37 dump(n->u[2].p, indent + 1); 38 dump(n->u[3].p, indent + 1); 39 } 40 41 static char *redir(int op) { 42 switch (op) { 43 case rCreate: return ">"; 44 case rAppend: return ">>"; 45 case rFrom: return "<"; 46 case rHeredoc: return "<<"; 47 case rHerestring: return "<<<"; 48 default: return "?"; 49 } 50 } 51 static void dump_dup(char *p, Node *n, int indent) { 52 fprint(2, "%s %s %d %d:\n", p, redir(n->u[0].i), n->u[1].i, n->u[2].i); 53 } 54 55 static void dump_redir(char *p, Node *n, int indent) { 56 fprint(2, "%s %s %d:\n", p, redir(n->u[0].i), n->u[1].i); 57 dump(n->u[2].p, indent + 1); 58 } 59 60 void dump(Node *n, int indent) { 61 int i; 62 63 if (n == NULL) 64 return; 65 66 for (i = 0; i < indent; ++i) 67 fprint(2, " "); 68 69 switch (n->type) { 70 case nAndalso: 71 dump_2("nAndalso", n, indent); 72 break; 73 case nArgs: 74 dump_2("nArgs", n, indent); 75 break; 76 case nAssign: 77 dump_2("nAassign", n, indent); 78 break; 79 case nBackq: 80 dump_1("nBackq", n, indent); 81 break; 82 case nBang: 83 dump_1("nBang", n, indent); 84 break; 85 case nBody: 86 dump_2("nBody", n, indent); 87 break; 88 case nBrace: 89 dump_1("nBrace", n, indent); 90 break; 91 case nCase: 92 dump_1("nCase", n, indent); 93 break; 94 case nCbody: 95 dump_2("nCbody", n, indent); 96 break; 97 case nConcat: 98 dump_2("nConcat", n, indent); 99 break; 100 case nCount: 101 dump_1("nCount", n, indent); 102 break; 103 case nDup: 104 dump_dup("nDup", n, indent); 105 break; 106 case nElse: 107 dump_2("nElse", n, indent); 108 break; 109 case nEpilog: 110 dump_2("nEpilog", n, indent); 111 break; 112 case nFlat: 113 dump_1("nFlat", n, indent); 114 break; 115 case nForin: 116 dump_3("nForin", n, indent); 117 break; 118 case nIf: 119 dump_2("nIf", n, indent); 120 break; 121 case nIfnot: 122 dump_1("nIfnot", n, indent); 123 break; 124 case nLappend: 125 dump_2("nLappend", n, indent); 126 break; 127 case nMatch: 128 dump_2("nMatch", n, indent); 129 break; 130 case nNewfn: 131 dump_2("nNewfn", n, indent); 132 break; 133 case nNmpipe: 134 dump_redir("nNowait", n, indent); 135 break; 136 case nNowait: 137 dump_1("nNowait", n, indent); 138 break; 139 case nOrelse: 140 dump_2("nNowait", n, indent); 141 break; 142 case nPipe: 143 dump_pipe("nPipe", n, indent); 144 break; 145 case nPre: 146 dump_2("nPre", n, indent); 147 break; 148 case nRedir: 149 dump_redir("nRedir", n, indent); 150 break; 151 case nRmfn: 152 dump_1("nRmfn", n, indent); 153 break; 154 case nSubshell: 155 dump_1("nSubshell", n, indent); 156 break; 157 case nSwitch: 158 dump_2("nSwitch", n, indent); 159 break; 160 case nVar: 161 dump_1("nVar", n, indent); 162 break; 163 case nVarsub: 164 dump_2("nVarsub", n, indent); 165 break; 166 case nWhile: 167 dump_2("nWhile", n, indent); 168 break; 169 case nWord: 170 dump_s("nWord", n, indent); 171 break; 172 default: 173 fprint(2, "unknown\n"); 174 break; 175 } 176 } 177 178 void tree_dump(Node *f) { 179 dump(f, 0); 180 } 181 #if 0 182 bool dollar = f->flags & FMT_altform; 183 Node *n = va_arg(f->args, Node *); 184 185 if (n == NULL) { 186 fmtprint(f, "()"); 187 return FALSE; 188 } 189 switch (n->type) { 190 case nBang: fmtprint(f, "!%X", n->u[0].p); break; 191 case nCase: fmtprint(f, "case %X", n->u[0].p); break; 192 case nNowait: fmtprint(f, "%X&", n->u[0].p); break; 193 case nRmfn: fmtprint(f, "fn %X", n->u[0].p); break; 194 case nSubshell: fmtprint(f, "@ %X", n->u[0].p); break; 195 case nAndalso: fmtprint(f, "%X&&%X", n->u[0].p, n->u[1].p); break; 196 case nAssign: fmtprint(f, "%X=%X", n->u[0].p, n->u[1].p); break; 197 case nConcat: fmtprint(f, "%X^%X", n->u[0].p, n->u[1].p); break; 198 case nElse: fmtprint(f, "{%X}else %X", n->u[0].p, n->u[1].p); break; 199 case nNewfn: fmtprint(f, "fn %X {%X}", n->u[0].p, n->u[1].p); break; 200 case nIf: fmtprint(f, "if(%X)%X", n->u[0].p, n->u[1].p); break; 201 case nOrelse: fmtprint(f, "%X||%X", n->u[0].p, n->u[1].p); break; 202 case nArgs: fmtprint(f, "nArgs: "); 203 Xconv(n->u[0].p, 4); 204 Xconv(n->u[1].p, 4); break; 205 case nSwitch: fmtprint(f, "switch(%X){%X}", n->u[0].p, n->u[1].p); break; 206 case nMatch: fmtprint(f, "~ %X %X", n->u[0].p, n->u[1].p); break; 207 case nWhile: fmtprint(f, "while(%X)%X", n->u[0].p, n->u[1].p); break; 208 case nForin: fmtprint(f, "for(%X in %X)%X", n->u[0].p, n->u[1].p, n->u[2].p); break; 209 case nVarsub: fmtprint(f, "$%X(%X)", n->u[0].p, n->u[1].p); break; 210 case nWord: 211 fmtprint(f, n->u[2].i && quotep(n->u[0].s, dollar) ? 212 "%#S" : "%S", n->u[0].s); 213 break; 214 case nLappend: { 215 static bool inlist; 216 if (!inlist) { 217 inlist = TRUE; 218 fmtprint(f, "(%X %X)", n->u[0].p, n->u[1].p); 219 inlist = FALSE; 220 } else { 221 fmtprint(f, "%X %X", n->u[0].p, n->u[1].p); 222 } 223 break; 224 } 225 case nCount: case nFlat: case nVar: { 226 char *lp = "", *rp = ""; 227 Node *n0 = n->u[0].p; 228 229 if (n0->type != nWord) 230 lp = "(", rp = ")"; 231 232 switch (n->type) { 233 default: panic("this can't happen"); break; 234 case nCount: fmtprint(f, "$#%s%#T%s", lp, n0, rp); break; 235 case nFlat: fmtprint(f, "$^%s%#T%s", lp, n0, rp); break; 236 case nVar: fmtprint(f, "$%s%#T%s", lp, n0, rp); break; 237 } 238 break; 239 } 240 case nDup: 241 if (n->u[2].i != -1) 242 fmtprint(f, "%D[%d=%d]", n->u[0].i, n->u[1].i, n->u[2].i); 243 else 244 fmtprint(f, "%D[%d=]", n->u[0].i, n->u[1].i); 245 break; 246 case nBackq: { 247 Node *n0 = n->u[0].p, *n00; 248 if (n0 != NULL && n0->type == nVar 249 && (n00 = n0->u[0].p) != NULL && n00->type == nWord && streq(n00->u[0].s, "ifs")) 250 fmtprint(f, "`"); 251 else 252 fmtprint(f, "``%X", n0); 253 fmtprint(f, "{%X}", n->u[1].p); 254 break; 255 } 256 case nCbody: 257 case nBody: { 258 Node *n0 = n->u[0].p; 259 if (n0 != NULL) 260 fmtprint(f, "%X", n->u[0].p); 261 if (n->u[1].p != NULL) { 262 if (n0 != NULL && n0->type != nNowait) 263 fmtprint(f, ";"); 264 fmtprint(f, "%X", n->u[1].p); 265 } 266 break; 267 } 268 case nBrace: 269 fmtprint(f, "{%X}", n->u[0].p); 270 if (n->u[1].p != NULL) 271 fmtprint(f, "%X", n->u[1].p); 272 break; 273 case nEpilog: 274 case nPre: 275 fmtprint(f, "%X", n->u[0].p); 276 if (n->u[1].p != NULL) 277 fmtprint(f, " %X", n->u[1].p); 278 break; 279 case nPipe: { 280 int ofd = n->u[0].i, ifd = n->u[1].i; 281 fmtprint(f, "%X|", n->u[2].p); 282 if (ifd != 0) 283 fmtprint(f, "[%d=%d]", ofd, ifd); 284 else if (ofd != 1) 285 fmtprint(f, "[%d]", ofd); 286 fmtprint(f, "%X", n->u[3].p); 287 break; 288 } 289 case nRedir: { 290 int op = n->u[0].i; 291 fmtprint(f, "%D", op); 292 fmtprint(f, "[%d]", n->u[1].i); 293 fmtprint(f, "%X", n->u[2].p); 294 break; 295 } 296 case nNmpipe: { 297 int op = n->u[0].i; 298 fmtprint(f, "%D", op); 299 fmtprint(f, "[%d]", n->u[1].i); 300 fmtprint(f, "{%X}", n->u[2].p); 301 break; 302 } 303 } 304 return FALSE; 305 } 306 #endif