28 for (
auto& it : parameters)
41 PopulateRawArgs(argc, argv);
44 ExpandAbbreviations();
46 executableName = std::string(rawArgs[0]);
49 while (i < rawArgs.size())
51 if ((rawArgs[i].length() > 2) && (rawArgs[i].substr(0, 2) ==
"--"))
54 i = ParseNextParameter(i, param);
56 parameters.insert(std::pair<std::string, Parameter*>(param->
Key(), param));
65 if ((!catchHelp) || (!
HasParam(
"--help")))
73 std::cerr <<
"Fatal error: Command-line parameter value-type mismatch at \"" << hctm.
What() <<
"\"!";
84 std::cerr <<
"Fatal error: Missing required command-line parameter \"" << hctm.
What() <<
"\"!";
92 if ((catchHelp) && (
HasParam(
"--help")))
101 std::size_t Hazelnupp::ParseNextParameter(
const std::size_t parIndex,
Parameter*& out_Par)
103 std::size_t i = parIndex;
104 const std::string key = rawArgs[parIndex];
105 std::vector<std::string> values;
108 for (i++; i < rawArgs.size(); i++)
110 if ((rawArgs[i].length() < 2) || (rawArgs[i].substr(0, 2) !=
"--"))
111 values.emplace_back(rawArgs[i]);
120 Value* parsedVal = ParseValue(values, pcn);
121 if (parsedVal !=
nullptr)
129 throw std::runtime_error(
"Unable to parse parameter!");
134 void Hazelnupp::PopulateRawArgs(
const int argc,
const char*
const* argv)
137 rawArgs.reserve(argc);
139 for (
int i = 0; i < argc; i++)
140 rawArgs.emplace_back(std::string(argv[i]));
145 void Hazelnupp::ExpandAbbreviations()
148 if (parameterAbreviations.size() == 0)
151 for (std::string& arg : rawArgs)
154 auto abbr = parameterAbreviations.find(arg);
155 if (abbr != parameterAbreviations.end())
167 return parameters.find(key) != parameters.end();
170 Value* Hazelnupp::ParseValue(
const std::vector<std::string>& values,
const ParamConstraint* constraint)
173 const bool constrainType = (constraint !=
nullptr) && (constraint->
constrainType);
176 if (values.size() == 0)
179 if ((constrainType) &&
184 if ((constrainType) &&
193 if ((constrainType) &&
200 else if (values.size() > 1)
203 if ((constrainType) &&
210 for (
const std::string& val : values)
212 Value* tmp = ParseValue({ val });
220 const std::string& val = values[0];
227 if ((constrainType) &&
234 Value* tmp = ParseValue({ val });
250 if ((constrainType) &&
266 return new IntValue((
long long int)num);
274 Value* tmp = ParseValue({ val });
286 return new IntValue((
long long int)num);
304 this->catchHelp = catchHelp;
315 briefDescription = description;
321 return briefDescription;
326 parameterDescriptions[parameter] = description;
333 if (!HasDescription(parameter))
338 return parameterDescriptions.find(parameter)->second;
343 return parameterDescriptions.find(parameter) != parameterDescriptions.end();
349 parameterDescriptions.erase(parameter);
355 parameterDescriptions.clear();
361 std::stringstream ss;
364 if (briefDescription.length() > 0)
365 ss << briefDescription << std::endl;
370 std::string abbreviation;
371 std::string description;
373 bool required =
false;
374 bool typeIsForced =
false;
375 std::string defaultVal;
377 std::unordered_map<std::string, ParamDocEntry> paramInfos;
380 for (
const auto& it : parameterDescriptions)
383 if (paramInfos.find(it.first) == paramInfos.end())
385 paramInfos[it.first] = ParamDocEntry();
387 paramInfos[it.first].description = it.second;
392 for (
const auto& it : parameterAbreviations)
395 if (paramInfos.find(it.second) == paramInfos.end())
397 paramInfos[it.second] = ParamDocEntry();
399 paramInfos[it.second].abbreviation = it.first;
403 for (
const auto& it : parameterConstraints)
406 if (paramInfos.find(it.first) == paramInfos.end())
408 paramInfos[it.first] = ParamDocEntry();
410 ParamDocEntry& cached = paramInfos[it.first];
411 cached.required = it.second.required;
412 cached.typeIsForced = it.second.constrainType;
415 std::stringstream defaultValueSs;
416 for (
const std::string& s : it.second.defaultValue)
418 defaultValueSs <<
'\'' << s <<
'\'';
421 if ((
void*)&s != (
void*)&it.second.defaultValue.back())
422 defaultValueSs <<
" ";
424 cached.defaultVal = defaultValueSs.str();
428 if (paramInfos.size() > 0)
431 <<
"==== AVAILABLE PARAMETERS ===="
432 << std::endl << std::endl;
434 for (
const auto& it : paramInfos)
436 const ParamDocEntry& pde = it.second;
439 ss << it.first <<
" ";
442 if (pde.abbreviation.length() > 0)
443 ss << pde.abbreviation <<
" ";
446 if (pde.typeIsForced)
447 ss << pde.type <<
" ";
450 if (pde.defaultVal.length() > 0)
451 ss <<
"default=[" << pde.defaultVal <<
"] ";
454 if ((pde.required) && (pde.defaultVal.length() == 0))
455 ss <<
"[[REQUIRED]] ";
458 if (pde.description.length() > 0)
459 ss << pde.description;
461 ss << std::endl << std::endl;
468 void Hazelnupp::ApplyConstraints()
471 for (
const auto& pc : parameterConstraints)
476 if (pc.second.defaultValue.size() > 0)
480 Value* tmp = ParseValue(pc.second.defaultValue, &pc.second);
481 parameters.insert(std::pair<std::string, Parameter*>(
493 if (pc.second.required)
504 return parameterConstraints.find(parameter)->second;
509 parameterConstraints.erase(parameter);
515 return executableName;
524 return *parameters.find(key)->second->GetValue();
529 parameterAbreviations.insert(std::pair<std::string, std::string>(abbrev, target));
538 return parameterAbreviations.find(abbrev)->second;
543 return parameterAbreviations.find(abbrev) != parameterAbreviations.end();
548 parameterAbreviations.erase(abbrevation);
554 parameterAbreviations.clear();
561 (parameterConstraints[key] = constraint).key = key;
567 parameterConstraints.clear();
573 this->crashOnFail = crashOnFail;
577 const ParamConstraint* Hazelnupp::GetConstraintForKey(
const std::string& key)
const
579 const auto constraint = parameterConstraints.find(key);
581 if (constraint == parameterConstraints.end())
584 return &constraint->second;