|
|
1.1 ! root 1: /* ! 2: * command tree climbing ! 3: */ ! 4: ! 5: static char *RCSid = "$Header: /newbits/usr/bin/korn/RCS/tree.c,v 1.2 91/08/01 12:41:25 bin Exp Locker: bin $"; ! 6: ! 7: #include <stddef.h> ! 8: #include <stdlib.h> ! 9: #include <string.h> ! 10: #include <stdio.h> ! 11: #include <errno.h> ! 12: #include <setjmp.h> ! 13: #include <varargs.h> ! 14: #include "sh.h" ! 15: #include "tree.h" ! 16: ! 17: #define FSTRING (FILE*)NULL ! 18: ! 19: static int tputc ARGS((int c, FILE *f)); ! 20: static void tputC ARGS((int c, FILE *f)); ! 21: static void tputS ARGS((char *wp, FILE *f)); ! 22: ! 23: /* ! 24: * print a command tree ! 25: */ ! 26: ! 27: void ! 28: ptree(t, f) ! 29: register struct op *t; ! 30: register FILE *f; ! 31: { ! 32: register char **w; ! 33: struct ioword **ioact; ! 34: struct op *t1; ! 35: ! 36: Chain: ! 37: if (t == NULL) ! 38: return; ! 39: switch (t->type) { ! 40: case TCOM: ! 41: for (w = t->vars; *w != NULL; ) ! 42: fptreef(f, "%S ", *w++); ! 43: for (w = t->args; *w != NULL; ) ! 44: fptreef(f, "%S ", *w++); ! 45: break; ! 46: case TEXEC: ! 47: t = t->left; ! 48: goto Chain; ! 49: case TPAREN: ! 50: fptreef(f, "(%T)", t->left); ! 51: break; ! 52: case TPIPE: ! 53: fptreef(f, "%T | ", t->left); ! 54: t = t->right; ! 55: goto Chain; ! 56: case TLIST: ! 57: fptreef(f, "%T%;", t->left); ! 58: t = t->right; ! 59: goto Chain; ! 60: case TOR: ! 61: case TAND: ! 62: fptreef(f, "%T %s %T", ! 63: t->left, (t->type==TOR) ? "||" : "&&", t->right); ! 64: break; ! 65: case TFOR: ! 66: fptreef(f, "for %s ", t->str); ! 67: if (t->vars != NULL) { ! 68: fptreef(f, "in "); ! 69: for (w = t->vars; *w; ) ! 70: fptreef(f, "%S ", *w++); ! 71: fptreef(f, "%;"); ! 72: } ! 73: fptreef(f, "do %T%;done ", t->left); ! 74: break; ! 75: case TCASE: ! 76: fptreef(f, "case %S in%;", t->str); ! 77: for (t1 = t->left; t1 != NULL; t1 = t1->right) { ! 78: fptreef(f, "("); ! 79: for (w = t1->vars; *w != NULL; w++) ! 80: fptreef(f, "%S%c", *w, (w[1] != NULL) ? '|' : ')'); ! 81: fptreef(f, " %T;;%;", t1->left); ! 82: } ! 83: fptreef(f, "esac "); ! 84: break; ! 85: case TIF: ! 86: fptreef(f, "if %T%;", t->left); ! 87: t = t->right; ! 88: if (t->left != NULL) ! 89: fptreef(f, "then %T%;", t->left); ! 90: if (t->right != NULL) ! 91: fptreef(f, "else %T%;", t->right); ! 92: fptreef(f, "fi "); ! 93: break; ! 94: case TWHILE: ! 95: case TUNTIL: ! 96: fptreef(f, "%s %T%;do %T%;done ", ! 97: (t->type==TWHILE) ? "while" : "until", ! 98: t->left, t->right); ! 99: break; ! 100: case TBRACE: ! 101: fptreef(f, "{%;%T%;} ", t->left); ! 102: break; ! 103: case TASYNC: ! 104: fptreef(f, "%T &", t->left); ! 105: break; ! 106: case TFUNCT: ! 107: fptreef(f, "function %s %T", t->str, t->left); ! 108: break; ! 109: case TTIME: ! 110: fptreef(f, "time %T", t->left); ! 111: break; ! 112: default: ! 113: fptreef(f, "<botch>"); ! 114: break; ! 115: } ! 116: if ((ioact = t->ioact) != NULL) ! 117: while (*ioact != NULL) ! 118: pioact(f, *ioact++); ! 119: } ! 120: ! 121: /* ! 122: * print out a redirection node. ! 123: */ ! 124: pioact(f, iop) ! 125: register FILE *f; ! 126: register struct ioword *iop; ! 127: { ! 128: char *redir = NULL; ! 129: ! 130: switch (iop->flag & (IOREAD|IOHERE|IOWRITE|IOCAT|IOXHERE|IODUP)) { ! 131: case IOREAD: redir = "<"; break; ! 132: case IOREAD|IOHERE: redir = "<<"; break; ! 133: case IOREAD|IODUP: redir = "<&"; break; ! 134: case IOWRITE: redir = ">"; break; ! 135: case IOWRITE|IOCAT: redir = ">>"; break; ! 136: case IOWRITE|IODUP: redir = ">&"; break; ! 137: case IOXHERE: redir = "<<"; break; ! 138: default: redir = ">?<"; break; ! 139: } ! 140: fptreef(f, "%c%s%S ", '0' + iop->unit, redir, iop->name); ! 141: } ! 142: ! 143: ! 144: /* ! 145: * variants of fputc, fputs for ptreef and snptreef ! 146: */ ! 147: ! 148: static char *snpf_s; /* snptreef string */ ! 149: static int snpf_n; /* snptreef length */ ! 150: ! 151: static int ! 152: tputc(c, f) ! 153: int c; ! 154: register FILE *f; ! 155: { ! 156: if (f != NULL) ! 157: putc(c, f); ! 158: else ! 159: if (--snpf_n >= 0) ! 160: *snpf_s++ = c; ! 161: return c; ! 162: } ! 163: ! 164: static void ! 165: tputC(c, f) ! 166: register int c; ! 167: register FILE *f; ! 168: { ! 169: if ((c&0x60) == 0) { /* C0|C1 */ ! 170: tputc((c&0x80) ? '$' : '^', f); ! 171: tputc((c&0x7F|0x40), f); ! 172: } else if ((c&0x7F) == 0x7F) { /* DEL */ ! 173: tputc((c&0x80) ? '$' : '^', f); ! 174: tputc('?', f); ! 175: } else ! 176: tputc(c, f); ! 177: } ! 178: ! 179: static void ! 180: tputS(wp, f) ! 181: register char *wp; ! 182: register FILE *f; ! 183: { ! 184: register int c; ! 185: ! 186: while (1) ! 187: switch ((c = *wp++)) { ! 188: case EOS: ! 189: return; ! 190: case CHAR: ! 191: tputC(*wp++, f); ! 192: break; ! 193: case QCHAR: ! 194: tputc('\\', f); ! 195: tputC(*wp++, f); ! 196: break; ! 197: case OQUOTE: ! 198: case CQUOTE: ! 199: tputc('"', f); ! 200: break; ! 201: case OSUBST: ! 202: tputc('$', f); ! 203: tputc('{', f); ! 204: while ((c = *wp++) != 0) ! 205: tputc(c, f); ! 206: if (*wp != CSUBST) ! 207: tputC(*wp++, f); ! 208: break; ! 209: case CSUBST: ! 210: tputc('}', f); ! 211: break; ! 212: case COMSUB: ! 213: tputc('$', f); ! 214: tputc('(', f); ! 215: while (*wp != 0) ! 216: tputC(*wp++, f); ! 217: tputc(')', f); ! 218: break; ! 219: } ! 220: } ! 221: ! 222: /* TODO: use varargs properly */ ! 223: ! 224: /* VARARGS */ int ! 225: fptreef(f, va_alist) va_dcl ! 226: register FILE *f; ! 227: { ! 228: va_list va; ! 229: char *fmt; ! 230: ! 231: va_start(va); ! 232: fmt = va_arg(va, char *); ! 233: vfptreef(f, fmt, va); ! 234: va_end(va); ! 235: return 0; ! 236: } ! 237: ! 238: /* VARARGS */ int ! 239: snptreef(s, n, va_alist) va_dcl ! 240: char *s; ! 241: int n; ! 242: { ! 243: va_list va; ! 244: char *fmt; ! 245: ! 246: snpf_s = s; ! 247: snpf_n = n; ! 248: va_start(va); ! 249: fmt = va_arg(va, char *); ! 250: vfptreef(FSTRING, fmt, va); ! 251: tputc('\0', FSTRING); ! 252: va_end(va); ! 253: return 0; ! 254: } ! 255: ! 256: vfptreef(f, fmt, va) ! 257: register FILE *f; ! 258: register char *fmt; ! 259: register va_list va; ! 260: { ! 261: register int c; ! 262: ! 263: while ((c = *fmt++)) ! 264: if (c == '%') { ! 265: register long n; ! 266: register char *p; ! 267: int neg; ! 268: ! 269: switch ((c = *fmt++)) { ! 270: case 'c': ! 271: tputc(va_arg(va, int), f); ! 272: break; ! 273: case 's': ! 274: p = va_arg(va, char *); ! 275: while (*p) ! 276: tputc(*p++, f); ! 277: break; ! 278: case 'S': /* word */ ! 279: p = va_arg(va, char *); ! 280: tputS(p, f); ! 281: break; ! 282: case 'd': case 'u': /* decimal */ ! 283: n = (c == 'd') ? va_arg(va, int) : va_arg(va, unsigned int); ! 284: neg = c=='d' && n<0; ! 285: p = ulton((neg) ? -n : n, 10); ! 286: if (neg) ! 287: *--p = '-'; ! 288: while (*p) ! 289: tputc(*p++, f); ! 290: break; ! 291: case 'T': /* format tree */ ! 292: ptree(va_arg(va, struct op *), f); ! 293: break; ! 294: case ';': /* newline or ; */ ! 295: p = (f == FSTRING) ? "; " : "\n"; ! 296: while (*p) ! 297: tputc(*p++, f); ! 298: break; ! 299: default: ! 300: tputc(c, f); ! 301: break; ! 302: } ! 303: } else ! 304: tputc(c, f); ! 305: } ! 306: ! 307: /* ! 308: * copy tree (for function definition) ! 309: */ ! 310: ! 311: static struct ioword **iocopy(); ! 312: ! 313: struct op * ! 314: tcopy(t, ap) ! 315: register struct op *t; ! 316: Area *ap; ! 317: { ! 318: register struct op *r; ! 319: register char **tw, **rw; ! 320: ! 321: if (t == NULL) ! 322: return NULL; ! 323: ! 324: r = (struct op *) alloc(sizeof(struct op), ap); ! 325: ! 326: r->type = t->type; ! 327: ! 328: /* this will copy function and for identifiers quite accidently */ ! 329: r->str = (t->str == NULL) ? NULL : wdcopy(t->str, ap); ! 330: ! 331: if (t->vars == NULL) ! 332: r->vars = NULL; ! 333: else { ! 334: for (tw = t->vars; *tw++ != NULL; ) ! 335: ; ! 336: rw = r->vars = (char **) ! 337: alloc((int)(tw - t->vars) * sizeof(*tw), ap); ! 338: for (tw = t->vars; *tw != NULL; ) ! 339: *rw++ = wdcopy(*tw++, ap); ! 340: *rw = NULL; ! 341: } ! 342: ! 343: if (t->args == NULL) ! 344: r->args = NULL; ! 345: else { ! 346: for (tw = t->args; *tw++ != NULL; ) ! 347: ; ! 348: rw = r->args = (char **) ! 349: alloc((int)(tw - t->args) * sizeof(*tw), ap); ! 350: for (tw = t->args; *tw != NULL; ) ! 351: *rw++ = wdcopy(*tw++, ap); ! 352: *rw = NULL; ! 353: } ! 354: ! 355: r->ioact = (t->ioact == NULL) ? NULL : iocopy(t->ioact, ap); ! 356: ! 357: r->left = tcopy(t->left, ap); ! 358: r->right = tcopy(t->right, ap); ! 359: ! 360: return r; ! 361: } ! 362: ! 363: char * ! 364: wdcopy(wp, ap) ! 365: char *wp; ! 366: Area *ap; ! 367: { ! 368: size_t len = wdscan(wp, EOS) - wp; ! 369: return memcpy(alloc(len, ap), wp, len); ! 370: } ! 371: ! 372: /* return the position of prefix c in wp plus 1 */ ! 373: char * ! 374: wdscan(wp, c) ! 375: register char *wp; ! 376: register int c; ! 377: { ! 378: register int nest = 0; ! 379: ! 380: while (1) ! 381: switch (*wp++) { ! 382: case EOS: ! 383: return wp; ! 384: case CHAR: ! 385: case QCHAR: ! 386: wp++; ! 387: break; ! 388: case OQUOTE: ! 389: case CQUOTE: ! 390: break; ! 391: case OSUBST: ! 392: nest++; ! 393: while (*wp++ != 0) ! 394: ; ! 395: if (*wp != CSUBST) ! 396: wp++; ! 397: break; ! 398: case CSUBST: ! 399: if (c == CSUBST && nest == 0) ! 400: return wp; ! 401: nest--; ! 402: break; ! 403: case COMSUB: ! 404: while (*wp++ != 0) ! 405: ; ! 406: break; ! 407: } ! 408: } ! 409: ! 410: static struct ioword ** ! 411: iocopy(iow, ap) ! 412: register struct ioword **iow; ! 413: Area *ap; ! 414: { ! 415: register struct ioword **ior; ! 416: register int i; ! 417: ! 418: for (ior = iow; *ior++ != NULL; ) ! 419: ; ! 420: ior = (struct ioword **) alloc((int)(ior - iow) * sizeof(*ior), ap); ! 421: ! 422: for (i = 0; iow[i] != NULL; i++) { ! 423: register struct ioword *p, *q; ! 424: ! 425: p = iow[i]; ! 426: q = (struct ioword *) alloc(sizeof(*p), ap); ! 427: ior[i] = q; ! 428: *q = *p; ! 429: if (p->name != NULL) ! 430: q->name = wdcopy(p->name, ap); ! 431: } ! 432: ior[i] = NULL; ! 433: ! 434: return ior; ! 435: } ! 436: ! 437: /* ! 438: * free tree (for function definition) ! 439: */ ! 440: ! 441: static void iofree(); ! 442: ! 443: void ! 444: tfree(t, ap) ! 445: register struct op *t; ! 446: Area *ap; ! 447: { ! 448: register char **w; ! 449: ! 450: if (t == NULL) ! 451: return; ! 452: ! 453: if (t->str != NULL) ! 454: afree((Void*)t->str, ap); ! 455: ! 456: if (t->vars != NULL) { ! 457: for (w = t->vars; *w != NULL; w++) ! 458: afree((Void*)*w, ap); ! 459: afree((Void*)t->vars, ap); ! 460: } ! 461: ! 462: if (t->args != NULL) { ! 463: for (w = t->args; *w != NULL; w++) ! 464: afree((Void*)*w, ap); ! 465: afree((Void*)t->args, ap); ! 466: } ! 467: ! 468: if (t->ioact != NULL) ! 469: iofree(t->ioact, ap); ! 470: ! 471: tfree(t->left, ap); ! 472: tfree(t->right, ap); ! 473: ! 474: afree((Void*)t, ap); ! 475: } ! 476: ! 477: static void ! 478: iofree(iow, ap) ! 479: struct ioword **iow; ! 480: Area *ap; ! 481: { ! 482: register struct ioword **iop; ! 483: register struct ioword *p; ! 484: ! 485: for (iop = iow; (p = *iop++) != NULL; ) { ! 486: if (p->name != NULL) ! 487: afree((Void*)p->name, ap); ! 488: afree((Void*)p, ap); ! 489: } ! 490: } ! 491:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.