diff options
author | ragge <ragge> | 2009-12-31 11:46:13 +0000 |
---|---|---|
committer | ragge <ragge> | 2009-12-31 11:46:13 +0000 |
commit | c0199e5a6297875646a8ada4f9cf169634e9e1bb (patch) | |
tree | 930e8808674bf2f43ae29814cb7c5a4b49df2bdb | |
parent | 6c327e7cf3d36a5cbba11b352857025c544deb91 (diff) |
Understand gcc directive #include_next. Solves Jira#PCC-106 by Altamiranus.
-rw-r--r-- | cpp.c | 60 | ||||
-rw-r--r-- | cpp.h | 5 | ||||
-rw-r--r-- | token.c | 13 |
3 files changed, 59 insertions, 19 deletions
@@ -171,6 +171,7 @@ static void expdef(usch *proto, struct recur *, int gotwarn); void define(void); static int canexpand(struct recur *, struct symtab *np); void include(void); +void include_next(void); void line(void); void flbuf(void); void usage(void); @@ -185,6 +186,7 @@ main(int argc, char **argv) struct incs *w, *w2; struct symtab *nl; register int ch; + usch *fn1, *fn2; #ifdef TIMING struct timeval t1, t2; @@ -316,7 +318,13 @@ main(int argc, char **argv) ofd = 1; /* stdout */ istty = isatty(ofd); - if (pushfile((usch *)(argc && strcmp(argv[0], "-") ? argv[0] : NULL))) + if (argc && strcmp(argv[0], "-")) { + fn1 = fn2 = (usch *)argv[0]; + } else { + fn1 = NULL; + fn2 = (usch *)""; + } + if (pushfile(fn1, fn2, 0, NULL)) error("cannot open %s", argv[0]); flbuf(); @@ -485,6 +493,31 @@ bad: error("bad line directive"); } /* + * Search for and include next file. + * Return 1 on success. + */ +static int +fsrch(usch *fn, int idx, struct incs *w) +{ + int i; + + for (i = idx; i < 2; i++) { + if (i > idx) + w = incdir[i]; + for (; w; w = w->next) { + usch *nm = stringbuf; + + savstr(w->dir); savch('/'); + savstr(fn); savch(0); + if (pushfile(nm, fn, i, w->next) == 0) + return 1; + stringbuf = nm; + } + } + return 0; +} + +/* * Include a file. Include order: * - For <...> files, first search -I directories, then system directories. * - For "..." files, first search "current" dir, then as <...> files. @@ -493,10 +526,9 @@ void include() { struct symtab *nl; - struct incs *w; usch *osp; usch *fn, *safefn; - int i, c, it; + int c, it; if (flslvl) return; @@ -549,23 +581,14 @@ include() c = yylex(); if (c != '\n') goto bad; - if (pushfile(nm) == 0) + if (pushfile(nm, safefn, 0, NULL) == 0) goto okret; /* XXX may loose stringbuf space */ } - /* create search path and try to open file */ - for (i = 0; i < 2; i++) { - for (w = incdir[i]; w; w = w->next) { - usch *nm = stringbuf; + if (fsrch(safefn, 0, incdir[0])) + goto okret; - savstr(w->dir); savch('/'); - savstr(safefn); savch(0); - if (pushfile(nm) == 0) - goto okret; - stringbuf = nm; - } - } error("cannot find '%s'", safefn); /* error() do not return */ @@ -575,6 +598,13 @@ okret: prtline(); } +void +include_next() +{ + if (fsrch(ifiles->fn, ifiles->idx, ifiles->incs) == 0) + error("cannot find '%s'", ifiles->fn); +} + static int definp(void) { @@ -78,6 +78,9 @@ struct includ { usch *maxread; usch *ostr; usch *buffer; + int idx; + void *incs; + usch *fn; usch bbuf[NAMEMAX+CPPBUF+1]; } *ifiles; @@ -118,7 +121,7 @@ struct symtab *lookup(usch *namep, int enterf); usch *gotident(struct symtab *nl); int slow; /* scan slowly for new tokens */ -int pushfile(usch *fname); +int pushfile(usch *fname, usch *fn, int idx, void *incs); void popfile(void); void prtline(void); int yylex(void); @@ -71,6 +71,7 @@ static void badop(const char *); static int chktg(void); static void ppdir(void); void include(void); +void include_next(void); void define(void); static int inpch(void); @@ -672,7 +673,7 @@ prinit(struct initar *it, struct includ *ic) * Return 0 on success, -1 if file to be included is not found. */ int -pushfile(usch *file) +pushfile(usch *file, usch *fn, int idx, void *incs) { extern struct initar *initar; struct includ ibuf; @@ -697,6 +698,9 @@ pushfile(usch *file) ifiles = ic; ic->lineno = 1; ic->maxread = ic->curptr; + ic->idx = idx; + ic->incs = incs; + ic->fn = fn; prtline(); if (initar) { *ic->maxread = 0; @@ -1117,6 +1121,9 @@ static struct { { "line", line }, { "pragma", pragmastmt }, { "elif", elifstmt }, +#ifdef GCC_COMPAT + { "include_next", include_next }, +#endif }; /* @@ -1125,7 +1132,7 @@ static struct { void ppdir(void) { - char bp[10]; + char bp[20]; int ch, i; while ((ch = inch()) == ' ' || ch == '\t') @@ -1138,7 +1145,7 @@ ppdir(void) if (i == sizeof(bp)-1) goto out; /* too long */ ch = inch(); - } while (ch >= 'a' && ch <= 'z'); + } while ((ch >= 'a' && ch <= 'z') || (ch == '_')); unch(ch); bp[i++] = 0; |