/* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * nodes.c * * Node allocation, deallocation, searching, printing * and other node handling */ #include #include "param.h" #include "nodes.h" extern FILE *output; NODE *freelist; #define NODEINCR 100 extern int oflags[]; #define debug oflags['n'-'a'] #define NODELEN (sizeof(NODE)/4) int nodesmade, nodesavail; NODE * allocnode() { char *calloc(); NODE *t; int i; retry: if (freelist != 0) { t = freelist; freelist = t->n_next; lclr(t, NODELEN); nodesavail--; if (debug) printf("%lx+ ", t); return t; } t = (NODE *)calloc(NODEINCR, sizeof(NODE)); if (t == 0) { printf("malloc failure\n"); exit(1); } nodesmade += NODEINCR; nodesavail += NODEINCR; for (i=0; in_flags & N_ISFREE) { printf("%lx ", t); error("Freeing free node"); exit(1); } else t->n_flags |= N_ISFREE; t->n_next = freelist; freelist = t; nodesavail++; if (debug) printf("%lx- ", t); } freenode(t) NODE *t; { register NODE *nxt; if (t == NULL) return; again: if (t->n_right) freenode(t->n_right); if (t->n_nmx) freenode(t->n_nmx); if (t->n_tptr && (t->n_flags & N_COPYT) == 0) freenode(t->n_tptr); nxt = t->n_left; freeunit(t); if (nxt) { t = nxt; goto again; /* minimize left recursion */ } } put_nnm(t) NODE *t; { printf("%s", t->n_name); while (t->n_nmx) { t = t->n_nmx; printf("%s", t->n_name); } } qput_nnm(t, fd) NODE *t; FILE *fd; { fprintf(fd, "%s", t->n_name); while (t->n_nmx) { t = t->n_nmx; fprintf(fd, "%s", t->n_name); } } fput_nnm(t) NODE *t; { fprintf(output, "%s", t->n_name); while (t->n_nmx) { t = t->n_nmx; fprintf(output, "%s", t->n_name); } } /* add a short string (less than NMXSIZE) to front of name */ nnmins(t, s) NODEP t; char *s; { register i, j; char tbuf[NMSIZE]; NODEP n; i = strlen(t->n_name); j = strlen(s); if (j > NMSIZE-1) return; /* compiler error */ if (i+j <= NMSIZE-1) { /* fits in node */ strcpy(tbuf, t->n_name); strcpy(t->n_name, s); strcpy(t->n_name+j, tbuf); } else { n = allocnode(); n->n_nmx = t->n_nmx; t->n_nmx = n; strcpy(n->n_name, t->n_name); strcpy(t->n_name, s); } } /* add a short string (less than NMXSIZE) to end of name */ nnmadd(t, s) NODE *t; char *s; { register i,j; int sizeb; NODEP n; /* find last node */ sizeb = NMSIZE; while (t->n_nmx) { t = t->n_nmx; sizeb = NMXSIZE; } /* fits in current last node? */ i = strlen(s); j = strlen(t->n_name); if (i < sizeb-j) { strcat(t->n_name, s); return; } /* put all of s in new node */ n = allocnode(); t->n_nmx = n; t = n; strncpy(t->n_name, s, NMXSIZE-1); t->n_name[NMXSIZE-1] = 0; } nscpy(t, s) NODE *t; char *s; { register i; NODEP n; i = strlen(s); strncpy(t->n_name, s, NMSIZE-1); t->n_name[NMSIZE-1] = 0; i -= NMSIZE-1; s += NMSIZE-1; while (i > 0) { n = allocnode(); t->n_nmx = n; t = n; strncpy(t->n_name, s, NMXSIZE-1); t->n_name[NMXSIZE-1] = 0; i -= NMXSIZE-1; s += NMXSIZE-1; } } putlist(head, np) NODE **head, *np; { np->n_next = *head; *head = np; } puthlist(head, np) NODE *head[], *np; { putlist(&head[hash(np->n_name)], np); } NODE * llook(head, np) NODE *head, *np; { register NODEP p; for (p=head; p != NULL; p = p->n_next) if (xstrcmp(p, np) == 0) { return p; } return NULL; } NODE * hlook(head, np) NODE *head[], *np; { register NODEP p; p = head[hash(np->n_name)]; return llook(p, np); } hash(s) register char *s; { register hval; hval = 0; while (*s) hval += *s++; return hval & (NHASH-1); } xstrcmp(p1, p2) NODE *p1, *p2; { int rv; if ((rv = strcmp(p1->n_name, p2->n_name)) != 0) return rv; if (p1->n_nmx == NULL) { if (p2->n_nmx == NULL) return 0; return -1; } if (p2->n_nmx == NULL) return 1; return xstrcmp(p1->n_nmx, p2->n_nmx); } char * scopy(s) char *s; { int i; char *p; i = strlen(s)+1; if (i > sizeof(NODE)) { error("preproc name too big"); i = sizeof(NODE); s[i-1] = 0; } p = (char *)allocnode(); strcpy(p, s); return p; } sfree(s) char *s; { NODEP np; np = (NODEP)s; np->n_flags = 0; freeunit(np); } printlist(np) NODE *np; { putchar('\n'); prln(np, 2); } prln(np, indent) NODE *np; { register NODE *svl, *nxtl; for (svl=np; svl != NULL; svl = nxtl) { nxtl = svl->n_next; svl->n_next = NULL; prnode(svl,indent); svl->n_next = nxtl; /* special hack for tag list */ if ((svl->n_flags & N_BRKPR) && svl->n_right) prln(svl->n_right, indent+2); } } codeprint(np) NODEP np; { putchar('\n'); cprnode(np,0); } cprnode(np,indent) NODE *np; { int ni; NODEP tp; ni = indent+1; while (indent--) putchar(' '); if (np == NULL) { printf("\n"); return; } put_nnm(np); /* Note: BRKPR doesnt break long names */ if (np->g_offs) printf(" o%ld ", np->g_offs); if (np->g_rno) printf(" r%d ", np->g_rno); if (np->g_needs) printf(" n%x ", np->g_needs); if (debug) { printf("@%lx ", np); if (np->n_flags & N_COPYT) printf("C "); if (np->n_flags & N_BRKPR) printf("B "); } if (np->n_flags & N_BRKPR) { putchar('\n'); return; } if (np->g_betw) printf(" {%s}", np->g_betw); if (np->g_code) { if (np->n_flags & N_COPYT) printf(" <%s>", np->g_code); else for (tp=np->g_code; tp; tp = tp->g_code) printf(" <%s>", tp->n_name); } putchar(' '); out_a(np, stdout); putchar('\n'); if (np->n_left) { cprnode(np->n_left,ni); } else if (np->n_right) cprnode(NULL, ni); if (np->n_right) { cprnode(np->n_right,ni); } } printnode(np) NODE *np; { putchar('\n'); prnode(np,0); } prnode(np,indent) NODE *np; { int ni; ni = indent+1; while (indent--) putchar(' '); if (np == NULL) { printf("\n"); return; } put_nnm(np); /* Note: BRKPR doesnt break long names */ if (np->e_offs) printf(" o%ld ", np->e_offs); if (np->e_rno) printf(" r%d ", np->e_rno); if (np->e_fldw) printf(" (%d,%d) ", np->e_fldw, np->e_fldo); if (debug) { printf("@%lx ", np); if (np->n_flags & N_COPYT) printf("C "); if (np->n_flags & N_BRKPR) printf("B "); } if (np->n_flags & N_BRKPR) { putchar('\n'); return; } if (np->n_tptr) { if (np->e_flags & 256) /* IMMEDID */ printf(" $$$ "); tprint(np->n_tptr); } putchar('\n'); if (np->n_left) { prnode(np->n_left,ni); } else if (np->n_right) prnode(NULL, ni); if (np->n_right) { prnode(np->n_right,ni); } } tprint(np) NODEP np; { while (np != NULL) { putchar(' '); put_nnm(np); #ifdef HANS if (np->t_size) printf(" s%ld", np->t_size); if (np->t_aln) printf(" a%d", np->t_aln); #endif if (debug) printf("@%lx", np); np = np->n_tptr; } } NODEP copynode(op) NODEP op; { NODEP np; if (op == NULL) return NULL; np = allocnode(); lcpy(np, op, NODELEN); if (np->n_nmx) np->n_nmx = copynode(np->n_nmx); if (np->n_right) np->n_right = copynode(np->n_right); if (np->n_left) np->n_left = copynode(np->n_left); if (np->n_tptr) np->n_flags |= N_COPYT; return np; } NODEP copyone(op) NODEP op; { NODEP np; if (op == NULL) return NULL; np = allocnode(); lcpy(np, op, NODELEN); if (np->n_nmx) np->n_nmx = copyone(np->n_nmx); if (np->n_right) np->n_right = NULL; if (np->n_left) np->n_left = NULL; if (np->n_tptr) np->n_flags |= N_COPYT; return np; } NODEP copy_nol(op) NODEP op; { NODEP np; if (op == NULL) return NULL; np = allocnode(); lcpy(np, op, NODELEN); if (np->n_nmx) np->n_nmx = copynode(np->n_nmx); if (np->n_right) /* break right links */ np->n_right = NULL; if (np->n_tptr) np->n_flags |= N_COPYT; return np; } NODEP copylist(np, tailp) NODE *np, **tailp; { NODEP rv, nx; register NODEP tail; if (np == NULL) { *tailp = NULL; return NULL; } rv = copy_nol(np); tail = rv; while (tail->n_left) { nx = copy_nol(tail->n_left); tail->n_left = nx; tail = nx; } *tailp = tail; return rv; } NODE * nthnode(np, n) NODE *np; { while (n--) if (np == NULL) return NULL; else np=np->n_next; return np; } NODE * rthnode(np, n) NODE *np; { while (n--) if (np == NULL) return NULL; else np=np->n_right; return np; }