ref: dc2c97fe0cf129941b54f8213e536ab2bbfd8463
parent: 6068b565f5f487ad725cacc1ff79ed4451cd89b7
author: ISSOtm <[email protected]>
date: Fri Aug 30 16:47:04 EDT 2019
Comment and improve ParseSymbol and AppendMacroArg
--- a/include/asm/lexer.h
+++ b/include/asm/lexer.h
@@ -65,7 +65,7 @@
int yywrap(void);
int yylex(void);
void yyunput(char c);
-void yyunputstr(char *s);
+void yyunputstr(const char *s);
void yyskipbytes(uint32_t count);
void yyunputbytes(uint32_t count);
--- a/src/asm/globlex.c
+++ b/src/asm/globlex.c
@@ -188,11 +188,11 @@
}
/*
- * If the symbol name ends before the end of the macro arg, return true
- * and point "rest" to the rest of the macro arg.
- * Otherwise, return false.
+ * If the symbol name ends before the end of the macro arg,
+ * return a pointer to the rest of the macro arg.
+ * Otherwise, return NULL.
*/
-bool AppendMacroArg(char whichArg, char *dest, size_t *destIndex, char **rest)
+char *AppendMacroArg(char whichArg, char *dest, size_t *destIndex)
{
char *marg;
@@ -222,14 +222,13 @@
dest[*destIndex] = ch;
(*destIndex)++;
} else {
- *rest = marg;
- return true;
+ return marg;
}
marg++;
}
- return false;
+ return NULL;
}
uint32_t ParseSymbol(char *src, uint32_t size)
@@ -251,7 +250,9 @@
*/
ch = src[srcIndex++];
- if (AppendMacroArg(ch, dest, &destIndex, &rest))
+ rest = AppendMacroArg(ch, dest, &destIndex);
+ /* If the symbol's end was in the middle of the token */
+ if (rest)
break;
} else {
if (destIndex >= MAXSYMLEN)
@@ -262,27 +263,32 @@
dest[destIndex] = 0;
+ /* Tell the lexer we read all bytes that we did */
+ yyskipbytes(srcIndex);
+
+ /*
+ * If an escape's expansion left some chars after the symbol's end,
+ * such as the `::` in a `Backup\1` expanded to `BackupCamX::`,
+ * put those into the buffer.
+ * Note that this NEEDS to be done after the `yyskipbytes` above.
+ */
+ if (rest)
+ yyunputstr(rest);
+
+ /* If the symbol is an EQUS, expand it */
if (!oDontExpandStrings && sym_isString(dest)) {
char *s;
- yyskipbytes(srcIndex);
-
- if (rest)
- yyunputstr(rest);
-
+ /* Feed the symbol's contents into the buffer */
yyunputstr(s = sym_GetStringValue(dest));
+ /* Lines inserted this way shall not increase nLineNo */
while (*s) {
if (*s++ == '\n')
- nLineNo -= 1;
+ nLineNo--;
}
return 0;
}
-
- yyskipbytes(srcIndex);
-
- if (rest)
- yyunputstr(rest);
strcpy(yylval.tzSym, dest);
return 1;
--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -88,17 +88,18 @@
*(--pLexBuffer) = c;
}
-void yyunputstr(char *s)
+void yyunputstr(const char *s)
{
- int32_t i, len;
+ int32_t len;
len = strlen(s);
- if (pLexBuffer - len < pLexBufferRealStart)
+ pLexBuffer -= len;
+
+ if (pLexBuffer < pLexBufferRealStart)
fatalerror("Buffer safety margin exceeded");
- for (i = len - 1; i >= 0; i--)
- *(--pLexBuffer) = s[i];
+ memcpy(pLexBuffer, s, len);
}
void yy_switch_to_buffer(YY_BUFFER_STATE buf)