Only increment the unique \@ ID when it is first used per context (#1030)

This avoids changes to generated `\@` labels just by adding or
removing macros or loops which do not actually use `\@`.

Fixes #1019
This commit is contained in:
Rangi
2022-08-31 17:45:21 -04:00
committed by GitHub
parent a52a00a9ca
commit c01317e08d
5 changed files with 88 additions and 6 deletions

View File

@@ -285,6 +285,9 @@ static void newContext(struct FileStackNode *fileInfo)
++contextDepth; ++contextDepth;
fstk_NewRecursionDepth(maxRecursionDepth); // Only checks if the max depth was exceeded fstk_NewRecursionDepth(maxRecursionDepth); // Only checks if the max depth was exceeded
// Save the current `\@` value, to be restored when this context ends
contextStack->uniqueID = macro_GetUniqueID();
struct Context *context = malloc(sizeof(*context)); struct Context *context = malloc(sizeof(*context));
if (!context) if (!context)

View File

@@ -6,7 +6,6 @@
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#include <assert.h>
#include <errno.h> #include <errno.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h> #include <stdbool.h>
@@ -145,17 +144,19 @@ uint32_t macro_GetUniqueID(void)
char const *macro_GetUniqueIDStr(void) char const *macro_GetUniqueIDStr(void)
{ {
// Generate a new unique ID on the first use of `\@`
if (uniqueID == 0)
macro_SetUniqueID(++maxUniqueID);
return uniqueIDPtr; return uniqueIDPtr;
} }
void macro_SetUniqueID(uint32_t id) void macro_SetUniqueID(uint32_t id)
{ {
uniqueID = id; uniqueID = id;
if (id == 0) { if (id == 0 || id == (uint32_t)-1) {
uniqueIDPtr = NULL; uniqueIDPtr = NULL;
} else { } else {
if (uniqueID > maxUniqueID)
maxUniqueID = uniqueID;
// The buffer is guaranteed to be the correct size // The buffer is guaranteed to be the correct size
// This is a valid label fragment, but not a valid numeric // This is a valid label fragment, but not a valid numeric
sprintf(uniqueIDBuf, "_u%" PRIu32, id); sprintf(uniqueIDBuf, "_u%" PRIu32, id);
@@ -165,13 +166,15 @@ void macro_SetUniqueID(uint32_t id)
uint32_t macro_UseNewUniqueID(void) uint32_t macro_UseNewUniqueID(void)
{ {
macro_SetUniqueID(++maxUniqueID); // A new ID will be generated on the first use of `\@`
macro_SetUniqueID(0);
return uniqueID; return uniqueID;
} }
uint32_t macro_UndefUniqueID(void) uint32_t macro_UndefUniqueID(void)
{ {
macro_SetUniqueID(0); // No ID will be generated; use of `\@` is an error
macro_SetUniqueID((uint32_t)-1);
return uniqueID; return uniqueID;
} }

View File

@@ -0,0 +1,22 @@
MACRO m
println " m: \@"
for q, \#
if q % 2 == 0
println " q = {d:q}: \@"
else
println " q = {d:q}"
endc
endr
println " (m: still \@)"
ENDM
for p, 10
if p % 3 == 0
println "p = {d:p}: \@"
m 3
m 3, 6
println " (p: still \@)"
else
println "p = {d:p}"
endc
endr

View File

View File

@@ -0,0 +1,54 @@
p = 0: _u1
m: _u2
q = 0: _u3
q = 1
q = 2: _u4
(m: still _u2)
m: _u5
q = 3
q = 4: _u6
q = 5
(m: still _u5)
(p: still _u1)
p = 1
p = 2
p = 3: _u7
m: _u8
q = 0: _u9
q = 1
q = 2: _u10
(m: still _u8)
m: _u11
q = 3
q = 4: _u12
q = 5
(m: still _u11)
(p: still _u7)
p = 4
p = 5
p = 6: _u13
m: _u14
q = 0: _u15
q = 1
q = 2: _u16
(m: still _u14)
m: _u17
q = 3
q = 4: _u18
q = 5
(m: still _u17)
(p: still _u13)
p = 7
p = 8
p = 9: _u19
m: _u20
q = 0: _u21
q = 1
q = 2: _u22
(m: still _u20)
m: _u23
q = 3
q = 4: _u24
q = 5
(m: still _u23)
(p: still _u19)