Annotation of 43BSD/ucb/pascal/pdx/source/source.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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