libosmscout  1.1.1
CmdLineParsing.h
Go to the documentation of this file.
1 #ifndef OSMSCOUT_UTIL_CMDLINEPARSING_H
2 #define OSMSCOUT_UTIL_CMDLINEPARSING_H
3 
4 /*
5  This source is part of the libosmscout library
6  Copyright (C) 2017 Tim Teulings
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22 
23 #include <functional>
24 #include <map>
25 #include <memory>
26 #include <string>
27 #include <vector>
28 
30 
31 #include <osmscout/GeoCoord.h>
32 
33 #include <osmscout/util/String.h>
34 
35 namespace osmscout {
36 
38  {
39  private:
40  std::vector<std::string> arguments;
41  size_t nextArg;
42 
43  public:
44  CmdLineScanner(int argc, char* argv[]); // NOLINT
45 
46  explicit CmdLineScanner(const std::vector<std::string>& arguments);
47 
48  bool HasNextArg() const;
49  std::string PeakNextArg() const;
50  std::string Advance();
51  std::string GetCurrentArg() const;
52  };
53 
54 
56  {
57  private:
58  bool hasError;
59  std::string errorDescription;
60 
61  public:
63 
64  explicit CmdLineParseResult(const std::string& errorDescription);
65 
66  bool Success() const;
67  bool HasError() const;
68 
69  std::string GetErrorDescription() const;
70  };
71 
73  {
74  private:
75  std::string optionName; //<! The unqualified option name
76  std::string argumentName; //<! The actual command line argument name
77 
78  protected:
79  std::string GetOptionName() const;
80  std::string GetArgumentName() const;
81 
82  public:
83  virtual ~CmdLineArgParser()=default;
84 
85  void SetOptionName(const std::string& optionName);
86  void SetArgumentName(const std::string& argumentName);
87 
88  virtual std::string GetOptionHint() const = 0;
89  virtual std::string GetPositionalHint(const std::string& positional) const = 0;
90  virtual CmdLineParseResult Parse(CmdLineScanner& scanner) = 0;
91  };
92 
93  using CmdLineArgParserRef = std::shared_ptr<CmdLineArgParser>;
94 
96  {
97  public:
98  using SetterFunction = std::function<void (const bool &)>;
99 
100  private:
101  SetterFunction setter;
102 
103  public:
104  explicit CmdLineFlagArgParser(SetterFunction&& setter);
105 
106  std::string GetOptionHint() const override;
107  std::string GetPositionalHint(const std::string& positional) const override;
108 
109  CmdLineParseResult Parse(CmdLineScanner& scanner) override;
110  };
111 
113  {
114  public:
115  using SetterFunction = std::function<void (const std::string &)>;
116 
117  private:
118  SetterFunction setter;
119  std::string lastArgumentCalled;
120 
121  public:
123 
124  std::string GetOptionHint() const override;
125  std::string GetPositionalHint(const std::string& positional) const override;
126 
127  CmdLineParseResult Parse(CmdLineScanner& scanner) override;
128  };
129 
131  {
132  public:
133  using SetterFunction = std::function<void (const bool &)>;
134 
135  private:
136  SetterFunction setter;
137 
138  public:
139  explicit CmdLineBoolArgParser(SetterFunction&& setter);
140 
141  std::string GetOptionHint() const override;
142  std::string GetPositionalHint(const std::string& positional) const override;
143 
144  CmdLineParseResult Parse(CmdLineScanner& scanner) override;
145  };
146 
148  {
149  public:
150  using SetterFunction = std::function<void (const std::string &)>;
151 
152  private:
153  SetterFunction setter;
154 
155  public:
156  explicit CmdLineStringArgParser(SetterFunction&& setter);
157 
158  std::string GetOptionHint() const override;
159  std::string GetPositionalHint(const std::string& positional) const override;
160 
161  CmdLineParseResult Parse(CmdLineScanner& scanner) override;
162  };
163 
165  {
166  public:
167  using AppendFunction = std::function<void (const std::string &)>;
168 
169  private:
170  AppendFunction appender;
171 
172  public:
173  explicit CmdLineStringListArgParser(AppendFunction&& appender);
174 
175  std::string GetOptionHint() const override;
176  std::string GetPositionalHint(const std::string& positional) const override;
177 
178  CmdLineParseResult Parse(CmdLineScanner& scanner) override;
179  };
180 
181  template<typename N>
183  {
184  public:
185  using SetterFunction = std::function<void (const N &)>;
186 
187  private:
188  SetterFunction setter;
189 
190  public:
192  : setter(setter)
193  {
194  // no code
195  }
196 
197  std::string GetOptionHint() const override
198  {
199  return "number";
200  }
201 
202  std::string GetPositionalHint(const std::string& positional) const override
203  {
204  return positional;
205  }
206 
208  {
209  if (!scanner.HasNextArg()) {
210  return CmdLineParseResult("Missing value for number argument '"+GetArgumentName()+"'");
211  }
212 
213  std::string valueString=scanner.Advance();
214  N value;
215 
216  if (StringToNumber(valueString,value)) {
217  setter(value);
218  return CmdLineParseResult();
219  }
220 
221  return CmdLineParseResult("Value for number argument '"+GetArgumentName()+"' is not a valid number '"+valueString+"'");
222  }
223  };
224 
226  {
227  public:
228  using SetterFunction = std::function<void (const GeoCoord &)>;
229 
230  private:
231  SetterFunction setter;
232 
233  public:
234  explicit CmdLineGeoCoordArgParser(SetterFunction&& setter);
235 
236  std::string GetOptionHint() const override;
237  std::string GetPositionalHint(const std::string& positional) const override;
238 
239  CmdLineParseResult Parse(CmdLineScanner& scanner) override;
240  };
241 
242  template<class ...Args>
244  {
245  return std::make_shared<CmdLineFlagArgParser>(std::forward<Args>(args)...);
246  }
247 
248  template<class ...Args>
250  {
251  return std::make_shared<CmdLineAlternativeFlagArgParser>(std::forward<Args>(args)...);
252  }
253 
254  template<class ...Args>
256  {
257  return std::make_shared<CmdLineBoolArgParser>(std::forward<Args>(args)...);
258  }
259 
260  template<class ...Args>
262  {
263  return std::make_shared<CmdLineStringArgParser>(std::forward<Args>(args)...);
264  }
265 
266  template<class ...Args>
268  {
269  return std::make_shared<CmdLineStringListArgParser>(std::forward<Args>(args)...);
270  }
271 
272  template<class T, class ...Args>
274  {
275  return std::make_shared<CmdLineNumberArgParser<T>>(std::forward<Args>(args)...);
276  }
277 
278  template<class ...Args>
280  {
281  return std::make_shared<CmdLineNumberArgParser<int>>(std::forward<Args>(args)...);
282  }
283 
284  template<class ...Args>
286  {
287  return std::make_shared<CmdLineNumberArgParser<unsigned int>>(std::forward<Args>(args)...);
288  }
289 
290  template<class ...Args>
292  {
293  return std::make_shared<CmdLineNumberArgParser<long>>(std::forward<Args>(args)...);
294  }
295 
296  template<class ...Args>
298  {
299  return std::make_shared<CmdLineNumberArgParser<unsigned long>>(std::forward<Args>(args)...);
300  }
301 
302  template<class ...Args>
304  {
305  return std::make_shared<CmdLineNumberArgParser<size_t>>(std::forward<Args>(args)...);
306  }
307 
308  template<class ...Args>
310  {
311  return std::make_shared<CmdLineNumberArgParser<double>>(std::forward<Args>(args)...);
312  }
313 
314  template<class ...Args>
316  {
317  return std::make_shared<CmdLineGeoCoordArgParser>(std::forward<Args>(args)...);
318  }
319 
321  {
322  private:
323  struct CmdLineOption
324  {
325  CmdLineArgParserRef parser;
326  std::string option;
327  std::string argument;
328  bool stopParsing;
329 
330  CmdLineOption(const CmdLineArgParserRef& parser,
331  const std::string& option,
332  const std::string& argument,
333  bool stopParsing)
334  : parser(parser),
335  option(option),
336  argument(argument),
337  stopParsing(stopParsing)
338  {
339  // no code
340  }
341  };
342 
343  struct CmdLinePositional
344  {
345  CmdLineArgParserRef parser;
346  std::string positional;
347 
348  CmdLinePositional(const CmdLineArgParserRef& parser,
349  const std::string& positional)
350  : parser(parser),
351  positional(positional)
352  {
353  // no code
354  }
355  };
356 
357  struct CmdLineArgHelp
358  {
359  std::vector<std::string> argTemplates;
360  std::string helpString;
361 
362  CmdLineArgHelp(const std::string& argTemplate,
363  const std::string& helpString)
364  : helpString(helpString)
365  {
366  argTemplates.push_back(argTemplate);
367  }
368 
369  CmdLineArgHelp(const std::vector<std::string>& argTemplates,
370  const std::string& helpString)
371  : argTemplates(argTemplates),
372  helpString(helpString)
373  {
374  // no code
375  }
376  };
377 
378  private:
379  std::string appName;
380  CmdLineScanner scanner;
381 
382  std::map<std::string,CmdLineOption> options;
383  std::list<CmdLinePositional> positionals;
384  std::list<CmdLineArgHelp> optionHelps;
385  std::list<CmdLineArgHelp> positionalHelps;
386 
387  public:
388  CmdLineParser(const std::string& appName,
389  int argc, char* argv[]); // NOLINT
390  CmdLineParser(const std::string& appName,
391  const std::vector<std::string>& arguments);
392 
393  void AddOption(const CmdLineArgParserRef& parser,
394  const std::string& optionName,
395  const std::string& helpString,
396  bool stopParsing=false);
397 
398  void AddOption(const CmdLineArgParserRef& parser,
399  const std::vector<std::string>& optionNames,
400  const std::string& helpString,
401  bool stopParsing=false);
402 
403  void AddPositional(const CmdLineArgParserRef& parser,
404  const std::string& helpString,
405  const std::string& argumentName);
406 
407  CmdLineParseResult Parse();
408 
409  std::string GetHelp(size_t indent=2) const;
410  };
411 
412  extern OSMSCOUT_API bool ParseBoolArgument(int argc,
413  char* argv[], // NOLINT
414  int& currentIndex,
415  bool& value);
416 
417  extern OSMSCOUT_API bool ParseStringArgument(int argc,
418  char* argv[], // NOLINT
419  int& currentIndex,
420  std::string& value);
421 
422  extern OSMSCOUT_API bool ParseSizeTArgument(int argc,
423  char* argv[], // NOLINT
424  int& currentIndex,
425  size_t& value);
426  extern OSMSCOUT_API bool ParseUInt32Argument(int argc,
427  char* argv[], // NOLINT
428  int& currentIndex,
429  uint32_t& value);
430 }
431 
432 #endif
CmdLineArgParserRef CmdLineAlternativeFlag(Args &&...args)
Definition: CmdLineParsing.h:249
CmdLineArgParserRef CmdLineBoolOption(Args &&...args)
Definition: CmdLineParsing.h:255
CmdLineArgParserRef CmdLineNumberOption(Args &&...args)
Definition: CmdLineParsing.h:273
bool StringToNumber(const std::string &string, N &number, size_t base=10)
Definition: String.h:282
Definition: CmdLineParsing.h:95
CmdLineArgParserRef CmdLineFlag(Args &&...args)
Definition: CmdLineParsing.h:243
Definition: CmdLineParsing.h:55
Definition: CmdLineParsing.h:182
CmdLineArgParserRef CmdLineStringOption(Args &&...args)
Definition: CmdLineParsing.h:261
std::string GetArgumentName() const
Definition: CmdLineParsing.h:112
std::function< void(const std::string &)> AppendFunction
Definition: CmdLineParsing.h:167
std::shared_ptr< CmdLineArgParser > CmdLineArgParserRef
Definition: CmdLineParsing.h:93
CmdLineArgParserRef CmdLineLongOption(Args &&...args)
Definition: CmdLineParsing.h:291
std::string GetPositionalHint(const std::string &positional) const override
Definition: CmdLineParsing.h:202
std::string GetOptionHint() const override
Definition: CmdLineParsing.h:197
Definition: CmdLineParsing.h:130
OSMSCOUT_API bool ParseBoolArgument(int argc, char *argv[], int &currentIndex, bool &value)
Definition: Area.h:38
Definition: CmdLineParsing.h:164
CmdLineArgParserRef CmdLineUIntOption(Args &&...args)
Definition: CmdLineParsing.h:285
#define OSMSCOUT_API
Definition: CoreImportExport.h:45
CmdLineArgParserRef CmdLineULongOption(Args &&...args)
Definition: CmdLineParsing.h:297
std::function< void(const GeoCoord &)> SetterFunction
Definition: CmdLineParsing.h:228
Definition: CmdLineParsing.h:72
std::function< void(const bool &)> SetterFunction
Definition: CmdLineParsing.h:133
std::function< void(const std::string &)> SetterFunction
Definition: CmdLineParsing.h:150
Definition: CmdLineParsing.h:37
CmdLineArgParserRef CmdLineSizeTOption(Args &&...args)
Definition: CmdLineParsing.h:303
Definition: CmdLineParsing.h:225
std::function< void(const bool &)> SetterFunction
Definition: CmdLineParsing.h:98
std::function< void(const std::string &)> SetterFunction
Definition: CmdLineParsing.h:115
Definition: CmdLineParsing.h:147
CmdLineArgParserRef CmdLineGeoCoordOption(Args &&...args)
Definition: CmdLineParsing.h:315
CmdLineArgParserRef CmdLineDoubleOption(Args &&...args)
Definition: CmdLineParsing.h:309
OSMSCOUT_API bool ParseStringArgument(int argc, char *argv[], int &currentIndex, std::string &value)
OSMSCOUT_API bool ParseUInt32Argument(int argc, char *argv[], int &currentIndex, uint32_t &value)
OSMSCOUT_API bool ParseSizeTArgument(int argc, char *argv[], int &currentIndex, size_t &value)
CmdLineArgParserRef CmdLineIntOption(Args &&...args)
Definition: CmdLineParsing.h:279
CmdLineParseResult Parse(CmdLineScanner &scanner) override
Definition: CmdLineParsing.h:207
CmdLineArgParserRef CmdLineStringListOption(Args &&...args)
Definition: CmdLineParsing.h:267
Definition: CmdLineParsing.h:320
CmdLineNumberArgParser(SetterFunction &&setter)
Definition: CmdLineParsing.h:191
std::function< void(const N &)> SetterFunction
Definition: CmdLineParsing.h:185