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 2008-present Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/OpenImageIO/oiio
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  /// By default, if the command line arguments do not conform to what is
240  /// declared to ArgParse (for example, if unknown commands are
241  /// encountered, required arguments are not found, etc.), the ArgParse
242  /// (during `parse_args()` will print an error message, the full help
243  /// guide, and then exit the application with a failure return code.
244  ///
245  /// Calling `exit_on_error(false)` disables this behavior. In this case,
246  /// the application is responsible for checking the return code of
247  /// `parse_args()` and responding appropriately.
248  ArgParse& exit_on_error(bool exit_on_error);
249 
250  /// If called by an argument's action, halts the rest of the command
251  /// line from continuing to be processed. Call with `aborted = false` to
252  /// unabort and restore operations.
253  void abort(bool aborted = true);
254 
255  /// Reveal whether the current state is aborted.
256  bool aborted() const;
257 
258  /// @}
259 
260  // ------------------------------------------------------------------
261  /// @defgroup Parsing arguments
262  /// @{
263 
264  /// With the options already set up, parse the command line. Return 0 if
265  /// ok, -1 if it's a malformed command line.
266  int parse_args(int argc, const char** argv);
267 
268  /// Is there a pending error message waiting to be retrieved?
269  bool has_error() const;
270 
271  /// Return any error messages generated during the course of parse()
272  /// (and by default, clear any error flags). If no error has occurred
273  /// since the last time geterror() was called, it will return an empty
274  /// string.
275  std::string geterror(bool clear = true) const;
276 
277  /// Return the name of the program. This will be either derived from the
278  /// original command line that launched this application, or else
279  /// overridden by a prior call to `prog()`.
280  std::string prog_name() const;
281 
282  /// Print the full help message to stdout. The usage message is
283  /// generated and formatted automatically based on the arguments
284  /// declared.
285  void print_help() const;
286 
287  /// Print a brief usage message to stdout. The usage message is
288  /// generated and formatted automatically based on the arguments
289  /// declared.
290  void briefusage() const;
291 
292  /// Return the entire command-line as one string.
293  std::string command_line() const;
294 
295  /// @}
296 
297  // ------------------------------------------------------------------
298  /// @defgroup Declaring arguments
299  /// @{
300 
301  /// Add an argument declaration. Ordinary arguments start with a leading
302  /// `-` character (or `--`, either will be accepted). Positional
303  /// arguments lack a leading `-`.
304  ///
305  /// The argname consists of any of these options:
306  ///
307  /// * "name" : a positional argument.
308  ///
309  /// * "-name" or "--name" : an ordinary flag argument. If this argument
310  /// should be followed by parameters, they will later be declared
311  /// using some combination of `Arg::nargs()` and `Arg::metavar()`.
312  ///
313  /// * "--name A B C" : including the names of parameters following the
314  /// flag itself implicitly means the same thing as calling `nargs()`
315  /// and `metavar()`, and there is no need to call them separately.
316  ///
317  /// This method returns an `Arg&`, so it is permissible to chain Arg
318  /// method calls. Those chained calls are what communicates the number
319  /// of parameters, help message, action, etc. See the `Arg` class for
320  /// all the possible Arg methods.
321  ///
322  Arg& add_argument(const char* argname);
323 
324  /// Alternate way to add an argument, specifying external storage
325  /// destinations for the parameters. This is more reminiscent of the
326  /// older, pre-2.2 API, and also can be convenient as an alternative to
327  /// extracting every parameter and putting them into variables.
328  ///
329  /// Flags with no parameters are followed by a `bool*`. Args with
330  /// parameters must declare them as "%T:NAME", where the "%T" part
331  /// corresponds to the storage type, `%d` for int, `%f` for float, `%s`
332  /// for std::string, and `%L` for `std::vector<std::string>`.
333  ///
334  /// Examples:
335  ///
336  /// ArgParse ap;
337  /// bool verbose = false;
338  /// ap.add_argument("-v", &verbose)
339  /// .help("verbose mode");
340  ///
341  /// float r = 0, g = 0, b = 0;
342  /// ap.add_argument("--color %f:R %f:G %f:B", &r, &g, &b)
343  /// .help("diffuse color")
344  /// .action(ArgParse::store<float>());
345  ///
346  template<typename... T> Arg& add_argument(const char* argname, T... args)
347  {
348  return argx(argname, args...);
349  }
350 
351  /// Shorter synonym for add_argument().
352  Arg& arg(const char* argname) { return add_argument(argname); }
353 
354  /// Shorter synonym for add_argument().
355  template<typename... T> Arg& arg(const char* argname, T... args)
356  {
357  return argx(argname, args...);
358  }
359 
360  /// Add a separator with a text message. This can be used to group
361  /// arguments with section headings.
362  ///
363  /// Example:
364  ///
365  /// ArgParse ap;
366  /// ap.separator("Basic arguments:");
367  /// ap.add_argument("-v");
368  /// ap.add_argument("-a");
369  /// ap.separator("Advanced arguments:");
370  /// ap.add_argument("-b");
371  /// ap.add_argument("-c");
372  ///
373  /// Will print the help section like:
374  ///
375  /// Basic arguments:
376  /// -v
377  /// -a
378  /// Advanced arguments:
379  /// -b
380  /// -c
381  ///
382  Arg& separator(string_view text);
383 
384 
385  /// Holder for a callback that takes a span of C strings as arguments.
386  // typedef std::function<void(cspan<const char*> myargs)> Action;
387  using Action = std::function<void(cspan<const char*> myargs)>;
388 
389  /// Holder for a callback that takes an Arg ref and a span of C strings
390  /// as arguments.
391  using ArgAction = std::function<void(Arg& arg, cspan<const char*> myargs)>;
392 
393 
394  /// A call to `ArgParse::arg()` returns an `Arg&`. There are lots of
395  /// things you can do to that reference to modify it. Nearly all
396  /// Arg methods return an `Arg&` so you can chain the calls, like this:
397  ///
398  /// ArgParse ap;
399  /// ...
400  /// ap.add_argument("-v")
401  /// .help("Verbose mode")
402  /// .action(Arg::store_true());
403  ///
405  public:
406  // Arg constructor. This should only be called by
407  // ArgParse::add_argument().
409  : m_argparse(ap)
410  {
411  }
412  // Disallow copy ctr and assignment
413  Arg(const Arg&) = delete;
414  const Arg& operator=(const Arg&) = delete;
415 
416  /// Set the help / description of this command line argument.
418 
419  /// Set the number of subsequent parameters to this argument.
420  /// Setting `nargs(0)` means it is a flag only, with no parameters.
421  Arg& nargs(int n);
422 
423  // TODO:
424  // Set the number of subsequent parameters to this arguments. "?"
425  // means a single optional value, "*" means any number of optional
426  // values (and implies action(append)), "+" means one or more
427  // optional values (just like "*", but will be an error if none are
428  // supplied at all).
429  // Arg& nargs(string_view n);
430 
431 
432  /// Set the name(s) of any argument parameters as they are printed
433  /// in the help message. For arguments that take multiple
434  /// parameters, just put spaces between them. Note that the number
435  /// of arguments is inferred by the number of metavar names, so
436  /// there is no need to set nargs separately if metavar() is called
437  /// properly.
438  ///
439  /// Examples:
440  ///
441  /// ArgParse ap;
442  /// ap.add_argument("--aa")
443  /// .help("set sampling rate (per pixel)")
444  /// .metavar("SAMPLES");
445  /// ap.add_argument("--color")
446  /// .help("set the diffuse color")
447  /// .metavar("R G B");
448  ///
449  /// Will print help like:
450  ///
451  /// --aa SAMPLES set sampling rate (per pixel)
452  /// --color R G B set the diffuse color
453  ///
454  Arg& metavar(string_view name);
455 
456  /// Override the destination attribute name (versus the default
457  /// which is simply the name of the command line option with the
458  /// leading dashes stripped away). The main use case is if you want
459  /// two differently named command line options to both store values
460  /// into the same attribute. It is very important that if you use
461  /// dest(), you call it before setting the action.
462  ///
463  /// Example:
464  ///
465  /// // Add -v argument, but store its result in `ap["verbose"]`
466  /// // rather than the default `ap["v"]`.
467  /// ap.add_argument("-v")
468  /// .help("verbose mode")
469  /// .dest("verbose")
470  /// .action(ArgParse::store_true());
471  ///
472  Arg& dest(string_view dest);
473 
474  /// Initialize the destination attribute with a default value. Do
475  /// not call `.dest("name")` on the argument after calling
476  /// defaultval, of it will end up with the default value in the
477  /// wrong attribute.
478  template<typename T> Arg& defaultval(const T& val)
479  {
480  m_argparse.params()[dest()] = val;
481  return *this;
482  }
483 
484  /// Mark the argument as hidden from the help message.
485  Arg& hidden();
486 
487  /// Set the action for this argument to store 1 in the destination
488  /// attribute. Initialize the destination attribute to 0 now. Do not
489  /// call `.dest("name")` on the argument after calling store_true,
490  /// you must override the destination first!
492  {
493  m_argparse.params()[dest()] = 0;
494  action(ArgParse::store_true());
495  return *this;
496  }
497 
498  /// Set the action for this argument to store 0 in the destination
499  /// attribute. Initialize the destination attribute to 1 now. Do not
500  /// call `.dest("name")` on the argument after calling store_false,
501  /// you must override the destination first!
503  {
504  m_argparse.params()[dest()] = 1;
505  action(ArgParse::store_false());
506  return *this;
507  }
508 
509  /// Add an arbitrary action: `func(Arg&, cspan<const char*>)`
510  Arg& action(ArgAction&& func);
511 
512  /// Add an arbitrary action: `func(cspan<const char*>)`
514  {
515  // Implemented with a lambda that applies a wrapper to turn
516  // it into func(Arg&,cspan<const char*>).
517  return action([=](Arg&, cspan<const char*> a) { func(a); });
518  }
519 #if OIIO_MSVS_BEFORE_2017
520  // MSVS 2015 seems to need this, fixed in later versions.
521  Arg& action(void (*func)(cspan<const char*> myargs))
522  {
523  return action([=](Arg&, cspan<const char*> a) { func(a); });
524  }
525 #endif
526 
527  /// Add an arbitrary action: `func()`
528  Arg& action(void (*func)())
529  {
530  return action([=](Arg&, cspan<const char*>) { func(); });
531  }
532 
533  // Old style action for compatibility
534  Arg& action(int (*func)(int, const char**))
535  {
536  return action([=](Arg&, cspan<const char*> a) {
537  func(int(a.size()), (const char**)a.data());
538  });
539  }
540 
541  /// Return the name of the argument.
542  string_view name() const;
543 
544  /// Return the "destination", the name of the attribute in which
545  /// the argument value will be stored.
546  string_view dest() const;
547 
548  /// Get a reference to the ArgParse that owns this Arg.
549  ArgParse& argparse() { return m_argparse; }
550 
551  protected:
553  };
554 
555  /// @}
556 
557  // ------------------------------------------------------------------
558  /// @defgroup Action library
559  /// @{
560  ///
561  /// These are actions provided for convenience.
562  /// Examples of their use:
563  ///
564  /// ArgParse ap;
565  /// ...
566  ///
567  /// // Flag, just store 1 if set (default to 0)
568  /// ap.add_argument("-v")
569  /// .action(ArgParse::store_true());
570  ///
571  /// // Store 42 if the flag is encountered (default is 1)
572  /// ap.add_argument("--foo")
573  /// .defaultval(1)
574  /// .action(ArgParse::store_const(42));
575  ///
576  /// // Take an integer argument and store it
577  /// ap.add_argument("--bar")
578  /// .action(ArgParse::store<int>());
579  ///
580  /// // Take 3 floating point arguments, pass default as Color3f.
581  /// ap.add_argument("--color")
582  /// .nargs(3)
583  /// .metavar("R G B")
584  /// .action(ArgParse::store<float>)
585  /// .defaultval(Imath::Color3f(0.5f, 0.5f, 0.5f));
586  ///
587  /// // Take a single string argument, but *append* it, so if the
588  /// // option appears multiple time, you get a list of strings.
589  /// ap.add_argument("-o")
590  /// .action(ArgParse::append());
591  ///
592  /// // Another string appending example, but using a positional
593  /// // argument.
594  /// ap.add_argument("filename")
595  /// .action(ArgParse::append());
596  ///
597 
598  /// Return an action that stores 1 into its destination attribute.
599  static ArgAction store_true();
600 
601  /// Return an action that stores 0 into its destination attribute.
602  static ArgAction store_false();
603 
604  /// Return an action that stores a constant value into its destination
605  /// attribute.
606  template<typename T> static ArgAction store_const(const T& value)
607  {
608  return [&, value](Arg& arg, cspan<const char*> myarg) {
609  arg.argparse().params()[arg.dest()] = value;
610  };
611  }
612 
613  static ArgAction store_const(const char* value)
614  {
615  return [&, value](Arg& arg, cspan<const char*> myarg) {
616  arg.argparse().params()[arg.dest()] = string_view(value);
617  };
618  }
619 
620  /// Return an action that stores into its destination attribute the
621  /// following `n` command line arguments (where `n` is the number of
622  /// additional command line arguments that this option requires).
623  template<typename T = ustring> static ArgAction store()
624  {
625  return [&](Arg& arg, cspan<const char*> myarg) {
626  if (myarg[0][0] == '-') // Skip command itself
627  myarg = myarg.subspan(1);
628  ParamValueList& pl(arg.argparse().params());
629  int n = int(myarg.size());
630  T* vals = OIIO_ALLOCA(T, n);
631  for (int i = 0; i < n; ++i)
632  vals[i] = Strutil::from_string<T>(myarg[i]);
633  if (n == 1) {
634  pl[arg.dest()] = vals[0];
635  } else { // array case -- always store as strings
636  pl.attribute(arg.dest(), TypeDesc(BaseTypeFromC<T>::value, n),
637  vals);
638  }
639  };
640  }
641 
642  /// Return an action that appends into its destination attribute the
643  /// following `n` command line arguments (where `n` is the number of
644  /// additional command line arguments that this option requires).
645  template<typename T = ustring> static ArgAction append()
646  {
647  return [&](Arg& arg, cspan<const char*> myarg) {
648  if (myarg[0][0] == '-') // Skip command itself
649  myarg = myarg.subspan(1);
650  ParamValueList& pl(arg.argparse().params());
651  ParamValue* pv = pl.find_pv(arg.dest());
652  // TypeDesc t = pv ? pv->type() : TypeUnknown;
653  int nold = pv ? pv->type().basevalues() : 0;
654  int nnew = int(myarg.size());
655  int n = nold + nnew;
656  T* vals = OIIO_ALLOCA(T, n);
657  for (int i = 0; i < nold; ++i)
658  vals[i] = Strutil::from_string<T>(pv->get_string_indexed(i));
659  for (int i = 0; i < nnew; ++i)
660  vals[i + nold] = Strutil::from_string<T>(myarg[i]);
661  if (n == 1) {
662  pl[arg.dest()] = vals[0];
663  } else { // array case -- always store as strings
664  pl.attribute(arg.dest(), TypeDesc(BaseTypeFromC<T>::value, n),
665  vals);
666  }
667  };
668  }
669 
670  /// Return an action that does nothing. I guess you could use use this
671  /// for an argument that is obsolete and is still accepted, but no
672  /// longer has any function.
673  static Action do_nothing();
674 
675  /// @}
676 
677 
678  // ------------------------------------------------------------------
679  /// @defgroup Retrieving values of parsed arguments
680  /// @{
681  ///
682  /// Retrieve arguments in the same manner that you would access them
683  /// from a OIIO::ParamValueList.
684  ///
685  /// Examples:
686  ///
687  /// // Please see the code example in the "Action library" section above
688  /// // for the argument declarations.
689  ///
690  /// // retrieve whether -v flag was set
691  /// bool verbose = ap["v"].get<int>();
692  ///
693  /// // Retrieve the parameter passed to --bar, defaulting to 13 if
694  /// // never set on the command line:
695  /// int bar = ap["bar"].get<int>(13);
696  ///
697  /// // Retrieve the color, which had 3 float parameters. Extract
698  /// // it as an Imath::Color3f.
699  /// Imath::Color3f diffuse = ap["color"].get<Imath::Color3f>();
700  ///
701  /// // Retrieve the filename list as a vector:
702  /// auto filenames = ap["filename"].as_vec<std::string>();
703  /// for (auto& f : filenames)
704  /// Strutil::printf(" file: \"%s\"\n", f);
705  ///
706 
707  /// Access a single argument result by name.
709  {
710  return { &cparams(), name };
711  }
712  /// Access a single argument result by name.
714  {
715  return { &params(), name };
716  }
717 
718  /// Directly access the ParamValueList that holds the argument results.
720  /// Directly access the ParamValueList that holds the argument results
721  /// (const version).
722  const ParamValueList& cparams() const;
723 
724  /// @}
725 
726 
727 private:
728  class Impl;
729  std::shared_ptr<Impl> m_impl; // PIMPL pattern
730  Arg& argx(const char* argname, ...);
731  friend class ArgOption;
732 
733 public:
734  // ------------------------------------------------------------------
735  // Old API. DEPRECATED(2.2)
736 
737  // Declare the command line options. After the introductory message,
738  // parameters are a set of format strings and variable pointers. Each
739  // string contains an option name and a scanf-like format string to
740  // enumerate the arguments of that option (eg. `"-option %d %f %s"`).
741  // The format string is followed by a list of pointers to the argument
742  // variables, just like scanf. A NULL terminates the list. Multiple
743  // calls to options() will append additional options.
744  int options(const char* intro, ...);
745 
746  // old name
747  // DEPRECATED(2.2)
748  int parse(int argc, const char** argv) { return parse_args(argc, argv); }
749 
750  // Type for a callback that writes something to the output stream.
751  typedef std::function<void(const ArgParse& ap, std::ostream&)> callback_t;
752  // Set callbacks to run that will print any matter you want as part
753  // of the verbose usage, before and after the options are detailed.
754  void set_preoption_help(callback_t callback);
755  void set_postoption_help(callback_t callback);
756 
757  // DEPRECATED(2.2) synonym for `print_help()`.
758  void usage() const { print_help(); }
759 };
760 
761 
762 
763 // Define symbols that let client applications determine if newly added
764 // features are supported.
765 #define OIIO_ARGPARSE_SUPPORTS_BRIEFUSAGE 1
766 #define OIIO_ARGPARSE_SUPPORTS_HUMAN_PARAMNAME 1
767 
OIIO_API std::string geterror(bool clear=true)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
void usage() const
Definition: argparse.h:758
OIIO_API bool has_error()
Is there a pending global error message waiting to be retrieved?
#define OIIO_ALLOCA(type, size)
Definition: platform.h:318
ArgParse(ArgParse &&other)
Move constructor.
Definition: argparse.h:196
static ArgAction store()
Definition: argparse.h:623
ArgParse & argparse()
Get a reference to the ArgParse that owns this Arg.
Definition: argparse.h:549
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
GLsizei const GLfloat * value
Definition: glcorearb.h:824
Arg & arg(const char *argname, T...args)
Shorter synonym for add_argument().
Definition: argparse.h:355
Definition: span.h:73
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:387
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:346
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:513
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1736
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:522
OIIO_HOSTDEVICE OIIO_CONSTEXPR14 size_t basevalues() const noexcept
Definition: typedesc.h:191
GLdouble n
Definition: glcorearb.h:2008
Arg & action(void(*func)())
Add an arbitrary action: func()
Definition: argparse.h:528
ArgParse & m_argparse
Definition: argparse.h:552
Arg & defaultval(const T &val)
Definition: argparse.h:478
AttrDelegate< ParamValueList > operator[](string_view name)
Access a single argument result by name.
Definition: argparse.h:713
constexpr size_type size() const noexcept
Definition: span.h:185
GLuint const GLchar * name
Definition: glcorearb.h:786
Arg(ArgParse &ap)
Definition: argparse.h:408
static ArgAction store_const(const T &value)
Definition: argparse.h:606
int parse(int argc, const char **argv)
Definition: argparse.h:748
static ArgAction append()
Definition: argparse.h:645
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:708
TypeDesc type() const noexcept
Definition: paramlist.h:155
std::function< void(Arg &arg, cspan< const char * > myargs)> ArgAction
Definition: argparse.h:391
GLuint GLfloat * val
Definition: glcorearb.h:1608
static ArgAction store_const(const char *value)
Definition: argparse.h:613
**If you just want to fire and args
Definition: thread.h:609
Definition: core.h:1131
Arg & arg(const char *argname)
Shorter synonym for add_argument().
Definition: argparse.h:352
Arg & action(int(*func)(int, const char **))
Definition: argparse.h:534
std::function< void(const ArgParse &ap, std::ostream &)> callback_t
Definition: argparse.h:751
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:94
ParamValueList & params()
Directly access the ParamValueList that holds the argument results.
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2976
constexpr pointer data() const noexcept
Definition: span.h:189
Arg & store_true()
Definition: argparse.h:491
Arg & store_false()
Definition: argparse.h:502
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:93