mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:57:45 +00:00
Userland+Terminal: Port to new CArgsParser API
While at it, also add some niceties and fix some things.
This commit is contained in:
parent
9276582535
commit
f983dfe319
22 changed files with 392 additions and 653 deletions
|
@ -193,11 +193,11 @@ int main(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CArgsParser args_parser("Terminal");
|
const char* command_to_execute = "/bin/Shell";
|
||||||
|
|
||||||
args_parser.add_arg("e", "execute", "Execute this command inside the terminal.");
|
CArgsParser args_parser;
|
||||||
|
args_parser.add_option(command_to_execute, "Execute this command inside the terminal", nullptr, 'e', "command");
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
args_parser.parse(argc, argv);
|
||||||
|
|
||||||
if (chdir(get_current_user_home_path().characters()) < 0)
|
if (chdir(get_current_user_home_path().characters()) < 0)
|
||||||
perror("chdir");
|
perror("chdir");
|
||||||
|
@ -208,7 +208,7 @@ int main(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
run_command(ptm_fd, args.get("e"));
|
run_command(ptm_fd, command_to_execute);
|
||||||
|
|
||||||
auto window = GWindow::construct();
|
auto window = GWindow::construct();
|
||||||
window->set_title("Terminal");
|
window->set_title("Terminal");
|
||||||
|
@ -269,7 +269,6 @@ int main(int argc, char** argv)
|
||||||
edit_menu->add_action(terminal->paste_action());
|
edit_menu->add_action(terminal->paste_action());
|
||||||
menubar->add_menu(move(edit_menu));
|
menubar->add_menu(move(edit_menu));
|
||||||
|
|
||||||
|
|
||||||
GActionGroup font_action_group;
|
GActionGroup font_action_group;
|
||||||
font_action_group.set_exclusive(true);
|
font_action_group.set_exclusive(true);
|
||||||
auto font_menu = GMenu::construct("Font");
|
auto font_menu = GMenu::construct("Font");
|
||||||
|
|
|
@ -128,69 +128,56 @@ void clean_buffers()
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CArgsParser args_parser("cal");
|
int day = 0;
|
||||||
// FIXME: This i a bit of a cheat, as no nested optional args are available on CArgsParser
|
int month = 0;
|
||||||
args_parser.add_single_value("[[day] month] year");
|
int year = 0;
|
||||||
|
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
CArgsParser args_parser;
|
||||||
Vector<String> values = args.get_single_values();
|
// FIXME: This should ensure two values get parsed as month + year
|
||||||
|
args_parser.add_positional_argument(day, "Day of year", "day", CArgsParser::Required::No);
|
||||||
if (values.size() > 3) {
|
args_parser.add_positional_argument(month, "Month", "month", CArgsParser::Required::No);
|
||||||
printf("Invalid number of values\n");
|
args_parser.add_positional_argument(year, "Year", "year", CArgsParser::Required::No);
|
||||||
args_parser.print_usage();
|
args_parser.parse(argc, argv);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t now = time(nullptr);
|
time_t now = time(nullptr);
|
||||||
auto* tm = localtime(&now);
|
auto* tm = localtime(&now);
|
||||||
|
|
||||||
target_year = tm->tm_year + 1900;
|
// Hack: workaround two values parsing as day + month.
|
||||||
target_month = tm->tm_mon + 1;
|
if (day && month && !year) {
|
||||||
target_day = tm->tm_mday;
|
year = month;
|
||||||
|
month = day;
|
||||||
current_year = target_year;
|
day = 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
clean_buffers();
|
||||||
|
|
||||||
if (year_mode) {
|
if (year_mode) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
printf("Year %4d", target_year);
|
printf("Year %4d", year);
|
||||||
printf(" \n\n");
|
printf(" \n\n");
|
||||||
|
|
||||||
for (int i = 1; i < 12; ++i) {
|
for (int i = 1; i < 12; ++i) {
|
||||||
insert_month_to_print(0, i++, target_year);
|
insert_month_to_print(0, i++, year);
|
||||||
insert_month_to_print(1, i++, target_year);
|
insert_month_to_print(1, i++, year);
|
||||||
insert_month_to_print(2, i, target_year);
|
insert_month_to_print(2, i, year);
|
||||||
printf(print_buffer);
|
printf(print_buffer);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
clean_buffers();
|
clean_buffers();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
insert_month_to_print(0, target_month, target_year);
|
insert_month_to_print(0, month, year);
|
||||||
printf(print_buffer);
|
printf(print_buffer);
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
clean_buffers();
|
clean_buffers();
|
||||||
|
|
|
@ -24,82 +24,51 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/String.h>
|
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
|
#include <LibCore/CArgsParser.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.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)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
const char* path = nullptr;
|
||||||
|
const char* program = "/bin/Shell";
|
||||||
|
int flags = -1;
|
||||||
|
|
||||||
Options options = parse_options(argc, argv);
|
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);
|
||||||
|
|
||||||
if (chroot_with_mount_flags(options.path, options.flags) < 0) {
|
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");
|
perror("chroot");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +78,7 @@ int main(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
execl(options.program, options.program, nullptr);
|
execl(program, program, nullptr);
|
||||||
perror("execl");
|
perror("execl");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,74 +27,32 @@
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
|
#include <LibCore/CArgsParser.h>
|
||||||
#include <LibCore/CFile.h>
|
#include <LibCore/CFile.h>
|
||||||
#include <LibGUI/GApplication.h>
|
#include <LibGUI/GApplication.h>
|
||||||
#include <LibGUI/GClipboard.h>
|
#include <LibGUI/GClipboard.h>
|
||||||
#include <getopt.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
struct Options {
|
struct Options {
|
||||||
String data;
|
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 parse_options(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
const char* type = nullptr;
|
||||||
|
Vector<const char*> text;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
Options options;
|
Options options;
|
||||||
|
options.type = type;
|
||||||
|
|
||||||
static struct option long_options[] = {
|
if (text.is_empty()) {
|
||||||
{ "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;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
// Copy our stdin.
|
// Copy our stdin.
|
||||||
auto c_stdin = CFile::construct();
|
auto c_stdin = CFile::construct();
|
||||||
bool success = c_stdin->open(
|
bool success = c_stdin->open(
|
||||||
|
@ -105,6 +63,17 @@ Options parse_options(int argc, char* argv[])
|
||||||
auto buffer = c_stdin->read_all();
|
auto buffer = c_stdin->read_all();
|
||||||
dbg() << "Read size " << buffer.size();
|
dbg() << "Read size " << buffer.size();
|
||||||
options.data = String((char*)buffer.data(), 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;
|
return options;
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/String.h>
|
|
||||||
#include <AK/FileSystemPath.h>
|
#include <AK/FileSystemPath.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <LibCore/CArgsParser.h>
|
#include <LibCore/CArgsParser.h>
|
||||||
#include <LibCore/CDirIterator.h>
|
#include <LibCore/CDirIterator.h>
|
||||||
|
@ -46,27 +46,28 @@ int main(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CArgsParser args_parser("cp");
|
bool recursion_allowed = false;
|
||||||
args_parser.add_arg("r", "copy directories recursively");
|
Vector<const char*> sources;
|
||||||
args_parser.add_required_single_value("source");
|
const char* destination = nullptr;
|
||||||
args_parser.add_required_single_value("destination");
|
|
||||||
|
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
CArgsParser args_parser;
|
||||||
Vector<String> values = args.get_single_values();
|
args_parser.add_option(recursion_allowed, "Copy directories recursively", "recursive", 'r');
|
||||||
if (values.size() == 0) {
|
args_parser.add_positional_argument(sources, "Source file path", "source");
|
||||||
args_parser.print_usage();
|
args_parser.add_positional_argument(destination, "Destination file path", "destination");
|
||||||
return 0;
|
args_parser.parse(argc, argv);
|
||||||
|
|
||||||
|
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");
|
return 0;
|
||||||
String src_path = values[0];
|
|
||||||
String dst_path = values[1];
|
|
||||||
return copy_file_or_directory(src_path, dst_path, recursion_allowed) ? 0 : 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
* otherwise. If there is an error, its description is output to stderr.
|
||||||
*
|
*
|
||||||
* Directories should only be copied if recursion_allowed is set.
|
* Directories should only be copied if recursion_allowed is set.
|
||||||
*/
|
*/
|
||||||
bool copy_file_or_directory(String src_path, String dst_path, bool recursion_allowed)
|
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.
|
* 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.
|
* 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)
|
bool copy_file(String src_path, String dst_path, struct stat src_stat, int src_fd)
|
||||||
|
|
|
@ -35,56 +35,29 @@ int head(const String& filename, bool print_filename, int line_count, int char_c
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
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;
|
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;
|
int char_count = 0;
|
||||||
if (args.is_present("c")) {
|
bool never_print_filenames = false;
|
||||||
char_count = strtol(args.get("c").characters(), NULL, 10);
|
bool always_print_filenames = false;
|
||||||
if (errno) {
|
Vector<const char*> files;
|
||||||
args_parser.print_usage();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!char_count) {
|
CArgsParser args_parser;
|
||||||
args_parser.print_usage();
|
args_parser.add_option(line_count, "Number of lines to print (default 10)", "lines", 'n', "number");
|
||||||
return -1;
|
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) {
|
if (line_count == 0 && char_count == 0) {
|
||||||
line_count = 10;
|
line_count = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<String> files = args.get_single_values();
|
|
||||||
|
|
||||||
bool print_filenames = files.size() > 1;
|
bool print_filenames = files.size() > 1;
|
||||||
|
if (always_print_filenames)
|
||||||
if (args.is_present("v")) {
|
|
||||||
print_filenames = true;
|
print_filenames = true;
|
||||||
} else if (args.is_present("q")) {
|
else if (never_print_filenames)
|
||||||
print_filenames = false;
|
print_filenames = false;
|
||||||
}
|
|
||||||
|
|
||||||
if (files.is_empty()) {
|
if (files.is_empty()) {
|
||||||
return head("", print_filenames, line_count, char_count);
|
return head("", print_filenames, line_count, char_count);
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <LibCore/CArgsParser.h>
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
#include <getopt.h>
|
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -59,28 +59,13 @@ int main(int argc, char** argv)
|
||||||
perror("pledge");
|
perror("pledge");
|
||||||
return 1;
|
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:
|
CArgsParser args_parser;
|
||||||
fprintf(stderr, "usage: id [-%s]\n", valid_option_characters);
|
args_parser.add_option(flag_print_uid, "Print UID", nullptr, 'u');
|
||||||
return 1;
|
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)) {
|
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");
|
fprintf(stderr, "cannot print only names or real IDs in default format\n");
|
||||||
|
|
|
@ -32,21 +32,18 @@
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
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");
|
CArgsParser args_parser;
|
||||||
args_parser.add_required_single_value("target");
|
args_parser.add_option(symbolic, "Create a symlink", "symbolic", 's');
|
||||||
args_parser.add_required_single_value("link-path");
|
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);
|
if (symbolic) {
|
||||||
Vector<String> values = args.get_single_values();
|
int rc = symlink(target, path);
|
||||||
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 (rc < 0) {
|
if (rc < 0) {
|
||||||
perror("symlink");
|
perror("symlink");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -54,7 +51,7 @@ int main(int argc, char** argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = link(values[0].characters(), values[1].characters());
|
int rc = link(target, path);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
perror("link");
|
perror("link");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -29,12 +29,12 @@
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
#include <LibCore/CArgsParser.h>
|
||||||
#include <LibCore/CDirIterator.h>
|
#include <LibCore/CDirIterator.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <getopt.h>
|
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -83,39 +83,19 @@ int main(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* valid_option_characters = "ltraiGnh";
|
Vector<const char*> paths;
|
||||||
int opt;
|
|
||||||
while ((opt = getopt(argc, argv, valid_option_characters)) != -1) {
|
CArgsParser args_parser;
|
||||||
switch (opt) {
|
args_parser.add_option(flag_show_dotfiles, "Show dotfiles", "all", 'a');
|
||||||
case 'a':
|
args_parser.add_option(flag_long, "Display long info", "long", 'l');
|
||||||
flag_show_dotfiles = true;
|
args_parser.add_option(flag_sort_by_timestamp, "Sort files by timestamp", nullptr, 't');
|
||||||
break;
|
args_parser.add_option(flag_reverse_sort, "Reverse sort order", "reverse", 'r');
|
||||||
case 'l':
|
args_parser.add_option(flag_colorize, "Use pretty colors", nullptr, 'G');
|
||||||
flag_long = true;
|
args_parser.add_option(flag_show_inode, "Show inode ids", "inode", 'i');
|
||||||
break;
|
args_parser.add_option(flag_print_numeric, "In long format, display numeric UID/GID", "numeric-uid-gid", 'n');
|
||||||
case 't':
|
args_parser.add_option(flag_human_readable, "Print human-readable sizes", "human-readable", 'h');
|
||||||
flag_sort_by_timestamp = true;
|
args_parser.add_positional_argument(paths, "Directory to list", "path", CArgsParser::Required::No);
|
||||||
break;
|
args_parser.parse(argc, argv);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag_long) {
|
if (flag_long) {
|
||||||
setpwent();
|
setpwent();
|
||||||
|
@ -135,14 +115,14 @@ int main(int argc, char** argv)
|
||||||
};
|
};
|
||||||
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
if (optind >= argc) {
|
if (paths.is_empty()) {
|
||||||
status = do_file_system_object(".");
|
status = do_file_system_object(".");
|
||||||
} else if (optind + 1 >= argc) {
|
} else if (paths.size() == 1) {
|
||||||
status = do_file_system_object(argv[optind]);
|
status = do_file_system_object(paths[0]);
|
||||||
} else {
|
} else {
|
||||||
for (; optind < argc; ++optind) {
|
for (auto& path : paths) {
|
||||||
printf("%s:\n", argv[optind]);
|
printf("%s:\n", path);
|
||||||
status = do_file_system_object(argv[optind]);
|
status = do_file_system_object(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
|
|
|
@ -152,35 +152,39 @@ bool print_mounts()
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CArgsParser args_parser("mount");
|
const char* source = nullptr;
|
||||||
args_parser.add_arg("devname", "device path");
|
const char* mountpoint = nullptr;
|
||||||
args_parser.add_arg("mountpoint", "mount point");
|
const char* fs_type = nullptr;
|
||||||
args_parser.add_arg("t", "fstype", "file system type");
|
const char* options = nullptr;
|
||||||
args_parser.add_arg("o", "options", "mount options");
|
bool should_mount_all = false;
|
||||||
args_parser.add_arg("a", "mount all systems listed in /etc/fstab");
|
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
|
||||||
|
|
||||||
if (args.is_present("a")) {
|
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;
|
return mount_all() ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (args.get_single_values().size()) {
|
if (!source && !mountpoint)
|
||||||
case 0:
|
|
||||||
return print_mounts() ? 0 : 1;
|
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");
|
perror("mount");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
args_parser.print_usage();
|
args_parser.print_usage(stderr, argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
121
Userland/nl.cpp
121
Userland/nl.cpp
|
@ -31,80 +31,57 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
enum NumberStyle {
|
||||||
|
NumberAllLines,
|
||||||
|
NumberNonEmptyLines,
|
||||||
|
NumberNoLines,
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CArgsParser args_parser("nl");
|
NumberStyle number_style = NumberNonEmptyLines;
|
||||||
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.");
|
int increment = 1;
|
||||||
args_parser.add_arg("i", "incr", "Set line count increment.");
|
const char* separator = " ";
|
||||||
args_parser.add_arg("s", "delim", "Set buffer between the line numbers and text. 1-63 bytes");
|
int start_number = 1;
|
||||||
args_parser.add_arg("v", "startnum", "Initial value used to number logical page lines.");
|
int number_width = 6;
|
||||||
args_parser.add_arg("w", "width", "The number of characters used for the line number.");
|
Vector<const char*> files;
|
||||||
args_parser.add_single_value("file");
|
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
|
||||||
|
|
||||||
bool all_lines_flag = false;
|
CArgsParser args_parser;
|
||||||
bool line_numbers_flag = true;
|
|
||||||
String value_of_b;
|
CArgsParser::Option number_style_option {
|
||||||
if (args.is_present("b")) {
|
true,
|
||||||
value_of_b = args.get("b");
|
"Line numbering style: 't' for non-empty lines, 'a' for all lines, 'n' for no lines",
|
||||||
if (value_of_b == "a")
|
"body-numbering",
|
||||||
all_lines_flag = true;
|
'b',
|
||||||
else if (value_of_b == "t")
|
"style",
|
||||||
all_lines_flag = false;
|
[&number_style](const char* s) {
|
||||||
else if (value_of_b == "n")
|
if (!strcmp(s, "t"))
|
||||||
line_numbers_flag = false;
|
number_style = NumberNonEmptyLines;
|
||||||
else {
|
else if (!strcmp(s, "a"))
|
||||||
args_parser.print_usage();
|
number_style = NumberAllLines;
|
||||||
return 1;
|
else if (!strcmp(s, "n"))
|
||||||
|
number_style = NumberNoLines;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
long line_number_increment = 1;
|
args_parser.add_option(move(number_style_option));
|
||||||
String value_of_i;
|
args_parser.add_option(increment, "Line count increment", "increment", 'i', "number");
|
||||||
if (args.is_present("i")) {
|
args_parser.add_option(separator, "Separator between line numbers and lines", "separator", 's', "string");
|
||||||
value_of_i = args.get("i");
|
args_parser.add_option(start_number, "Initial line number", "startnum", 'v', "number");
|
||||||
line_number_increment = atol(value_of_i.characters());
|
args_parser.add_option(number_width, "Number width", "width", 'w', "number");
|
||||||
if (!line_number_increment) {
|
args_parser.add_positional_argument(files, "Files to process", "file", CArgsParser::Required::No);
|
||||||
args_parser.print_usage();
|
args_parser.parse(argc, argv);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<String> files = args.get_single_values();
|
|
||||||
Vector<FILE*> file_pointers;
|
Vector<FILE*> file_pointers;
|
||||||
if (files.size() > 0) {
|
if (!files.is_empty()) {
|
||||||
for (auto& file : files) {
|
for (auto& file : files) {
|
||||||
FILE* file_pointer;
|
FILE* file_pointer = fopen(file, "r");
|
||||||
if ((file_pointer = fopen(file.characters(), "r")) == NULL) {
|
if (!file_pointer) {
|
||||||
fprintf(stderr, "unable to open %s\n", file.characters());
|
fprintf(stderr, "unable to open %s\n", file);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
file_pointers.append(file_pointer);
|
file_pointers.append(file_pointer);
|
||||||
|
@ -113,21 +90,21 @@ int main(int argc, char** argv)
|
||||||
file_pointers.append(stdin);
|
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) {
|
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 previous_character = 0;
|
||||||
int next_character = 0;
|
int next_character = 0;
|
||||||
while ((next_character = fgetc(file_pointer)) != EOF) {
|
while ((next_character = fgetc(file_pointer)) != EOF) {
|
||||||
if (previous_character == 0 || previous_character == '\n') {
|
if (previous_character == 0 || previous_character == '\n') {
|
||||||
if (!all_lines_flag && next_character == '\n') {
|
if (next_character == '\n' && number_style != NumberAllLines) {
|
||||||
// skips printing line count on empty lines if all_lines_flags is false
|
// Skip printing line count on empty lines.
|
||||||
printf("\n");
|
printf("\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line_numbers_flag)
|
if (number_style != NumberNoLines)
|
||||||
printf("%*lu%s", line_number_width, (line_number += line_number_increment), delimiter);
|
printf("%*d%s", number_width, (line_number += increment), separator);
|
||||||
else
|
else
|
||||||
printf("%*s", line_number_width, "");
|
printf("%*s", number_width, "");
|
||||||
}
|
}
|
||||||
putchar(next_character);
|
putchar(next_character);
|
||||||
previous_character = next_character;
|
previous_character = next_character;
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/String.h>
|
|
||||||
#include <AK/FileSystemPath.h>
|
#include <AK/FileSystemPath.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibCore/CArgsParser.h>
|
#include <LibCore/CArgsParser.h>
|
||||||
|
@ -76,26 +76,22 @@ static int handle_set_pape(const String& name)
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
bool show_all = false;
|
||||||
|
bool show_current = false;
|
||||||
|
const char* name = nullptr;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
GApplication app(argc, argv);
|
GApplication app(argc, argv);
|
||||||
|
|
||||||
CArgsParser args_parser("pape");
|
if (show_all)
|
||||||
|
|
||||||
args_parser.add_arg("a", "show all wallpapers");
|
|
||||||
args_parser.add_arg("c", "show current wallpaper");
|
|
||||||
args_parser.add_single_value("name");
|
|
||||||
|
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
|
||||||
|
|
||||||
if (args.is_present("a"))
|
|
||||||
return handle_show_all();
|
return handle_show_all();
|
||||||
else if (args.is_present("c"))
|
else if (show_current)
|
||||||
return handle_show_current();
|
return handle_show_current();
|
||||||
|
|
||||||
Vector<String> values = args.get_single_values();
|
return handle_set_pape(name);
|
||||||
if (values.size() != 1) {
|
|
||||||
args_parser.print_usage();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return handle_set_pape(values[0]);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,81 +25,32 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
#include <LibCore/CArgsParser.h>
|
||||||
#include <LibGUI/GApplication.h>
|
#include <LibGUI/GApplication.h>
|
||||||
#include <LibGUI/GClipboard.h>
|
#include <LibGUI/GClipboard.h>
|
||||||
#include <getopt.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.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[])
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
GApplication app(argc, argv);
|
bool print_type = false;
|
||||||
|
bool no_newline = false;
|
||||||
|
|
||||||
Options options = parse_options(argc, argv);
|
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);
|
||||||
|
|
||||||
|
GApplication app(argc, argv);
|
||||||
|
|
||||||
GClipboard& clipboard = GClipboard::the();
|
GClipboard& clipboard = GClipboard::the();
|
||||||
auto data_and_type = clipboard.data_and_type();
|
auto data_and_type = clipboard.data_and_type();
|
||||||
|
|
||||||
if (!options.print_type) {
|
if (!print_type) {
|
||||||
printf("%s", data_and_type.data.characters());
|
printf("%s", data_and_type.data.characters());
|
||||||
// Append a newline to text contents, but
|
// Append a newline to text contents, but
|
||||||
// only if we're not asked not to do this.
|
// 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');
|
putchar('\n');
|
||||||
} else {
|
} else {
|
||||||
printf("%s\n", data_and_type.type.characters());
|
printf("%s\n", data_and_type.type.characters());
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/String.h>
|
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibCore/CArgsParser.h>
|
#include <LibCore/CArgsParser.h>
|
||||||
#include <LibCore/CProcessStatisticsReader.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)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CArgsParser args_parser("pidof");
|
bool single_shot = false;
|
||||||
|
const char* omit_pid_value = nullptr;
|
||||||
|
const char* process_name = nullptr;
|
||||||
|
|
||||||
args_parser.add_arg("s", "Single shot - this instructs the program to only return one pid");
|
CArgsParser args_parser;
|
||||||
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.");
|
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");
|
||||||
|
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
args_parser.parse(argc, argv);
|
||||||
|
|
||||||
bool s_arg = args.is_present("s");
|
pid_t pid_to_omit = 0;
|
||||||
bool o_arg = args.is_present("o");
|
if (omit_pid_value) {
|
||||||
pid_t pid = 0;
|
bool ok = true;
|
||||||
|
if (!strcmp(omit_pid_value, "%PPID"))
|
||||||
if (o_arg) {
|
pid_to_omit = getppid();
|
||||||
bool ok = false;
|
|
||||||
String pid_str = args.get("o");
|
|
||||||
|
|
||||||
if (pid_str == "%PPID")
|
|
||||||
pid = getppid();
|
|
||||||
else
|
else
|
||||||
pid = pid_str.to_uint(ok);
|
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(process_name, single_shot, omit_pid_value != nullptr, pid_to_omit);
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pid_of(values[0], s_arg, o_arg, pid);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,16 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int remove(bool recursive, const char* path)
|
int remove(bool recursive, String path)
|
||||||
{
|
{
|
||||||
struct stat path_stat;
|
struct stat path_stat;
|
||||||
if (lstat(path, &path_stat) < 0) {
|
if (lstat(path.characters(), &path_stat) < 0) {
|
||||||
perror("lstat");
|
perror("lstat");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISDIR(path_stat.st_mode) && recursive) {
|
if (S_ISDIR(path_stat.st_mode) && recursive) {
|
||||||
DIR* derp = opendir(path);
|
DIR* derp = opendir(path.characters());
|
||||||
if (!derp) {
|
if (!derp) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -55,18 +55,18 @@ int remove(bool recursive, const char* path)
|
||||||
builder.append(path);
|
builder.append(path);
|
||||||
builder.append('/');
|
builder.append('/');
|
||||||
builder.append(de->d_name);
|
builder.append(de->d_name);
|
||||||
int s = remove(true, builder.to_string().characters());
|
int s = remove(true, builder.to_string());
|
||||||
if (s < 0)
|
if (s < 0)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int s = rmdir(path);
|
int s = rmdir(path.characters());
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
perror("rmdir");
|
perror("rmdir");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int rc = unlink(path);
|
int rc = unlink(path.characters());
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
perror("unlink");
|
perror("unlink");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -77,16 +77,13 @@ int remove(bool recursive, const char* path)
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CArgsParser args_parser("rm");
|
bool recursive = false;
|
||||||
args_parser.add_arg("r", "Delete directory recursively.");
|
const char* path = nullptr;
|
||||||
args_parser.add_required_single_value("path");
|
|
||||||
|
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
CArgsParser args_parser;
|
||||||
Vector<String> values = args.get_single_values();
|
args_parser.add_option(recursive, "Delete directories recursively", "recursive", 'r');
|
||||||
if (values.size() == 0) {
|
args_parser.add_positional_argument(path, "File to remove", "path");
|
||||||
args_parser.print_usage();
|
args_parser.parse(argc, argv);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return remove(args.is_present("r"), values[0].characters());
|
return remove(recursive, path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,17 +30,19 @@
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CArgsParser args_parser("shutdown");
|
bool now = false;
|
||||||
args_parser.add_arg("n", "shut down now");
|
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
|
||||||
|
|
||||||
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) {
|
if (halt() < 0) {
|
||||||
perror("shutdown");
|
perror("shutdown");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
args_parser.print_usage();
|
args_parser.print_usage(stderr, argv[0]);
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,20 +109,17 @@ static int handle_var(const String& var)
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
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");
|
CArgsParser args_parser;
|
||||||
args_parser.add_single_value("variable=[value]");
|
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 (show_all) {
|
||||||
|
|
||||||
if (args.is_present("a")) {
|
|
||||||
return handle_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(var);
|
||||||
return handle_var(values[0]);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,34 +101,19 @@ int main(int argc, char* argv[])
|
||||||
return 1;
|
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");
|
CArgsParser args_parser;
|
||||||
args_parser.add_arg("n", "lines", "fetch the specified number of lines");
|
args_parser.add_option(follow, "Output data as it is written to the file", "follow", 'f');
|
||||||
args_parser.add_required_single_value("file");
|
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);
|
auto f = CFile::construct(file);
|
||||||
|
|
||||||
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]);
|
|
||||||
if (!f->open(CIODevice::ReadOnly)) {
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +122,6 @@ int main(int argc, char* argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flag_follow = args.is_present("f");
|
|
||||||
auto pos = find_seek_pos(*f, line_count);
|
auto pos = find_seek_pos(*f, line_count);
|
||||||
return tail_from_pos(*f, pos, flag_follow);
|
return tail_from_pos(*f, pos, follow);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,18 +25,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
#include <LibCore/CArgsParser.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <getopt.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.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;
|
int oflag;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
if (aflag) {
|
if (append) {
|
||||||
oflag = O_APPEND;
|
oflag = O_APPEND;
|
||||||
mode = 0;
|
mode = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,8 +45,8 @@ static Vector<int> collect_fds(int argc, char** argv, int start, bool aflag, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<int> fds;
|
Vector<int> fds;
|
||||||
for (int i = start; i < argc; ++i) {
|
for (const char* path : paths) {
|
||||||
int fd = open(argv[i], oflag, mode);
|
int fd = open(path, oflag, mode);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
perror("failed to open file for writing");
|
perror("failed to open file for writing");
|
||||||
*err = true;
|
*err = true;
|
||||||
|
@ -119,28 +119,24 @@ static void int_handler(int)
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
bool aflag = false, iflag = false;
|
bool append = false;
|
||||||
int c = 0;
|
bool ignore_interrupts = false;
|
||||||
while ((c = getopt(argc, argv, "ai")) != -1) {
|
Vector<const char*> paths;
|
||||||
switch (c) {
|
|
||||||
case 'a':
|
|
||||||
aflag = true;
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
iflag = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iflag) {
|
CArgsParser args_parser;
|
||||||
if (signal(SIGINT, int_handler) == SIG_ERR) {
|
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 (ignore_interrupts) {
|
||||||
|
if (signal(SIGINT, int_handler) == SIG_ERR)
|
||||||
perror("failed to install SIGINT handler");
|
perror("failed to install SIGINT handler");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool err_open = false;
|
bool err_open = false;
|
||||||
bool err_write = 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);
|
copy_stdin(fds, &err_write);
|
||||||
close_fds(fds);
|
close_fds(fds);
|
||||||
|
|
||||||
|
|
|
@ -38,29 +38,31 @@ enum TruncateOperation {
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CArgsParser args_parser("truncate");
|
const char* resize = nullptr;
|
||||||
|
const char* reference = nullptr;
|
||||||
|
const char* file = nullptr;
|
||||||
|
|
||||||
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.");
|
CArgsParser args_parser;
|
||||||
args_parser.add_arg("r", "reference", "Resize the target file to match the size of this one.");
|
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_required_single_value("file");
|
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);
|
||||||
|
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
if (!resize && !reference) {
|
||||||
|
args_parser.print_usage(stderr, argv[0]);
|
||||||
if (!args.is_present("s") && !args.is_present("r")) {
|
return 1;
|
||||||
args_parser.print_usage();
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.is_present("s") && args.is_present("r")) {
|
if (resize && reference) {
|
||||||
args_parser.print_usage();
|
args_parser.print_usage(stderr, argv[0]);
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto op = OP_Set;
|
auto op = OP_Set;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
if (args.is_present("s")) {
|
if (resize) {
|
||||||
auto str = args.get("s");
|
String str = resize;
|
||||||
|
|
||||||
switch (str[0]) {
|
switch (str[0]) {
|
||||||
case '+':
|
case '+':
|
||||||
|
@ -76,35 +78,33 @@ int main(int argc, char** argv)
|
||||||
bool ok;
|
bool ok;
|
||||||
size = str.to_int(ok);
|
size = str.to_int(ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
args_parser.print_usage();
|
args_parser.print_usage(stderr, argv[0]);
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.is_present("r")) {
|
if (reference) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int rc = stat(args.get("r").characters(), &st);
|
int rc = stat(reference, &st);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
perror("stat");
|
perror("stat");
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
op = OP_Set;
|
op = OP_Set;
|
||||||
size = st.st_size;
|
size = st.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = args.get_single_values()[0];
|
int fd = open(file, O_RDWR | O_CREAT, 0666);
|
||||||
|
|
||||||
int fd = open(name.characters(), O_RDWR | O_CREAT, 0666);
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
perror("open");
|
perror("open");
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat(fd, &st) < 0) {
|
if (fstat(fd, &st) < 0) {
|
||||||
perror("fstat");
|
perror("fstat");
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -120,12 +120,12 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
if (ftruncate(fd, size) < 0) {
|
if (ftruncate(fd, size) < 0) {
|
||||||
perror("ftruncate");
|
perror("ftruncate");
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close(fd) < 0) {
|
if (close(fd) < 0) {
|
||||||
perror("close");
|
perror("close");
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -30,19 +30,15 @@
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CArgsParser args_parser("umount");
|
const char* mount_point = nullptr;
|
||||||
args_parser.add_arg("mountpoint", "mount point");
|
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
|
||||||
|
|
||||||
if (argc == 2) {
|
CArgsParser args_parser;
|
||||||
if (umount(argv[1]) < 0) {
|
args_parser.add_positional_argument(mount_point, "Mount point", "mountpoint");
|
||||||
perror("umount");
|
args_parser.parse(argc, argv);
|
||||||
return 1;
|
|
||||||
}
|
if (umount(mount_point) < 0) {
|
||||||
} else {
|
perror("umount");
|
||||||
args_parser.print_usage();
|
return 1;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ Count get_count(const String& file_name)
|
||||||
|
|
||||||
Count get_total_count(Vector<Count>& counts)
|
Count get_total_count(Vector<Count>& counts)
|
||||||
{
|
{
|
||||||
Count total_count{ "total" };
|
Count total_count { "total" };
|
||||||
for (auto& count : counts) {
|
for (auto& count : counts) {
|
||||||
total_count.lines += count.lines;
|
total_count.lines += count.lines;
|
||||||
total_count.words += count.words;
|
total_count.words += count.words;
|
||||||
|
@ -122,47 +122,30 @@ Count get_total_count(Vector<Count>& counts)
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CArgsParser args_parser("wc");
|
Vector<const char*> files;
|
||||||
args_parser.add_arg("l", "Output line count");
|
|
||||||
args_parser.add_arg("c", "Output byte count");
|
CArgsParser args_parser;
|
||||||
args_parser.add_arg("m", "Output character count");
|
args_parser.add_option(output_line, "Output line count", "lines", 'l');
|
||||||
args_parser.add_arg("w", "Output word count");
|
args_parser.add_option(output_byte, "Output byte count", "bytes", 'c');
|
||||||
args_parser.add_arg("h", "Print help message");
|
args_parser.add_option(output_word, "Output word count", "words", 'w');
|
||||||
CArgsParserResult args = args_parser.parse(argc, argv);
|
args_parser.add_positional_argument(files, "File to process", "file", CArgsParser::Required::No);
|
||||||
if (args.is_present("h")) {
|
args_parser.parse(argc, argv);
|
||||||
args_parser.print_usage();
|
|
||||||
return 1;
|
if (!output_line && !output_byte && !output_word)
|
||||||
}
|
output_line = output_byte = output_word = true;
|
||||||
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<String> file_names = args.get_single_values();
|
|
||||||
Vector<Count> counts;
|
Vector<Count> counts;
|
||||||
for (auto& file_name : file_names) {
|
for (auto& file : files) {
|
||||||
Count count = get_count(file_name);
|
Count count = get_count(file);
|
||||||
counts.append(count);
|
counts.append(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_names.size() > 1) {
|
if (files.size() > 1) {
|
||||||
Count total_count = get_total_count(counts);
|
Count total_count = get_total_count(counts);
|
||||||
counts.append(total_count);
|
counts.append(total_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_names.is_empty()) {
|
if (files.is_empty()) {
|
||||||
Count count = get_count("-");
|
Count count = get_count("-");
|
||||||
counts.append(count);
|
counts.append(count);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue