1
0
Эх сурвалжийг харах

Merge topic 'cmOutputConverter-stringstream'

d645b03e cmOutputConverter: implement Shell__GetArgument using ostringstream
Brad King 9 жил өмнө
parent
commit
a854e1795f

+ 36 - 178
Source/cmOutputConverter.cxx

@@ -15,6 +15,7 @@
 #include "cmake.h"
 
 #include <assert.h>
+#include <sstream>
 
 #include <ctype.h>  /* isalpha */
 #include <string.h> /* strlen */
@@ -328,19 +329,9 @@ std::string cmOutputConverter::EscapeForShell(const std::string& str,
     flags |= Shell_Flag_NMake;
   }
 
-  // Compute the buffer size needed.
-  int size = (this->GetState()->UseWindowsShell()
-                ? Shell_GetArgumentSizeForWindows(str.c_str(), flags)
-                : Shell_GetArgumentSizeForUnix(str.c_str(), flags));
-
-  // Compute the shell argument itself.
-  std::vector<char> arg(size);
-  if (this->GetState()->UseWindowsShell()) {
-    Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags);
-  } else {
-    Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags);
-  }
-  return std::string(&arg[0]);
+  return this->GetState()->UseWindowsShell()
+    ? Shell_GetArgumentForWindows(str.c_str(), flags)
+    : Shell_GetArgumentForUnix(str.c_str(), flags);
 }
 
 std::string cmOutputConverter::EscapeForCMake(const std::string& str)
@@ -369,18 +360,7 @@ std::string cmOutputConverter::EscapeForCMake(const std::string& str)
 std::string cmOutputConverter::EscapeWindowsShellArgument(const char* arg,
                                                           int shell_flags)
 {
-  char local_buffer[1024];
-  char* buffer = local_buffer;
-  int size = Shell_GetArgumentSizeForWindows(arg, shell_flags);
-  if (size > 1024) {
-    buffer = new char[size];
-  }
-  Shell_GetArgumentForWindows(arg, buffer, shell_flags);
-  std::string result(buffer);
-  if (buffer != local_buffer) {
-    delete[] buffer;
-  }
-  return result;
+  return Shell_GetArgumentForWindows(arg, shell_flags);
 }
 
 cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
@@ -586,12 +566,10 @@ int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int isUnix,
   return 0;
 }
 
