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

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 f0f9a6 was e4afb4, checked in by Frederik Heber <heber@…>, 15 years ago

Huge refactoring: Introduction of Traits to Actions.

This change is really big but the introduction of the Trait concept (at least
in its current light form) is so fundamental that lots of pieces had to be
changed in order to get everything working.

The main point why it was necessary to add these traits in the first place was
to comfortably allow for adding extension of Actions information-wise, i.e.
with stuff that is only important for the QtUI, such as icons, or tooltips, ...
This extra information should not be stored with Action itself, as it has
nothing to do with the workings of the Action. And neither should it get
stored with some blown-out-of-proportions MapOfActions class ...

The gist of the change is as follows:

  • OptionTrait contains the token, description, shortform and type of an option, such as ("position", "position in space, none, typeid(Vector)).
  • ActionTrait is the derived form for actions where additionally MenuPosition and MenuName are stored (and probably more to come for the GUI), also we have a set of OptionTrait instances, one for each option of the Action.
  • Action then contains this ActionTrait, specialized for each Action.
  • the preprocessor macros have been enhanced to gather all this information from the .def files.
  • MapOfActions is gone. Completely. Most of its use was to store this extra information and the ValueStorage part now is just in class ValueStorage.
  • ValueStorage is no more an interface to MapOfActions but as the name says a (type-safe) ValueStorage.

Listing the (remaining) changes in alphabetical order of the class:

  • Action
    • member value ::name dropped, ::getName() uses ActionTraits::getName()
    • new define NODEFAULT which is used in paramdefaults in .def files
    • all derived actions classes such as Process, Calculations, MakroAction,... have been adapated to use the ActionTrait concept as well.
  • ActionHistory
    • extraced RedoAction and UndoAction, shifted implementation into their own object files and they use .def files as well (i.e. streamlined with method used for other actions)
  • MenuDescription
    • contain information on Menus such as name, ...
    • new unit test checks for consistency
  • molecule
    • const member functions: Copy(), Output() and OutputBonds()
  • OptionRegistry
    • new registry class for options only
    • we want the same type throughout the code for each token, e.g. "position"
    • the registry containts checks for consistency
  • OptionTrait
    • default values are specified in paramdefaults, none are given by NODEFAULT
    • introduced default for translate-atoms, point-correlation, pair-correlation
  • Registry pattern
    • new unit test, but only sceleton code so far
  • ...Query, also ...Pipe
    • atoms, molecule and elements are now all const
    • also ValueStorage's signatures all have const therein
  • ValueStorage
    • set/queryCurrentValue from MapOfActions
    • at times VectorValue has been in .def files where Vector was in the signature. This is cleared. Such stuff is only present for e.g. BoxVector being queried as a Vector. But this is a feature and intended.
  • World
    • most of the (un)selection functions now work on const atoms and molecules
    • in one case we need a const_cast to remove this, but this is intentional, as the vector of selected atoms stores non-const pointers and this is ok.

There is only one test which had to be changed slightly because a specific
option token as "position" must now have the same type everywhere, e.g. always
Vector.

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