From c49a7d1e2fa230827f6b9e2a9996d92748ab0280 Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sat, 20 Sep 2025 13:54:28 -0400 Subject: [PATCH] Make CLI and `OPT` options `-p` and `-Q` more consistent (#1834) --- src/asm/main.cpp | 2 +- src/asm/opt.cpp | 89 +++++++++++++++++----------------------- test/asm/invalid-opt.err | 6 +-- test/asm/opt-r.err | 4 +- test/asm/opt.asm | 5 ++- test/asm/opt.err | 2 +- 6 files changed, 48 insertions(+), 60 deletions(-) diff --git a/src/asm/main.cpp b/src/asm/main.cpp index f678e2c6..b477309c 100644 --- a/src/asm/main.cpp +++ b/src/asm/main.cpp @@ -402,7 +402,7 @@ int main(int argc, char *argv[]) { char *endptr; unsigned long precision = strtoul(precisionArg, &endptr, 0); - if (musl_optarg[0] == '\0' || *endptr != '\0') { + if (precisionArg[0] == '\0' || *endptr != '\0') { fatal("Invalid argument for option '-Q'"); } diff --git a/src/asm/opt.cpp b/src/asm/opt.cpp index 23c28e99..e4249581 100644 --- a/src/asm/opt.cpp +++ b/src/asm/opt.cpp @@ -55,84 +55,71 @@ void opt_W(char const *flag) { void opt_Parse(char const *s) { if (s[0] == '-') { - ++s; + ++s; // Skip a leading '-' } - switch (s[0]) { + + char c = *s++; + + while (isBlankSpace(*s)) { + ++s; // Skip leading blank spaces + } + + switch (c) { case 'b': - if (strlen(&s[1]) == 2) { - opt_B(&s[1]); + if (strlen(s) == 2) { + opt_B(s); } else { error("Must specify exactly 2 characters for option 'b'"); } break; case 'g': - if (strlen(&s[1]) == 4) { - opt_G(&s[1]); + if (strlen(s) == 4) { + opt_G(s); } else { error("Must specify exactly 4 characters for option 'g'"); } break; - case 'p': - if (strlen(&s[1]) <= 2) { - int result; - unsigned int padByte; + case 'p': { + char *endptr; + unsigned long padByte = strtoul(s, &endptr, 0); - result = sscanf(&s[1], "%x", &padByte); - if (result != 1) { - error("Invalid argument for option 'p'"); - } else { - // Two characters cannot be scanned as a hex number greater than 0xFF - assume(padByte <= 0xFF); - opt_P(padByte); - } - } else { + if (s[0] == '\0' || *endptr != '\0') { error("Invalid argument for option 'p'"); + } else if (padByte > 0xFF) { + error("Argument for option 'p' must be between 0 and 0xFF"); + } else { + opt_P(padByte); } break; + } case 'Q': { - char const *precisionArg = &s[1]; - if (precisionArg[0] == '.') { - ++precisionArg; + if (s[0] == '.') { + ++s; // Skip leading '.' } - if (strlen(precisionArg) <= 2) { - int result; - unsigned int fixPrecision; + char *endptr; + unsigned long precision = strtoul(s, &endptr, 0); - result = sscanf(precisionArg, "%u", &fixPrecision); - if (result != 1) { - error("Invalid argument for option 'Q'"); - } else if (fixPrecision < 1 || fixPrecision > 31) { - error("Argument for option 'Q' must be between 1 and 31"); - } else { - opt_Q(fixPrecision); - } - } else { + if (s[0] == '\0' || *endptr != '\0') { error("Invalid argument for option 'Q'"); + } else if (precision < 1 || precision > 31) { + error("Argument for option 'Q' must be between 1 and 31"); + } else { + opt_Q(precision); } break; } case 'r': { - ++s; // Skip 'r' - while (isBlankSpace(*s)) { - ++s; // Skip leading blank spaces - } - - if (s[0] == '\0') { - error("Missing argument for option 'r'"); - break; - } - char *endptr; - unsigned long maxRecursionDepth = strtoul(s, &endptr, 10); + unsigned long maxRecursionDepth = strtoul(s, &endptr, 0); - if (*endptr != '\0') { - error("Invalid argument for option 'r' (\"%s\")", s); + if (s[0] == '\0' || *endptr != '\0') { + error("Invalid argument for option 'r'"); } else if (errno == ERANGE) { - error("Argument for option 'r' is out of range (\"%s\")", s); + error("Argument for option 'r' is out of range"); } else { opt_R(maxRecursionDepth); } @@ -140,15 +127,15 @@ void opt_Parse(char const *s) { } case 'W': - if (strlen(&s[1]) > 0) { - opt_W(&s[1]); + if (strlen(s) > 0) { + opt_W(s); } else { error("Must specify an argument for option 'W'"); } break; default: - error("Unknown option '%c'", s[0]); + error("Unknown option '%c'", c); break; } } diff --git a/test/asm/invalid-opt.err b/test/asm/invalid-opt.err index 55c2958a..9a4029b0 100644 --- a/test/asm/invalid-opt.err +++ b/test/asm/invalid-opt.err @@ -20,15 +20,15 @@ error: Repeated digit for graphics constant 'y' at invalid-opt.asm(10) error: Invalid argument for option 'p' at invalid-opt.asm(11) -error: Invalid argument for option 'p' +error: Argument for option 'p' must be between 0 and 0xFF at invalid-opt.asm(12) error: Invalid argument for option 'Q' at invalid-opt.asm(13) -error: Invalid argument for option 'Q' +error: Argument for option 'Q' must be between 1 and 31 at invalid-opt.asm(14) error: Argument for option 'Q' must be between 1 and 31 at invalid-opt.asm(15) -error: Argument for option 'r' is out of range ("99999999999999999999999999") +error: Argument for option 'r' is out of range at invalid-opt.asm(16) error: Must specify an argument for option 'W' at invalid-opt.asm(17) diff --git a/test/asm/opt-r.err b/test/asm/opt-r.err index 6590f7c3..44caf947 100644 --- a/test/asm/opt-r.err +++ b/test/asm/opt-r.err @@ -1,6 +1,6 @@ -error: Missing argument for option 'r' +error: Invalid argument for option 'r' at opt-r.asm(5) -error: Invalid argument for option 'r' ("2a") +error: Invalid argument for option 'r' at opt-r.asm(6) FATAL: Recursion limit (0) exceeded at opt-r.asm(13) diff --git a/test/asm/opt.asm b/test/asm/opt.asm index fbe20b49..4028e114 100644 --- a/test/asm/opt.asm +++ b/test/asm/opt.asm @@ -1,7 +1,8 @@ SECTION "test", ROM0 pusho - opt p42, -Q.4, Wno-div + opt p66, -Q.4, Wno-div + opt -p 0x42, Q .0x04, -W no-div ; idempotent ds 1 println $8000_0000 / -1 def n = 3.14 @@ -13,6 +14,6 @@ popo def n = 3.14 println "{x:n} = {f:n}" -pusho -p99 +pusho -p153 ds 1 popo diff --git a/test/asm/opt.err b/test/asm/opt.err index a14e1c32..ec3f556d 100644 --- a/test/asm/opt.err +++ b/test/asm/opt.err @@ -1,2 +1,2 @@ warning: Division of -2147483648 by -1 yields -2147483648 [-Wdiv] - at opt.asm(12) + at opt.asm(13)