* @brief Default constructor.
*/
SubstitutionFiltersList::SubstitutionFiltersList()
-: m_pOptionsMgr(nullptr)
+: m_enabled(false)
+, m_pOptionsMgr(nullptr)
{
}
#include <Poco/RegularExpression.h>
#include "unicoder.h"
+static std::string replaceEscapeSequences(const std::string& input)
+{
+ std::string result;
+
+ for (size_t i = 0; i < input.size(); ++i)
+ {
+ if (input[i] == '\\')
+ {
+ if (i + 1 < input.size())
+ {
+ switch (input[i + 1])
+ {
+ case 'a':
+ result += '\a';
+ break;
+ case 'b':
+ result += '\b';
+ break;
+ case 'f':
+ result += '\f';
+ break;
+ case 'n':
+ result += '\n';
+ break;
+ case 'r':
+ result += '\r';
+ break;
+ case 't':
+ result += '\t';
+ break;
+ case 'v':
+ result += '\v';
+ break;
+ case 'x':
+ if (i + 3 < input.size())
+ {
+ std::string hexValue = input.substr(i + 2, 2);
+ try {
+ unsigned int intValue = std::stoul(hexValue, nullptr, 16);
+ result += static_cast<char>(intValue);
+ i += 2;
+ }
+ catch (const std::invalid_argument&) {
+ result += "\\x";
+ }
+ }
+ else
+ {
+ result += "\\x";
+ }
+ break;
+ default:
+ if (isdigit(input[i + 1]))
+ result += '$';
+ result += input[i + 1];
+ break;
+ }
+ ++i;
+ }
+ }
+ else
+ {
+ result += input[i];
+ }
+ }
+
+ return result;
+}
+
SubstitutionItem::SubstitutionItem(const std::string& pattern,
const std::string& replacement, int regexpCompileOptions)
: pattern(pattern)
- , replacement(replacement)
+ , replacement(replaceEscapeSequences(replacement))
, regexpCompileOptions(regexpCompileOptions)
, regexp(pattern, regexpCompileOptions)
{
--- /dev/null
+#include "pch.h"
+#include <gtest/gtest.h>
+#include <vector>
+#include "SubstitutionList.h"
+#include "Environment.h"
+#include "paths.h"
+
+namespace
+{
+ // The fixture for testing string differencing functions.
+ class SubstitutionListTest : public testing::Test
+ {
+ protected:
+ // You can remove any or all of the following functions if its body
+ // is empty.
+
+ SubstitutionListTest()
+ {
+ // You can do set-up work for each test here.
+ }
+
+ virtual ~SubstitutionListTest()
+ {
+ // You can do clean-up work that doesn't throw exceptions here.
+ }
+
+ // If the constructor and destructor are not enough for setting up
+ // and cleaning up each test, you can define the following methods:
+
+ virtual void SetUp()
+ {
+ // Code here will be called immediately after the constructor (right
+ // before each test).
+ }
+
+ virtual void TearDown()
+ {
+ // Code here will be called immediately after each test (right
+ // before the destructor).
+ }
+
+ // Objects declared here can be used by all tests in the test case for Foo.
+ SubstitutionList m_substitutionList;
+ };
+
+ TEST_F(SubstitutionListTest, test)
+ {
+ SubstitutionList list;
+ EXPECT_FALSE(list.HasRegExps());
+ list.Add("abc", "\\a\\b\\f\\n\\r\\t\\v", Poco::RegularExpression::RE_MULTILINE);
+ EXPECT_TRUE(list.HasRegExps());
+ list.Add("([0-9]+) ([A-Z]+)", "\\2-\\1", Poco::RegularExpression::RE_MULTILINE);
+ list.Add("def", "\\x01\\xEF\\xab\\x", Poco::RegularExpression::RE_MULTILINE);
+ EXPECT_EQ(3, list.GetCount());
+ EXPECT_EQ("-\a\b\f\n\r\t\v-", list.Subst("-abc-"));
+ EXPECT_EQ("-ABCD-0123-", list.Subst("-0123 ABCD-"));
+ EXPECT_EQ("\x01\xef\xab\\x", list.Subst("def"));
+ list.RemoveAllFilters();
+ EXPECT_EQ(0, list.GetCount());
+ }
+
+
+
+} // namespace
</ClCompile>
<ClCompile Include="..\..\..\Src\HashCalc.cpp" />
<ClCompile Include="..\..\..\Src\PropertySystem.cpp" />
+ <ClCompile Include="..\..\..\Src\SubstitutionList.cpp" />
<ClCompile Include="..\BinaryCompare\BinaryCompare_test.cpp">
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>
</ClCompile>
+ <ClCompile Include="..\DirFilter\DirFilters_test.cpp">
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>
+ </ClCompile>
<ClCompile Include="..\DirWatcher\DirWatcher_test.cpp" />
<ClCompile Include="..\PropertySystem\PropertySystem_test.cpp" />
<ClCompile Include="..\ShellFileOperations\ShellFileOperations_test.cpp">
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>
</ClCompile>
+ <ClCompile Include="..\SubstitutionList\SubstitutionList_test.cpp" />
<ClCompile Include="..\TimeSizeCompare\TimeSizeCompare_test.cpp">
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<ClInclude Include="..\..\..\Src\Common\unicoder.h" />
<ClInclude Include="..\..\..\Src\Common\UnicodeString.h" />
<ClInclude Include="..\..\..\Src\Common\varprop.h" />
+ <ClInclude Include="..\..\..\Src\SubstitutionList.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<ClCompile Include="..\..\..\Src\Common\cio.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\DirFilter\DirFilters_test.cpp">
+ <Filter>Tests</Filter>
+ </ClCompile>
+ <ClCompile Include="..\SubstitutionList\SubstitutionList_test.cpp">
+ <Filter>Tests</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\SubstitutionList.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Src\CompareEngines\ByteComparator.h">
<ClInclude Include="..\..\..\Src\Common\cio.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\Src\SubstitutionList.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file