diff options
Diffstat (limited to 'usr/src/lib/libpp/common/ppsearch.c')
-rw-r--r-- | usr/src/lib/libpp/common/ppsearch.c | 807 |
1 files changed, 807 insertions, 0 deletions
diff --git a/usr/src/lib/libpp/common/ppsearch.c b/usr/src/lib/libpp/common/ppsearch.c new file mode 100644 index 0000000000..f9bf29fe01 --- /dev/null +++ b/usr/src/lib/libpp/common/ppsearch.c @@ -0,0 +1,807 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1986-2007 AT&T Knowledge Ventures * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Knowledge Ventures * +* * +* A copy of the License is available at * +* http://www.opensource.org/licenses/cpl1.0.txt * +* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + * + * include file search support + */ + +#include "pplib.h" + +#define SEARCH_NEXT (SEARCH_USER<<1)/* search for next (uncover) */ +#define SEARCH_SKIP (SEARCH_USER<<2)/* current binding skipped */ +#define SEARCH_TEST (SEARCH_USER<<3)/* test for binding */ +#define SEARCH_FOUND (SEARCH_USER<<4)/* current binding found */ + +#define COLUMN_TAB 7 +#define COLUMN_MAX 72 + +#if ARCHIVE + +#include <vdb.h> +#include <ls.h> + +#endif + +/* + * multiple include test + * fp is a canonicalized ppfile pointer + * + * test + * + * INC_CLEAR can be included again + * INC_TEST test if include required + * <symbol> ifndef guard symbol + * + * test!=INC_CLEAR returns 1 if file can be included again + * + * NOTE: + * + * (1) different hard links to the same file are treated as + * different files + * + * (2) symbolic links in combination with .. may cause two + * different files to be treated as the same file: + * + * "../h/<file>" == "/usr/include/sys/../h/<file>" -> "/usr/include/h/<file>" + * "h/<file>" -> "/usr/include/h/<file>" + */ + +int +ppmultiple(register struct ppfile* fp, register struct ppsymbol* test) +{ + register struct ppsymbol* status; + + status = fp->guard; + 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)); + if (status == INC_IGNORE) + { + message((-2, "%s: ignored [%s]", fp->name, pp.ignore)); + return 0; + } + if (test == INC_TEST) + { + if (status != INC_CLEAR) + { + if (status != INC_TEST && status->macro || !(pp.mode & ALLMULTIPLE) && !(pp.state & STRICT)) + { + if ((pp.mode & (ALLMULTIPLE|LOADING)) == LOADING) + fp->guard = INC_IGNORE; + if (pp.state & WARN) + error(1, "%s: ignored -- already included", fp->name); + else + message((-3, "%s: ignored -- already included", fp->name)); + return 0; + } + return 1; + } + if ((pp.mode & (ALLMULTIPLE|LOADING)) == LOADING) + test = INC_IGNORE; + } + fp->guard = test; + return 1; +} + +/* + * search for file using directories in dp + */ + +static int +search(register struct ppfile* fp, register struct ppdirs* dp, int type, int flags) +{ + register char* prefix; + register struct ppdirs* up; + register struct ppfile* xp; + struct ppfile* mp; + int fd; + int index; + int need; + int markhosted; + char* t; + + if (!(pp.option & PREFIX)) + prefix = 0; + else if ((prefix = strrchr(fp->name, '/')) && prefix > fp->name) + { + *prefix = 0; + t = ppsetfile(fp->name)->name; + *prefix = '/'; + prefix = t; + } + 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", + fp->name, + (flags & SEARCH_INCLUDE) ? "include" : "exists", + (flags & SEARCH_VENDOR) ? " vendor" : "", + (flags & SEARCH_HOSTED) ? " hosted" : "", + (flags & SEARCH_NEXT) ? " next" : "", + (flags & SEARCH_SKIP) ? " skip" : "", + (flags & SEARCH_TEST) ? " test" : "", + type == T_HEADER ? "<*>" : "\"*\"", prefix, + (fp->flags & INC_SELF) ? "SELF|" : "", + (fp->flags & INC_EXISTS) ? "EXISTS|" : "", + (fp->flags & INC_BOUND(INC_PREFIX)) ? "PREFIX|" : "", + (fp->flags & INC_BOUND(INC_LOCAL)) ? "LOCAL|" : "", + (fp->flags & INC_BOUND(INC_VENDOR)) ? "VENDOR|" : "", + (fp->flags & INC_BOUND(INC_STANDARD)) ? "STANDARD|" : "", + dp ? (dp->index == INC_PREFIX ? "pre" : dp->index == INC_LOCAL ? "lcl" : dp->index == INC_VENDOR ? "vnd" : "std") : NiL, + dp ? dp->name : NiL, + !(fp->flags & INC_MEMBER(INC_PREFIX)) && (xp = fp->bound[INC_PREFIX]) ? xp->name : NiL, + !(fp->flags & INC_MEMBER(INC_LOCAL)) && (xp = fp->bound[INC_LOCAL]) ? xp->name : NiL, + !(fp->flags & INC_MEMBER(INC_VENDOR)) && (xp = fp->bound[INC_VENDOR]) ? xp->name : NiL, + !(fp->flags & INC_MEMBER(INC_STANDARD)) && (xp = fp->bound[INC_STANDARD]) ? xp->name : NiL, + error_info.file + )); + if (flags & SEARCH_HOSTED) + need = TYPE_HOSTED; + else if (flags & SEARCH_VENDOR) + need = TYPE_VENDOR; + else + need = TYPE_INCLUDE; + for (index = -1; dp; dp = dp->next) + if (dp->type & need) + { + 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)); +#if ARCHIVE + if (!(dp->type & (TYPE_ARCHIVE|TYPE_DIRECTORY))) + { + struct stat st; + + if (stat(dp->name, &st)) + { + message((-3, "search: omit %s", dp->name)); + dp->type = 0; + continue; + } + if (S_ISREG(st.st_mode)) + { + register char* s; + char* e; + int delimiter; + int variant; + unsigned long siz; + unsigned long off; + struct ppmember* ap; + Sfio_t* sp; + + /* + * check for vdb header archive + */ + + if (!(sp = sfopen(NiL, dp->name, "r"))) + { + error(ERROR_SYSTEM|1, "%s: ignored -- cannot open", dp->name); + dp->type = 0; + continue; + } + variant = sfsprintf(pp.tmpbuf, MAXTOKEN, "%c%s%c%s:archive", VDB_DELIMITER, VDB_MAGIC, VDB_DELIMITER, pp.pass); + if (!(s = sfgetr(sp, '\n', 1)) || !strneq(s, pp.tmpbuf, variant)) + { + sfclose(sp); + error(1, "%s: ignored -- not a directory or archive", dp->name); + dp->type = 0; + continue; + } + + /* + * parse the options + */ + + dp->type |= TYPE_ARCHIVE; + for (s += variant;;) + { + while (*s == ' ') s++; + e = s; + for (t = 0; *s && *s != ' '; s++) + if (*s == '=') + { + *s = 0; + t = s + 1; + } + if (*s) + *s++ = 0; + if (!*e) + break; + switch ((int)hashref(pp.strtab, e)) + { + case X_CHECKPOINT: +#if CHECKPOINT + dp->type |= TYPE_CHECKPOINT; + break; +#else + error(1, "preprocessor not compiled with checkpoint enabled"); + goto notvdb; +#endif + case X_HIDE: + + if (t) + error(1, "%s: %s: archive option value ignored", e); + if (e = strrchr(dp->name, '/')) + *e = 0; + else + dp->name = "."; + break; + case X_MAP: + if (!t) + error(1, "%s: archive option value expected", e); + else + dp->name = strdup(t); + break; + default: + error(1, "%s: unknown archive option", e); + break; + } + } + if (sfseek(sp, -(VDB_LENGTH + 1), SEEK_END) <= 0 || !(s = sfgetr(sp, '\n', 1))) + { + notvdb: + sfclose(sp); + error(1, "%s: ignored -- cannot load archive", dp->name); + dp->type = 0; + continue; + } + if (variant = *s != 0) + s++; + else if (!(s = sfgetr(sp, '\n', 1))) + goto notvdb; + if (sfvalue(sp) != (VDB_LENGTH + variant)) + goto notvdb; + if (!strneq(s, VDB_DIRECTORY, sizeof(VDB_DIRECTORY) - 1)) + goto notvdb; + delimiter = s[VDB_OFFSET - 1]; + off = strtol(s + VDB_OFFSET, NiL, 10) - sizeof(VDB_DIRECTORY); + siz = strtol(s + VDB_SIZE, NiL, 10); + if (sfseek(sp, off, SEEK_SET) != off) + goto notvdb; + if (!(s = sfreserve(sp, siz + 1, 0))) + goto notvdb; + s[siz] = 0; + if (!strneq(s, VDB_DIRECTORY, sizeof(VDB_DIRECTORY)) - 1) + goto notvdb; + if (!(s = strchr(s, '\n'))) + goto notvdb; + s++; + while (e = strchr(s, '\n')) + { + delimiter = variant ? *s++ : delimiter; + if (!(t = strchr(s, delimiter))) + break; + *t = 0; + if (!streq(s, VDB_DIRECTORY)) + { + pathcanon(s, 0); + ap = newof(0, struct ppmember, 1, 0); + ap->archive = dp; + ap->offset = strtol(t + 1, &t, 10); + ap->size = strtol(t + 1, NiL, 10); + xp = ppsetfile(s); + xp->flags |= INC_MEMBER(dp->index); + xp->bound[dp->index] = (struct ppfile*)ap; +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); + } + s = e + 1; + } + if (sfseek(sp, 0L, SEEK_SET)) + goto notvdb; + if (!(pp.test & 0x4000) && +#if POOL + (pp.pool.input || !(dp->type & TYPE_CHECKPOINT)) +#else + !(dp->type & TYPE_CHECKPOINT) +#endif + && (dp->info.buffer = sfreserve(sp, off, 0))) + dp->type |= TYPE_BUFFER; + else + { + dp->info.sp = sp; +#if POOL + if (pp.pool.input) + sfset(sp, SF_SHARE, 1); +#endif + } + } + else + dp->type |= TYPE_DIRECTORY; + } +#endif + if (streq(fp->name, ".")) + continue; + if (prefix && *fp->name != '/' && dp->index != INC_PREFIX) +#if ARCHIVE + if (dp->type & TYPE_DIRECTORY) +#endif + { + for (up = dp->info.subdir; up; up = up->next) + if (up->name == prefix) + break; + if (!up) + { + up = newof(0, struct ppdirs, 1, 0); + up->name = prefix; + up->type = dp->type; + up->next = dp->info.subdir; + dp->info.subdir = up; + if (!*dp->name) + t = prefix; + else + sfsprintf(t = pp.path, PATH_MAX - 1, "%s/%s", dp->name, prefix); + if (eaccess(t, X_OK)) + { + message((-3, "search: omit %s", t)); + continue; + } + up->type |= TYPE_HOSTED; + } + else if (!(up->type & TYPE_HOSTED)) + continue; + } + mp = xp = 0; + if (!(flags & SEARCH_NEXT) && index != dp->index && (!(need & TYPE_HOSTED) || dp->index == INC_STANDARD) && (!(need & TYPE_VENDOR) || dp->index == INC_VENDOR)) + { + if (index >= 0 && !(fp->flags & INC_MEMBER(index))) + fp->flags |= INC_BOUND(index); + index = dp->index; + if (fp->flags & INC_BOUND(index)) + { + xp = fp->bound[index]; + if (index == INC_PREFIX) + { + if (*fp->name == '/' || !*dp->name) + strcpy(pp.path, fp->name); + else + sfsprintf(pp.path, PATH_MAX - 1, "%s/%s", dp->name, fp->name); + pathcanon(pp.path, 0); + if (!xp || !streq(xp->name, pp.path)) + { + fp->bound[index] = xp = ppsetfile(pp.path); + if (dp->type & TYPE_HOSTED) + xp->flags |= INC_HOSTED; + if ((flags & SEARCH_INCLUDE) || (xp->flags & INC_EXISTS)) + { + if (!(flags & SEARCH_INCLUDE)) + return 0; + if (!ppmultiple(xp, INC_TEST)) + { + if (flags & SEARCH_TEST) + pp.include = xp->name; + return 0; + } + mp = xp; + } + } + } + else if (!xp) + { + while (dp->next && dp->next->index == index) + dp = dp->next; + message((-3, "search: omit %s/%s", dp->name, fp->name)); + continue; + } + else + { + strcpy(pp.path, xp->name); + if (!(flags & SEARCH_INCLUDE)) + return 0; + if (!ppmultiple(xp, INC_TEST)) + { + if (flags & SEARCH_TEST) + pp.include = xp->name; + return 0; + } + mp = xp; + } + } + } + if (!(fp->flags & INC_BOUND(index)) || (flags & SEARCH_NEXT)) + { + if (*fp->name == '/' || !*dp->name) + strcpy(pp.path, fp->name); + else + sfsprintf(pp.path, PATH_MAX - 1, "%s/%s", dp->name, fp->name); + pathcanon(pp.path, 0); + if (!(flags & SEARCH_SKIP)) + { + int found; + struct ppinstk* in; + + if (streq(error_info.file, pp.path)) + found = 1; + else + { + found = 0; + for (in = pp.in; in; in = in->prev) + if (in->type == IN_FILE && in->file && streq(in->file, pp.path)) + { + found = 1; + break; + } + } + if (found) + { + flags |= SEARCH_FOUND; + continue; + } + if (!(flags & SEARCH_FOUND)) + continue; + } + } + if ((xp || (xp = ppgetfile(pp.path))) && (xp->flags & INC_SELF)) + { + if (xp->flags & INC_EXISTS) + { + if (!(flags & SEARCH_INCLUDE)) + return 0; + if (!(flags & SEARCH_NEXT) && mp != xp && (mp = xp) && !ppmultiple(xp, INC_TEST)) + { + if (flags & SEARCH_TEST) + pp.include = xp->name; + return 0; + } + } + else if (*fp->name == '/') + break; + else + continue; + } + message((-3, "search: file=%s path=%s", fp->name, pp.path)); +#if ARCHIVE +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); + if ((fp->flags & INC_MEMBER(index)) && ((struct ppmember*)fp->bound[index])->archive == dp) + { + fd = 0; + pp.member = (struct ppmember*)fp->bound[index]; +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); + } + else if (!(dp->type & TYPE_DIRECTORY)) + continue; + else +#endif + { + pp.member = 0; + fd = (flags & SEARCH_INCLUDE) ? open(pp.path, O_RDONLY) : eaccess(pp.path, R_OK); + } + if (fd >= 0) + { + pp.found = dp; + if ((pp.option & (PLUSPLUS|NOPROTO)) == PLUSPLUS && !(pp.test & TEST_noproto)) + { + if (dp->c) + pp.mode |= MARKC; + else + pp.mode &= ~MARKC; + } + if (xp) + markhosted = xp->flags & INC_HOSTED; + else if (!(markhosted = (dp->type & TYPE_HOSTED)) && dp->index == INC_PREFIX && (pp.mode & (FILEDEPS|HEADERDEPS|INIT)) == FILEDEPS) + { + up = dp; + while ((up = up->next) && !streq(up->name, dp->name)); + if (up && (up->type & TYPE_HOSTED)) + markhosted = 1; + } + if (markhosted) + pp.mode |= MARKHOSTED; + else + pp.mode &= ~MARKHOSTED; + xp = ppsetfile(pp.path); + if (markhosted) + xp->flags |= INC_HOSTED; + message((-2, "search: %s -> %s%s%s", fp->name, pp.path, (pp.mode & MARKC) ? " [C]" : "", (pp.mode & MARKHOSTED) ? " [hosted]" : "")); +#if ARCHIVE + if (!pp.member) + { +#endif + fp->flags |= INC_BOUND(index); + fp->bound[index] = xp; + if ((index == INC_STANDARD || index == INC_VENDOR) && type != T_HEADER && !(fp->flags & INC_BOUND(INC_LOCAL))) + { + fp->flags |= INC_BOUND(INC_LOCAL); + fp->bound[INC_LOCAL] = xp; + } +#if ARCHIVE + } +#endif + xp->flags |= INC_SELF|INC_EXISTS; + if (flags & SEARCH_INCLUDE) + { + if ((pp.prefix = prefix) || (pp.prefix = pp.in->prefix)) + message((-2, "search: %s: prefix=%s", xp->name, pp.prefix)); + if (!(pp.mode & ALLMULTIPLE)) + { + if (xp->guard == INC_CLEAR || xp == mp) + xp->guard = INC_TEST; + else + { + if (pp.state & WARN) + error(1, "%s: ignored -- already included", xp->name); + else + message((-3, "%s: ignored -- already included", xp->name)); + xp->guard = fp->guard = INC_IGNORE; +#if ARCHIVE + if (!pp.member) +#endif + if (fd > 0) + close(fd); + if (flags & SEARCH_TEST) + pp.include = xp->name; + return 0; + } + } + pp.include = xp->name; + if ((pp.mode & (FILEDEPS|INIT)) == FILEDEPS && ((pp.mode & HEADERDEPS) || !(pp.mode & MARKHOSTED)) && !(xp->flags & INC_LISTED)) + { + xp->flags |= INC_LISTED; + if ((pp.column + strlen(xp->name)) >= COLUMN_MAX) + { + sfprintf(pp.filedeps.sp, " \\\n"); + pp.column = COLUMN_TAB; + index = '\t'; + } + else + index = ' '; + pp.column += sfprintf(pp.filedeps.sp, "%c%s", index, xp->name); + } + } + return fd; + } + if (xp) + xp->flags |= INC_SELF; + if (errno == EMFILE) + error(3, "%s: too many open files", fp->name); + else if (errno != ENOENT && errno != ENOTDIR) + error(ERROR_SYSTEM|1, "%s: cannot open file for reading", pp.path); + if (*fp->name == '/') + break; + } + strcpy(pp.path, fp->name); + message((-2, "search: %s%s not found", (flags & SEARCH_NEXT) ? "next " : "", fp->name)); + return -1; +} + +/* + * search for an include file + * if (flags&SEARCH_INCLUDE) then + * if file found then open read file descriptor returned + * with pp.path set to the full path and + * pp.prefix set to the directory prefix + * otherwise 0 returned if file found but ignored + * otherwise -1 returned + * otherwise + * if file found then 0 returned + * otherwise -1 returned + */ + +int +ppsearch(char* file, int type, int flags) +{ + register struct ppfile* fp; + register char* s; + register struct ppdirs* dp; + struct oplist* cp; + struct ppfile* xp; + int dospath; + int fd; + int index; + char name[MAXTOKEN + 1]; + + pp.include = 0; + fd = -1; + dospath = 0; + again: + pathcanon(file, 0); + for (cp = pp.chop; cp; cp = cp->next) + if (strneq(file, cp->value, cp->op)) + { + if (cp->value[cp->op + 1]) + { + sfsprintf(name, sizeof(name) - 1, "%s%s", cp->value + cp->op + 1, file + cp->op); + message((-3, "chop: %s -> %s", file, name)); + file = name; + } + else if (strchr(file + cp->op, '/')) + { + message((-3, "chop: %s -> %s", file, file + cp->op)); + file += cp->op; + } + break; + } + fp = ppsetfile(file); + while ((fp->flags & INC_MAPALL) || (fp->flags & INC_MAPHOSTED) && (pp.mode & HOSTED) || (fp->flags & INC_MAPNOHOSTED) && !(pp.mode & HOSTED)) + { + if (!(xp = fp->bound[type == T_HEADER ? INC_STANDARD : INC_LOCAL]) || xp == fp) + break; + message((-1, "map: %s -> %s", fp->name, xp->name)); + fp = xp; + } + if ((fp->flags & INC_MAPNOLOCAL) && (pp.mode & HOSTED)) + flags |= SEARCH_HOSTED; + else if (pp.vendor) + flags |= SEARCH_VENDOR; + pp.original = fp; + if (type == T_HEADER && strneq(fp->name, "...", 3) && (!fp->name[3] || fp->name[3] == '/')) + { + if (fp->name[3] == '/') + { + int n; + int m; + + n = strlen(error_info.file); + m = strlen(fp->name + 4); + if (n < m || !streq(fp->name + 4, error_info.file + n - m)) + { + if ((fd = ppsearch(fp->name + 4, type, flags|SEARCH_TEST)) < 0) + return -1; + if (fd > 0) + close(fd); + s = error_info.file; + error_info.file = pp.include; + fd = ppsearch(fp->name + 4, type, flags|SEARCH_NEXT); + error_info.file = s; + return fd; + } + file = error_info.file + n - m; + } + else if (file = strrchr(error_info.file, '/')) + file++; + else + file = error_info.file; + flags |= SEARCH_NEXT; +#if _HUH_2002_05_28 + if (pp.in->prefix) + { + sfsprintf(name, sizeof(name) - 1, "%s/%s", pp.in->prefix, file); + fp = ppsetfile(name); + if ((fd = ppsearch(fp->name, type, flags)) >= 0) + return fd; + } +#endif + fp = ppsetfile(file); + return ppsearch(fp->name, type, flags); + } + else if ((flags & SEARCH_INCLUDE) && fp->guard == INC_IGNORE) + { + strcpy(pp.path, fp->name); + message((-2, "%s: ignored", fp->name)); + return 0; + } + else if (!(flags & SEARCH_NEXT)) + flags |= SEARCH_SKIP; + pp.prefix = 0; + if (type == T_HEADER) + dp = pp.stddirs->next; + else + { + dp = pp.lcldirs; + if (dp == pp.firstdir) + { + /* + * look in directory of including file first + */ + + if (error_info.file && (s = strrchr(error_info.file, '/'))) + { + *s = 0; + dp->name = ppsetfile(error_info.file)->name; + *s = '/'; + } + else + dp->name = ""; + } + else if (pp.in->prefix && pp.lcldirs != pp.firstdir) + { + /* + * look in prefix directory of including file first + */ + + if (*fp->name != '/') + { + if ((s = strchr(fp->name, '/')) && (fp->name[0] +!= '.' || fp->name[1] != '.' || fp->name[2] != '/')) + { + *s = 0; + if (!streq(fp->name, pp.in->prefix)) + fd = 0; + *s = '/'; + } + else + fd = 0; + } + if (fd >= 0) + { + sfsprintf(name, sizeof(name) - 1, "%s/%s", pp.in->prefix, fp->name); + pathcanon(name, 0); + xp = ppsetfile(name); + if ((fd = search(xp, dp, type, flags)) >= 0) + return fd; + } + } + } + if ((fd = search(fp, dp, type, flags)) < 0) + { + if ((pp.option & PLUSPLUS) && file != pp.tmpbuf) + { + s = file + strlen(file); + while (s > file && *--s != '/' && *s != '\\' && *s != '.'); + if (*s != '.') + { + sfsprintf(pp.tmpbuf, MAXTOKEN, "%s.h", file); + file = pp.tmpbuf; + goto again; + } + } + + /* + * hackery for msdos files viewed through unix + */ + + switch (dospath) + { + case 0: + if (s = strchr(file, '\\')) + { + do *s++ = '/'; while (s = strchr(s, '\\')); + pathcanon(file, 0); + dospath = 1; + goto again; + } + /*FALLTHROUGH*/ + case 1: + if (ppisid(file[0]) && file[1] == ':' && file[2] == '/') + { + file[1] = file[0]; + file[0] = '/'; + pathcanon(file, 0); + dospath = 2; + goto again; + } + break; + case 2: + file += 2; + goto again; + } + if ((flags & (SEARCH_INCLUDE|SEARCH_NEXT)) == SEARCH_INCLUDE) + { + if (!(pp.mode & GENDEPS)) + { + if (!(pp.option & ALLPOSSIBLE) || pp.in->prev->prev) + error(2, "%s: cannot find include file", file); + } + else if (!(pp.mode & INIT)) + { + xp = ppsetfile(file); + if (!(xp->flags & INC_LISTED)) + { + xp->flags |= INC_LISTED; + if ((pp.column + strlen(file)) >= COLUMN_MAX) + { + sfprintf(pp.filedeps.sp, " \\\n"); + pp.column = COLUMN_TAB; + index = '\t'; + } + else + index = ' '; + pp.column += sfprintf(pp.filedeps.sp, "%c%s", index, file); + } + } + } + } + return fd; +} |