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