Browse Source

cmExpandList and cmExpandLists rely on cmList class

Marc Chevrier 2 năm trước cách đây
mục cha
commit
51b0d45d91
3 tập tin đã thay đổi với 66 bổ sung75 xóa
  1. 53 3
      Source/cmList.h
  2. 0 64
      Source/cmStringAlgorithms.cxx
  3. 13 8
      Source/cmStringAlgorithms.h

+ 53 - 3
Source/cmList.h

@@ -16,6 +16,8 @@
 #include <vector>
 
 #include <cm/string_view>
+#include <cm/type_traits>
+#include <cmext/iterator>
 
 #include "cmValue.h"
 
@@ -1177,6 +1179,13 @@ inline std::vector<std::string>& operator+=(std::vector<std::string>& l,
   return l;
 }
 
+namespace std {
+inline void swap(cmList& lhs, cmList& rhs) noexcept
+{
+  lhs.swap(rhs);
+}
+} // namespace std
+
 namespace cm {
 inline void erase(cmList& list, const std::string& value)
 {
@@ -1188,11 +1197,52 @@ inline void erase_if(cmList& list, Predicate pred)
 {
   list.erase(std::remove_if(list.begin(), list.end(), pred), list.end());
 }
+
+//
+// Provide a special implementation of cm::append because, in this case,
+// expansion must not be applied to the inserted elements
+//
+#if defined(__SUNPRO_CC) && defined(__sparc)
+// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile
+// templates with constraints.
+// So, on this platform, use only simple templates.
+template <typename InputIt,
+          cm::enable_if_t<cm::is_input_iterator<InputIt>::value, int> = 0>
+void append(cmList& v, InputIt first, InputIt last)
+{
+  v.append(first, last, cmList::ExpandElements::No);
 }
 
-namespace srd {
-inline void swap(cmList& lhs, cmList& rhs) noexcept
+template <typename Range,
+          cm::enable_if_t<cm::is_input_range<Range>::value, int> = 0>
+void append(cmList& v, Range const& r)
 {
-  lhs.swap(rhs);
+  v.append(r.begin(), r.end(), cmList::ExpandElements::No);
+}
+
+#else
+
+template <
+  typename InputIt,
+  cm::enable_if_t<
+    cm::is_input_iterator<InputIt>::value &&
+      std::is_convertible<typename std::iterator_traits<InputIt>::value_type,
+                          cmList::value_type>::value,
+    int> = 0>
+void append(cmList& v, InputIt first, InputIt last)
+{
+  v.append(first, last, cmList::ExpandElements::No);
 }
+
+template <typename Range,
+          cm::enable_if_t<cm::is_input_range<Range>::value &&
+                            std::is_convertible<typename Range::value_type,
+                                                cmList::value_type>::value,
+                          int> = 0>
+void append(cmList& v, Range const& r)
+{
+  v.append(r.begin(), r.end(), cmList::ExpandElements::No);
 }
+#endif
+
+} // namespace cm

+ 0 - 64
Source/cmStringAlgorithms.cxx

@@ -80,70 +80,6 @@ std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep)
   return tokens;
 }
 
-void cmExpandList(cm::string_view arg, std::vector<std::string>& argsOut,
-                  bool emptyArgs)
-{
-  // If argument is empty, it is an empty list.
-  if (!emptyArgs && arg.empty()) {
-    return;
-  }
-
-  // if there are no ; in the name then just copy the current string
-  if (arg.find(';') == cm::string_view::npos) {
-    argsOut.emplace_back(arg);
-    return;
-  }
-
-  std::string newArg;
-  // Break the string at non-escaped semicolons not nested in [].
-  int squareNesting = 0;
-  cm::string_view::iterator last = arg.begin();
-  cm::string_view::iterator const cend = arg.end();
-  for (cm::string_view::iterator c = last; c != cend; ++c) {
-    switch (*c) {
-      case '\\': {
-        // We only want to allow escaping of semicolons.  Other
-        // escapes should not be processed here.
-        cm::string_view::iterator cnext = c + 1;
-        if ((cnext != cend) && *cnext == ';') {
-          newArg.append(last, c);
-          // Skip over the escape character
-          last = cnext;
-          c = cnext;
-        }
-      } break;
-      case '[': {
-        ++squareNesting;
-      } break;
-      case ']': {
-        --squareNesting;
-      } break;
-      case ';': {
-        // Break the string here if we are not nested inside square
-        // brackets.
-        if (squareNesting == 0) {
-          newArg.append(last, c);
-          // Skip over the semicolon
-          last = c + 1;
-          if (!newArg.empty() || emptyArgs) {
-            // Add the last argument if the string is not empty.
-            argsOut.push_back(newArg);
-            newArg.clear();
-          }
-        }
-      } break;
-      default: {
-        // Just append this character.
-      } break;
-    }
-  }
-  newArg.append(last, cend);
-  if (!newArg.empty() || emptyArgs) {
-    // Add the last argument if the string is not empty.
-    argsOut.push_back(std::move(newArg));
-  }
-}
-
 std::vector<std::string> cmExpandedList(cm::string_view arg, bool emptyArgs)
 {
   std::vector<std::string> argsOut;

+ 13 - 8
Source/cmStringAlgorithms.h

@@ -14,6 +14,7 @@
 
 #include <cm/string_view>
 
+#include "cmList.h"
 #include "cmRange.h"
 #include "cmValue.h"
 
@@ -92,14 +93,20 @@ std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep);
  * Expand the ; separated string @a arg into multiple arguments.
  * All found arguments are appended to @a argsOut.
  */
-void cmExpandList(cm::string_view arg, std::vector<std::string>& argsOut,
-                  bool emptyArgs = false);
+inline void cmExpandList(cm::string_view arg,
+                         std::vector<std::string>& argsOut,
+                         bool emptyArgs = false)
+{
+  cmList::append(arg, argsOut,
+                 emptyArgs ? cmList::EmptyElements::Yes
+                           : cmList::EmptyElements::No);
+}
 inline void cmExpandList(cmValue arg, std::vector<std::string>& argsOut,
                          bool emptyArgs = false)
 {
-  if (arg) {
-    cmExpandList(*arg, argsOut, emptyArgs);
-  }
+  cmList::append(arg, argsOut,
+                 emptyArgs ? cmList::EmptyElements::Yes
+                           : cmList::EmptyElements::No);
 }
 
 /**
@@ -111,9 +118,7 @@ template <class InputIt>
 void cmExpandLists(InputIt first, InputIt last,
                    std::vector<std::string>& argsOut)
 {
-  for (; first != last; ++first) {
-    cmExpandList(*first, argsOut);
-  }
+  cmList::append(first, last, argsOut);
 }
 
 /**