summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--diargs.cpp30
-rw-r--r--diargs.hpp68
2 files changed, 87 insertions, 11 deletions
diff --git a/diargs.cpp b/diargs.cpp
index c13eee7..b7aa79e 100644
--- a/diargs.cpp
+++ b/diargs.cpp
@@ -1,3 +1,25 @@
+/**
+ * diargs.cpp
+ * Copyright (c) 2022 Jon Santmyer <jon@jonsantmyer.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
#include "diargs.hpp"
#include <string_view>
#include <list>
@@ -10,14 +32,16 @@ ArgumentParser::ArgumentParser(
ArgumentList &arguments,
ArgsPair argcv)
{
+ /*Raw c strings passed to string_view for safety*/
std::vector<std::string_view> argv(argcv.argc);
for(int arg = 0; arg < argcv.argc; arg++) {
argv[arg] = std::string_view(argcv.argv[arg]);
}
+ /*Skip the first argument because it will always be the path to the program*/
for(auto it = argv.begin() + 1; it != argv.end(); it++) {
- if(it->at(0) == '-') {
- if(it->at(1) == '-') {
+ if(it->at(0) == '-') { /*Argument could be shortform*/
+ if(it->at(1) == '-') { /*Argument is longform*/
std::string_view parsing = std::string_view(it->data() + 2);
if(parsing.size() == 0) continue;
for(auto &argdef : arguments.arguments) {
@@ -45,7 +69,7 @@ ArgumentParser::ArgumentParser(
}
}
continue;
- }
+ } /*When argument is unmarked, it's an ordered type*/
for(auto argit = arguments.arguments.begin();
argit != arguments.arguments.end();
argit++) {
diff --git a/diargs.hpp b/diargs.hpp
index 9d6881d..ee5cf63 100644
--- a/diargs.hpp
+++ b/diargs.hpp
@@ -1,3 +1,49 @@
+/**
+ * diargs.hpp
+ * Copyright (c) 2022 Jon Santmyer <jon@jonsantmyer.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * diargs - An alternative to GNU getopt for modern C++
+ * Provides tools to parse command line arguments for C++17 programs
+ *
+ * Usage: Instantiate an ArgumentParser class, passing in a fallback
+ * error function, an ArgumentList struct, and an argc,argv pair.
+ *
+ * Example:
+ *
+ * void printusage(int err) {
+ * std::cout << "-h --help : Print this message" << std::endl;
+ * std::exit(err);
+ * }
+ *
+ * int main(int argc, char **argv) {
+ * bool helpflag;
+ *
+ * ArgsPair args{argc, argv};
+ * ArgumentList argslist(
+ * ToggleArgument("help", 'h', helpflag, true)
+ * );
+ * ArgumentParser parser(printusage, argslist, args);
+ * return 0;
+ * }
+ */
#ifndef DIARGS_HPP
#define DIARGS_HPP 1
@@ -10,15 +56,17 @@
namespace diargs {
+ /*Passed to ArgumentParser*/
struct ArgsPair {
int argc {};
char **argv {};
};
+ /*Interface for argument types. Makes the whole system tick*/
struct IArgument
{
- std::string longform {};
- char shortform {};
+ std::string longform {}; /*Name parsed when passed through with '--'*/
+ char shortform {}; /*Character parsed when passed through with '-'*/
IArgument() = default;
IArgument(const std::string &Longform, char Shortform) :
@@ -33,7 +81,8 @@ namespace diargs {
template<typename T>
struct MultiArgument : public IArgument
{
- T *flag;
+ T *flag; /*Value set when encountered. Taken from next argument
+ i.e. --arg [VALUE]*/
MultiArgument(T &Flag) : flag(&Flag) {}
MultiArgument(const std::string &Longform, T &Flag) :
@@ -45,7 +94,8 @@ namespace diargs {
std::optional<std::vector<std::string_view>::iterator> parse(
std::vector<std::string_view> &argv,
std::vector<std::string_view>::iterator arg) {
- if(++arg == argv.end()) return std::nullopt;
+ if(++arg == argv.end()) return std::nullopt; /*Not having the
+ value is an error case*/
std::stringstream ss((*arg).data());
ss >> std::noskipws >> *flag;
return arg;
@@ -55,8 +105,8 @@ namespace diargs {
template<typename T>
struct ToggleArgument : public IArgument
{
- T *flag;
- T set;
+ T *flag; /*Value set to [set] when encountered*/
+ T set; /*Value that [flag] is set to when parsed*/
ToggleArgument(T &Flag, const T Set) :
flag(&Flag), set(Set) {}
@@ -75,10 +125,11 @@ namespace diargs {
}
};
+ /*Type for values not denoted with '-' or '--'*/
template<typename T>
struct OrderedArgument : public IArgument
{
- T *flag;
+ T *flag; /*Value set when passed arg is not any other type*/
std::optional<T> dflt;
OrderedArgument(T &Flag) :
flag(&Flag), dflt(std::nullopt) {}
@@ -94,6 +145,7 @@ namespace diargs {
}
};
+ /*Container for argument checking*/
struct ArgumentList
{
std::vector<std::unique_ptr<IArgument>> arguments;
@@ -111,9 +163,9 @@ namespace diargs {
}
};
+ /*Instantiation results in parsed arguments*/
class ArgumentParser
{
- void (*m_abortfunc)(int);
public:
ArgumentParser(
void (*failfunc)(int),