2525#pragma warning(push)
2626#pragma warning(disable : 4996) // warning STL4010: Various members of std::allocator are deprecated in C++17
2727#include < boost/regex.hpp>
28- #include < boost/iostreams/device/mapped_file.hpp>
29-
3028#pragma warning(pop)
3129
30+ template <typename CharT>
3231class NumberReplacer
3332{
3433public:
@@ -40,41 +39,22 @@ class NumberReplacer
4039 {
4140 }
4241
43- bool leadZero;
44- int padding;
45- int start;
46- int increment;
47- std::wstring expression;
48- };
49-
50- class NumberReplacerA
51- {
52- public:
53- NumberReplacerA ()
54- : leadZero(false )
55- , padding(0 )
56- , start(1 )
57- , increment(1 )
58- {
59- }
60-
61- bool leadZero;
62- int padding;
63- int start;
64- int increment;
65- std::string expression;
42+ bool leadZero;
43+ int padding;
44+ int start;
45+ int increment;
46+ std::basic_string<CharT> expression;
6647};
6748
68- extern std::vector<NumberReplacer> g_incVec;
69- extern std::vector<NumberReplacerA> g_incVecA;
70-
49+ // Iter is the same as the BidirectionalIterator in which `regex_replace` it is used
50+ template <typename CharT, typename Iter = std::basic_string<CharT>::const_iterator>
7151class RegexReplaceFormatter
7252{
7353public:
74- RegexReplaceFormatter (const std::wstring& sReplace )
75- : m_sReplace(sReplace )
54+ RegexReplaceFormatter (const std::basic_string<CharT>& str )
55+ : m_sReplace(str )
7656 {
77- g_incVec .clear ();
57+ m_incVec .clear ();
7858 // parse for ${count0L}, ${count0L(n)}, ${count0L(n,m)}, where
7959 // ${count}
8060 // is replaced later with numbers starting from 1, incremented by 1
@@ -84,53 +64,71 @@ class RegexReplaceFormatter
8464 // is replaced with numbers starting from n, incremented by m
8565 // 0 and L are optional and specify the size of the right-aligned
8666 // number string. If 0 is specified, zeros are used for padding, otherwise spaces.
87- // boost::wregex expression = boost::wregex(L"(?<!\\\\)\\$\\{count(?<leadzero>0)?(?<length>\\d+)?(\\((?<startval>[-0-9]+)\\)||\\((?<startval>[-0-9]+),(?<increment>[-0-9]+)\\))?\\}", boost::regex::normal);
88- boost::wregex expression = boost::wregex (L" \\ $\\ {count(?<leadzero>0)?(?<length>\\ d+)?(\\ ((?<startval>[-0-9]+)\\ )||\\ ((?<startval>[-0-9]+),(?<increment>[-0-9]+)\\ ))?\\ }" , boost::regex::normal);
89- boost::match_results<std::wstring::const_iterator> whatc;
90- std::wstring::const_iterator start = m_sReplace.begin ();
91- std::wstring::const_iterator end = m_sReplace.end ();
92- boost::match_flag_type flags = boost::match_default | boost::format_all;
93- while (boost::regex_search (start, end, whatc, expression, flags))
67+ // expr: "\\$\\{count(?<leadzero>0)?(?<length>\\d+)?(\\((?<startval>[-0-9]+)\\)||\\((?<startval>[-0-9]+),(?<increment>[-0-9]+)\\))?\\}"
68+ CharT expr[] = {
69+ ' \\ ' , ' $' , ' \\ ' , ' {' ,
70+ ' c' , ' o' , ' u' , ' n' , ' t' ,
71+ ' (' , ' ?' , ' <' , ' l' , ' e' , ' a' , ' d' , ' z' , ' e' , ' r' , ' o' , ' >' , ' 0' , ' )' , ' ?' ,
72+ ' (' , ' ?' , ' <' , ' l' , ' e' , ' n' , ' g' , ' t' , ' h' , ' >' , ' \\ ' , ' d' , ' +' , ' )' , ' ?' ,
73+ ' (' ,
74+ ' \\ ' , ' (' , ' (' , ' ?' , ' <' , ' s' , ' t' , ' a' , ' r' , ' t' , ' v' , ' a' , ' l' , ' >' , ' [' , ' -' , ' 0' , ' -' , ' 9' , ' ]' , ' +' , ' )' , ' \\ ' , ' )' , ' |' , ' |' ,
75+ ' \\ ' , ' (' , ' (' , ' ?' , ' <' , ' s' , ' t' , ' a' , ' r' , ' t' , ' v' , ' a' , ' l' , ' >' , ' [' , ' -' , ' 0' , ' -' , ' 9' , ' ]' , ' +' , ' )' , ' ,' ,
76+ ' (' , ' ?' , ' <' , ' i' , ' n' , ' c' , ' r' , ' e' , ' m' , ' e' , ' n' , ' t' , ' >' , ' [' , ' -' , ' 0' , ' -' , ' 9' , ' ]' , ' +' , ' )' ,
77+ ' \\ ' , ' )' ,
78+ ' )' , ' ?' ,
79+ ' \\ ' , ' }' , 0
80+ };
81+ boost::basic_regex<CharT> regEx = boost::basic_regex<CharT>(expr, boost::regex::normal);
82+ boost::match_results<std::basic_string<CharT>::const_iterator> whatC;
83+ typename std::basic_string<CharT>::const_iterator start = m_sReplace.begin ();
84+ typename std::basic_string<CharT>::const_iterator end = m_sReplace.end ();
85+ boost::match_flag_type flags = boost::match_default | boost::format_all;
86+ while (boost::regex_search (start, end, whatC, regEx, flags))
9487 {
95- if (whatc [0 ].matched )
88+ if (whatC [0 ].matched )
9689 {
97- NumberReplacer nr;
98- nr.leadZero = (static_cast <std::wstring>(whatc[L" leadzero" ]) == L" 0" );
99- nr.padding = _wtoi (static_cast <std::wstring>(whatc[L" length" ]).c_str ());
100- std::wstring s = static_cast <std::wstring>(whatc[L" startval" ]);
90+ NumberReplacer<CharT> nr;
91+ CharT leadzero[] = {' l' , ' e' , ' a' , ' d' , ' z' , ' e' , ' r' , ' o' , 0 };
92+ CharT zero[] = {' 0' , 0 };
93+ nr.leadZero = (static_cast <std::basic_string<CharT>>(whatC[leadzero]) == zero);
94+ CharT length[] = {' l' , ' e' , ' n' , ' g' , ' t' , ' h' , 0 };
95+ nr.padding = t_ttoi (static_cast <std::basic_string<CharT>>(whatC[length]).c_str ());
96+ CharT startval[] = {' s' , ' t' , ' a' , ' r' , ' t' , ' v' , ' a' , ' l' , 0 };
97+ std::basic_string<CharT> s = static_cast <std::basic_string<CharT>>(whatC[startval]);
10198 if (!s.empty ())
102- nr.start = _wtoi (s.c_str ());
103- s = static_cast <std::wstring>(whatc[L" increment" ]);
99+ nr.start = t_ttoi (s.c_str ());
100+ CharT increment[] = {' i' , ' n' , ' c' , ' r' , ' e' , ' m' , ' e' , ' n' , ' t' , 0 };
101+ s = static_cast <std::basic_string<CharT>>(whatC[increment]);
104102 if (!s.empty ())
105- nr.increment = _wtoi (s.c_str ());
103+ nr.increment = t_ttoi (s.c_str ());
106104 if (nr.increment == 0 )
107105 nr.increment = 1 ;
108- nr.expression = static_cast <std::wstring>(whatc [0 ]);
109- g_incVec .push_back (nr);
106+ nr.expression = static_cast <std::basic_string<CharT>>(whatC [0 ]);
107+ m_incVec .push_back (nr);
110108 }
111109 // update search position:
112- if (start == whatc [0 ].second )
110+ if (start == whatC [0 ].second )
113111 {
114112 if (start == end)
115113 break ;
116114 ++start;
117115 }
118116 else
119- start = whatc [0 ].second ;
117+ start = whatC [0 ].second ;
120118 // update flags:
121119 flags |= boost::match_prev_avail;
122120 flags |= boost::match_not_bob;
123121 }
124122 }
125123
126- void SetReplacePair (const std::wstring & s1, const std::wstring & s2)
124+ void SetReplacePair (const std::basic_string<CharT> & s1, const std::basic_string<CharT> & s2)
127125 {
128126 m_replaceMap[s1] = s2;
129127 }
130128
131- std::wstring operator ()(boost::match_results<std::wstring::const_iterator > what) const
129+ std::basic_string<CharT> operator ()(boost::match_results<Iter > what)
132130 {
133- std::wstring sReplace = what.format (m_sReplace);
131+ std::basic_string<CharT> sReplace = what.format (m_sReplace);
134132 if (!m_replaceMap.empty ())
135133 {
136134 for (auto it = m_replaceMap.cbegin (); it != m_replaceMap.cend (); ++it)
@@ -151,31 +149,38 @@ class RegexReplaceFormatter
151149 }
152150 }
153151 }
154- if (!g_incVec .empty ())
152+ if (!m_incVec .empty ())
155153 {
156- for (auto it = g_incVec .begin (); it != g_incVec .end (); ++it)
154+ for (auto it = m_incVec .begin (); it != m_incVec .end (); ++it)
157155 {
158156 auto itBegin = std::search (sReplace .begin (), sReplace .end (), it->expression .begin (), it->expression .end ());
159157 if (itBegin != sReplace .end ())
160158 {
161159 if ((itBegin == sReplace .begin ()) || ((*(itBegin - 1 )) != ' \\ ' ))
162160 {
163161 auto itEnd = itBegin + it->expression .size ();
164- wchar_t format[20 ] = {0 };
162+ CharT format[20 ] = {0 };
165163 if (it->padding )
166164 {
165+ CharT *fmt;
166+ CharT fmt1[] = {' %' , ' %' , ' 0' , ' %' , ' d' , ' d' , 0 };
167+ CharT fmt2[] = {' %' , ' %' , ' %' , ' d' , ' d' , 0 };
167168 if (it->leadZero )
168- swprintf_s (format, _countof (format), L" %%0%dd " , it-> padding ) ;
169+ fmt = fmt1 ;
169170 else
170- swprintf_s (format, _countof (format), L" %%%dd" , it->padding );
171+ fmt = fmt2;
172+ t_stprintf_s (format, _countof (format), fmt, it->padding );
171173 }
172174 else
173- wcscpy_s (format, L" %d" );
175+ {
176+ CharT fmt[] = {' %' , ' d' , 0 };
177+ t_tcscpy_s (format, fmt);
178+ }
174179 if (it->padding < 50 )
175180 {
176181 // for small strings, reserve space on the stack
177- wchar_t buf[128 ] = {0 };
178- swprintf_s (buf, _countof (buf), format, it->start );
182+ CharT buf[128 ] = {0 };
183+ t_stprintf_s (buf, _countof (buf), format, it->start );
179184 sReplace .replace (itBegin, itEnd, buf);
180185 }
181186 else
@@ -193,146 +198,54 @@ class RegexReplaceFormatter
193198 }
194199 }
195200
196- // sReplace = boost::regex_replace(what[0].str(), sReplace, boost::match_default);
197-
198201 return sReplace ;
199202 }
200203
201204private:
202- std::wstring m_sReplace;
203- std::map<std::wstring, std::wstring> m_replaceMap;
204- };
205+ int t_ttoi (const wchar_t *str)
206+ {
207+ return _wtoi (str);
208+ }
205209
206- class RegexReplaceFormatterA
207- {
208- public:
209- RegexReplaceFormatterA (const std::string& sReplace )
210- : m_sReplace(sReplace )
210+ int t_ttoi (const char *str)
211211 {
212- g_incVec.clear ();
213- // parse for ${count0L}, ${count0L(n)}, ${count0L(n,m)}, where
214- // ${count}
215- // is replaced later with numbers starting from 1, incremented by 1
216- // ${count(n)}
217- // is replaced with numbers starting from n, incremented by 1
218- // ${count(n,m)}
219- // is replaced with numbers starting from n, incremented by m
220- // 0 and L are optional and specify the size of the right-aligned
221- // number string. If 0 is specified, zeros are used for padding, otherwise spaces.
222- // boost::wregex expression = boost::wregex(L"(?<!\\\\)\\$\\{count(?<leadzero>0)?(?<length>\\d+)?(\\((?<startval>[-0-9]+)\\)||\\((?<startval>[-0-9]+),(?<increment>[-0-9]+)\\))?\\}", boost::regex::normal);
223- boost::regex expression = boost::regex (" \\ $\\ {count(?<leadzero>0)?(?<length>\\ d+)?(\\ ((?<startval>[-0-9]+)\\ )||\\ ((?<startval>[-0-9]+),(?<increment>[-0-9]+)\\ ))?\\ }" , boost::regex::normal);
224- boost::match_results<std::string::const_iterator> whatc;
225- std::string::const_iterator start = m_sReplace.begin ();
226- std::string::const_iterator end = m_sReplace.end ();
227- boost::match_flag_type flags = boost::match_default | boost::format_all;
228- while (boost::regex_search (start, end, whatc, expression, flags))
229- {
230- if (whatc[0 ].matched )
231- {
232- NumberReplacerA nr;
233- nr.leadZero = (static_cast <std::string>(whatc[" leadzero" ]) == " 0" );
234- nr.padding = atoi (static_cast <std::string>(whatc[" length" ]).c_str ());
235- std::string s = static_cast <std::string>(whatc[" startval" ]);
236- if (!s.empty ())
237- nr.start = atoi (s.c_str ());
238- s = static_cast <std::string>(whatc[" increment" ]);
239- if (!s.empty ())
240- nr.increment = atoi (s.c_str ());
241- if (nr.increment == 0 )
242- nr.increment = 1 ;
243- nr.expression = static_cast <std::string>(whatc[0 ]);
244- g_incVecA.push_back (nr);
245- }
246- // update search position:
247- if (start == whatc[0 ].second )
248- {
249- if (start == end)
250- break ;
251- ++start;
252- }
253- else
254- start = whatc[0 ].second ;
255- // update flags:
256- flags |= boost::match_prev_avail;
257- flags |= boost::match_not_bob;
258- }
212+ return atoi (str);
259213 }
260214
261- void SetReplacePair ( const std::string& s1 , const std::string& s2 )
215+ int t_stprintf_s ( wchar_t *buffer, size_t sizeOfBuffer , const wchar_t *format, ... )
262216 {
263- m_replaceMap[s1] = s2;
217+ int _Result;
218+ va_list _ArgList;
219+ __crt_va_start (_ArgList, format);
220+ _Result = _vswprintf_s_l (buffer, sizeOfBuffer, format, NULL , _ArgList);
221+ __crt_va_end (_ArgList);
222+ return _Result;
264223 }
265224
266- template <typename It>
267- std::string operator ()(boost::match_results<It> what) const
225+ int t_stprintf_s (char *buffer, size_t sizeOfBuffer, const char *format, ...)
268226 {
269- std::string sReplace = what.format (m_sReplace);
270- if (!m_replaceMap.empty ())
271- {
272- for (auto it = m_replaceMap.cbegin (); it != m_replaceMap.cend (); ++it)
273- {
274- auto itBegin = std::search (sReplace .begin (), sReplace .end (), it->first .begin (), it->first .end ());
275- while (itBegin != sReplace .end ())
276- {
277- if ((itBegin == sReplace .begin ()) || ((*(itBegin - 1 )) != ' \\ ' ))
278- {
279- auto itEnd = itBegin + it->first .size ();
280- sReplace .replace (itBegin, itEnd, it->second );
281- }
282- else if ((*(itBegin - 1 )) == ' \\ ' )
283- {
284- sReplace .erase (itBegin - 1 );
285- };
286- itBegin = std::search (sReplace .begin (), sReplace .end (), it->first .begin (), it->first .end ());
287- }
288- }
289- }
290- if (!g_incVec.empty ())
291- {
292- for (auto it = g_incVec.begin (); it != g_incVec.end (); ++it)
293- {
294- auto itBegin = std::search (sReplace .begin (), sReplace .end (), it->expression .begin (), it->expression .end ());
295- if (itBegin != sReplace .end ())
296- {
297- if ((itBegin == sReplace .begin ()) || ((*(itBegin - 1 )) != ' \\ ' ))
298- {
299- auto itEnd = itBegin + it->expression .size ();
300- char format[20 ] = {0 };
301- if (it->padding )
302- {
303- if (it->leadZero )
304- sprintf_s (format, _countof (format), " %%0%dd" , it->padding );
305- else
306- sprintf_s (format, _countof (format), " %%%dd" , it->padding );
307- }
308- else
309- strcpy_s (format, " %d" );
310- if (it->padding < 50 )
311- {
312- // for small strings, reserve space on the stack
313- char buf[128 ] = {0 };
314- sprintf_s (buf, _countof (buf), format, it->start );
315- sReplace .replace (itBegin, itEnd, buf);
316- }
317- else
318- {
319- auto s = CStringUtils::Format (format, it->start );
320- sReplace .replace (itBegin, itEnd, s);
321- }
322- it->start += it->increment ;
323- }
324- else if ((*(itBegin - 1 )) == ' \\ ' )
325- {
326- sReplace .erase (itBegin - 1 );
327- };
328- }
329- }
330- }
227+ int _Result;
228+ va_list _ArgList;
229+ __crt_va_start (_ArgList, format);
230+ _Result = _vsprintf_s_l (buffer, sizeOfBuffer, format, NULL , _ArgList);
231+ __crt_va_end (_ArgList);
232+ return _Result;
233+ }
331234
332- return sReplace ;
235+ template <size_t size>
236+ errno_t t_tcscpy_s (wchar_t (&dest)[size], const wchar_t *src)
237+ {
238+ return wcscpy_s (dest, size, src);
239+ }
240+
241+ template <size_t size>
242+ errno_t t_tcscpy_s (char (&dest)[size], const char *src)
243+ {
244+ return strcpy_s (dest, size, src);
333245 }
334246
335247private:
336- std::string m_sReplace;
337- std::map<std::string, std::string> m_replaceMap;
248+ std::vector<NumberReplacer<CharT>> m_incVec;
249+ std::basic_string<CharT> m_sReplace;
250+ std::map<std::basic_string<CharT>, std::basic_string<CharT>> m_replaceMap;
338251};
0 commit comments