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