source: src/UIElements/CommandLineUI/CommandLineParser.cpp@ 7963c8

ForceAnnealing_with_BondGraph_continued_betteresults
Last change on this file since 7963c8 was 78ea3c, checked in by Frederik Heber <frederik.heber@…>, 8 years ago

Merge branch 'Docu_Python_wait' into Candidate_v1.6.1

Conflicts:

tests/Python/AllActions/options.dat

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