source: src/UIElements/CommandLineUI/CommandLineParser.cpp@ 15d21e

Action_Thermostats Add_AtomRandomPerturbation Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 ChangeBugEmailaddress ChemicalSpaceEvaluator Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_oldresults ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks StoppableMakroAction TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps
Last change on this file since 15d21e was 15d21e, checked in by Frederik Heber <frederik.heber@…>, 8 years ago

CommandLineParser is now able to parse negative numbers.

  • before they were recognized as shortforms of arguments. Now, we found a nice solution on stackoverflow that preparses all options and checks whether the shortform is actually convertible to a number and skips it then.
  • Property mode set to 100644
File size: 24.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * CommandLineParser.cpp
25 *
26 * Created on: May 8, 2010
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35//#include "CodePatterns/MemDebug.hpp"
36
37#include <boost/filesystem.hpp>
38#include <boost/lexical_cast.hpp>
39#include <boost/program_options/option.hpp>
40#include <boost/program_options/value_semantic.hpp>
41#include <boost/program_options.hpp>
42#include <fstream>
43#include <iostream>
44#include <set>
45#include <map>
46
47#include "Actions/Action.hpp"
48#include "Actions/ActionQueue.hpp"
49#include "Actions/ActionTrait.hpp"
50#include "Actions/OptionRegistry.hpp"
51#include "Actions/OptionTrait.hpp"
52#include "Actions/Values.hpp"
53#include "CodePatterns/Log.hpp"
54#include "CodePatterns/Verbose.hpp"
55#include "CommandLineParser.hpp"
56#include "CommandLineParser_validate.hpp"
57#include "Parameters/Specifics/KeyValuePair.hpp"
58#include "World.hpp"
59
60#include "CodePatterns/Singleton_impl.hpp"
61
62using namespace MoleCuilder;
63
64class element;
65
66/** Constructor of class CommandLineParser.
67 *
68 */
69CommandLineParser::CommandLineParser() :
70 analysis("Analysis options"),
71 atom("Atom options"),
72 bond("Bond options"),
73 command("Command options"),
74 fill("fill options"),
75 shape("shape options"),
76 fragmentation("Fragmentation options"),
77 graph("Graph options"),
78 molecule("Molecule options"),
79 options("Secondary options"),
80 parser("Parser options"),
81 potential("Potential options"),
82 selection("Selection options"),
83 tesselation("Tesselation options"),
84 world("World options")
85{
86 // put all options lists into a lookup
87 CmdParserLookup["analysis"] = &analysis;
88 CmdParserLookup["atom"] = &atom;
89 CmdParserLookup["bond"] = &bond;
90 CmdParserLookup["command"] = &command;
91 CmdParserLookup["edit"] = &edit;
92 CmdParserLookup["fill"] = &fill;
93 CmdParserLookup["shape"] = &shape;
94 CmdParserLookup["fragmentation"] = &fragmentation;
95 CmdParserLookup["graph"] = &graph;
96 CmdParserLookup["options"] = &options;
97 CmdParserLookup["molecule"] = &molecule;
98 CmdParserLookup["parser"] = &parser;
99 CmdParserLookup["potential"] = &potential;
100 CmdParserLookup["selection"] = &selection;
101 CmdParserLookup["tesselation"] = &tesselation;
102 CmdParserLookup["world"] = &world;
103}
104
105/** Destructor of class CommandLineParser.
106 *
107 */
108CommandLineParser::~CommandLineParser()
109{}
110
111/** Initializes command arguments to accept.
112 * Goes through ActionRegistry and puts all actions therein into the map.
113 */
114void CommandLineParser::InitializeCommandArguments()
115{
116 // we need a list of already added options, otherwise we get ambigious exceptions
117 std::set<std::string> AlreadyAddedOptionNames;
118
119 bool ActionAlreadyAdded_flag = false;
120 ActionQueue &AQ = ActionQueue::getInstance();
121 ActionQueue::ActionTokens_t tokens = AQ.getListOfActions();
122 for (ActionQueue::ActionTokens_t::const_iterator iter = tokens.begin();
123 iter != tokens.end(); ++iter) {
124 const ActionTrait &CurrentTrait = AQ.getActionsTrait(*iter);
125 ActionAlreadyAdded_flag = false;
126 //std::cout << "Current Action to initialize is: " << actioniter->first << std::endl;
127
128 for (ActionTrait::options_const_iterator optioniter = CurrentTrait.getBeginIter();
129 optioniter != CurrentTrait.getEndIter();
130 ++optioniter) {
131 if (optioniter->first == *iter)
132 ActionAlreadyAdded_flag = true;
133 ASSERT( OptionRegistry::getInstance().isOptionPresentByName(optioniter->first),
134 "CommandLineParser::Init() - Option "+optioniter->first+" not present in OptionRegistry." );
135 const OptionTrait* const currentOption = OptionRegistry::getInstance().getOptionByName(optioniter->first);
136
137 if (AlreadyAddedOptionNames.find(optioniter->first) == AlreadyAddedOptionNames.end()) {
138 // add the option
139// std::cout << "Registering Option "
140// << currentOption->getName()
141// << " with type '" << currentOption->getTypeName() << "' "
142// << " with description '" << currentOption->getDescription() << "' ";
143// if (currentOption->hasShortForm())
144// std::cout << ", with short form " << currentOption->getShortForm();
145// else
146// std::cout << ", with no short form ";
147// if (currentOption->hasDefaultValue())
148// std::cout << ", with default value " << currentOption->getDefaultValue();
149// else
150// std::cout << ", with no default value ";
151// std::cout << std::endl;
152
153 AddOptionToParser(currentOption, (CmdParserLookup["options"]),
154 (optioniter->first == *iter) ?
155 true : false);
156
157 AlreadyAddedOptionNames.insert(optioniter->first);
158 } else {
159// std::cout << "Option " << currentOption->getName() << " already registered." << std::endl;
160 }
161 }
162
163 if (!ActionAlreadyAdded_flag) {
164 // add the action
165// std::cout << "Registering Action "
166// << currentAction->Traits.getName()
167// << " in menu " << currentAction->Traits.getMenuName()
168// << " with type '" << currentAction->Traits.getTypeName() << "' "
169// << " with description '" << currentAction->Traits.getDescription() << "' ";
170// if (currentAction->Traits.hasShortForm())
171// std::cout << ", with short form " << currentAction->Traits.getShortForm();
172// else
173// std::cout << ", with no short form ";
174// if (currentAction->Traits.hasDefaultValue())
175// std::cout << ", with default value " << currentAction->Traits.getDefaultValue();
176// else
177// std::cout << ", with no default value ";
178// std::cout << std::endl;
179
180 ASSERT(CmdParserLookup.find(CurrentTrait.getMenuName()) != CmdParserLookup.end(),
181 "CommandLineParser: boost::program_options::options_description for this Action not present.");
182 AddOptionToParser(
183 dynamic_cast<const OptionTrait * const>(&CurrentTrait),
184 (CmdParserLookup[CurrentTrait.getMenuName()]),
185 false);
186 }
187 }
188 // note: positioning is not important on the command line
189}
190
191/** Adds an Action or Option to the CommandLineParser.
192 * Note that Action is derived from Option(Trait)
193 *
194 * This ugly switch function is necessary because of the compile-time problem:
195 * po::value<T> has to be instantiated at compile-time however we do know the type not until run-time.
196 * Not even a templated function like po::value<T> getProgramOptionValuefromType() does help, specialized
197 * to each available type, as the signatures of all the functions differ. Hence, they cannot not put into
198 * one type_info -> po::value<T> map ...
199 *
200 * \param *currentOption pointer to Action/Option to add
201 * \param *OptionList program_options list to add to
202 * \param _DefaultAsImplicit whether to add a default value as default_value or
203 * as implicit_value (default = option token present or not, implicit =
204 option token present but not necessarily followed by argument)
205 */
206void CommandLineParser::AddOptionToParser(
207 const OptionTrait * const currentOption,
208 po::options_description* OptionList,
209 const bool _DefaultAsImplicit)
210{
211 // check whether dynamic_cast in Init() suceeded
212 ASSERT(currentOption != NULL, "CommandLineParser::AddOptionToParser() - currentOption is NULL!");
213 // add other options
214// std::cout << "Adding Action " << currentOption->getName() << " with type "
215// << currentOption->getType()->name() << ", " << (currentOption->hasDefaultValue() ? "with" : "without")
216// << " default value, and KeyandShortform " << currentOption->getKeyAndShortForm()
217// << " to CommandLineParser." << std::endl;
218 switch(TypeToEnums.getEnumforType(currentOption->getType())) {
219 default:
220 case TypeEnumContainer::NoneType:
221 OptionList->add_options()
222 (currentOption->getKeyAndShortForm().c_str(), currentOption->getDescription().c_str())
223 ;
224 break;
225 case TypeEnumContainer::BooleanType:
226 OptionList->add_options()
227 (currentOption->getKeyAndShortForm().c_str(),
228 currentOption->hasDefaultValue() ?
229 (_DefaultAsImplicit ?
230 po::value < bool >()->implicit_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str())) :
231 po::value < bool >()->default_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str()))) :
232 po::value < bool >(),
233 currentOption->getDescription().c_str())
234 ;
235 break;
236 case TypeEnumContainer::FileType:
237 OptionList->add_options()
238 (currentOption->getKeyAndShortForm().c_str(),
239// currentOption->hasDefaultValue() ?
240// po::value < boost::filesystem::path >()->default_value(boost::lexical_cast<boost::filesystem::path>(currentOption->getDefaultValue().c_str())) :
241 po::value < boost::filesystem::path >(),
242 currentOption->getDescription().c_str())
243 ;
244 break;
245 case TypeEnumContainer::ListOfFilesType:
246 OptionList->add_options()
247 (currentOption->getKeyAndShortForm().c_str(),
248// currentOption->hasDefaultValue() ?
249// po::value < std::vector<boost::filesystem::path> >()->default_value(boost::lexical_cast< std::vector<boost::filesystem::path> >(currentOption->getDefaultValue().c_str())) :
250 po::value < std::vector<boost::filesystem::path> >()->multitoken(),
251 currentOption->getDescription().c_str())
252 ;
253 break;
254 case TypeEnumContainer::IntegerType:
255 OptionList->add_options()
256 (currentOption->getKeyAndShortForm().c_str(),
257 currentOption->hasDefaultValue() ?
258 (_DefaultAsImplicit ?
259 po::value < int >()->implicit_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str())) :
260 po::value < int >()->default_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str()))) :
261 po::value < int >(),
262 currentOption->getDescription().c_str())
263 ;
264 break;
265 case TypeEnumContainer::ListOfIntegersType:
266 OptionList->add_options()
267 (currentOption->getKeyAndShortForm().c_str(),
268// currentOption->hasDefaultValue() ?
269// po::value < std::vector<int> >()->default_value(boost::lexical_cast< std::vector<int> >(currentOption->getDefaultValue().c_str())) :
270 po::value < std::vector<int> >()->multitoken(),
271 currentOption->getDescription().c_str())
272 ;
273 break;
274 case TypeEnumContainer::UnsignedIntegerType:
275 OptionList->add_options()
276 (currentOption->getKeyAndShortForm().c_str(),
277 currentOption->hasDefaultValue() ?
278 (_DefaultAsImplicit ?
279 po::value < unsigned int >()->implicit_value(boost::lexical_cast<unsigned int>(currentOption->getDefaultValue().c_str())) :
280 po::value < unsigned int >()->default_value(boost::lexical_cast<unsigned int>(currentOption->getDefaultValue().c_str()))) :
281 po::value < unsigned int >(),
282 currentOption->getDescription().c_str())
283 ;
284 break;
285 case TypeEnumContainer::ListOfUnsignedIntegersType:
286 OptionList->add_options()
287 (currentOption->getKeyAndShortForm().c_str(),
288// currentOption->hasDefaultValue() ?
289// po::value < std::vector<unsigned int> >()->default_value(boost::lexical_cast< std::vector<unsigned int> >(currentOption->getDefaultValue().c_str())) :
290 po::value < std::vector<unsigned int> >()->multitoken(),
291 currentOption->getDescription().c_str())
292 ;
293 break;
294 case TypeEnumContainer::DoubleType:
295 OptionList->add_options()
296 (currentOption->getKeyAndShortForm().c_str(),
297 currentOption->hasDefaultValue() ?
298 (_DefaultAsImplicit ?
299 po::value < double >()->implicit_value(boost::lexical_cast<double>(currentOption->getDefaultValue().c_str())) :
300 po::value < double >()->default_value(boost::lexical_cast<double>(currentOption->getDefaultValue().c_str()))) :
301 po::value < double >(),
302 currentOption->getDescription().c_str())
303 ;
304 break;
305 case TypeEnumContainer::ListOfDoublesType:
306 OptionList->add_options()
307 (currentOption->getKeyAndShortForm().c_str(),
308// currentOption->hasDefaultValue() ?
309// po::value < std::vector<double> >()->default_value(boost::lexical_cast< std::vector<double> >(currentOption->getDefaultValue().c_str())) :
310 po::value < std::vector<double> >()->multitoken(),
311 currentOption->getDescription().c_str())
312 ;
313 break;
314 case TypeEnumContainer::StringType:
315 OptionList->add_options()
316 (currentOption->getKeyAndShortForm().c_str(),
317 currentOption->hasDefaultValue() ?
318 (_DefaultAsImplicit ?
319 po::value < std::string >()->implicit_value(currentOption->getDefaultValue()) :
320 po::value < std::string >()->default_value(currentOption->getDefaultValue())) :
321 po::value < std::string >(),
322 currentOption->getDescription().c_str())
323 ;
324 break;
325 case TypeEnumContainer::ListOfStringsType:
326 OptionList->add_options()
327 (currentOption->getKeyAndShortForm().c_str(),
328// currentOption->hasDefaultValue() ?
329// po::value < std::vector<std::string> >()->default_value(boost::lexical_cast< std::vector<std::string> >(currentOption->getDefaultValue().c_str())) :
330 po::value < std::vector<std::string> >()->multitoken(),
331 currentOption->getDescription().c_str())
332 ;
333 break;
334 case TypeEnumContainer::VectorType:
335 OptionList->add_options()
336 (currentOption->getKeyAndShortForm().c_str(),
337// currentOption->hasDefaultValue() ?
338// po::value < VectorValue >()->default_value(boost::lexical_cast<VectorValue>(currentOption->getDefaultValue().c_str())) :
339 po::value < VectorValue >(),
340 currentOption->getDescription().c_str())
341 ;
342 break;
343 case TypeEnumContainer::ListOfVectorsType:
344 OptionList->add_options()
345 (currentOption->getKeyAndShortForm().c_str(),
346// currentOption->hasDefaultValue() ?
347// po::value < std::vector<VectorValue> >()->default_value(boost::lexical_cast< std::vector<VectorValue> >(currentOption->getDefaultValue().c_str())) :
348 po::value < std::vector<VectorValue> >()->multitoken(),
349 currentOption->getDescription().c_str())
350 ;
351 break;
352 case TypeEnumContainer::MoleculeType:
353 OptionList->add_options()
354 (currentOption->getKeyAndShortForm().c_str(),
355// currentOption->hasDefaultValue() ?
356// po::value < const molecule * >()->default_value(boost::lexical_cast<const molecule *>(currentOption->getDefaultValue().c_str())) :
357 po::value < int >(),
358 currentOption->getDescription().c_str())
359 ;
360 break;
361 case TypeEnumContainer::ListOfMoleculesType:
362 OptionList->add_options()
363 (currentOption->getKeyAndShortForm().c_str(),
364// currentOption->hasDefaultValue() ?
365// po::value < std::vector<const molecule *> >()->default_value(boost::lexical_cast< std::vector<const molecule *> >(currentOption->getDefaultValue().c_str())) :
366 po::value < std::vector<int> >()->multitoken(),
367 currentOption->getDescription().c_str())
368 ;
369 break;
370 case TypeEnumContainer::AtomType:
371 OptionList->add_options()
372 (currentOption->getKeyAndShortForm().c_str(),
373 currentOption->hasDefaultValue() ?
374 (_DefaultAsImplicit ?
375 po::value < int >()->implicit_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str())) :
376 po::value < int >()->default_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str()))) :
377 po::value < int >(),
378 currentOption->getDescription().c_str())
379 ;
380 break;
381 case TypeEnumContainer::ListOfAtomsType:
382 OptionList->add_options()
383 (currentOption->getKeyAndShortForm().c_str(),
384// currentOption->hasDefaultValue() ?
385// po::value < std::vector<const atom *> >()->default_value(boost::lexical_cast< std::vector<const atom *> >(currentOption->getDefaultValue().c_str())) :
386 po::value < std::vector<int> >()->multitoken(),
387 currentOption->getDescription().c_str())
388 ;
389 break;
390 case TypeEnumContainer::ElementType:
391 OptionList->add_options()
392 (currentOption->getKeyAndShortForm().c_str(),
393// currentOption->hasDefaultValue() ?
394// po::value < const element * >()->default_value(boost::lexical_cast<const element *>(currentOption->getDefaultValue().c_str())) :
395 po::value < std::string >(),
396 currentOption->getDescription().c_str())
397 ;
398 break;
399 case TypeEnumContainer::ListOfElementsType:
400 OptionList->add_options()
401 (currentOption->getKeyAndShortForm().c_str(),
402// currentOption->hasDefaultValue() ?
403// po::value < std::vector<const element *> >()->default_value(boost::lexical_cast< std::vector<const element *> >(currentOption->getDefaultValue().c_str())) :
404 po::value < std::vector<std::string> >()->multitoken(),
405 currentOption->getDescription().c_str())
406 ;
407 break;
408 case TypeEnumContainer::RealSpaceMatrixType:
409 OptionList->add_options()
410 (currentOption->getKeyAndShortForm().c_str(),
411// currentOption->hasDefaultValue() ?
412// po::value < RealSpaceMatrixValue >()->default_value(boost::lexical_cast<BoxValue>(currentOption->getDefaultValue().c_str())) :
413 po::value < RealSpaceMatrixValue >(),
414 currentOption->getDescription().c_str())
415 ;
416 break;
417 case TypeEnumContainer::KeyValueType:
418 OptionList->add_options()
419 (currentOption->getKeyAndShortForm().c_str(),
420 currentOption->hasDefaultValue() ?
421 (_DefaultAsImplicit ?
422 po::value < KeyValuePair >()->implicit_value(boost::lexical_cast< KeyValuePair >(currentOption->getDefaultValue().c_str())) :
423 po::value < KeyValuePair >()->default_value(boost::lexical_cast< KeyValuePair >(currentOption->getDefaultValue().c_str()))) :
424 po::value < KeyValuePair >(),
425 currentOption->getDescription().c_str())
426 ;
427 break;
428 case TypeEnumContainer::ListOfKeyValuesType:
429 OptionList->add_options()
430 (currentOption->getKeyAndShortForm().c_str(),
431// currentOption->hasDefaultValue() ?
432// po::value < std::vector<KeyValuePair> >()->default_value(boost::lexical_cast< std::vector<KeyValuePair> >(currentOption->getDefaultValue().c_str())) :
433 po::value < std::vector<KeyValuePair> >()->multitoken(),
434 currentOption->getDescription().c_str())
435 ;
436 break;
437 }
438}
439
440/** States whether there are command line arguments.
441 * \return true - there are none, false - there is at least one command line argument
442 */
443bool CommandLineParser::isEmpty()
444{
445 return vm.empty();
446}
447
448/** Sets the options.
449 * \param _argc arg count from main()
450 * \param **_argv argument array from main()
451 */
452void CommandLineParser::setOptions(int _argc, char **_argv)
453{
454 argc = _argc;
455 argv = _argv;
456 config_file_options.add(options);
457 // append all option_descriptions to both cmdline_options and visible
458 for (CmdParserLookupMap::iterator iter = CmdParserLookup.begin();
459 iter != CmdParserLookup.end();
460 ++iter) {
461 cmdline_options.add(*(iter->second));
462 visible.add(*(iter->second));
463 }
464}
465
466/** This is due to the answer by Aleksey Vitebskiy
467 * in http://stackoverflow.com/questions/4107087/accepting-negative-doubles-with-boostprogram-options
468 *
469 */
470std::vector<po::option> ignore_numbers(std::vector<std::string>& args)
471{
472 std::vector<po::option> result;
473 int pos = 0;
474 while(!args.empty()) {
475 const std::string& arg = args[0];
476 bool isNumber = true;
477 try {
478 boost::lexical_cast<double>(arg);
479 } catch(boost::bad_lexical_cast) {
480 isNumber = false;
481 }
482 if (isNumber) {
483 result.push_back(po::option());
484 po::option& opt = result.back();
485
486 opt.position_key = pos++;
487 opt.value.push_back(arg);
488 opt.original_tokens.push_back(arg);
489
490 args.erase(args.begin());
491 } else {
492 break;
493 }
494 }
495
496 return result;
497}
498
499/** Parses the command line arguments.
500 * Calls program_options::store() and program_options::notify()
501 *
502 * @return true - all is ok, false - command-line options could not be parsed
503 * correctly
504 */
505bool CommandLineParser::Parse()
506{
507 bool status = true;
508 try {
509 po::store(po::command_line_parser(argc,argv).extra_style_parser(&ignore_numbers).options(cmdline_options).run(), vm);
510 } catch (std::exception &e) {
511 std::cerr << "Something went wrong with parsing the command-line arguments: "
512 << e.what() << std::endl;
513 World::getInstance().setExitFlag(134);
514#ifdef HAVE_ACTION_THREAD
515 // force action queue to stop thread
516 ActionQueue::getInstance().stop();
517 ActionQueue::getInstance().clearTempQueue();
518#endif
519 ActionQueue::getInstance().clearQueue();
520 status = false;
521 }
522 if (status) {
523 std::ifstream input;
524 input.open("example.cfg");
525 if (!input.fail())
526 po::store(po::parse_config_file(input, config_file_options), vm);
527 input.close();
528 po::notify(vm);
529 }
530 return status;
531}
532
533/** Scan the argument list for -a or --arguments and store their order for later use.
534 */
535void CommandLineParser::scanforSequenceOfArguments()
536{
537 std::map <std::string, std::string> ShortFormToActionMap = getShortFormToActionMap();
538 LOG(0, "Scanning command line arguments and recognizing Actions.");
539 // go through all arguments
540 for (int i=1;i<argc;i++) {
541 LOG(2, "Checking on " << argv[i]);
542 // check whether they
543 if (argv[i][0] == '-') { // .. begin with -
544 LOG(2, "Possible argument: " << argv[i]);
545 if (argv[i][1] == '-') { // .. or --
546 LOG(1, "Putting " << argv[i] << " into the sequence.");
547 SequenceOfActions.push_back(&(argv[i][2]));
548 // .. and check that next letter is not numeric, if so insert
549 } else if (((argv[i][1] < '0') || (argv[i][1] > '9')) && ((argv[i][1] != '.'))) {
550 std::map <std::string, std::string>::iterator iter = ShortFormToActionMap.find(&(argv[i][1]));
551 if (iter != ShortFormToActionMap.end()) {
552 LOG(1, "Putting " << iter->second << " for " << iter->first << " into the sequence.");
553 SequenceOfActions.push_back(iter->second);
554 }
555 }
556 }
557 }
558}
559
560/** Makes the Parser parse the command line options with current known options.
561 * \param _argc arg count from main()
562 * \param **_argv argument array from main()
563 */
564void CommandLineParser::Run(int _argc, char **_argv)
565{
566 setOptions(_argc,_argv);
567 const bool status = Parse();
568 if (status)
569 scanforSequenceOfArguments();
570}
571
572/** Go through all Actions and create a map from short form to their token.
573 * \return map from Action's ShortForm to token.
574 */
575std::map <std::string, std::string> CommandLineParser::getShortFormToActionMap() const
576{
577 std::map <std::string, std::string> result;
578
579 ActionQueue &AQ = ActionQueue::getInstance();
580 ActionQueue::ActionTokens_t tokens = AQ.getListOfActions();
581 for (ActionQueue::ActionTokens_t::const_iterator iter = tokens.begin();
582 iter != tokens.end(); ++iter) {
583 const ActionTrait &CurrentTrait = AQ.getActionsTrait(*iter);
584 if (CurrentTrait.hasShortForm()) {
585 ASSERT(result.find(CurrentTrait.getShortForm()) == result.end(),
586 "Short form "+toString(CurrentTrait.getShortForm())+
587 " for action "+toString(*iter)+" already present from "+
588 std::string(result[CurrentTrait.getShortForm()])+"!");
589 result[CurrentTrait.getShortForm()] = *iter;
590 }
591 }
592
593 return result;
594}
595
596CONSTRUCT_SINGLETON(CommandLineParser)
Note: See TracBrowser for help on using the repository browser.