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: }

Defined functions

chkline defined in line 60; used 2 times
free_seektab defined in line 148; used 1 times
printlines defined in line 75; never used
skimsource defined in line 102; never used

Defined variables

sccsid defined in line 8; never used
seektab defined in line 52; used 7 times

Defined typedef's

SEEKADDR defined in line 42; used 4 times

Defined macros

NLINESPERSLOT defined in line 45; used 5 times
NSLOTS defined in line 44; used 3 times
index defined in line 48; used 1 times
slot_alloc defined in line 49; used 1 times
slotno defined in line 47; used 1 times
srcaddr defined in line 50; used 1 times
  • in line 88
Last modified: 1985-06-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1011
Valid CSS Valid XHTML 1.0 Strict