WvStreams
wvregex.h
1 /* -*- Mode: C++ -*-
2  * Worldvisions Weaver Software:
3  * Copyright (C) 1997-2004 Net Integration Technologies, Inc.
4  *
5  * Regular expression support though libc
6  */
7 #ifndef __WVREGEX_H
8 #define __WVREGEX_H
9 
10 #include "wverror.h"
11 #include "wvstring.h"
12 #include <sys/types.h>
13 #include <regex.h>
14 
15 #define __WVRE_REG(n) __wvre_r##n
16 #define __WVRE_DECL_FORM(n) WvString &__WVRE_REG(n) = WvRegex::__wvre_null_reg
17 #define WVREGEX_REGS_DECL \
18  __WVRE_DECL_FORM( 0), __WVRE_DECL_FORM( 1), \
19  __WVRE_DECL_FORM( 2), __WVRE_DECL_FORM( 3), \
20  __WVRE_DECL_FORM( 4), __WVRE_DECL_FORM( 5), \
21  __WVRE_DECL_FORM( 6), __WVRE_DECL_FORM( 7), \
22  __WVRE_DECL_FORM( 8), __WVRE_DECL_FORM( 9), \
23  __WVRE_DECL_FORM(10), __WVRE_DECL_FORM(11), \
24  __WVRE_DECL_FORM(12), __WVRE_DECL_FORM(13), \
25  __WVRE_DECL_FORM(14), __WVRE_DECL_FORM(15), \
26  __WVRE_DECL_FORM(16), __WVRE_DECL_FORM(17), \
27  __WVRE_DECL_FORM(18), __WVRE_DECL_FORM(19)
28 #define __WVRE_CALL_FORM(n) __WVRE_REG(n)
29 #define WVREGEX_REGS_CALL \
30  __WVRE_CALL_FORM( 0), __WVRE_CALL_FORM( 1), \
31  __WVRE_CALL_FORM( 2), __WVRE_CALL_FORM( 3), \
32  __WVRE_CALL_FORM( 4), __WVRE_CALL_FORM( 5), \
33  __WVRE_CALL_FORM( 6), __WVRE_CALL_FORM( 7), \
34  __WVRE_CALL_FORM( 8), __WVRE_CALL_FORM( 9), \
35  __WVRE_CALL_FORM(10), __WVRE_CALL_FORM(11), \
36  __WVRE_CALL_FORM(12), __WVRE_CALL_FORM(13), \
37  __WVRE_CALL_FORM(14), __WVRE_CALL_FORM(15), \
38  __WVRE_CALL_FORM(16), __WVRE_CALL_FORM(17), \
39  __WVRE_CALL_FORM(18), __WVRE_CALL_FORM(19)
40 
47 class WvRegex: public WvErrorBase
48 {
49 private:
50  bool have_preg;
51  regex_t preg;
52 
53  bool match(WvStringParm string, int eflags,
54  size_t nmatch, regmatch_t pmatch[]) const;
55 
56  virtual void seterr(int _errnum);
57 
58  bool _match(WvStringParm string, int eflags,
59  int &match_start, int &match_end, WVREGEX_REGS_DECL) const
60  {
61  regmatch_t pmatch[21];
62  int nmatch = 1;
63 
64 #define __WVRE_COUNT_REGS(n) \
65  if ( &__WVRE_REG(n) != &__wvre_null_reg) ++nmatch
66 
67  __WVRE_COUNT_REGS( 0); __WVRE_COUNT_REGS( 1);
68  __WVRE_COUNT_REGS( 2); __WVRE_COUNT_REGS( 3);
69  __WVRE_COUNT_REGS( 4); __WVRE_COUNT_REGS( 5);
70  __WVRE_COUNT_REGS( 6); __WVRE_COUNT_REGS( 7);
71  __WVRE_COUNT_REGS( 8); __WVRE_COUNT_REGS( 9);
72  __WVRE_COUNT_REGS(10); __WVRE_COUNT_REGS(11);
73  __WVRE_COUNT_REGS(12); __WVRE_COUNT_REGS(13);
74  __WVRE_COUNT_REGS(14); __WVRE_COUNT_REGS(15);
75  __WVRE_COUNT_REGS(16); __WVRE_COUNT_REGS(17);
76  __WVRE_COUNT_REGS(18); __WVRE_COUNT_REGS(19);
77 
78  if (!match(string, eflags, nmatch, pmatch)) return false;
79 
80  match_start = pmatch[0].rm_so;
81  match_end = pmatch[0].rm_eo;
82 
83 #define __WVRE_STORE_REGS(n) \
84  if (&__WVRE_REG(n) != &__wvre_null_reg \
85  && pmatch[n+1].rm_so != -1 && pmatch[n+1].rm_eo != -1) \
86  { \
87  int len = pmatch[n+1].rm_eo-pmatch[n+1].rm_so; \
88  __WVRE_REG(n).setsize(len+1); \
89  memcpy(__WVRE_REG(n).edit(), &string[pmatch[n+1].rm_so], len); \
90  __WVRE_REG(n).edit()[len] = '\0'; \
91  }
92 
93  __WVRE_STORE_REGS( 0); __WVRE_STORE_REGS( 1);
94  __WVRE_STORE_REGS( 2); __WVRE_STORE_REGS( 3);
95  __WVRE_STORE_REGS( 4); __WVRE_STORE_REGS( 5);
96  __WVRE_STORE_REGS( 6); __WVRE_STORE_REGS( 7);
97  __WVRE_STORE_REGS( 8); __WVRE_STORE_REGS( 9);
98  __WVRE_STORE_REGS(10); __WVRE_STORE_REGS(11);
99  __WVRE_STORE_REGS(12); __WVRE_STORE_REGS(13);
100  __WVRE_STORE_REGS(14); __WVRE_STORE_REGS(15);
101  __WVRE_STORE_REGS(16); __WVRE_STORE_REGS(17);
102  __WVRE_STORE_REGS(18); __WVRE_STORE_REGS(19);
103 
104  return true;
105  }
106 
107 public:
112  enum CFlags {
113  // Use (obsolete) basic regex syntax (like grep). See regex(7).
114  BASIC = 0,
115  // Use extended regex syntax (like egrep). See regex(7).
116  EXTENDED = REG_EXTENDED,
117  // Case insensitive
118  ICASE = REG_ICASE,
119  // Do not collect match start and end or registers; faster
120  NOSUB = REG_NOSUB,
121  // Match-any-character operators don't match a newline. See regex(3)
122  NEWLINE = REG_NEWLINE
123  };
124  static const int default_cflags;
125 
130  enum EFlags
131  {
132  // Matching begining of line always fails (unless NEWLINE cflag is set)
133  NOTBOL = REG_NOTBOL,
134  // Matching end of line always fails (unless NEWLINE cflag is set)
135  NOTEOL = REG_NOTEOL
136  };
137  static const int default_eflags;
138 
143 
148  WvRegex() : have_preg(false) {}
156  WvRegex(WvStringParm regex, int cflags = default_cflags) : have_preg(false)
157  { set(regex, cflags); }
158  ~WvRegex();
159 
167  bool set(WvStringParm regex, int cflags = default_cflags);
168 
183  bool match(WvStringParm string, WVREGEX_REGS_DECL) const
184  {
185  int match_start, match_end;
186  return _match(string, default_eflags,
187  match_start, match_end, WVREGEX_REGS_CALL);
188  }
197  bool match(WvStringParm string, int eflags, WVREGEX_REGS_DECL) const
198  {
199  int match_start, match_end;
200  return _match(string, eflags,
201  match_start, match_end, WVREGEX_REGS_CALL);
202  }
203 
230  bool continuable_match(WvStringParm string,
231  int &match_start, int &match_end,
232  WVREGEX_REGS_DECL) const
233  {
234  return _match(string, default_eflags,
235  match_start, match_end, WVREGEX_REGS_CALL);
236  }
250  bool continuable_match(WvStringParm string, int eflags,
251  int &match_start, int &match_end,
252  WVREGEX_REGS_DECL) const
253  {
254  return _match(string, eflags,
255  match_start, match_end, WVREGEX_REGS_CALL);
256  }
257 };
258 
259 #endif // __WVREGEX_H
WvRegex::continuable_match
bool continuable_match(WvStringParm string, int eflags, int &match_start, int &match_end, WVREGEX_REGS_DECL) const
Match a given string against the compiled regular expression, capturing the start and end positions o...
Definition: wvregex.h:250
WvRegex::EFlags
EFlags
Flags that affect matching of regex.
Definition: wvregex.h:130
WvRegex::set
bool set(WvStringParm regex, int cflags=default_cflags)
Replace the current regex to match with a new one.
Definition: wvregex.cc:27
WvRegex::continuable_match
bool continuable_match(WvStringParm string, int &match_start, int &match_end, WVREGEX_REGS_DECL) const
Match a given string against the compiled regular expression, capturing the start and end positions o...
Definition: wvregex.h:230
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
WvRegex::__wvre_null_reg
static WvString __wvre_null_reg
Internal use only.
Definition: wvregex.h:142
WvErrorBase
A class for managing error numbers and strings.
Definition: wverror.h:23
WvRegex
WvRegex – Unified support for regular expressions.
Definition: wvregex.h:47
WvRegex::WvRegex
WvRegex(WvStringParm regex, int cflags=default_cflags)
Construct a regex object, compiling the given regex.
Definition: wvregex.h:156
WvRegex::CFlags
CFlags
Flags that affect interpretation of the regex; used in Regex() and set()
Definition: wvregex.h:112
WvRegex::match
bool match(WvStringParm string, int eflags, WVREGEX_REGS_DECL) const
Match a given string against the compiled regular expression.
Definition: wvregex.h:197
WvRegex::match
bool match(WvStringParm string, WVREGEX_REGS_DECL) const
Match a given string against the compiled regular expression.
Definition: wvregex.h:183
WvRegex::WvRegex
WvRegex()
Construct an empty regex object.
Definition: wvregex.h:148