Remove errx and errors.hpp (#1737)

This commit is contained in:
Rangi
2025-07-09 11:04:23 -04:00
committed by GitHub
parent 9acba4b412
commit 5e43ece578
179 changed files with 366 additions and 393 deletions

View File

@@ -3,8 +3,8 @@
configure_file(version.cpp _version.cpp ESCAPE_QUOTES)
set(common_src
"error.cpp"
"extern/getopt.cpp"
"diagnostics.cpp"
"_version.cpp"
)
@@ -47,10 +47,7 @@ set(rgbasm_src
"asm/section.cpp"
"asm/symbol.cpp"
"asm/warning.cpp"
"extern/getopt.cpp"
"extern/utf8decoder.cpp"
"diagnostics.cpp"
"error.cpp"
"linkdefs.cpp"
"opmath.cpp"
"util.cpp"
@@ -67,9 +64,7 @@ set(rgblink_src
"link/section.cpp"
"link/symbol.cpp"
"link/warning.cpp"
"extern/getopt.cpp"
"extern/utf8decoder.cpp"
"error.cpp"
"linkdefs.cpp"
"opmath.cpp"
"util.cpp"
@@ -77,8 +72,6 @@ set(rgblink_src
set(rgbfix_src
"fix/main.cpp"
"extern/getopt.cpp"
"error.cpp"
)
set(rgbgfx_src
@@ -91,8 +84,6 @@ set(rgbgfx_src
"gfx/reverse.cpp"
"gfx/rgba.cpp"
"gfx/warning.cpp"
"extern/getopt.cpp"
"error.cpp"
)
foreach(PROG "asm" "fix" "gfx" "link")

View File

@@ -10,7 +10,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "error.hpp"
#include "diagnostics.hpp"
#include "helpers.hpp"
#include "linkdefs.hpp"
#include "platform.hpp" // S_ISDIR (stat macro)
@@ -72,12 +72,13 @@ std::string const &FileStackNode::dump(uint32_t curLineNo) const {
}
}
void fstk_DumpCurrent() {
bool fstk_DumpCurrent() {
if (lexer_AtTopLevel()) {
fputs("at top level", stderr);
return;
return false;
}
assume(!contextStack.empty());
contextStack.top().fileInfo->dump(lexer_GetLineNo());
return true;
}
std::shared_ptr<FileStackNode> fstk_GetFileStack() {
@@ -159,7 +160,7 @@ bool yywrap() {
uint32_t ifDepth = lexer_GetIFDepth();
if (ifDepth != 0) {
fatalerror(
fatal(
"Ended block with %" PRIu32 " unterminated IF construct%s",
ifDepth,
ifDepth == 1 ? "" : "s"
@@ -188,7 +189,7 @@ bool yywrap() {
// This error message will refer to the current iteration
if (sym->type != SYM_VAR) {
fatalerror("Failed to update FOR symbol value");
fatal("Failed to update FOR symbol value");
}
}
// Advance to the next iteration
@@ -211,11 +212,11 @@ bool yywrap() {
static void checkRecursionDepth() {
if (contextStack.size() > maxRecursionDepth) {
fatalerror("Recursion limit (%zu) exceeded", maxRecursionDepth);
fatal("Recursion limit (%zu) exceeded", maxRecursionDepth);
}
}
static bool newFileContext(std::string const &filePath, bool updateStateNow) {
static void newFileContext(std::string const &filePath, bool updateStateNow) {
checkRecursionDepth();
std::shared_ptr<std::string> uniqueIDStr = nullptr;
@@ -237,7 +238,7 @@ static bool newFileContext(std::string const &filePath, bool updateStateNow) {
.macroArgs = macroArgs,
});
return context.lexerState.setFileAsNextState(filePath, updateStateNow);
context.lexerState.setFileAsNextState(filePath, updateStateNow);
}
static void newMacroContext(Symbol const &macro, std::shared_ptr<MacroArgs> macroArgs) {
@@ -322,9 +323,7 @@ void fstk_RunInclude(std::string const &path, bool preInclude) {
return;
}
if (!newFileContext(*fullPath, false)) {
fatalerror("Failed to set up lexer for file include"); // LCOV_EXCL_LINE
}
newFileContext(*fullPath, false);
}
void fstk_RunMacro(std::string const &macroName, std::shared_ptr<MacroArgs> macroArgs) {
@@ -402,15 +401,13 @@ bool fstk_Break() {
void fstk_NewRecursionDepth(size_t newDepth) {
if (contextStack.size() > newDepth + 1) {
fatalerror("Recursion limit (%zu) exceeded", newDepth);
fatal("Recursion limit (%zu) exceeded", newDepth);
}
maxRecursionDepth = newDepth;
}
void fstk_Init(std::string const &mainPath, size_t maxDepth) {
if (!newFileContext(mainPath, true)) {
fatalerror("Failed to open main file");
}
newFileContext(mainPath, true);
maxRecursionDepth = maxDepth;

View File

@@ -384,7 +384,7 @@ void lexer_IncIFDepth() {
void lexer_DecIFDepth() {
if (lexerState->ifStack.empty()) {
fatalerror("Found ENDC outside of an IF construct");
fatal("Found ENDC outside of an IF construct");
}
lexerState->ifStack.pop_front();
@@ -410,7 +410,7 @@ void LexerState::setAsCurrentState() {
lexerState = this;
}
bool LexerState::setFileAsNextState(std::string const &filePath, bool updateStateNow) {
void LexerState::setFileAsNextState(std::string const &filePath, bool updateStateNow) {
if (filePath == "-") {
path = "<stdin>";
content.emplace<BufferedContent>(STDIN_FILENO);
@@ -423,8 +423,7 @@ bool LexerState::setFileAsNextState(std::string const &filePath, bool updateStat
struct stat statBuf;
if (stat(filePath.c_str(), &statBuf) != 0) {
// LCOV_EXCL_START
error("Failed to stat file \"%s\": %s", filePath.c_str(), strerror(errno));
return false;
fatal("Failed to stat file \"%s\": %s", filePath.c_str(), strerror(errno));
// LCOV_EXCL_STOP
}
path = filePath;
@@ -432,8 +431,7 @@ bool LexerState::setFileAsNextState(std::string const &filePath, bool updateStat
int fd = open(path.c_str(), O_RDONLY);
if (fd < 0) {
// LCOV_EXCL_START
error("Failed to open file \"%s\": %s", path.c_str(), strerror(errno));
return false;
fatal("Failed to open file \"%s\": %s", path.c_str(), strerror(errno));
// LCOV_EXCL_STOP
}
@@ -478,7 +476,6 @@ bool LexerState::setFileAsNextState(std::string const &filePath, bool updateStat
} else {
lexerStateEOL = this;
}
return true;
}
void LexerState::setViewAsNextState(char const *name, ContentSpan const &span, uint32_t lineNo_) {
@@ -565,7 +562,7 @@ size_t BufferedContent::readMore(size_t startIndex, size_t nbChars) {
if (nbReadChars == -1) {
// LCOV_EXCL_START
fatalerror("Error while reading \"%s\": %s", lexerState->path.c_str(), strerror(errno));
fatal("Error while reading \"%s\": %s", lexerState->path.c_str(), strerror(errno));
// LCOV_EXCL_STOP
}
@@ -600,7 +597,7 @@ static void beginExpansion(std::shared_ptr<std::string> str, std::optional<std::
void lexer_CheckRecursionDepth() {
if (lexerState->expansions.size() > maxRecursionDepth + 1) {
fatalerror("Recursion limit (%zu) exceeded", maxRecursionDepth);
fatal("Recursion limit (%zu) exceeded", maxRecursionDepth);
}
}
@@ -1337,7 +1334,7 @@ static Token readIdentifier(char firstChar, bool raw) {
static std::shared_ptr<std::string> readInterpolation(size_t depth) {
if (depth > maxRecursionDepth) {
fatalerror("Recursion limit (%zu) exceeded", maxRecursionDepth);
fatal("Recursion limit (%zu) exceeded", maxRecursionDepth);
}
std::string fmtBuf;
@@ -2292,7 +2289,7 @@ static Token skipIfBlock(bool toEndc) {
case T_(POP_ELIF):
if (lexer_ReachedELSEBlock()) {
// This should be redundant, as the parser handles this error first.
fatalerror("Found ELIF after an ELSE block"); // LCOV_EXCL_LINE
fatal("Found ELIF after an ELSE block"); // LCOV_EXCL_LINE
}
if (!toEndc && lexer_GetIFDepth() == startingDepth) {
return token;
@@ -2301,7 +2298,7 @@ static Token skipIfBlock(bool toEndc) {
case T_(POP_ELSE):
if (lexer_ReachedELSEBlock()) {
fatalerror("Found ELSE after an ELSE block");
fatal("Found ELSE after an ELSE block");
}
lexer_ReachELSEBlock();
if (!toEndc && lexer_GetIFDepth() == startingDepth) {

View File

@@ -11,7 +11,7 @@
#include <string.h>
#include <time.h>
#include "error.hpp"
#include "diagnostics.hpp"
#include "extern/getopt.hpp"
#include "helpers.hpp"
#include "parser.hpp"
@@ -164,7 +164,7 @@ int main(int argc, char *argv[]) {
if (strlen(musl_optarg) == 2) {
opt_B(musl_optarg);
} else {
errx("Must specify exactly 2 characters for option 'b'");
fatal("Must specify exactly 2 characters for option 'b'");
}
break;
@@ -187,7 +187,7 @@ int main(int argc, char *argv[]) {
if (strlen(musl_optarg) == 4) {
opt_G(musl_optarg);
} else {
errx("Must specify exactly 4 characters for option 'g'");
fatal("Must specify exactly 4 characters for option 'g'");
}
break;
@@ -214,7 +214,7 @@ int main(int argc, char *argv[]) {
}
if (dependFile == nullptr) {
// LCOV_EXCL_START
errx("Failed to open dependfile \"%s\": %s", dependFileName, strerror(errno));
fatal("Failed to open dependfile \"%s\": %s", dependFileName, strerror(errno));
// LCOV_EXCL_STOP
}
break;
@@ -232,11 +232,11 @@ int main(int argc, char *argv[]) {
padByte = strtoul(musl_optarg, &endptr, 0);
if (musl_optarg[0] == '\0' || *endptr != '\0') {
errx("Invalid argument for option 'p'");
fatal("Invalid argument for option 'p'");
}
if (padByte > 0xFF) {
errx("Argument for option 'p' must be between 0 and 0xFF");
fatal("Argument for option 'p' must be between 0 and 0xFF");
}
opt_P(padByte);
@@ -252,11 +252,11 @@ int main(int argc, char *argv[]) {
precision = strtoul(precisionArg, &endptr, 0);
if (musl_optarg[0] == '\0' || *endptr != '\0') {
errx("Invalid argument for option 'Q'");
fatal("Invalid argument for option 'Q'");
}
if (precision < 1 || precision > 31) {
errx("Argument for option 'Q' must be between 1 and 31");
fatal("Argument for option 'Q' must be between 1 and 31");
}
opt_Q(precision);
@@ -266,7 +266,7 @@ int main(int argc, char *argv[]) {
maxDepth = strtoul(musl_optarg, &endptr, 0);
if (musl_optarg[0] == '\0' || *endptr != '\0') {
errx("Invalid argument for option 'r'");
fatal("Invalid argument for option 'r'");
}
break;
@@ -274,7 +274,7 @@ int main(int argc, char *argv[]) {
// Split "<features>:<name>" so `musl_optarg` is "<features>" and `name` is "<name>"
char *name = strchr(musl_optarg, ':');
if (!name) {
errx("Invalid argument for option 's'");
fatal("Invalid argument for option 's'");
}
*name++ = '\0';
@@ -293,7 +293,7 @@ int main(int argc, char *argv[]) {
}
// A feature must be specified
if (*feature == '\0') {
errx("Empty feature for option 's'");
fatal("Empty feature for option 's'");
}
// Parse the `feature` and update the `features` list
if (!strcasecmp(feature, "all")) {
@@ -309,7 +309,7 @@ int main(int argc, char *argv[]) {
: !strcasecmp(feature, "macro") ? STATE_MACRO
: NB_STATE_FEATURES;
if (value == NB_STATE_FEATURES) {
errx("Invalid feature for option 's': \"%s\"", feature);
fatal("Invalid feature for option 's': \"%s\"", feature);
} else if (std::find(RANGE(features), value) != features.end()) {
warnx("Ignoring duplicate feature for option 's': \"%s\"", feature);
} else {
@@ -354,11 +354,11 @@ int main(int argc, char *argv[]) {
maxValue = strtoul(musl_optarg, &endptr, 0);
if (musl_optarg[0] == '\0' || *endptr != '\0') {
errx("Invalid argument for option 'X'");
fatal("Invalid argument for option 'X'");
}
if (maxValue > UINT_MAX) {
errx("Argument for option 'X' must be between 0 and %u", UINT_MAX);
fatal("Argument for option 'X' must be between 0 and %u", UINT_MAX);
}
maxErrors = maxValue;
@@ -416,8 +416,8 @@ int main(int argc, char *argv[]) {
if (dependFile) {
if (targetFileName.empty()) {
errx("Dependency files can only be created if a target file is specified with either "
"-o, -MQ or -MT");
fatal("Dependency files can only be created if a target file is specified with either "
"-o, -MQ or -MT");
}
fprintf(dependFile, "%s: %s\n", targetFileName.c_str(), mainFileName.c_str());
@@ -444,7 +444,8 @@ int main(int argc, char *argv[]) {
}
if (nbErrors != 0) {
errx("Assembly aborted (%u error%s)!", nbErrors, nbErrors == 1 ? "" : "s");
fprintf(stderr, "Assembly aborted with %u error%s!\n", nbErrors, nbErrors == 1 ? "" : "s");
exit(1);
}
// If parse aborted due to missing an include, and `-MG` was given, exit normally

View File

@@ -11,7 +11,7 @@
#include <string.h>
#include <string>
#include "error.hpp"
#include "diagnostics.hpp"
#include "helpers.hpp" // assume, Defer
#include "platform.hpp"
@@ -73,7 +73,7 @@ static uint32_t getSectIDIfAny(Section *sect) {
}
// Every section that exists should be in `sectionMap`
fatalerror("Unknown section '%s'", sect->name.c_str()); // LCOV_EXCL_LINE
fatal("Unknown section '%s'", sect->name.c_str()); // LCOV_EXCL_LINE
}
static void writePatch(Patch const &patch, FILE *file) {
@@ -326,7 +326,7 @@ void out_WriteObject() {
}
if (!file) {
// LCOV_EXCL_START
errx("Failed to open object file '%s': %s", objectFileName.c_str(), strerror(errno));
fatal("Failed to open object file '%s': %s", objectFileName.c_str(), strerror(errno));
// LCOV_EXCL_STOP
}
Defer closeFile{[&] { fclose(file); }};
@@ -528,7 +528,7 @@ void out_WriteState(std::string name, std::vector<StateFeature> const &features)
}
if (!file) {
// LCOV_EXCL_START
errx("Failed to open state file '%s': %s", name.c_str(), strerror(errno));
fatal("Failed to open state file '%s': %s", name.c_str(), strerror(errno));
// LCOV_EXCL_STOP
}
Defer closeFile{[&] { fclose(file); }};

View File

@@ -488,11 +488,11 @@ if:
elif:
POP_ELIF iconst NEWLINE {
if (lexer_GetIFDepth() == 0) {
fatalerror("Found ELIF outside of an IF construct");
fatal("Found ELIF outside of an IF construct");
}
if (lexer_RanIFBlock()) {
if (lexer_ReachedELSEBlock()) {
fatalerror("Found ELIF after an ELSE block");
fatal("Found ELIF after an ELSE block");
}
lexer_SetMode(LEXER_SKIP_TO_ENDC);
} else if ($2) {
@@ -506,11 +506,11 @@ elif:
else:
POP_ELSE NEWLINE {
if (lexer_GetIFDepth() == 0) {
fatalerror("Found ELSE outside of an IF construct");
fatal("Found ELSE outside of an IF construct");
}
if (lexer_RanIFBlock()) {
if (lexer_ReachedELSEBlock()) {
fatalerror("Found ELSE after an ELSE block");
fatal("Found ELSE after an ELSE block");
}
lexer_SetMode(LEXER_SKIP_TO_ENDC);
} else {
@@ -779,7 +779,7 @@ endsection:
fail:
POP_FAIL string {
fatalerror("%s", $2.c_str());
fatal("%s", $2.c_str());
}
;
@@ -1608,7 +1608,7 @@ uconst:
iconst {
$$ = $1;
if ($$ < 0) {
fatalerror("Constant must not be negative: %d", $$);
fatal("Constant must not be negative: %d", $$);
}
}
;
@@ -1705,15 +1705,15 @@ string_literal:
if (!sym) {
if (sym_IsPurgedScoped($3)) {
fatalerror("Unknown symbol \"%s\"; it was purged", $3.c_str());
fatal("Unknown symbol \"%s\"; it was purged", $3.c_str());
} else {
fatalerror("Unknown symbol \"%s\"", $3.c_str());
fatal("Unknown symbol \"%s\"", $3.c_str());
}
}
Section const *section = sym->getSection();
if (!section) {
fatalerror("\"%s\" does not belong to any section", sym->name.c_str());
fatal("\"%s\" does not belong to any section", sym->name.c_str());
}
// Section names are capped by rgbasm's maximum string length,
// so this currently can't overflow.
@@ -3041,7 +3041,7 @@ static void compoundAssignment(std::string const &symName, RPNCommand op, int32_
static void failAssert(AssertionType type) {
switch (type) {
case ASSERT_FATAL:
fatalerror("Assertion failed");
fatal("Assertion failed");
case ASSERT_ERROR:
error("Assertion failed");
break;
@@ -3054,7 +3054,7 @@ static void failAssert(AssertionType type) {
static void failAssertMsg(AssertionType type, std::string const &message) {
switch (type) {
case ASSERT_FATAL:
fatalerror("Assertion failed: %s", message.c_str());
fatal("Assertion failed: %s", message.c_str());
case ASSERT_ERROR:
error("Assertion failed: %s", message.c_str());
break;

View File

@@ -434,7 +434,7 @@ void Expression::makeBinaryOp(RPNCommand op, Expression &&src1, Expression const
break;
case RPN_DIV:
if (rval == 0) {
fatalerror("Division by zero");
fatal("Division by zero");
}
if (lval == INT32_MIN && rval == -1) {
@@ -451,7 +451,7 @@ void Expression::makeBinaryOp(RPNCommand op, Expression &&src1, Expression const
break;
case RPN_MOD:
if (rval == 0) {
fatalerror("Modulo by zero");
fatal("Modulo by zero");
}
if (lval == INT32_MIN && rval == -1) {
@@ -462,7 +462,7 @@ void Expression::makeBinaryOp(RPNCommand op, Expression &&src1, Expression const
break;
case RPN_EXP:
if (rval < 0) {
fatalerror("Exponentiation by negative power");
fatal("Exponentiation by negative power");
}
data = op_exponent(lval, rval);

View File

@@ -265,7 +265,7 @@ static void mergeSections(
}
if (nbSectErrors) {
fatalerror(
fatal(
"Cannot create section \"%s\" (%u error%s)",
sect.name.c_str(),
nbSectErrors,
@@ -411,7 +411,7 @@ static Section *getSection(
// Set the current section
static void changeSection() {
if (!currentUnionStack.empty()) {
fatalerror("Cannot change the section within a UNION");
fatal("Cannot change the section within a UNION");
}
sym_ResetCurrentLabelScopes();
@@ -448,7 +448,7 @@ void sect_NewSection(
) {
for (SectionStackEntry &entry : sectionStack) {
if (entry.section && entry.section->name == name) {
fatalerror("Section '%s' is already on the stack", name.c_str());
fatal("Section '%s' is already on the stack", name.c_str());
}
}
@@ -609,7 +609,7 @@ void sect_AlignPC(uint8_t alignment, uint16_t offset) {
static void growSection(uint32_t growth) {
if (growth > 0 && curOffset > UINT32_MAX - growth) {
fatalerror("Section size would overflow internal counter");
fatal("Section size would overflow internal counter");
}
curOffset += growth;
if (uint32_t outOffset = sect_GetOutputOffset(); outOffset > currentSection->size) {
@@ -1025,7 +1025,7 @@ void sect_PushSection() {
void sect_PopSection() {
if (sectionStack.empty()) {
fatalerror("No entries in the section stack");
fatal("No entries in the section stack");
}
if (currentLoadSection) {
@@ -1052,11 +1052,11 @@ void sect_CheckStack() {
void sect_EndSection() {
if (!currentSection) {
fatalerror("Cannot end the section outside of a SECTION");
fatal("Cannot end the section outside of a SECTION");
}
if (!currentUnionStack.empty()) {
fatalerror("Cannot end the section within a UNION");
fatal("Cannot end the section within a UNION");
}
if (currentLoadSection) {

View File

@@ -9,7 +9,7 @@
#include <unordered_map>
#include <unordered_set>
#include "error.hpp"
#include "diagnostics.hpp"
#include "helpers.hpp" // assume
#include "util.hpp"
#include "version.hpp"
@@ -217,12 +217,12 @@ static bool isAutoScoped(std::string const &symName) {
// Check for nothing after the dot
if (dotPos == symName.length() - 1) {
fatalerror("'%s' is a nonsensical reference to an empty local label", symName.c_str());
fatal("'%s' is a nonsensical reference to an empty local label", symName.c_str());
}
// Check for more than one dot
if (symName.find('.', dotPos + 1) != std::string::npos) {
fatalerror("'%s' is a nonsensical reference to a nested local label", symName.c_str());
fatal("'%s' is a nonsensical reference to a nested local label", symName.c_str());
}
// Check for already-qualified local label
@@ -232,7 +232,7 @@ static bool isAutoScoped(std::string const &symName) {
// Check for unqualifiable local label
if (!globalScope) {
fatalerror("Unqualified local label '%s' in main scope", symName.c_str());
fatal("Unqualified local label '%s' in main scope", symName.c_str());
}
return true;

View File

@@ -9,7 +9,7 @@
#include <stdlib.h>
#include <string.h>
#include "error.hpp"
#include "diagnostics.hpp"
#include "helpers.hpp"
#include "itertools.hpp"
@@ -70,9 +70,10 @@ static void printDiag(
) {
fputs(type, stderr);
fputs(": ", stderr);
fstk_DumpCurrent();
fprintf(stderr, flagfmt, flag);
fputs("\n ", stderr);
if (fstk_DumpCurrent()) {
fprintf(stderr, flagfmt, flag);
fputs("\n ", stderr);
}
vfprintf(stderr, fmt, args);
putc('\n', stderr);
lexer_DumpStringExpansions();
@@ -82,12 +83,14 @@ static void incrementErrors() {
// This intentionally makes 0 act as "unlimited" (or at least "limited to sizeof(unsigned)")
nbErrors++;
if (nbErrors == maxErrors) {
errx(
"The maximum of %u error%s was reached (configure with \"-X/--max-errors\"); assembly "
"aborted!",
maxErrors,
maxErrors == 1 ? "" : "s"
fprintf(
stderr,
"Assembly aborted after the maximum of %u error%s! (configure with "
"'-X/--max-errors')\n",
nbErrors,
nbErrors == 1 ? "" : "s"
);
exit(1);
}
}
@@ -103,8 +106,9 @@ void error(char const *fmt, ...) {
void error(std::function<void()> callback) {
fputs("error: ", stderr);
fstk_DumpCurrent();
fputs(":\n ", stderr);
if (fstk_DumpCurrent()) {
fputs(":\n ", stderr);
}
callback();
putc('\n', stderr);
lexer_DumpStringExpansions();
@@ -113,7 +117,7 @@ void error(std::function<void()> callback) {
}
[[noreturn]]
void fatalerror(char const *fmt, ...) {
void fatal(char const *fmt, ...) {
va_list args;
va_start(args, fmt);

View File

@@ -1,5 +1,14 @@
#include "diagnostics.hpp"
void warnx(char const *fmt, ...) {
va_list ap;
fputs("warning: ", stderr);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
putc('\n', stderr);
}
void WarningState::update(WarningState other) {
if (other.state != WARNING_DEFAULT) {
state = other.state;

View File

@@ -1,29 +0,0 @@
// SPDX-License-Identifier: MIT
#include "error.hpp"
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void warnx(char const *fmt, ...) {
va_list ap;
fputs("warning: ", stderr);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
putc('\n', stderr);
}
[[noreturn]]
void errx(char const *fmt, ...) {
va_list ap;
fputs("error: ", stderr);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
putc('\n', stderr);
exit(1);
}

View File

@@ -12,7 +12,7 @@
#include <string.h>
#include <vector>
#include "error.hpp"
#include "diagnostics.hpp"
#include "extern/getopt.hpp"
#include "helpers.hpp"
#include "platform.hpp"

View File

@@ -14,7 +14,7 @@
#include <string_view>
#include <vector>
#include "error.hpp"
#include "diagnostics.hpp"
#include "extern/getopt.hpp"
#include "file.hpp"
#include "platform.hpp"

View File

@@ -17,7 +17,7 @@
#include <string_view>
#include <tuple>
#include "error.hpp"
#include "diagnostics.hpp"
#include "helpers.hpp"
#include "platform.hpp"

View File

@@ -15,7 +15,7 @@
#include <utility>
#include <vector>
#include "error.hpp"
#include "diagnostics.hpp"
#include "file.hpp"
#include "helpers.hpp"
#include "itertools.hpp"

View File

@@ -12,7 +12,7 @@
#include <string.h>
#include <vector>
#include "error.hpp"
#include "diagnostics.hpp"
#include "file.hpp"
#include "helpers.hpp" // assume

View File

@@ -9,7 +9,7 @@
#include <string.h>
#include <vector>
#include "error.hpp"
#include "diagnostics.hpp"
#include "helpers.hpp"
#include "itertools.hpp"
#include "linkdefs.hpp"
@@ -299,7 +299,7 @@ static void placeSection(Section &section) {
// If a section failed to go to several places, nothing we can report
if (!section.isBankFixed || !section.isAddressFixed) {
errx(
fatal(
"Unable to place \"%s\" (%s section) %s",
section.name.c_str(),
sectionTypeInfo[section.type].name.c_str(),
@@ -308,7 +308,7 @@ static void placeSection(Section &section) {
}
// If the section just can't fit the bank, report that
else if (section.org + section.size > endaddr(section.type) + 1) {
errx(
fatal(
"Unable to place \"%s\" (%s section) %s: section runs past end of region ($%04x > "
"$%04x)",
section.name.c_str(),
@@ -320,7 +320,7 @@ static void placeSection(Section &section) {
}
// Otherwise there is overlap with another section
else {
errx(
fatal(
"Unable to place \"%s\" (%s section) %s: section overlaps with \"%s\"",
section.name.c_str(),
sectionTypeInfo[section.type].name.c_str(),

View File

@@ -9,7 +9,7 @@
#include <stdlib.h>
#include <string.h>
#include "error.hpp"
#include "diagnostics.hpp"
#include "extern/getopt.hpp"
#include "helpers.hpp" // assume
#include "itertools.hpp"

View File

@@ -13,7 +13,7 @@
#include <string.h>
#include <vector>
#include "error.hpp"
#include "diagnostics.hpp"
#include "helpers.hpp"
#include "linkdefs.hpp"
#include "platform.hpp"
@@ -37,7 +37,7 @@ static std::vector<std::vector<FileStackNode>> nodes;
FILE *tmpFile = file; \
type tmpVal = func(tmpFile); \
if (tmpVal == (errval)) { \
errx(__VA_ARGS__, feof(tmpFile) ? "Unexpected end of file" : strerror(errno)); \
fatal(__VA_ARGS__, feof(tmpFile) ? "Unexpected end of file" : strerror(errno)); \
} \
var = static_cast<vartype>(tmpVal); \
} while (0)
@@ -78,7 +78,7 @@ static int64_t readLong(FILE *file) {
std::string &tmpVal = var; \
for (int tmpByte = getc(tmpFile); tmpByte != '\0'; tmpByte = getc(tmpFile)) { \
if (tmpByte == EOF) { \
errx(__VA_ARGS__, feof(tmpFile) ? "Unexpected end of file" : strerror(errno)); \
fatal(__VA_ARGS__, feof(tmpFile) ? "Unexpected end of file" : strerror(errno)); \
} else { \
tmpVal.push_back(tmpByte); \
} \
@@ -136,8 +136,6 @@ static void readFileStackNode(
}
if (!node.parent) {
fatal(
nullptr,
0,
"%s is not a valid object file: root node (#%" PRIu32 ") may not be REPT",
fileName,
nodeID
@@ -275,7 +273,7 @@ static void readPatch(
size_t nbElementsRead = fread(patch.rpnExpression.data(), 1, rpnSize, file);
if (nbElementsRead != rpnSize) {
errx(
fatal(
"%s: Cannot read \"%s\"'s patch #%" PRIu32 "'s RPN expression: %s",
fileName,
sectName.c_str(),
@@ -314,7 +312,7 @@ static void readSection(
);
tryReadLong(tmp, file, "%s: Cannot read \"%s\"'s' size: %s", fileName, section.name.c_str());
if (tmp < 0 || tmp > UINT16_MAX) {
errx("\"%s\"'s section size ($%" PRIx32 ") is invalid", section.name.c_str(), tmp);
fatal("\"%s\"'s section size ($%" PRIx32 ") is invalid", section.name.c_str(), tmp);
}
section.size = tmp;
section.offset = 0;
@@ -322,7 +320,7 @@ static void readSection(
uint8_t, byte, file, "%s: Cannot read \"%s\"'s type: %s", fileName, section.name.c_str()
);
if (uint8_t type = byte & 0x3F; type >= SECTTYPE_INVALID) {
errx("\"%s\" has unknown section type 0x%02x", section.name.c_str(), type);
fatal("\"%s\" has unknown section type 0x%02x", section.name.c_str(), type);
} else {
section.type = SectionType(type);
}
@@ -336,7 +334,7 @@ static void readSection(
tryReadLong(tmp, file, "%s: Cannot read \"%s\"'s org: %s", fileName, section.name.c_str());
section.isAddressFixed = tmp >= 0;
if (tmp > UINT16_MAX) {
error(nullptr, 0, "\"%s\"'s org is too large ($%" PRIx32 ")", section.name.c_str(), tmp);
error("\"%s\"'s org is too large ($%" PRIx32 ")", section.name.c_str(), tmp);
tmp = UINT16_MAX;
}
section.org = tmp;
@@ -360,13 +358,7 @@ static void readSection(
tmp, file, "%s: Cannot read \"%s\"'s alignment offset: %s", fileName, section.name.c_str()
);
if (tmp > UINT16_MAX) {
error(
nullptr,
0,
"\"%s\"'s alignment offset is too large ($%" PRIx32 ")",
section.name.c_str(),
tmp
);
error("\"%s\"'s alignment offset is too large ($%" PRIx32 ")", section.name.c_str(), tmp);
tmp = UINT16_MAX;
}
section.alignOfs = tmp;
@@ -376,7 +368,7 @@ static void readSection(
section.data.resize(section.size);
if (size_t nbRead = fread(section.data.data(), 1, section.size, file);
nbRead != section.size) {
errx(
fatal(
"%s: Cannot read \"%s\"'s data: %s",
fileName,
section.name.c_str(),
@@ -446,7 +438,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
file = stdin;
}
if (!file) {
errx("Failed to open file \"%s\": %s", fileName, strerror(errno));
fatal("Failed to open file \"%s\": %s", fileName, strerror(errno));
}
Defer closeFile{[&] { fclose(file); }};
@@ -457,7 +449,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
ungetc(c, file); // Guaranteed to work
switch (c) {
case EOF:
fatal(nullptr, 0, "File \"%s\" is empty!", fileName);
fatal("File \"%s\" is empty!", fileName);
case 'R':
break;
@@ -484,7 +476,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
if (fscanf(file, RGBDS_OBJECT_VERSION_STRING "%n", &matchedElems) == 1
&& matchedElems != literal_strlen(RGBDS_OBJECT_VERSION_STRING)) {
errx("%s: Not a RGBDS object file", fileName);
fatal("%s: Not a RGBDS object file", fileName);
}
verbosePrint("Reading object file %s\n", fileName);
@@ -493,7 +485,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
tryReadLong(revNum, file, "%s: Cannot read revision number: %s", fileName);
if (revNum != RGBDS_OBJECT_REV) {
errx(
fatal(
"%s: Unsupported object file for rgblink %s; try rebuilding \"%s\"%s"
" (expected revision %d, got %d)",
fileName,

View File

@@ -11,7 +11,7 @@
#include <string.h>
#include <vector>
#include "error.hpp"
#include "diagnostics.hpp"
#include "extern/utf8decoder.hpp"
#include "helpers.hpp"
#include "linkdefs.hpp"
@@ -71,7 +71,7 @@ void out_AddSection(Section const &section) {
uint32_t minNbBanks = targetBank + 1;
if (minNbBanks > maxNbBanks[section.type]) {
errx(
fatal(
"Section \"%s\" has an invalid bank range (%" PRIu32 " > %" PRIu32 ")",
section.name.c_str(),
section.bank,
@@ -213,7 +213,7 @@ static void writeROM() {
outputFile = stdout;
}
if (!outputFile) {
errx("Failed to open output file \"%s\": %s", outputFileName, strerror(errno));
fatal("Failed to open output file \"%s\": %s", outputFileName, strerror(errno));
}
}
Defer closeOutputFile{[&] {
@@ -231,7 +231,7 @@ static void writeROM() {
overlayFile = stdin;
}
if (!overlayFile) {
errx("Failed to open overlay file \"%s\": %s", overlayFileName, strerror(errno));
fatal("Failed to open overlay file \"%s\": %s", overlayFileName, strerror(errno));
}
}
Defer closeOverlayFile{[&] {
@@ -574,7 +574,7 @@ static void writeSym() {
symFile = stdout;
}
if (!symFile) {
errx("Failed to open sym file \"%s\": %s", symFileName, strerror(errno));
fatal("Failed to open sym file \"%s\": %s", symFileName, strerror(errno));
}
Defer closeSymFile{[&] { fclose(symFile); }};
@@ -625,7 +625,7 @@ static void writeMap() {
mapFile = stdout;
}
if (!mapFile) {
errx("Failed to open map file \"%s\": %s", mapFileName, strerror(errno));
fatal("Failed to open map file \"%s\": %s", mapFileName, strerror(errno));
}
Defer closeMapFile{[&] { fclose(mapFile); }};

View File

@@ -150,8 +150,6 @@ optional:
#define scriptError(context, fmt, ...) \
::error( \
nullptr, \
0, \
"%s(%" PRIu32 "): " fmt, \
context.path.c_str(), \
context.lineNo __VA_OPT__(, ) __VA_ARGS__ \
@@ -746,7 +744,7 @@ void script_ProcessScript(char const *path) {
auto &newContext = lexerStack.emplace_back(std::string(path));
if (!newContext.file.open(newContext.path, std::ios_base::in)) {
error(nullptr, 0, "Failed to open linker script \"%s\"", newContext.path.c_str());
error("Failed to open linker script \"%s\"", newContext.path.c_str());
lexerStack.clear();
} else {
yy::parser linkerScriptParser;

View File

@@ -7,7 +7,7 @@
#include <string.h>
#include <unordered_map>
#include "error.hpp"
#include "diagnostics.hpp"
#include "helpers.hpp"
#include "link/warning.hpp"
@@ -219,7 +219,7 @@ void sect_AddSection(std::unique_ptr<Section> &&section) {
if (Section *target = sect_GetSection(section->name); target) {
mergeSections(*target, std::move(section));
} else if (section->modifier == SECTION_UNION && sect_HasData(section->type)) {
errx(
fatal(
"Section \"%s\" is of type %s, which cannot be unionized",
section->name.c_str(),
sectionTypeInfo[section->type].name.c_str()
@@ -242,10 +242,7 @@ static void doSanityChecks(Section &section) {
// This is trapped early in RGBDS objects (because then the format is not parseable),
// which leaves SDAS objects.
error(
nullptr,
0,
"Section \"%s\" has not been assigned a type by a linker script",
section.name.c_str()
"Section \"%s\" has not been assigned a type by a linker script", section.name.c_str()
);
return;
}
@@ -253,8 +250,6 @@ static void doSanityChecks(Section &section) {
if (is32kMode && section.type == SECTTYPE_ROMX) {
if (section.isBankFixed && section.bank != 1) {
error(
nullptr,
0,
"Section \"%s\" has type ROMX, which must be in bank 1 (if any) with option `-t`",
section.name.c_str()
);
@@ -265,8 +260,6 @@ static void doSanityChecks(Section &section) {
if (isWRAM0Mode && section.type == SECTTYPE_WRAMX) {
if (section.isBankFixed && section.bank != 1) {
error(
nullptr,
0,
"Section \"%s\" has type WRAMX, which must be in bank 1 with options `-w` or `-d`",
section.name.c_str()
);
@@ -276,8 +269,6 @@ static void doSanityChecks(Section &section) {
}
if (isDmgMode && section.type == SECTTYPE_VRAM && section.bank == 1) {
error(
nullptr,
0,
"Section \"%s\" has type VRAM, which must be in bank 0 with option `-d`",
section.name.c_str()
);
@@ -292,8 +283,6 @@ static void doSanityChecks(Section &section) {
// Too large an alignment may not be satisfiable
if (section.isAlignFixed && (section.alignMask & sectionTypeInfo[section.type].startAddr)) {
error(
nullptr,
0,
"Section \"%s\" has type %s, which cannot be aligned to $%04x bytes",
section.name.c_str(),
sectionTypeInfo[section.type].name.c_str(),
@@ -306,8 +295,6 @@ static void doSanityChecks(Section &section) {
if (section.isBankFixed && section.bank < minbank && section.bank > maxbank) {
error(
nullptr,
0,
minbank == maxbank
? "Cannot place section \"%s\" in bank %" PRIu32 ", it must be %" PRIu32
: "Cannot place section \"%s\" in bank %" PRIu32 ", it must be between %" PRIu32
@@ -322,8 +309,6 @@ static void doSanityChecks(Section &section) {
// Check if section has a chance to be placed
if (section.size > sectionTypeInfo[section.type].size) {
error(
nullptr,
0,
"Section \"%s\" is bigger than the max size for that type: $%" PRIx16 " > $%" PRIx16,
section.name.c_str(),
section.size,
@@ -343,8 +328,6 @@ static void doSanityChecks(Section &section) {
if (section.isAlignFixed) {
if ((section.org & section.alignMask) != section.alignOfs) {
error(
nullptr,
0,
"Section \"%s\"'s fixed address doesn't match its alignment",
section.name.c_str()
);
@@ -356,8 +339,6 @@ static void doSanityChecks(Section &section) {
if (section.org < sectionTypeInfo[section.type].startAddr
|| section.org > endaddr(section.type)) {
error(
nullptr,
0,
"Section \"%s\"'s fixed address $%04" PRIx16 " is outside of range [$%04" PRIx16
"; $%04" PRIx16 "]",
section.name.c_str(),
@@ -369,8 +350,6 @@ static void doSanityChecks(Section &section) {
if (section.org + section.size > endaddr(section.type) + 1) {
error(
nullptr,
0,
"Section \"%s\"'s end address $%04x is greater than last address $%04x",
section.name.c_str(),
section.org + section.size,

View File

@@ -10,10 +10,9 @@
static uint32_t nbErrors = 0;
static void printDiag(
char const *fmt, va_list args, char const *type, FileStackNode const *where, uint32_t lineNo
FileStackNode const *where, uint32_t lineNo, char const *fmt, va_list args, char const *type
) {
fputs(type, stderr);
fputs(": ", stderr);
fprintf(stderr, "%s: ", type);
if (where) {
where->dump(lineNo);
fputs(": ", stderr);
@@ -22,22 +21,54 @@ static void printDiag(
putc('\n', stderr);
}
static void incrementErrors() {
if (nbErrors != UINT32_MAX) {
nbErrors++;
}
}
[[noreturn]]
static void abortLinking(char const *verb) {
fprintf(
stderr,
"Linking %s with %" PRIu32 " error%s\n",
verb ? verb : "aborted",
nbErrors,
nbErrors == 1 ? "" : "s"
);
exit(1);
}
void warning(FileStackNode const *where, uint32_t lineNo, char const *fmt, ...) {
va_list args;
va_start(args, fmt);
printDiag(fmt, args, "warning", where, lineNo);
printDiag(where, lineNo, fmt, args, "warning");
va_end(args);
}
void warning(char const *fmt, ...) {
va_list args;
va_start(args, fmt);
printDiag(nullptr, 0, fmt, args, "warning");
va_end(args);
}
void error(FileStackNode const *where, uint32_t lineNo, char const *fmt, ...) {
va_list args;
va_start(args, fmt);
printDiag(fmt, args, "error", where, lineNo);
printDiag(where, lineNo, fmt, args, "error");
va_end(args);
if (nbErrors != UINT32_MAX) {
nbErrors++;
}
incrementErrors();
}
void error(char const *fmt, ...) {
va_list args;
va_start(args, fmt);
printDiag(nullptr, 0, fmt, args, "error");
va_end(args);
incrementErrors();
}
void errorNoDump(char const *fmt, ...) {
@@ -47,9 +78,7 @@ void errorNoDump(char const *fmt, ...) {
vfprintf(stderr, fmt, args);
va_end(args);
if (nbErrors != UINT32_MAX) {
nbErrors++;
}
incrementErrors();
}
void argErr(char flag, char const *fmt, ...) {
@@ -60,33 +89,33 @@ void argErr(char flag, char const *fmt, ...) {
va_end(args);
putc('\n', stderr);
if (nbErrors != UINT32_MAX) {
nbErrors++;
}
incrementErrors();
}
[[noreturn]]
void fatal(FileStackNode const *where, uint32_t lineNo, char const *fmt, ...) {
va_list args;
va_start(args, fmt);
printDiag(fmt, args, "FATAL", where, lineNo);
printDiag(where, lineNo, fmt, args, "FATAL");
va_end(args);
if (nbErrors != UINT32_MAX) {
nbErrors++;
}
incrementErrors();
abortLinking(nullptr);
}
fprintf(
stderr, "Linking aborted after %" PRIu32 " error%s\n", nbErrors, nbErrors == 1 ? "" : "s"
);
exit(1);
[[noreturn]]
void fatal(char const *fmt, ...) {
va_list args;
va_start(args, fmt);
printDiag(nullptr, 0, fmt, args, "FATAL");
va_end(args);
incrementErrors();
abortLinking(nullptr);
}
void requireZeroErrors() {
if (nbErrors != 0) {
fprintf(
stderr, "Linking failed with %" PRIu32 " error%s\n", nbErrors, nbErrors == 1 ? "" : "s"
);
exit(1);
abortLinking("failed");
}
}