libos: Put everything under the os namespace

This commit is contained in:
apio 2023-04-07 10:40:46 +02:00
parent f1e2937528
commit c752b2b343
Signed by: apio
GPG Key ID: B8A7D06E42258954
6 changed files with 199 additions and 193 deletions

View File

@ -35,7 +35,7 @@ int main(int argc, char** argv)
{
StringView filename;
ArgumentParser parser;
os::ArgumentParser parser;
parser.add_positional_argument(filename, "file"_sv, "-"_sv);
Vector<StringView> extra_files = parser.parse(argc, argv).value();

View File

@ -9,7 +9,7 @@ int main(int argc, char** argv)
{
StringView date;
ArgumentParser parser;
os::ArgumentParser parser;
parser.add_value_argument(date, 'd', "date"_sv, true);
parser.parse(argc, argv);

View File

@ -9,7 +9,7 @@ int main(int argc, char** argv)
FILE* f;
StringView pathname;
ArgumentParser parser;
os::ArgumentParser parser;
parser.add_positional_argument(pathname, "file"_sv, true);
parser.parse(argc, argv);

View File

@ -11,7 +11,7 @@ int main(int argc, char** argv)
bool show_all { false };
bool show_almost_all { false };
ArgumentParser parser;
os::ArgumentParser parser;
parser.add_positional_argument(pathname, "directory"_sv, "/"_sv);
parser.add_switch_argument(show_all, 'a', "all"_sv);
parser.add_switch_argument(show_almost_all, 'A', "almost-all"_sv);

View File

@ -2,47 +2,50 @@
#include <luna/StringView.h>
#include <luna/Vector.h>
class ArgumentParser
namespace os
{
public:
ArgumentParser() = default;
Result<void> add_positional_argument(StringView& out, StringView name, bool required);
Result<void> add_positional_argument(StringView& out, StringView name, StringView fallback);
Result<void> add_switch_argument(bool& out, char short_flag, StringView long_flag);
Result<void> add_value_argument(StringView& out, char short_flag, StringView long_flag, bool value_required);
Result<void> add_value_argument(StringView& out, char short_flag, StringView long_flag, StringView fallback);
Result<Vector<StringView>> parse(int argc, char* const* argv);
private:
struct PositionalArgument
class ArgumentParser
{
StringView* out;
StringView name;
bool required;
StringView fallback;
};
public:
ArgumentParser() = default;
struct SwitchArgument
{
bool* out;
char short_flag;
StringView long_flag;
};
Result<void> add_positional_argument(StringView& out, StringView name, bool required);
Result<void> add_positional_argument(StringView& out, StringView name, StringView fallback);
struct ValueArgument
{
StringView* out;
char short_flag;
StringView long_flag;
bool required;
StringView fallback;
};
Result<void> add_switch_argument(bool& out, char short_flag, StringView long_flag);
Vector<PositionalArgument> m_positional_args;
Vector<SwitchArgument> m_switch_args;
Vector<ValueArgument> m_value_args;
};
Result<void> add_value_argument(StringView& out, char short_flag, StringView long_flag, bool value_required);
Result<void> add_value_argument(StringView& out, char short_flag, StringView long_flag, StringView fallback);
Result<Vector<StringView>> parse(int argc, char* const* argv);
private:
struct PositionalArgument
{
StringView* out;
StringView name;
bool required;
StringView fallback;
};
struct SwitchArgument
{
bool* out;
char short_flag;
StringView long_flag;
};
struct ValueArgument
{
StringView* out;
char short_flag;
StringView long_flag;
bool required;
StringView fallback;
};
Vector<PositionalArgument> m_positional_args;
Vector<SwitchArgument> m_switch_args;
Vector<ValueArgument> m_value_args;
};
}

View File

