rc

[fork] interactive rc shell
git clone https://hhvn.uk/rc
git clone git://hhvn.uk/rc
Log | Files | Refs | README | LICENSE

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