28 for (
auto& it : parameters)
41 PopulateRawArgs(argc, argv);
44 ExpandAbbreviations();
46 executableName = std::string(rawArgs[0]);
50 while (i < rawArgs.size())
52 if ((rawArgs[i].length() > 2) && (rawArgs[i].substr(0, 2) ==
"--"))
55 i = ParseNextParameter(i, param);
57 parameters.insert(std::pair<std::string, Parameter*>(param->
Key(), param));
66 if ((!catchHelp) || (!
HasParam(
"--help")))
74 std::cerr <<
"Parameter error: " << exc.
What() << std::endl;
85 std::cerr <<
"Parameter error: " << exc.
What() << std::endl;
96 std::cerr <<
"Parameter error: " << exc.
What() << std::endl;
107 std::cerr <<
"Parameter error: " << exc.
What() << std::endl;
118 std::cerr <<
"Parameter error: " << exc.
What() << std::endl;
126 if ((catchHelp) && (
HasParam(
"--help")))
135 std::size_t CmdArgsInterface::ParseNextParameter(
const std::size_t parIndex,
Parameter*& out_Par)
137 std::size_t i = parIndex;
138 const std::string key = rawArgs[parIndex];
139 std::vector<std::string> values;
142 for (i++; i < rawArgs.size(); i++)
144 if ((rawArgs[i].length() < 2) || (rawArgs[i].substr(0, 2) !=
"--"))
145 values.emplace_back(rawArgs[i]);
154 Value* parsedVal = ParseValue(values, pcn);
155 if (parsedVal !=
nullptr)
163 throw std::runtime_error(
"Unable to parse parameter!");
168 void CmdArgsInterface::PopulateRawArgs(
const int argc,
const char*
const* argv)
171 rawArgs.reserve(argc);
173 for (
int i = 0; i < argc; i++)
174 rawArgs.emplace_back(std::string(argv[i]));
179 void CmdArgsInterface::ExpandAbbreviations()
182 if (parameterAbreviations.size() == 0)
185 for (std::string& arg : rawArgs)
188 auto abbr = parameterAbreviations.find(arg);
189 if (abbr != parameterAbreviations.end())
201 return parameters.find(key) != parameters.end();
204 Value* CmdArgsInterface::ParseValue(
const std::vector<std::string>& values,
const ParamConstraint* constraint)
210 const bool constrainType = (constraint !=
nullptr) && (constraint->
constrainType);
213 if (values.size() == 0)
218 if ((constrainType) &&
223 else if ((constrainType) &&
228 else if ((constrainType) &&
243 else if ((constrainType) &&
250 else if (values.size() > 1)
255 if ((constrainType) &&
267 for (
const std::string& val : values)
269 Value* tmp = ParseValue({ val });
277 const std::string& val = values[0];
286 if ((constrainType) &&
293 Value* tmp = ParseValue({ val });
314 if ((constrainType) &&
332 return new IntValue((
long long int)num);
340 Value* tmp = ParseValue({ val });
352 return new IntValue((
long long int)num);
370 this->catchHelp = catchHelp;
381 briefDescription = description;
387 return briefDescription;
392 parameterDescriptions[parameter] = description;
404 return parameterDescriptions.find(parameter)->second;
409 return parameterDescriptions.find(parameter) != parameterDescriptions.end();
415 parameterDescriptions.erase(parameter);
421 parameterDescriptions.clear();
427 std::stringstream ss;
430 if (briefDescription.length() > 0)
431 ss << briefDescription << std::endl;
436 std::string abbreviation;
437 std::string description;
439 bool required =
false;
440 bool typeIsForced =
false;
441 std::string defaultVal;
442 std::string incompatibilities;
444 std::unordered_map<std::string, ParamDocEntry> paramInfos;
447 for (
const auto& it : parameterDescriptions)
450 if (paramInfos.find(it.first) == paramInfos.end())
452 paramInfos[it.first] = ParamDocEntry();
454 paramInfos[it.first].description = it.second;
459 for (
const auto& it : parameterAbreviations)
462 if (paramInfos.find(it.second) == paramInfos.end())
464 paramInfos[it.second] = ParamDocEntry();
466 paramInfos[it.second].abbreviation = it.first;
470 for (
const auto& it : parameterConstraints)
473 if (paramInfos.find(it.first) == paramInfos.end())
475 paramInfos[it.first] = ParamDocEntry();
477 ParamDocEntry& cached = paramInfos[it.first];
478 cached.required = it.second.required;
479 cached.typeIsForced = it.second.constrainType;
483 std::stringstream vec2str_ss;
484 for (
const std::string& s : it.second.defaultValue)
486 vec2str_ss <<
'\'' << s <<
'\'';
489 if ((
void*)&s != (
void*)&it.second.defaultValue.back())
492 cached.defaultVal = vec2str_ss.str();
497 for (
const std::string& s : it.second.incompatibleParameters)
502 if ((
void*)&s != (
void*)&it.second.incompatibleParameters.back())
505 cached.incompatibilities = vec2str_ss.str();
509 if (paramInfos.size() > 0)
512 <<
"==== AVAILABLE PARAMETERS ====" 513 << std::endl << std::endl;
515 std::size_t counter = 0;
516 for (
const auto& it : paramInfos)
518 const ParamDocEntry& pde = it.second;
521 ss << it.first <<
" ";
524 if (pde.abbreviation.length() > 0)
525 ss << pde.abbreviation <<
" ";
528 if (pde.typeIsForced)
529 ss << pde.type <<
" ";
532 if (pde.defaultVal.length() > 0)
533 ss <<
"default=[" << pde.defaultVal <<
"] ";
536 if (pde.incompatibilities.length() > 0)
537 ss <<
"incompatibilities=[" << pde.incompatibilities <<
"] ";
540 if ((pde.required) && (pde.defaultVal.length() == 0))
541 ss <<
"[[REQUIRED]] ";
544 if (pde.description.length() > 0)
545 ss << pde.description;
548 if (counter < paramInfos.size()-1)
549 ss << std::endl << std::endl;
558 void CmdArgsInterface::ApplyConstraints()
561 for (
const auto& pc : parameterConstraints)
566 if (pc.second.defaultValue.size() > 0)
569 Value* tmp = ParseValue(pc.second.defaultValue, &pc.second);
570 parameters.insert(std::pair<std::string, Parameter*>(
582 if (pc.second.required)
596 for (
const std::string& incompatibility : pc.second.incompatibleParameters)
597 for (
const auto& otherParam : parameters)
599 if (otherParam.first == incompatibility)
609 return parameterConstraints.find(parameter)->second;
614 parameterConstraints.erase(parameter);
620 return executableName;
629 return *parameters.find(key)->second->GetValue();
634 parameterAbreviations.insert(std::pair<std::string, std::string>(abbrev, target));
643 return parameterAbreviations.find(abbrev)->second;
648 return parameterAbreviations.find(abbrev) != parameterAbreviations.end();
653 parameterAbreviations.erase(abbrevation);
659 parameterAbreviations.clear();
666 (parameterConstraints[key] = constraint).key = key;
672 parameterConstraints.clear();
678 this->crashOnFail = crashOnFail;
682 const ParamConstraint* CmdArgsInterface::GetConstraintForKey(
const std::string& key)
const 684 const auto constraint = parameterConstraints.find(key);
686 if (constraint == parameterConstraints.end())
689 return &constraint->second;
bool HasAbbreviation(const std::string &abbrev) const
Will check wether or not an abbreviation is registered.
Specializations for void values.
const Value & operator[](const std::string &key) const
Will return the value given a key.
Specializations for string values (uses std::string)
bool GetCrashOnFail() const
Gets whether the application crashes on an exception whilst parsing, and prints to stderr...
static const std::string g_emptyString
The only purpose of this is to provide the ability to return an empty string as an error for std::str...
Specializations for integer values (uses long long int)
const std::string & Key() const
Will return the key of this parameter.
Gets thrown when a parameter is of a type that does not match the required type, and is not convertib...
void Parse(const int argc, const char *const *argv)
Will parse command line arguments.
Specializations for floating point values (uses long double)
bool GetCatchHelp() const
Retruns whether the CmdArgsInterface should automatically catch the –help parameter, print the parameter documentation to stdout, and exit or not.
Gets thrown something bad happens because of parameter constraints.
const std::string & What() const
Will return an error message.
void RegisterDescription(const std::string ¶meter, const std::string &description)
Willl register a short description for a parameter.
Specializations for list values (uses std::vector<Value*>)
DATA_TYPE requiredType
Constrain the parameter to this value. Requires constrainType to be set to true.
const std::string & GetBriefDescription()
Returns the brief description of the application to be automatically added to the documentation...
const std::string & GetAbbreviation(const std::string &abbrev) const
Will return the long form of an abbreviation (like –force for -f) Returns "" if no match is found...
void SetCatchHelp(bool catchHelp)
Sets whether the CmdArgsInterface should automatically catch the –help parameter, print the parameter documentation to stdout, and exit or not.
void RegisterConstraint(const std::string &key, const ParamConstraint &constraint)
Will register a constraint for a parameter.
const std::string & GetDescription(const std::string ¶meter) const
Will return a short description for a parameter, if it exists.
Gets thrown when a parameter constrained to be required is not provided, and has no default value set...
ParamConstraint GetConstraint(const std::string ¶meter) const
Will return the constraint information for a specific parameter.
void ClearDescription(const std::string ¶meter)
Will delete the description of a parameter if it exists.
void ClearConstraint(const std::string ¶meter)
Will the constraint of a specific parameter.
void SetBriefDescription(const std::string &description)
Sets a brief description of the application to be automatically added to the documentation.
void ClearConstraints()
Will delete all constraints.
std::string GenerateDocumentation() const
Will generate a text-based documentation suited to show the user, for example on –help.
void ClearAbbreviations()
Will delete all abbreviations.
void ClearAbbreviation(const std::string &abbrevation)
Will delete the abbreviation for a given parameter.
static std::string DataTypeToString(DATA_TYPE type)
void RegisterAbbreviation(const std::string &abbrev, const std::string &target)
Will register an abbreviation (like -f for –force)
Generic hazelnupp exception.
void ClearDescriptions()
Will delete all parameter descriptions.
Abstract class for values.
bool HasParam(const std::string &key) const
Will check wether a parameter exists given a key, or not.
bool constrainType
Should this parameter be forced to be of a certain type? Remember to set constrainTo to the wanted ty...
bool HasDescription(const std::string ¶meter) const
Returns whether or not a given parameter has a registered description.
DATA_TYPE
The different data types a paramater can be.
Gets thrown when an non-existent key gets dereferenced.
void SetCrashOnFail(bool crashOnFail)
Sets whether to crash the application, and print to stderr, when an exception is raised whilst parsin...
Gets thrown when a parameter constrained to be incompatible with other parameters gets supplied along...
void AddValue(const Value *value)
Will add this value to the list.
const std::string & GetExecutableName() const
Will return argv[0], the name of the executable.