| [0b990d] | 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 | 
|---|
| [9259c3] | 68 | // database. The first argument is the option string. The second | 
|---|
| [0b990d] | 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 |  | 
|---|
| [9259c3] | 86 | if ( (getenv("A_OUT") == NULL) || (option.parse(getenv("A_OUT"), "A_OUT") < 1) ) | 
|---|
| [0b990d] | 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 |  | 
|---|