xref: /csrg-svn/usr.bin/pascal/pxref/pxref.p (revision 22268)
1*22268Sdist(*
2*22268Sdist * Copyright (c) 1980 Regents of the University of California.
3*22268Sdist * All rights reserved.  The Berkeley software License Agreement
4*22268Sdist * specifies the terms and conditions for redistribution.
5*22268Sdist *)
6*22268Sdist
7*22268Sdist#ifndef lint
8*22268Sdistchar copyright[] =
9*22268Sdist"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10*22268Sdist All rights reserved.\n";
11*22268Sdist#endif not lint
12*22268Sdist
13*22268Sdist#ifndef lint
14*22268Sdiststatic char sccsid[] = "@(#)pxref.p	5.1 (Berkeley) 06/05/85";
15*22268Sdist#endif not lint
16*22268Sdist
172843Swnj{$t-,p-,b2,w+}
182843Swnjprogram xref(input, output);
192843Swnjlabel
202843Swnj    99, 100;
212843Swnjconst
22*22268Sdist    { sccsid = '@(#)pxref.p	5.1 (Berkeley) 06/05/85'; }
232843Swnj    alfasize = 18;
242843Swnj    linesize = 10;
252843Swnj    namesize = 64;
262843Swnj    linelength = 133;
272843Swnj    maxlineno = 30000;
282843Swnj    charclassize = 127;
292843Swnj    p = 1000;
302843Swnj    nk = 36;
312843Swnj    blanks = '  ';
322843Swnjtype
332843Swnj    alfa =
342843Swnj      array[1..alfasize] of
352843Swnj	char;
362843Swnj    index = 0..p;
372843Swnj    linptr = 0..linelength;
382843Swnj    linebuf = array[1..linelength] of char;
392843Swnj    ref = ^item;
402843Swnj    filename = array [1..namesize] of char;
412843Swnj    charclasses = (digit, letter, separator, illegal);
422843Swnj    charclasstype = array[0..charclassize] of charclasses;
432843Swnj    word =
442843Swnj      record
452843Swnj	key: alfa;
462843Swnj	first, last: ref;
472843Swnj	fol: index
482843Swnj      end;
492843Swnj    item =   packed
502843Swnj      record
512843Swnj	lno: 0..maxlineno;
522843Swnj	next: ref
532843Swnj      end;
542843Swnjvar
552843Swnj    i, top: index;
562843Swnj    formfeed :char;
572843Swnj    scr: alfa;
582843Swnj    list: boolean;
592843Swnj    k, k1: integer;
602843Swnj    n: integer;
612843Swnj    c1, c2: integer;
622843Swnj    inputfile : filename;
632843Swnj    lineptr :linptr;
642843Swnj    line :linebuf;
652843Swnj    charclass :charclasstype;
662843Swnj    id:
672843Swnj      record
682843Swnj	case boolean of
692843Swnj	  false:(
702843Swnj	    a: alfa
712843Swnj	  );
722843Swnj	  true:(
732843Swnj	    ord: integer
742843Swnj	  )
752843Swnj      end;
762843Swnj    a: array [1..alfasize] of char;
772843Swnj    t: array [index] of word;
782843Swnj    key: array [1..nk] of alfa;
792843Swnj    empty: alfa;
802843Swnj
812843Swnj    function nokey(x: alfa): Boolean;
822843Swnj    var
832843Swnj	i, j, k: integer;
842843Swnj    begin
852843Swnj	i := 1;
862843Swnj	j := nk;
872843Swnj	repeat
882843Swnj	    k := (i + j) div 2;
892843Swnj	    if key[k] <= x then
902843Swnj		i := k + 1;
912843Swnj	    if key[k] >= x then
922843Swnj		j := k - 1
932843Swnj	until i > j;
942843Swnj	nokey := key[k] <> x
952843Swnj    end { nokey };
962843Swnj
972843Swnj    procedure search;
982843Swnj    var
992843Swnj	h, d: index;
1002843Swnj	x: ref;
1012843Swnj	f: Boolean;
1022843Swnj    begin
1032843Swnj	h := id.ord div 4096 mod p;
1042843Swnj	f := false;
1052843Swnj	d := 1;
1062843Swnj	c2 := c2 + 1;
1072843Swnj	new(x);
1082843Swnj	x^.lno := n;
1092843Swnj	x^.next := nil;
1102843Swnj	repeat
1112843Swnj	    if t[h].key = id.a then begin
1122843Swnj		f := true;
1132843Swnj		t[h].last^.next := x;
1142843Swnj		t[h].last := x
1152843Swnj	    end else if t[h].key = empty then begin
1162843Swnj		f := true;
1172843Swnj		c1 := c1 + 1;
1182843Swnj		t[h].key := id.a;
1192843Swnj		t[h].first := x;
1202843Swnj		t[h].last := x;
1212843Swnj		t[h].fol := top;
1222843Swnj		top := h
1232843Swnj	    end else begin
1242843Swnj		h := (h + d) mod p;
1252843Swnj		d := d + 2;
1266043Smckusic		if d >= p then begin
1272843Swnj		    writeln;
1282843Swnj		    writeln(' **** table full');
1292843Swnj		    goto 99
1302843Swnj		end
1312843Swnj	    end
1322843Swnj	until f
1332843Swnj    end { search };
1342843Swnj
1352843Swnj    procedure printword(w: word);
1362843Swnj    var
1372843Swnj	l: integer;
1382843Swnj	x: ref;
1392843Swnj    begin
1402843Swnj	write(' ', w.key);
1412843Swnj	x := w.first;
1422843Swnj	l := 0;
1432843Swnj	repeat
1442843Swnj	    if l = linesize then begin
1452843Swnj		l := 0;
1462843Swnj		writeln;
1472843Swnj		write(' ', empty)
1482843Swnj	    end;
1492843Swnj	    l := l + 1;
1502843Swnj	    write(x^.lno: 6);
1512843Swnj	    x := x^.next
1522843Swnj	until x = nil;
1532843Swnj	writeln
1542843Swnj    end { printword };
1552843Swnj
1562843Swnj    procedure printtable;
1572843Swnj    var
1582843Swnj	i, j, m: index;
1592843Swnj    begin
1602843Swnj	i := top;
1612843Swnj	while i <> p do begin
1622843Swnj	    m := i;
1632843Swnj	    j := t[i].fol;
1642843Swnj	    while j <> p do begin
1652843Swnj		if t[j].key < t[m].key then
1662843Swnj		    m := j;
1672843Swnj		j := t[j].fol
1682843Swnj	    end;
1692843Swnj	    printword(t[m]);
1702843Swnj	    if m <> i then begin
1712843Swnj		t[m].key := t[i].key;
1722843Swnj		t[m].first := t[i].first;
1732843Swnj		t[m].last := t[i].last
1742843Swnj	    end;
1752843Swnj	    i := t[i].fol
1762843Swnj	end
1772843Swnj    end { printtable };
1782843Swnj
1792843Swnj    procedure readinput(var inpfile :filename);
1802843Swnj    var
1812843Swnj    inp :file of char;
1822843Swnj
1832843Swnj    procedure lwriteln;
1842843Swnj    begin
1852843Swnj	if list then begin
18615775Saoki	    { write sans trailing blanks }
18715775Saoki	    if lineptr > 0 then
18815775Saoki		writeln(line: lineptr)
18915775Saoki	    else
19015775Saoki		writeln;
1912843Swnj	end;
1922843Swnj	get(inp);
1932843Swnj	lineptr:=0
1942843Swnj    end { lwriteln };
1952843Swnj
1962843Swnj    procedure newline;
1972843Swnj    begin
1982843Swnj	n:=n+1;
1992843Swnj	if n = maxlineno then begin
2002843Swnj	    writeln(' text too long');
2012843Swnj	    goto 99
2022843Swnj	end;
2032843Swnj	if inp^ = formfeed then begin
2042843Swnj	    if list then
2052843Swnj		page(output);
2062843Swnj	    get(inp)
2072843Swnj	end;
2082843Swnj	if list then
2092843Swnj	    if not eoln(inp) then
2102843Swnj		write(n:6,'  ')
2112843Swnj    end { newline };
2122843Swnj
2132843Swnj    begin
2142843Swnj	reset(inp,inpfile);
2152843Swnj	while not eof(inp) do begin
2162843Swnj	    newline;
2172843Swnj	    if inp^ = '#' then begin
2182843Swnj		while inp^ <> '"' do begin
2192843Swnj		    lineptr:=lineptr+1;
2202843Swnj		    read(inp,line[lineptr])
2212843Swnj		end;
2222843Swnj		lineptr:=lineptr+1;
2232843Swnj		read(inp,line[lineptr]);
2242843Swnj		k:=0;
2252843Swnj		inputfile:=blanks;
2262843Swnj		repeat
2272843Swnj		    k:=k+1;
2282843Swnj		    if k <= namesize then
2292843Swnj			inputfile[k]:=inp^;
2302843Swnj		    lineptr:=lineptr+1;
2312843Swnj		    read(inp,line[lineptr])
2322843Swnj		until inp^ = '"';
2332843Swnj		while not eoln(inp) do begin
2342843Swnj		    lineptr:=lineptr+1;
2352843Swnj		    read(inp,line[lineptr])
2362843Swnj		end;
2372843Swnj		id.a := '#include';
2382843Swnj		search;
2392843Swnj		lwriteln;
2402843Swnj		readinput(inputfile);
2412843Swnj	    end else begin
2422843Swnj		while not eoln(inp) do begin
2432843Swnj		    if (inp^ = ' ') or (inp^ = tab) then begin
2442843Swnj			lineptr:=lineptr+1;
2452843Swnj			read(inp,line[lineptr])
2462843Swnj		    end else if charclass[ord(inp^)] = letter then begin
2472843Swnj		        k := 0;
2482843Swnj			a:=blanks;
2492843Swnj		        repeat
2502843Swnj			    k := k + 1;
2512843Swnj			    if k <= alfasize then
2522843Swnj			        a[k] := inp^;
2532843Swnj			    lineptr:=lineptr+1;
2542843Swnj			    read(inp,line[lineptr])
2552843Swnj		        until (charclass[ord(inp^)] <> letter) and
2562843Swnj			      (charclass[ord(inp^)] <> digit);
2572843Swnj		        pack(a, 1, id.a);
2582843Swnj		        if nokey(id.a) then
2592843Swnj			    search
2602843Swnj		    end else if charclass[ord(inp^)] = digit then
2612843Swnj		        repeat
2622843Swnj			    lineptr:=lineptr+1;
2632843Swnj			    read(inp,line[lineptr])
2642843Swnj		        until charclass[ord(inp^)] <> digit
2652843Swnj		    else if inp^='''' then begin
2662843Swnj		        repeat
2672843Swnj			    lineptr:=lineptr+1;
2682843Swnj			    read(inp,line[lineptr])
2692843Swnj		        until inp^ = '''';
2702843Swnj			lineptr:=lineptr+1;
2712843Swnj			read(inp,line[lineptr])
2722843Swnj		    end else if inp^ = '{' then begin
2732843Swnj		        repeat
2742843Swnj			    lineptr:=lineptr+1;
2752843Swnj			    read(inp,line[lineptr]);
2762843Swnj			    while eoln(inp) do begin
2772843Swnj			        lwriteln;
2782843Swnj				newline
2792843Swnj			    end
2802843Swnj		        until inp^ = '}';
2812843Swnj			lineptr:=lineptr+1;
2822843Swnj			read(inp,line[lineptr])
2832843Swnj		    end else if inp^ = '(' then begin
2842843Swnj			lineptr:=lineptr+1;
2852843Swnj			read(inp,line[lineptr]);
2862843Swnj		        if inp^ = '*' then begin
2872843Swnj			    lineptr:=lineptr+1;
2882843Swnj			    read(inp,line[lineptr]);
2892843Swnj			    repeat
2902843Swnj			        while inp^ <> '*' do
2912843Swnj				    if eoln(inp) then begin
2922843Swnj				        lwriteln;
2932843Swnj					newline
2942843Swnj				    end else begin
2952843Swnj					lineptr:=lineptr+1;
2962843Swnj					read(inp,line[lineptr])
2972843Swnj			            end;
2982843Swnj				lineptr:=lineptr+1;
2992843Swnj				read(inp,line[lineptr])
3002843Swnj			    until inp^ = ')';
3012843Swnj			    lineptr:=lineptr+1;
3022843Swnj			    read(inp,line[lineptr])
3032843Swnj		        end
3042843Swnj		    end else begin
3052843Swnj			lineptr:=lineptr+1;
3062843Swnj			read(inp,line[lineptr]);
3072843Swnj		    end
3082843Swnj		end; { scan of token }
3092843Swnj		lwriteln;
3102843Swnj	    end; { scan of line }
3112843Swnj	end; { while not eof }
3122843Swnj    end; {readinput }
3132843Swnj
3142843Swnjbegin { xref }
3152843Swnj    empty := blanks;
3162843Swnj    list := true;
3172843Swnj    if argc = 3 then begin
3182843Swnj	argv(1, scr);
3192843Swnj	if (scr[1] <> '-') or (scr[2] <> ' ') then begin
3202843Swnj	    writeln('usage: pxref [ - ] file');
3212843Swnj	    goto 100
3222843Swnj	end;
3232843Swnj	list := false
3242843Swnj    end;
3252843Swnj    if (argc < 2) or (argc > 3) then begin
3262843Swnj	writeln('usage: pxref [ - ] file');
3272843Swnj	goto 100
3282843Swnj    end;
3292843Swnj    for i := 0 to p - 1 do
3302843Swnj	t[i].key := empty;
3312843Swnj    c1 := 0;
3322843Swnj    c2 := 0;
3332843Swnj    key[1] := 'and';
3342843Swnj    key[2] := 'array';
3352843Swnj    key[3] := 'assert';
3362843Swnj    key[4] := 'begin';
3372843Swnj    key[5] := 'case';
3382843Swnj    key[6] := 'const';
3392843Swnj    key[7] := 'div';
3402843Swnj    key[8] := 'do';
3412843Swnj    key[9] := 'downto';
3422843Swnj    key[10] := 'else';
3432843Swnj    key[11] := 'end';
3442843Swnj    key[12] := 'file';
3452843Swnj    key[13] := 'for';
3462843Swnj    key[14] := 'function';
3472843Swnj    key[15] := 'hex';
3482843Swnj    key[16] := 'if';
3492843Swnj    key[17] := 'in';
3502843Swnj    key[18] := 'mod';
3512843Swnj    key[19] := 'nil';
3522843Swnj    key[20] := 'not';
3532843Swnj    key[21] := 'oct';
3542843Swnj    key[22] := 'of';
3552843Swnj    key[23] := 'or';
3562843Swnj    key[24] := 'packed';
3572843Swnj    key[25] := 'procedure';
3582843Swnj    key[26] := 'program';
3592843Swnj    key[27] := 'record';
3602843Swnj    key[28] := 'repeat';
3612843Swnj    key[29] := 'set';
3622843Swnj    key[30] := 'then';
3632843Swnj    key[31] := 'to';
3642843Swnj    key[32] := 'type';
3652843Swnj    key[33] := 'until';
3662843Swnj    key[34] := 'var';
3672843Swnj    key[35] := 'while';
3682843Swnj    key[36] := 'with';
3692843Swnj    for k:= 0 to charclassize do
3702843Swnj	charclass[k]:=illegal;
3712843Swnj    for k:=ord('a') to ord('z') do
3722843Swnj	charclass[k]:=letter;
3732843Swnj    for k:=ord('A') to ord('Z') do
3742843Swnj	charclass[k]:=letter;
3752843Swnj    for k:=ord('0') to ord('9') do
3762843Swnj	charclass[k]:=digit;
3772843Swnj    charclass[ord('_')]:=letter;
3782843Swnj    charclass[ord(' ')]:=separator;
3792843Swnj    charclass[ord(tab)]:=separator;
3802843Swnj    n := 0;
3812843Swnj    lineptr:=0;
3822843Swnj    line:=blanks;
3832843Swnj    top := p;
3842843Swnj    k1 := alfasize;
3852843Swnj    formfeed:=chr(12);
3862843Swnj    if list then
3872843Swnj        argv(1,inputfile)
3882843Swnj    else
3892843Swnj        argv(2,inputfile);
3902843Swnj    readinput(inputfile);
3912843Swnj99:
3922843Swnj    if list then begin
3932843Swnj	page(output);
3942843Swnj        writeln;
3952843Swnj        end;
3962843Swnj    printtable;
3972843Swnj    writeln;
3982843Swnj    writeln(c1, ' identifiers', c2, ' occurrences');
3992843Swnj100:
4002843Swnj    {nil}
4012843Swnjend { xref }.
402