--- tccpp.c 2023-07-05 19:28:58.000000000 +0200 +++ tccpp_patched.c 2023-07-29 15:48:08.919820600 +0200 @@ -51,6 +51,7 @@ static int pp_once; static int pp_expr; static int pp_counter; +static char pp_wd[1024]; static void tok_print(const char *msg, const int *str); static struct TinyAlloc *toksym_alloc; @@ -1629,77 +1630,98 @@ } #endif +unsigned char* normlizepath (const char *filename) { + // + char fullname[sizeof(pp_wd)]; + unsigned char *s, *t, *f, *e; + + if (IS_DIRSEP (filename[0])) + pstrcpy (fullname, sizeof(fullname), filename); + else { + pstrcpy (fullname, sizeof(fullname), pp_wd); + pstrcat (fullname, sizeof(fullname), "/"); + pstrcat (fullname, sizeof(fullname), filename); + } +#ifdef _WIN32 + normalize_slashes(fullname); +#endif + /* Skip possible drive letter */ + f = (unsigned char *) fullname; + while (*f != '/') + f++; + s = f; + t = f; + while (*s) { + if (*s == '/') { + *t++ = *s++; + while (*s == '/') { + s++; + } + } + if (s[0] == '.' && s[1] == '/') + s += 2; + else if (s[0] == '.' && s[1] == '.' && s[2] == '/') { + s += 3; + if (t > (f + 1) && t[-1] == '/') + t--; + while (t > (f + 1) && t[-1] != '/') + t--; + } + else + while (*s && *s != '/') { + *t++ = *s++; + } + } + *t = '\0'; + e = tcc_malloc(sizeof(fullname)); + strcpy(e, fullname); + return e; +} + static CachedInclude *search_cached_include(TCCState *s1, const char *filename, int add) { unsigned int h = 0; CachedInclude *e; int i; - struct stat st; -#ifdef _WIN32 - unsigned long long hash = 0; -#endif + unsigned char *s0, *s; - /* This is needed for #pragmae once - * We cannot use stat on windows because st_ino is not set correctly - * so we calculate a hash of file contents. - * This also works for hard/soft links as in gcc/clang. - */ - memset (&st, 0, sizeof(st)); - if (stat (filename, &st)) - goto skip; - h = st.st_size & (CACHED_INCLUDES_HASH_SIZE - 1); + h = TOK_HASH_INIT; + //s = (unsigned char *) fullname; + s=s0= normlizepath(filename); + //printf("filename %s fullname %s\n",filename,s); + while (*s) { #ifdef _WIN32 - /* Only calculate file hash if file size same. */ - i = s1->cached_includes_hash[h]; - for(;;) { - if (i == 0) - break; - e = s1->cached_includes[i - 1]; - if (e->st.st_size == st.st_size) { - if (0 == PATHCMP(e->filename, filename)) { - hash = e->hash; - break; - } - if (e->hash == 0) - e->hash = calc_file_hash(e->filename); - if (hash == 0) - hash = calc_file_hash(filename); - } - i = e->hash_next; - } + h = TOK_HASH_FUNC(h, toup(*s)); +#else + h = TOK_HASH_FUNC(h, *s); #endif + s++; + } + h &= (CACHED_INCLUDES_HASH_SIZE - 1); i = s1->cached_includes_hash[h]; for(;;) { if (i == 0) break; e = s1->cached_includes[i - 1]; -#ifdef _WIN32 - if (e->st.st_size == st.st_size && e->hash == hash) -#else - if (st.st_dev == e->st.st_dev && st.st_ino == e->st.st_ino) -#endif + if (0 == PATHCMP(e->filename, s0)) return e; i = e->hash_next; } -skip: if (!add) return NULL; - e = tcc_malloc(sizeof(CachedInclude) + strlen(filename)); - e->st = st; -#ifdef _WIN32 - e->hash = hash; -#endif - strcpy(e->filename, filename); + e = tcc_malloc(sizeof(CachedInclude) + strlen(s0)); + strcpy(e->filename, s0); e->ifndef_macro = e->once = 0; dynarray_add(&s1->cached_includes, &s1->nb_cached_includes, e); /* add in hash table */ 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); +#ifdef INC_DEBUG + printf("adding cached '%s' hash %d\n", e->filename,h); #endif + tcc_free(s0); return e; } @@ -3709,6 +3731,7 @@ parse_flags = is_asm ? PARSE_FLAG_ASM_FILE : 0; tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; + getcwd(pp_wd, sizeof(pp_wd)); } /* cleanup from error/setjmp */