OSDN Git Service

Shell Extension for Windows 11 or later (5)
[winmerge-jp/winmerge-jp.git] / Src / SubstitutionList.cpp
1 /** 
2  * @file  SubstitutionList.cpp
3  *
4  * @brief Implementation file for SubstitutionList.
5  */
6
7 #include "pch.h"
8 #include "SubstitutionList.h"
9 #include <vector>
10 #include <Poco/RegularExpression.h>
11 #include "unicoder.h"
12
13 SubstitutionItem::SubstitutionItem(const std::string& pattern,
14         const std::string& replacement, int regexpCompileOptions)
15         : pattern(pattern)
16         , replacement(replacement)
17         , regexpCompileOptions(regexpCompileOptions)
18         , regexp(pattern, regexpCompileOptions)
19 {
20 }
21
22 SubstitutionItem::SubstitutionItem(const SubstitutionItem& other)
23         : pattern(other.pattern)
24         , replacement(other.replacement)
25         , regexpCompileOptions(other.regexpCompileOptions)
26         , regexp(other.pattern, other.regexpCompileOptions)
27 {
28 }
29
30 void SubstitutionList::Add(const std::string& pattern, const std::string& replacement, int regexpCompileOptions)
31 {
32         m_list.emplace_back(pattern, replacement, regexpCompileOptions);
33 }
34
35 void SubstitutionList::Add(
36         const std::string& pattern, const std::string& replacement,
37         bool caseSensitive, bool matchWholeWordOnly)
38 {
39         int regexpCompileOptions = 
40                 caseSensitive ? 0 : Poco::RegularExpression::RE_CASELESS;
41         std::string rePattern;
42         for (auto c: pattern)
43         {
44                 switch (c)
45                 {
46                 case '\\': case '.': case '^': case '$': case '|':
47                 case '[':  case ']': case '(': case ')': case '!':
48                 case '?': case '*':  case '+': case '{': case '}':
49                         rePattern.push_back('\\');
50                         break;
51                 default:
52                         break;
53                 }
54                 rePattern.push_back(c);
55         }
56         if (matchWholeWordOnly)
57                 rePattern = "\b" + rePattern + "\b";
58         m_list.emplace_back(rePattern, replacement, regexpCompileOptions);
59 }
60
61 std::string SubstitutionList::Subst(const std::string& subject, int codepage/*=CP_UTF8*/) const
62 {
63         std::string replaced;
64
65         if (codepage != ucr::CP_UTF_8)
66         {
67                 // convert string into UTF-8
68                 ucr::buffer buf(subject.length() * 2);
69
70                 ucr::convert(ucr::NONE, codepage, reinterpret_cast<const unsigned char*>(subject.c_str()),
71                         subject.length(), ucr::UTF8, ucr::CP_UTF_8, &buf);
72
73                 replaced.assign(reinterpret_cast<const char *>(buf.ptr), buf.size);
74         }
75         else
76         {
77                 replaced = subject;
78         }
79
80         for (const auto& item : m_list)
81         {
82                 try
83                 {
84                         item.regexp.subst(replaced, item.replacement, Poco::RegularExpression::RE_GLOBAL);
85                 }
86                 catch (...)
87                 {
88                         // TODO:
89                 }
90         }
91
92         return replaced;
93 }
94
95 void SubstitutionList::RemoveAllFilters()
96 {
97         m_list.clear();
98 }
99