mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Reduce nesting depth in diagnostics.cpp
This commit is contained in:
@@ -39,57 +39,49 @@ std::pair<WarningState, std::optional<uint8_t>> getInitialWarningState(std::stri
|
||||
state = {.state = WARNING_ENABLED, .error = WARNING_DEFAULT};
|
||||
}
|
||||
|
||||
// Check for an `=` parameter to process as a parametric warning
|
||||
// `-Wno-<flag>` and `-Wno-error=<flag>` negation cannot have an `=` parameter, but without a
|
||||
// parameter, the 0 value will apply to all levels of a parametric warning
|
||||
// Check if there is an "equals" sign followed by a decimal number
|
||||
// Ignore an equals sign at the very end of the string
|
||||
auto equals = flag.find('=');
|
||||
// `-Wno-<flag>` and `-Wno-error=<flag>` negation cannot have an `=` parameter, but without
|
||||
// one, the 0 value will apply to all levels of a parametric warning
|
||||
if (state.state != WARNING_ENABLED || equals == flag.npos || equals == flag.size() - 1) {
|
||||
return {state, std::nullopt};
|
||||
}
|
||||
|
||||
// Is the rest of the string a decimal number?
|
||||
// We want to avoid `strtoul`'s whitespace and sign, so we parse manually
|
||||
char const *ptr = flag.c_str() + equals + 1;
|
||||
uint8_t param = 0;
|
||||
bool hasParam = false;
|
||||
if (state.state == WARNING_ENABLED) {
|
||||
// First, check if there is an "equals" sign followed by a decimal number
|
||||
// Ignore an equal sign at the very end of the string
|
||||
if (auto equals = flag.find('='); equals != flag.npos && equals != flag.size() - 1) {
|
||||
hasParam = true;
|
||||
bool warned = false;
|
||||
|
||||
// Is the rest of the string a decimal number?
|
||||
// We want to avoid `strtoul`'s whitespace and sign, so we parse manually
|
||||
char const *ptr = flag.c_str() + equals + 1;
|
||||
bool warned = false;
|
||||
|
||||
// The `if`'s condition above ensures that this will run at least once
|
||||
do {
|
||||
// If we don't have a digit, bail
|
||||
if (*ptr < '0' || *ptr > '9') {
|
||||
break;
|
||||
}
|
||||
// Avoid overflowing!
|
||||
if (param > UINT8_MAX - (*ptr - '0')) {
|
||||
if (!warned) {
|
||||
warnx(
|
||||
"Invalid warning flag \"%s\": capping parameter at 255", flag.c_str()
|
||||
);
|
||||
}
|
||||
warned = true; // Only warn once, cap always
|
||||
param = 255;
|
||||
continue;
|
||||
}
|
||||
param = param * 10 + (*ptr - '0');
|
||||
|
||||
ptr++;
|
||||
} while (*ptr);
|
||||
|
||||
// If we reached the end of the string, truncate it at the '='
|
||||
if (*ptr == '\0') {
|
||||
flag.resize(equals);
|
||||
// `-W<flag>=0` is equivalent to `-Wno-<flag>`
|
||||
if (param == 0) {
|
||||
state.state = WARNING_DISABLED;
|
||||
}
|
||||
// The `if`'s condition above ensures that this will run at least once
|
||||
do {
|
||||
// If we don't have a digit, bail
|
||||
if (*ptr < '0' || *ptr > '9') {
|
||||
break;
|
||||
}
|
||||
// Avoid overflowing!
|
||||
if (param > UINT8_MAX - (*ptr - '0')) {
|
||||
if (!warned) {
|
||||
warnx("Invalid warning flag \"%s\": capping parameter at 255", flag.c_str());
|
||||
}
|
||||
warned = true; // Only warn once, cap always
|
||||
param = 255;
|
||||
continue;
|
||||
}
|
||||
param = param * 10 + (*ptr - '0');
|
||||
|
||||
ptr++;
|
||||
} while (*ptr);
|
||||
|
||||
// If we reached the end of the string, truncate it at the '='
|
||||
if (*ptr == '\0') {
|
||||
flag.resize(equals);
|
||||
// `-W<flag>=0` is equivalent to `-Wno-<flag>`
|
||||
if (param == 0) {
|
||||
state.state = WARNING_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasParam) {
|
||||
return {state, param};
|
||||
}
|
||||
return {state, std::nullopt};
|
||||
return {state, param};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user