includefile(include/header)

COMMENT(manpage, section, releasedate, archive, short name)
manpage(FBB::Arg)(3bobcat)(_CurYrs_)(libbobcat-dev__CurVers_)
                    (Command Line Arguments)

manpagename(FBB::Arg)(A singleton class interfacing command line arguments)

manpagesynopsis()
    bf(#include <bobcat/arg>)nl()
    Linking option: tt(-lbobcat) 

manpagedescription()
    Singleton class (see Gamma em(et al.), 1995) built around bf(getopt())(3)
and bf(getopt_long())(3). The class handles short- and long command-line
options,

includefile(include/namespace)

manpagesection(INHERITS FROM)
    -

manpagesection(ENUMERATION)

    The bf(FBB::Arg::Type) enumeration is defined by the bf(FBB::Arg)
class. It is used to specify whether or not long options require arguments. It
defines the following values: bf(None, Required, Optional).
    itemization(
    it() bf(None): the long option does not use an argument;
    it() bf(Required): the long option requires an argument value;
    it() bf(Optional): the long option may optionally be provided with  an
        argument value; 
    )

These values are used when constructing objects of the following (nested)
class bf(FBB::Arg::LongOption).

manpagesection(THE NESTED CLASS FBB::Arg::LongOption)
   Long options are defined using objects of the nested class
    bf(FBB::Arg::LongOption). This class provides the following constructors:
   itemization(
    itb(FBB::Arg::LongOption(char const *name, FBB::Arg::Type type =
        FBB::Arg::None)) 
       This constructor is used to define a long option for which no
        corresponding short option is defined. The parameter tt(name) is the
        name of the long option (without prefixing the tt(--) characters,
        which em(are) required when specifying the long option).

    itb(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 tt(name) is the
        name of the long option (without prefixing the tt(--) characters,
        which em(are) required when specifying the long option).
    )
    In a program, long options may be specified as follows:
    itemization(
    it() First, construct an array 
        verb(
    FBB::Arg::LongOption longOptions[] = { c1, c2, ... cn };
        )
    Where tt(c1, c2, ..., cn) are bf(n) constructor invocations of 
            bf(FBB::Arg::LongOption()) constructors

    it() Next, pass bf(longOptions, LongOptions + n)
                as 2nd and 3rd arguments to bf(Arg's) member bf(initialize())
    )

    The class tt(LongOptions) is primarily used internally by the tt(Arg)
object, but it can also be used outside of the tt(Arg) object. For that
situation the following members are provided:
    itemization(
    itb(std::string const &longName() const)
       returns the tt(LongOption's) long option name;
    itb(int optionChar() const)
       returns the tt(LongOption's) option character (or one of the
        tt(Arg::Type) enumeration values if there is no option character
        associated with the tt(LongOption)).
    )

manpagesection(CONSTRUCTORS)
    Since the class is a em(Singleton) there are no public
constructors. Instead, static members are offered for initializing and
accessing the single bf(FBB::Arg) object.

manpagesection(STATIC MEMBERS)
    itemization(
    itb(FBB::Arg &initialize(char const *optstring, int argc, char **argv))
       Initializes the bf(FBB::Arg) singleton. May be called only once.
        Throws an bf(FBB::Exception) exception if called repeatedly or if
        called with tt(argv) containing an undefined option. If so, the
        bf(Exception) object's tt(what()) member provides details. A
        reference to the singleton object is returned.

    itb(FBB::Arg &initialize(char const *optstring,
                                LongOption const *const begin,
                                LongOption const *const end,
                                int argc, char **argv))
       Initializes the bf(FBB::Arg) singleton. Accepts two iterators of an
        array of bf(Arg::LongOption) objects. May be called only once. Throws
        an bf(FBB::Exception) exception if called repeatedly or if called with
        tt(argv) containing a undefined option. If so, the bf(Exception)
        object's tt(what()) member provides details.  See the description of
        bf(Arg::LongOption) below.  A reference to the singleton
        object is returned.

        The parameter tt(optstring) must point to a null-terminated byte
        string (NTBS) containing option characters, possibly postfixed by:
        itemization(
        it() a colon (tt(:)), indicating that the option requires an option
            value. 
        it() a double colon (tt(::)), indicating that the option has an
            optional argument. With short options the option value is
            considered absent unless it it directly attached to the short
            option (e.g., tt(-tvalue)). Long options optionally accepting
            arguments should always immediately be followed by an assignment
            character (tt(=)). Here the option's value must immediately follow
            the tt(=) character, and must start with a non-blank
            character. E.g., tt(--value=) indicates an absent option value,
            tt(--value=text) indicates the option's value equals tt(text).  If
            an option value itself contains blanks, it must be surrounded by
            single or double quotes (e.g., tt(-t'this value'), or
            tt(--text='this value')). The surrounding quotes are
            not part of the option's value.
        )

    itb(FBB::Arg &instance()) 
       Returns a reference to the iitialized bf(Arg) object. If called before
        initialization, an tt(FBB::Exception) exception is thrown.
    )

manpagesection(OVERLOADED OPERATOR)

    itemization(
    itb(char const *operator[](size_t idx) const)
       Returns tt(argument[idx]), after having removed all specified options.
        It returns 0 if no tt(arg[x]) is available.  The program's name
        (tt(argv[0])) is NOT counted here: index 0 refers to the first
        ARGUMENT, e.g., the program's tt(argv[1]).
    )

manpagesection(NON-STATIC MEMBER FUNCTIONS)
    itemization(
    itb(char const **argPointers() const)
       Returns tt(argv)-like set of pointers to all remaining arguments. The
        last element is guaranteed to be a 0-pointer. The first tt(nArg())
        elements point to the respective values of the NTBS arguments that
        were passed to the program.

       The caller is responsible for returning the array of pointers to the
        common pool, but should not delete the C-strings to which the pointers
        point. The following two statements illustrate this:
      verb(
    char const **ptr = Arg::instance().argPointers();
    delete[] ptr;
      )

    itb(std::string const &basename() const)
        Returns the program's basename.

    itb(size_t beyondDashes() const)
       Returns the index of the first argument after a tt(--) argument or
        returns tt(nArgs()) if no tt(--) argument was encountered.nl()
       A tt(--) argument ends tt(Arg)'s argument processing, and all arguments
        beyond the first tt(--) argument are kept `as is'. The
        tt(beyondDashes) member returns the index of the first argument beyond
        the tt(--) argument, which itself is removed from the remaining set of
        arguments.

    itb(void help() const)
       If the member tt(versionHelp) (see below) has been called then this
        member calls the tt(usage) function that was passed to
        tt(versionHelp). If tt(versionHelp) has not been called (i.e., if no
        tt(usage) function has been specified) an bf(FBB::Exception) is
        thrown.

    itb(size_t nArgs() const)
       Returns the number of arguments left after option-removal.  The
        program name bf(argv[0]) is NOT counted here.

    itb(size_t nLongOptions() const) 
       Returns the number of long options not having short option synonyms If
        long options are multiply specified, then each specification is
        counted.

    itb(size_t nOptions() const)
       Returns the number of specified single character options. If short
        options have long option synonyms, then these long option synonyms are
        counted as if they were specified as single character options. If
        single character options (or their long option synonyms) are multiply
        specified, then each specification is separately counted.

    itb(size_t option(int option) const)
       Returns the number of times `option' was specified (or its long option
        synonym, if defined).

    itb(size_t option(std::string const &options) const)
       Returns the number of times each of the options specified in the `option'
        argument were specified (or their long option synonyms). Note that
        each character in tt(options) must specify a single-character option.

    itb(size_t option(string *value, int option) const)
       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 first occurrence of this option is stored in tt(*value), which
        is left untouched if `option' was not present. The parameter tt(value)
        may be initialized to 0 if the option does not have a value or if the
        option's value should not be stored.

    itb(size_t option(size_t idx, string *value, int option) const)
       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 tt(idx)th occurrence (0-based offset) of this option is stored
        in tt(*value), which is left untouched if `option' was not present or
        if tt(idx) is or exceeds the number of specifications of the provided
        option. 0 may be specified for bf(value) if the option does not have a
        value or if the value should not be stored.

    itb(size_t option(size_t *idx, string *value, int option) const)
       Returns 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 tt(option) specifications) of the first option
        having a non-empty option value is returned in tt(*idx), while its
        option value is stored in tt(*value). Both tt(*value) and tt(*idx) are
        left untouched if `option' was not present. 0 may be specified for
        bf(value) if the option does not have a value or if the value should
        not be stored.

    itb(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. Its value is then stored in
        tt(*value), which is left untouched if the long option was not
        present. 0 may be specified for bf(value) if the option does not have
        a value or if the value should not be stored.

    itb(size_t option(size_t idx, string *value, 
                                        char const * longOption) const)
       Returns 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 tt(idx)th occurrence (0-based offset) of this
        long option is stored in tt(*value), which is left untouched if the
        long option was not present or if tt(idx) is or exceeds the number of
        specifications of the provided long option. 0 may be specified for
        bf(value) if the long option does not have a value or if the value
        should not be stored.

    itb(size_t option(size_t *idx, string *value, int longOption) const)
       Returns 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 tt(*idx), while its option value is stored in tt(*value). Both
        tt(*value) and tt(*idx) are left untouched if long option was not
        present. 0 may be specified for bf(value) if the long option does not
        have a value or if the value should not be stored.

    itb(void versionHelp(void (*usage)(std::string const &progname), 
        char const *version, size_t minArgs, int helpFlag = 'h', 
        int versionFlag = 'v') const)
       If the tt(helpFlag) was specified tt(usage()) is called with
        argument bf(basename()) whereafter the program throws tt(int 0).

       If tt(versionFlag) was specified the program's name (using basename())
        and version is displayed to tt(std::cout) whereafter the program
        throws tt(int 0).

       If there are fewer arguments than tt(minArgs) tt(usage()) is called with
        argument bf(basename()) and the program ends with exit value 1.

       Note that tt(versionhelp) compares tt(minArgs) against tt(nArgs). If
        tt(minArgs) should be compaired against the number of arguments up to
        a possible `--' argument (i.e., tt(beyondDashes)' return value), then
        add tt(nArgs() - beyondDashes()) to the tt(minArg) argument. E.g.,
            verb(
    arg.versionHelp(usage, version, 2 + arg.nArgs() 
                                      - arg.beyondDashes());
            )
       The address of the tt(usage()) function, the current version and the
        minimum number of arguments must be specified. Default argument values
        are provided for the option flags.
    )

manpagesection(EXAMPLE)
    The following example illustrates defining long options and shows an
initialization. It is not a full-fledched example in the sense of a small 
runnable program.
        verb(
#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;
}
    )

manpagefiles()
    em(bobcat/arg) - defines the class interface

manpageseealso()
    bf(bobcat)(7)

manpagebugs()
    None Reported.

includefile(include/trailer)
