source: src/UIElements/CommandLineUI/CommandLineParser.cpp@ a5f2fa

ForceAnnealing_goodresults ForceAnnealing_tocheck
Last change on this file since a5f2fa was a5f2fa, 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
RevLine 
[e4afb4]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
[0aa122]4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
[94d5ac6]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/>.
[e4afb4]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
[9eb71b3]35//#include "CodePatterns/MemDebug.hpp"
[e4afb4]36
37#include <boost/filesystem.hpp>
[a5f2fa]38#include <boost/lexical_cast.hpp>
39#include <boost/program_options/option.hpp>
40#include <boost/program_options/value_semantic.hpp>
[e4afb4]41#include <boost/program_options.hpp>
42#include <fstream>
43#include <iostream>
[5a8f38]44#include <set>
[e4afb4]45#include <map>
46
47#include "Actions/Action.hpp"
[628577]48#include "Actions/ActionQueue.hpp"
[3139b2]49#include "Actions/ActionTrait.hpp"
[e4afb4]50#include "Actions/OptionRegistry.hpp"
51#include "Actions/OptionTrait.hpp"
52#include "Actions/Values.hpp"
[ad011c]53#include "CodePatterns/Log.hpp"
54#include "CodePatterns/Verbose.hpp"
[e4afb4]55#include "CommandLineParser.hpp"
[3a21a7]56#include "CommandLineParser_validate.hpp"
[33e801]57#include "Parameters/Specifics/KeyValuePair.hpp"
[11d433]58#include "World.hpp"
[e4afb4]59
[ad011c]60#include "CodePatterns/Singleton_impl.hpp"
[e4afb4]61
[ce7fdc]62using namespace MoleCuilder;
63
[e4afb4]64class element;
65
66/** Constructor of class CommandLineParser.
67 *
68 */
69CommandLineParser::CommandLineParser() :
70 analysis("Analysis options"),
71 atom("Atom options"),
[f63e41]72 bond("Bond options"),
[e4afb4]73 command("Command options"),
[a88452]74 fill("fill options"),
[4dc309]75 shape("shape options"),
[e4afb4]76 fragmentation("Fragmentation options"),
[d09093]77 graph("Graph options"),
[e4afb4]78 molecule("Molecule options"),
[d09093]79 options("Secondary options"),
[e4afb4]80 parser("Parser options"),
[f5724f]81 potential("Potential options"),
[e4afb4]82 selection("Selection options"),
83 tesselation("Tesselation options"),
[d09093]84 world("World options")
[e4afb4]85{
86 // put all options lists into a lookup
87 CmdParserLookup["analysis"] = &analysis;
88 CmdParserLookup["atom"] = &atom;
[f63e41]89 CmdParserLookup["bond"] = &bond;
[e4afb4]90 CmdParserLookup["command"] = &command;
91 CmdParserLookup["edit"] = &edit;
[a88452]92 CmdParserLookup["fill"] = &fill;
[4dc309]93 CmdParserLookup["shape"] = &shape;
[e4afb4]94 CmdParserLookup["fragmentation"] = &fragmentation;
[d09093]95 CmdParserLookup["graph"] = &graph;
96 CmdParserLookup["options"] = &options;
[e4afb4]97 CmdParserLookup["molecule"] = &molecule;
98 CmdParserLookup["parser"] = &parser;
[f5724f]99 CmdParserLookup["potential"] = &potential;
[e4afb4]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{
[5a8f38]116 // we need a list of already added options, otherwise we get ambigious exceptions
117 std::set<std::string> AlreadyAddedOptionNames;
118
[e4afb4]119 bool ActionAlreadyAdded_flag = false;
[690741]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);
[e4afb4]125 ActionAlreadyAdded_flag = false;
126 //std::cout << "Current Action to initialize is: " << actioniter->first << std::endl;
127
[690741]128 for (ActionTrait::options_const_iterator optioniter = CurrentTrait.getBeginIter();
129 optioniter != CurrentTrait.getEndIter();
[e4afb4]130 ++optioniter) {
[690741]131 if (optioniter->first == *iter)
[e4afb4]132 ActionAlreadyAdded_flag = true;
133 ASSERT( OptionRegistry::getInstance().isOptionPresentByName(optioniter->first),
[5a8f38]134 "CommandLineParser::Init() - Option "+optioniter->first+" not present in OptionRegistry." );
[e4afb4]135 const OptionTrait* const currentOption = OptionRegistry::getInstance().getOptionByName(optioniter->first);
136
[5a8f38]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
[7912e9]153 AddOptionToParser(currentOption, (CmdParserLookup["options"]),
154 (optioniter->first == *iter) ?
155 true : false);
[5a8f38]156
157 AlreadyAddedOptionNames.insert(optioniter->first);
158 } else {
159// std::cout << "Option " << currentOption->getName() << " already registered." << std::endl;
160 }
[e4afb4]161 }
162
163 if (!ActionAlreadyAdded_flag) {
164 // add the action
[ad7270]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;
[e4afb4]179
[690741]180 ASSERT(CmdParserLookup.find(CurrentTrait.getMenuName()) != CmdParserLookup.end(),
[e4afb4]181 "CommandLineParser: boost::program_options::options_description for this Action not present.");
[7912e9]182 AddOptionToParser(
183 dynamic_cast<const OptionTrait * const>(&CurrentTrait),
184 (CmdParserLookup[CurrentTrait.getMenuName()]),
185 false);
[e4afb4]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
[7912e9]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)
[e4afb4]205 */
[7912e9]206void CommandLineParser::AddOptionToParser(
207 const OptionTrait * const currentOption,
208 po::options_description* OptionList,
209 const bool _DefaultAsImplicit)
[e4afb4]210{
211 // check whether dynamic_cast in Init() suceeded
212 ASSERT(currentOption != NULL, "CommandLineParser::AddOptionToParser() - currentOption is NULL!");
213 // add other options
[ec098d]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;
[e4afb4]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() ?
[7912e9]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()))) :
[e4afb4]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() ?
[7912e9]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()))) :
[e4afb4]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;
[838cd0]274 case TypeEnumContainer::UnsignedIntegerType:
275 OptionList->add_options()
276 (currentOption->getKeyAndShortForm().c_str(),
277 currentOption->hasDefaultValue() ?
[7912e9]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()))) :
[838cd0]281 po::value < unsigned int >(),
282 currentOption->getDescription().c_str())
283 ;
284 break;
[12948c]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;
[e4afb4]294 case TypeEnumContainer::DoubleType:
295 OptionList->add_options()
296 (currentOption->getKeyAndShortForm().c_str(),
297 currentOption->hasDefaultValue() ?
[7912e9]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()))) :
[e4afb4]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() ?
[7912e9]318 (_DefaultAsImplicit ?
319 po::value < std::string >()->implicit_value(currentOption->getDefaultValue()) :
320 po::value < std::string >()->default_value(currentOption->getDefaultValue())) :
[e4afb4]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() ?
[7912e9]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()))) :
[e4afb4]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())) :
[2f429e]395 po::value < std::string >(),
[e4afb4]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())) :
[2f429e]404 po::value < std::vector<std::string> >()->multitoken(),
[e4afb4]405 currentOption->getDescription().c_str())
406 ;
407 break;
[7d9416]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;
[33e801]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;
[e4afb4]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);
[c6e5eb]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 }
[e4afb4]464}
465
[a5f2fa]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
[e4afb4]499/** Parses the command line arguments.
500 * Calls program_options::store() and program_options::notify()
[06b5df]501 *
502 * @return true - all is ok, false - command-line options could not be parsed
503 * correctly
[e4afb4]504 */
[06b5df]505bool CommandLineParser::Parse()
[e4afb4]506{
[06b5df]507 bool status = true;
[11d433]508 try {
[a5f2fa]509 po::store(po::command_line_parser(argc,argv).extra_style_parser(&ignore_numbers).options(cmdline_options).run(), vm);
[11d433]510 } catch (std::exception &e) {
[7912e9]511 std::cerr << "Something went wrong with parsing the command-line arguments: "
512 << e.what() << std::endl;
[11d433]513 World::getInstance().setExitFlag(134);
514#ifdef HAVE_ACTION_THREAD
515 // force action queue to stop thread
516 ActionQueue::getInstance().stop();
[601ef8]517 ActionQueue::getInstance().clearTempQueue();
[11d433]518#endif
519 ActionQueue::getInstance().clearQueue();
[06b5df]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);
[11d433]529 }
[06b5df]530 return status;
[e4afb4]531}
532
533/** Scan the argument list for -a or --arguments and store their order for later use.
534 */
535void CommandLineParser::scanforSequenceOfArguments()
536{
[3a21a7]537 std::map <std::string, std::string> ShortFormToActionMap = getShortFormToActionMap();
[47d041]538 LOG(0, "Scanning command line arguments and recognizing Actions.");
[e4afb4]539 // go through all arguments
540 for (int i=1;i<argc;i++) {
[47d041]541 LOG(2, "Checking on " << argv[i]);
[e4afb4]542 // check whether they
543 if (argv[i][0] == '-') { // .. begin with -
[47d041]544 LOG(2, "Possible argument: " << argv[i]);
[e4afb4]545 if (argv[i][1] == '-') { // .. or --
[47d041]546 LOG(1, "Putting " << argv[i] << " into the sequence.");
[e4afb4]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] != '.'))) {
[3a21a7]550 std::map <std::string, std::string>::iterator iter = ShortFormToActionMap.find(&(argv[i][1]));
[e4afb4]551 if (iter != ShortFormToActionMap.end()) {
[47d041]552 LOG(1, "Putting " << iter->second << " for " << iter->first << " into the sequence.");
[e4afb4]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);
[06b5df]567 const bool status = Parse();
568 if (status)
569 scanforSequenceOfArguments();
[e4afb4]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 */
[2a0a9e3]575std::map <std::string, std::string> CommandLineParser::getShortFormToActionMap() const
[e4afb4]576{
[3a21a7]577 std::map <std::string, std::string> result;
[e4afb4]578
[690741]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;
[e4afb4]590 }
[690741]591 }
[e4afb4]592
593 return result;
594}
595
596CONSTRUCT_SINGLETON(CommandLineParser)
Note: See TracBrowser for help on using the repository browser.