BDE 4.39.x Production Release
Loading...
Searching...
No Matches
balcl_commandline.h
Go to the documentation of this file.
1/// @file balcl_commandline.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balcl_commandline.h -*-C++-*-
8#ifndef INCLUDED_BALCL_COMMANDLINE
9#define INCLUDED_BALCL_COMMANDLINE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balcl_commandline balcl_commandline
15/// @brief Provide command line parsing, validation, and access.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balcl
19/// @{
20/// @addtogroup balcl_commandline
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balcl_commandline-purpose"> Purpose</a>
25/// * <a href="#balcl_commandline-classes"> Classes </a>
26/// * <a href="#balcl_commandline-description"> Description </a>
27/// * <a href="#balcl_commandline-component-features-summary"> Component Features Summary </a>
28/// * <a href="#balcl_commandline-background-for-unix-style-command-line-arguments-and-definitions"> Background for Unix-Style Command-Line Arguments and Definitions </a>
29/// * <a href="#balcl_commandline-specifying-option-values"> Specifying Option Values </a>
30/// * <a href="#balcl_commandline-flag-grouping"> Flag Grouping </a>
31/// * <a href="#balcl_commandline-multi-valued-options-and-how-to-specify-them"> Multi-Valued Options and How to Specify Them </a>
32/// * <a href="#balcl_commandline-order-of-arguments"> Order of Arguments </a>
33/// * <a href="#balcl_commandline-setting-options-via-environment-variables"> Setting Options via Environment Variables </a>
34/// * <a href="#balcl_commandline-setting-boolean-options-via-environment-variables"> Setting Boolean Options via Environment Variables </a>
35/// * <a href="#balcl_commandline-setting-array-options-via-environement-variables"> Setting Array Options via Environement Variables </a>
36/// * <a href="#balcl_commandline-best-practices-for-environment-variable-naming"> Best Practices for Environment Variable Naming </a>
37/// * <a href="#balcl_commandline-specifying-options"> Specifying Options </a>
38/// * <a href="#balcl_commandline-balcl-optioninfo-versus-balcl-option"> balcl::OptionInfo versus balcl::Option </a>
39/// * <a href="#balcl_commandline-tag-field"> Tag Field </a>
40/// * <a href="#balcl_commandline-name-field"> Name Field </a>
41/// * <a href="#balcl_commandline-description-field"> Description Field </a>
42/// * <a href="#balcl_commandline-type-and-constraint-field"> Type-and-Constraint Field </a>
43/// * <a href="#balcl_commandline-linked-variables"> Linked Variables </a>
44/// * <a href="#balcl_commandline-occurrence-information-field"> Occurrence Information Field </a>
45/// * <a href="#balcl_commandline-environment-variable-name-field"> Environment Variable Name Field </a>
46/// * <a href="#balcl_commandline-example-field-values"> Example Field Values </a>
47/// * <a href="#balcl_commandline-example-tag-field"> Example: Tag Field </a>
48/// * <a href="#balcl_commandline-example-name-field"> Example: Name Field </a>
49/// * <a href="#balcl_commandline-example-type-and-constraint-field"> Example: Type-and-Constraint Field </a>
50/// * <a href="#balcl_commandline-example-occurrence-information-field"> Example: Occurrence Information Field </a>
51/// * <a href="#balcl_commandline-example-environment-variable-name-field"> Example: Environment Variable Name Field </a>
52/// * <a href="#balcl_commandline-supported-types"> Supported Types </a>
53/// * <a href="#balcl_commandline-supported-constraint-values"> Supported Constraint Values </a>
54/// * <a href="#balcl_commandline-building-new-constraints"> Building New Constraints </a>
55/// * <a href="#balcl_commandline-valid-balcl-optioninfo-specifications"> Valid balcl::OptionInfo Specifications </a>
56/// * <a href="#balcl_commandline-tagnamedescription-fields"> TagNameDescription Fields </a>
57/// * <a href="#balcl_commandline-default-values"> Default Values </a>
58/// * <a href="#balcl_commandline-non-option-arguments"> Non-Option Arguments </a>
59/// * <a href="#balcl_commandline-boolean-options"> Boolean Options (Flags) </a>
60/// * <a href="#balcl_commandline-usage"> Usage </a>
61/// * <a href="#balcl_commandline-example-1-parsing-command-line-options-using-minimal-functionality"> Example 1: Parsing Command Line Options Using Minimal Functionality </a>
62/// * <a href="#balcl_commandline-example-2-accessing-option-values-through-balcl-commandline-accessors"> Example 2: Accessing Option Values Through balcl::CommandLine Accessors </a>
63/// * <a href="#balcl_commandline-example-3-default-values-and-specifying-values-via-the-environment"> Example 3: Default Values and Specifying Values Via The Environment </a>
64/// * <a href="#balcl_commandline-example-4-option-constraints"> Example 4: Option Constraints </a>
65/// * <a href="#balcl_commandline-example-5-using-bsl-optional-for-optional-command-line-parameters"> Example 5: Using bsl::optional for Optional Command Line Parameters </a>
66///
67/// # Purpose {#balcl_commandline-purpose}
68/// Provide command line parsing, validation, and access.
69///
70/// # Classes {#balcl_commandline-classes}
71///
72/// - balcl::CommandLine: value-semantic command-line arguments
73/// - balcl::CommandLineOptionsHandle: references to parsed options
74///
75/// @see balcl_optionvalue, balcl_optiontype
76///
77/// # Description {#balcl_commandline-description}
78/// This component provides a value-semantic class,
79/// `balcl::CommandLine`, used to represent the command-line arguments passed to
80/// a process. Also provided is `balcl::CommandLineOptionsHandle`, an
81/// optionally-used class that provides an alternate means of access to the
82/// options (and associative values, if any) found in a `balcl::CommandLine`
83/// object in a "parsed" state.
84///
85/// The constructor of `balcl::CommandLine` takes a specification describing the
86/// command-line arguments. Once created, `printUsage` can be invoked to print
87/// the usage syntax. The `parse` method takes command-line arguments and
88/// validates them against the specification supplied at construction, printing
89/// suitable messages on an optionally-specified stream in case of a parsing
90/// error. Once parsed, options and values can be accessed using various access
91/// methods. The class provides a set of *theType* access methods (for example,
92/// `theString`, `theInt`) that return the value of the specified option name.
93/// It is also possible to link a variable with an option in the specification;
94/// doing so will cause the variable to be loaded with the option value once
95/// `parse` has been invoked and was successful.
96///
97/// ## Component Features Summary {#balcl_commandline-component-features-summary}
98///
99///
100/// This component offers the following features:
101///
102/// 1. Validation of command-line arguments against the provided specification.
103/// 2. The ability to specify sophisticated constraints easily. Users can also
104/// build their own constraints and use them in the specification.
105/// 3. The ability to automatically generate usage syntax.
106/// 4. The ability to directly link a variable to an option. Parsing a command
107/// line loads such variables with the option value as specified on the
108/// command line (or a default value if one is configured). Linked variables
109/// provide a sometimes convenient alternative to using the accessor methods.
110/// See {Type-and-Constraint Field}. Linked variables can be `bsl::optional`
111/// objects for each of the scalar option types except `bool`.
112/// 5. The ability to access options and their corresponding values through
113/// various accessor methods.
114/// 6. The ability to parse Unix-style command lines (for example, grouping of
115/// flags, allowing any ordering of options, or a mix between options and
116/// non-option arguments, short tag and long tag forms, etc.).
117/// 7. The ability to have multiple non-option arguments of possibly different
118/// types. Note that only the last non-option argument may be multi-valued,
119/// and that if a non-option has a default value, then all subsequent
120/// non-options must also have a default value.
121/// 8. The ability to specify option values through environment variables.
122/// 9. The ability to specify defaults for options, to be used when options are
123/// not specified on the command line or through environment variables.
124///
125/// A lower bound can be placed on the number of multi-valued non-option
126/// arguments (e.g., two or more values) can be achieved by explicitly
127/// specifying the required number of single-valued non-option arguments of the
128/// same type before the unrestricted multi-value non-option of that same type.
129///
130/// ## Background for Unix-Style Command-Line Arguments and Definitions {#balcl_commandline-background-for-unix-style-command-line-arguments-and-definitions}
131///
132///
133/// This section provides background on Unix-style command-line arguments, as
134/// well as definitions of terms used frequently in this documentation (such as
135/// "option", "flag", "non-option", "tag", "short tag", "long tag"). Readers
136/// familiar with Unix command lines can skim this section or omit entirely.
137///
138/// Command-line arguments can be classified as:
139///
140/// * command name (there is only one, and it is always the first argument)
141/// * options (tags and associated values)
142/// * flags (boolean options)
143/// * non-option arguments
144///
145/// For example, in the following command line:
146/// @code
147/// $ mybuildcommand -e -c CC64 myproject
148/// @endcode
149/// the command name is `mybuildcommand`. There is one option, described by
150/// `-c CC64`: `c` is the tag name, and `CC64` is the option value. There is
151/// also one boolean option (flag): `-e` is a flag, `e` is the flag name. The
152/// last parameter, `myproject`, is a non-option argument.
153///
154/// Sometimes *option* is also used where "flag" or "non-option" would be more
155/// accurate. What is actually intended should be clear from context.
156///
157/// A user specifies an option on a command line by entering one of the tag
158/// values configured for that option. Each option has a mandatory long tag and
159/// an optional short tag. The short tag, if specified, must be a single
160/// character; the long tag generally must follow the same rules applicable to
161/// C/C++ identifiers, except that `-` is allowed (but not as the leading
162/// character). When a short tag is used on a command line, it must be preceded
163/// by `-`, and when a long tag is used it must be preceded by `--`. Flags have
164/// no corresponding values; they are either present or absent. Option tags
165/// *must* be followed by a corresponding option value. An option can have
166/// multiple values (such options are called multi-valued options). When
167/// multiple values are provided for an option, the tag must appear with each
168/// value (see the section {Multi-Valued Options and How to Specify Them}).
169/// Arguments that are not the command name, options, or flags are called
170/// "non-option" arguments and can be either single-valued or multi-valued.
171/// They do not have any tag associated with them.
172///
173/// Consider the syntax of a typical Unix-style command whose options are
174/// described by the usage string:
175/// @code
176/// usage: mysort [-r|reverse] [-o|outputfile <outfile>] files...
177/// @endcode
178/// Here:
179/// @code
180/// '-r|reverse' is a flag: 'r' is the short tag, 'reverse' is the long tag.
181///
182/// '-o|outputfile' is an option: 'o' is the short tag, 'outputfile' is the
183/// long tag. The value is parsed from the string 'outfile'.
184///
185/// 'files...' describes the multi-valued non-option argument.
186/// @endcode
187/// The command can be invoked as follows:
188/// @code
189/// $ mysort -r -o myoutfile file1 file2 file3
190/// @endcode
191/// and an equivalent command line is:
192/// @code
193/// $ mysort --reverse --outputfile myoutfile file1 file2 file3
194/// @endcode
195/// Note that short tags must be prepended with `-` and long tags with `--`. To
196/// specify a non-option argument beginning with `-`, use a single `--`
197/// separator (not followed by a long tag).
198///
199/// ## Specifying Option Values {#balcl_commandline-specifying-option-values}
200///
201///
202/// This component supports a variety of forms for specifying option values.
203/// They are best described by example. Consider the command-line specification
204/// described by the following usage string:
205/// @code
206/// usage: myserver [-p|port <portNumber>]
207/// @endcode
208/// The following (valid) forms can be used with equivalent meaning:
209/// @code
210/// $ myserver -p 13
211/// $ myserver -p=13 # option value is '13' and *not* '=13'
212/// $ myserver -p13
213/// $ myserver --port 13
214/// $ myserver --port=13
215/// @endcode
216/// Note that if `=13` is desired as an option value, then whitespace must be
217/// used as in:
218/// @code
219/// $ myserver -p =13 # option value *is* '=13'
220/// @endcode
221/// All of the following are invalid:
222/// @code
223/// $ myserver -port13
224/// $ myserver --p 13
225/// $ myserver -port 13
226/// @endcode
227///
228/// ## Flag Grouping {#balcl_commandline-flag-grouping}
229///
230///
231/// Flags can be grouped (i.e., expressed more succinctly like `-ctv` instead of
232/// `-c -t -v`). While grouping flags, short tags must be used. For example,
233/// given the command-line specification described by the following usage
234/// string:
235/// @code
236/// usage: mysort [-r|reverse] [-i|insensitiveToCase] [-u|uniq]
237/// @endcode
238/// the following command lines are valid and equivalent:
239/// @code
240/// $ mysort -r -i -u
241/// $ cmd -riu
242/// $ cmd -uir
243/// $ cmd -i -ru
244/// @endcode
245/// Note that the last character in a group need not be a flag; it could be an
246/// option. Any character that is the short tag of an option signals the end of
247/// the flag group, and it must be followed by the value of the option. For
248/// example, given the command-line specification described by the following
249/// usage string:
250/// @code
251/// usage: mysort [-r|reverse] [-i|insensitiveToCase] [-u|uniq]
252/// [-o|outfile <outputfile>]
253/// @endcode
254/// the following command lines are valid and equivalent:
255/// @code
256/// $ mysort -riu -o myoutfile
257/// $ mysort -riuo myoutfile
258/// $ mysort -riuomyoutfile
259/// $ mysort -riuo=myoutfile
260/// @endcode
261///
262/// ## Multi-Valued Options and How to Specify Them {#balcl_commandline-multi-valued-options-and-how-to-specify-them}
263///
264///
265/// Options can have several values. For example, in the command-line
266/// specification described by the following usage string, `*` denotes a
267/// multi-valued option, and `+` denotes a multivalued option that must occur at
268/// least once.
269/// @code
270/// usage: mycompiler [-l|library <libName>]* [-o|out outFile] [<object>]+
271/// @endcode
272/// multiple values can be given as follows:
273/// @code
274/// $ mycompiler -l lib1 -l lib2 -l lib3 -o main a.o b.o
275/// @endcode
276/// They need not be supplied contiguously. For example, the following command
277/// line is valid and equivalent to the above:
278/// @code
279/// $ mycompiler -l lib1 -o main -l lib2 -l lib3 a.o b.o
280/// @endcode
281/// Note that the tag needs to be repeated for every option value. For example,
282/// the following command line is invalid (because `-l` must be repeated before
283/// both `lib2` and `lib3`):
284/// @code
285/// $ mycompiler -l lib1 lib2 lib3 -o main a.o b.o
286/// @endcode
287/// Short and long forms can be used in mixed fashion, however:
288/// @code
289/// $ mycompiler -l lib1 -o main --library lib2 -l lib3 a.o b.o
290/// @endcode
291///
292/// ## Order of Arguments {#balcl_commandline-order-of-arguments}
293///
294///
295/// Command-line arguments can appear in any order. For example, given the
296/// command-line specification described by the following usage string:
297/// @code
298/// usage: mysort [-r|reverse] [-o|outputfile <outfile>] [<file>]+
299/// @endcode
300/// all the following command lines are valid (and equivalent):
301/// @code
302/// $ mysort -r -o myoutfile file1 file2 file3
303/// $ mysort file1 file2 file3 -r -o myoutfile
304/// $ mysort file1 -o myoutfile file2 -r file3
305/// $ mysort file1 -o=myoutfile file2 -r file3
306/// @endcode
307/// There are three exceptions to the above rule on argument order:
308///
309/// 1. An option tag must be followed by that option's value, if any (either in
310/// the next argument, or in the same argument using "=value").
311/// 2. When a non-option argument starts with a `-` then it must not appear
312/// before any option or flag *and* a `--` must be put on the command line to
313/// indicate the end of all options and flags.
314/// 3. Non-option arguments are parsed and assigned in the order they appear on
315/// the command line.
316///
317/// For example, the following is invalid because of rule (1) above (because
318/// `-o` should be followed by `myoutfile`):
319/// @code
320/// $ mysort -o -r myoutfile file1 file2 file3
321/// @endcode
322/// and the following is incorrect because of rule (2) (because
323/// `-weirdfilename`, which starts with `-`, must appear after `--`):
324/// @code
325/// $ mysort -weirdfilename file2 file3 -r -o myoutfile
326/// @endcode
327/// The previous examples can be corrected in either of the following ways:
328/// @code
329/// $ mysort -r -o myoutfile -- -weirdfilename file2 file3
330/// $ mysort file2 file3 -r -o myoutfile -- -weirdfilename
331/// @endcode
332/// Note that the order of values within the sequence of multi-valued non-option
333/// arguments differs in both examples, as per rule (3). In the first example,
334/// the non-option arguments have for a value the (ordered) sequence:
335/// @code
336/// -weirdfilename file2 file3
337/// @endcode
338/// while in the second example, the non-option argument value is the sequence:
339/// @code
340/// file2 file3 -weirdfilename
341/// @endcode
342/// This order may or may not matter to the application.
343///
344/// ## Setting Options via Environment Variables {#balcl_commandline-setting-options-via-environment-variables}
345///
346///
347/// Sometimes users may wish to supply configuration via environment variables,
348/// which is common practice, for example, for services deployed via Docker
349/// containers in cloud environments.
350///
351/// By default, parsed command line option values are unaffected by the
352/// environment. If an environment variable name is specified for an option,
353/// then, during parsing, if an option is not set on the command line, and the
354/// specified environment variable has a value, that value is used for the
355/// command line option. If a value is not supplied, either via the command
356/// line, or via an environment variable, then the default value for the option,
357/// if any, is used.
358///
359/// ### Setting Boolean Options via Environment Variables {#balcl_commandline-setting-boolean-options-via-environment-variables}
360///
361///
362/// Boolean options when set via the environment variable must be associated
363/// with a string.
364/// @code
365/// +---------------+--------------+
366/// | desired value | valid text |
367/// +---------------+--------------+
368/// | true | "true", "1" |
369/// | false | "false", "0" |
370/// +---------------+--------------+
371/// @endcode
372/// Any other text, including an empty string, is treated as invalid input.
373///
374/// ### Setting Array Options via Environement Variables {#balcl_commandline-setting-array-options-via-environement-variables}
375///
376///
377/// Array options can be set by environment variable. When an array option is
378/// supplied via an environment variable string, the discrete values must be
379/// separated using the space character. For example, if the program takes an
380/// integer array of years as an option, and that option is associated with the
381/// environment variable name "MYPROG_YEARS", to supply a value via the command
382/// line one could specify:
383/// @code
384/// $ export MYPROG_YEARS="2010 2014 2018 2022"
385/// @endcode
386/// The '\' is used as an escape-character if an element of an array contains a
387/// space. For example:
388/// @code
389/// $ export MYPROG_WINPATH='C:\\Program\ Files\\MyProg D:\\Another\\Path'
390/// @endcode
391/// would configure an array containing "C:\Program Files\MyProg" and
392/// "D:\Another\Path".
393///
394/// ### Best Practices for Environment Variable Naming {#balcl_commandline-best-practices-for-environment-variable-naming}
395///
396///
397/// Environment variable exist in a single namespace accessed by all programs
398/// run in the shell, and many environment variable names are used by many
399/// different systems for different purposes. For that reason, we strongly
400/// encourage selecting a (ideally) unique prefix for the environment variables
401/// used by your application, to reduce the likelihood of collisions with
402/// environment variables used by other applications for different purposes.
403///
404/// For example, if someone were writing a trading application `tradesvc`, they
405/// might choose to use "TRADESVC_" as a common prefix for the environment
406/// variables.
407///
408/// ## Specifying Options {#balcl_commandline-specifying-options}
409///
410///
411/// A command line is described by an *option* *table* (supplied as an array of
412/// `balcl::OptionInfo`). Each entry (row) of the table describes an option
413/// (i.e., an option, flag, or non-option argument). Each entry has several
414/// fields, specified in the following order:
415/// @code
416/// Field name Main purpose (see below for more details)
417/// ============================ ===========================================
418/// tag field Specify tags (short and long) for options
419/// and flags. A non-option argument is
420/// indicated by an empty string.
421///
422/// name field Specify the name through which the option
423/// value can be accessed.
424///
425/// description field Used in printing usage.
426///
427/// type-and-constraint field (1) Specify the type of the option value(s).
428/// (2) Specify a variable to be linked to the
429/// option.
430/// (3) Specify other constraints on individual
431/// value(s).
432///
433/// occurrence information field (1) Specify a default value for an option.
434/// (2) Specify whether an option is required on
435/// the command line or is optional (by
436/// default, an option is optional).
437///
438/// environment variable name Specify an environment variable name that
439/// can be used to set the option.
440/// @endcode
441/// The first three fields *must* be specified. The type-and-constraint field
442/// can be omitted (meaning no constraint), and the occurrence information field
443/// likewise can be omitted (meaning that the option is not required on the
444/// command line).
445///
446/// The following sections provide a more detailed description of each field,
447/// including example values for each field.
448///
449/// ### balcl::OptionInfo versus balcl::Option {#balcl_commandline-balcl-optioninfo-versus-balcl-option}
450///
451///
452/// In some applications, command-line specifications *must* *be* defined using
453/// a statically-initialized array. For that reason, there are two classes that
454/// serve the same purpose: `balcl::OptionInfo` is a statically-initializable
455/// class but it does not conform to the `bslma` allocator protocol, while
456/// `balcl::Option` is convertible from `balcl::OptionInfo`, takes allocators,
457/// and is suitable for storing into containers.
458///
459/// ### Tag Field {#balcl_commandline-tag-field}
460///
461///
462/// The tag field specifies the (optional) short tag and long tag for the
463/// corresponding option or flag, except that non-option arguments are indicated
464/// by an empty string for a tag field. There can only be one multi-valued
465/// entry for non-option arguments, and it must be listed last among the
466/// non-options.
467///
468/// The general format is either:
469/// 1. "" (empty string) for non-option arguments;
470/// 2. "<s>|<long>" for options and flags, where `<s>` is the short tag, and
471/// `<long>` is the long tag; or
472/// 3. "<long>" for options and flags where a short tag is not specified.
473///
474/// Note that for short tags (`<s>`), `s` must be a single character (different
475/// from `-` and `|`); for long tags ("<long>"), `long` must have 2 or more
476/// characters (which may contain `-`, but not as the first character, and
477/// cannot contain `|`). Also note that either no tag (empty string), both
478/// short and long tags, or only a long tag, may be specified.
479///
480/// The tag field cannot be omitted, but it can be the empty string.
481///
482/// ### Name Field {#balcl_commandline-name-field}
483///
484///
485/// The name field specifies the name through which the option value can be
486/// accessed either through one of the *theType* methods.
487///
488/// The general format is any non-empty string. In most cases, the name will be
489/// used as-is. Note that any suffix starting at the first occurrence of `=`,
490/// if any, is removed from the name before storing in the `balcl::Option`.
491/// Thus, if a name having such a suffix is specified in a `balcl::OptionInfo`
492/// (e.g., "nameOption=someAttribute"), the correct name to use for querying
493/// this option by name does not include the suffix (e.g.,
494/// `cmdLine.numSpecified("nameOption=someAttribute")` will always return 0, but
495/// `cmdLine.numSpecified("nameOption")` will return the appropriate value).
496///
497/// This field cannot be omitted, and it cannot be an empty string.
498///
499/// ### Description Field {#balcl_commandline-description-field}
500///
501///
502/// The description field is used when printing the usage string.
503///
504/// The general format is any non-empty string.
505///
506/// This field cannot be omitted, and it cannot be an empty string.
507///
508/// ### Type-and-Constraint Field {#balcl_commandline-type-and-constraint-field}
509///
510///
511/// The type-and-constraint field specifies the type and constraints for the
512/// option values. Flags are identified by having the boolean type; note that
513/// flags cannot have constraints. Multiple values (for multi-valued options
514/// and multi-valued non-option arguments) can be specified by using array
515/// types. The list of the supported types is provided in the section
516/// @ref balcl_commandline-supported-types below.
517///
518/// Other constraints can be placed on individual value(s). When the type is an
519/// array type, then those constraints are placed on the individual value(s)
520/// held in the array and not on the entire array. A list of useful constraints
521/// is provided in the section @ref balcl_commandline-supported-constraint-values . Also see the
522/// section @ref balcl_commandline-building-new-constraints to see how new constraints can be built
523/// so that they can be used in the same manner as the available constraints.
524///
525/// Additionally, this field allows a specified variable to be linked to the
526/// option. In that case, after parsing, the variable is loaded with the option
527/// value specified on the command line (or its default value, if any, if the
528/// option is absent from the command line). @ref balcl_commandline-occurrence-information-field
529/// describes how to configure a default value.
530///
531/// The general format can be one of either:
532/// @code
533/// /// Link the option with the specified `variable`. Note that the option
534/// /// type is inferred from the type of `variable`. Optionally place the
535/// /// user-specified `constraint`, of a type defined in
536/// /// `balcl::Constraint`, on the value.
537/// balcl::TypeInfo(&variable)
538/// balcl::TypeInfo(&variable, constraint)
539///
540/// /// Specify the type of this option to be of the specified `type`.
541/// /// Optionally place the user-specified `constraint`, of a type defined
542/// /// in `balcl::Constraint`, on the value. Don't link this
543/// /// option with any variable. `type` must be one of the static
544/// /// variables (null pointers) listed in @ref balcl_optiontype-enumerators .
545/// balcl::TypeInfo(type)
546/// balcl::TypeInfo(type, constraint)
547/// @endcode
548/// This field can be omitted. If so, the type is assumed to be of string type
549/// with no constraints and no variable is linked to the option. No occurrence
550/// information field can then be specified; if such a field is desired, then
551/// the type-and-constraint field needs to be set explicitly.
552///
553/// #### Linked Variables {#balcl_commandline-linked-variables}
554///
555///
556/// Linked variables are updated by the `parse` method of `balcl::CommandLine`
557/// should that method determine a value for an option; otherwise, the linked
558/// variable is left unchanged. The value for an option is determined either
559/// from the command-line arguments passed to `parse` or obtained from a
560/// pre-configured default value, if any (see
561/// @ref balcl_commandline-occurrence-information-field ).
562///
563/// Linked variables can be `bsl::optional` objects that wrap any of the
564/// non-array option types except for `bool` (see @ref balcl_commandline-supported-types ). Also,
565/// a link to a `bsl::optional` object is disallowed if the option is "required"
566/// or has a default value (see @ref balcl_commandline-occurrence-information-field ).
567///
568/// ### Occurrence Information Field {#balcl_commandline-occurrence-information-field}
569///
570///
571/// The occurrence information field is used to specify a default value for an
572/// option, and whether an option is required on the command line or is
573/// optional. An option may also be "hidden" (i.e., not displayed by
574/// `printUsage`).
575///
576/// The general format of this field is one of the following:
577/// @code
578/// balcl::OccurrenceInfo::e_HIDDEN
579/// balcl::OccurrenceInfo::e_OPTIONAL
580/// balcl::OccurrenceInfo::e_REQUIRED
581/// a default value
582/// @endcode
583/// If a default value is specified, the option is assumed to be optional; in
584/// addition, the default value must satisfy the type and constraint indicated
585/// by the specified type-and-constraint field.
586///
587/// This field can be omitted, and is always omitted if the type-and-constraint
588/// field is not specified. If omitted, the option is not required on the
589/// command line and has no default value; furthermore, if the option is not
590/// present on the command line, the linked variable, if any, is unaffected.
591///
592/// ### Environment Variable Name Field {#balcl_commandline-environment-variable-name-field}
593///
594///
595/// The environment variable name field is used to specify a string which is the
596/// name of an environment variable which, if set, allows the environment to be
597/// searched for a value of the option. If an option is specified on the
598/// command line, the environment is never searched for that option. If an
599/// option has a default value, and a value is specified in the environment, the
600/// value in the environment takes precedence over the default value.
601///
602/// ## Example Field Values {#balcl_commandline-example-field-values}
603///
604///
605/// The following tables give examples of field values.
606///
607/// ### Example: Tag Field {#balcl_commandline-example-tag-field}
608///
609///
610/// The tag field may be declared using the following forms:
611/// @code
612/// Usage Meaning
613/// ============== =======================================================
614/// "o|outputfile" The option being defined is either an option or a flag.
615/// The short tag is "o" and the long tag is "outputfile".
616///
617/// Note that "o" alone is invalid since a long tag must be
618/// specified.
619///
620/// "outputfile" The option being defined is either an option or a flag.
621/// There is no short tag and the long tag is "outputfile".
622///
623/// "" Specifies a non-option argument.
624/// @endcode
625///
626/// ### Example: Name Field {#balcl_commandline-example-name-field}
627///
628///
629/// The name field may be declared using the following form:
630/// @code
631/// Usage Meaning
632/// =============== =======================================================
633/// "xyz" The option value can be accessed by "xyz".
634/// @endcode
635///
636/// ### Example: Type-and-Constraint Field {#balcl_commandline-example-type-and-constraint-field}
637///
638///
639/// Suppose, for example, that our application has the following parameters:
640/// @code
641/// int portNum; // a variable to be linked to an
642/// // option
643///
644/// bool isVerbose; // a variable to be linked to a flag
645///
646/// bsl::vector<bsl::string> fileNames; // a variable to be linked to a
647/// // multi-valued option
648/// @endcode
649/// The type and constraint fields may be declared using the following values:
650/// @code
651/// Usage Meaning
652/// =============== =======================================================
653/// balcl::TypeInfo(&portNum)
654/// (1) Link the variable 'portNum' with this option value.
655/// That is, after successful parsing, this variable will
656/// contain the option value specified on the command line.
657/// (2) An integer value must be provided on the command
658/// line for this option (the type 'int' is inferred
659/// implicitly from the type of 'portNum').
660///
661/// balcl::TypeInfo(balcl::OptionType::k_INT)
662/// This option value must be an integer. Since there is no
663/// linked variable, the value of the option must be obtained
664/// using the field name passed to the 'the<TYPE>' accessor
665/// (in this case 'theInt').
666///
667/// balcl::TypeInfo(&isVerbose)
668/// Load the variable 'isVerbose' with this option value.
669///
670/// balcl::TypeInfo(balcl::OptionType::k_BOOL)
671/// This option is a flag.
672///
673/// balcl::TypeInfo(&fileNames)
674/// Load the variable 'fileNames' with the values specified
675/// for this multi-valued option (or multi-valued
676/// non-option argument). That is, after successful parsing,
677/// this variable will contain the sequence of values
678/// specified on the command line, in the same order.
679///
680/// balcl::TypeInfo(balcl::OptionType::k_STRING_ARRAY)
681/// This option value consists of a sequence of string
682/// values specified on the command line, in the same order.
683/// @endcode
684///
685/// ### Example: Occurrence Information Field {#balcl_commandline-example-occurrence-information-field}
686///
687///
688/// The following values may be used for this field:
689/// @code
690/// Usage Meaning
691/// =============== ========================================================
692/// balcl::OccurrenceInfo::e_REQUIRED
693/// The value(s) for this option *must* be provided on the
694/// command line. For options that are of an array type, at
695/// least one value must be provided. Omission manifests
696/// as a parse error.
697///
698/// balcl::OccurrenceInfo::e_OPTIONAL
699/// Value(s) for this option may be omitted on the command
700/// line.
701///
702/// balcl::OccurrenceInfo::e_HIDDEN
703/// Same as 'e_OPTIONAL'; in addition, this option will not
704/// be displayed by 'printUsage'.
705///
706/// 13 The default value for this option is 13 and the option
707/// is not required on the command line. If no value is
708/// provided, then 13 is used. If the type described by the
709/// type-and-constraint field is not integer, then it is an
710/// error.
711/// @endcode
712/// *Note*: If an option is optional *and* no value is provided on the command
713/// line or through an environment variable, `isSpecified` will will return
714/// `false and `numSpecified' will return 0. If no default value is provided
715/// and if the variable is a linked variable, it will be unmodified by the
716/// parsing. If the variable is accessed through
717/// `CommandLineOptionsHandle::value`, it will be in a null state (defined type
718/// but *no* defined value).
719///
720/// ### Example: Environment Variable Name Field {#balcl_commandline-example-environment-variable-name-field}
721///
722///
723/// The name field may be declared using the following form:
724/// @code
725/// Usage Meaning
726/// =============== =======================================================
727/// "MYPROG_XYZ" The option can be set by "export MYPROG_XYZ=<value>"
728/// @endcode
729///
730/// ## Supported Types {#balcl_commandline-supported-types}
731///
732///
733/// The following types are supported. The type is specified by an enumeration
734/// value (see @ref balcl_optiontype ) supplied as the first argument to:
735/// @code
736/// balcl::TypeInfo(type, constraint)
737/// @endcode
738/// which is used to create the type-and-constraint field value in the
739/// command-line specification. When the constraint need only specify the type
740/// of the option value (i.e., no linked variable or programmatic constraint),
741/// one can supply any of the public data members of `balcl::OptionType` shown
742/// below:
743/// @code
744/// Type Specifier
745/// ----------------------------- -------------------------
746/// bool OptionType::k_BOOL
747/// char OptionType::k_CHAR
748/// int OptionType::k_INT
749/// bsls::Types::Int64 OptionType::k_INT64
750/// double OptionType::k_DOUBLE
751/// bsl::string OptionType::k_STRING
752/// bdlt::Datetime OptionType::k_DATETIME
753/// bdlt::Date OptionType::k_DATE
754/// bdlt::Time OptionType::k_TIME
755/// bsl::vector<char> OptionType::k_CHAR_ARRAY
756/// bsl::vector<int> OptionType::k_INT_ARRAY
757/// bsl::vector<bsls::Types::Int64> OptionType::k_INT64_ARRAY
758/// bsl::vector<double> OptionType::k_DOUBLE_ARRAY
759/// bsl::vector<bsl::string> OptionType::k_STRING_ARRAY
760/// bsl::vector<bdlt::Datetime> OptionType::k_DATETIME_ARRAY
761/// bsl::vector<bdlt::Date> OptionType::k_DATE_ARRAY
762/// bsl::vector<bdlt::Time> OptionType::k_TIME_ARRAY
763/// @endcode
764/// The ASCII representation of these values (i.e., the actual format of the
765/// values on command lines) depends on the type:
766/// * Numeric Values: see @ref bdlb_numericparseutil .
767/// * Date/Time Values: see @ref bdlt_iso8601util .
768///
769/// ## Supported Constraint Values {#balcl_commandline-supported-constraint-values}
770///
771///
772/// This component supports constraint values for each supported type except
773/// `bool`. Specifically, the utility `struct` `balcl::Constraint` defines
774/// `TYPEConstraint` types (for instance, `StringConstraint`, `IntConstraint`)
775/// that can be used to define a constraint suitable for the `balcl::TypeInfo`
776/// class.
777///
778/// ## Building New Constraints {#balcl_commandline-building-new-constraints}
779///
780///
781/// A constraint is simply a function object that takes as its first argument
782/// the (address of the) data to be constrained and as its second argument the
783/// stream that should be written to with an appropriate error message when the
784/// data does not follow the constraint. The functor should return a `bool`
785/// value indicating whether or not the data abides by the constraint (with
786/// `true` indicating success). A constraint for a given option whose value has
787/// the given type must be convertible to one of the `TYPEConstraint` types
788/// defined in the utility `struct` `balcl::Constraint`. Note that when passing
789/// a function as a constraint, the *address* of the function must be passed.
790///
791/// ## Valid balcl::OptionInfo Specifications {#balcl_commandline-valid-balcl-optioninfo-specifications}
792///
793///
794/// The `balcl::CommandLine` class has a complex set of preconditions on the
795/// option specification table (array of `balcl::OptionInfo` objects) passed to
796/// each of its constructors. There are requirements on individual elements, on
797/// elements relative to each other, and on the entire set of elements. If
798/// these preconditions are not met, the behavior of the constructor is
799/// undefined.
800///
801/// The preconditions (some previously mentioned) are given in their entirety
802/// below. Moreover, an overloaded class method,
803/// `balcl::CommandLine::isValidOptionSpecification`, is provided to allow
804/// programmatic checking without risk of incurring undefined behavior.
805///
806/// ### TagNameDescription Fields {#balcl_commandline-tagnamedescription-fields}
807///
808///
809/// The tag, name, and description fields must pass the `isTagValid`,
810/// `isNameValid, and `isDescriptionValid' methods of `balcl::Option`,
811/// respectively.
812///
813/// * The tag field:
814/// - If empty (a non-option argument), the option must not be a flag.
815/// - If non-empty, see {Tag Field} above for details.
816/// * The name field must be non-empty.
817/// * The description field must be non-empty.
818///
819/// Collectively, each non-empty short tag, each long tag, and each name must be
820/// unique in the specification.
821///
822/// ### Default Values {#balcl_commandline-default-values}
823///
824///
825/// * Default values are disallowed for flags.
826/// * The type of a default value must match the type of its option.
827/// * The default value must satisfy the user-defined constraint on the option
828/// value, if any.
829///
830/// ### Non-Option Arguments {#balcl_commandline-non-option-arguments}
831///
832///
833/// * Cannot be a flag (see {Tag/Name/Description Fields}).
834/// * Cannot be a hidden option.
835/// * Only the last non-option argument can be multi-valued (i.e., an array
836/// type).
837/// * If a non-option argument has a default value, all subsequent non-option
838/// arguments must also have default values.
839///
840/// ### Boolean Options (Flags) {#balcl_commandline-boolean-options}
841///
842///
843/// Options having the `bool` type (also known as "flags") are distinguished
844/// from the other supported option types in several ways:
845///
846/// * The command-line syntax does not allow an explicit value for flag types
847/// (e.g., `-x=true` and `-xFlag false` are disallowed when setting booleans
848/// on the command line). The presence or absence of the tag name (either
849/// long or short form) on the command line determines the value of the
850/// option.
851/// * If providing a boolean option through an environment variable, an
852/// explicit value is required, and that value must be either "true", "1",
853/// "false", or "0" -- any other value, including the empty string, is
854/// invalid (see {Setting Boolean Options via Environment Variables}).
855/// * The boolean option type has no "array" form (i.e., there is no
856/// `BoolArray` option type).
857/// - Multiple instances of the tag for a boolean option are allowed on the
858/// command line (e.g., `-x -x -x`). For other option types, specifying
859/// multiple tags for a non-array option is an error.
860/// - Multiple instances of a boolean tag idempotently set the flag to
861/// `true`; however, one can determine the number of appearances by using
862/// the `position` accessor.
863/// * A boolean option type cannot be configured to:
864/// - have a default value, or
865/// - have a constraint, or
866/// - be linked to a `bsl::optional<bool>` variable.
867/// * A boolean option type *can* be configured to be a required parameter;
868/// however, that combination defeats the purpose of having a flag option so
869/// the requirement that the flag appear on the command line is *not*
870/// enforced.
871/// * The `theBool` method returns the same value (`true` or `false`) as the
872/// `isSpecified` method. In contrast, the `the*` accessor methods for the
873/// other option types have a precondition such that either `isSpecified()`
874/// must be `true` or the option must have a default value.
875///
876/// ## Usage {#balcl_commandline-usage}
877///
878///
879/// This section illustrates intended use of this component.
880///
881/// ### Example 1: Parsing Command Line Options Using Minimal Functionality {#balcl_commandline-example-1-parsing-command-line-options-using-minimal-functionality}
882///
883///
884/// Suppose we want to design a sorting utility named `mysort` that has the
885/// following syntax:
886/// @code
887/// Usage: mysort [-r|reverse] [-f|field-separator <fieldSeparator>]
888/// -o|outputfile <outputFile> [<fileList>]+
889/// // Sort the specified files (in 'fileList'), and
890/// // write the output to the specified output file.
891/// @endcode
892/// The `<fileList>` argument is a `non-option`, meaning that its value or
893/// values appear on the command line unannounced by tags. In this case, the
894/// `+` following the argument means that it is an array type of argument where
895/// at least one element is required, so its values are stored in a
896/// `bsl::vector`.
897/// @code
898/// int main(int argc, const char **argv)
899/// {
900/// using balcl::TypeInfo;
901/// using balcl::OccurrenceInfo;
902/// @endcode
903/// First, we define our variables to be initialized from the command line. All
904/// values must be initialized to their default state:
905/// @code
906/// bool reverse = false;
907/// bsl::string outputFile;
908/// char fieldSeparator = '|';
909/// bsl::vector<bsl::string> files;
910/// @endcode
911/// Then, we define our `OptionInfo` table of attributes to be set. The fields
912/// of the `OptionInfo` are:
913///
914/// * tag - the tag on the command line for supplying the option
915/// * name - a one word description of the value to provide for the option
916/// * description - a short body of text describing the purpose of the option
917/// etc.
918/// * TypeInfo - information about the type of the input expected (possibly the
919/// variable in which to load the value)
920/// * OccurenceInfo - (optional) whether the option is required, optional, or
921/// hidden (where hidden means hidden from the help text)
922/// * environment variable name - (optional) the name of an environment
923/// variable to use for the option if the option is not provided on the
924/// command line
925/// @code
926/// static const balcl::OptionInfo specTable[] = {
927/// {
928/// "r|reverse", // tag
929/// "isReverse", // name
930/// "sort in reverse order", // description
931/// TypeInfo(&reverse), // link
932/// OccurrenceInfo(), // occurrence
933/// "" // env var name
934/// },
935/// {
936/// "f|field-separator", // tag
937/// "fieldSeparator", // name
938/// "field separator character", // description
939/// TypeInfo(&fieldSeparator), // link
940/// OccurrenceInfo(), // occurrence
941/// "" // env var name
942/// },
943/// {
944/// "o|outputfile", // tag
945/// "outputFile", // name
946/// "output file", // description
947/// TypeInfo(&outputFile), // link
948/// OccurrenceInfo::e_REQUIRED, // occurrence info
949/// // (not optional)
950/// "" // env var name
951/// },
952/// {
953/// "", // non-option
954/// "fileList", // name
955/// "input files to be sorted", // description
956/// TypeInfo(&files), // link
957/// OccurrenceInfo::e_REQUIRED, // occurrence info
958/// // (at least one
959/// // file required)
960/// "" // env var name
961/// }
962/// };
963/// @endcode
964/// Now, we create a balcl command-line object, supplying it with the spec table
965/// that we have just defined:
966/// @code
967/// balcl::CommandLine cmdLine(specTable);
968/// @endcode
969/// Parse the options and if an error occurred, print a usage message describing
970/// the options:
971/// @code
972/// if (cmdLine.parse(argc, argv)) {
973/// cmdLine.printUsage();
974/// return -1; // RETURN
975/// }
976/// @endcode
977/// If there are no errors in the specification table and correct arguments are
978/// passed, `parse` will set any variables that were specified on the command
979/// line, return 0 and there will be no output.
980///
981/// Finally, we show what will happen if `mysort` is called with invalid
982/// arguments. We will call without specifying an input file to `fileList`,
983/// which will be an error. `parse` streams a message describing the error and
984/// then returns non-zero, so our program will call `cmdLine.printUsage`, which
985/// prints a detailed usage message.
986/// @code
987/// $ mysort -r -o sorted.txt
988/// Error: No value supplied for the non-option argument "fileList".
989///
990/// Usage: mysort [-r|reverse] [-f|field-separator <fieldSeparator>]
991/// -o|outputfile <outputFile> [<fileList>]+
992/// Where:
993/// -r | --reverse
994/// sort in reverse order
995/// -f | --field-separator <fieldSeparator>
996/// field separator character
997/// -o | --outputfile <outputFile>
998/// output file
999/// <fileList>
1000/// input files to be sorted
1001/// @endcode
1002///
1003/// ### Example 2: Accessing Option Values Through balcl::CommandLine Accessors {#balcl_commandline-example-2-accessing-option-values-through-balcl-commandline-accessors}
1004///
1005///
1006/// Imagine we defined the same `mysort` program with the same options. After a
1007/// successful `parse`, `balcl::Commandline` makes the state of every option
1008/// available through accessors (in addition to setting external variables as
1009/// shown in example 1).
1010///
1011/// For every type that is supported, there is a `the<TYPE>` accessor which
1012/// takes a single argument, the name of the argument. In the above program, if
1013/// parsing was successful, the following asserts will always pass:
1014/// @code
1015/// assert(cmdLine.theBool("isReverse") == reverse);
1016/// assert(cmdLine.theString("outputFile") == outputFile);
1017/// assert(cmdLine.theStringArray("fileList") == files);
1018/// @endcode
1019/// The next accessors we'll discuss are `isSpecified` and `numSpecified`.
1020/// Here, we use `isSpecified` to determine whether "fieldSeparator" was
1021/// specified on the command line, and we use `numSpecified` to determine the
1022/// number of times the "fieldSeparator" option appeared on the command line:
1023/// @code
1024/// if (cmdLine.isSpecified("fieldSeparator")) {
1025/// const unsigned char uc = cmdLine.theChar("fieldSeparator");
1026/// if (!::isprint(uc)) {
1027/// bsl::cerr << "'fieldSeparator' must be printable.\n";
1028///
1029/// return -1; // RETURN
1030/// }
1031/// }
1032///
1033/// if (1 < cmdLine.numSpecified("fieldSeparator")) {
1034/// bsl::cerr <<
1035/// "'fieldSeparator' may not be specified more than once.\n";
1036///
1037/// return -1; // RETURN
1038/// }
1039/// @endcode
1040///
1041/// ### Example 3: Default Values and Specifying Values Via The Environment {#balcl_commandline-example-3-default-values-and-specifying-values-via-the-environment}
1042///
1043///
1044/// Suppose we are implementing `mysort` (from examples 1 & 2) again, but here
1045/// we want to make use of default option values and the ability to supply
1046/// options via the environment.
1047///
1048/// In this example, we have decided not to link local variables, and instead
1049/// access the option values via the `balcl::CommandLine` object. Since we are
1050/// not linking local variables, we specify `OptionType::k_<TYPE>` in the
1051/// specification table below for each `TypeInfo` field.
1052///
1053/// To specify default values, we pass the default value to the `OccurrenceInfo`
1054/// field. Boolean options always have a default value of `false`.
1055///
1056/// We also choose to allow these options to be supplied through the
1057/// environment. To enable this, we specify an environment variable name as the
1058/// 5th (optional) element of the `OptionInfo` specification for the option. If
1059/// no name is supplied for the environment variable, the option cannot be set
1060/// via the environment.
1061///
1062/// First, in `main`, we define our spec table:
1063/// @code
1064/// using balcl::TypeInfo;
1065/// using balcl::OptionType;
1066/// using balcl::OccurrenceInfo;
1067///
1068/// // option specification table
1069/// static const balcl::OptionInfo specTable[] = {
1070/// {
1071/// "r|reverse", // tag
1072/// "isReverse", // name
1073/// "sort in reverse order", // description
1074/// TypeInfo(OptionType::k_BOOL), // type
1075/// OccurrenceInfo::e_OPTIONAL, // optional
1076/// "MYSORT_REVERSE" // env var name
1077/// },
1078/// {
1079/// "", // non-option
1080/// "fileList", // name
1081/// "input files to be sorted", // description
1082/// TypeInfo(OptionType::k_STRING_ARRAY), // type
1083/// OccurrenceInfo::e_REQUIRED, // at least one file required
1084/// "MYSORT_FILES" // env var name
1085/// }
1086/// };
1087///
1088/// int main(int argc, const char **argv)
1089/// {
1090/// @endcode
1091/// Then, we declare our `cmdLine` object. This time, we pass it a stream, and
1092/// messages will be written to that stream rather than `cerr` (the default).
1093/// @code
1094/// balcl::CommandLine cmdLine(specTable, bsl::cout);
1095/// @endcode
1096/// Next, we call `parse` (just like in Example 1):
1097/// @code
1098/// if (cmdLine.parse(argc, argv)) {
1099/// cmdLine.printUsage();
1100/// return -1; // RETURN
1101/// }
1102/// @endcode
1103///
1104/// `balcl::CommandLine` uses the following precedence to determine the value of
1105/// a command line option:
1106///
1107/// 1. Use the option value on the command-line (if one was supplied)
1108/// 2. Use the option value supplied by an environment variable (if one was
1109/// supplied)
1110/// 3. Use the default value (if one was supplied, or `false` for booleans)
1111///
1112/// Finally, if an option value is not supplied by either the command line or
1113/// environment, and there is no default value, any linked variable will be
1114/// unmodified, `cmdLine.hasValue` for the option will return `false`, and the
1115/// behavior is undefined if `cmdLine.the<TYPE>` for the option is called.
1116///
1117/// Note that `cmdLine.isSpecified` will be `true` only if an option was
1118/// supplied by the command line or the environment.
1119///
1120/// If an array options is set by an environment variable, the different
1121/// elements of the array are separated by spaces by default.
1122///
1123/// All these calling sequences are equivalent:
1124/// @code
1125/// $ mysort -r inputFile1 inputFile2 inputFile3
1126/// @endcode
1127/// or
1128/// @code
1129/// $ mysort inputFile1 --reverse inputFile2 inputFile3
1130/// @endcode
1131/// or
1132/// @code
1133/// $ mysort inputFile1 inputFile2 inputFile3 -r
1134/// @endcode
1135/// or the user can specify arguments through environment variables:
1136/// @code
1137/// $ export MYSORT_REVERSE=true
1138/// $ export MYSORT_FILES="inputFile1 inputFile2 inputFile3"
1139/// $ mysort
1140/// @endcode
1141/// or as a combination of command line arguments and environment variables:
1142/// @code
1143/// $ export MYSORT_FILES="inputFile1 inputFile2 inputFile3"
1144/// $ mysort -r
1145/// @endcode
1146/// The '\' character is used as an escape character for array values provided
1147/// via an environment variable. So, for example, if we needed to encode file
1148/// names that contain a space (` `), which is the element separator (by
1149/// default), we would use "\ ":
1150/// @code
1151/// $ export MYSORT_FILES='C:\\file\ name\ 1 C:\\file\ name\ 2'
1152/// @endcode
1153/// Notice we used a single tick to avoid requiring a double escape when
1154/// supplying the string to the shell (e.g., avoiding "C:\\\\file\\ name\\ 1").
1155///
1156/// ### Example 4: Option Constraints {#balcl_commandline-example-4-option-constraints}
1157///
1158///
1159/// Suppose, we are again implementing `mysort`, and we want to introduce some
1160/// constraints on the values supplied for the variables. In this example, we
1161/// will ensure that the supplied input files exist and are not directories, and
1162/// that `fieldSeparator` is appropriate.
1163///
1164/// First, we write a validation function for the file name. A validation
1165/// function supplied to `balcl::CommandLine` takes an argument of a const
1166/// pointer to the input option type (with the user provided value) and a stream
1167/// on which to write an error message, and the validation function returns a
1168/// `bool` that is `true` if the option is valid, and `false` otherwise.
1169///
1170/// Here, we implement a function to validate a file name, that returns `true`
1171/// if the file exists and is a regular file, and `false` otherwise (writing an
1172/// description of the error to the `stream`):
1173/// @code
1174/// bool isValidFileName(const bsl::string *fileName, bsl::ostream& stream)
1175/// {
1176/// if (!bdls::FilesystemUtil::isRegularFile(*fileName, true)) {
1177/// stream << "Invalid file: " << *fileName << bsl::endl;
1178///
1179/// return false; // RETURN
1180/// }
1181///
1182/// return true;
1183/// }
1184/// @endcode
1185/// Then, we also want to make sure that the specified `fieldSeparator` is
1186/// a non-whitespace printable ascii character, so we write a function for that:
1187/// @code
1188/// bool isValidFieldSeparator(const char *fieldSeparator,
1189/// bsl::ostream& stream)
1190/// {
1191/// const unsigned char uc = *fieldSeparator;
1192/// if (::isspace(uc) || !::isprint(uc)) {
1193/// stream << "Invalid field separator specified." << bsl::endl;
1194///
1195/// return false; // RETURN
1196/// }
1197///
1198/// return true;
1199/// }
1200/// @endcode
1201/// Next, we define `main` and declare the variables to be configured:
1202/// @code
1203/// int main(int argc, const char **argv)
1204/// {
1205/// using balcl::Constraint;
1206/// using balcl::OptionType;
1207/// using balcl::OccurrenceInfo;
1208/// using balcl::TypeInfo;
1209///
1210/// bool reverse = false;
1211/// char fieldSeparator;
1212/// bsl::vector<bsl::string> files;
1213/// @endcode
1214/// Notice that `fieldSeparator` are in automatic storage with no constructor or
1215/// initial value. We can safely use an uninitialized variable in the
1216/// `specTable` below because the `specTable` provides a default value for it,
1217/// which will be assigned to the variable if an option value is not provided on
1218/// the command line or through environment variables. `reverse` has to be
1219/// initialized because no default for it is provided in `specTable`.
1220///
1221/// Then, we declare our `specTable`, providing function pointers for our
1222/// constraint functions to the second argument of the `TypeInfo` constructor.
1223/// @code
1224/// // option specification table
1225///
1226/// static const balcl::OptionInfo specTable[] = {
1227/// {
1228/// "r|reverse", // tag
1229/// "isReverse", // name
1230/// "sort in reverse order", // description
1231/// TypeInfo(&reverse), // linked variable
1232/// OccurrenceInfo(), // default value
1233/// "" // env variable name
1234/// },
1235/// {
1236/// "f|field-separator", // tag
1237/// "fieldSeparator", // name
1238/// "field separator character", // description
1239/// TypeInfo(&fieldSeparator, // linked variable
1240/// &isValidFieldSeparator), // constraint
1241/// OccurrenceInfo('|'),
1242/// "" // env variable name
1243/// },
1244/// {
1245/// "", // non-option
1246/// "fileList", // name
1247/// "input files to be sorted", // description
1248/// TypeInfo(&files, &isValidFileName), // linked variable and
1249/// // constraint
1250/// OccurrenceInfo::e_REQUIRED, // at least one file
1251/// // required
1252/// "" // env variable name
1253/// }
1254/// };
1255///
1256/// balcl::CommandLine cmdLine(specTable);
1257/// if (cmdLine.parse(argc, argv)) {
1258/// cmdLine.printUsage();
1259/// return -1; // RETURN
1260/// }
1261/// @endcode
1262/// If the constraint functions return `false`, `cmdLine.parse` will return
1263/// non-zero, and the output will contain the message from the constraint
1264/// function followed by the usage message.
1265///
1266/// ### Example 5: Using bsl::optional for Optional Command Line Parameters {#balcl_commandline-example-5-using-bsl-optional-for-optional-command-line-parameters}
1267///
1268///
1269/// We can use a `bsl::optional` variables when providing optional command line
1270/// parameters. Suppose we want to write a command line that takes an optional
1271/// input file, and if the file is not supplied, take input from a
1272/// `bsl::stringstream`.
1273///
1274/// To represent the optional file name parameter, we link a variable of type
1275/// `bsl::optional<bsl::string>`. In general, when linking a variable to an
1276/// option, we can choose to use `bsl::optonal<TYPE>` in place of `TYPE`, for
1277/// any option type other than `bool`.
1278/// @code
1279/// int main(int argc, const char **argv)
1280/// {
1281/// bsl::optional<bsl::string> optionalFileName;
1282///
1283/// const balcl::OptionInfo specTable[] = {
1284/// {
1285/// "i|inputFile", // tag
1286/// "filename", // name
1287/// "name of input file", // description
1288/// balcl::TypeInfo(&optionalFileName), // linked optional variable
1289/// balcl::OccurrenceInfo(), // occurence info
1290/// "" // env variable name
1291/// }
1292/// };
1293///
1294/// balcl::CommandLine cmdLine(specTable);
1295/// if (cmdLine.parse(argc, argv)) {
1296/// cmdLine.printUsage();
1297/// return -1; // RETURN
1298/// }
1299/// @endcode
1300/// Finally, we test whether `optionalFileName` has been set, and if it has not
1301/// been set, take input from a prepared `stringstream`.
1302/// @code
1303/// bsl::stringstream ss;
1304/// bsl::istream *inStream = &ss;
1305///
1306/// bsl::ifstream fileStream;
1307/// if (optionalFileName.has_value()) {
1308/// fileStream.open(optionalFileName->c_str());
1309/// inStream = &fileStream;
1310/// }
1311/// else {
1312/// // Prepare the 'stringstream'.
1313///
1314/// ss << "The quick brown fox jumps over the lazy dog\n";
1315/// }
1316///
1317/// performTask(*inStream);
1318/// @endcode
1319/// @}
1320/** @} */
1321/** @} */
1322
1323/** @addtogroup bal
1324 * @{
1325 */
1326/** @addtogroup balcl
1327 * @{
1328 */
1329/** @addtogroup balcl_commandline
1330 * @{
1331 */
1332
1333#include <balscm_version.h>
1334
1335#include <balcl_option.h>
1336#include <balcl_optioninfo.h>
1337#include <balcl_optiontype.h>
1338#include <balcl_optionvalue.h>
1339
1340#include <bdlb_printmethods.h>
1341
1343
1344#include <bslma_allocator.h>
1346
1347#include <bsls_assert.h>
1348#include <bsls_types.h>
1349
1350#include <bsl_cstddef.h> // 'bsl::size_t'
1351#include <bsl_cstring.h> // 'bsl::strcmp'
1352#include <bsl_iosfwd.h>
1353#include <bsl_sstream.h> // 'bsl::ostringstream'
1354#include <bsl_string.h>
1355#include <bsl_string_view.h>
1356#include <bsl_vector.h>
1357
1358#include <bdlt_date.h>
1359#include <bdlt_datetime.h>
1360#include <bdlt_time.h>
1361
1362
1363
1364namespace balcl {
1365
1366 // =============================
1367 // struct CommandLine_SchemaData
1368 // =============================
1369
1370/// This `struct`, a pure value-semantic type, is used to manage option
1371/// value type and name information in support of public interfaces to
1372/// parsed options. See `CommandLineOptionsHandle`.
1373///
1374/// See @ref balcl_commandline
1376
1377 // PUBLIC DATA
1378 OptionType::Enum d_type; // option data type
1379 const char *d_name_p; // option name
1380};
1381
1382// FREE OPERATORS
1383
1384/// Return `true` if the specified `lhs` and `rhs` have the same value, and
1385/// `false` otherwise. Two `CommandLine_SchemaData` objects have the same
1386/// value if their `type` attributes are the same and if their `name`
1387/// attributes compare equal.
1388bool operator==(const CommandLine_SchemaData& lhs,
1389 const CommandLine_SchemaData& rhs);
1390
1391/// Return `true` if the specified `lhs` and `rhs` do note have the same
1392/// value, and `false` otherwise. Two `CommandLine_SchemaData` objects do
1393/// not have the same value if their `type` attributes are not the same or
1394/// if their `name` attributes do not compare equal.
1395bool operator!=(const CommandLine_SchemaData& lhs,
1396 const CommandLine_SchemaData& rhs);
1397
1398 // =================
1399 // class CommandLine
1400 // =================
1401
1403
1404/// This value-semantic `class` parses, validates, and provides access to
1405/// command-line arguments. The constructor takes the specification
1406/// describing the command-line arguments. Once created, `printUsage` can
1407/// be invoked to print the usage syntax. The `parse` method takes
1408/// command-line arguments and validates them against the specification
1409/// provided at creation, writing a suitable message to an
1410/// optionally-specified stream in case of a parsing error. Once parsed,
1411/// options and values can be accessed using various accessors. The class
1412/// has a set of `theType` methods (e.g., `theString`, `theInt`) that
1413/// provide access, by name, to the value of the indicated option. It is
1414/// also possible to link a variable with an option in the specification;
1415/// doing so will cause the variable to be loaded with the option value once
1416/// `parse` has been invoked. The `options` method returns a
1417/// `balcl::CommandLineOptionsHandle` object referring to the option names
1418/// and their values. A similar but different method, `specifiedOptions`,
1419/// is suitable for overwriting other configuration parameters (possibly
1420/// obtained from a configuration file).
1421///
1422/// See @ref balcl_commandline
1424
1425 // PRIVATE TYPES
1428
1429 enum State {
1430 e_INVALID = 0,
1431 e_PARSED = 1,
1432 e_NOT_PARSED = 2
1433 };
1434
1435 // DATA
1436 bsl::vector<Option> d_options; // command-line options
1437 // specified at
1438 // construction
1439
1440 bsl::vector<bsl::vector<int> > d_positions; // set of positions of
1441 // each command-line
1442 // option in the
1443 // arguments specified to
1444 // 'parse', indexed by
1445 // position of option in
1446 // 'd_options'
1447
1448 bsl::vector<int> d_nonOptionIndices;
1449 // set of positions of
1450 // each command-line
1451 // non-option in the
1452 // arguments specified to
1453 // 'parse', indexed by
1454 // non-option rank in
1455 // 'd_options'
1456
1457 State d_state; // indicates whether
1458 // 'parse' was invoked,
1459 // and with what result
1460
1461 bsl::vector<bsl::string> d_arguments; // command-line arguments
1462 // specified to 'parse'
1463
1464 CommandLine_Schema d_schema; // schema describing the
1465 // structure of the
1466 // option values in the
1467 // returned handle
1468
1469 OptionValueList d_data; // primary option values,
1470 // recorded one by one as
1471 // they are parsed by the
1472 // 'parse' manipulator
1473
1474 OptionValueList d_dataFinal; // final option values,
1475 // copied from 'd_data'
1476 // and from default
1477 // values by 'postParse'
1478
1479 mutable OptionValueList d_specifiedOptions;
1480 // specified data, i.e.
1481 // 'd_dataFinal' with
1482 // non-specified
1483 // arguments reset,
1484 // created by the
1485 // 'specifiedOptions'
1486 // manipulator
1487
1488 mutable bool d_isBindin2Valid;
1489 // records whether
1490 // 'd_specifiedOptions'
1491 // was initialized by
1492 // 'specifiedOptions'
1493
1494 bool d_envVarsPresent;
1495 // 'true' if any
1496 // environment variable
1497 // names are present in
1498 // 'd_options'
1499
1500 private:
1501 // PRIVATE MANIPULATORS
1502
1503 /// Reset this command-line object to an uninitialized state.
1504 ///
1505 /// \note Note that the state is set to `INVALID` and not `NOT_PARSED`.
1506 void clear();
1507
1508 /// Store the specified `argc` entries from the specified `argv` array
1509 /// of command-line arguments in this object.
1510 void initArgs(int argc, const char *const argv[]);
1511
1512 /// Parse the command-line arguments contained in `d_arguments`, and
1513 /// write a description of any errors that occur to the specified `errorStream`.
1514 ///
1515 /// \note Note that this operation will parse command line
1516 /// arguments implementing the documented behavior for `parse`, using
1517 /// `postParseImp` to perform verification of the parsed values.
1518 int parseImp(bsl::ostream& errorStream);
1519
1520 /// Verify that all required arguments have been given a value, and in
1521 /// that case load all the primary option values (if set) or default
1522 /// option values (if the primary option value is optional and set by no
1523 /// command-line argument) into the final option values and set the
1524 /// linked variables, if any. Return 0 on success, and a non-zero value
1525 /// if not all required arguments are provided with a value (and in this
1526 /// case, leave the final option values and linked variables unchanged).
1527 /// Upon encountering an error, output to the specified `errorStream` a
1528 /// descriptive error message and abort parsing subsequent arguments.
1529 int postParseImp(bsl::ostream& errorStream);
1530
1531 /// Validate the command-line options passed at construction with
1532 /// respect to the command-line documented invariants (e.g., valid tags,
1533 /// names, and descriptions, default values satisfying constraints,
1534 /// uniqueness of tags and names, and miscellaneous constraints), and
1535 /// initialize all internal state for parsing. Optionally specify an
1536 /// output `errorStream`. If `errorStream` is not specified,
1537 /// `bsl::cerr` is used. Upon encountering errors, output descriptive
1538 /// error messages and abort the execution of this program by invoking
1539 /// the currently installed assertion handler (unconditionally).
1540 ///
1541 /// \note Note that this method will attempt to report as many errors as possible
1542 /// before aborting, but that correcting all these errors will not
1543 /// guarantee that subsequent execution would result in successful
1544 /// validation.
1545 void validateAndInitialize();
1546 void validateAndInitialize(bsl::ostream& errorStream);
1547
1548 // PRIVATE ACCESSORS
1549
1550 /// Return the index (in the options table passed at construction) of an
1551 /// option whose name matches the specified `name` string, or -1 if no
1552 /// such `name` exists.
1553 int findName(const bsl::string_view& name) const;
1554
1555 /// Return the index (in the options table passed at construction) of a
1556 /// command-line option whose long tag matches the specified `longTag`
1557 /// string of the specified `tagLength`, or -1 if no such `longTag`
1558 /// exists.
1559 int findTag(const bsl::string_view& longTag) const;
1560
1561 /// Return the index (in the options table passed at construction) of an
1562 /// option whose short tag matches the specified `shortTag` character,
1563 /// or -1 if no such `shortTag` exists.
1564 int findTag(char shortTag) const;
1565
1566 /// Output to the specified `errorStream` a message describing the location
1567 /// in the argument at the specified `index` (in the list of command-line
1568 /// arguments) where an error was found. Optionally specify a `start`
1569 /// character position in that argument; if `start` is specified,
1570 /// optionally specify an `end` character position as well.
1571 void location(bsl::ostream& errorStream,
1572 int index,
1573 int start = -1,
1574 int end = -1) const;
1575
1576 /// Return the length of the longest name in all the possible non-flag
1577 /// options of this command line.
1578 int longestNonFlagNameSize() const;
1579
1580 /// Return the length of the longest long tag in all the possible options of this command line.
1581 ///
1582 /// \note Note that short tags are ignored.
1583 int longestTagSize() const;
1584
1585 /// Check that all required options have already been parsed. Optionally
1586 /// specify `checkAlsoNonOptions`. If `checkAlsoNonOptions` is `true` or
1587 /// not specified, required non-option arguments that have not been parsed
1588 /// will also be returned; if `false`, they will be ignored. Return the
1589 /// index of the first missing option, or -1 if none.
1590 int missing(bool checkAlsoNonOptions = true) const;
1591
1592 public:
1593 // TRAITS
1596
1597 // CLASS METHODS
1598
1599 /// Return `true` if the specified (statically-initialized) `specTable` of
1600 /// the specified `LENGTH` has a valid set of command-line option
1601 /// specifications, and `false` otherwise. Optionally specify
1602 /// `errorStream` to which error messages are written. If no `errorStream`
1603 /// is specified, this method produces no output. See {Valid
1604 /// `balcl::OptionInfo` Specifications} for a description of the validity
1605 /// requirements.
1606 template <int LENGTH>
1608 const OptionInfo (&specTable)[LENGTH]);
1609 template <int LENGTH>
1611 OptionInfo (&specTable)[LENGTH]);
1612 template <int LENGTH>
1614 const OptionInfo (&specTable)[LENGTH],
1615 bsl::ostream& errorStream);
1616 template <int LENGTH>
1618 OptionInfo (&specTable)[LENGTH],
1619 bsl::ostream& errorStream);
1620
1621 /// Return `true` if the specified `specTable` of the specified `length`
1622 /// has a valid set of command-line option specifications, and `false`
1623 /// otherwise. Optionally specify `errorStream` to which error messages
1624 /// are written. If no `errorStream` is specified, this method produces
1625 /// not output. See {Valid `balcl::OptionInfo` Specifications} for a
1626 /// description of the validity requirements.
1627 ///
1628 /// \pre The behavior is undefined unless `0 <= length`.
1629 /// \note Note that `specTable` need not be statically
1630 /// initialized.
1631 static bool isValidOptionSpecificationTable(const OptionInfo *specTable,
1632 int length);
1633 static bool isValidOptionSpecificationTable(const OptionInfo *specTable,
1634 int length,
1635 bsl::ostream& errorStream);
1636
1637 // CREATORS
1638
1639 /// Create an object accepting the command-line options described by the
1640 /// specified (statically-initialized) `specTable`. Optionally specify a
1641 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
1642 /// currently installed default allocator is used.
1643 ///
1644 /// \pre The behavior is undefined unless `specTable` satisfies the `isValidOptionSpecificationTable` function.
1645 ///
1646 /// \note Note that an appropriate
1647 /// error message is written to the specified `errorStream`.
1648 template <int LENGTH>
1649 CommandLine(const OptionInfo (&specTable)[LENGTH],
1650 bsl::ostream& errorStream,
1651 bslma::Allocator *basicAllocator = 0);
1652 template <int LENGTH>
1653 CommandLine(OptionInfo (&specTable)[LENGTH],
1654 bsl::ostream& errorStream,
1655 bslma::Allocator *basicAllocator = 0);
1656
1657 /// Create an object accepting the command-line options described by the
1658 /// specified (statically-initialized) `specTable`. Optionally specify a
1659 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
1660 /// currently installed default allocator is used.
1661 ///
1662 /// \pre The behavior is undefined unless `specTable` satisfies the `isValidOptionSpecificationTable` function.
1663 ///
1664 /// \note Note that an appropriate
1665 /// error message is written to `bsl::cerr`.
1666 template <int LENGTH>
1667 explicit
1668 CommandLine(const OptionInfo (&specTable)[LENGTH],
1669 bslma::Allocator *basicAllocator = 0);
1670 template <int LENGTH>
1671 explicit
1672 CommandLine(OptionInfo (&specTable)[LENGTH],
1673 bslma::Allocator *basicAllocator = 0);
1674
1675 /// Create an object accepting the command-line options described by the
1676 /// specified `specTable` of the specified `length`. Optionally specify a
1677 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
1678 /// currently installed default allocator is used.
1679 ///
1680 /// \pre The behavior is undefined unless `specTable` satisfies the `isValidOptionSpecificationTable` function.
1681 ///
1682 /// \note Note that an appropriate
1683 /// error message is written to `bsl::cerr`. Also note that `specTable`
1684 /// need not be statically initialized.
1685 CommandLine(const OptionInfo *specTable,
1686 int length,
1687 bslma::Allocator *basicAllocator = 0);
1688
1689 /// Create an object accepting the command-line options described by the
1690 /// specified `specTable` of the specified `length`. Optionally specify a
1691 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
1692 /// currently installed default allocator is used.
1693 ///
1694 /// \pre The behavior is undefined unless `specTable` satisfies the `isValidOptionSpecificationTable` function.
1695 ///
1696 /// \note Note that an appropriate
1697 /// error message is written to the specified `errorStream`. Also note
1698 /// that `specTable` need not be statically initialized.
1699 CommandLine(const OptionInfo *specTable,
1700 int length,
1701 bsl::ostream& errorStream,
1702 bslma::Allocator *basicAllocator = 0);
1703
1704 /// Create a command-line object having the value of the specified
1705 /// `original` command line, if the `original` is parsed, and otherwise
1706 /// having a state such that parsing command-line arguments results in the
1707 /// same value as parsing the same command-line arguments with the
1708 /// `original`. Optionally specify a `basicAllocator` used to supply
1709 /// memory. If `basicAllocator` is 0, the currently installed default allocator is used.
1710 ///
1711 /// \pre The behavior is undefined unless `original` is
1712 /// valid (i.e., `original.isValid()` returns `true`).
1713 CommandLine(const CommandLine& original,
1714 bslma::Allocator *basicAllocator = 0);
1715
1716 /// Destroy this command-line object.
1718
1719 // MANIPULATORS
1720
1721 /// Assign to this command-line object the value of the specified `rhs`
1722 /// command-line object and return a reference providing modifiable access to this object.
1723 ///
1724 /// \pre The behavior is undefined unless both `rhs` and this
1725 /// object are valid (i.e., `isValid()` and `rhs.isValid()` both return
1726 /// `true`).
1728
1729 /// Parse the command-line arguments contained in the array starting at the
1730 /// specified `argv` having the specified `argc` length. Optionally
1731 /// specify an `errorStream` to which an appropriate error message is
1732 /// written if parsing fails. If `errorStream` is not specified,
1733 /// `bsl::cerr` is used. Return 0 on success, and a non-zero value
1734 /// otherwise. If an argument is not specified on the command-line, then
1735 /// if the `Option` object configuration for this `CommandLine` defines an
1736 /// environment variable name and the runtime environment for this
1737 /// application has set that environment variable, then set the option to
1738 /// the value of the environment variable. Otherwise, if an option is not
1739 /// set by the command line, or the environment, set the option using the
1740 /// default value if one has been provided. If the option has not been set
1741 /// by the command line, environment, or by default, `hasValue` for the
1742 /// option will return `false`. After a successful call `isParsed()` and
1743 /// `isValid()` will both be `true`, and the information provided by `argv`
1744 /// can be viewed via the accessors. After an unsuccessful call
1745 /// `isParsed()` and `isValid()` will both be `false`.
1746 ///
1747 /// \pre The behavior is undefined unless `isValid()` is `true` and `isParsed()` is `false`
1748 /// (i.e. the `CommandLine` was constructed in a valid state, and `parse`
1749 /// has not previously been called).
1750 int parse(int argc, const char *const argv[]);
1751 int parse(int argc, const char *const argv[], bsl::ostream& errorStream);
1752
1753 // ACCESSORS
1754
1755 /// Return `true` if this command-line object is configured with an option
1756 /// having the specified `name`, and `false` otherwise.
1757 bool hasOption(const bsl::string_view& name) const;
1758
1759 /// Return `true` if this command-line object's option having the specified
1760 /// `name` has a defined value, and `false` otherwise. An option has a
1761 /// defined value if `isSpecified(name)` or if a default value was
1762 /// configured for the option (see {Occurrence Information Field}).
1763 ///
1764 /// \pre The behavior is undefined unless this command-line object `isParsed()` and
1765 /// `hasOption(name)`.
1766 bool hasValue(const bsl::string_view& name) const;
1767
1768 /// Return `true` if this object was parsed successfully, and `false` otherwise.
1769 ///
1770 /// \note Note that if `parse` was invoked but failed, this method
1771 /// returns `false`.
1772 bool isParsed() const;
1773
1774 /// Return `true` if the option with the specified `name` has been entered
1775 /// on the command line and, if the optionally specified `count` is not 0,
1776 /// load into `count` the number of times the option `name` has been
1777 /// entered on the command line; otherwise, return `false` and leave `count` unaffected.
1778 ///
1779 /// \note Note that, in order to receive the valid value,
1780 /// the command line must be successfully parsed.
1781 bool isSpecified(const bsl::string_view& name) const;
1782 bool isSpecified(const bsl::string_view& name, int *count) const;
1783
1784 /// Return `true` if this object is in a valid state, and `false`
1785 /// otherwise. Objects are in a valid state after construction from a
1786 /// valid set of option specifications (see the function-level
1787 /// documentation of the `isValidOptionSpecificationTable` method) and
1788 /// after a successful invocation of the `parse` method. Conversely,
1789 /// construction from invalid option specifications or an unsuccessful
1790 /// invocation of the `parse` method leaves this object in an invalid state.
1791 ///
1792 /// \note Note that additional object state is available from the
1793 /// `isParsed` accessor method.
1794 bool isValid() const;
1795
1796 /// Return the number of times the option with the specified `name` has
1797 /// been entered on the command line, or 0 if `name` is not the name of a
1798 /// field in the command-line specification passed at construction to this object.
1799 ///
1800 /// \note Note that, in order to receive the valid number of
1801 /// occurrences, the command line must be successfully parsed.
1802 int numSpecified(const bsl::string_view& name) const;
1803
1804 /// Return the command-line options and their values. If an option was not
1805 /// entered on the command line *and* a default value was provided for that
1806 /// option, then that default value will be used (note the difference with
1807 /// the `specifiedOptions` method). If an option was not entered on the
1808 /// command line *and* no default value was provided for that option, then
1809 /// the corresponding option will be in a null state.
1810 ///
1811 /// \pre The behavior is undefined unless `isParsed` returns `true`.
1813
1814 /// Return the position where the option with the specified `name` has been
1815 /// entered on the command line (i.e., the index in the `argv` argument to
1816 /// the `parse` method). If the option was specified multiple times on the
1817 /// command line, return the position of the first instance. If the option
1818 /// was specified as an environment variable but not on the command line,
1819 /// return -2. If the option was not specified, return -1.
1820 ///
1821 /// \pre The behavior is undefined unless the option is of scalar type.
1822 int position(const bsl::string_view& name) const;
1823
1824 /// Return the positions where the option with the specified `name` has
1825 /// been entered on the command line (i.e., the offset in the `argv`
1826 /// argument to the `parse` method). If the option was not specified, return an empty vector.
1827 ///
1828 /// \note Note that, in order to receive the valid
1829 /// positions, the command line must be successfully parsed.
1831
1832 /// Print usage to the specified output `errorStream`, describing what the
1833 /// command line should look like. If `errorStream` is not specified,
1834 /// print usage to `stderr`. Optionally specify `programName` to use as
1835 /// the name of the program in the printed usage. If `programName` is not
1836 /// specified and if `parse` has been previously called successfully, use
1837 /// the first element of the `argv` argument; otherwise, use a default
1838 /// name. This method can be invoked at any time, even before `parse` has
1839 /// been invoked on this object.
1840 void printUsage() const;
1841 void printUsage(const bsl::string_view& programName) const;
1842 void printUsage(bsl::ostream& errorStream) const;
1843 void printUsage(bsl::ostream& errorStream,
1844 const bsl::string_view& programName) const;
1845
1846 /// Return the command-line options and their values. If an option was not
1847 /// entered on the command line or set through an environment variable,
1848 /// then the option will be in a null state (note the difference with the
1849 /// `options` method). This method is especially useful for overwriting
1850 /// some other configuration (potentially obtained from a configuration file).
1851 ///
1852 /// \pre The behavior is undefined unless `isParsed` returns `true`.
1854
1855 /// Return the type of the option having the specified `name`.
1856 ///
1857 /// \pre The behavior is undefined unless this command-line object
1858 /// `hasOption(name)`.
1860
1861 // 'the*' Accessors
1862
1863// BDE_VERIFY pragma: -FABC01 // not in alphabetic order
1864
1865 /// Return the value of the option having the specified `name`. The value
1866 /// returned matches that returned by `isSpecified(name)`.
1867 ///
1868 /// \pre The behavior is undefined unless this command-line object `isParsed()`,
1869 /// `hasOption(name)`, and `OptionType::e_BOOL == type(name)`.
1870 bool theBool(const bsl::string_view& name) const;
1871
1872 /// Return the value of the option having the specified `name`.
1873 ///
1874 /// \pre The behavior is undefined unless this command-line object `isParsed()`,
1875 /// `hasOption(name)`, `OptionType::e_CHAR == type(name)`, and
1876 /// `hasValue(name)`.
1877 char theChar(const bsl::string_view& name) const;
1878
1879 /// Return the value of the option having the specified `name`.
1880 ///
1881 /// \pre The behavior is undefined unless this command-line object `isParsed()`,
1882 /// `hasOption(name)`, `OptionType::e_INT == type(name)`, and
1883 /// `hasValue(name)`.
1884 int theInt(const bsl::string_view& name) const;
1885
1886 /// Return the value of the option having the specified `name`.
1887 ///
1888 /// \pre The behavior is undefined unless this command-line object `isParsed()`,
1889 /// `hasOption(name)`, `OptionType::e_INT64 == type(name)`, and
1890 /// `hasValue(name)`.
1892
1893 /// Return the value of the option having the specified `name`.
1894 ///
1895 /// \pre The behavior is undefined unless this command-line object `isParsed()`,
1896 /// `hasOption(name)`, `OptionType::e_DOUBLE == type(name)`, and
1897 /// `hasValue(name)`.
1898 double theDouble(const bsl::string_view& name) const;
1899
1900 /// Return a `const` reference to the value of the option having the specified `name`.
1901 ///
1902 /// \pre The behavior is undefined unless this
1903 /// command-line object `isParsed()`, `hasOption(name)`,
1904 /// `OptionType::e_STRING == type(name)`, and `hasValue(name)`.
1905 const bsl::string& theString(const bsl::string_view& name) const;
1906
1907 /// Return a `const` reference to the value of the option having the specified `name`.
1908 ///
1909 /// \pre The behavior is undefined unless this
1910 /// command-line object `isParsed()`, `hasOption(name)`,
1911 /// `OptionType::e_DATETIME == type(name)`, and `hasValue(name)`.
1913
1914 /// Return a `const` reference to the value of the option having the specified `name`.
1915 ///
1916 /// \pre The behavior is undefined unless this
1917 /// command-line object `isParsed()`, `hasOption(name)`,
1918 /// `OptionType::e_DATE == type(name)`, and `hasValue(name)`.
1919 const bdlt::Date& theDate(const bsl::string_view& name) const;
1920
1921 /// Return a `const` reference to the value of the option having the specified `name`.
1922 ///
1923 /// \pre The behavior is undefined unless this
1924 /// command-line object `isParsed()`, `hasOption(name)`,
1925 /// `OptionType::e_TIME == type(name)`, and `hasValue(name)`.
1926 const bdlt::Time& theTime(const bsl::string_view& name) const;
1927
1928 /// Return a `const` reference to the value of the option having the specified `name`.
1929 ///
1930 /// \pre The behavior is undefined unless this
1931 /// command-line object `isParsed()`, `hasOption(name)`,
1932 /// `OptionType::e_CHAR_ARRAY == type(name)`, and `hasValue(name)`.
1934
1935 /// Return a `const` reference to the value of the option having the specified `name`.
1936 ///
1937 /// \pre The behavior is undefined unless this
1938 /// command-line object `isParsed()`, `hasOption(name)`,
1939 /// `OptionType::e_INT_ARRAY == type(name)`, and `hasValue(name)`.
1941
1942 /// Return a `const` reference to the value of the option having the specified `name`.
1943 ///
1944 /// \pre The behavior is undefined unless this
1945 /// command-line object `isParsed()`, `hasOption(name)`,
1946 /// `OptionType::e_INT64_ARRAY == type(name)`, and `hasValue(name)`.
1948 const bsl::string_view& name) const;
1949
1950 /// Return a `const` reference to the value of the option having the specified `name`.
1951 ///
1952 /// \pre The behavior is undefined unless this
1953 /// command-line object `isParsed()`, `hasOption(name)`,
1954 /// `OptionType::e_DOUBLE_ARRAY == type(name)`, and `hasValue(name)`.
1956 const bsl::string_view& name) const;
1957
1958 /// Return a `const` reference to the value of the option having the specified `name`.
1959 ///
1960 /// \pre The behavior is undefined unless this
1961 /// command-line object `isParsed()`, `hasOption(name)`,
1962 /// `OptionType::e_STRING_ARRAY == type(name)`, and `hasValue(name)`.
1964 const bsl::string_view& name) const;
1965
1966 /// Return a `const` reference to the value of the option having the specified `name`.
1967 ///
1968 /// \pre The behavior is undefined unless this
1969 /// command-line object `isParsed()`, `hasOption(name)`,
1970 /// `OptionType::e_DATETIME_ARRAY == type(name)`, and `hasValue(name)`.
1972 const bsl::string_view& name) const;
1973
1974 /// Return a `const` reference to the value of the option having the specified `name`.
1975 ///
1976 /// \pre The behavior is undefined unless this
1977 /// command-line object `isParsed()`, `hasOption(name)`,
1978 /// `OptionType::e_DATE_ARRAY == type(name)`, and `hasValue(name)`.
1980 const bsl::string_view& name) const;
1981
1982 /// Return a `const` reference to the value of the option having the specified `name`.
1983 ///
1984 /// \pre The behavior is undefined unless this
1985 /// command-line object `isParsed()`, `hasOption(name)`,
1986 /// `OptionType::e_TIME_ARRAY == type(name)`, and `hasValue(name)`.
1988 const bsl::string_view& name) const;
1989
1990// BDE_VERIFY pragma: +FABC01 // not in alphabetic order
1991
1992 // Aspects
1993
1994 /// Return the allocator used by this object to supply memory.
1995 ///
1996 /// \note Note that if no allocator was supplied at construction the currently
1997 /// installed default allocator at construction is used.
1999
2000 /// Format this command-line object to the specified output `stream` at
2001 /// the (absolute value of) the optionally specified indentation `level`
2002 /// and return a reference to `stream`. If `level` is specified,
2003 /// optionally specify `spacesPerLevel`, the number of spaces per
2004 /// indentation level for this object. If `level` is negative, suppress indentation of the first line.
2005 ///
2006 /// \pre The behavior is undefined unless
2007 /// `0 <= spacesPerLevel`. If `stream` is not valid on entry, this
2008 /// operation has no effect.
2009 bsl::ostream& print(bsl::ostream& stream,
2010 int level = 0,
2011 int spacesPerLevel = 4) const;
2012};
2013
2014// FREE OPERATORS
2015
2016/// Return `true` if the specified `lhs` and `rhs` have the same value, and
2017/// `false` otherwise. Two command-line arguments have the same value if
2018/// and only if they are both parsed successfully and have the same
2019/// command-line specifications and the same values for flags, options, and non-option arguments.
2020///
2021/// \note Note that two identical copies built with the
2022/// same option table, but unparsed, are *not* equal.
2023bool operator==(const CommandLine& lhs, const CommandLine& rhs);
2024
2025/// Return `false` if the specified `lhs` and `rhs` have the same value, and
2026/// `true` otherwise. Two command-line arguments do not have the same value
2027/// if and only if they have different command-line specifications, or one
2028/// is parsed successfully but the other is not, or neither is, or else both
2029/// have the same specification and both are parsed successfully but they
2030/// have different values for at least one flag, option or non-option argument.
2031///
2032/// \note Note that two identical copies built with the same option
2033/// table, but unparsed, are *not* equal.
2034bool operator!=(const CommandLine& lhs, const CommandLine& rhs);
2035
2036/// Write the options and their values in the specified `rhs` to the
2037/// specified output `stream` in a (multi-line) human readable format and return a reference to `errorStream`.
2038///
2039/// \note Note that the last line is *not*
2040/// terminated by a newline character.
2041bsl::ostream& operator<<(bsl::ostream& stream, const CommandLine& rhs);
2042
2043 // ==============================
2044 // class CommandLineOptionsHandle
2045 // ==============================
2046
2047/// This class provides access to the parsed options (if any) of its creating `CommandLine` object.
2048///
2049/// \pre The behavior is undefined if any of the
2050/// methods of this class (accessors all) are invoked after a subsequent
2051/// invocation of the `parse` method of the creating object or after the
2052/// destruction of the creating object.
2053///
2054/// See @ref balcl_commandline
2056
2057 // PRIVATE TYPES
2060
2061 // DATA
2062 const OptionValueList *d_data_p;
2063 const CommandLine_Schema *d_schema_p;
2064
2065 // FRIENDS
2066 friend class CommandLine;
2071
2072 // PRIVATE CREATORS
2073
2074 /// Create a `CommandLineOptionsHandle` object referring to the
2075 /// specified `dataPtr` and `schemaPtr`.
2076 ///
2077 /// \pre The behavior is undefined unless `dataPtr->size() == schemaPtr->size()`.
2079 const CommandLine_Schema *schemaPtr);
2080
2081 public:
2082 // ACCESSORS
2083
2084 /// Return the position in this handle object of the option having the
2085 /// specified `name`, and -1 if the handle has no option of that name.
2086 ///
2087 /// \note Note that, on success, the return values are in the range
2088 /// `[0 .. numOptions() - 1]`.
2089 int index(const bsl::string_view& name) const;
2090
2091 /// Return the name of the option at the specified `index`.
2092 ///
2093 /// \pre The behavior is undefined unless `index < numOptions()`.
2094 const char *name(bsl::size_t index) const;
2095
2096 /// Return the number of parsed options.
2097 bsl::size_t numOptions() const;
2098
2099 /// Return the type of the option at the specified `index` in this handle object.
2100 ///
2101 /// \pre The behavior is undefined unless
2102 /// `index < numOptions()`.
2103 OptionType::Enum type(bsl::size_t index) const;
2104
2105 /// Return the type of the option having the specified `name`.
2106 ///
2107 /// \pre The behavior is undefined unless this handle object has a `name` option
2108 /// (i.e., `0 <= index(name)`).
2110
2111 /// Return a `const` reference to the value (possibly in a null state)
2112 /// of the option at the specified `index` in this handle object.
2113 ///
2114 /// \pre The behavior is undefined unless `index < numOptions()`.
2115 const OptionValue& value(bsl::size_t index) const;
2116
2117 /// Return a `const` reference to the value (possibly in a null state)
2118 /// of this handle object's option having the specified `name`.
2119 ///
2120 /// \pre The behavior is undefined unless this handle object has a `name` option
2121 /// (i.e., `0 <= index(name)`).
2122 const OptionValue& value(const bsl::string_view& name) const;
2123
2124 // 'the*' Accessors
2125
2126// BDE_VERIFY pragma: -FABC01 // not in alphabetic order
2127
2128 /// Return a `const` reference to the value of the option at the
2129 /// specified `index`. Template parameter `TYPE` must be one of the
2130 /// supported types (see {Supported Types}).
2131 ///
2132 /// \pre The behavior is undefined unless `index < numOptions()`, the option has the (template
2133 /// parameter) `TYPE` (i.e.,
2134 /// `OptionType::TypeToEnum<TYPE>::value == type(index)`), and the
2135 /// option has a value (i.e., `false == value(index).isNull()`).
2136 template <class TYPE>
2137 const TYPE& the(bsl::size_t index) const;
2138
2139 /// Return a `const` reference to the value of the option having the
2140 /// specified `name`. Template parameter `TYPE` must be one of the
2141 /// supported types (see {Supported Types}).
2142 ///
2143 /// \pre The behavior is undefined unless this handle object has a `name` option (i.e.,
2144 /// `0 <= index(name)`), the option has (template parameter) `TYPE`
2145 /// (i.e., `OptionType::TypeToEnum<TYPE>::value == type(name)`), and the
2146 /// option has a value (i.e., `false == value(name).isNull()`).
2147 template <class TYPE>
2148 const TYPE& the(const bsl::string_view& name) const;
2149
2150 /// Return the value of the option having the specified `name`.
2151 ///
2152 /// \pre The behavior is undefined unless this handle object has a `name` option
2153 /// (i.e., `0 <= index(name)`), the option has type `bool` (i.e.,
2154 /// `OptionType::e_BOOL == type(name)`), and the option has a value
2155 /// (i.e., `false == value(name).isNull()`).
2156 bool theBool(const bsl::string_view& name) const;
2157
2158 /// Return the value of the option having the specified `name`.
2159 ///
2160 /// \pre The behavior is undefined unless this handle object has a `name` option
2161 /// (i.e., `0 <= index(name)`), the option has type `char` (i.e.,
2162 /// `OptionType::e_CHAR == type(name)`), and the option has a value
2163 /// (i.e., `false == value(name).isNull()`).
2164 char theChar(const bsl::string_view& name) const;
2165
2166 /// Return the value of the option having the specified `name`.
2167 ///
2168 /// \pre The behavior is undefined unless this handle object has a `name` option
2169 /// (i.e., `0 <= index(name)`), the option has type `int` (i.e.,
2170 /// `OptionType::e_INT == type(name)`), and the option has a value
2171 /// (i.e., `false == value(name).isNull()`).
2172 int theInt(const bsl::string_view& name) const;
2173
2174 /// Return the value of the option having the specified `name`.
2175 ///
2176 /// \pre The behavior is undefined unless this handle object has a `name` option
2177 /// (i.e., `0 <= index(name)`), the option has type `bsls::Types::Int64`
2178 /// (i.e., `OptionType::e_INT64 == type(name)`), and the option has a
2179 /// value (i.e., `false == value(name).isNull()`).
2181
2182 /// Return the value of the option having the specified `name`.
2183 ///
2184 /// \pre The behavior is undefined unless this handle object has a `name` option
2185 /// (i.e., `0 <= index(name)`), the option has type `double` (i.e.,
2186 /// `OptionType::e_DOUBLE == type(name)`), and the option has a value
2187 /// (i.e., `false == value(name).isNull()`).
2188 double theDouble(const bsl::string_view& name) const;
2189
2190 /// Return a `const` reference to the value of the option having the specified `name`.
2191 ///
2192 /// \pre The behavior is undefined unless this handle
2193 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2194 /// has type `bsl::string` (i.e., `OptionType::e_STRING == type(name)`),
2195 /// and the option has a value (i.e., `false == value(name).isNull()`).
2196 const bsl::string& theString(const bsl::string_view& name) const;
2197
2198 /// Return a `const` reference to the value of the option having the specified `name`.
2199 ///
2200 /// \pre The behavior is undefined unless this handle
2201 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2202 /// has type `bdlt::Datetime` (i.e.,
2203 /// `OptionType::e_DATETIME == type(name)`), and the option has a value
2204 /// (i.e., `false == value(name).isNull()`).
2205 const bdlt::Datetime& theDatetime(const bsl::string_view& name) const;
2206
2207 /// Return a `const` reference to the value of the option having the specified `name`.
2208 ///
2209 /// \pre The behavior is undefined unless this handle
2210 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2211 /// has type `bdlt::Date` (i.e., `OptionType::e_DATE == type(name)`),
2212 /// and the option has a value (i.e., `false == value(name).isNull()`).
2213 const bdlt::Date& theDate(const bsl::string_view& name) const;
2214
2215 /// Return a `const` reference to the value of the option having the specified `name`.
2216 ///
2217 /// \pre The behavior is undefined unless this handle
2218 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2219 /// has type `bdlt::Time` (i.e., `OptionType::e_TIME == type(name)`),
2220 /// and the option has a value (i.e., `false == value(name).isNull()`).
2221 const bdlt::Time& theTime(const bsl::string_view& name) const;
2222
2223 /// Return a `const` reference to the value of the option having the specified `name`.
2224 ///
2225 /// \pre The behavior is undefined unless this handle
2226 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2227 /// has type `bsl::vector<char>` (i.e.,
2228 /// `OptionType::e_CHAR_ARRAY == type(name)`), and the option has a
2229 /// value (i.e., `false == value(name).isNull()`).
2231
2232 /// Return a `const` reference to the value of the option having the specified `name`.
2233 ///
2234 /// \pre The behavior is undefined unless this handle
2235 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2236 /// has type `bsl::vector<int>` (i.e.,
2237 /// `OptionType::e_INT_ARRAY == type(name)`), and the option has a value
2238 /// (i.e., `false == value(name).isNull()`).
2240
2241 /// Return a `const` reference to the value of the option having the specified `name`.
2242 ///
2243 /// \pre The behavior is undefined unless this handle
2244 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2245 /// has type `bsl::vector<bsls::Types::Int64>` (i.e.,
2246 /// `OptionType::e_INT64_ARRAY == type(name)`), and the option has a
2247 /// value (i.e., `false == value(name).isNull()`).
2249 const bsl::string_view& name) const;
2250
2251 /// Return a `const` reference to the value of the option having the specified `name`.
2252 ///
2253 /// \pre The behavior is undefined unless this handle
2254 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2255 /// has type `bsl::vector<double>` (i.e.,
2256 /// `OptionType::e_DOUBLE_ARRAY == type(name)`), and the option has a
2257 /// value (i.e., `false == value(name).isNull()`).
2259 const bsl::string_view& name) const;
2260
2261 /// Return a `const` reference to the value of the option having the specified `name`.
2262 ///
2263 /// \pre The behavior is undefined unless this handle
2264 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2265 /// has type `bsl::vector<bsl::string>` (i.e.,
2266 /// `OptionType::e_STRING_ARRAY == type(name)`), and the option has a
2267 /// value (i.e., `false == value(name).isNull()`).
2269 const bsl::string_view& name) const;
2270
2271 /// Return a `const` reference to the value of the option having the specified `name`.
2272 ///
2273 /// \pre The behavior is undefined unless this handle
2274 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2275 /// has type `bsl::vector<bdlt::Datetime>` (i.e.,
2276 /// `OptionType::e_DATETIME_ARRAY == type(name)`), and the option has a
2277 /// value (i.e., `false == value(name).isNull()`).
2279 const bsl::string_view& name) const;
2280
2281 /// Return a `const` reference to the value of the option having the specified `name`.
2282 ///
2283 /// \pre The behavior is undefined unless this handle
2284 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2285 /// has type `bsl::vector<bdlt::Date>` (i.e.,
2286 /// `OptionType::e_DATE_ARRAY == type(name)`), and the option has a
2287 /// value (i.e., `false == value(name).isNull()`).
2289 const bsl::string_view& name) const;
2290
2291 /// Return a `const` reference to the value of the option having the specified `name`.
2292 ///
2293 /// \pre The behavior is undefined unless this handle
2294 /// object has a `name` option (i.e., `0 <= index(name)`), the option
2295 /// has type `bsl::vector<bdlt::TIME>` (i.e.,
2296 /// `OptionType::e_TIME_ARRAY == type(name)`), and the option has a
2297 /// value (i.e., `false == value(name).isNull()`).
2299 const bsl::string_view& name) const;
2300
2301// BDE_VERIFY pragma: +FABC01 // not in alphabetic order
2302};
2303
2304// FREE OPERATORS
2305
2306/// Return `true` if the specified `lhs` and `rhs` have the same value, and
2307/// `false` otherwise. Two `CommandLineOptionsHandle` objects have the same
2308/// value if they have the same `numOptions` and each of those options have
2309/// the same `name`, `type`, and `value` or are in the null state.
2310bool operator==(const CommandLineOptionsHandle& lhs,
2311 const CommandLineOptionsHandle& rhs);
2312
2313/// Return `true` if the specified `lhs` and `rhs` do not have the same
2314/// value, and `false` otherwise. Two `CommandLineOptionsHandle` objects do
2315/// not have the same value if they do not have the same `numOptions` or if
2316/// any of their options differ in `name`, `type`, or 'value (or null
2317/// state).
2318bool operator!=(const CommandLineOptionsHandle& lhs,
2319 const CommandLineOptionsHandle& rhs);
2320
2321// ============================================================================
2322// INLINE DEFINITIONS
2323// ============================================================================
2324
2325 // -----------------------------
2326 // struct CommandLine_SchemaData
2327 // -----------------------------
2328
2329} // close package namespace
2330
2331// FREE OPERATORS
2332inline
2333bool balcl::operator==(const CommandLine_SchemaData& lhs,
2334 const CommandLine_SchemaData& rhs)
2335{
2336 return lhs.d_type == rhs.d_type
2337 && 0 == bsl::strcmp(lhs.d_name_p, rhs.d_name_p);
2338}
2339
2340inline
2341bool balcl::operator!=(const CommandLine_SchemaData& lhs,
2342 const CommandLine_SchemaData& rhs)
2343{
2344 return lhs.d_type != rhs.d_type
2345 || 0 != bsl::strcmp(lhs.d_name_p, rhs.d_name_p);
2346}
2347
2348namespace balcl {
2349
2350 // -----------------
2351 // class CommandLine
2352 // -----------------
2353
2354// CLASS METHODS
2355template <int LENGTH>
2356inline
2358 const OptionInfo (&specTable)[LENGTH])
2359{
2360 return isValidOptionSpecificationTable(specTable, LENGTH);
2361}
2362
2363template <int LENGTH>
2364inline
2366 OptionInfo (&specTable)[LENGTH])
2367{
2368 return isValidOptionSpecificationTable(specTable, LENGTH);
2369}
2370
2371template <int LENGTH>
2372inline
2374 const OptionInfo (&specTable)[LENGTH],
2375 bsl::ostream& errorStream)
2376{
2377 return isValidOptionSpecificationTable(specTable, LENGTH, errorStream);
2378}
2379
2380template <int LENGTH>
2381inline
2383 OptionInfo (&specTable)[LENGTH],
2384 bsl::ostream& errorStream)
2385{
2386 return isValidOptionSpecificationTable(specTable, LENGTH, errorStream);
2387}
2388
2389inline
2391 int length)
2392{
2393 BSLS_ASSERT(specTable);
2394 BSLS_ASSERT(0 <= length);
2395
2397 return isValidOptionSpecificationTable(specTable, length, oss);
2398}
2399
2400// CREATORS
2401template <int LENGTH>
2402CommandLine::CommandLine(const OptionInfo (&specTable)[LENGTH],
2403 bsl::ostream& errorStream,
2404 bslma::Allocator *basicAllocator)
2405: d_options(basicAllocator)
2406, d_positions(basicAllocator)
2407, d_nonOptionIndices(basicAllocator)
2408, d_state(e_INVALID)
2409, d_arguments(basicAllocator)
2410, d_schema(basicAllocator)
2411, d_data(basicAllocator)
2412, d_dataFinal(basicAllocator)
2413, d_specifiedOptions(basicAllocator)
2414, d_isBindin2Valid(false)
2415, d_envVarsPresent(false)
2416{
2417 d_options.reserve(LENGTH);
2418 for (int ii = 0; ii < LENGTH; ++ii) {
2419 d_options.push_back(Option(specTable[ii], allocator()));
2420 }
2421 validateAndInitialize(errorStream);
2422 d_state = e_NOT_PARSED;
2423}
2424
2425template <int LENGTH>
2427 bsl::ostream& errorStream,
2428 bslma::Allocator *basicAllocator)
2429: d_options(basicAllocator)
2430, d_positions(basicAllocator)
2431, d_nonOptionIndices(basicAllocator)
2432, d_state(e_INVALID)
2433, d_arguments(basicAllocator)
2434, d_schema(basicAllocator)
2435, d_data(basicAllocator)
2436, d_dataFinal(basicAllocator)
2437, d_specifiedOptions(basicAllocator)
2438, d_isBindin2Valid(false)
2439, d_envVarsPresent(false)
2440{
2441 d_options.reserve(LENGTH);
2442 for (int i = 0; i < LENGTH; ++i) {
2443 d_options.push_back(Option(specTable[i], allocator()));
2444 }
2445 validateAndInitialize(errorStream);
2446 d_state = e_NOT_PARSED;
2447}
2448
2449template <int LENGTH>
2450CommandLine::CommandLine(const OptionInfo (&specTable)[LENGTH],
2451 bslma::Allocator *basicAllocator)
2452: d_options(basicAllocator)
2453, d_positions(basicAllocator)
2454, d_nonOptionIndices(basicAllocator)
2455, d_state(e_INVALID)
2456, d_arguments(basicAllocator)
2457, d_schema(basicAllocator)
2458, d_data(basicAllocator)
2459, d_dataFinal(basicAllocator)
2460, d_specifiedOptions(basicAllocator)
2461, d_isBindin2Valid(false)
2462, d_envVarsPresent(false)
2463{
2464 d_options.reserve(LENGTH);
2465 for (int ii = 0; ii < LENGTH; ++ii) {
2466 d_options.push_back(Option(specTable[ii], allocator()));
2467 }
2468 validateAndInitialize();
2469 d_state = e_NOT_PARSED;
2470}
2471
2472template <int LENGTH>
2474 bslma::Allocator *basicAllocator)
2475: d_options(basicAllocator)
2476, d_positions(basicAllocator)
2477, d_nonOptionIndices(basicAllocator)
2478, d_state(e_INVALID)
2479, d_arguments(basicAllocator)
2480, d_schema(basicAllocator)
2481, d_data(basicAllocator)
2482, d_dataFinal(basicAllocator)
2483, d_specifiedOptions(basicAllocator)
2484, d_isBindin2Valid(false)
2485, d_envVarsPresent(false)
2486{
2487 d_options.reserve(LENGTH);
2488 for (int ii = 0; ii < LENGTH; ++ii) {
2489 d_options.push_back(Option(specTable[ii], allocator()));
2490 }
2491 validateAndInitialize();
2492 d_state = e_NOT_PARSED;
2493}
2494
2495 // ------------------------------
2496 // class CommandLineOptionsHandle
2497 // ------------------------------
2498
2499// PRIVATE CREATORS
2500inline
2501CommandLineOptionsHandle::CommandLineOptionsHandle(
2502 const OptionValueList *dataPtr,
2503 const CommandLine_Schema *schemaPtr)
2504: d_data_p(dataPtr)
2505, d_schema_p(schemaPtr)
2506{
2507 BSLS_ASSERT(dataPtr);
2508 BSLS_ASSERT(schemaPtr);
2509 BSLS_ASSERT(dataPtr->size() == schemaPtr->size());
2510}
2511
2512// ACCESSORS
2513inline
2514const char *CommandLineOptionsHandle::name(bsl::size_t index) const
2515{
2516 BSLS_ASSERT(index < d_schema_p->size());
2517
2518 return (*d_schema_p)[index].d_name_p;
2519}
2520
2521inline
2523{
2524 return d_schema_p->size();
2525}
2526
2527inline
2529{
2530 BSLS_ASSERT(index < d_schema_p->size());
2531
2532 return (*d_schema_p)[index].d_type;
2533}
2534
2535inline
2537 const bsl::string_view& name) const
2538{
2539 int index = this->index(name);
2540
2541 BSLS_ASSERT(0 <= index);
2542 BSLS_ASSERT(static_cast<bsl::size_t>(index) < d_schema_p->size());
2543
2544 return (*d_schema_p)[index].d_type;
2545}
2546
2547inline
2548const OptionValue& CommandLineOptionsHandle::value(bsl::size_t index) const
2549{
2550 BSLS_ASSERT(index < d_schema_p->size());
2551
2552 return (*d_data_p)[index];
2553}
2554
2555inline
2557 const bsl::string_view& name) const
2558{
2559 int index = this->index(name);
2560
2561 BSLS_ASSERT(0 <= index);
2562 BSLS_ASSERT(static_cast<bsl::size_t>(index) < d_schema_p->size());
2563
2564 return (*d_data_p)[index];
2565}
2566
2567 // 'the*' Accessors
2568
2569// BDE_VERIFY pragma: -FABC01 // not in alphabetic order
2570
2571template <class TYPE>
2572const TYPE& CommandLineOptionsHandle::the(bsl::size_t index) const
2573{
2575 BSLS_ASSERT(!value(index).isNull());
2576
2577 return (*d_data_p)[index].the<TYPE>();
2578}
2579
2580template <class TYPE>
2582{
2583 int index = this->index(name);
2584
2585 BSLS_ASSERT(0 <= index);
2587 BSLS_ASSERT(!value(index).isNull());
2588
2589 return the<TYPE>(index);
2590}
2591
2592inline
2594{
2595 int index = this->index(name);
2596
2597 BSLS_ASSERT(0 <= index);
2599 BSLS_ASSERT(!value(index).isNull());
2600
2601 return the<OptionType::Bool>(index);
2602}
2603
2604inline
2606{
2607 int index = this->index(name);
2608
2609 BSLS_ASSERT(0 <= index);
2611 BSLS_ASSERT(!value(index).isNull());
2612
2613 return the<OptionType::Char>(index);
2614}
2615
2616inline
2618{
2619 int index = this->index(name);
2620
2621 BSLS_ASSERT(0 <= index);
2623 BSLS_ASSERT(!value(index).isNull());
2624
2625 return the<OptionType::Int>(index);
2626}
2627
2628inline
2630 const bsl::string_view& name) const
2631{
2632 int index = this->index(name);
2633
2634 BSLS_ASSERT(0 <= index);
2636 BSLS_ASSERT(!value(index).isNull());
2637
2638 return the<OptionType::Int64>(index);
2639}
2640
2641inline
2643{
2644 int index = this->index(name);
2645
2646 BSLS_ASSERT(0 <= index);
2648 BSLS_ASSERT(!value(index).isNull());
2649
2650 return the<OptionType::Double>(index);
2651}
2652
2653inline
2654const bsl::string&
2656{
2657 int index = this->index(name);
2658
2659 BSLS_ASSERT(0 <= index);
2661 BSLS_ASSERT(!value(index).isNull());
2662
2663 return the<OptionType::String>(index);
2664}
2665
2666inline
2667const bdlt::Datetime&
2669{
2670 int index = this->index(name);
2671
2672 BSLS_ASSERT(0 <= index);
2674 BSLS_ASSERT(!value(index).isNull());
2675
2676 return the<OptionType::Datetime>(index);
2677}
2678
2679inline
2680const bdlt::Date&
2682{
2683 int index = this->index(name);
2684
2685 BSLS_ASSERT(0 <= index);
2687 BSLS_ASSERT(!value(index).isNull());
2688
2689 return the<OptionType::Date>(index);
2690}
2691
2692inline
2694 const bsl::string_view& name) const
2695{
2696 int index = this->index(name);
2697
2698 BSLS_ASSERT(0 <= index);
2700 BSLS_ASSERT(!value(index).isNull());
2701
2702 return the<OptionType::Time>(index);
2703}
2704
2705inline
2706const bsl::vector<char>&
2708{
2709 int index = this->index(name);
2710
2711 BSLS_ASSERT(0 <= index);
2713 BSLS_ASSERT(!value(index).isNull());
2714
2715 return the<OptionType::CharArray>(index);
2716}
2717
2718inline
2719const bsl::vector<int>&
2721{
2722 int index = this->index(name);
2723
2724 BSLS_ASSERT(0 <= index);
2726 BSLS_ASSERT(!value(index).isNull());
2727
2728 return the<OptionType::IntArray>(index);
2729}
2730
2731inline
2734{
2735 int index = this->index(name);
2736
2737 BSLS_ASSERT(0 <= index);
2739 BSLS_ASSERT(!value(index).isNull());
2740
2741 return the<OptionType::Int64Array>(index);
2742}
2743
2744inline
2747{
2748 int index = this->index(name);
2749
2750 BSLS_ASSERT(0 <= index);
2752 BSLS_ASSERT(!value(index).isNull());
2753
2754 return the<OptionType::DoubleArray>(index);
2755}
2756
2757inline
2760{
2761 int index = this->index(name);
2762
2763 BSLS_ASSERT(0 <= index);
2765 BSLS_ASSERT(!value(index).isNull());
2766
2767 return the<OptionType::StringArray>(index);
2768}
2769
2770inline
2773{
2774 int index = this->index(name);
2775
2776 BSLS_ASSERT(0 <= index);
2778 BSLS_ASSERT(!value(index).isNull());
2779
2780 return the<OptionType::DatetimeArray>(index);
2781}
2782
2783inline
2786{
2787 int index = this->index(name);
2788
2789 BSLS_ASSERT(0 <= index);
2791 BSLS_ASSERT(!value(index).isNull());
2792
2793 return the<OptionType::DateArray>(index);
2794}
2795
2796inline
2799{
2800 int index = this->index(name);
2801
2802 BSLS_ASSERT(0 <= index);
2804 BSLS_ASSERT(!value(index).isNull());
2805
2806 return the<OptionType::TimeArray>(index);
2807}
2808
2809// BDE_VERIFY pragma: +FABC01 // not in alphabetic order
2810
2811} // close package namespace
2812
2813// FREE OPERATORS
2814inline
2817{
2818 BSLS_ASSERT(lhs.d_data_p); BSLS_ASSERT(lhs.d_schema_p);
2819 BSLS_ASSERT(rhs.d_data_p); BSLS_ASSERT(rhs.d_schema_p);
2820
2821 return *lhs.d_data_p == *rhs.d_data_p
2822 && *lhs.d_schema_p == *rhs.d_schema_p;
2823}
2824
2825inline
2828{
2829 BSLS_ASSERT(lhs.d_data_p); BSLS_ASSERT(lhs.d_schema_p);
2830 BSLS_ASSERT(rhs.d_data_p); BSLS_ASSERT(rhs.d_schema_p);
2831
2832 return *lhs.d_data_p != *rhs.d_data_p
2833 || *lhs.d_schema_p != *rhs.d_schema_p;
2834}
2835
2836
2837
2838#endif
2839
2840// ----------------------------------------------------------------------------
2841// Copyright 2020 Bloomberg Finance L.P.
2842//
2843// Licensed under the Apache License, Version 2.0 (the "License");
2844// you may not use this file except in compliance with the License.
2845// You may obtain a copy of the License at
2846//
2847// http://www.apache.org/licenses/LICENSE-2.0
2848//
2849// Unless required by applicable law or agreed to in writing, software
2850// distributed under the License is distributed on an "AS IS" BASIS,
2851// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2852// See the License for the specific language governing permissions and
2853// limitations under the License.
2854// ----------------------------- END-OF-FILE ----------------------------------
2855
2856/** @} */
2857/** @} */
2858/** @} */
Definition balcl_commandline.h:2055
const TYPE & the(bsl::size_t index) const
Definition balcl_commandline.h:2572
const bdlt::Time & theTime(const bsl::string_view &name) const
Definition balcl_commandline.h:2693
const bsl::string & theString(const bsl::string_view &name) const
Definition balcl_commandline.h:2655
char theChar(const bsl::string_view &name) const
Definition balcl_commandline.h:2605
const bsl::vector< bdlt::Time > & theTimeArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2798
bsls::Types::Int64 theInt64(const bsl::string_view &name) const
Definition balcl_commandline.h:2629
OptionType::Enum type(bsl::size_t index) const
Definition balcl_commandline.h:2528
const bsl::vector< bdlt::Datetime > & theDatetimeArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2772
const bdlt::Date & theDate(const bsl::string_view &name) const
Definition balcl_commandline.h:2681
bsl::size_t numOptions() const
Return the number of parsed options.
Definition balcl_commandline.h:2522
const bsl::vector< char > & theCharArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2707
bool theBool(const bsl::string_view &name) const
Definition balcl_commandline.h:2593
friend bool operator!=(const CommandLineOptionsHandle &, const CommandLineOptionsHandle &)
const OptionValue & value(bsl::size_t index) const
Definition balcl_commandline.h:2548
double theDouble(const bsl::string_view &name) const
Definition balcl_commandline.h:2642
const bsl::vector< bdlt::Date > & theDateArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2785
int index(const bsl::string_view &name) const
const bsl::vector< double > & theDoubleArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2746
const bsl::vector< int > & theIntArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2720
const char * name(bsl::size_t index) const
Definition balcl_commandline.h:2514
int theInt(const bsl::string_view &name) const
Definition balcl_commandline.h:2617
const bdlt::Datetime & theDatetime(const bsl::string_view &name) const
Definition balcl_commandline.h:2668
const bsl::vector< bsl::string > & theStringArray(const bsl::string_view &name) const
Definition balcl_commandline.h:2759
friend bool operator==(const CommandLineOptionsHandle &, const CommandLineOptionsHandle &)
const bsl::vector< bsls::Types::Int64 > & theInt64Array(const bsl::string_view &name) const
Definition balcl_commandline.h:2733
Definition balcl_commandline.h:1423
CommandLine(const OptionInfo(&specTable)[LENGTH], bsl::ostream &errorStream, bslma::Allocator *basicAllocator=0)
Definition balcl_commandline.h:2402
bool hasOption(const bsl::string_view &name) const
OptionType::Enum type(const bsl::string_view &name) const
int theInt(const bsl::string_view &name) const
const bdlt::Date & theDate(const bsl::string_view &name) const
bool isParsed() const
BSLMF_NESTED_TRAIT_DECLARATION(CommandLine, bdlb::HasPrintMethod)
bool hasValue(const bsl::string_view &name) const
void printUsage() const
CommandLine(const OptionInfo *specTable, int length, bsl::ostream &errorStream, bslma::Allocator *basicAllocator=0)
static bool isValidOptionSpecificationTable(const OptionInfo *specTable, int length, bsl::ostream &errorStream)
bslma::Allocator * allocator() const
const bsl::vector< bdlt::Date > & theDateArray(const bsl::string_view &name) const
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
const bdlt::Time & theTime(const bsl::string_view &name) const
const bdlt::Datetime & theDatetime(const bsl::string_view &name) const
double theDouble(const bsl::string_view &name) const
~CommandLine()
Destroy this command-line object.
const bsl::vector< int > & positions(const bsl::string_view &name) const
CommandLineOptionsHandle specifiedOptions() const
const bsl::vector< bdlt::Time > & theTimeArray(const bsl::string_view &name) const
CommandLineOptionsHandle options() const
const bsl::vector< bdlt::Datetime > & theDatetimeArray(const bsl::string_view &name) const
BSLMF_NESTED_TRAIT_DECLARATION(CommandLine, bslma::UsesBslmaAllocator)
const bsl::vector< char > & theCharArray(const bsl::string_view &name) const
int numSpecified(const bsl::string_view &name) const
int parse(int argc, const char *const argv[], bsl::ostream &errorStream)
CommandLine & operator=(const CommandLine &rhs)
const bsl::vector< bsl::string > & theStringArray(const bsl::string_view &name) const
bool isSpecified(const bsl::string_view &name, int *count) const
static bool isValidOptionSpecificationTable(const OptionInfo(&specTable)[LENGTH])
Definition balcl_commandline.h:2357
void printUsage(const bsl::string_view &programName) const
bool theBool(const bsl::string_view &name) const
char theChar(const bsl::string_view &name) const
void printUsage(bsl::ostream &errorStream) const
bool isSpecified(const bsl::string_view &name) const
CommandLine(const OptionInfo *specTable, int length, bslma::Allocator *basicAllocator=0)
int position(const bsl::string_view &name) const
bsls::Types::Int64 theInt64(const bsl::string_view &name) const
const bsl::vector< double > & theDoubleArray(const bsl::string_view &name) const
CommandLine(const CommandLine &original, bslma::Allocator *basicAllocator=0)
bool isValid() const
const bsl::vector< bsls::Types::Int64 > & theInt64Array(const bsl::string_view &name) const
void printUsage(bsl::ostream &errorStream, const bsl::string_view &programName) const
const bsl::string & theString(const bsl::string_view &name) const
const bsl::vector< int > & theIntArray(const bsl::string_view &name) const
int parse(int argc, const char *const argv[])
Definition balcl_optionvalue.h:396
Definition balcl_option.h:132
Definition bdlt_date.h:294
Definition bdlt_datetime.h:330
Definition bdlt_time.h:195
Definition bslstl_stringview.h:471
Definition bslstl_string.h:1252
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:3019
Definition bslstl_vector.h:1120
void reserve(size_type newCapacity)
Definition bslstl_vector.h:4263
void push_back(const VALUE_TYPE &value)
Definition bslstl_vector.h:4343
Definition bslma_allocator.h:545
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition balcl_commandline.h:1364
bool operator==(const CommandLine_SchemaData &lhs, const CommandLine_SchemaData &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, const CommandLine &rhs)
bool operator!=(const CommandLine_SchemaData &lhs, const CommandLine_SchemaData &rhs)
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
basic_ostringstream< char, char_traits< char >, allocator< char > > ostringstream
Definition bslstl_iosfwd.h:97
Definition balcl_commandline.h:1375
const char * d_name_p
Definition balcl_commandline.h:1379
OptionType::Enum d_type
Definition balcl_commandline.h:1378
Definition balcl_optioninfo.h:135
Definition balcl_optiontype.h:288
Enum
Definition balcl_optiontype.h:250
@ e_DOUBLE
Definition balcl_optiontype.h:257
@ e_CHAR_ARRAY
Definition balcl_optiontype.h:262
@ e_STRING
Definition balcl_optiontype.h:258
@ e_INT
Definition balcl_optiontype.h:255
@ e_INT64
Definition balcl_optiontype.h:256
@ e_CHAR
Definition balcl_optiontype.h:254
@ e_DATE_ARRAY
Definition balcl_optiontype.h:268
@ e_DATE
Definition balcl_optiontype.h:260
@ e_BOOL
Definition balcl_optiontype.h:253
@ e_INT64_ARRAY
Definition balcl_optiontype.h:264
@ e_INT_ARRAY
Definition balcl_optiontype.h:263
@ e_STRING_ARRAY
Definition balcl_optiontype.h:266
@ e_TIME
Definition balcl_optiontype.h:261
@ e_DATETIME
Definition balcl_optiontype.h:259
@ e_TIME_ARRAY
Definition balcl_optiontype.h:269
@ e_DATETIME_ARRAY
Definition balcl_optiontype.h:267
@ e_DOUBLE_ARRAY
Definition balcl_optiontype.h:265
Definition bdlb_printmethods.h:306
Definition bslma_usesbslmaallocator.h:344
long long Int64
Definition bsls_types.h:134