diff --git a/libtcc.c b/libtcc.c index 2b29d87..64a40ff 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1809,14 +1809,13 @@ static int link_option(const char *str, const char *val, const char **ptr) /* '=' near eos means ',' or '=' is ok */ if (*q == '=') { + if (*p == 0) + *ptr = p; if (*p != ',' && *p != '=') return 0; p++; - q++; } - - if (ptr) - *ptr = p; + *ptr = p; return 1; } @@ -1838,9 +1837,9 @@ static char *copy_linker_arg(const char *p) /* set linker options */ static int tcc_set_linker(TCCState *s, const char *option) { - while (option && *option) { + while (*option) { - const char *p = option; + const char *p = NULL; char *end = NULL; int ignoring = 0; @@ -1916,20 +1915,19 @@ static int tcc_set_linker(TCCState *s, const char *option) } else goto err; #endif - } else - goto err; - - if (ignoring && s->warn_unsupported) err: { - char buf[100], *e; - pstrcpy(buf, sizeof buf, e = copy_linker_arg(option)), tcc_free(e); - if (ignoring) - tcc_warning("unsupported linker option '%s'", buf); - else - tcc_error("unsupported linker option '%s'", buf); + } else if (p) { + return 0; + } else { + err: + tcc_error("unsupported linker option '%s'", option); } + + if (ignoring && s->warn_unsupported) + tcc_warning("unsupported linker option '%s'", option); + option = skip_linker_arg(&p); } - return 0; + return 1; } typedef struct TCCOption { @@ -2089,9 +2087,10 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) int optind = 0; int run = 0; int x; + CString linker_arg; /* collect -Wl options */ char buf[1024]; - ++s->args_ref; + cstr_new(&linker_arg); while (optind < argc) { @@ -2124,6 +2123,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) if (popt->flags & TCC_OPTION_HAS_ARG) { if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) { if (optind >= argc) + arg_err: tcc_error("argument to '%s' is missing", r); optarg = argv[optind++]; } @@ -2157,7 +2157,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) break; case TCC_OPTION_pthread: parse_option_D(s, "_REENTRANT"); - s->args_pthread = 1; + s->option_pthread = 1; break; case TCC_OPTION_bench: s->do_bench = 1; @@ -2273,9 +2273,11 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) s->rdynamic = 1; break; case TCC_OPTION_Wl: - if (s->linker_arg.size) - --s->linker_arg.size, cstr_ccat(&s->linker_arg, ','); - cstr_cat(&s->linker_arg, optarg, 0); + if (linker_arg.size) + --linker_arg.size, cstr_ccat(&linker_arg, ','); + cstr_cat(&linker_arg, optarg, 0); + if (tcc_set_linker(s, linker_arg.data)) + cstr_free(&linker_arg); break; case TCC_OPTION_E: x = TCC_OUTPUT_PREPROCESS; @@ -2323,19 +2325,10 @@ unsupported_option: } } - if (1 == s->args_ref) { - /* top instance */ - if (s->output_type != TCC_OUTPUT_OBJ) { - tcc_set_linker(s, (const char *)s->linker_arg.data); - if (s->args_pthread) { - args_parser_add_file(s, optarg, 'l'); - s->nb_libraries++; - } - } - cstr_free(&s->linker_arg); - s->args_pthread = 0; + if (linker_arg.size) { + r = linker_arg.data; + goto arg_err; } - --s->args_ref; return optind; } diff --git a/tcc.c b/tcc.c index 0e516d1..2bfc672 100644 --- a/tcc.c +++ b/tcc.c @@ -303,6 +303,9 @@ int main(int argc, char **argv) if (!s->ppfp) tcc_error("could not write '%s'", s->outfile); } + } else if (s->output_type != TCC_OUTPUT_OBJ) { + if (s->option_pthread) + tcc_set_options(s, "-lpthread"); } if (s->do_bench) diff --git a/tcc.h b/tcc.h index 19093e1..2c38fa5 100644 --- a/tcc.h +++ b/tcc.h @@ -762,10 +762,7 @@ struct TCCState { int do_bench; /* option -bench */ int gen_deps; /* option -MD */ char *deps_outfile; /* option -MF */ - - int args_pthread; /* -pthread option */ - CString linker_arg; /* collect -Wl options for input such as "-Wl,-rpath -Wl," */ - int args_ref; /* tcc_parse_args recursive counter */ + int option_pthread; /* -pthread option */ }; struct filespec {