https://gcc.gnu.org/g:041248ca43beb158afae8350117378c98e9191ad

commit r16-3137-g041248ca43beb158afae8350117378c98e9191ad
Author: Nicolas Werner <nicolas.wer...@hotmail.de>
Date:   Sun Aug 3 16:38:08 2025 +0200

    c++: Quoting in -fmodules-mapper
    
    Users might be using a space in their build directory path. To allow
    specifying such a root for the module mapper started by GCC, we need the
    command to allow quotes. Previously quoting a path passed to the module
    mapper was not possible, so replace the custom argv parsing with
    the argv parsing logic from libiberty, that supports fairly standard
    shell quoting using single and double quotes.
    
    The primary purpose of this patch is to allow passing paths with spaces
    to the --root parameter of the module mapper.
    
    No test is included as spaces in build directories are tricky cross
    platform. The patch was tested manually on my system.
    
    gcc/cp/ChangeLog:
    
            * mapper-client.cc (spawn_mapper_program): change argv parsing
    
    Signed-off-by: Nicolas Werner <nicolas.wer...@hotmail.de>

Diff:
---
 gcc/cp/mapper-client.cc | 44 +++++++++++++-------------------------------
 1 file changed, 13 insertions(+), 31 deletions(-)

diff --git a/gcc/cp/mapper-client.cc b/gcc/cp/mapper-client.cc
index 9477feeee310..ac414f0b1bd8 100644
--- a/gcc/cp/mapper-client.cc
+++ b/gcc/cp/mapper-client.cc
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 #define INCLUDE_VECTOR
 #define INCLUDE_MAP
 #include "system.h"
+#include "libiberty.h"
 
 #include "line-map.h"
 #include "rich-location.h"
@@ -51,37 +52,18 @@ static module_client *
 spawn_mapper_program (char const **errmsg, std::string &name,
                      char const *full_program_name)
 {
-  /* Split writable at white-space.  No space-containing args for
-     you!  */
-  // At most every other char could be an argument
-  char **argv = new char *[name.size () / 2 + 2];
-  unsigned arg_no = 0;
-  char *str = new char[name.size ()];
-  memcpy (str, name.c_str () + 1, name.size ());
+  // Split mapper argument into parameters.
+  char** original_argv = buildargv (name.c_str () + 1);
+  int arg_no = countargv (original_argv);
+  char **argv = new char *[arg_no + 1];
+  for (int i = 0; i < arg_no; i++)
+    argv[i] = original_argv[i];
 
-  for (auto ptr = str; ; ++ptr)
-    {
-      while (*ptr == ' ')
-       ptr++;
-      if (!*ptr)
-       break;
-
-      if (!arg_no)
-       {
-         /* @name means look in the compiler's install dir.  */
-         if (ptr[0] == '@')
-           ptr++;
-         else
-           full_program_name = nullptr;
-       }
-
-      argv[arg_no++] = ptr;
-      while (*ptr && *ptr != ' ')
-       ptr++;
-      if (!*ptr)
-       break;
-      *ptr = 0;
-    }
+  /* @name means look in the compiler's install dir.  */
+  if (arg_no && argv[0][0] == '@')
+    argv[0] = argv[0] + 1;
+  else
+    full_program_name = nullptr;
   argv[arg_no] = nullptr;
 
   auto *pex = pex_init (PEX_USE_PIPES, progname, NULL);
@@ -108,8 +90,8 @@ spawn_mapper_program (char const **errmsg, std::string &name,
       int err;
       *errmsg = pex_run (pex, flags, argv[0], argv, NULL, NULL, &err);
     }
-  delete[] str;
   delete[] argv;
+  freeargv (original_argv);
 
   int fd_from = -1, fd_to = -1;
   if (!*errmsg)

Reply via email to