poafloc

Parser Of Arguments For Lines Of Commands
git clone git://git.dimitrijedobrota.com/poafloc.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit 36fd7278d9c884f92d36fa9a886e0c420dc36551
parent 660f946bfbd9e8aa1aae6eca0d235385ef89ed45
author Dimitrije Dobrota <mail@dimitrijedobrota.com>
date Wed, 5 Jun 2024 21:15:12 +0200

Recognize long and short options

Diffstat:
M args.hpp | +++++++++++++++++++++++++++++++ ---------------
M demo.cpp | ++++++++++++++++ ----------------------------

2 files changed, 47 insertions(+), 43 deletions(-)


diff --git a/ args.hpp b/ args.hpp

@@ -9,7 +9,7 @@ class Parser { public: struct option_t { const char *name;
char key;
const char key;
const char *arg; };

@@ -20,25 +20,44 @@ class Parser { const parse_f parser; };
static int parse(const argp_t *argp, int argc, const char *argv[], void *input) {
static int parse(argp_t *argp, int argc, char *argv[], void *input) {
for (int i = 1; i < argc; i++) {
bool opt_short = false, opt_long = false;
if (argv[i][0] != '-') {
argp->parser(-1, argv[i], input);
continue;
}
if (argv[i][1] != '-') opt_short = true;
else opt_long = true;
const char *opt = argv[i] + opt_long + 1;
bool found = false;
for (int j = 0; argp->options[j].name; j++) {
for (int j = 0; argp->options[j].key; j++) {
const auto &option = argp->options[j];
const auto n = std::strlen(option.name);
const char *arg = 0;
if (std::strncmp(argv[i], option.name, n)) continue;
if (opt_short && opt[0] != option.key) continue;
if (argv[i][n] == '=') {
if (!option.arg) {
std::cerr << "option doesn't require a value\n";
exit(1);
if (opt_long) {
if(!option.name) continue;
const auto n = std::strlen(option.name);
if (std::strncmp(argv[i] + 2, option.name, n)) continue;
if (opt[n] == '=') {
if (!option.arg) {
std::cerr << "option doesn't require a value\n";
exit(1);
}
arg = opt + n + 1;
}
}
arg = argv[i] + n + 1;
} else if (option.arg) {
if (option.arg && !arg) {
if (i == argc) { std::cerr << "option missing a value\n"; exit(1);

@@ -59,8 +78,6 @@ class Parser { std::cerr << std::format("unknown option {}\n", argv[i]); return 1; }
argp->parser(-1, argv[i], input);
} return 0;

@@ -70,4 +87,3 @@ class Parser { }; #endif

diff --git a/ demo.cpp b/ demo.cpp

@@ -1,7 +1,6 @@ #include "args.hpp" #include <cstdint>
#include <unordered_map>
#include <vector> void error(const std::string &message) {

@@ -10,14 +9,13 @@ void error(const std::string &message) { } struct arguments_t {
std::vector<const char *> args;
std::unordered_map<std::string, uint32_t> places;
const char *output_file = 0; bool debug = 0; bool hex = 0; bool relocatable = 0;
std::vector<const char *> args;
}; int parse_opt(int key, const char *arg, void *input) {

@@ -34,18 +32,6 @@ int parse_opt(int key, const char *arg, void *input) { arguments->relocatable = true; break; case 'o': arguments->output_file = arg; break;
case 'p': {
const std::string s = arg;
const auto pos = s.find('@');
if (pos == std::string::npos) error("Invalid argument for -place");
const auto value = stol(s.substr(pos + 1), 0, 16);
const auto [_, a] = arguments->places.emplace(s.substr(0, pos), value);
if (!a) error("duplicate place for the same section");
break;
}
default: arguments->args.push_back(arg); }

@@ -54,16 +40,15 @@ int parse_opt(int key, const char *arg, void *input) { // clang-format off static const Parser::option_t options[] = {
{ "--debug", 'd', 0},
{ "--hex", 'h', 0},
{"--relocatable", 'r', 0},
{ "-o", 'o', "file"},
{ "--place", 'p', "address"},
{ 0, 'o', "file"},
{ "debug", 'd', 0},
{ "hex", 'h', 0},
{"relocatable", 'r', 0},
{0}, }; // clang-format on
int main(int argc, const char *argv[]) {
int main(int argc, char *argv[]) {
Parser::argp_t argp = {options, parse_opt}; arguments_t arguments;

@@ -71,13 +56,16 @@ int main(int argc, const char *argv[]) { error("There was an error while parsing arguments"); }
if (arguments.args.size() == 0) {
error("please provide at least one input file");
}
std::cout << "Command line options: " << std::endl;
if (!arguments.hex && !arguments.relocatable) {
error("please provide hex or relocatable flags");
}
std::cout << "\t output: " << arguments.output_file << std::endl;
std::cout << "\t hex: " << arguments.hex << std::endl;
std::cout << "\t debug: " << arguments.debug << std::endl;
std::cout << "\t relocatable: " << arguments.relocatable << std::endl;
std::cout << "\t args: ";
for (const auto &arg : arguments.args) std::cout << arg << " ";
std::cout << std::endl;
return 0; }