mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Rework defining variables on command-line
Avoids allocating memory Detects CLI errors even when failing to open file Reports symbols as defined on command-line instead of input line 0 (!?)
This commit is contained in:
@@ -104,6 +104,9 @@ void fstk_DumpCurrent(void)
|
|||||||
|
|
||||||
struct FileStackNode *fstk_GetFileStack(void)
|
struct FileStackNode *fstk_GetFileStack(void)
|
||||||
{
|
{
|
||||||
|
if (!contextStack)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
struct FileStackNode *node = contextStack->fileInfo;
|
struct FileStackNode *node = contextStack->fileInfo;
|
||||||
|
|
||||||
/* Mark node and all of its parents as referenced if not already so they don't get freed */
|
/* Mark node and all of its parents as referenced if not already so they don't get freed */
|
||||||
|
|||||||
@@ -40,12 +40,6 @@
|
|||||||
// Unfortunately, macOS still ships 2.3, which is from 2008...
|
// Unfortunately, macOS still ships 2.3, which is from 2008...
|
||||||
int yyparse(void);
|
int yyparse(void);
|
||||||
|
|
||||||
size_t cldefines_index;
|
|
||||||
size_t cldefines_numindices;
|
|
||||||
size_t cldefines_bufsize;
|
|
||||||
const size_t cldefine_entrysize = 2 * sizeof(void *);
|
|
||||||
char **cldefines;
|
|
||||||
|
|
||||||
#if defined(YYDEBUG) && YYDEBUG
|
#if defined(YYDEBUG) && YYDEBUG
|
||||||
extern int yydebug;
|
extern int yydebug;
|
||||||
#endif
|
#endif
|
||||||
@@ -61,44 +55,6 @@ bool optimizeloads;
|
|||||||
bool verbose;
|
bool verbose;
|
||||||
bool warnings; /* True to enable warnings, false to disable them. */
|
bool warnings; /* True to enable warnings, false to disable them. */
|
||||||
|
|
||||||
void opt_AddDefine(char *s)
|
|
||||||
{
|
|
||||||
char *value, *equals;
|
|
||||||
|
|
||||||
if (cldefines_index >= cldefines_numindices) {
|
|
||||||
/* Check for overflows */
|
|
||||||
if ((cldefines_numindices * 2) < cldefines_numindices)
|
|
||||||
fatalerror("No memory for command line defines\n");
|
|
||||||
|
|
||||||
if ((cldefines_bufsize * 2) < cldefines_bufsize)
|
|
||||||
fatalerror("No memory for command line defines\n");
|
|
||||||
|
|
||||||
cldefines_numindices *= 2;
|
|
||||||
cldefines_bufsize *= 2;
|
|
||||||
|
|
||||||
cldefines = realloc(cldefines, cldefines_bufsize);
|
|
||||||
if (!cldefines)
|
|
||||||
fatalerror("No memory for command line defines\n");
|
|
||||||
}
|
|
||||||
equals = strchr(s, '=');
|
|
||||||
if (equals) {
|
|
||||||
*equals = '\0';
|
|
||||||
value = equals + 1;
|
|
||||||
} else {
|
|
||||||
value = "1";
|
|
||||||
}
|
|
||||||
cldefines[cldefines_index++] = s;
|
|
||||||
cldefines[cldefines_index++] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void opt_ParseDefines(void)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < cldefines_index; i += 2)
|
|
||||||
sym_AddString(cldefines[i], cldefines[i + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Escapes Make-special chars from a string */
|
/* Escapes Make-special chars from a string */
|
||||||
static char *make_escape(const char *str)
|
static char *make_escape(const char *str)
|
||||||
{
|
{
|
||||||
@@ -193,17 +149,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
dependfile = NULL;
|
dependfile = NULL;
|
||||||
|
|
||||||
/* Initial number of allocated elements in array */
|
|
||||||
cldefines_numindices = 32;
|
|
||||||
cldefines_bufsize = cldefines_numindices * cldefine_entrysize;
|
|
||||||
cldefines = malloc(cldefines_bufsize);
|
|
||||||
if (!cldefines)
|
|
||||||
fatalerror("No memory for command line defines\n");
|
|
||||||
|
|
||||||
#if defined(YYDEBUG) && YYDEBUG
|
#if defined(YYDEBUG) && YYDEBUG
|
||||||
yydebug = 1;
|
yydebug = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Perform some init for below
|
||||||
|
sym_Init(now);
|
||||||
|
|
||||||
// Set defaults
|
// Set defaults
|
||||||
|
|
||||||
oGeneratePhonyDeps = false;
|
oGeneratePhonyDeps = false;
|
||||||
@@ -218,9 +170,9 @@ int main(int argc, char *argv[])
|
|||||||
haltnop = true;
|
haltnop = true;
|
||||||
verbose = false;
|
verbose = false;
|
||||||
warnings = true;
|
warnings = true;
|
||||||
|
sym_SetExportAll(false);
|
||||||
uint32_t maxRecursionDepth = 64;
|
uint32_t maxRecursionDepth = 64;
|
||||||
size_t nTargetFileNameLen = 0;
|
size_t nTargetFileNameLen = 0;
|
||||||
bool exportall = false;
|
|
||||||
|
|
||||||
while ((ch = musl_getopt_long_only(argc, argv, optstring, longopts, NULL)) != -1) {
|
while ((ch = musl_getopt_long_only(argc, argv, optstring, longopts, NULL)) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
@@ -231,12 +183,19 @@ int main(int argc, char *argv[])
|
|||||||
errx(1, "Must specify exactly 2 characters for option 'b'");
|
errx(1, "Must specify exactly 2 characters for option 'b'");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
char *equals;
|
||||||
case 'D':
|
case 'D':
|
||||||
opt_AddDefine(optarg);
|
equals = strchr(optarg, '=');
|
||||||
|
if (equals) {
|
||||||
|
*equals = '\0';
|
||||||
|
sym_AddString(optarg, equals + 1);
|
||||||
|
} else {
|
||||||
|
sym_AddString(optarg, "1");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'E':
|
case 'E':
|
||||||
exportall = true;
|
sym_SetExportAll(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g':
|
case 'g':
|
||||||
@@ -264,8 +223,7 @@ int main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
dependfile = fopen(optarg, "w");
|
dependfile = fopen(optarg, "w");
|
||||||
if (dependfile == NULL)
|
if (dependfile == NULL)
|
||||||
err(1, "Could not open dependfile %s",
|
err(1, "Could not open dependfile %s", optarg);
|
||||||
optarg);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
@@ -321,8 +279,7 @@ int main(int argc, char *argv[])
|
|||||||
case 'Q':
|
case 'Q':
|
||||||
case 'T':
|
case 'T':
|
||||||
if (optind == argc)
|
if (optind == argc)
|
||||||
errx(1, "-M%c takes a target file name argument",
|
errx(1, "-M%c takes a target file name argument", depType);
|
||||||
depType);
|
|
||||||
ep = optarg;
|
ep = optarg;
|
||||||
if (depType == 'Q')
|
if (depType == 'Q')
|
||||||
ep = make_escape(ep);
|
ep = make_escape(ep);
|
||||||
@@ -330,22 +287,20 @@ int main(int argc, char *argv[])
|
|||||||
nTargetFileNameLen += strlen(ep) + 1;
|
nTargetFileNameLen += strlen(ep) + 1;
|
||||||
if (!tzTargetFileName) {
|
if (!tzTargetFileName) {
|
||||||
/* On first alloc, make an empty str */
|
/* On first alloc, make an empty str */
|
||||||
tzTargetFileName =
|
tzTargetFileName = malloc(nTargetFileNameLen + 1);
|
||||||
malloc(nTargetFileNameLen + 1);
|
|
||||||
if (tzTargetFileName)
|
if (tzTargetFileName)
|
||||||
*tzTargetFileName = '\0';
|
*tzTargetFileName = '\0';
|
||||||
} else {
|
} else {
|
||||||
tzTargetFileName =
|
tzTargetFileName = realloc(tzTargetFileName,
|
||||||
realloc(tzTargetFileName,
|
nTargetFileNameLen + 1);
|
||||||
nTargetFileNameLen + 1);
|
|
||||||
}
|
}
|
||||||
if (tzTargetFileName == NULL)
|
if (tzTargetFileName == NULL)
|
||||||
err(1, "Cannot append new file to target file list");
|
err(1, "Cannot append new file to target file list");
|
||||||
strcat(tzTargetFileName, ep);
|
strcat(tzTargetFileName, ep);
|
||||||
if (depType == 'Q')
|
if (depType == 'Q')
|
||||||
free(ep);
|
free(ep);
|
||||||
char *ptr = tzTargetFileName +
|
char *ptr = tzTargetFileName + strlen(tzTargetFileName);
|
||||||
strlen(tzTargetFileName);
|
|
||||||
*ptr++ = ' ';
|
*ptr++ = ' ';
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
break;
|
break;
|
||||||
@@ -386,10 +341,6 @@ int main(int argc, char *argv[])
|
|||||||
lexer_Init();
|
lexer_Init();
|
||||||
fstk_Init(mainFileName, maxRecursionDepth);
|
fstk_Init(mainFileName, maxRecursionDepth);
|
||||||
|
|
||||||
sym_Init(now);
|
|
||||||
sym_SetExportAll(exportall);
|
|
||||||
|
|
||||||
opt_ParseDefines();
|
|
||||||
charmap_New("main", NULL);
|
charmap_New("main", NULL);
|
||||||
|
|
||||||
if (yyparse() != 0 || nbErrors != 0)
|
if (yyparse() != 0 || nbErrors != 0)
|
||||||
|
|||||||
@@ -153,10 +153,12 @@ int32_t sym_GetValue(struct Symbol const *sym)
|
|||||||
|
|
||||||
static void dumpFilename(struct Symbol const *sym)
|
static void dumpFilename(struct Symbol const *sym)
|
||||||
{
|
{
|
||||||
if (!sym->src)
|
if (sym->src)
|
||||||
fputs("<builtin>", stderr);
|
|
||||||
else
|
|
||||||
fstk_Dump(sym->src, sym->fileLine);
|
fstk_Dump(sym->src, sym->fileLine);
|
||||||
|
else if (sym->fileLine == 0)
|
||||||
|
fputs("<command-line>", stderr);
|
||||||
|
else
|
||||||
|
fputs("<builtin>", stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -165,7 +167,7 @@ static void dumpFilename(struct Symbol const *sym)
|
|||||||
static void setSymbolFilename(struct Symbol *sym)
|
static void setSymbolFilename(struct Symbol *sym)
|
||||||
{
|
{
|
||||||
sym->src = fstk_GetFileStack();
|
sym->src = fstk_GetFileStack();
|
||||||
sym->fileLine = lexer_GetLineNo();
|
sym->fileLine = sym->src ? lexer_GetLineNo() : 0; // This is (NULL, 1) for built-ins
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -177,7 +179,7 @@ static void updateSymbolFilename(struct Symbol *sym)
|
|||||||
|
|
||||||
setSymbolFilename(sym);
|
setSymbolFilename(sym);
|
||||||
/* If the old node was referenced, ensure the new one is */
|
/* If the old node was referenced, ensure the new one is */
|
||||||
if (oldSrc->referenced && oldSrc->ID != -1)
|
if (oldSrc && oldSrc->referenced && oldSrc->ID != -1)
|
||||||
out_RegisterNode(sym->src);
|
out_RegisterNode(sym->src);
|
||||||
/* TODO: unref the old node, and use `out_ReplaceNode` instead if deleting it */
|
/* TODO: unref the old node, and use `out_ReplaceNode` instead if deleting it */
|
||||||
}
|
}
|
||||||
@@ -679,7 +681,7 @@ static inline struct Symbol *createBuiltinSymbol(char const *name)
|
|||||||
sym->isBuiltin = true;
|
sym->isBuiltin = true;
|
||||||
sym->hasCallback = true;
|
sym->hasCallback = true;
|
||||||
sym->src = NULL;
|
sym->src = NULL;
|
||||||
sym->fileLine = 0;
|
sym->fileLine = 1; // This is 0 for CLI-defined symbols
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user