Signed-off-by: Byron Torres <b@torresjrjr.com>
---
basename.ha | 3 +--
dirname.ha | 3 +--
head.ha | 9 ++++++---
main/main.ha | 23 +++++++++++++++++++++++
nl.ha | 39 +++++++++++++++------------------------
sleep.ha | 9 ++-------
uname.ha | 3 +--
uniq.ha | 5 +----
wc.ha | 4 ++--
9 files changed, 52 insertions(+), 46 deletions(-)
diff --git a/basename.ha b/basename.ha
index a8db3d0..1ea478d 100644
--- a/basename.ha
@@ -13,8 +13,7 @@ export fn utilmain() (main::error | void) = {
const cmd = getopt::parse(os::args, help...);
defer getopt::finish(&cmd);
if (len(cmd.args) != 1 && len(cmd.args) != 2) {
- getopt::printusage(os::stderr, os::args[0], help);
- os::exit(1);
+ main::usage(help);
};
let basename = path::basename(cmd.args[0]);
if (len(cmd.args) == 2) {
diff --git a/dirname.ha b/dirname.ha
index 4fb0548..f0420e3 100644
--- a/dirname.ha
+++ b/dirname.ha
@@ -14,8 +14,7 @@ export fn utilmain() (main::error | void) = {
const cmd = getopt::parse(os::args, help...);
defer getopt::finish(&cmd);
if (len(cmd.args) != 1) {
- getopt::printusage(os::stderr, os::args[0], help);
- os::exit(1);
+ main::usage(help);
};
fmt::println(path::dirname(cmd.args[0]))?;
return void;
diff --git a/head.ha b/head.ha
index 30da5d2..c06b7ea 100644
--- a/head.ha
+++ b/head.ha
@@ -9,8 +9,11 @@ use os;
use strconv;
export fn utilmain() (void | main::error) = {
- const cmd = getopt::parse(os::args, "print the first lines of files",
- ('n', "lines", "set the number of lines to print"));
+ const help: []getopt::help = [
+ "print the first lines of files",
+ ('n', "lines", "print maximum number of lines"),
+ ];
+ const cmd = getopt::parse(os::args, help...);
defer getopt::finish(&cmd);
let n = 10u;
@@ -19,7 +22,7 @@ export fn utilmain() (void | main::error) = {
// Only opt is -n
n = match (strconv::stou(opt.1)) {
case (strconv::invalid | strconv::overflow) =>
- fmt::fatal("Invalid number given for -n");
+ main::usage(help, 'n');
case let n: uint =>
yield n;
};
diff --git a/main/main.ha b/main/main.ha
index 6b3b0d5..8f7936a 100644
--- a/main/main.ha
+++ b/main/main.ha
@@ -1,6 +1,8 @@
use fmt;
use fs;
+use getopt;
use io;
+use os;
use os::exec;
export type error = !(io::error | fs::error | exec::error);
@@ -19,3 +21,24 @@ export @symbol("main") fn main() void = {
case void => void;
};
};
+
+// Prints to stderr a flag error message if specified, then the program usage.
+// Exists the program with error code 1.
+export @noreturn fn usage(help: []getopt::help, flags: rune...) void = {
+ const progname = os::args[0];
+
+ if (len(flags) == 1) {
+ fmt::errorfln("{}: invalid argument for option -{}",
+ progname, flags[0])!;
+ } else if (len(flags) > 1) {
+ fmt::errorf("{}: invalid combination of options",
+ progname)!;
+ for (let i = 0z; i < len(flags); i += 1) {
+ fmt::errorf(" -{}", flags[i])!;
+ };
+ fmt::errorln()!;
+ };
+
+ getopt::printusage(os::stderr, progname, help)!;
+ os::exit(1);
+};
diff --git a/nl.ha b/nl.ha
index 00496cc..4ec228f 100644
--- a/nl.ha
+++ b/nl.ha
@@ -59,7 +59,7 @@ export fn utilmain() (void | main::error) = {
defer getopt::finish(&cmd);
if (len(cmd.args) > 1) {
- usage(help, void);
+ main::usage(help);
};
static const delim_buf: [3 * 2 * 4]u8 = [0...]; // 3 pairs of runes
@@ -98,7 +98,7 @@ export fn utilmain() (void | main::error) = {
case let re: regex::regex =>
yield re;
case let err: regex::error =>
- fmt::fatal("Error: -bp<string>: {}", err);
+ fmt::fatalf("Error: -bp<string>: {}", err);
};
} else {
yield switch (opt.1) {
@@ -109,7 +109,7 @@ export fn utilmain() (void | main::error) = {
case "n" =>
yield none;
case =>
- usage(help, 'b');
+ main::usage(help, 'b');
};
};
case 'd' =>
@@ -121,7 +121,7 @@ export fn utilmain() (void | main::error) = {
case 2 =>
yield opt.1;
case =>
- usage(help, 'd');
+ main::usage(help, 'd');
};
case 'f' =>
foot_style = if (strings::hasprefix(opt.1, "p")) {
@@ -130,7 +130,7 @@ export fn utilmain() (void | main::error) = {
case let re: regex::regex =>
yield re;
case let err: regex::error =>
- fmt::fatal("Error: -fp<string>: {}", err);
+ fmt::fatalf("Error: -fp<string>: {}", err);
};
} else {
yield switch (opt.1) {
@@ -141,7 +141,7 @@ export fn utilmain() (void | main::error) = {
case "n" =>
yield none;
case =>
- usage(help, 'f');
+ main::usage(help, 'f');
};
};
case 'h' =>
@@ -151,7 +151,7 @@ export fn utilmain() (void | main::error) = {
case let re: regex::regex =>
yield re;
case let err: regex::error =>
- fmt::fatal("Error: -hp<string>: {}", err);
+ fmt::fatalf("Error: -hp<string>: {}", err);
};
} else {
yield switch (opt.1) {
@@ -162,25 +162,25 @@ export fn utilmain() (void | main::error) = {
case "n" =>
yield none;
case =>
- usage(help, 'h');
+ main::usage(help, 'h');
};
};
case 'i' =>
ctx.incr = match (strconv::stoi(opt.1)) {
case (strconv::invalid | strconv::overflow) =>
- usage(help, 'i');
+ main::usage(help, 'i');
case let incr: int =>
yield incr;
};
case 'l' =>
ctx.maxblanks = match (strconv::stou(opt.1)) {
case (strconv::invalid | strconv::overflow) =>
- usage(help, 'l');
+ main::usage(help, 'l');
case let maxblanks: uint =>
yield if (maxblanks > 0)
maxblanks
else
- usage(help, 'l');
+ main::usage(help, 'l');
};
case 'n' =>
ctx.mod.padding = switch (opt.1) {
@@ -191,24 +191,24 @@ export fn utilmain() (void | main::error) = {
case "rz" =>
yield fmt::padding::ZEROES;
case =>
- usage(help, 'n');
+ main::usage(help, 'n');
};
case 's' =>
ctx.sep = opt.1;
case 'w' =>
ctx.mod.width = match (strconv::stou(opt.1)) {
case (strconv::invalid | strconv::overflow) =>
- usage(help, 'w');
+ main::usage(help, 'w');
case let width: uint =>
yield if (width > 0)
width
else
- usage(help, 'w');
+ main::usage(help, 'w');
};
case 'v' =>
startnum = match (strconv::stoi(opt.1)) {
case (strconv::invalid | strconv::overflow) =>
- usage(help, 'v');
+ main::usage(help, 'v');
case let startnum: int =>
yield startnum;
};
@@ -356,12 +356,3 @@ fn isblank(line: str) bool = {
};
return true;
};
-
-@noreturn fn usage(help: []getopt::help, flag: (rune | void)) void = {
- if (flag is rune) {
- fmt::errorfln("{}: invalid option parameter for -{}",
- os::args[0], flag: rune)!;
- };
- getopt::printusage(os::stderr, os::args[0], help);
- os::exit(1);
-};
diff --git a/sleep.ha b/sleep.ha
index e7d927f..7e75d1b 100644
--- a/sleep.ha
+++ b/sleep.ha
@@ -13,20 +13,15 @@ export fn utilmain() (void | main::error) = {
defer getopt::finish(&cmd);
if (len(cmd.args) != 1) {
- usage(help);
+ main::usage(help);
};
const seconds = match (strconv::stou(cmd.args[0])) {
case (strconv::invalid | strconv::overflow) =>
- usage(help);
+ main::usage(help);
case let s: uint =>
yield s: int;
};
time::sleep(seconds * time::SECOND);
};
-
-@noreturn fn usage(help: []getopt::help) void = {
- getopt::printusage(os::stderr, os::args[0], help);
- os::exit(1);
-};
diff --git a/uname.ha b/uname.ha
index 66f4fa7..e4cd459 100644
--- a/uname.ha
+++ b/uname.ha
@@ -26,8 +26,7 @@ export fn utilmain() (void | main::error) = {
defer getopt::finish(&cmd);
if (len(cmd.args) != 0) {
- getopt::printusage(os::stderr, os::args[0], help);
- os::exit(1);
+ main::usage(help);
};
let flags: flags = if (len(cmd.opts) == 0) flags::IMPLNAME else 0;
diff --git a/uniq.ha b/uniq.ha
index 3209184..1b9123a 100644
--- a/uniq.ha
+++ b/uniq.ha
@@ -124,8 +124,7 @@ export fn utilmain() (main::error | void) = {
case 's' =>
cfg.skipchars = match (strconv::stou(opt.1)) {
case (strconv::invalid | strconv::overflow) =>
- getopt::printusage(os::stderr, os::args[0], help);
- fmt::fatal("Error: invalid argument for -s");
+ main::usage(help, 's');
case let skipchars: uint =>
yield skipchars;
};
@@ -140,7 +139,6 @@ export fn utilmain() (main::error | void) = {
if (len(cmd.args) >= 1 && cmd.args[0] != "-") {
match (os::open(cmd.args[0])) {
case let err: fs::error =>
- getopt::printusage(os::stderr, os::args[0], help);
fmt::fatalf("Error opening '{}': {}",
cmd.args[0], fs::strerror(err));
case let file: io::file =>
@@ -154,7 +152,6 @@ export fn utilmain() (main::error | void) = {
if (len(cmd.args) == 2) {
match (os::create(cmd.args[1], 0o666, fs::flags::WRONLY)) {
case let err: fs::error =>
- getopt::printusage(os::stderr, os::args[0], help);
fmt::fatalf("Error opening '{}': {}",
cmd.args[1], fs::strerror(err));
case let file: io::file =>
diff --git a/wc.ha b/wc.ha
index 15bc557..fe45946 100644
--- a/wc.ha
+++ b/wc.ha
@@ -45,12 +45,12 @@ export fn utilmain() (main::error | void) = {
switch (opt.0) {
case 'c' =>
if (mode & items::CHARS != 0) {
- fmt::fatal("Error: -c and -m are mutually exclusive");
+ main::usage(help, 'c', 'm');
};
mode |= items::BYTES;
case 'm' =>
if (mode & items::BYTES != 0) {
- fmt::fatal("Error: -c and -m are mutually exclusive");
+ main::usage(help, 'c', 'm');
};
mode |= items::CHARS;
case 'l' =>
--
2.41.0