From df9cce24a87442079d878978e56caa0787f37e1a Mon Sep 17 00:00:00 2001 From: grischka Date: Mon, 1 Aug 2011 01:10:36 +0200 Subject: [PATCH] Accept colon separated paths with -L and -I This allows passing colon separated paths to tcc_add_library_path tcc_add_sysinclude_path tcc_add_include_path Also there are new configure variables CONFIG_TCC_LIBPATH CONFIG_TCC_SYSINCLUDE_PATHS which define the lib/sysinclude paths all in one and can be overridden from configure/make For TCC_TARGET_PE semicolons (;) are used as separators Also, \b in the path string is replaced by s->tcc_lib_path (CONFIG_TCCDIR rsp. -B option) --- Makefile | 11 +++- libtcc.c | 163 +++++++++++++++++++------------------------------------ tcc.h | 47 ++++++++++++---- tccelf.c | 13 +---- tccgen.c | 9 +++ 5 files changed, 111 insertions(+), 132 deletions(-) diff --git a/Makefile b/Makefile index f60f465..453748c 100644 --- a/Makefile +++ b/Makefile @@ -159,10 +159,15 @@ tcc$(EXESUF): tcc.o $(LIBTCC) %-tcc$(EXESUF): $(CC) -o $@ tcc.c -DONE_SOURCE $(DEFINES) $(CFLAGS) $(LIBS) $(LDFLAGS) -$(I386_CROSS): DEFINES = -DTCC_TARGET_I386 -DCONFIG_TCCDIR="\"$(tccdir)/i386\"" +$(I386_CROSS): DEFINES = -DTCC_TARGET_I386 \ + -DCONFIG_TCCDIR="\"$(tccdir)/i386\"" $(X64_CROSS): DEFINES = -DTCC_TARGET_X86_64 -$(WIN32_CROSS): DEFINES = -DTCC_TARGET_I386 -DTCC_TARGET_PE -DCONFIG_TCCDIR="\"$(tccdir)/win32\"" -DCONFIG_TCC_CROSSLIB="\"lib/32\"" -$(WIN64_CROSS): DEFINES = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DCONFIG_TCCDIR="\"$(tccdir)/win32\"" -DCONFIG_TCC_CROSSLIB="\"lib/64\"" +$(WIN32_CROSS): DEFINES = -DTCC_TARGET_I386 -DTCC_TARGET_PE \ + -DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \ + -DCONFIG_TCC_LIBPATH="\"\b/lib/32;\b/lib\"" +$(WIN64_CROSS): DEFINES = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE \ + -DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \ + -DCONFIG_TCC_LIBPATH="\"\b/lib/64;\b/lib\"" $(WINCE_CROSS): DEFINES = -DTCC_TARGET_PE $(C67_CROSS): DEFINES = -DTCC_TARGET_C67 $(ARM_FPA_CROSS): DEFINES = -DTCC_TARGET_ARM diff --git a/libtcc.c b/libtcc.c index 0488f33..34b6daf 100644 --- a/libtcc.c +++ b/libtcc.c @@ -111,6 +111,13 @@ static void tcc_set_lib_path_w32(TCCState *s) tcc_set_lib_path(s, path); } +static void tcc_add_systemdir(TCCState *s) +{ + char buf[1000]; + GetSystemDirectory(buf, sizeof buf); + tcc_add_library_path(s, buf); +} + #ifndef CONFIG_TCC_STATIC void dlclose(void *p) { @@ -159,11 +166,18 @@ PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s) return buf; } +PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num) +{ + memcpy(out, in, num); + out[num] = '\0'; + return out; +} + /* extract the basename of a file */ PUB_FUNC char *tcc_basename(const char *name) { char *p = strchr(name, 0); - while (p > name && !IS_PATHSEP(p[-1])) + while (p > name && !IS_DIRSEP(p[-1])) --p; return p; } @@ -293,39 +307,37 @@ PUB_FUNC void dynarray_reset(void *pp, int *n) } /* out must not point to a valid dynarray since a new one is created */ -PUB_FUNC int tcc_split_path(const char *in, const char * const *prefixs, - int nb_prefixs, char ***out) +static void tcc_split_path(TCCState *s, void ***p_ary, int *p_nb_ary, const char *in) { - int i, nb_comps = 0; - char *path; - const char *end; - size_t size; - - *out = NULL; + const char *p; do { - end = in; - while (*end && *end != ':') - ++end; - for (i = 0; i < nb_prefixs; i++) { - size = (strlen(prefixs[i]) + 1) * sizeof(char) - + (end - in); - path = tcc_malloc(size); - pstrcpy(path, size, prefixs[i]); - pstrcat(path, size, in); - dynarray_add((void ***) out, &nb_comps, path); - } - in = end + 1; - } while (*end); - return nb_comps; -} + const char *r = NULL; + int c; + CString str; -/* we use our own 'finite' function to avoid potential problems with - non standard math libs */ -/* XXX: endianness dependent */ -ST_FUNC int ieee_finite(double d) -{ - int *p = (int *)&d; - return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; + cstr_new(&str); + for (p = in;;) { + if (r) { + if ((c = *r++) == 0) { + r = NULL; + continue; + } + } else if ((c = *p++) == 0) { + ; + } else if (c == PATHSEP) { + c = 0; + } else if (c == '\b') { + r = s->tcc_lib_path; + continue; + } + cstr_ccat(&str, c); + if (0 == c) + break; + } + //printf("path: %s\n", (char*)str.data); + dynarray_add(p_ary, p_nb_ary, str.data); + in = p; + } while (p[-1]); } /********************************************************/ @@ -994,27 +1006,7 @@ LIBTCCAPI TCCState *tcc_new(void) #ifndef TCC_TARGET_PE /* default library paths */ - tcc_add_library_path(s, CONFIG_TCC_CRT_PREFIX); - tcc_add_library_path(s, CONFIG_SYSROOT CONFIG_TCC_LDDIR); - tcc_add_library_path(s, CONFIG_SYSROOT "/usr/local"CONFIG_TCC_LDDIR); -#ifdef CONFIG_TCC_EXTRA_LDDIR - { - int i, nb_extra_lddirs, nb_prefixs; - char **extra_lddirs; - char extra_lddir_str[] = CONFIG_TCC_EXTRA_LDDIR; - const char lddir_prefix1[] = CONFIG_SYSROOT; - const char lddir_prefix2[] = CONFIG_SYSROOT "/usr/local"; - const char * const lddir_prefixs[] = {lddir_prefix1, lddir_prefix2}; - - nb_prefixs = sizeof lddir_prefixs / sizeof *lddir_prefixs; - nb_extra_lddirs = tcc_split_path(CONFIG_TCC_EXTRA_LDDIR, - lddir_prefixs, nb_prefixs, - &extra_lddirs); - for (i = 0; i < nb_extra_lddirs; i++) - tcc_add_library_path(s, extra_lddirs[i]); - dynarray_reset(&extra_lddirs, &nb_extra_lddirs); - } -#endif + tcc_add_library_path(s, CONFIG_TCC_LIBPATH); #endif /* no section zero */ @@ -1101,21 +1093,15 @@ LIBTCCAPI void tcc_delete(TCCState *s1) tcc_free(s1); } -LIBTCCAPI int tcc_add_include_path(TCCState *s1, const char *pathname) +LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname) { - char *pathname1; - - pathname1 = tcc_strdup(pathname); - dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1); + tcc_split_path(s, (void ***)&s->include_paths, &s->nb_include_paths, pathname); return 0; } -LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s1, const char *pathname) +LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) { - char *pathname1; - - pathname1 = tcc_strdup(pathname); - dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1); + tcc_split_path(s, (void ***)&s->sysinclude_paths, &s->nb_sysinclude_paths, pathname); return 0; } @@ -1252,10 +1238,7 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) { - char *pathname1; - - pathname1 = tcc_strdup(pathname); - dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1); + tcc_split_path(s, (void ***)&s->library_paths, &s->nb_library_paths, pathname); return 0; } @@ -1318,37 +1301,12 @@ LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val) LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) { - char buf[1024]; - s->output_type = output_type; if (!s->nostdinc) { /* default include paths */ /* -isystem paths have already been handled */ -#ifndef TCC_TARGET_PE - { - int i, nb_extra_incdirs, nb_prefixs; - char **extra_incdirs; - const char incdir_prefix1[] = CONFIG_SYSROOT "/usr/local/include"; - const char incdir_prefix2[] = CONFIG_SYSROOT "/usr/include"; - const char * const incdir_prefixs[] = {incdir_prefix1, - incdir_prefix2}; - - nb_prefixs = sizeof incdir_prefixs / sizeof *incdir_prefixs; - nb_extra_incdirs = tcc_split_path(CONFIG_TCC_INCSUBDIR, - incdir_prefixs, nb_prefixs, - &extra_incdirs); - for (i = 0; i < nb_extra_incdirs; i++) - tcc_add_sysinclude_path(s, extra_incdirs[i]); - dynarray_reset(&extra_incdirs, &nb_extra_incdirs); - } -#endif - snprintf(buf, sizeof(buf), "%s/include", s->tcc_lib_path); - tcc_add_sysinclude_path(s, buf); -#ifdef TCC_TARGET_PE - snprintf(buf, sizeof(buf), "%s/include/winapi", s->tcc_lib_path); - tcc_add_sysinclude_path(s, buf); -#endif + tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDE_PATHS); } /* if bound checking, then add corresponding sections */ @@ -1381,7 +1339,12 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) } /* add libc crt1/crti objects */ -#ifndef TCC_TARGET_PE +#ifdef TCC_TARGET_PE + tcc_add_library_path(s, CONFIG_TCC_LIBPATH); +# ifdef _WIN32 + tcc_add_systemdir(s); +# endif +#else if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && !s->nostdlib) { if (output_type != TCC_OUTPUT_DLL) @@ -1389,20 +1352,6 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o"); } #endif - -#ifdef TCC_TARGET_PE -#ifdef CONFIG_TCC_CROSSLIB - snprintf(buf, sizeof(buf), "%s/" CONFIG_TCC_CROSSLIB, s->tcc_lib_path); - tcc_add_library_path(s, buf); -#endif - snprintf(buf, sizeof(buf), "%s/lib", s->tcc_lib_path); - tcc_add_library_path(s, buf); -#ifdef _WIN32 - if (GetSystemDirectory(buf, sizeof buf)) - tcc_add_library_path(s, buf); -#endif -#endif - return 0; } diff --git a/tcc.h b/tcc.h index c2a69ca..636822b 100644 --- a/tcc.h +++ b/tcc.h @@ -139,9 +139,6 @@ #define true 1 typedef int BOOL; -/* path to find crt1.o, crti.o and crtn.o. Only needed when generating - executables or dlls */ - #ifndef CONFIG_TCC_LDDIR #if defined(TCC_TARGET_X86_64_CENTOS) #define CONFIG_TCC_LDDIR "/lib64" @@ -149,9 +146,29 @@ typedef int BOOL; #define CONFIG_TCC_LDDIR "/lib" #endif #endif -#define CONFIG_TCC_CRT_PREFIX CONFIG_SYSROOT "/usr" CONFIG_TCC_LDDIR -#ifndef CONFIG_TCC_INCSUBDIR - #define CONFIG_TCC_INCSUBDIR "" + +/* path to find crt1.o, crti.o and crtn.o */ +#ifndef CONFIG_TCC_CRT_PREFIX +# define CONFIG_TCC_CRT_PREFIX CONFIG_SYSROOT "/usr" CONFIG_TCC_LDDIR +#endif + +#ifndef CONFIG_TCC_SYSINCLUDE_PATHS +# ifdef TCC_TARGET_PE +# define CONFIG_TCC_SYSINCLUDE_PATHS "\b/include;\b/include/winapi" +# else +# define CONFIG_TCC_SYSINCLUDE_PATHS "/usr/local/include:/usr/include:\b/include" +# endif +#endif + +#ifndef CONFIG_TCC_LIBPATH +# ifdef TCC_TARGET_PE +# define CONFIG_TCC_LIBPATH "\b/lib" +# else +# define CONFIG_TCC_LIBPATH \ + CONFIG_TCC_CRT_PREFIX \ + ":" CONFIG_SYSROOT CONFIG_TCC_LDDIR \ + ":" CONFIG_SYSROOT "/usr/local" CONFIG_TCC_LDDIR +# endif #endif #define INCLUDE_STACK_SIZE 32 @@ -843,15 +860,21 @@ extern long double strtold (const char *__nptr, char **__endptr); #endif #ifdef _WIN32 -#define IS_PATHSEP(c) (c == '/' || c == '\\') -#define IS_ABSPATH(p) (IS_PATHSEP(p[0]) || (p[0] && p[1] == ':' && IS_PATHSEP(p[2]))) +#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 #else -#define IS_PATHSEP(c) (c == '/') -#define IS_ABSPATH(p) IS_PATHSEP(p[0]) +#define IS_DIRSEP(c) (c == '/') +#define IS_ABSPATH(p) IS_DIRSEP(p[0]) #define PATHCMP strcmp #endif +#ifdef TCC_TARGET_PE +#define PATHSEP ';' +#else +#define PATHSEP ':' +#endif + /* space exlcuding newline */ static inline int is_space(int ch) { @@ -912,6 +935,7 @@ ST_DATA void *rt_prog_main; /* public functions currently used by the tcc main function */ PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s); PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s); +PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num); PUB_FUNC char *tcc_basename(const char *name); PUB_FUNC char *tcc_fileextension (const char *name); PUB_FUNC void tcc_free(void *ptr); @@ -970,8 +994,6 @@ PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value); PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time); PUB_FUNC void set_num_callers(int n); -ST_FUNC int ieee_finite(double d); - /* ------------ tccpp.c ------------ */ ST_DATA struct BufferedFile *file; @@ -1066,6 +1088,7 @@ ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc ST_DATA char *funcname; ST_INLN int is_float(int t); +ST_FUNC int ieee_finite(double d); ST_FUNC void test_lvalue(void); ST_FUNC void swap(int *p, int *q); ST_FUNC void vpushi(int v); diff --git a/tccelf.c b/tccelf.c index 10d3c02..3ac71cb 100644 --- a/tccelf.c +++ b/tccelf.c @@ -2857,13 +2857,6 @@ static int ld_next(TCCState *s1, char *name, int name_size) return c; } -char *tcc_strcpy_part(char *out, const char *in, size_t num) -{ - memcpy(out, in, num); - out[num] = '\0'; - return out; -} - /* * Extract the library name from the file name * Return 0 if the file isn't a library @@ -2886,20 +2879,20 @@ static int filename_to_libname(TCCState *s1, const char filename[], char libname #ifdef TCC_TARGET_PE if (!strcmp(ext, ".def")) { size_t len = ext - filename; - tcc_strcpy_part(libname, filename, len); + pstrncpy(libname, filename, len); return 1; } #else if (libprefix && (!strcmp(ext, ".so"))) { size_t len = ext - filename - 3; - tcc_strcpy_part(libname, filename + 3, len); + pstrncpy(libname, filename + 3, len); return 1; } #endif } else { if (libprefix && (!strcmp(ext, ".a"))) { size_t len = ext - filename - 3; - tcc_strcpy_part(libname, filename + 3, len); + pstrncpy(libname, filename + 3, len); return 1; } } diff --git a/tccgen.c b/tccgen.c index e488c65..2df5de5 100644 --- a/tccgen.c +++ b/tccgen.c @@ -90,6 +90,15 @@ ST_INLN int is_float(int t) return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT; } +/* we use our own 'finite' function to avoid potential problems with + non standard math libs */ +/* XXX: endianness dependent */ +ST_FUNC int ieee_finite(double d) +{ + int *p = (int *)&d; + return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; +} + ST_FUNC void test_lvalue(void) { if (!(vtop->r & VT_LVAL))