Command line argument handling library


0. Contents

   1. Purpose
   2. Supported
   3. Headers
      3.1. C++ header: argh.hh
      3.2. C header: argh.h
   4. Copying
   5. Requirements
   6. Downloading

1. Purpose

Handles commandline parameters.

2. Supported

C, C++

3. Headers

3.1. C++ header: argh.hh

#ifndef optrar_argh_hh
#define optrar_argh_hh

/* Copyright (C) 1992,2004 Bisqwit (http://iki.fi/bisqwit/) */

/*
 * C++ USAGE EXAMPLE
 * 

#include <argh.hh>

int main(int argc, const char *const *argv)
{
    vector<string> files;
    
    string buildfn;
    bool worst = false;
    
    ParamHandler Argh;
    
    Argh.AddLong("worst",   'w').SetBool().SetDesc("Least optimal.");
    Argh.AddLong("help",    'h').SetBool().SetDesc("This help.");
    Argh.AddLong("version", 'V').SetBool().SetDesc("Displays version information.");
    Argh.AddLong("build",   'b').SetString().SetDesc("Builds the archive.", "<file>");
    Argh.AddLong("make",    'b');
    
    Argh.AddBool('k');
    Argh.AddDesc('k', "This option does nothing.");
    Argh.AddLong("idle", 500).SetDesc("This option does nothing.");
    
    Argh.StartParse(argc, argv);
    for(;;)
    {
        int c = Argh.GetParam();
        if(c == -1)break;
        switch(c)
        {
            case 'w': worst = Argh.GetBool(); break;
            case 'V': printf("%s\n", VERSION); return 0;
            case 'b': buildfn = Argh.GetString(); break;
            case 'k': break; // -k
            case 500: break; // --idle
            case 'h':
                printf(
                    "This is software\n"
                    "\nUsage: software [<option> [<...>]] <file> [<...>]\n"
                    "\nThis software does something for the files.\n"
                    "\nOptions:\n");
                Argh.ListOptions();
                printf("\nNo warranty whatsoever.\n");
                return 0;
            default:
                files.push_back(Argh.GetString());
        }
    }
    if(!Argh.ok())return -1;
    if(!files.size())
    {
        fprintf(stderr, "Error: At least one file must be specified.\n");
        return -1;
    }
    
    ...
}

*/

/* The header begins here. */

#include <string>
class ParamHandler
{
private:
    /* No copying */
    void operator=(const ParamHandler &);
    ParamHandler (const ParamHandler &);
    class Reference;
public:
    typedef long keytype;
    
    ParamHandler();
    virtual ~ParamHandler();
    virtual void PrintOpt(unsigned space, const std::string &opts, const std::string &desc);
    
    Reference AddLong(const std::string &longname, keytype alias);
    Reference AddBool(keytype c);
    Reference AddInt(keytype c, int min, int max);
    Reference AddFloat(keytype c, double min, double max);
    Reference AddString(keytype c, unsigned min=1, unsigned max=std::string::npos);
    Reference AddDesc(keytype c, const std::string &s, const std::string &param="");

    // Support for many conventions
    void StartParse(int ac, const char *const *av, int firstarg=1);
    void StartParse(int ac, const char **av, int firstarg=1);
    void StartParse(int ac, char **av, int firstarg=1);
    void StartParse(int ac, char *const*av, int firstarg=1);
    
    const std::string ProgName() const { return A0; }

    /* --not-x, --no-x, --without-x and --with-x are recognized.
     * Therefore you should use GetBool().
     */
    inline const bool GetBool() const      { return polarity; }
    inline const int GetInt() const        { return intparm; }
    inline const double GetFloat() const   { return doubleparm; }
    inline const std::string &GetString() const { return param; }
    inline const bool ok() const           { return !error; }
    
    keytype GetParam();
    void ListOptions();

