Annotation of 43BSDTahoe/ucb/pascal/pdx/source/source.c, revision 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.