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#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 138inline Arg::Arg() : arg_(NULL), parser_(parse_null) { } 139inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { } 140 141inline 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 154MAKE_INTEGER_PARSER(short, short) /* */ 155MAKE_INTEGER_PARSER(unsigned short, ushort) /* */ 156MAKE_INTEGER_PARSER(int, int) /* Don't use semicolons */ 157MAKE_INTEGER_PARSER(unsigned int, uint) /* after these statement */ 158MAKE_INTEGER_PARSER(long, long) /* because they can cause */ 159MAKE_INTEGER_PARSER(unsigned long, ulong) /* compiler warnings if */ 160#if @pcre_have_long_long@ /* the checking level is */ 161MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */ 162#endif /* */ 163#if @pcre_have_ulong_long@ /* */ 164MAKE_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