Make CLI and OPT options -p and -Q more consistent (#1834)

This commit is contained in:
Rangi
2025-09-20 13:54:28 -04:00
committed by GitHub
parent d8aff148bb
commit c49a7d1e2f
6 changed files with 48 additions and 60 deletions

View File

@@ -402,7 +402,7 @@ int main(int argc, char *argv[]) {
char *endptr; char *endptr;
unsigned long precision = strtoul(precisionArg, &endptr, 0); 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'"); fatal("Invalid argument for option '-Q'");
} }

View File

@@ -55,84 +55,71 @@ void opt_W(char const *flag) {
void opt_Parse(char const *s) { void opt_Parse(char const *s) {
if (s[0] == '-') { 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': case 'b':
if (strlen(&s[1]) == 2) { if (strlen(s) == 2) {
opt_B(&s[1]); opt_B(s);
} else { } else {
error("Must specify exactly 2 characters for option 'b'"); error("Must specify exactly 2 characters for option 'b'");
} }
break; break;
case 'g': case 'g':
if (strlen(&s[1]) == 4) { if (strlen(s) == 4) {
opt_G(&s[1]); opt_G(s);
} else { } else {
error("Must specify exactly 4 characters for option 'g'"); error("Must specify exactly 4 characters for option 'g'");
} }
break; break;
case 'p': case 'p': {
if (strlen(&s[1]) <= 2) { char *endptr;
int result; unsigned long padByte = strtoul(s, &endptr, 0);
unsigned int padByte;
result = sscanf(&s[1], "%x", &padByte); if (s[0] == '\0' || *endptr != '\0') {
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 {
error("Invalid argument for option 'p'"); 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; break;
}
case 'Q': { case 'Q': {
char const *precisionArg = &s[1]; if (s[0] == '.') {
if (precisionArg[0] == '.') { ++s; // Skip leading '.'
++precisionArg;
} }
if (strlen(precisionArg) <= 2) { char *endptr;
int result; unsigned long precision = strtoul(s, &endptr, 0);
unsigned int fixPrecision;
result = sscanf(precisionArg, "%u", &fixPrecision); if (s[0] == '\0' || *endptr != '\0') {
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 {
error("Invalid argument for option 'Q'"); 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; break;
} }
case 'r': { 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; char *endptr;
unsigned long maxRecursionDepth = strtoul(s, &endptr, 10); unsigned long maxRecursionDepth = strtoul(s, &endptr, 0);
if (*endptr != '\0') { if (s[0] == '\0' || *endptr != '\0') {
error("Invalid argument for option 'r' (\"%s\")", s); error("Invalid argument for option 'r'");
} else if (errno == ERANGE) { } 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 { } else {
opt_R(maxRecursionDepth); opt_R(maxRecursionDepth);
} }
@@ -140,15 +127,15 @@ void opt_Parse(char const *s) {
} }
case 'W': case 'W':
if (strlen(&s[1]) > 0) { if (strlen(s) > 0) {
opt_W(&s[1]); opt_W(s);
} else { } else {
error("Must specify an argument for option 'W'"); error("Must specify an argument for option 'W'");
} }
break; break;
default: default:
error("Unknown option '%c'", s[0]); error("Unknown option '%c'", c);
break; break;
} }
} }

View File

@@ -20,15 +20,15 @@ error: Repeated digit for graphics constant 'y'
at invalid-opt.asm(10) at invalid-opt.asm(10)
error: Invalid argument for option 'p' error: Invalid argument for option 'p'
at invalid-opt.asm(11) 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) at invalid-opt.asm(12)
error: Invalid argument for option 'Q' error: Invalid argument for option 'Q'
at invalid-opt.asm(13) 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) at invalid-opt.asm(14)
error: Argument for option 'Q' must be between 1 and 31 error: Argument for option 'Q' must be between 1 and 31
at invalid-opt.asm(15) 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) at invalid-opt.asm(16)
error: Must specify an argument for option 'W' error: Must specify an argument for option 'W'
at invalid-opt.asm(17) at invalid-opt.asm(17)

View File

@@ -1,6 +1,6 @@
error: Missing argument for option 'r' error: Invalid argument for option 'r'
at opt-r.asm(5) at opt-r.asm(5)
error: Invalid argument for option 'r' ("2a") error: Invalid argument for option 'r'
at opt-r.asm(6) at opt-r.asm(6)
FATAL: Recursion limit (0) exceeded FATAL: Recursion limit (0) exceeded
at opt-r.asm(13) at opt-r.asm(13)

View File

@@ -1,7 +1,8 @@
SECTION "test", ROM0 SECTION "test", ROM0
pusho pusho
opt p42, -Q.4, Wno-div opt p66, -Q.4, Wno-div
opt -p 0x42, Q .0x04, -W no-div ; idempotent
ds 1 ds 1
println $8000_0000 / -1 println $8000_0000 / -1
def n = 3.14 def n = 3.14
@@ -13,6 +14,6 @@ popo
def n = 3.14 def n = 3.14
println "{x:n} = {f:n}" println "{x:n} = {f:n}"
pusho -p99 pusho -p153
ds 1 ds 1
popo popo

View File

@@ -1,2 +1,2 @@
warning: Division of -2147483648 by -1 yields -2147483648 [-Wdiv] warning: Division of -2147483648 by -1 yields -2147483648 [-Wdiv]
at opt.asm(12) at opt.asm(13)