Treat `-Wp,-foo,bar' as `-foo bar' rather than `-foo,bar'. Compatible with
typical cc; useful when a user is used to a compiler like cproc, which doesn't
accept `-MMD -MF file' but does correctly forward `-Wp,-MMD,-MF,file' to the
system cpp. `-Wp,-MMD,-MF file' also works.
---
libtcc.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
tcc-doc.texi | 4 ++--
tcc.c | 2 +-
3 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/libtcc.c b/libtcc.c
index 21b1b251..63da9dfa 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -1864,6 +1864,43 @@ static uint32_t parse_version(TCCState *s1, const char
*version)
}
#endif
+/* Allocate a new argv, with element argv[ind] replaced with comma-split
+ newargs. `mem' points to an argv that this function allocated before, or
+ points to NULL on the first call, and will point to the new argv. Returns
+ the new argc.
+
+ Some serious pointer aliasing goes on in these arguments */
+static int splice_argv(char *** mem, const char *const *const argv, const int
argc,
+ const int ind, char *newargs)
+{
+ const int mem_was_null = !*mem;
+ size_t n_newargs = 1; /* if no commas are found, there is one arg */
+ char *p;
+ size_t i;
+
+ for (p = newargs; (p = strchr(p, ',')); n_newargs++)
+ *p++ = '\0';
+
+ *mem = tcc_realloc(*mem, (argc + n_newargs) * sizeof *argv);
+ if (mem_was_null)
+ memcpy(*mem, argv, ind * sizeof **mem);
+
+ /* If mem_was_null, argv is still valid and doesn't alias *mem, and can
+ be memcpy'd from. If not, argv is no longer valid, but *mem has been
+ realloc'd and thus already has argv contents, which must be memmove'd
+ to make way for the spliced args */
+ (mem_was_null ? memcpy : memmove)(
+ *mem + ind + n_newargs,
+ (mem_was_null ? argv : (void*)*mem) + ind + 1,
+ (argc - ind) * sizeof **mem
+ );
+
+ for (i = 0, p = newargs; i < n_newargs; p += 1 + strlen(p), i++)
+ (*mem)[ind + i] = p;
+
+ return argc + n_newargs - 1; /* -1 as argc shouldn't include NULL ending
argv */
+}
+
PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
{
TCCState *s1 = s;
@@ -1874,6 +1911,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char
***pargv, int optind)
int tool = 0, arg_start = 0, noaction = optind;
char **argv = *pargv;
int argc = *pargc;
+ char **mem = NULL; /* state for splice_argv() */
cstr_reset(&s->linker_arg);
@@ -2106,7 +2144,11 @@ dorun:
return -1;
break;
case TCC_OPTION_Wp:
- r = optarg;
+ /* we could tcc_strdup(optarg), but the caller is warned that none
+ of pargv is const, and I see no further use for optarg as is */
+ argc = splice_argv(&mem, (const char *const *)argv, argc, optind -
1, (char*)optarg);
+ argv = mem;
+ r = argv[optind - 1];
goto reparse;
case TCC_OPTION_E:
x = TCC_OUTPUT_PREPROCESS;
diff --git a/tcc-doc.texi b/tcc-doc.texi
index d9df2d1a..bcaf30bf 100644
--- a/tcc-doc.texi
+++ b/tcc-doc.texi
@@ -239,8 +239,8 @@ Output alternative @code{#line} directives.
@item -dD, -dM
Output @code{#define} directives.
-@item -Wp,-opt
-Same as @option{-opt}.
+@item -Wp,-opt1,arg,-opt2
+Same as @option{-opt1 arg -opt2}.
@end table
diff --git a/tcc.c b/tcc.c
index 9b400e71..84c0944a 100644
--- a/tcc.c
+++ b/tcc.c
@@ -96,7 +96,7 @@ static const char help2[] =
" -dD -dM with -E: output #define directives\n"
" -pthread same as -D_REENTRANT and -lpthread\n"
" -On same as -D__OPTIMIZE__ for n > 0\n"
- " -Wp,-opt same as -opt\n"
+ " -Wp,-opt1,arg,-opt2 same as -opt1 arg -opt2\n"
" -include file include 'file' above each input file\n"
" -nostdlib do not link with standard crt/libs\n"
" -isystem dir add 'dir' to system include path\n"
--
2.48.1
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel