From 5a84a126422a3d89a9ec769c743027347db36d67 Mon Sep 17 00:00:00 2001 From: Ventsy Velev Date: Fri, 10 Nov 2023 10:33:23 -0500 Subject: [PATCH] Extracts append and appendGroup into separate functions. Adds double quotes handling --- src/Expander.cpp | 119 ++++++++++++++++++++++++++++-------------- src/Expander.h | 4 +- test/TestExpander.cpp | 22 ++++++++ 3 files changed, 104 insertions(+), 41 deletions(-) diff --git a/src/Expander.cpp b/src/Expander.cpp index 394360e..37c42cf 100755 --- a/src/Expander.cpp +++ b/src/Expander.cpp @@ -11,6 +11,53 @@ Expander::Expander(wchar_t esc, wchar_t range, wchar_t grpBegin, wchar_t grpEnd) { } +void Expander::append(vector &results, const wstring &newData) +{ + if (results.size() == 0) //data array is empty + { + results.push_back(newData); + } + else //variations are present. + { + //add the constant character to all variations + //Just appending the constant character to all patterns + for (size_t j = 0; j < results.size(); j++) + { + results[j] = results[j] + newData; + } + } +} + +void Expander::appendGroup(bool &isFirstInGroup, const wstring &newData, vector &partials, vector &results) +{ + //when we first enter the variable block, we save the + //existing patterns + if (isFirstInGroup) + { + partials = results; + //The variable block is not optional, so we need to clear the result set + //For example: 1[a-c] is expected to produce 1a, 1b, 1c + //Without the clear, it produces 1, 1a, 1b, 1c + results.clear(); + isFirstInGroup = false; + } + //It's possible the variable block appears first in the pattern + //That means that the result set is empty + //If that's the case, just add the first item from the varible block + if (partials.empty()) + results.push_back(newData); + else + { + //The result set is not empty + //Append the first item of the variable block to the existing patterns, + //then add it the result set. + for (uint item = 0; item < partials.size(); item++) + { + results.push_back(partials[item] + newData); + } + } +} + void Expander::generate(const wstring &pattern) { vector results; @@ -53,54 +100,37 @@ void Expander::generate(const wstring &pattern) load--; continue; } - - //it is a part of the pattern - if (load == 0) //constant character - escape sequences here are disregarded + else if (expandedPattern[i] == DOUBLE_QUOTE) { - if (results.size() == 0) //data array is empty + //Just skip everything thats in quotes + uint startIndex = ++i; + while (expandedPattern[i] != DOUBLE_QUOTE && i < pLength) { - results.push_back(wstring(1, expandedPattern[i])); - } - else //variations are present. - { - //add the constant character to all variations - //Just appending the constant character to all patterns - for (size_t j = 0; j < results.size(); j++) - { - results[j] = results[j] + expandedPattern[i]; - } + i++; } - } - else if (load > 0) //wchar_tacter inside a variable block - { - //when we first enter the variable block, we save the - //existing patterns - if (isFirstInGroup) + + uint numChars = i - startIndex; + wstring quotedStr = expandedPattern.substr(startIndex, numChars); + if (load == 0) //constant character - escape sequences here are disregarded { - partials = results; - //The variable block is not optional, so we need to clear the result set - //For example: 1[a-c] is expected to produce 1a, 1b, 1c - //Without the clear, it produces 1, 1a, 1b, 1c - results.clear(); - isFirstInGroup = false; + append(results, quotedStr); } - - //It's possible the variable block appears first in the pattern - //That means that the result set is empty - //If that's the case, just add the first item from the varible block - if (partials.empty()) - results.push_back(wstring(1, expandedPattern[i])); - else + else if (load > 0) //wchar_tacter inside a variable block { - //The result set is not empty - //Append the first item of the variable block to the existing patterns, - //then add it the result set. - for (uint item = 0; item < partials.size(); item++) - { - results.push_back(partials[item] + expandedPattern[i]); - } + appendGroup(isFirstInGroup, quotedStr, partials, results); } + //Skip the trailing quote + continue; + } + if (load == 0) //constant character - escape sequences here are disregarded + { + append(results, wstring(1,expandedPattern[i])); + } + else if (load > 0) //wchar_tacter inside a variable block + { + auto newData = wstring(1,expandedPattern[i]); + appendGroup(isFirstInGroup, newData, partials, results); } escSeqReached = false; } //end for @@ -220,6 +250,15 @@ std::wstring Expander::expand(const std::wstring &pattern) i++; continue; } + else if (pattern[i] == DOUBLE_QUOTE) + { + //Just skip everything thats in quotes + i++; + while (pattern[i] != DOUBLE_QUOTE && i < size) + { + i++; + } + } else if (pattern[i] == groupBegin) { load++; diff --git a/src/Expander.h b/src/Expander.h index 3b08551..a56a92e 100755 --- a/src/Expander.h +++ b/src/Expander.h @@ -123,7 +123,9 @@ class Expander void processGroup(const std::wstring &pattern, uint &i, uint ¤tItem); bool getLoadBalance(const std::wstring &pattern); - + void append(std::vector &results, + const std::wstring &newData); + void appendGroup(bool &isFirstInGroup, const std::wstring &newData, std::vector &partials, std::vector &results); }; } //end namespace diff --git a/test/TestExpander.cpp b/test/TestExpander.cpp index 6479039..469b977 100644 --- a/test/TestExpander.cpp +++ b/test/TestExpander.cpp @@ -707,6 +707,28 @@ TEST_F(TestExpander, testGenerate_Static_Range_End) EXPECT_EQ(data[2], L"3a-c"); } +TEST_F(TestExpander, testGenerate_QuotedString_InGroup) +{ + + wstring pattern = L"a[b\"123\"c]\""; + underTest.generate(pattern); + auto data = underTest.getData(); + EXPECT_EQ(data.size(), 3); + EXPECT_EQ(data[0], L"ab"); + EXPECT_EQ(data[1], L"a123"); + EXPECT_EQ(data[2], L"ac"); +} + +TEST_F(TestExpander, testGenerate_QuotedString) +{ + + wstring pattern = L"\"[a-c]\""; + underTest.generate(pattern); + auto data = underTest.getData(); + EXPECT_EQ(data.size(), 1); + EXPECT_EQ(data[0], L"[a-c]"); +} + int main(int argc, char **argv) {