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)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
StringView filename;
|
StringView filename;
|
||||||
|
Vector<StringView> files;
|
||||||
|
|
||||||
os::ArgumentParser parser;
|
os::ArgumentParser parser;
|
||||||
parser.add_description("Concatenate files to standard output."_sv);
|
parser.add_description("Concatenate files to standard output."_sv);
|
||||||
parser.add_system_program_info("cat"_sv);
|
parser.add_system_program_info("cat"_sv);
|
||||||
parser.add_positional_argument(filename, "file"_sv, "-"_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));
|
TRY(do_cat(filename));
|
||||||
|
|
||||||
for (auto file : extra_files) TRY(do_cat(file));
|
for (auto file : files) TRY(do_cat(file));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,9 @@ namespace os
|
|||||||
Result<void> add_value_argument(StringView& out, char short_flag, StringView long_flag, StringView fallback,
|
Result<void> add_value_argument(StringView& out, char short_flag, StringView long_flag, StringView fallback,
|
||||||
StringView help = {});
|
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
|
struct ProgramInfo
|
||||||
{
|
{
|
||||||
@ -74,6 +76,8 @@ namespace os
|
|||||||
Vector<PositionalArgument> m_positional_args;
|
Vector<PositionalArgument> m_positional_args;
|
||||||
Vector<SwitchArgument> m_switch_args;
|
Vector<SwitchArgument> m_switch_args;
|
||||||
Vector<ValueArgument> m_value_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;
|
ProgramInfo m_program_info;
|
||||||
StringView m_description = {};
|
StringView m_description = {};
|
||||||
bool m_add_short_help_flag { false };
|
bool m_add_short_help_flag { false };
|
||||||
|
@ -68,6 +68,13 @@ namespace os
|
|||||||
return m_value_args.try_append(move(arg));
|
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 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/>";
|
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] == '-';
|
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];
|
StringView program_name = argv[0];
|
||||||
|
|
||||||
Vector<StringView> leftovers;
|
|
||||||
|
|
||||||
Option<ValueArgument> current_value_argument = {};
|
Option<ValueArgument> current_value_argument = {};
|
||||||
bool is_parsing_value_argument = false;
|
bool is_parsing_value_argument = false;
|
||||||
|
|
||||||
@ -225,7 +230,11 @@ namespace os
|
|||||||
Option<PositionalArgument> current = m_positional_args.try_dequeue();
|
Option<PositionalArgument> current = m_positional_args.try_dequeue();
|
||||||
if (!current.has_value())
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +263,7 @@ namespace os
|
|||||||
else { *arg.out = arg.fallback; }
|
else { *arg.out = arg.fallback; }
|
||||||
}
|
}
|
||||||
|
|
||||||
return leftovers;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> ArgumentParser::usage(StringView program_name)
|
Result<void> ArgumentParser::usage(StringView program_name)
|
||||||
@ -268,6 +277,8 @@ namespace os
|
|||||||
else { TRY(sb.format(" [%s]", arg.name.chars())); }
|
else { TRY(sb.format(" [%s]", arg.name.chars())); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_vector_argument) sb.format("%s..."_sv, m_positional_args.size() ? "" : " ");
|
||||||
|
|
||||||
TRY(sb.add('\n'));
|
TRY(sb.add('\n'));
|
||||||
|
|
||||||
auto usage_line = TRY(sb.string());
|
auto usage_line = TRY(sb.string());
|
||||||
|
Loading…
Reference in New Issue
Block a user