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