MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Parser.hpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef CPCD_PARSER_HPP
19 #define CPCD_PARSER_HPP
20 
21 #include "Vector.hpp"
22 #include "Properties.hpp"
23 #include "InputStream.hpp"
24 
25 class ParserImpl;
26 template<class T> struct ParserRow;
27 
28 //#define PARSER_DEBUG
29 #ifdef PARSER_DEBUG
30 #include "NdbOut.hpp"
31 #define DEBUG(x) \
32  ndbout_c("%s:%d:%s", __FILE__, __LINE__, x);
33 #else
34 #define DEBUG(x)
35 #endif
36 
40 template<class T>
41 class Parser {
42 public:
46  enum ParserStatus {
47  Ok = 0,
48  Eof = 1,
49  NoLine = 2,
50  EmptyLine = 3,
51  UnknownCommand = 4,
52  UnknownArgument = 5,
53  TypeMismatch = 6,
54  InvalidArgumentFormat = 7,
55  UnknownArgumentType = 8,
56  CommandWithoutFunction = 9,
57  ArgumentGivenTwice = 10,
58  ExternalStop = 11,
59  MissingMandatoryArgument = 12
60  };
61 
65  class Context {
66  public:
67  Context() { m_mutex= NULL; };
68  ParserStatus m_status;
69  const ParserRow<T> * m_currentCmd;
70  const ParserRow<T> * m_currentArg;
71  char * m_currentToken;
72  STATIC_CONST(MaxParseBytes = 512);
73  char m_tokenBuffer[ MaxParseBytes ];
74  NdbMutex *m_mutex;
75 
76  Vector<const ParserRow<T> *> m_aliasUsed;
77  };
78 
82  Parser(const ParserRow<T> rows[], class InputStream & in = Stdin,
83  bool breakOnCommand = false,
84  bool breakOnEmptyLine = true,
85  bool breakOnInvalidArg = false);
86  ~Parser();
87 
91  bool run(Context &, T &, volatile bool * stop = 0) const;
92 
97  const Properties *parse(Context &, T &);
98 
99  bool getBreakOnCommand() const;
100  void setBreakOnCommand(bool v);
101 
102  bool getBreakOnEmptyLine() const;
103  void setBreakOnEmptyLine(bool v);
104 
105  bool getBreakOnInvalidArg() const;
106  void setBreakOnInvalidArg(bool v);
107 
108 private:
109  ParserImpl * impl;
110 };
111 
112 template<class T>
113 struct ParserRow {
114 public:
115  enum Type { Cmd, Arg, CmdAlias, ArgAlias };
116  enum ArgType { String, Int, Properties };
117  enum ArgRequired { Mandatory, Optional };
118  enum ArgMinMax { CheckMinMax, IgnoreMinMax };
119 
120  const char * name;
121  const char * realName;
122  Type type;
123  ArgType argType;
124  ArgRequired argRequired;
125  ArgMinMax argMinMax;
126  int minVal;
127  int maxVal;
128  void (T::* function)(typename Parser<T>::Context & ctx,
129  const class Properties& args);
130  const char * description;
131  void *user_value;
132 };
133 
137 class ParserImpl {
138 public:
139  class Dummy {};
140  typedef ParserRow<Dummy> DummyRow;
142 
143 
144  ParserImpl(const DummyRow rows[], class InputStream & in,
145  bool b_cmd, bool b_empty, bool b_iarg);
146  ~ParserImpl();
147 
148  bool run(Context *ctx, const class Properties **, volatile bool *) const ;
149 
150  static const DummyRow* matchCommand(Context*, const char*, const DummyRow*);
151  static const DummyRow* matchArg(Context*, const char *, const DummyRow *);
152  static bool parseArg(Context*, char*, const DummyRow*, Properties*);
153  static bool checkMandatory(Context*, const Properties*);
154 private:
155  const DummyRow * const m_rows;
156  class ParseInputStream & input;
157  bool m_breakOnEmpty;
158  bool m_breakOnCmd;
159  bool m_breakOnInvalidArg;
160 };
161 
162 template<class T>
163 inline
164 Parser<T>::Parser(const ParserRow<T> rows[], class InputStream & in,
165  bool b_cmd, bool b_empty, bool b_iarg){
166  impl = new ParserImpl((ParserImpl::DummyRow *)rows, in,
167  b_cmd, b_empty, b_iarg);
168 }
169 
170 template<class T>
171 inline
173  delete impl;
174 }
175 
176 template<class T>
177 inline
178 bool
179 Parser<T>::run(Context & ctx, T & t, volatile bool * stop) const {
180  const Properties * p;
181  DEBUG("Executing Parser<T>::run");
182  if(impl->run((ParserImpl::Context*)&ctx, &p, stop)){
183  const ParserRow<T> * cmd = ctx.m_currentCmd; // Cast to correct type
184  if(cmd == 0){
188  abort();
189  }
190 
191  for(unsigned i = 0; i<ctx.m_aliasUsed.size(); i++){
192  const ParserRow<T> * alias = ctx.m_aliasUsed[i];
193  if(alias->function != 0){
197  DEBUG("Alias usage with callback");
198  (t.* alias->function)(ctx, * p);
199  }
200  }
201 
202  if(cmd->function == 0){
203  ctx.m_status = CommandWithoutFunction;
204  DEBUG("CommandWithoutFunction");
205  delete p;
206  return false;
207  }
208  (t.* cmd->function)(ctx, * p); // Call the function
209  delete p;
210  return true;
211  }
212  DEBUG("");
213  return false;
214 }
215 
216 template<class T>
217 inline
218 const Properties *
220  const Properties * p;
221  volatile bool stop = false;
222  DEBUG("Executing Parser<T>::parse");
223 
224  if(impl->run((ParserImpl::Context*)&ctx, &p, &stop)){
225  const ParserRow<T> * cmd = ctx.m_currentCmd; // Cast to correct type
226  if(cmd == 0){
230  abort();
231  }
232 
233  for(unsigned i = 0; i<ctx.m_aliasUsed.size(); i++){
234  const ParserRow<T> * alias = ctx.m_aliasUsed[i];
235  if(alias->function != 0){
239  DEBUG("Alias usage with callback");
240  (t.* alias->function)(ctx, * p);
241  }
242  }
243 
244  if(cmd->function == 0){
245  DEBUG("CommandWithoutFunction");
246  ctx.m_status = CommandWithoutFunction;
247  return p;
248  }
249  return p;
250  }
251  DEBUG("");
252  return NULL;
253 }
254 
255 template<class T>
256 inline
257 bool
259  return impl->m_breakOnCmd;
260 }
261 
262 template<class T>
263 inline
264 void
266  impl->m_breakOnCmd = v;
267 }
268 
269 template<class T>
270 inline
271 bool
273  return impl->m_breakOnEmpty;
274 }
275 template<class T>
276 inline
277 void
279  impl->m_breakOnEmpty = v;
280 }
281 
282 template<class T>
283 inline
284 bool
286  return impl->m_breakOnInvalidArg;
287 }
288 
289 template<class T>
290 inline
291 void
293  impl->m_breakOnInvalidArg = v;
294 }
295 
296 #endif