1*2843Swnj{$t-,p-,b2,w+} 2*2843Swnjprogram xref(input, output); 3*2843Swnjlabel 4*2843Swnj 99, 100; 5*2843Swnjconst 6*2843Swnj { sccsid = '@(#)pxref.p 1.1 (Berkeley) 03/02/81'; } 7*2843Swnj alfasize = 18; 8*2843Swnj linesize = 10; 9*2843Swnj namesize = 64; 10*2843Swnj linelength = 133; 11*2843Swnj maxlineno = 30000; 12*2843Swnj charclassize = 127; 13*2843Swnj p = 1000; 14*2843Swnj nk = 36; 15*2843Swnj blanks = ' '; 16*2843Swnjtype 17*2843Swnj alfa = 18*2843Swnj array[1..alfasize] of 19*2843Swnj char; 20*2843Swnj index = 0..p; 21*2843Swnj linptr = 0..linelength; 22*2843Swnj linebuf = array[1..linelength] of char; 23*2843Swnj ref = ^item; 24*2843Swnj filename = array [1..namesize] of char; 25*2843Swnj charclasses = (digit, letter, separator, illegal); 26*2843Swnj charclasstype = array[0..charclassize] of charclasses; 27*2843Swnj word = 28*2843Swnj record 29*2843Swnj key: alfa; 30*2843Swnj first, last: ref; 31*2843Swnj fol: index 32*2843Swnj end; 33*2843Swnj item = packed 34*2843Swnj record 35*2843Swnj lno: 0..maxlineno; 36*2843Swnj next: ref 37*2843Swnj end; 38*2843Swnjvar 39*2843Swnj i, top: index; 40*2843Swnj formfeed :char; 41*2843Swnj scr: alfa; 42*2843Swnj list: boolean; 43*2843Swnj k, k1: integer; 44*2843Swnj n: integer; 45*2843Swnj c1, c2: integer; 46*2843Swnj inputfile : filename; 47*2843Swnj lineptr :linptr; 48*2843Swnj line :linebuf; 49*2843Swnj charclass :charclasstype; 50*2843Swnj id: 51*2843Swnj record 52*2843Swnj case boolean of 53*2843Swnj false:( 54*2843Swnj a: alfa 55*2843Swnj ); 56*2843Swnj true:( 57*2843Swnj ord: integer 58*2843Swnj ) 59*2843Swnj end; 60*2843Swnj a: array [1..alfasize] of char; 61*2843Swnj t: array [index] of word; 62*2843Swnj key: array [1..nk] of alfa; 63*2843Swnj empty: alfa; 64*2843Swnj 65*2843Swnj function nokey(x: alfa): Boolean; 66*2843Swnj var 67*2843Swnj i, j, k: integer; 68*2843Swnj begin 69*2843Swnj i := 1; 70*2843Swnj j := nk; 71*2843Swnj repeat 72*2843Swnj k := (i + j) div 2; 73*2843Swnj if key[k] <= x then 74*2843Swnj i := k + 1; 75*2843Swnj if key[k] >= x then 76*2843Swnj j := k - 1 77*2843Swnj until i > j; 78*2843Swnj nokey := key[k] <> x 79*2843Swnj end { nokey }; 80*2843Swnj 81*2843Swnj procedure search; 82*2843Swnj var 83*2843Swnj h, d: index; 84*2843Swnj x: ref; 85*2843Swnj f: Boolean; 86*2843Swnj begin 87*2843Swnj h := id.ord div 4096 mod p; 88*2843Swnj f := false; 89*2843Swnj d := 1; 90*2843Swnj c2 := c2 + 1; 91*2843Swnj new(x); 92*2843Swnj x^.lno := n; 93*2843Swnj x^.next := nil; 94*2843Swnj repeat 95*2843Swnj if t[h].key = id.a then begin 96*2843Swnj f := true; 97*2843Swnj t[h].last^.next := x; 98*2843Swnj t[h].last := x 99*2843Swnj end else if t[h].key = empty then begin 100*2843Swnj f := true; 101*2843Swnj c1 := c1 + 1; 102*2843Swnj t[h].key := id.a; 103*2843Swnj t[h].first := x; 104*2843Swnj t[h].last := x; 105*2843Swnj t[h].fol := top; 106*2843Swnj top := h 107*2843Swnj end else begin 108*2843Swnj h := (h + d) mod p; 109*2843Swnj d := d + 2; 110*2843Swnj if d = p then begin 111*2843Swnj writeln; 112*2843Swnj writeln(' **** table full'); 113*2843Swnj goto 99 114*2843Swnj end 115*2843Swnj end 116*2843Swnj until f 117*2843Swnj end { search }; 118*2843Swnj 119*2843Swnj procedure printword(w: word); 120*2843Swnj var 121*2843Swnj l: integer; 122*2843Swnj x: ref; 123*2843Swnj begin 124*2843Swnj write(' ', w.key); 125*2843Swnj x := w.first; 126*2843Swnj l := 0; 127*2843Swnj repeat 128*2843Swnj if l = linesize then begin 129*2843Swnj l := 0; 130*2843Swnj writeln; 131*2843Swnj write(' ', empty) 132*2843Swnj end; 133*2843Swnj l := l + 1; 134*2843Swnj write(x^.lno: 6); 135*2843Swnj x := x^.next 136*2843Swnj until x = nil; 137*2843Swnj writeln 138*2843Swnj end { printword }; 139*2843Swnj 140*2843Swnj procedure printtable; 141*2843Swnj var 142*2843Swnj i, j, m: index; 143*2843Swnj begin 144*2843Swnj i := top; 145*2843Swnj while i <> p do begin 146*2843Swnj m := i; 147*2843Swnj j := t[i].fol; 148*2843Swnj while j <> p do begin 149*2843Swnj if t[j].key < t[m].key then 150*2843Swnj m := j; 151*2843Swnj j := t[j].fol 152*2843Swnj end; 153*2843Swnj printword(t[m]); 154*2843Swnj if m <> i then begin 155*2843Swnj t[m].key := t[i].key; 156*2843Swnj t[m].first := t[i].first; 157*2843Swnj t[m].last := t[i].last 158*2843Swnj end; 159*2843Swnj i := t[i].fol 160*2843Swnj end 161*2843Swnj end { printtable }; 162*2843Swnj 163*2843Swnj procedure readinput(var inpfile :filename); 164*2843Swnj var 165*2843Swnj inp :file of char; 166*2843Swnj 167*2843Swnj procedure lwriteln; 168*2843Swnj var 169*2843Swnj i :linptr; 170*2843Swnj begin 171*2843Swnj if list then begin 172*2843Swnj { actually should use ... 173*2843Swnj for i:=1 to lineptr do 174*2843Swnj write(line[i]); 175*2843Swnj } 176*2843Swnj line[lineptr+1]:=chr(0); 177*2843Swnj writeln(line); 178*2843Swnj end; 179*2843Swnj get(inp); 180*2843Swnj line:=blanks; 181*2843Swnj lineptr:=0 182*2843Swnj end { lwriteln }; 183*2843Swnj 184*2843Swnj procedure newline; 185*2843Swnj begin 186*2843Swnj n:=n+1; 187*2843Swnj if n = maxlineno then begin 188*2843Swnj writeln(' text too long'); 189*2843Swnj goto 99 190*2843Swnj end; 191*2843Swnj if inp^ = formfeed then begin 192*2843Swnj if list then 193*2843Swnj page(output); 194*2843Swnj get(inp) 195*2843Swnj end; 196*2843Swnj if list then 197*2843Swnj if not eoln(inp) then 198*2843Swnj write(n:6,' ') 199*2843Swnj end { newline }; 200*2843Swnj 201*2843Swnj begin 202*2843Swnj reset(inp,inpfile); 203*2843Swnj while not eof(inp) do begin 204*2843Swnj newline; 205*2843Swnj if inp^ = '#' then begin 206*2843Swnj while inp^ <> '"' do begin 207*2843Swnj lineptr:=lineptr+1; 208*2843Swnj read(inp,line[lineptr]) 209*2843Swnj end; 210*2843Swnj lineptr:=lineptr+1; 211*2843Swnj read(inp,line[lineptr]); 212*2843Swnj k:=0; 213*2843Swnj inputfile:=blanks; 214*2843Swnj repeat 215*2843Swnj k:=k+1; 216*2843Swnj if k <= namesize then 217*2843Swnj inputfile[k]:=inp^; 218*2843Swnj lineptr:=lineptr+1; 219*2843Swnj read(inp,line[lineptr]) 220*2843Swnj until inp^ = '"'; 221*2843Swnj while not eoln(inp) do begin 222*2843Swnj lineptr:=lineptr+1; 223*2843Swnj read(inp,line[lineptr]) 224*2843Swnj end; 225*2843Swnj id.a := '#include'; 226*2843Swnj search; 227*2843Swnj lwriteln; 228*2843Swnj readinput(inputfile); 229*2843Swnj end else begin 230*2843Swnj while not eoln(inp) do begin 231*2843Swnj if (inp^ = ' ') or (inp^ = tab) then begin 232*2843Swnj lineptr:=lineptr+1; 233*2843Swnj read(inp,line[lineptr]) 234*2843Swnj end else if charclass[ord(inp^)] = letter then begin 235*2843Swnj k := 0; 236*2843Swnj a:=blanks; 237*2843Swnj repeat 238*2843Swnj k := k + 1; 239*2843Swnj if k <= alfasize then 240*2843Swnj a[k] := inp^; 241*2843Swnj lineptr:=lineptr+1; 242*2843Swnj read(inp,line[lineptr]) 243*2843Swnj until (charclass[ord(inp^)] <> letter) and 244*2843Swnj (charclass[ord(inp^)] <> digit); 245*2843Swnj pack(a, 1, id.a); 246*2843Swnj if nokey(id.a) then 247*2843Swnj search 248*2843Swnj end else if charclass[ord(inp^)] = digit then 249*2843Swnj repeat 250*2843Swnj lineptr:=lineptr+1; 251*2843Swnj read(inp,line[lineptr]) 252*2843Swnj until charclass[ord(inp^)] <> digit 253*2843Swnj else if inp^='''' then begin 254*2843Swnj repeat 255*2843Swnj lineptr:=lineptr+1; 256*2843Swnj read(inp,line[lineptr]) 257*2843Swnj until inp^ = ''''; 258*2843Swnj lineptr:=lineptr+1; 259*2843Swnj read(inp,line[lineptr]) 260*2843Swnj end else if inp^ = '{' then begin 261*2843Swnj repeat 262*2843Swnj lineptr:=lineptr+1; 263*2843Swnj read(inp,line[lineptr]); 264*2843Swnj while eoln(inp) do begin 265*2843Swnj lwriteln; 266*2843Swnj newline 267*2843Swnj end 268*2843Swnj until inp^ = '}'; 269*2843Swnj lineptr:=lineptr+1; 270*2843Swnj read(inp,line[lineptr]) 271*2843Swnj end else if inp^ = '(' then begin 272*2843Swnj lineptr:=lineptr+1; 273*2843Swnj read(inp,line[lineptr]); 274*2843Swnj if inp^ = '*' then begin 275*2843Swnj lineptr:=lineptr+1; 276*2843Swnj read(inp,line[lineptr]); 277*2843Swnj repeat 278*2843Swnj while inp^ <> '*' do 279*2843Swnj if eoln(inp) then begin 280*2843Swnj lwriteln; 281*2843Swnj newline 282*2843Swnj end else begin 283*2843Swnj lineptr:=lineptr+1; 284*2843Swnj read(inp,line[lineptr]) 285*2843Swnj end; 286*2843Swnj lineptr:=lineptr+1; 287*2843Swnj read(inp,line[lineptr]) 288*2843Swnj until inp^ = ')'; 289*2843Swnj lineptr:=lineptr+1; 290*2843Swnj read(inp,line[lineptr]) 291*2843Swnj end 292*2843Swnj end else begin 293*2843Swnj lineptr:=lineptr+1; 294*2843Swnj read(inp,line[lineptr]); 295*2843Swnj end 296*2843Swnj end; { scan of token } 297*2843Swnj lwriteln; 298*2843Swnj end; { scan of line } 299*2843Swnj end; { while not eof } 300*2843Swnj end; {readinput } 301*2843Swnj 302*2843Swnjbegin { xref } 303*2843Swnj empty := blanks; 304*2843Swnj list := true; 305*2843Swnj if argc = 3 then begin 306*2843Swnj argv(1, scr); 307*2843Swnj if (scr[1] <> '-') or (scr[2] <> ' ') then begin 308*2843Swnj writeln('usage: pxref [ - ] file'); 309*2843Swnj goto 100 310*2843Swnj end; 311*2843Swnj list := false 312*2843Swnj end; 313*2843Swnj if (argc < 2) or (argc > 3) then begin 314*2843Swnj writeln('usage: pxref [ - ] file'); 315*2843Swnj goto 100 316*2843Swnj end; 317*2843Swnj for i := 0 to p - 1 do 318*2843Swnj t[i].key := empty; 319*2843Swnj c1 := 0; 320*2843Swnj c2 := 0; 321*2843Swnj key[1] := 'and'; 322*2843Swnj key[2] := 'array'; 323*2843Swnj key[3] := 'assert'; 324*2843Swnj key[4] := 'begin'; 325*2843Swnj key[5] := 'case'; 326*2843Swnj key[6] := 'const'; 327*2843Swnj key[7] := 'div'; 328*2843Swnj key[8] := 'do'; 329*2843Swnj key[9] := 'downto'; 330*2843Swnj key[10] := 'else'; 331*2843Swnj key[11] := 'end'; 332*2843Swnj key[12] := 'file'; 333*2843Swnj key[13] := 'for'; 334*2843Swnj key[14] := 'function'; 335*2843Swnj key[15] := 'hex'; 336*2843Swnj key[16] := 'if'; 337*2843Swnj key[17] := 'in'; 338*2843Swnj key[18] := 'mod'; 339*2843Swnj key[19] := 'nil'; 340*2843Swnj key[20] := 'not'; 341*2843Swnj key[21] := 'oct'; 342*2843Swnj key[22] := 'of'; 343*2843Swnj key[23] := 'or'; 344*2843Swnj key[24] := 'packed'; 345*2843Swnj key[25] := 'procedure'; 346*2843Swnj key[26] := 'program'; 347*2843Swnj key[27] := 'record'; 348*2843Swnj key[28] := 'repeat'; 349*2843Swnj key[29] := 'set'; 350*2843Swnj key[30] := 'then'; 351*2843Swnj key[31] := 'to'; 352*2843Swnj key[32] := 'type'; 353*2843Swnj key[33] := 'until'; 354*2843Swnj key[34] := 'var'; 355*2843Swnj key[35] := 'while'; 356*2843Swnj key[36] := 'with'; 357*2843Swnj for k:= 0 to charclassize do 358*2843Swnj charclass[k]:=illegal; 359*2843Swnj for k:=ord('a') to ord('z') do 360*2843Swnj charclass[k]:=letter; 361*2843Swnj for k:=ord('A') to ord('Z') do 362*2843Swnj charclass[k]:=letter; 363*2843Swnj for k:=ord('0') to ord('9') do 364*2843Swnj charclass[k]:=digit; 365*2843Swnj charclass[ord('_')]:=letter; 366*2843Swnj charclass[ord(' ')]:=separator; 367*2843Swnj charclass[ord(tab)]:=separator; 368*2843Swnj n := 0; 369*2843Swnj lineptr:=0; 370*2843Swnj line:=blanks; 371*2843Swnj top := p; 372*2843Swnj k1 := alfasize; 373*2843Swnj formfeed:=chr(12); 374*2843Swnj if list then 375*2843Swnj argv(1,inputfile) 376*2843Swnj else 377*2843Swnj argv(2,inputfile); 378*2843Swnj readinput(inputfile); 379*2843Swnj99: 380*2843Swnj if list then begin 381*2843Swnj page(output); 382*2843Swnj writeln; 383*2843Swnj end; 384*2843Swnj printtable; 385*2843Swnj writeln; 386*2843Swnj writeln(c1, ' identifiers', c2, ' occurrences'); 387*2843Swnj100: 388*2843Swnj {nil} 389*2843Swnjend { xref }. 390