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;