mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-23 03:22:08 +00:00
Use a Defer struct to close files and restore lexer state with RAII (#1379)
This commit is contained in:
@@ -393,7 +393,7 @@ void assign_AssignSections() {
|
||||
fprintf(stderr, "%c \"%s\"", nbSections == 0 ? ';' : ',', section->name.c_str());
|
||||
nbSections++;
|
||||
if (nbSections == 10)
|
||||
goto max_out;
|
||||
goto max_out; // Can't `break` out of a nested loop
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -320,7 +320,7 @@ static void parseScrambleSpec(char const *spec) {
|
||||
argErr('S', "Cannot imply limit for region \"%.*s\"", regionNamePrintLen, regionName);
|
||||
}
|
||||
|
||||
next:
|
||||
next: // Can't `continue` a `for` loop with this nontrivial iteration logic
|
||||
if (spec) {
|
||||
assert(*spec == ',' || *spec == '\0');
|
||||
if (*spec == ',')
|
||||
|
||||
@@ -473,7 +473,6 @@ static void readAssertion(
|
||||
|
||||
void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
||||
FILE *file;
|
||||
|
||||
if (strcmp(fileName, "-")) {
|
||||
file = fopen(fileName, "rb");
|
||||
} else {
|
||||
@@ -482,6 +481,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
||||
}
|
||||
if (!file)
|
||||
err("Failed to open file \"%s\"", fileName);
|
||||
Defer closeFile{[&] { fclose(file); }};
|
||||
|
||||
// First, check if the object is a RGBDS object or a SDCC one. If the first byte is 'R',
|
||||
// we'll assume it's a RGBDS object file, and otherwise, that it's a SDCC object file.
|
||||
@@ -630,8 +630,6 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
void obj_CheckAssertions() {
|
||||
|
||||
@@ -199,6 +199,10 @@ static void writeROM() {
|
||||
if (!outputFile)
|
||||
err("Failed to open output file \"%s\"", outputFileName);
|
||||
}
|
||||
Defer closeOutputFile{[&] {
|
||||
if (outputFile)
|
||||
fclose(outputFile);
|
||||
}};
|
||||
|
||||
if (overlayFileName) {
|
||||
if (strcmp(overlayFileName, "-")) {
|
||||
@@ -210,6 +214,10 @@ static void writeROM() {
|
||||
if (!overlayFile)
|
||||
err("Failed to open overlay file \"%s\"", overlayFileName);
|
||||
}
|
||||
Defer closeOverlayFile{[&] {
|
||||
if (overlayFile)
|
||||
fclose(overlayFile);
|
||||
}};
|
||||
|
||||
uint32_t nbOverlayBanks = checkOverlaySize();
|
||||
|
||||
@@ -230,11 +238,6 @@ static void writeROM() {
|
||||
sectionTypeInfo[SECTTYPE_ROMX].size
|
||||
);
|
||||
}
|
||||
|
||||
if (outputFile)
|
||||
fclose(outputFile);
|
||||
if (overlayFile)
|
||||
fclose(overlayFile);
|
||||
}
|
||||
|
||||
// Checks whether this character is legal as the first character of a symbol's name in a sym file
|
||||
@@ -533,6 +536,7 @@ static void writeSym() {
|
||||
}
|
||||
if (!symFile)
|
||||
err("Failed to open sym file \"%s\"", symFileName);
|
||||
Defer closeSymFile{[&] { fclose(symFile); }};
|
||||
|
||||
fputs("; File generated by rgblink\n", symFile);
|
||||
|
||||
@@ -542,8 +546,6 @@ static void writeSym() {
|
||||
for (uint32_t bank = 0; bank < sections[type].size(); bank++)
|
||||
writeSymBank(sections[type][bank], type, bank);
|
||||
}
|
||||
|
||||
fclose(symFile);
|
||||
}
|
||||
|
||||
// Writes the map file, if applicable.
|
||||
@@ -559,6 +561,7 @@ static void writeMap() {
|
||||
}
|
||||
if (!mapFile)
|
||||
err("Failed to open map file \"%s\"", mapFileName);
|
||||
Defer closeMapFile{[&] { fclose(mapFile); }};
|
||||
|
||||
writeMapSummary();
|
||||
|
||||
@@ -568,8 +571,6 @@ static void writeMap() {
|
||||
for (uint32_t bank = 0; bank < sections[type].size(); bank++)
|
||||
writeMapBank(sections[type][bank], type, bank);
|
||||
}
|
||||
|
||||
fclose(mapFile);
|
||||
}
|
||||
|
||||
void out_WriteFiles() {
|
||||
|
||||
@@ -225,7 +225,6 @@ static uint8_t parseHexDigit(int c) {
|
||||
}
|
||||
|
||||
yy::parser::symbol_type yylex() {
|
||||
try_again: // Can't use a `do {} while(0)` loop, otherwise compilers (wrongly) think it can end.
|
||||
auto &context = lexerStack.back();
|
||||
auto c = context.file.sbumpc();
|
||||
|
||||
@@ -245,7 +244,7 @@ try_again: // Can't use a `do {} while(0)` loop, otherwise compilers (wrongly) t
|
||||
// Basically yywrap().
|
||||
if (lexerStack.size() != 1) {
|
||||
lexerStack.pop_back();
|
||||
goto try_again;
|
||||
return yylex();
|
||||
} else if (!atEof) {
|
||||
// Inject a newline at EOF, to avoid errors for files that don't end with one.
|
||||
atEof = true;
|
||||
@@ -353,7 +352,7 @@ try_again: // Can't use a `do {} while(0)` loop, otherwise compilers (wrongly) t
|
||||
}
|
||||
|
||||
scriptError(context, "Unknown keyword \"%s\"", ident.c_str());
|
||||
goto try_again; // Try lexing another token.
|
||||
return yylex();
|
||||
} else {
|
||||
scriptError(context, "Unexpected character '%s'", printChar(c));
|
||||
// Keep reading characters until the EOL, to avoid reporting too many errors.
|
||||
@@ -363,7 +362,7 @@ try_again: // Can't use a `do {} while(0)` loop, otherwise compilers (wrongly) t
|
||||
}
|
||||
context.file.sbumpc();
|
||||
}
|
||||
goto try_again;
|
||||
return yylex();
|
||||
}
|
||||
// Not marking as unreachable; this will generate a warning if any codepath forgets to return.
|
||||
}
|
||||
|
||||
@@ -797,6 +797,10 @@ void sdobj_ReadFile(FileStackNode const &where, FILE *file, std::vector<Symbol>
|
||||
}
|
||||
}
|
||||
|
||||
#undef expectEol
|
||||
#undef expectToken
|
||||
#undef getToken
|
||||
|
||||
if (!data.empty())
|
||||
warning(&where, lineNo, "Last 'T' line had no 'R' line (ignored)");
|
||||
if (fileSections.size() < expectedNbAreas)
|
||||
@@ -841,10 +845,4 @@ void sdobj_ReadFile(FileStackNode const &where, FILE *file, std::vector<Symbol>
|
||||
// Calling `sect_AddSection` invalidates the contents of `fileSections`!
|
||||
sect_AddSection(std::move(section));
|
||||
}
|
||||
|
||||
#undef expectEol
|
||||
#undef expectToken
|
||||
#undef getToken
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user