ref: b8385a50e3cffb224e889760a68f6f1c93844d6a
parent: 02923a67f3d023586d127a6fda0b7b03949332b4
author: Rangi <[email protected]>
date: Sat Sep 24 08:37:16 EDT 2022
Support `-P/--preinclude` to pre-INCLUDE a file (#1043) Fixes #1041 Co-authored-by: ISSOtm <[email protected]>
--- a/contrib/bash_compl/_rgbasm.bash
+++ b/contrib/bash_compl/_rgbasm.bash
@@ -38,6 +38,7 @@
[i]="include:dir"
[M]="dependfile:glob-*.mk *.d"
[o]="output:glob-*.o"
+ [P]="preinclude:glob-*.asm *.inc"
[p]="pad-value:unk"
[Q]="q-precision:unk"
[r]="recursion-depth:unk"
--- a/contrib/zsh_compl/_rgbasm
+++ b/contrib/zsh_compl/_rgbasm
@@ -55,6 +55,7 @@
'*'-MT"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'"
'*'-MQ"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'"
'(-o --output)'{-o,--output}'+[Output file]:output file:_files'
+ '(-P --preinclude)'{-P,--preinclude}"+[Pre-include a file]:include file:_files -g '*.{asm,inc}'"
'(-p --pad-value)'{-p,--pad-value}'+[Set padding byte]:padding byte:'
'(-Q --q-precision)'{-Q,--q-precision}'+[Set fixed-point precision]:precision:'
'(-r --recursion-depth)'{-r,--recursion-depth}'+[Set maximum recursion depth]:depth:'
--- a/include/asm/fstack.h
+++ b/include/asm/fstack.h
@@ -58,6 +58,7 @@
char const *fstk_GetFileName(void);
void fstk_AddIncludePath(char const *s);
+void fstk_SetPreIncludeFile(char const *s);
/*
* @param path The user-provided file name
* @param fullPath The address of a pointer, which will be made to point at the full path
--- a/man/rgbasm.1
+++ b/man/rgbasm.1
@@ -24,21 +24,21 @@
.Op Fl MT Ar target_file
.Op Fl MQ Ar target_file
.Op Fl o Ar out_file
+.Op Fl P Ar include_file
.Op Fl p Ar pad_value
.Op Fl Q Ar fix_precision
.Op Fl r Ar recursion_depth
.Op Fl W Ar warning
-.Ar
+.Ar asmfile
.Sh DESCRIPTION
The
.Nm
program creates an RGB object file from an assembly source file.
The input
-.Ar file
-can be a file path, or
+.Ar asmfile
+can be a path to a file, or
.Cm \-
-denoting
-.Cm stdin .
+to read from standard input.
.Pp
Note that options can be abbreviated as long as the abbreviation is unambiguous:
.Fl Fl verb
@@ -87,7 +87,19 @@
.Ic halt
instruction.
.It Fl i Ar path , Fl Fl include Ar path
-Add an include path.
+Add a new
+.Dq include path ; Ar path
+must point to a directory.
+When a
+.Ic INCLUDE
+.Pq including the implicit one from Fl P
+or
+.Ic INCBIN
+is attempted,
+.Nm
+first looks up the provided path from its working directory; if this fails, it tries again from each of the
+.Dq include path
+directories, in the order they were provided.
.It Fl L , Fl Fl preserve-ld
By default,
.Nm
@@ -116,6 +128,7 @@
.Nm
assume that missing files are auto-generated: when
.Ic INCLUDE
+.Pq including the implicit one from Fl P
or
.Ic INCBIN
is attempted on a non-existent file, it is added as a dependency, then
@@ -146,6 +159,12 @@
.Sq $ .
.It Fl o Ar out_file , Fl Fl output Ar out_file
Write an object file to the given filename.
+.It Fl P Ar include_file , Fl Fl preinclude Ar include_file
+Pre-include a file.
+This acts as if a
+.Ql Ic INCLUDE Qq Ar include_file
+was read before the input
+.Ar asmfile .
.It Fl p Ar pad_value , Fl Fl pad-value Ar pad_value
When padding an image, pad with this value.
The default is 0x00.
--- a/man/rgbasm.5
+++ b/man/rgbasm.5
@@ -1972,6 +1972,13 @@
.Bd -literal -offset indent
INCLUDE "irq.inc"
.Ed
+.Pp
+You may also implicitly
+.Ic INCLUDE
+a file before the source file with the
+.Fl P
+option of
+.Xr rgbasm 1 .
.Ss Conditional assembling
The four commands
.Ic IF , ELIF , ELSE ,
--- a/src/asm/fstack.c
+++ b/src/asm/fstack.c
@@ -42,6 +42,8 @@
static unsigned int nbIncPaths = 0;
static char const *includePaths[MAXINCPATHS];
+static const char *preIncludeName;
+
static const char *dumpNodeAndParents(struct FileStackNode const *node)
{
char const *name;
@@ -133,6 +135,11 @@
includePaths[nbIncPaths++] = str;
}
+void fstk_SetPreIncludeFile(char const *path)
+{
+ preIncludeName = path;
+}
+
static void printDep(char const *path)
{
if (dependfile) {
@@ -274,6 +281,7 @@
lexer_SetState(contextStack->lexerState);
macro_SetUniqueID(contextStack->uniqueID);
+
return false;
}
@@ -342,6 +350,41 @@
contextStack->uniqueID = macro_UndefUniqueID();
}
+// Similar to `fstk_RunInclude`, but not subject to `-MG`, and
+// calling `lexer_SetState` instead of `lexer_SetStateAtEOL`.
+static void runPreIncludeFile(void)
+{
+ if (!preIncludeName)
+ return;
+
+ char *fullPath = NULL;
+ size_t size = 0;
+
+ if (!fstk_FindFile(preIncludeName, &fullPath, &size)) {
+ free(fullPath);
+ error("Unable to open included file '%s': %s\n", preIncludeName, strerror(errno));
+ return;
+ }
+
+ struct FileStackNamedNode *fileInfo = malloc(sizeof(*fileInfo) + size);
+
+ if (!fileInfo) {
+ error("Failed to alloc file info for pre-include: %s\n", strerror(errno));
+ return;
+ }
+ fileInfo->node.type = NODE_FILE;
+ strcpy(fileInfo->name, fullPath);
+ free(fullPath);
+
+ newContext((struct FileStackNode *)fileInfo);
+ contextStack->lexerState = lexer_OpenFile(fileInfo->name);
+ if (!contextStack->lexerState)
+ fatalerror("Failed to set up lexer for file include\n");
+ lexer_SetState(contextStack->lexerState);
+ // We're back at top-level, so most things are reset
+ contextStack->uniqueID = macro_UndefUniqueID();
+}
+
void fstk_RunMacro(char const *macroName, struct MacroArgs *args)
{
struct Symbol *macro = sym_FindExactSymbol(macroName);
@@ -563,4 +606,6 @@
// Make sure that the default of 64 is OK, though
assert(DEPTH_LIMIT >= DEFAULT_MAX_DEPTH);
#undef DEPTH_LIMIT
+
+ runPreIncludeFile();
}
--- a/src/asm/main.c
+++ b/src/asm/main.c
@@ -87,7 +87,7 @@
}
// Short options
-static const char *optstring = "b:D:Eg:Hhi:LlM:o:p:Q:r:VvW:w";
+static const char *optstring = "b:D:Eg:Hhi:LlM:o:P:p:Q:r:VvW:w";
// Variables for the long-only options
static int depType; // Variants of `-M`
@@ -116,6 +116,7 @@
{ "MT", required_argument, &depType, 'T' },
{ "MQ", required_argument, &depType, 'Q' },
{ "output", required_argument, NULL, 'o' },
+ { "preinclude", required_argument, NULL, 'P' },
{ "pad-value", required_argument, NULL, 'p' },
{ "q-precision", required_argument, NULL, 'Q' },
{ "recursion-depth", required_argument, NULL, 'r' },
@@ -130,8 +131,8 @@
fputs(
"Usage: rgbasm [-EHhLlVvw] [-b chars] [-D name[=value]] [-g chars] [-i path]\n"
" [-M depend_file] [-MG] [-MP] [-MT target_file] [-MQ target_file]\n"
-" [-o out_file] [-p pad_value] [-Q precision] [-r depth]\n"
-" [-W warning] <file>\n"
+" [-o out_file] [-P include_file] [-p pad_value] [-Q precision]\n"
+" [-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"
@@ -252,6 +253,10 @@
case 'o':
out_SetFileName(musl_optarg);
+ break;
+
+ case 'P':
+ fstk_SetPreIncludeFile(musl_optarg);
break;
unsigned long padByte;
--- /dev/null
+++ b/test/asm/preinclude.asm
@@ -1,0 +1,3 @@
+warn "main {__FILE__}"
+def v3 = v1 + v2
+println "{d:v1} + {d:v2} = {d:v3}"
--- /dev/null
+++ b/test/asm/preinclude.err
@@ -1,0 +1,4 @@
+warning: preinclude.asm(0) -> preinclude.inc(1): [-Wuser]
+ pre-include "preinclude.inc"
+warning: preinclude.asm(1): [-Wuser]
+ main "preinclude.asm"
--- /dev/null
+++ b/test/asm/preinclude.flags
@@ -1,0 +1,1 @@
+-Weverything -P preinclude.inc
--- /dev/null
+++ b/test/asm/preinclude.inc
@@ -1,0 +1,11 @@
+warn "pre-include {__FILE__}"
+
+def v1 = 12
+rept 3
+ println "rept 3"
+endr
+
+def v2 = 34
+for i, 3
+ println "for {d:i}/3"
+endr
--- /dev/null
+++ b/test/asm/preinclude.out
@@ -1,0 +1,7 @@
+rept 3
+rept 3
+rept 3
+for 0/3
+for 1/3
+for 2/3
+12 + 34 = 46
--- a/test/asm/test.sh
+++ b/test/asm/test.sh
@@ -76,6 +76,11 @@
fi
for i in *.asm; do
+ flags=${i%.asm}.flags
+ RGBASMFLAGS=-Weverything
+ if [ -f $flags ]; then
+ RGBASMFLAGS="$(head -n 1 "$flags")" # Allow other lines to serve as comments
+ fi
for variant in '' '.pipe'; do
echo "${bold}${green}${i%.asm}${variant}...${rescolors}${resbold}"
desired_errname=${i%.asm}.err
@@ -83,7 +88,7 @@
desired_errname=${i%.asm}.simple.err
fi
if [ -z "$variant" ]; then
- $RGBASM -Weverything -o $o $i > $output 2> $errput
+ $RGBASM $RGBASMFLAGS -o $o $i > $output 2> $errput
desired_output=${i%.asm}.out
desired_errput=$desired_errname
else
@@ -97,7 +102,7 @@
# stdin redirection makes the input an unseekable pipe - a scenario
# that's harder to deal with and was broken when the feature was
# first implemented.
- cat $i | $RGBASM -Weverything -o $o - > $output 2> $errput
+ cat $i | $RGBASM $RGBASMFLAGS -o $o - > $output 2> $errput
# Use two otherwise unused files for temp storage
desired_output=$input