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 |

commit0dfc1d32da3d539129533341c4a2eb45a3848b78
parent42b158159fc1188afc6b1afecf30ac0184fb0c52
authorDimitrije Dobrota <mail@dimitrijedobrota.com>
dateSat, 29 Jun 2024 10:32:41 +0200

Add test suite, bug fixing

Diffstat:
MCMakeLists.txt|+-
Msource/poafloc.cpp|+++++++++++++++++---------
Msource/trie.cpp|+++------------
Mtest/CMakeLists.txt|++++++++++++++++++++++++++++++++++++++++++++++++++-
Mtest/source/poafloc_test.cpp|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-

5 files changed, 130 insertions(+), 24 deletions(-)


diff --git a/CMakeLists.txt b/CMakeLists.txt

@@ -4,7 +4,7 @@ include(cmake/prelude.cmake)

project(
poafloc
VERSION 1.0.1
VERSION 1.0.2
DESCRIPTION "Parser Of Arguments For Lines Of Commands"
HOMEPAGE_URL "https://git.dimitrijedobrota.com/poafloc.git"
LANGUAGES C CXX

diff --git a/source/poafloc.cpp b/source/poafloc.cpp

@@ -103,7 +103,7 @@ Parser::Parser(const arg_t* argp, unsigned flags, void* input)

else
{
// duplicate key, silently ignoring
if (!m_options.contains(opt.key)) continue;
if (m_options.contains(opt.key)) continue;
if (opt.name != nullptr) m_trie.insert(opt.name, opt.key);
m_options[key_last = opt.key] = &opt;

@@ -204,26 +204,33 @@ int Parser::parse(std::size_t argc, char* argv[])

const auto* option = m_options[key];
bool const is_opt = (option->flags & ARG_OPTIONAL) != 0;
if (option->arg == nullptr)
{
m_argp->parse(key, nullptr, this);
continue;
}
if (opt[j + 1] != 0)
{
m_argp->parse(key, opt.substr(j + 1).c_str(), this);
break;
}
if (is_opt) m_argp->parse(key, nullptr, this);
else if (idx + 1 != argc)
if (is_opt)
{
m_argp->parse(key, args[++idx], this);
break;
m_argp->parse(key, nullptr, this);
continue;
}
else
if (idx + 1 != argc)
{
err_code = handle_missing(true, args[idx]);
goto error;
m_argp->parse(key, args[++idx], this);
break;
}
err_code = handle_missing(true, args[idx]);
goto error;
}
}
else

@@ -320,6 +327,7 @@ int Parser::parse(std::size_t argc, char* argv[])

return 0;
error:
m_argp->parse(Key::ERROR, nullptr, this);
return err_code;
}

@@ -329,7 +337,7 @@ int Parser::handle_unknown(bool shrt, const char* argv)

return m_argp->parse(Key::ERROR, nullptr, this);
static const char* const unknown_fmt[2] = {
"unrem_argpized option '-%s'\n",
"unrecognized option '-%s'\n",
"invalid option -- '%s'\n",
};

diff --git a/source/trie.cpp b/source/trie.cpp

@@ -9,10 +9,7 @@ bool Parser::trie_t::insert(const std::string& option, int key)

