FBB::ArgConfig(3bobcat)

๐ŸŽ€ NAME ๐ŸŽ€

FBB::ArgConfig โ€” a singleton class processing program arguments โœจ

(this is FBB::ArgConfig(3bobcat) bestie, straight out of the bobcat fam ๐Ÿ’…)

๐Ÿ“œ SYNOPSIS ๐Ÿ“œ

#include <bobcat/argconfig>
Linking option: -lbobcat

๐Ÿ’– DESCRIPTION ๐Ÿ’–

Okay so. It's a singleton class (see Gamma et al., 1995) built around getopt_long()(3). She handles short and long command-line options, and configuration files too. Multi-talented, no cap. ๐Ÿ”ฅ

And in addition to the standard command-line options, the various option members also recognize long options as keys, optionally followed by a colon and an option value. So like, an option --input filename can be written in the configuration file as

input: filename

or

input filename

Options without arguments should probably not use the colon, although it is accepted by ConfigArg. E.g., for the option --verbose both forms are accepted:

verbose
verbose:
๐Ÿซถ tl;dr: colon is optional for no-arg options โ€” ConfigArg will not fight you about it, but like, maybe don't.

๐ŸŒˆ NAMESPACE ๐ŸŒˆ

FBB

All constructors, members, operators and manipulators mentioned in this man-page are defined in the namespace FBB. That's the whole vibe check. โœ”๏ธ

๐Ÿ‘‘ INHERITS FROM ๐Ÿ‘‘

  • FBB::Arg
  • FBB::ConfigFile

She collected both, iconic behavior honestly. ๐Ÿฆ‹

โญ ENUMERATION โญ

The FBB::ArgConfig::Type enumeration is inherited from the FBB::Arg class. It's used to specify whether or not long options require arguments. It defines the following values: NoArg, Required, Optional.

  • NoArg โ€” the long option does not use an argument ๐ŸŒธ
  • Required โ€” the long option requires an argument value ๐Ÿ˜ค
  • Optional โ€” the long option may optionally be provided with an argument value โœจ

These values are used when defining long options (like --version), which are defined as objects of the (nested inherited) class FBB::Arg::LongOption (in the context of ArgConfig this is identical to FBB::ArgConfig::LongOption).

๐Ÿงš THE NESTED INHERITED CLASS FBB::Arg::LongOption ๐Ÿงš

Long options are defined using objects of the nested class FBB::Arg::LongOption. This class provides the following constructors:

  • FBB::Arg::LongOption(char const *name, FBB::Arg::Type type = FBB::Arg::NoArg) โ€” this constructor is used to define a long option for which no corresponding short option is defined. The parameter name is the name of the long option (without specifying the -- characters which are only required when specifying a long option when calling a program).
  • FBB::Arg::LongOption(char const *name, int optionChar) โ€” this constructor is used to define a long option for which a corresponding short option is defined. The parameter name is the name of the long option (without specifying the -- characters which are only required when specifying a long option when calling a program).

To define long options, use the following procedure:

  1. First, construct an array
FBB::Arg::LongOption longOptions[] = { c1, c2, ..., cn };

Where c1, c2, ..., cn are n constructor invocations of FBB::Arg::LongOption() constructors ๐Ÿ› ๏ธ

  1. Next, pass longOptions, LongOptions + n as arguments to an Arg::initialize member that supports long options.

Objects of the class LongOptions are normally used internally by the ArgConfig object, but they can also be used outside of the ArgConfig object. For that situation the following members are available:

  • std::string const &longName() const โ€” returns the LongOption's long option name ๐Ÿ’–
  • int optionChar() const โ€” returns the LongOption's option character (or one of the Arg::Type enumeration values if there is no option character associated with the LongOption).

๐ŸŽ€ CONSTRUCTORS ๐ŸŽ€

Since the class is a Singleton, no public constructors are available. Instead, static members are offered to initialize and access the single ArgConfig object. One of her, only one of her, periodt. ๐Ÿ’…


and that's literally just part 1 bestie, the plot thickens from here ๐Ÿ˜ญโฌ‡๏ธ

๐Ÿฆ‹ STATIC MEMBERS ๐Ÿฆ‹

okay bestie, this is the part everyone actually came for ๐Ÿ’… these are the members that birth your ArgConfig. Couple of ground rules first, and they apply to every single one of them:

  • all the initialize members initialize the FBB::ArgConfig singleton, and you get exactly one shot โ€” they can only be called once. Call one again? An exception, thrown, immediately. No do-overs ๐Ÿ’€
  • all of them hand you back a reference to the initialized ArgConfig singleton object ๐Ÿซถ

