27 for (
auto& it : parameters)
40 PopulateRawArgs(argc, argv);
43 ExpandAbbreviations();
45 executableName = std::string(rawArgs[0]);
48 while (i < rawArgs.size())
50 if ((rawArgs[i].length() > 2) && (rawArgs[i].substr(0, 2) ==
"--"))
53 i = ParseNextParameter(i, param);
55 parameters.insert(std::pair<std::string, Parameter*>(param->
Key(), param));
64 if ((!catchHelp) || (!
HasParam(
"--help")))
72 std::cerr <<
"Fatal error: Command-line parameter value-type mismatch at \"" << hctm.
What() <<
"\"!";
83 std::cerr <<
"Fatal error: Missing required command-line parameter \"" << hctm.
What() <<
"\"!";
91 if ((catchHelp) && (
HasParam(
"--help")))
100 std::size_t Hazelnupp::ParseNextParameter(
const std::size_t parIndex,
Parameter*& out_Par)
102 std::size_t i = parIndex;
103 const std::string key = rawArgs[parIndex];
104 std::vector<std::string> values;
107 for (i++; i < rawArgs.size(); i++)
109 if ((rawArgs[i].length() < 2) || (rawArgs[i].substr(0, 2) !=
"--"))
110 values.emplace_back(rawArgs[i]);
119 Value* parsedVal = ParseValue(values, pcn);
120 if (parsedVal !=
nullptr)
128 throw std::runtime_error(
"Unable to parse parameter!");
133 void Hazelnupp::PopulateRawArgs(
const int argc,
const char*
const* argv)
136 rawArgs.reserve(argc);
138 for (
int i = 0; i < argc; i++)
139 rawArgs.emplace_back(std::string(argv[i]));
144 void Hazelnupp::ExpandAbbreviations()
147 if (abbreviations.size() == 0)
150 for (std::string& arg : rawArgs)
153 auto abbr = abbreviations.find(arg);
154 if (abbr != abbreviations.end())
166 return parameters.find(key) != parameters.end();
169 Value* Hazelnupp::ParseValue(
const std::vector<std::string>& values,
const ParamConstraint* constraint)
172 const bool constrainType = (constraint !=
nullptr) && (constraint->
constrainType);
175 if (values.size() == 0)
178 if ((constrainType) &&
186 if ((constrainType) &&
193 else if (values.size() > 1)
196 if ((constrainType) &&
203 for (
const std::string& val : values)
205 Value* tmp = ParseValue({ val });
213 const std::string& val = values[0];
220 if ((constrainType) &&
227 Value* tmp = ParseValue({ val });
243 if ((constrainType) &&
259 return new IntValue((
long long int)num);
267 Value* tmp = ParseValue({ val });
279 return new IntValue((
long long int)num);
297 this->catchHelp = catchHelp;
308 briefDescription = description;
314 return briefDescription;
319 parameterDescriptions[parameter] = description;
326 const auto par = parameterDescriptions.find(parameter);
327 if (par == parameterDescriptions.end())
338 parameterDescriptions.erase(parameter);
344 std::stringstream ss;
347 if (briefDescription.length() > 0)
348 ss << briefDescription << std::endl;
353 std::string abbreviation;
354 std::string description;
356 bool required =
false;
357 bool typeIsForced =
false;
358 std::string defaultVal;
360 std::unordered_map<std::string, ParamDocEntry> paramInfos;
363 for (
const auto& it : parameterDescriptions)
366 if (paramInfos.find(it.first) == paramInfos.end())
368 paramInfos[it.first] = ParamDocEntry();
370 paramInfos[it.first].description = it.second;
375 for (
const auto& it : abbreviations)
378 if (paramInfos.find(it.second) == paramInfos.end())
380 paramInfos[it.second] = ParamDocEntry();
382 paramInfos[it.second].abbreviation = it.first;
386 for (
const auto& it : constraints)
389 if (paramInfos.find(it.first) == paramInfos.end())
391 paramInfos[it.first] = ParamDocEntry();
393 ParamDocEntry& cached = paramInfos[it.first];
394 cached.required = it.second.required;
395 cached.typeIsForced = it.second.constrainType;
398 std::stringstream defaultValueSs;
399 for (
const std::string& s : it.second.defaultValue)
401 defaultValueSs <<
'\'' << s <<
'\'';
404 if ((
void*)&s != (
void*)&it.second.defaultValue.back())
405 defaultValueSs <<
" ";
407 cached.defaultVal = defaultValueSs.str();
411 if (paramInfos.size() > 0)
414 <<
"==== AVAILABLE PARAMETERS ===="
415 << std::endl << std::endl;
417 for (
const auto& it : paramInfos)
419 const ParamDocEntry& pde = it.second;
422 ss << it.first <<
" ";
425 if (pde.abbreviation.length() > 0)
426 ss << pde.abbreviation <<
" ";
429 if (pde.typeIsForced)
430 ss << pde.type <<
" ";
433 if (pde.defaultVal.length() > 0)
434 ss <<
"default=[" << pde.defaultVal <<
"] ";
437 if ((pde.required) && (pde.defaultVal.length() == 0))
438 ss <<
"[[REQUIRED]] ";
441 if (pde.description.length() > 0)
442 ss << pde.description;
444 ss << std::endl << std::endl;
451 void Hazelnupp::ApplyConstraints()
454 for (
const auto& pc : constraints)
459 if (pc.second.defaultValue.size() > 0)
463 Value* tmp = ParseValue(pc.second.defaultValue, &pc.second);
464 parameters.insert(std::pair<std::string, Parameter*>(
476 if (pc.second.required)
487 return executableName;
496 return *parameters.find(key)->second->GetValue();
501 abbreviations.insert(std::pair<std::string, std::string>(abbrev, target));
507 return abbreviations.find(abbrev)->second;
512 return abbreviations.find(abbrev) != abbreviations.end();
517 abbreviations.clear();
526 const auto constraint = this->constraints.find(pc.key);
528 if (constraint != this->constraints.end())
529 constraint->second = pc;
533 this->constraints.insert(std::pair<std::string, ParamConstraint>(
550 this->crashOnFail = crashOnFail;
554 const ParamConstraint* Hazelnupp::GetConstraintForKey(
const std::string& key)
const
556 const auto constraint = constraints.find(key);
558 if (constraint == constraints.end())
561 return &constraint->second;