Annotation of 42BSD/ucb/pascal/pdx/source/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.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.