mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-18 00:02:21 +08:00
cmExpandList and cmExpandLists rely on cmList class
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <cm/string_view>
|
#include <cm/string_view>
|
||||||
|
#include <cm/type_traits>
|
||||||
|
#include <cmext/iterator>
|
||||||
|
|
||||||
#include "cmValue.h"
|
#include "cmValue.h"
|
||||||
|
|
||||||
@@ -1177,6 +1179,13 @@ inline std::vector<std::string>& operator+=(std::vector<std::string>& l,
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
inline void swap(cmList& lhs, cmList& rhs) noexcept
|
||||||
|
{
|
||||||
|
lhs.swap(rhs);
|
||||||
|
}
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
namespace cm {
|
namespace cm {
|
||||||
inline void erase(cmList& list, const std::string& value)
|
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());
|
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 {
|
template <typename Range,
|
||||||
inline void swap(cmList& lhs, cmList& rhs) noexcept
|
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
|
||||||
|
@@ -80,70 +80,6 @@ std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep)
|
|||||||
return tokens;
|
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> cmExpandedList(cm::string_view arg, bool emptyArgs)
|
||||||
{
|
{
|
||||||
std::vector<std::string> argsOut;
|
std::vector<std::string> argsOut;
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <cm/string_view>
|
#include <cm/string_view>
|
||||||
|
|
||||||
|
#include "cmList.h"
|
||||||
#include "cmRange.h"
|
#include "cmRange.h"
|
||||||
#include "cmValue.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.
|
* Expand the ; separated string @a arg into multiple arguments.
|
||||||
* All found arguments are appended to @a argsOut.
|
* All found arguments are appended to @a argsOut.
|
||||||
*/
|
*/
|
||||||
void cmExpandList(cm::string_view arg, std::vector<std::string>& argsOut,
|
inline void cmExpandList(cm::string_view arg,
|
||||||
bool emptyArgs = false);
|
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,
|
inline void cmExpandList(cmValue arg, std::vector<std::string>& argsOut,
|
||||||
bool emptyArgs = false)
|
bool emptyArgs = false)
|
||||||
{
|
{
|
||||||
if (arg) {
|
cmList::append(arg, argsOut,
|
||||||
cmExpandList(*arg, argsOut, emptyArgs);
|
emptyArgs ? cmList::EmptyElements::Yes
|
||||||
}
|
: cmList::EmptyElements::No);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,9 +118,7 @@ template <class InputIt>
|
|||||||
void cmExpandLists(InputIt first, InputIt last,
|
void cmExpandLists(InputIt first, InputIt last,
|
||||||
std::vector<std::string>& argsOut)
|
std::vector<std::string>& argsOut)
|
||||||
{
|
{
|
||||||
for (; first != last; ++first) {
|
cmList::append(first, last, argsOut);
|
||||||
cmExpandList(*first, argsOut);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user