[Cmake-commits] [cmake-commits] king committed SharedForward.h.in 1.9 1.10
cmake-commits at cmake.org
cmake-commits at cmake.org
Fri Sep 26 08:24:27 EDT 2008
Update of /cvsroot/CMake/CMake/Source/kwsys
In directory public:/mounts/ram/cvs-serv22571/Source/kwsys
Modified Files:
SharedForward.h.in
Log Message:
BUG: Fix SharedForward with spaces on windows
The windows execvp function does not re-escape arguments correctly.
Instead we generate the escape sequences before calling it.
Index: SharedForward.h.in
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/kwsys/SharedForward.h.in,v
retrieving revision 1.9
retrieving revision 1.10
diff -C 2 -d -r1.9 -r1.10
*** SharedForward.h.in 26 Sep 2008 12:24:20 -0000 1.9
--- SharedForward.h.in 26 Sep 2008 12:24:25 -0000 1.10
***************
*** 158,161 ****
--- 158,162 ----
# include <windows.h>
# include <process.h>
+ # define KWSYS_SHARED_FORWARD_ESCAPE_ARGV /* re-escape argv for execvp */
#else
# include <unistd.h>
***************
*** 270,273 ****
--- 271,414 ----
#endif
+ #ifdef KWSYS_SHARED_FORWARD_ESCAPE_ARGV
+ /*--------------------------------------------------------------------------*/
+ typedef struct kwsys_sf_arg_info_s
+ {
+ const char* arg;
+ int size;
+ int quote;
+ } kwsys_sf_arg_info;
+
+ /*--------------------------------------------------------------------------*/
+ static kwsys_sf_arg_info kwsys_sf_get_arg_info(const char* in)
+ {
+ /* Initialize information. */
+ kwsys_sf_arg_info info;
+
+ /* String iterator. */
+ const char* c;
+
+ /* Keep track of how many backslashes have been encountered in a row. */
+ int windows_backslashes = 0;
+
+ /* Start with the length of the original argument, plus one for
+ either a terminating null or a separating space. */
+ info.arg = in;
+ info.size = (int)strlen(in) + 1;
+ info.quote = 0;
+
+ /* Scan the string for characters that require escaping or quoting. */
+ for(c=in; *c; ++c)
+ {
+ /* Check whether this character needs quotes. */
+ if(strchr(" \t?'#&<>|^", *c))
+ {
+ info.quote = 1;
+ }
+
+ /* On Windows only backslashes and double-quotes need escaping. */
+ if(*c == '\\')
+ {
+ /* Found a backslash. It may need to be escaped later. */
+ ++windows_backslashes;
+ }
+ else if(*c == '"')
+ {
+ /* Found a double-quote. We need to escape it and all
+ immediately preceding backslashes. */
+ info.size += windows_backslashes + 1;
+ windows_backslashes = 0;
+ }
+ else
+ {
+ /* Found another character. This eliminates the possibility
+ that any immediately preceding backslashes will be
+ escaped. */
+ windows_backslashes = 0;
+ }
+ }
+
+ /* Check whether the argument needs surrounding quotes. */
+ if(info.quote)
+ {
+ /* Surrounding quotes are needed. Allocate space for them. */
+ info.size += 2;
+
+ /* We must escape all ending backslashes when quoting on windows. */
+ info.size += windows_backslashes;
+ }
+
+ return info;
+ }
+
+ /*--------------------------------------------------------------------------*/
+ static char* kwsys_sf_get_arg(kwsys_sf_arg_info info, char* out)
+ {
+ /* String iterator. */
+ const char* c;
+
+ /* Keep track of how many backslashes have been encountered in a row. */
+ int windows_backslashes = 0;
+
+ /* Whether the argument must be quoted. */
+ if(info.quote)
+ {
+ /* Add the opening quote for this argument. */
+ *out++ = '"';
+ }
+
+ /* Scan the string for characters that require escaping or quoting. */
+ for(c=info.arg; *c; ++c)
+ {
+ /* On Windows only backslashes and double-quotes need escaping. */
+ if(*c == '\\')
+ {
+ /* Found a backslash. It may need to be escaped later. */
+ ++windows_backslashes;
+ }
+ else if(*c == '"')
+ {
+ /* Found a double-quote. Escape all immediately preceding
+ backslashes. */
+ while(windows_backslashes > 0)
+ {
+ --windows_backslashes;
+ *out++ = '\\';
+ }
+
+ /* Add the backslash to escape the double-quote. */
+ *out++ = '\\';
+ }
+ else
+ {
+ /* We encountered a normal character. This eliminates any
+ escaping needed for preceding backslashes. */
+ windows_backslashes = 0;
+ }
+
+ /* Store this character. */
+ *out++ = *c;
+ }
+
+ if(info.quote)
+ {
+ /* Add enough backslashes to escape any trailing ones. */
+ while(windows_backslashes > 0)
+ {
+ --windows_backslashes;
+ *out++ = '\\';
+ }
+
+ /* Add the closing quote for this argument. */
+ *out++ = '"';
+ }
+
+ /* Store a terminating null without incrementing. */
+ *out = 0;
+
+ return out;
+ }
+ #endif
+
/*--------------------------------------------------------------------------*/
/* Function to convert a logical or relative path to a physical full path. */
***************
*** 342,347 ****
/*--------------------------------------------------------------------------*/
/* Functions to execute a child process. */
! static void kwsys_shared_forward_execvp(const char* cmd, char* const argv[])
{
#if defined(_MSC_VER)
_execvp(cmd, argv);
--- 483,514 ----
/*--------------------------------------------------------------------------*/
/* Functions to execute a child process. */
! static void kwsys_shared_forward_execvp(const char* cmd, char* const* argv)
{
+ #ifdef KWSYS_SHARED_FORWARD_ESCAPE_ARGV
+ /* Count the number of arguments. */
+ int argc = 0;
+ {
+ char* const* argvc;
+ for(argvc = argv; *argvc; ++argvc,++argc) {}
+ }
+
+ /* Create the escaped arguments. */
+ {
+ char** nargv = (char**)malloc((argc+1) * sizeof(char*));
+ int i;
+ for(i=0; i < argc; ++i)
+ {
+ kwsys_sf_arg_info info = kwsys_sf_get_arg_info(argv[i]);
+ nargv[i] = (char*)malloc(info.size);
+ kwsys_sf_get_arg(info, nargv[i]);
+ }
+ nargv[argc] = 0;
+
+ /* Replace the command line to be used. */
+ argv = nargv;
+ }
+ #endif
+
+ /* Invoke the child process. */
#if defined(_MSC_VER)
_execvp(cmd, argv);
More information about the Cmake-commits
mailing list