HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
argparse.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause and Apache-2.0
3 // https://github.com/AcademySoftwareFoundation/OpenImageIO
4 
5 
6 #pragma once
7 
8 #if defined(_MSC_VER)
9 // Ignore warnings about DLL exported classes with member variables that are template classes.
10 // This happens with the std::string m_errmessage member of ArgParse below.
11 # pragma warning(disable : 4251)
12 #endif
13 
14 #include <functional>
15 #include <memory>
16 #include <vector>
17 
18 #include <OpenImageIO/export.h>
20 #include <OpenImageIO/paramlist.h>
21 #include <OpenImageIO/strutil.h>
22 
23 
25 
26 
27 /////////////////////////////////////////////////////////////////////////////
28 ///
29 /// \class ArgParse
30 ///
31 /// Argument Parsing. Kind of resembles Python argparse library.
32 ///
33 /// Set up argument parser:
34 ///
35 /// ArgParse ap;
36 /// ap.intro("myapp does good things")
37 /// .usage("myapp [options] filename...");
38 /// ap.arg("filename")
39 /// .hidden()
40 /// .action([&](cspan<const char*> argv){ filenames.emplace_back(argv[0]); });
41 ///
42 /// Declare arguments. Some examples of common idioms:
43 ///
44 /// // Boolean option (no arguments)
45 /// ap.arg("-v")
46 /// .help("verbose mode")
47 /// .action(ArgParse::store_true());
48 ///
49 /// // integer option
50 /// ap.arg("-passes NPASSES")
51 /// .help("number of passes")
52 /// .defaultval(1)
53 /// .action(ArgParse::store<int>);
54 ///
55 /// // An option that takes 3 float arguments, like a V3f
56 /// ap.arg("-camera X Y Z")
57 /// .help("set the camera position")
58 /// .defaultval(Imath::V3f(0.0f, 0.0f, -1.0f))
59 /// .action(ArgParse::store<float>());
60 ///
61 /// // Positional argument -- append strings
62 /// ap.arg("filename")
63 /// .action(ArgParse::append())
64 /// .hidden();
65 ///
66 /// Parse the command line:
67 ///
68 /// ap.parse (argc, argv);
69 ///
70 /// Extract the values like they are attributes in a ParamValueList:
71 ///
72 /// int passes = ap["passes"].get<int>();
73 /// bool verbose = ap["verbose"].get<int>();
74 /// Imath::V3f camera = ap["camera"].get<Imath::V3f>();
75 ///
76 //
77 // ------------------------------------------------------------------
78 //
79 // Old syntax
80 // ----------
81 //
82 // We still support this old syntax as well:
83 //
84 // The parse function takes a list of options and variables or functions
85 // for storing option values and return <0 on failure:
86 //
87 // static int parse_files (int argc, const char *argv[])
88 // {
89 // for (int i = 0; i < argc; i++)
90 // filenames.push_back (argv[i]);
91 // return 0;
92 // }
93 //
94 // static int blah_callback (int argc, const char *argv[])
95 // {
96 // std::cout << "blah argument was " << argv[1] << "\n";
97 // return 0;
98 // }
99 //
100 // ...
101 //
102 // ArgParse ap;
103 //
104 // ap.options ("Usage: myapp [options] filename...",
105 // "%*", parse_objects, "",
106 // "-camera %f %f %f", &camera[0], &camera[1], &camera[2],
107 // "set the camera position",
108 // "-lookat %f %f %f", &lx, &ly, &lz,
109 // "set the position of interest",
110 // "-oversampling %d", &oversampling, "oversamping rate",
111 // "-passes %d", &passes, "number of passes",
112 // "-lens %f %f %f", &aperture, &focalDistance, &focalLength,
113 // "set aperture, focal distance, focal length",
114 // "-format %d %d %f", &width, &height, &aspect,
115 // "set width, height, aspect ratio",
116 // "-v", &verbose, "verbose output",
117 // "-q %!", &verbose, "quiet mode",
118 // "--blah %@ %s", blahcallback, "Make the callback",
119 // NULL);
120 //
121 // if (ap.parse (argc, argv) < 0) {
122 // std::cerr << ap.geterror() << std::endl;
123 // ap.usage ();
124 // return EXIT_FAILURE;
125 // }
126 //
127 // The available argument types are:
128 // - no \% argument - bool flag
129 // - \%! - a bool flag, but set it to false if the option is set
130 // - \%d - 32bit integer
131 // - \%f - 32bit float
132 // - \%F - 64bit float (double)
133 // - \%s - std::string
134 // - \%L - std::vector<std::string> (takes 1 arg, appends to list)
135 // - \%@ - a function pointer for a callback function will be invoked
136 // immediately. The prototype for the callback is
137 // int callback (int argc, char *argv[])
138 // - \%* - catch all non-options and pass individually as an (argc,argv)
139 // sublist to a callback, each immediately after it's found
140 // - \%1 - catch all non-options that occur before any option is
141 // encountered (like %*, but only for those prior to the first
142 // real option.
143 //
144 // The argument type specifier may be followed by an optional colon (:) and
145 // then a human-readable parameter that will be printed in the help
146 // message. For example,
147 //
148 // "--foo %d:WIDTH %d:HEIGHT", ...
149 //
150 // indicates that `--foo` takes two integer arguments, and the help message
151 // will be rendered as:
152 //
153 // --foo WIDTH HEIGHT Set the foo size
154 //
155 // There are several special format tokens:
156 // - "<SEPARATOR>" - not an option at all, just a description to print
157 // in the usage output.
158 //
159 // Notes:
160 // - If an option doesn't have any arguments, a bool flag argument is
161 // assumed.
162 // - No argument destinations are initialized.
163 // - The empty string, "", is used as a global sublist (ie. "%*").
164 // - Sublist functions are all of the form "int func(int argc, char **argv)".
165 // - If a sublist function returns -1, parse() will terminate early.
166 // - It is perfectly legal for the user to append ':' and more characters
167 // to the end of an option name, it will match only the portion before
168 // the semicolon (but a callback can detect the full string, this is
169 // useful for making arguments: myprog --flag:myopt=1 foobar
170 //
171 /////////////////////////////////////////////////////////////////////////////
172 
173 
175 public:
176  class Arg; // Forward declarion of Arg
177 
178  // ------------------------------------------------------------------
179  /// @defgroup Setting up an ArgParse
180  /// @{
181 
182  /// Construct an ArgParse.
183  ArgParse();
184 
185  /// Destroy an ArgParse.
186  ~ArgParse();
187 
188  // Old ctr. Don't use this. Instead, pass argc/argv to parse_args().
189  ArgParse(int argc, const char** argv);
190 
191  // Disallow copy ctr and assignment
192  ArgParse(const ArgParse&) = delete;
193  const ArgParse& operator=(const ArgParse&) = delete;
194 
195  /// Move constructor
197  : m_impl(std::move(other.m_impl))
198  {
199  }
200 
201  /// Set an optional "intro" message, printed first when --help is used
202  /// or an error is found in the program arguments.
203  ArgParse& intro(string_view str);
204 
205  /// Set the "usage" string, which will be printed after the intro, and
206  /// preceded by the message "Usage: ".
207  ArgParse& usage(string_view str);
208 
209  /// Set an optional description of the program, to be printed after the
210  /// usage but before the detailed argument help.
211  ArgParse& description(string_view str);
212 
213  /// Set an optional epilog to be printed after the detailed argument
214  /// help.
215  ArgParse& epilog(string_view str);
216 
217  /// Optionally override the name of the program, as understood by
218  /// ArgParse. If not supplied, it will be derived from the original
219  /// command line.
220  ArgParse& prog(string_view str);
221 
222  /// If true, this will cause the detailed help message to print the
223  /// default value of all options for which it was supplied (the default
224  /// is false).
225  ArgParse& print_defaults(bool print);
226 
227  /// By default, every ArgParse automatically adds a `--help` argument
228  /// that, if invoked, prints the full explanatory help message (i.e.,
229  /// calls `print_help()`) and then exits the application with a success
230  /// return code of 0.
231  ///
232  /// Calling `add_help(false)` disable the automatic `--help` argument.
233  /// If you do this but want a help option (for example, you want to call
234  /// it something different, or not exit the application, or have some
235  /// other behavior), it's up to the user to add it and its behavior just
236  /// like any other argument.
237  ArgParse& add_help(bool add_help);
238 
239  /// Calling `add_version()` adds a `--version` argument, which will print
240  /// the version string supplied.
241  ArgParse& add_version(string_view version_string);
242 
243  /// By default, if the command line arguments do not conform to what is
244  /// declared to ArgParse (for example, if unknown commands are
245  /// encountered, required arguments are not found, etc.), the ArgParse
246  /// (during `parse_args()` will print an error message, the full help
247  /// guide, and then exit the application with a failure return code.
248  ///
249  /// Calling `exit_on_error(false)` disables this behavior. In this case,
250  /// the application is responsible for checking the return code of
251  /// `parse_args()` and responding appropriately.
252  ArgParse& exit_on_error(bool exit_on_error);
253 
254  /// If called by an argument's action, halts the rest of the command
255  /// line from continuing to be processed. Call with `aborted = false` to
256  /// unabort and restore operations.
257  void abort(bool aborted = true);
258 
259  /// Reveal whether the current state is aborted.
260  bool aborted() const;
261 
262  /// Set whether current actions should run.
263  void running(bool run);
264 
265  /// Reveal whether current actions should run.
266  bool running() const;
267 
268  /// Reveal the current argument that is being parsed.
269  int current_arg() const;
270 
271  /// Set the next argument to be processed. Use with extreme caution!
272  void set_next_arg(int nextarg);
273 
274  /// @}
275 
276  // ------------------------------------------------------------------
277  /// @defgroup Parsing arguments
278  /// @{
279 
280  /// With the options already set up, parse the command line. Return 0 if
281  /// ok, -1 if it's a malformed command line.
282  int parse_args(int argc, const char** argv);
283 
284  /// Is there a pending error message waiting to be retrieved?
285  bool has_error() const;
286 
287  /// Return any error messages generated during the course of parse()
288  /// (and by default, clear any error flags). If no error has occurred
289  /// since the last time geterror() was called, it will return an empty
290  /// string.
291  std::string geterror(bool clear = true) const;
292 
293  /// Return the name of the program. This will be either derived from the
294  /// original command line that launched this application, or else
295  /// overridden by a prior call to `prog()`.
296  std::string prog_name() const;
297 
298  /// Print the full help message to stdout. The usage message is
299  /// generated and formatted automatically based on the arguments
300  /// declared.
301  void print_help() const;
302 
303  /// Print a brief usage message to stdout. The usage message is
304  /// generated and formatted automatically based on the arguments
305  /// declared.
306  void briefusage() const;
307 
308  /// Return the entire command-line as one string.
309  std::string command_line() const;
310 
311  /// @}
312 
313  // ------------------------------------------------------------------
314  /// @defgroup Declaring arguments
315  /// @{
316 
317  /// Add an argument declaration. Ordinary arguments start with a leading
318  /// `-` character (or `--`, either will be accepted). Positional
319  /// arguments lack a leading `-`.
320  ///
321  /// The argname consists of any of these options:
322  ///
323  /// * "name" : a positional argument.
324  ///
325  /// * "-name" or "--name" : an ordinary flag argument. If this argument
326  /// should be followed by parameters, they will later be declared
327  /// using some combination of `Arg::nargs()` and `Arg::metavar()`.
328  ///
329  /// * "--name A B C" : including the names of parameters following the
330  /// flag itself implicitly means the same thing as calling `nargs()`
331  /// and `metavar()`, and there is no need to call them separately.
332  ///
333  /// This method returns an `Arg&`, so it is permissible to chain Arg
334  /// method calls. Those chained calls are what communicates the number
335  /// of parameters, help message, action, etc. See the `Arg` class for
336  /// all the possible Arg methods.
337  ///
338  Arg& add_argument(const char* argname);
339 
340  /// Alternate way to add an argument, specifying external storage
341  /// destinations for the parameters. This is more reminiscent of the
342  /// older, pre-2.2 API, and also can be convenient as an alternative to
343  /// extracting every parameter and putting them into variables.
344  ///
345  /// Flags with no parameters are followed by a `bool*`. Args with
346  /// parameters must declare them as "%T:NAME", where the "%T" part
347  /// corresponds to the storage type, `%d` for int, `%f` for float, `%s`
348  /// for std::string, and `%L` for `std::vector<std::string>`.
349  ///
350  /// Examples:
351  ///
352  /// ArgParse ap;
353  /// bool verbose = false;
354  /// ap.add_argument("-v", &verbose)
355  /// .help("verbose mode");
356  ///
357  /// float r = 0, g = 0, b = 0;
358  /// ap.add_argument("--color %f:R %f:G %f:B", &r, &g, &b)
359  /// .help("diffuse color")
360  /// .action(ArgParse::store<float>());
361  ///
362  template<typename... T> Arg& add_argument(const char* argname, T... args)
363  {
364  return argx(argname, args...);
365  }
366 
367  /// Shorter synonym for add_argument().
368  Arg& arg(const char* argname) { return add_argument(argname); }
369 
370  /// Shorter synonym for add_argument().
371  template<typename... T> Arg& arg(const char* argname, T... args)
372  {
373  return argx(argname, args...);
374  }
375 
376  /// Add a separator with a text message. This can be used to group
377  /// arguments with section headings.
378  ///
379  /// Example:
380  ///
381  /// ArgParse ap;
382  /// ap.separator("Basic arguments:");
383  /// ap.add_argument("-v");
384  /// ap.add_argument("-a");
385  /// ap.separator("Advanced arguments:");
386  /// ap.add_argument("-b");
387  /// ap.add_argument("-c");
388  ///
389  /// Will print the help section like:
390  ///
391  /// Basic arguments:
392  /// -v
393  /// -a
394  /// Advanced arguments:
395  /// -b
396  /// -c
397  ///
398  Arg& separator(string_view text);
399 
400 
401  /// Holder for a callback that takes a span of C strings as arguments.
402  // typedef std::function<void(cspan<const char*> myargs)> Action;
403  using Action = std::function<void(cspan<const char*> myargs)>;
404 
405  /// Holder for a callback that takes an Arg ref and a span of C strings
406  /// as arguments.
407  using ArgAction = std::function<void(Arg& arg, cspan<const char*> myargs)>;
408 
409 
410  /// A call to `ArgParse::arg()` returns an `Arg&`. There are lots of
411  /// things you can do to that reference to modify it. Nearly all
412  /// Arg methods return an `Arg&` so you can chain the calls, like this:
413  ///
414  /// ArgParse ap;
415  /// ...
416  /// ap.add_argument("-v")
417  /// .help("Verbose mode")
418  /// .action(Arg::store_true());
419  ///
421  public:
422  // Arg constructor. This should only be called by
423  // ArgParse::add_argument().
425  : m_argparse(ap)
426  {
427  }
428  // Disallow copy ctr and assignment
429  Arg(const Arg&) = delete;
430  const Arg& operator=(const Arg&) = delete;
431 
432  /// Set the help / description of this command line argument.
434 
435  /// Set the number of subsequent parameters to this argument.
436  /// Setting `nargs(0)` means it is a flag only, with no parameters.
437  Arg& nargs(int n);
438 
439  // TODO:
440  // Set the number of subsequent parameters to this arguments. "?"
441  // means a single optional value, "*" means any number of optional
442  // values (and implies action(append)), "+" means one or more
443  // optional values (just like "*", but will be an error if none are
444  // supplied at all).
445  // Arg& nargs(string_view n);
446 
447 
448  /// Set the name(s) of any argument parameters as they are printed
449  /// in the help message. For arguments that take multiple
450  /// parameters, just put spaces between them. Note that the number
451  /// of arguments is inferred by the number of metavar names, so
452  /// there is no need to set nargs separately if metavar() is called
453  /// properly.
454  ///
455  /// Examples:
456  ///
457  /// ArgParse ap;
458  /// ap.add_argument("--aa")
459  /// .help("set sampling rate (per pixel)")
460  /// .metavar("SAMPLES");
461  /// ap.add_argument("--color")
462  /// .help("set the diffuse color")
463  /// .metavar("R G B");
464  ///
465  /// Will print help like:
466  ///
467  /// --aa SAMPLES set sampling rate (per pixel)
468  /// --color R G B set the diffuse color
469  ///
470  Arg& metavar(string_view name);
471 
472  /// Override the destination attribute name (versus the default
473  /// which is simply the name of the command line option with the
474  /// leading dashes stripped away). The main use case is if you want
475  /// two differently named command line options to both store values
476  /// into the same attribute. It is very important that if you use
477  /// dest(), you call it before setting the action.
478  ///
479  /// Example:
480  ///
481  /// // Add -v argument, but store its result in `ap["verbose"]`
482  /// // rather than the default `ap["v"]`.
483  /// ap.add_argument("-v")
484  /// .help("verbose mode")
485  /// .dest("verbose")
486  /// .action(ArgParse::store_true());
487  ///
488  Arg& dest(string_view dest);
489 
490  /// Initialize the destination attribute with a default value. Do
491  /// not call `.dest("name")` on the argument after calling
492  /// defaultval, of it will end up with the default value in the
493  /// wrong attribute.
494  template<typename T> Arg& defaultval(const T& val)
495  {
496  m_argparse.params()[dest()] = val;
497  return *this;
498  }
499 
500  /// Mark the argument as hidden from the help message.
501  Arg& hidden();
502 
503  /// Always run, even when ArgParse.running() is false.
504  Arg& always_run();
505 
506  /// Set the action for this argument to store 1 in the destination
507  /// attribute. Initialize the destination attribute to 0 now. Do not
508  /// call `.dest("name")` on the argument after calling store_true,
509  /// you must override the destination first!
511  {
512  m_argparse.params()[dest()] = 0;
513  action(ArgParse::store_true());
514  return *this;
515  }
516 
517  /// Set the action for this argument to store 0 in the destination
518  /// attribute. Initialize the destination attribute to 1 now. Do not
519  /// call `.dest("name")` on the argument after calling store_false,
520  /// you must override the destination first!
522  {
523  m_argparse.params()[dest()] = 1;
524  action(ArgParse::store_false());
525  return *this;
526  }
527 
528  /// Add an arbitrary action: `func(Arg&, cspan<const char*>)`
529  Arg& action(ArgAction&& func);
530 
531  /// Add an arbitrary action: `func(cspan<const char*>)`
533  {
534  // Implemented with a lambda that applies a wrapper to turn
535  // it into func(Arg&,cspan<const char*>).
536  return action([=](Arg&, cspan<const char*> a) { func(a); });
537  }
538 #if OIIO_MSVS_BEFORE_2017
539  // MSVS 2015 seems to need this, fixed in later versions.
540  Arg& action(void (*func)(cspan<const char*> myargs))
541  {
542  return action([=](Arg&, cspan<const char*> a) { func(a); });
543  }
544 #endif
545 
546  /// Add an arbitrary action: `func()`
547  Arg& action(void (*func)())
548  {
549  return action([=](Arg&, cspan<const char*>) { func(); });
550  }
551 
552  // Old style action for compatibility
553  Arg& action(int (*func)(int, const char**))
554  {
555  return action([=](Arg&, cspan<const char*> a) {
556  func(int(a.size()), (const char**)a.data());
557  });
558  }
559 
560  /// Return the name of the argument.
561  string_view name() const;
562 
563  /// Return the "destination", the name of the attribute in which
564  /// the argument value will be stored.
565  string_view dest() const;
566 
567  /// Get a reference to the ArgParse that owns this Arg.
568  ArgParse& argparse() { return m_argparse; }
569 
570  protected:
572  };
573 
574  /// @}
575 
576  // ------------------------------------------------------------------
577  /// @defgroup Action library
578  /// @{
579  ///
580  /// These are actions provided for convenience.
581  /// Examples of their use:
582  ///
583  /// ArgParse ap;
584  /// ...
585  ///
586  /// // Flag, just store 1 if set (default to 0)
587  /// ap.add_argument("-v")
588  /// .action(ArgParse::store_true());
589  ///
590  /// // Store 42 if the flag is encountered (default is 1)
591  /// ap.add_argument("--foo")
592  /// .defaultval(1)
593  /// .action(ArgParse::store_const(42));
594  ///
595  /// // Take an integer argument and store it
596  /// ap.add_argument("--bar")
597  /// .action(ArgParse::store<int>());
598  ///
599  /// // Take 3 floating point arguments, pass default as Color3f.
600  /// ap.add_argument("--color")
601  /// .nargs(3)
602  /// .metavar("R G B")
603  /// .action(ArgParse::store<float>)
604  /// .defaultval(Imath::Color3f(0.5f, 0.5f, 0.5f));
605  ///
606  /// // Take a single string argument, but *append* it, so if the
607  /// // option appears multiple time, you get a list of strings.
608  /// ap.add_argument("-o")
609  /// .action(ArgParse::append());
610  ///
611  /// // Another string appending example, but using a positional
612  /// // argument.
613  /// ap.add_argument("filename")
614  /// .action(ArgParse::append());
615  ///
616 
617  /// Return an action that stores 1 into its destination attribute.
618  static ArgAction store_true();
619 
620  /// Return an action that stores 0 into its destination attribute.
621  static ArgAction store_false();
622 
623  /// Return an action that stores a constant value into its destination
624  /// attribute.
625  template<typename T> static ArgAction store_const(const T& value)
626  {
627  return [&, value](Arg& arg, cspan<const char*> myarg) {
628  arg.argparse().params()[arg.dest()] = value;
629  };
630  }
631 
632  static ArgAction store_const(const char* value)
633  {
634  return [&, value](Arg& arg, cspan<const char*> myarg) {
635  arg.argparse().params()[arg.dest()] = string_view(value);
636  };
637  }
638 
639  /// Return an action that stores into its destination attribute the
640  /// following `n` command line arguments (where `n` is the number of
641  /// additional command line arguments that this option requires).
642  template<typename T = ustring> static ArgAction store()
643  {
644  return [&](Arg& arg, cspan<const char*> myarg) {
645  if (myarg[0][0] == '-') // Skip command itself
646  myarg = myarg.subspan(1);
647  ParamValueList& pl(arg.argparse().params());
648  int n = int(myarg.size());
649  T* vals = OIIO_ALLOCA(T, n);
650  for (int i = 0; i < n; ++i)
651  vals[i] = Strutil::from_string<T>(myarg[i]);
652  if (n == 1) {
653  pl[arg.dest()] = vals[0];
654  } else { // array case -- always store as strings
655  pl.attribute(arg.dest(), TypeDesc(BaseTypeFromC<T>::value, n),
656  vals);
657  }
658  };
659  }
660 
661  /// Return an action that appends into its destination attribute the
662  /// following `n` command line arguments (where `n` is the number of
663  /// additional command line arguments that this option requires).
664  template<typename T = ustring> static ArgAction append()
665  {
666  return [&](Arg& arg, cspan<const char*> myarg) {
667  if (myarg[0][0] == '-') // Skip command itself
668  myarg = myarg.subspan(1);
669  ParamValueList& pl(arg.argparse().params());
670  ParamValue* pv = pl.find_pv(arg.dest());
671  // TypeDesc t = pv ? pv->type() : TypeUnknown;
672  int nold = pv ? pv->type().basevalues() : 0;
673  int nnew = int(myarg.size());
674  int n = nold + nnew;
675  T* vals = OIIO_ALLOCA(T, n);
676  for (int i = 0; i < nold; ++i)
677  vals[i] = Strutil::from_string<T>(pv->get_string_indexed(i));
678  for (int i = 0; i < nnew; ++i)
679  vals[i + nold] = Strutil::from_string<T>(myarg[i]);
680  if (n == 1) {
681  pl[arg.dest()] = vals[0];
682  } else { // array case -- always store as strings
683  pl.attribute(arg.dest(), TypeDesc(BaseTypeFromC<T>::value, n),
684  vals);
685  }
686  };
687  }
688 
689  /// Return an action that does nothing. I guess you could use use this
690  /// for an argument that is obsolete and is still accepted, but no
691  /// longer has any function.
692  static Action do_nothing();
693 
694  /// @}
695 
696 
697  // ------------------------------------------------------------------
698  /// @defgroup Retrieving values of parsed arguments
699  /// @{
700  ///
701  /// Retrieve arguments in the same manner that you would access them
702  /// from a OIIO::ParamValueList.
703  ///
704  /// Examples:
705  ///
706  /// // Please see the code example in the "Action library" section above
707  /// // for the argument declarations.
708  ///
709  /// // retrieve whether -v flag was set
710  /// bool verbose = ap["v"].get<int>();
711  ///
712  /// // Retrieve the parameter passed to --bar, defaulting to 13 if
713  /// // never set on the command line:
714  /// int bar = ap["bar"].get<int>(13);
715  ///
716  /// // Retrieve the color, which had 3 float parameters. Extract
717  /// // it as an Imath::Color3f.
718  /// Imath::Color3f diffuse = ap["color"].get<Imath::Color3f>();
719  ///
720  /// // Retrieve the filename list as a vector:
721  /// auto filenames = ap["filename"].as_vec<std::string>();
722  /// for (auto& f : filenames)
723  /// Strutil::printf(" file: \"%s\"\n", f);
724  ///
725 
726  /// Access a single argument result by name.
728  {
729  return { &cparams(), name };
730  }
731  /// Access a single argument result by name.
733  {
734  return { &params(), name };
735  }
736 
737  /// Directly access the ParamValueList that holds the argument results.
739  /// Directly access the ParamValueList that holds the argument results
740  /// (const version).
741  const ParamValueList& cparams() const;
742 
743  /// @}
744 
745 
746 private:
747  class Impl;
748  std::shared_ptr<Impl> m_impl; // PIMPL pattern
749  Arg& argx(const char* argname, ...);
750  friend class ArgOption;
751 
752 public:
753  // ------------------------------------------------------------------
754  // Old API. DEPRECATED(2.2)
755 
756  // Declare the command line options. After the introductory message,
757  // parameters are a set of format strings and variable pointers. Each
758  // string contains an option name and a scanf-like format string to
759  // enumerate the arguments of that option (eg. `"-option %d %f %s"`).
760  // The format string is followed by a list of pointers to the argument
761  // variables, just like scanf. A NULL terminates the list. Multiple
762  // calls to options() will append additional options.
763  int options(const char* intro, ...);
764 
765  // old name
766  // DEPRECATED(2.2)
767  int parse(int argc, const char** argv) { return parse_args(argc, argv); }
768 
769  // Type for a callback that writes something to the output stream.
770  typedef std::function<void(const ArgParse& ap, std::ostream&)> callback_t;
771  // Set callbacks to run that will print any matter you want as part
772  // of the verbose usage, before and after the options are detailed.
773  void set_preoption_help(callback_t callback);
774  void set_postoption_help(callback_t callback);
775 
776  // DEPRECATED(2.2) synonym for `print_help()`.
777  void usage() const { print_help(); }
778 };
779 
780 
781 
782 // Define symbols that let client applications determine if newly added
783 // features are supported.
784 #define OIIO_ARGPARSE_SUPPORTS_BRIEFUSAGE 1
785 #define OIIO_ARGPARSE_SUPPORTS_HUMAN_PARAMNAME 1
786 
OIIO_API std::string geterror(bool clear=true)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
void usage() const
Definition: argparse.h:777
OIIO_API bool has_error()
Is there a pending global error message waiting to be retrieved?
#define OIIO_ALLOCA(type, size)
Definition: platform.h:326
ArgParse(ArgParse &&other)
Move constructor.
Definition: argparse.h:196
static ArgAction store()
Definition: argparse.h:642
ArgParse & argparse()
Get a reference to the ArgParse that owns this Arg.
Definition: argparse.h:568
GLsizei const GLfloat * value
Definition: glcorearb.h:824
Arg & arg(const char *argname, T...args)
Shorter synonym for add_argument().
Definition: argparse.h:371
Definition: span.h:74
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
Arg & dest(string_view dest)
std::function< void(cspan< const char * > myargs)> Action
Holder for a callback that takes a span of C strings as arguments.
Definition: argparse.h:403
static ArgAction store_true()
Return an action that stores 1 into its destination attribute.
std::string help(const App *app, const Error &e)
Printout the full help string on error (if this fn is set, the old default for CLI11) ...
Definition: CLI11.h:8978
Arg & add_argument(const char *argname, T...args)
Definition: argparse.h:362
static ArgAction store_false()
Return an action that stores 0 into its destination attribute.
Arg & action(Action &&func)
Add an arbitrary action: func(cspan<const char*>)
Definition: argparse.h:532
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1859
GLenum const GLfloat * params
Definition: glcorearb.h:105
String-related utilities, all in namespace Strutil.
#define OIIO_UTIL_API
Definition: export.h:71
basic_string_view< char > string_view
Definition: core.h:501
OIIO_HOSTDEVICE OIIO_CONSTEXPR14 size_t basevalues() const noexcept
Definition: typedesc.h:189
GLdouble n
Definition: glcorearb.h:2008
Arg & action(void(*func)())
Add an arbitrary action: func()
Definition: argparse.h:547
ArgParse & m_argparse
Definition: argparse.h:571
Arg & defaultval(const T &val)
Definition: argparse.h:494
AttrDelegate< ParamValueList > operator[](string_view name)
Access a single argument result by name.
Definition: argparse.h:732
constexpr size_type size() const noexcept
Definition: span.h:186
GLuint const GLchar * name
Definition: glcorearb.h:786
Arg(ArgParse &ap)
Definition: argparse.h:424
static ArgAction store_const(const T &value)
Definition: argparse.h:625
int parse(int argc, const char **argv)
Definition: argparse.h:767
static ArgAction append()
Definition: argparse.h:664
GLsizeiptr const void GLenum usage
Definition: glcorearb.h:664
GLenum func
Definition: glcorearb.h:783
AttrDelegate< const ParamValueList > operator[](string_view name) const
Access a single argument result by name.
Definition: argparse.h:727
TypeDesc type() const noexcept
Definition: paramlist.h:202
std::function< void(Arg &arg, cspan< const char * > myargs)> ArgAction
Definition: argparse.h:407
LeafData & operator=(const LeafData &)=delete
GLuint GLfloat * val
Definition: glcorearb.h:1608
static ArgAction store_const(const char *value)
Definition: argparse.h:632
**If you just want to fire and args
Definition: thread.h:618
Arg & arg(const char *argname)
Shorter synonym for add_argument().
Definition: argparse.h:368
Arg & action(int(*func)(int, const char **))
Definition: argparse.h:553
std::function< void(const ArgParse &ap, std::ostream &)> callback_t
Definition: argparse.h:770
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:127
ParamValueList & params()
Directly access the ParamValueList that holds the argument results.
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2903
constexpr pointer data() const noexcept
Definition: span.h:190
Arg & store_true()
Definition: argparse.h:510
Arg & store_false()
Definition: argparse.h:521
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:126