shithub: rgbds

Download patch

ref: bf75971a3a823a8bac2d4012c8ae0ccf33eec189
parent: 8a59994c0dd9e15fd50462d1242377fedcdcdad4
author: ISSOtm <[email protected]>
date: Fri Oct 11 05:04:50 EDT 2019

Only open files when necessary

--- a/include/link/main.h
+++ b/include/link/main.h
@@ -16,11 +16,11 @@
 
 /* Variables related to CLI options */
 extern bool isDmgMode;
-extern FILE *linkerScript;
-extern FILE *mapFile;
-extern FILE *symFile;
-extern FILE *overlayFile;
-extern FILE *outputFile;
+extern char const *linkerScriptName;
+extern char const *mapFileName;
+extern char const *symFileName;
+extern char const *overlayFileName;
+extern char const *outputFileName;
 extern uint8_t padValue;
 extern bool is32kMode;
 extern bool beVerbose;
@@ -31,5 +31,19 @@
 					if (beVerbose) \
 						fprintf(stderr, __VA_ARGS__); \
 				} while (0)
+
+/**
+ * Opens a file if specified, and aborts on error.
+ * @param fileName The name of the file to open; if NULL, no file will be opened
+ * @param mode The mode to open the file with
+ * @return A pointer to a valid FILE structure, or NULL if fileName was NULL
+ */
+FILE *openFile(char const *fileName, char const *mode);
+
+#define closeFile(file) do { \
+				FILE *tmp = file; \
+				if (tmp) \
+					fclose(tmp); \
+			} while (0)
 
 #endif /* RGBDS_LINK_MAIN_H */
--- a/include/link/script.h
+++ b/include/link/script.h
@@ -12,6 +12,8 @@
 
 #include <stdint.h>
 
+extern FILE *linkerScript;
+
 struct SectionPlacement {
 	struct Section *section;
 	uint16_t org;
--- a/src/link/assign.c
+++ b/src/link/assign.c
@@ -58,10 +58,12 @@
  */
 static void processLinkerScript(void)
 {
-	if (!linkerScript)
+	if (!linkerScriptName)
 		return;
 	verbosePrint("Reading linker script...\n");
 
+	linkerScript = openFile(linkerScriptName, "r");
+
 	/* Modify all sections according to the linker script */
 	struct SectionPlacement *placement;
 
@@ -86,6 +88,8 @@
 		section->bank = placement->bank;
 		section->isAlignFixed = false; /* The alignment is satisfied */
 	}
+
+	fclose(linkerScript);
 }
 
 /**
@@ -385,7 +389,7 @@
 
 	/* Overlaying requires only fully-constrained sections */
 	verbosePrint("Assigning other sections...\n");
-	if (overlayFile)
+	if (overlayFileName)
 		errx(1, "All sections must be fixed when using an overlay file; %u, %sn't",
 		     nbSectionsToAssign, nbSectionsToAssign == 1 ? "is" : "are");
 
--- a/src/link/main.c
+++ b/src/link/main.c
@@ -6,6 +6,8 @@
  * SPDX-License-Identifier: MIT
  */
 
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdbool.h>
@@ -22,17 +24,30 @@
 #include "extern/err.h"
 #include "version.h"
 
-bool isDmgMode;     /* -d */
-FILE *linkerScript; /* -l */
-FILE *mapFile;      /* -m */
-FILE *symFile;      /* -n */
-FILE *overlayFile;  /* -O */
-FILE *outputFile;   /* -o */
-uint8_t padValue;   /* -p */
-bool is32kMode;     /* -t */
-bool beVerbose;     /* -v */
-bool isWRA0Mode;    /* -w */
+bool isDmgMode;               /* -d */
+char const *linkerScriptName; /* -l */
+char const *mapFileName;      /* -m */
+char const *symFileName;      /* -n */
+char const *overlayFileName;  /* -O */
+char const *outputFileName;   /* -o */
+uint8_t padValue;             /* -p */
+bool is32kMode;               /* -t */
+bool beVerbose;               /* -v */
+bool isWRA0Mode;              /* -w */
 
