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
2074 dynarray_add((void ***)&s->files, &s->nb_files, f);2074 dynarray_add((void ***)&s->files, &s->nb_files, f);
2075}2075}
2076 2076
2077ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv)2077/* read list file */
2078static 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
2095PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
2078{2096{
2079 const TCCOption *popt;2097 const TCCOption *popt;
2080 const char *optarg, *r;2098 const char *optarg, *r;
2081 int optind = 0;2099 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;
2083 2106
2084 while (optind < argc) {2107 while (optind < argc) {
2085 2108
2086 r = argv[optind++];2109 r = argv[optind++];
2110
2111 if (r[0] == '@' && r[1] != '\0') {
2112 args_parser_listfile(s, r + 1);
2113 continue;
2114 }
2115
2087 if (r[0] != '-' || r[1] == '\0') {2116 if (r[0] != '-' || r[1] == '\0') {
2088 /* handle list files */2117 args_parser_add_file(s, r, filetype);
2089 if (r[0] == '@' && r[1]) {2118 if (run) {
2090 char buf[sizeof file->filename], *p;2119 optind--;
2091 char **argv = NULL;2120 /* argv[0] will be this file */
2092 int argc = 0;2121 break;
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 }
2114 }2122 }
2115 continue;2123 continue;
2116 }2124 }
@@ -2160,7 +2168,7 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 43 unmodified lines
2160 break;2168 break;
2161 case TCC_OPTION_pthread:2169 case TCC_OPTION_pthread:
2162 parse_option_D(s, "_REENTRANT");2170 parse_option_D(s, "_REENTRANT");
2163 pas->pthread = 1;2171 s->args_pthread = 1;
2164 break;2172 break;
2165 case TCC_OPTION_bench:2173 case TCC_OPTION_bench:
2166 s->do_bench = 1;2174 s->do_bench = 1;
@@ -2180,9 +2188,11 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 13 unmodified lines
2180 s->do_debug = 1;2188 s->do_debug = 1;
2181 break;2189 break;
2182 case TCC_OPTION_c:2190 case TCC_OPTION_c:
2191 x = TCC_OUTPUT_OBJ;
2192 set_output_type:
2183 if (s->output_type)2193 if (s->output_type)
2184 tcc_warning("-c: some compiler action already specified (%d)", s->output_type);2194 tcc_warning("-%s: overriding compiler action already specified", popt->name);
2185 s->output_type = TCC_OUTPUT_OBJ;2195 s->output_type = x;
2186 break;2196 break;
2187 case TCC_OPTION_d:2197 case TCC_OPTION_d:
2188 if (*optarg == 'D')2198 if (*optarg == 'D')
@@ -2214,10 +2224,8 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 25 unmodified lines
2214 allow to use a tcc as a reference compiler for "make test" */2224 allow to use a tcc as a reference compiler for "make test" */
2215 break;2225 break;
2216 case TCC_OPTION_shared:2226 case TCC_OPTION_shared:
2217 if (s->output_type)2227 x = TCC_OUTPUT_DLL;
2218 tcc_warning("-shared: some compiler action already specified (%d)", s->output_type);2228 goto set_output_type;
2219 s->output_type = TCC_OUTPUT_DLL;
2220 break;
2221 case TCC_OPTION_soname:2229 case TCC_OPTION_soname:
2222 s->soname = tcc_strdup(optarg);2230 s->soname = tcc_strdup(optarg);
2223 break;2231 break;
@@ -2233,34 +2241,15 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 9 unmodified lines
2233 break;2241 break;
2234 case TCC_OPTION_r:2242 case TCC_OPTION_r:
2235 /* generate a .o merging several output files */2243 /* 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);
2238 s->option_r = 1;2244 s->option_r = 1;
2239 s->output_type = TCC_OUTPUT_OBJ;2245 x = TCC_OUTPUT_OBJ;
2240 break;2246 goto set_output_type;
2241 case TCC_OPTION_isystem:2247 case TCC_OPTION_isystem:
2242 tcc_add_sysinclude_path(s, optarg);2248 tcc_add_sysinclude_path(s, optarg);
2243 break;2249 break;
2244 case TCC_OPTION_iwithprefix:2250 case TCC_OPTION_iwithprefix:
2245 if (1) {2251 snprintf(buf, sizeof buf, "{B}/%s", optarg);
2246 char buf[1024];2252 tcc_add_sysinclude_path(s, buf);
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 }
2264 break;2253 break;
2265 case TCC_OPTION_nostdinc:2254 case TCC_OPTION_nostdinc:
2266 s->nostdinc = 1;2255 s->nostdinc = 1;
@@ -2275,12 +2264,10 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 8 unmodified lines
2275#ifndef TCC_IS_NATIVE2264#ifndef TCC_IS_NATIVE
2276 tcc_error("-run is not available in a cross compiler");2265 tcc_error("-run is not available in a cross compiler");
2277#endif2266#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;
2281 tcc_set_options(s, optarg);2267 tcc_set_options(s, optarg);
2282 pas->run = 1;2268 run = 1;
2283 break;2269 x = TCC_OUTPUT_MEMORY;
2270 goto set_output_type;
2284 case TCC_OPTION_v:2271 case TCC_OPTION_v:
2285 do ++s->verbose; while (*optarg++ == 'v');2272 do ++s->verbose; while (*optarg++ == 'v');
2286 break;2273 break;
@@ -2299,15 +2286,13 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 12 unmodified lines
2299 s->rdynamic = 1;2286 s->rdynamic = 1;
2300 break;2287 break;
2301 case TCC_OPTION_Wl:2288 case TCC_OPTION_Wl:
2302 if (pas->linker_arg.size)2289 if (s->linker_arg.size)
2303 --pas->linker_arg.size, cstr_ccat(&pas->linker_arg, ',');2290 --s->linker_arg.size, cstr_ccat(&s->linker_arg, ',');
2304 cstr_cat(&pas->linker_arg, optarg, 0);2291 cstr_cat(&s->linker_arg, optarg, 0);
2305 break;2292 break;
2306 case TCC_OPTION_E:2293 case TCC_OPTION_E:
2307 if (s->output_type)2294 x = TCC_OUTPUT_PREPROCESS;
2308 tcc_warning("-E: some compiler action already specified (%d)", s->output_type);2295 goto set_output_type;
2309 s->output_type = TCC_OUTPUT_PREPROCESS;
2310 break;
2311 case TCC_OPTION_P:2296 case TCC_OPTION_P:
2312 s->Pflag = atoi(optarg) + 1;2297 s->Pflag = atoi(optarg) + 1;
2313 break;2298 break;
@@ -2327,25 +2312,20 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv) · 13 unmodified lines
2327 break;2312 break;
2328 case TCC_OPTION_x:2313 case TCC_OPTION_x:
2329 if (*optarg == 'c')2314 if (*optarg == 'c')
2330 pas->filetype = TCC_FILETYPE_C;2315 filetype = TCC_FILETYPE_C;
2331 else2316 else
2332 if (*optarg == 'a')2317 if (*optarg == 'a')
2333 pas->filetype = TCC_FILETYPE_ASM_PP;2318 filetype = TCC_FILETYPE_ASM_PP;
2334 else2319 else
2335 if (*optarg == 'n')2320 if (*optarg == 'n')
2336 pas->filetype = 0;2321 filetype = 0;
2337 else2322 else
2338 tcc_warning("unsupported language '%s'", optarg);2323 tcc_warning("unsupported language '%s'", optarg);
2339 break;2324 break;
2340 case TCC_OPTION_O:2325 case TCC_OPTION_O:
2341 if (1) {2326 x = atoi(optarg);
2342 int opt = atoi(optarg);2327 if (x > 0)
2343 char *sym = "__OPTIMIZE__";2328 tcc_define_symbol(s, "__OPTIMIZE__", NULL);
2344 if (opt)
2345 tcc_define_symbol(s, sym, 0);
2346 else
2347 tcc_undefine_symbol(s, sym);
2348 }
2349 break;2329 break;
2350 case TCC_OPTION_pedantic:2330 case TCC_OPTION_pedantic:
2351 case TCC_OPTION_pipe:2331 case TCC_OPTION_pipe:
@@ -2358,62 +2338,55 @@ unsupported_option: · 6 unmodified lines
2358 break;2338 break;
2359 }2339 }
2360 }2340 }
2361 return optind;
2362}
2363
2364PUB_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;
2375 2341
2376 ret = tcc_parse_args1(s, argc, argv);2342 if (1 == s->args_ref) {
2377 2343 /* top instance */
2378 if (s->output_type == 0)2344 if (s->output_type != TCC_OUTPUT_OBJ) {
2379 s->output_type = TCC_OUTPUT_EXE;2345 tcc_set_linker(s, (const char *)s->linker_arg.data);
2380 2346 if (s->args_pthread) {
2381 if (pas->pthread && s->output_type != TCC_OUTPUT_OBJ) {2347 args_parser_add_file(s, optarg, 'l');
2382 args_parser_add_file(s, "-lpthread", TCC_FILETYPE_BINARY);2348 s->nb_libraries++;
2383 s->nb_libraries++;2349 }
2350 }
2351 cstr_free(&s->linker_arg);
2352 s->args_pthread = 0;
2384 }2353 }
2354 --s->args_ref;
2385 2355
2386 if (s->output_type == TCC_OUTPUT_EXE || s->output_type == TCC_OUTPUT_DLL)2356 return optind;
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;
2395}2357}
2396 2358
2397LIBTCCAPI int tcc_set_options(TCCState *s, const char *str)2359LIBTCCAPI int tcc_set_options(TCCState *s, const char *r)
2398{2360{
2399 const char *s1;2361 char **argv;
2400 char **argv, *arg;2362 int argc;
2401 int argc, len;2363 int ret, q, c;
2402 int ret;2364 CString str;
2403 2365
2404 argc = 0, argv = NULL;2366 argc = 0, argv = NULL;
2405 for(;;) {2367 for(;;) {
2406 while (is_space(*str))2368 while (c = (unsigned char)*r, c && c <= ' ')
2407 str++;2369 ++r;
2408 if (*str == '\0')2370 if (c == 0)
2409 break;2371 break;
2410 s1 = str;2372 q = 0;
2411 while (*str != '\0' && !is_space(*str))2373 cstr_new(&str);
2412 str++;2374 while (c = (unsigned char)*r, c) {
2413 len = str - s1;2375 ++r;
2414 arg = tcc_malloc(len + 1);2376 if (c == '\\' && (*r == '"' || *r == '\\')) {
2415 pstrncpy(arg, s1, len);2377 c = *r++;
2416 dynarray_add((void ***)&argv, &argc, arg);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);
2417 }2390 }
2418 ret = tcc_parse_args(s, argc, argv);2391 ret = tcc_parse_args(s, argc, argv);
2419 dynarray_reset(&argv, &argc);2392 dynarray_reset(&argv, &argc);
tcc.c+19−17
@@ -92,7 +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 " @listfile read arguments from listfile\n"
96 "Preprocessor options:\n"96 "Preprocessor options:\n"
97 " -Idir add include path 'dir'\n"97 " -Idir add include path 'dir'\n"
98 " -Dsym[=val] define 'sym' with value 'val'\n"98 " -Dsym[=val] define 'sym' with value 'val'\n"
@@ -256,9 +256,6 @@ int main(int argc, char **argv) · 157 unmodified lines
256 256
257 optind = tcc_parse_args(s, argc - 1, argv + 1);257 optind = tcc_parse_args(s, argc - 1, argv + 1);
258 258
259 if (s->do_bench)
260 start_time = getclock_us();
261
262 tcc_set_environment(s);259 tcc_set_environment(s);
263 260
264 if (optind == 0) {261 if (optind == 0) {
@@ -272,17 +269,18 @@ int main(int argc, char **argv) · 7 unmodified lines
272 if (s->verbose)269 if (s->verbose)
273 display_info(s, 0);270 display_info(s, 0);
274 271
275 if (s->print_search_dirs || (s->verbose == 2 && optind == 1)) {272 if (s->nb_files == 0) {
276 tcc_set_output_type(s, TCC_OUTPUT_MEMORY);273 if (optind == 1) {
277 display_info(s, 1);274 if (s->print_search_dirs || s->verbose == 2) {
278 return 0;275 tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
279 }276 display_info(s, 1);
280 277 return 1;
281 if (s->verbose && optind == 1)278 }
282 return 0;279 if (s->verbose)
283 280 return 1;
284 if (s->nb_files == 0)281 }
285 tcc_error("no input files\n");282 tcc_error("no input files\n");
283 }
286 284
287 /* check -c consistency : only single file handled. XXX: checks file type */285 /* check -c consistency : only single file handled. XXX: checks file type */
288 if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {286 if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
@@ -293,6 +291,8 @@ int main(int argc, char **argv) · 4 unmodified lines
293 tcc_error("cannot specify multiple files with -c");291 tcc_error("cannot specify multiple files with -c");
294 }292 }
295 293
294 if (s->output_type == 0)
295 s->output_type = TCC_OUTPUT_EXE;
296 tcc_set_output_type(s, s->output_type);296 tcc_set_output_type(s, s->output_type);
297 297
298 if (s->output_type == TCC_OUTPUT_PREPROCESS) {298 if (s->output_type == TCC_OUTPUT_PREPROCESS) {
@@ -305,6 +305,9 @@ int main(int argc, char **argv) · 6 unmodified lines
305 }305 }
306 }306 }
307 307
308 if (s->do_bench)
309 start_time = getclock_us();
310
308 /* compile or add each files or library */311 /* compile or add each files or library */
309 for(i = ret = 0; i < s->nb_files && ret == 0; i++) {312 for(i = ret = 0; i < s->nb_files && ret == 0; i++) {
310 struct filespec *f = s->files[i];313 struct filespec *f = s->files[i];
@@ -322,6 +325,8 @@ int main(int argc, char **argv) · 11 unmodified lines
322 }325 }
323 326
324 if (0 == ret) {327 if (0 == ret) {
328 if (s->do_bench)
329 tcc_print_stats(s, getclock_us() - start_time);
325 if (s->output_type == TCC_OUTPUT_MEMORY) {330 if (s->output_type == TCC_OUTPUT_MEMORY) {
326#ifdef TCC_IS_NATIVE331#ifdef TCC_IS_NATIVE
327 ret = tcc_run(s, argc - 1 - optind, argv + 1 + optind);332 ret = tcc_run(s, argc - 1 - optind, argv + 1 + optind);
@@ -335,9 +340,6 @@ int main(int argc, char **argv) · 7 unmodified lines
335 }340 }
336 }341 }
337 342
338 if (s->do_bench)
339 tcc_print_stats(s, getclock_us() - start_time);
340
341 tcc_delete(s);343 tcc_delete(s);
342 return ret;344 return ret;
343}345}
tcc.h+5−11
@@ -638,14 +638,6 @@ struct sym_attr { · 637 unmodified lines
638#endif638#endif
639};639};
640 640
641typedef 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
649#if !defined(MEM_DEBUG)641#if !defined(MEM_DEBUG)
650#define tal_free(al, p) tal_free_impl(al, p)642#define tal_free(al, p) tal_free_impl(al, p)
651#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size)643#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size)
@@ -682,6 +674,7 @@ typedef struct tal_header_t { · 30 unmodified lines
682#endif674#endif
683} tal_header_t;675} tal_header_t;
684 676
677
685struct TCCState {678struct TCCState {
686 679
687 int verbose; /* if true, display some information during compilation */680 int verbose; /* if true, display some information during compilation */
@@ -860,7 +853,10 @@ struct TCCState { · 172 unmodified lines
860 int do_bench; /* option -bench */853 int do_bench; /* option -bench */
861 int gen_deps; /* option -MD */854 int gen_deps; /* option -MD */
862 char *deps_outfile; /* option -MF */855 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 */
864};860};
865 861
866struct filespec {862struct filespec {
@@ -1312,8 +1308,6 @@ ST_FUNC void preprocess_delete(void); · 445 unmodified lines
1312ST_FUNC int tcc_preprocess(TCCState *s1);1308ST_FUNC int tcc_preprocess(TCCState *s1);
1313ST_FUNC void skip(int c);1309ST_FUNC void skip(int c);
1314ST_FUNC NORETURN void expect(const char *msg);1310ST_FUNC NORETURN void expect(const char *msg);
1315ST_FUNC char *trimfront(char *p);
1316ST_FUNC char *trimback(char *a, char *e);
1317 1311
1318/* ------------ tccgen.c ------------ */1312/* ------------ tccgen.c ------------ */
1319 1313
tccpe.c+17−0
@@ -1565,6 +1565,23 @@ quit: · 1564 unmodified lines
1565 return ret;1565 return ret;
1566}1566}
1567 1567
1568/* ------------------------------------------------------------- */
1569
1570static char *trimfront(char *p)
1571{
1572 while (*p && (unsigned char)*p <= ' ')
1573 ++p;
1574 return p;
1575}
1576
1577static 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
1568/* ------------------------------------------------------------- */1585/* ------------------------------------------------------------- */
1569static int pe_load_def(TCCState *s1, int fd)1586static int pe_load_def(TCCState *s1, int fd)
1570{1587{
tccpp.c+0−15
@@ -133,21 +133,6 @@ ST_FUNC void end_macro(void) · 132 unmodified lines
133 }133 }
134}134}
135 135
136ST_FUNC char *trimfront(char *p)
137{
138 while (*p && (unsigned char)*p <= ' ')
139 ++p;
140 return p;
141}
142
143ST_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
151/* ------------------------------------------------------------------------- */136/* ------------------------------------------------------------------------- */
152/* Custom allocator for tiny objects */137/* Custom allocator for tiny objects */
153 138

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