Compare commits

..

3 Commits

Author SHA1 Message Date
43f90c4f88
cat: Use ArgumentParser
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-29 22:10:51 +02:00
e6645ed607
StringView+apps: Add a _sv literal suffix to not confuse function overloads
C++ was being naughty and implicitly casting our fallback const char* to a boolean.
2023-03-29 22:10:01 +02:00
e1c03150f8
ArgumentParser: Return leftover arguments from parse() 2023-03-29 22:07:42 +02:00
8 changed files with 50 additions and 30 deletions

View File

@ -7,9 +7,11 @@ function(luna_app SOURCE_FILE APP_NAME)
endfunction()
luna_app(init.cpp init)
luna_app(cat.cpp cat)
luna_app(sh.cpp sh)
luna_app(cat.cpp cat)
target_link_libraries(cat PRIVATE os)
luna_app(date.cpp date)
target_link_libraries(date PRIVATE os)

View File

@ -1,9 +1,24 @@
#include <os/ArgumentParser.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void do_cat(FILE* f)
static void do_cat(StringView path)
{
FILE* f;
if (path == "-") f = stdin;
else
{
f = fopen(path.chars(), "r");
if (!f)
{
perror(path.chars());
exit(1);
}
}
char buffer[4096];
while (1)
@ -12,30 +27,19 @@ static void do_cat(FILE* f)
if (nread == 0) return;
fwrite(buffer, 1, nread, stdout);
}
if (f != stdin) fclose(f);
}
int main(int argc, char** argv)
{
FILE* f;
StringView filename;
if (argc < 2) { do_cat(stdin); }
else
{
for (int i = 1; i < argc; i++)
{
if (!strcmp(argv[i], "-")) f = stdin;
else
{
f = fopen(argv[i], "r");
if (!f)
{
perror(argv[i]);
return 1;
}
}
ArgumentParser parser;
parser.add_positional_argument(filename, "file"_sv, "-"_sv);
Vector<StringView> extra_files = parser.parse(argc, argv).value();
do_cat(f);
if (f != stdin) fclose(f);
}
}
do_cat(filename);
for (auto file : extra_files) { do_cat(file); }
}

View File

@ -10,7 +10,7 @@ int main(int argc, char** argv)
StringView date;
ArgumentParser parser;
parser.add_value_argument(date, 'd', "date", false);
parser.add_value_argument(date, 'd', "date"_sv, false);
parser.parse(argc, argv);
time_t now;

View File

@ -10,7 +10,7 @@ int main(int argc, char** argv)
StringView pathname;
ArgumentParser parser;
parser.add_positional_argument(pathname, "file", true);
parser.add_positional_argument(pathname, "file"_sv, true);
parser.parse(argc, argv);
f = fopen(pathname.chars(), "w");

View File

@ -12,9 +12,9 @@ int main(int argc, char** argv)
bool show_almost_all;
ArgumentParser parser;
parser.add_positional_argument(pathname, "directory", "/");
parser.add_switch_argument(show_all, 'a', "all");
parser.add_switch_argument(show_almost_all, 'A', "almost-all");
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);
parser.parse(argc, argv);
DIR* dp = opendir(pathname.chars());

View File

@ -52,3 +52,13 @@ class StringView
usize m_length { 0 };
};
inline StringView operator""_sv(const char* cstring)
{
return StringView { cstring };
}
inline StringView operator""_sv(const char* cstring, usize length)
{
return StringView { cstring, length };
}

View File

@ -15,7 +15,7 @@ class ArgumentParser
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);
void parse(int argc, char* const* argv);
Result<Vector<StringView>> parse(int argc, char* const* argv);
private:
struct PositionalArgument

View File

@ -49,10 +49,12 @@ static bool looks_like_long_flag(StringView arg)
return arg.length() > 2 && arg[0] == '-' && arg[1] == '-';
}
void ArgumentParser::parse(int argc, char* const* argv)
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;
@ -144,7 +146,7 @@ void ArgumentParser::parse(int argc, char* const* argv)
Option<PositionalArgument> current = m_positional_args.try_dequeue();
if (!current.has_value())
{
fprintf(stderr, "%s: unused argument '%s'\n", program_name.chars(), arg.chars());
TRY(leftovers.try_append(arg));
continue;
}
@ -172,4 +174,6 @@ void ArgumentParser::parse(int argc, char* const* argv)
}
else { *arg.out = arg.fallback; }
}
return leftovers;
}