1: /* 2: * macro-11 cross reference generator 3: * Jim Reeds for use with Harvard m11. 4: * 5: * Usage: 6: * macxrf -[olsmpcer] infile [outfile] 7: * 8: * -l spool output to lpr 9: * -o if specified, send output to stdout. else to av[2] 10: * -s make a user-defined symbol cross reference 11: * -m make a macro cross reference 12: * -p make a permanent symbol cross reference 13: * -c make a .pcsect cross reference. ['c' is holdover from rt-11, 14: * where the only .psects are .csects] 15: * -e make an error cross reference. [keyed by one-letter codes] 16: * -r make a register use cross reference 17: * 18: * If none of [smpcer] are specified the default of "sme" is used. 19: * 20: * Effciency bug: should take input ('infile') from a pipe. 21: */ 22: 23: #include <stdio.h> 24: #define LPR "/usr/ucb/bin/lpr" 25: #define NCOLS 8 26: 27: /* 28: * Codes emitted by m11 29: */ 30: 31: #define PAGE 02 32: #define LINE 03 33: 34: #include <ctype.h> 35: char *lets = "smpcer"; 36: int want[6]; 37: 38: char *desire; 39: int outflag; 40: int lprflag; 41: int debug; 42: char *Roll[] = { 43: "Symbols", 44: "Macros", 45: "Permanent symbols", 46: "Psects", 47: "Errors", 48: "Registers" 49: }; 50: /* 51: * # means a definition reference 52: * * means a destructive reference 53: */ 54: char *Code[] = {" ", "# ", "* ", "#*"}; 55: long tcount[6]; /* keep track of how many of each type */ 56: int tany = 0; 57: 58: /* 59: * Structure to store a reference. 60: */ 61: 62: struct item { 63: char *i_name; 64: int i_code; 65: int i_page; 66: int i_line; 67: struct item *i_left, *i_right; 68: } *ihead = NULL; 69: 70: /* 71: * Text strings are stored in a tree. This way 72: * duplicate references to the same string use the same core. 73: * This whole scheme is of doubtful cost-effectiveness. 74: */ 75: struct string { 76: char *s_data; 77: struct string *s_left, *s_right; 78: } *shead = NULL; 79: 80: int Maxpage; 81: char *symnam; 82: 83: main(ac, av) 84: char **av; 85: { 86: char *s; 87: int i; 88: char symbol[7]; 89: int code; 90: int page, line, c; 91: FILE *x = fopen(av[2], "r"); 92: int Type; 93: if(x == NULL) 94: perror(av[2]),exit(1); 95: lprflag = any('l', av[1]); 96: outflag = any('o', av[1]); 97: debug = any('x', av[1]); 98: if(join(lets, av[1])) 99: desire = av[1]; 100: else 101: desire = "sme"; /* default cref request */ 102: 103: for(i=0;i<6;i++) 104: want[i] = any(lets[i], desire); 105: 106: if(!outflag) 107: freopen(av[3], "a", stdout), fseek(stdout, 0L, 2); 108: 109: unlink(av[2]); 110: line = 0; 111: page = 0; 112: while((c = getc(x)) != EOF) 113: { 114: if (c==0) 115: break; 116: else if(c == PAGE) 117: line = 0, page++; 118: else if(c == LINE) 119: line++; 120: else if (c<040 && (c >= 020)) 121: { 122: Type = c - 020; 123: if(Type>5) 124: fprintf(stderr, "*** CREF TYPE %o ***\n", c); 125: } 126: else if (c >= 040) 127: { 128: ungetc(c, x); 129: s = symbol; 130: while( (c = getc(x)) >= 040) 131: { 132: if(isupper(c)) 133: c =tolower(c); 134: *s++ = c; 135: } 136: *s = 0; 137: 138: if(c <020 || c > 023 ) 139: fprintf(stderr, "*** CREF CODE %o ***\n", c); 140: process(Type, symbol, c & 3, page, line); 141: } 142: } 143: 144: 145: 146: if(debug) 147: dump(ihead); 148: if(debug) 149: { 150: fprintf(stderr, "tany=%d\n", tany); 151: for(i=0; i<ac; i++)fprintf(stderr, "%s\n", av[i]); 152: for(i=0; i<6; i++) fprintf(stderr, "want = %d, tcount = %D\n", 153: want[i], tcount[i]); 154: } 155: if(tany) { 156: printf("\nMacro-11 Cross Reference Listing.\n"); 157: for(i=0; i<6; i++) { 158: if(tcount[i] == 0L) continue; 159: if(want[i] == 0) continue; 160: printf("\n%s:\n", Roll[i]); 161: symnam = 0; 162: crprint(ihead, i); 163: printf("\n"); 164: } 165: } 166: if(lprflag && outflag) { 167: execl(LPR, LPR, av[3], 0); 168: perror(LPR); 169: exit(1); 170: } 171: exit(0); 172: } 173: 174: char *__s; 175: 176: int nocore = 0; 177: process(t, s, c, page, l) 178: char *s; 179: { 180: register struct item *p; 181: struct item *addtree(); 182: char *calloc(), *stash(); 183: 184: if(page>Maxpage) 185: Maxpage = page; 186: if(debug) 187: fprintf(stderr, "process(%o, %s, %o, %d, %d)\n", 188: t, s, c, page,l); 189: if(nocore) 190: return; 191: if(want[t] == 0) return; 192: p = (struct item *) calloc(1, sizeof (struct item)); 193: if(p == NULL) 194: { 195: fprintf(stderr, "Cref: Ran out of core, page %d, line %d\n",p, l); 196: nocore++; 197: return; 198: } 199: tcount[t]++; 200: tany |= 1; 201: p->i_code = t | (c<<8); 202: p->i_name = stash(s); 203: p->i_page = page; 204: p->i_line = l; 205: 206: ihead = addtree(ihead, p); 207: } 208: 209: comp(p, q) 210: register struct item *p, *q; 211: { 212: register x; 213: 214: if(p->i_name != q->i_name) 215: x = strcmp(p->i_name, q->i_name); 216: else 217: x = 0; 218: if(x == 0) { 219: x = p->i_page - q->i_page; 220: if(x == 0) 221: x = p->i_line - q->i_line; 222: if(x == 0) 223: x= p->i_code - q->i_code; 224: } 225: return(x); 226: } 227: 228: struct item * 229: addtree(b, p) 230: struct item *b, *p; 231: { 232: register c; 233: 234: if(b == NULL) 235: return(b = p); 236: c = comp(b, p); 237: if(c < 0) 238: b->i_left = addtree(b->i_left, p); 239: else if (c>0) 240: b->i_right= addtree(b->i_right, p); 241: return(b); 242: } 243: 244: char *stash(s) 245: register char *s; 246: { 247: shead = store(shead, s); 248: return(__s); 249: } 250: store(b, s) 251: register struct string *b; 252: register char *s; 253: { 254: register x; 255: 256: if(b == 0) { 257: b = (struct string *) calloc(1, sizeof(struct string)); 258: __s = b->s_data = strsave(s); 259: } else if((x=strcmp(b->s_data, s)) == 0) 260: __s = b->s_data; 261: else if(x<0) 262: b->s_left = store(b->s_left, s); 263: else 264: b->s_right= store(b->s_right,s); 265: return(b); 266: } 267: strsave(s) 268: register char *s; 269: { 270: register char *t; 271: char *calloc(); 272: 273: t = calloc(strlen(s)+1, 1); 274: strcpy(t, s); 275: return(t); 276: } 277: int crcol = 0; 278: crprint(p, i) 279: register struct item *p; 280: { 281: if(p == NULL) return; 282: 283: crprint(p->i_right, i); 284: if ((p->i_code & 07) == i) { 285: char *code; 286: if (symnam != p->i_name) 287: crcol = 0, printf("\n%-6.6s\t", symnam = p->i_name); 288: if(crcol == NCOLS) { 289: crcol = 1; 290: printf("\n\t"); 291: } 292: else crcol++; 293: 294: 295: if(i == 4 || i == 2) 296: code = 0; 297: else 298: code = Code[3 & (p->i_code >>8)]; 299: 300: prx(p->i_page, p->i_line, code, crcol); 301: } 302: crprint(p->i_left, i); 303: } 304: prx(page, line, code, col) 305: char *code; 306: { 307: char buf[15]; 308: 309: if(Maxpage>1) 310: sprintf(buf, "%d-%d", page, line); 311: else 312: sprintf(buf, "%d", line); 313: if(code) 314: strcat(buf, code); 315: if(col == NCOLS) 316: printf("%s", buf); 317: else { 318: printf("%8s", buf); 319: if(strlen(buf) > 7) printf(" "); 320: } 321: } 322: join(s,t) 323: register char *s, *t; 324: { 325: for(;*s;s++) 326: if(any(*s, t)) 327: return(1); 328: return(0); 329: } 330: 331: any(c, s) 332: register char c, *s; 333: { 334: for(;*s;s++) 335: if(*s == c) 336: return(1); 337: return(0); 338: } 339: minuspr(x, y) 340: { 341: char buf[30]; 342: sprintf(buf,"%d-%d", x, y); 343: printf(" %4s", buf); 344: } 345: dump(p) 346: struct item *p; 347: { 348: if(p==NULL)return; 349: dump(p->i_left); 350: fprintf(stderr, "%s: %o %d %d\n", p->i_name, p->i_code, p->i_page, p->i_line); 351: dump(p->i_right); 352: }