mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Support -P/--preinclude to pre-INCLUDE a file (#1043)
Fixes #1041 Co-authored-by: ISSOtm <eldredhabert0@gmail.com>
This commit is contained in:
@@ -38,6 +38,7 @@ _rgbasm_completions() {
|
||||
[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"
|
||||
|
||||
@@ -55,6 +55,7 @@ local args=(
|
||||
'*'-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:'
|
||||
|
||||
@@ -58,6 +58,7 @@ struct FileStackNode *fstk_GetFileStack(void);
|
||||
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
|
||||
|
||||
31
man/rgbasm.1
31
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 @@ instruction immediately after any
|
||||
.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 @@ This makes
|
||||
.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 @@ characters, essentially
|
||||
.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.
|
||||
|
||||
@@ -1972,6 +1972,13 @@ calls infinitely (or until you run out of memory, whichever comes first).
|
||||
.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 ,
|
||||
|
||||
@@ -42,6 +42,8 @@ size_t maxRecursionDepth;
|
||||
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 @@ void fstk_AddIncludePath(char const *path)
|
||||
includePaths[nbIncPaths++] = str;
|
||||
}
|
||||
|
||||
void fstk_SetPreIncludeFile(char const *path)
|
||||
{
|
||||
preIncludeName = path;
|
||||
}
|
||||
|
||||
static void printDep(char const *path)
|
||||
{
|
||||
if (dependfile) {
|
||||
@@ -274,6 +281,7 @@ bool yywrap(void)
|
||||
|
||||
lexer_SetState(contextStack->lexerState);
|
||||
macro_SetUniqueID(contextStack->uniqueID);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -342,6 +350,41 @@ void fstk_RunInclude(char const *path)
|
||||
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 @@ void fstk_Init(char const *mainPath, size_t maxDepth)
|
||||
// Make sure that the default of 64 is OK, though
|
||||
assert(DEPTH_LIMIT >= DEFAULT_MAX_DEPTH);
|
||||
#undef DEPTH_LIMIT
|
||||
|
||||
runPreIncludeFile();
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ static char *make_escape(char const *str)
|
||||
}
|
||||
|
||||
// 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 @@ static struct option const longopts[] = {
|
||||
{ "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 @@ static void print_usage(void)
|
||||
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"
|
||||
@@ -254,6 +255,10 @@ int main(int argc, char *argv[])
|
||||
out_SetFileName(musl_optarg);
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
fstk_SetPreIncludeFile(musl_optarg);
|
||||
break;
|
||||
|
||||
unsigned long padByte;
|
||||
case 'p':
|
||||
padByte = strtoul(musl_optarg, &ep, 0);
|
||||
|
||||
3
test/asm/preinclude.asm
Normal file
3
test/asm/preinclude.asm
Normal file
@@ -0,0 +1,3 @@
|
||||
warn "main {__FILE__}"
|
||||
def v3 = v1 + v2
|
||||
println "{d:v1} + {d:v2} = {d:v3}"
|
||||
4
test/asm/preinclude.err
Normal file
4
test/asm/preinclude.err
Normal file
@@ -0,0 +1,4 @@
|
||||
warning: preinclude.asm(0) -> preinclude.inc(1): [-Wuser]
|
||||
pre-include "preinclude.inc"
|
||||
warning: preinclude.asm(1): [-Wuser]
|
||||
main "preinclude.asm"
|
||||
1
test/asm/preinclude.flags
Normal file
1
test/asm/preinclude.flags
Normal file
@@ -0,0 +1 @@
|
||||
-Weverything -P preinclude.inc
|
||||
11
test/asm/preinclude.inc
Normal file
11
test/asm/preinclude.inc
Normal file
@@ -0,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
|
||||
7
test/asm/preinclude.out
Normal file
7
test/asm/preinclude.out
Normal file
@@ -0,0 +1,7 @@
|
||||
rept 3
|
||||
rept 3
|
||||
rept 3
|
||||
for 0/3
|
||||
for 1/3
|
||||
for 2/3
|
||||
12 + 34 = 46
|
||||
@@ -76,6 +76,11 @@ if ! diff --strip-trailing-cr syntax-error.err $errput; then
|
||||
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 @@ for i in *.asm; do
|
||||
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 @@ for i in *.asm; do
|
||||
# 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
|
||||
|
||||
Reference in New Issue
Block a user