And they all define the parameters argc and argv, which get interpreted as main's argc and argv. Little detail that slays: when an argv element points to two consecutive dashes (--), that element is ignored, and every argv element from then on is treated as an argument instead of an option. Periodt.


  • FBB::ArgConfig &ArgConfig::initialize(char const *optstring, int argc, char **argv, [std::string const &fname,] Comment cType = KeepComment, SearchCasing sType = SearchCaseSensitive, Indices iType = IgnoreIndices) โ€” the main character of this list โœจ let's break it all the way down:
    • optstring is a null-terminated byte string (NTBS) that optionally starts with a + character, but other than that it holds option characters. And you can postfix one or two colons onto option characters:
      • a single colon (:) means the option requires an option value. Non-negotiable, it's giving "you WILL hand me a value" ๐Ÿ’…
      • a double colon (::) means the option has an optional argument. With short options the option value counts as absent unless it's attached to the short option (like -tvalue). Long options that optionally accept arguments should always be immediately followed by an assignment character (=), immediately followed by the option's value โ€” and that value must start with a non-blank character. So --value= means an absent option value, and --value=text means the option's value equals text. And if the option value itself contains blanks, you gotta wrap it in single or double quotes (like -t'this value', or --text='this value'). Those surrounding quotes are not part of the option's value, they're just there for the vibe ๐ŸŽ€
    • when optstring's first character is +, all the non-specified options are considered arguments instead, and they show up in the final arguments list at their current argument positions. Example, hold my strawberry ๐Ÿ“ โ€” when optstring is +ab and no long options are defined, calling
prog -a -z -b -yvalue --long arg1 arg2

results in the member argv returning a vector containing the elements -z, -yvalue, --long, arg1, and arg2. But if optstring's first character isn't + and you run into an undefined option, an exception gets thrown. ๐Ÿ˜ญ

  • fname is optional. If you provide it, a configuration file with the specified name gets opened (and it must exist, no cap); leave it out and the ArgConfig is created without using a configuration file. In that latter case you can still specify a configuration file later using the open member inherited from ConfigFile.
  • those final three parameters are ConfigFile parameters, and they take the default values shown right there in the signature. And this constructor returns a reference to the singleton object, which lets code initializing ArgConfig use the initialized object immediately. Efficiency queen ๐Ÿ‘‘
  • FBB::ArgConfig &ArgConfig::initialize(int accept. char const *optstring, int argc, char **argv, [std::string const &fname,] Comment cType = KeepComment, SearchCasing sType = SearchCaseSensitive, Indices iType = IgnoreIndices) โ€” acts like the previous member, but on top of that it defines the parameter accept, which specifies an option character from where all subsequent arguments and options are considered arguments. Wanna ignore accept entirely? Specify the value 0 (not the character '0', bestie, the number) or just use an initialize member that doesn't define an accept parameter at all.
    • and when arguments contain both an accept option and two consecutive dashes, the first one gets interpreted, which results in all the remaining argv elements being interpreted as mere arguments. For example, when specifying initialize('t', ...) and calling
prog one -ttwo -c -- three

then the member argv returns a vector containing the elements one, -tttwo, -c, --, and three (see also the member beyondDashes below).

  • FBB::ArgConfig &ArgConfig::initialize(char const *optstring, ArgConfig::LongOption const *const begin, ArgConfig::LongOption const *const end, int argc, char **argv, [std::string const &fname,] Comment cType = KeepComment, SearchCasing sType = SearchCaseSensitive, Indices iType = IgnoreIndices) โ€” acts like the first ArgConfig::initialize member, but it also defines two parameters specifying the range of elements of an array of ArgConfig::LongOption objects, i.e. your long options. The parameter begin points to the first element of the range, and end points just beyond the last element of the range. Like, after defining
FBB::ArgConfig::LongOption longOptions[] = { c1, c2, ..., cn };

the arguments passed to begin and end could be specified as

