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

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since f894fe was 3139b2, checked in by Frederik Heber <heber@…>, 13 years ago

Renamed ActionTrait and ActionTraits.

  • the specialized Trait contains multiple OptionTraits, hence is now called ActionTrait_s_, where its base class (that just has the OptionTrait for itself) is called ActionTrait.
  • This caused many changes in other Action related files.
  • Property mode set to 100644
File size: 20.1 KB
RevLine 
[e4afb4]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * CommandLineParser.cpp
10 *
11 * Created on: May 8, 2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
[ad011c]20#include "CodePatterns/MemDebug.hpp"
[e4afb4]21
22#include <boost/filesystem.hpp>
23#include <boost/program_options.hpp>
24#include <fstream>
25#include <iostream>
[5a8f38]26#include <set>
[e4afb4]27#include <map>
28
29#include "Actions/Action.hpp"
30#include "Actions/ActionRegistry.hpp"
[3139b2]31#include "Actions/ActionTrait.hpp"
[e4afb4]32#include "Actions/OptionRegistry.hpp"
33#include "Actions/OptionTrait.hpp"
34#include "Actions/Values.hpp"
[ad011c]35#include "CodePatterns/Log.hpp"
36#include "CodePatterns/Verbose.hpp"
[e4afb4]37#include "CommandLineParser.hpp"
[3a21a7]38#include "CommandLineParser_validate.hpp"
[e4afb4]39
[ad011c]40#include "CodePatterns/Singleton_impl.hpp"
[e4afb4]41
[ce7fdc]42using namespace MoleCuilder;
43
[e4afb4]44class element;
45
46/** Constructor of class CommandLineParser.
47 *
48 */
49CommandLineParser::CommandLineParser() :
50 analysis("Analysis options"),
51 atom("Atom options"),
52 command("Command options"),
53 fragmentation("Fragmentation options"),
[d09093]54 graph("Graph options"),
[e4afb4]55 molecule("Molecule options"),
[d09093]56 options("Secondary options"),
[e4afb4]57 parser("Parser options"),
58 selection("Selection options"),
59 tesselation("Tesselation options"),
[d09093]60 world("World options")
[e4afb4]61{
62 // put all options lists into a lookup
63 CmdParserLookup["analysis"] = &analysis;
64 CmdParserLookup["atom"] = &atom;
65 CmdParserLookup["command"] = &command;
66 CmdParserLookup["edit"] = &edit;
67 CmdParserLookup["fragmentation"] = &fragmentation;
[d09093]68 CmdParserLookup["graph"] = &graph;
69 CmdParserLookup["options"] = &options;
[e4afb4]70 CmdParserLookup["molecule"] = &molecule;
71 CmdParserLookup["parser"] = &parser;
72 CmdParserLookup["selection"] = &selection;
73 CmdParserLookup["tesselation"] = &tesselation;
74 CmdParserLookup["world"] = &world;
75}
76
77/** Destructor of class CommandLineParser.
78 *
79 */
80CommandLineParser::~CommandLineParser()
81{}
82
83/** Initializes command arguments to accept.
84 * Goes through ActionRegistry and puts all actions therein into the map.
85 */
86void CommandLineParser::InitializeCommandArguments()
87{
[5a8f38]88 // we need a list of already added options, otherwise we get ambigious exceptions
89 std::set<std::string> AlreadyAddedOptionNames;
90
[e4afb4]91 ActionRegistry &AR = ActionRegistry::getInstance();
92 bool ActionAlreadyAdded_flag = false;
93 for (ActionRegistry::const_iterator actioniter = AR.getBeginIter(); actioniter != AR.getEndIter(); ++actioniter) {
94 ActionAlreadyAdded_flag = false;
95 Action* const currentAction = actioniter->second;
96 //std::cout << "Current Action to initialize is: " << actioniter->first << std::endl;
97
[3139b2]98 for (ActionTrait::options_const_iterator optioniter = currentAction->Traits.getBeginIter();
[e4afb4]99 optioniter != currentAction->Traits.getEndIter();
100 ++optioniter) {
101 if (optioniter->first == actioniter->first)
102 ActionAlreadyAdded_flag = true;
103 ASSERT( OptionRegistry::getInstance().isOptionPresentByName(optioniter->first),
[5a8f38]104 "CommandLineParser::Init() - Option "+optioniter->first+" not present in OptionRegistry." );
[e4afb4]105 const OptionTrait* const currentOption = OptionRegistry::getInstance().getOptionByName(optioniter->first);
106
[5a8f38]107 if (AlreadyAddedOptionNames.find(optioniter->first) == AlreadyAddedOptionNames.end()) {
108 // add the option
109// std::cout << "Registering Option "
110// << currentOption->getName()
111// << " with type '" << currentOption->getTypeName() << "' "
112// << " with description '" << currentOption->getDescription() << "' ";
113// if (currentOption->hasShortForm())
114// std::cout << ", with short form " << currentOption->getShortForm();
115// else
116// std::cout << ", with no short form ";
117// if (currentOption->hasDefaultValue())
118// std::cout << ", with default value " << currentOption->getDefaultValue();
119// else
120// std::cout << ", with no default value ";
121// std::cout << std::endl;
122
123 AddOptionToParser(currentOption, (CmdParserLookup["options"]));
124
125 AlreadyAddedOptionNames.insert(optioniter->first);
126 } else {
127// std::cout << "Option " << currentOption->getName() << " already registered." << std::endl;
128 }
[e4afb4]129 }
130
131 if (!ActionAlreadyAdded_flag) {
132 // add the action
[ad7270]133// std::cout << "Registering Action "
134// << currentAction->Traits.getName()
135// << " in menu " << currentAction->Traits.getMenuName()
136// << " with type '" << currentAction->Traits.getTypeName() << "' "
137// << " with description '" << currentAction->Traits.getDescription() << "' ";
138// if (currentAction->Traits.hasShortForm())
139// std::cout << ", with short form " << currentAction->Traits.getShortForm();
140// else
141// std::cout << ", with no short form ";
142// if (currentAction->Traits.hasDefaultValue())
143// std::cout << ", with default value " << currentAction->Traits.getDefaultValue();
144// else
145// std::cout << ", with no default value ";
146// std::cout << std::endl;
[e4afb4]147
148 ASSERT(CmdParserLookup.find(currentAction->Traits.getMenuName()) != CmdParserLookup.end(),
149 "CommandLineParser: boost::program_options::options_description for this Action not present.");
150 AddOptionToParser(dynamic_cast<const OptionTrait * const>(&(currentAction->Traits)),(CmdParserLookup[currentAction->Traits.getMenuName()]));
151 }
152 }
153 // note: positioning is not important on the command line
154}
155
156/** Adds an Action or Option to the CommandLineParser.
157 * Note that Action is derived from Option(Trait)
158 *
159 * This ugly switch function is necessary because of the compile-time problem:
160 * po::value<T> has to be instantiated at compile-time however we do know the type not until run-time.
161 * Not even a templated function like po::value<T> getProgramOptionValuefromType() does help, specialized
162 * to each available type, as the signatures of all the functions differ. Hence, they cannot not put into
163 * one type_info -> po::value<T> map ...
164 *
165 * \param *currentOption pointer to Action/Option to add
166 * \param *OptionList program_options list to add to
167 */
168void CommandLineParser::AddOptionToParser(const OptionTrait * const currentOption, po::options_description* OptionList)
169{
170 // check whether dynamic_cast in Init() suceeded
171 ASSERT(currentOption != NULL, "CommandLineParser::AddOptionToParser() - currentOption is NULL!");
172 // add other options
[ec098d]173// std::cout << "Adding Action " << currentOption->getName() << " with type "
174// << currentOption->getType()->name() << ", " << (currentOption->hasDefaultValue() ? "with" : "without")
175// << " default value, and KeyandShortform " << currentOption->getKeyAndShortForm()
176// << " to CommandLineParser." << std::endl;
[e4afb4]177 switch(TypeToEnums.getEnumforType(currentOption->getType())) {
178 default:
179 case TypeEnumContainer::NoneType:
180 OptionList->add_options()
181 (currentOption->getKeyAndShortForm().c_str(), currentOption->getDescription().c_str())
182 ;
183 break;
184 case TypeEnumContainer::BooleanType:
185 OptionList->add_options()
186 (currentOption->getKeyAndShortForm().c_str(),
187 currentOption->hasDefaultValue() ?
188 po::value < bool >()->default_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str())) :
189 po::value < bool >(),
190 currentOption->getDescription().c_str())
191 ;
192 break;
193 case TypeEnumContainer::BoxType:
194 OptionList->add_options()
195 (currentOption->getKeyAndShortForm().c_str(),
196// currentOption->hasDefaultValue() ?
197// po::value < BoxValue >()->default_value(boost::lexical_cast<BoxValue>(currentOption->getDefaultValue().c_str())) :
198 po::value < BoxValue >(),
199 currentOption->getDescription().c_str())
200 ;
201 break;
202 case TypeEnumContainer::FileType:
203 OptionList->add_options()
204 (currentOption->getKeyAndShortForm().c_str(),
205// currentOption->hasDefaultValue() ?
206// po::value < boost::filesystem::path >()->default_value(boost::lexical_cast<boost::filesystem::path>(currentOption->getDefaultValue().c_str())) :
207 po::value < boost::filesystem::path >(),
208 currentOption->getDescription().c_str())
209 ;
210 break;
211 case TypeEnumContainer::ListOfFilesType:
212 OptionList->add_options()
213 (currentOption->getKeyAndShortForm().c_str(),
214// currentOption->hasDefaultValue() ?
215// po::value < std::vector<boost::filesystem::path> >()->default_value(boost::lexical_cast< std::vector<boost::filesystem::path> >(currentOption->getDefaultValue().c_str())) :
216 po::value < std::vector<boost::filesystem::path> >()->multitoken(),
217 currentOption->getDescription().c_str())
218 ;
219 break;
220 case TypeEnumContainer::IntegerType:
221 OptionList->add_options()
222 (currentOption->getKeyAndShortForm().c_str(),
223 currentOption->hasDefaultValue() ?
224 po::value < int >()->default_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str())) :
225 po::value < int >(),
226 currentOption->getDescription().c_str())
227 ;
228 break;
229 case TypeEnumContainer::ListOfIntegersType:
230 OptionList->add_options()
231 (currentOption->getKeyAndShortForm().c_str(),
232// currentOption->hasDefaultValue() ?
233// po::value < std::vector<int> >()->default_value(boost::lexical_cast< std::vector<int> >(currentOption->getDefaultValue().c_str())) :
234 po::value < std::vector<int> >()->multitoken(),
235 currentOption->getDescription().c_str())
236 ;
237 break;
[838cd0]238 case TypeEnumContainer::UnsignedIntegerType:
239 OptionList->add_options()
240 (currentOption->getKeyAndShortForm().c_str(),
241 currentOption->hasDefaultValue() ?
242 po::value < unsigned int >()->default_value(boost::lexical_cast<unsigned int>(currentOption->getDefaultValue().c_str())) :
243 po::value < unsigned int >(),
244 currentOption->getDescription().c_str())
245 ;
246 break;
[12948c]247 case TypeEnumContainer::ListOfUnsignedIntegersType:
248 OptionList->add_options()
249 (currentOption->getKeyAndShortForm().c_str(),
250// currentOption->hasDefaultValue() ?
251// po::value < std::vector<unsigned int> >()->default_value(boost::lexical_cast< std::vector<unsigned int> >(currentOption->getDefaultValue().c_str())) :
252 po::value < std::vector<unsigned int> >()->multitoken(),
253 currentOption->getDescription().c_str())
254 ;
255 break;
[e4afb4]256 case TypeEnumContainer::DoubleType:
257 OptionList->add_options()
258 (currentOption->getKeyAndShortForm().c_str(),
259 currentOption->hasDefaultValue() ?
260 po::value < double >()->default_value(boost::lexical_cast<double>(currentOption->getDefaultValue().c_str())) :
261 po::value < double >(),
262 currentOption->getDescription().c_str())
263 ;
264 break;
265 case TypeEnumContainer::ListOfDoublesType:
266 OptionList->add_options()
267 (currentOption->getKeyAndShortForm().c_str(),
268// currentOption->hasDefaultValue() ?
269// po::value < std::vector<double> >()->default_value(boost::lexical_cast< std::vector<double> >(currentOption->getDefaultValue().c_str())) :
270 po::value < std::vector<double> >()->multitoken(),
271 currentOption->getDescription().c_str())
272 ;
273 break;
274 case TypeEnumContainer::StringType:
275 OptionList->add_options()
276 (currentOption->getKeyAndShortForm().c_str(),
277 currentOption->hasDefaultValue() ?
278 po::value < std::string >()->default_value(currentOption->getDefaultValue()) :
279 po::value < std::string >(),
280 currentOption->getDescription().c_str())
281 ;
282 break;
283 case TypeEnumContainer::ListOfStringsType:
284 OptionList->add_options()
285 (currentOption->getKeyAndShortForm().c_str(),
286// currentOption->hasDefaultValue() ?
287// po::value < std::vector<std::string> >()->default_value(boost::lexical_cast< std::vector<std::string> >(currentOption->getDefaultValue().c_str())) :
288 po::value < std::vector<std::string> >()->multitoken(),
289 currentOption->getDescription().c_str())
290 ;
291 break;
292 case TypeEnumContainer::VectorType:
293 OptionList->add_options()
294 (currentOption->getKeyAndShortForm().c_str(),
295// currentOption->hasDefaultValue() ?
296// po::value < VectorValue >()->default_value(boost::lexical_cast<VectorValue>(currentOption->getDefaultValue().c_str())) :
297 po::value < VectorValue >(),
298 currentOption->getDescription().c_str())
299 ;
300 break;
301 case TypeEnumContainer::ListOfVectorsType:
302 OptionList->add_options()
303 (currentOption->getKeyAndShortForm().c_str(),
304// currentOption->hasDefaultValue() ?
305// po::value < std::vector<VectorValue> >()->default_value(boost::lexical_cast< std::vector<VectorValue> >(currentOption->getDefaultValue().c_str())) :
306 po::value < std::vector<VectorValue> >()->multitoken(),
307 currentOption->getDescription().c_str())
308 ;
309 break;
310 case TypeEnumContainer::MoleculeType:
311 OptionList->add_options()
312 (currentOption->getKeyAndShortForm().c_str(),
313// currentOption->hasDefaultValue() ?
314// po::value < const molecule * >()->default_value(boost::lexical_cast<const molecule *>(currentOption->getDefaultValue().c_str())) :
315 po::value < int >(),
316 currentOption->getDescription().c_str())
317 ;
318 break;
319 case TypeEnumContainer::ListOfMoleculesType:
320 OptionList->add_options()
321 (currentOption->getKeyAndShortForm().c_str(),
322// currentOption->hasDefaultValue() ?
323// po::value < std::vector<const molecule *> >()->default_value(boost::lexical_cast< std::vector<const molecule *> >(currentOption->getDefaultValue().c_str())) :
324 po::value < std::vector<int> >()->multitoken(),
325 currentOption->getDescription().c_str())
326 ;
327 break;
328 case TypeEnumContainer::AtomType:
329 OptionList->add_options()
330 (currentOption->getKeyAndShortForm().c_str(),
331 currentOption->hasDefaultValue() ?
332 po::value < int >()->default_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str())) :
333 po::value < int >(),
334 currentOption->getDescription().c_str())
335 ;
336 break;
337 case TypeEnumContainer::ListOfAtomsType:
338 OptionList->add_options()
339 (currentOption->getKeyAndShortForm().c_str(),
340// currentOption->hasDefaultValue() ?
341// po::value < std::vector<const atom *> >()->default_value(boost::lexical_cast< std::vector<const atom *> >(currentOption->getDefaultValue().c_str())) :
342 po::value < std::vector<int> >()->multitoken(),
343 currentOption->getDescription().c_str())
344 ;
345 break;
346 case TypeEnumContainer::ElementType:
347 OptionList->add_options()
348 (currentOption->getKeyAndShortForm().c_str(),
349// currentOption->hasDefaultValue() ?
350// po::value < const element * >()->default_value(boost::lexical_cast<const element *>(currentOption->getDefaultValue().c_str())) :
351 po::value < int >(),
352 currentOption->getDescription().c_str())
353 ;
354 break;
355 case TypeEnumContainer::ListOfElementsType:
356 OptionList->add_options()
357 (currentOption->getKeyAndShortForm().c_str(),
358// currentOption->hasDefaultValue() ?
359// po::value < std::vector<const element *> >()->default_value(boost::lexical_cast< std::vector<const element *> >(currentOption->getDefaultValue().c_str())) :
360 po::value < std::vector<int> >()->multitoken(),
361 currentOption->getDescription().c_str())
362 ;
363 break;
[0275ad]364 case TypeEnumContainer::RandomNumberDistribution_ParametersType:
365 OptionList->add_options()
366 (currentOption->getKeyAndShortForm().c_str(),
367 currentOption->hasDefaultValue() ?
368 po::value < std::string >()->default_value(boost::lexical_cast< std::string >(currentOption->getDefaultValue().c_str())) :
369 po::value < std::string >(),
370 currentOption->getDescription().c_str())
371 ;
372 break;
[e4afb4]373 }
374}
375
376/** States whether there are command line arguments.
377 * \return true - there are none, false - there is at least one command line argument
378 */
379bool CommandLineParser::isEmpty()
380{
381 return vm.empty();
382}
383
384/** Sets the options.
385 * \param _argc arg count from main()
386 * \param **_argv argument array from main()
387 */
388void CommandLineParser::setOptions(int _argc, char **_argv)
389{
390 argc = _argc;
391 argv = _argv;
392 config_file_options.add(options);
[c6e5eb]393 // append all option_descriptions to both cmdline_options and visible
394 for (CmdParserLookupMap::iterator iter = CmdParserLookup.begin();
395 iter != CmdParserLookup.end();
396 ++iter) {
397 cmdline_options.add(*(iter->second));
398 visible.add(*(iter->second));
399 }
[e4afb4]400}
401
402/** Parses the command line arguments.
403 * Calls program_options::store() and program_options::notify()
404 */
405void CommandLineParser::Parse()
406{
407 po::store(po::command_line_parser(argc,argv).options(cmdline_options).run(), vm);
[3a21a7]408 std::ifstream input;
[e4afb4]409 input.open("example.cfg");
410 if (!input.fail())
411 po::store(po::parse_config_file(input, config_file_options), vm);
412 input.close();
413 po::notify(vm);
414}
415
416/** Scan the argument list for -a or --arguments and store their order for later use.
417 */
418void CommandLineParser::scanforSequenceOfArguments()
419{
[3a21a7]420 std::map <std::string, std::string> ShortFormToActionMap = getShortFormToActionMap();
[47d041]421 LOG(0, "Scanning command line arguments and recognizing Actions.");
[e4afb4]422 // go through all arguments
423 for (int i=1;i<argc;i++) {
[47d041]424 LOG(2, "Checking on " << argv[i]);
[e4afb4]425 // check whether they
426 if (argv[i][0] == '-') { // .. begin with -
[47d041]427 LOG(2, "Possible argument: " << argv[i]);
[e4afb4]428 if (argv[i][1] == '-') { // .. or --
[47d041]429 LOG(1, "Putting " << argv[i] << " into the sequence.");
[e4afb4]430 SequenceOfActions.push_back(&(argv[i][2]));
431 // .. and check that next letter is not numeric, if so insert
432 } else if (((argv[i][1] < '0') || (argv[i][1] > '9')) && ((argv[i][1] != '.'))) {
[3a21a7]433 std::map <std::string, std::string>::iterator iter = ShortFormToActionMap.find(&(argv[i][1]));
[e4afb4]434 if (iter != ShortFormToActionMap.end()) {
[47d041]435 LOG(1, "Putting " << iter->second << " for " << iter->first << " into the sequence.");
[e4afb4]436 SequenceOfActions.push_back(iter->second);
437 }
438 }
439 }
440 }
441}
442
443/** Makes the Parser parse the command line options with current known options.
444 * \param _argc arg count from main()
445 * \param **_argv argument array from main()
446 */
447void CommandLineParser::Run(int _argc, char **_argv)
448{
449 setOptions(_argc,_argv);
450 Parse();
451 scanforSequenceOfArguments();
452}
453
454/** Go through all Actions and create a map from short form to their token.
455 * \return map from Action's ShortForm to token.
456 */
[2a0a9e3]457std::map <std::string, std::string> CommandLineParser::getShortFormToActionMap() const
[e4afb4]458{
[3a21a7]459 std::map <std::string, std::string> result;
[e4afb4]460
461 ActionRegistry &AR = ActionRegistry::getInstance();
462 for (ActionRegistry::const_iterator iter = AR.getBeginIter(); iter != AR.getEndIter(); ++iter)
463 if ((iter->second)->Traits.hasShortForm()) {
464 ASSERT(result.find((iter->second)->Traits.getShortForm()) == result.end(),
[cfc53b]465 "Short form "+toString((iter->second)->Traits.getShortForm())+
466 " for action "+toString(iter->first)+" already present from "+
[e4afb4]467 std::string(result[(iter->second)->Traits.getShortForm()])+"!");
468 result[(iter->second)->Traits.getShortForm()] = (iter->second)->getName();
469 }
470
471 return result;
472}
473
474CONSTRUCT_SINGLETON(CommandLineParser)
Note: See TracBrowser for help on using the repository browser.