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