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
20812081 dynarray_add((void ***)&s->files, &s->nb_files, p);
20822082 }
20832083
2084−PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
2084+ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv);
2085+
2086+ST_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+
2094+ST_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+
2122+ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv)
20852123 {
20862124 const TCCOption *popt;
20872125 const char *optarg, *r;
2088− int run = 0;
2089− int pthread = 0;
20902126 int optind = 0;
2091− int filetype = 0;
2092−
2093− /* collect -Wl options for input such as "-Wl,-rpath -Wl,<path>" */
2094− CString linker_arg;
2095− cstr_new(&linker_arg);
2127+ ParseArgsState *pas = s->parse_args_state;
20962128
20972129 while (optind < argc) {
20982130
20992131 r = argv[optind++];
21002132 if (r[0] != '-' || r[1] == '\0') {
2101− args_parser_add_file(s, r, filetype);
2102− if (run) {
2103− optind--;
2104− /* argv[0] will be this file */
2105− break;
2133+ /* handle list files */
2134+ if (r[0] == '@' && r[1]) {
2135+ args_parser_add_listfile(s, r + 1);
2136+ } else {
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+ }
21062143 }
21072144 continue;
21082145 }
@@ -2152,7 +2189,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 43 unmodified lines
21522189 break;
21532190 case TCC_OPTION_pthread:
21542191 parse_option_D(s, "_REENTRANT");
2155− pthread = 1;
2192+ pas->pthread = 1;
21562193 break;
21572194 case TCC_OPTION_bench:
21582195 s->do_bench = 1;
@@ -2267,7 +2304,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 108 unmodified lines
22672304 tcc_warning("-run: some compiler action already specified (%d)", s->output_type);
22682305 s->output_type = TCC_OUTPUT_MEMORY;
22692306 tcc_set_options(s, optarg);
2270− run = 1;
2307+ pas->run = 1;
22712308 break;
22722309 case TCC_OPTION_v:
22732310 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
22882325 s->rdynamic = 1;
22892326 break;
22902327 case TCC_OPTION_Wl:
2291− if (linker_arg.size)
2292− --linker_arg.size, cstr_ccat(&linker_arg, ',');
2293− cstr_cat(&linker_arg, optarg);
2294− cstr_ccat(&linker_arg, '\0');
2328+ if (pas->linker_arg.size)
2329+ --pas->linker_arg.size, cstr_ccat(&pas->linker_arg, ',');
2330+ cstr_cat(&pas->linker_arg, optarg);
2331+ cstr_ccat(&pas->linker_arg, '\0');
22952332 break;
22962333 case TCC_OPTION_E:
22972334 if (s->output_type)
@@ -2317,13 +2354,13 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 19 unmodified lines
23172354 break;
23182355 case TCC_OPTION_x:
23192356 if (*optarg == 'c')
2320− filetype = TCC_FILETYPE_C;
2357+ pas->filetype = TCC_FILETYPE_C;
23212358 else
23222359 if (*optarg == 'a')
2323− filetype = TCC_FILETYPE_ASM_PP;
2360+ pas->filetype = TCC_FILETYPE_ASM_PP;
23242361 else
23252362 if (*optarg == 'n')
2326− filetype = 0;
2363+ pas->filetype = 0;
23272364 else
23282365 tcc_warning("unsupported language '%s'", optarg);
23292366 break;
@@ -2349,18 +2386,38 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 19 unmodified lines
23492386 break;
23502387 }
23512388 }
2389+ return optind;
2390+}
2391+
2392+PUB_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);
23522405
23532406 if (s->output_type == 0)
2354− s->output_type = TCC_OUTPUT_EXE;
2407+ s->output_type = TCC_OUTPUT_EXE;
23552408
2356− if (pthread && s->output_type != TCC_OUTPUT_OBJ)
2409+ if (pas->pthread && s->output_type != TCC_OUTPUT_OBJ)
23572410 tcc_set_options(s, "-lpthread");
23582411
23592412 if (s->output_type == TCC_OUTPUT_EXE)
2360− tcc_set_linker(s, (const char *)linker_arg.data);
2361− cstr_free(&linker_arg);
2413+ tcc_set_linker(s, (const char *)pas->linker_arg.data);
23622414
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;
23642421 }
23652422
23662423 LIBTCCAPI int tcc_set_options(TCCState *s, const char *str)
tcc.c+1−0
@@ -92,6 +92,7 @@ static void help(void) · 91 unmodified lines
9292 " -bench show compilation statistics\n"
9393 " -xc -xa specify type of the next infile\n"
9494 " - use stdin pipe as infile\n"
95+ " @listfile read line separated arguments from 'listfile'\n"
9596 "Preprocessor options:\n"
9697 " -Idir add include path 'dir'\n"
9798 " -Dsym[=val] define 'sym' with value 'val'\n"
tcc.h+9−0
@@ -627,6 +627,14 @@ struct sym_attr { · 626 unmodified lines
627627 #endif
628628 };
629629
630+typedef 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+
630638 struct TCCState {
631639
632640 int verbose; /* if true, display some information during compilation */
@@ -806,6 +814,7 @@ struct TCCState { · 173 unmodified lines
806814 int do_bench; /* option -bench */
807815 int gen_deps; /* option -MD */
808816 char *deps_outfile; /* option -MF */
817+ ParseArgsState *parse_args_state;
809818 };
810819
811820 /* 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