Bring .ENDM label in correspondence with the manual.

This commit is contained in:
Olaf Seibert 2015-05-12 22:59:21 +02:00
parent 1e9e8023b3
commit e703403017

View File

@ -74,7 +74,6 @@ void read_body(
int called)
{
int nest;
unsigned int self_redef = 0;
/* Read the stream in until the end marker is hit */
@ -107,67 +106,29 @@ void read_body(
if (op->section->type == SECTION_PSEUDO) {
if (op->value == P_MACRO || op->value == P_REPT || op->value == P_IRP || op->value == P_IRPC) {
nest++;
self_redef <<= 1;
if (op->value == P_MACRO) {
/* Check for self-redefinition. If that occurs,
* we can't currently cut the outermost macro definition
* short when we encounter .ENDM <self>.
* self_redef keeps a "stack" of booleans for the
* currently nested levels, indicating whether each
* level is a self-redefinition.
*/
char *nested_name = get_symbol(cp, &cp, NULL);
if (nested_name != NULL) {
if (strcmp(nested_name, name) == 0) {
self_redef |= 1;
}
free(nested_name);
}
}
}
if (op->value == P_ENDM || op->value == P_ENDR) {
nest--;
/* If there's a name on the .ENDM, then */
/* close the body early if it matches the definition */
/* That is however a bad idea for this case:
* .MACRO FAB$BT DEF
* .MCALL DEF
* DEF FB$BID,3
* ...
* .MACRO FAB$BT DEF
* .ENDM FAB$BT
* .ENDM FAB$BT
* Therefore we are a bit more selective.
*
* (in fact, on page 7-3 of the manual, there is no
* allowance for early termination of macros, but instead
* the name is checked and if it doesn't match the currently
* defined macro, an error code A is issued.
/* If there's a name on the .ENDM, then
* check if the name matches the one on .MACRO.
* See page 7-3.
* Since we don't keep a stack of nested
* .MACRO names, just check for the outer one.
*/
if (!self_redef && nest > 0 &&
name && op->value == P_ENDM) {
if (nest == 0 && name && op->value == P_ENDM) {
cp = skipwhite(cp);
if (!EOL(*cp)) {
char *label = get_symbol(cp, &cp, NULL);
if (label) {
if (strcmp(label, name) == 0) {
/* Something similar to the following code
* maybe later, if we do need accurate named
* escapes from nested macro definitions:
while (!(self_redef & 1)) {
nest--;
self_redef >>= 1;
}
*/
nest = 0; /* End of macro body. */
if (strcmp(label, name) != 0) {
report(stack->top, ".ENDM '%s' does not match .MACRO '%s'\n", label, name);
}
free(label);
}
}
}
self_redef >>= 1;
}
if (nest == 0)