shithub: rgbds

Download patch

ref: 20e5685c1a54d4c530d36bf34864c4d34ce1bcb7
parent: ac6232bc87d0855337dac0efb1e2f8283a588798
parent: 7bb55469fe80dd089019b0fcb198ab8efc24eb45
author: Eldred Habert <eldredhabert0@gmail.com>
date: Sun Feb 2 22:50:09 EST 2020

Merge pull request #424 from ISSOtm/better_deps

Improve dependency generation

--- a/include/asm/main.h
+++ b/include/asm/main.h
@@ -35,6 +35,10 @@
 extern struct sOptions CurrentOptions;
 
 extern FILE *dependfile;
+extern char *tzTargetFileName;
+extern bool oGeneratedMissingIncludes;
+extern bool oFailedOnMissingInclude;
+extern bool oGeneratePhonyDeps;
 
 void opt_Push(void);
 void opt_Pop(void);
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -1004,6 +1004,8 @@
 include		: T_POP_INCLUDE string
 		{
 			fstk_RunInclude($2);
+			if (oFailedOnMissingInclude)
+				YYACCEPT;
 		}
 ;
 
@@ -1010,10 +1012,14 @@
 incbin		: T_POP_INCBIN string
 		{
 			out_BinaryFile($2);
+			if (oFailedOnMissingInclude)
+				YYACCEPT;
 		}
 		| T_POP_INCBIN string comma uconst comma uconst
 		{
 			out_BinaryFileSlice($2, $4, $6);
+			if (oFailedOnMissingInclude)
+				YYACCEPT;
 		}
 ;
 
--- a/src/asm/fstack.c
+++ b/src/asm/fstack.c
@@ -325,6 +325,15 @@
 		fatalerror("Include path too long '%s'", s);
 }
 
+static void printdep(const char *fileName)
+{
+	if (dependfile) {
+		fprintf(dependfile, "%s: %s\n", tzTargetFileName, fileName);
+		if (oGeneratePhonyDeps)
+			fprintf(dependfile, "%s:\n", fileName);
+	}
+}
+
 FILE *fstk_FindFile(char *fname, char **incPathUsed)
 {
 	char path[_MAX_PATH];
@@ -337,9 +346,7 @@
 	f = fopen(fname, "rb");
 
 	if (f != NULL || errno != ENOENT) {
-		if (dependfile)
-			fprintf(dependfile, "%s: %s\n", tzObjectname, fname);
-
+		printdep(fname);
 		return f;
 	}
 
@@ -362,10 +369,8 @@
 		f = fopen(path, "rb");
 
 		if (f != NULL || errno != ENOENT) {
-			if (dependfile) {
-				fprintf(dependfile, "%s: %s\n", tzObjectname,
-					path);
-			}
+			printdep(path);
+
 			if (incPathUsed)
 				*incPathUsed = IncludePaths[i];
 			return f;
@@ -373,6 +378,8 @@
 	}
 
 	errno = ENOENT;
+	if (oGeneratedMissingIncludes)
+		printdep(fname);
 	return NULL;
 }
 
@@ -384,8 +391,13 @@
 	char *incPathUsed = "";
 	FILE *f = fstk_FindFile(tzFileName, &incPathUsed);
 
-	if (f == NULL)
+	if (f == NULL) {
+		if (oGeneratedMissingIncludes) {
+			oFailedOnMissingInclude = true;
+			return;
+		}
 		err(1, "Unable to open included file '%s'", tzFileName);
+	}
 
 	pushcontext();
 	nLineNo = 1;
--- a/src/asm/main.c
+++ b/src/asm/main.c
@@ -14,6 +14,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <errno.h>
 
 #include "asm/symbol.h"
 #include "asm/fstack.h"
@@ -46,6 +47,10 @@
 /* extern int yydebug; */
 
 FILE *dependfile;
