mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-16 05:26:58 +08:00
cmStringAlgorithms: Add cmExpandList functions
This commit is contained in:
@@ -72,6 +72,77 @@ 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> argsOut;
|
||||||
|
cmExpandList(arg, argsOut, emptyArgs);
|
||||||
|
return argsOut;
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template <std::size_t N, typename T>
|
template <std::size_t N, typename T>
|
||||||
inline void MakeDigits(cm::string_view& view, char (&digits)[N],
|
inline void MakeDigits(cm::string_view& view, char (&digits)[N],
|
||||||
|
@@ -68,6 +68,48 @@ std::string cmJoin(Range const& rng, cm::string_view separator)
|
|||||||
/** Extract tokens that are separated by any of the characters in @a sep. */
|
/** Extract tokens that are separated by any of the characters in @a sep. */
|
||||||
std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep);
|
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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand out any arguments in the string range [@a first, @a last) that have
|
||||||
|
* ; separated strings into multiple arguments. All found arguments are
|
||||||
|
* appended to @a argsOut.
|
||||||
|
*/
|
||||||
|
template <class InputIt>
|
||||||
|
void cmExpandLists(InputIt first, InputIt last,
|
||||||
|
std::vector<std::string>& argsOut)
|
||||||
|
{
|
||||||
|
for (; first != last; ++first) {
|
||||||
|
ExpandList(*first, argsOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as cmExpandList but a new vector is created containing
|
||||||
|
* the expanded arguments from the string @a arg.
|
||||||
|
*/
|
||||||
|
std::vector<std::string> cmExpandedList(cm::string_view arg,
|
||||||
|
bool emptyArgs = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as cmExpandList but a new vector is created containing the expanded
|
||||||
|
* versions of all arguments in the string range [@a first, @a last).
|
||||||
|
*/
|
||||||
|
template <class InputIt>
|
||||||
|
std::vector<std::string> cmExpandedLists(InputIt first, InputIt last)
|
||||||
|
{
|
||||||
|
std::vector<std::string> argsOut;
|
||||||
|
for (; first != last; ++first) {
|
||||||
|
cmExpandList(*first, argsOut);
|
||||||
|
}
|
||||||
|
return argsOut;
|
||||||
|
}
|
||||||
|
|
||||||
/** Concatenate string pieces into a single string. */
|
/** Concatenate string pieces into a single string. */
|
||||||
std::string cmCatViews(std::initializer_list<cm::string_view> views);
|
std::string cmCatViews(std::initializer_list<cm::string_view> views);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user