|
|
1.1 ! root 1: /* Copyright (c) 1982 Regents of the University of California */ ! 2: ! 3: static char sccsid[] = "@(#)savenl.c 1.5 8/26/82"; ! 4: ! 5: /* ! 6: * savenl - routines for saving namelist and line number information ! 7: * ! 8: * This module contains the routines that make pi dump a namelist ! 9: * at the end of the object file. We do this by first creating ! 10: * four temporary files in "startnlfile". One temp file contains ! 11: * the string table, one the symbol table, one the file name ! 12: * information and one the line number information. ! 13: * ! 14: * Prior to generation of the code for a statement the "lineno" ! 15: * routine is called to dump the line number and current object ! 16: * address. At the end of each block "savenl" is called to dump ! 17: * the strings and symbol structures. ! 18: * ! 19: * At the end of execution "copynlfile" is called and it copies ! 20: * the temp files onto the end of the obj file. ! 21: * ! 22: * In case of error, "removenlfile" is called to destroy the temp files. ! 23: * ! 24: * The only other changes to pi are in calling these routines from ! 25: * ! 26: * "main" (main.c) ! 27: * "yymain" (yymain.c) ! 28: * "funcend" (fend.c) ! 29: * "yyget" (yyget.c) ! 30: * "putline" (stat.c) ! 31: */ ! 32: ! 33: #include "whoami.h" ! 34: #ifdef OBJ ! 35: /* ! 36: * and the rest of the file ! 37: */ ! 38: #include "0.h" ! 39: #include "objfmt.h" ! 40: ! 41: #undef NIL ! 42: ! 43: /* ! 44: * pdx header files ! 45: */ ! 46: ! 47: #include "../pdx/defs.h" ! 48: #include "../pdx/object.h" ! 49: #include "../pdx/object/objsym.rep" ! 50: #include "../pdx/mappings.h" ! 51: #include "../pdx/mappings/filetab.h" ! 52: ! 53: LOCAL char *symname = "/tmp/obj.symXXXX"; ! 54: LOCAL char *strname = "/tmp/obj.strXXXX"; ! 55: LOCAL char *filesname = "/tmp/obj.filesXXXX"; ! 56: LOCAL char *linesname = "/tmp/obj.linesXXXX"; ! 57: ! 58: LOCAL FILE *symfp; ! 59: LOCAL FILE *strfp; ! 60: LOCAL FILE *filesfp; ! 61: LOCAL FILE *linesfp; ! 62: ! 63: LOCAL long nlsize; ! 64: ! 65: /* ! 66: * create temporary files for the namelist info ! 67: */ ! 68: ! 69: startnlfile() ! 70: { ! 71: nlsize = 0; ! 72: mktemp(symname); ! 73: mktemp(strname); ! 74: mktemp(filesname); ! 75: mktemp(linesname); ! 76: symfp = fopen(symname, "w"); ! 77: strfp = fopen(strname, "w"); ! 78: filesfp = fopen(filesname, "w"); ! 79: linesfp = fopen(linesname, "w"); ! 80: if (symfp==NULL || strfp==NULL || filesfp==NULL || linesfp==NULL) { ! 81: fprintf(stderr, "can't create /tmp/obj"); ! 82: pexit(NOSTART); ! 83: } ! 84: newfile(filename, 1); ! 85: } ! 86: ! 87: /* ! 88: * now copy the temp files back to obj; strings, symbols, file names, and lines ! 89: * ! 90: * There's some efficiency garbage here that uses straight system ! 91: * calls rather than standard I/O library calls. ! 92: */ ! 93: ! 94: copynlfile() ! 95: { ! 96: register int n; ! 97: int symfd, strfd, filesfd, linesfd; ! 98: char buff[BUFSIZ]; ! 99: ! 100: fclose(symfp); ! 101: fclose(strfp); ! 102: fclose(filesfp); ! 103: fclose(linesfp); ! 104: if (!opt('g')) { ! 105: removenlfile(); ! 106: return; ! 107: } ! 108: symfd = open(symname, 0); ! 109: strfd = open(strname, 0); ! 110: filesfd = open(filesname, 0); ! 111: linesfd = open(linesname, 0); ! 112: if (symfd < 0 || strfd < 0 || filesfd < 0 || linesfd < 0) { ! 113: fprintf(stderr, "sync error on /tmp/obj"); ! 114: pexit(ERRS); ! 115: } ! 116: lseek(ofil, 0L, 2); ! 117: write(ofil, &nlhdr, sizeof(nlhdr)); ! 118: n = read(strfd, buff, BUFSIZ - sizeof(nlhdr)); ! 119: write(ofil, buff, n); ! 120: cat(strfd); ! 121: cat(symfd); ! 122: cat(filesfd); ! 123: cat(linesfd); ! 124: removenlfile(); ! 125: } ! 126: ! 127: cat(fd) ! 128: int fd; ! 129: { ! 130: register int n; ! 131: char buff[BUFSIZ]; ! 132: ! 133: while ((n = read(fd, buff, BUFSIZ)) > 0) { ! 134: write(ofil, buff, n); ! 135: } ! 136: close(fd); ! 137: } ! 138: ! 139: removenlfile() ! 140: { ! 141: unlink(symname); ! 142: unlink(strname); ! 143: unlink(filesname); ! 144: unlink(linesname); ! 145: } ! 146: ! 147: nlhdrsize() ! 148: { ! 149: int r; ! 150: ! 151: if (!opt('g')) { ! 152: r = 0; ! 153: } else { ! 154: r = nlsize + sizeof(nlhdr); ! 155: } ! 156: return r; ! 157: } ! 158: ! 159: #define isblock(s) (s->class == FUNC || s->class == PROC) ! 160: #define isbuiltin(s) ((s->nl_block&037) == 0 && isblock(s)) ! 161: #define symno(p) (p==NULL ? 0 : nloff(p)) ! 162: ! 163: struct nls { ! 164: struct nl *nls_low; ! 165: struct nl *nls_high; ! 166: }; ! 167: ! 168: struct nl nl[], *nlp, ntab[], *nlact; ! 169: ! 170: savenl(to, rout) ! 171: struct nl *to; ! 172: { ! 173: register struct nl *p; ! 174: register OBJSYM *s; ! 175: OBJSYM tmpsym; ! 176: struct nls *nlsp; ! 177: int v; ! 178: ! 179: if (to != NIL) { ! 180: putblock(rout); ! 181: } else { ! 182: putblock("main program"); ! 183: } ! 184: nlsp = nlact; ! 185: s = &tmpsym; ! 186: for (p = nlp; p != to;) { ! 187: if (p == nlsp->nls_low) { ! 188: if (nlsp == &ntab[0]) ! 189: break; ! 190: nlsp--; ! 191: p = nlsp->nls_high; ! 192: } ! 193: p--; ! 194: if (isbuiltin(p) || symno(p) == 0) { ! 195: continue; ! 196: } ! 197: nlhdr.nsyms++; ! 198: nlsize += sizeof(OBJSYM) + sizeof(int); ! 199: putw(symno(p), symfp); ! 200: if (p->symbol != NULL) { ! 201: s->strindex = nlhdr.stringsize; ! 202: putstring(p->symbol); ! 203: } else { ! 204: s->strindex = 0; ! 205: } ! 206: s->oclass = p->class; ! 207: s->oblkno = (p->nl_block&037); ! 208: s->typno = symno(p->type); ! 209: s->chno = symno(p->chain); ! 210: s->osymvalue.orangev.lower = p->range[0]; ! 211: s->osymvalue.orangev.upper = p->range[1]; ! 212: if (isblock(p)) { ! 213: s->osymvalue.ofuncv.codeloc = p->value[NL_ENTLOC]; ! 214: } else if (p->class == RECORD || p->class == VARNT) { ! 215: s->osymvalue.ovarnt.vtorecno = symno(p->ptr[2]); ! 216: s->osymvalue.ovarnt.vtagno = symno(p->ptr[3]); ! 217: } ! 218: fwrite(s, sizeof(*s), 1, symfp); ! 219: } ! 220: } ! 221: ! 222: /* ! 223: * Dump a line number and the current object location counter. ! 224: * ! 225: * To save space the difference from the previous line number and offset ! 226: * (one byte each) is dumped. ! 227: */ ! 228: ! 229: LOCAL int oline = 0; ! 230: LOCAL int olc = HEADER_BYTES; ! 231: ! 232: lineno(line) ! 233: int line; ! 234: { ! 235: OBJLINE info; ! 236: ! 237: if (line != oline) { ! 238: nlhdr.nlines++; ! 239: nlsize += sizeof(OBJLINE); ! 240: info.separate.lineincr = line - oline; ! 241: info.separate.addrincr = lc - olc; ! 242: putw(info.together, linesfp); ! 243: oline = line; ! 244: olc = lc; ! 245: } ! 246: } ! 247: ! 248: /* ! 249: * put out a file name entry, including: ! 250: * ! 251: * the current line number for the new file ! 252: * the current location counter ! 253: * the string table address of the file name ! 254: * an index into the current line number information ! 255: */ ! 256: ! 257: newfile(s, line) ! 258: char *s; ! 259: int line; ! 260: { ! 261: FILETAB ft; ! 262: ! 263: nlhdr.nfiles++; ! 264: nlsize += sizeof(FILETAB); ! 265: ft.line = line; ! 266: oline = line; ! 267: if (lc == 0) { ! 268: ft.addr = 0; ! 269: } else { ! 270: ft.addr = lc - HEADER_BYTES; ! 271: } ! 272: ft.filename = (char *) nlhdr.stringsize; ! 273: putstring(s); ! 274: ft.lineindex = nlhdr.nlines; ! 275: fwrite(&ft, sizeof(ft), 1, filesfp); ! 276: } ! 277: ! 278: /* ! 279: * put out a dummy symbol at the beginning of a block ! 280: */ ! 281: ! 282: LOCAL putblock(s) ! 283: char *s; ! 284: { ! 285: register int i; ! 286: static OBJSYM zerosym; ! 287: ! 288: nlhdr.nsyms++; ! 289: nlsize += sizeof(OBJSYM) + sizeof(int); ! 290: putw(0, symfp); ! 291: zerosym.strindex = nlhdr.stringsize; ! 292: putstring(s); ! 293: fwrite(&zerosym, sizeof(zerosym), 1, symfp); ! 294: } ! 295: ! 296: /* ! 297: * put out a string to the string table file ! 298: */ ! 299: ! 300: LOCAL putstring(s) ! 301: char *s; ! 302: { ! 303: register char *p; ! 304: ! 305: for (p = s; *p != '\0'; p++) { ! 306: putc(*p, strfp); ! 307: } ! 308: nlhdr.stringsize += (p - s + 1); ! 309: nlsize += (p - s + 1); ! 310: putc('\0', strfp); ! 311: } ! 312: #endif OBJ
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.