1 karl 1.27 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.12 //
|
3 karl 1.24 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.23 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.24 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.25 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.27 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.12 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.17 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.12 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.27 //
|
21 kumpf 1.17 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.12 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 kumpf 1.17 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.12 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Bob Blair (bblair@bmc.com)
33 //
|
34 david.dillard 1.26 // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
35 // (carolann_graves@hp.com)
36 // David Dillard, VERITAS Software Corp.
37 // (david.dillard@veritas.com)
|
38 mike 1.12 //
39 //%/////////////////////////////////////////////////////////////////////////////
40
41
42 //
43 // Yet another attempt to create a general-purpose, object-oriented,
44 // portable C++ command line parser.
45 //
46 // There are two classes involved:
47 // getoopt which encapsulates three functions:
48 // 1. Registration of program-defined flags and their characteristics
49 // 2. Parsing of the command line IAW the flag definitions
50 // 3. Orderly retrieval of the command line components
51 //
52 // Optarg which abstracts the idea of a command line argument.
53 //
54 // The details of these classes are discussed in the comments above each
55 // class.
|
56 david.dillard 1.26 //
|
57 mike 1.12
58 #ifndef _GETOOPT_H_
59 #define _GETOOPT_H_
60
|
61 mike 1.13 #include <stdio.h>
|
62 mike 1.12 #include <iostream>
|
63 kumpf 1.20 #include <Pegasus/Common/ArrayInternal.h>
|
64 mike 1.12 #include <Pegasus/Common/String.h>
65 #include <Pegasus/Common/Config.h>
|
66 mike 1.13 #include <Pegasus/Common/Exception.h>
|
67 kumpf 1.18 #include <Pegasus/getoopt/Linkage.h>
|
68 mike 1.12
69 PEGASUS_USING_STD;
70 PEGASUS_USING_PEGASUS;
71
72 //
73 // This structure describes a program-defined command line option.
74 // The syntax of these options are the same as those understood by
|
75 david.dillard 1.26 // the standard C language routines getopt() and getopt_long()
|
76 mike 1.12 //
77 // Command line options are named, and the name is prefaced by
78 // either a hyphen or by two hyphens. Names prefixed by one
79 // hyphen are restricted to a length of one character. There is
80 // no limit to the size of names prefixed by two hyphens. The
81 // two-hyphen-named options are called "long" options.
82 //
83 // The argtype indicates whether the name should be bound to a value.
84 // If it never has a value, the type is 0. If it always has a value,
85 // the type is 1. If it can optionally have a value, the type is 2.
86 // Type 2 is valid only with long-named options
87 //
88 // The islong flag tells whether the option is long-named.
|
89 david.dillard 1.26 //
|
90 mike 1.12 // The isactive flag tells whether the option should be considered
91 // during parsing. It is on unless explicitly turned off by the program.
92 struct flagspec {
|
93 kumpf 1.28 String name;
94 int argtype;
95 Boolean islong;
96 Boolean active;
|
97 mike 1.12 };
98
99 //
100 // Class Optarg encapsulates a command line argument as it was parsed.
101 // If it has a name, it means that it is bound to that command line option.
102 // For example, if the command line were
103 // myprog --database=xyz mytable
104 // then the name "database" would be associated with the first argument.
105 // There would be no name associated with the second argument ("mytable").
106 //
107 // In the example above, the value property of the arguments would
108 // be "xyz" bound to the name "database" and "mytable" bound to a
109 // blank name.
110 //
111 // The option type further describes the binding:
112 // A FLAG means that the value is bound to a short-named option name (flag)
113 // A LONGFLAG means that the value is bound to a long-named option name
114 // REGULAR means that the argument value is not preceded by a flag
115 //
|
116 kumpf 1.28 class PEGASUS_GETOOPT_LINKAGE Optarg
117 {
118 public:
119 enum opttype {FLAG, LONGFLAG, REGULAR};
120
121 private:
122 String _name;
123 opttype _opttype;
124 String _value;
125
126 public:
127 // Constructors and Destructor. Default copying is OK for this class.
128 Optarg();
129 Optarg(
130 const String& name,
131 opttype type,
132 const String& value);
133 ~Optarg();
134
135 // Methods to set or reset the properties
136 void setName(const String& name);
137 kumpf 1.28 void setType(opttype type);
138 void setValue(const String& value);
139
140 // Methods to get information about the object
141 const String& getName() const;
142 const String& getopt() const;
143 opttype getType() const;
144 Boolean isFlag() const; // Is the opttype == "FLAG" or "LONGFLAG"?
145 Boolean isLongFlag() const; // IS the Opttype == LONGFLAG?
146 const String& Value() const; // return the value as a String
147 const String& optarg() const; // ditto, in getopt() terminology
148 void Value(String& v) const ; // Fill in a String with the Value
149 // @exception TypeMismatchException
150 void Value(int& v) const; // Fill in an int with
151 // the value
152 // @exception TypeMismatchException
153 void Value(unsigned int& v) const; // ditto an
154 // unsigned int
155 void Value(long& v) const ; // ditto a long
156 void Value(unsigned long& v) const; // ditto an unsigned long
157 void Value(double& d) const; // ditto a double
158 kumpf 1.28 ostream& print(ostream& os) const; // print the members (for debug)
|
159 mike 1.12 };
|
160 mike 1.13
161
|
162 mike 1.12 //
163 // class getoopt (a portamentau of "getopt" and "oo") is a container
164 // for Optarg objects parsed from the command line, and it provides
165 // methods for specifying command line options and initiating the
166 // parse.
167 //
168 // The idea is to be able to do getopt()-like things with it:
169 // getoopt cmdline(optstring);
170 // for (getoopt::const_iterator it = cmdline.begin();
|
171 kumpf 1.28 // it != cmdline.end();
172 // it++)
173 // {
174 // . . . (process an Optarg represented by *it.)
|
175 mike 1.12 //
176 // There are three steps in using this class:
177 // 1. Initialization -- specifying the command line options
178 // You can pass a String identical in format the an optstring
179 // to the object either in the constructor or by an explicit method.
180 // If you have long-named options to describe, use as manu
181 // addLongFilespec() calls as you need.
182 // 2. Parse the command line.
183 // This will almost always be cmdline.parse(argc, argv);
184 // You can check for errors (violations of the command line
185 // options specified) by calling hasErrors(). If you need
186 // a description of the errors, they are stored in a
187 // Array<String> which can be retrieved with getErrorStrings();
188 // You can also print the error strings with printErrors();
189 // 3. Analyze the parsed data. You can either iterate through the
190 // the command line, or use indexes like this:
191 // for (unsigned int i = cmdline.first(); i < cmdline.last(); i++)
192 // . . . (process an Optarg represented by cmdline[i])
193 //
194 // You can also look at the parsed data for named arguments
195 // in an adhoc fashion by calling
196 mike 1.12 // isSet(flagName);
197 // and
198 // value(flagName);
|
199 david.dillard 1.26 //
|
200 kumpf 1.28 class PEGASUS_GETOOPT_LINKAGE getoopt
201 {
202 public:
203 typedef Array<flagspec> Flagspec_List;
204 typedef Array<String> Error_List;
205 typedef Array<Optarg> Arg_List;
206
207 /**
208 In the valid option definition string, following an option,
209 indicates that the preceding option takes a required argument.
210 */
211 static const char GETOPT_ARGUMENT_DESIGNATOR;
212
213 private:
214 Flagspec_List _flagspecs;
215 Error_List _errorStrings;
216 Arg_List _args;
217 flagspec* getFlagspecForUpdate(char c);
218 flagspec* getFlagspecForUpdate(const String& s);
219 String emptystring;
220 Optarg _emptyopt;
221 kumpf 1.28
222 public:
223 enum argtype {NOARG, MUSTHAVEARG, OPTIONALARG};
224 // Constructor and destructor. You can initialize an instance with
225 // an optstring to specify command line flags.
226 getoopt(const char* optstring = 0);
227 ~getoopt();
228
229 // Routines for specifying the command line options
230 // add short-named flags, either en masse as an optstring
231 Boolean addFlagspec(const String& opt);
232 // or individually
233 Boolean addFlagspec(char opt, Boolean hasarg = false);
234 // (You can also remove a short flag specification if you need to)
235 Boolean removeFlagspec(char opt);
236 // You can add long-named flags only individually
237 Boolean addLongFlagspec(const String& name, argtype type);
238 // and remove them in the same way.
239 Boolean removeLongFlagspec(const String& name);
240 // You can also get a pointer to the flagspec structure for
241 // a particular flag, specifying a char for short or String for long name
242 kumpf 1.28 const flagspec* getFlagspec(char c);
243 const flagspec* getFlagspec(const String& s);
244
245 // Routines for initiating the parse and checking its success.
246 Boolean parse(int argc, char** argv);
247 Boolean hasErrors() const;
248 const Error_List& getErrorStrings() const;
249 ostream& printErrors(ostream& os) const;
250 void printErrors(String& s) const;
251
252 // Routines for processing the parsed command line
253 // Using indexes
254 unsigned int size() const; // The number of arguments found
255 const Optarg& operator[](unsigned int n); // The nth element
256 unsigned int first() const; // always 0 (duh)
257 unsigned int last() const; // always == size();
258 // Ad Hoc
259 // isSet returns the number of times a particular option appeared
260 // in the argument set.
261 unsigned int isSet(char opt) const;
262 unsigned int isSet(const String& opt) const;
263 kumpf 1.28 // value returns the String value bount to the nth instance of
264 // the flag on the command line
265 const String& value(char opt, unsigned int idx = 0) const;
266 const String& value(const String& opt, unsigned int idx = 0) const;
267 // Still not flexible enough? Here's an array of the results for
268 // your perusal.
269 const Arg_List& getArgs() const;
270
271 // Miscellanous methods
272 // You can add your own error to the error list if you want
273 void addError(const String& errstr);
274 // This method gives the number of named arguments (flags)
275 // size() - flagent() == number of nonflag arguments.
276 unsigned int flagcnt() const;
|
277 mike 1.12 };
278
279 inline int operator==(const Optarg& x, const Optarg& y)
280 {
281 return 0;
282 }
283
284 inline int operator==(const flagspec& x, const flagspec& y)
285 {
286 return 0;
287 }
288
289 #endif
|