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