CLRX  1
An unofficial OpenCL extensions designed for Radeon GPUs
CLIParser.h
Go to the documentation of this file.
1 /*
2  * CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3  * Copyright (C) 2014-2016 Mateusz Szpakowski
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
23 #ifndef __CLRX_CLIPARSER_H__
24 #define __CLRX_CLIPARSER_H__
25 
26 #include <CLRX/Config.h>
27 #include <exception>
28 #include <string>
29 #include <vector>
30 #include <ostream>
31 #include <iostream>
32 #include <memory>
33 #include <CLRX/utils/Utilities.h>
34 #include <CLRX/utils/Containers.h>
35 
37 namespace CLRX
38 {
40 #define CLRX_CLI_AUTOHELP \
41  { "help", '?', CLIArgType::NONE, false, false, "print help", nullptr }, \
42  { "usage", 0, CLIArgType::NONE, false, false, "print usage", nullptr }, \
43  { "version", 0, CLIArgType::NONE, false, false, "print version", nullptr },
44 
45 /*
46  * CommandLine Interface
47  */
48 
50 enum class CLIArgType: cxuchar
51 {
52  NONE = 0,
53  BOOL, UINT, INT, UINT64, INT64, SIZE, FLOAT, DOUBLE, STRING,
55  SINGLE_MAX = TRIMMED_STRING,
56  BOOL_ARRAY = 32,
57  UINT_ARRAY, INT_ARRAY, UINT64_ARRAY, INT64_ARRAY, SIZE_ARRAY, FLOAT_ARRAY,
58  DOUBLE_ARRAY, STRING_ARRAY,
60  ARRAY_MAX = TRIMMED_STRING_ARRAY
61 };
62 
64 struct CLIOption
65 {
66  const char* longName;
67  char shortName;
70 
73 
74  const char* description;
75  const char* argName;
76 };
77 
79 class CLIException: public Exception
80 {
81 public:
83  CLIException() = default;
85  explicit CLIException(const std::string& message);
87  CLIException(const std::string& message, char shortName);
89  CLIException(const std::string& message, const std::string& longName);
91  CLIException(const std::string& message, const CLIOption& option,
92  bool chooseShortName);
94  virtual ~CLIException() noexcept = default;
95 };
96 
98 
122 {
123 private:
124  template<typename T>
125  struct OptTypeTrait { static const CLIArgType type; };
126 
128 
129  struct OptionEntry
130  {
131  bool isSet;
132  bool isArg;
133 
135  union Value {
136  bool b;
137  cxint i;
138  cxuint u;
139  cxlong li;
140  cxulong lu;
141  cxllong lli;
142  cxullong llu;
143  int32_t i32;
144  uint32_t u32;
145  int64_t i64;
146  uint64_t u64;
147  size_t size;
148  float f;
149  double d;
150  const char* s;
151  bool* bArr;
152  cxint* iArr;
153  cxuint* uArr;
154  cxlong* liArr;
155  cxulong* luArr;
156  cxllong* lliArr;
157  cxullong* lluArr;
158  int32_t* i32Arr;
159  uint32_t* u32Arr;
160  int64_t* i64Arr;
161  uint64_t* u64Arr;
162  size_t* sizeArr;
163  float* fArr;
164  double* dArr;
165  const char** sArr;
166 
168  operator bool() const { return b; }
170  operator cxint() const { return i; }
172  operator cxuint() const { return u; }
174  operator cxlong() const { return li; }
176  operator cxulong() const { return lu; }
178  operator cxllong() const { return lli; }
180  operator cxullong() const { return llu; }
182  operator float() const { return f; }
184  operator double() const { return d; }
186  operator const char*() const { return s; }
187 
189  operator const bool*() const { return bArr; }
191  operator const cxint*() const { return iArr; }
193  operator const cxuint*() const { return uArr; }
195  operator const cxlong*() const { return liArr; }
197  operator const cxulong*() const { return luArr; }
199  operator const cxllong*() const { return lliArr; }
201  operator const cxullong*() const { return lluArr; }
203  operator const float*() const { return fArr; }
205  operator const double*() const { return dArr; }
207  operator const char**() const { return sArr; }
208  };
209  Value v;
210  size_t arrSize;
211  OptionEntry() : isSet(false), isArg(false), arrSize(0)
212  { ::memset(&v, 0, sizeof(v)); /* use memset, workaround for CLang++ */ }
213  };
214 
215  const CLIOption* options;
216  const char* programName;
217  const char* packageName;
218  cxuint argc;
219  const char** argv;
220  std::vector<const char*> leftOverArgs;
221 
222  Array<OptionEntry> optionEntries;
223  LongNameMap longNameMap;
224  std::unique_ptr<cxuint[]> shortNameMap;
225 
226  void handleExceptionsForGetOptArg(cxuint optionId, CLIArgType argType) const;
227  void parseOptionArg(cxuint optionId, const char* optArg, bool chooseShortName);
228 
229 public:
231 
237  CLIParser(const char* programName, const CLIOption* options,
238  cxuint argc, const char** argv);
239  ~CLIParser();
240 
242  void setPackageName(const char* pkgName)
243  { packageName = pkgName; }
244 
246  void parse();
247 
249  bool handleHelpOrUsage(std::ostream& os = std::cout) const;
250 
252  cxuint findOption(char shortName) const;
253 
255  cxuint findOption(const char* longName) const;
256 
258  template<typename T>
259  T getOptArg(cxuint optionId) const
260  {
261  handleExceptionsForGetOptArg(optionId, OptTypeTrait<T>::type);
262  return static_cast<T>(optionEntries[optionId].v);
263  }
264 
266  template<typename T>
267  T getShortOptArg(char shortName) const
268  { return getOptArg<T>(findOption(shortName)); }
269 
271  template<typename T>
272  T getLongOptArg(const char* longName) const
273  { return getOptArg<T>(findOption(longName)); }
274 
276 
281  template<typename T>
282  const T* getOptArgArray(cxuint optionId, size_t& length) const
283  {
284  handleExceptionsForGetOptArg(optionId, OptTypeTrait<T*>::type);
285  const OptionEntry& optEntry = optionEntries[optionId];
286  length = optEntry.arrSize;
287  return static_cast<const T*>(optEntry.v);
288  }
289 
291 
296  template<typename T>
297  const T* getShortOptArgArray(char shortName, size_t& length) const
298  { return getOptArgArray<T>(findOption(shortName), length); }
299 
301 
306  template<typename T>
307  const T* getLongOptArgArray(const char* longName, size_t& length) const
308  { return getOptArgArray<T>(findOption(longName), length); }
309 
311  bool hasOptArg(cxuint optionId) const
312  {
313  if (optionId >= optionEntries.size())
314  throw CLIException("No such command line option!");
315  return optionEntries[optionId].isArg;
316  }
317 
319  bool hasShortOptArg(char shortName) const
320  { return hasOptArg(findOption(shortName)); }
321 
323  bool hasLongOptArg(const char* longName) const
324  { return hasOptArg(findOption(longName)); }
325 
327  bool hasOption(cxuint optionId) const
328  {
329  if (optionId >= optionEntries.size())
330  throw CLIException("No such command line option!");
331  return optionEntries[optionId].isSet;
332  }
333 
335  bool hasShortOption(char shortName) const
336  { return hasOption(findOption(shortName)); }
337 
339  bool hasLongOption(const char* longName) const
340  { return hasOption(findOption(longName)); }
341 
343  cxuint getArgsNum() const
344  { return leftOverArgs.size()-1; }
346  const char* const* getArgs() const
347  { return leftOverArgs.data(); }
348 
350  void printHelp(std::ostream& os = std::cout) const;
352  void printUsage(std::ostream& os = std::cout) const;
354  void printVersion(std::ostream& os = std::cout) const;
355 };
356 
358 template<>
359 struct CLIParser::OptTypeTrait<bool> {
360 static const CLIArgType type = CLIArgType::BOOL;
361 };
362 
364 template<>
365 struct CLIParser::OptTypeTrait<cxuint> {
366 static const CLIArgType type = CLIArgType::UINT;
367 };
368 
370 template<>
371 struct CLIParser::OptTypeTrait<cxint> {
372 static const CLIArgType type = CLIArgType::INT;
373 };
374 
376 template<>
377 struct CLIParser::OptTypeTrait<cxulong> {
379 static const CLIArgType type = (sizeof(cxulong)==8)?CLIArgType::UINT64:CLIArgType::UINT; };
380 
382 template<>
383 struct CLIParser::OptTypeTrait<cxlong> {
385 static const CLIArgType type = (sizeof(cxlong)==8)?CLIArgType::INT64:CLIArgType::INT; };
386 
388 template<>
389 struct CLIParser::OptTypeTrait<cxullong> {
390 static const CLIArgType type = CLIArgType::UINT64;
391 };
392 
394 template<>
395 struct CLIParser::OptTypeTrait<cxllong> {
396 static const CLIArgType type = CLIArgType::INT64;
397 };
398 
400 template<>
401 struct CLIParser::OptTypeTrait<float> {
402 static const CLIArgType type = CLIArgType::FLOAT;
403 };
404 
406 template<>
407 struct CLIParser::OptTypeTrait<double> {
408 static const CLIArgType type = CLIArgType::DOUBLE;
409 };
410 
412 template<>
413 struct CLIParser::OptTypeTrait<const char*> {
414 static const CLIArgType type = CLIArgType::STRING;
415 };
416 
418 template<>
419 struct CLIParser::OptTypeTrait<bool*> {
420 static const CLIArgType type = CLIArgType::BOOL_ARRAY;
421 };
422 
424 template<>
425 struct CLIParser::OptTypeTrait<cxuint*> {
426 static const CLIArgType type = CLIArgType::UINT_ARRAY;
427 };
428 
430 template<>
431 struct CLIParser::OptTypeTrait<cxint*> {
432 static const CLIArgType type = CLIArgType::INT_ARRAY;
433 };
434 
436 template<>
437 struct CLIParser::OptTypeTrait<cxulong*> {
439 static const CLIArgType type =
440  (sizeof(cxulong)==8)?CLIArgType::UINT64_ARRAY:CLIArgType::UINT_ARRAY; };
441 
443 template<>
444 struct CLIParser::OptTypeTrait<cxlong*> {
446 static const CLIArgType type =
447  (sizeof(cxlong)==8)?CLIArgType::INT64_ARRAY:CLIArgType::INT_ARRAY; };
448 
450 template<>
451 struct CLIParser::OptTypeTrait<cxullong*> {
452 static const CLIArgType type = CLIArgType::UINT64_ARRAY;
453 };
454 
456 template<>
457 struct CLIParser::OptTypeTrait<cxllong*> {
458 static const CLIArgType type = CLIArgType::INT64_ARRAY;
459 };
460 
462 template<>
463 struct CLIParser::OptTypeTrait<float*> {
464 static const CLIArgType type = CLIArgType::FLOAT_ARRAY;
465 };
466 
468 template<>
469 struct CLIParser::OptTypeTrait<double*> {
470 static const CLIArgType type = CLIArgType::DOUBLE_ARRAY;
471 };
472 
474 template<>
475 struct CLIParser::OptTypeTrait<const char**> {
476 static const CLIArgType type = CLIArgType::STRING_ARRAY;
477 };
478 
479 };
480 
481 #endif
T getOptArg(cxuint optionId) const
get option argument if it provided
Definition: CLIParser.h:259
cxllong * lliArr
array of cxllongs
Definition: CLIParser.h:156
const T * getOptArgArray(cxuint optionId, size_t &length) const
get option argument array if it provided
Definition: CLIParser.h:282
non copyable and non movable base structure (class)
Definition: Utilities.h:43
T getShortOptArg(char shortName) const
get option argument if it provided
Definition: CLIParser.h:267
trimmed string (without spaces at begin and end)
bool b
boolean
Definition: CLIParser.h:136
none operation
bool * bArr
array of booleans
Definition: CLIParser.h:151
bool hasShortOptArg(char shortName) const
returns true when argument provided for specified option
Definition: CLIParser.h:319
uint64_t * u64Arr
array of 64-bit uints
Definition: CLIParser.h:161
uint32_t * u32Arr
array of 32-bit uints
Definition: CLIParser.h:159
cxint i
cxint
Definition: CLIParser.h:137
CLIArgType argType
type of argument of option (or none)
Definition: CLIParser.h:68
bool arrayFromOccurrences
construct argument array from any occurrence of option argument
Definition: CLIParser.h:72
cxint * iArr
array of cxints
Definition: CLIParser.h:152
cxullong * lluArr
array of cxullongs
Definition: CLIParser.h:157
bool argIsOptional
if true then option argument is optional
Definition: CLIParser.h:69
trimmed string (without spaces at begin and end)
float * fArr
array of floats
Definition: CLIParser.h:163
an array class
Definition: Containers.h:38
float f
float
Definition: CLIParser.h:148
cxulong lu
cxulong
Definition: CLIParser.h:140
cxuint u
cxuint
Definition: CLIParser.h:138
const char *const * getArgs() const
get left over arguments (null-terminated)
Definition: CLIParser.h:346
Command line option description.
Definition: CLIParser.h:64
const char ** sArr
array of C-style strings
Definition: CLIParser.h:165
double * dArr
array of doubles
Definition: CLIParser.h:164
int32_t * i32Arr
array of 32-bit ints
Definition: CLIParser.h:158
cxlong li
cxlong
Definition: CLIParser.h:139
CLIArgType
type of argument of the option
Definition: CLIParser.h:50
int64_t * i64Arr
array of 64-bit ints
Definition: CLIParser.h:160
void setPackageName(const char *pkgName)
set package name
Definition: CLIParser.h:242
cxuint * uArr
array of cxuints
Definition: CLIParser.h:153
bool hasLongOption(const char *longName) const
returns true if option included in command line
Definition: CLIParser.h:339
char shortName
short name of option (single character)
Definition: CLIParser.h:67
uint64_t u64
64-bit uint
Definition: CLIParser.h:146
const char * argName
name of argument of option
Definition: CLIParser.h:75
cxuint getArgsNum() const
get left over arguments number
Definition: CLIParser.h:343
const char * longName
long name of option
Definition: CLIParser.h:66
bool hasOptArg(cxuint optionId) const
returns true when argument provided for specified option
Definition: CLIParser.h:311
main namespace
Definition: AsmFormats.h:41
const char * description
description of option
Definition: CLIParser.h:74
value holder
Definition: CLIParser.h:135
int64_t i64
64-bit int
Definition: CLIParser.h:145
const char * s
C-style string.
Definition: CLIParser.h:150
cxullong llu
cxullong
Definition: CLIParser.h:142
cxllong lli
cxllong
Definition: CLIParser.h:141
double d
double
Definition: CLIParser.h:149
size_t size
size
Definition: CLIParser.h:147
utilities for other libraries and programs
bool hasOption(cxuint optionId) const
returns true if option included in command line
Definition: CLIParser.h:327
const T * getLongOptArgArray(const char *longName, size_t &length) const
get option argument array if it provided
Definition: CLIParser.h:307
cxlong * liArr
array of cxlongs
Definition: CLIParser.h:154
exception class
Definition: Utilities.h:58
size_t * sizeArr
array of sizes
Definition: CLIParser.h:162
T getLongOptArg(const char *longName) const
get option argument if it provided
Definition: CLIParser.h:272
size_t size() const
returns number of elements
Definition: Containers.h:169
cxulong * luArr
array cxulongs
Definition: CLIParser.h:155
The Command Line Parser (parses options and their arguments)
Definition: CLIParser.h:121
uint32_t u32
32-bit uint
Definition: CLIParser.h:144
CLI exception class.
Definition: CLIParser.h:79
bool hasLongOptArg(const char *longName) const
returns true when argument provided for specified option
Definition: CLIParser.h:323
int32_t i32
32-bit int
Definition: CLIParser.h:143
const T * getShortOptArgArray(char shortName, size_t &length) const
get option argument array if it provided
Definition: CLIParser.h:297
containers and other utils for other libraries and programs
bool hasShortOption(char shortName) const
returns true if option included in command line
Definition: CLIParser.h:335