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