fix for the #include_next, v4 (final)

This version looks rigth. Comparing to the original
    algorithm:

    1) Loop breaking. We remember a start point after wich
    we can try next path. Do not search include stack after
    this.

    2) But compare next file patch with the start point.
    Skip if it the same. Remove "./" before comparing.

    PS: a problems with compaling a coreutils-8.24.51-8802e
    remain. There are errors messages like:
    src/chgrp
        src/chown-core.c:42: multiple definition of `make_timespec'
        src/chgrp.c:42: first defined here
    A problem is in the lib/config.h
        #define _GL_INLINE_ extern inline // gcc
        #define _GL_INLINE_ inline        // tcc

    A long description from the lib/config.h
    * suppress extern inline with HP-UX cc, as it appears to be broken
    * suppress extern inline with Sun C in standards-conformance mode
    * suppress extern inline on configurations that mistakenly use
      'static inline' to implement functions or macros in standard
      C headers like <ctype.h>.

    GCC and Clang are excluded from this list. Why not tcc?
master
seyko 2015-10-20 07:32:53 +03:00
parent ad1c01f96c
commit 003c532bf3
1 changed files with 54 additions and 19 deletions

73
tccpp.c
View File

@ -1528,7 +1528,7 @@ ST_FUNC void preprocess(int is_bof)
int i, c, n, saved_parse_flags;
char buf[1024], *q;
Sym *s;
int include_next_count = 0;
char *p3 = 0;
saved_parse_flags = parse_flags;
parse_flags = PARSE_FLAG_PREPROCESS
@ -1618,6 +1618,11 @@ ST_FUNC void preprocess(int is_bof)
/* store current file in stack, but increment stack later below */
*s1->include_stack_ptr = file;
#ifdef INC_DEBUG
if (tok == TOK_INCLUDE_NEXT)
printf("%s (1) include_next file %s\n", file->filename, buf);
#endif
n = s1->nb_include_paths + s1->nb_sysinclude_paths;
for (i = -2; i < n; ++i) {
char buf1[sizeof file->filename];
@ -1649,36 +1654,67 @@ ST_FUNC void preprocess(int is_bof)
pstrcat(buf1, sizeof(buf1), "/");
}
#ifdef INC_DEBUG
if (tok == TOK_INCLUDE_NEXT)
printf("%s (2) include_next path <%s> name <%s>\n", file->filename, buf1, buf);
#endif
pstrcat(buf1, sizeof(buf1), buf);
if (tok == TOK_INCLUDE_NEXT) {
for (f = s1->include_stack_ptr; f >= s1->include_stack; --f)
if (0 == PATHCMP((*f)->filename, buf1)) {
#ifdef INC_DEBUG
printf("%s: #include_next skipping %s\n", file->filename, buf1);
#endif
include_next_count++;
char *p1 = buf1;
if ((p1[0] == '.') && IS_DIRSEP(p1[1])) p1 += 2;
if (p3) {
if (0 == PATHCMP(p1, p3)) {
#ifdef INC_DEBUG
printf("%s (3) include_next skipping <%s>\n", file->filename, p1);
#endif
goto include_trynext;
}
}
else {
for (f = s1->include_stack_ptr; f >= s1->include_stack; --f) {
char *p2 = (*f)->filename;
if ((p2[0] == '.') && IS_DIRSEP(p2[1])) p2 += 2;
if (0 == PATHCMP(p2, p1)) {
p3 = p2;
break;
}
}
#ifdef INC_DEBUG
printf("%s: (4) include_next skipping <%s> (p3=%p)\n", file->filename, buf1, p3);
#endif
goto include_trynext;
}
#ifdef INC_DEBUG
printf("%s (5) include_next considering <%s>\n", file->filename, buf1);
#endif
}
e = search_cached_include(s1, buf1);
if (e && (define_find(e->ifndef_macro) || e->ifndef_macro == TOK_once)) {
/* no need to parse the include because the 'ifndef macro'
is defined */
#ifdef INC_DEBUG
printf("%s: skipping cached %s\n", file->filename, buf1);
#endif
#ifdef INC_DEBUG
printf("%s: skipping cached <%s>\n", file->filename, buf1);
#endif
goto include_done;
}
if (tcc_open(s1, buf1) < 0)
if (tcc_open(s1, buf1) < 0) {
#ifdef INC_DEBUG
printf("%s: include open failed <%s>\n", file->filename, buf1);
#endif
include_trynext:
continue;
}
#ifdef INC_DEBUG
printf("%s: including <%s>\n", file->prev->filename, file->filename);
#endif
#ifdef INC_DEBUG
printf("%s: including %s\n", file->prev->filename, file->filename);
#endif
/* update target deps */
dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
tcc_strdup(buf1));
@ -1691,8 +1727,7 @@ include_trynext:
ch = file->buf_ptr[0];
goto the_end;
}
if (include_next_count == 0)
tcc_error("include file '%s' not found", buf);
tcc_error("include file '%s' not found", buf);
include_done:
break;
case TOK_IFNDEF:
@ -1709,9 +1744,9 @@ include_done:
tcc_error("invalid argument for '#if%sdef'", c ? "n" : "");
if (is_bof) {
if (c) {
#ifdef INC_DEBUG
printf("#ifndef %s\n", get_tok_str(tok, NULL));
#endif
#ifdef INC_DEBUG
printf("#ifndef %s\n", get_tok_str(tok, NULL));
#endif
file->ifndef_macro = tok;
}
}