	/* - disabled, not supported.
public:
     // Keys for 2,3,4 character options with single hyphen
     static inline keytype char2opt(char c1, char c2) { return (unsigned char)c1 + (unsigned char)c2 * 256; }
     static inline keytype char3opt(char c1, char c2, char c3) { return (unsigned char)c1 + 256 * char2opt(c2, c3); }
     static inline keytype char4opt(char c1, char c2, char c3, char c4) { return char2opt(c1, c2) + 65536 * char2opt(c3, c4); }
    */
private:    
    void ErrorIllegalOption(keytype key);
    void ErrorNeedsArg(keytype key);
    void ErrorNeedsArg(const std::string &longo);
    void ErrorNeedNoArg(const std::string &longo);
    void InternalError(keytype key, const char *s);
    void ErrorOutOfRange(const std::string &param);
    void ErrorUnknownOption(const char *s, bool negafail);
        
public:
    /* argh_atypemap needs this and I don't know how to make it friend. */
    class ArgInfo { public: char type; int min,max;unsigned maxl;double fmin,fmax; };
private:
    class argh_aliasmap *aliases;
    class argh_descsmap *descs;
    class argh_atypemap *argtypes;
    class Reference
    {
        ParamHandler& par;
        keytype key;
    public:
        Reference(ParamHandler& p, keytype k) : par(p), key(k) { }
        Reference &SetBool();
        Reference &SetInt(int min, int max);
        Reference &SetFloat(double min, double max);
        Reference &SetString(unsigned min=1, unsigned max=std::string::npos);
        Reference &SetDesc(const std::string &s, const std::string &param="");
    /*- disabled, not needed.
    private:
        Reference(const Reference&);
        const Reference& operator= (const Reference& );
    */
    };
    Reference MakeRef(keytype key);
    int ParseError();
    int ShortOpt(keytype key, const char *s);
private:
    int argc; const char *const *argv;
    const char *A0;
    /* parser volatile */
    int argpos; bool opts; std::string longo, longobuf; std::string param;
    const char *shortpointer; bool error, polarity; int intparm; double doubleparm;
};

#endif

3.2. C header: argh.h

#ifndef optrar_argh_h
#define optrar_argh_h

/* Copyright (C) 1992,2004 Bisqwit (http://iki.fi/bisqwit/) */

#ifdef __cplusplus
extern "C" {
#endif

extern void argh_init(void);
extern void argh_done(void);
extern void argh_add_long(const char *longname, int alias);
extern void argh_add_bool(int alias);
extern void argh_add_int(int c, int min, int max);
extern void argh_add_float(int c, double min, double max);
extern void argh_add_string(int c, unsigned minlen, unsigned maxlen);
extern void argh_add_desc(int c, const char *s, const char *optparam);
extern void argh_start_parse(int argc, const char *const *argv);
extern int argh_get_bool(void);
extern int argh_get_int(void);
extern double argh_get_float(void);
extern int argh_ok(void);
extern int argh_get_param(void);
extern void argh_list_options(void);
/* Note: This pointer is only valid until next argh_get_param() call */
/* Attention: Do not try to free() it. */
extern const char *argh_get_string(void);

#ifdef __cplusplus
}
#endif

/* C language usage example: 

static int stereo=0;
static int Rate  =43200;
static char *host = NULL;

static void PrintVersionInfo(void)
{
    printf("erec - polydriving recording server v"VERSION" (C) 1992,2000 Bisqwit\n");
}

#include <argh.h>

int main(int argc, const char *const *argv)
{
    int Heelp = 0;
    
    argh_init();
    
    argh_add_long("stereo", '2'); argh_add_bool('2'); argh_add_desc('2', "Specifies stereo sound. Default is mono.", NULL);
    argh_add_long("mono",   'm'); argh_add_bool('m'); argh_add_desc('m', "Redundant. It's here for esd compatibility.", NULL);
    argh_add_long("rate",   'r'); argh_add_int('r',18,999999); argh_add_desc('r', "Specifies recording rate. 43200 is default.", "<num>");
    argh_add_long("device", 'd'); argh_add_string('d',1,1023); argh_add_desc('d', "Specify device.", "<file>");
    argh_add_long("help",   'h'); argh_add_bool('h'); argh_add_desc('h', "Help", NULL);
    argh_add_long("version",'V'); argh_add_bool('V'); argh_add_desc('V', "Version information", NULL);
    
    argh_start_parse(argc, argv);
    for(;;)
    {
        int c = argh_get_param();
        if(c == -1)break;
        switch(c)
        {
            case 'V':
                PrintVersionInfo();
                return 0;
            case 'h':
                Heelp = 1;
                break;
            case '2':
                if(argh_get_bool())++stereo;else stereo=0;
                break;
            case 'm':
                if(argh_get_bool())stereo = 0;else ++stereo;
                break;
            case 'r':
                Rate = argh_get_int();
                break;
            case 'd':
                strncpy(Device, argh_get_string(), sizeof Device);
                Device[sizeof(Device)-1] = 0;
                break;
            default:
            {
                const char *s = argh_get_string();
                host = (char *)malloc(strlen(s)+1);
                strcpy(host, s);
            }
        }
    }
    if(!host)host = (char *)"10.104.2.2";
    
    if(!argh_ok())return -1;
    
    if(Heelp)
    {
        PrintVersionInfo();
        printf(
            "\nAllows multiple applications request recorded data"
            "\nat the same time with different stream attributes.\n");
        printf(
            "Usage: erec [<options> [<...>]] [<host> | none]\n"
            "Options:\n");
        argh_list_options();
        printf("\n"
            "If <host> is other than none, the output will be sent with esdcat.\n");
        return 0;
    }
    
    ...
}

*/

