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

Defined functions

cat defined in line 136; used 4 times
copynlfile defined in line 102; used 1 times
lineno defined in line 241; used 1 times
newfile defined in line 266; used 3 times
nlhdrsize defined in line 156; used 1 times
putblock defined in line 291; used 2 times
putstring defined in line 308; used 3 times
removenlfile defined in line 148; used 3 times
startnlfile defined in line 77; used 1 times

Defined variables

filesname defined in line 61; used 4 times
linesname defined in line 62; used 4 times
nl defined in line 177; never used
nlact defined in line 177; used 1 times
nlp defined in line 177; used 1 times
nlsize defined in line 69; used 7 times
ntab defined in line 177; used 1 times
olc defined in line 239; used 2 times
oline defined in line 238; used 4 times
sccsid defined in line 8; never used
strname defined in line 60; used 4 times
symname defined in line 59; used 4 times

Defined struct's

nls defined in line 172; used 6 times

Defined macros

isblock defined in line 168; used 2 times
isbuiltin defined in line 169; used 1 times
symno defined in line 170; used 6 times
Last modified: 1985-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3372
Valid CSS Valid XHTML 1.0 Strict