/* * macro-11 cross reference generator * Jim Reeds for use with Harvard m11. * * Usage: * macxrf -[olsmpcer] infile [outfile] * * -l spool output to lpr * -o if specified, send output to stdout. else to av[2] * -s make a user-defined symbol cross reference * -m make a macro cross reference * -p make a permanent symbol cross reference * -c make a .pcsect cross reference. ['c' is holdover from rt-11, * where the only .psects are .csects] * -e make an error cross reference. [keyed by one-letter codes] * -r make a register use cross reference * * If none of [smpcer] are specified the default of "sme" is used. * * Effciency bug: should take input ('infile') from a pipe. */ #include #define LPR "/usr/ucb/bin/lpr" #define NCOLS 8 /* * Codes emitted by m11 */ #define PAGE 02 #define LINE 03 #include char *lets = "smpcer"; int want[6]; char *desire; int outflag; int lprflag; int debug; char *Roll[] = { "Symbols", "Macros", "Permanent symbols", "Psects", "Errors", "Registers" }; /* * # means a definition reference * * means a destructive reference */ char *Code[] = {" ", "# ", "* ", "#*"}; long tcount[6]; /* keep track of how many of each type */ int tany = 0; /* * Structure to store a reference. */ struct item { char *i_name; int i_code; int i_page; int i_line; struct item *i_left, *i_right; } *ihead = NULL; /* * Text strings are stored in a tree. This way * duplicate references to the same string use the same core. * This whole scheme is of doubtful cost-effectiveness. */ struct string { char *s_data; struct string *s_left, *s_right; } *shead = NULL; int Maxpage; char *symnam; main(ac, av) char **av; { char *s; int i; char symbol[7]; int code; int page, line, c; FILE *x = fopen(av[2], "r"); int Type; if(x == NULL) perror(av[2]),exit(1); lprflag = any('l', av[1]); outflag = any('o', av[1]); debug = any('x', av[1]); if(join(lets, av[1])) desire = av[1]; else desire = "sme"; /* default cref request */ for(i=0;i<6;i++) want[i] = any(lets[i], desire); if(!outflag) freopen(av[3], "a", stdout), fseek(stdout, 0L, 2); unlink(av[2]); line = 0; page = 0; while((c = getc(x)) != EOF) { if (c==0) break; else if(c == PAGE) line = 0, page++; else if(c == LINE) line++; else if (c<040 && (c >= 020)) { Type = c - 020; if(Type>5) fprintf(stderr, "*** CREF TYPE %o ***\n", c); } else if (c >= 040) { ungetc(c, x); s = symbol; while( (c = getc(x)) >= 040) { if(isupper(c)) c =tolower(c); *s++ = c; } *s = 0; if(c <020 || c > 023 ) fprintf(stderr, "*** CREF CODE %o ***\n", c); process(Type, symbol, c & 3, page, line); } } if(debug) dump(ihead); if(debug) { fprintf(stderr, "tany=%d\n", tany); for(i=0; iMaxpage) Maxpage = page; if(debug) fprintf(stderr, "process(%o, %s, %o, %d, %d)\n", t, s, c, page,l); if(nocore) return; if(want[t] == 0) return; p = (struct item *) calloc(1, sizeof (struct item)); if(p == NULL) { fprintf(stderr, "Cref: Ran out of core, page %d, line %d\n",p, l); nocore++; return; } tcount[t]++; tany |= 1; p->i_code = t | (c<<8); p->i_name = stash(s); p->i_page = page; p->i_line = l; ihead = addtree(ihead, p); } comp(p, q) register struct item *p, *q; { register x; if(p->i_name != q->i_name) x = strcmp(p->i_name, q->i_name); else x = 0; if(x == 0) { x = p->i_page - q->i_page; if(x == 0) x = p->i_line - q->i_line; if(x == 0) x= p->i_code - q->i_code; } return(x); } struct item * addtree(b, p) struct item *b, *p; { register c; if(b == NULL) return(b = p); c = comp(b, p); if(c < 0) b->i_left = addtree(b->i_left, p); else if (c>0) b->i_right= addtree(b->i_right, p); return(b); } char *stash(s) register char *s; { shead = store(shead, s); return(__s); } store(b, s) register struct string *b; register char *s; { register x; if(b == 0) { b = (struct string *) calloc(1, sizeof(struct string)); __s = b->s_data = strsave(s); } else if((x=strcmp(b->s_data, s)) == 0) __s = b->s_data; else if(x<0) b->s_left = store(b->s_left, s); else b->s_right= store(b->s_right,s); return(b); } strsave(s) register char *s; { register char *t; char *calloc(); t = calloc(strlen(s)+1, 1); strcpy(t, s); return(t); } int crcol = 0; crprint(p, i) register struct item *p; { if(p == NULL) return; crprint(p->i_right, i); if ((p->i_code & 07) == i) { char *code; if (symnam != p->i_name) crcol = 0, printf("\n%-6.6s\t", symnam = p->i_name); if(crcol == NCOLS) { crcol = 1; printf("\n\t"); } else crcol++; if(i == 4 || i == 2) code = 0; else code = Code[3 & (p->i_code >>8)]; prx(p->i_page, p->i_line, code, crcol); } crprint(p->i_left, i); } prx(page, line, code, col) char *code; { char buf[15]; if(Maxpage>1) sprintf(buf, "%d-%d", page, line); else sprintf(buf, "%d", line); if(code) strcat(buf, code); if(col == NCOLS) printf("%s", buf); else { printf("%8s", buf); if(strlen(buf) > 7) printf(" "); } } join(s,t) register char *s, *t; { for(;*s;s++) if(any(*s, t)) return(1); return(0); } any(c, s) register char c, *s; { for(;*s;s++) if(*s == c) return(1); return(0); } minuspr(x, y) { char buf[30]; sprintf(buf,"%d-%d", x, y); printf(" %4s", buf); } dump(p) struct item *p; { if(p==NULL)return; dump(p->i_left); fprintf(stderr, "%s: %o %d %d\n", p->i_name, p->i_code, p->i_page, p->i_line); dump(p->i_right); }