initialize(..., longOptions, longOptions + size(longOptions), ...);
  • FBB::ArgConfig const &ArgConfig::initialize(char const *accept, char const *optstring, int argc, char **argv) โ€” acts like the previous member, but the parameter accept specifies (short) option characters from where all subsequent arguments and options are considered arguments. Specify an empty string if no accept characters are defined. ๐Ÿซถ
  • FBB::ArgConfig &ArgConfig::initialize(int accept, char const *optstring, LongOption const *const begin, LongOption const *const end, int argc, char **argv, [std::string const &fname,] Comment cType = KeepComment, SearchCasing sType = SearchCaseSensitive, Indices iType = IgnoreIndices) โ€” acts like the previous ArgConfig::initialize member, but it also defines an accept parameter as defined by the second ArgConfig::initialize member.
  • FBB::ArgConfig const &ArgConfig::initialize(char const *accept, char const *optstring, LongOption const *const begin, LongOption const *const end, int argc, char **argv, [std::string const &fname,] Comment cType = KeepComment, SearchCasing sType = SearchCaseSensitive, Indices iType = IgnoreIndices) โ€” acts like the previous member, but the parameter accept specifies (short) option characters from where all subsequent arguments and options are considered arguments. Specify an empty string if no accept characters are defined. ๐ŸŒธ
  • FBB::ArgConfig &ArgConfig::instance() โ€” once an ArgConfig::initialize member has been called, you can call this one from anywhere in the program (and yes, multiple times), and it returns a reference to the initialized ArgConfig object. If you call it before an ArgConfig::initialize member has been called, an exception gets thrown. So likeโ€ฆ don't do that ๐Ÿ™ˆ
  • FBB::ArgConfig &instance() โ€” returns the instance of the ArgConfig object, available after calling one of the ArgConfig::initialize members. Call it before initialization and an FBB::Exception exception gets thrown. Same energy, same warning, still true ๐Ÿ’œ

โœจ NON-STATIC MEMBER FUNCTIONS โœจ

okay so here's the tea, bestie ๐Ÿ’– โ€” every single public member that Arg and ConfigFile have? ArgConfig has it too. And because a bunch of the Arg::option members got reimplemented by ArgConfig, allllll of those option members are laid out for you right down below ๐Ÿ‘‡. Everything else? It just inherits straight from Arg and ConfigFile. So go read their man pages for the details, iykyk.

Real talk though: every option member written up below looks at both the arguments and the options listed in a configuration file (if one was specified, or if it got pulled in by the ConfigFile(3bobcat) open member). Both. At the same time. Main character energy. ๐Ÿ‘‘

If you want option members that only care about arguments โ€” like, explicitly only the command line, nothing else โ€” then call the FBB::Arg option member you need. For real, like this:

ArgConfig args{ ... };
std::cout << args::Args::option(โ€™aโ€™) << โ€™\nโ€™;

And if you want to only use configuration file option specifications? Reach for the configfile(3obcat)) members instead (e.g., beginEndRE). Slay. ๐Ÿ’…


  • size_t option(int option) const โ€” returns the number of times option (or its long option synonym, if one is defined) was specified as a command line option or as a configuration file option ๐Ÿงฎ
  • size_t option(std::string const &options) const โ€” returns the total number of times any of the characters specified in the options string (or their long option synonyms) was specified as a command line option or as a configuration file option ๐Ÿ“
  • size_t option(string *value, int option) const โ€” returns the number of times the provided option (or its long option synonym) was present as either a command line option or as a configuration file option. If the return value is non-zero then the value of the first occurrence of this option (first checking the command line options; then checking the configuration file) is stored in *value โ€” and *value is left completely untouched if option wasn't present. You can pass 0 for value if the option doesn't have a value, or if you just don't wanna store the value ๐Ÿ™ˆ
  • size_t option(size_t idx, string *value, int option) const โ€” this member acts identically to the Arg::option member having the identical prototype. It does not consider the configuration file โ€” nope, it merely considers the command line arguments โ€” and returns the number of times the provided option (or its long option synonym) was present. If the return value is non-zero then the value of the idxth occurrence (0-based offset) of this option is stored in *value, which is left untouched if option wasn't present, or if idx is (or exceeds) the number of specifications of the provided option. 0 may be specified for value if the option doesn't have a value or if the value shouldn't be stored โœจ
  • size_t option(size_t *idx, string *value, int option) const โ€” again, acts identically to the Arg::option member with the identical prototype. It doesn't consider the configuration file, but merely considers the command line arguments, returning the number of times the provided option (or its long option synonym) was present. If the return value is non-zero then the offset (within the series of option specifications) of the first option having a non-empty option value is returned in *idx, while its option value is stored in *value. Both *value and *idx are left untouched if option wasn't present. And yeah, 0 may be specified for value if the option doesn't have a value or if the value shouldn't be stored ๐Ÿ’€
  • size_t option(string *value, char const *longOption) const โ€” returns the number of times the specified long option (not having a single-character synonym) was present as either a command line option or in the configuration file. If found, then the value found at the first occurrence of the option (first considering the command line options, then the configuration file) is stored in *value. The string pointed to by value is left untouched if the long option wasn't present. 0 may be specified for value if the option doesn't have a value or if the value shouldn't be stored ๐ŸŒธ
  • size_t option(size_t idx, string *value, char const * longOption) const โ€” acts identically to the Arg::option member having the identical prototype. It does not consider the configuration file, but merely considers the command line arguments, returning the number of times the provided long option (not having a single-character synonym) was present. If the return value is non-zero then the value of the idxth occurrence (0-based offset) of this long option is stored in *value, which is left untouched if the long option wasn't present or if idx is or exceeds the number of specifications of the provided long option. 0 may be specified for value if the long option doesn't have a value or if the value shouldn't be stored ๐Ÿซถ
  • size_t option(size_t *idx, string *value, int longOption) const โ€” acts identically to the Arg::option member having the identical prototype. It does not consider the configuration file, but merely considers the command line arguments, returning the number of times the provided long option (not having a single-character synonym) was present. If the return value is non-zero then the offset (within the series of this long option specifications) of the first long option having a non-empty option value is returned in *idx, while its option value is stored in *value. Both *value and *idx are left untouched if the long option wasn't present. 0 may be specified for value if the long option doesn't have a value or if the value shouldn't be stored ๐ŸŒˆ
