/src/dcmtk/ofstd/libsrc/ofcmdln.cc
Line | Count | Source |
1 | | /* |
2 | | * |
3 | | * Copyright (C) 1998-2024, OFFIS e.V. |
4 | | * All rights reserved. See COPYRIGHT file for details. |
5 | | * |
6 | | * This software and supporting documentation were developed by |
7 | | * |
8 | | * OFFIS e.V. |
9 | | * R&D Division Health |
10 | | * Escherweg 2 |
11 | | * D-26121 Oldenburg, Germany |
12 | | * |
13 | | * |
14 | | * Module: ofstd |
15 | | * |
16 | | * Author: Joerg Riesmeier |
17 | | * |
18 | | * Purpose: Handle command line arguments (Source) |
19 | | * |
20 | | */ |
21 | | |
22 | | |
23 | | #include "dcmtk/config/osconfig.h" |
24 | | |
25 | | #include "dcmtk/ofstd/ofcmdln.h" |
26 | | #include "dcmtk/ofstd/ofstd.h" |
27 | | #include "dcmtk/ofstd/ofcast.h" |
28 | | #include "dcmtk/ofstd/ofchrenc.h" |
29 | | |
30 | | #if defined(HAVE_WINDOWS_H) && !defined(__MINGW32__) |
31 | | #define WIN32_LEAN_AND_MEAN |
32 | | #include <windows.h> |
33 | | #endif |
34 | | |
35 | | /*---------------------* |
36 | | * macro definitions * |
37 | | *---------------------*/ |
38 | | |
39 | 0 | #define COMMAND_FILE_PREFIX '@' |
40 | | |
41 | | #ifdef DCMTK_USE_WCHAR_T |
42 | | #define WIDE_COMMAND_FILE_PREFIX L'@' |
43 | | #endif |
44 | | |
45 | | |
46 | | /*----------------------------* |
47 | | * constant initializations * |
48 | | *----------------------------*/ |
49 | | |
50 | | const int OFCommandLine::PF_ExpandWildcards = 0x0001; // not used anymore |
51 | | const int OFCommandLine::PF_NoCommandFiles = 0x0002; |
52 | | |
53 | | const int OFCommandLine::AF_Exclusive = 0x0001; |
54 | | const int OFCommandLine::AF_Internal = 0x0002; |
55 | | const int OFCommandLine::AF_NoWarning = 0x0004; |
56 | | |
57 | | /*-----------------------* |
58 | | * struct declarations * |
59 | | *-----------------------*/ |
60 | | |
61 | | /* Internal structure to store valid command line options. |
62 | | * Options are command line arguments to use optional functions and to specify optional properties of a program. |
63 | | * They are all starting with one or more special characters and can therefore be detected. |
64 | | */ |
65 | | struct OFCmdOption |
66 | | { |
67 | | |
68 | | /** constructor |
69 | | * |
70 | | ** @param longOpt long option name |
71 | | * @param shortOpt short option name |
72 | | * @param valueCount number of additional values |
73 | | * @param valueDescr description of optional values |
74 | | * @param optDescr description of command line option |
75 | | * @param flags flags (see AF_xxx) |
76 | | */ |
77 | | OFCmdOption(const char *longOpt, |
78 | | const char *shortOpt, |
79 | | const int valueCount, |
80 | | const char *valueDescr, |
81 | | const char *optDescr, |
82 | | const int flags) |
83 | 0 | : LongOption(longOpt), |
84 | 0 | ShortOption(shortOpt), |
85 | 0 | ValueCount(valueCount), |
86 | 0 | ValueDescription(valueDescr), |
87 | 0 | OptionDescription(optDescr), |
88 | 0 | Flags(flags), |
89 | 0 | Checked(OFFalse) |
90 | 0 | { |
91 | 0 | } |
92 | | |
93 | | /** destructor |
94 | | */ |
95 | | ~OFCmdOption() |
96 | 0 | { |
97 | | #ifdef DEBUG |
98 | | if (!Checked && !(Flags & (OFCommandLine::AF_Exclusive | OFCommandLine::AF_NoWarning)) && !LongOption.empty()) |
99 | | { |
100 | | ofConsole.lockCerr() << "WARNING: option " << LongOption << " has possibly never been checked !" << OFendl; |
101 | | ofConsole.unlockCerr(); |
102 | | } |
103 | | #endif |
104 | 0 | } |
105 | | |
106 | | /// long option name |
107 | | const OFString LongOption; |
108 | | /// short option name |
109 | | const OFString ShortOption; |
110 | | /// number of additional values |
111 | | const int ValueCount; |
112 | | /// description of optional values |
113 | | const OFString ValueDescription; |
114 | | /// description of command line option |
115 | | const OFString OptionDescription; |
116 | | /// flags (see AF_xxx) |
117 | | const int Flags; |
118 | | /// OFTrue if findOption has been applied to this option |
119 | | OFBool Checked; |
120 | | |
121 | | private: |
122 | | |
123 | | /// private undefined copy assignment operator |
124 | | OFCmdOption& operator=(const OFCmdOption& arg); |
125 | | }; |
126 | | |
127 | | |
128 | | /* Internal structure to handle position of command line parameters. |
129 | | * Parameters are all command line arguments which are no options (e.g. file names). |
130 | | */ |
131 | | struct OFCmdParamPos |
132 | | { |
133 | | |
134 | | /** constructor |
135 | | * |
136 | | ** @param parIter iterator pointing to a specific parameter |
137 | | * @param optIter iterator pointing to first option iterator in front of the parameter |
138 | | * @param optCount number of options in front of the parameter |
139 | | * @param directOpt number of options which are direct predecessor in the argument list |
140 | | */ |
141 | | OFCmdParamPos(const OFListIterator(OFString) &parIter, |
142 | | const OFListIterator(OFListIterator_OFString) &optIter, |
143 | | const int optCount, |
144 | | const int directOpt) |
145 | 0 | : ParamIter(parIter), |
146 | 0 | OptionIter(optIter), |
147 | 0 | OptionCount(optCount), |
148 | 0 | DirectOption(directOpt) |
149 | 0 | { |
150 | 0 | } |
151 | | |
152 | | /// iterator pointing to a specific parameter |
153 | | const OFListIterator(OFString) ParamIter; |
154 | | /// iterator pointing to first option iterator in front of the parameter |
155 | | const OFListIterator(OFListIterator_OFString) OptionIter; |
156 | | /// number of options in front of the parameter |
157 | | const int OptionCount; |
158 | | /// number of options which are direct predecessor in the argument list |
159 | | const int DirectOption; |
160 | | |
161 | | private: |
162 | | |
163 | | /// private undefined copy assignment operator |
164 | | OFCmdParamPos& operator=(const OFCmdParamPos& arg); |
165 | | }; |
166 | | |
167 | | |
168 | | /*------------------* |
169 | | * implementation * |
170 | | *------------------*/ |
171 | | |
172 | | OFCommandLine::OFCommandLine() |
173 | 0 | : ProgramName(), |
174 | 0 | ValidOptionList(), |
175 | 0 | ValidParamList(), |
176 | 0 | ArgumentList(), |
177 | 0 | ArgumentIterator(), |
178 | 0 | ParamPosList(), |
179 | 0 | ParamPosNumber(0), |
180 | 0 | ParamPosIterator(), |
181 | 0 | OptionPosList(), |
182 | 0 | OptionPosIterator(), |
183 | 0 | OptionBlockIterator(), |
184 | 0 | OptionBlockMode(OFFalse), |
185 | 0 | OptionChars("+-"), |
186 | 0 | ExclusiveOption(OFFalse), |
187 | 0 | WideCharMode(OFFalse), |
188 | 0 | LongColumn(0), |
189 | 0 | ShortColumn(0), |
190 | 0 | ParamColumn(0), |
191 | 0 | MinParamCount(0), |
192 | 0 | MaxParamCount(0), |
193 | 0 | LastParamMode(OFCmdParam::PM_Mandatory) |
194 | 0 | { |
195 | 0 | } |
196 | | |
197 | | |
198 | | OFCommandLine::~OFCommandLine() |
199 | 0 | { |
200 | 0 | OFListIterator(OFCmdOption *) first_o = ValidOptionList.begin(); |
201 | 0 | const OFListIterator(OFCmdOption *) last_o = ValidOptionList.end(); |
202 | 0 | while (first_o != last_o) |
203 | 0 | { |
204 | | /* avoid wrong warning message */ |
205 | 0 | if (ExclusiveOption) |
206 | 0 | (*first_o)->Checked = OFTrue; |
207 | | /* delete object and remove from list */ |
208 | 0 | delete (*first_o); |
209 | 0 | first_o = ValidOptionList.erase(first_o); |
210 | 0 | } |
211 | 0 | OFListIterator(OFCmdParam *) first_p = ValidParamList.begin(); |
212 | 0 | const OFListIterator(OFCmdParam *) last_p = ValidParamList.end(); |
213 | 0 | while (first_p != last_p) |
214 | 0 | { |
215 | 0 | delete (*first_p); |
216 | 0 | first_p = ValidParamList.erase(first_p); |
217 | 0 | } |
218 | 0 | OFListIterator(OFCmdParamPos *) first_pp = ParamPosList.begin(); |
219 | 0 | const OFListIterator(OFCmdParamPos *) last_pp = ParamPosList.end(); |
220 | 0 | while (first_pp != last_pp) |
221 | 0 | { |
222 | 0 | delete (*first_pp); |
223 | 0 | first_pp = ParamPosList.erase(first_pp); |
224 | 0 | } |
225 | 0 | } |
226 | | |
227 | | |
228 | | void OFCommandLine::setOptionChars(const char *chars) |
229 | 0 | { |
230 | 0 | OptionChars = chars; |
231 | 0 | } |
232 | | |
233 | | |
234 | | void OFCommandLine::setOptionColumns(const int longCols, |
235 | | const int shortCols) |
236 | 0 | { |
237 | 0 | LongColumn = longCols; |
238 | 0 | ShortColumn = shortCols; |
239 | 0 | } |
240 | | |
241 | | |
242 | | void OFCommandLine::setParamColumn(const int column) |
243 | 0 | { |
244 | 0 | ParamColumn = column; |
245 | 0 | } |
246 | | |
247 | | |
248 | | OFBool OFCommandLine::checkOption(const OFString &option, |
249 | | const OFBool mode) const |
250 | 0 | { |
251 | 0 | OFBool result = mode; |
252 | 0 | const size_t optionLen = option.length(); |
253 | 0 | if (optionLen > 0) // empty strings are allowed to support (sub)groups |
254 | 0 | { |
255 | 0 | result = OFFalse; |
256 | 0 | if (optionLen >= 2) |
257 | 0 | { |
258 | 0 | if (OptionChars.find(option.at(0)) != OFString_npos) // options have to start with one of the defined chars |
259 | 0 | { |
260 | 0 | if (((option.at(0) != '-') && (option.at(0) != '+')) || // but when starting with sign character ... |
261 | 0 | (option.at(1) < '0') || (option.at(1) > '9')) // ... don't allow a number as the following character |
262 | 0 | { |
263 | 0 | result = OFTrue; |
264 | 0 | } |
265 | 0 | } |
266 | 0 | } |
267 | 0 | } |
268 | 0 | return result; |
269 | 0 | } |
270 | | |
271 | | void OFCommandLine::addGeneralOptions(const int longCols, |
272 | | const int shortCols) |
273 | 0 | { |
274 | 0 | addGroup("general options:", longCols, shortCols + 2); |
275 | 0 | addOption("--help", "-h", "print this help text and exit", OFCommandLine::AF_Exclusive); |
276 | 0 | addOption("--version", "print version information and exit", OFCommandLine::AF_Exclusive); |
277 | 0 | } |
278 | | |
279 | | OFBool OFCommandLine::addOption(const char *longOpt, |
280 | | const char *shortOpt, |
281 | | const int valueCount, |
282 | | const char *valueDescr, |
283 | | const char *optDescr, |
284 | | const int flags) |
285 | 0 | { |
286 | 0 | if (checkOption(longOpt) && checkOption(shortOpt)) |
287 | 0 | { |
288 | | #ifdef DEBUG |
289 | | if (strlen(longOpt) > 0) |
290 | | { |
291 | | OFListIterator(OFCmdOption *) iter = ValidOptionList.begin(); |
292 | | const OFListIterator(OFCmdOption *) last = ValidOptionList.end(); |
293 | | while (iter != last) |
294 | | { |
295 | | if ((*iter)->LongOption == longOpt) |
296 | | { |
297 | | ofConsole.lockCerr() << "WARNING: long option " << longOpt << " already defined ... not added !" << OFendl; |
298 | | ofConsole.unlockCerr(); |
299 | | return OFFalse; |
300 | | } |
301 | | if ((strlen(shortOpt) > 0) && ((*iter)->ShortOption == shortOpt)) |
302 | | { |
303 | | ofConsole.lockCerr() << "WARNING: short option " << shortOpt << " already defined for " << (*iter)->LongOption |
304 | | << " ..." << OFendl << " option " << longOpt << " not added !" << OFendl; |
305 | | ofConsole.unlockCerr(); |
306 | | return OFFalse; |
307 | | } |
308 | | ++iter; |
309 | | } |
310 | | } |
311 | | #endif |
312 | 0 | OFCmdOption *opt = new OFCmdOption(longOpt, shortOpt, valueCount, valueDescr, optDescr, flags); |
313 | 0 | if (opt != NULL) |
314 | 0 | { |
315 | 0 | ValidOptionList.push_back(opt); |
316 | 0 | return OFTrue; |
317 | 0 | } |
318 | 0 | } |
319 | | #ifdef DEBUG |
320 | | ofConsole.lockCerr() << "WARNING: invalid option " << shortOpt << "/" <<longOpt << " ... not added !" << OFendl; |
321 | | ofConsole.unlockCerr(); |
322 | | #endif |
323 | 0 | return OFFalse; |
324 | 0 | } |
325 | | |
326 | | |
327 | | OFBool OFCommandLine::addOption(const char *longOpt, |
328 | | const char *shortOpt, |
329 | | const char *optDescr, |
330 | | const int flags) |
331 | 0 | { |
332 | 0 | return addOption(longOpt, shortOpt, 0, "", optDescr, flags); |
333 | 0 | } |
334 | | |
335 | | |
336 | | OFBool OFCommandLine::addOption(const char *longOpt, |
337 | | const int valueCount, |
338 | | const char *valueDescr, |
339 | | const char *optDescr, |
340 | | const int flags) |
341 | 0 | { |
342 | 0 | return addOption(longOpt, "", valueCount, valueDescr, optDescr, flags); |
343 | 0 | } |
344 | | |
345 | | |
346 | | OFBool OFCommandLine::addOption(const char *longOpt, |
347 | | const char *optDescr, |
348 | | const int flags) |
349 | 0 | { |
350 | 0 | return addOption(longOpt, "", 0, "", optDescr, flags); |
351 | 0 | } |
352 | | |
353 | | |
354 | | void OFCommandLine::addGroup(const char *name, |
355 | | const int longCols, |
356 | | const int shortCols) |
357 | 0 | { |
358 | 0 | addOption("", "", packColumnValues(longCols, shortCols), "", name); |
359 | 0 | } |
360 | | |
361 | | |
362 | | void OFCommandLine::addSubGroup(const char *name, |
363 | | const int longCols, |
364 | | const int shortCols) |
365 | 0 | { |
366 | 0 | addOption("", "", packColumnValues(longCols, shortCols), name, ""); |
367 | 0 | } |
368 | | |
369 | | |
370 | | OFBool OFCommandLine::addParam(const char *param, |
371 | | const char *descr, |
372 | | const OFCmdParam::E_ParamMode mode) |
373 | 0 | { |
374 | 0 | if (param != NULL) |
375 | 0 | { |
376 | | #ifdef DEBUG |
377 | | switch (LastParamMode) |
378 | | { |
379 | | case OFCmdParam::PM_Optional: |
380 | | if ((mode != OFCmdParam::PM_Optional) && (mode != OFCmdParam::PM_MultiOptional)) |
381 | | { |
382 | | ofConsole.lockCerr() << "WARNING: " << ValidParamList.size() << ". parameter is optional => hides " |
383 | | << param << " !" << OFendl; |
384 | | ofConsole.unlockCerr(); |
385 | | } |
386 | | break; |
387 | | /* |
388 | | case OFCmdParam::PM_MultiMandatory: |
389 | | { |
390 | | ofConsole.lockCerr() << "WARNING: " << ValidParamList.size() << ". parameter is multi-mandatory => hides " |
391 | | << param << " !" << OFendl; |
392 | | ofConsole.unlockCerr(); |
393 | | } |
394 | | break; |
395 | | */ |
396 | | case OFCmdParam::PM_MultiOptional: |
397 | | { |
398 | | ofConsole.lockCerr() << "WARNING: " << ValidParamList.size() << ". parameter is multi-optional => hides " |
399 | | << param << " !" << OFendl; |
400 | | ofConsole.unlockCerr(); |
401 | | } |
402 | | break; |
403 | | default: |
404 | | break; |
405 | | } |
406 | | LastParamMode = mode; |
407 | | #endif |
408 | 0 | OFCmdParam *par = new OFCmdParam(param, descr, mode); |
409 | 0 | if (par != NULL) |
410 | 0 | { |
411 | 0 | ValidParamList.push_back(par); |
412 | 0 | return OFTrue; |
413 | 0 | } |
414 | 0 | } |
415 | 0 | return OFFalse; |
416 | 0 | } |
417 | | |
418 | | |
419 | | OFBool OFCommandLine::addParam(const char *param, |
420 | | const OFCmdParam::E_ParamMode mode) |
421 | 0 | { |
422 | 0 | return addParam(param, "", mode); |
423 | 0 | } |
424 | | |
425 | | |
426 | | OFBool OFCommandLine::gotoFirstArg() |
427 | 0 | { |
428 | 0 | ArgumentIterator = ArgumentList.begin(); |
429 | 0 | return ArgumentIterator != ArgumentList.end(); |
430 | 0 | } |
431 | | |
432 | | |
433 | | OFBool OFCommandLine::gotoNextArg() |
434 | 0 | { |
435 | 0 | if (ArgumentIterator != ArgumentList.end()) |
436 | 0 | return ++ArgumentIterator != ArgumentList.end(); |
437 | 0 | return OFFalse; |
438 | 0 | } |
439 | | |
440 | | |
441 | | OFBool OFCommandLine::getCurrentArg(const char *&arg) |
442 | 0 | { |
443 | 0 | if (ArgumentIterator != ArgumentList.end()) |
444 | 0 | return strlen(arg = (*ArgumentIterator).c_str()) > 0; |
445 | 0 | return OFFalse; |
446 | |
|
447 | 0 | } |
448 | | |
449 | | |
450 | | OFBool OFCommandLine::getCurrentArg(OFCmdString &arg) |
451 | 0 | { |
452 | 0 | if (ArgumentIterator != ArgumentList.end()) |
453 | 0 | return !(arg = *ArgumentIterator).empty(); |
454 | 0 | return OFFalse; |
455 | |
|
456 | 0 | } |
457 | | |
458 | | |
459 | | OFBool OFCommandLine::getLastArg(OFString &arg) |
460 | 0 | { |
461 | 0 | if (!ArgumentList.empty()) |
462 | 0 | return !(arg = ArgumentList.back()).empty(); |
463 | 0 | return OFFalse; |
464 | 0 | } |
465 | | |
466 | | |
467 | | OFBool OFCommandLine::findParam(const int pos) |
468 | 0 | { |
469 | 0 | OFListIterator(OFCmdParamPos *) iter; |
470 | 0 | return findParam(pos, iter); |
471 | 0 | } |
472 | | |
473 | | |
474 | | OFBool OFCommandLine::findParam(const int pos, |
475 | | OFListIterator(OFCmdParamPos *) &pos_iter) |
476 | 0 | { |
477 | 0 | if ((pos > 0) && (pos <= getParamCount())) |
478 | 0 | { |
479 | 0 | int counter; |
480 | 0 | if ((ParamPosNumber > 0) && (pos >= ParamPosNumber)) // can we start from previous position? |
481 | 0 | { |
482 | 0 | counter = pos - ParamPosNumber + 1; |
483 | 0 | pos_iter = ParamPosIterator; |
484 | 0 | } else { // if not, start from beginning |
485 | 0 | counter = pos; |
486 | 0 | pos_iter = ParamPosList.begin(); |
487 | 0 | } |
488 | 0 | const OFListIterator(OFCmdParamPos *) pos_last = ParamPosList.end(); |
489 | 0 | while (pos_iter != pos_last) |
490 | 0 | { |
491 | 0 | ArgumentIterator = (*pos_iter)->ParamIter; |
492 | 0 | if (--counter == 0) |
493 | 0 | { |
494 | 0 | ParamPosNumber = pos; // if found, store current position |
495 | 0 | ParamPosIterator = pos_iter; |
496 | 0 | return OFTrue; |
497 | 0 | } |
498 | 0 | ++pos_iter; |
499 | 0 | } |
500 | 0 | } |
501 | 0 | return OFFalse; |
502 | 0 | } |
503 | | |
504 | | |
505 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParam(const int pos, |
506 | | OFCmdSignedInt &value) |
507 | 0 | { |
508 | 0 | if (findParam(pos)) |
509 | 0 | { |
510 | 0 | if (sscanf((*ArgumentIterator).c_str(), "%li", &value) == 1) |
511 | 0 | return PVS_Normal; |
512 | 0 | return PVS_Invalid; |
513 | 0 | } |
514 | 0 | return PVS_CantFind; |
515 | 0 | } |
516 | | |
517 | | |
518 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParamAndCheckMin(const int pos, |
519 | | OFCmdSignedInt &value, |
520 | | const OFCmdSignedInt low, |
521 | | const OFExplicitBool incl) |
522 | 0 | { |
523 | 0 | E_ParamValueStatus status = getParam(pos, value); |
524 | 0 | if (status == PVS_Normal) |
525 | 0 | { |
526 | 0 | if ((value < low) || (!incl && (value == low))) |
527 | 0 | return PVS_Underflow; |
528 | 0 | } |
529 | 0 | return status; |
530 | 0 | } |
531 | | |
532 | | |
533 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParamAndCheckMinMax(const int pos, |
534 | | OFCmdSignedInt &value, |
535 | | const OFCmdSignedInt low, |
536 | | const OFCmdSignedInt high) |
537 | 0 | { |
538 | 0 | E_ParamValueStatus status = getParam(pos, value); |
539 | 0 | if (status == PVS_Normal) |
540 | 0 | { |
541 | 0 | if (value < low) |
542 | 0 | return PVS_Underflow; |
543 | 0 | else if (value > high) |
544 | 0 | return PVS_Overflow; |
545 | 0 | } |
546 | 0 | return status; |
547 | 0 | } |
548 | | |
549 | | |
550 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParam(const int pos, |
551 | | OFCmdUnsignedInt &value) |
552 | 0 | { |
553 | 0 | if (findParam(pos)) |
554 | 0 | { |
555 | 0 | if (sscanf((*ArgumentIterator).c_str(), "%lu", &value) == 1) |
556 | 0 | return PVS_Normal; |
557 | 0 | return PVS_Invalid; |
558 | 0 | } |
559 | 0 | return PVS_CantFind; |
560 | 0 | } |
561 | | |
562 | | |
563 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParamAndCheckMin(const int pos, |
564 | | OFCmdUnsignedInt &value, |
565 | | const OFCmdUnsignedInt low, |
566 | | const OFExplicitBool incl) |
567 | 0 | { |
568 | 0 | E_ParamValueStatus status = getParam(pos, value); |
569 | 0 | if (status == PVS_Normal) |
570 | 0 | { |
571 | 0 | if ((value < low) || (!incl && (value == low))) |
572 | 0 | return PVS_Underflow; |
573 | 0 | } |
574 | 0 | return status; |
575 | 0 | } |
576 | | |
577 | | |
578 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParamAndCheckMinMax(const int pos, |
579 | | OFCmdUnsignedInt &value, |
580 | | const OFCmdUnsignedInt low, |
581 | | const OFCmdUnsignedInt high) |
582 | 0 | { |
583 | 0 | E_ParamValueStatus status = getParam(pos, value); |
584 | 0 | if (status == PVS_Normal) |
585 | 0 | { |
586 | 0 | if (value < low) |
587 | 0 | return PVS_Underflow; |
588 | 0 | else if (value > high) |
589 | 0 | return PVS_Overflow; |
590 | 0 | } |
591 | 0 | return status; |
592 | 0 | } |
593 | | |
594 | | |
595 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParam(const int pos, |
596 | | OFCmdFloat &value) |
597 | 0 | { |
598 | 0 | if (findParam(pos)) |
599 | 0 | { |
600 | 0 | OFBool success = OFFalse; |
601 | 0 | value = OFStandard::atof((*ArgumentIterator).c_str(), &success); |
602 | 0 | if (success) return PVS_Normal; |
603 | 0 | return PVS_Invalid; |
604 | 0 | } |
605 | 0 | return PVS_CantFind; |
606 | 0 | } |
607 | | |
608 | | |
609 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParamAndCheckMin(const int pos, |
610 | | OFCmdFloat &value, |
611 | | const OFCmdFloat low, |
612 | | const OFExplicitBool incl) |
613 | 0 | { |
614 | 0 | E_ParamValueStatus status = getParam(pos, value); |
615 | 0 | if (status == PVS_Normal) |
616 | 0 | { |
617 | 0 | if ((value < low) || (!incl && (value == low))) |
618 | 0 | return PVS_Underflow; |
619 | 0 | } |
620 | 0 | return status; |
621 | 0 | } |
622 | | |
623 | | |
624 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParamAndCheckMinMax(const int pos, |
625 | | OFCmdFloat &value, |
626 | | const OFCmdFloat low, |
627 | | const OFCmdFloat high) |
628 | 0 | { |
629 | 0 | E_ParamValueStatus status = getParam(pos, value); |
630 | 0 | if (status == PVS_Normal) |
631 | 0 | { |
632 | 0 | if (value < low) |
633 | 0 | return PVS_Underflow; |
634 | 0 | else if (value > high) |
635 | 0 | return PVS_Overflow; |
636 | 0 | } |
637 | 0 | return status; |
638 | 0 | } |
639 | | |
640 | | |
641 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParam(const int pos, |
642 | | const char *&value) |
643 | 0 | { |
644 | 0 | if (findParam(pos)) |
645 | 0 | { |
646 | 0 | value = (*ArgumentIterator).c_str(); |
647 | 0 | if (strlen(value) > 0) |
648 | 0 | return PVS_Normal; |
649 | 0 | return PVS_Empty; |
650 | 0 | } |
651 | 0 | return PVS_CantFind; |
652 | 0 | } |
653 | | |
654 | | |
655 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParam(const int pos, |
656 | | OFCmdString &value) |
657 | 0 | { |
658 | 0 | if (findParam(pos)) |
659 | 0 | { |
660 | 0 | value = *ArgumentIterator; |
661 | 0 | if (!value.empty()) |
662 | 0 | return PVS_Normal; |
663 | 0 | return PVS_Empty; |
664 | 0 | } |
665 | 0 | return PVS_CantFind; |
666 | 0 | } |
667 | | |
668 | | |
669 | | OFCommandLine::E_ParamValueStatus OFCommandLine::getParam(const int pos, |
670 | | OFFilename &filename) |
671 | 0 | { |
672 | 0 | OFString value; |
673 | 0 | E_ParamValueStatus status = getParam(pos, value); |
674 | 0 | if (status != PVS_CantFind) |
675 | 0 | { |
676 | 0 | if (status != PVS_Empty) |
677 | 0 | filename.set(value, WideCharMode /* convert */); |
678 | 0 | else |
679 | 0 | filename.clear(); |
680 | 0 | } |
681 | 0 | return status; |
682 | 0 | } |
683 | | |
684 | | |
685 | | OFBool OFCommandLine::findOption(const char *longOpt, |
686 | | const signed int pos, |
687 | | const E_FindOptionMode mode) |
688 | 0 | { |
689 | | #ifdef DEBUG |
690 | | OFListIterator(OFCmdOption *) iter = ValidOptionList.begin(); |
691 | | const OFListIterator(OFCmdOption *) last = ValidOptionList.end(); |
692 | | while (iter != last) |
693 | | { |
694 | | if ((*iter)->LongOption == longOpt) |
695 | | { |
696 | | (*iter)->Checked = OFTrue; |
697 | | break; |
698 | | } |
699 | | ++iter; |
700 | | } |
701 | | if (iter == last) |
702 | | { |
703 | | ofConsole.lockCerr() << "WARNING: unknown option " << longOpt << " in OFCommandLine::findOption() !" << OFendl; |
704 | | ofConsole.unlockCerr(); |
705 | | return OFFalse; |
706 | | } |
707 | | #endif |
708 | | // reverse direction (left to right) |
709 | 0 | if ((mode == FOM_FirstFromLeft) || (mode == FOM_NextFromLeft)) |
710 | 0 | { |
711 | | #ifdef DEBUG |
712 | | if (pos != 0) |
713 | | { |
714 | | ofConsole.lockCerr() << "WARNING: OFCommandLine::findOption() parameter 'pos' (" << pos << ") ignored !" << OFendl; |
715 | | ofConsole.unlockCerr(); |
716 | | } |
717 | | #endif |
718 | 0 | OFListIterator(OFListIterator_OFString) pos_iter = OptionPosList.begin(); |
719 | 0 | const OFListIterator(OFListIterator_OFString) pos_end = OptionPosList.end(); |
720 | 0 | if (mode == FOM_NextFromLeft) |
721 | 0 | pos_iter = (OptionPosIterator == pos_end) ? pos_end : ++OptionPosIterator; |
722 | 0 | while (pos_iter != pos_end) |
723 | 0 | { |
724 | 0 | ArgumentIterator = *pos_iter; |
725 | 0 | if (*ArgumentIterator == longOpt) // searched option |
726 | 0 | { |
727 | 0 | OptionPosIterator = pos_iter; // store option position |
728 | 0 | return OFTrue; |
729 | 0 | } |
730 | 0 | pos_iter++; |
731 | 0 | } |
732 | 0 | } else { |
733 | | // normal direction (right to left) |
734 | 0 | OFListIterator(OFListIterator_OFString) pos_iter = (mode == FOM_Next) ? OptionPosIterator : OptionPosList.end(); |
735 | 0 | const OFListIterator(OFListIterator_OFString) pos_first = OptionPosList.begin(); |
736 | 0 | OFListIterator(OFCmdParamPos *) param_iter; |
737 | 0 | int diropt = 0; |
738 | 0 | if (findParam(abs(pos), param_iter)) // go to specified parameter position |
739 | 0 | { |
740 | 0 | diropt = (*param_iter)->DirectOption; // number of direct predecessors |
741 | 0 | if (((*param_iter)->OptionCount == 0) || // no options in front of specified parameter or |
742 | 0 | ((pos < 0) && (diropt == 0))) // no 'direct' option ... |
743 | 0 | return OFFalse; |
744 | 0 | pos_iter = (*param_iter)->OptionIter; // first option in front of parameter |
745 | 0 | ++pos_iter; // goto next to facilitate loop condition |
746 | 0 | } |
747 | 0 | while (pos_iter != pos_first) |
748 | 0 | { |
749 | 0 | ArgumentIterator = *(--pos_iter); |
750 | 0 | if (OptionBlockMode && (pos_iter == OptionBlockIterator)) // new option is in front of alternative block option |
751 | 0 | return OFFalse; |
752 | 0 | else if (*ArgumentIterator == longOpt) // searched option |
753 | 0 | { |
754 | 0 | OptionPosIterator = pos_iter; // store option position |
755 | 0 | if (mode == FOM_Normal) |
756 | 0 | OptionBlockIterator = pos_iter; |
757 | 0 | return OFTrue; |
758 | 0 | } |
759 | 0 | else if ((pos < 0) && (--diropt <= 0)) // search only for the direct predecessor |
760 | 0 | return OFFalse; |
761 | 0 | } |
762 | 0 | } |
763 | 0 | return OFFalse; |
764 | 0 | } |
765 | | |
766 | | |
767 | | OFBool OFCommandLine::gotoFirstOption() |
768 | 0 | { |
769 | 0 | OptionPosIterator = OptionPosList.begin(); |
770 | 0 | if (OptionPosIterator != OptionPosList.end()) |
771 | 0 | { |
772 | 0 | ArgumentIterator = *OptionPosIterator; |
773 | 0 | return OFTrue; |
774 | 0 | } |
775 | 0 | return OFFalse; |
776 | 0 | } |
777 | | |
778 | | |
779 | | OFBool OFCommandLine::gotoNextOption() |
780 | 0 | { |
781 | 0 | if (OptionPosIterator != OptionPosList.end()) |
782 | 0 | { |
783 | 0 | if (++OptionPosIterator != OptionPosList.end()) |
784 | 0 | { |
785 | 0 | ArgumentIterator = *OptionPosIterator; |
786 | 0 | return OFTrue; |
787 | 0 | } |
788 | 0 | } |
789 | 0 | return OFFalse; |
790 | 0 | } |
791 | | |
792 | | |
793 | | OFBool OFCommandLine::getCurrentOption(const char *&opt) |
794 | 0 | { |
795 | 0 | if (OptionPosIterator != OptionPosList.end()) |
796 | 0 | return (opt = (**OptionPosIterator).c_str())[0] != '\0'; |
797 | 0 | return OFFalse; |
798 | 0 | } |
799 | | |
800 | | |
801 | | OFBool OFCommandLine::getCurrentOption(OFCmdString &opt) |
802 | 0 | { |
803 | 0 | if (OptionPosIterator != OptionPosList.end()) |
804 | 0 | return !(opt = **OptionPosIterator).empty(); |
805 | 0 | return OFFalse; |
806 | 0 | } |
807 | | |
808 | | |
809 | | void OFCommandLine::beginOptionBlock() |
810 | 0 | { |
811 | 0 | OptionBlockIterator = OptionPosList.end(); |
812 | 0 | OptionBlockMode = OFTrue; |
813 | 0 | } |
814 | | |
815 | | |
816 | | void OFCommandLine::endOptionBlock() |
817 | 0 | { |
818 | 0 | OptionBlockMode = OFFalse; |
819 | 0 | } |
820 | | |
821 | | |
822 | | OFCommandLine::E_ValueStatus OFCommandLine::getValue(OFCmdSignedInt &value) |
823 | 0 | { |
824 | 0 | if (++ArgumentIterator != ArgumentList.end()) |
825 | 0 | { |
826 | 0 | if (sscanf((*ArgumentIterator).c_str(), "%li", &value) == 1) |
827 | 0 | return VS_Normal; |
828 | 0 | return VS_Invalid; |
829 | 0 | } |
830 | 0 | return VS_NoMore; |
831 | 0 | } |
832 | | |
833 | | |
834 | | OFCommandLine::E_ValueStatus OFCommandLine::getValueAndCheckMin(OFCmdSignedInt &value, |
835 | | const OFCmdSignedInt low, |
836 | | const OFExplicitBool incl) |
837 | 0 | { |
838 | 0 | E_ValueStatus status = getValue(value); |
839 | 0 | if (status == VS_Normal) |
840 | 0 | { |
841 | 0 | if ((value < low) || (!incl && (value == low))) |
842 | 0 | return VS_Underflow; |
843 | 0 | } |
844 | 0 | return status; |
845 | 0 | } |
846 | | |
847 | | |
848 | | OFCommandLine::E_ValueStatus OFCommandLine::getValueAndCheckMinMax(OFCmdSignedInt &value, |
849 | | const OFCmdSignedInt low, |
850 | | const OFCmdSignedInt high) |
851 | 0 | { |
852 | 0 | E_ValueStatus status = getValue(value); |
853 | 0 | if (status == VS_Normal) |
854 | 0 | { |
855 | 0 | if (value < low) |
856 | 0 | return VS_Underflow; |
857 | 0 | else if (value > high) |
858 | 0 | return VS_Overflow; |
859 | 0 | } |
860 | 0 | return status; |
861 | 0 | } |
862 | | |
863 | | |
864 | | OFCommandLine::E_ValueStatus OFCommandLine::getValue(OFCmdUnsignedInt &value) |
865 | 0 | { |
866 | 0 | if (++ArgumentIterator != ArgumentList.end()) |
867 | 0 | { |
868 | 0 | OFString &strVal = *ArgumentIterator; |
869 | 0 | if (sscanf(strVal.c_str(), "%lu", &value) == 1) |
870 | 0 | { |
871 | | // skip leading spaces |
872 | 0 | size_t strPos = strVal.find_first_not_of(' '); |
873 | | // check for minus sign (negative number) |
874 | 0 | if ((strPos != OFString_npos) && (strVal.at(strPos) != '-')) |
875 | 0 | return VS_Normal; |
876 | 0 | } |
877 | 0 | return VS_Invalid; |
878 | 0 | } |
879 | 0 | return VS_NoMore; |
880 | 0 | } |
881 | | |
882 | | |
883 | | OFCommandLine::E_ValueStatus OFCommandLine::getValueAndCheckMin(OFCmdUnsignedInt &value, |
884 | | const OFCmdUnsignedInt low, |
885 | | const OFExplicitBool incl) |
886 | 0 | { |
887 | 0 | E_ValueStatus status = getValue(value); |
888 | 0 | if (status == VS_Normal) |
889 | 0 | { |
890 | 0 | if ((value < low) || (!incl && (value == low))) |
891 | 0 | return VS_Underflow; |
892 | 0 | } |
893 | 0 | return status; |
894 | 0 | } |
895 | | |
896 | | |
897 | | OFCommandLine::E_ValueStatus OFCommandLine::getValueAndCheckMinMax(OFCmdUnsignedInt &value, |
898 | | const OFCmdUnsignedInt low, |
899 | | const OFCmdUnsignedInt high) |
900 | 0 | { |
901 | 0 | E_ValueStatus status = getValue(value); |
902 | 0 | if (status == VS_Normal) |
903 | 0 | { |
904 | 0 | if (value < low) |
905 | 0 | return VS_Underflow; |
906 | 0 | else if (value > high) |
907 | 0 | return VS_Overflow; |
908 | 0 | } |
909 | 0 | return status; |
910 | 0 | } |
911 | | |
912 | | |
913 | | OFCommandLine::E_ValueStatus OFCommandLine::getValue(OFCmdFloat &value) |
914 | 0 | { |
915 | 0 | if (++ArgumentIterator != ArgumentList.end()) |
916 | 0 | { |
917 | 0 | OFBool success = OFFalse; |
918 | 0 | value = OFStandard::atof((*ArgumentIterator).c_str(), &success); |
919 | 0 | if (success) return VS_Normal; |
920 | 0 | return VS_Invalid; |
921 | 0 | } |
922 | 0 | return VS_NoMore; |
923 | 0 | } |
924 | | |
925 | | |
926 | | OFCommandLine::E_ValueStatus OFCommandLine::getValueAndCheckMin(OFCmdFloat &value, |
927 | | const OFCmdFloat low, |
928 | | const OFExplicitBool incl) |
929 | 0 | { |
930 | 0 | E_ValueStatus status = getValue(value); |
931 | 0 | if (status == VS_Normal) |
932 | 0 | { |
933 | 0 | if ((value < low) || (!incl && (value == low))) |
934 | 0 | return VS_Underflow; |
935 | 0 | } |
936 | 0 | return status; |
937 | 0 | } |
938 | | |
939 | | |
940 | | OFCommandLine::E_ValueStatus OFCommandLine::getValueAndCheckMinMax(OFCmdFloat &value, |
941 | | const OFCmdFloat low, |
942 | | const OFCmdFloat high) |
943 | 0 | { |
944 | 0 | E_ValueStatus status = getValue(value); |
945 | 0 | if (status == VS_Normal) |
946 | 0 | { |
947 | 0 | if (value < low) |
948 | 0 | return VS_Underflow; |
949 | 0 | else if (value > high) |
950 | 0 | return VS_Overflow; |
951 | 0 | } |
952 | 0 | return status; |
953 | 0 | } |
954 | | |
955 | | |
956 | | OFCommandLine::E_ValueStatus OFCommandLine::getValue(const char *&value) |
957 | 0 | { |
958 | 0 | if (++ArgumentIterator != ArgumentList.end()) |
959 | 0 | { |
960 | 0 | value = (*ArgumentIterator).c_str(); |
961 | 0 | if (strlen(value) > 0) |
962 | 0 | return VS_Normal; |
963 | 0 | return VS_Empty; |
964 | 0 | } |
965 | 0 | return VS_NoMore; |
966 | 0 | } |
967 | | |
968 | | |
969 | | OFCommandLine::E_ValueStatus OFCommandLine::getValue(OFCmdString &value) |
970 | 0 | { |
971 | 0 | if (++ArgumentIterator != ArgumentList.end()) |
972 | 0 | { |
973 | 0 | value = *ArgumentIterator; |
974 | 0 | if (!value.empty()) |
975 | 0 | return VS_Normal; |
976 | 0 | return VS_Empty; |
977 | 0 | } |
978 | 0 | return VS_NoMore; |
979 | 0 | } |
980 | | |
981 | | |
982 | | OFCommandLine::E_ValueStatus OFCommandLine::getValue(OFFilename &filename) |
983 | 0 | { |
984 | 0 | if (++ArgumentIterator != ArgumentList.end()) |
985 | 0 | { |
986 | 0 | OFString strValue = *ArgumentIterator; |
987 | 0 | if (!strValue.empty()) |
988 | 0 | { |
989 | 0 | filename.set(strValue, WideCharMode /* convert */); |
990 | 0 | return VS_Normal; |
991 | 0 | } else |
992 | 0 | filename.clear(); |
993 | 0 | return VS_Empty; |
994 | 0 | } |
995 | 0 | return VS_NoMore; |
996 | 0 | } |
997 | | |
998 | | |
999 | | const OFCmdOption *OFCommandLine::findCmdOption(const OFString &option) const |
1000 | 0 | { |
1001 | 0 | OFListConstIterator(OFCmdOption *) iter = ValidOptionList.begin(); |
1002 | 0 | OFListConstIterator(OFCmdOption *) last = ValidOptionList.end(); |
1003 | 0 | while (iter != last) |
1004 | 0 | { |
1005 | 0 | if (((*iter)->LongOption == option) || ((*iter)->ShortOption == option)) |
1006 | 0 | return *iter; |
1007 | 0 | ++iter; |
1008 | 0 | } |
1009 | 0 | return NULL; |
1010 | 0 | } |
1011 | | |
1012 | | |
1013 | | void OFCommandLine::storeParameter(const OFString ¶m, |
1014 | | const int directOpt) |
1015 | 0 | { |
1016 | 0 | ArgumentList.push_back(param); |
1017 | 0 | const OFListIterator(OFListIterator_OFString) iter = (OptionPosList.size() == 0) ? OptionPosList.end() : --OptionPosList.end(); |
1018 | 0 | OFCmdParamPos *paramPos = new OFCmdParamPos(--ArgumentList.end(), iter, OFstatic_cast(int, OptionPosList.size()), directOpt); |
1019 | 0 | if (paramPos != NULL) |
1020 | 0 | ParamPosList.push_back(paramPos); |
1021 | 0 | } |
1022 | | |
1023 | | |
1024 | | int OFCommandLine::packColumnValues(int longCols, |
1025 | | int shortCols) const |
1026 | 0 | { |
1027 | 0 | if (longCols < 0) |
1028 | 0 | longCols = 0; |
1029 | 0 | if (shortCols < 0) |
1030 | 0 | shortCols = 0; |
1031 | 0 | return ((longCols & 0xffff) << 16) | (shortCols & 0xffff); |
1032 | 0 | } |
1033 | | |
1034 | | |
1035 | | void OFCommandLine::unpackColumnValues(const int value, |
1036 | | unsigned int &longCols, |
1037 | | unsigned int &shortCols) const |
1038 | 0 | { |
1039 | 0 | longCols = (value == 0) ? LongColumn : (value >> 16) & 0xffff; |
1040 | 0 | shortCols = (value == 0) ? ShortColumn : (value & 0xffff); |
1041 | 0 | } |
1042 | | |
1043 | | |
1044 | | OFCommandLine::E_ParseStatus OFCommandLine::checkParamCount() |
1045 | 0 | { |
1046 | 0 | MinParamCount = 0; |
1047 | 0 | MaxParamCount = 0; |
1048 | 0 | OFListIterator(OFCmdParam *) iter = ValidParamList.begin(); |
1049 | 0 | const OFListIterator(OFCmdParam *) last = ValidParamList.end(); |
1050 | 0 | while (iter != last) |
1051 | 0 | { |
1052 | 0 | if (!(*iter)->ParamName.empty()) |
1053 | 0 | { |
1054 | 0 | switch ((*iter)->ParamMode) |
1055 | 0 | { |
1056 | 0 | case OFCmdParam::PM_Mandatory: |
1057 | 0 | MinParamCount++; |
1058 | 0 | if (MaxParamCount >= 0) |
1059 | 0 | MaxParamCount++; |
1060 | 0 | break; |
1061 | 0 | case OFCmdParam::PM_MultiMandatory: |
1062 | 0 | MinParamCount++; |
1063 | 0 | MaxParamCount = -1; |
1064 | 0 | break; |
1065 | 0 | case OFCmdParam::PM_Optional: |
1066 | 0 | if (MaxParamCount >= 0) |
1067 | 0 | MaxParamCount++; |
1068 | 0 | break; |
1069 | 0 | case OFCmdParam::PM_MultiOptional: |
1070 | 0 | MaxParamCount = -1; |
1071 | 0 | break; |
1072 | 0 | } |
1073 | 0 | } |
1074 | 0 | ++iter; |
1075 | 0 | } |
1076 | 0 | if (getArgCount() == 0) |
1077 | 0 | return PS_NoArguments; |
1078 | 0 | else if (hasExclusiveOption()) |
1079 | 0 | return PS_ExclusiveOption; |
1080 | 0 | else if (getParamCount() < MinParamCount) |
1081 | 0 | return PS_MissingParameter; |
1082 | 0 | else if ((MaxParamCount >= 0) && (getParamCount() > MaxParamCount)) |
1083 | 0 | return PS_TooManyParameters; |
1084 | 0 | return PS_Normal; |
1085 | 0 | } |
1086 | | |
1087 | | |
1088 | | OFCommandLine::E_ParseStatus OFCommandLine::parseCommandFile(const char *argValue, |
1089 | | OFList<OFString> &argList) |
1090 | 0 | { |
1091 | 0 | E_ParseStatus result = PS_NoArguments; |
1092 | | /* check for command file parameter (syntax: "@filename") */ |
1093 | 0 | if ((argValue != NULL) && (argValue[0] == COMMAND_FILE_PREFIX) && (argValue[1] != '\0')) |
1094 | 0 | { |
1095 | | /* skip '@' symbol in filename */ |
1096 | 0 | const char *filename = argValue + 1; |
1097 | | /* open command file */ |
1098 | 0 | STD_NAMESPACE ifstream cmdFile(filename, OFopenmode_in_nocreate); |
1099 | 0 | if (cmdFile) |
1100 | 0 | { |
1101 | 0 | char c, block = 0; |
1102 | 0 | OFString value; |
1103 | | /* append command file content to the list of arguments */ |
1104 | 0 | while (cmdFile.get(c)) |
1105 | 0 | { |
1106 | | /* double or single quote */ |
1107 | 0 | if ((c == '"') || (c == '\'')) |
1108 | 0 | { |
1109 | 0 | if (block == c) |
1110 | 0 | { |
1111 | | /* closing current quote block (also empty value) */ |
1112 | 0 | argList.push_back(value); |
1113 | 0 | value.clear(); |
1114 | 0 | block = 0; |
1115 | 0 | } |
1116 | 0 | else if (block == 0) |
1117 | 0 | { |
1118 | | /* starting new quote block */ |
1119 | 0 | block = c; |
1120 | 0 | } else { |
1121 | | /* append character */ |
1122 | 0 | value += c; |
1123 | 0 | } |
1124 | 0 | } |
1125 | | /* space, tab, newline or return */ |
1126 | 0 | else if ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r')) |
1127 | 0 | { |
1128 | | /* outside block quote? */ |
1129 | 0 | if (block == 0) |
1130 | 0 | { |
1131 | 0 | if (!value.empty()) |
1132 | 0 | { |
1133 | | /* and add current value to the list of arguments */ |
1134 | 0 | argList.push_back(value); |
1135 | 0 | value.clear(); |
1136 | 0 | } |
1137 | 0 | } else |
1138 | 0 | value += c; |
1139 | 0 | } else |
1140 | 0 | value += c; |
1141 | 0 | } |
1142 | | /* append remaining argument (if any) */ |
1143 | 0 | if (!value.empty()) |
1144 | 0 | argList.push_back(value); |
1145 | | #ifdef DEBUG |
1146 | | if (block != 0) |
1147 | | { |
1148 | | ofConsole.lockCerr() << "WARNING: closing quotation mark (" << block << ") missing in command file " << filename << OFendl; |
1149 | | ofConsole.unlockCerr(); |
1150 | | } |
1151 | | #endif |
1152 | 0 | result = PS_Normal; |
1153 | 0 | } else |
1154 | 0 | result = PS_CannotOpenCommandFile; |
1155 | 0 | } |
1156 | 0 | return result; |
1157 | 0 | } |
1158 | | |
1159 | | |
1160 | | #ifdef DCMTK_USE_WCHAR_T |
1161 | | |
1162 | | // Windows-specific version with wide character strings (UTF-16) |
1163 | | #ifdef DEBUG |
1164 | | OFCommandLine::E_ParseStatus OFCommandLine::parseCommandFile(const wchar_t *argValue, |
1165 | | const OFString &strValue, |
1166 | | OFList<OFString> &argList) |
1167 | | #else |
1168 | | OFCommandLine::E_ParseStatus OFCommandLine::parseCommandFile(const wchar_t *argValue, |
1169 | | const OFString & /* strValue */, |
1170 | | OFList<OFString> &argList) |
1171 | | #endif |
1172 | | { |
1173 | | E_ParseStatus result = PS_NoArguments; |
1174 | | /* check for command file parameter (syntax: "@filename") */ |
1175 | | if ((argValue != NULL) && (argValue[0] == WIDE_COMMAND_FILE_PREFIX) && (argValue[1] != L'\0')) |
1176 | | { |
1177 | | /* skip '@' symbol in filename */ |
1178 | | const wchar_t *filename = argValue + 1; |
1179 | | /* open command file */ |
1180 | | STD_NAMESPACE wifstream cmdFile(filename, OFopenmode_in_nocreate); |
1181 | | if (cmdFile) |
1182 | | { |
1183 | | wchar_t c, block = 0; |
1184 | | STD_NAMESPACE wstring value; |
1185 | | /* append command file content to the list of arguments */ |
1186 | | while (cmdFile.get(c)) |
1187 | | { |
1188 | | /* double or single quote */ |
1189 | | if ((c == L'"') || (c == L'\'')) |
1190 | | { |
1191 | | if (block == c) |
1192 | | { |
1193 | | /* closing current quote block (also empty value) */ |
1194 | | OFString tmpString; |
1195 | | /* convert current value to UTF-8 */ |
1196 | | OFCharacterEncoding::convertFromWideCharString(value.c_str(), value.length(), |
1197 | | tmpString, OFCharacterEncoding::CPC_UTF8); |
1198 | | /* ... and add it to the list of arguments */ |
1199 | | argList.push_back(tmpString); |
1200 | | value.clear(); |
1201 | | block = 0; |
1202 | | } |
1203 | | else if (block == 0) |
1204 | | { |
1205 | | /* starting new quote block */ |
1206 | | block = c; |
1207 | | } else { |
1208 | | /* append character */ |
1209 | | value += c; |
1210 | | } |
1211 | | } |
1212 | | /* space, tab, newline or return */ |
1213 | | else if ((c == L' ') || (c == L'\t') || (c == L'\n') || (c == L'\r')) |
1214 | | { |
1215 | | /* outside block quote? */ |
1216 | | if (block == 0) |
1217 | | { |
1218 | | if (!value.empty()) |
1219 | | { |
1220 | | OFString tmpString; |
1221 | | /* convert current value to UTF-8 */ |
1222 | | OFCharacterEncoding::convertFromWideCharString(value.c_str(), value.length(), |
1223 | | tmpString, OFCharacterEncoding::CPC_UTF8); |
1224 | | /* ... and add it to the list of arguments */ |
1225 | | argList.push_back(tmpString); |
1226 | | value.clear(); |
1227 | | } |
1228 | | } else |
1229 | | value += c; |
1230 | | } else |
1231 | | value += c; |
1232 | | } |
1233 | | /* append remaining argument (if any) */ |
1234 | | if (!value.empty()) |
1235 | | { |
1236 | | OFString tmpString; |
1237 | | /* convert current value to UTF-8 */ |
1238 | | OFCharacterEncoding::convertFromWideCharString(value.c_str(), value.length(), tmpString, |
1239 | | OFCharacterEncoding::CPC_UTF8); |
1240 | | /* ... and add it to the list of arguments */ |
1241 | | argList.push_back(tmpString); |
1242 | | } |
1243 | | #ifdef DEBUG |
1244 | | if (block != 0) |
1245 | | { |
1246 | | // Right now the code below prints the character code of the 'block' wchar_t character instead |
1247 | | // of the character itself. This is an interim solution until a proper conversion function |
1248 | | // is added in the future in order to print the original character. |
1249 | | ofConsole.lockCerr() << "WARNING: closing quotation mark (" << OFstatic_cast(unsigned, block) << ") missing in command file " << strValue << OFendl; |
1250 | | ofConsole.unlockCerr(); |
1251 | | } |
1252 | | #endif |
1253 | | result = PS_Normal; |
1254 | | } else |
1255 | | result = PS_CannotOpenCommandFile; |
1256 | | } |
1257 | | return result; |
1258 | | } |
1259 | | |
1260 | | #endif // DCMTK_USE_WCHAR_T |
1261 | | |
1262 | | |
1263 | | OFCommandLine::E_ParseStatus OFCommandLine::parseArgumentList(OFList<OFString> &argList, |
1264 | | const int /*flags*/) |
1265 | 0 | { |
1266 | 0 | ArgumentList.clear(); // initialize lists/positions |
1267 | 0 | ParamPosList.clear(); |
1268 | 0 | OptionPosList.clear(); |
1269 | 0 | ParamPosNumber = 0; |
1270 | 0 | ExclusiveOption = OFFalse; |
1271 | |
|
1272 | 0 | int directOption = 0; // number of direct predecessor |
1273 | 0 | int i = OFstatic_cast(int, argList.size()); |
1274 | 0 | OFListIterator(OFString) argIter = argList.begin(); |
1275 | 0 | const OFListIterator(OFString) argEnd = argList.end(); |
1276 | | /* iterate over all command line arguments */ |
1277 | 0 | while (argIter != argEnd) |
1278 | 0 | { |
1279 | 0 | if (!checkOption(*argIter, OFFalse)) // arg = parameter |
1280 | 0 | { |
1281 | 0 | storeParameter(*argIter, directOption); |
1282 | 0 | directOption = 0; |
1283 | 0 | } else { // arg = option |
1284 | 0 | const OFCmdOption *opt = findCmdOption(*argIter); |
1285 | 0 | if (opt != NULL) |
1286 | 0 | { |
1287 | 0 | ArgumentList.push_back(OFstatic_cast(OFString, opt->LongOption)); // convert argument to long format |
1288 | 0 | OptionPosList.push_back(--ArgumentList.end()); |
1289 | 0 | if (opt->Flags & AF_Exclusive) // check for an "exclusive" option |
1290 | 0 | ExclusiveOption = OFTrue; |
1291 | 0 | directOption++; |
1292 | 0 | int j = opt->ValueCount; // number of expected values |
1293 | 0 | if (j >= i) |
1294 | 0 | return PS_MissingValue; // expecting more values than present |
1295 | 0 | while (j-- > 0) |
1296 | 0 | { |
1297 | 0 | ArgumentList.push_back(*(++argIter)); // add values to argument list |
1298 | 0 | i--; |
1299 | 0 | } |
1300 | 0 | } else { // unknown |
1301 | 0 | ArgumentList.push_back(*argIter); // store argument |
1302 | 0 | return PS_UnknownOption; |
1303 | 0 | } |
1304 | 0 | } |
1305 | 0 | ++argIter; |
1306 | 0 | i--; |
1307 | 0 | } |
1308 | 0 | return checkParamCount(); |
1309 | 0 | } |
1310 | | |
1311 | | |
1312 | | OFCommandLine::E_ParseStatus OFCommandLine::parseLine(int argCount, |
1313 | | char *argValue[], |
1314 | | const int flags, |
1315 | | const int startPos) |
1316 | 0 | { |
1317 | 0 | OFList<OFString> argList; // "expanded" list of arguments |
1318 | 0 | WideCharMode = OFFalse; |
1319 | 0 | if (argCount > 0) // determine program name |
1320 | 0 | ProgramName = argValue[0]; |
1321 | 0 | else |
1322 | 0 | ProgramName.clear(); |
1323 | 0 | if (argCount > startPos) // any command line arguments? |
1324 | 0 | { |
1325 | | /* expand command files (if any) */ |
1326 | 0 | for (int i = startPos; i < argCount; i++) // skip program name (argValue[0]) |
1327 | 0 | { |
1328 | 0 | if (flags & PF_NoCommandFiles) // do not try to detect command files |
1329 | 0 | argList.push_back(argValue[i]); |
1330 | 0 | else |
1331 | 0 | { |
1332 | | /* parse command file content */ |
1333 | 0 | E_ParseStatus status = parseCommandFile(argValue[i], argList); |
1334 | 0 | if (status == PS_NoArguments) |
1335 | 0 | argList.push_back(argValue[i]); // store parameter as is |
1336 | 0 | else if (status != PS_Normal) |
1337 | 0 | { |
1338 | 0 | ArgumentList.push_back(argValue[i] + 1); // store filename for error message |
1339 | 0 | return status; |
1340 | 0 | } |
1341 | 0 | } |
1342 | 0 | } |
1343 | 0 | } |
1344 | | /* call the real function after the preparatory work is done */ |
1345 | 0 | return parseArgumentList(argList, flags); |
1346 | 0 | } |
1347 | | |
1348 | | |
1349 | | #ifdef DCMTK_USE_WCHAR_T |
1350 | | |
1351 | | // Windows-specific version with wide character strings (UTF-16) |
1352 | | OFCommandLine::E_ParseStatus OFCommandLine::parseLine(int argCount, |
1353 | | wchar_t *argValue[], |
1354 | | const int flags, |
1355 | | const int startPos) |
1356 | | { |
1357 | | OFList<OFString> argList; // "expanded" list of arguments |
1358 | | WideCharMode = OFTrue; |
1359 | | if (argCount > 0) // determine program name (convert to UTF-8) |
1360 | | { |
1361 | | OFCharacterEncoding::convertFromWideCharString(argValue[0], wcslen(argValue[0]), |
1362 | | ProgramName, OFCharacterEncoding::CPC_UTF8); |
1363 | | } else |
1364 | | ProgramName.clear(); |
1365 | | if (argCount > startPos) // any command line arguments? |
1366 | | { |
1367 | | OFString strValue; |
1368 | | /* expand command files (if any) */ |
1369 | | for (int i = startPos; i < argCount; i++) // skip program name (argValue[0]) |
1370 | | { |
1371 | | OFCharacterEncoding::convertFromWideCharString(argValue[i], wcslen(argValue[i]), |
1372 | | strValue, OFCharacterEncoding::CPC_UTF8, OFTrue /* clearMode */); |
1373 | | if (flags & PF_NoCommandFiles) // do not try to detect command files |
1374 | | argList.push_back(strValue); |
1375 | | else |
1376 | | { |
1377 | | /* parse command file content */ |
1378 | | E_ParseStatus status = parseCommandFile(argValue[i], strValue, argList); |
1379 | | if (status == PS_NoArguments) |
1380 | | argList.push_back(strValue); // store parameter as is |
1381 | | else if (status != PS_Normal) |
1382 | | { |
1383 | | ArgumentList.push_back(strValue.c_str() + 1); // store filename for error message |
1384 | | return status; |
1385 | | } |
1386 | | } |
1387 | | } |
1388 | | } |
1389 | | /* call the real function after the preparatory work is done */ |
1390 | | return parseArgumentList(argList, flags); |
1391 | | } |
1392 | | |
1393 | | #endif // DCMTK_USE_WCHAR_T |
1394 | | |
1395 | | |
1396 | | void OFCommandLine::getSyntaxString(OFString &syntaxStr) const |
1397 | 0 | { |
1398 | 0 | syntaxStr.clear(); |
1399 | 0 | if (!ValidOptionList.empty()) |
1400 | 0 | syntaxStr += " [options]"; |
1401 | 0 | if (!ValidParamList.empty()) |
1402 | 0 | { |
1403 | 0 | OFListConstIterator(OFCmdParam *) iter = ValidParamList.begin(); |
1404 | 0 | OFListConstIterator(OFCmdParam *) last = ValidParamList.end(); |
1405 | 0 | while (iter != last) |
1406 | 0 | { |
1407 | 0 | if (!(*iter)->ParamName.empty()) |
1408 | 0 | { |
1409 | 0 | switch ((*iter)->ParamMode) |
1410 | 0 | { |
1411 | 0 | case OFCmdParam::PM_Mandatory: |
1412 | 0 | syntaxStr += " "; |
1413 | 0 | syntaxStr += (*iter)->ParamName; |
1414 | 0 | break; |
1415 | 0 | case OFCmdParam::PM_Optional: |
1416 | 0 | syntaxStr += " ["; |
1417 | 0 | syntaxStr += (*iter)->ParamName; |
1418 | 0 | syntaxStr += "]"; |
1419 | 0 | break; |
1420 | 0 | case OFCmdParam::PM_MultiMandatory: |
1421 | 0 | syntaxStr += " "; |
1422 | 0 | syntaxStr += (*iter)->ParamName; |
1423 | 0 | syntaxStr += "..."; |
1424 | 0 | break; |
1425 | 0 | case OFCmdParam::PM_MultiOptional: |
1426 | 0 | syntaxStr += " ["; |
1427 | 0 | syntaxStr += (*iter)->ParamName; |
1428 | 0 | syntaxStr += "...]"; |
1429 | 0 | break; |
1430 | 0 | } |
1431 | 0 | } |
1432 | 0 | ++iter; |
1433 | 0 | } |
1434 | 0 | } |
1435 | 0 | } |
1436 | | |
1437 | | |
1438 | | void OFCommandLine::getOptionString(OFString &optionStr) const |
1439 | 0 | { |
1440 | 0 | optionStr.clear(); |
1441 | 0 | if (!ValidOptionList.empty()) |
1442 | 0 | { |
1443 | 0 | OFListConstIterator(OFCmdOption *) iter = ValidOptionList.begin(); |
1444 | 0 | OFListConstIterator(OFCmdOption *) last = ValidOptionList.end(); |
1445 | 0 | OFString str; |
1446 | 0 | int newGrp = 1; |
1447 | 0 | unsigned int shortSize = ShortColumn; |
1448 | 0 | unsigned int longSize = LongColumn; |
1449 | 0 | unsigned int lineIndent = 0; |
1450 | 0 | const unsigned int groupIndent = 2; |
1451 | 0 | const unsigned int subGrpIndent = 4; |
1452 | 0 | const unsigned int columnSpace = 2; |
1453 | 0 | while (iter != last) |
1454 | 0 | { |
1455 | | /* skip internal options */ |
1456 | 0 | if (!((*iter)->Flags & OFCommandLine::AF_Internal)) |
1457 | 0 | { |
1458 | 0 | if (newGrp) |
1459 | 0 | { |
1460 | | /* determine column width per group */ |
1461 | 0 | OFListConstIterator(OFCmdOption *) i = iter; |
1462 | 0 | while ((i != last) && !(*i)->LongOption.empty()) |
1463 | 0 | { |
1464 | 0 | if (!((*i)->Flags & OFCommandLine::AF_Internal)) |
1465 | 0 | { |
1466 | 0 | if ((*i)->ShortOption.length() > shortSize) |
1467 | 0 | shortSize = OFstatic_cast(unsigned int, (*i)->ShortOption.length()); |
1468 | 0 | if ((*i)->LongOption.length() > longSize) |
1469 | 0 | longSize = OFstatic_cast(unsigned int, (*i)->LongOption.length()); |
1470 | 0 | } |
1471 | 0 | i++; |
1472 | 0 | } |
1473 | 0 | newGrp = 0; |
1474 | 0 | } |
1475 | 0 | if ((*iter)->LongOption.empty()) |
1476 | 0 | { |
1477 | | /* group entry */ |
1478 | 0 | newGrp = 1; |
1479 | 0 | unpackColumnValues((*iter)->ValueCount, longSize, shortSize); |
1480 | 0 | if (!(*iter)->OptionDescription.empty()) // new group |
1481 | 0 | { |
1482 | 0 | optionStr += (*iter)->OptionDescription; |
1483 | 0 | lineIndent = groupIndent; |
1484 | 0 | } else { // new sub group |
1485 | 0 | optionStr.append(groupIndent, ' '); |
1486 | 0 | optionStr += (*iter)->ValueDescription; |
1487 | 0 | lineIndent = subGrpIndent; |
1488 | 0 | } |
1489 | 0 | optionStr += "\n"; |
1490 | 0 | } else { |
1491 | | /* regular option */ |
1492 | 0 | optionStr.append(lineIndent, ' '); |
1493 | 0 | if (shortSize > 0) |
1494 | 0 | { |
1495 | 0 | str = (*iter)->ShortOption; |
1496 | 0 | str.resize(shortSize, ' '); |
1497 | 0 | optionStr += str; |
1498 | 0 | optionStr.append(columnSpace, ' '); |
1499 | 0 | } |
1500 | 0 | str = (*iter)->LongOption; |
1501 | 0 | str.resize(longSize, ' '); |
1502 | 0 | optionStr += str; |
1503 | 0 | optionStr.append(columnSpace, ' '); |
1504 | 0 | if (!(*iter)->ValueDescription.empty()) |
1505 | 0 | { |
1506 | 0 | optionStr += (*iter)->ValueDescription; |
1507 | 0 | optionStr += "\n"; |
1508 | 0 | optionStr.append(lineIndent + shortSize + longSize + columnSpace, ' '); |
1509 | 0 | if (shortSize > 0) |
1510 | 0 | optionStr.append(columnSpace, ' '); |
1511 | 0 | } |
1512 | 0 | str = (*iter)->OptionDescription; |
1513 | 0 | size_t pos = 0; |
1514 | 0 | while (((pos = (str.find('\n', pos))) != OFString_npos) && (pos < str.length())) |
1515 | 0 | str.insert(++pos, OFString(lineIndent + shortSize + longSize + 2 * columnSpace, ' ')); |
1516 | 0 | optionStr += str; |
1517 | 0 | optionStr += "\n"; |
1518 | 0 | } |
1519 | 0 | } |
1520 | 0 | ++iter; |
1521 | 0 | } |
1522 | 0 | } |
1523 | 0 | } |
1524 | | |
1525 | | |
1526 | | void OFCommandLine::getParamString(OFString ¶mStr) const |
1527 | 0 | { |
1528 | 0 | paramStr.clear(); |
1529 | 0 | if (!ValidParamList.empty()) |
1530 | 0 | { |
1531 | 0 | OFListConstIterator(OFCmdParam *) iter = ValidParamList.begin(); |
1532 | 0 | OFListConstIterator(OFCmdParam *) last = ValidParamList.end(); |
1533 | 0 | OFString str; |
1534 | 0 | unsigned int columnSize = ParamColumn; |
1535 | 0 | const unsigned int lineIndent = 2; |
1536 | 0 | const unsigned int columnSpace = 2; |
1537 | 0 | while ((iter != last) && !(*iter)->ParamDescription.empty()) |
1538 | 0 | { |
1539 | 0 | if ((*iter)->ParamName.length() > columnSize) // determine maximum column width |
1540 | 0 | columnSize = OFstatic_cast(unsigned int, (*iter)->ParamName.length()); |
1541 | 0 | ++iter; |
1542 | 0 | } |
1543 | 0 | iter = ValidParamList.begin(); // reset iterator |
1544 | 0 | while (iter != last) |
1545 | 0 | { |
1546 | 0 | if (!(*iter)->ParamDescription.empty()) |
1547 | 0 | { |
1548 | 0 | if (paramStr.empty()) |
1549 | 0 | paramStr += "parameters:\n"; |
1550 | 0 | paramStr.append(lineIndent, ' '); |
1551 | 0 | str = (*iter)->ParamName; |
1552 | 0 | str.resize(columnSize, ' '); |
1553 | 0 | paramStr += str; |
1554 | 0 | paramStr.append(columnSpace, ' '); |
1555 | 0 | str = (*iter)->ParamDescription; |
1556 | 0 | size_t pos = 0; |
1557 | 0 | while (((pos = (str.find('\n', pos))) != OFString_npos) && (pos < str.length())) |
1558 | 0 | str.insert(++pos, OFString(lineIndent + columnSize + columnSpace, ' ')); |
1559 | 0 | paramStr += str; |
1560 | 0 | paramStr += "\n"; |
1561 | 0 | } |
1562 | 0 | ++iter; |
1563 | 0 | } |
1564 | 0 | } |
1565 | 0 | } |
1566 | | |
1567 | | |
1568 | | OFBool OFCommandLine::getMissingParam(OFString ¶m) |
1569 | 0 | { |
1570 | 0 | if (!ValidParamList.empty() && (getParamCount() < MinParamCount)) |
1571 | 0 | { |
1572 | 0 | OFListIterator(OFCmdParam *) iter = ValidParamList.begin(); |
1573 | 0 | const OFListIterator(OFCmdParam *) last = ValidParamList.end(); |
1574 | 0 | int i = getParamCount(); |
1575 | 0 | while ((iter != last) && (i-- > 0)) |
1576 | 0 | ++iter; |
1577 | 0 | if (iter != last) |
1578 | 0 | { |
1579 | 0 | param = (*iter)->ParamName; |
1580 | 0 | return OFTrue; |
1581 | 0 | } |
1582 | 0 | } |
1583 | 0 | return OFFalse; |
1584 | 0 | } |
1585 | | |
1586 | | |
1587 | | void OFCommandLine::getStatusString(const E_ParseStatus status, |
1588 | | OFString &statusStr) |
1589 | 0 | { |
1590 | 0 | OFString str; |
1591 | 0 | switch (status) |
1592 | 0 | { |
1593 | 0 | case PS_UnknownOption: |
1594 | 0 | statusStr = "Unknown option "; |
1595 | 0 | if (getLastArg(str)) |
1596 | 0 | statusStr += str; |
1597 | 0 | break; |
1598 | 0 | case PS_MissingValue: |
1599 | 0 | statusStr = "Missing value for option "; |
1600 | 0 | if (getLastArg(str)) |
1601 | 0 | statusStr += str; |
1602 | 0 | break; |
1603 | 0 | case PS_MissingParameter: |
1604 | 0 | statusStr = "Missing parameter "; |
1605 | 0 | if (getMissingParam(str)) |
1606 | 0 | statusStr += str; |
1607 | 0 | break; |
1608 | 0 | case PS_TooManyParameters: |
1609 | 0 | statusStr = "Too many parameters"; |
1610 | 0 | break; |
1611 | 0 | case PS_CannotOpenCommandFile: |
1612 | 0 | statusStr = "Cannot open command file"; |
1613 | 0 | if (getLastArg(str)) |
1614 | 0 | { |
1615 | 0 | statusStr += " '"; |
1616 | 0 | statusStr += str; |
1617 | 0 | statusStr += "'"; |
1618 | 0 | } |
1619 | 0 | break; |
1620 | 0 | default: |
1621 | 0 | statusStr.clear(); |
1622 | 0 | break; |
1623 | 0 | } |
1624 | 0 | } |
1625 | | |
1626 | | |
1627 | | void OFCommandLine::getStatusString(const E_ParamValueStatus status, |
1628 | | OFString &statusStr) |
1629 | 0 | { |
1630 | 0 | OFString str; |
1631 | 0 | switch (status) |
1632 | 0 | { |
1633 | 0 | case PVS_Invalid: |
1634 | 0 | statusStr = "Invalid parameter value "; |
1635 | 0 | if (getCurrentArg(str)) |
1636 | 0 | statusStr += str; |
1637 | 0 | break; |
1638 | 0 | case PVS_CantFind: |
1639 | 0 | statusStr = "Can't find parameter"; |
1640 | 0 | break; |
1641 | 0 | case PVS_Underflow: |
1642 | 0 | statusStr = "Invalid parameter value "; |
1643 | 0 | if (getCurrentArg(str)) |
1644 | 0 | { |
1645 | 0 | statusStr += str; |
1646 | 0 | statusStr += " (underflow)"; |
1647 | 0 | } |
1648 | 0 | break; |
1649 | 0 | case PVS_Overflow: |
1650 | 0 | statusStr = "Invalid parameter value "; |
1651 | 0 | if (getCurrentArg(str)) |
1652 | 0 | { |
1653 | 0 | statusStr += str; |
1654 | 0 | statusStr += " (overflow)"; |
1655 | 0 | } |
1656 | 0 | break; |
1657 | 0 | default: |
1658 | 0 | statusStr.clear(); |
1659 | 0 | break; |
1660 | 0 | } |
1661 | 0 | } |
1662 | | |
1663 | | |
1664 | | void OFCommandLine::getStatusString(const E_ValueStatus status, |
1665 | | OFString &statusStr) |
1666 | 0 | { |
1667 | 0 | OFString str; |
1668 | 0 | switch (status) |
1669 | 0 | { |
1670 | 0 | case VS_Normal: |
1671 | 0 | statusStr.clear(); |
1672 | 0 | break; |
1673 | 0 | case VS_Invalid: |
1674 | 0 | statusStr = "Invalid value for option "; |
1675 | 0 | if (getCurrentOption(str)) |
1676 | 0 | { |
1677 | 0 | statusStr += str; |
1678 | 0 | if (getCurrentArg(str)) |
1679 | 0 | { |
1680 | 0 | statusStr += " ("; |
1681 | 0 | statusStr += str; |
1682 | 0 | statusStr += ")"; |
1683 | 0 | } |
1684 | 0 | } |
1685 | 0 | break; |
1686 | 0 | case VS_Underflow: |
1687 | 0 | statusStr = "Invalid value for option "; |
1688 | 0 | if (getCurrentOption(str)) |
1689 | 0 | { |
1690 | 0 | statusStr += str; |
1691 | 0 | if (getCurrentArg(str)) |
1692 | 0 | { |
1693 | 0 | statusStr += " (underflow: "; |
1694 | 0 | statusStr += str; |
1695 | 0 | statusStr += ")"; |
1696 | 0 | } |
1697 | 0 | } |
1698 | 0 | break; |
1699 | 0 | case VS_Overflow: |
1700 | 0 | statusStr = "Invalid value for option "; |
1701 | 0 | if (getCurrentOption(str)) |
1702 | 0 | { |
1703 | 0 | statusStr += str; |
1704 | 0 | if (getCurrentArg(str)) |
1705 | 0 | { |
1706 | 0 | statusStr += " (overflow: "; |
1707 | 0 | statusStr += str; |
1708 | 0 | statusStr += ")"; |
1709 | 0 | } |
1710 | 0 | } |
1711 | 0 | break; |
1712 | 0 | default: |
1713 | 0 | statusStr.clear(); |
1714 | 0 | break; |
1715 | 0 | } |
1716 | 0 | } |