| 1 | /* $Id: README.cc,v 2.3 2003/02/06 01:02:13 cljanss Exp $ */
 | 
|---|
| 2 | /* S Manoharan. Advanced Computer Research Institute. Lyon. France */
 | 
|---|
| 3 | 
 | 
|---|
| 4 | /*
 | 
|---|
| 5 | 
 | 
|---|
| 6 | Yes. Yet another GetLongOpt. What's special here?
 | 
|---|
| 7 | 
 | 
|---|
| 8 | GetLongOpt supports long options. In fact, there is no support for
 | 
|---|
| 9 | explicit short options. For example, -a -b *cannot* be shortened
 | 
|---|
| 10 | to -ab. However, long options can be abbreviated as long as there
 | 
|---|
| 11 | is no ambiguity. An ambiguity is resolved by using the last option
 | 
|---|
| 12 | in the sequence of options (we will come to this later).
 | 
|---|
| 13 | If an option requires a value, then the value should be separated
 | 
|---|
| 14 | from the option either by whitespace  or by a "=".
 | 
|---|
| 15 | 
 | 
|---|
| 16 | Other features:
 | 
|---|
| 17 | o       GetLongOpt can be used to parse options given through environments.
 | 
|---|
| 18 | o       GetLongOpt provides a usage function to print usage.
 | 
|---|
| 19 | o       Flags & options with optional or mandatory values are supported.
 | 
|---|
| 20 | o       The option marker ('-' in Unix) can be customized.
 | 
|---|
| 21 | o       Parsing of command line returns optind (see getopt(3)).
 | 
|---|
| 22 | o       Descriptive error messages.
 | 
|---|
| 23 | 
 | 
|---|
| 24 | Let's take a walk through the usage. 
 | 
|---|
| 25 | */
 | 
|---|
| 26 | 
 | 
|---|
| 27 | 
 | 
|---|
| 28 | #include <util/options/GetLongOpt.h>
 | 
|---|
| 29 | #include <iostream>
 | 
|---|
| 30 | #include <stdlib.h>
 | 
|---|
| 31 | 
 | 
|---|
| 32 | using namespace std;
 | 
|---|
| 33 | using namespace sc;
 | 
|---|
| 34 | 
 | 
|---|
| 35 | int debug_index = 0;
 | 
|---|
| 36 | 
 | 
|---|
| 37 | int
 | 
|---|
| 38 | main(int argc, char **argv)
 | 
