1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 include_cross_reference: icref: proc;
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 dcl archive_util_$first_element entry (ptr, fixed bin);
42 dcl archive_util_$next_element entry (ptr, fixed bin);
43 dcl com_err_ entry options (variable);
44 dcl cu_$arg_ptr entry (fixed bin, ptr, fixed bin, fixed bin (35));
45 dcl cv_dec_ entry (char (*) aligned) returns (fixed bin (35));
46 dcl expand_path_ entry (ptr, fixed bin, ptr, ptr, fixed bin (35));
47 dcl get_system_free_area_ entry returns (ptr);
48 dcl ioa_ entry options (variable);
49 dcl hcs_$delentry_seg entry (ptr, fixed bin (35));
50 dcl hcs_$initiate_count entry (char (*) aligned, char (*) aligned, char (*), fixed bin (24), fixed bin (12),
51 ptr, fixed bin (35));
52 dcl hcs_$make_seg entry (char (*), char (*), char (*), fixed bin (5), ptr, fixed bin (35));
53 dcl hcs_$star_ entry (char (*) aligned, char (*), fixed bin (2), ptr, fixed bin, ptr, ptr, fixed bin (35));
54 dcl hcs_$terminate_noname entry (ptr, fixed bin (35));
55 dcl ios_$attach entry (char (*), char (*), char (*), char (*), bit (72) aligned);
56 dcl ios_$detach entry (char (*), char (*), char (*), bit (72) aligned);
57 dcl ioa_$ioa_stream entry options (variable);
58 dcl (tp, p, ap, sp, isegp) ptr;
59 dcl (areap) ptr init (null);
60 dcl (eptr, nptr) ptr init (null);
61 dcl (tc, acode, maxisp, next_path, j, ai, count, isp, sname_len, ename_len, iname_len) fixed bin;
62 dcl code fixed bin (35);
63 dcl (acl, cl) fixed bin (24);
64 dcl (type, bc, name_offset, nsegs, nchars, strx, inp, inp1, k, i) fixed bin;
65 dcl (archives_tested, segs_tested, segs_with_includes, number_of_includes, unbound_segs) fixed bin init (0);
66 dcl (dirname, path) char (168) aligned;
67 dcl outname char (168) init ((168) " ");
68 dcl stream_name char (12) init ("icref_stream");
69 dcl output_name char (11) init ("user_output");
70 dcl (ename, sname, iname) char (32) aligned;
71 dcl first_incl_sw bit (1) aligned init ("0"b);
72 dcl not_an_archive bit (1) aligned init ("0"b);
73 dcl status bit (72) aligned;
74 dcl (c1, c2, c3, c4) char (1) aligned;
75 dcl targ char (tc) based (tp);
76 dcl btarg char (tc) aligned based (tp);
77 dcl string char (262144) based (sp) aligned;
78 dcl nl char (1) aligned internal static initial ("
79 ");
80 dcl quote_sign char (1) aligned init ("""");
81 dcl hash_char bit (9) init ("000000000"b);
82 dcl star_name char (2) static init ("**");
83 dcl ctype (6) char (8) aligned static init ("pl1", "alm", "ioc", "fortran", "bcpl", "mexp");
84 dcl t3 char (3) aligned,
85 c char (1) aligned;
86
87 dcl 1 header based (p) aligned,
88 2 pad0 char (12),
89 2 name char (32),
90 2 pad1 char (40),
91 2 bitcnt char (8);
92
93 dcl 1 cha based,
94 2 r (0: 1) char (1);
95
96 dcl 1 ch based aligned,
97 2 a (0: 1) char (1) unal;
98
99 dcl ht (0:1) fixed bin based (isegp);
100
101 dcl enamea (262144) char (32) aligned based;
102
103 dcl 1 entries (1) based (eptr) aligned,
104 2 type bit (2) unal,
105 2 nname bit (16) unal,
106 2 nindex bit (18) unal;
107
108 dcl (addr, addrel, divide, fixed, index, null, ptr, substr, unspec) builtin;
109
110 call cu_$arg_ptr (1, tp, tc, code);
111 if code ^= 0 | tc = 0 then do;
112
113 call com_err_ (code, "icref", "Usage: icref path_of_search_file");
114 return;
115 end;
116
117 call expand_path_ (tp, tc, addr (dirname), addr (ename), code);
118 if code ^= 0 then do;
119 call com_err_ (code, "icref", targ);
120 return;
121 end;
122
123 outname = targ;
124 call hcs_$initiate_count (dirname, ename, "", cl, 0, p, code);
125 if p = null
126 then do;
127 call com_err_ (code, "icref", "^a>^a", dirname, ename);
128 return;
129 end;
130
131 cl = divide (cl, 9, 17, 0);
132
133
134
135 nchars, nsegs = 0;
136
137 call hcs_$make_seg ("", "ISEG", "", 01010b, isegp, code);
138 if isegp = null then do;
139 call com_err_ (code, "icref", "Trying to create [pd]>ISEG");
140 return;
141 end;
142
143 isp = 128;
144 declare sys_info$max_seg_size external static fixed binary (35);
145
146 maxisp = sys_info$max_seg_size;
147
148 if areap = null then areap = get_system_free_area_ ();
149 next_path = 1;
150 PATH_LOOP:
151 if next_path > cl then go to PRINT;
152 j = index (substr (p -> string, next_path, cl-next_path+1), nl) - 1;
153 if j <= 0 then go to PRINT;
154 path = substr (p -> string, next_path, j);
155 next_path = next_path + j + 1;
156
157 call hcs_$star_ (path, star_name, 2, areap, count, eptr, nptr, code);
158 if code ^= 0 then do;
159 call com_err_ (code, "icref", path);
160
161 go to PATH_LOOP;
162 end;
163
164
165
166
167
168 do ai = 1 to count;
169
170 if eptr -> entries (ai).type ^= "01"b then go to NEXT_ARCHIVE;
171 ename = nptr -> enamea (fixed (eptr -> entries (ai).nindex, 18));
172 call hcs_$initiate_count (path, ename, "", acl, 0, ap, code);
173 if ap = null then do;
174 call com_err_ (code, "icref", "^a>^a", path, ename);
175 go to NEXT_ARCHIVE;
176 end;
177
178
179 ename_len = index (ename, " ") -1;
180 if ename_len = -1 then ename_len = 32;
181 if ename_len <= 8 then go to UNBOUND;
182 sname = substr (ename, ename_len -1);
183
184 if substr (ename, ename_len - 7, 8) = ".archive"
185 then do;
186
187 call archive_util_$first_element (ap, acode);
188 if acode = 2 then go to AERROR;
189
190 if acode = 1
191 then do;
192 call ioa_ ("^a>^a is empty and will be ignored.", path, ename);
193 go to NEXT_ARCHIVE;
194 end;
195
196 if ap = null then go to AERROR;
197
198 archives_tested = archives_tested+1;
199 FOUND_SEGMENT:
200
201 not_an_archive = "0"b;
202
203
204 sname = ap -> header.name;
205 sname_len = index (sname, " ") - 1;
206 if sname_len = -1
207 then sname_len = 32;
208 sp = addrel (ap, 25);
209 bc = cv_dec_ (ap -> header.bitcnt);
210 bc = divide (bc, 9, 17, 0);
211
212 j = index (substr (sp -> string, 25, bc), "include");
213
214 end;
215
216
217
218
219 else do;
220 UNBOUND:
221
222 unbound_segs = unbound_segs + 1;
223 sname = ename;
224 sname_len = ename_len;
225 sp = ap;
226
227 bc = divide (acl, 9, 17, 0);
228
229
230 j = index (substr (sp -> string, 1, bc), "include");
231 not_an_archive = "1"b;
232
233 end;
234
235
236 segs_tested = segs_tested +1;
237 first_incl_sw = "1"b;
238
239
240
241 if j ^= 0 then do;
242 t3 = substr (sname, sname_len-2, 3);
243 if t3 = "pl1" | t3 = "cds" | substr (sname, sname_len-1, 2) = "rd"
244 then type = 1;
245 else if t3 = "alm" then type = 2;
246 else if t3 = "ioc" then type = 3;
247 else if substr (sname, sname_len-6, 7) = "fortran" then type = 4;
248 else if substr (sname, sname_len-3, 4) = "bcpl" then type = 5;
249 else if substr (sname, sname_len-3, 4) = "mexp" then type = 6;
250 else if substr (sname, sname_len-1, 2) = "ld" then do;
251 if not_an_archive = "1"b then unbound_segs = unbound_segs -1;
252 segs_tested = segs_tested -1;
253 first_incl_sw = "0"b;
254 go to NEXT_SEGMENT;
255 end;
256 else do;
257
258 call ioa_ ("Unknown segment suffix in ^a.", sname);
259 if not_an_archive = "1"b then unbound_segs = unbound_segs -1;
260 segs_tested = segs_tested -1;
261 first_incl_sw = "0"b;
262 go to NEXT_SEGMENT;
263 end;
264
265
266 substr (ptr (isegp, isp) -> string, 1, sname_len) = sname;
267 name_offset = isp;
268 isp = isp + divide (sname_len+3, 4, 17, 0);
269 nsegs = nsegs+1;
270 nchars = nchars+bc;
271
272 strx = 1;
273
274
275
276
277
278
279
280 INC_LOOP:
281 j = index (substr (string, strx, bc-strx+1), "include");
282 if j = 0 then go to NEXT_SEGMENT;
283 strx = strx + j + 6;
284 c1 = substr (string, strx, 1);
285 if c1 ^= " " then if c1 ^= " " then go to INC_LOOP;
286 if strx < 10 then go to OK;
287 c1 = sp -> ch.a (strx-10);
288 c2 = sp -> ch.a (strx-9);
289 if (type = 2) | (type = 3) then do;
290 if (c2 = nl) | (c2 = "%") then go to OK;
291 if c1 = nl then if c2 = " " then go to OK;
292 go to CHECK2;
293 end;
294 else if type = 6 then do;
295 if c2 = "&" then goto OK;
296 if c1 = "&" then if c2 = " " | c2 = " " then goto OK;
297 goto INC_LOOP;
298 end;
299 else do;
300 if (c2 = "%") then go to OK;
301 CHECK2: if c1 = "%" then if (c2 = " ") | (c2 = " ") then go to OK;
302 go to INC_LOOP;
303 end;
304
305 OK:
306
307
308 if strx < 13 then go to REALLY_OK;
309
310 do j = 1 to 120;
311 c1 = sp -> ch.a (strx- (9 +j));
312 c2 = sp -> ch.a (strx- (10 +j));
313 c3 = sp -> ch.a (strx- (11+j));
314 c4 = sp -> ch.a (strx- (12+j));
315 if (c1 = nl) then go to REALLY_OK;
316 if c1 = "*" then if c2 = "/" then go to INC_LOOP;
317 if c2 = "/" then if c1 = "*" then go to INC_LOOP;
318
319 if (c1 = quote_sign) then go to INC_LOOP;
320 end;
321
322 REALLY_OK:
323
324
325 do j = 1 to 20 while (sp -> ch.a (strx+j-2) = " " | sp -> ch.a (strx+j-2) = " ");
326 end;
327 strx = strx+j-1;
328 do i = 1 to 24;
329 c = substr (string, strx+i-1, 1);
330 if c = " " then go to STOP;
331 if c = " " then go to STOP;
332 if c = ";" then go to STOP;
333 if c = nl then go to STOP;
334 end;
335 go to INC_LOOP;
336 STOP:
337
338
339
340 if first_incl_sw = "1"b then do;
341 first_incl_sw = "0"b;
342 segs_with_includes = segs_with_includes +1;
343 end;
344
345 iname_len = i-1;
346 iname = substr (string, strx, iname_len);
347
348
349
350 if substr (iname, 1, 1) = quote_sign then do;
351 iname = substr (iname, 2);
352 iname_len = iname_len -1;
353 end;
354
355 i = index (iname, """");
356 if i ^= 0 then do;
357 iname = substr (iname, 1, iname_len -1);
358 iname_len = iname_len -1;
359 end;
360
361
362
363
364
365 inp = fixed (unspec (substr (iname, 1, 1)), 9);
366
367 do while (ht (inp) ^= 0);
368 inp1 = ht (inp);
369 j = 2;
370 tp = addr (ht (inp1+4));
371 do k = 2 to ht (inp1+2);
372 if j >= iname_len+1 then go to INSERT;
373 if substr (iname, j, 1) > tp -> ch.a (k-1) then go to NEXTN;
374 if substr (iname, j, 1) < tp -> ch.a (k-1) then go to INSERT;
375 j = j + 1;
376 end;
377 if j = iname_len+1 then if type = ht (inp1+1) then go to EQ; else go to NEXTN;
378
379 NEXTN: inp = inp1;
380 end;
381
382 INSERT:
383 number_of_includes = number_of_includes +1;
384 ht (isp) = ht (inp);
385 ht (isp+1) = type;
386 ht (isp+2) = iname_len;
387 ht (isp+3) = 0;
388 ht (inp) = isp;
389 substr (addr (ht (isp+4)) -> string, 1, iname_len) = iname;
390 isp = isp+4+divide (iname_len+3, 4, 17, 0);
391
392 EQ:
393 inp = ht (inp) + 3;
394 do while (ht (inp) ^= 0);
395 inp = ht (inp);
396 end;
397 ht (isp) = 0;
398 ht (isp+1) = name_offset;
399 ht (isp+2) = sname_len;
400 ht (inp) = isp;
401 isp = isp + 3;
402 if isp > maxisp then do;
403 call ioa_ ("OUT OF FREE STORAGE CELLS^");
404 go to PRINT;
405 end;
406 go to INC_LOOP;
407 end;
408
409 NEXT_SEGMENT:
410 if type = 6 then do;
411 type = 2;
412 strx = 1;
413 goto INC_LOOP;
414 end;
415
416
417 if not_an_archive = "1"b then do;
418 not_an_archive = "0"b;
419 end;
420
421
422 else do;
423 call archive_util_$next_element (ap, acode);
424 if acode = 2 then go to AERROR;
425 if ap ^= null then go to FOUND_SEGMENT;
426 end;
427 NEXT_ARCHIVE:
428 call hcs_$terminate_noname (ap, code);
429 end;
430
431
432
433
434
435 if eptr ^= null then free eptr -> entries;
436 if nptr ^= null then free nptr -> enamea;
437 go to PATH_LOOP;
438
439 AERROR: call ioa_ ("Archive format error in ^a>^a.", path, ename);
440 go to NEXT_ARCHIVE;
441 ^L
442
443
444
445 PRINT:
446 j = index (outname, " ");
447 substr (outname, j) = ".icrfout";
448 call ios_$attach (stream_name, "file_", outname, "", status);
449
450 do i = 0 to 127;
451 inp = i;
452 do while (ht (inp) ^= 0);
453 inp1 = ht (inp);
454 tc = ht (inp1+2);
455 tp = addr (ht (inp1+4));
456
457 call ioa_$ioa_stream (stream_name, "^/^a.incl.^a", btarg, ctype (ht (inp1+1)));
458 j = ht (inp1+3);
459 do while (j ^= 0);
460 tp = ptr (isegp, ht (j+1));
461 tc = ht (j+2);
462 call ioa_$ioa_stream (stream_name, " ^a", btarg);
463 j = ht (j);
464 end;
465 inp = inp1;
466 end;
467 end;
468 if nsegs = 0 then call ioa_$ioa_stream (stream_name, "^/^/No segments with includes.");
469 call ioa_$ioa_stream (stream_name, "^|^5/Summary of Include File Cross Reference:^5/");
470 call ioa_$ioa_stream (stream_name, "^/^/^-^-Total number of archives tested: ^d.", archives_tested);
471 call ioa_$ioa_stream (stream_name, "^/^/^-^-Total unbound segments tested: ^d.", unbound_segs);
472 call ioa_$ioa_stream (stream_name, "^/^-^-Total number of segments tested: ^d.", segs_tested);
473 call ioa_$ioa_stream (stream_name, "^/^-^-Total number of include files: ^d.", number_of_includes);
474 call ioa_$ioa_stream (stream_name, "^/^-^-Total segments with include files: ^d.", segs_with_includes);
475
476
477
478
479 call ios_$detach (stream_name, "", "", status);
480 call hcs_$delentry_seg (isegp, code);
481 end;