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