home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / prog_c / zc.lzh / ZC / ZCSRC.LZH / src / nodes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-06  |  10.1 KB  |  640 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    nodes.c
  12.  *
  13.  *    Node allocation, deallocation, searching, printing
  14.  *    and other node handling
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include "param.h"
  19. #include "nodes.h"
  20. #include "tytok.h"
  21.  
  22. extern FILE *output;
  23. NODE *freelist;
  24.  
  25. #define NODEINCR    100
  26.  
  27. extern int oflags[];
  28. #define debug oflags['n'-'a']
  29.  
  30. #define NODELEN    (sizeof(NODE)/4)
  31.  
  32. int nodesmade, nodesavail;
  33.  
  34. NODE *
  35. allocnode()
  36. {
  37.     char *calloc();
  38.     NODE *t;
  39.     int i;
  40.  
  41. retry:
  42.     if (freelist != 0) {
  43.         t = freelist;
  44.         freelist = t->n_next;
  45.         lclr(t, NODELEN);
  46.         nodesavail--;
  47.         if (debug)
  48.             printf("%lx+ ", t);
  49.         return t;
  50.     }
  51.     t = (NODE *)calloc(NODEINCR, sizeof(NODE));
  52.     if (t == 0) {
  53.         printf("malloc failure\n");
  54.         exit(1);
  55.     }
  56.     nodesmade += NODEINCR;
  57.     nodesavail += NODEINCR;
  58.     for (i=0; i<NODEINCR; i++)
  59.         t[i].n_next = &t[i+1];
  60.     t[NODEINCR-1].n_next = 0;
  61.     freelist = t;
  62.     goto retry;
  63. }
  64.  
  65. freeunit(t)
  66. NODE *t;
  67. {
  68.     if (t->n_flags & N_ISFREE) {
  69.         printf("%lx ", t);
  70.         error("Freeing free node");
  71.         exit(1);
  72.     } else
  73.         t->n_flags |= N_ISFREE;
  74.     t->n_next = freelist;
  75.     freelist = t;
  76.     nodesavail++;
  77.     if (debug)
  78.         printf("%lx- ", t);
  79. }
  80.  
  81. freenode(t)
  82. NODE *t;
  83. {
  84.     register NODE *nxt;
  85.  
  86.     if (t == NULL) return;
  87. again:
  88.     if (t->n_right)
  89.         freenode(t->n_right);
  90.     if (t->n_nmx)
  91.         freenode(t->n_nmx);
  92.     if (t->n_tptr && (t->n_flags & N_COPYT) == 0)
  93.         freenode(t->n_tptr);
  94.     nxt = t->n_left;
  95.     freeunit(t);
  96.     if (nxt) {
  97.         t = nxt;
  98.         goto again;    /* minimize left recursion */
  99.     }
  100. }
  101.  
  102. put_nnm(t)
  103. NODE *t;
  104. {
  105.     printf("%s", t->n_name);
  106.     while (t->n_nmx) {
  107.         t = t->n_nmx;
  108.         printf("%s", t->n_name);
  109.     }
  110. }
  111.  
  112. qput_nnm(t, fd)
  113. NODE *t;
  114. FILE *fd;
  115. {
  116.     fprintf(fd, "%s", t->n_name);
  117.     while (t->n_nmx) {
  118.         t = t->n_nmx;
  119.         fprintf(fd, "%s", t->n_name);
  120.     }
  121. }
  122.  
  123. fput_nnm(t)
  124. NODE *t;
  125. {
  126.     fprintf(output, "%s", t->n_name);
  127.     while (t->n_nmx) {
  128.         t = t->n_nmx;
  129.         fprintf(output, "%s", t->n_name);
  130.     }
  131. }
  132.  
  133. /* add a short string (less than NMXSIZE) to front of name */
  134. nnmins(t, s)
  135. NODEP t;
  136. char *s;
  137. {
  138.     register i, j;
  139.     char tbuf[NMSIZE];
  140.     NODEP n;
  141.  
  142.     i = strlen(t->n_name);
  143.     j = strlen(s);
  144.     if (j > NMSIZE-1)
  145.         return;        /* compiler error */
  146.     if (i+j <= NMSIZE-1) {        /* fits in node */
  147.         strcpy(tbuf, t->n_name);
  148.         strcpy(t->n_name, s);
  149.         strcpy(t->n_name+j, tbuf);
  150.     } else {
  151.         n = allocnode();
  152.         n->n_nmx = t->n_nmx;
  153.         t->n_nmx = n;
  154.         strcpy(n->n_name, t->n_name);
  155.         strcpy(t->n_name, s);
  156.     }
  157. }
  158.  
  159. /* add a short string (less than NMXSIZE) to end of name */
  160. nnmadd(t, s)
  161. NODE *t;
  162. char *s;
  163. {
  164.     register i,j;
  165.     int sizeb;
  166.     NODEP n;
  167.  
  168.     /* find last node */
  169.     sizeb = NMSIZE;
  170.     while (t->n_nmx) {
  171.         t = t->n_nmx;
  172.         sizeb = NMXSIZE;
  173.     }
  174.     /* fits in current last node? */
  175.     i = strlen(s);
  176.     j = strlen(t->n_name);
  177.     if (i < sizeb-j) {
  178.         strcat(t->n_name, s);
  179.         return;
  180.     }
  181.     /* put all of s in new node */
  182.     n = allocnode();
  183.     t->n_nmx = n;
  184.     t = n;
  185.     strncpy(t->n_name, s, NMXSIZE-1);
  186.     t->n_name[NMXSIZE-1] = 0;
  187. }
  188.  
  189. nscpy(t, s)
  190. NODE *t;
  191. char *s;
  192. {
  193.     register i;
  194.     NODEP n;
  195.  
  196.     i = strlen(s);
  197.     strncpy(t->n_name, s, NMSIZE-1);
  198.     t->n_name[NMSIZE-1] = 0;
  199.     i -= NMSIZE-1;
  200.     s += NMSIZE-1;
  201.     while (i > 0) {
  202.         n = allocnode();
  203.         t->n_nmx = n;
  204.         t = n;
  205.         strncpy(t->n_name, s, NMXSIZE-1);
  206.         t->n_name[NMXSIZE-1] = 0;
  207.         i -= NMXSIZE-1;
  208.         s += NMXSIZE-1;
  209.     }
  210. }
  211.  
  212. putlist(head, np)
  213. NODE **head, *np;
  214. {
  215.     np->n_next = *head;
  216.     *head = np;
  217. }
  218.  
  219. puthlist(head, np)
  220. NODE *head[], *np;
  221. {
  222.     putlist(&head[hash(np->n_name)], np);
  223. }
  224.  
  225. NODE *
  226. llook(head, np)
  227. NODE *head, *np;
  228. {
  229.     register NODEP p;
  230.  
  231.     for (p=head; p != NULL; p = p->n_next)
  232.         if (xstrcmp(p, np) == 0) {
  233.             return p;
  234.         }
  235.     return NULL;
  236. }
  237.  
  238. NODE *
  239. hlook(head, np)
  240. NODE *head[], *np;
  241. {
  242.     register NODEP p;
  243.  
  244.     p = head[hash(np->n_name)];
  245.     return llook(p, np);
  246. }
  247.  
  248. hash(s)
  249. register char *s;
  250. {
  251.     register hval;
  252.  
  253.     hval = 0;
  254.     while (*s)
  255.         hval += *s++;
  256.     return hval & (NHASH-1);
  257. }
  258.  
  259. xstrcmp(p1, p2)
  260. NODE *p1, *p2;
  261. {
  262.     int rv;
  263.  
  264.     if ((rv = strcmp(p1->n_name, p2->n_name)) != 0)
  265.         return rv;
  266.     if (p1->n_nmx == NULL) {
  267.         if (p2->n_nmx == NULL)
  268.             return 0;
  269.         return -1;
  270.     }
  271.     if (p2->n_nmx == NULL)
  272.         return 1;
  273.     return xstrcmp(p1->n_nmx, p2->n_nmx);
  274. }
  275.  
  276. char *
  277. scopy(s)
  278. char *s;
  279. {
  280.     int i;
  281.     char *p;
  282.  
  283.     i = strlen(s)+1;
  284.     if (i > sizeof(NODE)) {
  285.         error("preproc name too big");
  286.         i = sizeof(NODE);
  287.         s[i-1] = 0;
  288.     }
  289.     p = (char *)allocnode();
  290.     strcpy(p, s);
  291.     return p;
  292. }
  293.  
  294. sfree(s)
  295. char *s;
  296. {
  297.     NODEP np;
  298.  
  299.     np = (NODEP)s;
  300.     np->n_flags = 0;
  301.     freeunit(np);
  302. }
  303.  
  304. printlist(np)
  305. NODE *np;
  306. {
  307.     putchar('\n');
  308.     prln(np, 2);
  309. }
  310.  
  311. prln(np, indent)
  312. NODE *np;
  313. {
  314.     register NODE *svl, *nxtl;
  315.  
  316.     for (svl=np; svl != NULL; svl = nxtl) {
  317.         nxtl = svl->n_next;
  318.         svl->n_next = NULL;
  319.         prnode(svl,indent);
  320.         svl->n_next = nxtl;
  321.         /* special hack for tag list */
  322.         if ((svl->n_flags & N_BRKPR) && svl->n_right)
  323.             prln(svl->n_right, indent+2);
  324.     }
  325. }
  326.  
  327. codeprint(np)
  328. NODEP np;
  329. {
  330.     putchar('\n');
  331.     cprnode(np,0);
  332. }
  333.  
  334. cprnode(np,indent)
  335. NODE *np;
  336. {
  337.     int ni;
  338.     NODEP tp;
  339.  
  340.     ni = indent+1;
  341.     while (indent--)
  342.         putchar(' ');
  343.     if (np == NULL) {
  344.         printf("<NULL>\n");
  345.         return;
  346.     }
  347.     put_nnm(np);    /* Note: BRKPR doesnt break long names */
  348.     if (np->g_offs)
  349.         printf(" o%ld ", np->g_offs);
  350.     if (np->g_rno)
  351.         printf(" r%d ", np->g_rno);
  352.     if (np->g_needs)
  353.         printf(" n%x ", np->g_needs);
  354.     if (debug) {
  355.         printf("@%lx ", np);
  356.         if (np->n_flags & N_COPYT)
  357.             printf("C ");
  358.         if (np->n_flags & N_BRKPR)
  359.             printf("B ");
  360.     }
  361.     if (np->n_flags & N_BRKPR) {
  362.         putchar('\n');
  363.         return;
  364.     }
  365.     if (np->g_betw)
  366.         printf(" {%s}", np->g_betw);
  367.     if (np->g_code) {
  368.         if (np->n_flags & N_COPYT)
  369.             printf(" <%s>", np->g_code);
  370.         else
  371.             for (tp=np->g_code; tp; tp = tp->g_code)
  372.                 printf(" <%s>", tp->n_name);
  373.     }
  374.     putchar(' ');
  375.     out_a(np, stdout);
  376.     putchar('\n');
  377.     if (np->n_left) {
  378.         cprnode(np->n_left,ni);
  379.     } else if (np->n_right)
  380.         cprnode(NULL, ni);
  381.     if (np->n_right) {
  382.         cprnode(np->n_right,ni);
  383.     }
  384. }
  385.  
  386. printnode(np)
  387. NODE *np;
  388. {
  389.     putchar('\n');
  390.     prnode(np,0);
  391. }
  392.  
  393. prnode(np,indent)
  394. NODE *np;
  395. {
  396.     int ni;
  397.  
  398.     ni = indent+1;
  399.     while (indent--)
  400.         putchar(' ');
  401.     if (np == NULL) {
  402.         printf("<NULL>\n");
  403.         return;
  404.     }
  405.     put_nnm(np);    /* Note: BRKPR doesnt break long names */
  406.     if (np->e_offs)
  407.         printf(" o%ld ", np->e_offs);
  408.     if (np->e_rno)
  409.         printf(" r%d ", np->e_rno);
  410.     if (np->e_fldw)
  411.         printf(" (%d,%d) ", np->e_fldw, np->e_fldo);
  412.     if (debug) {
  413.         printf("@%lx ", np);
  414.         if (np->n_flags & N_COPYT)
  415.             printf("C ");
  416.         if (np->n_flags & N_BRKPR)
  417.             printf("B ");
  418.     }
  419.     if (np->n_flags & N_BRKPR) {
  420.         putchar('\n');
  421.         return;
  422.     }
  423.     if (np->n_tptr) {
  424.         if (np->e_flags & 256)    /* IMMEDID */
  425.             printf(" $$$ ");
  426.         tprint(np->n_tptr);
  427.     }
  428.     putchar('\n');
  429.     if (np->n_left) {
  430.         prnode(np->n_left,ni);
  431.     } else if (np->n_right)
  432.         prnode(NULL, ni);
  433.     if (np->n_right) {
  434.         prnode(np->n_right,ni);
  435.     }
  436. }
  437.  
  438. tprint(np)
  439. NODEP np;
  440. {
  441.     while (np != NULL) {
  442.         putchar(' ');
  443.         put_nnm(np);
  444. #ifdef HANS
  445.         if (np->t_size)
  446.             printf(" s%ld", np->t_size);
  447.         if (np->t_aln)
  448.             printf(" a%d", np->t_aln);
  449. #endif
  450.         if (np->e_sc)
  451.             printf(" c%c", np->e_sc);
  452.         if (debug)
  453.             printf("@%lx", np);
  454.         np = np->n_tptr;
  455.     }
  456. }
  457.  
  458. NODEP
  459. copynode(op)
  460. NODEP op;
  461. {
  462.     NODEP np;
  463.  
  464.     if (op == NULL) return NULL;
  465.     np = allocnode();
  466.     lcpy(np, op, NODELEN);
  467.     if (np->n_nmx)
  468.         np->n_nmx = copynode(np->n_nmx);
  469.     if (np->n_right)
  470.         np->n_right = copynode(np->n_right);
  471.     if (np->n_left)
  472.         np->n_left = copynode(np->n_left);
  473.     if (np->n_tptr)
  474.         np->n_flags |= N_COPYT;
  475.     return np;
  476. }
  477.  
  478. NODEP
  479. copyone(op)
  480. NODEP op;
  481. {
  482.     NODEP np;
  483.  
  484.     if (op == NULL) return NULL;
  485.     np = allocnode();
  486.     lcpy(np, op, NODELEN);
  487.     if (np->n_nmx)
  488.         np->n_nmx = copyone(np->n_nmx);
  489.     if (np->n_right)
  490.         np->n_right = NULL;
  491.     if (np->n_left)
  492.         np->n_left = NULL;
  493.     if (np->n_tptr)
  494.         np->n_flags |= N_COPYT;
  495.     return np;
  496. }
  497.  
  498. NODEP
  499. copy_nol(op)
  500. NODEP op;
  501. {
  502.     NODEP np;
  503.  
  504.     if (op == NULL) return NULL;
  505.     np = allocnode();
  506.     lcpy(np, op, NODELEN);
  507.     if (np->n_nmx)
  508.         np->n_nmx = copynode(np->n_nmx);
  509.     if (np->n_right) /* break right links */
  510.         np->n_right = NULL;
  511.     if (np->n_tptr)
  512.         np->n_flags |= N_COPYT;
  513.     return np;
  514. }
  515.  
  516. NODEP
  517. copylist(np, tailp)
  518. NODE *np, **tailp;
  519. {
  520.     NODEP rv, nx;
  521.     register NODEP tail;
  522.  
  523.     if (np == NULL) {
  524.         *tailp = NULL;
  525.         return NULL;
  526.     }
  527.     rv = copy_nol(np);
  528.     tail = rv;
  529.     while (tail->n_left) {
  530.         nx = copy_nol(tail->n_left);
  531.         tail->n_left = nx;
  532.         tail = nx;
  533.     }
  534.     *tailp = tail;
  535.     return rv;
  536. }
  537.  
  538. NODE *
  539. nthnode(np, n)
  540. NODE *np;
  541. {
  542.     while (n--)
  543.         if (np == NULL)
  544.             return NULL;
  545.         else
  546.             np=np->n_next;
  547.     return np;
  548. }
  549.  
  550. NODE *
  551. rthnode(np, n)
  552. NODE *np;
  553. {
  554.     while (n--)
  555.         if (np == NULL)
  556.             return NULL;
  557.         else
  558.             np=np->n_right;
  559.     return np;
  560. }
  561.  
  562. /*
  563.  * do_public: Put out a "Public" directive for each global symbol - JAL
  564.  */
  565. void do_public(np)
  566. NODE *np;
  567. {
  568.     register NODE *svl, *nxtl;
  569.     unsigned int i;
  570.     void putlibcall();
  571.  
  572.     for( svl=np; svl!=NULL; svl=nxtl){
  573.         nxtl = svl->n_next;
  574.         if ( (i = svl->n_flags & (N_XREF | N_XDEF)) ){
  575.             if ( i & N_XDEF )
  576.                 fputs("\tXDEF\t_", output);
  577.             else 
  578.                 fputs("\tXREF\t _", output);
  579.             fput_nnm(svl);
  580.             putc('\n', output);
  581.         }
  582.  
  583.     }
  584. }
  585.  
  586. /*
  587.  * Logic to save library call names added by J. Lydiatt.  These do not
  588.  * have to be very efficient as there aren't too many of these.
  589.  */
  590.  
  591. struct libcall{
  592.     struct libcall *next;
  593.     char name[1];
  594. };
  595.  
  596. typedef struct libcall LIBCALL;
  597. static LIBCALL sentinel={&sentinel,NULL};
  598. static LIBCALL *libcalltail = &sentinel;
  599. /*
  600.  * addlibcall: Save library calls in a link list to dump later.
  601.  */
  602. void addlibcall(name)
  603. char *name;
  604. {
  605.     register LIBCALL *p;
  606.     char *malloc();
  607.  
  608.     for (p=libcalltail; p!=&sentinel; p=p->next){
  609.         if ( strcmp(p->name, name) == 0 )
  610.             return; /* already there */
  611.     }
  612.  
  613.     /*
  614.      * Not there!  Let's add it.
  615.      */
  616.     p = (LIBCALL *)malloc(sizeof sentinel + strlen(name));
  617.     p->next = libcalltail;
  618.     libcalltail = p;
  619.     (void)strcpy(p->name, name);
  620. }
  621.  
  622. /*
  623.  * putlibcalls: gen a list of PUBLIC stmts for library calls.
  624.  *    (Internal calls begin with a "%")
  625.  */
  626. void putlibcalls()
  627. {
  628.     register LIBCALL *p, *q;
  629.  
  630.     for ( p=libcalltail; p!=&sentinel; p=q){
  631.         if ( p->name[0] == '%' )
  632.             fprintf(output, "\tXREF\t%s\n", &p->name[1]);
  633.         else
  634.             fprintf(output, "\tXREF\t_%s\n", p->name);
  635.         q = p->next;
  636.         free(p);
  637.     }
  638.     libcalltail = &sentinel;
  639. }
  640.