ref: 9081feab51c8727b81f938d4eeb0c324c18b7a0f
parent: cf992164f79a0e5c0fd49b445d698be2361a9b67
author: ISSOtm <eldredhabert0@gmail.com>
date: Sat Aug 15 11:15:18 EDT 2020
Reinstate macro arg scan distance Used to be broken, so it was removed, but doing so prevents escaping them. So it was instead put back in, but with corrected behavior
--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -278,6 +278,7 @@
char *captureBuf; /* Buffer to send the captured text to if non-NULL */
size_t captureCapacity; /* Size of the buffer above */
+ size_t macroArgScanDistance; /* Max distance already scanned for macro args */
bool expandStrings;
struct Expansion *expansions;
size_t expansionOfs; /* Offset into the current top-level expansion (negative = before) */
@@ -295,6 +296,7 @@
state->capturing = false;
state->captureBuf = NULL;
+ state->macroArgScanDistance = 0;
state->expandStrings = true;
state->expansions = NULL;
state->expansionOfs = 0;
@@ -716,16 +718,29 @@
{
int c = peekInternal(distance);
- /* If not capturing and character is a backslash, check for a macro arg */
- if (!lexerState->capturing && c == '\\') {
- distance++;
- c = peekInternal(distance);
- if (c == '@' || (c >= '0' && c <= '9')) {
- /* Expand the argument and return its first character */
- c = expandMacroArg(c, distance - 1)[0];
- /* WARNING: this assumes macro args can't be empty!! */
- } else {
- c = '\\';
+ if (distance >= lexerState->macroArgScanDistance) {
+ lexerState->macroArgScanDistance = distance + 1; /* Do not consider again */
+ /* If not capturing and character is a backslash, check for a macro arg */
+ if (!lexerState->capturing && c == '\\') {
+ distance++;
+ lexerState->macroArgScanDistance++;
+ c = peekInternal(distance);
+ if (c == '@' || (c >= '1' && c <= '9')) {
+ /* Expand the argument and return its first character */
+ char const *str = expandMacroArg(c, distance - 1);
+
+ /*
+ * Assuming macro args can't be recursive (I'll be damned if a way
+ * is found...), then we mark the entire macro arg as scanned;
+ * however, the two macro arg characters (\1) will be ignored,
+ * so they shouldn't be counted in the scan distance!
+ */
+ lexerState->macroArgScanDistance += strlen(str) - 2;
+ /* WARNING: this assumes macro args can't be empty!! */
+ c = str[0];
+ } else {
+ c = '\\';
+ }
}
}
return c;
@@ -744,6 +759,8 @@
lexerState->captureSize += distance;
}
}
+
+ lexerState->macroArgScanDistance -= distance;
/* FIXME: this may not be too great, as only the top level is considered... */