mods for new formal routine syntax
[unix-history] / usr / src / usr.bin / pascal / pxref / pxref.p
CommitLineData
176e9707
BJ
1{$t-,p-,b2,w+}
2program xref(input, output);
3label
4 99, 100;
5const
6 { sccsid = '@(#)pxref.p 1.1 (Berkeley) %G%'; }
7 alfasize = 18;
8 linesize = 10;
9 namesize = 64;
10 linelength = 133;
11 maxlineno = 30000;
12 charclassize = 127;
13 p = 1000;
14 nk = 36;
15 blanks = ' ';
16type
17 alfa =
18 array[1..alfasize] of
19 char;
20 index = 0..p;
21 linptr = 0..linelength;
22 linebuf = array[1..linelength] of char;
23 ref = ^item;
24 filename = array [1..namesize] of char;
25 charclasses = (digit, letter, separator, illegal);
26 charclasstype = array[0..charclassize] of charclasses;
27 word =
28 record
29 key: alfa;
30 first, last: ref;
31 fol: index
32 end;
33 item = packed
34 record
35 lno: 0..maxlineno;
36 next: ref
37 end;
38var
39 i, top: index;
40 formfeed :char;
41 scr: alfa;
42 list: boolean;
43 k, k1: integer;
44 n: integer;
45 c1, c2: integer;
46 inputfile : filename;
47 lineptr :linptr;
48 line :linebuf;
49 charclass :charclasstype;
50 id:
51 record
52 case boolean of
53 false:(
54 a: alfa
55 );
56 true:(
57 ord: integer
58 )
59 end;
60 a: array [1..alfasize] of char;
61 t: array [index] of word;
62 key: array [1..nk] of alfa;
63 empty: alfa;
64
65 function nokey(x: alfa): Boolean;
66 var
67 i, j, k: integer;
68 begin
69 i := 1;
70 j := nk;
71 repeat
72 k := (i + j) div 2;
73 if key[k] <= x then
74 i := k + 1;
75 if key[k] >= x then
76 j := k - 1
77 until i > j;
78 nokey := key[k] <> x
79 end { nokey };
80
81 procedure search;
82 var
83 h, d: index;
84 x: ref;
85 f: Boolean;
86 begin
87 h := id.ord div 4096 mod p;
88 f := false;
89 d := 1;
90 c2 := c2 + 1;
91 new(x);
92 x^.lno := n;
93 x^.next := nil;
94 repeat
95 if t[h].key = id.a then begin
96 f := true;
97 t[h].last^.next := x;
98 t[h].last := x
99 end else if t[h].key = empty then begin
100 f := true;
101 c1 := c1 + 1;
102 t[h].key := id.a;
103 t[h].first := x;
104 t[h].last := x;
105 t[h].fol := top;
106 top := h
107 end else begin
108 h := (h + d) mod p;
109 d := d + 2;
110 if d = p then begin
111 writeln;
112 writeln(' **** table full');
113 goto 99
114 end
115 end
116 until f
117 end { search };
118
119 procedure printword(w: word);
120 var
121 l: integer;
122 x: ref;
123 begin
124 write(' ', w.key);
125 x := w.first;
126 l := 0;
127 repeat
128 if l = linesize then begin
129 l := 0;
130 writeln;
131 write(' ', empty)
132 end;
133 l := l + 1;
134 write(x^.lno: 6);
135 x := x^.next
136 until x = nil;
137 writeln
138 end { printword };
139
140 procedure printtable;
141 var
142 i, j, m: index;
143 begin
144 i := top;
145 while i <> p do begin
146 m := i;
147 j := t[i].fol;
148 while j <> p do begin
149 if t[j].key < t[m].key then
150 m := j;
151 j := t[j].fol
152 end;
153 printword(t[m]);
154 if m <> i then begin
155 t[m].key := t[i].key;
156 t[m].first := t[i].first;
157 t[m].last := t[i].last
158 end;
159 i := t[i].fol
160 end
161 end { printtable };
162
163 procedure readinput(var inpfile :filename);
164 var
165 inp :file of char;
166
167 procedure lwriteln;
168 var
169 i :linptr;
170 begin
171 if list then begin
172 { actually should use ...
173 for i:=1 to lineptr do
174 write(line[i]);
175 }
176 line[lineptr+1]:=chr(0);
177 writeln(line);
178 end;
179 get(inp);
180 line:=blanks;
181 lineptr:=0
182 end { lwriteln };
183
184 procedure newline;
185 begin
186 n:=n+1;
187 if n = maxlineno then begin
188 writeln(' text too long');
189 goto 99
190 end;
191 if inp^ = formfeed then begin
192 if list then
193 page(output);
194 get(inp)
195 end;
196 if list then
197 if not eoln(inp) then
198 write(n:6,' ')
199 end { newline };
200
201 begin
202 reset(inp,inpfile);
203 while not eof(inp) do begin
204 newline;
205 if inp^ = '#' then begin
206 while inp^ <> '"' do begin
207 lineptr:=lineptr+1;
208 read(inp,line[lineptr])
209 end;
210 lineptr:=lineptr+1;
211 read(inp,line[lineptr]);
212 k:=0;
213 inputfile:=blanks;
214 repeat
215 k:=k+1;
216 if k <= namesize then
217 inputfile[k]:=inp^;
218 lineptr:=lineptr+1;
219 read(inp,line[lineptr])
220 until inp^ = '"';
221 while not eoln(inp) do begin
222 lineptr:=lineptr+1;
223 read(inp,line[lineptr])
224 end;
225 id.a := '#include';
226 search;
227 lwriteln;
228 readinput(inputfile);
229 end else begin
230 while not eoln(inp) do begin
231 if (inp^ = ' ') or (inp^ = tab) then begin
232 lineptr:=lineptr+1;
233 read(inp,line[lineptr])
234 end else if charclass[ord(inp^)] = letter then begin
235 k := 0;
236 a:=blanks;
237 repeat
238 k := k + 1;
239 if k <= alfasize then
240 a[k] := inp^;
241 lineptr:=lineptr+1;
242 read(inp,line[lineptr])
243 until (charclass[ord(inp^)] <> letter) and
244 (charclass[ord(inp^)] <> digit);
245 pack(a, 1, id.a);
246 if nokey(id.a) then
247 search
248 end else if charclass[ord(inp^)] = digit then
249 repeat
250 lineptr:=lineptr+1;
251 read(inp,line[lineptr])
252 until charclass[ord(inp^)] <> digit
253 else if inp^='''' then begin
254 repeat
255 lineptr:=lineptr+1;
256 read(inp,line[lineptr])
257 until inp^ = '''';
258 lineptr:=lineptr+1;
259 read(inp,line[lineptr])
260 end else if inp^ = '{' then begin
261 repeat
262 lineptr:=lineptr+1;
263 read(inp,line[lineptr]);
264 while eoln(inp) do begin
265 lwriteln;
266 newline
267 end
268 until inp^ = '}';
269 lineptr:=lineptr+1;
270 read(inp,line[lineptr])
271 end else if inp^ = '(' then begin
272 lineptr:=lineptr+1;
273 read(inp,line[lineptr]);
274 if inp^ = '*' then begin
275 lineptr:=lineptr+1;
276 read(inp,line[lineptr]);
277 repeat
278 while inp^ <> '*' do
279 if eoln(inp) then begin
280 lwriteln;
281 newline
282 end else begin
283 lineptr:=lineptr+1;
284 read(inp,line[lineptr])
285 end;
286 lineptr:=lineptr+1;
287 read(inp,line[lineptr])
288 until inp^ = ')';
289 lineptr:=lineptr+1;
290 read(inp,line[lineptr])
291 end
292 end else begin
293 lineptr:=lineptr+1;
294 read(inp,line[lineptr]);
295 end
296 end; { scan of token }
297 lwriteln;
298 end; { scan of line }
299 end; { while not eof }
300 end; {readinput }
301
302begin { xref }
303 empty := blanks;
304 list := true;
305 if argc = 3 then begin
306 argv(1, scr);
307 if (scr[1] <> '-') or (scr[2] <> ' ') then begin
308 writeln('usage: pxref [ - ] file');
309 goto 100
310 end;
311 list := false
312 end;
313 if (argc < 2) or (argc > 3) then begin
314 writeln('usage: pxref [ - ] file');
315 goto 100
316 end;
317 for i := 0 to p - 1 do
318 t[i].key := empty;
319 c1 := 0;
320 c2 := 0;
321 key[1] := 'and';
322 key[2] := 'array';
323 key[3] := 'assert';
324 key[4] := 'begin';
325 key[5] := 'case';
326 key[6] := 'const';
327 key[7] := 'div';
328 key[8] := 'do';
329 key[9] := 'downto';
330 key[10] := 'else';
331 key[11] := 'end';
332 key[12] := 'file';
333 key[13] := 'for';
334 key[14] := 'function';
335 key[15] := 'hex';
336 key[16] := 'if';
337 key[17] := 'in';
338 key[18] := 'mod';
339 key[19] := 'nil';
340 key[20] := 'not';
341 key[21] := 'oct';
342 key[22] := 'of';
343 key[23] := 'or';
344 key[24] := 'packed';
345 key[25] := 'procedure';
346 key[26] := 'program';
347 key[27] := 'record';
348 key[28] := 'repeat';
349 key[29] := 'set';
350 key[30] := 'then';
351 key[31] := 'to';
352 key[32] := 'type';
353 key[33] := 'until';
354 key[34] := 'var';
355 key[35] := 'while';
356 key[36] := 'with';
357 for k:= 0 to charclassize do
358 charclass[k]:=illegal;
359 for k:=ord('a') to ord('z') do
360 charclass[k]:=letter;
361 for k:=ord('A') to ord('Z') do
362 charclass[k]:=letter;
363 for k:=ord('0') to ord('9') do
364 charclass[k]:=digit;
365 charclass[ord('_')]:=letter;
366 charclass[ord(' ')]:=separator;
367 charclass[ord(tab)]:=separator;
368 n := 0;
369 lineptr:=0;
370 line:=blanks;
371 top := p;
372 k1 := alfasize;
373 formfeed:=chr(12);
374 if list then
375 argv(1,inputfile)
376 else
377 argv(2,inputfile);
378 readinput(inputfile);
37999:
380 if list then begin
381 page(output);
382 writeln;
383 end;
384 printtable;
385 writeln;
386 writeln(c1, ' identifiers', c2, ' occurrences');
387100:
388 {nil}
389end { xref }.