History

libtcc: cleanup @listfile

Also: - allow more than one item per line - respect "quoted items" and escaped quotes \" (also for LIBTCCAPI tcc_setoptions) - cleanup some copy & paste

grischka committed 10 years ago

Commit eacdc421 parent 09a487e5 files · +141 −170Browse files

Unified · Split

5 files
  1. libtcc.c +100 −127
  2. tcc.c +19 −17
  3. tcc.h +5 −11
  4. tccpe.c +17 −0
  5. tccpp.c +0 −15
libtcc.c+100−127
@@ -2074,43 +2074,51 @@ static void args_parser_add_file(TCCState *s, const char* filename, int filetype · 2073 unmodified lines
20742074 dynarray_add((void ***)&s->files, &s->nb_files, f);
20752075 }
20762076
2077−ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv)
2077+/* read list file */
2078+static void args_parser_listfile(TCCState *s, const char *filename)
2079+{
2080+ int fd;
2081+ size_t len;
2082+ char *p;
2083+
2084+ fd = open(filename, O_RDONLY | O_BINARY);
2085+ if (fd < 0)
2086+ tcc_error("file '%s' not found", filename);
2087+
2088+ len = lseek(fd, 0, SEEK_END);
2089+ p = tcc_malloc(len + 1), p[len] = 0;
2090+ lseek(fd, 0, SEEK_SET), read(fd, p, len), close(fd);
2091+ tcc_set_options(s, p);
2092+ tcc_free(p);
2093+}
2094+
2095+PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
20782096 {
20792097 const TCCOption *popt;
20802098 const char *optarg, *r;
20812099 int optind = 0;
2082− ParseArgsState *pas = s->parse_args_state;
2100+ int run = 0;
2101+ int filetype = 0;
2102+ int x;
2103+ char buf[1024];
2104+
2105+ ++s->args_ref;
20832106
20842107 while (optind < argc) {
20852108
20862109 r = argv[optind++];
2110+
2111+ if (r[0] == '@' && r[1] != '\0') {
2112+ args_parser_listfile(s, r + 1);
2113+ continue;
2114+ }
2115+
20872116 if (r[0] != '-' || r[1] == '\0') {
2088− /* handle list files */
2089− if (r[0] == '@' && r[1]) {
2090− char buf[sizeof file->filename], *p;
2091− char **argv = NULL;
2092− int argc = 0;
2093− FILE *fp;
2094−
2095− fp = fopen(r + 1, "rb");
2096− if (fp == NULL)
2097− tcc_error("list file '%s' not found", r + 1);
2098− while (fgets(buf, sizeof buf, fp)) {
2099− p = trimfront(trimback(buf, strchr(buf, 0)));
2100− if (0 == *p || ';' == *p)
2101− continue;
2102− dynarray_add((void ***)&argv, &argc, tcc_strdup(p));
2103− }
2104− fclose(fp);
2105− tcc_parse_args1(s, argc, argv);
2106− dynarray_reset(&argv, &argc);
2107− } else {
2108− args_parser_add_file(s, r, pas->filetype);
2109− if (pas->run) {
2110− optind--;
2111− /* argv[0] will be this file */
2112− break;
2113− }
2117+ args_parser_add_file(s, r, filetype);
2118+ if (run) {
2119+ optind--;
2120+ /* argv[0] will be this file */
2121+ break;
21142122 }
21152123 continue;
21162124 }
@@ -2160,7 +2168,7 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 43 unmodified lines
21602168 break;
21612169 case TCC_OPTION_pthread:
21622170 parse_option_D(s, "_REENTRANT");
2163− pas->pthread = 1;
2171+ s->args_pthread = 1;
21642172 break;
21652173 case TCC_OPTION_bench:
21662174 s->do_bench = 1;
@@ -2180,9 +2188,11 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 13 unmodified lines
21802188 s->do_debug = 1;
21812189 break;
21822190 case TCC_OPTION_c:
2191+ x = TCC_OUTPUT_OBJ;
2192+ set_output_type:
21832193 if (s->output_type)
2184− tcc_warning("-c: some compiler action already specified (%d)", s->output_type);
2185− s->output_type = TCC_OUTPUT_OBJ;
2194+ tcc_warning("-%s: overriding compiler action already specified", popt->name);
2195+ s->output_type = x;
21862196 break;
21872197 case TCC_OPTION_d:
21882198 if (*optarg == 'D')
@@ -2214,10 +2224,8 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 25 unmodified lines
22142224 allow to use a tcc as a reference compiler for "make test" */
22152225 break;
22162226 case TCC_OPTION_shared:
2217− if (s->output_type)
2218− tcc_warning("-shared: some compiler action already specified (%d)", s->output_type);
2219− s->output_type = TCC_OUTPUT_DLL;
2220− break;
2227+ x = TCC_OUTPUT_DLL;
2228+ goto set_output_type;
22212229 case TCC_OPTION_soname:
22222230 s->soname = tcc_strdup(optarg);
22232231 break;
@@ -2233,34 +2241,15 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 9 unmodified lines
22332241 break;
22342242 case TCC_OPTION_r:
22352243 /* generate a .o merging several output files */
2236− if (s->output_type)
2237− tcc_warning("-r: some compiler action already specified (%d)", s->output_type);
22382244 s->option_r = 1;
2239− s->output_type = TCC_OUTPUT_OBJ;
2240− break;
2245+ x = TCC_OUTPUT_OBJ;
2246+ goto set_output_type;
22412247 case TCC_OPTION_isystem:
22422248 tcc_add_sysinclude_path(s, optarg);
22432249 break;
22442250 case TCC_OPTION_iwithprefix:
2245− if (1) {
2246− char buf[1024];
2247− int buf_size = sizeof(buf)-1;
2248− char *p = &buf[0];
2249−
2250− char *sysroot = "{B}/";
2251− int len = strlen(sysroot);
2252− if (len > buf_size)
2253− len = buf_size;
2254− strncpy(p, sysroot, len);
2255− p += len;
2256− buf_size -= len;
2257−
2258− len = strlen(optarg);
2259− if (len > buf_size)
2260− len = buf_size;
2261− strncpy(p, optarg, len+1);
2262− tcc_add_sysinclude_path(s, buf);
2263− }
2251+ snprintf(buf, sizeof buf, "{B}/%s", optarg);
2252+ tcc_add_sysinclude_path(s, buf);
22642253 break;
22652254 case TCC_OPTION_nostdinc:
22662255 s->nostdinc = 1;
@@ -2275,12 +2264,10 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 8 unmodified lines
22752264 #ifndef TCC_IS_NATIVE
22762265 tcc_error("-run is not available in a cross compiler");
22772266 #endif
2278− if (s->output_type)
2279− tcc_warning("-run: some compiler action already specified (%d)", s->output_type);
2280− s->output_type = TCC_OUTPUT_MEMORY;
22812267 tcc_set_options(s, optarg);
2282− pas->run = 1;
2283− break;
2268+ run = 1;
2269+ x = TCC_OUTPUT_MEMORY;
2270+ goto set_output_type;
22842271 case TCC_OPTION_v:
22852272 do ++s->verbose; while (*optarg++ == 'v');
22862273 break;
@@ -2299,15 +2286,13 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 12 unmodified lines
22992286 s->rdynamic = 1;
23002287 break;
23012288 case TCC_OPTION_Wl:
2302− if (pas->linker_arg.size)
2303− --pas->linker_arg.size, cstr_ccat(&pas->linker_arg, ',');
2304− cstr_cat(&pas->linker_arg, optarg, 0);
2289+ if (s->linker_arg.size)
2290+ --s->linker_arg.size, cstr_ccat(&s->linker_arg, ',');
2291+ cstr_cat(&s->linker_arg, optarg, 0);
23052292 break;
23062293 case TCC_OPTION_E:
2307− if (s->output_type)
2308− tcc_warning("-E: some compiler action already specified (%d)", s->output_type);
2309− s->output_type = TCC_OUTPUT_PREPROCESS;
2310− break;
2294+ x = TCC_OUTPUT_PREPROCESS;
2295+ goto set_output_type;
23112296 case TCC_OPTION_P:
23122297 s->Pflag = atoi(optarg) + 1;
23132298 break;
@@ -2327,25 +2312,20 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 13 unmodified lines
23272312 break;
23282313 case TCC_OPTION_x:
23292314 if (*optarg == 'c')
2330− pas->filetype = TCC_FILETYPE_C;
2315+ filetype = TCC_FILETYPE_C;
23312316 else
23322317 if (*optarg == 'a')
2333− pas->filetype = TCC_FILETYPE_ASM_PP;
2318+ filetype = TCC_FILETYPE_ASM_PP;
23342319 else
23352320 if (*optarg == 'n')
2336− pas->filetype = 0;
2321+ filetype = 0;
23372322 else
23382323 tcc_warning("unsupported language '%s'", optarg);
23392324 break;
23402325 case TCC_OPTION_O:
2341− if (1) {
2342− int opt = atoi(optarg);
2343− char *sym = "__OPTIMIZE__";
2344− if (opt)
2345− tcc_define_symbol(s, sym, 0);
2346− else
2347− tcc_undefine_symbol(s, sym);
2348− }
2326+ x = atoi(optarg);
2327+ if (x > 0)
2328+ tcc_define_symbol(s, "__OPTIMIZE__", NULL);
23492329 break;
23502330 case TCC_OPTION_pedantic:
23512331 case TCC_OPTION_pipe:
@@ -2358,62 +2338,55 @@ unsupported_option: · 6 unmodified lines
23582338 break;
23592339 }
23602340 }
2361− return optind;
2362−}
2363−
2364−PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
2365−{
2366− ParseArgsState *pas;
2367− int ret, is_allocated = 0;
2368−
2369− if (!s->parse_args_state) {
2370− s->parse_args_state = tcc_mallocz(sizeof(ParseArgsState));
2371− cstr_new(&s->parse_args_state->linker_arg);
2372− is_allocated = 1;
2373− }
2374− pas = s->parse_args_state;
23752341
2376− ret = tcc_parse_args1(s, argc, argv);
2377−
2378− if (s->output_type == 0)
2379− s->output_type = TCC_OUTPUT_EXE;
2380−
2381− if (pas->pthread && s->output_type != TCC_OUTPUT_OBJ) {
2382− args_parser_add_file(s, "-lpthread", TCC_FILETYPE_BINARY);
2383− s->nb_libraries++;
2342+ if (1 == s->args_ref) {
2343+ /* top instance */
2344+ if (s->output_type != TCC_OUTPUT_OBJ) {
2345+ tcc_set_linker(s, (const char *)s->linker_arg.data);
2346+ if (s->args_pthread) {
2347+ args_parser_add_file(s, optarg, 'l');
2348+ s->nb_libraries++;
2349+ }
2350+ }
2351+ cstr_free(&s->linker_arg);
2352+ s->args_pthread = 0;
23842353 }
2354+ --s->args_ref;
23852355
2386− if (s->output_type == TCC_OUTPUT_EXE || s->output_type == TCC_OUTPUT_DLL)
2387− tcc_set_linker(s, (const char *)pas->linker_arg.data);
2388−
2389− if (is_allocated) {
2390− cstr_free(&pas->linker_arg);
2391− tcc_free(pas);
2392− s->parse_args_state = NULL;
2393− }
2394− return ret;
2356+ return optind;
23952357 }
23962358
2397−LIBTCCAPI int tcc_set_options(TCCState *s, const char *str)
2359+LIBTCCAPI int tcc_set_options(TCCState *s, const char *r)
23982360 {
2399− const char *s1;
2400− char **argv, *arg;
2401− int argc, len;
2402− int ret;
2361+ char **argv;
2362+ int argc;
2363+ int ret, q, c;
2364+ CString str;
24032365
24042366 argc = 0, argv = NULL;
24052367 for(;;) {
2406− while (is_space(*str))
2407− str++;
2408− if (*str == '\0')
2368+ while (c = (unsigned char)*r, c && c <= ' ')
2369+ ++r;
2370+ if (c == 0)
24092371 break;
2410− s1 = str;
2411− while (*str != '\0' && !is_space(*str))
2412− str++;
2413− len = str - s1;
2414− arg = tcc_malloc(len + 1);
2415− pstrncpy(arg, s1, len);
2416− dynarray_add((void ***)&argv, &argc, arg);
2372+ q = 0;
2373+ cstr_new(&str);
2374+ while (c = (unsigned char)*r, c) {
2375+ ++r;
2376+ if (c == '\\' && (*r == '"' || *r == '\\')) {
2377+ c = *r++;
2378+ } else if (c == '"') {
2379+ q = !q;
2380+ continue;
2381+ } else if (q == 0 && c <= ' ') {
2382+ break;
2383+ }
2384+ cstr_ccat(&str, c);
2385+ }
2386+ cstr_ccat(&str, 0);
2387+ //printf("<%s>\n", str.data), fflush(stdout);
2388+ dynarray_add((void ***)&argv, &argc, tcc_strdup(str.data));
2389+ cstr_free(&str);
24172390 }
24182391 ret = tcc_parse_args(s, argc, argv);
24192392 dynarray_reset(&argv, &argc);
tcc.c+19−17
@@ -92,7 +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"
95+ " @listfile read arguments from listfile\n"
9696 "Preprocessor options:\n"
9797 " -Idir add include path 'dir'\n"
9898 " -Dsym[=val] define 'sym' with value 'val'\n"
@@ -256,9 +256,6 @@ int main(int argc, char **argv) · 157 unmodified lines
256256
257257 optind = tcc_parse_args(s, argc - 1, argv + 1);
258258
259− if (s->do_bench)
260− start_time = getclock_us();
261−
262259 tcc_set_environment(s);
263260
264261 if (optind == 0) {
@@ -272,17 +269,18 @@ int main(int argc, char **argv) · 7 unmodified lines
272269 if (s->verbose)
273270 display_info(s, 0);
274271
275− if (s->print_search_dirs || (s->verbose == 2 && optind == 1)) {
276− tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
277− display_info(s, 1);
278− return 0;
279− }
280−
281− if (s->verbose && optind == 1)
282− return 0;
283−
284− if (s->nb_files == 0)
272+ if (s->nb_files == 0) {
273+ if (optind == 1) {
274+ if (s->print_search_dirs || s->verbose == 2) {
275+ tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
276+ display_info(s, 1);
277+ return 1;
278+ }
279+ if (s->verbose)
280+ return 1;
281+ }
285282 tcc_error("no input files\n");
283+ }
286284
287285 /* check -c consistency : only single file handled. XXX: checks file type */
288286 if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
@@ -293,6 +291,8 @@ int main(int argc, char **argv) · 4 unmodified lines
293291 tcc_error("cannot specify multiple files with -c");
294292 }
295293
294+ if (s->output_type == 0)
295+ s->output_type = TCC_OUTPUT_EXE;
296296 tcc_set_output_type(s, s->output_type);
297297
298298 if (s->output_type == TCC_OUTPUT_PREPROCESS) {
@@ -305,6 +305,9 @@ int main(int argc, char **argv) · 6 unmodified lines
305305 }
306306 }
307307
308+ if (s->do_bench)
309+ start_time = getclock_us();
310+
308311 /* compile or add each files or library */
309312 for(i = ret = 0; i < s->nb_files && ret == 0; i++) {
310313 struct filespec *f = s->files[i];
@@ -322,6 +325,8 @@ int main(int argc, char **argv) · 11 unmodified lines
322325 }
323326
324327 if (0 == ret) {
328+ if (s->do_bench)
329+ tcc_print_stats(s, getclock_us() - start_time);
325330 if (s->output_type == TCC_OUTPUT_MEMORY) {
326331 #ifdef TCC_IS_NATIVE
327332 ret = tcc_run(s, argc - 1 - optind, argv + 1 + optind);
@@ -335,9 +340,6 @@ int main(int argc, char **argv) · 7 unmodified lines
335340 }
336341 }
337342
338− if (s->do_bench)
339− tcc_print_stats(s, getclock_us() - start_time);
340−
341343 tcc_delete(s);
342344 return ret;
343345 }
tcc.h+5−11
@@ -638,14 +638,6 @@ struct sym_attr { · 637 unmodified lines
638638 #endif
639639 };
640640
641−typedef struct ParseArgsState
642−{
643− int run;
644− int pthread;
645− int filetype;
646− CString linker_arg; /* collect -Wl options for input such as "-Wl,-rpath -Wl,<path>" */
647−} ParseArgsState;
648−
649641 #if !defined(MEM_DEBUG)
650642 #define tal_free(al, p) tal_free_impl(al, p)
651643 #define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size)
@@ -682,6 +674,7 @@ typedef struct tal_header_t { · 30 unmodified lines
682674 #endif
683675 } tal_header_t;
684676
677+
685678 struct TCCState {
686679
687680 int verbose; /* if true, display some information during compilation */
@@ -860,7 +853,10 @@ struct TCCState { · 172 unmodified lines
860853 int do_bench; /* option -bench */
861854 int gen_deps; /* option -MD */
862855 char *deps_outfile; /* option -MF */
863− ParseArgsState *parse_args_state;
856+
857+ int args_pthread; /* -pthread option */
858+ CString linker_arg; /* collect -Wl options for input such as "-Wl,-rpath -Wl,<path>" */
859+ int args_ref; /* tcc_parse_args recursive counter */
864860 };
865861
866862 struct filespec {
@@ -1312,8 +1308,6 @@ ST_FUNC void preprocess_delete(void); · 445 unmodified lines
13121308 ST_FUNC int tcc_preprocess(TCCState *s1);
13131309 ST_FUNC void skip(int c);
13141310 ST_FUNC NORETURN void expect(const char *msg);
1315−ST_FUNC char *trimfront(char *p);
1316−ST_FUNC char *trimback(char *a, char *e);
13171311
13181312 /* ------------ tccgen.c ------------ */
13191313
tccpe.c+17−0
@@ -1565,6 +1565,23 @@ quit: · 1564 unmodified lines
15651565 return ret;
15661566 }
15671567
1568+/* ------------------------------------------------------------- */
1569+
1570+static char *trimfront(char *p)
1571+{
1572+ while (*p && (unsigned char)*p <= ' ')
1573+ ++p;
1574+ return p;
1575+}
1576+
1577+static char *trimback(char *a, char *e)
1578+{
1579+ while (e > a && (unsigned char)e[-1] <= ' ')
1580+ --e;
1581+ *e = 0;;
1582+ return a;
1583+}
1584+
15681585 /* ------------------------------------------------------------- */
15691586 static int pe_load_def(TCCState *s1, int fd)
15701587 {
tccpp.c+0−15
@@ -133,21 +133,6 @@ ST_FUNC void end_macro(void) · 132 unmodified lines
133133 }
134134 }
135135
136−ST_FUNC char *trimfront(char *p)
137−{
138− while (*p && (unsigned char)*p <= ' ')
139− ++p;
140− return p;
141−}
142−
143−ST_FUNC char *trimback(char *a, char *e)
144−{
145− while (e > a && (unsigned char)e[-1] <= ' ')
146− --e;
147− *e = 0;;
148− return a;
149−}
150−
151136 /* ------------------------------------------------------------------------- */
152137 /* Custom allocator for tiny objects */
153138

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