mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Refactor code that handles when included files are missing
- Single unified routine for erroring out or handling missing dependencies - Single three-state enum instead of two Booleans for missing dependencies (this causes `-MC` to imply `-MG` instead of needing `-MG -MC`) - Functions than can miss included files return a Boolean for whether the parser should `YYACCEPT` and exit
This commit is contained in:
@@ -146,7 +146,7 @@ std::optional<std::string> fstk_FindFile(std::string const &path) {
|
||||
}
|
||||
|
||||
errno = ENOENT;
|
||||
if (generatedMissingIncludes) {
|
||||
if (missingIncludeState != INC_ERROR) {
|
||||
printDep(path);
|
||||
}
|
||||
return std::nullopt;
|
||||
@@ -302,26 +302,30 @@ static Context &newReptContext(int32_t reptLineNo, ContentSpan const &span, uint
|
||||
return context;
|
||||
}
|
||||
|
||||
void fstk_RunInclude(std::string const &path, bool preInclude) {
|
||||
std::optional<std::string> fullPath = fstk_FindFile(path);
|
||||
|
||||
if (!fullPath) {
|
||||
if (generatedMissingIncludes && !preInclude) {
|
||||
// LCOV_EXCL_START
|
||||
if (!continueAfterMissingIncludes) {
|
||||
verbosePrint(
|
||||
"Aborting (-MG) on INCLUDE file '%s' (%s)\n", path.c_str(), strerror(errno)
|
||||
);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
failedOnMissingInclude = true;
|
||||
} else {
|
||||
error("Unable to open included file '%s': %s", path.c_str(), strerror(errno));
|
||||
bool fstk_FileError(std::string const &path, char const *functionName) {
|
||||
if (missingIncludeState == INC_ERROR) {
|
||||
error("Error opening %s file '%s': %s", functionName, path.c_str(), strerror(errno));
|
||||
} else {
|
||||
failedOnMissingInclude = true;
|
||||
// LCOV_EXCL_START
|
||||
if (missingIncludeState == GEN_EXIT) {
|
||||
verbosePrint(
|
||||
"Aborting (-MG) on %s file '%s' (%s)\n", functionName, path.c_str(), strerror(errno)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
assume(missingIncludeState == GEN_CONTINUE);
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
newFileContext(*fullPath, false);
|
||||
bool fstk_RunInclude(std::string const &path) {
|
||||
if (std::optional<std::string> fullPath = fstk_FindFile(path); fullPath) {
|
||||
newFileContext(*fullPath, false);
|
||||
return false;
|
||||
}
|
||||
return fstk_FileError(path, "INCLUDE");
|
||||
}
|
||||
|
||||
void fstk_RunMacro(std::string const ¯oName, std::shared_ptr<MacroArgs> macroArgs) {
|
||||
@@ -410,6 +414,12 @@ void fstk_Init(std::string const &mainPath, size_t maxDepth) {
|
||||
maxRecursionDepth = maxDepth;
|
||||
|
||||
if (!preIncludeName.empty()) {
|
||||
fstk_RunInclude(preIncludeName, true);
|
||||
if (std::optional<std::string> fullPath = fstk_FindFile(preIncludeName); fullPath) {
|
||||
newFileContext(*fullPath, false);
|
||||
} else {
|
||||
error(
|
||||
"Error reading pre-included file '%s': %s", preIncludeName.c_str(), strerror(errno)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@
|
||||
#include "asm/symbol.hpp"
|
||||
#include "asm/warning.hpp"
|
||||
|
||||
FILE *dependFile = nullptr; // -M
|
||||
bool continueAfterMissingIncludes = false; // -MC
|
||||
bool generatedMissingIncludes = false; // -MG
|
||||
bool generatePhonyDeps = false; // -MP
|
||||
std::string targetFileName; // -MQ, -MT
|
||||
bool failedOnMissingInclude = false;
|
||||
bool verbose = false; // -v
|
||||
|
||||
FILE *dependFile = nullptr; // -M
|
||||
MissingInclude missingIncludeState = INC_ERROR; // -MC, -MG
|
||||
bool generatePhonyDeps = false; // -MP
|
||||
std::string targetFileName; // -MQ, -MT
|
||||
bool failedOnMissingInclude = false;
|
||||
|
||||
// Escapes Make-special chars from a string
|
||||
static std::string make_escape(std::string &str) {
|
||||
std::string escaped;
|
||||
@@ -371,11 +371,11 @@ int main(int argc, char *argv[]) {
|
||||
case 0:
|
||||
switch (depType) {
|
||||
case 'C':
|
||||
continueAfterMissingIncludes = true;
|
||||
missingIncludeState = GEN_CONTINUE;
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
generatedMissingIncludes = true;
|
||||
missingIncludeState = GEN_EXIT;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
|
||||
@@ -1139,8 +1139,7 @@ export_def:
|
||||
|
||||
include:
|
||||
label POP_INCLUDE string endofline {
|
||||
fstk_RunInclude($3, false);
|
||||
if (failedOnMissingInclude && !continueAfterMissingIncludes) {
|
||||
if (fstk_RunInclude($3)) {
|
||||
YYACCEPT;
|
||||
}
|
||||
}
|
||||
@@ -1148,20 +1147,17 @@ include:
|
||||
|
||||
incbin:
|
||||
POP_INCBIN string {
|
||||
sect_BinaryFile($2, 0);
|
||||
if (failedOnMissingInclude && !continueAfterMissingIncludes) {
|
||||
if (sect_BinaryFile($2, 0)) {
|
||||
YYACCEPT;
|
||||
}
|
||||
}
|
||||
| POP_INCBIN string COMMA uconst {
|
||||
sect_BinaryFile($2, $4);
|
||||
if (failedOnMissingInclude && !continueAfterMissingIncludes) {
|
||||
if (sect_BinaryFile($2, $4)) {
|
||||
YYACCEPT;
|
||||
}
|
||||
}
|
||||
| POP_INCBIN string COMMA uconst COMMA uconst {
|
||||
sect_BinaryFileSlice($2, $4, $6);
|
||||
if (failedOnMissingInclude && !continueAfterMissingIncludes) {
|
||||
if (sect_BinaryFileSlice($2, $4, $6)) {
|
||||
YYACCEPT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -874,9 +874,9 @@ void sect_PCRelByte(Expression const &expr, uint32_t pcShift) {
|
||||
}
|
||||
}
|
||||
|
||||
void sect_BinaryFile(std::string const &name, uint32_t startPos) {
|
||||
bool sect_BinaryFile(std::string const &name, uint32_t startPos) {
|
||||
if (!requireCodeSection()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *file = nullptr;
|
||||
@@ -884,24 +884,14 @@ void sect_BinaryFile(std::string const &name, uint32_t startPos) {
|
||||
file = fopen(fullPath->c_str(), "rb");
|
||||
}
|
||||
if (!file) {
|
||||
if (generatedMissingIncludes) {
|
||||
// LCOV_EXCL_START
|
||||
if (verbose && !continueAfterMissingIncludes) {
|
||||
printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", name.c_str(), strerror(errno));
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
failedOnMissingInclude = true;
|
||||
} else {
|
||||
error("Error opening INCBIN file '%s': %s", name.c_str(), strerror(errno));
|
||||
}
|
||||
return;
|
||||
return fstk_FileError(name, "INCBIN");
|
||||
}
|
||||
Defer closeFile{[&] { fclose(file); }};
|
||||
|
||||
if (fseek(file, 0, SEEK_END) != -1) {
|
||||
if (startPos > ftell(file)) {
|
||||
error("Specified start position is greater than length of file '%s'", name.c_str());
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
// The file is seekable; skip to the specified start position
|
||||
fseek(file, startPos, SEEK_SET);
|
||||
@@ -913,7 +903,7 @@ void sect_BinaryFile(std::string const &name, uint32_t startPos) {
|
||||
while (startPos--) {
|
||||
if (fgetc(file) == EOF) {
|
||||
error("Specified start position is greater than length of file '%s'", name.c_str());
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -925,14 +915,15 @@ void sect_BinaryFile(std::string const &name, uint32_t startPos) {
|
||||
if (ferror(file)) {
|
||||
error("Error reading INCBIN file '%s': %s", name.c_str(), strerror(errno));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t length) {
|
||||
bool sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t length) {
|
||||
if (!requireCodeSection()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (length == 0) { // Don't even bother with 0-byte slices
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *file = nullptr;
|
||||
@@ -940,24 +931,14 @@ void sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t l
|
||||
file = fopen(fullPath->c_str(), "rb");
|
||||
}
|
||||
if (!file) {
|
||||
if (generatedMissingIncludes) {
|
||||
// LCOV_EXCL_START
|
||||
if (verbose && !continueAfterMissingIncludes) {
|
||||
printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", name.c_str(), strerror(errno));
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
failedOnMissingInclude = true;
|
||||
} else {
|
||||
error("Error opening INCBIN file '%s': %s", name.c_str(), strerror(errno));
|
||||
}
|
||||
return;
|
||||
return fstk_FileError(name, "INCBIN");
|
||||
}
|
||||
Defer closeFile{[&] { fclose(file); }};
|
||||
|
||||
if (fseek(file, 0, SEEK_END) != -1) {
|
||||
if (long fsize = ftell(file); startPos > fsize) {
|
||||
error("Specified start position is greater than length of file '%s'", name.c_str());
|
||||
return;
|
||||
return false;
|
||||
} else if (startPos + length > fsize) {
|
||||
error(
|
||||
"Specified range in INCBIN file '%s' is out of bounds (%" PRIu32 " + %" PRIu32
|
||||
@@ -967,7 +948,7 @@ void sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t l
|
||||
length,
|
||||
fsize
|
||||
);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
// The file is seekable; skip to the specified start position
|
||||
fseek(file, startPos, SEEK_SET);
|
||||
@@ -979,7 +960,7 @@ void sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t l
|
||||
while (startPos--) {
|
||||
if (fgetc(file) == EOF) {
|
||||
error("Specified start position is greater than length of file '%s'", name.c_str());
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -997,6 +978,7 @@ void sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t l
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void sect_PushSection() {
|
||||
|
||||
Reference in New Issue
Block a user