Annotation of 42BSD/ucb/pascal/pdx/source/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.4 3/24/83";
        !             4: 
        !             5: /*
        !             6:  * Source file management.
        !             7:  */
        !             8: 
        !             9: #include "defs.h"
        !            10: #include "source.h"
        !            11: 
        !            12: /*
        !            13:  * Seektab is the data structure used for indexing source
        !            14:  * seek addresses by line number.
        !            15:  *
        !            16:  * The constraints are:
        !            17:  *
        !            18:  *  we want an array so indexing is fast and easy
        !            19:  *  we don't want to waste space for small files
        !            20:  *  we don't want an upper bound on # of lines in a file
        !            21:  *  we don't know how many lines there are
        !            22:  *
        !            23:  * The solution is a sparse array. We have NSLOTS pointers to
        !            24:  * arrays of NLINESPERSLOT addresses.  To find the source address of
        !            25:  * a particular line we find the slot, allocate space if necessary,
        !            26:  * and then find its location within the pointed to array.
        !            27:  *
        !            28:  * As a result, there is a limit of NSLOTS*NLINESPERSLOT lines per file
        !            29:  * but this is plenty high and still fairly inexpensive.
        !            30:  *
        !            31:  * This implementation maintains only one source file at any given
        !            32:  * so as to avoid consuming too much memory.  In an environment where
        !            33:  * memory is less constrained and one expects to be changing between
        !            34:  * files often enough, it would be reasonable to have multiple seek tables.
        !            35:  */
        !            36: 
        !            37: typedef int SEEKADDR;
        !            38: 
        !            39: #define NSLOTS 40
        !            40: #define NLINESPERSLOT 500
        !            41: 
        !            42: #define slotno(line)   ((line)/NLINESPERSLOT)
        !            43: #define index(line)    ((line)%NLINESPERSLOT)
        !            44: #define slot_alloc()   alloc(NLINESPERSLOT, SEEKADDR)
        !            45: #define srcaddr(line)  seektab[(line)/NLINESPERSLOT][(line)%NLINESPERSLOT]
        !            46: 
        !            47: LOCAL SEEKADDR *seektab[NSLOTS];
        !            48: 
        !            49: LOCAL FILE *srcfp;
        !            50: 
        !            51: /*
        !            52:  * check to make sure a source line number is valid
        !            53:  */
        !            54: 
        !            55: chkline(linenum)
        !            56: register LINENO linenum;
        !            57: {
        !            58:     if (linenum < 1) {
        !            59:        error("line number must be positive");
        !            60:     }
        !            61:     if (linenum > lastlinenum) {
        !            62:        error("not that many lines");
        !            63:     }
        !            64: }
        !            65: 
        !            66: /*
        !            67:  * print out the given lines from the source
        !            68:  */
        !            69: 
        !            70: printlines(l1, l2)
        !            71: LINENO l1, l2;
        !            72: {
        !            73:     register int c;
        !            74:     register LINENO i;
        !            75:     register FILE *fp;
        !            76: 
        !            77:     chkline(l1);
        !            78:     chkline(l2);
        !            79:     if (l2 < l1) {
        !            80:        error("second line number less than first");
        !            81:     }
        !            82:     fp = srcfp;
        !            83:     fseek(fp, (long) srcaddr(l1), 0);
        !            84:     for (i = l1; i <= l2; i++) {
        !            85:        printf("%5d   ", i);
        !            86:        while ((c = getc(fp)) != '\n') {
        !            87:            putchar(c);
        !            88:        }
        !            89:        putchar('\n');
        !            90:     }
        !            91: }
        !            92: 
        !            93: /*
        !            94:  * read the source file getting seek pointers for each line
        !            95:  */
        !            96: 
        !            97: skimsource(file)
        !            98: char *file;
        !            99: {
        !           100:     register int c;
        !           101:     register SEEKADDR count;
        !           102:     register FILE *fp;
        !           103:     register LINENO linenum;
        !           104:     register SEEKADDR lastaddr;
        !           105:     register int slot;
        !           106: 
        !           107:     if (file == NIL || file == cursource) {
        !           108:        return;
        !           109:     }
        !           110:     if ((fp = fopen(file, "r")) == NULL) {
        !           111:        panic("can't open \"%s\"", file);
        !           112:     }
        !           113:     if (cursource != NIL) {
        !           114:        free_seektab();
        !           115:     }
        !           116:     cursource = file;
        !           117:     linenum = 0, count = 0, lastaddr = 0;
        !           118:     while ((c = getc(fp)) != EOF) {
        !           119:        count++;
        !           120:        if (c == '\n') {
        !           121:            slot = slotno(++linenum);
        !           122:            if (slot >= NSLOTS) {
        !           123:                panic("skimsource: too many lines");
        !           124:            }
        !           125:            if (seektab[slot] == NIL) {
        !           126:                seektab[slot] = slot_alloc();
        !           127:            }
        !           128:            seektab[slot][index(linenum)] = lastaddr;
        !           129:            lastaddr = count;
        !           130:        }
        !           131:     }
        !           132:     lastlinenum = linenum;
        !           133:     srcfp = fp;
        !           134: }
        !           135: 
        !           136: /*
        !           137:  * Erase information and release space in the current seektab.
        !           138:  * This is in preparation for reading in seek pointers for a
        !           139:  * new file.  It is possible that seek pointers for all files
        !           140:  * should be kept around, but the current concern is space.
        !           141:  */
        !           142: 
        !           143: LOCAL free_seektab()
        !           144: {
        !           145:     register int slot;
        !           146: 
        !           147:     for (slot = 0; slot < NSLOTS; slot++) {
        !           148:        if (seektab[slot] != NIL) {
        !           149:            free(seektab[slot]);
        !           150:            seektab[slot] = NIL;
        !           151:        }
        !           152:     }
        !           153: }

unix.superglobalmegacorp.com

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