summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorSergey Bugaev <bugaevc@serenityos.org>2020-01-27 20:25:36 +0300
committerAndreas Kling <kling@serenityos.org>2020-01-28 13:50:18 +0100
commitf983dfe319978b47b4c5314df9ea3373e3d69c05 (patch)
tree27d599f2c30ca6bfbfee6fbc3df98a08f33ac887 /Userland
parent92765825358daaed11fa105ca64cf2c7819e5563 (diff)
downloadserenity-f983dfe319978b47b4c5314df9ea3373e3d69c05.zip
Userland+Terminal: Port to new CArgsParser API
While at it, also add some niceties and fix some things.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/cal.cpp75
-rw-r--r--Userland/chroot.cpp111
-rw-r--r--Userland/copy.cpp75
-rw-r--r--Userland/cp.cpp37
-rw-r--r--Userland/head.cpp53
-rw-r--r--Userland/id.cpp31
-rw-r--r--Userland/ln.cpp25
-rw-r--r--Userland/ls.cpp60
-rw-r--r--Userland/mount.cpp46
-rw-r--r--Userland/nl.cpp117
-rw-r--r--Userland/pape.cpp30
-rw-r--r--Userland/paste.cpp69
-rw-r--r--Userland/pidof.cpp46
-rw-r--r--Userland/rm.cpp29
-rw-r--r--Userland/shutdown.cpp14
-rw-r--r--Userland/sysctl.cpp19
-rw-r--r--Userland/tail.cpp38
-rw-r--r--Userland/tee.cpp38
-rw-r--r--Userland/truncate.cpp56
-rw-r--r--Userland/umount.cpp20
-rw-r--r--Userland/wc.cpp49
21 files changed, 389 insertions, 649 deletions
diff --git a/Userland/cal.cpp b/Userland/cal.cpp
index ee3596983d..dd454f8c54 100644
--- a/Userland/cal.cpp
+++ b/Userland/cal.cpp
@@ -128,69 +128,56 @@ void clean_buffers()
int main(int argc, char** argv)
{
- CArgsParser args_parser("cal");
- // FIXME: This i a bit of a cheat, as no nested optional args are available on CArgsParser
- args_parser.add_single_value("[[day] month] year");
+ int day = 0;
+ int month = 0;
+ int year = 0;
- CArgsParserResult args = args_parser.parse(argc, argv);
- Vector<String> values = args.get_single_values();
-
- if (values.size() > 3) {
- printf("Invalid number of values\n");
- args_parser.print_usage();
- return 0;
- }
+ CArgsParser args_parser;
+ // FIXME: This should ensure two values get parsed as month + year
+ args_parser.add_positional_argument(day, "Day of year", "day", CArgsParser::Required::No);
+ args_parser.add_positional_argument(month, "Month", "month", CArgsParser::Required::No);
+ args_parser.add_positional_argument(year, "Year", "year", CArgsParser::Required::No);
+ args_parser.parse(argc, argv);
time_t now = time(nullptr);
auto* tm = localtime(&now);
- target_year = tm->tm_year + 1900;
- target_month = tm->tm_mon + 1;
- target_day = tm->tm_mday;
-
- current_year = target_year;
- current_month = target_month;
-
- bool year_mode = false;
- switch (values.size()) {
- case 3:
- target_day = atoi(values[0].characters());
- target_month = atoi(values[1].characters());
- target_year = atoi(values[2].characters());
-
- // When passing the 3 parameters (day, month and year) we assume we're there.
- current_year = target_year;
- current_month = target_month;
- break;
- case 2:
- target_month = atoi(values[0].characters());
- target_year = atoi(values[1].characters());
- break;
- case 1:
- target_year = atoi(values[0].characters());
- year_mode = true;
- break;
- default:
- break;
+ // Hack: workaround two values parsing as day + month.
+ if (day && month && !year) {
+ year = month;
+ month = day;
+ day = 0;
}
+ bool year_mode = !day && !month && year;
+
+ if (!year)
+ year = tm->tm_year + 1900;
+ if (!month)
+ month = tm->tm_mon + 1;
+ if (!day)
+ day = tm->tm_mday;
+
+ current_year = year;
+ current_month = month;
+
clean_buffers();
if (year_mode) {
printf(" ");
- printf("Year %4d", target_year);
+ printf("Year %4d", year);
printf(" \n\n");
for (int i = 1; i < 12; ++i) {
- insert_month_to_print(0, i++, target_year);
- insert_month_to_print(1, i++, target_year);
- insert_month_to_print(2, i, target_year);
+ insert_month_to_print(0, i++, year);
+ insert_month_to_print(1, i++, year);
+ insert_month_to_print(2, i, year);
printf(print_buffer);
printf("\n");
clean_buffers();
}
} else {
- insert_month_to_print(0, target_month, target_year);
+ insert_month_to_print(0, month, year);
printf(print_buffer);
printf("\n\n");
clean_buffers();
diff --git a/Userland/chroot.cpp b/Userland/chroot.cpp
index f209f6a197..e4e5cd3b6f 100644
--- a/Userland/chroot.cpp
+++ b/Userland/chroot.cpp
@@ -24,82 +24,51 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <AK/String.h>
#include <AK/StringView.h>
+#include <LibCore/CArgsParser.h>
#include <stdio.h>
#include <unistd.h>
-struct Options {
- const char* path;
- const char* program { "/bin/Shell" };
- int flags { -1 };
-};
-
-void print_usage(const char* argv0)
-{
- fprintf(
- stderr,
- "Usage:\n"
- "\t%s <path> [program] [-o options]\n",
- argv0
- );
-}
-
-Options parse_options(int argc, char** argv)
-{
- Options options;
-
- if (argc < 2) {
- print_usage(argv[0]);
- exit(1);
- }
-
- options.path = argv[1];
- int i = 2;
- if (i < argc && argv[i][0] != '-')
- options.program = argv[i++];
-
- if (i >= argc)
- return options;
-
- if (strcmp(argv[i], "-o") != 0) {
- print_usage(argv[0]);
- exit(1);
- }
- i++;
- if (i >= argc) {
- print_usage(argv[0]);
- exit(1);
- }
-
- options.flags = 0;
-
- StringView arg = argv[i];
- Vector<StringView> parts = arg.split_view(',');
- for (auto& part : parts) {
- if (part == "defaults")
- continue;
- else if (part == "nodev")
- options.flags |= MS_NODEV;
- else if (part == "noexec")
- options.flags |= MS_NOEXEC;
- else if (part == "nosuid")
- options.flags |= MS_NOSUID;
- else if (part == "bind")
- fprintf(stderr, "Ignoring -o bind, as it doesn't make sense for chroot");
- else
- fprintf(stderr, "Ignoring invalid option: %s\n", String(part).characters());
- }
-
- return options;
-}
-
int main(int argc, char** argv)
{
-
- Options options = parse_options(argc, argv);
-
- if (chroot_with_mount_flags(options.path, options.flags) < 0) {
+ const char* path = nullptr;
+ const char* program = "/bin/Shell";
+ int flags = -1;
+
+ CArgsParser args_parser;
+ args_parser.add_positional_argument(path, "New root directory", "path");
+ args_parser.add_positional_argument(program, "Program to run", "program", CArgsParser::Required::No);
+
+ CArgsParser::Option option {
+ true,
+ "Mount options",
+ "options",
+ 'o',
+ "options",
+ [&flags](const char* s) {
+ flags = 0;
+ Vector<StringView> parts = StringView(s).split_view(',');
+ for (auto& part : parts) {
+ if (part == "defaults")
+ continue;
+ else if (part == "nodev")
+ flags |= MS_NODEV;
+ else if (part == "noexec")
+ flags |= MS_NOEXEC;
+ else if (part == "nosuid")
+ flags |= MS_NOSUID;
+ else if (part == "bind")
+ fprintf(stderr, "Ignoring -o bind, as it doesn't make sense for chroot\n");
+ else
+ return false;
+ }
+ return true;
+ }
+ };
+ args_parser.add_option(move(option));
+ args_parser.parse(argc, argv);
+
+ if (chroot_with_mount_flags(path, flags) < 0) {
perror("chroot");
return 1;
}
@@ -109,7 +78,7 @@ int main(int argc, char** argv)
return 1;
}
- execl(options.program, options.program, nullptr);
+ execl(program, program, nullptr);
perror("execl");
return 1;
}
diff --git a/Userland/copy.cpp b/Userland/copy.cpp
index 708f8e929a..aa74e815f9 100644
--- a/Userland/copy.cpp
+++ b/Userland/copy.cpp
@@ -27,74 +27,32 @@
#include <AK/ByteBuffer.h>
#include <AK/String.h>
#include <AK/StringBuilder.h>
+#include <LibCore/CArgsParser.h>
#include <LibCore/CFile.h>
#include <LibGUI/GApplication.h>
#include <LibGUI/GClipboard.h>
-#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
struct Options {
String data;
- String type { "text" };
+ StringView type { "text" };
};
-void print_usage(FILE* stream, const char* argv0)
-{
- fprintf(
- stream,
- "Usage:\n"
- "\t%s [--type type] text\n"
- "\t%s [--type type] < file\n"
- "\n"
- "\t-t type, --type type\tPick a type.\n"
- "\t-h, --help\t\tPrint this help message.\n",
- argv0,
- argv0);
-}
-
Options parse_options(int argc, char* argv[])
{
- Options options;
+ const char* type = nullptr;
+ Vector<const char*> text;
- static struct option long_options[] = {
- { "type", required_argument, 0, 't' },
- { "help", no_argument, 0, 'h' },
- { 0, 0, 0, 0 }
- };
- while (true) {
- int option_index;
- int c = getopt_long(argc, argv, "t:h", long_options, &option_index);
- if (c == -1)
- break;
- if (c == 0)
- c = long_options[option_index].val;
+ CArgsParser args_parser;
+ args_parser.add_option(type, "Pick a type", "type", 't', "type");
+ args_parser.add_positional_argument(text, "Text to copy", "text", CArgsParser::Required::No);
+ args_parser.parse(argc, argv);
- switch (c) {
- case 't':
- options.type = optarg;
- break;
- case 'h':
- print_usage(stdout, argv[0]);
- exit(0);
- default:
- print_usage(stderr, argv[0]);
- exit(1);
- }
- }
+ Options options;
+ options.type = type;
- if (optind < argc) {
- // Copy the rest of our command-line args.
- StringBuilder builder;
- bool first = true;
- for (int i = optind; i < argc; i++) {
- if (!first)
- builder.append(' ');
- first = false;
- builder.append(argv[i]);
- }
- options.data = builder.to_string();
- } else {
+ if (text.is_empty()) {
// Copy our stdin.
auto c_stdin = CFile::construct();
bool success = c_stdin->open(
@@ -105,6 +63,17 @@ Options parse_options(int argc, char* argv[])
auto buffer = c_stdin->read_all();
dbg() << "Read size " << buffer.size();
options.data = String((char*)buffer.data(), buffer.size());
+ } else {
+ // Copy the rest of our command-line args.
+ StringBuilder builder;
+ bool first = true;
+ for (auto& word : text) {
+ if (!first)
+ builder.append(' ');
+ first = false;
+ builder.append(word);
+ }
+ options.data = builder.to_string();
}
return options;
diff --git a/Userland/cp.cpp b/Userland/cp.cpp
index b8ba7b49e4..2a6adc1f7f 100644
--- a/Userland/cp.cpp
+++ b/Userland/cp.cpp
@@ -24,8 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <AK/String.h>
#include <AK/FileSystemPath.h>
+#include <AK/String.h>
#include <AK/StringBuilder.h>
#include <LibCore/CArgsParser.h>
#include <LibCore/CDirIterator.h>
@@ -46,27 +46,28 @@ int main(int argc, char** argv)
return 1;
}
- CArgsParser args_parser("cp");
- args_parser.add_arg("r", "copy directories recursively");
- args_parser.add_required_single_value("source");
- args_parser.add_required_single_value("destination");
+ bool recursion_allowed = false;
+ Vector<const char*> sources;
+ const char* destination = nullptr;
+
+ CArgsParser args_parser;
+ args_parser.add_option(recursion_allowed, "Copy directories recursively", "recursive", 'r');
+ args_parser.add_positional_argument(sources, "Source file path", "source");
+ args_parser.add_positional_argument(destination, "Destination file path", "destination");
+ args_parser.parse(argc, argv);
- CArgsParserResult args = args_parser.parse(argc, argv);
- Vector<String> values = args.get_single_values();
- if (values.size() == 0) {
- args_parser.print_usage();
- return 0;
+ for (auto& source : sources) {
+ bool ok = copy_file_or_directory(source, destination, recursion_allowed);
+ if (!ok)
+ return 1;
}
- bool recursion_allowed = args.is_present("r");
- String src_path = values[0];
- String dst_path = values[1];
- return copy_file_or_directory(src_path, dst_path, recursion_allowed) ? 0 : 1;
+ return 0;
}
/**
- * Copy a file or directory to a new location. Returns true if successful, false
+ * Copy a file or directory to a new location. Returns true if successful, false
* otherwise. If there is an error, its description is output to stderr.
- *
+ *
* Directories should only be copied if recursion_allowed is set.
*/
bool copy_file_or_directory(String src_path, String dst_path, bool recursion_allowed)
@@ -95,9 +96,9 @@ bool copy_file_or_directory(String src_path, String dst_path, bool recursion_all
}
/**
- * Copy a source file to a destination file. Returns true if successful, false
+ * Copy a source file to a destination file. Returns true if successful, false
* otherwise. If there is an error, its description is output to stderr.
- *
+ *
* To avoid repeated work, the source file's stat and file descriptor are required.
*/
bool copy_file(String src_path, String dst_path, struct stat src_stat, int src_fd)
diff --git a/Userland/head.cpp b/Userland/head.cpp
index 84ccd942c3..aaeac55fa5 100644
--- a/Userland/head.cpp
+++ b/Userland/head.cpp
@@ -35,56 +35,29 @@ int head(const String& filename, bool print_filename, int line_count, int char_c
int main(int argc, char** argv)
{
- CArgsParser args_parser("head");
-
- args_parser.add_arg("n", "lines", "Number of lines to print (default 10)");
- args_parser.add_arg("c", "characters", "Number of characters to print");
- args_parser.add_arg("q", "Never print filenames");
- args_parser.add_arg("v", "Always print filenames");
-
- CArgsParserResult args = args_parser.parse(argc, argv);
-
int line_count = 0;
- if (args.is_present("n")) {
- line_count = strtol(args.get("n").characters(), NULL, 10);
- if (errno) {
- args_parser.print_usage();
- return -1;
- }
-
- if (!line_count) {
- args_parser.print_usage();
- return -1;
- }
- }
-
int char_count = 0;
- if (args.is_present("c")) {
- char_count = strtol(args.get("c").characters(), NULL, 10);
- if (errno) {
- args_parser.print_usage();
- return -1;
- }
-
- if (!char_count) {
- args_parser.print_usage();
- return -1;
- }
- }
+ bool never_print_filenames = false;
+ bool always_print_filenames = false;
+ Vector<const char*> files;
+
+ CArgsParser args_parser;
+ args_parser.add_option(line_count, "Number of lines to print (default 10)", "lines", 'n', "number");
+ args_parser.add_option(char_count, "Number of characters to print", "characters", 'c', "number");
+ args_parser.add_option(never_print_filenames, "Never print file names", "quiet", 'q');
+ args_parser.add_option(always_print_filenames, "Always print file names", "verbose", 'v');
+ args_parser.add_positional_argument(files, "File to process", "file", CArgsParser::Required::No);
+ args_parser.parse(argc, argv);
if (line_count == 0 && char_count == 0) {
line_count = 10;
}
- Vector<String> files = args.get_single_values();
-
bool print_filenames = files.size() > 1;
-
- if (args.is_present("v")) {
+ if (always_print_filenames)
print_filenames = true;
- } else if (args.is_present("q")) {
+ else if (never_print_filenames)
print_filenames = false;
- }
if (files.is_empty()) {
return head("", print_filenames, line_count, char_count);
diff --git a/Userland/id.cpp b/Userland/id.cpp
index 6403bf3382..90276e15f0 100644
--- a/Userland/id.cpp
+++ b/Userland/id.cpp
@@ -24,8 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <LibCore/CArgsParser.h>
#include <alloca.h>
-#include <getopt.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
@@ -59,28 +59,13 @@ int main(int argc, char** argv)
perror("pledge");
return 1;
}
- static const char* valid_option_characters = "ugGn";
- int opt;
- while ((opt = getopt(argc, argv, valid_option_characters)) != -1) {
- switch (opt) {
- case 'u':
- flag_print_uid = true;
- break;
- case 'g':
- flag_print_gid = true;
- break;
- case 'G':
- flag_print_gid_all = true;
- break;
- case 'n':
- flag_print_name = true;
- break;
-
- default:
- fprintf(stderr, "usage: id [-%s]\n", valid_option_characters);
- return 1;
- }
- }
+
+ CArgsParser args_parser;
+ args_parser.add_option(flag_print_uid, "Print UID", nullptr, 'u');
+ args_parser.add_option(flag_print_gid, "Print GID", nullptr, 'g');
+ args_parser.add_option(flag_print_gid_all, "Print all GIDs", nullptr, 'G');
+ args_parser.add_option(flag_print_name, "Print name", nullptr, 'n');
+ args_parser.parse(argc, argv);
if (flag_print_name && !(flag_print_uid || flag_print_gid || flag_print_gid_all)) {
fprintf(stderr, "cannot print only names or real IDs in default format\n");
diff --git a/Userland/ln.cpp b/Userland/ln.cpp
index a1379044b7..c567db7dc9 100644
--- a/Userland/ln.cpp
+++ b/Userland/ln.cpp
@@ -32,21 +32,18 @@
int main(int argc, char** argv)
{
- CArgsParser args_parser("ln");
+ bool symbolic = false;
+ const char* target = nullptr;
+ const char* path = nullptr;
- args_parser.add_arg("s", "create a symlink");
- args_parser.add_required_single_value("target");
- args_parser.add_required_single_value("link-path");
+ CArgsParser args_parser;
+ args_parser.add_option(symbolic, "Create a symlink", "symbolic", 's');
+ args_parser.add_positional_argument(target, "Link target", "target");
+ args_parser.add_positional_argument(path, "Link path", "path");
+ args_parser.parse(argc, argv);
- CArgsParserResult args = args_parser.parse(argc, argv);
- Vector<String> values = args.get_single_values();
- if (values.size() == 0) {
- args_parser.print_usage();
- return 0;
- }
-
- if (args.is_present("s")) {
- int rc = symlink(values[0].characters(), values[1].characters());
+ if (symbolic) {
+ int rc = symlink(target, path);
if (rc < 0) {
perror("symlink");
return 1;
@@ -54,7 +51,7 @@ int main(int argc, char** argv)
return 0;
}
- int rc = link(values[0].characters(), values[1].characters());
+ int rc = link(target, path);
if (rc < 0) {
perror("link");
return 1;
diff --git a/Userland/ls.cpp b/Userland/ls.cpp
index 9d15df2f5d..072cb16147 100644
--- a/Userland/ls.cpp
+++ b/Userland/ls.cpp
@@ -29,12 +29,12 @@
#include <AK/String.h>
#include <AK/StringBuilder.h>
#include <AK/Vector.h>
+#include <LibCore/CArgsParser.h>
#include <LibCore/CDirIterator.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
-#include <getopt.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
@@ -83,39 +83,19 @@ int main(int argc, char** argv)
return 1;
}
- static const char* valid_option_characters = "ltraiGnh";
- int opt;
- while ((opt = getopt(argc, argv, valid_option_characters)) != -1) {
- switch (opt) {
- case 'a':
- flag_show_dotfiles = true;
- break;
- case 'l':
- flag_long = true;
- break;
- case 't':
- flag_sort_by_timestamp = true;
- break;
- case 'r':
- flag_reverse_sort = true;
- break;
- case 'G':
- flag_colorize = false;
- break;
- case 'i':
- flag_show_inode = true;
- break;
- case 'n':
- flag_print_numeric = true;
- break;
- case 'h':
- flag_human_readable = true;
- break;
- default:
- fprintf(stderr, "usage: ls [-%s] [paths...]\n", valid_option_characters);
- return 1;
- }
- }
+ Vector<const char*> paths;
+
+ CArgsParser args_parser;
+ args_parser.add_option(flag_show_dotfiles, "Show dotfiles", "all", 'a');
+ args_parser.add_option(flag_long, "Display long info", "long", 'l');
+ args_parser.add_option(flag_sort_by_timestamp, "Sort files by timestamp", nullptr, 't');
+ args_parser.add_option(flag_reverse_sort, "Reverse sort order", "reverse", 'r');
+ args_parser.add_option(flag_colorize, "Use pretty colors", nullptr, 'G');
+ args_parser.add_option(flag_show_inode, "Show inode ids", "inode", 'i');
+ args_parser.add_option(flag_print_numeric, "In long format, display numeric UID/GID", "numeric-uid-gid", 'n');
+ args_parser.add_option(flag_human_readable, "Print human-readable sizes", "human-readable", 'h');
+ args_parser.add_positional_argument(paths, "Directory to list", "path", CArgsParser::Required::No);
+ args_parser.parse(argc, argv);
if (flag_long) {
setpwent();
@@ -135,14 +115,14 @@ int main(int argc, char** argv)
};
int status = 0;
- if (optind >= argc) {
+ if (paths.is_empty()) {
status = do_file_system_object(".");
- } else if (optind + 1 >= argc) {
- status = do_file_system_object(argv[optind]);
+ } else if (paths.size() == 1) {
+ status = do_file_system_object(paths[0]);
} else {
- for (; optind < argc; ++optind) {
- printf("%s:\n", argv[optind]);
- status = do_file_system_object(argv[optind]);
+ for (auto& path : paths) {
+ printf("%s:\n", path);
+ status = do_file_system_object(path);
}
}
return status;
diff --git a/Userland/mount.cpp b/Userland/mount.cpp
index f2da19c69c..4260946d87 100644
--- a/Userland/mount.cpp
+++ b/Userland/mount.cpp
@@ -152,35 +152,39 @@ bool print_mounts()
int main(int argc, char** argv)
{
- CArgsParser args_parser("mount");
- args_parser.add_arg("devname", "device path");
- args_parser.add_arg("mountpoint", "mount point");
- args_parser.add_arg("t", "fstype", "file system type");
- args_parser.add_arg("o", "options", "mount options");
- args_parser.add_arg("a", "mount all systems listed in /etc/fstab");
- CArgsParserResult args = args_parser.parse(argc, argv);
-
- if (args.is_present("a")) {
+ const char* source = nullptr;
+ const char* mountpoint = nullptr;
+ const char* fs_type = nullptr;
+ const char* options = nullptr;
+ bool should_mount_all = false;
+
+ CArgsParser args_parser;
+ args_parser.add_positional_argument(source, "Source path", "source", CArgsParser::Required::No);
+ args_parser.add_positional_argument(mountpoint, "Mount point", "mountpoint", CArgsParser::Required::No);
+ args_parser.add_option(fs_type, "File system type", nullptr, 't', "fstype");
+ args_parser.add_option(options, "Mount options", nullptr, 'o', "options");
+ args_parser.add_option(should_mount_all, "Mount all file systems listed in /etc/fstab", nullptr, 'a');
+ args_parser.parse(argc, argv);
+
+ if (should_mount_all) {
return mount_all() ? 0 : 1;
}
- switch (args.get_single_values().size()) {
- case 0:
+ if (!source && !mountpoint)
return print_mounts() ? 0 : 1;
- case 2: {
- String devname = args.get_single_values()[0];
- String mountpoint = args.get_single_values()[1];
- String fstype = args.is_present("t") ? args.get("t") : "ext2";
- int flags = args.is_present("o") ? parse_options(args.get("o")) : 0;
- if (mount(devname.characters(), mountpoint.characters(), fstype.characters(), flags) < 0) {
+ if (source && mountpoint) {
+ if (!fs_type)
+ fs_type = "ext2";
+ int flags = options ? parse_options(options) : 0;
+
+ if (mount(source, mountpoint, fs_type, flags) < 0) {
perror("mount");
return 1;
}
return 0;
}
- default:
- args_parser.print_usage();
- return 1;
- }
+
+ args_parser.print_usage(stderr, argv[0]);
+ return 1;
}
diff --git a/Userland/nl.cpp b/Userland/nl.cpp
index 32e420023b..ab7ca2615a 100644
--- a/Userland/nl.cpp
+++ b/Userland/nl.cpp
@@ -31,80 +31,57 @@
#include <stdio.h>
#include <string.h>
+enum NumberStyle {
+ NumberAllLines,
+ NumberNonEmptyLines,
+ NumberNoLines,
+};
+
int main(int argc, char** argv)
{
- CArgsParser args_parser("nl");
- args_parser.add_arg("b", "type", "Line count type. \n\tt counts non-empty lines. \n\ta counts all lines. \n\tn counts no lines.");
- args_parser.add_arg("i", "incr", "Set line count increment.");
- args_parser.add_arg("s", "delim", "Set buffer between the line numbers and text. 1-63 bytes");
- args_parser.add_arg("v", "startnum", "Initial value used to number logical page lines.");
- args_parser.add_arg("w", "width", "The number of characters used for the line number.");
- args_parser.add_single_value("file");
- CArgsParserResult args = args_parser.parse(argc, argv);
+ NumberStyle number_style = NumberNonEmptyLines;
+ int increment = 1;
+ const char* separator = " ";
+ int start_number = 1;
+ int number_width = 6;
+ Vector<const char*> files;
- bool all_lines_flag = false;
- bool line_numbers_flag = true;
- String value_of_b;
- if (args.is_present("b")) {
- value_of_b = args.get("b");
- if (value_of_b == "a")
- all_lines_flag = true;
- else if (value_of_b == "t")
- all_lines_flag = false;
- else if (value_of_b == "n")
- line_numbers_flag = false;
- else {
- args_parser.print_usage();
- return 1;
- }
- }
+ CArgsParser args_parser;
- long line_number_increment = 1;
- String value_of_i;
- if (args.is_present("i")) {
- value_of_i = args.get("i");
- line_number_increment = atol(value_of_i.characters());
- if (!line_number_increment) {
- args_parser.print_usage();
- return 1;
- }
- }
+ CArgsParser::Option number_style_option {
+ true,
+ "Line numbering style: 't' for non-empty lines, 'a' for all lines, 'n' for no lines",
+ "body-numbering",
+ 'b',
+ "style",
+ [&number_style](const char* s) {
+ if (!strcmp(s, "t"))
+ number_style = NumberNonEmptyLines;
+ else if (!strcmp(s, "a"))
+ number_style = NumberAllLines;
+ else if (!strcmp(s, "n"))
+ number_style = NumberNoLines;
+ else
+ return false;
- bool delimiter_flag = false;
- String value_of_s;
- if (args.is_present("s")) {
- value_of_s = args.get("s");
- if (value_of_s.length() > 0 && value_of_s.length() < 64)
- delimiter_flag = true;
- else {
- args_parser.print_usage();
- return 1;
+ return true;
}
- }
- char delimiter[64];
- strcpy(delimiter, delimiter_flag ? value_of_s.characters() : " ");
-
- long line_number = 1;
- String value_of_v;
- if (args.is_present("v")) {
- value_of_v = args.get("v");
- line_number = atol(value_of_v.characters());
- }
+ };
- String value_of_w;
- unsigned int line_number_width = 6;
- if (args.is_present("w")) {
- value_of_w = args.get("w");
- line_number_width = atol(value_of_w.characters());
- }
+ args_parser.add_option(move(number_style_option));
+ args_parser.add_option(increment, "Line count increment", "increment", 'i', "number");
+ args_parser.add_option(separator, "Separator between line numbers and lines", "separator", 's', "string");
+ args_parser.add_option(start_number, "Initial line number", "startnum", 'v', "number");
+ args_parser.add_option(number_width, "Number width", "width", 'w', "number");
+ args_parser.add_positional_argument(files, "Files to process", "file", CArgsParser::Required::No);
+ args_parser.parse(argc, argv);
- Vector<String> files = args.get_single_values();
Vector<FILE*> file_pointers;
- if (files.size() > 0) {
+ if (!files.is_empty()) {
for (auto& file : files) {
- FILE* file_pointer;
- if ((file_pointer = fopen(file.characters(), "r")) == NULL) {
- fprintf(stderr, "unable to open %s\n", file.characters());
+ FILE* file_pointer = fopen(file, "r");
+ if (!file_pointer) {
+ fprintf(stderr, "unable to open %s\n", file);
continue;
}
file_pointers.append(file_pointer);
@@ -113,21 +90,21 @@ int main(int argc, char** argv)
file_pointers.append(stdin);
}
- line_number -= line_number_increment; // so the line number can start at 1 when added below
for (auto& file_pointer : file_pointers) {
+ int line_number = start_number - increment; // so the line number can start at 1 when added below
int previous_character = 0;
int next_character = 0;
while ((next_character = fgetc(file_pointer)) != EOF) {
if (previous_character == 0 || previous_character == '\n') {
- if (!all_lines_flag && next_character == '\n') {
- // skips printing line count on empty lines if all_lines_flags is false
+ if (next_character == '\n' && number_style != NumberAllLines) {
+ // Skip printing line count on empty lines.
printf("\n");
continue;
}
- if (line_numbers_flag)
- printf("%*lu%s", line_number_width, (line_number += line_number_increment), delimiter);
+ if (number_style != NumberNoLines)
+ printf("%*d%s", number_width, (line_number += increment), separator);
else
- printf("%*s", line_number_width, "");
+ printf("%*s", number_width, "");
}
putchar(next_character);
previous_character = next_character;
diff --git a/Userland/pape.cpp b/Userland/pape.cpp
index 2c2fdc2d2a..317f54c133 100644
--- a/Userland/pape.cpp
+++ b/Userland/pape.cpp
@@ -24,8 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <AK/String.h>
#include <AK/FileSystemPath.h>
+#include <AK/String.h>
#include <AK/StringBuilder.h>
#include <AK/Vector.h>
#include <LibCore/CArgsParser.h>
@@ -76,26 +76,22 @@ static int handle_set_pape(const String& name)
int main(int argc, char** argv)
{
- GApplication app(argc, argv);
-
- CArgsParser args_parser("pape");
+ bool show_all = false;
+ bool show_current = false;
+ const char* name = nullptr;
- args_parser.add_arg("a", "show all wallpapers");
- args_parser.add_arg("c", "show current wallpaper");
- args_parser.add_single_value("name");
+ CArgsParser args_parser;
+ args_parser.add_option(show_all, "Show all wallpapers", "show-all", 'a');
+ args_parser.add_option(show_current, "Show current wallpaper", "show-current", 'c');
+ args_parser.add_positional_argument(name, "Wallpaper to set", "name", CArgsParser::Required::No);
+ args_parser.parse(argc, argv);
- CArgsParserResult args = args_parser.parse(argc, argv);
+ GApplication app(argc, argv);
- if (args.is_present("a"))
+ if (show_all)
return handle_show_all();
- else if (args.is_present("c"))
+ else if (show_current)
return handle_show_current();
- Vector<String> values = args.get_single_values();
- if (values.size() != 1) {
- args_parser.print_usage();
- return 0;
- }
-
- return handle_set_pape(values[0]);
+ return handle_set_pape(name);
}
diff --git a/Userland/paste.cpp b/Userland/paste.cpp
index 024d06027c..f14ad4588b 100644
--- a/Userland/paste.cpp
+++ b/Userland/paste.cpp
@@ -25,81 +25,32 @@
*/
#include <AK/String.h>
+#include <LibCore/CArgsParser.h>
#include <LibGUI/GApplication.h>
#include <LibGUI/GClipboard.h>
-#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
-struct Options {
- bool print_type { false };
- bool no_newline { false };
-};
-
-void print_usage(FILE* stream, const char* argv0)
-{
- fprintf(
- stream,
- "Usage:\n"
- "\t%s [--print-type] [--no-newline]\n"
- "\n"
- "\t--print-type\t\tDisplay the copied type.\n"
- "\t-n, --no-newline\tDo not append a newline.\n"
- "\t-h, --help\t\tPrint this help message.\n",
- argv0);
-}
-
-Options parse_options(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- Options options;
-
- static struct option long_options[] = {
- { "print-type", no_argument, 0, 'p' },
- { "no-newline", no_argument, 0, 'n' },
- { "help", no_argument, 0, 'h' },
- { 0, 0, 0, 0 }
- };
- while (true) {
- int option_index;
- int c = getopt_long(argc, argv, "hn", long_options, &option_index);
- if (c == -1)
- break;
- if (c == 0)
- c = long_options[option_index].val;
+ bool print_type = false;
+ bool no_newline = false;
- switch (c) {
- case 'p':
- options.print_type = true;
- break;
- case 'n':
- options.no_newline = true;
- break;
- case 'h':
- print_usage(stdout, argv[0]);
- exit(0);
- default:
- print_usage(stderr, argv[0]);
- exit(1);
- }
- }
-
- return options;
-}
+ CArgsParser args_parser;
+ args_parser.add_option(print_type, "Display the copied type", "print-type", 0);
+ args_parser.add_option(no_newline, "Do not append a newline", "no-newline", 'n');
+ args_parser.parse(argc, argv);
-int main(int argc, char* argv[])
-{
GApplication app(argc, argv);
- Options options = parse_options(argc, argv);
-
GClipboard& clipboard = GClipboard::the();
auto data_and_type = clipboard.data_and_type();
- if (!options.print_type) {
+ if (!print_type) {
printf("%s", data_and_type.data.characters());
// Append a newline to text contents, but
// only if we're not asked not to do this.
- if (data_and_type.type == "text" && !options.no_newline)
+ if (data_and_type.type == "text" && !no_newline)
putchar('\n');
} else {
printf("%s\n", data_and_type.type.characters());
diff --git a/Userland/pidof.cpp b/Userland/pidof.cpp
index 305fad8234..332cc794f0 100644
--- a/Userland/pidof.cpp
+++ b/Userland/pidof.cpp
@@ -24,8 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <AK/String.h>
#include <AK/HashMap.h>
+#include <AK/String.h>
#include <AK/Vector.h>
#include <LibCore/CArgsParser.h>
#include <LibCore/CProcessStatisticsReader.h>
@@ -60,33 +60,29 @@ static int pid_of(const String& process_name, bool single_shot, bool omit_pid, p
int main(int argc, char** argv)
{
- CArgsParser args_parser("pidof");
-
- args_parser.add_arg("s", "Single shot - this instructs the program to only return one pid");
- args_parser.add_arg("o", "pid", "Tells pidof to omit processes with that pid. The special pid %PPID can be used to name the parent process of the pidof program.");
-
- CArgsParserResult args = args_parser.parse(argc, argv);
+ bool single_shot = false;
+ const char* omit_pid_value = nullptr;
+ const char* process_name = nullptr;
- bool s_arg = args.is_present("s");
- bool o_arg = args.is_present("o");
- pid_t pid = 0;
+ CArgsParser args_parser;
+ args_parser.add_option(single_shot, "Only return one pid", nullptr, 's');
+ args_parser.add_option(omit_pid_value, "Omit the given PID, or the parent process if the special value %PPID is passed", nullptr, 'o', "pid");
+ args_parser.add_positional_argument(process_name, "Process name to search for", "process-name");
- if (o_arg) {
- bool ok = false;
- String pid_str = args.get("o");
+ args_parser.parse(argc, argv);
- if (pid_str == "%PPID")
- pid = getppid();
+ pid_t pid_to_omit = 0;
+ if (omit_pid_value) {
+ bool ok = true;
+ if (!strcmp(omit_pid_value, "%PPID"))
+ pid_to_omit = getppid();
else
- pid = pid_str.to_uint(ok);
- }
-
- // We should have one single value : the process name
- Vector<String> values = args.get_single_values();
- if (values.size() == 0) {
- args_parser.print_usage();
- return 0;
+ pid_to_omit = StringView(omit_pid_value).to_uint(ok);
+ if (!ok) {
+ fprintf(stderr, "Invalid value for -o\n");
+ args_parser.print_usage(stderr, argv[0]);
+ return 1;
+ }
}
-
- return pid_of(values[0], s_arg, o_arg, pid);
+ return pid_of(process_name, single_shot, omit_pid_value != nullptr, pid_to_omit);
}
diff --git a/Userland/rm.cpp b/Userland/rm.cpp
index 6974fce62a..3e208ae486 100644
--- a/Userland/rm.cpp
+++ b/Userland/rm.cpp
@@ -35,16 +35,16 @@
#include <sys/stat.h>
#include <unistd.h>
-int remove(bool recursive, const char* path)
+int remove(bool recursive, String path)
{
struct stat path_stat;
- if (lstat(path, &path_stat) < 0) {
+ if (lstat(path.characters(), &path_stat) < 0) {
perror("lstat");
return 1;
}
if (S_ISDIR(path_stat.st_mode) && recursive) {
- DIR* derp = opendir(path);
+ DIR* derp = opendir(path.characters());
if (!derp) {
return 1;
}
@@ -55,18 +55,18 @@ int remove(bool recursive, const char* path)
builder.append(path);
builder.append('/');
builder.append(de->d_name);
- int s = remove(true, builder.to_string().characters());
+ int s = remove(true, builder.to_string());
if (s < 0)
return s;
}
}
- int s = rmdir(path);
+ int s = rmdir(path.characters());
if (s < 0) {
perror("rmdir");
return 1;
}
} else {
- int rc = unlink(path);
+ int rc = unlink(path.characters());
if (rc < 0) {
perror("unlink");
return 1;
@@ -77,16 +77,13 @@ int remove(bool recursive, const char* path)
int main(int argc, char** argv)
{
- CArgsParser args_parser("rm");
- args_parser.add_arg("r", "Delete directory recursively.");
- args_parser.add_required_single_value("path");
+ bool recursive = false;
+ const char* path = nullptr;
- CArgsParserResult args = args_parser.parse(argc, argv);
- Vector<String> values = args.get_single_values();
- if (values.size() == 0) {
- args_parser.print_usage();
- return 1;
- }
+ CArgsParser args_parser;
+ args_parser.add_option(recursive, "Delete directories recursively", "recursive", 'r');
+ args_parser.add_positional_argument(path, "File to remove", "path");
+ args_parser.parse(argc, argv);
- return remove(args.is_present("r"), values[0].characters());
+ return remove(recursive, path);
}
diff --git a/Userland/shutdown.cpp b/Userland/shutdown.cpp
index 3ce7c71923..7dd7fecc57 100644
--- a/Userland/shutdown.cpp
+++ b/Userland/shutdown.cpp
@@ -30,17 +30,19 @@
int main(int argc, char** argv)
{
- CArgsParser args_parser("shutdown");
- args_parser.add_arg("n", "shut down now");
- CArgsParserResult args = args_parser.parse(argc, argv);
+ bool now = false;
- if (args.is_present("n")) {
+ CArgsParser args_parser;
+ args_parser.add_option(now, "Shut down now", "now", 'n');
+ args_parser.parse(argc, argv);
+
+ if (now) {
if (halt() < 0) {
perror("shutdown");
return 1;
}
} else {
- args_parser.print_usage();
- return 0;
+ args_parser.print_usage(stderr, argv[0]);
+ return 1;
}
}
diff --git a/Userland/sysctl.cpp b/Userland/sysctl.cpp
index 2fcb57fc64..35497c8cd2 100644
--- a/Userland/sysctl.cpp
+++ b/Userland/sysctl.cpp
@@ -109,20 +109,17 @@ static int handle_var(const String& var)
int main(int argc, char** argv)
{
- CArgsParser args_parser("sysctl");
+ bool show_all = false;
+ const char* var = nullptr;
- args_parser.add_arg("a", "show all variables");
- args_parser.add_single_value("variable=[value]");
+ CArgsParser args_parser;
+ args_parser.add_option(show_all, "Show all variables", nullptr, 'a');
+ args_parser.add_positional_argument(var, "Command (var[=value])", "command");
+ args_parser.parse(argc, argv);
- CArgsParserResult args = args_parser.parse(argc, argv);
-
- if (args.is_present("a")) {
+ if (show_all) {
return handle_show_all();
- } else if (args.get_single_values().size() != 1) {
- args_parser.print_usage();
- return 0;
}
- Vector<String> values = args.get_single_values();
- return handle_var(values[0]);
+ return handle_var(var);
}
diff --git a/Userland/tail.cpp b/Userland/tail.cpp
index ba0def38c4..220d9ab2ef 100644
--- a/Userland/tail.cpp
+++ b/Userland/tail.cpp
@@ -101,34 +101,19 @@ int main(int argc, char* argv[])
return 1;
}
- CArgsParser args_parser("tail");
+ bool follow = false;
+ int line_count = DEFAULT_LINE_COUNT;
+ const char* file = nullptr;
- args_parser.add_arg("f", "follow -- appended data is output as it is written to the file");
- args_parser.add_arg("n", "lines", "fetch the specified number of lines");
- args_parser.add_required_single_value("file");
+ CArgsParser args_parser;
+ args_parser.add_option(follow, "Output data as it is written to the file", "follow", 'f');
+ args_parser.add_option(line_count, "Fetch the specified number of lines", "lines", 'n', "number");
+ args_parser.add_positional_argument(file, "File path", "file");
+ args_parser.parse(argc, argv);
- CArgsParserResult args = args_parser.parse(argc, argv);
-
- Vector<String> values = args.get_single_values();
- if (values.size() != 1) {
- args_parser.print_usage();
- return 1;
- }
-
- int line_count = 0;
- if (args.is_present("n")) {
- line_count = strtol(args.get("n").characters(), NULL, 10);
- if (errno == EINVAL) {
- args_parser.print_usage();
- return 1;
- }
- } else {
- line_count = DEFAULT_LINE_COUNT;
- }
-
- auto f = CFile::construct(values[0]);
+ auto f = CFile::construct(file);
if (!f->open(CIODevice::ReadOnly)) {
- fprintf(stderr, "Error opening file %s: %s\n", f->filename().characters(), strerror(errno));
+ fprintf(stderr, "Error opening file %s: %s\n", file, strerror(errno));
exit(1);
}
@@ -137,7 +122,6 @@ int main(int argc, char* argv[])
return 1;
}
- bool flag_follow = args.is_present("f");
auto pos = find_seek_pos(*f, line_count);
- return tail_from_pos(*f, pos, flag_follow);
+ return tail_from_pos(*f, pos, follow);
}
diff --git a/Userland/tee.cpp b/Userland/tee.cpp
index ba07c2e2d6..40005366a9 100644
--- a/Userland/tee.cpp
+++ b/Userland/tee.cpp
@@ -25,18 +25,18 @@
*/
#include <AK/Vector.h>
+#include <LibCore/CArgsParser.h>
#include <errno.h>
#include <fcntl.h>
-#include <getopt.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
-static Vector<int> collect_fds(int argc, char** argv, int start, bool aflag, bool* err)
+static Vector<int> collect_fds(Vector<const char*> paths, bool append, bool* err)
{
int oflag;
mode_t mode;
- if (aflag) {
+ if (append) {
oflag = O_APPEND;
mode = 0;
} else {
@@ -45,8 +45,8 @@ static Vector<int> collect_fds(int argc, char** argv, int start, bool aflag, boo
}
Vector<int> fds;
- for (int i = start; i < argc; ++i) {
- int fd = open(argv[i], oflag, mode);
+ for (const char* path : paths) {
+ int fd = open(path, oflag, mode);
if (fd < 0) {
perror("failed to open file for writing");
*err = true;
@@ -119,28 +119,24 @@ static void int_handler(int)
int main(int argc, char** argv)
{
- bool aflag = false, iflag = false;
- int c = 0;
- while ((c = getopt(argc, argv, "ai")) != -1) {
- switch (c) {
- case 'a':
- aflag = true;
- break;
- case 'i':
- iflag = true;
- break;
- }
- }
+ bool append = false;
+ bool ignore_interrupts = false;
+ Vector<const char*> paths;
+
+ CArgsParser args_parser;
+ args_parser.add_option(append, "Append, don't overwrite", "append", 'a');
+ args_parser.add_option(ignore_interrupts, "Ignore SIGINT", "ignore-interrupts", 'i');
+ args_parser.add_positional_argument(paths, "Files to copy stdin to", "file", CArgsParser::Required::No);
+ args_parser.parse(argc, argv);
- if (iflag) {
- if (signal(SIGINT, int_handler) == SIG_ERR) {
+ if (ignore_interrupts) {
+ if (signal(SIGINT, int_handler) == SIG_ERR)
perror("failed to install SIGINT handler");
- }
}
bool err_open = false;
bool err_write = false;
- auto fds = collect_fds(argc, argv, optind, aflag, &err_open);
+ auto fds = collect_fds(paths, append, &err_open);
copy_stdin(fds, &err_write);
close_fds(fds);
diff --git a/Userland/truncate.cpp b/Userland/truncate.cpp
index 0bd5dd27ed..44f5079c17 100644
--- a/Userland/truncate.cpp
+++ b/Userland/truncate.cpp
@@ -38,29 +38,31 @@ enum TruncateOperation {
int main(int argc, char** argv)
{
- CArgsParser args_parser("truncate");
-
- args_parser.add_arg("s", "size", "Resize the target file to (or by) this size. Prefix with + or - to expand or shrink the file, or a bare number to set the size exactly.");
- args_parser.add_arg("r", "reference", "Resize the target file to match the size of this one.");
- args_parser.add_required_single_value("file");
-
- CArgsParserResult args = args_parser.parse(argc, argv);
-
- if (!args.is_present("s") && !args.is_present("r")) {
- args_parser.print_usage();
- return -1;
+ const char* resize = nullptr;
+ const char* reference = nullptr;
+ const char* file = nullptr;
+
+ CArgsParser args_parser;
+ args_parser.add_option(resize, "Resize the target file to (or by) this size. Prefix with + or - to expand or shrink the file, or a bare number to set the size exactly", "size", 's', "size");
+ args_parser.add_option(reference, "Resize the target file to match the size of this one", "reference", 'r', "file");
+ args_parser.add_positional_argument(file, "File path", "file");
+ args_parser.parse(argc, argv);
+
+ if (!resize && !reference) {
+ args_parser.print_usage(stderr, argv[0]);
+ return 1;
}
- if (args.is_present("s") && args.is_present("r")) {
- args_parser.print_usage();
- return -1;
+ if (resize && reference) {
+ args_parser.print_usage(stderr, argv[0]);
+ return 1;
}
auto op = OP_Set;
int size = 0;
- if (args.is_present("s")) {
- auto str = args.get("s");
+ if (resize) {
+ String str = resize;
switch (str[0]) {
case '+':
@@ -76,35 +78,33 @@ int main(int argc, char** argv)
bool ok;
size = str.to_int(ok);
if (!ok) {
- args_parser.print_usage();
- return -1;
+ args_parser.print_usage(stderr, argv[0]);
+ return 1;
}
}
- if (args.is_present("r")) {
+ if (reference) {
struct stat st;
- int rc = stat(args.get("r").characters(), &st);
+ int rc = stat(reference, &st);
if (rc < 0) {
perror("stat");
- return -1;
+ return 1;
}
op = OP_Set;
size = st.st_size;
}
- auto name = args.get_single_values()[0];
-
- int fd = open(name.characters(), O_RDWR | O_CREAT, 0666);
+ int fd = open(file, O_RDWR | O_CREAT, 0666);
if (fd < 0) {
perror("open");
- return -1;
+ return 1;
}
struct stat st;
if (fstat(fd, &st) < 0) {
perror("fstat");
- return -1;
+ return 1;
}
switch (op) {
@@ -120,12 +120,12 @@ int main(int argc, char** argv)
if (ftruncate(fd, size) < 0) {
perror("ftruncate");
- return -1;
+ return 1;
}
if (close(fd) < 0) {
perror("close");
- return -1;
+ return 1;
}
return 0;
diff --git a/Userland/umount.cpp b/Userland/umount.cpp
index 3b68dc98cd..845c3a50bf 100644
--- a/Userland/umount.cpp
+++ b/Userland/umount.cpp
@@ -30,19 +30,15 @@
int main(int argc, char** argv)
{
- CArgsParser args_parser("umount");
- args_parser.add_arg("mountpoint", "mount point");
- CArgsParserResult args = args_parser.parse(argc, argv);
+ const char* mount_point = nullptr;
- if (argc == 2) {
- if (umount(argv[1]) < 0) {
- perror("umount");
- return 1;
- }
- } else {
- args_parser.print_usage();
- return 0;
- }
+ CArgsParser args_parser;
+ args_parser.add_positional_argument(mount_point, "Mount point", "mountpoint");
+ args_parser.parse(argc, argv);
+ if (umount(mount_point) < 0) {
+ perror("umount");
+ return 1;
+ }
return 0;
}
diff --git a/Userland/wc.cpp b/Userland/wc.cpp
index 54d475f882..5cb2e95185 100644
--- a/Userland/wc.cpp
+++ b/Userland/wc.cpp
@@ -110,7 +110,7 @@ Count get_count(const String& file_name)
Count get_total_count(Vector<Count>& counts)
{
- Count total_count{ "total" };
+ Count total_count { "total" };
for (auto& count : counts) {
total_count.lines += count.lines;
total_count.words += count.words;
@@ -122,47 +122,30 @@ Count get_total_count(Vector<Count>& counts)
int main(int argc, char** argv)
{
- CArgsParser args_parser("wc");
- args_parser.add_arg("l", "Output line count");
- args_parser.add_arg("c", "Output byte count");
- args_parser.add_arg("m", "Output character count");
- args_parser.add_arg("w", "Output word count");
- args_parser.add_arg("h", "Print help message");
- CArgsParserResult args = args_parser.parse(argc, argv);
- if (args.is_present("h")) {
- args_parser.print_usage();
- return 1;
- }
- if (args.is_present("l")) {
- output_line = true;
- }
- if (args.is_present("w")) {
- output_word = true;
- }
- if (args.is_present("m")) {
- output_character = true;
- }
- if (args.is_present("c")) {
- if (!output_word && !output_line && !output_character)
- output_word = output_line = true;
- output_byte = true;
- }
- if (!output_line && !output_character && !output_word && !output_byte)
- output_line = output_character = output_word = true;
+ Vector<const char*> files;
+
+ CArgsParser args_parser;
+ args_parser.add_option(output_line, "Output line count", "lines", 'l');
+ args_parser.add_option(output_byte, "Output byte count", "bytes", 'c');
+ args_parser.add_option(output_word, "Output word count", "words", 'w');
+ args_parser.add_positional_argument(files, "File to process", "file", CArgsParser::Required::No);
+ args_parser.parse(argc, argv);
+
+ if (!output_line && !output_byte && !output_word)
+ output_line = output_byte = output_word = true;
- Vector<String> file_names = args.get_single_values();
Vector<Count> counts;
- for (auto& file_name : file_names) {
- Count count = get_count(file_name);
+ for (auto& file : files) {
+ Count count = get_count(file);
counts.append(count);
}
- if (file_names.size() > 1) {
+ if (files.size() > 1) {
Count total_count = get_total_count(counts);
counts.append(total_count);
}
- if (file_names.is_empty()) {
+ if (files.is_empty()) {
Count count = get_count("-");
counts.append(count);
}