-int cmOutputConverter::Shell__GetArgumentSize(const char* in, int isUnix,
-                                              int flags)
+std::string cmOutputConverter::Shell__GetArgument(const char* in, int isUnix,
+                                                  int flags)
 {
-  /* Start with the length of the original argument, plus one for
-     either a terminating null or a separating space.  */
-  int size = (int)strlen(in) + 1;
+  std::ostringstream out;
 
   /* String iterator.  */
   const char* c;
@@ -599,116 +577,17 @@ int cmOutputConverter::Shell__GetArgumentSize(const char* in, int isUnix,
   /* Keep track of how many backslashes have been encountered in a row.  */
   int windows_backslashes = 0;
 
-  /* Scan the string for characters that require escaping or quoting.  */
-  for (c = in; *c; ++c) {
-    /* Look for $(MAKEVAR) syntax if requested.  */
-    if (flags & Shell_Flag_AllowMakeVariables) {
-      /* Skip over the make variable references if any are present.  */
-      c = Shell__SkipMakeVariables(c);
-
-      /* Stop if we have reached the end of the string.  */
-      if (!*c) {
-        break;
-      }
-    }
-
-    /* Check whether this character needs escaping for the shell.  */
-    if (isUnix) {
-      /* On Unix a few special characters need escaping even inside a
-         quoted argument.  */
-      if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') {
-        /* This character needs a backslash to escape it.  */
-        ++size;
-      }
-    } else if (flags & Shell_Flag_EchoWindows) {
-      /* On Windows the built-in command shell echo never needs escaping.  */
-    } else {
-      /* 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.  */
-        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 this character needs escaping for a make tool.  */
-    if (*c == '$') {
-      if (flags & Shell_Flag_Make) {
-        /* In Makefiles a dollar is written $$ so we need one extra
-           character.  */
-        ++size;
-      } else if (flags & Shell_Flag_VSIDE) {
-        /* In a VS IDE a dollar is written "$" so we need two extra
-           characters.  */
-        size += 2;
-      }
-    } else if (*c == '#') {
-      if ((flags & Shell_Flag_Make) && (flags & Shell_Flag_WatcomWMake)) {
-        /* In Watcom WMake makefiles a pound is written $# so we need
-           one extra character.  */
-        ++size;
-      }
-    } else if (*c == '%') {
-      if ((flags & Shell_Flag_VSIDE) ||
-          ((flags & Shell_Flag_Make) &&
-           ((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) {
-        /* In the VS IDE, NMake, or MinGW make a percent is written %%
-           so we need one extra characters.  */
-        size += 1;
-      }
-    } else if (*c == ';') {
-      if (flags & Shell_Flag_VSIDE) {
-        /* In a VS IDE a semicolon is written ";" so we need two extra
-           characters.  */
-        size += 2;
-      }
-    }
-  }
-
-  /* Check whether the argument needs surrounding quotes.  */
-  if (Shell__ArgumentNeedsQuotes(in, isUnix, flags)) {
-    /* Surrounding quotes are needed.  Allocate space for them.  */
-    if ((flags & Shell_Flag_WatcomQuote) && (isUnix)) {
-      size += 2;
-    }
-    size += 2;
-
-    /* We must escape all ending backslashes when quoting on windows.  */
-    size += windows_backslashes;
-  }
-
-  return size;
-}
-
-char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
-                                            int isUnix, int flags)
-{
-  /* 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.  */
   int needQuotes = Shell__ArgumentNeedsQuotes(in, isUnix, flags);
   if (needQuotes) {
     /* Add the opening quote for this argument.  */
     if (flags & Shell_Flag_WatcomQuote) {
       if (isUnix) {
-        *out++ = '"';
+        out << '"';
       }
-      *out++ = '\'';
+      out << '\'';
     } else {
-      *out++ = '"';
+      out << '"';
     }
   }
 
@@ -720,7 +599,7 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
       if (skip != c) {
         /* Copy to the end of the make variable references.  */
         while (c != skip) {
-          *out++ = *c++;
+          out << *c++;
         }
 
         /* The make variable reference eliminates any escaping needed
@@ -740,7 +619,7 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
          quoted argument.  */
       if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') {
         /* This character needs a backslash to escape it.  */
-        *out++ = '\\';
+        out << '\\';
       }
     } else if (flags & Shell_Flag_EchoWindows) {
       /* On Windows the built-in command shell echo never needs escaping.  */
@@ -754,11 +633,11 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
            backslashes.  */
         while (windows_backslashes > 0) {
           --windows_backslashes;
-          *out++ = '\\';
+          out << '\\';
         }
 
         /* Add the backslash to escape the double-quote.  */
-        *out++ = '\\';
+        out << '\\';
       } else {
         /* We encountered a normal character.  This eliminates any
            escaping needed for preceding backslashes.  */
@@ -771,8 +650,7 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
       if (flags & Shell_Flag_Make) {
         /* In Makefiles a dollar is written $$.  The make tool will
            replace it with just $ before passing it to the shell.  */
-        *out++ = '$';
-        *out++ = '$';
+        out << "$$";
       } else if (flags & Shell_Flag_VSIDE) {
         /* In a VS IDE a dollar is written "$".  If this is written in
            an un-quoted argument it starts a quoted segment, inserts
@@ -780,34 +658,30 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
            argument it ends quoting, inserts the $ and restarts
            quoting.  Either way the $ is isolated from surrounding
            text to avoid looking like a variable reference.  */
-        *out++ = '"';
-        *out++ = '$';
-        *out++ = '"';
+        out << "\"$\"";
       } else {
         /* Otherwise a dollar is written just $. */
-        *out++ = '$';
+        out << '$';
       }
     } else if (*c == '#') {
       if ((flags & Shell_Flag_Make) && (flags & Shell_Flag_WatcomWMake)) {
         /* In Watcom WMake makefiles a pound is written $#.  The make
            tool will replace it with just # before passing it to the
            shell.  */
-        *out++ = '$';
-        *out++ = '#';
+        out << "$#";
       } else {
         /* Otherwise a pound is written just #. */
-        *out++ = '#';
+        out << '#';
       }
     } else if (*c == '%') {
       if ((flags & Shell_Flag_VSIDE) ||
           ((flags & Shell_Flag_Make) &&
            ((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) {
         /* In the VS IDE, NMake, or MinGW make a percent is written %%.  */
-        *out++ = '%';
-        *out++ = '%';
+        out << "%%";
       } else {
         /* Otherwise a percent is written just %. */
-        *out++ = '%';
+        out << '%';
       }
     } else if (*c == ';') {
       if (flags & Shell_Flag_VSIDE) {
@@ -816,16 +690,14 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
            inserts the ; and ends the segment.  If it is written in a
            quoted argument it ends quoting, inserts the ; and restarts
            quoting.  Either way the ; is isolated.  */
-        *out++ = '"';
-        *out++ = ';';
-        *out++ = '"';
+        out << "\";\"";
       } else {
         /* Otherwise a semicolon is written just ;. */
-        *out++ = ';';
+        out << ';';
       }
     } else {
       /* Store this character.  */
-      *out++ = *c;
+      out << *c;
     }
   }
 
@@ -833,45 +705,31 @@ char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
     /* Add enough backslashes to escape any trailing ones.  */
     while (windows_backslashes > 0) {
       --windows_backslashes;
-      *out++ = '\\';
+      out << '\\';
     }
 
     /* Add the closing quote for this argument.  */
     if (flags & Shell_Flag_WatcomQuote) {
-      *out++ = '\'';
+      out << '\'';
       if (isUnix) {
-        *out++ = '"';
+        out << '"';
       }
     } else {
-      *out++ = '"';
+      out << '"';
     }
   }
 
-  /* Store a terminating null without incrementing.  */
-  *out = 0;
-
-  return out;
-}
-
-char* cmOutputConverter::Shell_GetArgumentForWindows(const char* in, char* out,
-                                                     int flags)
-{
-  return Shell__GetArgument(in, out, 0, flags);
-}
-
-char* cmOutputConverter::Shell_GetArgumentForUnix(const char* in, char* out,
-                                                  int flags)
-{
-  return Shell__GetArgument(in, out, 1, flags);
+  return out.str();
 }
 
-int cmOutputConverter::Shell_GetArgumentSizeForWindows(const char* in,
-                                                       int flags)
+std::string cmOutputConverter::Shell_GetArgumentForWindows(const char* in,
+                                                           int flags)
 {
-  return Shell__GetArgumentSize(in, 0, flags);
+  return Shell__GetArgument(in, 0, flags);
 }
 
-int cmOutputConverter::Shell_GetArgumentSizeForUnix(const char* in, int flags)
+std::string cmOutputConverter::Shell_GetArgumentForUnix(const char* in,
+                                                        int flags)
 {
-  return Shell__GetArgumentSize(in, 1, flags);
+  return Shell__GetArgument(in, 1, flags);
 }

+ 3 - 14
Source/cmOutputConverter.h

@@ -126,17 +126,8 @@ public:
    * modify the generated quoting and escape sequences to work under
    * alternative environments.
    */
-  static char* Shell_GetArgumentForWindows(const char* in, char* out,
-                                           int flags);
-  static char* Shell_GetArgumentForUnix(const char* in, char* out, int flags);
-
-  /**
-   * Compute the size of the buffer required to store the output from
-   * Shell_GetArgumentForWindows or Shell_GetArgumentForUnix.  The flags
-   * passed must be identical between the two calls.
-   */
-  static int Shell_GetArgumentSizeForWindows(const char* in, int flags);
-  static int Shell_GetArgumentSizeForUnix(const char* in, int flags);
+  static std::string Shell_GetArgumentForWindows(const char* in, int flags);
+  static std::string Shell_GetArgumentForUnix(const char* in, int flags);
 
   std::string EscapeForShell(const std::string& str, bool makeVars = false,
                              bool forEcho = false,
@@ -182,9 +173,7 @@ private:
   static int Shell__CharIsMakeVariableName(char c);
   static const char* Shell__SkipMakeVariables(const char* c);
   static int Shell__ArgumentNeedsQuotes(const char* in, int isUnix, int flags);
-  static int Shell__GetArgumentSize(const char* in, int isUnix, int flags);
-  static char* Shell__GetArgument(const char* in, char* out, int isUnix,
-                                  int flags);
+  static std::string Shell__GetArgument(const char* in, int isUnix, int flags);
 
 private:
   cmState::Snapshot StateSnapshot;