1 /* $Id: ic_lib.c,v 1.7 1994/06/24 10:24:18 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
6 /* I N T E R M E D I A T E C O D E
17 #include "../share/types.h"
18 #include "../share/debug.h"
20 #include "ic_lookup.h"
22 #include "../share/global.h"
23 #include "../share/files.h"
30 /* Read a string of length n and void it */
38 STATIC skip_arguments()
40 /* Skip the arguments of a MES pseudo. The argument
41 * list is terminated by a sp_cend byte.
48 /* fall through !!! */
53 skip_string(get_off());
65 STATIC bool proc_wanted(name)
68 /* See if 'name' is the name of an external procedure
69 * that has been used before, but for which no body
70 * has been given so far.
75 if (( p = proclookup(name,IMPORTING)) != (proc_p) 0 &&
76 !(p->p_flags1 & PF_BODYSEEN)) {
85 STATIC bool data_wanted(name)
88 /* See if 'name' is the name of an externally visible
89 * data block that has been used before, but for which
90 * no defining occurrence has been given yet.
95 if ((db = symlookup(name,IMPORTING)) != (dblock_p) 0 &&
96 db->d_pseudo == DUNKNOWN) {
105 STATIC bool wanted_names()
107 /* Read the names of procedures and data labels,
108 * appearing in a 'MES ms_ext' pseudo. Those are
109 * the names of entities that are imported by
111 * If any of them is wanted, return TRUE.
112 * A name is wanted if it is the name of a procedure
113 * or data block for which applied occurrences but
114 * no defining occurrence has been met.
120 if (data_wanted(string)) {
123 /* A data entity with the name
124 * string is available.
128 if (proc_wanted(string)) {
135 error("wrong argument of MES %d", ms_ext);
142 STATIC FILE *curfile = NULL;
145 /* Determine if any entity imported by the current
146 * compact EM assembly file (which will usually be
147 * part of an archive file) is useful to us.
148 * The file must contain (before any other non-MES line)
149 * a 'MES ms_ext' pseudo that has as arguments the names
150 * of the entities imported.
154 if (table1() != PSEU || tabval != ps_mes) {
155 error("cannot find MES %d in library file",ms_ext);
157 if (table2() != CSTX1) {
158 error("message number expected");
160 if (tabval == ms_ext) {
161 /* This is the one we searched */
162 return wanted_names();
163 /* Read the names of the imported entities
164 * and check if any of them is wanted.
167 skip_arguments(); /* skip remainder of this MES */
174 STATIC bool is_archive(name)
177 /* See if 'name' is the name of an archive file, i.e. it
178 * should end on ".ma" and should at least be four characters
179 * long (i.e. the name ".ma" is not accepted as an archive name!).
184 for (p = name; *p; p++);
185 return (p > name+3) && (*--p == 'a') && (*--p == 'm') && (*--p == '.');
190 STATIC struct ar_hdr hdr;
192 STATIC bool read_hdr()
194 /* Read the header of an archive module */
197 register char *c = buf;
198 register char *p = hdr.ar_name;
201 fread(c, AR_TOTAL, 1, curfile);
202 if (feof(curfile)) return 0;
208 #define get2(c) (((c)[0]&0377) | ((unsigned) ((c)[1]&0377) << 8))
210 hdr.ar_date = ((long) get2(c)) << 16; c += 2;
211 hdr.ar_date |= ((long) get2(c)) & 0xffff; c += 2;
214 hdr.ar_mode = get2(c); c += 2;
215 hdr.ar_size = (long) get2(c) << 16; c += 2;
216 hdr.ar_size |= (long) get2(c) & 0xffff;
223 STATIC int argcnt = ARGSTART - 1;
224 STATIC short arstate = NO_ARCHIVE;
227 FILE *next_file(argc,argv)
231 /* See if there are more EM input files. The file names
232 * are given via argv. If a file is an archive file
233 * it is supposed to be a library of EM compact assembly
234 * files. A module (file) contained in this archive file
235 * is only used if it imports at least one procedure or
236 * datalabel for which we have not yet seen a defining
237 * occurrence, although we have seen a used occurrence.
243 /* This loop is only exited via a return */
244 if (arstate == ARCHIVE) {
245 /* We were reading an archive file */
246 if (ftell(curfile) & 1) {
247 /* modules in an archive file always
248 * begin on a word boundary, i.e. at
253 if (read_hdr()) { /* read header of next module */
254 ptr = ftell(curfile); /* file position */
255 file_init(curfile,ARCHIVE,hdr.ar_size);
256 /* tell i/o package that we're reading
257 * an archive module of given length.
260 /* re-initialize file, because 'useful'
261 * has read some bytes too.
263 fseek(curfile,ptr,0); /* start module */
264 file_init(curfile,ARCHIVE,hdr.ar_size);
267 /* skip this module */
272 /* done with this archive */
273 arstate = NO_ARCHIVE;
276 /* open next file, close old */
277 if (curfile != NULL) {
281 if (argcnt >= argc) {
282 /* done with all arguments */
285 filename = argv[argcnt];
286 if ((curfile = fopen(filename,"r")) == NULL) {
287 error("cannot open %s",filename);
289 if (is_archive(filename)) {
292 arch_init(curfile); /* read magic ar number */
294 file_init(curfile,NO_ARCHIVE,0L);