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
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to