FBB::Arg(3bobcat)

✨ FBB::Arg β€” Command Line Arguments ✨

okay bestie, welcome to FBB::Arg(3bobcat) πŸ’… this is the manual page for a singleton class that interfaces command line arguments, and yes she is iconic, let's get into it 🫢


🌸 NAME 🌸

FBB::Arg β€” a singleton class interfacing command line arguments ✨


πŸŽ€ SYNOPSIS πŸŽ€

#include <bobcat/arg>

Linking option: -lbobcat


πŸ’– DESCRIPTION πŸ’–

She's a Singleton class (see Gamma et al., 1995) that handles short- and long command-line options. main character energy fr fr πŸ‘‘

NOTE: since bobcat version 6.07.00, FBB::Arg::Type::None was renamed to FBB::Arg::Type::NoArg. so if you see None anywhere, that's the old name, bestie, do not be confused πŸ’€

🌈 NAMESPACE 🌈

FBB

All constructors, members, operators and manipulators mentioned in this man-page are defined in the namespace FBB. periodt πŸ’…


πŸ¦‹ INHERITS FROM πŸ¦‹

-

(nope, she inherits from nobody, she's self-made ✨)


⭐ ENUMERATION ⭐

The FBB::Arg::Type enumeration is defined by the FBB::Arg class. It's used to say whether or not long options require arguments, and 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 get used when you're defining long options (like --version), which are defined as objects of the (nested) class FBB::Arg::LongOption 🌸


🧚 THE NESTED 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 defines a long option that has no corresponding short option. The parameter name is the name of the long option (without specifying the -- characters, which are only required when you're actually specifying a long option when calling a program πŸ‘€).
  • FBB::Arg::LongOption(char const *name, int optionChar) β€” this constructor defines a long option that does have a corresponding short option. The parameter name is the name of the long option (again, without specifying the -- characters, which are only required when specifying a long option when calling a program).

To define long options, use this 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 Arg object, but they can also be used outside of the Arg 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's no option character associated with the LongOption).
  • FBB::Arg::Type type() const β€” returns the LongOption's type.

πŸ’œ CONSTRUCTORS πŸ’œ

Since the class Arg is a singleton there are no public constructors πŸ™ˆ instead, static members are available to initialize and to access the single FBB::Arg object. iykyk.


πŸ‘‘ STATIC MEMBERS πŸ‘‘

All initialize members initialize the FBB::Arg singleton, and can only be called once. An exception is thrown when called multiple times. All initialize members return a reference to the initialized Arg singleton object.

All initialize members define the parameters argc and argv, which are interpreted as main's argc and argv parameters. When an argv element points to two consecutive dashes (--) then that element is ignored, and all of argv's subsequent elements are considered arguments instead of options. lowkey a vibe check πŸ¦‹

Note: for backward compatibility, all initialize members and the instance member defined in previous versions return non-const references, even though all members of the FBB::Arg class are const members. Some new initialize members were added in version 6.14.00. In future releases these members may all return Arg const references. so heads up bestie, the API might glow up later ✨
  • FBB::Arg &Arg::initialize(char const *optstring, int argc, char **argv) β€” The parameter optstring is a null-terminated byte string (NTBS) optionally starting with a + character, but otherwise containing option characters. One or two colons may be postfixed to option characters:
    • a single colon (:) indicates that the option requires an option value.
    • a double colon (::) indicates that the option has an optional argument. With short options the option value is considered absent unless it is attached to the short option (e.g., -tvalue). Long options optionally using arguments should always immediately be followed by an assignment character (=), immediately followed by the option's value (which must start with a non-blank character). E.g., --value= indicates an absent option value, --value=text indicates the option's value equals text. If an option value itself contains blanks, it must be surrounded by single or double quotes (e.g., -t'this value', or --text='this value'). The surrounding quotes are not part of the option's value πŸ’…

When optstring's first character is + then all non-specified options are considered arguments, appearing in the final arguments list at their current argument positions. E.g., when optstring is +ab and no long options are defined, then 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: options -a and -b were recognized as short options and were not added to the vector returned by the argv member. If optstring's first character isn't + and an undefined option is encountered then an exception is thrown 😭

  • FBB::Arg &Arg::initialize(int accept, char const *optstring, int argc, char **argv) β€” Acts like the previous member, but in addition defines the parameter accept, specifying a (short) option character from where all subsequent arguments and options are considered arguments. To ignore accept the value 0 (not the character '0') can be specified, or an initialize member can be used that does not define an accept parameter πŸ‘‘

When arguments contain two consecutive dashes then all the -- argument is skipped and all remaining arguments are added as-is to the vector returned by the argv member.

For example, when specifying initialize('t', ...) and calling

prog one -ttwo -c -- three

then argv returns a vector containing the elements one, -tttwo, -c, -- three, and when calling

prog one -- -ttwo -c -- three

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

  • FBB::Arg const &Arg::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::Arg const &Arg::initialize(char const *optstring, Arg::LongOption const *const begin, Arg::LongOption const *const end, int argc, char **argv) β€” Acts like the first Arg::initialize member, but in addition defines two parameters specifying the range of elements of an array of Arg::LongOption objects specifying long options. The parameter begin points to the first element of the range, the parameter end points just beyond the last element of the range. E.g., after defining
FBB::Arg::LongOption longOptions[] = { c1, c2, ..., cn };

the arguments passed to begin and end could be specified as

initialize(..., longOptions, longOptions + size(longOptions), ...);
  • FBB::Arg &Arg::initialize(char accept, char const *optstring, LongOption const *const begin, LongOption const *const end, int argc, char **argv) β€” Acts like the previous Arg::initialize member, but in addition defines an accept parameter as defined by the second Arg::initialize member ✨
  • FBB::Arg const &Arg::initialize(char const *accept, char const *optstring, LongOption const *const begin, LongOption const *const end, 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::Arg &Arg::instance() β€” Once an Arg::initialize member has been called, this member can be called from anywhere in the program (and it can be called multiple times), returning a reference to the initialized Arg object.

If it is called before an Arg::initialize member has been called, an exception is thrown πŸ’€


πŸ’… OVERLOADED OPERATOR πŸ’…

  • char const *operator[](size_t idx) const β€” Returns argument[idx], after all options have been removed. It returns 0 if no arg[x] is available. The program's name (argv[0]) is NOT counted here: index 0 refers to the first argument after having removed (processed) the options. so no, bestie, [0] is not the program name, she's the first real argument πŸ‘‘

πŸ’– NON-STATIC MEMBER FUNCTIONS πŸ’–

okay bestie, this is the main event, the moment, the whole slay. these are the members you actually call on your Arg object. buckle up πŸŽ€

  • string const &argv0() const β€” hands you the program's name exactly as argv[0] said it (peep the basename member too, she's related πŸ’…).
  • char const **argPointers() const β€” gives you back all the arguments as a series of pointers, nArgs() of them. element nArgs() + 1 is a 0-pointer, iconic.

and listen, this part matters: you (the caller) are the one responsible for giving that array of pointers back to the common pool. but do not delete the NTBSs that the pointers point at. like, ever. the docs literally show it:

char const **ptr = Arg::instance().argPointers();
delete[] ptr;       // *** don't delete ptr[idx] elements !!
  • std::vector<std::string> const &args() const β€” a vector of strings with all the arguments, options already removed 🧚. the program's name (argv[0]) is not in here β€” element zero is the first actual argument, so like the program's argv[1], and so on.
  • std::string const &basename() const β€” the program's basename, aka whatever argv0() is past the last directory separator. the glow-up of the full path ✨
  • std::vector<std::string>::const_iterator begin() const β€” iterator to the program's first argument (so, args().begin()). pair her with end and now you can run generic algorithms over all the arguments, no cap πŸ”₯
  • size_t beyondDashes() const β€” returns the index of the first argument past the -- argument, or the index of the accept argument (whichever shows up first), or nArgs() if neither -- nor an accept argument was ever used. also go look at the nArgs member below, they're besties.
  • std::vector<std::string>::const_iterator end() const β€” iterator pointing one past the program's last argument (so, args().end()). with begin, generic algorithms can run through everything. the duo of all time πŸ‘‘
  • void help() const β€” if you already called the versionHelp member (see below πŸ‘‡) then this calls the usage function you handed to versionHelp. if you didn't call versionHelp β€” meaning no usage function was ever specified β€” she throws an exception. awkward. πŸ’€
  • size_t nArgs() const β€” number of arguments after the options got removed, i.e. args().size(). heads up: the program's name does not get counted here.
  • size_t nLongOptions() const β€” how many long options you have that don't have short option synonyms. if a long option got specified multiple times, each specification counts on its own. no grouping, we're counting individually πŸ“
  • size_t nOptions() const β€” how many single character options were specified. if short options have long option synonyms, those long synonyms get counted just like they were single character options. and if single character options (or their long synonyms) were given more than once, every single one counts. it's giving thorough πŸ’…
  • size_t option(int option) const β€” how many times option was specified, or its long option synonym if one is defined.
  • size_t option(std::string const &options) const β€” how many times each of the options named in the options argument was specified (or their long option synonyms). careful though: every character in options has to name a single-character option.
  • size_t option(string *value, int option) const β€” how many times the given option (or its long option synonym) was present. if that count is non-zero, the value of the first occurrence of the option lands in *value β€” and *value is left completely untouched if option was never there. you can init value to 0 if the option has no value, or if you don't want its value stored at all.
  • size_t option(size_t idx, string *value, int option) const β€” same deal, how many times the option (or its long synonym) was present. if non-zero, the value of the idxth occurrence (0-based, bestie) gets stored in *value. *value stays untouched if the option wasn't present, or if idx is, or goes past, the number of times the option was specified. pass 0 for value if the option doesn't have a value or you don't want it stored.
  • size_t option(size_t *idx, string *value, int option) const β€” how many times the option (or its long synonym) was present. if non-zero, the offset β€” within the series of option specifications β€” of the first option that has a non-empty option value goes into *idx, and its option value goes into *value. both *value and *idx are left alone if the option wasn't present. 0 is allowed for value if the option has no value or you don't want it kept.
  • size_t option(string *value, char const *longOption) const β€” how many times that long option (the kind with no single-character synonym) was present. its value then goes into *value, which stays untouched if the long option wasn't there. 0 for value if there's no value or you're not storing it.
  • size_t option(size_t idx, string *value, char const * longOption) const β€” how many times that long option (again, no single-character synonym) was present. if non-zero, the value of the idxth occurrence (0-based) of this long option goes into *value. *value stays untouched if the long option wasn't present, or if idx is or exceeds how many times that long option was specified. 0 for value if no value or no storing.
  • size_t option(size_t *idx, string *value, int longOption) const β€” how many times that long option (no single-character synonym, you know the drill) was present. if non-zero, the offset (within that series of long option specifications) of the first long option with a non-empty option value goes into *idx, and its option value goes into *value. both stay untouched if the long option wasn't present. 0 for value if no value or no storing.
  • void versionHelp(void (*usage)(std::string const &progname), char const *version, size_t minArgs, int helpFlag = 'h', int versionFlag = 'v') const β€” the multi-tool, the icon, the moment 🌈:
    • if helpFlag was specified, usage() gets called with basename() as its argument, and then the program throws int 0.
    • if versionFlag was specified, the program's name (via basename()) and version get printed to std::cout, and then the program throws int 0.
    • if there are fewer arguments than minArgs, usage() gets called with basename() and the program ends with exit value 1.
okay so listen: versionHelp compares minArgs against nArgs. so if you want minArgs compared against the number of arguments up to a possible -- argument β€” that's beyondDashes's return value β€” then add nArgs() - beyondDashes() to the minArg argument. literally like this:
arg.versionHelp(usage, version, 2 + arg.nArgs()
                                  - arg.beyondDashes());

the address of the usage() function, the current version, and the minimum number of arguments are all required. the option flags get default argument values, so those are chill. 🌸


🌟 EXAMPLE 🌟

this one shows you how to define long options and how an initialization looks. ngl it's not a full-fledged example β€” like, it's not a small runnable program β€” but it's the vibe check you need.

#include <bobcat/arg>

using namespace FBB;
using namespace std;

namespace   // the anonymous namespace can be used here
{
    Arg::LongOption longOptions[] =
    {
        Arg::LongOption{"debug"},
        Arg::LongOption{"filenames", 'f'},
        Arg::LongOption{"help", 'h'},
        Arg::LongOption{"version", 'v'},
    };
    auto longEnd = longOptions + size(longOptions);
}

int main(int argc, char **argv)
try
{
    Arg &arg = Arg::initialize("df:hv",
                    longOptions, longEnd,
                    argc, argv);

    // code using arg, etc.
}
catch (exception const &err)     // handle exceptions
{
    cerr << err.what() << '\n';
    return 1;
}

πŸŽ€ FILES πŸŽ€

  • bobcat/arg β€” defines the class interface

πŸ¦‹ SEE ALSO πŸ¦‹


πŸ’€ BUGS πŸ’€

None Reported. (she's clean, we love that for her ✨)


πŸ‘‘ 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, right? iconic naming fr.


This is free software, distributed under the terms of the GNU General Public License (GPL).


🫢 AUTHOR 🫢

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


and that's a wrap bestie!! πŸŽ‰ this whole thing lives in libbobcat-dev_6.15.01, dated 2005-2026, and if you ever need to find her again in the manual, she's listed as FBB::Arg(3bobcat). now go parse some arguments, you absolute legend πŸ’…βœ¨

πŸ“¦ where this page comes from