#endif

4. Copying

libargh has been written by Joel Yliluoma, a.k.a. Bisqwit,
and is distributed under the terms of the General Public License (GPL).

5. Requirements

argh has been written in C++, utilizing the standard template library.
GNU make is required.
libargh compiles without warnings at least on g++ versions 3.0.1 and 3.0.3.

6. Downloading

Downloading help

  • Do not download everything - you only need one file (newest version for your platform)!
  • Do not use download accelerators or you will be banned from this server before your download is complete!

Date (Y-md-Hi) acc        Size Name                
2011-0728-1410 r--       22765 libargh-1.1.1.tar.bz2
2011-0728-1410 r--       23334 libargh-1.1.1.tar.gz
2006-0807-2133 r--       21637 libargh-1.1.0.tar.bz2
2006-0807-2133 r--       21764 libargh-1.1.0.tar.gz
2006-0807-2133 r--        6124 patch-libargh-1.0.8-1.1.0.bz2
2006-0807-2133 r--        5752 patch-libargh-1.0.8-1.1.0.gz
2003-0927-1617 r--       21065 libargh-1.0.8.tar.bz2
2003-0927-1617 r--        2044 patch-libargh-1.0.7-1.0.8.bz2
2003-0916-1822 r--       20988 libargh-1.0.7.tar.bz2
2003-0916-1822 r--        3881 patch-libargh-1.0.6.1-1.0.7.bz2
2003-0916-1822 r--        9336 patch-libargh-1.0.6-1.0.7.bz2
2003-0124-1318 r--       20731 libargh-1.0.6.1.tar.bz2
2003-0124-1318 r--        7835 patch-libargh-1.0.6-1.0.6.1.bz2
2002-0813-1358 r--       19578 libargh-1.0.6.tar.bz2
2002-0813-1358 r--        6427 patch-libargh-1.0.5-1.0.6.bz2
2002-0209-0828 r--       16773 libargh-1.0.5.rar
2002-0514-1735 r--       17928 libargh-1.0.5.tar.bz2
2002-0514-1735 r--        7937 patch-libargh-1.0.4-1.0.5.bz2
2002-0118-2305 r--       16751 libargh-1.0.4.rar
2002-0118-2305 r--       16461 libargh-1.0.4.tar.bz2
2002-0118-2305 r--         440 patch-libargh-1.0.3-1.0.4.bz2
2002-0118-0255 r--       16743 libargh-1.0.3.rar
2002-0118-0255 r--       16460 libargh-1.0.3.tar.bz2
2002-0118-0255 r--         592 patch-libargh-1.0.2-1.0.3.bz2
2002-0113-0827 r--       16747 libargh-1.0.2.rar
2002-0113-0827 r--       16463 libargh-1.0.2.tar.bz2
2002-0113-0827 r--        4067 patch-libargh-1.0.1-1.0.2.bz2
2001-1023-0141 r--       15534 libargh-1.0.1.rar
2001-1023-0141 r--       15115 libargh-1.0.1.tar.bz2
2001-1023-0141 r--        5194 patch-libargh-1.0.0-1.0.1.bz2
2001-1022-0610 r--       14020 libargh-1.0.0.rar
2001-1022-0610 r--       13653 libargh-1.0.0.tar.bz2
Back to the source directory index at Bisqwit's homepage