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