@ -2,148 +2,94 @@
#include <stdio.h>
#include <stdlib.h>
Result<void> ArgumentParser::add_positional_argument(StringView& out, StringView name, bool required)
namespace os
{
PositionalArgument arg { &out, name, required, {} };
return m_positional_args.try_append(move(arg));
}
Result<void> ArgumentParser::add_positional_argument(StringView& out, StringView name, StringView fallback)
{
PositionalArgument arg { &out, name, false, fallback };
return m_positional_args.try_append(move(arg));
}
Result<void> ArgumentParser::add_switch_argument(bool& out, char short_flag, StringView long_flag)
{
SwitchArgument arg { &out, short_flag, long_flag };
return m_switch_args.try_append(move(arg));
}
Result<void> ArgumentParser::add_value_argument(StringView& out, char short_flag, StringView long_flag,
bool value_required)
{
ValueArgument arg { &out, short_flag, long_flag, value_required, {} };
return m_value_args.try_append(move(arg));
}
Result<void> ArgumentParser::add_value_argument(StringView& out, char short_flag, StringView long_flag,
StringView fallback)
{
ValueArgument arg { &out, short_flag, long_flag, false, fallback };
return m_value_args.try_append(move(arg));
}
static bool looks_like_short_flag(StringView arg)
{
return arg.length() > 1 && arg[0] == '-';
}
static bool looks_like_long_flag(StringView arg)
{
return arg.length() > 2 && arg[0] == '-' && arg[1] == '-';
}
Result<Vector<StringView>> 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;
bool is_still_parsing_flags = true;
for (int i = 1; i < argc; i++)
Result<void> ArgumentParser::add_positional_argument(StringView& out, StringView name, bool required)
{
StringView arg = argv[i];
PositionalArgument arg { &out, name, required, {} };
if (is_parsing_value_argument)
{
*current_value_argument->out = arg;
is_parsing_value_argument = false;
continue;
}
return m_positional_args.try_append(move(arg));
}
if (is_still_parsing_flags)
Result<void> ArgumentParser::add_positional_argument(StringView& out, StringView name, StringView fallback)
{
PositionalArgument arg { &out, name, false, fallback };
return m_positional_args.try_append(move(arg));
}
Result<void> ArgumentParser::add_switch_argument(bool& out, char short_flag, StringView long_flag)
{
SwitchArgument arg { &out, short_flag, long_flag };
return m_switch_args.try_append(move(arg));
}
Result<void> ArgumentParser::add_value_argument(StringView& out, char short_flag, StringView long_flag,
bool value_required)
{
ValueArgument arg { &out, short_flag, long_flag, value_required, {} };
return m_value_args.try_append(move(arg));
}
Result<void> ArgumentParser::add_value_argument(StringView& out, char short_flag, StringView long_flag,
StringView fallback)
{
ValueArgument arg { &out, short_flag, long_flag, false, fallback };
return m_value_args.try_append(move(arg));
}
static bool looks_like_short_flag(StringView arg)
{
return arg.length() > 1 && arg[0] == '-';
}
static bool looks_like_long_flag(StringView arg)
{
return arg.length() > 2 && arg[0] == '-' && arg[1] == '-';
}
Result<Vector<StringView>> 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;
bool is_still_parsing_flags = true;
for (int i = 1; i < argc; i++)
{
if (arg == "--")
StringView arg = argv[i];
if (is_parsing_value_argument)
{
is_still_parsing_flags = false;
*current_value_argument->out = arg;
is_parsing_value_argument = false;
continue;
}
if (looks_like_long_flag(arg))
if (is_still_parsing_flags)
{
StringView flag = &arg[2];
bool found = false;
for (const auto& current : m_switch_args)
if (arg == "--")
{
if (current.long_flag == flag)
{
*current.out = true;
found = true;
break;
}
is_still_parsing_flags = false;
continue;
}
for (const auto& current : m_value_args)
if (looks_like_long_flag(arg))
{
if (current.long_flag == flag)
{
current_value_argument = current;
is_parsing_value_argument = true;
found = true;
break;
}
}
StringView flag = &arg[2];
if (found) continue;
fprintf(stderr, "%s: unrecognized option '%s'\n", program_name.chars(), arg.chars());
exit(1);
}
else if (looks_like_short_flag(arg))
{
StringView flags = &arg[1];
for (usize j = 0; j < flags.length(); j++)
{
char c = flags[j];
bool found = false;
// Last flag, this could be a value flag
if (j + 1 == flags.length())
{
for (const auto& current : m_value_args)
{
if (current.short_flag == ' ') continue;
if (current.short_flag == c)
{
current_value_argument = current;
is_parsing_value_argument = true;
found = true;
break;
}
}
if (found) continue;
}
for (const auto& current : m_switch_args)
{
if (current.short_flag == ' ') continue;
if (current.short_flag == c)
if (current.long_flag == flag)
{
*current.out = true;
found = true;
@ -151,47 +97,104 @@ Result<Vector<StringView>> ArgumentParser::parse(int argc, char* const* argv)
}
}
for (const auto& current : m_value_args)
{
if (current.long_flag == flag)
{
current_value_argument = current;
is_parsing_value_argument = true;
found = true;
break;
}
}
if (found) continue;
fprintf(stderr, "%s: invalid option -- '%c'\n", program_name.chars(), c);
fprintf(stderr, "%s: unrecognized option '%s'\n", program_name.chars(), arg.chars());
exit(1);
}
else if (looks_like_short_flag(arg))
{
StringView flags = &arg[1];
for (usize j = 0; j < flags.length(); j++)
{
char c = flags[j];
bool found = false;
// Last flag, this could be a value flag
if (j + 1 == flags.length())
{
for (const auto& current : m_value_args)
{
if (current.short_flag == ' ') continue;
if (current.short_flag == c)
{
current_value_argument = current;
is_parsing_value_argument = true;
found = true;
break;
}
}
if (found) continue;
}
for (const auto& current : m_switch_args)
{
if (current.short_flag == ' ') continue;
if (current.short_flag == c)
{
*current.out = true;
found = true;
break;
}
}
if (found) continue;
fprintf(stderr, "%s: invalid option -- '%c'\n", program_name.chars(), c);
exit(1);
}
continue;
}
}
Option<PositionalArgument> current = m_positional_args.try_dequeue();
if (!current.has_value())
{
TRY(leftovers.try_append(arg));
continue;
}
*current->out = arg;
}
Option<PositionalArgument> current = m_positional_args.try_dequeue();
if (!current.has_value())
if (is_parsing_value_argument)
{
TRY(leftovers.try_append(arg));
continue;
if (current_value_argument->required)
{
fprintf(stderr, "%s: option '--%s' requires an argument\n", program_name.chars(),
current_value_argument->long_flag.chars());
exit(1);
}
else { *current_value_argument->out = current_value_argument->fallback; }
}
*current->out = arg;
}
if (is_parsing_value_argument)
{
if (current_value_argument->required)
// Loop through all remaining positional arguments.
for (const auto& arg : m_positional_args)
{
fprintf(stderr, "%s: option '--%s' requires an argument\n", program_name.chars(),
current_value_argument->long_flag.chars());
exit(1);
if (arg.required)
{
fprintf(stderr, "%s: required argument '%s' not provided\n", program_name.chars(), arg.name.chars());
exit(1);
}
else { *arg.out = arg.fallback; }
}
else { *current_value_argument->out = current_value_argument->fallback; }
}
// Loop through all remaining positional arguments.
for (const auto& arg : m_positional_args)
{
if (arg.required)
{
fprintf(stderr, "%s: required argument '%s' not provided\n", program_name.chars(), arg.name.chars());
exit(1);
}
else { *arg.out = arg.fallback; }
return leftovers;
}
return leftovers;
}