+bool oGeneratedMissingIncludes;
+bool oFailedOnMissingInclude;
+bool oGeneratePhonyDeps;
+char *tzTargetFileName;
 
 /*
  * Option stack
@@ -235,9 +240,32 @@
 		sym_AddString(cldefines[i], cldefines[i + 1]);
 }
 
+/* Escapes Make-special chars from a string */
+static char *make_escape(const char *str)
+{
+	char * const escaped_str = malloc(strlen(str) * 2 + 1);
+	char *dest = escaped_str;
+
+	if (escaped_str == NULL)
+		err(1, "%s: Failed to allocate memory", __func__);
+
+	while (*str) {
+		/* All dollars needs to be doubled */
+		if (*str == '$')
+			*dest++ = '$';
+		*dest++ = *str++;
+	}
+	*dest = '\0';
+
+	return escaped_str;
+}
+
 /* Short options */
 static char const *optstring = "b:D:Eg:hi:LM:o:p:r:VvW:w";
 
+/* Variables for the long-only options */
+static int depType; /* Variants of `-M` */
+
 /*
  * Equivalent long options
  * Please keep in the same order as short opts
@@ -249,21 +277,25 @@
  * over short opt matching
  */
 static struct option const longopts[] = {
-	{ "binary-digits",    required_argument, NULL, 'b' },
-	{ "define",           required_argument, NULL, 'D' },
-	{ "export-all",       no_argument,       NULL, 'E' },
-	{ "gfx-chars",        required_argument, NULL, 'g' },
-	{ "halt-without-nop", no_argument,       NULL, 'h' },
-	{ "include",          required_argument, NULL, 'i' },
-	{ "preserve-ld",      no_argument,       NULL, 'L' },
-	{ "dependfile",       required_argument, NULL, 'M' },
-	{ "output",           required_argument, NULL, 'o' },
-	{ "pad-value",        required_argument, NULL, 'p' },
-	{ "recursion-depth",  required_argument, NULL, 'r' },
-	{ "version",          no_argument,       NULL, 'V' },
-	{ "verbose",          no_argument,       NULL, 'v' },
-	{ "warning",          required_argument, NULL, 'W' },
-	{ NULL,               no_argument,       NULL, 0   }
+	{ "binary-digits",    required_argument, NULL,     'b' },
+	{ "define",           required_argument, NULL,     'D' },
+	{ "export-all",       no_argument,       NULL,     'E' },
+	{ "gfx-chars",        required_argument, NULL,     'g' },
+	{ "halt-without-nop", no_argument,       NULL,     'h' },
+	{ "include",          required_argument, NULL,     'i' },
+	{ "preserve-ld",      no_argument,       NULL,     'L' },
+	{ "dependfile",       required_argument, NULL,     'M' },
+	{ "MG",               no_argument,       &depType, 'G' },
+	{ "MP",               no_argument,       &depType, 'P' },
+	{ "MT",               required_argument, &depType, 'T' },
+	{ "MQ",               required_argument, &depType, 'Q' },
+	{ "output",           required_argument, NULL,     'o' },
+	{ "pad-value",        required_argument, NULL,     'p' },
+	{ "recursion-depth",  required_argument, NULL,     'r' },
+	{ "version",          no_argument,       NULL,     'V' },
+	{ "verbose",          no_argument,       NULL,     'v' },
+	{ "warning",          required_argument, NULL,     'W' },
+	{ NULL,               no_argument,       NULL,     0   }
 };
 
 static void print_usage(void)
