History

Allow tcc arguments to be read from @listfiles

From: Vlad Vissoultchev Date: Tue, 12 Apr 2016 20:43:15 +0300 Subject: Allow tcc arguments to be read from @listfiles This allows all @ prefixed arguments to be treated as listfiles containing list of source files or tcc options where each one is on a separate line. Can be used to benchmark compilation speed with non-trivial amount of source files. The impl of `tcc_parse_args` had to be moved to a new function that is able to be called recursively w/ the original one remaining as a driver of the new one. Listfiles parsing happens in a new `args_parser_add_listfile` function that uses `tcc_open`/`tcc_close/inp` for buffered file input.

seyko committed 10 years ago

Commit 989b5ee1 parent a1a5c813 files · +94 −27Browse files

Unified · Split

3 files
  1. libtcc.c +84 −27
  2. tcc.c +1 −0
  3. tcc.h +9 −0
libtcc.c+84−27
@@ -2081,28 +2081,65 @@ static void args_parser_add_file(TCCState *s, const char* filename, int filetype · 2080 unmodified lines
2081 dynarray_add((void ***)&s->files, &s->nb_files, p);2081 dynarray_add((void ***)&s->files, &s->nb_files, p);
2082}2082}
2083 2083
2084PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)2084ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv);
2085
2086ST_FUNC void args_parser_trim_ws()
2087{
2088 for (; ch != CH_EOF; inp()) {
2089 if (ch != '\n' && ch != '\r' && !is_space(ch))
2090 break;
2091 }
2092}
2093
2094ST_FUNC void args_parser_add_listfile(TCCState *s, const char *filename)
2095{
2096 char buf[sizeof file->filename], *pb = buf;
2097 char **argv = NULL;
2098 int argc = 0;
2099
2100 if (tcc_open(s, filename) < 0)
2101 tcc_error("list file '%s' not found", filename);
2102
2103 for (ch = handle_eob(), args_parser_trim_ws(); ; inp()) {
2104 /* on new line or buffer overflow */
2105 if (ch == '\n' || ch == '\r' || ch == CH_EOF
2106 || pb - buf >= sizeof(buf) - 1) {
2107 if (pb > buf) {
2108 *pb = 0, pb = buf;
2109 dynarray_add((void ***)&argv, &argc, tcc_strdup(buf));
2110 args_parser_trim_ws();
2111 }
2112 }
2113 if (ch == CH_EOF)
2114 break;
2115 *pb++ = ch;
2116 }
2117 tcc_close();
2118 tcc_parse_args1(s, argc, argv);
2119 dynarray_reset(&argv, &argc);
2120}
2121
2122ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv)
2085{2123{
2086 const TCCOption *popt;2124 const TCCOption *popt;
2087 const char *optarg, *r;2125 const char *optarg, *r;
2088 int run = 0;
2089 int pthread = 0;
2090 int optind = 0;2126 int optind = 0;
2091 int filetype = 0;2127 ParseArgsState *pas = s->parse_args_state;
2092
2093 /* collect -Wl options for input such as "-Wl,-rpath -Wl,<path>" */
2094 CString linker_arg;
2095 cstr_new(&linker_arg);
2096 2128
2097 while (optind < argc) {2129 while (optind < argc) {
2098 2130
2099 r = argv[optind++];2131 r = argv[optind++];
2100 if (r[0] != '-' || r[1] == '\0') {2132 if (r[0] != '-' || r[1] == '\0') {
2101 args_parser_add_file(s, r, filetype);2133 /* handle list files */
2102 if (run) {2134 if (r[0] == '@' && r[1]) {
2103 optind--;2135 args_parser_add_listfile(s, r + 1);
2104 /* argv[0] will be this file */2136 } else {
2105 break;2137 args_parser_add_file(s, r, pas->filetype);
2138 if (pas->run) {
2139 optind--;
2140 /* argv[0] will be this file */
2141 break;
2142 }
2106 }2143 }
2107 continue;2144 continue;
2108 }2145 }
@@ -2152,7 +2189,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 43 unmodified lines
2152 break;2189 break;
2153 case TCC_OPTION_pthread:2190 case TCC_OPTION_pthread:
2154 parse_option_D(s, "_REENTRANT");2191 parse_option_D(s, "_REENTRANT");
2155 pthread = 1;2192 pas->pthread = 1;
2156 break;2193 break;
2157 case TCC_OPTION_bench:2194 case TCC_OPTION_bench:
2158 s->do_bench = 1;2195 s->do_bench = 1;
@@ -2267,7 +2304,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 108 unmodified lines
2267 tcc_warning("-run: some compiler action already specified (%d)", s->output_type);2304 tcc_warning("-run: some compiler action already specified (%d)", s->output_type);
2268 s->output_type = TCC_OUTPUT_MEMORY;2305 s->output_type = TCC_OUTPUT_MEMORY;
2269 tcc_set_options(s, optarg);2306 tcc_set_options(s, optarg);
2270 run = 1;2307 pas->run = 1;
2271 break;2308 break;
2272 case TCC_OPTION_v:2309 case TCC_OPTION_v:
2273 do ++s->verbose; while (*optarg++ == 'v');2310 do ++s->verbose; while (*optarg++ == 'v');
@@ -2288,10 +2325,10 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 14 unmodified lines
2288 s->rdynamic = 1;2325 s->rdynamic = 1;
2289 break;2326 break;
2290 case TCC_OPTION_Wl:2327 case TCC_OPTION_Wl:
2291 if (linker_arg.size)2328 if (pas->linker_arg.size)
2292 --linker_arg.size, cstr_ccat(&linker_arg, ',');2329 --pas->linker_arg.size, cstr_ccat(&pas->linker_arg, ',');
2293 cstr_cat(&linker_arg, optarg);2330 cstr_cat(&pas->linker_arg, optarg);
2294 cstr_ccat(&linker_arg, '\0');2331 cstr_ccat(&pas->linker_arg, '\0');
2295 break;2332 break;
2296 case TCC_OPTION_E:2333 case TCC_OPTION_E:
2297 if (s->output_type)2334 if (s->output_type)
@@ -2317,13 +2354,13 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 19 unmodified lines
2317 break;2354 break;
2318 case TCC_OPTION_x:2355 case TCC_OPTION_x:
2319 if (*optarg == 'c')2356 if (*optarg == 'c')
2320 filetype = TCC_FILETYPE_C;2357 pas->filetype = TCC_FILETYPE_C;
2321 else2358 else
2322 if (*optarg == 'a')2359 if (*optarg == 'a')
2323 filetype = TCC_FILETYPE_ASM_PP;2360 pas->filetype = TCC_FILETYPE_ASM_PP;
2324 else2361 else
2325 if (*optarg == 'n')2362 if (*optarg == 'n')
2326 filetype = 0;2363 pas->filetype = 0;
2327 else2364 else
2328 tcc_warning("unsupported language '%s'", optarg);2365 tcc_warning("unsupported language '%s'", optarg);
2329 break;2366 break;
@@ -2349,18 +2386,38 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 19 unmodified lines
2349 break;2386 break;
2350 }2387 }
2351 }2388 }
2389 return optind;
2390}
2391
2392PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
2393{
2394 ParseArgsState *pas;
2395 int ret, is_allocated = 0;
2396
2397 if (!s->parse_args_state) {
2398 s->parse_args_state = tcc_mallocz(sizeof(ParseArgsState));
2399 cstr_new(&s->parse_args_state->linker_arg);
2400 is_allocated = 1;
2401 }
2402 pas = s->parse_args_state;
2403
2404 ret = tcc_parse_args1(s, argc, argv);
2352 2405
2353 if (s->output_type == 0)2406 if (s->output_type == 0)
2354 s->output_type = TCC_OUTPUT_EXE;2407 s->output_type = TCC_OUTPUT_EXE;
2355 2408
2356 if (pthread && s->output_type != TCC_OUTPUT_OBJ)2409 if (pas->pthread && s->output_type != TCC_OUTPUT_OBJ)
2357 tcc_set_options(s, "-lpthread");2410 tcc_set_options(s, "-lpthread");
2358 2411
2359 if (s->output_type == TCC_OUTPUT_EXE)2412 if (s->output_type == TCC_OUTPUT_EXE)
2360 tcc_set_linker(s, (const char *)linker_arg.data);2413 tcc_set_linker(s, (const char *)pas->linker_arg.data);
2361 cstr_free(&linker_arg);
2362 2414
2363 return optind;2415 if (is_allocated) {
2416 cstr_free(&pas->linker_arg);
2417 tcc_free(pas);
2418 s->parse_args_state = NULL;
2419 }
2420 return ret;
2364}2421}
2365 2422
2366LIBTCCAPI int tcc_set_options(TCCState *s, const char *str)2423LIBTCCAPI int tcc_set_options(TCCState *s, const char *str)
tcc.c+1−0
@@ -92,6 +92,7 @@ static void help(void) · 91 unmodified lines
92 " -bench show compilation statistics\n"92 " -bench show compilation statistics\n"
93 " -xc -xa specify type of the next infile\n"93 " -xc -xa specify type of the next infile\n"
94 " - use stdin pipe as infile\n"94 " - use stdin pipe as infile\n"
95 " @listfile read line separated arguments from 'listfile'\n"
95 "Preprocessor options:\n"96 "Preprocessor options:\n"
96 " -Idir add include path 'dir'\n"97 " -Idir add include path 'dir'\n"
97 " -Dsym[=val] define 'sym' with value 'val'\n"98 " -Dsym[=val] define 'sym' with value 'val'\n"
tcc.h+9−0
@@ -627,6 +627,14 @@ struct sym_attr { · 626 unmodified lines
627#endif627#endif
628};628};
629 629
630typedef struct ParseArgsState
631{
632 int run;
633 int pthread;
634 int filetype;
635 CString linker_arg; /* collect -Wl options for input such as "-Wl,-rpath -Wl,<path>" */
636} ParseArgsState;
637
630struct TCCState {638struct TCCState {
631 639
632 int verbose; /* if true, display some information during compilation */640 int verbose; /* if true, display some information during compilation */
@@ -806,6 +814,7 @@ struct TCCState { · 173 unmodified lines
806 int do_bench; /* option -bench */814 int do_bench; /* option -bench */
807 int gen_deps; /* option -MD */815 int gen_deps; /* option -MD */
808 char *deps_outfile; /* option -MF */816 char *deps_outfile; /* option -MF */
817 ParseArgsState *parse_args_state;
809};818};
810 819
811/* The current value can be: */820/* The current value can be: */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t