source: src/UIElements/CommandLineUI/CommandLineParser.cpp@ 5a8840

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 5a8840 was 12948c, checked in by Frederik Heber <heber@…>, 14 years ago

Added new Query for std::vector of unsigned int.

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