@@ -270,8 +302,8 @@
 {
 	fputs(
 "Usage: rgbasm [-EhLVvw] [-b chars] [-D name[=value]] [-g chars] [-i path]\n"
-"              [-M depend_file] [-o out_file] [-p pad_value] [-r depth]\n"
-"              [-W warning] <file> ...\n"
+"              [-M depend_file] [-MG] [-MP] [-MT target_file] [-MQ target_file]\n"
+"              [-o out_file] [-p pad_value] [-r depth] [-W warning] <file> ...\n"
 "Useful options:\n"
 "    -E, --export-all         export all labels\n"
 "    -M, --dependfile <path>  set the output dependency file\n"
@@ -306,6 +338,11 @@
 	/* yydebug=1; */
 
 	nMaxRecursionDepth = 64;
+	oGeneratePhonyDeps = false;
+	oGeneratedMissingIncludes = false;
+	oFailedOnMissingInclude = false;
+	tzTargetFileName = NULL;
+	size_t nTargetFileNameLen = 0;
 
 	DefaultOptions.gbgfx[0] = '0';
 	DefaultOptions.gbgfx[1] = '1';
@@ -361,10 +398,13 @@
 			newopt.optimizeloads = false;
 			break;
 		case 'M':
-			dependfile = fopen(optarg, "w");
+			if (!strcmp("-", optarg))
+				dependfile = stdout;
+			else
+				dependfile = fopen(optarg, "w");
 			if (dependfile == NULL)
-				err(1, "Could not open dependfile %s", optarg);
-
+				err(1, "Could not open dependfile %s",
+				    optarg);
 			break;
 		case 'o':
 			out_SetFileName(optarg);
@@ -397,6 +437,45 @@
 		case 'w':
 			newopt.warnings = false;
 			break;
+
+		/* Long-only options */
+		case 0:
+			if (depType) {
+				switch (depType) {
+				case 'G':
+					oGeneratedMissingIncludes = true;
+					break;
+				case 'P':
+					oGeneratePhonyDeps = true;
+					break;
+				case 'Q':
+				case 'T':
+					if (optind == argc)
+						errx(1, "-M%c takes a target file name argument",
+						     depType);
+					ep = optarg;
+					if (depType == 'Q')
+						ep = make_escape(ep);
+
+					nTargetFileNameLen += strlen(ep) + 1;
+					tzTargetFileName =
+						realloc(tzTargetFileName,
+							nTargetFileNameLen + 1);
+					if (tzTargetFileName == NULL)
+						err(1, "Cannot append new file to target file list");
+					strcat(tzTargetFileName, ep);
+					if (depType == 'Q')
+						free(ep);
+					char *ptr = tzTargetFileName +
+						strlen(tzTargetFileName);
+					*ptr++ = ' ';
+					*ptr = '\0';
+					break;
+				}
+			}
+			break;
+
+		/* Unrecognized options */
 		default:
 			print_usage();
 			/* NOTREACHED */
@@ -405,6 +484,9 @@
 	argc -= optind;
 	argv += optind;
 
+	if (tzTargetFileName == NULL)
+		tzTargetFileName = tzObjectname;
+
 	opt_SetCurrentOptions(&newopt);
 
 	DefaultOptions = CurrentOptions;
@@ -422,10 +504,10 @@
 		printf("Assembling %s\n", tzMainfile);
 
 	if (dependfile) {
-		if (!tzObjectname)
-			errx(1, "Dependency files can only be created if an output object file is specified.\n");
+		if (!tzTargetFileName)
+			errx(1, "Dependency files can only be created if a target file is specified with either -o, -MQ or -MT.\n");
 
-		fprintf(dependfile, "%s: %s\n", tzObjectname, tzMainfile);
+		fprintf(dependfile, "%s: %s\n", tzTargetFileName, tzMainfile);
 	}
 
 	nStartClock = clock();
@@ -447,6 +529,8 @@
 
 	if (yyparse() != 0 || nbErrors != 0)
 		errx(1, "Assembly aborted (%ld errors)!", nbErrors);
+	if (dependfile)
+		fclose(dependfile);
 
 	if (nIFDepth != 0)
 		errx(1, "Unterminated IF construct (%ld levels)!", nIFDepth);
@@ -470,6 +554,9 @@
 			printf("(%d lines/minute)\n",
 			       (int)(60 / timespent * nTotalLines));
 	}
+
+	if (oFailedOnMissingInclude)
+		return 0;
 
 	/* If no path specified, don't write file */
 	if (tzObjectname != NULL)
--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -880,8 +880,13 @@
 	FILE *f;
 
 	f = fstk_FindFile(s, NULL);
-	if (f == NULL)
+	if (f == NULL) {
+		if (oGeneratedMissingIncludes) {
+			oFailedOnMissingInclude = true;
+			return;
+		}
 		err(1, "Unable to open incbin file '%s'", s);
+	}
 
 	int32_t fsize;
 
@@ -915,8 +920,13 @@
 		fatalerror("Number of bytes to read must be greater than zero");
 
 	f = fstk_FindFile(s, NULL);
-	if (f == NULL)
+	if (f == NULL) {
+		if (oGeneratedMissingIncludes) {
+			oFailedOnMissingInclude = true;
+			return;
+		}
 		err(1, "Unable to open included file '%s'", s);
+	}
 
 	int32_t fsize;