|
|
1.1 root 1: /* $Header: depend.c,v 1.14 86/05/15 09:01:04 lepreau Exp $ */
2:
3: /*
4: * Author: Peter J. Nicklin
5: */
6: #include <ctype.h>
7: #include <stdio.h>
8: #include "Mkmf.h"
9: #include "dlist.h"
10: #include "hash.h"
11: #include "macro.h"
12: #include "null.h"
13: #include "path.h"
14: #include "slist.h"
15: #include "system.h"
16: #include "yesno.h"
17:
18: #define USRINCLUDE "/usr/include/"
19: #define CURINCLUDE "./"
20: #define TOLOWER(c) (isupper(c) ? tolower(c) : (c))
21: #define SKIPWHITESPACE(c, f) while ((c = getc(f))==' ' || c=='\t'); ungetc(c,f);
22:
23: /*
24: * Include file state
25: */
26: #define NOTFOUND 0 /* not found anywhere */
27: #define EXTERNAL 1 /* not found in current directory */
28: #define INTERNAL 2 /* found in current directory */
29: #define FROMRULE 3 /* derived from tranformation rule */
30:
31: /*
32: * Include files are stored in hash tables by direct chaining (See
33: * p. 134 in `The C Programming Language' by Kernighan and Ritchie).
34: * Included include files are also added to a singly-linked list
35: * attached to the hash table entry for the include file.
36: */
37: static HASH *C_INCLUDETABLE = NULL; /* C include file hash table */
38: static HASH *F_INCLUDETABLE = NULL; /* Fortran include file hash table */
39: static HASH *P_INCLUDETABLE = NULL; /* Pascal include file hash table */
40: /*
41: * Additional include directories are specified via the -I compiler
42: * command line option. These directories are stored in singly-linked lists.
43: * We also assume that the last look-up directory is "/usr/include".
44: */
45: static SLIST *C_INCDIR; /* C include directories */
46: static SLIST *F_INCDIR; /* Fortran include directories */
47: static SLIST *P_INCDIR; /* Pascal include directories */
48:
49: SLIST *EXTLIST; /* external header file name list */
50:
51: extern char *PGN; /* program name */
52:
53: /*
54: * addincdir() adds directories containing include files to the
55: * appropriate singly-linked list. The pathnames to the directories
56: * are derived from makefile macro definitions.
57: */
58: void
59: addincdir()
60: {
61: extern HASH *MDEFTABLE; /* macro definition table */
62: char *slappend(); /* append to singly-linked list */
63: HASHBLK *htb; /* hash table entry block */
64: HASHBLK *htlookup(); /* find hash table entry */
65: int cleanup(); /* remove temporary makefile and exit */
66: void getI(); /* get include directory pathnames */
67:
68: /* C files */
69: if ((htb = htlookup(MCFLAGS, MDEFTABLE)) != NULL)
70: getI(htb->h_key, htb->h_def, C_INCDIR);
71: if (slappend(USRINCLUDE, C_INCDIR) == NULL)
72: cleanup();
73:
74: /* Fortran files */
75: if ((htb = htlookup(MFFLAGS, MDEFTABLE)) != NULL)
76: getI(htb->h_key, htb->h_def, F_INCDIR);
77: if (slappend(USRINCLUDE, F_INCDIR) == NULL)
78: cleanup();
79:
80: /* Pascal files */
81: if ((htb = htlookup(MPFLAGS, MDEFTABLE)) != NULL)
82: getI(htb->h_key, htb->h_def, P_INCDIR);
83: if (slappend(USRINCLUDE, P_INCDIR) == NULL)
84: cleanup();
85: }
86:
87:
88:
89: /*
90: * findinclude() tries to find the pathname of an include file. Returns
91: * integer INTERNAL if found in the current directory, EXTERNAL if found
92: * somewhere else, FROMRULE if derived from a transformation rule,
93: * otherwise NOTFOUND. The pathname is copied into incpath.
94: */
95: #define LOCALDIR(f) (index(f, _PSC) == NULL)
96: #define INCLUDETYPE(f) ((index(f, _PSC) == NULL) ? INTERNAL : EXTERNAL)
97:
98: findinclude(incpath, incname, lastname, type)
99: char *incpath; /* pathname receiving buffer */
100: register char *incname; /* include file name */
101: char *lastname; /* file that includes incname */
102: int type; /* file type */
103: {
104: register char *pp; /* include file path pointer */
105: char *index(); /* find occurrence of character */
106: char *optpath(); /* optimize pathname */
107: char *pathcat(); /* pathname concatenation */
108: char *pathhead(); /* remove pathname tail */
109: char *strcpy(); /* string copy */
110: char *strpcpy(); /* string copy and update pointer */
111: int lookuprule(); /* look up transformation rules */
112: SLBLK *slb; /* singly-linked list block */
113: SLIST *slist; /* include directory list pointer */
114:
115: /*
116: * look in /usr/include only
117: */
118: if (*incname == '<')
119: {
120: pp = strpcpy(incpath, USRINCLUDE);
121: for (incname++; *incname != '>'; incname++, pp++)
122: *pp = *incname;
123: *pp = '\0';
124: return(FILEXIST(incpath) ? EXTERNAL : NOTFOUND);
125: }
126:
127: /*
128: * look for an absolute include file name
129: */
130: if (*incname == '/')
131: {
132: strcpy(incpath, incname);
133: return(FILEXIST(incpath) ? EXTERNAL : NOTFOUND);
134: }
135:
136: /*
137: * look in current include directory to see if the file exists,
138: * or can be generated by a transformation rule in the current
139: * working directory.
140: */
141: if (LOCALDIR(lastname))
142: {
143: if (LOCALDIR(incname))
144: {
145: if (lookuprule(incname, incpath) == YES)
146: return(FROMRULE);
147: }
148: strcpy(incpath, incname);
149: if (FILEXIST(incpath))
150: return(INCLUDETYPE(incpath));
151: }
152: else {
153: strcpy(incpath, lastname);
154: pathcat(incpath, pathhead(incpath), incname);
155: optpath(incpath);
156: if (FILEXIST(incpath))
157: return(INCLUDETYPE(incpath));
158: }
159:
160: /*
161: * search directory list
162: */
163: switch (type)
164: {
165: case INCLUDE_C:
166: slist = C_INCDIR;
167: break;
168: case INCLUDE_FORTRAN:
169: slist = F_INCDIR;
170: break;
171: case INCLUDE_PASCAL:
172: slist = P_INCDIR;
173: break;
174: }
175: for (slb = slist->head; slb != NULL; slb = slb->next)
176: {
177: pp = strpcpy(incpath, slb->key);
178: strcpy(pp, incname);
179: optpath(incpath);
180: if (FILEXIST(incpath))
181: return(INCLUDETYPE(incpath));
182: }
183: return(NOTFOUND);
184: }
185:
186:
187:
188: /*
189: * getI() appends include directories found via the -I compiler option to
190: * a singly linked list.
191: */
192: void
193: getI(mnam, mdef, slist)
194: char *mnam; /* compiler options macro name */
195: char *mdef; /* compiler options macro definition */
196: SLIST *slist; /* singly-linked list */
197: {
198: char *gettoken(); /* get next token */
199: char incpath[PATHSIZE]; /* include directory pathname buffer */
200: char *slappend(); /* append to singly-linked list */
201: char *strcat(); /* string concatenation */
202: int cleanup(); /* remove temporary makefile and exit */
203:
204: while ((mdef = gettoken(incpath, mdef)) != NULL)
205: if (incpath[0] == '-' && incpath[1] == 'I')
206: if (incpath[2] == '\0') /* -I dir option */
207: {
208: if ((mdef = gettoken(incpath, mdef)) != NULL)
209: {
210: strcat(incpath, PATHSEP);
211: if (slappend(incpath, slist) == NULL)
212: cleanup();
213: }
214: else {
215: warn2("missing include directory in %s %s",
216: mnam, "macro definition");
217: break;
218: }
219: }
220: else { /* -Idir option */
221: strcat(incpath+2, PATHSEP);
222: if (slappend(incpath+2, slist) == NULL)
223: cleanup();
224: }
225: }
226:
227:
228:
229: /*
230: * getinclude() fetchs an include file name from a line of source code.
231: * /usr/include '<' and '>' delimiters remain with the filename to
232: * distinguish it from an include file in a local directory. Returns
233: * NO if syntax error, otherwise YES.
234: */
235: getinclude(incname, curname, lineno, ifp)
236: char *curname; /* current file name */
237: char *incname; /* include file name receiving buffer */
238: int lineno; /* current line number */
239: register FILE *ifp; /* input stream */
240: {
241: register char *ip; /* include file name buffer pointer */
242: register int c; /* current character */
243:
244: SKIPWHITESPACE(c, ifp);
245: for (ip = incname; (c = getc(ifp)) != EOF; ip++)
246: {
247: *ip = c;
248: if (c == '\n' || c == '\t' || c == ' ' || c == ';' || c == ',')
249: {
250: ungetc(c, ifp);
251: break;
252: }
253: }
254: *ip = '\0';
255: if ((*incname == '<' && ip[-1] != '>') ||
256: (*incname == '\"' && ip[-1] != '\"') ||
257: (*incname == '\'' && ip[-1] != '\'') ||
258: (*incname == '(' && ip[-1] != ')'))
259: {
260: fprintf(stderr,
261: "%s: \"%s\", line %d: bad include syntax for %s\n",
262: PGN, curname, lineno, incname);
263: return(NO);
264: }
265: if (*incname == '\"' || *incname == '\'' || *incname == '(')
266: {
267: ip[-1] = '\0';
268: ip = incname + 1;
269: while (*incname++ = *ip++)
270: continue;
271: }
272: return(YES);
273: }
274:
275:
276:
277: /*
278: * inclink() stores a pointer to a hash table block (which contains
279: * include file information) somewhere. Returns a pointer to the somewhere,
280: * or calls cleanup() if out of memory.
281: */
282: INCBLK *
283: inclink(htb)
284: HASHBLK *htb; /* hash table block pointer to save */
285: {
286: char *malloc(); /* memory allocator */
287: INCBLK *iblk; /* pointer to new include chain block */
288: int cleanup(); /* remove temporary makefile and exit */
289:
290: if ((iblk = (INCBLK *) malloc(sizeof(INCBLK))) == NULL)
291: {
292: warn("out of memory");
293: cleanup();
294: }
295: iblk->i_loop = NO;
296: iblk->i_hblk = htb;
297: iblk->i_next = NULL;
298: return(iblk);
299: }
300:
301:
302:
303: /*
304: * instalinclude() adds an include file name to the appropriate include
305: * file hash table. Returns a pointer to the hash table block, or calls
306: * cleanup() if out of memory.
307: */
308: HASHBLK *
309: instalinclude(incname, incpath, type)
310: char *incname; /* name of include file */
311: char *incpath; /* path to include file */
312: int type; /* type of source file */
313: {
314: HASH *htinit(); /* initialize hash table */
315: HASHBLK *htb = NULL; /* hash table block */
316: HASHBLK *htinstall(); /* install hash table entry */
317: int cleanup(); /* remove temporary makefile and exit */
318: int ilen; /* include path length */
319: int strlen(); /* string length */
320:
321: ilen = strlen(incpath);
322: switch (type)
323: {
324: case INCLUDE_C:
325: if (C_INCLUDETABLE == NULL)
326: {
327: C_INCLUDETABLE = htinit(INCLUDETABLESIZE);
328: }
329: htb = htinstall(incname, incpath, ilen, C_INCLUDETABLE);
330: break;
331: case INCLUDE_FORTRAN:
332: if (F_INCLUDETABLE == NULL)
333: {
334: F_INCLUDETABLE = htinit(INCLUDETABLESIZE);
335: }
336: htb = htinstall(incname, incpath, ilen, F_INCLUDETABLE);
337: break;
338: case INCLUDE_PASCAL:
339: if (P_INCLUDETABLE == NULL)
340: {
341: P_INCLUDETABLE = htinit(INCLUDETABLESIZE);
342: }
343: htb = htinstall(incname, incpath, ilen, P_INCLUDETABLE);
344: break;
345: }
346: if (htb == NULL)
347: cleanup();
348: return(htb);
349: }
350:
351:
352:
353: /*
354: * lookupinclude() returns a pointer to an include hash table block
355: * corresponding to incname and type. Returns null if not found.
356: */
357: HASHBLK *
358: lookupinclude(incname, type)
359: char *incname; /* name of include file */
360: int type; /* type of source file */
361: {
362: HASH *includetable = NULL; /* include file hash table */
363: HASHBLK *htlookup(); /* find hash table entry */
364:
365: switch (type)
366: {
367: case INCLUDE_C:
368: includetable = C_INCLUDETABLE;
369: break;
370: case INCLUDE_FORTRAN:
371: includetable = F_INCLUDETABLE;
372: break;
373: case INCLUDE_PASCAL:
374: includetable = P_INCLUDETABLE;
375: break;
376: }
377: return((includetable == NULL) ? NULL : htlookup(incname, includetable));
378: }
379:
380:
381:
382: /*
383: * mkdepend() creates include file dependencies for object files and installs
384: * them to dependency list dlp. Returns a pointer to the dependency list.
385: */
386: DLIST *
387: mkdepend()
388: {
389: extern SLIST *SRCLIST; /* source file name list */
390: char *rindex(); /* find last occurrence of character */
391: char *suffix; /* suffix pointer */
392: DLBLK *dlappend(); /* append dependency list */
393: DLIST *dlinit(); /* initialize dependency list */
394: DLIST *dlist; /* dependency list */
395: INCBLK *ibp; /* pointer to chain of include files */
396: INCBLK *readC(); /* read C include-style files */
397: INCBLK *readF(); /* read Fortran include-style files */
398: INCBLK *readP(); /* read Pascal include-style files */
399: int cleanup(); /* remove temporary makefile and exit */
400: int lookuptypeofinclude(); /* look up the brand of include */
401: int slsort(); /* sort singly-linked list */
402: int strcmp(); /* string comparison */
403: int type; /* source file type */
404: SLBLK *lbp; /* list block pointer */
405: SLIST *slinit(); /* initialize singly-linked list */
406: void addincdir(); /* add to list of include directories */
407: void rmprinttag(); /* remove "already printed" tags */
408:
409: /* initialize include file look-up lists */
410: C_INCDIR = slinit();
411: F_INCDIR = slinit();
412: P_INCDIR = slinit();
413:
414: /* add additional include directories */
415: addincdir();
416:
417: /* initialize external header file name list */
418: EXTLIST = slinit();
419:
420: /* initialize dependency list */
421: dlist = dlinit();
422:
423: for (lbp = SRCLIST->head; lbp != NULL; lbp = lbp->next)
424: {
425: suffix = rindex(lbp->key, '.');
426: type = lookuptypeofinclude(++suffix);
427: switch (type)
428: {
429: case INCLUDE_C:
430: ibp = readC(lbp->key, 0, lbp->key);
431: break;
432: case INCLUDE_FORTRAN:
433: ibp = readF(lbp->key, 0, lbp->key);
434: break;
435: case INCLUDE_PASCAL:
436: ibp = readP(lbp->key, 0, lbp->key);
437: break;
438: case INCLUDE_NONE:
439: ibp = NULL;
440: break;
441: }
442: if (ibp != NULL)
443: {
444: if (dlappend(type, lbp, ibp, dlist) == NULL)
445: cleanup();
446: }
447: }
448: if (slsort(strcmp, EXTLIST) == NO)
449: cleanup();
450: return(dlist);
451: }
452:
453:
454:
455: /*
456: * notfound() prints a "can't find" filename error message.
457: */
458: void
459: notfound(curname, lineno, incname)
460: char *curname; /* current file name */
461: char *incname; /* name of include file */
462: int lineno; /* current line number */
463: {
464: if (PGN != NULL && *PGN != '\0')
465: {
466: fprintf(stderr, "%s: ", PGN);
467: }
468: if (*incname == '<')
469: {
470: fprintf(stderr, "\"%s\", line %d: can't find %s\n",
471: curname, lineno, incname);
472: }
473: else {
474: fprintf(stderr, "\"%s\", line %d: can't find \"%s\"\n",
475: curname, lineno, incname);
476: }
477: }
478:
479:
480:
481: /*
482: * readC() searches C files for included files. Returns a pointer to
483: * the chain of include files installed or found in the include file
484: * hash table, or null if no include files found.
485: */
486: INCBLK *
487: readC(lastfile, lastline, curname)
488: char *lastfile; /* parent file name */
489: int lastline; /* current line in parent file */
490: char *curname; /* current file name */
491: {
492: register char *p; /* include string pointer */
493: register FILE *ifp; /* input file stream */
494: register int c; /* current character */
495: char incname[PATHSIZE]; /* name of include file */
496: char incpath[PATHSIZE]; /* path to include file */
497: char *slappend(); /* append pathname to list */
498: FILE *fopen(); /* open file */
499: HASHBLK *ftb; /* fromrule hash table entry block */
500: HASHBLK *htb = NULL; /* hash table entry block */
501: HASHBLK *instalinclude(); /* install include name in hash table */
502: HASHBLK *lookupinclude(); /* look up include in hash table */
503: INCBLK *i_head = NULL; /* head of include chain */
504: INCBLK *i_tail = NULL; /* tail of include chain */
505: INCBLK *inclink(); /* link include file hash blocks */
506: int cleanup(); /* remove temporary makefile and exit */
507: int findinclude(); /* locate include file */
508: int getinclude(); /* get include name from input line */
509: int inctype; /* origin of include file */
510: int lineno = 1; /* current line number */
511: int strlen(); /* string length */
512: int type; /* file type */
513: void notfound(); /* print "can't find" filename msg */
514:
515: type = INCLUDE_C;
516:
517: if ((ifp = fopen(curname, "r")) == NULL)
518: {
519: if (lastline > 0)
520: fprintf(stderr, "%s: \"%s\", line %d: ", PGN,
521: lastfile, lastline);
522: else
523: fprintf(stderr, "%s: ", PGN);
524: perror(curname);
525: return(NULL);
526: }
527: while ((c = getc(ifp)) != EOF)
528: {
529: if (c != '#')
530: goto nextline;
531: SKIPWHITESPACE(c, ifp);
532: for (p = "include"; (c = getc(ifp)) == *p && *p != '\0' ; p++)
533: continue;
534: if (*p != '\0')
535: goto nextline;
536: if (getinclude(incname, curname, lineno, ifp) == NO)
537: goto nextline;
538: if ((htb = lookupinclude(incname, type)) == NULL)
539: {
540: inctype = findinclude(incpath, incname, curname, type);
541: if (inctype == INTERNAL)
542: {
543: htb = instalinclude(incname, incpath, type);
544: }
545: else if (inctype == EXTERNAL)
546: {
547: htb = instalinclude(incname, incpath, type);
548: if (slappend(incpath, EXTLIST) == NULL)
549: cleanup();
550: }
551: else if (inctype == FROMRULE)
552: {
553: htb = instalinclude(incname, incname, type);
554: ftb = instalinclude(incpath, incpath, type);
555: }
556: else {
557: notfound(curname, lineno, incname);
558: goto nextline;
559: }
560:
561: /* look for nested include files */
562: htb->h_sub = readC(curname, lineno, incpath);
563:
564: if (inctype == FROMRULE)
565: ftb->h_sub = htb->h_sub;
566: }
567: if (i_tail == NULL)
568: {
569: i_head = i_tail = inclink(htb);
570: }
571: else {
572: i_tail = i_tail->i_next = inclink(htb);
573: }
574: nextline: while (c != '\n' && c != EOF)
575: c = getc(ifp);
576: lineno++;
577: }
578: fclose(ifp);
579: return(i_head);
580: }
581:
582:
583:
584: /*
585: * readF() searches Fortran files for included files. Returns a pointer
586: * to the chain of include files installed or found in the include file
587: * hash table, or null if no include files found.
588: */
589: INCBLK *
590: readF(lastfile, lastline, curname)
591: char *lastfile; /* parent file name */
592: int lastline; /* current line in parent file */
593: char *curname; /* current file name */
594: {
595: register char *p; /* include string pointer */
596: register FILE *ifp; /* input file stream */
597: register int c; /* current character */
598: char incname[PATHSIZE]; /* name of include file */
599: char incpath[PATHSIZE]; /* path to include file */
600: char *slappend(); /* append pathname to list */
601: FILE *fopen(); /* open file */
602: HASHBLK *ftb; /* fromrule hash table entry block */
603: HASHBLK *htb = NULL; /* hash table entry block */
604: HASHBLK *instalinclude(); /* install include name in hash table */
605: HASHBLK *lookupinclude(); /* look up include in hash table */
606: INCBLK *i_head = NULL; /* head of include chain */
607: INCBLK *i_tail = NULL; /* tail of include chain */
608: INCBLK *inclink(); /* link include file hash blocks */
609: int cleanup(); /* remove temporary makefile and exit */
610: int findinclude(); /* locate include file */
611: int getinclude(); /* get include name from input line */
612: int inctype; /* origin of include file */
613: int lineno = 1; /* current line number */
614: int strlen(); /* string length */
615: int type; /* file type */
616: void notfound(); /* print "can't find" filename msg */
617:
618: type = INCLUDE_FORTRAN;
619:
620: if ((ifp = fopen(curname, "r")) == NULL)
621: {
622: if (lastline > 0)
623: fprintf(stderr, "%s: \"%s\", line %d: ", PGN,
624: lastfile, lastline);
625: else
626: fprintf(stderr, "%s: ", PGN);
627: perror(curname);
628: return(NULL);
629: }
630: while ((c = getc(ifp)) != EOF)
631: {
632: if (c == 'c' || c == 'C' || c == '*' || c == '\n')
633: goto nextline;
634: while ((c = getc(ifp)) == ' ' || c == '\t')
635: continue;
636: for (p = "include"; *p == TOLOWER(c) && *p != '\0'; p++)
637: c = getc(ifp);
638: if (*p != '\0')
639: goto nextline;
640: if (getinclude(incname, curname, lineno, ifp) == NO)
641: goto nextline;
642: if ((htb = lookupinclude(incname, type)) == NULL)
643: {
644: inctype = findinclude(incpath, incname, curname, type);
645: if (inctype == INTERNAL)
646: {
647: htb = instalinclude(incname, incpath, type);
648: }
649: else if (inctype == EXTERNAL)
650: {
651: htb = instalinclude(incname, incpath, type);
652: if (slappend(incpath, EXTLIST) == NULL)
653: cleanup();
654: }
655: else if (inctype == FROMRULE)
656: {
657: htb = instalinclude(incname, incname, type);
658: ftb = instalinclude(incpath, incpath, type);
659: }
660: else {
661: notfound(curname, lineno, incname);
662: goto nextline;
663: }
664:
665: /* look for nested include files */
666: htb->h_sub = readF(curname, lineno, incpath);
667:
668: if (inctype == FROMRULE)
669: ftb->h_sub = htb->h_sub;
670: }
671: if (i_tail == NULL)
672: {
673: i_head = i_tail = inclink(htb);
674: }
675: else {
676: i_tail = i_tail->i_next = inclink(htb);
677: }
678: nextline: while (c != '\n' && c != EOF)
679: c = getc(ifp);
680: lineno++;
681: }
682: fclose(ifp);
683: return(i_head);
684: }
685:
686:
687:
688: /*
689: * readP() searches Pascal files for included files. Returns a pointer
690: * to the chain of include files installed or found in the include file
691: * hash table, or null if no include files found.
692: */
693: INCBLK *
694: readP(lastfile, lastline, curname)
695: char *lastfile; /* parent file name */
696: int lastline; /* current line in parent file */
697: char *curname; /* current file name */
698: {
699: register char *p; /* include string pointer */
700: register FILE *ifp; /* input file stream */
701: register int c; /* current character */
702: char incname[PATHSIZE]; /* name of include file */
703: char incpath[PATHSIZE]; /* path to include file */
704: char *slappend(); /* append pathname to list */
705: FILE *fopen(); /* open file */
706: HASHBLK *ftb; /* fromrule hash table entry block */
707: HASHBLK *htb = NULL; /* hash table entry block */
708: HASHBLK *instalinclude(); /* install include name in hash table */
709: HASHBLK *lookupinclude(); /* look up include in hash table */
710: INCBLK *i_head = NULL; /* head of include chain */
711: INCBLK *i_tail = NULL; /* tail of include chain */
712: INCBLK *inclink(); /* link include file hash blocks */
713: int cleanup(); /* remove temporary makefile and exit */
714: int findinclude(); /* locate include file */
715: int getinclude(); /* get include name from input line */
716: int inctype; /* origin of include file */
717: int lineno = 1; /* current line number */
718: int strlen(); /* string length */
719: int type; /* file type */
720: void notfound(); /* print "can't find" filename msg */
721:
722: type = INCLUDE_PASCAL;
723:
724: if ((ifp = fopen(curname, "r")) == NULL)
725: {
726: if (lastline > 0)
727: fprintf(stderr, "%s: \"%s\", line %d: ", PGN,
728: lastfile, lastline);
729: else
730: fprintf(stderr, "%s: ", PGN);
731: perror(curname);
732: return(NULL);
733: }
734: while ((c = getc(ifp)) != EOF)
735: {
736: if (c != '#')
737: goto nextline;
738: while ((c = getc(ifp)) == ' ' || c == '\t')
739: continue;
740: for (p = "include"; *p == TOLOWER(c) && *p != '\0'; p++)
741: c = getc(ifp);
742: if (*p != '\0')
743: goto nextline;
744: if (getinclude(incname, curname, lineno, ifp) == NO)
745: goto nextline;
746: if ((htb = lookupinclude(incname, type)) == NULL)
747: {
748: inctype = findinclude(incpath, incname, curname, type);
749: if (inctype == INTERNAL)
750: {
751: htb = instalinclude(incname, incpath, type);
752: }
753: else if (inctype == EXTERNAL)
754: {
755: htb = instalinclude(incname, incpath, type);
756: if (slappend(incpath, EXTLIST) == NULL)
757: cleanup();
758: }
759: else if (inctype == FROMRULE)
760: {
761: htb = instalinclude(incname, incname, type);
762: ftb = instalinclude(incpath, incpath, type);
763: }
764: else {
765: notfound(curname, lineno, incname);
766: goto nextline;
767: }
768:
769: /* look for nested include files */
770: htb->h_sub = readP(curname, lineno, incpath);
771:
772: if (inctype == FROMRULE)
773: ftb->h_sub = htb->h_sub;
774: }
775: if (i_tail == NULL)
776: {
777: i_head = i_tail = inclink(htb);
778: }
779: else {
780: i_tail = i_tail->i_next = inclink(htb);
781: }
782: nextline: while (c != '\n' && c != EOF)
783: c = getc(ifp);
784: lineno++;
785: }
786: fclose(ifp);
787: return(i_head);
788: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.