lib/cli: finish initial implementation
This should be all functionality that is needed for now. The next step is building unit tests to check that everything works correctly. Who am I kidding? There will most certainly be bugs in there given that this code has been typed out without ever being run.BodgeMaster-unfinished
parent
a2084e296a
commit
390087fc35
|
@ -56,6 +56,7 @@ namespace CLI {
|
||||||
ArgumentsParser::ArgumentsParser(int argc, char* argv[], std::vector<Flag> flags, std::vector<UnpositionalArgument> unpositionalArguments, std::vector<PositionalArgument> positionalArguments) {
|
ArgumentsParser::ArgumentsParser(int argc, char* argv[], std::vector<Flag> flags, std::vector<UnpositionalArgument> unpositionalArguments, std::vector<PositionalArgument> positionalArguments) {
|
||||||
this->wrongUsage = false;
|
this->wrongUsage = false;
|
||||||
this->wrongUsageMessages = std::vector<std::string>();
|
this->wrongUsageMessages = std::vector<std::string>();
|
||||||
|
this->programName = std::string(argv[0]);
|
||||||
this->positionalArguments = positionalArguments;
|
this->positionalArguments = positionalArguments;
|
||||||
// create lookup tables for all flags and unpositional arguments
|
// create lookup tables for all flags and unpositional arguments
|
||||||
// by their names
|
// by their names
|
||||||
|
@ -78,7 +79,7 @@ namespace CLI {
|
||||||
|
|
||||||
UnpositionalArgument* argumentWaitingForValue = nullptr;
|
UnpositionalArgument* argumentWaitingForValue = nullptr;
|
||||||
std::vector<CLI::PositionalArgument>::size_type positionalArgumentCounter = 0;
|
std::vector<CLI::PositionalArgument>::size_type positionalArgumentCounter = 0;
|
||||||
for (int i=0; i<argc; i++) {
|
for (int i=1; i<argc; i++) {
|
||||||
std::string argument(argv[i]);
|
std::string argument(argv[i]);
|
||||||
if (argument[0]=='-') {
|
if (argument[0]=='-') {
|
||||||
// do we have unfinished business?
|
// do we have unfinished business?
|
||||||
|
@ -189,4 +190,58 @@ namespace CLI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorOr<std::string> ArgumentsParser::getProgramName() {
|
||||||
|
if (this->wrongUsage) {
|
||||||
|
return ErrorOr<std::string>(true, ErrorCodes::WRONG_USAGE, this->programName);
|
||||||
|
}
|
||||||
|
return ErrorOr<std::string>(this->programName);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<bool> ArgumentsParser::getFlag(int argc, char* argv[], char shortName) {
|
||||||
|
if (!this->flagsByShortName.contains(shortName)) return ErrorOr<bool>(true, ErrorCodes::UNKNOWN_KEY, false);
|
||||||
|
if (this->wrongUsage) {
|
||||||
|
return ErrorOr<bool>(true, ErrorCodes::WRONG_USAGE, this->flagsByShortName[shortName]->present);
|
||||||
|
}
|
||||||
|
return ErrorOr<bool>(this->flagsByShortName[shortName]->present);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<bool> ArgumentsParser::getFlag(int argc, char* argv[], std::string longName) {
|
||||||
|
if (!this->flagsByLongName.contains(longName)) return ErrorOr<bool>(true, ErrorCodes::UNKNOWN_KEY, false);
|
||||||
|
if (this->wrongUsage) {
|
||||||
|
return ErrorOr<bool>(true, ErrorCodes::WRONG_USAGE, this->flagsByLongName[longName]->present);
|
||||||
|
}
|
||||||
|
return ErrorOr<bool>(this->flagsByLongName[longName]->present);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<std::string> ArgumentsParser::getPositionalArgument(int argc, char* argv[], std::vector<CLI::PositionalArgument>::size_type position){
|
||||||
|
if (position >= this->positionalArguments.size()) return ErrorOr<std::string>(true, ErrorCodes::OUT_OF_RANGE, std::string(""));
|
||||||
|
if (this->wrongUsage) {
|
||||||
|
if (this->positionalArguments.at(position).present) return ErrorOr<std::string>(true, ErrorCodes::WRONG_USAGE, this->positionalArguments.at(position).value);
|
||||||
|
else return ErrorOr<std::string>(true, ErrorCodes::NOT_PRESENT, std::string(""));
|
||||||
|
}
|
||||||
|
return ErrorOr<std::string>(this->positionalArguments.at(position).value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<std::string> ArgumentsParser::getUnpositionalArgument(int argc, char* argv[], char shortName) {
|
||||||
|
if (!this->argumentsByShortName.contains(shortName)) return ErrorOr<std::string>(true, ErrorCodes::UNKNOWN_KEY, std::string(""));
|
||||||
|
if (this-wrongUsage) {
|
||||||
|
if (this->argumentsByShortName[shortName]->present) return ErrorOr<std::string>(true, ErrorCodes::WRONG_USAGE, this->argumentsByShortName[shortName]->value);
|
||||||
|
else return ErrorOr<std::string>(true, ErrorCodes::NOT_PRESENT, std::string(""));
|
||||||
|
}
|
||||||
|
if (this->argumentsByShortName[shortName]->present) return ErrorOr<std::string>(this->argumentsByShortName[shortName]->value);
|
||||||
|
// argument is not present, but this is not an error -> false, NOT_PRESENT, ""
|
||||||
|
else return ErrorOr<std::string>(false, ErrorCodes::NOT_PRESENT, std::string(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<std::string> ArgumentsParser::getUnpositionalArgument(int argc, char* argv[], std::string longName) {
|
||||||
|
if (!this->argumentsByLongName.contains(longName)) return ErrorOr<std::string>(true, ErrorCodes::UNKNOWN_KEY, std::string(""));
|
||||||
|
if (this-wrongUsage) {
|
||||||
|
if (this->argumentsByLongName[longName]->present) return ErrorOr<std::string>(true, ErrorCodes::WRONG_USAGE, this->argumentsByLongName[longName]->value);
|
||||||
|
else return ErrorOr<std::string>(true, ErrorCodes::NOT_PRESENT, std::string(""));
|
||||||
|
}
|
||||||
|
if (this->argumentsByLongName[longName]->present) return ErrorOr<std::string>(this->argumentsByLongName[longName]->value);
|
||||||
|
// argument is not present, but this is not an error -> false, NOT_PRESENT, ""
|
||||||
|
else return ErrorOr<std::string>(false, ErrorCodes::NOT_PRESENT, std::string(""));
|
||||||
|
}
|
||||||
|
//std::string ArgumentsParser::getUsage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,11 +77,11 @@ namespace CLI {
|
||||||
~ArgumentsParser();
|
~ArgumentsParser();
|
||||||
|
|
||||||
ErrorOr<std::string> getProgramName();
|
ErrorOr<std::string> getProgramName();
|
||||||
ErrorOr<bool> getFlag(int argc, char* argv, char shortName);
|
ErrorOr<bool> getFlag(int argc, char* argv[], char shortName);
|
||||||
ErrorOr<bool> getFlag(int argc, char* argv, std::string longName);
|
ErrorOr<bool> getFlag(int argc, char* argv[], std::string longName);
|
||||||
ErrorOr<std::string> getPositionalArgument(int argc, char* argv, int position);
|
ErrorOr<std::string> getPositionalArgument(int argc, char* argv[], std::vector<CLI::PositionalArgument>::size_type position);
|
||||||
ErrorOr<std::string> getUnpositionalArgument(int argc, char* argv, char shortName);
|
ErrorOr<std::string> getUnpositionalArgument(int argc, char* argv[], char shortName);
|
||||||
ErrorOr<std::string> getUnpositionalArgument(int argc, char* argv, std::string longName);
|
ErrorOr<std::string> getUnpositionalArgument(int argc, char* argv[], std::string longName);
|
||||||
|
|
||||||
std::string getUsage();
|
std::string getUsage();
|
||||||
};
|
};
|
||||||
|
|
|
@ -75,6 +75,9 @@ namespace ErrorCodes {
|
||||||
|
|
||||||
const uint8_t WRONG_USAGE = 4;
|
const uint8_t WRONG_USAGE = 4;
|
||||||
|
|
||||||
|
// when dealing with maps
|
||||||
|
const uint8_t UNKNOWN_KEY = 5;
|
||||||
|
|
||||||
const uint8_t UNIMPLEMENTED = 254;
|
const uint8_t UNIMPLEMENTED = 254;
|
||||||
|
|
||||||
const uint8_t UNKNOWN = 255;
|
const uint8_t UNKNOWN = 255;
|
||||||
|
|
Loading…
Reference in New Issue