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
Defined variables
sccsid
defined in line
8;
never used
Defined typedef's
Defined macros
index
defined in line
48; used 1 times