Annotation of 42BSD/ucb/dbx/source.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1982 Regents of the University of California */
                      2: 
                      3: static char sccsid[] = "@(#)source.c 1.9 8/5/83";
                      4: 
                      5: /*
                      6:  * Source file management.
                      7:  */
                      8: 
                      9: #include "defs.h"
                     10: #include "source.h"
                     11: #include "object.h"
                     12: #include "mappings.h"
                     13: #include "machine.h"
                     14: 
                     15: #ifndef public
                     16: typedef int Lineno;
                     17: 
                     18: String cursource;
                     19: Lineno curline;
                     20: Lineno cursrcline;
                     21: 
                     22: #define LASTLINE 0             /* recognized by printlines */
                     23: 
                     24: #include "lists.h"
                     25: 
                     26: List sourcepath;
                     27: #endif
                     28: 
                     29: private Lineno lastlinenum;
                     30: private String prevsource = nil;
                     31: 
                     32: /*
                     33:  * Data structure for indexing source seek addresses by line number.
                     34:  *
                     35:  * The constraints are:
                     36:  *
                     37:  *  we want an array so indexing is fast and easy
                     38:  *  we don't want to waste space for small files
                     39:  *  we don't want an upper bound on # of lines in a file
                     40:  *  we don't know how many lines there are
                     41:  *
                     42:  * The solution is a "dirty" hash table.  We have NSLOTS pointers to
                     43:  * arrays of NLINESPERSLOT addresses.  To find the source address of
                     44:  * a particular line we find the slot, allocate space if necessary,
                     45:  * and then find its location within the pointed to array.
                     46:  */
                     47: 
                     48: typedef long Seekaddr;
                     49: 
                     50: #define NSLOTS 20
                     51: #define NLINESPERSLOT 500
                     52: 
                     53: #define slotno(line)    ((line) div NLINESPERSLOT)
                     54: #define index(line)    ((line) mod NLINESPERSLOT)
                     55: #define slot_alloc()    newarr(Seekaddr, NLINESPERSLOT)
                     56: #define srcaddr(line)  seektab[slotno(line)][index(line)]
                     57: 
                     58: private File srcfp;
                     59: private Seekaddr *seektab[NSLOTS];
                     60: 
                     61: /*
                     62:  * Print out the given lines from the source.
                     63:  */
                     64: 
                     65: public printlines(l1, l2)
                     66: Lineno l1, l2;
                     67: {
                     68:     register int c;
                     69:     register Lineno i, lb, ub;
                     70:     register File f;
                     71: 
                     72:     if (cursource == nil) {
                     73:        beginerrmsg();
                     74:        fprintf(stderr, "no source file\n");
                     75:     } else {
                     76:        if (cursource != prevsource) {
                     77:            skimsource();
                     78:        }
                     79:        if (lastlinenum == 0) {
                     80:            beginerrmsg();
                     81:            fprintf(stderr, "couldn't read \"%s\"\n", cursource);
                     82:        } else {
                     83:            lb = (l1 == 0) ? lastlinenum : l1;
                     84:            ub = (l2 == 0) ? lastlinenum : l2;
                     85:            if (lb < 1) {
                     86:                beginerrmsg();
                     87:                fprintf(stderr, "line number must be positive\n");
                     88:            } else if (lb > lastlinenum) {
                     89:                beginerrmsg();
                     90:                if (lastlinenum == 1) {
                     91:                    fprintf(stderr, "\"%s\" has only 1 line\n", cursource);
                     92:                } else {
                     93:                    fprintf(stderr, "\"%s\" has only %d lines\n",
                     94:                        cursource, lastlinenum);
                     95:                }
                     96:            } else if (ub < lb) {
                     97:                beginerrmsg();
                     98:                fprintf(stderr, "second number must be greater than first\n");
                     99:            } else {
                    100:                if (ub > lastlinenum) {
                    101:                    ub = lastlinenum;
                    102:                }
                    103:                f = srcfp;
                    104:                fseek(f, srcaddr(lb), 0);
                    105:                for (i = lb; i <= ub; i++) {
                    106:                    printf("%5d   ", i);
                    107:                    while ((c = getc(f)) != '\n') {
                    108:                        putchar(c);
                    109:                    }
                    110:                    putchar('\n');
                    111:                }
                    112:                cursrcline = ub + 1;
                    113:            }
                    114:        }
                    115:     }
                    116: }
                    117: 
                    118: /*
                    119:  * Search the sourcepath for a file.
                    120:  */
                    121: 
                    122: static char fileNameBuf[1024];
                    123: 
                    124: public String findsource(filename)
                    125: String filename;
                    126: {
                    127:     register File f;
                    128:     register String src, dir;
                    129: 
                    130:     if (filename[0] == '/') {
                    131:        src = filename;
                    132:     } else {
                    133:        src = nil;
                    134:        foreach (String, dir, sourcepath)
                    135:            sprintf(fileNameBuf, "%s/%s", dir, filename);
                    136:            f = fopen(fileNameBuf, "r");
                    137:            if (f != nil) {
                    138:                fclose(f);
                    139:                src = fileNameBuf;
                    140:                break;
                    141:            }
                    142:        endfor
                    143:     }
                    144:     return src;
                    145: }
                    146: 
                    147: /*
                    148:  * Open a source file looking in the appropriate places.
                    149:  */
                    150: 
                    151: public File opensource(filename)
                    152: String filename;
                    153: {
                    154:     String s;
                    155:     File f;
                    156: 
                    157:     s = findsource(filename);
                    158:     if (s == nil) {
                    159:        f = nil;
                    160:     } else {
                    161:        f = fopen(s, "r");
                    162:     }
                    163:     return f;
                    164: }
                    165: 
                    166: /*
                    167:  * Set the current source file.
                    168:  */
                    169: 
                    170: public setsource(filename)
                    171: String filename;
                    172: {
                    173:     if (filename != nil and filename != cursource) {
                    174:        prevsource = cursource;
                    175:        cursource = filename;
                    176:        cursrcline = 1;
                    177:     }
                    178: }
                    179: 
                    180: /*
                    181:  * Read the source file getting seek pointers for each line.
                    182:  */
                    183: 
                    184: private skimsource()
                    185: {
                    186:     register int c;
                    187:     register Seekaddr count;
                    188:     register File f;
                    189:     register Lineno linenum;
                    190:     register Seekaddr lastaddr;
                    191:     register int slot;
                    192: 
                    193:     f = opensource(cursource);
                    194:     if (f == nil) {
                    195:        lastlinenum = 0;
                    196:     } else {
                    197:        if (prevsource != nil) {
                    198:            free_seektab();
                    199:            if (srcfp != nil) {
                    200:                fclose(srcfp);
                    201:            }
                    202:        }
                    203:        prevsource = cursource;
                    204:        linenum = 0;
                    205:        count = 0;
                    206:        lastaddr = 0;
                    207:        while ((c = getc(f)) != EOF) {
                    208:            ++count;
                    209:            if (c == '\n') {
                    210:                slot = slotno(++linenum);
                    211:                if (slot >= NSLOTS) {
                    212:                    panic("skimsource: too many lines");
                    213:                }
                    214:                if (seektab[slot] == nil) {
                    215:                    seektab[slot] = slot_alloc();
                    216:                }
                    217:                seektab[slot][index(linenum)] = lastaddr;
                    218:                lastaddr = count;
                    219:            }
                    220:        }
                    221:        lastlinenum = linenum;
                    222:        srcfp = f;
                    223:     }
                    224: }
                    225: 
                    226: /*
                    227:  * Erase information and release space in the current seektab.
                    228:  * This is in preparation for reading in seek pointers for a
                    229:  * new file.  It is possible that seek pointers for all files
                    230:  * should be kept around, but the current concern is space.
                    231:  */
                    232: 
                    233: private free_seektab()
                    234: {
                    235:     register int slot;
                    236: 
                    237:     for (slot = 0; slot < NSLOTS; slot++) {
                    238:        if (seektab[slot] != nil) {
                    239:            dispose(seektab[slot]);
                    240:        }
                    241:     }
                    242: }
                    243: 
                    244: /*
                    245:  * Figure out current source position.
                    246:  */
                    247: 
                    248: public getsrcpos()
                    249: {
                    250:     String filename;
                    251: 
                    252:     curline = srcline(pc);
                    253:     filename = srcfilename(pc);
                    254:     setsource(filename);
                    255:     if (curline != 0) {
                    256:        cursrcline = curline;
                    257:     }
                    258: }
                    259: 
                    260: /*
                    261:  * Print out the current source position.
                    262:  */
                    263: 
                    264: public printsrcpos()
                    265: {
                    266:     printf("at line %d", curline);
                    267:     if (nlhdr.nfiles > 1) {
                    268:        printf(" in file \"%s\"", cursource);
                    269:     }
                    270: }
                    271: 
                    272: #define DEF_EDITOR  "vi"
                    273: 
                    274: /*
                    275:  * Invoke an editor on the given file.  Which editor to use might change
                    276:  * installation to installation.  For now, we use "vi".  In any event,
                    277:  * the environment variable "EDITOR" overrides any default.
                    278:  */
                    279: 
                    280: public edit(filename)
                    281: String filename;
                    282: {
                    283:     extern String getenv();
                    284:     String ed, src, s;
                    285:     Symbol f;
                    286:     Address addr;
                    287:     char lineno[10];
                    288: 
                    289:     ed = getenv("EDITOR");
                    290:     if (ed == nil) {
                    291:        ed = DEF_EDITOR;
                    292:     }
                    293:     src = findsource((filename != nil) ? filename : cursource);
                    294:     if (src == nil) {
                    295:        f = which(identname(filename, true));
                    296:        if (not isblock(f)) {
                    297:            error("can't read \"%s\"", filename);
                    298:        }
                    299:        addr = firstline(f);
                    300:        if (addr == NOADDR) {
                    301:            error("no source for \"%s\"", filename);
                    302:        }
                    303:        src = srcfilename(addr);
                    304:        s = findsource(src);
                    305:        if (s != nil) {
                    306:            src = s;
                    307:        }
                    308:        sprintf(lineno, "+%d", srcline(addr));
                    309:     } else {
                    310:        sprintf(lineno, "+1");
                    311:     }
                    312:     call(ed, stdin, stdout, lineno, src, nil);
                    313: }

unix.superglobalmegacorp.com

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