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