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 PCRE_MAKE_PARSER(long long, parse_longlong); 82 PCRE_MAKE_PARSER(unsigned long long, parse_ulonglong); 83 PCRE_MAKE_PARSER(float, parse_float); 84 PCRE_MAKE_PARSER(double, parse_double); 85 PCRE_MAKE_PARSER(std::string, parse_string); 86 PCRE_MAKE_PARSER(StringPiece, parse_stringpiece); 87 88 #undef PCRE_MAKE_PARSER 89 90 // Generic constructor 91 template <class T> Arg(T*, Parser parser); 92 // Generic constructor template 93 template <class T> Arg(T* p) 94 : arg_(p), parser_(_RE_MatchObject<T>::Parse) { 95 } 96 97 // Parse the data 98 bool Parse(const char* str, int n) const; 99 100 private: 101 void* arg_; 102 Parser parser_; 103 104 static bool parse_null (const char* str, int n, void* dest); 105 static bool parse_char (const char* str, int n, void* dest); 106 static bool parse_uchar (const char* str, int n, void* dest); 107 static bool parse_float (const char* str, int n, void* dest); 108 static bool parse_double (const char* str, int n, void* dest); 109 static bool parse_string (const char* str, int n, void* dest); 110 static bool parse_stringpiece (const char* str, int n, void* dest); 111 112 #define PCRE_DECLARE_INTEGER_PARSER(name) \ 113 private: \ 114 static bool parse_ ## name(const char* str, int n, void* dest); \ 115 static bool parse_ ## name ## _radix( \ 116 const char* str, int n, void* dest, int radix); \ 117 public: \ 118 static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \ 119 static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \ 120 static bool parse_ ## name ## _cradix(const char* str, int n, void* dest) 121 122 PCRE_DECLARE_INTEGER_PARSER(short); 123 PCRE_DECLARE_INTEGER_PARSER(ushort); 124 PCRE_DECLARE_INTEGER_PARSER(int); 125 PCRE_DECLARE_INTEGER_PARSER(uint); 126 PCRE_DECLARE_INTEGER_PARSER(long); 127 PCRE_DECLARE_INTEGER_PARSER(ulong); 128 PCRE_DECLARE_INTEGER_PARSER(longlong); 129 PCRE_DECLARE_INTEGER_PARSER(ulonglong); 130 131 #undef PCRE_DECLARE_INTEGER_PARSER 132 }; 133 134 inline Arg::Arg() : arg_(NULL), parser_(parse_null) { } 135 inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { } 136 137 inline bool Arg::Parse(const char* str, int n) const { 138 return (*parser_)(str, n, arg_); 139 } 140 141 // This part of the parser, appropriate only for ints, deals with bases 142 #define MAKE_INTEGER_PARSER(type, name) \ 143 inline Arg Hex(type* ptr) { \ 144 return Arg(ptr, Arg::parse_ ## name ## _hex); } \ 145 inline Arg Octal(type* ptr) { \ 146 return Arg(ptr, Arg::parse_ ## name ## _octal); } \ 147 inline Arg CRadix(type* ptr) { \ 148 return Arg(ptr, Arg::parse_ ## name ## _cradix); } 149 150 MAKE_INTEGER_PARSER(short, short) /* */ 151 MAKE_INTEGER_PARSER(unsigned short, ushort) /* */ 152 MAKE_INTEGER_PARSER(int, int) /* Don't use semicolons */ 153 MAKE_INTEGER_PARSER(unsigned int, uint) /* after these statement */ 154 MAKE_INTEGER_PARSER(long, long) /* because they can cause */ 155 MAKE_INTEGER_PARSER(unsigned long, ulong) /* compiler warnings if */ 156 MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */ 157 MAKE_INTEGER_PARSER(unsigned long long, ulonglong) /* */ 158 159 #undef PCRE_IS_SET 160 #undef PCRE_SET_OR_CLEAR 161 #undef MAKE_INTEGER_PARSER 162 163 } // namespace pcrecpp 164 165 166 #endif /* _PCRECPPARG_H */ 167 168