From 7d71827c25ff1ab47c03aaa26f63a9a754b3d549 Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Sun, 3 Jul 2022 11:24:05 -0400 Subject: Condensed solar system csv files into one. Add argument parser for help and different systems --- include/diargs.hpp | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 include/diargs.hpp (limited to 'include/diargs.hpp') diff --git a/include/diargs.hpp b/include/diargs.hpp new file mode 100644 index 0000000..ee5cf63 --- /dev/null +++ b/include/diargs.hpp @@ -0,0 +1,177 @@ +/** + * diargs.hpp + * Copyright (c) 2022 Jon Santmyer + * + * 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 + +#include +#include +#include +#include +#include +#include + +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 {}; /*Name parsed when passed through with '--'*/ + char shortform {}; /*Character parsed when passed through with '-'*/ + + IArgument() = default; + IArgument(const std::string &Longform, char Shortform) : + longform(Longform), shortform(Shortform) {} + virtual ~IArgument() = default; + + virtual std::optional::iterator> parse( + std::vector &argv, + std::vector::iterator arg) = 0; + }; + + template + struct MultiArgument : public IArgument + { + 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) : + IArgument(Longform, 0), flag(&Flag) {} + MultiArgument(const std::string &Longform, char Shortform, T &Flag) : + IArgument(Longform, Shortform), flag(&Flag) {} + ~MultiArgument() {} + + std::optional::iterator> parse( + std::vector &argv, + std::vector::iterator arg) { + 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; + } + }; + + template + struct ToggleArgument : public IArgument + { + 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) {} + ToggleArgument(const std::string &Longform, T &Flag, const T Set) : + IArgument(Longform, 0), flag(&Flag), set(&Set) {} + ToggleArgument(const std::string &Longform, char Shortform, + T &Flag, const T Set) : + IArgument(Longform, Shortform), flag(&Flag), set(&Set) {} + ~ToggleArgument() {} + + std::optional::iterator> parse( + std::vector &argv, + std::vector::iterator arg) { + *flag = set; + return arg; + } + }; + + /*Type for values not denoted with '-' or '--'*/ + template + struct OrderedArgument : public IArgument + { + T *flag; /*Value set when passed arg is not any other type*/ + std::optional dflt; + OrderedArgument(T &Flag) : + flag(&Flag), dflt(std::nullopt) {} + OrderedArgument(T &Flag, T Dflt) : + flag(&Flag), dflt(Dflt) {} + ~OrderedArgument() {} + std::optional::iterator> parse( + std::vector &argv, + std::vector::iterator arg) { + std::stringstream ss((*arg).data()); + ss >> std::noskipws >> *flag; + return arg; + } + }; + + /*Container for argument checking*/ + struct ArgumentList + { + std::vector> arguments; + + void addArgument() {} + template + void addArgument(T arg, ArgumentPack... args) { + arguments.push_back(std::make_unique(arg)); + addArgument(args...); + } + + template + ArgumentList(ArgumentPack... arguments) { + addArgument(arguments...); + } + }; + + /*Instantiation results in parsed arguments*/ + class ArgumentParser + { + public: + ArgumentParser( + void (*failfunc)(int), + ArgumentList &arguments, + ArgsPair argcv); + }; +} + +#endif -- cgit v1.2.1