Thus it can parse command-line -Dsym=value directly, for the convenience of libtcc users or tcc itself Also used in libtcc_test_mt.c to avoid strdup().
Unified · Split
| @@ -751,12 +751,15 @@ LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str) · 750 unmodified lines | |||
| 751 | return tcc_compile(s, s->filetype, str, -1); | 751 | return tcc_compile(s, s->filetype, str, -1); |
| 752 | } | 752 | } |
| 753 | 753 | ||
| 754 | /* define a preprocessor symbol. A value can also be provided with the '=' operator */ | 754 | /* define a preprocessor symbol. value can be NULL, sym can be "sym=val" */ |
| 755 | LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) | 755 | LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) |
| 756 | { | 756 | { |
| 757 | if (!value) | 757 | const char *eq; |
| 758 | value = "1"; | 758 | if (NULL == (eq = strchr(sym, '='))) |
| 759 | cstr_printf(&s1->cmdline_defs, "#define %s %s\n", sym, value); | 759 | eq = strchr(sym, 0); |
| 760 | if (NULL == value) | ||
| 761 | value = *eq ? eq + 1 : "1"; | ||
| 762 | cstr_printf(&s1->cmdline_defs, "#define %.*s %s\n", (int)(eq-sym), sym, value); | ||
| 760 | } | 763 | } |
| 761 | 764 | ||
| 762 | /* undefine a preprocessor symbol */ | 765 | /* undefine a preprocessor symbol */ |
| @@ -1713,16 +1716,6 @@ static const FlagDef options_m[] = { · 950 unmodified lines | |||
| 1713 | { 0, 0, NULL } | 1716 | { 0, 0, NULL } |
| 1714 | }; | 1717 | }; |
| 1715 | 1718 | ||
| 1716 | static void parse_option_D(TCCState *s1, const char *optarg) | ||
| 1717 | { | ||
| 1718 | char *sym = tcc_strdup(optarg); | ||
| 1719 | char *value = strchr(sym, '='); | ||
| 1720 | if (value) | ||
| 1721 | *value++ = '\0'; | ||
| 1722 | tcc_define_symbol(s1, sym, value); | ||
| 1723 | tcc_free(sym); | ||
| 1724 | } | ||
| 1725 | |||
| 1726 | static void args_parser_add_file(TCCState *s, const char* filename, int filetype) | 1719 | static void args_parser_add_file(TCCState *s, const char* filename, int filetype) |
| 1727 | { | 1720 | { |
| 1728 | struct filespec *f = tcc_malloc(sizeof *f + strlen(filename)); | 1721 | struct filespec *f = tcc_malloc(sizeof *f + strlen(filename)); |
| @@ -1863,7 +1856,7 @@ reparse: · 134 unmodified lines | |||
| 1863 | tcc_add_include_path(s, optarg); | 1856 | tcc_add_include_path(s, optarg); |
| 1864 | break; | 1857 | break; |
| 1865 | case TCC_OPTION_D: | 1858 | case TCC_OPTION_D: |
| 1866 | parse_option_D(s, optarg); | 1859 | tcc_define_symbol(s, optarg, NULL); |
| 1867 | break; | 1860 | break; |
| 1868 | case TCC_OPTION_U: | 1861 | case TCC_OPTION_U: |
| 1869 | tcc_undefine_symbol(s, optarg); | 1862 | tcc_undefine_symbol(s, optarg); |
| @@ -45,7 +45,7 @@ LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname); · 44 unmodified lines | |||
| 45 | /* add in system include path */ | 45 | /* add in system include path */ |
| 46 | LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname); | 46 | LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname); |
| 47 | 47 | ||
| 48 | /* define preprocessor symbol 'sym'. Can put optional value */ | 48 | /* define preprocessor symbol 'sym'. value can be NULL, sym can be "sym=val" */ |
| 49 | LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value); | 49 | LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value); |
| 50 | 50 | ||
| 51 | /* undefine preprocess symbol 'sym' */ | 51 | /* undefine preprocess symbol 'sym' */ |
| @@ -104,26 +104,8 @@ void parse_args(TCCState *s) · 103 unmodified lines | |||
| 104 | tcc_add_include_path(s, a+2); | 104 | tcc_add_include_path(s, a+2); |
| 105 | else if (a[1] == 'L') | 105 | else if (a[1] == 'L') |
| 106 | tcc_add_library_path(s, a+2); | 106 | tcc_add_library_path(s, a+2); |
| 107 | else if (a[1] == 'D') { | 107 | else if (a[1] == 'D') |
| 108 | #if defined(__linux__) \ | 108 | tcc_define_symbol(s, a+2, NULL); |
| 109 | && defined(__STDC_VERSION__) \ | ||
| 110 | && (__STDC_VERSION__ >= 201112L) | ||
| 111 | /* | ||
| 112 | * gcc -std=c11 no longer declare strdup which fails with | ||
| 113 | * coredump (at least on Linux x64). | ||
| 114 | */ | ||
| 115 | extern char* strdup(const char*); | ||
| 116 | #endif | ||
| 117 | char *dup = strdup(a); | ||
| 118 | char *eq = strchr(dup+2, '='); | ||
| 119 | if (eq) { | ||
| 120 | *eq = 0; | ||
| 121 | tcc_define_symbol(s, dup+2, eq+1); | ||
| 122 | *eq = '='; | ||
| 123 | } else | ||
| 124 | tcc_define_symbol(s, dup+2, NULL); | ||
| 125 | free(dup); | ||
| 126 | } | ||
| 127 | } | 109 | } |
| 128 | } | 110 | } |
| 129 | } | 111 | } |
| @@ -273,32 +255,32 @@ int main(int argc, char **argv) · 143 unmodified lines | |||
| 273 | } | 255 | } |
| 274 | 256 | ||
| 275 | #if 1 | 257 | #if 1 |
| 276 | printf("mixed calls\n "), fflush(stdout); | 258 | printf("running fib with mixed calls\n "), fflush(stdout); |
| 277 | t = getclock_ms(); | 259 | t = getclock_ms(); |
| 278 | state_test(); | 260 | state_test(); |
| 279 | printf("\n(%u ms)\n", getclock_ms() - t); | 261 | printf("\n (%u ms)\n", getclock_ms() - t); |
| 280 | #endif | 262 | #endif |
| 281 | #if 1 | 263 | #if 1 |
| 282 | printf("threads\n "), fflush(stdout); | 264 | printf("running fib in threads\n "), fflush(stdout); |
| 283 | t = getclock_ms(); | 265 | t = getclock_ms(); |
| 284 | for (n = 0; n < M; ++n) | 266 | for (n = 0; n < M; ++n) |
| 285 | create_thread(thread_test_simple, n); | 267 | create_thread(thread_test_simple, n); |
| 286 | wait_threads(n); | 268 | wait_threads(n); |
| 287 | printf("\n(%u ms)\n", getclock_ms() - t); | 269 | printf("\n (%u ms)\n", getclock_ms() - t); |
| 288 | #endif | 270 | #endif |
| 289 | #if 1 | 271 | #if 1 |
| 290 | printf("tcc in threads\n "), fflush(stdout); | 272 | printf("running tcc.c in threads to run fib\n"), fflush(stdout); |
| 291 | t = getclock_ms(); | 273 | t = getclock_ms(); |
| 292 | for (n = 0; n < M; ++n) | 274 | for (n = 0; n < M; ++n) |
| 293 | create_thread(thread_test_complex, n); | 275 | create_thread(thread_test_complex, n); |
| 294 | wait_threads(n); | 276 | wait_threads(n); |
| 295 | printf("\n(%u ms)\n", getclock_ms() - t); | 277 | printf("\n (%u ms)\n", getclock_ms() - t); |
| 296 | #endif | 278 | #endif |
| 297 | #if 1 | 279 | #if 1 |
| 298 | printf("compiling tcc 10 times\n"), fflush(stdout); | 280 | printf("compiling tcc.c 10 times\n"), fflush(stdout); |
| 299 | t = getclock_ms(); | 281 | t = getclock_ms(); |
| 300 | time_tcc(10, argv[1]); | 282 | time_tcc(10, argv[1]); |
| 301 | printf("(%u ms)\n", (getclock_ms() - t) / 10), fflush(stdout); | 283 | printf(" (%u ms)\n", getclock_ms() - t), fflush(stdout); |
| 302 | #endif | 284 | #endif |
| 303 | return 0; | 285 | return 0; |
| 304 | } | 286 | } |