libos: Allow ArgumentParser users to specify they want leftover arguments
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
dc7e503342
commit
65d3195caa
@ -24,16 +24,18 @@ static Result<void> do_cat(StringView path)
|
||||
Result<int> luna_main(int argc, char** argv)
|
||||
{
|
||||
StringView filename;
|
||||
Vector<StringView> 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<StringView> 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;
|
||||
}
|
||||
|
@ -21,7 +21,9 @@ namespace os
|
||||
Result<void> add_value_argument(StringView& out, char short_flag, StringView long_flag, StringView fallback,
|
||||
StringView help = {});
|
||||
|
||||
Result<Vector<StringView>> parse(int argc, char* const* argv);
|
||||
void set_vector_argument(Vector<StringView>& out, bool allow_no_more_flags = false);
|
||||
|
||||
Result<void> parse(int argc, char* const* argv);
|
||||
|
||||
struct ProgramInfo
|
||||
{
|
||||
@ -74,6 +76,8 @@ namespace os
|
||||
Vector<PositionalArgument> m_positional_args;
|
||||
Vector<SwitchArgument> m_switch_args;
|
||||
Vector<ValueArgument> m_value_args;
|
||||
Vector<StringView>* 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 };
|
||||
|
@ -68,6 +68,13 @@ namespace os
|
||||
return m_value_args.try_append(move(arg));
|
||||
}
|
||||
|
||||
void ArgumentParser::set_vector_argument(Vector<StringView>& 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 <https://opensource.org/license/bsd-2-clause/>";
|
||||
|
||||
@ -104,12 +111,10 @@ namespace os
|
||||
return arg.length() > 2 && arg[0] == '-' && arg[1] == '-';
|
||||
}
|
||||
|
||||
Result<Vector<StringView>> ArgumentParser::parse(int argc, char* const* argv)
|
||||
Result<void> ArgumentParser::parse(int argc, char* const* argv)
|
||||
{
|
||||
StringView program_name = argv[0];
|
||||
|
||||
Vector<StringView> leftovers;
|
||||
|
||||
Option<ValueArgument> current_value_argument = {};
|
||||
bool is_parsing_value_argument = false;
|
||||
|
||||
@ -225,7 +230,11 @@ namespace os
|
||||
Option<PositionalArgument> 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<void> 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());
|
||||
|
Loading…
Reference in New Issue
Block a user