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 40namespace pcrecpp { 41 42class StringPiece; 43 44// Hex/Octal/Binary? 45 46// Special class for parsing into objects that define a ParseFrom() method 47template <class T> 48class _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 57class 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 134inline Arg::Arg() : arg_(NULL), parser_(parse_null) { } 135inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { } 136 137inline 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 150MAKE_INTEGER_PARSER(short, short) /* */ 151MAKE_INTEGER_PARSER(unsigned short, ushort) /* */ 152MAKE_INTEGER_PARSER(int, int) /* Don't use semicolons */ 153MAKE_INTEGER_PARSER(unsigned int, uint) /* after these statement */ 154MAKE_INTEGER_PARSER(long, long) /* because they can cause */ 155MAKE_INTEGER_PARSER(unsigned long, ulong) /* compiler warnings if */ 156MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */ 157MAKE_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