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 1 82 PCRE_MAKE_PARSER(long long, parse_longlong); 83 #endif 84 #if 1 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 1 /* the checking level is */ 161 MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */ 162 #endif /* */ 163 #if 1 /* */ 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 */ 175