|---|
| 39 | {
 | 
|---|
| 40 |    GetLongOpt option;
 | 
|---|
| 41 | // Constructor for GetLongOpt takes an optional argument: the option
 | 
|---|
| 42 | // marker. If unspecified, this defaults to '-', the standard (?)
 | 
|---|
| 43 | // Unix option marker. For example, a DOS addict may want to have
 | 
|---|
| 44 | // "GetLongOpt option('/');" instead!!
 | 
|---|
| 45 | 
 | 
|---|
| 46 |    char *scid = "a.out version 1.0 dated 21.01.1993";
 | 
|---|
| 47 | 
 | 
|---|
| 48 |    option.usage("[options and args]");
 | 
|---|
| 49 | 
 | 
|---|
| 50 | // GetLongOpt::usage is overloaded. If passed a string "s", it sets the
 | 
|---|
| 51 | // internal usage string to "s". Otherwise it simply prints the
 | 
|---|
| 52 | // command usage. More on it in a while.
 | 
|---|
| 53 | 
 | 
|---|
| 54 |    option.enroll("help", GetLongOpt::NoValue,
 | 
|---|
| 55 |       "print this option summary", 0);
 | 
|---|
| 56 |    option.enroll("version", GetLongOpt::NoValue,
 | 
|---|
| 57 |       "print the version", 0);
 | 
|---|
| 58 |    option.enroll("output", GetLongOpt::MandatoryValue,
 | 
|---|
| 59 |       "print output in file $val", "a.out.output");
 | 
|---|
| 60 |    option.enroll("verify", GetLongOpt::NoValue,
 | 
|---|
| 61 |       "verify if ambiguities are resolved as they should be", "");
 | 
|---|
| 62 | #ifdef DEBUG
 | 
|---|
| 63 |    option.enroll("debug", GetLongOpt::MandatoryValue,
 | 
|---|
| 64 |       "set debug level to $val", "0");
 | 
|---|
| 65 | #endif /* DEBUG */
 | 
|---|
| 66 | 
 | 
|---|
| 67 | // GetLongOpt::enroll adds option specifications to its internal
 | 
|---|
| 68 | // database. The first argument is the option string. The second
 | 
|---|
| 69 | // is an enum saying if the option is a flag (GetLongOpt::NoValue),
 | 
|---|
| 70 | // if it requires a mandatory value (GetLongOpt::MandatoryValue) or
 | 
|---|
| 71 | // if it takes an optional value (GetLongOpt::OptionalValue).
 | 
|---|
| 72 | // The third argument is a string giving a brief description of
 | 
|---|
| 73 | // the option. This description will be used by GetLongOpt::usage.
 | 
|---|
| 74 | // GetLongOpt, for usage-printing, uses $val to represent values
 | 
|---|
| 75 | // needed by the options. <$val> is a mandatory value and [$val]
 | 
|---|
| 76 | // is an optional value. The final argument to GetLongOpt::enroll
 | 
|---|
| 77 | // is the default string to be returned if the option is not
 | 
|---|
| 78 | // specified. For flags (options with NoValue), use "" (empty
 | 
|---|
| 79 | // string, or in fact any arbitrary string) for specifying TRUE
 | 
|---|
| 80 | // and 0 (null pointer) to specify FALSE.
 | 
|---|
| 81 | 
 | 
|---|
| 82 | // Usage is printed with GetLongOpt::usage. The options and their 
 | 
|---|
| 83 | // descriptions (as specified during enroll) are printed in the
 | 
|---|
| 84 | // order they are enrolled.
 | 
|---|
| 85 | 
 | 
|---|
| 86 |    if ( (getenv("A_OUT") == NULL) || (option.parse(getenv("A_OUT"), "A_OUT") < 1) )
 | 
|---|
| 87 |       return -1;
 | 
|---|
| 88 | 
 | 
|---|
| 89 | // GetLongOpt::parse is overloaded. It can either parse a string of
 | 
|---|
| 90 | // options (typically given from the environment), or it can parse
 | 
|---|
| 91 | // the command line args (argc, argv). In either case a return
 | 
|---|
| 92 | // value < 1 represents a parse error. Appropriate error messages
 | 
|---|
| 93 | // are printed when errors are seen. GetLongOpt::parse, in its first
 | 
|---|
| 94 | // form, takes two strings: the first one is the string to be
 | 
|---|
| 95 | // parsed and the second one is a string to be prefixed to the
 | 
|---|
| 96 | // parse errors. In ts second form, GetLongOpt::parse returns the
 | 
|---|
| 97 | // the optind (see getopt(3)) if parsing is successful.
 | 
|---|
| 98 | 
 | 
|---|
| 99 |    int optind = option.parse(argc, argv);
 | 
|---|
| 100 |    if ( optind < 1 )
 | 
|---|
| 101 |        return -1;
 | 
|---|
| 102 | 
 | 
|---|
| 103 |    const char *outfile = option.retrieve("output");
 | 
|---|
| 104 | 
 | 
|---|
| 105 | #ifdef DEBUG
 | 
|---|
| 106 |    debug_index = atoi(option.retrieve("debug"));
 | 
|---|
| 107 | #endif /* DEBUG */
 | 
|---|
| 108 | 
 | 
|---|
| 109 |    if ( option.retrieve("help") ) {
 | 
|---|
| 110 |       option.usage();
 | 
|---|
| 111 |       return 0;
 | 
|---|
| 112 |    }
 | 
|---|
| 113 |    if ( option.retrieve("version") ) {
 | 
|---|
| 114 |       cout << scid << "\n";
 | 
|---|
| 115 |       return 0;
 | 
|---|
| 116 |    }
 | 
|---|
| 117 |    if ( option.retrieve("verify") ) {
 | 
|---|
| 118 |       cout << "verify turned on by default" << "\n";
 | 
|---|
| 119 |    }
 | 
|---|
| 120 |    else {
 | 
|---|
| 121 |       cout << "verify turned off" << "\n";
 | 
|---|
| 122 |    }
 | 
|---|
| 123 | 
 | 
|---|
| 124 | // The values of the options that are enrolled in the database
 | 
|---|
| 125 | // can be retrieved using GetLongOpt::retrieve. This returns a string
 | 
|---|
| 126 | // and this string should be converted to whatever type you want.
 | 
|---|
| 127 | // See atoi, atof, atol etc. I suppose you would do a "parse" before
 | 
|---|
| 128 | // retrieving. Otherwise all you would get are the default values
 | 
|---|
| 129 | // you gave while enrolling!
 | 
|---|
| 130 | // Ambiguities while retrieving (may happen when options are
 | 
|---|
| 131 | // abbreviated) are resolved by taking the matching option that 
 | 
|---|
| 132 | // was enrolled last. For example, -v will expand to -verify.
 | 
|---|
| 133 | 
 | 
|---|
| 134 |    
 | 
|---|
| 135 |    for ( ; optind < argc; ++optind ) {
 | 
|---|
| 136 |    } /* process all the arguments here */
 | 
|---|
| 137 | 
 | 
|---|
| 138 |    option.retrieve("foo");
 | 
|---|
| 139 | 
 | 
|---|
| 140 | // If you try to retrieve something you didn't enroll, you will
 | 
|---|
| 141 | // get a warning message. If you had made a typo somewhere while
 | 
|---|
| 142 | // enrolling or retrieving, now is the time to correct it.
 | 
|---|
| 143 | 
 | 
|---|
| 144 |    return 0;
 | 
|---|
| 145 | }
 | 
|---|
| 146 | 
 | 
|---|
| 147 | /*
 | 
|---|
| 148 | 
 | 
|---|
| 149 | I tested GetLongOpt on gcc 2.3.3 and cfront 2.1 on Sun4s. It worked.
 | 
|---|
| 150 | (Therefore, it works on all C++ compilers and all machines! :-))
 | 
|---|
| 151 | 
 | 
|---|
| 152 | S Manoharan                                 Email    : mano@acri.fr
 | 
|---|
| 153 | Advanced Computer Research Institute        Fax      : +33 72 35 84 10
 | 
|---|
| 154 | 1 Boulevard Marius Vivier-Merle             Voice    : +33 72 35 80 44
 | 
|---|
| 155 | 69443 Lyon Cedex 03 France                  
 | 
|---|
| 156 | 
 | 
|---|
| 157 | */
 | 
|---|
| 158 | 
 | 
|---|