+FILE *openFile(char const *fileName, char const *mode)
+{
+	if (!fileName)
+		return NULL;
+
+	FILE *file = fopen(fileName, mode);
+
+	if (!file)
+		err(1, "Could not open file \"%s\"", fileName);
+
+	return file;
+}
+
 /**
  * Prints the program's usage to stdout.
  */
@@ -43,41 +58,11 @@
 }
 
 /**
- * Helper function for `main`'s argument parsing.
- * For use with options which take a file name to operate on
- * If the file fails to be opened, an error message will be printed,
- * and the function `exit`s.
- * @param mode The mode to open the file in
- * @param failureMessage A format string that will be printed on failure.
- *                       A single (string) argument is given, the file name.
- * @return What `fopen` returned; this cannot be NULL.
- */
-static FILE *openArgFile(char const *mode, char const *failureMessage)
-{
-	FILE *file = fopen(optarg, mode);
-
-	if (!file)
-		err(1, failureMessage, optarg);
-	return file;
-}
-
-/**
  * Cleans up what has been done
  * Mostly here to please tools such as `valgrind` so actual errors can be seen
  */
 static void cleanup(void)
 {
-	if (linkerScript)
-		fclose(linkerScript);
-	if (mapFile)
-		fclose(mapFile);
-	if (symFile)
-		fclose(symFile);
-	if (overlayFile)
-		fclose(overlayFile);
-	if (outputFile)
-		fclose(outputFile);
-
 	obj_Cleanup();
 }
 
@@ -95,19 +80,19 @@
 			isWRA0Mode = true;
 			break;
 		case 'l':
-			linkerScript = openArgFile("r", "Could not open linker script file \"%s\"");
+			linkerScriptName = optarg;
 			break;
 		case 'm':
-			mapFile = openArgFile("w", "Could not open map file \"%s\"");
+			mapFileName = optarg;
 			break;
 		case 'n':
-			symFile = openArgFile("w", "Could not open sym file \"%s\"");
+			symFileName = optarg;
 			break;
 		case 'O':
-			overlayFile = openArgFile("r+b", "Could not open overlay file \"%s\"");
+			overlayFileName = optarg;
 			break;
 		case 'o':
-			outputFile = openArgFile("wb", "Could not open output file \"%s\"");
+			outputFileName = optarg;
 			break;
 		case 'p':
 			value = strtoul(optarg, &endptr, 0);
--- a/src/link/output.c
+++ b/src/link/output.c
@@ -9,6 +9,11 @@
 
 #include "extern/err.h"
 
+FILE *outputFile;
+FILE *overlayFile;
+FILE *symFile;
+FILE *mapFile;
+
 struct SortedSection {
 	struct Section const *section;
 	struct SortedSection *next;
@@ -158,6 +163,9 @@
  */
 static void writeROM(void)
 {
+	outputFile = openFile(outputFileName, "wb");
+	overlayFile = openFile(overlayFileName, "rb");
+
 	checkOverlay();
 
 	if (outputFile) {
@@ -177,6 +185,9 @@
 			funlockfile(overlayFile);
 		funlockfile(outputFile);
 	}
+
+	closeFile(outputFile);
+	closeFile(overlayFile);
 }
 
 /**
@@ -310,7 +321,7 @@
  */
 static void writeSymAndMap(void)
 {
-	if (!symFile && !mapFile)
+	if (!symFileName && !mapFileName)
 		return;
 
 	enum SectionType typeMap[SECTTYPE_INVALID] = {
@@ -324,8 +335,12 @@
 		SECTTYPE_HRAM
 	};
 
-	if (symFile)
+	symFile = openFile(symFileName, "w");
+	mapFile = openFile(mapFileName, "w");
+
+	if (symFileName) {
 		fputs("; File generated by rgblink\n", symFile);
+	}
 
 	for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) {
 		enum SectionType type = typeMap[i];
@@ -339,6 +354,9 @@
 			}
 		}
 	}
+
+	closeFile(symFile);
+	closeFile(mapFile);
 }
 
 static void cleanupSections(struct SortedSection *section)
--- a/src/link/script.c
+++ b/src/link/script.c
@@ -11,6 +11,8 @@
 
 #include "extern/err.h"
 
+FILE *linkerScript;
+
 static inline bool isWhiteSpace(int c)
 {
 	return c == ' ' || c == '\t';