Annotation of 42BSD/ucb/dbx/source.c, revision 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.