]> git.cworth.org Git - vogl/blob - src/voglcore/vogl_regex.h
Initial vogl checkin
[vogl] / src / voglcore / vogl_regex.h
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 // File: vogl_regex.h
28 //
29 //
30 // Uses Henry Spencer's regex library, see regex_man.txt and regex2_man.txt
31 // regexp class enables REG_EXTENDED syntax.
32 //
33 #ifndef VOGL_REGEX_H
34 #define VOGL_REGEX_H
35
36 #include "vogl_core.h"
37 #include "regex/regex.h"
38
39 namespace vogl
40 {
41     enum regexp_flags
42     {
43         REGEX_IGNORE_CASE = REG_ICASE,
44         REGEX_NOSUB = REG_NOSUB,
45         REGEX_NEWLINE = REG_NEWLINE
46     };
47
48     struct regexp_match_loc
49     {
50         uint m_start;
51         uint m_len;
52
53         inline void set(uint start, uint len)
54         {
55             m_start = start;
56             m_len = len;
57         }
58     };
59
60     typedef vogl::vector<regexp_match_loc> regexp_match_loc_array;
61
62     class regexp
63     {
64         VOGL_NO_COPY_OR_ASSIGNMENT_OP(regexp);
65
66     public:
67         regexp();
68         regexp(const char *pPattern, uint flags = 0);
69         ~regexp();
70
71         bool init(const char *pPattern, uint flags = 0);
72         void deinit();
73
74         inline bool is_initialized() const
75         {
76             return m_is_initialized;
77         }
78
79         inline const dynamic_string &get_error() const
80         {
81             return m_error;
82         }
83
84         inline const dynamic_string_array &get_match_strings() const
85         {
86             return m_match_strings;
87         }
88         inline dynamic_string_array &get_match_strings()
89         {
90             return m_match_strings;
91         }
92
93         inline const regexp_match_loc_array &get_match_locs() const
94         {
95             return m_match_locs;
96         }
97         inline regexp_match_loc_array &get_match_locs()
98         {
99             return m_match_locs;
100         }
101
102         inline uint get_num_matches() const
103         {
104             return m_match_strings.size();
105         }
106         inline const dynamic_string &get_match_string(uint i) const
107         {
108             return m_match_strings[i];
109         }
110         inline const regexp_match_loc &get_match_loc(uint i) const
111         {
112             return m_match_locs[i];
113         }
114
115         // True if there are any matches within string.
116         bool find_any(const char *pString);
117
118         // Returns the first match, or NULL if there are no matches.
119         // begin will be the offset of the first char matched, end will be the offset 1 beyond the last char matched. end-begin=len of match.
120         const char *find_first(const char *pString, int &begin, int &end);
121
122         // Returns true if the regexp matches the entire string (i.e. find_first() successfully returns begin=0 end=length);
123         bool full_match(const char *pString);
124
125         // Finds all matches in string. To retrieve the matches, call get_num_matches(), get_match_string(), get_match_loc(), etc.
126         uint find(const char *pString);
127
128         uint replace(dynamic_string &result, const char *pString, const char *pReplacement);
129
130     private:
131         regex_t m_regex;
132         bool m_is_initialized;
133         dynamic_string_array m_match_strings;
134         regexp_match_loc_array m_match_locs;
135         dynamic_string m_error;
136     };
137
138     // Returns true if there are any matches.
139     inline bool regexp_find_any(const char *pString, const char *pPattern, uint flags = 0)
140     {
141         // TODO: Compile with REG_NOSUB?
142         regexp r;
143         if (!r.init(pPattern, flags))
144             return false;
145         return r.find_any(pString);
146     }
147
148     // Returns pointer to first match, or NULL if no matches.
149     inline const char *regexp_find_first(const char *pString, const char *pPattern, int &begin, int &end, uint flags = 0)
150     {
151         regexp r;
152         if (!r.init(pPattern, flags))
153             return NULL;
154         return r.find_first(pString, begin, end);
155     }
156
157     // true if pattern matches the entire string.
158     inline bool regexp_full_match(const char *pString, const char *pPattern, uint flags = 0)
159     {
160         regexp r;
161         if (!r.init(pPattern, flags))
162             return false;
163         return r.full_match(pString);
164     }
165
166     // Returns a string array containing all matches of pattern in string.
167     inline dynamic_string_array regexp_find(const char *pString, const char *pPattern, uint flags = 0)
168     {
169         regexp r;
170
171         dynamic_string_array result;
172         if (r.init(pPattern, flags))
173         {
174             if (r.find(pString))
175                 result.swap(r.get_match_strings());
176         }
177
178         return result;
179     }
180
181     // Replaces every instance of pattern in string, returns the new string. pReplacement may be NULL.
182     inline dynamic_string regexp_replace(const char *pString, const char *pPattern, const char *pReplacement, uint flags = 0)
183     {
184         dynamic_string result;
185
186         regexp r;
187         if (r.init(pPattern, flags))
188             r.replace(result, pString, pReplacement);
189
190         return result;
191     }
192
193     bool regexp_test();
194
195 } // namespace vogl
196
197 #endif // VOGL_REGEX_H