-
Notifications
You must be signed in to change notification settings - Fork 577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
parse_positional
sets m_positional
. We need a way to append into it too.
#300
Comments
Are you able to read the positional arguments before you call it again? |
What do you mean under My wrapper currently looks like this: cxxopts.cpp#include <HydrArgs/HydrArgs.hpp>
#include <HydrArgs/toolbox.hpp>
#include <HydrArgs/fallback/errors.hpp>
#include <cxxopts.hpp>
#include <memory>
#include <string>
#include <algorithm>
#include <streambuf>
#include <sstream>
struct CXXOptsBackend: public IBackendOwnStoredSpec{
cxxopts::Options app;
cxxopts::OptionAdder optAdder;
std::vector<std::string> remaining;
std::vector<char *> remainingPtrs;
std::vector<cxxopts::Option> nativeArgs;
std::vector<std::string> positionalArgs;
bool show_help = false;
CXXOptsBackend(const std::string& name, const std::string& descr, const std::string& usage [[maybe_unused]], std::vector<Arg*> dashedSpec, std::vector<Arg*> positionalSpec, Streams streams): IBackendOwnStoredSpec(dashedSpec, positionalSpec, streams), app(name, descr), optAdder(app.add_options()){
std::vector<std::string> positionals;
for(auto argPtr: dashedSpec){
_addArg(argPtr, false);
}
for(auto argPtr: positionalSpec){
_addArg(argPtr, true);
}
app.parse_positional(positionals);
app.allow_unrecognised_options();
//app.set_tab_expansion();
optAdder(DEFAULT_HELP_ARG.long_name.undashed, DEFAULT_HELP_ARG.doc);
}
virtual void _addArg(Arg* argPtr, bool isPositional) override {
switch(argPtr->type){
case ArgType::flag:
{
auto specOptPtr = static_cast<FlagArg*>(argPtr);
optAdder(specOptPtr->name, specOptPtr->description);
}
break;
case ArgType::s4:
{
auto specOptPtr = static_cast<IntArg*>(argPtr);
std::stringstream s;
s << specOptPtr->value;
optAdder(specOptPtr->name, specOptPtr->description, cxxopts::value<decltype(specOptPtr->value)>()->default_value(s.str()));
}
break;
case ArgType::string:
case ArgType::path:
{
auto specOptPtr = static_cast<StringArg*>(argPtr);
optAdder(specOptPtr->name, specOptPtr->description, cxxopts::value<decltype(specOptPtr->value)>()->default_value(specOptPtr->value));
}
break;
}
if(isPositional){
// `m_positional` is overridden (not appended) on every `app.parse_positional` (this function adds positional arguments). There is no way to only append element there. So we have to populate an own array and then call `app.parse_positional` in `_seal`
positionalArgs.emplace_back(argPtr->name);
/*
quote from the docs:
options.parse_positional({"first", "second", "last"})
where "last" should be the name of an option with a container type, and the others should have a single value.
*/
}
}
virtual ~CXXOptsBackend() override = default;
virtual void _seal() override {
app.parse_positional(positionalArgs);
}
virtual void _unseal() override {
}
virtual bool isSealed() const override {
return false;
}
virtual void printHelp(std::ostream &stream, const char * const argv0 [[maybe_unused]]) override {
stream << app.help({""});
}
virtual ParseResult _parseArgs(CLIRawArgs rawArgs) override {
auto result = app.parse(rawArgs.argc, rawArgs.argv);
PROCESS_CASE_OF_HELP_CALLED(result[DEFAULT_HELP_ARG.long_name.undashed].as<bool>());
size_t i=0;
std::pair<decltype(dashedSpec)&, bool> specs[]{
{dashedSpec, false},
{positionalSpec, true},
};
for(auto p: specs){
auto spec = p.first;
auto isPositional = p.second;
for(auto argPtr: spec){
if(result.count(argPtr->name)){
switch(argPtr->type){
case ArgType::flag:
{
auto specOptPtr = static_cast<FlagArg*>(argPtr);
specOptPtr->value = result[argPtr->name].as<bool>();
}
break;
case ArgType::s4:
{
auto specOptPtr = static_cast<IntArg*>(argPtr);
specOptPtr->value = result[argPtr->name].as<decltype(specOptPtr->value)>();
}
break;
case ArgType::string:
case ArgType::path:
{
auto specOptPtr = static_cast<StringArg*>(argPtr);
specOptPtr->value = result[argPtr->name].as<decltype(specOptPtr->value)>();
}
break;
}
} else {
PROCESS_ARGUMENT_MISSING_CASE();
}
++i;
}
}
//std::transform(begin(remaining), end(remaining), begin(remainingPtrs), [](std::string &el) -> char * {return el.data();});
return {
.parsingStatus = STATUS_OK,
.rest={
/*.argc = 0,
.argv = remainingPtrs.data()*/
.argc = 0,
.argv = nullptr
}
};
}
};
IArgsParser* argsParserFactory(const std::string& name, const std::string& descr, const std::string& usage [[maybe_unused]], std::vector<Arg*> dashedSpec, std::vector<Arg*> positionalSpec, Streams streams){
return new CXXOptsBackend(name, descr, usage, dashedSpec, positionalSpec, streams);
} Note the method |
I see the problem. You could probably just call |
It is already done like that ( BTW, I have created a GH repo for the project, though it is completely unfinished currently. https://github.com/HydrArgs/HydrArgs |
No description provided.
The text was updated successfully, but these errors were encountered: