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