home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume20 / rc / part03 / tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-22  |  4.5 KB  |  193 lines

  1. /* tree.c: functions for manipulating parse-trees. (create, copy, delete) */
  2.  
  3. #include <stdarg.h>
  4. #include "rc.h"
  5. #include "tree.h"
  6. #include "utils.h"
  7. #include "nalloc.h"
  8.  
  9. /* make a new node, pass it back to yyparse. Used to generate the parsetree. */
  10.  
  11. Node *newnode(int /*enum nodetype*/ t,...) {
  12.     va_list ap;
  13.     Node *n;
  14.  
  15.     va_start(ap,t);
  16.  
  17.     switch (t) {
  18.     default:
  19.         fprint(2,"newnode: this can't happen\n");
  20.         exit(1);
  21.         /* NOTREACHED */
  22.     case rDUP:
  23.         n = nalloc(offsetof(Node, u[3]));
  24.         n->u[0].i = va_arg(ap, int);
  25.         n->u[1].i = va_arg(ap, int);
  26.         n->u[2].i = va_arg(ap, int);
  27.         break;
  28.     case rWORD:
  29.         n = nalloc(offsetof(Node, u[2]));
  30.         n->u[0].s = va_arg(ap, char *);
  31.         n->u[1].s = va_arg(ap, char *);
  32.         break;
  33.     case rBANG: case NOWAIT:
  34.     case rCOUNT: case rFLAT: case RMFN: case rSUBSHELL:
  35.     case VAR:
  36.         n = nalloc(offsetof(Node, u[1]));
  37.         n->u[0].p = va_arg(ap, Node *);
  38.         break;
  39.     case rANDAND: case ASSIGN: case BACKQ: case BODY: case BRACE: case CONCAT:
  40.     case rELSE: case EPILOG: case rIF: case NEWFN:
  41.     case rOROR: case PRE: case ARGS: case rSWITCH:
  42.     case MATCH: case VARSUB: case rWHILE: case LAPPEND:
  43.         n = nalloc(offsetof(Node, u[2]));
  44.         n->u[0].p = va_arg(ap, Node *);
  45.         n->u[1].p = va_arg(ap, Node *);
  46.         break;
  47.     case FORIN:
  48.         n = nalloc(offsetof(Node, u[3]));
  49.         n->u[0].p = va_arg(ap, Node *);
  50.         n->u[1].p = va_arg(ap, Node *);
  51.         n->u[2].p = va_arg(ap, Node *);
  52.         break;
  53.     case rPIPE:
  54.         n = nalloc(offsetof(Node, u[4]));
  55.         n->u[0].i = va_arg(ap, int);
  56.         n->u[1].i = va_arg(ap, int);
  57.         n->u[2].p = va_arg(ap, Node *);
  58.         n->u[3].p = va_arg(ap, Node *);
  59.         break;
  60.     case rREDIR:
  61.     case NMPIPE:
  62.         n = nalloc(offsetof(Node, u[3]));
  63.         n->u[0].i = va_arg(ap, int);
  64.         n->u[1].i = va_arg(ap, int);
  65.         n->u[2].p = va_arg(ap, Node *);
  66.         break;
  67.      }
  68.     n->type = t;
  69.     va_end(ap);
  70.     return n;
  71. }
  72.  
  73. /* copy a tree to malloc space. Used when storing the definition of a function */
  74.  
  75. Node *treecpy(Node *s, void (*alloc(SIZE_T))) {
  76.     Node *n;
  77.  
  78.     if (s == NULL)
  79.         return NULL;
  80.  
  81.     switch (s->type) {
  82.     default:
  83.         fprint(2,"treecpy: this can't happen\n");
  84.         exit(1);
  85.         /* NOTREACHED */
  86.     case rDUP:
  87.         n = alloc(offsetof(Node, u[3]));
  88.         n->u[0].i = s->u[0].i;
  89.         n->u[1].i = s->u[1].i;
  90.         n->u[2].i = s->u[2].i;
  91.         break;
  92.     case rWORD:
  93.         n = alloc(offsetof(Node, u[2]));
  94.         n->u[0].s = ecpy(s->u[0].s);
  95.         if (s->u[1].s != NULL) {
  96.             SIZE_T i = strlen(s->u[0].s);
  97.  
  98.             n->u[1].s = alloc(i);
  99.             memcpy(n->u[1].s, s->u[1].s, i);
  100.         } else
  101.             n->u[1].s = NULL;
  102.         break;
  103.     case rBANG: case NOWAIT:
  104.     case rCOUNT: case rFLAT: case RMFN: case rSUBSHELL: case VAR:
  105.         n = alloc(offsetof(Node, u[1]));
  106.         n->u[0].p = treecpy(s->u[0].p, alloc);
  107.         break;
  108.     case rANDAND: case ASSIGN: case BACKQ: case BODY: case BRACE: case CONCAT:
  109.     case rELSE: case EPILOG: case rIF: case NEWFN:
  110.     case rOROR: case PRE: case ARGS: case rSWITCH:
  111.     case MATCH: case VARSUB: case rWHILE: case LAPPEND:
  112.         n = alloc(offsetof(Node, u[2]));
  113.         n->u[0].p = treecpy(s->u[0].p, alloc);
  114.         n->u[1].p = treecpy(s->u[1].p, alloc);
  115.         break;
  116.     case FORIN:
  117.         n = alloc(offsetof(Node, u[3]));
  118.         n->u[0].p = treecpy(s->u[0].p, alloc);
  119.         n->u[1].p = treecpy(s->u[1].p, alloc);
  120.         n->u[2].p = treecpy(s->u[2].p, alloc);
  121.         break;
  122.     case rPIPE:
  123.         n = alloc(offsetof(Node, u[4]));
  124.         n->u[0].i = s->u[0].i;
  125.         n->u[1].i = s->u[1].i;
  126.         n->u[2].p = treecpy(s->u[2].p, alloc);
  127.         n->u[3].p = treecpy(s->u[3].p, alloc);
  128.         break;
  129.     case rREDIR:
  130.     case NMPIPE:
  131.         n = alloc(offsetof(Node, u[3]));
  132.         n->u[0].i = s->u[0].i;
  133.         n->u[1].i = s->u[1].i;
  134.         n->u[2].p = treecpy(s->u[2].p, alloc);
  135.         break;
  136.     }
  137.     n->type = s->type;
  138.     return n;
  139. }
  140.  
  141. /* free a function definition that is no longer needed */
  142.  
  143. void treefree(Node *s) {
  144.     if (s == NULL)
  145.         return;
  146.     switch (s->type) {
  147.     case rDUP:
  148.         break;
  149.     case rWORD:
  150.         efree(s->u[0].s);
  151.         efree(s->u[1].s);
  152.         break;
  153.     case rBANG: case NOWAIT:
  154.     case rCOUNT: case rFLAT: case RMFN:
  155.     case rSUBSHELL: case VAR:
  156.         treefree(s->u[0].p);
  157.         efree(s->u[0].p);
  158.         break;
  159.     case rANDAND: case ASSIGN: case BACKQ: case BODY: case BRACE: case CONCAT:
  160.     case rELSE: case EPILOG: case rIF: case NEWFN:
  161.     case rOROR: case PRE: case ARGS:
  162.     case rSWITCH: case MATCH:  case VARSUB: case rWHILE:
  163.     case LAPPEND:
  164.         treefree(s->u[1].p);
  165.         treefree(s->u[0].p);
  166.         efree(s->u[1].p);
  167.         efree(s->u[0].p);
  168.         break;
  169.     case FORIN:
  170.         treefree(s->u[2].p);
  171.         treefree(s->u[1].p);
  172.         treefree(s->u[0].p);
  173.         efree(s->u[2].p);
  174.         efree(s->u[1].p);
  175.         efree(s->u[0].p);
  176.         break;
  177.     case rPIPE:
  178.         treefree(s->u[2].p);
  179.         treefree(s->u[3].p);
  180.         efree(s->u[2].p);
  181.         efree(s->u[3].p);
  182.         break;
  183.     case rREDIR:
  184.     case NMPIPE:
  185.         treefree(s->u[2].p);
  186.         efree(s->u[2].p);
  187.         break;
  188.     default:
  189.         fprint(2,"treefree: this can't happen\n");
  190.         exit(1);
  191.     }
  192. }
  193.