From 65d3195caab52855a953aa12e5ba2cdc3609f1de Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 13 May 2023 13:22:10 +0200 Subject: [PATCH] libos: Allow ArgumentParser users to specify they want leftover arguments --- apps/cat.cpp | 6 ++++-- libos/include/os/ArgumentParser.h | 6 +++++- libos/src/ArgumentParser.cpp | 21 ++++++++++++++++----- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/apps/cat.cpp b/apps/cat.cpp index 66953631..42e59199 100644 --- a/apps/cat.cpp +++ b/apps/cat.cpp @@ -24,16 +24,18 @@ static Result do_cat(StringView path) Result luna_main(int argc, char** argv) { StringView filename; + Vector files; os::ArgumentParser parser; parser.add_description("Concatenate files to standard output."_sv); parser.add_system_program_info("cat"_sv); parser.add_positional_argument(filename, "file"_sv, "-"_sv); - Vector extra_files = TRY(parser.parse(argc, argv)); + parser.set_vector_argument(files); + parser.parse(argc, argv); TRY(do_cat(filename)); - for (auto file : extra_files) TRY(do_cat(file)); + for (auto file : files) TRY(do_cat(file)); return 0; } diff --git a/libos/include/os/ArgumentParser.h b/libos/include/os/ArgumentParser.h index cce1d60d..392ed9b2 100644 --- a/libos/include/os/ArgumentParser.h +++ b/libos/include/os/ArgumentParser.h @@ -21,7 +21,9 @@ namespace os Result add_value_argument(StringView& out, char short_flag, StringView long_flag, StringView fallback, StringView help = {}); - Result> parse(int argc, char* const* argv); + void set_vector_argument(Vector& out, bool allow_no_more_flags = false); + + Result parse(int argc, char* const* argv); struct ProgramInfo { @@ -74,6 +76,8 @@ namespace os Vector m_positional_args; Vector m_switch_args; Vector m_value_args; + Vector* m_vector_argument { nullptr }; + bool m_allow_no_more_flags_after_vector_argument_start { false }; ProgramInfo m_program_info; StringView m_description = {}; bool m_add_short_help_flag { false }; diff --git a/libos/src/ArgumentParser.cpp b/libos/src/ArgumentParser.cpp index 62a1b6a2..775c808e 100644 --- a/libos/src/ArgumentParser.cpp +++ b/libos/src/ArgumentParser.cpp @@ -68,6 +68,13 @@ namespace os return m_value_args.try_append(move(arg)); } + void ArgumentParser::set_vector_argument(Vector& out, bool allow_no_more_flags) + { + m_vector_argument = &out; + m_allow_no_more_flags_after_vector_argument_start = allow_no_more_flags; + return; + } + constexpr auto copyright_text = "Copyright (C) 2023, the Luna authors."; constexpr auto license_text = "Licensed under the BSD-2 license "; @@ -104,12 +111,10 @@ namespace os return arg.length() > 2 && arg[0] == '-' && arg[1] == '-'; } - Result> ArgumentParser::parse(int argc, char* const* argv) + Result ArgumentParser::parse(int argc, char* const* argv) { StringView program_name = argv[0]; - Vector leftovers; - Option current_value_argument = {}; bool is_parsing_value_argument = false; @@ -225,7 +230,11 @@ namespace os Option current = m_positional_args.try_dequeue(); if (!current.has_value()) { - TRY(leftovers.try_append(arg)); + if (m_vector_argument) + { + TRY(m_vector_argument->try_append(arg)); + if (m_allow_no_more_flags_after_vector_argument_start) is_still_parsing_flags = false; + } continue; } @@ -254,7 +263,7 @@ namespace os else { *arg.out = arg.fallback; } } - return leftovers; + return {}; } Result ArgumentParser::usage(StringView program_name) @@ -268,6 +277,8 @@ namespace os else { TRY(sb.format(" [%s]", arg.name.chars())); } } + if (m_vector_argument) sb.format("%s..."_sv, m_positional_args.size() ? "" : " "); + TRY(sb.add('\n')); auto usage_line = TRY(sb.string());