{
trie_t* crnt = this;
if (!is_valid(option))
{
return false;
}
if (!is_valid(option)) return false;
for (const char chr : option)
{

@@ -36,10 +33,7 @@ int Parser::trie_t::get(const std::string& option) const

{
const trie_t* crnt = this;
if (!is_valid(option))
{
return 0;
}
if (!is_valid(option)) return 0;
for (const char chr : option)
{

@@ -49,10 +43,7 @@ int Parser::trie_t::get(const std::string& option) const

crnt = crnt->m_children.at(idx).get();
}
if (!crnt->m_terminal && crnt->m_count > 1)
{
return 0;
}
if (!crnt->m_terminal && crnt->m_count > 1) return 0;
return crnt->m_key;
}

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt

@@ -18,7 +18,56 @@ add_executable(poafloc_test source/poafloc_test.cpp)

target_link_libraries(poafloc_test PRIVATE poafloc::poafloc)
target_compile_features(poafloc_test PRIVATE cxx_std_20)
add_test(NAME poafloc_test COMMAND poafloc_test)
add_test(NAME poafloc_test_empty COMMAND poafloc_test)
set_tests_properties(poafloc_test_empty PROPERTIES PASS_REGULAR_EXPRESSION "init\nnoargs\nend\nsuccess")
add_test(NAME poafloc_test_arg_one COMMAND poafloc_test a1)
set_tests_properties(poafloc_test_arg_one PROPERTIES PASS_REGULAR_EXPRESSION "init\narg:a1\nend\nsuccess")
add_test(NAME poafloc_test_arg_two COMMAND poafloc_test a1 a2)
set_tests_properties(poafloc_test_arg_two PROPERTIES PASS_REGULAR_EXPRESSION "init\narg:a1\narg:a2\nend\nsuccess")
add_test(NAME poafloc_test_short COMMAND poafloc_test -s)
set_tests_properties(poafloc_test_short PROPERTIES PASS_REGULAR_EXPRESSION "init\ns\nnoargs\nend\nsuccess")
add_test(NAME poafloc_test_long COMMAND poafloc_test --long)
set_tests_properties(poafloc_test_long PROPERTIES PASS_REGULAR_EXPRESSION "init\nl\nnoargs\nend\nsuccess")
add_test(NAME poafloc_test_short_arg COMMAND poafloc_test -a a1)
set_tests_properties(poafloc_test_short_arg PROPERTIES PASS_REGULAR_EXPRESSION "init\na:a1\nnoargs\nend\nsuccess")
add_test(NAME poafloc_test_long_arg COMMAND poafloc_test --arg a1)
set_tests_properties(poafloc_test_long_arg PROPERTIES PASS_REGULAR_EXPRESSION "init\na:a1\nnoargs\nend\nsuccess")
add_test(NAME poafloc_test_short_arg_equal COMMAND poafloc_test -aa1)
set_tests_properties(poafloc_test_short_arg_equal PROPERTIES PASS_REGULAR_EXPRESSION "init\na:a1\nnoargs\nend\nsuccess")
add_test(NAME poafloc_test_long_arg_equal COMMAND poafloc_test --arg=a1)
set_tests_properties(poafloc_test_long_arg_equal PROPERTIES PASS_REGULAR_EXPRESSION "init\na:a1\nnoargs\nend\nsuccess")
add_test(NAME poafloc_test_short_arg_without COMMAND poafloc_test -a)
set_tests_properties(poafloc_test_short_arg_without PROPERTIES WILL_FAIL TRUE)
add_test(NAME poafloc_test_long_arg_without COMMAND poafloc_test --arg)
set_tests_properties(poafloc_test_long_arg_without PROPERTIES WILL_FAIL TRUE)
add_test(NAME poafloc_test_short_opt COMMAND poafloc_test -oa1)
set_tests_properties(poafloc_test_short_opt PROPERTIES PASS_REGULAR_EXPRESSION "init\no:a1\nnoargs\nend\nsuccess")
add_test(NAME poafloc_test_long_opt COMMAND poafloc_test --opt=a1)
set_tests_properties(poafloc_test_long_opt PROPERTIES PASS_REGULAR_EXPRESSION "init\no:a1\nnoargs\nend\nsuccess")
add_test(NAME poafloc_test_short_opt_without COMMAND poafloc_test -o)
set_tests_properties(poafloc_test_short_opt_without PROPERTIES PASS_REGULAR_EXPRESSION "init\no:default\nnoargs\nend\nsuccess")
add_test(NAME poafloc_test_long_opt_without COMMAND poafloc_test --opt)
set_tests_properties(poafloc_test_long_opt_without PROPERTIES PASS_REGULAR_EXPRESSION "init\no:default\nnoargs\nend\nsuccess")
add_test(NAME poafloc_test_short_opt_after COMMAND poafloc_test -o a1)
set_tests_properties(poafloc_test_short_opt_after PROPERTIES PASS_REGULAR_EXPRESSION "init\no:default\narg:a1\nend\nsuccess")
add_test(NAME poafloc_test_long_opt_after COMMAND poafloc_test --opt a1)
set_tests_properties(poafloc_test_long_opt_after PROPERTIES PASS_REGULAR_EXPRESSION "init\no:default\narg:a1\nend\nsuccess")
# ---- End-of-file commands ----

diff --git a/test/source/poafloc_test.cpp b/test/source/poafloc_test.cpp

@@ -1,8 +1,66 @@

#include <iostream>
#include <string>
#include "poafloc/poafloc.hpp"
int main()
using namespace poafloc; // NOLINT
//
int parse_opt(int key, const char* arg, Parser* parser)
{
std::ignore = parser;
switch (key)
{
case 's':
std::cout << 's' << std::endl;
break;
case 'l':
std::cout << 'l' << std::endl;
break;
case 'a':
std::cout << "a:" << arg << std::endl;
break;
case 'o':
std::cout << "o:" << (arg != nullptr ? arg : "default") << std::endl;
break;
case ARG:
std::cout << "arg:" << arg << std::endl;
break;
case INIT:
std::cout << "init" << std::endl;
break;
case END:
std::cout << "end" << std::endl;
break;
case SUCCESS:
std::cout << "success" << std::endl;
break;
case ERROR:
std::cout << "error" << std::endl;
break;
case NO_ARGS:
std::cout << "noargs" << std::endl;
break;
default:
break;
}
return 0;
}
// clang-format off
static const option_t options[] = {
{nullptr, 's', nullptr, 0, ""},
{ "long", 'l', nullptr, 0, ""},
{ "arg", 'a', "arg", 0, ""},
{ "opt", 'o', "arg", ARG_OPTIONAL, ""},
{},
};
// clang-format on
static const arg_t argp = {options, parse_opt, "", ""};
int main(int argc, char* argv[])
{
return parse(&argp, argc, argv, 0, nullptr);
}