fix "cached include" optimization

comparing the filenames as in the #include statement can be
ambiguous if including files are in different directories.

Now caches and checks the really opened filename instead.
tcc-xref
grischka 2009-05-11 18:55:16 +02:00
parent 530b77e365
commit aed6a7cb60
1 changed files with 59 additions and 54 deletions

113
tccpp.c
View File

@ -1190,13 +1190,10 @@ static void pragma_parse(TCCState *s1)
static void preprocess(int is_bof) static void preprocess(int is_bof)
{ {
TCCState *s1 = tcc_state; TCCState *s1 = tcc_state;
int size, i, c, n, saved_parse_flags; int i, c, n, saved_parse_flags;
char buf[1024], *q; char buf[1024], *q;
char buf1[1024];
BufferedFile *f;
Sym *s; Sym *s;
CachedInclude *e;
saved_parse_flags = parse_flags; saved_parse_flags = parse_flags;
parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
PARSE_FLAG_LINEFEED; PARSE_FLAG_LINEFEED;
@ -1275,70 +1272,76 @@ static void preprocess(int is_bof)
} }
} }
e = search_cached_include(s1, c, buf); if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
if (e && define_find(e->ifndef_macro)) { error("#include recursion too deep");
/* no need to parse the include because the 'ifndef macro'
is defined */
#ifdef INC_DEBUG
printf("%s: skipping %s\n", file->filename, buf);
#endif
} else {
if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
error("#include recursion too deep");
/* push current file in stack */
/* XXX: fix current line init */
*s1->include_stack_ptr++ = file;
/* check absolute include path */ n = s1->nb_include_paths + s1->nb_sysinclude_paths;
if (IS_ABSPATH(buf)) { for (i = -2; i < n; ++i) {
f = tcc_open(s1, buf); char buf1[sizeof file->filename];
if (f) BufferedFile *f;
goto found; CachedInclude *e;
} const char *path;
if (c == '\"') { int size;
/* first search in current dir if "header.h" */
if (i == -2) {
/* check absolute include path */
if (!IS_ABSPATH(buf))
continue;
buf1[0] = 0;
} else if (i == -1) {
/* search in current dir if "header.h" */
if (c != '\"')
continue;
size = tcc_basename(file->filename) - file->filename; size = tcc_basename(file->filename) - file->filename;
if (size > sizeof(buf1) - 1)
size = sizeof(buf1) - 1;
memcpy(buf1, file->filename, size); memcpy(buf1, file->filename, size);
buf1[size] = '\0'; buf1[size] = '\0';
pstrcat(buf1, sizeof(buf1), buf);
f = tcc_open(s1, buf1); } else {
if (f) { /* search in all the include paths */
if (tok == TOK_INCLUDE_NEXT)
tok = TOK_INCLUDE;
else
goto found;
}
}
/* now search in all the include paths */
n = s1->nb_include_paths + s1->nb_sysinclude_paths;
for(i = 0; i < n; i++) {
const char *path;
if (i < s1->nb_include_paths) if (i < s1->nb_include_paths)
path = s1->include_paths[i]; path = s1->include_paths[i];
else else
path = s1->sysinclude_paths[i - s1->nb_include_paths]; path = s1->sysinclude_paths[i - s1->nb_include_paths];
pstrcpy(buf1, sizeof(buf1), path); pstrcpy(buf1, sizeof(buf1), path);
pstrcat(buf1, sizeof(buf1), "/"); pstrcat(buf1, sizeof(buf1), "/");
pstrcat(buf1, sizeof(buf1), buf);
f = tcc_open(s1, buf1);
if (f) {
if (tok == TOK_INCLUDE_NEXT)
tok = TOK_INCLUDE;
else
goto found;
}
} }
--s1->include_stack_ptr;
error("include file '%s' not found", buf); pstrcat(buf1, sizeof(buf1), buf);
break;
found: e = search_cached_include(s1, c, buf1);
if (e && define_find(e->ifndef_macro)) {
/* no need to parse the include because the 'ifndef macro'
is defined */
#ifdef INC_DEBUG
printf("%s: skipping %s\n", file->filename, buf);
#endif
f = NULL;
} else {
f = tcc_open(s1, buf1);
if (!f)
continue;
}
if (tok == TOK_INCLUDE_NEXT) {
tok = TOK_INCLUDE;
if (f)
tcc_close(f);
continue;
}
if (!f)
goto include_done;
#ifdef INC_DEBUG #ifdef INC_DEBUG
printf("%s: including %s\n", file->filename, buf1); printf("%s: including %s\n", file->filename, buf1);
#endif #endif
/* XXX: fix current line init */
/* push current file in stack */
*s1->include_stack_ptr++ = file;
f->inc_type = c; f->inc_type = c;
pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf); pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf1);
file = f; file = f;
/* add include file debug info */ /* add include file debug info */
if (tcc_state->do_debug) { if (tcc_state->do_debug) {
@ -1348,6 +1351,8 @@ static void preprocess(int is_bof)
ch = file->buf_ptr[0]; ch = file->buf_ptr[0];
goto the_end; goto the_end;
} }
error("include file '%s' not found", buf);
include_done:
break; break;
case TOK_IFNDEF: case TOK_IFNDEF:
c = 1; c = 1;