|
|
@@ -0,0 +1,166 @@
|
|
|
+/*=========================================================================
|
|
|
+
|
|
|
+ Program: KWSys - Kitware System Library
|
|
|
+ Module: $RCSfile$
|
|
|
+
|
|
|
+ Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved.
|
|
|
+ See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
+
|
|
|
+ This software is distributed WITHOUT ANY WARRANTY; without even
|
|
|
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
+ PURPOSE. See the above copyright notices for more information.
|
|
|
+
|
|
|
+=========================================================================*/
|
|
|
+#include "kwsysPrivate.h"
|
|
|
+#include KWSYS_HEADER(System.h)
|
|
|
+
|
|
|
+/* Work-around CMake dependency scanning limitation. This must
|
|
|
+ duplicate the above list of headers. */
|
|
|
+#if 0
|
|
|
+# include "System.h.in"
|
|
|
+#endif
|
|
|
+
|
|
|
+#include <string.h> /* strlen */
|
|
|
+
|
|
|
+/*--------------------------------------------------------------------------*/
|
|
|
+int kwsysSystem_Windows_ShellArgumentSize(const char* in)
|
|
|
+{
|
|
|
+ /* Start with the length of the original argument, plus one for
|
|
|
+ either a terminating null or a separating space. */
|
|
|
+ int length = (int)strlen(in) + 1;
|
|
|
+
|
|
|
+ /* Keep track of how many backslashes have been encountered in a row. */
|
|
|
+ int backslashes = 0;
|
|
|
+
|
|
|
+ /* Scan the string for spaces. */
|
|
|
+ const char* c;
|
|
|
+ for(c=in; *c; ++c)
|
|
|
+ {
|
|
|
+ if(*c == ' ' || *c == '\t')
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If there are no spaces, we do not need any extra length. */
|
|
|
+ if(!*c)
|
|
|
+ {
|
|
|
+ return length;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Add 2 for double quotes since spaces are present. */
|
|
|
+ length += 2;
|
|
|
+
|
|
|
+ /* Scan the string to find characters that need escaping. */
|
|
|
+ for(c=in; *c; ++c)
|
|
|
+ {
|
|
|
+ if(*c == '\\')
|
|
|
+ {
|
|
|
+ /* Found a backslash. It may need to be escaped later. */
|
|
|
+ ++backslashes;
|
|
|
+ }
|
|
|
+ else if(*c == '"')
|
|
|
+ {
|
|
|
+ /* Found a double-quote. We need to escape it and all
|
|
|
+ immediately preceding backslashes. */
|
|
|
+ length += backslashes + 1;
|
|
|
+ backslashes = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* Found another character. This eliminates the possibility
|
|
|
+ that any immediately preceding backslashes will be
|
|
|
+ escaped. */
|
|
|
+ backslashes = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* We need to escape all ending backslashes. */
|
|
|
+ length += backslashes;
|
|
|
+
|
|
|
+ return length;
|
|
|
+}
|
|
|
+
|
|
|
+/*--------------------------------------------------------------------------*/
|
|
|
+char* kwsysSystem_Windows_ShellArgument(const char* in, char* out)
|
|
|
+{
|
|
|
+ /* Keep track of how many backslashes have been encountered in a row. */
|
|
|
+ int backslashes = 0;
|
|
|
+
|
|
|
+ /* Scan the string for spaces. */
|
|
|
+ const char* c;
|
|
|
+ for(c=in; *c; ++c)
|
|
|
+ {
|
|
|
+ if(*c == ' ' || *c == '\t')
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If there are no spaces, we can pass the argument verbatim. */
|
|
|
+ if(!*c)
|
|
|
+ {
|
|
|
+ /* Just copy the string. */
|
|
|
+ for(c=in; *c; ++c)
|
|
|
+ {
|
|
|
+ *out++ = *c;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Store a terminating null without incrementing. */
|
|
|
+ *out = 0;
|
|
|
+ return out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Add the opening double-quote for this argument. */
|
|
|
+ *out++ = '"';
|
|
|
+
|
|
|
+ /* Add the characters of the argument, possibly escaping them. */
|
|
|
+ for(c=in; *c; ++c)
|
|
|
+ {
|
|
|
+ if(*c == '\\')
|
|
|
+ {
|
|
|
+ /* Found a backslash. It may need to be escaped later. */
|
|
|
+ ++backslashes;
|
|
|
+ *out++ = '\\';
|
|
|
+ }
|
|
|
+ else if(*c == '"')
|
|
|
+ {
|
|
|
+ /* Add enough backslashes to escape any that preceded the
|
|
|
+ double-quote. */
|
|
|
+ while(backslashes > 0)
|
|
|
+ {
|
|
|
+ --backslashes;
|
|
|
+ *out++ = '\\';
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Add the backslash to escape the double-quote. */
|
|
|
+ *out++ = '\\';
|
|
|
+
|
|
|
+ /* Add the double-quote itself. */
|
|
|
+ *out++ = '"';
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* We encountered a normal character. This eliminates any
|
|
|
+ escaping needed for preceding backslashes. Add the
|
|
|
+ character. */
|
|
|
+ backslashes = 0;
|
|
|
+ *out++ = *c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Add enough backslashes to escape any trailing ones. */
|
|
|
+ while(backslashes > 0)
|
|
|
+ {
|
|
|
+ --backslashes;
|
|
|
+ *out++ = '\\';
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Add the closing double-quote for this argument. */
|
|
|
+ *out++ = '"';
|
|
|
+
|
|
|
+ /* Store a terminating null without incrementing. */
|
|
|
+ *out = 0;
|
|
|
+
|
|
|
+ return out;
|
|
|
+}
|