tccpp: #pragma once: make it work

after several "fixes" and "improvements"
   b3782c3cf5
   5fb57bead4
feature did not work at all

- Use 'once' flag, not 'ifndef_macro'
- Ignore filename letter case on _WIN32
- Increment global pp_once for each compilation
master
grischka 2016-10-01 20:03:48 +02:00
parent 07e47b3dd6
commit 3ddbfe1a82
2 changed files with 25 additions and 37 deletions

4
tcc.h
View File

@ -101,7 +101,6 @@
# define IS_DIRSEP(c) (c == '/' || c == '\\')
# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
# define PATHCMP stricmp
# define PATH_NOCASE
#else
# define IS_DIRSEP(c) (c == '/')
# define IS_ABSPATH(p) IS_DIRSEP(p[0])
@ -602,11 +601,12 @@ typedef struct InlineFunc {
inclusion if the include file is protected by #ifndef ... #endif */
typedef struct CachedInclude {
int ifndef_macro;
int once;
int hash_next; /* -1 if none */
char filename[1]; /* path specified in #include */
} CachedInclude;
#define CACHED_INCLUDES_HASH_SIZE 512
#define CACHED_INCLUDES_HASH_SIZE 32
#ifdef CONFIG_TCC_ASM
typedef struct ExprValue {

58
tccpp.c
View File

@ -50,6 +50,7 @@ static CString cstr_buf;
static TokenString tokstr_buf;
static unsigned char isidnum_table[256 - CH_EOF];
static int pp_debug_tok, pp_debug_symv;
static int pp_once;
static void tok_print(const char *msg, const int *str);
/* isidnum_table flags: */
@ -1474,26 +1475,25 @@ bad_twosharp:
define_push(v, t, &tokstr_buf, first);
}
static inline int hash_cached_include(const char *filename)
static CachedInclude *search_cached_include(TCCState *s1, const char *filename, int add)
{
const unsigned char *s;
unsigned int h;
CachedInclude *e;
int i;
h = TOK_HASH_INIT;
s = (unsigned char *) filename;
while (*s) {
#ifdef _WIN32
h = TOK_HASH_FUNC(h, toup(*s));
#else
h = TOK_HASH_FUNC(h, *s);
#endif
s++;
}
h &= (CACHED_INCLUDES_HASH_SIZE - 1);
return h;
}
static CachedInclude *search_cached_include(TCCState *s1, const char *filename)
{
CachedInclude *e;
int i, h;
h = hash_cached_include(filename);
i = s1->cached_includes_hash[h];
for(;;) {
if (i == 0)
@ -1503,31 +1503,22 @@ static CachedInclude *search_cached_include(TCCState *s1, const char *filename)
return e;
i = e->hash_next;
}
return NULL;
}
if (!add)
return NULL;
static inline void add_cached_include(TCCState *s1, const char *filename, int ifndef_macro)
{
CachedInclude *e;
int h;
if (search_cached_include(s1, filename))
return;
#ifdef INC_DEBUG
printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
#endif
e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
strcpy(e->filename, filename);
e->ifndef_macro = ifndef_macro;
e->ifndef_macro = e->once = 0;
dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
/* add in hash table */
h = hash_cached_include(filename);
e->hash_next = s1->cached_includes_hash[h];
s1->cached_includes_hash[h] = s1->nb_cached_includes;
#ifdef INC_DEBUG
printf("adding cached '%s'\n", filename);
#endif
return e;
}
#define ONCE_PREFIX "#ONCE#"
static void pragma_parse(TCCState *s1)
{
next_nomacro();
@ -1560,13 +1551,8 @@ static void pragma_parse(TCCState *s1)
pp_debug_tok = t, pp_debug_symv = v;
} else if (tok == TOK_once) {
char buf1[sizeof(file->filename) + sizeof(ONCE_PREFIX)];
strcpy(buf1, ONCE_PREFIX);
strcat(buf1, file->filename);
#ifdef PATH_NOCASE
strupr(buf1);
#endif
add_cached_include(s1, file->filename, tok_alloc(buf1, strlen(buf1))->tok);
search_cached_include(s1, file->filename, 1)->once = pp_once;
} else if (s1->ppfp) {
/* tcc -E: keep pragmas below unchanged */
unget_tok(' ');
@ -1767,10 +1753,10 @@ ST_FUNC void preprocess(int is_bof)
}
pstrcat(buf1, sizeof(buf1), buf);
e = search_cached_include(s1, buf1);
if (e && define_find(e->ifndef_macro)) {
e = search_cached_include(s1, buf1, 0);
if (e && (define_find(e->ifndef_macro) || e->once == pp_once)) {
/* no need to parse the include because the 'ifndef macro'
is defined */
is defined (or had #pragma once) */
#ifdef INC_DEBUG
printf("%s: skipping cached %s\n", file->filename, buf1);
#endif
@ -2484,7 +2470,8 @@ static inline void next_nomacro1(void)
#ifdef INC_DEBUG
printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
#endif
add_cached_include(s1, file->filename, file->ifndef_macro_saved);
search_cached_include(s1, file->filename, 1)
->ifndef_macro = file->ifndef_macro_saved;
tok_flags &= ~TOK_FLAG_ENDIF;
}
@ -3445,6 +3432,7 @@ ST_FUNC void preprocess_init(TCCState *s1)
file->ifdef_stack_ptr ? */
s1->ifdef_stack_ptr = s1->ifdef_stack;
file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
pp_once++;
pvtop = vtop = vstack - 1;
s1->pack_stack[0] = 0;