xref: /csrg-svn/usr.bin/pascal/pxref/pxref.p (revision 15775)
12843Swnj{$t-,p-,b2,w+}
22843Swnjprogram xref(input, output);
32843Swnjlabel
42843Swnj    99, 100;
52843Swnjconst
6*15775Saoki    { sccsid = '@(#)pxref.p	1.3 (Berkeley) 12/28/83'; }
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;
1106043Smckusic		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    begin
1692843Swnj	if list then begin
170*15775Saoki	    { write sans trailing blanks }
171*15775Saoki	    if lineptr > 0 then
172*15775Saoki		writeln(line: lineptr)
173*15775Saoki	    else
174*15775Saoki		writeln;
1752843Swnj	end;
1762843Swnj	get(inp);
1772843Swnj	lineptr:=0
1782843Swnj    end { lwriteln };
1792843Swnj
1802843Swnj    procedure newline;
1812843Swnj    begin
1822843Swnj	n:=n+1;
1832843Swnj	if n = maxlineno then begin
1842843Swnj	    writeln(' text too long');
1852843Swnj	    goto 99
1862843Swnj	end;
1872843Swnj	if inp^ = formfeed then begin
1882843Swnj	    if list then
1892843Swnj		page(output);
1902843Swnj	    get(inp)
1912843Swnj	end;
1922843Swnj	if list then
1932843Swnj	    if not eoln(inp) then
1942843Swnj		write(n:6,'  ')
1952843Swnj    end { newline };
1962843Swnj
1972843Swnj    begin
1982843Swnj	reset(inp,inpfile);
1992843Swnj	while not eof(inp) do begin
2002843Swnj	    newline;
2012843Swnj	    if inp^ = '#' then begin
2022843Swnj		while inp^ <> '"' do begin
2032843Swnj		    lineptr:=lineptr+1;
2042843Swnj		    read(inp,line[lineptr])
2052843Swnj		end;
2062843Swnj		lineptr:=lineptr+1;
2072843Swnj		read(inp,line[lineptr]);
2082843Swnj		k:=0;
2092843Swnj		inputfile:=blanks;
2102843Swnj		repeat
2112843Swnj		    k:=k+1;
2122843Swnj		    if k <= namesize then
2132843Swnj			inputfile[k]:=inp^;
2142843Swnj		    lineptr:=lineptr+1;
2152843Swnj		    read(inp,line[lineptr])
2162843Swnj		until inp^ = '"';
2172843Swnj		while not eoln(inp) do begin
2182843Swnj		    lineptr:=lineptr+1;
2192843Swnj		    read(inp,line[lineptr])
2202843Swnj		end;
2212843Swnj		id.a := '#include';
2222843Swnj		search;
2232843Swnj		lwriteln;
2242843Swnj		readinput(inputfile);
2252843Swnj	    end else begin
2262843Swnj		while not eoln(inp) do begin
2272843Swnj		    if (inp^ = ' ') or (inp^ = tab) then begin
2282843Swnj			lineptr:=lineptr+1;
2292843Swnj			read(inp,line[lineptr])
2302843Swnj		    end else if charclass[ord(inp^)] = letter then begin
2312843Swnj		        k := 0;
2322843Swnj			a:=blanks;
2332843Swnj		        repeat
2342843Swnj			    k := k + 1;
2352843Swnj			    if k <= alfasize then
2362843Swnj			        a[k] := inp^;
2372843Swnj			    lineptr:=lineptr+1;
2382843Swnj			    read(inp,line[lineptr])
2392843Swnj		        until (charclass[ord(inp^)] <> letter) and
2402843Swnj			      (charclass[ord(inp^)] <> digit);
2412843Swnj		        pack(a, 1, id.a);
2422843Swnj		        if nokey(id.a) then
2432843Swnj			    search
2442843Swnj		    end else if charclass[ord(inp^)] = digit then
2452843Swnj		        repeat
2462843Swnj			    lineptr:=lineptr+1;
2472843Swnj			    read(inp,line[lineptr])
2482843Swnj		        until charclass[ord(inp^)] <> digit
2492843Swnj		    else if inp^='''' then begin
2502843Swnj		        repeat
2512843Swnj			    lineptr:=lineptr+1;
2522843Swnj			    read(inp,line[lineptr])
2532843Swnj		        until inp^ = '''';
2542843Swnj			lineptr:=lineptr+1;
2552843Swnj			read(inp,line[lineptr])
2562843Swnj		    end else if inp^ = '{' then begin
2572843Swnj		        repeat
2582843Swnj			    lineptr:=lineptr+1;
2592843Swnj			    read(inp,line[lineptr]);
2602843Swnj			    while eoln(inp) do begin
2612843Swnj			        lwriteln;
2622843Swnj				newline
2632843Swnj			    end
2642843Swnj		        until inp^ = '}';
2652843Swnj			lineptr:=lineptr+1;
2662843Swnj			read(inp,line[lineptr])
2672843Swnj		    end else if inp^ = '(' then begin
2682843Swnj			lineptr:=lineptr+1;
2692843Swnj			read(inp,line[lineptr]);
2702843Swnj		        if inp^ = '*' then begin
2712843Swnj			    lineptr:=lineptr+1;
2722843Swnj			    read(inp,line[lineptr]);
2732843Swnj			    repeat
2742843Swnj			        while inp^ <> '*' do
2752843Swnj				    if eoln(inp) then begin
2762843Swnj				        lwriteln;
2772843Swnj					newline
2782843Swnj				    end else begin
2792843Swnj					lineptr:=lineptr+1;
2802843Swnj					read(inp,line[lineptr])
2812843Swnj			            end;
2822843Swnj				lineptr:=lineptr+1;
2832843Swnj				read(inp,line[lineptr])
2842843Swnj			    until inp^ = ')';
2852843Swnj			    lineptr:=lineptr+1;
2862843Swnj			    read(inp,line[lineptr])
2872843Swnj		        end
2882843Swnj		    end else begin
2892843Swnj			lineptr:=lineptr+1;
2902843Swnj			read(inp,line[lineptr]);
2912843Swnj		    end
2922843Swnj		end; { scan of token }
2932843Swnj		lwriteln;
2942843Swnj	    end; { scan of line }
2952843Swnj	end; { while not eof }
2962843Swnj    end; {readinput }
2972843Swnj
2982843Swnjbegin { xref }
2992843Swnj    empty := blanks;
3002843Swnj    list := true;
3012843Swnj    if argc = 3 then begin
3022843Swnj	argv(1, scr);
3032843Swnj	if (scr[1] <> '-') or (scr[2] <> ' ') then begin
3042843Swnj	    writeln('usage: pxref [ - ] file');
3052843Swnj	    goto 100
3062843Swnj	end;
3072843Swnj	list := false
3082843Swnj    end;
3092843Swnj    if (argc < 2) or (argc > 3) then begin
3102843Swnj	writeln('usage: pxref [ - ] file');
3112843Swnj	goto 100
3122843Swnj    end;
3132843Swnj    for i := 0 to p - 1 do
3142843Swnj	t[i].key := empty;
3152843Swnj    c1 := 0;
3162843Swnj    c2 := 0;
3172843Swnj    key[1] := 'and';
3182843Swnj    key[2] := 'array';
3192843Swnj    key[3] := 'assert';
3202843Swnj    key[4] := 'begin';
3212843Swnj    key[5] := 'case';
3222843Swnj    key[6] := 'const';
3232843Swnj    key[7] := 'div';
3242843Swnj    key[8] := 'do';
3252843Swnj    key[9] := 'downto';
3262843Swnj    key[10] := 'else';
3272843Swnj    key[11] := 'end';
3282843Swnj    key[12] := 'file';
3292843Swnj    key[13] := 'for';
3302843Swnj    key[14] := 'function';
3312843Swnj    key[15] := 'hex';
3322843Swnj    key[16] := 'if';
3332843Swnj    key[17] := 'in';
3342843Swnj    key[18] := 'mod';
3352843Swnj    key[19] := 'nil';
3362843Swnj    key[20] := 'not';
3372843Swnj    key[21] := 'oct';
3382843Swnj    key[22] := 'of';
3392843Swnj    key[23] := 'or';
3402843Swnj    key[24] := 'packed';
3412843Swnj    key[25] := 'procedure';
3422843Swnj    key[26] := 'program';
3432843Swnj    key[27] := 'record';
3442843Swnj    key[28] := 'repeat';
3452843Swnj    key[29] := 'set';
3462843Swnj    key[30] := 'then';
3472843Swnj    key[31] := 'to';
3482843Swnj    key[32] := 'type';
3492843Swnj    key[33] := 'until';
3502843Swnj    key[34] := 'var';
3512843Swnj    key[35] := 'while';
3522843Swnj    key[36] := 'with';
3532843Swnj    for k:= 0 to charclassize do
3542843Swnj	charclass[k]:=illegal;
3552843Swnj    for k:=ord('a') to ord('z') do
3562843Swnj	charclass[k]:=letter;
3572843Swnj    for k:=ord('A') to ord('Z') do
3582843Swnj	charclass[k]:=letter;
3592843Swnj    for k:=ord('0') to ord('9') do
3602843Swnj	charclass[k]:=digit;
3612843Swnj    charclass[ord('_')]:=letter;
3622843Swnj    charclass[ord(' ')]:=separator;
3632843Swnj    charclass[ord(tab)]:=separator;
3642843Swnj    n := 0;
3652843Swnj    lineptr:=0;
3662843Swnj    line:=blanks;
3672843Swnj    top := p;
3682843Swnj    k1 := alfasize;
3692843Swnj    formfeed:=chr(12);
3702843Swnj    if list then
3712843Swnj        argv(1,inputfile)
3722843Swnj    else
3732843Swnj        argv(2,inputfile);
3742843Swnj    readinput(inputfile);
3752843Swnj99:
3762843Swnj    if list then begin
3772843Swnj	page(output);
3782843Swnj        writeln;
3792843Swnj        end;
3802843Swnj    printtable;
3812843Swnj    writeln;
3822843Swnj    writeln(c1, ' identifiers', c2, ' occurrences');
3832843Swnj100:
3842843Swnj    {nil}
3852843Swnjend { xref }.
386