|
1 // Copyright (c) 2005, Google Inc. |
|
2 // All rights reserved. |
|
3 // |
|
4 // Redistribution and use in source and binary forms, with or without |
|
5 // modification, are permitted provided that the following conditions are |
|
6 // met: |
|
7 // |
|
8 // * Redistributions of source code must retain the above copyright |
|
9 // notice, this list of conditions and the following disclaimer. |
|
10 // * Redistributions in binary form must reproduce the above |
|
11 // copyright notice, this list of conditions and the following disclaimer |
|
12 // in the documentation and/or other materials provided with the |
|
13 // distribution. |
|
14 // * Neither the name of Google Inc. nor the names of its |
|
15 // contributors may be used to endorse or promote products derived from |
|
16 // this software without specific prior written permission. |
|
17 // |
|
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
29 // |
|
30 // Author: Sanjay Ghemawat |
|
31 |
|
32 #ifndef _PCRECPPARG_H |
|
33 #define _PCRECPPARG_H |
|
34 |
|
35 #include <stdlib.h> // for NULL |
|
36 #include <string> |
|
37 |
|
38 #include <pcre.h> |
|
39 |
|
40 namespace pcrecpp { |
|
41 |
|
42 class StringPiece; |
|
43 |
|
44 // Hex/Octal/Binary? |
|
45 |
|
46 // Special class for parsing into objects that define a ParseFrom() method |
|
47 template <class T> |
|
48 class _RE_MatchObject { |
|
49 public: |
|
50 static inline bool Parse(const char* str, int n, void* dest) { |
|
51 if (dest == NULL) return true; |
|
52 T* object = reinterpret_cast<T*>(dest); |
|
53 return object->ParseFrom(str, n); |
|
54 } |
|
55 }; |
|
56 |
|
57 class PCRECPP_EXP_DEFN Arg { |
|
58 public: |
|
59 // Empty constructor so we can declare arrays of Arg |
|
60 Arg(); |
|
61 |
|
62 // Constructor specially designed for NULL arguments |
|
63 Arg(void*); |
|
64 |
|
65 typedef bool (*Parser)(const char* str, int n, void* dest); |
|
66 |
|
67 // Type-specific parsers |
|
68 #define PCRE_MAKE_PARSER(type,name) \ |
|
69 Arg(type* p) : arg_(p), parser_(name) { } \ |
|
70 Arg(type* p, Parser parser) : arg_(p), parser_(parser) { } |
|
71 |
|
72 |
|
73 PCRE_MAKE_PARSER(char, parse_char); |
|
74 PCRE_MAKE_PARSER(unsigned char, parse_uchar); |
|
75 PCRE_MAKE_PARSER(short, parse_short); |
|
76 PCRE_MAKE_PARSER(unsigned short, parse_ushort); |
|
77 PCRE_MAKE_PARSER(int, parse_int); |
|
78 PCRE_MAKE_PARSER(unsigned int, parse_uint); |
|
79 PCRE_MAKE_PARSER(long, parse_long); |
|
80 PCRE_MAKE_PARSER(unsigned long, parse_ulong); |
|
81 #if @pcre_have_long_long@ |
|
82 PCRE_MAKE_PARSER(long long, parse_longlong); |
|
83 #endif |
|
84 #if @pcre_have_ulong_long@ |
|
85 PCRE_MAKE_PARSER(unsigned long long, parse_ulonglong); |
|
86 #endif |
|
87 PCRE_MAKE_PARSER(float, parse_float); |
|
88 PCRE_MAKE_PARSER(double, parse_double); |
|
89 PCRE_MAKE_PARSER(std::string, parse_string); |
|
90 PCRE_MAKE_PARSER(StringPiece, parse_stringpiece); |
|
91 |
|
92 #undef PCRE_MAKE_PARSER |
|
93 |
|
94 // Generic constructor |
|
95 template <class T> Arg(T*, Parser parser); |
|
96 // Generic constructor template |
|
97 template <class T> Arg(T* p) |
|
98 : arg_(p), parser_(_RE_MatchObject<T>::Parse) { |
|
99 } |
|
100 |
|
101 // Parse the data |
|
102 bool Parse(const char* str, int n) const; |
|
103 |
|
104 private: |
|
105 void* arg_; |
|
106 Parser parser_; |
|
107 |
|
108 static bool parse_null (const char* str, int n, void* dest); |
|
109 static bool parse_char (const char* str, int n, void* dest); |
|
110 static bool parse_uchar (const char* str, int n, void* dest); |
|
111 static bool parse_float (const char* str, int n, void* dest); |
|
112 static bool parse_double (const char* str, int n, void* dest); |
|
113 static bool parse_string (const char* str, int n, void* dest); |
|
114 static bool parse_stringpiece (const char* str, int n, void* dest); |
|
115 |
|
116 #define PCRE_DECLARE_INTEGER_PARSER(name) \ |
|
117 private: \ |
|
118 static bool parse_ ## name(const char* str, int n, void* dest); \ |
|
119 static bool parse_ ## name ## _radix( \ |
|
120 const char* str, int n, void* dest, int radix); \ |
|
121 public: \ |
|
122 static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \ |
|
123 static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \ |
|
124 static bool parse_ ## name ## _cradix(const char* str, int n, void* dest) |
|
125 |
|
126 PCRE_DECLARE_INTEGER_PARSER(short); |
|
127 PCRE_DECLARE_INTEGER_PARSER(ushort); |
|
128 PCRE_DECLARE_INTEGER_PARSER(int); |
|
129 PCRE_DECLARE_INTEGER_PARSER(uint); |
|
130 PCRE_DECLARE_INTEGER_PARSER(long); |
|
131 PCRE_DECLARE_INTEGER_PARSER(ulong); |
|
132 PCRE_DECLARE_INTEGER_PARSER(longlong); |
|
133 PCRE_DECLARE_INTEGER_PARSER(ulonglong); |
|
134 |
|
135 #undef PCRE_DECLARE_INTEGER_PARSER |
|
136 }; |
|
137 |
|
138 inline Arg::Arg() : arg_(NULL), parser_(parse_null) { } |
|
139 inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { } |
|
140 |
|
141 inline bool Arg::Parse(const char* str, int n) const { |
|
142 return (*parser_)(str, n, arg_); |
|
143 } |
|
144 |
|
145 // This part of the parser, appropriate only for ints, deals with bases |
|
146 #define MAKE_INTEGER_PARSER(type, name) \ |
|
147 inline Arg Hex(type* ptr) { \ |
|
148 return Arg(ptr, Arg::parse_ ## name ## _hex); } \ |
|
149 inline Arg Octal(type* ptr) { \ |
|
150 return Arg(ptr, Arg::parse_ ## name ## _octal); } \ |
|
151 inline Arg CRadix(type* ptr) { \ |
|
152 return Arg(ptr, Arg::parse_ ## name ## _cradix); } |
|
153 |
|
154 MAKE_INTEGER_PARSER(short, short) /* */ |
|
155 MAKE_INTEGER_PARSER(unsigned short, ushort) /* */ |
|
156 MAKE_INTEGER_PARSER(int, int) /* Don't use semicolons */ |
|
157 MAKE_INTEGER_PARSER(unsigned int, uint) /* after these statement */ |
|
158 MAKE_INTEGER_PARSER(long, long) /* because they can cause */ |
|
159 MAKE_INTEGER_PARSER(unsigned long, ulong) /* compiler warnings if */ |
|
160 #if @pcre_have_long_long@ /* the checking level is */ |
|
161 MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */ |
|
162 #endif /* */ |
|
163 #if @pcre_have_ulong_long@ /* */ |
|
164 MAKE_INTEGER_PARSER(unsigned long long, ulonglong) /* */ |
|
165 #endif |
|
166 |
|
167 #undef PCRE_IS_SET |
|
168 #undef PCRE_SET_OR_CLEAR |
|
169 #undef MAKE_INTEGER_PARSER |
|
170 |
|
171 } // namespace pcrecpp |
|
172 |
|
173 |
|
174 #endif /* _PCRECPPARG_H */ |