mirror of
https://github.com/frida/tinycc
synced 2024-12-24 22:16:49 +03:00
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
This commit is contained in:
parent
07e47b3dd6
commit
3ddbfe1a82
4
tcc.h
4
tcc.h
@ -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
58
tccpp.c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user