Annotation of 42BSD/ucb/pascal/src/savenl.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.