/src/wxwidgets/include/wx/cmdline.h
Line | Count | Source (jump to first uncovered line) |
1 | | /////////////////////////////////////////////////////////////////////////////// |
2 | | // Name: wx/cmdline.h |
3 | | // Purpose: wxCmdLineParser and related classes for parsing the command |
4 | | // line options |
5 | | // Author: Vadim Zeitlin |
6 | | // Created: 04.01.00 |
7 | | // Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> |
8 | | // Licence: wxWindows licence |
9 | | /////////////////////////////////////////////////////////////////////////////// |
10 | | |
11 | | #ifndef _WX_CMDLINE_H_ |
12 | | #define _WX_CMDLINE_H_ |
13 | | |
14 | | #include "wx/defs.h" |
15 | | |
16 | | #include "wx/string.h" |
17 | | #include "wx/arrstr.h" |
18 | | #include "wx/cmdargs.h" |
19 | | |
20 | | // determines ConvertStringToArgs() behaviour |
21 | | enum wxCmdLineSplitType |
22 | | { |
23 | | wxCMD_LINE_SPLIT_DOS, |
24 | | wxCMD_LINE_SPLIT_UNIX |
25 | | }; |
26 | | |
27 | | #if wxUSE_CMDLINE_PARSER |
28 | | |
29 | | class WXDLLIMPEXP_FWD_BASE wxCmdLineParser; |
30 | | class WXDLLIMPEXP_FWD_BASE wxDateTime; |
31 | | |
32 | | // ---------------------------------------------------------------------------- |
33 | | // constants |
34 | | // ---------------------------------------------------------------------------- |
35 | | |
36 | | // by default, options are optional (sic) and each call to AddParam() allows |
37 | | // one more parameter - this may be changed by giving non-default flags to it |
38 | | enum wxCmdLineEntryFlags |
39 | | { |
40 | | wxCMD_LINE_OPTION_MANDATORY = 0x01, // this option must be given |
41 | | wxCMD_LINE_PARAM_OPTIONAL = 0x02, // the parameter may be omitted |
42 | | wxCMD_LINE_PARAM_MULTIPLE = 0x04, // the parameter may be repeated |
43 | | wxCMD_LINE_OPTION_HELP = 0x08, // this option is a help request |
44 | | wxCMD_LINE_NEEDS_SEPARATOR = 0x10, // must have sep before the value |
45 | | wxCMD_LINE_SWITCH_NEGATABLE = 0x20, // this switch can be negated (e.g. /S-) |
46 | | wxCMD_LINE_HIDDEN = 0x40 // this switch is not listed by Usage() |
47 | | }; |
48 | | |
49 | | // an option value or parameter may be a string (the most common case), a |
50 | | // number or a date |
51 | | enum wxCmdLineParamType |
52 | | { |
53 | | wxCMD_LINE_VAL_STRING, // should be 0 (default) |
54 | | wxCMD_LINE_VAL_NUMBER, |
55 | | wxCMD_LINE_VAL_DATE, |
56 | | wxCMD_LINE_VAL_DOUBLE, |
57 | | wxCMD_LINE_VAL_NONE |
58 | | }; |
59 | | |
60 | | // for constructing the cmd line description using Init() |
61 | | enum wxCmdLineEntryType |
62 | | { |
63 | | wxCMD_LINE_SWITCH, |
64 | | wxCMD_LINE_OPTION, |
65 | | wxCMD_LINE_PARAM, |
66 | | wxCMD_LINE_USAGE_TEXT, |
67 | | wxCMD_LINE_NONE // to terminate the list |
68 | | }; |
69 | | |
70 | | // Possible return values of wxCmdLineParser::FoundSwitch() |
71 | | enum wxCmdLineSwitchState |
72 | | { |
73 | | wxCMD_SWITCH_OFF = -1, // Found but turned off/negated. |
74 | | wxCMD_SWITCH_NOT_FOUND, // Not found at all. |
75 | | wxCMD_SWITCH_ON // Found in normal state. |
76 | | }; |
77 | | |
78 | | // Constants determining how (and if) to wrap the usage message |
79 | | constexpr int wxCMD_LINE_WRAP_AUTO = -1; |
80 | | constexpr int wxCMD_LINE_WRAP_NONE = 0; |
81 | | |
82 | | // ---------------------------------------------------------------------------- |
83 | | // wxCmdLineEntryDesc is a description of one command line |
84 | | // switch/option/parameter |
85 | | // ---------------------------------------------------------------------------- |
86 | | |
87 | | struct wxCmdLineEntryDesc |
88 | | { |
89 | | wxCmdLineEntryType kind; |
90 | | const char *shortName; |
91 | | const char *longName; |
92 | | const char *description; |
93 | | wxCmdLineParamType type; |
94 | | int flags; |
95 | | }; |
96 | | |
97 | | // the list of wxCmdLineEntryDesc objects should be terminated with this one |
98 | | #define wxCMD_LINE_DESC_END \ |
99 | 0 | { wxCMD_LINE_NONE, nullptr, nullptr, nullptr, wxCMD_LINE_VAL_NONE, 0x0 } |
100 | | |
101 | | // ---------------------------------------------------------------------------- |
102 | | // wxCmdLineArg contains the value for one command line argument |
103 | | // ---------------------------------------------------------------------------- |
104 | | |
105 | | class WXDLLIMPEXP_BASE wxCmdLineArg |
106 | | { |
107 | | public: |
108 | 0 | virtual ~wxCmdLineArg() = default; |
109 | | |
110 | | virtual double GetDoubleVal() const = 0; |
111 | | virtual long GetLongVal() const = 0; |
112 | | virtual const wxString& GetStrVal() const = 0; |
113 | | #if wxUSE_DATETIME |
114 | | virtual const wxDateTime& GetDateVal() const = 0; |
115 | | #endif // wxUSE_DATETIME |
116 | | |
117 | | virtual bool IsNegated() const = 0; |
118 | | |
119 | | virtual wxCmdLineEntryType GetKind() const = 0; |
120 | | virtual wxString GetShortName() const = 0; |
121 | | virtual wxString GetLongName() const = 0; |
122 | | virtual wxCmdLineParamType GetType() const = 0; |
123 | | }; |
124 | | |
125 | | // ---------------------------------------------------------------------------- |
126 | | // wxCmdLineArgs is a container of command line arguments actually parsed and |
127 | | // allows enumerating them using the standard iterator-based approach. |
128 | | // ---------------------------------------------------------------------------- |
129 | | |
130 | | class WXDLLIMPEXP_BASE wxCmdLineArgs |
131 | | { |
132 | | public: |
133 | | class WXDLLIMPEXP_BASE const_iterator |
134 | | { |
135 | | public: |
136 | | typedef int difference_type; |
137 | | typedef wxCmdLineArg value_type; |
138 | | typedef const wxCmdLineArg* pointer; |
139 | | typedef const wxCmdLineArg& reference; |
140 | | typedef std::bidirectional_iterator_tag iterator_category; |
141 | | |
142 | 0 | const_iterator() : m_parser(nullptr), m_index(0) {} |
143 | | reference operator *() const; |
144 | | pointer operator ->() const; |
145 | | const_iterator &operator ++ (); |
146 | | const_iterator operator ++ (int); |
147 | | const_iterator &operator -- (); |
148 | | const_iterator operator -- (int); |
149 | | |
150 | 0 | bool operator == (const const_iterator &other) const { |
151 | 0 | return m_parser==other.m_parser && m_index==other.m_index; |
152 | 0 | } |
153 | 0 | bool operator != (const const_iterator &other) const { |
154 | 0 | return !operator==(other); |
155 | 0 | } |
156 | | |
157 | | private: |
158 | | const_iterator (const wxCmdLineParser& parser, size_t index) |
159 | 0 | : m_parser(&parser), m_index(index) { |
160 | 0 | } |
161 | | |
162 | | const wxCmdLineParser* m_parser; |
163 | | size_t m_index; |
164 | | |
165 | | friend class wxCmdLineArgs; |
166 | | }; |
167 | | |
168 | 0 | wxCmdLineArgs (const wxCmdLineParser& parser) : m_parser(parser) {} |
169 | | |
170 | 0 | const_iterator begin() const { return const_iterator(m_parser, 0); } |
171 | 0 | const_iterator end() const { return const_iterator(m_parser, size()); } |
172 | | |
173 | | size_t size() const; |
174 | | |
175 | | private: |
176 | | const wxCmdLineParser& m_parser; |
177 | | wxDECLARE_NO_ASSIGN_DEF_COPY(wxCmdLineArgs); |
178 | | }; |
179 | | |
180 | | // ---------------------------------------------------------------------------- |
181 | | // wxCmdLineParser is a class for parsing command line. |
182 | | // |
183 | | // It has the following features: |
184 | | // |
185 | | // 1. distinguishes options, switches and parameters; allows option grouping |
186 | | // 2. allows both short and long options |
187 | | // 3. automatically generates the usage message from the cmd line description |
188 | | // 4. does type checks on the options values (number, date, ...) |
189 | | // |
190 | | // To use it you should: |
191 | | // |
192 | | // 1. construct it giving it the cmd line to parse and optionally its desc |
193 | | // 2. construct the cmd line description using AddXXX() if not done in (1) |
194 | | // 3. call Parse() |
195 | | // 4. use GetXXX() to retrieve the parsed info |
196 | | // ---------------------------------------------------------------------------- |
197 | | |
198 | | class WXDLLIMPEXP_BASE wxCmdLineParser |
199 | | { |
200 | | public: |
201 | | // ctors and initializers |
202 | | // ---------------------- |
203 | | |
204 | | // default ctor or ctor giving the cmd line in either Unix or Win form |
205 | 0 | wxCmdLineParser() { Init(); } |
206 | 0 | wxCmdLineParser(int argc, char **argv) { Init(); SetCmdLine(argc, argv); } |
207 | 0 | wxCmdLineParser(int argc, wxChar **argv) { Init(); SetCmdLine(argc, argv); } |
208 | | wxCmdLineParser(int argc, const wxCmdLineArgsArray& argv) |
209 | 0 | { Init(); SetCmdLine(argc, argv); } |
210 | 0 | wxCmdLineParser(const wxString& cmdline) { Init(); SetCmdLine(cmdline); } |
211 | | |
212 | | // the same as above, but also gives the cmd line description - otherwise, |
213 | | // use AddXXX() later |
214 | | wxCmdLineParser(const wxCmdLineEntryDesc *desc) |
215 | 0 | { Init(); SetDesc(desc); } |
216 | | wxCmdLineParser(const wxCmdLineEntryDesc *desc, int argc, char **argv) |
217 | 0 | { Init(); SetCmdLine(argc, argv); SetDesc(desc); } |
218 | | wxCmdLineParser(const wxCmdLineEntryDesc *desc, int argc, wxChar **argv) |
219 | 0 | { Init(); SetCmdLine(argc, argv); SetDesc(desc); } |
220 | | wxCmdLineParser(const wxCmdLineEntryDesc *desc, |
221 | | int argc, |
222 | | const wxCmdLineArgsArray& argv) |
223 | 0 | { Init(); SetCmdLine(argc, argv); SetDesc(desc); } |
224 | | wxCmdLineParser(const wxCmdLineEntryDesc *desc, const wxString& cmdline) |
225 | 0 | { Init(); SetCmdLine(cmdline); SetDesc(desc); } |
226 | | |
227 | | // set cmd line to parse after using one of the ctors which don't do it |
228 | | void SetCmdLine(int argc, char **argv); |
229 | | void SetCmdLine(int argc, wxChar **argv); |
230 | | void SetCmdLine(int argc, const wxCmdLineArgsArray& argv); |
231 | | void SetCmdLine(const wxString& cmdline); |
232 | | |
233 | | // not virtual, don't use this class polymorphically |
234 | | ~wxCmdLineParser(); |
235 | | |
236 | | // set different parser options |
237 | | // ---------------------------- |
238 | | |
239 | | // by default, '-' is switch char under Unix, '-' or '/' under Win: |
240 | | // switchChars contains all characters with which an option or switch may |
241 | | // start |
242 | | void SetSwitchChars(const wxString& switchChars); |
243 | | |
244 | | // long options are not POSIX-compliant, this option allows to disable them |
245 | | void EnableLongOptions(bool enable = true); |
246 | 0 | void DisableLongOptions() { EnableLongOptions(false); } |
247 | | |
248 | | bool AreLongOptionsEnabled() const; |
249 | | |
250 | | // extra text may be shown by Usage() method if set by this function |
251 | | void SetLogo(const wxString& logo); |
252 | | |
253 | | // set the brief usage string instead of constructing it automatically |
254 | | void SetUsageSynopsis(const wxString& synopsis); |
255 | | |
256 | | // construct the cmd line description |
257 | | // ---------------------------------- |
258 | | |
259 | | // take the cmd line description from the wxCMD_LINE_NONE terminated table |
260 | | void SetDesc(const wxCmdLineEntryDesc *desc); |
261 | | |
262 | | // a switch: i.e. an option without value |
263 | | void AddSwitch(const wxString& name, const wxString& lng = wxEmptyString, |
264 | | const wxString& desc = wxEmptyString, |
265 | | int flags = 0); |
266 | | void AddLongSwitch(const wxString& lng, |
267 | | const wxString& desc = wxEmptyString, |
268 | | int flags = 0) |
269 | 0 | { |
270 | 0 | AddSwitch(wxString(), lng, desc, flags); |
271 | 0 | } |
272 | | |
273 | | // an option taking a value of the given type |
274 | | void AddOption(const wxString& name, const wxString& lng = wxEmptyString, |
275 | | const wxString& desc = wxEmptyString, |
276 | | wxCmdLineParamType type = wxCMD_LINE_VAL_STRING, |
277 | | int flags = 0); |
278 | | void AddLongOption(const wxString& lng, |
279 | | const wxString& desc = wxEmptyString, |
280 | | wxCmdLineParamType type = wxCMD_LINE_VAL_STRING, |
281 | | int flags = 0) |
282 | 0 | { |
283 | 0 | AddOption(wxString(), lng, desc, type, flags); |
284 | 0 | } |
285 | | |
286 | | // a parameter |
287 | | void AddParam(const wxString& desc = wxEmptyString, |
288 | | wxCmdLineParamType type = wxCMD_LINE_VAL_STRING, |
289 | | int flags = 0); |
290 | | |
291 | | // add an explanatory text to be shown to the user in help |
292 | | void AddUsageText(const wxString& text); |
293 | | |
294 | | // actions |
295 | | // ------- |
296 | | |
297 | | // parse the command line, return 0 if ok, -1 if "-h" or "--help" option |
298 | | // was encountered and the help message was given or a positive value if a |
299 | | // syntax error occurred |
300 | | // |
301 | | // if showUsage is true, Usage() is called in case of syntax error or if |
302 | | // help was requested and if wrapColumn is not 0, the usage message is |
303 | | // wrapped at the specified column, which will be the terminal width for |
304 | | // its default value |
305 | | int Parse(bool showUsage = true, int wrapColumn = wxCMD_LINE_WRAP_AUTO); |
306 | | |
307 | | // give the usage message describing all program options |
308 | | void Usage(int wrapColumn = wxCMD_LINE_WRAP_AUTO) const; |
309 | | |
310 | | // return the usage string, call Usage() to directly show it to the user |
311 | | wxString GetUsageString(int wrapColumn = wxCMD_LINE_WRAP_AUTO) const; |
312 | | |
313 | | // get the command line arguments |
314 | | // ------------------------------ |
315 | | |
316 | | // returns true if the given switch was found |
317 | | bool Found(const wxString& name) const; |
318 | | |
319 | | // Returns wxCMD_SWITCH_NOT_FOUND if the switch was not found at all, |
320 | | // wxCMD_SWITCH_ON if it was found in normal state and wxCMD_SWITCH_OFF if |
321 | | // it was found but negated (i.e. followed by "-", this can only happen for |
322 | | // the switches with wxCMD_LINE_SWITCH_NEGATABLE flag). |
323 | | wxCmdLineSwitchState FoundSwitch(const wxString& name) const; |
324 | | |
325 | | // returns true if an option taking a string value was found and stores the |
326 | | // value in the provided pointer |
327 | | bool Found(const wxString& name, wxString *value) const; |
328 | | |
329 | | // returns true if an option taking an integer value was found and stores |
330 | | // the value in the provided pointer |
331 | | bool Found(const wxString& name, long *value) const; |
332 | | |
333 | | // returns true if an option taking a double value was found and stores |
334 | | // the value in the provided pointer |
335 | | bool Found(const wxString& name, double *value) const; |
336 | | |
337 | | #if wxUSE_DATETIME |
338 | | // returns true if an option taking a date value was found and stores the |
339 | | // value in the provided pointer |
340 | | bool Found(const wxString& name, wxDateTime *value) const; |
341 | | #endif // wxUSE_DATETIME |
342 | | |
343 | | // gets the number of parameters found |
344 | | size_t GetParamCount() const; |
345 | | |
346 | | // gets the value of Nth parameter (as string only for now) |
347 | | wxString GetParam(size_t n = 0u) const; |
348 | | |
349 | | // returns a reference to the container of all command line arguments |
350 | 0 | wxCmdLineArgs GetArguments() const { return wxCmdLineArgs(*this); } |
351 | | |
352 | | // Resets switches and options |
353 | | void Reset(); |
354 | | |
355 | | // break down the command line in arguments |
356 | | static wxArrayString |
357 | | ConvertStringToArgs(const wxString& cmdline, |
358 | | wxCmdLineSplitType type = wxCMD_LINE_SPLIT_DOS); |
359 | | |
360 | | private: |
361 | | // common part of all ctors |
362 | | void Init(); |
363 | | |
364 | | struct wxCmdLineParserData *m_data; |
365 | | |
366 | | friend class wxCmdLineArgs; |
367 | | friend class wxCmdLineArgs::const_iterator; |
368 | | wxDECLARE_NO_COPY_CLASS(wxCmdLineParser); |
369 | | }; |
370 | | |
371 | | #else // !wxUSE_CMDLINE_PARSER |
372 | | |
373 | | // this function is always available (even if !wxUSE_CMDLINE_PARSER) because it |
374 | | // is used by wxWin itself under Windows |
375 | | class WXDLLIMPEXP_BASE wxCmdLineParser |
376 | | { |
377 | | public: |
378 | | static wxArrayString |
379 | | ConvertStringToArgs(const wxString& cmdline, |
380 | | wxCmdLineSplitType type = wxCMD_LINE_SPLIT_DOS); |
381 | | }; |
382 | | |
383 | | #endif // wxUSE_CMDLINE_PARSER/!wxUSE_CMDLINE_PARSER |
384 | | |
385 | | #endif // _WX_CMDLINE_H_ |