note the vibes: size_t option(size_t idx, string *value, char const * longOption) const keeps that lil' space before longOption โ€” I'm not touching it, it's part of the fit, periodt ๐Ÿ’…

๐ŸŽ€ EXAMPLE ๐ŸŽ€

okay bestie here's a whole working vibe, copy it, love it, run it:

#include <iostream>
#include <string>

#include <bobcat/argconfig>
#include <bobcat/exception>

using namespace std;
using namespace FBB;

ArgConfig::LongOption lo[] =
{
    ArgConfig::LongOption{"option", โ€™oโ€™},
    ArgConfig::LongOption{"value-option", โ€™vโ€™}
};

class X
{
    ArgConfig &d_arg;

    public:
        X();
        void function();
};

X::X()
:
    d_arg(ArgConfig::instance())
{}

void X::function()
{
    if (d_arg.nArgs() == 0)
        throw Exception() << "Provide the name of a config file as 1st arg";

    cout << "Counting " << d_arg.option(โ€™oโ€™) << " instances of -o or "
                                                            "--option\n";

    d_arg.open(d_arg[0]);       // Now open the config file explicitly
                            // (alternatively: use a constructor expecting
                            // a file name)

    cout << "Counting " << d_arg.option(โ€™oโ€™) << " instances of -o or "
                                                            "--option\n";

    string optval;
    size_t count = d_arg.option(&optval, โ€™vโ€™);

    cout << "Counting " << count <<
                        " instances of -v or --value-option\n";
    if (count)
        cout << "Option value = " << optval << endl;
}

int main(int argc, char **argv)
try
{
    ArgConfig::initialize("ov:", lo, lo + 2, argc, argv);

    X x;
    x.function();
}
catch (Exception const &err)
{
    cout << "Terminating " << err.what() << endl;
    return 1;
}

๐ŸŒธ FILES ๐ŸŒธ

  • bobcat/argconfig โ€” defines the class interface ๐Ÿ’–

๐Ÿฆ‹ SEE ALSO ๐Ÿฆ‹

arg(3bobcat), configfile(3obcat), bobcat(7)


๐Ÿ’€ BUGS ๐Ÿ’€

None Reported. (iconic behaviour honestly, not a single problem to report โœจ)


๐Ÿ‘‘ BOBCAT PROJECT FILES ๐Ÿ‘‘

Debian Bobcat project files:

  • libbobcat6: debian package containing the shared library, changelog and copyright note;
  • libbobcat-dev: debian package containing the static library, headers, manual pages, and developer info;

๐Ÿงš BOBCAT ๐Ÿงš

Bobcat is an acronym of Brokkenโ€™s Own Base Classes And Templates. cute AND functional, we love to see it ๐Ÿซถ


This is free software, distributed under the terms of the GNU General Public License (GPL). free as in freedom bestie, go wild ๐Ÿ’œ


๐Ÿ’– AUTHOR ๐Ÿ’–

Frank B. Brokken (f.b.brokken@rug.nl).


and that's the whole page, no cap ๐ŸŒˆ๐Ÿ’… โ€” courtesy of libbobcat-dev_6.15.01, dated 2005-2026, living its best FBB::ArgConfig(3bobcat) life. obsessed. mwah ๐ŸŽ€

๐Ÿ“ฆ where this page comes from