JPCRE2  10.31.02
C++ wrapper for PCRE2 library
jpcre2.hpp
Go to the documentation of this file.
1 /* *****************************************************************************
2  * ******************* C++ wrapper for PCRE2 Library ****************************
3  * *****************************************************************************
4  * Copyright (c) 2015-2018 Md. Jahidul Hamid
5  *
6  * -----------------------------------------------------------------------------
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * * Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * * The names of its contributors may not be used to endorse or promote
18  * products derived from this software without specific prior written
19  * permission.
20  *
21  * Disclaimer:
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  * */
35 
47 #ifndef JPCRE2_HPP
48 #define JPCRE2_HPP
49 
50 #ifndef PCRE2_CODE_UNIT_WIDTH
51 
58 #define PCRE2_CODE_UNIT_WIDTH 0
59 #endif
60 
61 //previous inclusion of pcre2.h will be respected and we won't try to include it twice.
62 //Thus one can pre-include pcre2.h from an arbitrary/non-standard path.
63 #ifndef PCRE2_MAJOR
64  #include <pcre2.h> // pcre2 header
65 #endif
66 #include <string> // std::string, std::wstring
67 #include <vector> // std::vector
68 #include <map> // std::map
69 #include <cstdio> // std::fprintf
70 #include <climits> // CHAR_BIT
71 #include <cstdlib> // std::abort()
72 
73 #if __cplusplus >= 201103L
74  #include <utility>
75  #ifndef JPCRE2_USE_FUNCTION_POINTER_CALLBACK
76  #include <functional> // std::function
77  #endif
78 #endif
79 
80 #define JPCRE2_UNUSED(x) ((void)(x))
81 #if defined(NDEBUG) || defined(JPCRE2_NDEBUG)
82  #define JPCRE2_ASSERT(cond, msg) ((void)0)
83  #define JPCRE2_VECTOR_DATA_ASSERT(cond, name) ((void)0)
84 #else
85  #define JPCRE2_ASSERT(cond, msg) jpcre2::jassert(cond, msg, __FILE__, __LINE__)
86  #define JPCRE2_VECTOR_DATA_ASSERT(cond, name) jpcre2::_jvassert(cond, name, __FILE__, __LINE__)
87 #endif
88 
89 
99 namespace jpcre2 {
100 
101 
104 #define JPCRE2_VERSION 103102L
105 
110 namespace INFO {
111  static const char NAME[] = "JPCRE2";
112  static const char FULL_VERSION[] = "10.31.02";
113  static const char VERSION_GENRE[] = "10";
114  static const char VERSION_MAJOR[] = "31";
115  static const char VERSION_MINOR[] = "02";
116  static const char VERSION_PRE_RELEASE[] = "";
117 }
118 
119 
120 typedef PCRE2_SIZE SIZE_T;
121 typedef uint32_t Uint;
122 typedef uint8_t Ush;
123 typedef std::vector<SIZE_T> VecOff;
124 typedef std::vector<Uint> VecOpt;
125 
128 namespace ERROR {
133  enum {
136  };
137 }
138 
139 
142 enum {
143  NONE = 0x0000000u,
144  FIND_ALL = 0x0000002u,
145  JIT_COMPILE = 0x0000004u
146 };
147 
148 
149 //enableif and is_same implementation
150 template<bool B, typename T = void>
151 struct EnableIf{};
152 template<typename T>
153 struct EnableIf<true, T>{typedef T Type;};
154 
155 template<typename T1, typename T2>
156 struct IsSame{ static const bool value = false; };
157 template<typename T>
158 struct IsSame<T,T>{ static const bool value = true; };
159 
160 
167 static inline void jassert(bool cond, const char* msg, const char* f, size_t line){
168  if(!cond) {
169  std::fprintf(stderr,"\n\tE: AssertionFailure\n%s\nAssertion failed in file: %s\t at line: %u\n", msg, f, (unsigned)line);
170  std::abort();
171  }
172 }
173 
174 static inline void _jvassert(bool cond, char const * name, const char* f, size_t line){
175  jassert(cond, (std::string("ValueError: \n\
176  Required data vector of type ")+std::string(name)+" is empty.\n\
177  Your MatchEvaluator callback function is not\n\
178  compatible with existing data!!\n\
179  You are trying to use a vector that does not\n\
180  have any match data. Either call nreplace() or replace()\n\
181  with true or perform a match with appropriate\n\
182  callback function. For more details, refer to\n\
183  the doc in MatchEvaluator section.").c_str(), f, line);
184 }
185 
186 static inline std::string _tostdstring(unsigned x){
187  char buf[128];
188  int written = std::sprintf(buf, "%u", x);
189  return (written > 0) ? std::string(buf, buf + written) : std::string();
190 }
191 
192 
194 
195 //forward declaration
196 
197 template<Ush BS> struct Pcre2Type;
198 template<Ush BS> struct Pcre2Func;
199 
200 //PCRE2 types
201 //These templated types will be used in place of actual types
202 template<Ush BS> struct Pcre2Type {};
203 
204 template<> struct Pcre2Type<8>{
205  //typedefs used
206  typedef PCRE2_UCHAR8 Pcre2Uchar;
207  typedef PCRE2_SPTR8 Pcre2Sptr;
208  typedef pcre2_code_8 Pcre2Code;
209  typedef pcre2_compile_context_8 CompileContext;
210  typedef pcre2_match_data_8 MatchData;
211  typedef pcre2_general_context_8 GeneralContext;
212  typedef pcre2_match_context_8 MatchContext;
213  typedef pcre2_jit_callback_8 JitCallback;
214  typedef pcre2_jit_stack_8 JitStack;
215 };
216 
217 template<> struct Pcre2Type<16>{
218  //typedefs used
219  typedef PCRE2_UCHAR16 Pcre2Uchar;
220  typedef PCRE2_SPTR16 Pcre2Sptr;
221  typedef pcre2_code_16 Pcre2Code;
222  typedef pcre2_compile_context_16 CompileContext;
223  typedef pcre2_match_data_16 MatchData;
224  typedef pcre2_general_context_16 GeneralContext;
225  typedef pcre2_match_context_16 MatchContext;
226  typedef pcre2_jit_callback_16 JitCallback;
227  typedef pcre2_jit_stack_16 JitStack;
228 };
229 
230 template<> struct Pcre2Type<32>{
231  //typedefs used
232  typedef PCRE2_UCHAR32 Pcre2Uchar;
233  typedef PCRE2_SPTR32 Pcre2Sptr;
234  typedef pcre2_code_32 Pcre2Code;
235  typedef pcre2_compile_context_32 CompileContext;
236  typedef pcre2_match_data_32 MatchData;
237  typedef pcre2_general_context_32 GeneralContext;
238  typedef pcre2_match_context_32 MatchContext;
239  typedef pcre2_jit_callback_32 JitCallback;
240  typedef pcre2_jit_stack_32 JitStack;
241 };
242 
243 //wrappers for PCRE2 functions
244 template<Ush BS> struct Pcre2Func{};
245 
246 //8-bit version
247 template<> struct Pcre2Func<8> {
248  static Pcre2Type<8>::CompileContext* compile_context_create(Pcre2Type<8>::GeneralContext *gcontext){
249  return pcre2_compile_context_create_8(gcontext);
250  }
251  static void compile_context_free(Pcre2Type<8>::CompileContext *ccontext){
252  pcre2_compile_context_free_8(ccontext);
253  }
254  static Pcre2Type<8>::CompileContext* compile_context_copy(Pcre2Type<8>::CompileContext* ccontext){
255  return pcre2_compile_context_copy_8(ccontext);
256  }
257  static const unsigned char * maketables(Pcre2Type<8>::GeneralContext* gcontext){
258  return pcre2_maketables_8(gcontext);
259  }
260  static int set_character_tables(Pcre2Type<8>::CompileContext * ccontext, const unsigned char * table){
261  return pcre2_set_character_tables_8(ccontext, table);
262  }
263  static Pcre2Type<8>::Pcre2Code * compile(Pcre2Type<8>::Pcre2Sptr pattern,
264  PCRE2_SIZE length,
265  uint32_t options,
266  int *errorcode,
267  PCRE2_SIZE *erroroffset,
268  Pcre2Type<8>::CompileContext *ccontext){
269  return pcre2_compile_8(pattern, length, options, errorcode, erroroffset, ccontext);
270  }
271  static int jit_compile(Pcre2Type<8>::Pcre2Code *code, uint32_t options){
272  return pcre2_jit_compile_8(code, options);
273  }
274  static int substitute( const Pcre2Type<8>::Pcre2Code *code,
275  Pcre2Type<8>::Pcre2Sptr subject,
276  PCRE2_SIZE length,
277  PCRE2_SIZE startoffset,
278  uint32_t options,
279  Pcre2Type<8>::MatchData *match_data,
280  Pcre2Type<8>::MatchContext *mcontext,
281  Pcre2Type<8>::Pcre2Sptr replacement,
282  PCRE2_SIZE rlength,
283  Pcre2Type<8>::Pcre2Uchar *outputbuffer,
284  PCRE2_SIZE *outlengthptr){
285  return pcre2_substitute_8( code, subject, length, startoffset, options, match_data,
286  mcontext, replacement, rlength, outputbuffer, outlengthptr);
287  }
288  //~ static int substring_get_bynumber(Pcre2Type<8>::MatchData *match_data,
289  //~ uint32_t number,
290  //~ Pcre2Type<8>::Pcre2Uchar **bufferptr,
291  //~ PCRE2_SIZE *bufflen){
292  //~ return pcre2_substring_get_bynumber_8(match_data, number, bufferptr, bufflen);
293  //~ }
294  //~ static int substring_get_byname(Pcre2Type<8>::MatchData *match_data,
295  //~ Pcre2Type<8>::Pcre2Sptr name,
296  //~ Pcre2Type<8>::Pcre2Uchar **bufferptr,
297  //~ PCRE2_SIZE *bufflen){
298  //~ return pcre2_substring_get_byname_8(match_data, name, bufferptr, bufflen);
299  //~ }
300  //~ static void substring_free(Pcre2Type<8>::Pcre2Uchar *buffer){
301  //~ pcre2_substring_free_8(buffer);
302  //~ }
303  //~ static Pcre2Type<8>::Pcre2Code * code_copy(const Pcre2Type<8>::Pcre2Code *code){
304  //~ return pcre2_code_copy_8(code);
305  //~ }
306  static void code_free(Pcre2Type<8>::Pcre2Code *code){
307  pcre2_code_free_8(code);
308  }
309  static int get_error_message( int errorcode,
310  Pcre2Type<8>::Pcre2Uchar *buffer,
311  PCRE2_SIZE bufflen){
312  return pcre2_get_error_message_8(errorcode, buffer, bufflen);
313  }
314  static Pcre2Type<8>::MatchData * match_data_create_from_pattern(
315  const Pcre2Type<8>::Pcre2Code *code,
316  Pcre2Type<8>::GeneralContext *gcontext){
317  return pcre2_match_data_create_from_pattern_8(code, gcontext);
318 
319  }
320  static int match( const Pcre2Type<8>::Pcre2Code *code,
321  Pcre2Type<8>::Pcre2Sptr subject,
322  PCRE2_SIZE length,
323  PCRE2_SIZE startoffset,
324  uint32_t options,
325  Pcre2Type<8>::MatchData *match_data,
326  Pcre2Type<8>::MatchContext *mcontext){
327  return pcre2_match_8(code, subject, length, startoffset, options, match_data, mcontext);
328  }
329  static void match_data_free(Pcre2Type<8>::MatchData *match_data){
330  pcre2_match_data_free_8(match_data);
331  }
332  static PCRE2_SIZE * get_ovector_pointer(Pcre2Type<8>::MatchData *match_data){
333  return pcre2_get_ovector_pointer_8(match_data);
334  }
335  static int pattern_info(const Pcre2Type<8>::Pcre2Code *code, uint32_t what, void *where){
336  return pcre2_pattern_info_8(code, what, where);
337  }
338  static int set_newline(Pcre2Type<8>::CompileContext *ccontext, uint32_t value){
339  return pcre2_set_newline_8(ccontext, value);
340  }
341  //~ static void jit_stack_assign(Pcre2Type<8>::MatchContext *mcontext,
342  //~ Pcre2Type<8>::JitCallback callback_function,
343  //~ void *callback_data){
344  //~ pcre2_jit_stack_assign_8(mcontext, callback_function, callback_data);
345  //~ }
346  //~ static Pcre2Type<8>::JitStack *jit_stack_create(PCRE2_SIZE startsize, PCRE2_SIZE maxsize,
347  //~ Pcre2Type<8>::GeneralContext *gcontext){
348  //~ return pcre2_jit_stack_create_8(startsize, maxsize, gcontext);
349  //~ }
350  //~ static void jit_stack_free(Pcre2Type<8>::JitStack *jit_stack){
351  //~ pcre2_jit_stack_free_8(jit_stack);
352  //~ }
353  //~ static void jit_free_unused_memory(Pcre2Type<8>::GeneralContext *gcontext){
354  //~ pcre2_jit_free_unused_memory_8(gcontext);
355  //~ }
356  //~ static Pcre2Type<8>::MatchContext *match_context_create(Pcre2Type<8>::GeneralContext *gcontext){
357  //~ return pcre2_match_context_create_8(gcontext);
358  //~ }
359  //~ static Pcre2Type<8>::MatchContext *match_context_copy(Pcre2Type<8>::MatchContext *mcontext){
360  //~ return pcre2_match_context_copy_8(mcontext);
361  //~ }
362  //~ static void match_context_free(Pcre2Type<8>::MatchContext *mcontext){
363  //~ pcre2_match_context_free_8(mcontext);
364  //~ }
365  static uint32_t get_ovector_count(Pcre2Type<8>::MatchData *match_data){
366  return pcre2_get_ovector_count_8(match_data);
367  }
368 };
369 
370 //16-bit version
371 template<> struct Pcre2Func<16> {
372  static Pcre2Type<16>::CompileContext* compile_context_create(Pcre2Type<16>::GeneralContext *gcontext){
373  return pcre2_compile_context_create_16(gcontext);
374  }
375  static void compile_context_free(Pcre2Type<16>::CompileContext *ccontext){
376  pcre2_compile_context_free_16(ccontext);
377  }
378  static Pcre2Type<16>::CompileContext* compile_context_copy(Pcre2Type<16>::CompileContext* ccontext){
379  return pcre2_compile_context_copy_16(ccontext);
380  }
381  static const unsigned char * maketables(Pcre2Type<16>::GeneralContext* gcontext){
382  return pcre2_maketables_16(gcontext);
383  }
384  static int set_character_tables(Pcre2Type<16>::CompileContext * ccontext, const unsigned char * table){
385  return pcre2_set_character_tables_16(ccontext, table);
386  }
387  static Pcre2Type<16>::Pcre2Code * compile(Pcre2Type<16>::Pcre2Sptr pattern,
388  PCRE2_SIZE length,
389  uint32_t options,
390  int *errorcode,
391  PCRE2_SIZE *erroroffset,
392  Pcre2Type<16>::CompileContext *ccontext){
393  return pcre2_compile_16(pattern, length, options, errorcode, erroroffset, ccontext);
394  }
395  static int jit_compile(Pcre2Type<16>::Pcre2Code *code, uint32_t options){
396  return pcre2_jit_compile_16(code, options);
397  }
398  static int substitute( const Pcre2Type<16>::Pcre2Code *code,
399  Pcre2Type<16>::Pcre2Sptr subject,
400  PCRE2_SIZE length,
401  PCRE2_SIZE startoffset,
402  uint32_t options,
403  Pcre2Type<16>::MatchData *match_data,
404  Pcre2Type<16>::MatchContext *mcontext,
405  Pcre2Type<16>::Pcre2Sptr replacement,
406  PCRE2_SIZE rlength,
407  Pcre2Type<16>::Pcre2Uchar *outputbuffer,
408  PCRE2_SIZE *outlengthptr){
409  return pcre2_substitute_16( code, subject, length, startoffset, options, match_data,
410  mcontext, replacement, rlength, outputbuffer, outlengthptr);
411  }
412  //~ static int substring_get_bynumber(Pcre2Type<16>::MatchData *match_data,
413  //~ uint32_t number,
414  //~ Pcre2Type<16>::Pcre2Uchar **bufferptr,
415  //~ PCRE2_SIZE *bufflen){
416  //~ return pcre2_substring_get_bynumber_16(match_data, number, bufferptr, bufflen);
417  //~ }
418  //~ static int substring_get_byname(Pcre2Type<16>::MatchData *match_data,
419  //~ Pcre2Type<16>::Pcre2Sptr name,
420  //~ Pcre2Type<16>::Pcre2Uchar **bufferptr,
421  //~ PCRE2_SIZE *bufflen){
422  //~ return pcre2_substring_get_byname_16(match_data, name, bufferptr, bufflen);
423  //~ }
424  //~ static void substring_free(Pcre2Type<16>::Pcre2Uchar *buffer){
425  //~ pcre2_substring_free_16(buffer);
426  //~ }
427  //~ static Pcre2Type<16>::Pcre2Code * code_copy(const Pcre2Type<16>::Pcre2Code *code){
428  //~ return pcre2_code_copy_16(code);
429  //~ }
430  static void code_free(Pcre2Type<16>::Pcre2Code *code){
431  pcre2_code_free_16(code);
432  }
433  static int get_error_message( int errorcode,
434  Pcre2Type<16>::Pcre2Uchar *buffer,
435  PCRE2_SIZE bufflen){
436  return pcre2_get_error_message_16(errorcode, buffer, bufflen);
437  }
438  static Pcre2Type<16>::MatchData * match_data_create_from_pattern(
439  const Pcre2Type<16>::Pcre2Code *code,
440  Pcre2Type<16>::GeneralContext *gcontext){
441  return pcre2_match_data_create_from_pattern_16(code, gcontext);
442 
443  }
444  static int match( const Pcre2Type<16>::Pcre2Code *code,
445  Pcre2Type<16>::Pcre2Sptr subject,
446  PCRE2_SIZE length,
447  PCRE2_SIZE startoffset,
448  uint32_t options,
449  Pcre2Type<16>::MatchData *match_data,
450  Pcre2Type<16>::MatchContext *mcontext){
451  return pcre2_match_16(code, subject, length, startoffset, options, match_data, mcontext);
452  }
453  static void match_data_free(Pcre2Type<16>::MatchData *match_data){
454  pcre2_match_data_free_16(match_data);
455  }
456  static PCRE2_SIZE * get_ovector_pointer(Pcre2Type<16>::MatchData *match_data){
457  return pcre2_get_ovector_pointer_16(match_data);
458  }
459  static int pattern_info(const Pcre2Type<16>::Pcre2Code *code, uint32_t what, void *where){
460  return pcre2_pattern_info_16(code, what, where);
461  }
462  static int set_newline(Pcre2Type<16>::CompileContext *ccontext, uint32_t value){
463  return pcre2_set_newline_16(ccontext, value);
464  }
465  //~ static void jit_stack_assign(Pcre2Type<16>::MatchContext *mcontext,
466  //~ Pcre2Type<16>::JitCallback callback_function,
467  //~ void *callback_data){
468  //~ pcre2_jit_stack_assign_16(mcontext, callback_function, callback_data);
469  //~ }
470  //~ static Pcre2Type<16>::JitStack *jit_stack_create(PCRE2_SIZE startsize, PCRE2_SIZE maxsize,
471  //~ Pcre2Type<16>::GeneralContext *gcontext){
472  //~ return pcre2_jit_stack_create_16(startsize, maxsize, gcontext);
473  //~ }
474  //~ static void jit_stack_free(Pcre2Type<16>::JitStack *jit_stack){
475  //~ pcre2_jit_stack_free_16(jit_stack);
476  //~ }
477  //~ static void jit_free_unused_memory(Pcre2Type<16>::GeneralContext *gcontext){
478  //~ pcre2_jit_free_unused_memory_16(gcontext);
479  //~ }
480  //~ static Pcre2Type<16>::MatchContext *match_context_create(Pcre2Type<16>::GeneralContext *gcontext){
481  //~ return pcre2_match_context_create_16(gcontext);
482  //~ }
483  //~ static Pcre2Type<16>::MatchContext *match_context_copy(Pcre2Type<16>::MatchContext *mcontext){
484  //~ return pcre2_match_context_copy_16(mcontext);
485  //~ }
486  //~ static void match_context_free(Pcre2Type<16>::MatchContext *mcontext){
487  //~ pcre2_match_context_free_16(mcontext);
488  //~ }
489  static uint32_t get_ovector_count(Pcre2Type<16>::MatchData *match_data){
490  return pcre2_get_ovector_count_16(match_data);
491  }
492 };
493 
494 //32-bit version
495 template<> struct Pcre2Func<32> {
496  static Pcre2Type<32>::CompileContext* compile_context_create(Pcre2Type<32>::GeneralContext *gcontext){
497  return pcre2_compile_context_create_32(gcontext);
498  }
499  static void compile_context_free(Pcre2Type<32>::CompileContext *ccontext){
500  pcre2_compile_context_free_32(ccontext);
501  }
502  static Pcre2Type<32>::CompileContext* compile_context_copy(Pcre2Type<32>::CompileContext* ccontext){
503  return pcre2_compile_context_copy_32(ccontext);
504  }
505  static const unsigned char * maketables(Pcre2Type<32>::GeneralContext* gcontext){
506  return pcre2_maketables_32(gcontext);
507  }
508  static int set_character_tables(Pcre2Type<32>::CompileContext * ccontext, const unsigned char * table){
509  return pcre2_set_character_tables_32(ccontext, table);
510  }
511  static Pcre2Type<32>::Pcre2Code * compile(Pcre2Type<32>::Pcre2Sptr pattern,
512  PCRE2_SIZE length,
513  uint32_t options,
514  int *errorcode,
515  PCRE2_SIZE *erroroffset,
516  Pcre2Type<32>::CompileContext *ccontext){
517  return pcre2_compile_32(pattern, length, options, errorcode, erroroffset, ccontext);
518  }
519  static int jit_compile(Pcre2Type<32>::Pcre2Code *code, uint32_t options){
520  return pcre2_jit_compile_32(code, options);
521  }
522  static int substitute( const Pcre2Type<32>::Pcre2Code *code,
523  Pcre2Type<32>::Pcre2Sptr subject,
524  PCRE2_SIZE length,
525  PCRE2_SIZE startoffset,
526  uint32_t options,
527  Pcre2Type<32>::MatchData *match_data,
528  Pcre2Type<32>::MatchContext *mcontext,
529  Pcre2Type<32>::Pcre2Sptr replacement,
530  PCRE2_SIZE rlength,
531  Pcre2Type<32>::Pcre2Uchar *outputbuffer,
532  PCRE2_SIZE *outlengthptr){
533  return pcre2_substitute_32( code, subject, length, startoffset, options, match_data,
534  mcontext, replacement, rlength, outputbuffer, outlengthptr);
535  }
536  //~ static int substring_get_bynumber(Pcre2Type<32>::MatchData *match_data,
537  //~ uint32_t number,
538  //~ Pcre2Type<32>::Pcre2Uchar **bufferptr,
539  //~ PCRE2_SIZE *bufflen){
540  //~ return pcre2_substring_get_bynumber_32(match_data, number, bufferptr, bufflen);
541  //~ }
542  //~ static int substring_get_byname(Pcre2Type<32>::MatchData *match_data,
543  //~ Pcre2Type<32>::Pcre2Sptr name,
544  //~ Pcre2Type<32>::Pcre2Uchar **bufferptr,
545  //~ PCRE2_SIZE *bufflen){
546  //~ return pcre2_substring_get_byname_32(match_data, name, bufferptr, bufflen);
547  //~ }
548  //~ static void substring_free(Pcre2Type<32>::Pcre2Uchar *buffer){
549  //~ pcre2_substring_free_32(buffer);
550  //~ }
551  //~ static Pcre2Type<32>::Pcre2Code * code_copy(const Pcre2Type<32>::Pcre2Code *code){
552  //~ return pcre2_code_copy_32(code);
553  //~ }
554  static void code_free(Pcre2Type<32>::Pcre2Code *code){
555  pcre2_code_free_32(code);
556  }
557  static int get_error_message( int errorcode,
558  Pcre2Type<32>::Pcre2Uchar *buffer,
559  PCRE2_SIZE bufflen){
560  return pcre2_get_error_message_32(errorcode, buffer, bufflen);
561  }
562  static Pcre2Type<32>::MatchData * match_data_create_from_pattern(
563  const Pcre2Type<32>::Pcre2Code *code,
564  Pcre2Type<32>::GeneralContext *gcontext){
565  return pcre2_match_data_create_from_pattern_32(code, gcontext);
566 
567  }
568  static int match( const Pcre2Type<32>::Pcre2Code *code,
569  Pcre2Type<32>::Pcre2Sptr subject,
570  PCRE2_SIZE length,
571  PCRE2_SIZE startoffset,
572  uint32_t options,
573  Pcre2Type<32>::MatchData *match_data,
574  Pcre2Type<32>::MatchContext *mcontext){
575  return pcre2_match_32(code, subject, length, startoffset, options, match_data, mcontext);
576  }
577  static void match_data_free(Pcre2Type<32>::MatchData *match_data){
578  pcre2_match_data_free_32(match_data);
579  }
580  static PCRE2_SIZE * get_ovector_pointer(Pcre2Type<32>::MatchData *match_data){
581  return pcre2_get_ovector_pointer_32(match_data);
582  }
583  static int pattern_info(const Pcre2Type<32>::Pcre2Code *code, uint32_t what, void *where){
584  return pcre2_pattern_info_32(code, what, where);
585  }
586  static int set_newline(Pcre2Type<32>::CompileContext *ccontext, uint32_t value){
587  return pcre2_set_newline_32(ccontext, value);
588  }
589  //~ static void jit_stack_assign(Pcre2Type<32>::MatchContext *mcontext,
590  //~ Pcre2Type<32>::JitCallback callback_function,
591  //~ void *callback_data){
592  //~ pcre2_jit_stack_assign_32(mcontext, callback_function, callback_data);
593  //~ }
594  //~ static Pcre2Type<32>::JitStack *jit_stack_create(PCRE2_SIZE startsize, PCRE2_SIZE maxsize,
595  //~ Pcre2Type<32>::GeneralContext *gcontext){
596  //~ return pcre2_jit_stack_create_32(startsize, maxsize, gcontext);
597  //~ }
598  //~ static void jit_stack_free(Pcre2Type<32>::JitStack *jit_stack){
599  //~ pcre2_jit_stack_free_32(jit_stack);
600  //~ }
601  //~ static void jit_free_unused_memory(Pcre2Type<32>::GeneralContext *gcontext){
602  //~ pcre2_jit_free_unused_memory_32(gcontext);
603  //~ }
604  //~ static Pcre2Type<32>::MatchContext *match_context_create(Pcre2Type<32>::GeneralContext *gcontext){
605  //~ return pcre2_match_context_create_32(gcontext);
606  //~ }
607  //~ static Pcre2Type<32>::MatchContext *match_context_copy(Pcre2Type<32>::MatchContext *mcontext){
608  //~ return pcre2_match_context_copy_32(mcontext);
609  //~ }
610  //~ static void match_context_free(Pcre2Type<32>::MatchContext *mcontext){
611  //~ pcre2_match_context_free_32(mcontext);
612  //~ }
613  static uint32_t get_ovector_count(Pcre2Type<32>::MatchData *match_data){
614  return pcre2_get_ovector_count_32(match_data);
615  }
616 };
617 
619 
620 
625 class Modifier{
626  std::string mod;
627 
628  public:
631 
634  Modifier(std::string const& x):mod(x){}
635 
638  Modifier(char const *x):mod(x?x:""){}
639 
642  std::string str() const { return mod; }
643 
646  char const * c_str() const { return mod.c_str(); }
647 
650  const SIZE_T length() const{ return mod.length(); }
651 
655  const char operator[](SIZE_T i) const { return mod[i]; }
656 };
657 
658 
659 // Namespace for modifier constants.
660 // For each modifier constant there is a jpcre2::Uint option value.
661 // Some modifiers may have multiple values set together (ORed in bitwise operation) and
662 // thus they may include other modifiers. Such an example is the 'n' modifier. It is combined together with 'u'.
663 namespace MOD {
664 
665  // Define modifiers for compile
666  // String of compile modifier characters for PCRE2 options
667  static const char C_N[] = "eijmnsuxADJU";
668  // Array of compile modifier values for PCRE2 options
669  // Uint is being used in getModifier() in for loop to get the number of element in this array,
670  // be sure to chnage there if you change here.
671  static const jpcre2::Uint C_V[12] = { PCRE2_MATCH_UNSET_BACKREF, // Modifier e
672  PCRE2_CASELESS, // Modifier i
673  PCRE2_ALT_BSUX | PCRE2_MATCH_UNSET_BACKREF, // Modifier j
674  PCRE2_MULTILINE, // Modifier m
675  PCRE2_UTF | PCRE2_UCP, // Modifier n (includes u)
676  PCRE2_DOTALL, // Modifier s
677  PCRE2_UTF, // Modifier u
678  PCRE2_EXTENDED, // Modifier x
679  PCRE2_ANCHORED, // Modifier A
680  PCRE2_DOLLAR_ENDONLY, // Modifier D
681  PCRE2_DUPNAMES, // Modifier J
682  PCRE2_UNGREEDY // Modifier U
683  };
684 
685 
686  // String of compile modifier characters for JPCRE2 options
687  static const char CJ_N[] = "S";
688  // Array of compile modifier values for JPCRE2 options
689  static const jpcre2::Uint CJ_V[1] = { JIT_COMPILE, // Modifier S
690  };
691 
692 
693  // Define modifiers for replace
694  // String of action (replace) modifier characters for PCRE2 options
695  static const char R_N[] = "eEgx";
696  // Array of action (replace) modifier values for PCRE2 options
697  static const jpcre2::Uint R_V[4] = { PCRE2_SUBSTITUTE_UNSET_EMPTY, // Modifier e
698  PCRE2_SUBSTITUTE_UNKNOWN_UNSET | PCRE2_SUBSTITUTE_UNSET_EMPTY, // Modifier E (includes e)
699  PCRE2_SUBSTITUTE_GLOBAL, // Modifier g
700  PCRE2_SUBSTITUTE_EXTENDED // Modifier x
701  };
702 
703 
704  // String of action (replace) modifier characters for JPCRE2 options
705  static const char RJ_N[] = "";
706  // Array of action (replace) modifier values for JPCRE2 options
707  static const jpcre2::Uint RJ_V[1] = { NONE //placeholder
708  };
709 
710  // Define modifiers for match
711  // String of action (match) modifier characters for PCRE2 options
712  static const char M_N[] = "A";
713  // Array of action (match) modifier values for PCRE2 options
714  static const jpcre2::Uint M_V[1] = { PCRE2_ANCHORED // Modifier A
715  };
716 
717 
718  // String of action (match) modifier characters for JPCRE2 options
719  static const char MJ_N[] = "g";
720  // Array of action (match) modifier values for JPCRE2 options
721  static const jpcre2::Uint MJ_V[1] = { FIND_ALL, // Modifier g
722  };
723 
724  static inline void toOption(Modifier const& mod, bool x,
725  Uint const * J_V, char const * J_N, SIZE_T SJ,
726  Uint const * V, char const * N, SIZE_T S,
727  Uint* po, Uint* jo,
728  int* en, SIZE_T* eo
729  ){
730  //loop through mod
731  SIZE_T n = mod.length();
732  for (SIZE_T i = 0; i < n; ++i) {
733  //First check for JPCRE2 mods
734  for(SIZE_T j = 0; j < SJ; ++j){
735  if(J_N[j] == mod[i]) {
736  if(x) *jo |= J_V[j];
737  else *jo &= ~J_V[j];
738  goto endfor;
739  }
740  }
741 
742  //Now check for PCRE2 mods
743  for(SIZE_T j = 0; j< S; ++j){
744  if(N[j] == mod[i]){
745  if(x) *po |= V[j];
746  else *po &= ~V[j];
747  goto endfor;
748  }
749  }
750 
751  //Modifier didn't match, invalid modifier
752  *en = (int)ERROR::INVALID_MODIFIER;
753  *eo = (int)mod[i];
754 
755  endfor:;
756  }
757  }
758 
759  static inline void toMatchOption(Modifier const& mod, bool x, Uint* po, Uint* jo, int* en, SIZE_T* eo){
760  toOption(mod, x,
761  MJ_V, MJ_N, sizeof(MJ_V)/sizeof(Uint),
762  M_V, M_N, sizeof(M_V)/sizeof(Uint),
763  po, jo, en, eo);
764  }
765 
766  static inline void toReplaceOption(Modifier const& mod, bool x, Uint* po, Uint* jo, int* en, SIZE_T* eo){
767  toOption(mod, x,
768  RJ_V, RJ_N, sizeof(RJ_V)/sizeof(Uint),
769  R_V, R_N, sizeof(R_V)/sizeof(Uint),
770  po, jo, en, eo);
771  }
772 
773  static inline void toCompileOption(Modifier const& mod, bool x, Uint* po, Uint* jo, int* en, SIZE_T* eo){
774  toOption(mod, x,
775  CJ_V, CJ_N, sizeof(CJ_V)/sizeof(Uint),
776  C_V, C_N, sizeof(C_V)/sizeof(Uint),
777  po, jo, en, eo);
778  }
779 
780  static inline std::string fromOption(Uint const * J_V, char const * J_N, SIZE_T SJ,
781  Uint const * V, char const * N, SIZE_T S,
782  Uint po, Uint jo
783  ){
784  std::string mod;
785  //Calculate PCRE2 mod
786  for(SIZE_T i = 0; i < S; ++i){
787  if( (V[i] & po) != 0 &&
788  (V[i] & po) == V[i]) //One option can include other
789  mod += N[i];
790  }
791  //Calculate JPCRE2 mod
792  for(SIZE_T i = 0; i < SJ; ++i){
793  if( (J_V[i] & jo) != 0 &&
794  (J_V[i] & jo) == J_V[i]) //One option can include other
795  mod += J_N[i];
796  }
797  return mod;
798  }
799 
800  static inline std::string fromMatchOption(Uint po, Uint jo){
801  return fromOption(MJ_V, MJ_N, sizeof(MJ_V)/sizeof(Uint),
802  M_V, M_N, sizeof(M_V)/sizeof(Uint),
803  po, jo);
804  }
805 
806  static inline std::string fromReplaceOption(Uint po, Uint jo){
807  return fromOption(RJ_V, RJ_N, sizeof(RJ_V)/sizeof(Uint),
808  R_V, R_N, sizeof(R_V)/sizeof(Uint),
809  po, jo);
810  }
811 
812  static inline std::string fromCompileOption(Uint po, Uint jo){
813  return fromOption(CJ_V, CJ_N, sizeof(CJ_V)/sizeof(Uint),
814  C_V, C_N, sizeof(C_V)/sizeof(Uint),
815  po, jo);
816  }
817 
818 } //MOD namespace ends
819 
824 
825  std::string tabjms;
826  std::string tabms;
827  std::string tabjrs;
828  std::string tabrs;
829  std::string tabjcs;
830  std::string tabcs;
831  VecOpt tabjmv;
832  VecOpt tabmv;
833  VecOpt tabjrv;
834  VecOpt tabrv;
835  VecOpt tabjcv;
836  VecOpt tabcv;
837 
838  void toOption(Modifier const& mod, bool x,
839  VecOpt const& J_V, std::string const& J_N,
840  VecOpt const& V, std::string const& N,
841  Uint* po, Uint* jo, int* en, SIZE_T* eo
842  ) const{
843  SIZE_T SJ = J_V.size();
844  SIZE_T S = V.size();
845  JPCRE2_ASSERT(SJ == J_N.length(), ("ValueError: Modifier character and value table must be of the same size (" + _tostdstring(SJ) + " == " + _tostdstring(J_N.length()) + ").").c_str());
846  JPCRE2_ASSERT(S == N.length(), ("ValueError: Modifier character and value table must be of the same size (" + _tostdstring(S) + " == " + _tostdstring(N.length()) + ").").c_str());
847  MOD::toOption(mod, x,
848  J_V.empty()?0:&J_V[0], J_N.c_str(), SJ,
849  V.empty()?0:&V[0], N.c_str(), S,
850  po, jo, en, eo
851  );
852  }
853 
854  std::string fromOption(VecOpt const& J_V, std::string const& J_N,
855  VecOpt const& V, std::string const& N,
856  Uint po, Uint jo) const{
857  SIZE_T SJ = J_V.size();
858  SIZE_T S = V.size();
859  JPCRE2_ASSERT(SJ == J_N.length(), ("ValueError: Modifier character and value table must be of the same size (" + _tostdstring(SJ) + " == " + _tostdstring(J_N.length()) + ").").c_str());
860  JPCRE2_ASSERT(S == N.length(), ("ValueError: Modifier character and value table must be of the same size (" + _tostdstring(S) + " == " + _tostdstring(N.length()) + ").").c_str());
861  return MOD::fromOption(J_V.empty()?0:&J_V[0], J_N.c_str(), SJ,
862  V.empty()?0:&V[0], N.c_str(), S,
863  po, jo);
864  }
865 
866  void parseModifierTable(std::string& tabjs, VecOpt& tabjv,
867  std::string& tab_s, VecOpt& tab_v,
868  std::string const& tabs, VecOpt const& tabv);
869  public:
870 
873 
876  ModifierTable(bool deflt){
877  if(deflt) setAllToDefault();
878  }
879 
883  std::string().swap(tabjms);
884  std::string().swap(tabms);
885  VecOpt().swap(tabjmv);
886  VecOpt().swap(tabmv);
887  return *this;
888  }
889 
893  std::string().swap(tabjrs);
894  std::string().swap(tabrs);
895  VecOpt().swap(tabjrv);
896  VecOpt().swap(tabrv);
897  return *this;
898  }
899 
903  std::string().swap(tabjcs);
904  std::string().swap(tabcs);
905  VecOpt().swap(tabjcv);
906  VecOpt().swap(tabcv);
907  return *this;
908  }
909 
913  resetMatchModifierTable();
914  resetReplaceModifierTable();
915  resetCompileModifierTable();
916  return *this;
917  }
918 
923  tabjms.clear();
924  tabms.clear();
925  tabjmv.clear();
926  tabmv.clear();
927  return *this;
928  }
929 
934  tabjrs.clear();
935  tabrs.clear();
936  tabjrv.clear();
937  tabrv.clear();
938  return *this;
939  }
940 
945  tabjcs.clear();
946  tabcs.clear();
947  tabjcv.clear();
948  tabcv.clear();
949  return *this;
950  }
951 
956  clearMatchModifierTable();
957  clearReplaceModifierTable();
958  clearCompileModifierTable();
959  return *this;
960  }
961 
969  void toMatchOption(Modifier const& mod, bool x, Uint* po, Uint* jo, int* en, SIZE_T* eo) const {
970  toOption(mod, x,tabjmv,tabjms,tabmv, tabms,po,jo,en,eo);
971  }
972 
980  void toReplaceOption(Modifier const& mod, bool x, Uint* po, Uint* jo, int* en, SIZE_T* eo) const {
981  return toOption(mod, x,tabjrv,tabjrs,tabrv,tabrs,po,jo,en,eo);
982  }
983 
991  void toCompileOption(Modifier const& mod, bool x, Uint* po, Uint* jo, int* en, SIZE_T* eo) const {
992  return toOption(mod, x,tabjcv,tabjcs,tabcv,tabcs,po,jo,en,eo);
993  }
994 
999  std::string fromMatchOption(Uint po, Uint jo) const {
1000  return fromOption(tabjmv,tabjms,tabmv,tabms,po,jo);
1001  }
1002 
1007  std::string fromReplaceOption(Uint po, Uint jo) const {
1008  return fromOption(tabjrv,tabjrs,tabrv,tabrs,po,jo);
1009  }
1010 
1015  std::string fromCompileOption(Uint po, Uint jo) const {
1016  return fromOption(tabjcv,tabjcs,tabcv,tabcs,po,jo);
1017  }
1018 
1024  ModifierTable& setMatchModifierTable(std::string const& tabs, VecOpt const& tabv){
1025  parseModifierTable(tabjms, tabjmv, tabms, tabmv, tabs, tabv);
1026  return *this;
1027  }
1028 
1034  ModifierTable& setMatchModifierTable(std::string const& tabs, const Uint* tabvp){
1035  if(tabvp) {
1036  VecOpt tabv(tabvp, tabvp + tabs.length());
1037  setMatchModifierTable(tabs, tabv);
1038  } else clearMatchModifierTable();
1039  return *this;
1040  }
1041 
1050  ModifierTable& setMatchModifierTable(const char* tabsp, const Uint* tabvp){
1051  if(tabsp && tabvp) {
1052  std::string tabs(tabsp);
1053  VecOpt tabv(tabvp, tabvp + tabs.length());
1054  setMatchModifierTable(tabs, tabv);
1055  } else clearMatchModifierTable();
1056  return *this;
1057  }
1058 
1064  ModifierTable& setReplaceModifierTable(std::string const& tabs, VecOpt const& tabv){
1065  parseModifierTable(tabjrs, tabjrv, tabrs, tabrv, tabs, tabv);
1066  return *this;
1067  }
1068 
1074  ModifierTable& setReplaceModifierTable(std::string const& tabs, const Uint* tabvp){
1075  if(tabvp) {
1076  VecOpt tabv(tabvp, tabvp + tabs.length());
1077  setReplaceModifierTable(tabs, tabv);
1078  } else clearReplaceModifierTable();
1079  return *this;
1080  }
1081 
1090  ModifierTable& setReplaceModifierTable(const char* tabsp, const Uint* tabvp){
1091  if(tabsp && tabvp) {
1092  std::string tabs(tabsp);
1093  VecOpt tabv(tabvp, tabvp + tabs.length());
1094  setReplaceModifierTable(tabs, tabv);
1095  } else clearReplaceModifierTable();
1096  return *this;
1097  }
1098 
1104  ModifierTable& setCompileModifierTable(std::string const& tabs, VecOpt const& tabv){
1105  parseModifierTable(tabjcs, tabjcv, tabcs, tabcv, tabs, tabv);
1106  return *this;
1107  }
1108 
1114  ModifierTable& setCompileModifierTable(std::string const& tabs, const Uint* tabvp){
1115  if(tabvp) {
1116  VecOpt tabv(tabvp, tabvp + tabs.length());
1117  setCompileModifierTable(tabs, tabv);
1118  } else clearCompileModifierTable();
1119  return *this;
1120  }
1121 
1130  ModifierTable& setCompileModifierTable(const char* tabsp, const Uint* tabvp){
1131  if(tabsp && tabvp) {
1132  std::string tabs(tabsp);
1133  VecOpt tabv(tabvp, tabvp + tabs.length());
1134  setCompileModifierTable(tabs, tabv);
1135  } else clearCompileModifierTable();
1136  return *this;
1137  }
1138 
1142  tabjms = std::string(MOD::MJ_N, MOD::MJ_N + sizeof(MOD::MJ_V)/sizeof(Uint));
1143  tabms = std::string(MOD::M_N, MOD::M_N + sizeof(MOD::M_V)/sizeof(Uint));
1144  tabjmv = VecOpt(MOD::MJ_V, MOD::MJ_V + sizeof(MOD::MJ_V)/sizeof(Uint));
1145  tabmv = VecOpt(MOD::M_V, MOD::M_V + sizeof(MOD::M_V)/sizeof(Uint));
1146  return *this;
1147  }
1148 
1152  tabjrs = std::string(MOD::RJ_N, MOD::RJ_N + sizeof(MOD::RJ_V)/sizeof(Uint));
1153  tabrs = std::string(MOD::R_N, MOD::R_N + sizeof(MOD::R_V)/sizeof(Uint));
1154  tabjrv = VecOpt(MOD::RJ_V, MOD::RJ_V + sizeof(MOD::RJ_V)/sizeof(Uint));
1155  tabrv = VecOpt(MOD::R_V, MOD::R_V + sizeof(MOD::R_V)/sizeof(Uint));
1156  return *this;
1157  }
1158 
1162  tabjcs = std::string(MOD::CJ_N, MOD::CJ_N + sizeof(MOD::CJ_V)/sizeof(Uint));
1163  tabcs = std::string(MOD::C_N, MOD::C_N + sizeof(MOD::C_V)/sizeof(Uint));
1164  tabjcv = VecOpt(MOD::CJ_V, MOD::CJ_V + sizeof(MOD::CJ_V)/sizeof(Uint));
1165  tabcv = VecOpt(MOD::C_V, MOD::C_V + sizeof(MOD::C_V)/sizeof(Uint));
1166  return *this;
1167  }
1168 
1172  setMatchModifierTableToDefault();
1173  setReplaceModifierTableToDefault();
1174  setCompileModifierTableToDefault();
1175  return *this;
1176  }
1177 };
1178 
1179 
1180 //These message strings are used for error/warning message construction.
1181 //take care to prevent multiple definition
1182 template<typename Char_T> struct MSG{
1183  static std::basic_string<Char_T> INVALID_MODIFIER(void);
1184  static std::basic_string<Char_T> INSUFFICIENT_OVECTOR(void);
1185 };
1186 //specialization
1187 template<> inline std::basic_string<char> MSG<char>::INVALID_MODIFIER(){ return "Invalid modifier: "; }
1188 template<> inline std::basic_string<wchar_t> MSG<wchar_t>::INVALID_MODIFIER(){ return L"Invalid modifier: "; }
1189 template<> inline std::basic_string<char> MSG<char>::INSUFFICIENT_OVECTOR(){ return "ovector wasn't big enough"; }
1190 template<> inline std::basic_string<wchar_t> MSG<wchar_t>::INSUFFICIENT_OVECTOR(){ return L"ovector wasn't big enough"; }
1191 #if __cplusplus >= 201103L
1192 template<> inline std::basic_string<char16_t> MSG<char16_t>::INVALID_MODIFIER(){ return u"Invalid modifier: "; }
1193 template<> inline std::basic_string<char32_t> MSG<char32_t>::INVALID_MODIFIER(){ return U"Invalid modifier: "; }
1194 template<> inline std::basic_string<char16_t> MSG<char16_t>::INSUFFICIENT_OVECTOR(){ return u"ovector wasn't big enough"; }
1195 template<> inline std::basic_string<char32_t> MSG<char32_t>::INSUFFICIENT_OVECTOR(){ return U"ovector wasn't big enough"; }
1196 #endif
1197 
1224 #if __cplusplus >= 201103L
1225 template<typename Char_T, template<typename...> class Map=std::map>
1226 #else
1227 template<typename Char_T>
1228 #endif
1229 struct select{
1230 
1232  typedef Char_T Char;
1233 
1234  //typedef Char_T Char;
1244  typedef typename std::basic_string<Char_T> String;
1245 
1246  #if __cplusplus >= 201103L
1247  typedef class Map<String, String> MapNas;
1250  typedef class Map<String, SIZE_T> MapNtN;
1251  #else
1252  typedef typename std::map<String, String> MapNas;
1255  typedef typename std::map<String, SIZE_T> MapNtN;
1256  #endif
1257 
1259  typedef MapNtN MapNtn;
1260 
1262  typedef typename std::vector<String> NumSub;
1264  typedef typename std::vector<MapNas> VecNas;
1266  typedef typename std::vector<MapNtN> VecNtN;
1268  typedef VecNtN VecNtn;
1270  typedef typename std::vector<NumSub> VecNum;
1271 
1272  //These are to shorten the code
1273  typedef typename Pcre2Type<sizeof( Char_T ) * CHAR_BIT>::Pcre2Uchar Pcre2Uchar;
1274  typedef typename Pcre2Type<sizeof( Char_T ) * CHAR_BIT>::Pcre2Sptr Pcre2Sptr;
1275  typedef typename Pcre2Type<sizeof( Char_T ) * CHAR_BIT>::Pcre2Code Pcre2Code;
1276  typedef typename Pcre2Type<sizeof( Char_T ) * CHAR_BIT>::CompileContext CompileContext;
1277  typedef typename Pcre2Type<sizeof( Char_T ) * CHAR_BIT>::MatchData MatchData;
1278  typedef typename Pcre2Type<sizeof( Char_T ) * CHAR_BIT>::GeneralContext GeneralContext;
1279  typedef typename Pcre2Type<sizeof( Char_T ) * CHAR_BIT>::MatchContext MatchContext;
1280  typedef typename Pcre2Type<sizeof( Char_T ) * CHAR_BIT>::JitCallback JitCallback;
1281  typedef typename Pcre2Type<sizeof( Char_T ) * CHAR_BIT>::JitStack JitStack;
1282 
1283  template<typename T>
1284  static String toString(T); //prevent implicit type conversion of T
1285 
1289  static String toString(Char a){
1290  return a?String(1, a):String();
1291  }
1292 
1298  static String toString(Char const *a){
1299  return a?String(a):String();
1300  }
1301 
1307  static String toString(Char* a){
1308  return a?String(a):String();
1309  }
1310 
1316  static String toString(Pcre2Uchar* a) {
1317  return a?String((Char*) a):String();
1318  }
1319 
1323  static String getPcre2ErrorMessage(int err_num) {
1324  Pcre2Uchar buffer[sizeof(Char)*CHAR_BIT*1024];
1325  Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::get_error_message(err_num, buffer, sizeof(buffer));
1326  return toString((Pcre2Uchar*) buffer);
1327  }
1328 
1333  static String getErrorMessage(int err_num, int err_off) {
1334  if(err_num == (int)ERROR::INVALID_MODIFIER){
1335  return MSG<Char>::INVALID_MODIFIER() + toString((Char)err_off);
1336  } else if(err_num == (int)ERROR::INSUFFICIENT_OVECTOR){
1338  } else if(err_num != 0) {
1339  return getPcre2ErrorMessage((int) err_num);
1340  } else return String();
1341  }
1342 
1343  //forward declaration
1344  class Regex;
1345  class RegexMatch;
1346  class RegexReplace;
1347  class MatchEvaluator;
1348 
1366  class RegexMatch {
1367 
1368  private:
1369 
1370  friend class MatchEvaluator;
1371 
1372  Regex const *re;
1373 
1374  String m_subject;
1375  String const *m_subject_ptr;
1376  Uint match_opts;
1377  Uint jpcre2_match_opts;
1378  MatchContext *mcontext;
1379  ModifierTable const * modtab;
1380  MatchData * mdata;
1381 
1382  PCRE2_SIZE _start_offset; //name collision, use _ at start
1383 
1384  VecNum* vec_num;
1385  VecNas* vec_nas;
1386  VecNtN* vec_ntn;
1387 
1388  VecOff* vec_soff;
1389  VecOff* vec_eoff;
1390 
1391  bool getNumberedSubstrings(int, Pcre2Sptr, PCRE2_SIZE*);
1392 
1393  bool getNamedSubstrings(int, int, Pcre2Sptr, Pcre2Sptr, PCRE2_SIZE*);
1394 
1395  void init_vars() {
1396  re = 0;
1397  vec_num = 0;
1398  vec_nas = 0;
1399  vec_ntn = 0;
1400  vec_soff = 0;
1401  vec_eoff = 0;
1402  match_opts = 0;
1403  jpcre2_match_opts = 0;
1404  error_number = 0;
1405  error_offset = 0;
1406  _start_offset = 0;
1407  m_subject_ptr = &m_subject;
1408  mcontext = 0;
1409  modtab = 0;
1410  mdata = 0;
1411  }
1412 
1413  void onlyCopy(RegexMatch const &rm){
1414  re = rm.re; //only pointer should be copied
1415 
1416  //pointer to subject may point to m_subject or other user data
1417  m_subject_ptr = (rm.m_subject_ptr == &rm.m_subject) ? &m_subject //not &rm.m_subject
1418  : rm.m_subject_ptr;
1419 
1420  //underlying data of vectors are not handled by RegexMatch
1421  //thus it's safe to just copy the pointers.
1422  vec_num = rm.vec_num;
1423  vec_nas = rm.vec_nas;
1424  vec_ntn = rm.vec_ntn;
1425  vec_soff = rm.vec_soff;
1426  vec_eoff = rm.vec_eoff;
1427 
1428  match_opts = rm.match_opts;
1429  jpcre2_match_opts = rm.jpcre2_match_opts;
1430  error_number = rm.error_number;
1431  error_offset = rm.error_offset;
1432  _start_offset = rm._start_offset;
1433  mcontext = rm.mcontext;
1434  modtab = rm.modtab;
1435  mdata = rm.mdata;
1436  }
1437 
1438  void deepCopy(RegexMatch const &rm){
1439  m_subject = rm.m_subject;
1440  onlyCopy(rm);
1441  }
1442 
1443  #if __cplusplus >= 201103L
1444  void deepMove(RegexMatch& rm){
1445  m_subject = std::move_if_noexcept(rm.m_subject);
1446  onlyCopy(rm);
1447  }
1448  #endif
1449 
1450  friend class Regex;
1451 
1452  protected:
1453 
1454  int error_number;
1455  PCRE2_SIZE error_offset;
1456 
1457  public:
1458 
1461  init_vars();
1462  }
1463 
1469  RegexMatch(Regex const *r) {
1470  init_vars();
1471  re = r;
1472  }
1473 
1479  init_vars();
1480  deepCopy(rm);
1481  }
1482 
1486  virtual RegexMatch& operator=(RegexMatch const &rm){
1487  if(this == &rm) return *this;
1488  deepCopy(rm);
1489  return *this;
1490  }
1491 
1492  #if __cplusplus >= 201103L
1493  RegexMatch(RegexMatch&& rm){
1501  init_vars();
1502  deepMove(rm);
1503  }
1504 
1514  if(this == &rm) return *this;
1515  deepMove(rm);
1516  return *this;
1517  }
1518  #endif
1519 
1522  virtual ~RegexMatch() {}
1523 
1528  virtual RegexMatch& reset() {
1529  String().swap(m_subject); //not ptr , external string won't be modified.
1530  init_vars();
1531  return *this;
1532  }
1533 
1538  virtual RegexMatch& clear(){
1539  m_subject.clear(); //not ptr , external string won't be modified.
1540  init_vars();
1541  return *this;
1542  }
1543 
1553  error_number = 0;
1554  error_offset = 0;
1555  return *this;
1556  }
1557 
1560  virtual int getErrorNumber() const {
1561  return error_number;
1562  }
1563 
1566  virtual int getErrorOffset() const {
1567  return (int)error_offset;
1568  }
1569 
1572  virtual String getErrorMessage() const {
1573  #if __cplusplus >= 201103L
1574  return select<Char, Map>::getErrorMessage(error_number, error_offset);
1575  #else
1576  return select<Char>::getErrorMessage(error_number, error_offset);
1577  #endif
1578  }
1579 
1583  virtual String getSubject() const {
1584  return *m_subject_ptr;
1585  }
1586 
1591  virtual String const * getSubjectPointer() const {
1592  return m_subject_ptr;
1593  }
1594 
1595 
1610  virtual std::string getModifier() const {
1611  return modtab ? modtab->fromMatchOption(match_opts, jpcre2_match_opts)
1612  : MOD::fromMatchOption(match_opts, jpcre2_match_opts);
1613  }
1614 
1618  return modtab;
1619  }
1620 
1621 
1626  virtual Uint getPcre2Option() const {
1627  return match_opts;
1628  }
1629 
1634  virtual Uint getJpcre2Option() const {
1635  return jpcre2_match_opts;
1636  }
1637 
1640  virtual PCRE2_SIZE getStartOffset() const {
1641  return _start_offset;
1642  }
1643 
1648  virtual VecOff const* getMatchStartOffsetVector() const {
1649  return vec_soff;
1650  }
1651 
1656  virtual VecOff const* getMatchEndOffsetVector() const {
1657  return vec_eoff;
1658  }
1659 
1663  virtual Regex const * getRegexObject() const {
1664  return re;
1665  }
1666 
1669  virtual VecNum const* getNumberedSubstringVector() const {
1670  return vec_num;
1671  }
1672 
1675  virtual VecNas const* getNamedSubstringVector() const {
1676  return vec_nas;
1677  }
1678 
1681  virtual VecNtN const* getNameToNumberMapVector() const {
1682  return vec_ntn;
1683  }
1684 
1690  virtual RegexMatch& setRegexObject(Regex const *r){
1691  re = r;
1692  return *this;
1693  }
1694 
1702  vec_num = v;
1703  return *this;
1704  }
1705 
1712  virtual RegexMatch& setNamedSubstringVector(VecNas* v) {
1713  vec_nas = v;
1714  return *this;
1715  }
1716 
1723  virtual RegexMatch& setNameToNumberMapVector(VecNtN* v) {
1724  vec_ntn = v;
1725  return *this;
1726  }
1727 
1734  vec_soff = v;
1735  return *this;
1736  }
1737 
1744  vec_eoff = v;
1745  return *this;
1746  }
1747 
1753  virtual RegexMatch& setSubject(String const &s) {
1754  m_subject = s;
1755  m_subject_ptr = &m_subject; //must overwrite
1756  return *this;
1757  }
1758 
1765  virtual RegexMatch& setSubject(String const *s) {
1766  if(s) m_subject_ptr = s;
1767  else {
1768  m_subject.clear();
1769  m_subject_ptr = &m_subject;
1770  }
1771  return *this;
1772  }
1773 
1774 
1781  virtual RegexMatch& setModifier(Modifier const& s) {
1782  match_opts = 0;
1783  jpcre2_match_opts = 0;
1784  changeModifier(s, true);
1785  return *this;
1786  }
1787 
1792  modtab = mdt;
1793  return *this;
1794  }
1795 
1801  virtual RegexMatch& setJpcre2Option(Uint x) {
1802  jpcre2_match_opts = x;
1803  return *this;
1804  }
1805 
1811  virtual RegexMatch& setPcre2Option(Uint x) {
1812  match_opts = x;
1813  return *this;
1814  }
1815 
1819  virtual RegexMatch& setFindAll(bool x) {
1820  jpcre2_match_opts = x?jpcre2_match_opts | FIND_ALL:jpcre2_match_opts & ~FIND_ALL;
1821  return *this;
1822  }
1823 
1828  virtual RegexMatch& setFindAll() {
1829  return setFindAll(true);
1830  }
1831 
1837  virtual RegexMatch& setStartOffset(PCRE2_SIZE offset) {
1838  _start_offset = offset;
1839  return *this;
1840  }
1841 
1848  virtual RegexMatch& setMatchContext(MatchContext *match_context){
1849  mcontext = match_context;
1850  return *this;
1851  }
1852 
1856  virtual MatchContext* getMatchContext(){
1857  return mcontext;
1858  }
1859 
1865  virtual RegexMatch& setMatchDataBlock(MatchData* madt){
1866  mdata = madt;
1867  return *this;
1868  }
1869 
1873  virtual MatchData* getMatchDataBlock(){
1874  return mdata;
1875  }
1876 
1889  virtual RegexMatch& changeModifier(Modifier const& mod, bool x){
1890  modtab ? modtab->toMatchOption(mod, x, &match_opts, &jpcre2_match_opts, &error_number, &error_offset)
1891  : MOD::toMatchOption(mod, x, &match_opts, &jpcre2_match_opts, &error_number, &error_offset);
1892  return *this;
1893  }
1894 
1901  virtual RegexMatch& changeJpcre2Option(Uint opt, bool x) {
1902  jpcre2_match_opts = x ? jpcre2_match_opts | opt : jpcre2_match_opts & ~opt;
1903  return *this;
1904  }
1905 
1912  virtual RegexMatch& changePcre2Option(Uint opt, bool x) {
1913  match_opts = x ? match_opts | opt : match_opts & ~opt;
1914  return *this;
1915  }
1916 
1923  virtual RegexMatch& addModifier(Modifier const& mod){
1924  return changeModifier(mod, true);
1925  }
1926 
1932  virtual RegexMatch& addJpcre2Option(Uint x) {
1933  jpcre2_match_opts |= x;
1934  return *this;
1935  }
1936 
1942  virtual RegexMatch& addPcre2Option(Uint x) {
1943  match_opts |= x;
1944  return *this;
1945  }
1946 
1947 
1953  virtual SIZE_T match(void);
1954  };
1955 
1956 
1989  template<typename T1, typename T2, typename T3>
1991  #if !defined JPCRE2_USE_FUNCTION_POINTER_CALLBACK && __cplusplus >= 201103L
1992  typedef std::function<String (T1,T2,T3)> Callback;
1993  #else
1994  typedef String (*Callback)(T1,T2,T3);
1995  #endif
1996  };
1997 
2003  struct callback{
2013  static String eraseFill(NumSub const &num, MapNas const &nas, MapNtN const &ntn){
2014  return String();
2015  }
2016 
2027  static String erase(void*, void*, void*){
2028  return String();
2029  }
2030 
2037  static String fill(NumSub const &num, MapNas const &nas, MapNtn const &ntn){
2038  return num[0];
2039  }
2040 
2041  private:
2042  //prevent object instantiation.
2043  callback();
2044  callback(callback const &);
2045  #if __cplusplus >= 201103L
2046  callback(callback&&);
2047  #endif
2048  ~callback();
2049  };
2050 
2126  class MatchEvaluator: virtual public RegexMatch{
2127  private:
2128  friend class RegexReplace;
2129 
2130  VecNum vec_num;
2131  VecNas vec_nas;
2132  VecNtN vec_ntn;
2133  VecOff vec_soff;
2134  VecOff vec_eoff;
2135  int callbackn;
2136  typename MatchEvaluatorCallback<void*, void*, void*>::Callback callback0;
2137  typename MatchEvaluatorCallback<NumSub const &, void*, void*>::Callback callback1;
2138  typename MatchEvaluatorCallback<void*, MapNas const &, void*>::Callback callback2;
2139  typename MatchEvaluatorCallback<NumSub const &, MapNas const &, void*>::Callback callback3;
2140  typename MatchEvaluatorCallback<void*, void*, MapNtN const &>::Callback callback4;
2141  typename MatchEvaluatorCallback<NumSub const &, void*, MapNtN const &>::Callback callback5;
2142  typename MatchEvaluatorCallback<void*, MapNas const &, MapNtN const &>::Callback callback6;
2143  typename MatchEvaluatorCallback<NumSub const &, MapNas const &, MapNtN const &>::Callback callback7;
2144  //Q: Why the callback names seem random? is it random?
2145  //A: No, it's not random, NumSub = 1, MapNas = 2, MapNtn = 4, thus:
2146  // NumSub + MapNas = 3
2147  // NumSub + MapNtn = 5
2148  // MapNas + MapNtn = 6
2149  // NumSub + MapNas + MapNtn = 7
2150  //Q: Why is it like this?
2151  //A: It's historical. Once, there was not this many callback declaration, there was only one (a templated one).
2152  // The nreplace function itself used to calculate a mode value according to available vectors
2153  // and determine what kind of callback function needed to be called.
2154  //Q: Why the history changed?
2155  //A: We had some compatibility issues with the single templated callback.
2156  // Also, this approach proved to be more readable and robust.
2157 
2158  PCRE2_SIZE buffer_size;
2159 
2160 
2161  void init(){
2162  callbackn = 0;
2163  callback0 = callback::erase;
2164  callback1 = 0;
2165  callback2 = 0;
2166  callback3 = 0;
2167  callback4 = 0;
2168  callback5 = 0;
2169  callback6 = 0;
2170  callback7 = 0;
2171  setMatchStartOffsetVector(&vec_soff);
2172  setMatchEndOffsetVector(&vec_eoff);
2173  buffer_size = 0;
2174  }
2175 
2176  void setVectorPointersAccordingToCallback(){
2177  switch(callbackn){
2178  case 0: break;
2179  case 1: setNumberedSubstringVector(&vec_num);break;
2180  case 2: setNamedSubstringVector(&vec_nas);break;
2181  case 3: setNumberedSubstringVector(&vec_num).setNamedSubstringVector(&vec_nas);break;
2182  case 4: setNameToNumberMapVector(&vec_ntn);break;
2183  case 5: setNumberedSubstringVector(&vec_num).setNameToNumberMapVector(&vec_ntn);break;
2184  case 6: setNamedSubstringVector(&vec_nas).setNameToNumberMapVector(&vec_ntn);break;
2185  case 7: setNumberedSubstringVector(&vec_num).setNamedSubstringVector(&vec_nas).setNameToNumberMapVector(&vec_ntn);break;
2186  }
2187  }
2188 
2189  void onlyCopy(MatchEvaluator const &me){
2190  callbackn = me.callbackn;
2191  callback0 = me.callback0;
2192  callback1 = me.callback1;
2193  callback2 = me.callback2;
2194  callback3 = me.callback3;
2195  callback4 = me.callback4;
2196  callback5 = me.callback5;
2197  callback6 = me.callback6;
2198  callback7 = me.callback7;
2199  //must update the pointers to point to this class vectors.
2200  setVectorPointersAccordingToCallback();
2201  buffer_size = me.buffer_size;
2202  }
2203 
2204  void deepCopy(MatchEvaluator const &me) {
2205  vec_num = me.vec_num;
2206  vec_nas = me.vec_nas;
2207  vec_ntn = me.vec_ntn;
2208  vec_soff = me.vec_soff;
2209  vec_eoff = me.vec_eoff;
2210  onlyCopy(me);
2211  }
2212 
2213  #if __cplusplus >= 201103L
2214  void deepMove(MatchEvaluator& me){
2215  vec_num = std::move_if_noexcept(me.vec_num);
2216  vec_nas = std::move_if_noexcept(me.vec_nas);
2217  vec_ntn = std::move_if_noexcept(me.vec_ntn);
2218  vec_soff = std::move_if_noexcept(me.vec_soff);
2219  vec_eoff = std::move_if_noexcept(me.vec_eoff);
2220  onlyCopy(me);
2221  }
2222  #endif
2223 
2224  //prevent public access to some funcitons
2225  MatchEvaluator& setNumberedSubstringVector(VecNum* v){
2226  RegexMatch::setNumberedSubstringVector(v);
2227  return *this;
2228  }
2229  MatchEvaluator& setNamedSubstringVector(VecNas* v){
2230  RegexMatch::setNamedSubstringVector(v);
2231  return *this;
2232  }
2233  MatchEvaluator& setNameToNumberMapVector(VecNtN* v){
2234  RegexMatch::setNameToNumberMapVector(v);
2235  return *this;
2236  }
2237  MatchEvaluator& setMatchStartOffsetVector(VecOff* v){
2238  RegexMatch::setMatchStartOffsetVector(v);
2239  return *this;
2240  }
2241  MatchEvaluator& setMatchEndOffsetVector(VecOff* v){
2242  RegexMatch::setMatchEndOffsetVector(v);
2243  return *this;
2244  }
2245 
2246  public:
2247 
2262  explicit
2264  init();
2265  }
2266 
2275  explicit
2277  init();
2278  }
2279 
2285  explicit
2286  MatchEvaluator(typename MatchEvaluatorCallback<void*, void*, void*>::Callback mef): RegexMatch(){
2287  init();
2288  setCallback(mef);
2289  }
2290 
2295  explicit
2296  MatchEvaluator(typename MatchEvaluatorCallback<NumSub const &, void*, void*>::Callback mef): RegexMatch(){
2297  init();
2298  setCallback(mef);
2299  }
2300 
2305  explicit
2306  MatchEvaluator(typename MatchEvaluatorCallback<NumSub const &, MapNas const &, void*>::Callback mef): RegexMatch(){
2307  init();
2308  setCallback(mef);
2309  }
2310 
2315  explicit
2316  MatchEvaluator(typename MatchEvaluatorCallback<NumSub const &, void*, MapNtN const &>::Callback mef): RegexMatch(){
2317  init();
2318  setCallback(mef);
2319  }
2320 
2325  explicit
2326  MatchEvaluator(typename MatchEvaluatorCallback<NumSub const &, MapNas const &, MapNtN const &>::Callback mef): RegexMatch(){
2327  init();
2328  setCallback(mef);
2329  }
2330 
2335  explicit
2336  MatchEvaluator(typename MatchEvaluatorCallback<void*, MapNas const &, void*>::Callback mef): RegexMatch(){
2337  init();
2338  setCallback(mef);
2339  }
2340 
2341 
2346  explicit
2347  MatchEvaluator(typename MatchEvaluatorCallback<void*, MapNas const &, MapNtN const &>::Callback mef): RegexMatch(){
2348  init();
2349  setCallback(mef);
2350  }
2351 
2352 
2353 
2358  explicit
2359  MatchEvaluator(typename MatchEvaluatorCallback<void*, void*, MapNtN const &>::Callback mef): RegexMatch(){
2360  init();
2361  setCallback(mef);
2362  }
2363 
2364 
2365 
2371  init();
2372  deepCopy(me);
2373  }
2374 
2379  if(this == &me) return *this;
2380  RegexMatch::operator=(me);
2381  deepCopy(me);
2382  return *this;
2383  }
2384 
2385  #if __cplusplus >= 201103L
2386 
2395  init();
2396  deepMove(me);
2397  }
2398 
2409  if(this == &me) return *this;
2410  RegexMatch::operator=(me);
2411  deepMove(me);
2412  return *this;
2413  }
2414 
2415  #endif
2416 
2417  virtual ~MatchEvaluator(){}
2418 
2425  MatchEvaluator& setCallback(typename MatchEvaluatorCallback<void*, void*, void*>::Callback mef){
2426  callback0 = mef;
2427  callbackn = 0;
2428  return *this;
2429  }
2430 
2437  MatchEvaluator& setCallback(typename MatchEvaluatorCallback<NumSub const &, void*, void*>::Callback mef){
2438  callback1 = mef;
2439  callbackn = 1;
2440  setNumberedSubstringVector(&vec_num);
2441  return *this;
2442  }
2443 
2460  MatchEvaluator& setCallback(typename MatchEvaluatorCallback<NumSub const &, MapNas const &, void*>::Callback mef){
2461  callback3 = mef;
2462  callbackn = 3;
2463  setNumberedSubstringVector(&vec_num);
2464  setNamedSubstringVector(&vec_nas);
2465  return *this;
2466  }
2467 
2484  MatchEvaluator& setCallback(typename MatchEvaluatorCallback<NumSub const &, void*, MapNtN const &>::Callback mef){
2485  callback5 = mef;
2486  callbackn = 5;
2487  setNumberedSubstringVector(&vec_num);
2488  setNameToNumberMapVector(&vec_ntn);
2489  return *this;
2490  }
2491 
2492 
2509  MatchEvaluator& setCallback(typename MatchEvaluatorCallback<NumSub const &, MapNas const &, MapNtN const &>::Callback mef){
2510  callback7 = mef;
2511  callbackn = 7;
2512  setNumberedSubstringVector(&vec_num);
2513  setNamedSubstringVector(&vec_nas);
2514  setNameToNumberMapVector(&vec_ntn);
2515  return *this;
2516  }
2517 
2534  MatchEvaluator& setCallback(typename MatchEvaluatorCallback<void*, MapNas const &, void*>::Callback mef){
2535  callback2 = mef;
2536  callbackn = 2;
2537  setNamedSubstringVector(&vec_nas);
2538  return *this;
2539  }
2540 
2557  MatchEvaluator& setCallback(typename MatchEvaluatorCallback<void*, MapNas const &, MapNtN const &>::Callback mef){
2558  callback6 = mef;
2559  callbackn = 6;
2560  setNamedSubstringVector(&vec_nas);
2561  setNameToNumberMapVector(&vec_ntn);
2562  return *this;
2563  }
2564 
2581  MatchEvaluator& setCallback(typename MatchEvaluatorCallback<void*, void*, MapNtN const &>::Callback mef){
2582  callback4 = mef;
2583  callbackn = 4;
2584  setNameToNumberMapVector(&vec_ntn);
2585  return *this;
2586  }
2587 
2594  vec_num.clear();
2595  vec_nas.clear();
2596  vec_ntn.clear();
2597  vec_soff.clear();
2598  vec_eoff.clear();
2599  return *this;
2600  }
2601 
2607  VecNum().swap(vec_num);
2608  VecNas().swap(vec_nas);
2609  VecNtN().swap(vec_ntn);
2610  VecOff().swap(vec_soff);
2611  VecOff().swap(vec_eoff);
2612  return *this;
2613  }
2614 
2615 
2619  RegexMatch::reset();
2620  resetMatchData();
2621  init();
2622  return *this;
2623  }
2624 
2629  RegexMatch::clear();
2630  clearMatchData();
2631  init();
2632  return *this;
2633  }
2634 
2638  RegexMatch::resetErrors();
2639  return *this;
2640  }
2641 
2646  RegexMatch::setRegexObject(r);
2647  return *this;
2648  }
2649 
2653  MatchEvaluator& setSubject (String const &s){
2654  RegexMatch::setSubject(s);
2655  return *this;
2656  }
2657 
2661  MatchEvaluator& setSubject (String const *s){
2662  RegexMatch::setSubject(s);
2663  return *this;
2664  }
2665 
2670  RegexMatch::setModifier(s);
2671  return *this;
2672  }
2673 
2678  RegexMatch::setModifierTable(mdt);
2679  return *this;
2680  }
2681 
2686  RegexMatch::setJpcre2Option(x);
2687  return *this;
2688  }
2689 
2694  RegexMatch::setPcre2Option(x);
2695  return *this;
2696  }
2697 
2702  RegexMatch::setFindAll(x);
2703  return *this;
2704  }
2705 
2709  RegexMatch::setFindAll();
2710  return *this;
2711  }
2712 
2716  MatchEvaluator& setStartOffset (PCRE2_SIZE offset){
2717  RegexMatch::setStartOffset(offset);
2718  return *this;
2719  }
2720 
2724  MatchEvaluator& setMatchContext (MatchContext *match_context){
2725  RegexMatch::setMatchContext(match_context);
2726  return *this;
2727  }
2728 
2733  RegexMatch::setMatchDataBlock(mdt);
2734  return *this;
2735  }
2736 
2744  buffer_size = x;
2745  return *this;
2746  }
2747 
2750  PCRE2_SIZE getBufferSize(){
2751  return buffer_size;
2752  }
2753 
2758  MatchEvaluator& changeModifier (Modifier const& mod, bool x){
2759  RegexMatch::changeModifier(mod, x);
2760  return *this;
2761  }
2762 
2767  MatchEvaluator& changeJpcre2Option (Uint opt, bool x){
2768  RegexMatch::changeJpcre2Option(opt, x);
2769  return *this;
2770  }
2771 
2776  MatchEvaluator& changePcre2Option (Uint opt, bool x){
2777  RegexMatch::changePcre2Option(opt, x);
2778  return *this;
2779  }
2780 
2785  RegexMatch::addModifier(mod);
2786  return *this;
2787  }
2788 
2793  RegexMatch::addJpcre2Option(x);
2794  return *this;
2795  }
2796 
2801  RegexMatch::addPcre2Option(x);
2802  return *this;
2803  }
2804 
2810  SIZE_T match(void){
2811  //remove bad matching options
2812  RegexMatch::changePcre2Option(PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT, false);
2813  return RegexMatch::match();
2814  }
2815 
2840  String nreplace(bool do_match=true, Uint jro=0, SIZE_T* counter=0);
2841 
2861  String replace(bool do_match=true, Uint ro=0, SIZE_T* counter=0);
2862  };
2863 
2881  class RegexReplace {
2882 
2883  private:
2884 
2885  friend class Regex;
2886 
2887  Regex const *re;
2888 
2889  String r_subject;
2890  String *r_subject_ptr; //preplace method modifies it in-place
2891  String r_replw;
2892  String const *r_replw_ptr;
2893  Uint replace_opts;
2894  Uint jpcre2_replace_opts;
2895  PCRE2_SIZE buffer_size;
2896  PCRE2_SIZE _start_offset;
2897  MatchData *mdata;
2898  MatchContext *mcontext;
2899  ModifierTable const * modtab;
2900  SIZE_T last_replace_count;
2901  SIZE_T* last_replace_counter;
2902 
2903  void init_vars() {
2904  re = 0;
2905  r_subject_ptr = &r_subject;
2906  r_replw_ptr = &r_replw;
2907  replace_opts = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH;
2908  jpcre2_replace_opts = 0;
2909  buffer_size = 0;
2910  error_number = 0;
2911  error_offset = 0;
2912  _start_offset = 0;
2913  mdata = 0;
2914  mcontext = 0;
2915  modtab = 0;
2916  last_replace_count = 0;
2917  last_replace_counter = &last_replace_count;
2918  }
2919 
2920  void onlyCopy(RegexReplace const &rr){
2921  re = rr.re; //only pointer should be copied.
2922 
2923  //rr.r_subject_ptr may point to rr.r_subject or other user data
2924  r_subject_ptr = (rr.r_subject_ptr == &rr.r_subject) ? &r_subject //not rr.r_subject
2925  : rr.r_subject_ptr; //other user data
2926 
2927  r_replw = rr.r_replw;
2928  //rr.r_replw_ptr may point to rr.r_replw or other user data
2929  r_replw_ptr = (rr.r_replw_ptr == &rr.r_replw) ? &r_replw //not rr.r_replw
2930  : rr.r_replw_ptr; //other user data
2931 
2932  replace_opts = rr.replace_opts;
2933  jpcre2_replace_opts = rr.jpcre2_replace_opts;
2934  buffer_size = rr.buffer_size;
2935  error_number = rr.error_number;
2936  error_offset = rr.error_offset;
2937  _start_offset = rr._start_offset;
2938  mdata = rr.mdata;
2939  mcontext = rr.mcontext;
2940  modtab = rr.modtab;
2941  last_replace_count = rr.last_replace_count;
2942  last_replace_counter = (rr.last_replace_counter == &rr.last_replace_count) ? &last_replace_count
2943  : rr.last_replace_counter;
2944  }
2945 
2946  void deepCopy(RegexReplace const &rr){
2947  r_subject = rr.r_subject;
2948  onlyCopy(rr);
2949  }
2950 
2951  #if __cplusplus >= 201103L
2952  void deepMove(RegexReplace& rr){
2953  r_subject = std::move_if_noexcept(rr.r_subject);
2954  onlyCopy(rr);
2955  }
2956  #endif
2957 
2958 
2959  protected:
2960 
2961  int error_number;
2962  PCRE2_SIZE error_offset;
2963 
2964  public:
2965 
2968  init_vars();
2969  }
2970 
2976  RegexReplace(Regex const *r) {
2977  init_vars();
2978  re = r;
2979  }
2980 
2986  init_vars();
2987  deepCopy(rr);
2988  }
2989 
2994  if(this == &rr) return *this;
2995  deepCopy(rr);
2996  return *this;
2997  }
2998 
2999  #if __cplusplus >= 201103L
3000 
3009  init_vars();
3010  deepMove(rr);
3011  }
3012 
3022  if(this == &rr) return *this;
3023  deepMove(rr);
3024  return *this;
3025  }
3026 
3027  #endif
3028 
3029  virtual ~RegexReplace() {}
3030 
3034  String().swap(r_subject);
3035  String().swap(r_replw);
3036  init_vars();
3037  return *this;
3038  }
3039 
3043  r_subject.clear();
3044  r_replw.clear();
3045  init_vars();
3046  return *this;
3047  }
3048 
3054  error_number = 0;
3055  error_offset = 0;
3056  return *this;
3057  }
3058 
3061  int getErrorNumber() const {
3062  return error_number;
3063  }
3064 
3067  int getErrorOffset() const {
3068  return (int)error_offset;
3069  }
3070 
3073  String getErrorMessage() const {
3074  #if __cplusplus >= 201103L
3075  return select<Char, Map>::getErrorMessage(error_number, error_offset);
3076  #else
3077  return select<Char>::getErrorMessage(error_number, error_offset);
3078  #endif
3079  }
3080 
3083  String getReplaceWith() const {
3084  return *r_replw_ptr;
3085  }
3086 
3089  String const * getReplaceWithPointer() const {
3090  return r_replw_ptr;
3091  }
3092 
3096  String getSubject() const {
3097  return *r_subject_ptr;
3098  }
3099 
3103  String const * getSubjectPointer() const {
3104  return r_subject_ptr;
3105  }
3106 
3107 
3122  std::string getModifier() const {
3123  return modtab ? modtab->fromReplaceOption(replace_opts, jpcre2_replace_opts)
3124  : MOD::fromReplaceOption(replace_opts, jpcre2_replace_opts);
3125  }
3126 
3130  return modtab;
3131  }
3132 
3135  PCRE2_SIZE getStartOffset() const {
3136  return _start_offset;
3137  }
3138 
3143  Uint getPcre2Option() const {
3144  return replace_opts;
3145  }
3146 
3151  Uint getJpcre2Option() const {
3152  return jpcre2_replace_opts;
3153  }
3154 
3158  Regex const * getRegexObject() const {
3159  return re;
3160  }
3161 
3165  MatchContext* getMatchContext(){
3166  return mcontext;
3167  }
3168 
3172  virtual MatchData* getMatchDataBlock(){
3173  return mdata;
3174  }
3175 
3178  PCRE2_SIZE getBufferSize(){
3179  return buffer_size;
3180  }
3181 
3188  return *last_replace_counter;
3189  }
3190 
3197  RegexReplace& setReplaceCounter(SIZE_T* counter){
3198  last_replace_count = 0;
3199  last_replace_counter = counter ? counter : &last_replace_count;
3200  return *this;
3201  }
3202 
3208  re = r;
3209  return *this;
3210  }
3211 
3218  RegexReplace& setSubject(String const &s) {
3219  r_subject = s;
3220  r_subject_ptr = &r_subject; //must overwrite
3221  return *this;
3222  }
3223 
3231  RegexReplace& setSubject(String *s) {
3232  if(s) r_subject_ptr = s;
3233  else {
3234  r_subject.clear();
3235  r_subject_ptr = &r_subject;
3236  }
3237  return *this;
3238  }
3239 
3252  RegexReplace& setReplaceWith(String const &s) {
3253  r_replw = s;
3254  r_replw_ptr = &r_replw; //must overwrite
3255  return *this;
3256  }
3257 
3262  RegexReplace& setReplaceWith(String const *s) {
3263  if(s) r_replw_ptr = s;
3264  else {
3265  r_replw.clear();
3266  r_replw_ptr = &r_replw;
3267  }
3268  return *this;
3269  }
3270 
3277  replace_opts = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH; /* must not be initialized to 0 */
3278  jpcre2_replace_opts = 0;
3279  return changeModifier(s, true);
3280  }
3281 
3286  modtab = mdt;
3287  return *this;
3288  }
3289 
3293  RegexReplace& setBufferSize(PCRE2_SIZE x) {
3294  buffer_size = x;
3295  return *this;
3296  }
3297 
3302  RegexReplace& setStartOffset(PCRE2_SIZE start_offset){
3303  _start_offset = start_offset;
3304  return *this;
3305  }
3306 
3312 
3314  jpcre2_replace_opts = x;
3315  return *this;
3316  }
3317 
3323 
3325  replace_opts = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH | x;
3326  return *this;
3327  }
3328 
3335  RegexReplace& setMatchContext(MatchContext * match_context){
3336  mcontext = match_context;
3337  return *this;
3338  }
3339 
3346  RegexReplace& setMatchDataBlock(MatchData *match_data){
3347  mdata = match_data;
3348  return *this;
3349  }
3350 
3363  RegexReplace& changeModifier(Modifier const& mod, bool x){
3364  modtab ? modtab->toReplaceOption(mod, x, &replace_opts, &jpcre2_replace_opts, &error_number, &error_offset)
3365  : MOD::toReplaceOption(mod, x, &replace_opts, &jpcre2_replace_opts, &error_number, &error_offset);
3366  return *this;
3367  }
3368 
3376  RegexReplace& changeJpcre2Option(Uint opt, bool x) {
3377  jpcre2_replace_opts = x ? jpcre2_replace_opts | opt : jpcre2_replace_opts & ~opt;
3378  return *this;
3379  }
3380 
3387  RegexReplace& changePcre2Option(Uint opt, bool x) {
3388  replace_opts = x ? replace_opts | opt : replace_opts & ~opt;
3389  //replace_opts |= PCRE2_SUBSTITUTE_OVERFLOW_LENGTH; /* It's important, but let user override it. */
3390  return *this;
3391  }
3392 
3401  return changeModifier(mod, true);
3402  }
3403 
3410  jpcre2_replace_opts |= x;
3411  return *this;
3412  }
3413 
3420  replace_opts |= x;
3421  return *this;
3422  }
3423 
3435  String replace(void);
3436 
3442  SIZE_T preplace(void){
3443  *r_subject_ptr = replace();
3444  return *last_replace_counter;
3445  }
3446 
3458  *r_subject_ptr = me.setRegexObject(getRegexObject())
3459  .setSubject(r_subject_ptr) //do not use method
3460  .setFindAll((getPcre2Option() & PCRE2_SUBSTITUTE_GLOBAL)!=0)
3461  .setMatchContext(getMatchContext())
3462  .setMatchDataBlock(getMatchDataBlock())
3463  .setBufferSize(getBufferSize())
3464  .setStartOffset(getStartOffset())
3465  .replace(true, getPcre2Option(), last_replace_counter);
3466  return *last_replace_counter;
3467  }
3468 
3497  return me.setRegexObject(getRegexObject())
3498  .setSubject(getSubjectPointer())
3499  .setFindAll((getPcre2Option() & PCRE2_SUBSTITUTE_GLOBAL)!=0)
3500  .setMatchContext(getMatchContext())
3501  .setMatchDataBlock(getMatchDataBlock())
3502  .setStartOffset(getStartOffset())
3503  .nreplace(true, getJpcre2Option(), last_replace_counter);
3504  }
3505 
3515  return me.setRegexObject(getRegexObject())
3516  .setSubject(getSubjectPointer())
3517  .setFindAll((getPcre2Option() & PCRE2_SUBSTITUTE_GLOBAL)!=0)
3518  .setMatchContext(getMatchContext())
3519  .setMatchDataBlock(getMatchDataBlock())
3520  .setBufferSize(getBufferSize())
3521  .setStartOffset(getStartOffset())
3522  .replace(true, getPcre2Option(), last_replace_counter);
3523  }
3524  };
3525 
3526 
3541  class Regex {
3542 
3543  private:
3544 
3545  friend class RegexMatch;
3546  friend class RegexReplace;
3547  friend class MatchEvaluator;
3548 
3549  String pat_str;
3550  String const *pat_str_ptr;
3551  Pcre2Code *code;
3552  Uint compile_opts;
3553  Uint jpcre2_compile_opts;
3554  ModifierTable const * modtab;
3555 
3556  CompileContext *ccontext;
3557  std::vector<unsigned char> tabv;
3558 
3559 
3560  void init_vars() {
3561  jpcre2_compile_opts = 0;
3562  compile_opts = 0;
3563  error_number = 0;
3564  error_offset = 0;
3565  code = 0;
3566  pat_str_ptr = &pat_str;
3567  ccontext = 0;
3568  modtab = 0;
3569  }
3570 
3571  void freeRegexMemory(void) {
3572  Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::code_free(code);
3573  code = 0; //we may use it again
3574  }
3575 
3576  void freeCompileContext(){
3577  Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::compile_context_free(ccontext);
3578  ccontext = 0;
3579  }
3580 
3581  void onlyCopy(Regex const &r){
3582  //r.pat_str_ptr may point to other user data
3583  pat_str_ptr = (r.pat_str_ptr == &r.pat_str) ? &pat_str //not r.pat_str
3584  : r.pat_str_ptr; //other user data
3585 
3586  compile_opts = r.compile_opts;
3587  jpcre2_compile_opts = r.jpcre2_compile_opts;
3588  error_number = r.error_number;
3589  error_offset = r.error_offset;
3590  modtab = r.modtab;
3591  }
3592 
3593  void deepCopy(Regex const &r) {
3594  pat_str = r.pat_str; //must not use setPattern() here
3595 
3596  onlyCopy(r);
3597 
3598  //copy tables
3599  tabv = r.tabv;
3600  //copy ccontext if it's not null
3601  freeCompileContext();
3602  ccontext = (r.ccontext) ? Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::compile_context_copy(r.ccontext) : 0;
3603  //if tabv is not empty and ccontext is ok (not null) set the table pointer to ccontext
3604  if(ccontext && !tabv.empty()) Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::set_character_tables(ccontext, &tabv[0]);
3605 
3606  //table pointer must be updated in the compiled code itself, jit memory copy is not available.
3607  //copy is not going to work, we need a recompile.
3608  //as all vars are already copied, we can just call compile()
3609  r.code ? compile() //compile frees previous memory.
3610  : freeRegexMemory();
3611  }
3612 
3613  #if __cplusplus >= 201103L
3614 
3615  void deepMove(Regex& r) {
3616  pat_str = std::move_if_noexcept(r.pat_str);
3617 
3618  onlyCopy(r);
3619 
3620  //steal tables
3621  tabv = std::move_if_noexcept(r.tabv);
3622 
3623  //steal ccontext
3624  freeCompileContext();
3625  ccontext = r.ccontext; r.ccontext = 0; //must set this to 0
3626  if(ccontext && !tabv.empty()) Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::set_character_tables(ccontext, &tabv[0]);
3627 
3628  //steal the code
3629  freeRegexMemory();
3630  code = r.code; r.code = 0; //must set this to 0
3631  }
3632 
3633  #endif
3634 
3635  protected:
3636 
3637  int error_number;
3638  PCRE2_SIZE error_offset;
3639 
3640  public:
3641 
3645  Regex() {
3646  init_vars();
3647  }
3648 
3651  Regex(String const &re) {
3652  init_vars();
3653  compile(re);
3654  }
3655 
3658  Regex(String const *re) {
3659  init_vars();
3660  compile(re);
3661  }
3662 
3666  Regex(String const &re, Modifier const& mod) {
3667  init_vars();
3668  compile(re, mod);
3669  }
3670 
3674  Regex(String const *re, Modifier const& mod) {
3675  init_vars();
3676  compile(re, mod);
3677  }
3678 
3682  Regex(String const &re, Uint po) {
3683  init_vars();
3684  compile(re, po);
3685  }
3686 
3690  Regex(String const *re, Uint po) {
3691  init_vars();
3692  compile(re, po);
3693  }
3694 
3699  Regex(String const &re, Uint po, Uint jo) {
3700  init_vars();
3701  compile(re, po, jo);
3702  }
3703 
3708  Regex(String const *re, Uint po, Uint jo) {
3709  init_vars();
3710  compile(re, po, jo);
3711  }
3712 
3719  Regex(Regex const &r) {
3720  init_vars();
3721  deepCopy(r);
3722  }
3723 
3727  Regex& operator=(Regex const &r) {
3728  if (this == &r) return *this;
3729  deepCopy(r);
3730  return *this;
3731  }
3732 
3733 
3734  #if __cplusplus >= 201103L
3735 
3736 
3744  Regex(Regex&& r) {
3745  init_vars();
3746  deepMove(r);
3747  }
3748 
3758  if (this == &r) return *this;
3759  deepMove(r);
3760  return *this;
3761  }
3762 
3785  explicit operator bool() const {
3786  return (code != 0);
3787  }
3788  #endif
3789 
3815  bool operator!() const {
3816  return (code == 0);
3817  }
3818 
3819  virtual ~Regex() {
3820  freeRegexMemory();
3821  freeCompileContext();
3822  }
3823 
3826  Regex& reset() {
3827  freeRegexMemory();
3828  freeCompileContext();
3829  String().swap(pat_str);
3830  init_vars();
3831  return *this;
3832  }
3833 
3836  Regex& clear() {
3837  freeRegexMemory();
3838  freeCompileContext();
3839  pat_str.clear();
3840  init_vars();
3841  return *this;
3842  }
3843 
3849  error_number = 0;
3850  error_offset = 0;
3851  return *this;
3852  }
3853 
3862  const unsigned char* tables = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::maketables(0); //must pass 0, we are using free() to free the tables.
3863  tabv = std::vector<unsigned char>(tables, tables+1088);
3864  ::free((void*)tables); //must free memory
3865  if(!ccontext)
3866  ccontext = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::compile_context_create(0);
3867  Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::set_character_tables(ccontext, &tabv[0]);
3868  return *this;
3869  }
3870 
3873  Pcre2Code const* getPcre2Code() const{
3874  return code;
3875  }
3876 
3879  String getPattern() const {
3880  return *pat_str_ptr;
3881  }
3882 
3885  String const * getPatternPointer() const {
3886  return pat_str_ptr;
3887  }
3888 
3889 
3902  std::string getModifier() const {
3903  return modtab ? modtab->fromCompileOption(compile_opts, jpcre2_compile_opts)
3904  : MOD::fromCompileOption(compile_opts, jpcre2_compile_opts);
3905  }
3906 
3911  Uint getPcre2Option() const {
3912  return compile_opts;
3913  }
3914 
3919  Uint getJpcre2Option() const {
3920  return jpcre2_compile_opts;
3921  }
3922 
3925  int getErrorNumber() const {
3926  return error_number;
3927  }
3928 
3931  int getErrorOffset() const {
3932  return (int)error_offset;
3933  }
3934 
3937  String getErrorMessage() const {
3938  #if __cplusplus >= 201103L
3939  return select<Char, Map>::getErrorMessage(error_number, error_offset);
3940  #else
3941  return select<Char>::getErrorMessage(error_number, error_offset);
3942  #endif
3943  }
3944 
3954  Uint getNewLine() {
3955  if(!code) return 0;
3956  Uint newline = 0;
3957  int ret = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::pattern_info(code, PCRE2_INFO_NEWLINE, &newline);
3958  if(ret < 0) error_number = ret;
3959  return newline;
3960  }
3961 
3965  return modtab;
3966  }
3967 
3968 
3979  Regex& setNewLine(Uint value){
3980  if(!ccontext)
3981  ccontext = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::compile_context_create(0);
3982  int ret = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::set_newline(ccontext, value);
3983  if(ret < 0) error_number = ret;
3984  return *this;
3985  }
3986 
3990  Regex& setPattern(String const &re) {
3991  pat_str = re;
3992  pat_str_ptr = &pat_str; //must overwrite
3993  return *this;
3994  }
3995 
3999  Regex& setPattern(String const *re) {
4000  if(re) pat_str_ptr = re;
4001  else {
4002  pat_str.clear();
4003  pat_str_ptr = &pat_str;
4004  }
4005  return *this;
4006  }
4007 
4016  compile_opts = 0;
4017  jpcre2_compile_opts = 0;
4018  return changeModifier(x, true);
4019  }
4020 
4025  modtab = mdt;
4026  return *this;
4027  }
4028 
4035  jpcre2_compile_opts = x;
4036  return *this;
4037  }
4038 
4044  Regex& setPcre2Option(Uint x) {
4045  compile_opts = x;
4046  return *this;
4047  }
4048 
4061  Regex& changeModifier(Modifier const& mod, bool x){
4062  modtab ? modtab->toCompileOption(mod, x, &compile_opts, &jpcre2_compile_opts, &error_number, &error_offset)
4063  : MOD::toCompileOption(mod, x, &compile_opts, &jpcre2_compile_opts, &error_number, &error_offset);
4064  return *this;
4065  }
4066 
4073  Regex& changeJpcre2Option(Uint opt, bool x) {
4074  jpcre2_compile_opts = x ? jpcre2_compile_opts | opt : jpcre2_compile_opts & ~opt;
4075  return *this;
4076  }
4077 
4084  Regex& changePcre2Option(Uint opt, bool x) {
4085  compile_opts = x ? compile_opts | opt : compile_opts & ~opt;
4086  return *this;
4087  }
4088 
4096  Regex& addModifier(Modifier const& mod){
4097  return changeModifier(mod, true);
4098  }
4099 
4106  jpcre2_compile_opts |= x;
4107  return *this;
4108  }
4109 
4115  Regex& addPcre2Option(Uint x) {
4116  compile_opts |= x;
4117  return *this;
4118  }
4119 
4125  void compile(void);
4126 
4133  void compile(String const &re, Uint po, Uint jo) {
4134  setPattern(re).setPcre2Option(po).setJpcre2Option(jo);
4135  compile();
4136  }
4137 
4138 
4143  void compile(String const *re, Uint po, Uint jo) {
4144  setPattern(re).setPcre2Option(po).setJpcre2Option(jo);
4145  compile();
4146  }
4147 
4151  void compile(String const &re, Uint po) {
4152  setPattern(re).setPcre2Option(po);
4153  compile();
4154  }
4155 
4159  void compile(String const *re, Uint po) {
4160  setPattern(re).setPcre2Option(po);
4161  compile();
4162  }
4163 
4167  void compile(String const &re, Modifier const& mod) {
4168  setPattern(re).setModifier(mod);
4169  compile();
4170  }
4171 
4175  void compile(String const *re, Modifier const& mod) {
4176  setPattern(re).setModifier(mod);
4177  compile();
4178  }
4179 
4182  void compile(String const &re) {
4183  setPattern(re);
4184  compile();
4185  }
4186 
4189  void compile(String const *re) {
4190  setPattern(re);
4191  compile();
4192  }
4193 
4199  RegexMatch rm(this);
4200  rm.setModifierTable(modtab);
4201  return rm;
4202  }
4203 
4207  return initMatch();
4208  }
4209 
4218  SIZE_T match(String const &s, Modifier const& mod, PCRE2_SIZE start_offset=0) {
4219  return initMatch().setStartOffset(start_offset).setSubject(s).setModifier(mod).match();
4220  }
4221 
4228  SIZE_T match(String const *s, Modifier const& mod, PCRE2_SIZE start_offset=0) {
4229  return initMatch().setStartOffset(start_offset).setSubject(s).setModifier(mod).match();
4230  }
4231 
4238  SIZE_T match(String const &s, PCRE2_SIZE start_offset=0) {
4239  return initMatch().setStartOffset(start_offset).setSubject(s).match();
4240  }
4241 
4248  SIZE_T match(String const *s, PCRE2_SIZE start_offset=0) {
4249  return initMatch().setStartOffset(start_offset).setSubject(s).match();
4250  }
4251 
4256  RegexReplace rr(this);
4257  rr.setModifierTable(modtab);
4258  return rr;
4259  }
4260 
4264  return initReplace();
4265  }
4266 
4276  String replace(String const &mains, String const &repl, Modifier const& mod="", SIZE_T* counter=0) {
4277  return initReplace().setSubject(mains).setReplaceWith(repl).setModifier(mod).setReplaceCounter(counter).replace();
4278  }
4279 
4287  String replace(String *mains, String const &repl, Modifier const& mod="", SIZE_T* counter=0) {
4288  return initReplace().setSubject(mains).setReplaceWith(repl).setModifier(mod).setReplaceCounter(counter).replace();
4289  }
4290 
4299  String replace(String const &mains, String const *repl, Modifier const& mod="", SIZE_T* counter=0) {
4300  return initReplace().setSubject(mains).setReplaceWith(repl).setModifier(mod).setReplaceCounter(counter).replace();
4301  }
4302 
4311  String replace(String *mains, String const *repl, Modifier const& mod="", SIZE_T* counter=0) {
4312  return initReplace().setSubject(mains).setReplaceWith(repl).setModifier(mod).setReplaceCounter(counter).replace();
4313  }
4314 
4323  SIZE_T preplace(String * mains, String const& repl, Modifier const& mod=""){
4324  SIZE_T counter = 0;
4325  if(mains) *mains = initReplace().setSubject(mains).setReplaceWith(repl).setModifier(mod).setReplaceCounter(&counter).replace();
4326  return counter;
4327  }
4328 
4339  SIZE_T preplace(String * mains, String const* repl, Modifier const& mod=""){
4340  SIZE_T counter = 0;
4341  if(mains) *mains = initReplace().setSubject(mains).setReplaceWith(repl).setModifier(mod).setReplaceCounter(&counter).replace();
4342  return counter;
4343  }
4344 
4355  SIZE_T preplace(String const& mains, String const& repl, Modifier const& mod=""){
4356  SIZE_T counter = 0;
4357  initReplace().setSubject(mains).setReplaceWith(repl).setModifier(mod).setReplaceCounter(&counter).replace();
4358  return counter;
4359  }
4360 
4371  SIZE_T preplace(String const& mains, String const* repl, Modifier const& mod=""){
4372  SIZE_T counter = 0;
4373  initReplace().setSubject(mains).setReplaceWith(repl).setModifier(mod).setReplaceCounter(&counter).replace();
4374  return counter;
4375  }
4376  };
4377 
4378  private:
4379  //prevent object instantiation of select class
4380  select();
4381  select(select const &);
4382  #if __cplusplus >= 201103L
4383  select(select&&);
4384  #endif
4385  ~select();
4386 };//struct select
4387 }//jpcre2 namespace
4388 
4389 
4390 inline void jpcre2::ModifierTable::parseModifierTable(std::string& tabjs, VecOpt& tabjv,
4391  std::string& tab_s, VecOpt& tab_v,
4392  std::string const& tabs, VecOpt const& tabv){
4393  SIZE_T n = tabs.length();
4394  JPCRE2_ASSERT(n == tabv.size(), ("ValueError: Could not set Modifier table.\
4395  Modifier character and value tables are not of the same size (" + _tostdstring(n) + " == " + _tostdstring(tabv.size()) + ").").c_str());
4396  tabjs.clear();
4397  tab_s.clear(); tab_s.reserve(n);
4398  tabjv.clear();
4399  tab_v.clear(); tab_v.reserve(n);
4400  for(SIZE_T i=0;i<n;++i){
4401  switch(tabv[i]){
4402  case JIT_COMPILE:
4403  case FIND_ALL: //JPCRE2 options are unique, so it's not necessary to check if it's compile or replace or match.
4404  tabjs.push_back(tabs[i]); tabjv.push_back(tabv[i]);break;
4405  default: tab_s.push_back(tabs[i]); tab_v.push_back(tabv[i]); break;
4406  }
4407  }
4408 }
4409 
4410 
4411 #if __cplusplus >= 201103L
4412 template<typename Char_T, template<typename...> class Map>
4414 #else
4415 template<typename Char_T>
4417 #endif
4418  //Get c_str of pattern
4419  Pcre2Sptr c_pattern = (Pcre2Sptr) pat_str_ptr->c_str();
4420  int err_number = 0;
4421  PCRE2_SIZE err_offset = 0;
4422 
4423  /**************************************************************************
4424  * Compile the regular expression pattern, and handle
4425  * any errors that are detected.
4426  *************************************************************************/
4427 
4428  //first release any previous memory
4429  freeRegexMemory();
4430  code = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::compile( c_pattern, /* the pattern */
4431  PCRE2_ZERO_TERMINATED, /* indicates pattern is zero-terminated */
4432  compile_opts, /* default options */
4433  &err_number, /* for error number */
4434  &err_offset, /* for error offset */
4435  ccontext); /* use compile context */
4436 
4437  if (code == 0) {
4438  /* Compilation failed */
4439  //must not free regex memory, the only function has that right is the destructor
4440  error_number = err_number;
4441  error_offset = err_offset;
4442  return;
4443  } else if ((jpcre2_compile_opts & JIT_COMPILE) != 0) {
4445  int jit_ret = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::jit_compile(code, PCRE2_JIT_COMPLETE);
4446  if(jit_ret < 0) error_number = jit_ret;
4447  }
4448  //everything's OK
4449 }
4450 
4451 
4452 #if __cplusplus >= 201103L
4453 template<typename Char_T, template<typename...> class Map>
4455 #else
4456 template<typename Char_T>
4457 typename jpcre2::select<Char_T>::String jpcre2::select<Char_T>::MatchEvaluator::replace(bool do_match, Uint replace_opts, SIZE_T * counter) {
4458 #endif
4459  if(counter) *counter = 0;
4460 
4461  replace_opts |= PCRE2_SUBSTITUTE_OVERFLOW_LENGTH;
4462  replace_opts &= ~PCRE2_SUBSTITUTE_GLOBAL;
4463  Regex const * re = RegexMatch::getRegexObject();
4464  // If re or re->code is null, return the subject string unmodified.
4465  if (!re || re->code == 0)
4466  return RegexMatch::getSubject();
4467 
4468  Pcre2Sptr r_subject_ptr = (Pcre2Sptr) RegexMatch::getSubjectPointer()->c_str();
4469  //~ SIZE_T totlen = RegexMatch::getSubjectPointer()->length();
4470 
4471  if(do_match) match();
4472  SIZE_T mcount = vec_soff.size();
4473  // if mcount is 0, return the subject string. (there's no need to worry about re)
4474  if(!mcount) return RegexMatch::getSubject();
4475  SIZE_T current_offset = 0; //needs to be zero, not start_offset, because it's from where unmatched parts will be copied.
4476  String res, tmp;
4477 
4478  //A check, this check is not fullproof.
4479  SIZE_T last = vec_eoff.size();
4480  last = (last>0)?last-1:0;
4481  JPCRE2_ASSERT(vec_eoff[last] <= RegexMatch::getSubject().size(), "ValueError: subject string is not of the required size, may be it's changed!!!\
4482  If you are using esisting match data, try a new match.");
4483 
4484  //loop through the matches
4485  for(SIZE_T i=0;i<mcount;++i){
4486  //first copy the unmatched part.
4487  //Matches that use \K to end before they start are not supported.
4488  if(vec_soff[i] < current_offset || vec_eoff[i] < vec_soff[i]){
4489  RegexMatch::error_number = PCRE2_ERROR_BADSUBSPATTERN;
4490  return RegexMatch::getSubject();
4491  } else {
4492  //~ res += RegexMatch::getSubject().substr(current_offset, vec_soff[i]-current_offset);
4493  res += String(r_subject_ptr+current_offset, r_subject_ptr+vec_soff[i]);
4494  }
4495  //now process the matched part
4496  switch(callbackn){
4497  case 0: tmp = callback0((void*)0, (void*)0, (void*)0); break;
4498  case 1: JPCRE2_VECTOR_DATA_ASSERT(vec_num.size() == mcount, "VecNum");
4499  tmp = callback1(vec_num[i], (void*)0, (void*)0); break;
4500  case 2: JPCRE2_VECTOR_DATA_ASSERT(vec_nas.size() == mcount, "VecNas");
4501  tmp = callback2((void*)0, vec_nas[i], (void*)0); break;
4502  case 3: JPCRE2_VECTOR_DATA_ASSERT(vec_num.size() == mcount && vec_nas.size() == mcount, "VecNum or VecNas");
4503  tmp = callback3(vec_num[i], vec_nas[i], (void*)0); break;
4504  case 4: JPCRE2_VECTOR_DATA_ASSERT(vec_ntn.size() == mcount, "VecNtn");
4505  tmp = callback4((void*)0, (void*)0, vec_ntn[i]); break;
4506  case 5: JPCRE2_VECTOR_DATA_ASSERT(vec_num.size() == mcount && vec_ntn.size() == mcount, "VecNum or VecNtn");
4507  tmp = callback5(vec_num[i], (void*)0, vec_ntn[i]); break;
4508  case 6: JPCRE2_VECTOR_DATA_ASSERT(vec_nas.size() == mcount && vec_ntn.size() == mcount, "VecNas or VecNtn");
4509  tmp = callback6((void*)0, vec_nas[i], vec_ntn[i]); break;
4510  case 7: JPCRE2_VECTOR_DATA_ASSERT(vec_num.size() == mcount && vec_nas.size() == mcount && vec_ntn.size() == mcount, "VecNum\n or VecNas or VecNtn");
4511  tmp = callback7(vec_num[i], vec_nas[i], vec_ntn[i]); break;
4512  default: JPCRE2_ASSERT(2 == 1, "Invalid callbackn. Please file a bug report (must include the line number from below)."); break;
4513  }
4514  //reset the current offset
4515  current_offset = vec_eoff[i];
4516 
4517  //second part
4519  //~ Pcre2Sptr subject = (Pcre2Sptr) RegexMatch::getSubjectPointer()->c_str();
4520  //substr(vec_soff[i], vec_eoff[i] - vec_soff[i]).c_str();//->substr(vec_soff[i], vec_eoff[i]-vec_soff[i]);
4521  Pcre2Sptr subject = r_subject_ptr + vec_soff[i];
4522  PCRE2_SIZE subject_length = vec_eoff[i] - vec_soff[i];
4523 
4525  Pcre2Sptr replace = (Pcre2Sptr) tmp.c_str();
4526  PCRE2_SIZE replace_length = tmp.length();
4527  bool retry = true;
4528  int ret = 0;
4529  PCRE2_SIZE outlengthptr = 0;
4530  Pcre2Uchar* output_buffer = new Pcre2Uchar[outlengthptr + 1]();
4531 
4532  while (true) {
4533  ret = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::substitute(
4534  re->code, /*Points to the compiled pattern*/
4535  subject, /*Points to the subject string*/
4536  subject_length, /*Length of the subject string*/
4537  0, /*Offset in the subject at which to start matching*/ //must be zero
4538  replace_opts, /*Option bits*/
4539  RegexMatch::mdata, /*Points to a match data block, or is NULL*/
4540  RegexMatch::mcontext, /*Points to a match context, or is NULL*/
4541  replace, /*Points to the replacement string*/
4542  replace_length, /*Length of the replacement string*/
4543  output_buffer, /*Points to the output buffer*/
4544  &outlengthptr /*Points to the length of the output buffer*/
4545  );
4546 
4547  if (ret < 0) {
4548  //Handle errors
4549  if ((replace_opts & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) != 0
4550  && ret == (int) PCRE2_ERROR_NOMEMORY && retry) {
4551  retry = false;
4554  delete[] output_buffer;
4555  output_buffer = new Pcre2Uchar[outlengthptr + 1]();
4556  // Go and try to perform the substitute again
4557  continue;
4558  } else {
4559  RegexMatch::error_number = ret;
4560  delete[] output_buffer;
4561  return RegexMatch::getSubject();
4562  }
4563  }
4564  //If everything's ok exit the loop
4565  break;
4566  }
4567  res += String((Char*) output_buffer,(Char*) (output_buffer + outlengthptr) );
4568  delete[] output_buffer;
4569  if(counter) *counter += ret;
4570  //if FIND_ALL is not set, single match will be performed
4571  if((RegexMatch::getJpcre2Option() & FIND_ALL) == 0) break;
4572  }
4573  //All matched parts have been dealt with.
4574  //now copy rest of the string from current_offset
4575  res += RegexMatch::getSubject().substr(current_offset, String::npos);
4576  return res;
4577 }
4578 
4579 
4580 #if __cplusplus >= 201103L
4581 template<typename Char_T, template<typename...> class Map>
4583 #else
4584 template<typename Char_T>
4586 #endif
4587  if(counter) *counter = 0;
4588  if(do_match) match();
4589  SIZE_T mcount = vec_soff.size();
4590  // if mcount is 0, return the subject string. (there's no need to worry about re)
4591  if(!mcount) return RegexMatch::getSubject();
4592  SIZE_T current_offset = 0; //no need for worrying about start offset, it's handled by match and we get valid offsets out of it.
4593  String res;
4594 
4595  //A check, this check is not fullproof
4596  SIZE_T last = vec_eoff.size();
4597  last = (last>0)?last-1:0;
4598  JPCRE2_ASSERT(vec_eoff[last] <= RegexMatch::getSubject().size(), "ValueError: subject string is not of the required size, may be it's changed!!!\
4599  If you are using esisting match data, try a new match.");
4600 
4601  //loop through the matches
4602  for(SIZE_T i=0;i<mcount;++i){
4603  //first copy the unmatched part.
4604  //Matches that use \K to end before they start are not supported.
4605  if(vec_soff[i] < current_offset){
4606  RegexMatch::error_number = PCRE2_ERROR_BADSUBSPATTERN;
4607  return RegexMatch::getSubject();
4608  } else {
4609  res += RegexMatch::getSubject().substr(current_offset, vec_soff[i]-current_offset);
4610  }
4611  //now process the matched part
4612  switch(callbackn){
4613  case 0: res += callback0((void*)0, (void*)0, (void*)0); break;
4614  case 1: JPCRE2_VECTOR_DATA_ASSERT(vec_num.size() == mcount, "VecNum");
4615  res += callback1(vec_num[i], (void*)0, (void*)0); break;
4616  case 2: JPCRE2_VECTOR_DATA_ASSERT(vec_nas.size() == mcount, "VecNas");
4617  res += callback2((void*)0, vec_nas[i], (void*)0); break;
4618  case 3: JPCRE2_VECTOR_DATA_ASSERT(vec_num.size() == mcount && vec_nas.size() == mcount, "VecNum or VecNas");
4619  res += callback3(vec_num[i], vec_nas[i], (void*)0); break;
4620  case 4: JPCRE2_VECTOR_DATA_ASSERT(vec_ntn.size() == mcount, "VecNtn");
4621  res += callback4((void*)0, (void*)0, vec_ntn[i]); break;
4622  case 5: JPCRE2_VECTOR_DATA_ASSERT(vec_num.size() == mcount && vec_ntn.size() == mcount, "VecNum or VecNtn");
4623  res += callback5(vec_num[i], (void*)0, vec_ntn[i]); break;
4624  case 6: JPCRE2_VECTOR_DATA_ASSERT(vec_nas.size() == mcount && vec_ntn.size() == mcount, "VecNas or VecNtn");
4625  res += callback6((void*)0, vec_nas[i], vec_ntn[i]); break;
4626  case 7: JPCRE2_VECTOR_DATA_ASSERT(vec_num.size() == mcount && vec_nas.size() == mcount && vec_ntn.size() == mcount, "VecNum\n or VecNas or VecNtn");
4627  res += callback7(vec_num[i], vec_nas[i], vec_ntn[i]); break;
4628  default: JPCRE2_ASSERT(2 == 1, "Invalid callbackn. Please file a bug report (must include the line number from below)."); break;
4629  }
4630  //reset the current offset
4631  current_offset = vec_eoff[i];
4632  if(counter) *counter += 1;
4633  //if FIND_ALL is not set, single match will be performd
4634  if((RegexMatch::getJpcre2Option() & FIND_ALL) == 0) break;
4635  }
4636  //All matched parts have been dealt with.
4637  //now copy rest of the string from current_offset
4638  res += RegexMatch::getSubject().substr(current_offset, String::npos);
4639  return res;
4640 }
4641 
4642 
4643 #if __cplusplus >= 201103L
4644 template<typename Char_T, template<typename...> class Map>
4646 #else
4647 template<typename Char_T>
4649 #endif
4650  *last_replace_counter = 0;
4651 
4652  // If re or re->code is null, return the subject string unmodified.
4653  if (!re || re->code == 0)
4654  return *r_subject_ptr;
4655 
4656  Pcre2Sptr subject = (Pcre2Sptr) r_subject_ptr->c_str();
4657  PCRE2_SIZE subject_length = r_subject_ptr->length();
4658  Pcre2Sptr replace = (Pcre2Sptr) r_replw_ptr->c_str();
4659  PCRE2_SIZE replace_length = r_replw_ptr->length();
4660  PCRE2_SIZE outlengthptr = (PCRE2_SIZE) buffer_size;
4661  bool retry = true;
4662  int ret = 0;
4663  Pcre2Uchar* output_buffer = new Pcre2Uchar[outlengthptr + 1]();
4664 
4665  while (true) {
4666  ret = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::substitute(
4667  re->code, /*Points to the compiled pattern*/
4668  subject, /*Points to the subject string*/
4669  subject_length, /*Length of the subject string*/
4670  _start_offset, /*Offset in the subject at which to start matching*/
4671  replace_opts, /*Option bits*/
4672  mdata, /*Points to a match data block, or is NULL*/
4673  mcontext, /*Points to a match context, or is NULL*/
4674  replace, /*Points to the replacement string*/
4675  replace_length, /*Length of the replacement string*/
4676  output_buffer, /*Points to the output buffer*/
4677  &outlengthptr /*Points to the length of the output buffer*/
4678  );
4679 
4680  if (ret < 0) {
4681  //Handle errors
4682  if ((replace_opts & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) != 0
4683  && ret == (int) PCRE2_ERROR_NOMEMORY && retry) {
4684  retry = false;
4687  delete[] output_buffer;
4688  output_buffer = new Pcre2Uchar[outlengthptr + 1]();
4689  // Go and try to perform the substitute again
4690  continue;
4691  } else {
4692  error_number = ret;
4693  delete[] output_buffer;
4694  return *r_subject_ptr;
4695  }
4696  }
4697  //If everything's ok exit the loop
4698  break;
4699  }
4700  *last_replace_counter += ret;
4701  String result = String((Char*) output_buffer,(Char*) (output_buffer + outlengthptr) );
4702  delete[] output_buffer;
4703  return result;
4704 }
4705 
4706 
4707 #if __cplusplus >= 201103L
4708 template<typename Char_T, template<typename...> class Map>
4709 bool jpcre2::select<Char_T, Map>::RegexMatch::getNumberedSubstrings(int rc, Pcre2Sptr subject, PCRE2_SIZE* ovector) {
4710 #else
4711 template<typename Char_T>
4712 bool jpcre2::select<Char_T>::RegexMatch::getNumberedSubstrings(int rc, Pcre2Sptr subject, PCRE2_SIZE* ovector) {
4713 #endif
4714  NumSub num_sub;
4715  num_sub.reserve(rc); //we know exactly how many elements it will have.
4716  for (int i = 0; i < rc; i++)
4717  num_sub.push_back(String((Char*)(subject + ovector[2*i]), ovector[2*i+1] - ovector[2*i]));
4718  vec_num->push_back(num_sub); //this function shouldn't be called if this vector is null
4719  return true;
4720 }
4721 
4722 
4723 #if __cplusplus >= 201103L
4724 template<typename Char_T, template<typename...> class Map>
4725 bool jpcre2::select<Char_T, Map>::RegexMatch::getNamedSubstrings(int namecount, int name_entry_size,
4726  Pcre2Sptr name_table,
4727  Pcre2Sptr subject, PCRE2_SIZE* ovector ) {
4728 #else
4729 template<typename Char_T>
4730 bool jpcre2::select<Char_T>::RegexMatch::getNamedSubstrings(int namecount, int name_entry_size,
4731  Pcre2Sptr name_table,
4732  Pcre2Sptr subject, PCRE2_SIZE* ovector ) {
4733 #endif
4734  Pcre2Sptr tabptr = name_table;
4735  String key;
4736  MapNas map_nas;
4737  MapNtN map_ntn;
4738  for (int i = 0; i < namecount; i++) {
4739  int n;
4740  if(sizeof( Char_T ) * CHAR_BIT == 8){
4741  n = (int)((tabptr[0] << 8) | tabptr[1]);
4742  key = toString((Char*) (tabptr + 2));
4743  }
4744  else{
4745  n = (int)tabptr[0];
4746  key = toString((Char*) (tabptr + 1));
4747  }
4748  //Use of tabptr is finished for this iteration, let's increment it now.
4749  tabptr += name_entry_size;
4750  String value((Char*)(subject + ovector[2*n]), ovector[2*n+1] - ovector[2*n]); //n, not i.
4751  if(vec_nas) map_nas[key] = value;
4752  if(vec_ntn) map_ntn[key] = n;
4753  }
4754  //push the maps into vectors:
4755  if(vec_nas) vec_nas->push_back(map_nas);
4756  if(vec_ntn) vec_ntn->push_back(map_ntn);
4757  return true;
4758 }
4759 
4760 
4761 #if __cplusplus >= 201103L
4762 template<typename Char_T, template<typename...> class Map>
4764 #else
4765 template<typename Char_T>
4767 #endif
4768 
4769  // If re or re->code is null, return 0 as the match count
4770  if (!re || re->code == 0)
4771  return 0;
4772 
4773  Pcre2Sptr subject = (Pcre2Sptr) m_subject_ptr->c_str();
4774  Pcre2Sptr name_table = 0;
4775  int crlf_is_newline = 0;
4776  int namecount = 0;
4777  int name_entry_size = 0;
4778  int rc = 0;
4779  int utf = 0;
4780  SIZE_T count = 0;
4781  Uint option_bits;
4782  Uint newline = 0;
4783  PCRE2_SIZE *ovector = 0;
4784  SIZE_T subject_length = 0;
4785  MatchData *match_data = 0;
4786  subject_length = m_subject_ptr->length();
4787  bool mdc = false; //mdata created.
4788 
4789 
4790  if (vec_num) vec_num->clear();
4791  if (vec_nas) vec_nas->clear();
4792  if (vec_ntn) vec_ntn->clear();
4793  if(vec_soff) vec_soff->clear();
4794  if(vec_eoff) vec_eoff->clear();
4795 
4796 
4797  /* Using this function ensures that the block is exactly the right size for
4798  the number of capturing parentheses in the pattern. */
4799  if(mdata) match_data = mdata;
4800  else {
4801  match_data = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::match_data_create_from_pattern(re->code, 0);
4802  mdc = true;
4803  }
4804 
4805  rc = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::match( re->code, /* the compiled pattern */
4806  subject, /* the subject string */
4807  subject_length, /* the length of the subject */
4808  _start_offset, /* start at offset 'start_offset' in the subject */
4809  match_opts, /* default options */
4810  match_data, /* block for storing the result */
4811  mcontext); /* use default match context */
4812 
4813  /* Matching failed: handle error cases */
4814 
4815  if (rc < 0) {
4816  if(mdc)
4817  Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::match_data_free(match_data); /* Release memory used for the match */
4818  //must not free code. This function has no right to modify regex
4819  switch (rc) {
4820  case PCRE2_ERROR_NOMATCH:
4821  return count;
4822  /*
4823  Handle other special cases if you like
4824  */
4825  default:;
4826  }
4827  error_number = rc;
4828  return count;
4829  }
4830 
4831  ++count; //Increment the counter
4832  /* Match succeded. Get a pointer to the output vector, where string offsets are
4833  stored. */
4834  ovector = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::get_ovector_pointer(match_data);
4835 
4836  /************************************************************************//*
4837  * We have found the first match within the subject string. If the output *
4838  * vector wasn't big enough, say so. Then output any substrings that were *
4839  * captured. *
4840  *************************************************************************/
4841 
4842  /* The output vector wasn't big enough. This should not happen, because we used
4843  pcre2_match_data_create_from_pattern() above. */
4844 
4845  if (rc == 0) {
4846  //ovector was not big enough for all the captured substrings;
4847  error_number = (int)ERROR::INSUFFICIENT_OVECTOR;
4848  rc = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::get_ovector_count(match_data);
4849  }
4850  //match succeeded at offset ovector[0]
4851  if(vec_soff) vec_soff->push_back(ovector[0]);
4852  if(vec_eoff) vec_eoff->push_back(ovector[1]);
4853 
4854  // Get numbered substrings if vec_num isn't null
4855  if (vec_num) { //must do null check
4856  if(!getNumberedSubstrings(rc, subject, ovector))
4857  return count;
4858  }
4859 
4860  //get named substrings if either vec_nas or vec_ntn is given.
4861  if (vec_nas || vec_ntn) {
4862  /* See if there are any named substrings, and if so, show them by name. First
4863  we have to extract the count of named parentheses from the pattern. */
4864 
4865  (void) Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::pattern_info( re->code, /* the compiled pattern */
4866  PCRE2_INFO_NAMECOUNT, /* get the number of named substrings */
4867  &namecount); /* where to put the answer */
4868 
4869  if (namecount <= 0); /*No named substrings*/
4870 
4871  else {
4872  /* Before we can access the substrings, we must extract the table for
4873  translating names to numbers, and the size of each entry in the table. */
4874 
4875  (void) Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::pattern_info( re->code, /* the compiled pattern */
4876  PCRE2_INFO_NAMETABLE, /* address of the table */
4877  &name_table); /* where to put the answer */
4878 
4879  (void) Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::pattern_info( re->code, /* the compiled pattern */
4880  PCRE2_INFO_NAMEENTRYSIZE, /* size of each entry in the table */
4881  &name_entry_size); /* where to put the answer */
4882 
4883  /* Now we can scan the table and, for each entry, print the number, the name,
4884  and the substring itself. In the 8-bit library the number is held in two
4885  bytes, most significant first. */
4886 
4887 
4888  // Get named substrings if vec_nas isn't null.
4889  // Get name to number map if vec_ntn isn't null.
4890  }
4891  //the following must be outside the above if-else
4892  if(!getNamedSubstrings(namecount, name_entry_size, name_table, subject, ovector))
4893  return count;
4894  }
4895 
4896  /***********************************************************************//*
4897  * If the "g" modifier was given, we want to continue *
4898  * to search for additional matches in the subject string, in a similar *
4899  * way to the /g option in Perl. This turns out to be trickier than you *
4900  * might think because of the possibility of matching an empty string. *
4901  * What happens is as follows: *
4902  * *
4903  * If the previous match was NOT for an empty string, we can just start *
4904  * the next match at the end of the previous one. *
4905  * *
4906  * If the previous match WAS for an empty string, we can't do that, as it *
4907  * would lead to an infinite loop. Instead, a call of pcre2_match() is *
4908  * made with the PCRE2_NOTEMPTY_ATSTART and PCRE2_ANCHORED flags set. The *
4909  * first of these tells PCRE2 that an empty string at the start of the *
4910  * subject is not a valid match; other possibilities must be tried. The *
4911  * second flag restricts PCRE2 to one match attempt at the initial string *
4912  * position. If this match succeeds, an alternative to the empty string *
4913  * match has been found, and we can print it and proceed round the loop, *
4914  * advancing by the length of whatever was found. If this match does not *
4915  * succeed, we still stay in the loop, advancing by just one character. *
4916  * In UTF-8 mode, which can be set by (*UTF) in the pattern, this may be *
4917  * more than one byte. *
4918  * *
4919  * However, there is a complication concerned with newlines. When the *
4920  * newline convention is such that CRLF is a valid newline, we must *
4921  * advance by two characters rather than one. The newline convention can *
4922  * be set in the regex by (*CR), etc.; if not, we must find the default. *
4923  *************************************************************************/
4924 
4925  if ((jpcre2_match_opts & FIND_ALL) == 0) {
4926  if(mdc)
4927  Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::match_data_free(match_data); /* Release the memory that was used */
4928  // Must not free code. This function has no right to modify regex.
4929  return count; /* Exit the program. */
4930  }
4931 
4932  /* Before running the loop, check for UTF-8 and whether CRLF is a valid newline
4933  sequence. First, find the options with which the regex was compiled and extract
4934  the UTF state. */
4935 
4936  (void) Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::pattern_info(re->code, PCRE2_INFO_ALLOPTIONS, &option_bits);
4937  utf = ((option_bits & PCRE2_UTF) != 0);
4938 
4939  /* Now find the newline convention and see whether CRLF is a valid newline
4940  sequence. */
4941 
4942  (void) Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::pattern_info(re->code, PCRE2_INFO_NEWLINE, &newline);
4943  crlf_is_newline = newline == PCRE2_NEWLINE_ANY
4944  || newline == PCRE2_NEWLINE_CRLF
4945  || newline == PCRE2_NEWLINE_ANYCRLF;
4946 
4949  for (;;) {
4950 
4951  Uint options = match_opts; /* Normally no options */
4952  PCRE2_SIZE start_offset = ovector[1]; /* Start at end of previous match */
4953 
4954  /* If the previous match was for an empty string, we are finished if we are
4955  at the end of the subject. Otherwise, arrange to run another match at the
4956  same point to see if a non-empty match can be found. */
4957 
4958  if (ovector[0] == ovector[1]) {
4959  if (ovector[0] == subject_length)
4960  break;
4961  options |= PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
4962  }
4963 
4965 
4966  rc = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::match( re->code, /* the compiled pattern */
4967  subject, /* the subject string */
4968  subject_length, /* the length of the subject */
4969  start_offset, /* starting offset in the subject */
4970  options, /* options */
4971  match_data, /* block for storing the result */
4972  mcontext); /* use match context */
4973 
4974  /* This time, a result of NOMATCH isn't an error. If the value in "options"
4975  is zero, it just means we have found all possible matches, so the loop ends.
4976  Otherwise, it means we have failed to find a non-empty-string match at a
4977  point where there was a previous empty-string match. In this case, we do what
4978  Perl does: advance the matching position by one character, and continue. We
4979  do this by setting the "end of previous match" offset, because that is picked
4980  up at the top of the loop as the point at which to start again.
4981 
4982  There are two complications: (a) When CRLF is a valid newline sequence, and
4983  the current position is just before it, advance by an extra byte. (b)
4984  Otherwise we must ensure that we skip an entire UTF character if we are in
4985  UTF mode. */
4986 
4987  if (rc == PCRE2_ERROR_NOMATCH) {
4988  if (options == 0)
4989  break; /* All matches found */
4990  ovector[1] = start_offset + 1; /* Advance one code unit */
4991  if (crlf_is_newline && /* If CRLF is newline & */
4992  start_offset < subject_length - 1 && /* we are at CRLF, */
4993  subject[start_offset] == '\r' && subject[start_offset + 1] == '\n')
4994  ovector[1] += 1; /* Advance by one more. */
4995  else if (utf) { /* advance a whole UTF (8 or 16), for UTF-32, it's not needed */
4996  while (ovector[1] < subject_length) {
4997  if(sizeof( Char_T ) * CHAR_BIT == 8 && (subject[ovector[1]] & 0xc0) != 0x80) break;
4998  else if(sizeof( Char_T ) * CHAR_BIT == 16 && (subject[ovector[1]] & 0xfc00) != 0xdc00) break;
4999  else if(sizeof( Char_T ) * CHAR_BIT == 32) break; //must be else if
5000  ovector[1] += 1;
5001  }
5002  }
5003  continue; /* Go round the loop again */
5004  }
5005 
5006  /* Other matching errors are not recoverable. */
5007 
5008  if (rc < 0) {
5009  if(mdc)
5010  Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::match_data_free(match_data);
5011  // Must not free code. This function has no right to modify regex.
5012  error_number = rc;
5013  return count;
5014  }
5015 
5016  /* match succeeded */
5017  ++count; //Increment the counter
5018 
5019  if (rc == 0) {
5020  /* The match succeeded, but the output vector wasn't big enough. This
5021  should not happen. */
5022  error_number = (int)ERROR::INSUFFICIENT_OVECTOR;
5023  rc = Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::get_ovector_count(match_data);
5024  }
5025 
5026  //match succeded at ovector[0]
5027  if(vec_soff) vec_soff->push_back(ovector[0]);
5028  if(vec_eoff) vec_eoff->push_back(ovector[1]);
5029 
5030  /* As before, get substrings stored in the output vector by number, and then
5031  also any named substrings. */
5032 
5033  // Get numbered substrings if vec_num isn't null
5034  if (vec_num) { //must do null check
5035  if(!getNumberedSubstrings(rc, subject, ovector))
5036  return count;
5037  }
5038 
5039  if (vec_nas || vec_ntn) {
5040  //must call this whether we have named substrings or not:
5041  if(!getNamedSubstrings(namecount, name_entry_size, name_table, subject, ovector))
5042  return count;
5043  }
5044  } /* End of loop to find second and subsequent matches */
5045 
5046  if(mdc)
5047  Pcre2Func<sizeof( Char_T ) * CHAR_BIT>::match_data_free(match_data);
5048  // Must not free code. This function has no right to modify regex.
5049  return count;
5050 }
5051 
5052 #undef JPCRE2_VECTOR_DATA_ASSERT
5053 #undef JPCRE2_UNUSED
5054 
5055 //some macro documentation for doxygen
5056 
5057 #ifdef __DOXYGEN__
5058 
5059 
5060 #ifndef JPCRE2_USE_FUNCTION_POINTER_CALLBACK
5061 #define JPCRE2_USE_FUNCTION_POINTER_CALLBACK
5062 #endif
5063 
5064 #ifndef JPCRE2_NDEBUG
5065 #define JPCRE2_NDEBUG
5066 #endif
5067 
5068 
5079 
5080 
5087 
5088 
5097 
5098 #endif
5099 
5100 
5101 #endif
ModifierTable & setReplaceModifierTable(std::string const &tabs, const Uint *tabvp)
Set modifier table for replace.
Definition: jpcre2.hpp:1074
SIZE_T preplace(String const &mains, String const &repl, Modifier const &mod="")
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4355
virtual String const * getSubjectPointer() const
Get pointer to subject string.
Definition: jpcre2.hpp:1591
void compile(void)
Compile pattern using info from class variables.
Definition: jpcre2.hpp:4413
MatchEvaluator(typename MatchEvaluatorCallback< void *, MapNas const &, MapNtN const &>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2347
Modifier(std::string const &x)
Constructor that takes a std::string.
Definition: jpcre2.hpp:634
virtual SIZE_T match(void)
Perform match operation using info from class variables and return the match count and store the resu...
Definition: jpcre2.hpp:4763
MatchEvaluator & setCallback(typename MatchEvaluatorCallback< void *, MapNas const &, void *>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2534
VecNtN VecNtn
Allow spelling mistake of VecNtN as VecNtn.
Definition: jpcre2.hpp:1268
std::string fromReplaceOption(Uint po, Uint jo) const
Take replace related option value and convert to modifier string.
Definition: jpcre2.hpp:1007
char const * c_str() const
Returns the c_str() of modifier string.
Definition: jpcre2.hpp:646
Regex()
Default Constructor.
Definition: jpcre2.hpp:3645
MatchEvaluator(typename MatchEvaluatorCallback< NumSub const &, void *, void *>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2296
Modifier()
Default constructor.
Definition: jpcre2.hpp:630
SIZE_T match(void)
Perform match and return the match count.
Definition: jpcre2.hpp:2810
MatchEvaluator(typename MatchEvaluatorCallback< void *, void *, void *>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2286
void toCompileOption(Modifier const &mod, bool x, Uint *po, Uint *jo, int *en, SIZE_T *eo) const
Modifier parser for compile related options.
Definition: jpcre2.hpp:991
MatchEvaluator & setCallback(typename MatchEvaluatorCallback< NumSub const &, MapNas const &, void *>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2460
virtual RegexMatch & setJpcre2Option(Uint x)
Set JPCRE2 option for match (resets all)
Definition: jpcre2.hpp:1801
static String fill(NumSub const &num, MapNas const &nas, MapNtn const &ntn)
Callback function for populating match vectors that does not modify the subject string.
Definition: jpcre2.hpp:2037
MatchEvaluator & changeJpcre2Option(Uint opt, bool x)
Call RegexMatch::changeJpcre2Option(Uint opt, bool x).
Definition: jpcre2.hpp:2767
void compile(String const &re, Uint po, Uint jo)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4133
Regex & setJpcre2Option(Uint x)
Set JPCRE2 option for compile (overwrites existing option)
Definition: jpcre2.hpp:4034
MatchEvaluator(typename MatchEvaluatorCallback< NumSub const &, MapNas const &, void *>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2306
std::string str() const
Returns the modifier string.
Definition: jpcre2.hpp:642
static String getPcre2ErrorMessage(int err_num)
Retruns error message from PCRE2 error number.
Definition: jpcre2.hpp:1323
PCRE2_SIZE getBufferSize()
Get the initial buffer size that is being used by internal function pcre2_substitute.
Definition: jpcre2.hpp:2750
static String toString(Char a)
Converts a Char_T to jpcre2::select::String.
Definition: jpcre2.hpp:1289
std::vector< MapNas > VecNas
Vector of matches with named substrings.
Definition: jpcre2.hpp:1264
String replace(String *mains, String const &repl, Modifier const &mod="", SIZE_T *counter=0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4287
SIZE_T match(String const &s, PCRE2_SIZE start_offset=0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4238
static void jassert(bool cond, const char *msg, const char *f, size_t line)
JPCRE2 assert function.
Definition: jpcre2.hpp:167
Uint getJpcre2Option() const
Get JPCRE2 option.
Definition: jpcre2.hpp:3919
PCRE2_SIZE getStartOffset() const
Get start offset.
Definition: jpcre2.hpp:3135
const char operator[](SIZE_T i) const
operator[] overload to access character by index.
Definition: jpcre2.hpp:655
virtual int getErrorOffset() const
Returns the last error offset.
Definition: jpcre2.hpp:1566
virtual String getErrorMessage() const
Returns the last error message.
Definition: jpcre2.hpp:1572
RegexReplace(Regex const *r)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2976
ModifierTable & setCompileModifierTable(std::string const &tabs, const Uint *tabvp)
Set modifier table for compile.
Definition: jpcre2.hpp:1114
MatchEvaluator & addJpcre2Option(Uint x)
Call RegexMatch::addJpcre2Option(Uint x).
Definition: jpcre2.hpp:2792
MatchEvaluator & setBufferSize(PCRE2_SIZE x)
Set the buffer size that will be used by pcre2_substitute (replace()).
Definition: jpcre2.hpp:2743
std::string fromMatchOption(Uint po, Uint jo) const
Take match related option value and convert to modifier string.
Definition: jpcre2.hpp:999
SIZE_T preplace(String *mains, String const &repl, Modifier const &mod="")
Perl compatible replace method.
Definition: jpcre2.hpp:4323
virtual String getSubject() const
Get subject string (by value).
Definition: jpcre2.hpp:1583
virtual PCRE2_SIZE getStartOffset() const
Get offset from where match will start in the subject.
Definition: jpcre2.hpp:1640
static String toString(Pcre2Uchar *a)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:1316
virtual RegexMatch & setStartOffset(PCRE2_SIZE offset)
Set offset from where match starts.
Definition: jpcre2.hpp:1837
SIZE_T preplace(String const &mains, String const *repl, Modifier const &mod="")
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4371
This class contains a typedef of a function pointer or a templated function wrapper (std::function) t...
Definition: jpcre2.hpp:1990
ModifierTable()
Default constructor that creates an empty modifier table.
Definition: jpcre2.hpp:872
int getErrorNumber() const
Returns the last error number.
Definition: jpcre2.hpp:3061
String replace(String const &mains, String const *repl, Modifier const &mod="", SIZE_T *counter=0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4299
RegexReplace & setStartOffset(PCRE2_SIZE start_offset)
Set start offset.
Definition: jpcre2.hpp:3302
RegexReplace getReplaceObject()
Synonym for initReplace()
Definition: jpcre2.hpp:4263
virtual RegexMatch & operator=(RegexMatch &&rm)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:1513
ModifierTable & clear()
Clear the modifier tables to their initial (empty) state.
Definition: jpcre2.hpp:955
Class to take a std::string modifier value with null safety.
Definition: jpcre2.hpp:625
Regex & addJpcre2Option(Uint x)
Add option to existing JPCRE2 options for compile.
Definition: jpcre2.hpp:4105
SIZE_T preplace(void)
Perl compatible replace method.
Definition: jpcre2.hpp:3442
std::string getModifier() const
Calculate modifier string from PCRE2 and JPCRE2 options and return it.
Definition: jpcre2.hpp:3122
SIZE_T preplace(MatchEvaluator me)
Perl compatible replace method with match evaluator.
Definition: jpcre2.hpp:3457
Regex & clear()
Clear all class variables to its default (initial) state (some memory may retain for further use)...
Definition: jpcre2.hpp:3836
int getErrorNumber() const
Returns the last error number.
Definition: jpcre2.hpp:3925
static const char NAME[]
Name of the project.
Definition: jpcre2.hpp:111
String const * getSubjectPointer() const
Get pointer to subject string.
Definition: jpcre2.hpp:3103
void compile(String const *re)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4189
virtual RegexMatch & setNamedSubstringVector(VecNas *v)
Set a pointer to the named substring vector.
Definition: jpcre2.hpp:1712
RegexReplace & setJpcre2Option(Uint x)
Set JPCRE2 option for replace (overwrite existing option)
Definition: jpcre2.hpp:3313
MatchEvaluator & resetErrors()
Call RegexMatch::resetErrors().
Definition: jpcre2.hpp:2637
ModifierTable & clearMatchModifierTable()
Clear the match modifier table to its initial (empty) state.
Definition: jpcre2.hpp:922
SIZE_T match(String const *s, Modifier const &mod, PCRE2_SIZE start_offset=0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4228
virtual RegexMatch & setNumberedSubstringVector(VecNum *v)
Set a pointer to the numbered substring vector.
Definition: jpcre2.hpp:1701
virtual RegexMatch & operator=(RegexMatch const &rm)
Overloaded copy-assignment operator.
Definition: jpcre2.hpp:1486
Lets you create custom modifier tables.
Definition: jpcre2.hpp:823
void toReplaceOption(Modifier const &mod, bool x, Uint *po, Uint *jo, int *en, SIZE_T *eo) const
Modifier parser for replace related options.
Definition: jpcre2.hpp:980
MatchEvaluator & setMatchDataBlock(MatchData *mdt)
Call RegexMatch::setMatchDataBlock(MatchContext * mdt);.
Definition: jpcre2.hpp:2732
RegexReplace & setModifier(Modifier const &s)
Set the modifier string (resets all JPCRE2 and PCRE2 options) by calling RegexReplace::changeModifier...
Definition: jpcre2.hpp:3276
RegexReplace & reset()
Reset all class variables to its default (initial) state including memory.
Definition: jpcre2.hpp:3033
MatchEvaluator & resetMatchData()
Reset match data to initial state.
Definition: jpcre2.hpp:2606
MatchEvaluator & setCallback(typename MatchEvaluatorCallback< NumSub const &, void *, void *>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2437
MatchEvaluator()
Default constructor.
Definition: jpcre2.hpp:2263
Regex(String const *re, Uint po)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3690
virtual RegexMatch & changeJpcre2Option(Uint opt, bool x)
Add or remove a JPCRE2 option.
Definition: jpcre2.hpp:1901
ModifierTable const * getModifierTable()
Get the modifier table that is set,.
Definition: jpcre2.hpp:3129
Regex & addPcre2Option(Uint x)
Add option to existing PCRE2 options for compile.
Definition: jpcre2.hpp:4115
RegexMatch initMatch()
Returns a default constructed RegexMatch object by value.
Definition: jpcre2.hpp:4198
String getSubject() const
Get subject string.
Definition: jpcre2.hpp:3096
void compile(String const &re, Uint po)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4151
virtual RegexMatch & setMatchContext(MatchContext *match_context)
Set the match context.
Definition: jpcre2.hpp:1848
RegexReplace & changePcre2Option(Uint opt, bool x)
Add or remove a PCRE2 option.
Definition: jpcre2.hpp:3387
class Map< String, SIZE_T > MapNtN
Substring name to Substring number map.
Definition: jpcre2.hpp:1250
MatchEvaluator & setPcre2Option(Uint x)
Call RegexMatch::setPcre2Option (Uint x).
Definition: jpcre2.hpp:2693
std::string getModifier() const
Calculate modifier string from PCRE2 and JPCRE2 options and return it.
Definition: jpcre2.hpp:3902
static String eraseFill(NumSub const &num, MapNas const &nas, MapNtN const &ntn)
Callback function that removes the matched part/s in the subject string and takes all match vectors a...
Definition: jpcre2.hpp:2013
const SIZE_T length() const
Returns the length of the modifier string.
Definition: jpcre2.hpp:650
virtual int getErrorNumber() const
Returns the last error number.
Definition: jpcre2.hpp:1560
MatchEvaluator(Regex const *r)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2276
MatchEvaluator & clearMatchData()
Clear match data.
Definition: jpcre2.hpp:2593
RegexMatch()
Default constructor.
Definition: jpcre2.hpp:1460
String nreplace(bool do_match=true, Uint jro=0, SIZE_T *counter=0)
Perform regex replace with this match evaluator.
Definition: jpcre2.hpp:4582
Find all during match (global match)
Definition: jpcre2.hpp:144
Top level namespace of JPCRE2.
MatchEvaluator & setCallback(typename MatchEvaluatorCallback< void *, void *, void *>::Callback mef)
Member function to set a callback function with no vector reference.
Definition: jpcre2.hpp:2425
class Map< String, String > MapNas
Map for Named substrings.
Definition: jpcre2.hpp:1248
MatchEvaluator & setCallback(typename MatchEvaluatorCallback< NumSub const &, void *, MapNtN const &>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2484
MatchEvaluator & changeModifier(Modifier const &mod, bool x)
Call RegexMatch::changeModifier(Modifier const& mod, bool x).
Definition: jpcre2.hpp:2758
Regex(String const &re, Modifier const &mod)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3666
String replace(String const &mains, String const &repl, Modifier const &mod="", SIZE_T *counter=0)
Perform regex replace and return the replaced string using a temporary replace object.
Definition: jpcre2.hpp:4276
String getErrorMessage() const
Returns the last error message.
Definition: jpcre2.hpp:3937
virtual RegexMatch & resetErrors()
reset match related errors to zero.
Definition: jpcre2.hpp:1552
virtual RegexMatch & setMatchStartOffsetVector(VecOff *v)
Set the pointer to a vector to store the offsets where matches start in the subject.
Definition: jpcre2.hpp:1733
Regex & setModifierTable(ModifierTable const *mdt)
Set a custom modifier table to be used.
Definition: jpcre2.hpp:4024
Uint getPcre2Option() const
Get PCRE2 option.
Definition: jpcre2.hpp:3911
String replace(void)
Perform regex replace by retrieving subject string, replacement string, modifier and other options fr...
Definition: jpcre2.hpp:4645
MapNtN MapNtn
Allow spelling mistake of MapNtN as MapNtn.
Definition: jpcre2.hpp:1259
Regex const * getRegexObject() const
Get a pointer to the associated Regex object.
Definition: jpcre2.hpp:3158
virtual RegexMatch & setFindAll(bool x)
Set whether to perform global match.
Definition: jpcre2.hpp:1819
void compile(String const *re, Modifier const &mod)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4175
String const * getPatternPointer() const
Get pointer to pattern string.
Definition: jpcre2.hpp:3885
PCRE2_SIZE SIZE_T
Used for match count and vector size.
Definition: jpcre2.hpp:120
String getPattern() const
Get pattern string.
Definition: jpcre2.hpp:3879
MatchEvaluator & clear()
Clears MatchEvaluator.
Definition: jpcre2.hpp:2628
ModifierTable & resetMatchModifierTable()
Reset the match modifier table to its initial (empty) state including memory.
Definition: jpcre2.hpp:882
MatchEvaluator & setRegexObject(Regex const *r)
Call RegexMatch::setRegexObject(r).
Definition: jpcre2.hpp:2645
struct to select the types.
Definition: jpcre2.hpp:1229
String const * getReplaceWithPointer() const
Get pointer to replacement string.
Definition: jpcre2.hpp:3089
ModifierTable(bool deflt)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:876
MatchEvaluator & setModifier(Modifier const &s)
Call RegexMatch::setModifier(Modifier const& s).
Definition: jpcre2.hpp:2669
virtual RegexMatch & setRegexObject(Regex const *r)
Set the associated regex object.
Definition: jpcre2.hpp:1690
RegexReplace & setMatchDataBlock(MatchData *match_data)
Set the match data block to be used.
Definition: jpcre2.hpp:3346
RegexReplace & changeJpcre2Option(Uint opt, bool x)
Parse modifier and add/remove equivalent PCRE2 and JPCRE2 options.
Definition: jpcre2.hpp:3376
static const char VERSION_PRE_RELEASE[]
Alpha or beta (testing) release version.
Definition: jpcre2.hpp:116
std::vector< SIZE_T > VecOff
vector of size_t.
Definition: jpcre2.hpp:123
RegexMatch(RegexMatch const &rm)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:1478
Regex(String const &re, Uint po)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3682
MatchEvaluator(typename MatchEvaluatorCallback< void *, MapNas const &, void *>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2336
String getErrorMessage() const
Returns the last error message.
Definition: jpcre2.hpp:3073
MatchEvaluator(typename MatchEvaluatorCallback< void *, void *, MapNtN const &>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2359
virtual ModifierTable const * getModifierTable()
Get the modifier table that is set,.
Definition: jpcre2.hpp:1617
RegexMatch(Regex const *r)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:1469
Regex(String const &re, Uint po, Uint jo)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3699
MatchEvaluator & setSubject(String const *s)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2661
RegexReplace & resetErrors()
Reset replace related errors to zero.
Definition: jpcre2.hpp:3053
virtual RegexMatch & setMatchEndOffsetVector(VecOff *v)
Set the pointer to a vector to store the offsets where matches end in the subject.
Definition: jpcre2.hpp:1743
virtual RegexMatch & setMatchDataBlock(MatchData *madt)
Set the match data block to be used.
Definition: jpcre2.hpp:1865
Perform JIT compilation for optimization.
Definition: jpcre2.hpp:145
Invalid modifier was detected.
Definition: jpcre2.hpp:134
uint32_t Uint
Used for options (bitwise operation)
Definition: jpcre2.hpp:121
void compile(String const *re, Uint po, Uint jo)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4143
Regex(String const *re, Uint po, Uint jo)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3708
Provides public constructors to create RegexMatch objects.
Definition: jpcre2.hpp:1366
MatchEvaluator & setCallback(typename MatchEvaluatorCallback< void *, void *, MapNtN const &>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2581
virtual VecOff const * getMatchEndOffsetVector() const
Get pre-set match end offset vector pointer.
Definition: jpcre2.hpp:1656
Regex & changePcre2Option(Uint opt, bool x)
Add or remove a PCRE2 option.
Definition: jpcre2.hpp:4084
Regex(String const *re, Modifier const &mod)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3674
ModifierTable & setMatchModifierTable(std::string const &tabs, VecOpt const &tabv)
Set modifier table for match.
Definition: jpcre2.hpp:1024
MatchContext * getMatchContext()
Return pointer to the match context that was previously set with setMatchContext().
Definition: jpcre2.hpp:3165
RegexReplace & changeModifier(Modifier const &mod, bool x)
After a call to this function PCRE2 and JPCRE2 options will be properly set.
Definition: jpcre2.hpp:3363
std::basic_string< Char_T > String
Typedef for string (std::string, std::wstring, std::u16string, std::u32string).
Definition: jpcre2.hpp:1244
std::vector< NumSub > VecNum
Vector of matches with numbered substrings.
Definition: jpcre2.hpp:1270
MatchEvaluator & reset()
Reset MatchEvaluator to initial state including memory.
Definition: jpcre2.hpp:2618
static const char VERSION_MINOR[]
Minor version, includes bug fix or minor feature upgrade.
Definition: jpcre2.hpp:115
RegexReplace & setPcre2Option(Uint x)
Set PCRE2 option replace (overwrite existing option)
Definition: jpcre2.hpp:3324
static String toString(Char *a)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:1307
virtual VecNtN const * getNameToNumberMapVector() const
Get pointer to name to number map vector.
Definition: jpcre2.hpp:1681
ModifierTable & resetCompileModifierTable()
Reset the compile modifier table to its initial (empty) state including memory.
Definition: jpcre2.hpp:902
virtual RegexMatch & addJpcre2Option(Uint x)
Add option to existing JPCRE2 options for match.
Definition: jpcre2.hpp:1932
virtual RegexMatch & changePcre2Option(Uint opt, bool x)
Add or remove a PCRE2 option.
Definition: jpcre2.hpp:1912
Regex & setNewLine(Uint value)
Set new line convention.
Definition: jpcre2.hpp:3979
ModifierTable & setAllToDefault()
Set all tables to default.
Definition: jpcre2.hpp:1171
MatchEvaluator & changePcre2Option(Uint opt, bool x)
Call RegexMatch::changePcre2Option(Uint opt, bool x).
Definition: jpcre2.hpp:2776
Option 0 (zero)
Definition: jpcre2.hpp:143
RegexReplace initReplace()
Returns a default constructed RegexReplace object by value.
Definition: jpcre2.hpp:4255
virtual VecNas const * getNamedSubstringVector() const
Get pointer to named substring vector.
Definition: jpcre2.hpp:1675
Regex & resetErrors()
Reset regex compile related errors to zero.
Definition: jpcre2.hpp:3848
static const char VERSION_GENRE[]
Generation, depends on original PCRE2 version.
Definition: jpcre2.hpp:113
RegexMatch getMatchObject()
Synonym for initMatch()
Definition: jpcre2.hpp:4206
RegexReplace & setReplaceWith(String const *s)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3262
MatchEvaluator(MatchEvaluator &&me)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2394
virtual RegexMatch & setSubject(String const &s)
Set the subject string for match.
Definition: jpcre2.hpp:1753
uint8_t Ush
8 bit unsigned integer.
Definition: jpcre2.hpp:122
RegexReplace & addModifier(Modifier const &mod)
Parse modifier string and add equivalent PCRE2 and JPCRE2 options.
Definition: jpcre2.hpp:3400
std::string fromCompileOption(Uint po, Uint jo) const
Take compile related option value and convert to modifier string.
Definition: jpcre2.hpp:1015
PCRE2_SIZE getBufferSize()
Get the initial buffer size that is being used by internal function pcre2_substitute.
Definition: jpcre2.hpp:3178
ModifierTable & reset()
Reset the modifier tables to their initial (empty) state including memory.
Definition: jpcre2.hpp:912
MatchEvaluator & setFindAll(bool x)
Call RegexMatch::setFindAll(bool x).
Definition: jpcre2.hpp:2701
Regex(String const &re)
Compile pattern with initialization.
Definition: jpcre2.hpp:3651
ModifierTable & clearReplaceModifierTable()
Clear the replace modifier table to its initial (empty) state.
Definition: jpcre2.hpp:933
Regex & setModifier(Modifier const &x)
set the modifier (resets all JPCRE2 and PCRE2 options) by calling Regex::changeModifier().
Definition: jpcre2.hpp:4015
String replace(MatchEvaluator me)
PCRE2 compatible replace function that takes a MatchEvaluator.
Definition: jpcre2.hpp:3514
RegexReplace & setSubject(String *s)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3231
virtual RegexMatch & setPcre2Option(Uint x)
Set PCRE2 option match (overwrite existing option)
Definition: jpcre2.hpp:1811
RegexReplace & setBufferSize(PCRE2_SIZE x)
Set the initial buffer size to be allocated for replaced string (used by PCRE2)
Definition: jpcre2.hpp:3293
virtual RegexMatch & addModifier(Modifier const &mod)
Parse modifier string and add equivalent PCRE2 and JPCRE2 options.
Definition: jpcre2.hpp:1923
virtual RegexMatch & changeModifier(Modifier const &mod, bool x)
Parse modifier and add/remove equivalent PCRE2 and JPCRE2 options.
Definition: jpcre2.hpp:1889
SIZE_T getLastReplaceCount()
Get the number of replacement in last replace operation.
Definition: jpcre2.hpp:3187
ModifierTable & resetReplaceModifierTable()
Reset the replace modifier table to its initial (empty) state including memory.
Definition: jpcre2.hpp:892
MatchEvaluator & setCallback(typename MatchEvaluatorCallback< NumSub const &, MapNas const &, MapNtN const &>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2509
MatchEvaluator & setModifierTable(ModifierTable const *mdt)
Call RegexMatch::setModifierTable(ModifierTable const * s).
Definition: jpcre2.hpp:2677
ModifierTable & setReplaceModifierTable(const char *tabsp, const Uint *tabvp)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:1090
String replace(bool do_match=true, Uint ro=0, SIZE_T *counter=0)
PCRE2 compatible replace function that uses this MatchEvaluator.
Definition: jpcre2.hpp:4454
Regex & setPattern(String const *re)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3999
ModifierTable & setCompileModifierTable(std::string const &tabs, VecOpt const &tabv)
Set modifier table for compile.
Definition: jpcre2.hpp:1104
Regex & reset()
Reset all class variables to its default (initial) state including memory.
Definition: jpcre2.hpp:3826
virtual Regex const * getRegexObject() const
Get a pointer to the associated Regex object.
Definition: jpcre2.hpp:1663
Uint getPcre2Option() const
Get PCRE2 option.
Definition: jpcre2.hpp:3143
RegexReplace & setModifierTable(ModifierTable const *mdt)
Set a custom modifier table to be used.
Definition: jpcre2.hpp:3285
Uint getJpcre2Option() const
Get JPCRE2 option.
Definition: jpcre2.hpp:3151
#define JPCRE2_ASSERT(cond, msg)
Macro to call jpcre2::jassert() with file path and line number.
RegexReplace & setMatchContext(MatchContext *match_context)
Set the match context to be used.
Definition: jpcre2.hpp:3335
MatchEvaluator & operator=(MatchEvaluator const &me)
Overloaded copy-assignment operator.
Definition: jpcre2.hpp:2378
void compile(String const *re, Uint po)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4159
virtual RegexMatch & reset()
Reset all class variables to its default (initial) state including memory.
Definition: jpcre2.hpp:1528
ModifierTable & clearCompileModifierTable()
Clear the compile modifier table to its initial (empty) state.
Definition: jpcre2.hpp:944
virtual RegexMatch & setNameToNumberMapVector(VecNtN *v)
Set a pointer to the name to number map vector.
Definition: jpcre2.hpp:1723
Regex & resetCharacterTables()
Recreate character tables used by PCRE2.
Definition: jpcre2.hpp:3861
static String getErrorMessage(int err_num, int err_off)
Returns error message (either JPCRE2 or PCRE2) from error number and error offset.
Definition: jpcre2.hpp:1333
Regex(Regex const &r)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3719
RegexReplace & addPcre2Option(Uint x)
Add specified PCRE2 option to existing options for replace.
Definition: jpcre2.hpp:3419
Pcre2Code const * getPcre2Code() const
Get Pcre2 raw compiled code pointer.
Definition: jpcre2.hpp:3873
virtual RegexMatch & clear()
Clear all class variables (may retain some memory for further use).
Definition: jpcre2.hpp:1538
int getErrorOffset() const
Returns the last error offset.
Definition: jpcre2.hpp:3931
MatchEvaluator & operator=(MatchEvaluator &&me)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2408
static const char VERSION_MAJOR[]
Major version, updated when API change is made.
Definition: jpcre2.hpp:114
This class inherits RegexMatch and provides a similar functionality.
Definition: jpcre2.hpp:2126
Regex & operator=(Regex const &r)
Overloaded assignment operator.
Definition: jpcre2.hpp:3727
MatchEvaluator(typename MatchEvaluatorCallback< NumSub const &, MapNas const &, MapNtN const &>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2326
String nreplace(MatchEvaluator me)
JPCRE2 native replace function.
Definition: jpcre2.hpp:3496
RegexReplace & setReplaceWith(String const &s)
Set the replacement string.
Definition: jpcre2.hpp:3252
static String toString(Char const *a)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:1298
String getReplaceWith() const
Get replacement string.
Definition: jpcre2.hpp:3083
RegexReplace & setRegexObject(Regex const *r)
Set the associated Regex object.
Definition: jpcre2.hpp:3207
MatchEvaluator & setMatchContext(MatchContext *match_context)
Call RegexMatch::setMatchContext(MatchContext *match_context).
Definition: jpcre2.hpp:2724
MatchEvaluator & addPcre2Option(Uint x)
Call RegexMatch::addPcre2Option(Uint x).
Definition: jpcre2.hpp:2800
virtual MatchData * getMatchDataBlock()
Get the pointer to the match data block that was set previously with setMatchData() Handling memory i...
Definition: jpcre2.hpp:3172
ModifierTable & setCompileModifierTable(const char *tabsp, const Uint *tabvp)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:1130
RegexReplace & setSubject(String const &s)
Set the subject string for replace.
Definition: jpcre2.hpp:3218
Char_T Char
Typedef for character (char, wchar_t, char16_t, char32_t)
Definition: jpcre2.hpp:1232
virtual RegexMatch & addPcre2Option(Uint x)
Add option to existing PCRE2 options for match.
Definition: jpcre2.hpp:1942
void toMatchOption(Modifier const &mod, bool x, Uint *po, Uint *jo, int *en, SIZE_T *eo) const
Modifier parser for match related options.
Definition: jpcre2.hpp:969
Regex & changeJpcre2Option(Uint opt, bool x)
Add or remove a JPCRE2 option.
Definition: jpcre2.hpp:4073
ModifierTable & setMatchModifierTableToDefault()
Set match modifie table to default.
Definition: jpcre2.hpp:1141
RegexReplace & operator=(RegexReplace &&rr)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3021
RegexReplace()
Default constructor.
Definition: jpcre2.hpp:2967
virtual VecOff const * getMatchStartOffsetVector() const
Get pre-set match start offset vector pointer.
Definition: jpcre2.hpp:1648
virtual RegexMatch & setSubject(String const *s)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:1765
static String erase(void *, void *, void *)
Callback function that removes the matched part/s in the subject string and does not take any match v...
Definition: jpcre2.hpp:2027
SIZE_T preplace(String *mains, String const *repl, Modifier const &mod="")
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4339
RegexReplace(RegexReplace const &rr)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2985
Provides public constructors to create Regex object.
Definition: jpcre2.hpp:3541
RegexReplace & operator=(RegexReplace const &rr)
Overloaded Copy assignment operator.
Definition: jpcre2.hpp:2993
Provides some default static callback functions.
Definition: jpcre2.hpp:2003
RegexReplace & clear()
Clear all class variables to its default (initial) state (some memory may retain for further use)...
Definition: jpcre2.hpp:3042
virtual Uint getJpcre2Option() const
Get JPCRE2 option.
Definition: jpcre2.hpp:1634
int getErrorOffset() const
Returns the last error offset.
Definition: jpcre2.hpp:3067
std::vector< MapNtN > VecNtN
Vector of substring name to substring number map.
Definition: jpcre2.hpp:1266
MatchEvaluator & addModifier(Modifier const &mod)
Call RegexMatch::addModifier(Modifier const& mod).
Definition: jpcre2.hpp:2784
static const char FULL_VERSION[]
Full version string.
Definition: jpcre2.hpp:112
Regex(Regex &&r)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3744
ModifierTable & setMatchModifierTable(std::string const &tabs, const Uint *tabvp)
Set modifier table for match.
Definition: jpcre2.hpp:1034
SIZE_T match(String const &s, Modifier const &mod, PCRE2_SIZE start_offset=0)
Perform regex match and return match count using a temporary match object.
Definition: jpcre2.hpp:4218
ModifierTable & setCompileModifierTableToDefault()
Set compile modifier table to default.
Definition: jpcre2.hpp:1161
virtual MatchData * getMatchDataBlock()
Get the pointer to the match data block that was set previously with setMatchData() Handling memory i...
Definition: jpcre2.hpp:1873
MatchEvaluator(MatchEvaluator const &me)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2370
bool operator!() const
Provides boolean check for the status of the object.
Definition: jpcre2.hpp:3815
String replace(String *mains, String const *repl, Modifier const &mod="", SIZE_T *counter=0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4311
virtual MatchContext * getMatchContext()
Return pointer to the match context that was previously set with setMatchContext().
Definition: jpcre2.hpp:1856
void compile(String const &re, Modifier const &mod)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4167
MatchEvaluator & setStartOffset(PCRE2_SIZE offset)
Call RegexMatch::setStartOffset (PCRE2_SIZE offset).
Definition: jpcre2.hpp:2716
virtual RegexMatch & setModifier(Modifier const &s)
Set the modifier (resets all JPCRE2 and PCRE2 options) by calling RegexMatch::changeModifier().
Definition: jpcre2.hpp:1781
Regex & setPcre2Option(Uint x)
Set PCRE2 option for compile (overwrites existing option)
Definition: jpcre2.hpp:4044
virtual RegexMatch & setFindAll()
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:1828
MatchEvaluator & setCallback(typename MatchEvaluatorCallback< void *, MapNas const &, MapNtN const &>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2557
Regex & setPattern(String const &re)
Set the pattern string to compile.
Definition: jpcre2.hpp:3990
virtual RegexMatch & setModifierTable(ModifierTable const *mdt)
Set a custom modifier table to be used.
Definition: jpcre2.hpp:1791
SIZE_T match(String const *s, PCRE2_SIZE start_offset=0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4248
RegexReplace(RegexReplace &&rr)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3008
ModifierTable & setReplaceModifierTableToDefault()
Set replace modifier table to default.
Definition: jpcre2.hpp:1151
Regex(String const *re)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3658
void compile(String const &re)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:4182
virtual ~RegexMatch()
Destructor Frees all internal memories that were used.
Definition: jpcre2.hpp:1522
ModifierTable & setReplaceModifierTable(std::string const &tabs, VecOpt const &tabv)
Set modifier table for replace.
Definition: jpcre2.hpp:1064
Regex & addModifier(Modifier const &mod)
Parse modifier string and add equivalent PCRE2 and JPCRE2 options.
Definition: jpcre2.hpp:4096
Uint getNewLine()
Get new line convention from compiled code.
Definition: jpcre2.hpp:3954
virtual Uint getPcre2Option() const
Get PCRE2 option.
Definition: jpcre2.hpp:1626
ModifierTable const * getModifierTable()
Get the modifier table that is set,.
Definition: jpcre2.hpp:3964
MatchEvaluator(typename MatchEvaluatorCallback< NumSub const &, void *, MapNtN const &>::Callback mef)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:2316
Provides public constructors to create RegexReplace objects.
Definition: jpcre2.hpp:2881
MatchEvaluator & setFindAll()
Call RegexMatch::setFindAll().
Definition: jpcre2.hpp:2708
RegexReplace & setReplaceCounter(SIZE_T *counter)
Set an external counter variable to store the replacement count.
Definition: jpcre2.hpp:3197
std::vector< String > NumSub
Vector for Numbered substrings (Sub container).
Definition: jpcre2.hpp:1262
virtual VecNum const * getNumberedSubstringVector() const
Get pointer to numbered substring vector.
Definition: jpcre2.hpp:1669
virtual std::string getModifier() const
Calculate modifier string from PCRE2 and JPCRE2 options and return it.
Definition: jpcre2.hpp:1610
Modifier(char const *x)
Constructor that takes char const * (null safety is provided by this one)
Definition: jpcre2.hpp:638
Regex & operator=(Regex &&r)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:3757
MatchEvaluator & setJpcre2Option(Uint x)
Call RegexMatch::setJpcre2Option(Uint x).
Definition: jpcre2.hpp:2685
std::vector< Uint > VecOpt
vector for Uint option values.
Definition: jpcre2.hpp:124
MatchEvaluator & setSubject(String const &s)
Call RegexMatch::setSubject(String const &s).
Definition: jpcre2.hpp:2653
Regex & changeModifier(Modifier const &mod, bool x)
Parse modifier and add/remove equivalent PCRE2 and JPCRE2 options.
Definition: jpcre2.hpp:4061
RegexReplace & addJpcre2Option(Uint x)
Add specified JPCRE2 option to existing options for replace.
Definition: jpcre2.hpp:3409
Ovector was not big enough during a match.
Definition: jpcre2.hpp:135
ModifierTable & setMatchModifierTable(const char *tabsp, const Uint *tabvp)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: jpcre2.hpp:1050