1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman * *
3*b30d1939SAndy Fiddaman * This software is part of the ast package *
4*b30d1939SAndy Fiddaman * Copyright (c) 1986-2012 AT&T Intellectual Property *
5*b30d1939SAndy Fiddaman * and is licensed under the *
6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 *
7*b30d1939SAndy Fiddaman * by AT&T Intellectual Property *
8*b30d1939SAndy Fiddaman * *
9*b30d1939SAndy Fiddaman * A copy of the License is available at *
10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html *
11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12*b30d1939SAndy Fiddaman * *
13*b30d1939SAndy Fiddaman * Information and Software Systems Research *
14*b30d1939SAndy Fiddaman * AT&T Research *
15*b30d1939SAndy Fiddaman * Florham Park NJ *
16*b30d1939SAndy Fiddaman * *
17*b30d1939SAndy Fiddaman * Glenn Fowler <gsf@research.att.com> *
18*b30d1939SAndy Fiddaman * *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman /*
22*b30d1939SAndy Fiddaman * Glenn Fowler
23*b30d1939SAndy Fiddaman * AT&T Research
24*b30d1939SAndy Fiddaman *
25*b30d1939SAndy Fiddaman * include file search support
26*b30d1939SAndy Fiddaman */
27*b30d1939SAndy Fiddaman
28*b30d1939SAndy Fiddaman #include "pplib.h"
29*b30d1939SAndy Fiddaman
30*b30d1939SAndy Fiddaman #define SEARCH_NEXT (SEARCH_USER<<1)/* search for next (uncover) */
31*b30d1939SAndy Fiddaman #define SEARCH_SKIP (SEARCH_USER<<2)/* current binding skipped */
32*b30d1939SAndy Fiddaman #define SEARCH_TEST (SEARCH_USER<<3)/* test for binding */
33*b30d1939SAndy Fiddaman #define SEARCH_FOUND (SEARCH_USER<<4)/* current binding found */
34*b30d1939SAndy Fiddaman
35*b30d1939SAndy Fiddaman #define COLUMN_TAB 7
36*b30d1939SAndy Fiddaman #define COLUMN_MAX 72
37*b30d1939SAndy Fiddaman
38*b30d1939SAndy Fiddaman #if ARCHIVE
39*b30d1939SAndy Fiddaman
40*b30d1939SAndy Fiddaman #include <vdb.h>
41*b30d1939SAndy Fiddaman #include <ls.h>
42*b30d1939SAndy Fiddaman
43*b30d1939SAndy Fiddaman #endif
44*b30d1939SAndy Fiddaman
45*b30d1939SAndy Fiddaman /*
46*b30d1939SAndy Fiddaman * multiple include test
47*b30d1939SAndy Fiddaman * fp is a canonicalized ppfile pointer
48*b30d1939SAndy Fiddaman *
49*b30d1939SAndy Fiddaman * test
50*b30d1939SAndy Fiddaman *
51*b30d1939SAndy Fiddaman * INC_CLEAR can be included again
52*b30d1939SAndy Fiddaman * INC_TEST test if include required
53*b30d1939SAndy Fiddaman * <symbol> ifndef guard symbol
54*b30d1939SAndy Fiddaman *
55*b30d1939SAndy Fiddaman * test!=INC_CLEAR returns 1 if file can be included again
56*b30d1939SAndy Fiddaman *
57*b30d1939SAndy Fiddaman * NOTE:
58*b30d1939SAndy Fiddaman *
59*b30d1939SAndy Fiddaman * (1) different hard links to the same file are treated as
60*b30d1939SAndy Fiddaman * different files
61*b30d1939SAndy Fiddaman *
62*b30d1939SAndy Fiddaman * (2) symbolic links in combination with .. may cause two
63*b30d1939SAndy Fiddaman * different files to be treated as the same file:
64*b30d1939SAndy Fiddaman *
65*b30d1939SAndy Fiddaman * "../h/<file>" == "/usr/include/sys/../h/<file>" -> "/usr/include/h/<file>"
66*b30d1939SAndy Fiddaman * "h/<file>" -> "/usr/include/h/<file>"
67*b30d1939SAndy Fiddaman */
68*b30d1939SAndy Fiddaman
69*b30d1939SAndy Fiddaman int
ppmultiple(register struct ppfile * fp,register struct ppsymbol * test)70*b30d1939SAndy Fiddaman ppmultiple(register struct ppfile* fp, register struct ppsymbol* test)
71*b30d1939SAndy Fiddaman {
72*b30d1939SAndy Fiddaman register struct ppsymbol* status;
73*b30d1939SAndy Fiddaman
74*b30d1939SAndy Fiddaman status = fp->guard;
75*b30d1939SAndy Fiddaman message((-3, "search: %s: status=%s%s test=%s", fp->name, status == INC_CLEAR ? "[CLEAR]" : status == INC_TEST ? "[ONCE]" : status == INC_IGNORE ? "[IGNORE]" : status->name, (pp.mode & HOSTED) ? "[HOSTED]" : "", test == INC_CLEAR ? "[CLEAR]" : test == INC_TEST ? "[TEST]" : test->name));
76*b30d1939SAndy Fiddaman if (status == INC_IGNORE)
77*b30d1939SAndy Fiddaman {
78*b30d1939SAndy Fiddaman message((-2, "%s: ignored [%s]", fp->name, pp.ignore));
79*b30d1939SAndy Fiddaman return 0;
80*b30d1939SAndy Fiddaman }
81*b30d1939SAndy Fiddaman if (test == INC_TEST)
82*b30d1939SAndy Fiddaman {
83*b30d1939SAndy Fiddaman if (status != INC_CLEAR)
84*b30d1939SAndy Fiddaman {
85*b30d1939SAndy Fiddaman if (status == INC_TEST || status->macro)
86*b30d1939SAndy Fiddaman {
87*b30d1939SAndy Fiddaman if ((pp.mode & (ALLMULTIPLE|LOADING)) == LOADING)
88*b30d1939SAndy Fiddaman fp->guard = INC_IGNORE;
89*b30d1939SAndy Fiddaman if ((pp.state & WARN) && (pp.mode & (HOSTED|MARKHOSTED|RELAX|PEDANTIC)) == PEDANTIC)
90*b30d1939SAndy Fiddaman error(1, "%s: ignored -- already included", fp->name);
91*b30d1939SAndy Fiddaman else
92*b30d1939SAndy Fiddaman message((-3, "%s: ignored -- already included", fp->name));
93*b30d1939SAndy Fiddaman return 0;
94*b30d1939SAndy Fiddaman }
95*b30d1939SAndy Fiddaman return 1;
96*b30d1939SAndy Fiddaman }
97*b30d1939SAndy Fiddaman if ((pp.mode & (ALLMULTIPLE|LOADING)) == LOADING)
98*b30d1939SAndy Fiddaman test = INC_IGNORE;
99*b30d1939SAndy Fiddaman else
100*b30d1939SAndy Fiddaman return 1;
101*b30d1939SAndy Fiddaman }
102*b30d1939SAndy Fiddaman fp->guard = test;
103*b30d1939SAndy Fiddaman return 1;
104*b30d1939SAndy Fiddaman }
105*b30d1939SAndy Fiddaman
106*b30d1939SAndy Fiddaman /*
107*b30d1939SAndy Fiddaman * search for file using directories in dp
108*b30d1939SAndy Fiddaman */
109*b30d1939SAndy Fiddaman
110*b30d1939SAndy Fiddaman static int
search(register struct ppfile * fp,register struct ppdirs * dp,int type,int flags)111*b30d1939SAndy Fiddaman search(register struct ppfile* fp, register struct ppdirs* dp, int type, int flags)
112*b30d1939SAndy Fiddaman {
113*b30d1939SAndy Fiddaman register char* prefix;
114*b30d1939SAndy Fiddaman register struct ppdirs* up;
115*b30d1939SAndy Fiddaman register struct ppfile* xp;
116*b30d1939SAndy Fiddaman struct ppfile* mp;
117*b30d1939SAndy Fiddaman int fd;
118*b30d1939SAndy Fiddaman int index;
119*b30d1939SAndy Fiddaman int need;
120*b30d1939SAndy Fiddaman int markhosted;
121*b30d1939SAndy Fiddaman char* t;
122*b30d1939SAndy Fiddaman
123*b30d1939SAndy Fiddaman if (!(pp.option & PREFIX))
124*b30d1939SAndy Fiddaman prefix = 0;
125*b30d1939SAndy Fiddaman else if ((prefix = strrchr(fp->name, '/')) && prefix > fp->name)
126*b30d1939SAndy Fiddaman {
127*b30d1939SAndy Fiddaman *prefix = 0;
128*b30d1939SAndy Fiddaman t = ppsetfile(fp->name)->name;
129*b30d1939SAndy Fiddaman *prefix = '/';
130*b30d1939SAndy Fiddaman prefix = t;
131*b30d1939SAndy Fiddaman }
132*b30d1939SAndy Fiddaman message((-3, "search: %s %s%s%s%s%s%s type=%s prefix=%s flags=|%s%s%s%s%s%s start=%s=\"%s\" pre=%s lcl=%s vnd=%s std=%s cur=%s",
133*b30d1939SAndy Fiddaman fp->name,
134*b30d1939SAndy Fiddaman (flags & SEARCH_INCLUDE) ? "include" : "exists",
135*b30d1939SAndy Fiddaman (flags & SEARCH_VENDOR) ? " vendor" : "",
136*b30d1939SAndy Fiddaman (flags & SEARCH_HOSTED) ? " hosted" : "",
137*b30d1939SAndy Fiddaman (flags & SEARCH_NEXT) ? " next" : "",
138*b30d1939SAndy Fiddaman (flags & SEARCH_SKIP) ? " skip" : "",
139*b30d1939SAndy Fiddaman (flags & SEARCH_TEST) ? " test" : "",
140*b30d1939SAndy Fiddaman type == T_HEADER ? "<*>" : "\"*\"", prefix,
141*b30d1939SAndy Fiddaman (fp->flags & INC_SELF) ? "SELF|" : "",
142*b30d1939SAndy Fiddaman (fp->flags & INC_EXISTS) ? "EXISTS|" : "",
143*b30d1939SAndy Fiddaman (fp->flags & INC_BOUND(INC_PREFIX)) ? "PREFIX|" : "",
144*b30d1939SAndy Fiddaman (fp->flags & INC_BOUND(INC_LOCAL)) ? "LOCAL|" : "",
145*b30d1939SAndy Fiddaman (fp->flags & INC_BOUND(INC_VENDOR)) ? "VENDOR|" : "",
146*b30d1939SAndy Fiddaman (fp->flags & INC_BOUND(INC_STANDARD)) ? "STANDARD|" : "",
147*b30d1939SAndy Fiddaman dp ? (dp->index == INC_PREFIX ? "pre" : dp->index == INC_LOCAL ? "lcl" : dp->index == INC_VENDOR ? "vnd" : "std") : NiL,
148*b30d1939SAndy Fiddaman dp ? dp->name : NiL,
149*b30d1939SAndy Fiddaman !(fp->flags & INC_MEMBER(INC_PREFIX)) && fp->bound[INC_PREFIX] ? fp->bound[INC_PREFIX]->name : NiL,
150*b30d1939SAndy Fiddaman !(fp->flags & INC_MEMBER(INC_LOCAL)) && fp->bound[INC_LOCAL] ? fp->bound[INC_LOCAL]->name : NiL,
151*b30d1939SAndy Fiddaman !(fp->flags & INC_MEMBER(INC_VENDOR)) && fp->bound[INC_VENDOR] ? fp->bound[INC_VENDOR]->name : NiL,
152*b30d1939SAndy Fiddaman !(fp->flags & INC_MEMBER(INC_STANDARD)) && (xp = fp->bound[INC_STANDARD]) ? xp->name : NiL,
153*b30d1939SAndy Fiddaman error_info.file
154*b30d1939SAndy Fiddaman ));
155*b30d1939SAndy Fiddaman if (flags & SEARCH_HOSTED)
156*b30d1939SAndy Fiddaman need = TYPE_HOSTED;
157*b30d1939SAndy Fiddaman else if (flags & SEARCH_VENDOR)
158*b30d1939SAndy Fiddaman need = TYPE_VENDOR;
159*b30d1939SAndy Fiddaman else
160*b30d1939SAndy Fiddaman need = TYPE_INCLUDE;
161*b30d1939SAndy Fiddaman for (index = -1; dp; dp = dp->next)
162*b30d1939SAndy Fiddaman if (dp->type & need)
163*b30d1939SAndy Fiddaman {
164*b30d1939SAndy Fiddaman message((-3, "search: fp=%s need=%02x index=%d dp=%s type=%02x index=%d", fp->name, need, index, dp->name, dp->type, dp->index));
165*b30d1939SAndy Fiddaman #if ARCHIVE
166*b30d1939SAndy Fiddaman if (!(dp->type & (TYPE_ARCHIVE|TYPE_DIRECTORY)))
167*b30d1939SAndy Fiddaman {
168*b30d1939SAndy Fiddaman struct stat st;
169*b30d1939SAndy Fiddaman
170*b30d1939SAndy Fiddaman if (stat(dp->name, &st))
171*b30d1939SAndy Fiddaman {
172*b30d1939SAndy Fiddaman message((-3, "search: omit %s", dp->name));
173*b30d1939SAndy Fiddaman dp->type = 0;
174*b30d1939SAndy Fiddaman continue;
175*b30d1939SAndy Fiddaman }
176*b30d1939SAndy Fiddaman if (S_ISREG(st.st_mode))
177*b30d1939SAndy Fiddaman {
178*b30d1939SAndy Fiddaman register char* s;
179*b30d1939SAndy Fiddaman char* e;
180*b30d1939SAndy Fiddaman int delimiter;
181*b30d1939SAndy Fiddaman int variant;
182*b30d1939SAndy Fiddaman unsigned long siz;
183*b30d1939SAndy Fiddaman unsigned long off;
184*b30d1939SAndy Fiddaman struct ppmember* ap;
185*b30d1939SAndy Fiddaman Sfio_t* sp;
186*b30d1939SAndy Fiddaman
187*b30d1939SAndy Fiddaman /*
188*b30d1939SAndy Fiddaman * check for vdb header archive
189*b30d1939SAndy Fiddaman */
190*b30d1939SAndy Fiddaman
191*b30d1939SAndy Fiddaman if (!(sp = sfopen(NiL, dp->name, "r")))
192*b30d1939SAndy Fiddaman {
193*b30d1939SAndy Fiddaman error(ERROR_SYSTEM|1, "%s: ignored -- cannot open", dp->name);
194*b30d1939SAndy Fiddaman dp->type = 0;
195*b30d1939SAndy Fiddaman continue;
196*b30d1939SAndy Fiddaman }
197*b30d1939SAndy Fiddaman variant = sfsprintf(pp.tmpbuf, MAXTOKEN, "%c%s%c%s:archive", VDB_DELIMITER, VDB_MAGIC, VDB_DELIMITER, pp.pass);
198*b30d1939SAndy Fiddaman if (!(s = sfgetr(sp, '\n', 1)) || !strneq(s, pp.tmpbuf, variant))
199*b30d1939SAndy Fiddaman {
200*b30d1939SAndy Fiddaman sfclose(sp);
201*b30d1939SAndy Fiddaman error(1, "%s: ignored -- not a directory or archive", dp->name);
202*b30d1939SAndy Fiddaman dp->type = 0;
203*b30d1939SAndy Fiddaman continue;
204*b30d1939SAndy Fiddaman }
205*b30d1939SAndy Fiddaman
206*b30d1939SAndy Fiddaman /*
207*b30d1939SAndy Fiddaman * parse the options
208*b30d1939SAndy Fiddaman */
209*b30d1939SAndy Fiddaman
210*b30d1939SAndy Fiddaman dp->type |= TYPE_ARCHIVE;
211*b30d1939SAndy Fiddaman for (s += variant;;)
212*b30d1939SAndy Fiddaman {
213*b30d1939SAndy Fiddaman while (*s == ' ') s++;
214*b30d1939SAndy Fiddaman e = s;
215*b30d1939SAndy Fiddaman for (t = 0; *s && *s != ' '; s++)
216*b30d1939SAndy Fiddaman if (*s == '=')
217*b30d1939SAndy Fiddaman {
218*b30d1939SAndy Fiddaman *s = 0;
219*b30d1939SAndy Fiddaman t = s + 1;
220*b30d1939SAndy Fiddaman }
221*b30d1939SAndy Fiddaman if (*s)
222*b30d1939SAndy Fiddaman *s++ = 0;
223*b30d1939SAndy Fiddaman if (!*e)
224*b30d1939SAndy Fiddaman break;
225*b30d1939SAndy Fiddaman switch ((int)hashref(pp.strtab, e))
226*b30d1939SAndy Fiddaman {
227*b30d1939SAndy Fiddaman case X_CHECKPOINT:
228*b30d1939SAndy Fiddaman #if CHECKPOINT
229*b30d1939SAndy Fiddaman dp->type |= TYPE_CHECKPOINT;
230*b30d1939SAndy Fiddaman break;
231*b30d1939SAndy Fiddaman #else
232*b30d1939SAndy Fiddaman error(1, "preprocessor not compiled with checkpoint enabled");
233*b30d1939SAndy Fiddaman goto notvdb;
234*b30d1939SAndy Fiddaman #endif
235*b30d1939SAndy Fiddaman case X_HIDE:
236*b30d1939SAndy Fiddaman
237*b30d1939SAndy Fiddaman if (t)
238*b30d1939SAndy Fiddaman error(1, "%s: %s: archive option value ignored", e);
239*b30d1939SAndy Fiddaman if (e = strrchr(dp->name, '/'))
240*b30d1939SAndy Fiddaman *e = 0;
241*b30d1939SAndy Fiddaman else
242*b30d1939SAndy Fiddaman dp->name = ".";
243*b30d1939SAndy Fiddaman break;
244*b30d1939SAndy Fiddaman case X_MAP:
245*b30d1939SAndy Fiddaman if (!t)
246*b30d1939SAndy Fiddaman error(1, "%s: archive option value expected", e);
247*b30d1939SAndy Fiddaman else
248*b30d1939SAndy Fiddaman dp->name = strdup(t);
249*b30d1939SAndy Fiddaman break;
250*b30d1939SAndy Fiddaman default:
251*b30d1939SAndy Fiddaman error(1, "%s: unknown archive option", e);
252*b30d1939SAndy Fiddaman break;
253*b30d1939SAndy Fiddaman }
254*b30d1939SAndy Fiddaman }
255*b30d1939SAndy Fiddaman if (sfseek(sp, -(VDB_LENGTH + 1), SEEK_END) <= 0 || !(s = sfgetr(sp, '\n', 1)))
256*b30d1939SAndy Fiddaman {
257*b30d1939SAndy Fiddaman notvdb:
258*b30d1939SAndy Fiddaman sfclose(sp);
259*b30d1939SAndy Fiddaman error(1, "%s: ignored -- cannot load archive", dp->name);
260*b30d1939SAndy Fiddaman dp->type = 0;
261*b30d1939SAndy Fiddaman continue;
262*b30d1939SAndy Fiddaman }
263*b30d1939SAndy Fiddaman if (variant = *s != 0)
264*b30d1939SAndy Fiddaman s++;
265*b30d1939SAndy Fiddaman else if (!(s = sfgetr(sp, '\n', 1)))
266*b30d1939SAndy Fiddaman goto notvdb;
267*b30d1939SAndy Fiddaman if (sfvalue(sp) != (VDB_LENGTH + variant))
268*b30d1939SAndy Fiddaman goto notvdb;
269*b30d1939SAndy Fiddaman if (!strneq(s, VDB_DIRECTORY, sizeof(VDB_DIRECTORY) - 1))
270*b30d1939SAndy Fiddaman goto notvdb;
271*b30d1939SAndy Fiddaman delimiter = s[VDB_OFFSET - 1];
272*b30d1939SAndy Fiddaman off = strtol(s + VDB_OFFSET, NiL, 10) - sizeof(VDB_DIRECTORY);
273*b30d1939SAndy Fiddaman siz = strtol(s + VDB_SIZE, NiL, 10);
274*b30d1939SAndy Fiddaman if (sfseek(sp, off, SEEK_SET) != off)
275*b30d1939SAndy Fiddaman goto notvdb;
276*b30d1939SAndy Fiddaman if (!(s = sfreserve(sp, siz + 1, 0)))
277*b30d1939SAndy Fiddaman goto notvdb;
278*b30d1939SAndy Fiddaman s[siz] = 0;
279*b30d1939SAndy Fiddaman if (!strneq(s, VDB_DIRECTORY, sizeof(VDB_DIRECTORY)) - 1)
280*b30d1939SAndy Fiddaman goto notvdb;
281*b30d1939SAndy Fiddaman if (!(s = strchr(s, '\n')))
282*b30d1939SAndy Fiddaman goto notvdb;
283*b30d1939SAndy Fiddaman s++;
284*b30d1939SAndy Fiddaman while (e = strchr(s, '\n'))
285*b30d1939SAndy Fiddaman {
286*b30d1939SAndy Fiddaman delimiter = variant ? *s++ : delimiter;
287*b30d1939SAndy Fiddaman if (!(t = strchr(s, delimiter)))
288*b30d1939SAndy Fiddaman break;
289*b30d1939SAndy Fiddaman *t = 0;
290*b30d1939SAndy Fiddaman if (!streq(s, VDB_DIRECTORY))
291*b30d1939SAndy Fiddaman {
292*b30d1939SAndy Fiddaman pathcanon(s, 0, 0);
293*b30d1939SAndy Fiddaman ap = newof(0, struct ppmember, 1, 0);
294*b30d1939SAndy Fiddaman ap->archive = dp;
295*b30d1939SAndy Fiddaman ap->offset = strtol(t + 1, &t, 10);
296*b30d1939SAndy Fiddaman ap->size = strtol(t + 1, NiL, 10);
297*b30d1939SAndy Fiddaman xp = ppsetfile(s);
298*b30d1939SAndy Fiddaman xp->flags |= INC_MEMBER(dp->index);
299*b30d1939SAndy Fiddaman xp->bound[dp->index] = (struct ppfile*)ap;
300*b30d1939SAndy Fiddaman if (pp.test & 0x0020) error(1, "VDB#%d %s %s index=%d data=<%lu,%lu>", __LINE__, dp->name, xp->name, index, ap->offset, ap->size);
301*b30d1939SAndy Fiddaman }
302*b30d1939SAndy Fiddaman s = e + 1;
303*b30d1939SAndy Fiddaman }
304*b30d1939SAndy Fiddaman if (sfseek(sp, 0L, SEEK_SET))
305*b30d1939SAndy Fiddaman goto notvdb;
306*b30d1939SAndy Fiddaman if (!(pp.test & 0x4000) &&
307*b30d1939SAndy Fiddaman #if POOL
308*b30d1939SAndy Fiddaman (pp.pool.input || !(dp->type & TYPE_CHECKPOINT))
309*b30d1939SAndy Fiddaman #else
310*b30d1939SAndy Fiddaman !(dp->type & TYPE_CHECKPOINT)
311*b30d1939SAndy Fiddaman #endif
312*b30d1939SAndy Fiddaman && (dp->info.buffer = sfreserve(sp, off, 0)))
313*b30d1939SAndy Fiddaman dp->type |= TYPE_BUFFER;
314*b30d1939SAndy Fiddaman else
315*b30d1939SAndy Fiddaman {
316*b30d1939SAndy Fiddaman dp->info.sp = sp;
317*b30d1939SAndy Fiddaman #if POOL
318*b30d1939SAndy Fiddaman if (pp.pool.input)
319*b30d1939SAndy Fiddaman sfset(sp, SF_SHARE, 1);
320*b30d1939SAndy Fiddaman #endif
321*b30d1939SAndy Fiddaman }
322*b30d1939SAndy Fiddaman }
323*b30d1939SAndy Fiddaman else
324*b30d1939SAndy Fiddaman dp->type |= TYPE_DIRECTORY;
325*b30d1939SAndy Fiddaman }
326*b30d1939SAndy Fiddaman #endif
327*b30d1939SAndy Fiddaman if (streq(fp->name, "."))
328*b30d1939SAndy Fiddaman continue;
329*b30d1939SAndy Fiddaman if (prefix && *fp->name != '/' && dp->index != INC_PREFIX)
330*b30d1939SAndy Fiddaman #if ARCHIVE
331*b30d1939SAndy Fiddaman if (dp->type & TYPE_DIRECTORY)
332*b30d1939SAndy Fiddaman #endif
333*b30d1939SAndy Fiddaman {
334*b30d1939SAndy Fiddaman for (up = dp->info.subdir; up; up = up->next)
335*b30d1939SAndy Fiddaman if (up->name == prefix)
336*b30d1939SAndy Fiddaman break;
337*b30d1939SAndy Fiddaman if (!up)
338*b30d1939SAndy Fiddaman {
339*b30d1939SAndy Fiddaman up = newof(0, struct ppdirs, 1, 0);
340*b30d1939SAndy Fiddaman up->name = prefix;
341*b30d1939SAndy Fiddaman up->type = dp->type;
342*b30d1939SAndy Fiddaman up->next = dp->info.subdir;
343*b30d1939SAndy Fiddaman dp->info.subdir = up;
344*b30d1939SAndy Fiddaman if (!*dp->name)
345*b30d1939SAndy Fiddaman t = prefix;
346*b30d1939SAndy Fiddaman else
347*b30d1939SAndy Fiddaman sfsprintf(t = pp.path, PATH_MAX - 1, "%s/%s", dp->name, prefix);
348*b30d1939SAndy Fiddaman if (eaccess(t, X_OK))
349*b30d1939SAndy Fiddaman {
350*b30d1939SAndy Fiddaman message((-3, "search: omit %s", t));
351*b30d1939SAndy Fiddaman continue;
352*b30d1939SAndy Fiddaman }
353*b30d1939SAndy Fiddaman up->type |= TYPE_HOSTED;
354*b30d1939SAndy Fiddaman }
355*b30d1939SAndy Fiddaman else if (!(up->type & TYPE_HOSTED))
356*b30d1939SAndy Fiddaman continue;
357*b30d1939SAndy Fiddaman }
358*b30d1939SAndy Fiddaman mp = xp = 0;
359*b30d1939SAndy Fiddaman if (!(flags & SEARCH_NEXT) && index != dp->index && (!(need & TYPE_HOSTED) || dp->index == INC_STANDARD) && (!(need & TYPE_VENDOR) || dp->index == INC_VENDOR))
360*b30d1939SAndy Fiddaman {
361*b30d1939SAndy Fiddaman if (index >= 0 && !(fp->flags & INC_MEMBER(index)))
362*b30d1939SAndy Fiddaman fp->flags |= INC_BOUND(index);
363*b30d1939SAndy Fiddaman index = dp->index;
364*b30d1939SAndy Fiddaman if (fp->flags & INC_BOUND(index))
365*b30d1939SAndy Fiddaman {
366*b30d1939SAndy Fiddaman xp = fp->bound[index];
367*b30d1939SAndy Fiddaman if (index == INC_PREFIX)
368*b30d1939SAndy Fiddaman {
369*b30d1939SAndy Fiddaman if (*fp->name == '/' || !*dp->name)
370*b30d1939SAndy Fiddaman strcpy(pp.path, fp->name);
371*b30d1939SAndy Fiddaman else
372*b30d1939SAndy Fiddaman sfsprintf(pp.path, PATH_MAX - 1, "%s/%s", dp->name, fp->name);
373*b30d1939SAndy Fiddaman pathcanon(pp.path, PATH_MAX, 0);
374*b30d1939SAndy Fiddaman if (!xp || !streq(xp->name, pp.path))
375*b30d1939SAndy Fiddaman {
376*b30d1939SAndy Fiddaman fp->bound[index] = xp = ppsetfile(pp.path);
377*b30d1939SAndy Fiddaman if (dp->type & TYPE_HOSTED)
378*b30d1939SAndy Fiddaman xp->flags |= INC_HOSTED;
379*b30d1939SAndy Fiddaman if ((flags & SEARCH_INCLUDE) || (xp->flags & INC_EXISTS))
380*b30d1939SAndy Fiddaman {
381*b30d1939SAndy Fiddaman if (!(flags & SEARCH_INCLUDE))
382*b30d1939SAndy Fiddaman return 0;
383*b30d1939SAndy Fiddaman if (!ppmultiple(xp, INC_TEST))
384*b30d1939SAndy Fiddaman {
385*b30d1939SAndy Fiddaman if (flags & SEARCH_TEST)
386*b30d1939SAndy Fiddaman pp.include = xp->name;
387*b30d1939SAndy Fiddaman return 0;
388*b30d1939SAndy Fiddaman }
389*b30d1939SAndy Fiddaman mp = xp;
390*b30d1939SAndy Fiddaman }
391*b30d1939SAndy Fiddaman }
392*b30d1939SAndy Fiddaman }
393*b30d1939SAndy Fiddaman else if (!xp)
394*b30d1939SAndy Fiddaman {
395*b30d1939SAndy Fiddaman while (dp->next && dp->next->index == index)
396*b30d1939SAndy Fiddaman dp = dp->next;
397*b30d1939SAndy Fiddaman message((-3, "search: omit %s/%s", dp->name, fp->name));
398*b30d1939SAndy Fiddaman continue;
399*b30d1939SAndy Fiddaman }
400*b30d1939SAndy Fiddaman else
401*b30d1939SAndy Fiddaman {
402*b30d1939SAndy Fiddaman strcpy(pp.path, xp->name);
403*b30d1939SAndy Fiddaman if (!(flags & SEARCH_INCLUDE))
404*b30d1939SAndy Fiddaman return 0;
405*b30d1939SAndy Fiddaman if (!ppmultiple(xp, INC_TEST))
406*b30d1939SAndy Fiddaman {
407*b30d1939SAndy Fiddaman if (flags & SEARCH_TEST)
408*b30d1939SAndy Fiddaman pp.include = xp->name;
409*b30d1939SAndy Fiddaman return 0;
410*b30d1939SAndy Fiddaman }
411*b30d1939SAndy Fiddaman mp = xp;
412*b30d1939SAndy Fiddaman }
413*b30d1939SAndy Fiddaman }
414*b30d1939SAndy Fiddaman }
415*b30d1939SAndy Fiddaman if (!(fp->flags & INC_BOUND(index)) || (flags & SEARCH_NEXT))
416*b30d1939SAndy Fiddaman {
417*b30d1939SAndy Fiddaman if (*fp->name == '/' || !*dp->name)
418*b30d1939SAndy Fiddaman strcpy(pp.path, fp->name);
419*b30d1939SAndy Fiddaman else
420*b30d1939SAndy Fiddaman sfsprintf(pp.path, PATH_MAX - 1, "%s/%s", dp->name, fp->name);
421*b30d1939SAndy Fiddaman pathcanon(pp.path, PATH_MAX, 0);
422*b30d1939SAndy Fiddaman if (!(flags & SEARCH_SKIP))
423*b30d1939SAndy Fiddaman {
424*b30d1939SAndy Fiddaman int found;
425*b30d1939SAndy Fiddaman struct ppinstk* in;
426*b30d1939SAndy Fiddaman
427*b30d1939SAndy Fiddaman if (streq(error_info.file, pp.path))
428*b30d1939SAndy Fiddaman found = 1;
429*b30d1939SAndy Fiddaman else
430*b30d1939SAndy Fiddaman {
431*b30d1939SAndy Fiddaman found = 0;
432*b30d1939SAndy Fiddaman for (in = pp.in; in; in = in->prev)
433*b30d1939SAndy Fiddaman if (in->type == IN_FILE && in->file && streq(in->file, pp.path))
434*b30d1939SAndy Fiddaman {
435*b30d1939SAndy Fiddaman found = 1;
436*b30d1939SAndy Fiddaman break;
437*b30d1939SAndy Fiddaman }
438*b30d1939SAndy Fiddaman }
439*b30d1939SAndy Fiddaman if (found)
440*b30d1939SAndy Fiddaman {
441*b30d1939SAndy Fiddaman flags |= SEARCH_FOUND;
442*b30d1939SAndy Fiddaman continue;
443*b30d1939SAndy Fiddaman }
444*b30d1939SAndy Fiddaman if (!(flags & SEARCH_FOUND))
445*b30d1939SAndy Fiddaman continue;
446*b30d1939SAndy Fiddaman }
447*b30d1939SAndy Fiddaman }
448*b30d1939SAndy Fiddaman if ((xp || (xp = ppgetfile(pp.path))) && (xp->flags & INC_SELF))
449*b30d1939SAndy Fiddaman {
450*b30d1939SAndy Fiddaman if (xp->flags & INC_EXISTS)
451*b30d1939SAndy Fiddaman {
452*b30d1939SAndy Fiddaman if (!(flags & SEARCH_INCLUDE))
453*b30d1939SAndy Fiddaman return 0;
454*b30d1939SAndy Fiddaman if (!(flags & SEARCH_NEXT) && mp != xp && (mp = xp) && !ppmultiple(xp, INC_TEST))
455*b30d1939SAndy Fiddaman {
456*b30d1939SAndy Fiddaman if (flags & SEARCH_TEST)
457*b30d1939SAndy Fiddaman pp.include = xp->name;
458*b30d1939SAndy Fiddaman return 0;
459*b30d1939SAndy Fiddaman }
460*b30d1939SAndy Fiddaman }
461*b30d1939SAndy Fiddaman else if (*fp->name == '/')
462*b30d1939SAndy Fiddaman break;
463*b30d1939SAndy Fiddaman else
464*b30d1939SAndy Fiddaman continue;
465*b30d1939SAndy Fiddaman }
466*b30d1939SAndy Fiddaman message((-3, "search: file=%s path=%s", fp->name, pp.path));
467*b30d1939SAndy Fiddaman #if ARCHIVE
468*b30d1939SAndy Fiddaman if (pp.test & 0x0040) error(1, "SEARCH#%d dir=%s%s%s%s%s file=%s%s path=%s index=%d", __LINE__, dp->name, (dp->type & TYPE_ARCHIVE) ? " ARCHIVE" : "", (dp->type & TYPE_BUFFER) ? " BUFFER" : "", (dp->type & TYPE_CHECKPOINT) ? " CHECKPOINT" : "", (dp->type & TYPE_DIRECTORY) ? " DIRECTORY" : "", fp->name, (fp->flags & INC_MEMBER(index)) ? " MEMBER" : "", pp.path, index);
469*b30d1939SAndy Fiddaman if ((fp->flags & INC_MEMBER(index)) && ((struct ppmember*)fp->bound[index])->archive == dp)
470*b30d1939SAndy Fiddaman {
471*b30d1939SAndy Fiddaman fd = 0;
472*b30d1939SAndy Fiddaman pp.member = (struct ppmember*)fp->bound[index];
473*b30d1939SAndy Fiddaman if (pp.test & 0x0010) error(1, "SEARCH#%d file=%s path=%s index=%d data=<%lu,%lu>", __LINE__, fp->name, pp.path, index, pp.member->offset, pp.member->size);
474*b30d1939SAndy Fiddaman }
475*b30d1939SAndy Fiddaman else if (!(dp->type & TYPE_DIRECTORY))
476*b30d1939SAndy Fiddaman continue;
477*b30d1939SAndy Fiddaman else
478*b30d1939SAndy Fiddaman #endif
479*b30d1939SAndy Fiddaman {
480*b30d1939SAndy Fiddaman pp.member = 0;
481*b30d1939SAndy Fiddaman fd = (flags & SEARCH_INCLUDE) ? open(pp.path, O_RDONLY) : eaccess(pp.path, R_OK);
482*b30d1939SAndy Fiddaman }
483*b30d1939SAndy Fiddaman if (fd >= 0)
484*b30d1939SAndy Fiddaman {
485*b30d1939SAndy Fiddaman pp.found = dp;
486*b30d1939SAndy Fiddaman if ((pp.option & (PLUSPLUS|NOPROTO)) == PLUSPLUS && !(pp.test & TEST_noproto))
487*b30d1939SAndy Fiddaman {
488*b30d1939SAndy Fiddaman if (dp->c)
489*b30d1939SAndy Fiddaman pp.mode |= MARKC;
490*b30d1939SAndy Fiddaman else
491*b30d1939SAndy Fiddaman pp.mode &= ~MARKC;
492*b30d1939SAndy Fiddaman }
493*b30d1939SAndy Fiddaman if (xp)
494*b30d1939SAndy Fiddaman markhosted = xp->flags & INC_HOSTED;
495*b30d1939SAndy Fiddaman else if (!(markhosted = (dp->type & TYPE_HOSTED)) && dp->index == INC_PREFIX && (pp.mode & (FILEDEPS|HEADERDEPS|INIT)) == FILEDEPS)
496*b30d1939SAndy Fiddaman {
497*b30d1939SAndy Fiddaman up = dp;
498*b30d1939SAndy Fiddaman while ((up = up->next) && !streq(up->name, dp->name));
499*b30d1939SAndy Fiddaman if (up && (up->type & TYPE_HOSTED))
500*b30d1939SAndy Fiddaman markhosted = 1;
501*b30d1939SAndy Fiddaman }
502*b30d1939SAndy Fiddaman if (markhosted)
503*b30d1939SAndy Fiddaman pp.mode |= MARKHOSTED;
504*b30d1939SAndy Fiddaman else
505*b30d1939SAndy Fiddaman pp.mode &= ~MARKHOSTED;
506*b30d1939SAndy Fiddaman xp = ppsetfile(pp.path);
507*b30d1939SAndy Fiddaman if (markhosted)
508*b30d1939SAndy Fiddaman xp->flags |= INC_HOSTED;
509*b30d1939SAndy Fiddaman message((-2, "search: %s -> %s%s%s", fp->name, pp.path, (pp.mode & MARKC) ? " [C]" : "", (pp.mode & MARKHOSTED) ? " [hosted]" : ""));
510*b30d1939SAndy Fiddaman #if ARCHIVE
511*b30d1939SAndy Fiddaman if (!pp.member)
512*b30d1939SAndy Fiddaman {
513*b30d1939SAndy Fiddaman #endif
514*b30d1939SAndy Fiddaman fp->flags |= INC_BOUND(index);
515*b30d1939SAndy Fiddaman fp->bound[index] = xp;
516*b30d1939SAndy Fiddaman if ((index == INC_STANDARD || index == INC_VENDOR) && type != T_HEADER && !(fp->flags & INC_BOUND(INC_LOCAL)))
517*b30d1939SAndy Fiddaman {
518*b30d1939SAndy Fiddaman fp->flags |= INC_BOUND(INC_LOCAL);
519*b30d1939SAndy Fiddaman fp->bound[INC_LOCAL] = xp;
520*b30d1939SAndy Fiddaman }
521*b30d1939SAndy Fiddaman #if ARCHIVE
522*b30d1939SAndy Fiddaman }
523*b30d1939SAndy Fiddaman #endif
524*b30d1939SAndy Fiddaman xp->flags |= INC_SELF|INC_EXISTS;
525*b30d1939SAndy Fiddaman if (flags & SEARCH_INCLUDE)
526*b30d1939SAndy Fiddaman {
527*b30d1939SAndy Fiddaman if ((pp.prefix = prefix) || (pp.prefix = pp.in->prefix))
528*b30d1939SAndy Fiddaman message((-2, "search: %s: prefix=%s", xp->name, pp.prefix));
529*b30d1939SAndy Fiddaman if (!(pp.mode & ALLMULTIPLE))
530*b30d1939SAndy Fiddaman {
531*b30d1939SAndy Fiddaman if (xp->guard == INC_CLEAR || xp == mp)
532*b30d1939SAndy Fiddaman xp->guard = INC_TEST;
533*b30d1939SAndy Fiddaman else
534*b30d1939SAndy Fiddaman {
535*b30d1939SAndy Fiddaman if ((pp.state & WARN) && (pp.mode & (HOSTED|MARKHOSTED|RELAX|PEDANTIC)) == PEDANTIC)
536*b30d1939SAndy Fiddaman error(1, "%s: ignored -- already included", xp->name);
537*b30d1939SAndy Fiddaman else
538*b30d1939SAndy Fiddaman message((-3, "%s: ignored -- already included", xp->name));
539*b30d1939SAndy Fiddaman xp->guard = fp->guard = INC_IGNORE;
540*b30d1939SAndy Fiddaman #if ARCHIVE
541*b30d1939SAndy Fiddaman if (!pp.member)
542*b30d1939SAndy Fiddaman #endif
543*b30d1939SAndy Fiddaman if (fd > 0)
544*b30d1939SAndy Fiddaman close(fd);
545*b30d1939SAndy Fiddaman if (flags & SEARCH_TEST)
546*b30d1939SAndy Fiddaman pp.include = xp->name;
547*b30d1939SAndy Fiddaman return 0;
548*b30d1939SAndy Fiddaman }
549*b30d1939SAndy Fiddaman }
550*b30d1939SAndy Fiddaman pp.include = xp->name;
551*b30d1939SAndy Fiddaman if ((pp.mode & (FILEDEPS|INIT)) == FILEDEPS && ((pp.mode & HEADERDEPS) || !(pp.mode & MARKHOSTED)) && !(xp->flags & INC_LISTED))
552*b30d1939SAndy Fiddaman {
553*b30d1939SAndy Fiddaman xp->flags |= INC_LISTED;
554*b30d1939SAndy Fiddaman if ((pp.column + strlen(xp->name)) >= COLUMN_MAX)
555*b30d1939SAndy Fiddaman {
556*b30d1939SAndy Fiddaman sfprintf(pp.filedeps.sp, " \\\n");
557*b30d1939SAndy Fiddaman pp.column = COLUMN_TAB;
558*b30d1939SAndy Fiddaman index = '\t';
559*b30d1939SAndy Fiddaman }
560*b30d1939SAndy Fiddaman else
561*b30d1939SAndy Fiddaman index = ' ';
562*b30d1939SAndy Fiddaman pp.column += sfprintf(pp.filedeps.sp, "%c%s", index, xp->name);
563*b30d1939SAndy Fiddaman }
564*b30d1939SAndy Fiddaman }
565*b30d1939SAndy Fiddaman return fd;
566*b30d1939SAndy Fiddaman }
567*b30d1939SAndy Fiddaman if (xp)
568*b30d1939SAndy Fiddaman xp->flags |= INC_SELF;
569*b30d1939SAndy Fiddaman if (errno == EMFILE)
570*b30d1939SAndy Fiddaman error(3, "%s: too many open files", fp->name);
571*b30d1939SAndy Fiddaman else if (errno != ENOENT && errno != ENOTDIR)
572*b30d1939SAndy Fiddaman error(ERROR_SYSTEM|1, "%s: cannot open file for reading", pp.path);
573*b30d1939SAndy Fiddaman if (*fp->name == '/')
574*b30d1939SAndy Fiddaman break;
575*b30d1939SAndy Fiddaman }
576*b30d1939SAndy Fiddaman strcpy(pp.path, fp->name);
577*b30d1939SAndy Fiddaman message((-2, "search: %s%s not found", (flags & SEARCH_NEXT) ? "next " : "", fp->name));
578*b30d1939SAndy Fiddaman return -1;
579*b30d1939SAndy Fiddaman }
580*b30d1939SAndy Fiddaman
581*b30d1939SAndy Fiddaman /*
582*b30d1939SAndy Fiddaman * search for an include file
583*b30d1939SAndy Fiddaman * if (flags&SEARCH_INCLUDE) then
584*b30d1939SAndy Fiddaman * if file found then open read file descriptor returned
585*b30d1939SAndy Fiddaman * with pp.path set to the full path and
586*b30d1939SAndy Fiddaman * pp.prefix set to the directory prefix
587*b30d1939SAndy Fiddaman * otherwise 0 returned if file found but ignored
588*b30d1939SAndy Fiddaman * otherwise -1 returned
589*b30d1939SAndy Fiddaman * otherwise
590*b30d1939SAndy Fiddaman * if file found then 0 returned
591*b30d1939SAndy Fiddaman * otherwise -1 returned
592*b30d1939SAndy Fiddaman */
593*b30d1939SAndy Fiddaman
594*b30d1939SAndy Fiddaman int
ppsearch(char * file,int type,int flags)595*b30d1939SAndy Fiddaman ppsearch(char* file, int type, int flags)
596*b30d1939SAndy Fiddaman {
597*b30d1939SAndy Fiddaman register struct ppfile* fp;
598*b30d1939SAndy Fiddaman register char* s;
599*b30d1939SAndy Fiddaman register struct ppdirs* dp;
600*b30d1939SAndy Fiddaman char* t;
601*b30d1939SAndy Fiddaman struct oplist* cp;
602*b30d1939SAndy Fiddaman struct ppfile* xp;
603*b30d1939SAndy Fiddaman int dospath;
604*b30d1939SAndy Fiddaman int chop;
605*b30d1939SAndy Fiddaman int fd;
606*b30d1939SAndy Fiddaman int index;
607*b30d1939SAndy Fiddaman int prefix;
608*b30d1939SAndy Fiddaman char name[MAXTOKEN + 1];
609*b30d1939SAndy Fiddaman
610*b30d1939SAndy Fiddaman pp.include = 0;
611*b30d1939SAndy Fiddaman fd = -1;
612*b30d1939SAndy Fiddaman chop = 0;
613*b30d1939SAndy Fiddaman prefix = pp.chop ? -1 : 0;
614*b30d1939SAndy Fiddaman if (s = strchr(file, '\\'))
615*b30d1939SAndy Fiddaman {
616*b30d1939SAndy Fiddaman do *s++ = '/'; while (s = strchr(s, '\\'));
617*b30d1939SAndy Fiddaman dospath = 1;
618*b30d1939SAndy Fiddaman }
619*b30d1939SAndy Fiddaman else
620*b30d1939SAndy Fiddaman dospath = 0;
621*b30d1939SAndy Fiddaman again:
622*b30d1939SAndy Fiddaman pathcanon(file, 0, 0);
623*b30d1939SAndy Fiddaman if (chop)
624*b30d1939SAndy Fiddaman for (cp = pp.chop; cp; cp = cp->next)
625*b30d1939SAndy Fiddaman if (strneq(file, cp->value, cp->op))
626*b30d1939SAndy Fiddaman {
627*b30d1939SAndy Fiddaman if (cp->value[cp->op + 1])
628*b30d1939SAndy Fiddaman {
629*b30d1939SAndy Fiddaman sfsprintf(name, sizeof(name) - 1, "%s%s", cp->value + cp->op + 1, file + cp->op);
630*b30d1939SAndy Fiddaman message((-2, "search: %s -> %s", file, name));
631*b30d1939SAndy Fiddaman file = name;
632*b30d1939SAndy Fiddaman }
633*b30d1939SAndy Fiddaman else if (strchr(file + cp->op, '/'))
634*b30d1939SAndy Fiddaman {
635*b30d1939SAndy Fiddaman message((-2, "search: %s -> %s", file, file + cp->op));
636*b30d1939SAndy Fiddaman file += cp->op;
637*b30d1939SAndy Fiddaman }
638*b30d1939SAndy Fiddaman break;
639*b30d1939SAndy Fiddaman }
640*b30d1939SAndy Fiddaman fp = ppsetfile(file);
641*b30d1939SAndy Fiddaman while ((fp->flags & INC_MAPALL) || (fp->flags & INC_MAPHOSTED) && (pp.mode & HOSTED) || (fp->flags & INC_MAPNOHOSTED) && !(pp.mode & HOSTED))
642*b30d1939SAndy Fiddaman {
643*b30d1939SAndy Fiddaman if (!(xp = fp->bound[type == T_HEADER ? INC_STANDARD : INC_LOCAL]) || xp == fp)
644*b30d1939SAndy Fiddaman break;
645*b30d1939SAndy Fiddaman message((-1, "map: %s -> %s", fp->name, xp->name));
646*b30d1939SAndy Fiddaman fp = xp;
647*b30d1939SAndy Fiddaman }
648*b30d1939SAndy Fiddaman if ((fp->flags & INC_MAPNOLOCAL) && (pp.mode & HOSTED))
649*b30d1939SAndy Fiddaman flags |= SEARCH_HOSTED;
650*b30d1939SAndy Fiddaman else if (pp.vendor)
651*b30d1939SAndy Fiddaman flags |= SEARCH_VENDOR;
652*b30d1939SAndy Fiddaman pp.original = fp;
653*b30d1939SAndy Fiddaman if (type == T_HEADER && strneq(fp->name, "...", 3) && (!fp->name[3] || fp->name[3] == '/'))
654*b30d1939SAndy Fiddaman {
655*b30d1939SAndy Fiddaman if (fp->name[3] == '/')
656*b30d1939SAndy Fiddaman {
657*b30d1939SAndy Fiddaman int n;
658*b30d1939SAndy Fiddaman int m;
659*b30d1939SAndy Fiddaman
660*b30d1939SAndy Fiddaman n = strlen(error_info.file);
661*b30d1939SAndy Fiddaman m = strlen(fp->name + 4);
662*b30d1939SAndy Fiddaman if (n < m || !streq(fp->name + 4, error_info.file + n - m))
663*b30d1939SAndy Fiddaman {
664*b30d1939SAndy Fiddaman if ((fd = ppsearch(fp->name + 4, type, flags|SEARCH_TEST)) < 0)
665*b30d1939SAndy Fiddaman return -1;
666*b30d1939SAndy Fiddaman if (fd > 0)
667*b30d1939SAndy Fiddaman close(fd);
668*b30d1939SAndy Fiddaman s = error_info.file;
669*b30d1939SAndy Fiddaman error_info.file = pp.include;
670*b30d1939SAndy Fiddaman fd = ppsearch(fp->name + 4, type, flags|SEARCH_NEXT);
671*b30d1939SAndy Fiddaman error_info.file = s;
672*b30d1939SAndy Fiddaman return fd;
673*b30d1939SAndy Fiddaman }
674*b30d1939SAndy Fiddaman file = error_info.file + n - m;
675*b30d1939SAndy Fiddaman }
676*b30d1939SAndy Fiddaman else if (file = strrchr(error_info.file, '/'))
677*b30d1939SAndy Fiddaman file++;
678*b30d1939SAndy Fiddaman else
679*b30d1939SAndy Fiddaman file = error_info.file;
680*b30d1939SAndy Fiddaman flags |= SEARCH_NEXT;
681*b30d1939SAndy Fiddaman #if _HUH_2002_05_28
682*b30d1939SAndy Fiddaman if (pp.in->prefix)
683*b30d1939SAndy Fiddaman {
684*b30d1939SAndy Fiddaman sfsprintf(name, sizeof(name) - 1, "%s/%s", pp.in->prefix, file);
685*b30d1939SAndy Fiddaman fp = ppsetfile(name);
686*b30d1939SAndy Fiddaman if ((fd = ppsearch(fp->name, type, flags)) >= 0)
687*b30d1939SAndy Fiddaman return fd;
688*b30d1939SAndy Fiddaman }
689*b30d1939SAndy Fiddaman #endif
690*b30d1939SAndy Fiddaman fp = ppsetfile(file);
691*b30d1939SAndy Fiddaman return ppsearch(fp->name, type, flags);
692*b30d1939SAndy Fiddaman }
693*b30d1939SAndy Fiddaman else if ((flags & SEARCH_INCLUDE) && fp->guard == INC_IGNORE)
694*b30d1939SAndy Fiddaman {
695*b30d1939SAndy Fiddaman strcpy(pp.path, fp->name);
696*b30d1939SAndy Fiddaman message((-2, "%s: ignored", fp->name));
697*b30d1939SAndy Fiddaman return 0;
698*b30d1939SAndy Fiddaman }
699*b30d1939SAndy Fiddaman else if (!(flags & SEARCH_NEXT))
700*b30d1939SAndy Fiddaman flags |= SEARCH_SKIP;
701*b30d1939SAndy Fiddaman pp.prefix = 0;
702*b30d1939SAndy Fiddaman if (type == T_HEADER)
703*b30d1939SAndy Fiddaman dp = pp.stddirs->next;
704*b30d1939SAndy Fiddaman else
705*b30d1939SAndy Fiddaman {
706*b30d1939SAndy Fiddaman dp = pp.lcldirs;
707*b30d1939SAndy Fiddaman if (dp == pp.firstdir)
708*b30d1939SAndy Fiddaman {
709*b30d1939SAndy Fiddaman /*
710*b30d1939SAndy Fiddaman * look in directory of including file first
711*b30d1939SAndy Fiddaman */
712*b30d1939SAndy Fiddaman
713*b30d1939SAndy Fiddaman if (error_info.file && (s = strrchr(error_info.file, '/')))
714*b30d1939SAndy Fiddaman {
715*b30d1939SAndy Fiddaman *s = 0;
716*b30d1939SAndy Fiddaman dp->name = ppsetfile(error_info.file)->name;
717*b30d1939SAndy Fiddaman *s = '/';
718*b30d1939SAndy Fiddaman }
719*b30d1939SAndy Fiddaman else
720*b30d1939SAndy Fiddaman dp->name = "";
721*b30d1939SAndy Fiddaman }
722*b30d1939SAndy Fiddaman else if (pp.in->prefix && pp.lcldirs != pp.firstdir)
723*b30d1939SAndy Fiddaman {
724*b30d1939SAndy Fiddaman /*
725*b30d1939SAndy Fiddaman * look in prefix directory of including file first
726*b30d1939SAndy Fiddaman */
727*b30d1939SAndy Fiddaman
728*b30d1939SAndy Fiddaman if (*fp->name != '/')
729*b30d1939SAndy Fiddaman {
730*b30d1939SAndy Fiddaman if ((s = strchr(fp->name, '/')) && (fp->name[0]
731*b30d1939SAndy Fiddaman != '.' || fp->name[1] != '.' || fp->name[2] != '/'))
732*b30d1939SAndy Fiddaman {
733*b30d1939SAndy Fiddaman *s = 0;
734*b30d1939SAndy Fiddaman if (!streq(fp->name, pp.in->prefix))
735*b30d1939SAndy Fiddaman fd = 0;
736*b30d1939SAndy Fiddaman *s = '/';
737*b30d1939SAndy Fiddaman }
738*b30d1939SAndy Fiddaman else
739*b30d1939SAndy Fiddaman fd = 0;
740*b30d1939SAndy Fiddaman }
741*b30d1939SAndy Fiddaman if (fd >= 0)
742*b30d1939SAndy Fiddaman {
743*b30d1939SAndy Fiddaman sfsprintf(name, sizeof(name) - 1, "%s/%s", pp.in->prefix, fp->name);
744*b30d1939SAndy Fiddaman pathcanon(name, sizeof(name), 0);
745*b30d1939SAndy Fiddaman xp = ppsetfile(name);
746*b30d1939SAndy Fiddaman if ((fd = search(xp, dp, type, flags)) >= 0)
747*b30d1939SAndy Fiddaman return fd;
748*b30d1939SAndy Fiddaman }
749*b30d1939SAndy Fiddaman }
750*b30d1939SAndy Fiddaman else if (!prefix)
751*b30d1939SAndy Fiddaman prefix = 1;
752*b30d1939SAndy Fiddaman }
753*b30d1939SAndy Fiddaman if ((fd = search(fp, dp, type, flags)) < 0)
754*b30d1939SAndy Fiddaman {
755*b30d1939SAndy Fiddaman if ((pp.option & PLUSPLUS) && file != pp.tmpbuf)
756*b30d1939SAndy Fiddaman {
757*b30d1939SAndy Fiddaman s = file + strlen(file);
758*b30d1939SAndy Fiddaman while (s > file && *--s != '/' && *s != '\\' && *s != '.');
759*b30d1939SAndy Fiddaman if (*s != '.')
760*b30d1939SAndy Fiddaman {
761*b30d1939SAndy Fiddaman sfsprintf(pp.tmpbuf, MAXTOKEN, "%s.h", file);
762*b30d1939SAndy Fiddaman file = pp.tmpbuf;
763*b30d1939SAndy Fiddaman goto again;
764*b30d1939SAndy Fiddaman }
765*b30d1939SAndy Fiddaman }
766*b30d1939SAndy Fiddaman
767*b30d1939SAndy Fiddaman /*
768*b30d1939SAndy Fiddaman * hackery for msdos files viewed through unix
769*b30d1939SAndy Fiddaman */
770*b30d1939SAndy Fiddaman
771*b30d1939SAndy Fiddaman switch (dospath)
772*b30d1939SAndy Fiddaman {
773*b30d1939SAndy Fiddaman case 1:
774*b30d1939SAndy Fiddaman if (ppisid(file[0]) && file[1] == ':' && file[2] == '/')
775*b30d1939SAndy Fiddaman {
776*b30d1939SAndy Fiddaman file[1] = file[0];
777*b30d1939SAndy Fiddaman file[0] = '/';
778*b30d1939SAndy Fiddaman pathcanon(file, 0, 0);
779*b30d1939SAndy Fiddaman dospath = 2;
780*b30d1939SAndy Fiddaman goto again;
781*b30d1939SAndy Fiddaman }
782*b30d1939SAndy Fiddaman break;
783*b30d1939SAndy Fiddaman case 2:
784*b30d1939SAndy Fiddaman file += 2;
785*b30d1939SAndy Fiddaman goto again;
786*b30d1939SAndy Fiddaman }
787*b30d1939SAndy Fiddaman if ((flags & (SEARCH_INCLUDE|SEARCH_NEXT)) == SEARCH_INCLUDE)
788*b30d1939SAndy Fiddaman {
789*b30d1939SAndy Fiddaman if (!chop && pp.chop)
790*b30d1939SAndy Fiddaman {
791*b30d1939SAndy Fiddaman chop = 1;
792*b30d1939SAndy Fiddaman type = T_STRING;
793*b30d1939SAndy Fiddaman goto again;
794*b30d1939SAndy Fiddaman }
795*b30d1939SAndy Fiddaman if (prefix > 0)
796*b30d1939SAndy Fiddaman {
797*b30d1939SAndy Fiddaman prefix = -1;
798*b30d1939SAndy Fiddaman if (error_info.file && *error_info.file && (s = strrchr(error_info.file + 1, '/')))
799*b30d1939SAndy Fiddaman {
800*b30d1939SAndy Fiddaman *s = 0;
801*b30d1939SAndy Fiddaman if (t = strrchr(error_info.file + 1, '/'))
802*b30d1939SAndy Fiddaman {
803*b30d1939SAndy Fiddaman sfsprintf(name, sizeof(name), "%s/%s", t + 1, file);
804*b30d1939SAndy Fiddaman file = ppsetfile(name)->name;
805*b30d1939SAndy Fiddaman }
806*b30d1939SAndy Fiddaman *s = '/';
807*b30d1939SAndy Fiddaman if (t)
808*b30d1939SAndy Fiddaman goto again;
809*b30d1939SAndy Fiddaman }
810*b30d1939SAndy Fiddaman }
811*b30d1939SAndy Fiddaman if (!(pp.mode & GENDEPS))
812*b30d1939SAndy Fiddaman {
813*b30d1939SAndy Fiddaman if (!(pp.option & ALLPOSSIBLE) || pp.in->prev->prev)
814*b30d1939SAndy Fiddaman error(2, "%s: cannot find include file", file);
815*b30d1939SAndy Fiddaman }
816*b30d1939SAndy Fiddaman else if (!(pp.mode & INIT))
817*b30d1939SAndy Fiddaman {
818*b30d1939SAndy Fiddaman xp = ppsetfile(file);
819*b30d1939SAndy Fiddaman if (!(xp->flags & INC_LISTED))
820*b30d1939SAndy Fiddaman {
821*b30d1939SAndy Fiddaman xp->flags |= INC_LISTED;
822*b30d1939SAndy Fiddaman if ((pp.column + strlen(file)) >= COLUMN_MAX)
823*b30d1939SAndy Fiddaman {
824*b30d1939SAndy Fiddaman sfprintf(pp.filedeps.sp, " \\\n");
825*b30d1939SAndy Fiddaman pp.column = COLUMN_TAB;
826*b30d1939SAndy Fiddaman index = '\t';
827*b30d1939SAndy Fiddaman }
828*b30d1939SAndy Fiddaman else
829*b30d1939SAndy Fiddaman index = ' ';
830*b30d1939SAndy Fiddaman pp.column += sfprintf(pp.filedeps.sp, "%c%s", index, file);
831*b30d1939SAndy Fiddaman }
832*b30d1939SAndy Fiddaman }
833*b30d1939SAndy Fiddaman }
834*b30d1939SAndy Fiddaman }
835*b30d1939SAndy Fiddaman return fd;
836*b30d1939SAndy Fiddaman }
837