- Marks the end of a macro definition.
+ Marks the end of a macro definition. Note, .ENDMACRO should be on
+ its own line to successfully end the macro definition. It is possible to use
+ to create a symbol that references
+ .ENDMACRO without ending the macro definition.
+
+ Example:
+
+
+ .macro new_mac
+ .define startmac .macro
+ .define endmac .endmacro
+ .endmacro
+
See: ,
,
diff --git a/src/ca65/macro.c b/src/ca65/macro.c
index 4812b12c4..904c80756 100644
--- a/src/ca65/macro.c
+++ b/src/ca65/macro.c
@@ -390,7 +390,20 @@ void MacDef (unsigned Style)
{
Macro* M;
TokNode* N;
+ FilePos Pos;
int HaveParams;
+ int LastTokWasSep;
+
+ /* For classic macros, remember if we are at the beginning of the line.
+ ** If the macro name and parameters pass our checks then we will be on a
+ ** new line, so set it now
+ */
+ LastTokWasSep = 1;
+
+ /* Save the position of the start of the macro definition to allow
+ ** using Perror to display the error if .endmacro isn't found
+ */
+ Pos = CurTok.Pos;
/* We expect a macro name here */
if (CurTok.Tok != TOK_IDENT) {
@@ -491,14 +504,16 @@ void MacDef (unsigned Style)
while (1) {
/* Check for end of macro */
if (Style == MAC_STYLE_CLASSIC) {
- /* In classic macros, only .endmacro is allowed */
- if (CurTok.Tok == TOK_ENDMACRO) {
+ /* In classic macros, if .endmacro is not at the start of the line
+ ** it will be added to the macro definition instead of closing it.
+ */
+ if (CurTok.Tok == TOK_ENDMACRO && LastTokWasSep) {
/* Done */
break;
}
/* May not have end of file in a macro definition */
if (CurTok.Tok == TOK_EOF) {
- Error ("'.ENDMACRO' expected");
+ PError (&Pos, "'.ENDMACRO' expected for macro '%m%p'", &M->Name);
goto Done;
}
} else {
@@ -573,6 +588,11 @@ void MacDef (unsigned Style)
}
++M->TokCount;
+ /* Save if last token was a separator to know if .endmacro is at
+ ** the start of a line
+ */
+ LastTokWasSep = TokIsSep(CurTok.Tok);
+
/* Read the next token */
NextTok ();
}
diff --git a/test/asm/err/endmacro.s b/test/asm/err/endmacro.s
new file mode 100644
index 000000000..8907675fb
--- /dev/null
+++ b/test/asm/err/endmacro.s
@@ -0,0 +1,6 @@
+; for PR #2013
+; should produce error output:
+; ... Error: '.ENDMACRO' expected for macro 'test'
+
+.macro test
+ nop .endmacro
diff --git a/test/asm/val/endmacro.s b/test/asm/val/endmacro.s
new file mode 100644
index 000000000..cfb8efefb
--- /dev/null
+++ b/test/asm/val/endmacro.s
@@ -0,0 +1,30 @@
+; for PR #2013
+ .import _exit
+ .export _main
+
+ ; this macro is invalid, but should not cause an error (if it is never expanded)
+ .macro invalid
+ nop .endmacro
+ .endmacro
+
+ .define temp_endmac .endmacro
+ .macro new_mac
+ .define startmac .macro
+ .define endmac .endmacro
+ temp_endmac
+
+ .undefine temp_endmac
+
+ new_mac
+
+ startmac dex2
+ dex
+ dex
+ endmac
+
+_main:
+ ldx #$02
+ dex2
+ ; x should be zero
+ txa
+ jmp _exit