mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Merge pull request #390 from ISSOtm/print_types
Add "print types" to bracketed symbols
This commit is contained in:
@@ -39,6 +39,7 @@ extern struct sSymbol *tHashedSymbols[HASHSIZE];
|
|||||||
extern struct sSymbol *pPCSymbol;
|
extern struct sSymbol *pPCSymbol;
|
||||||
extern bool oDontExpandStrings;
|
extern bool oDontExpandStrings;
|
||||||
|
|
||||||
size_t symvaluetostring(char *dest, size_t maxLength, char *sym);
|
size_t symvaluetostring(char *dest, size_t maxLength, char *sym,
|
||||||
|
const char *mode);
|
||||||
|
|
||||||
#endif /* RGBDS_ASM_ASM_H */
|
#endif /* RGBDS_ASM_ASM_H */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of RGBDS.
|
* This file is part of RGBDS.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
|
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -75,7 +75,8 @@ static void bankrangecheck(char *name, uint32_t secttype, int32_t org,
|
|||||||
out_NewAbsSection(name, secttype, org, bank);
|
out_NewAbsSection(name, secttype, org, bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t symvaluetostring(char *dest, size_t maxLength, char *sym)
|
size_t symvaluetostring(char *dest, size_t maxLength, char *sym,
|
||||||
|
const char *mode)
|
||||||
{
|
{
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
||||||
@@ -83,6 +84,9 @@ size_t symvaluetostring(char *dest, size_t maxLength, char *sym)
|
|||||||
char *src = sym_GetStringValue(sym);
|
char *src = sym_GetStringValue(sym);
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
if (mode)
|
||||||
|
yyerror("Print types are only allowed for numbers");
|
||||||
|
|
||||||
for (i = 0; src[i] != 0; i++) {
|
for (i = 0; src[i] != 0; i++) {
|
||||||
if (i >= maxLength)
|
if (i >= maxLength)
|
||||||
fatalerror("Symbol value too long to fit buffer");
|
fatalerror("Symbol value too long to fit buffer");
|
||||||
@@ -94,8 +98,25 @@ size_t symvaluetostring(char *dest, size_t maxLength, char *sym)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
uint32_t value = sym_GetConstantValue(sym);
|
uint32_t value = sym_GetConstantValue(sym);
|
||||||
int32_t fullLength = snprintf(dest, maxLength + 1, "$%X",
|
int32_t fullLength;
|
||||||
value);
|
|
||||||
|
/* Special cheat for binary */
|
||||||
|
if (mode && !mode[0]) {
|
||||||
|
char binary[33]; /* 32 bits + 1 terminator */
|
||||||
|
char *write_ptr = binary + 32;
|
||||||
|
fullLength = 0;
|
||||||
|
binary[32] = 0;
|
||||||
|
do {
|
||||||
|
*(--write_ptr) = (value & 1) + '0';
|
||||||
|
value >>= 1;
|
||||||
|
fullLength++;
|
||||||
|
} while(value);
|
||||||
|
strncpy(dest, write_ptr, maxLength + 1);
|
||||||
|
} else {
|
||||||
|
fullLength = snprintf(dest, maxLength + 1,
|
||||||
|
mode ? : "$%X",
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
|
||||||
if (fullLength < 0) {
|
if (fullLength < 0) {
|
||||||
fatalerror("snprintf encoding error");
|
fatalerror("snprintf encoding error");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of RGBDS.
|
* This file is part of RGBDS.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
|
* Copyright (c) 1997-2019, Carsten Sorensen and RGBDS contributors.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -599,6 +599,7 @@ size_t yylex_ReadBracketedSymbol(char *dest, size_t index)
|
|||||||
char ch;
|
char ch;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
size_t length, maxLength;
|
size_t length, maxLength;
|
||||||
|
const char *mode = NULL;
|
||||||
|
|
||||||
for (ch = *pLexBuffer;
|
for (ch = *pLexBuffer;
|
||||||
ch != '}' && ch != '"' && ch != '\n';
|
ch != '}' && ch != '"' && ch != '\n';
|
||||||
@@ -612,16 +613,42 @@ size_t yylex_ReadBracketedSymbol(char *dest, size_t index)
|
|||||||
i += length;
|
i += length;
|
||||||
else
|
else
|
||||||
fatalerror("Illegal character escape '%c'", ch);
|
fatalerror("Illegal character escape '%c'", ch);
|
||||||
|
} else if (ch == ':' && !mode) { /* Only grab 1st colon */
|
||||||
|
/* Use a whitelist of modes, which does prevent the
|
||||||
|
* use of some features such as precision,
|
||||||
|
* but also avoids a security flaw
|
||||||
|
*/
|
||||||
|
const char *acceptedModes = "bxXd";
|
||||||
|
/* Binary isn't natively supported,
|
||||||
|
* so it's handled differently
|
||||||
|
*/
|
||||||
|
static const char * const formatSpecifiers[] = {
|
||||||
|
"", "%x", "%X", "%d"
|
||||||
|
};
|
||||||
|
/* Prevent reading out of bounds! */
|
||||||
|
const char *designatedMode;
|
||||||
|
|
||||||
|
if (i != 1)
|
||||||
|
fatalerror("Print types are exactly 1 character long");
|
||||||
|
|
||||||
|
designatedMode = strchr(acceptedModes, sym[i - 1]);
|
||||||
|
if (!designatedMode)
|
||||||
|
fatalerror("Illegal print type '%c'",
|
||||||
|
sym[i - 1]);
|
||||||
|
mode = formatSpecifiers[designatedMode - acceptedModes];
|
||||||
|
/* Begin writing the symbol again */
|
||||||
|
i = 0;
|
||||||
} else {
|
} else {
|
||||||
yylex_SymbolWriteChar(sym, i++, ch);
|
yylex_SymbolWriteChar(sym, i++, ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Properly terminate the string */
|
||||||
yylex_SymbolWriteChar(sym, i, 0);
|
yylex_SymbolWriteChar(sym, i, 0);
|
||||||
|
|
||||||
/* It's assumed we're writing to a T_STRING */
|
/* It's assumed we're writing to a T_STRING */
|
||||||
maxLength = MAXSTRLEN - index;
|
maxLength = MAXSTRLEN - index;
|
||||||
length = symvaluetostring(&dest[index], maxLength, sym);
|
length = symvaluetostring(&dest[index], maxLength, sym, mode);
|
||||||
|
|
||||||
if (*pLexBuffer == '}')
|
if (*pLexBuffer == '}')
|
||||||
pLexBuffer++;
|
pLexBuffer++;
|
||||||
|
|||||||
@@ -1079,7 +1079,20 @@ within a string.
|
|||||||
This will examine the type of the symbol and insert its value accordingly.
|
This will examine the type of the symbol and insert its value accordingly.
|
||||||
If symbol is a string symbol, the symbols value is simply copied.
|
If symbol is a string symbol, the symbols value is simply copied.
|
||||||
If it's a numeric symbol, the value is converted to hexadecimal notation and
|
If it's a numeric symbol, the value is converted to hexadecimal notation and
|
||||||
inserted as a string.
|
inserted as a string with a dollar prepended.
|
||||||
|
.Pp
|
||||||
|
It's possible to change the way numeric symbols are converted by specifying
|
||||||
|
a print type like so:
|
||||||
|
.Sy {d:symbol}
|
||||||
|
Valid print types are:
|
||||||
|
.Bl -column -offset indent
|
||||||
|
.It Sy Print type Ta Sy Format Ta Sy Example
|
||||||
|
.It Li d Ta Decimal Ta 42
|
||||||
|
.It Li x Ta Lowercase hexadecimal Ta 2a
|
||||||
|
.It Li X Ta Uppercase hexadecimal Ta 2A
|
||||||
|
.It Li b Ta Binary Ta 101010
|
||||||
|
.Pp
|
||||||
|
Note that print types should only be used with numeric values, not strings.
|
||||||
.Pp
|
.Pp
|
||||||
HINT: The
|
HINT: The
|
||||||
.Sy {symbol}
|
.Sy {symbol}
|
||||||
|
|||||||
20
test/asm/bracketed-symbols.asm
Normal file
20
test/asm/bracketed-symbols.asm
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
X = 42
|
||||||
|
PRINTT "{X}\n"
|
||||||
|
PRINTT "{x:X}\n"
|
||||||
|
PRINTT "{X:X}\n"
|
||||||
|
PRINTT "{d:X}\n"
|
||||||
|
PRINTT "{b:X}\n"
|
||||||
|
|
||||||
|
Y equ 1337
|
||||||
|
PRINTT "{b:Y}\n"
|
||||||
|
|
||||||
|
rsreset
|
||||||
|
R rb 0
|
||||||
|
PRINTT "{d:R}\n"
|
||||||
|
|
||||||
|
S equs "You can't format me!"
|
||||||
|
PRINTT "{X:S}\n"
|
||||||
|
|
||||||
|
SECTION "Test", ROM0
|
||||||
|
Label:
|
||||||
|
PRINTT "{x:Label}\n"
|
||||||
12
test/asm/bracketed-symbols.out
Normal file
12
test/asm/bracketed-symbols.out
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
ERROR: bracketed-symbols.asm(16):
|
||||||
|
Print types are only allowed for numbers
|
||||||
|
ERROR: bracketed-symbols.asm(20):
|
||||||
|
Expression must have a constant value
|
||||||
|
$2A
|
||||||
|
2a
|
||||||
|
2A
|
||||||
|
42
|
||||||
|
101010
|
||||||
|
10100111001
|
||||||
|
0
|
||||||
|
You can't format me!
|
||||||
12
test/asm/bracketed-symbols.out.pipe
Normal file
12
test/asm/bracketed-symbols.out.pipe
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
ERROR: -(16):
|
||||||
|
Print types are only allowed for numbers
|
||||||
|
ERROR: -(20):
|
||||||
|
Expression must have a constant value
|
||||||
|
$2A
|
||||||
|
2a
|
||||||
|
2A
|
||||||
|
42
|
||||||
|
101010
|
||||||
|
10100111001
|
||||||
|
0
|
||||||
|
You can't format me!
|
||||||
Reference in New Issue
Block a user