0
0
mirror of https://github.com/netwide-assembler/nasm.git synced 2025-07-24 10:25:42 -04:00

preproc: massive cleanup of smacro expansion

The smacro expansion code was virtually impossible to understand, and
was leading to very strange failures. Clean it up, and do much better
handling of magic macros.  This should also allow for recursive
macros, but recursive macros are extremely tricky in that it is very
hard to keep them from recursing forever, unless there is at least one
argument which is never expanded. They are not currently implemented.

Even so, I believe token pasting makes it possible to create infinite
loops; e.g.:

%define foo foo %+

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin (Intel) 2019-04-25 18:00:32 -07:00
parent 6189133363
commit 41e9682efe
5 changed files with 452 additions and 389 deletions

File diff suppressed because it is too large Load Diff

View File

@ -41,13 +41,19 @@
#include "nasmlib.h" #include "nasmlib.h"
#include "quote.h" #include "quote.h"
char *nasm_quote(const char *str, size_t len) /*
* Create a NASM quoted string in newly allocated memory. Update the
* *lenp parameter with the output length (sans final NUL).
*/
char *nasm_quote(const char *str, size_t *lenp)
{ {
const char *p, *ep; const char *p, *ep;
char c, c1, *q, *nstr; char c, c1, *q, *nstr;
unsigned char uc; unsigned char uc;
bool sq_ok, dq_ok; bool sq_ok, dq_ok;
size_t qlen; size_t qlen;
size_t len = *lenp;
sq_ok = dq_ok = true; sq_ok = dq_ok = true;
ep = str+len; ep = str+len;
@ -105,7 +111,7 @@ char *nasm_quote(const char *str, size_t len)
/* Use '...' or "..." */ /* Use '...' or "..." */
nstr = nasm_malloc(len+3); nstr = nasm_malloc(len+3);
nstr[0] = nstr[len+1] = sq_ok ? '\'' : '\"'; nstr[0] = nstr[len+1] = sq_ok ? '\'' : '\"';
nstr[len+2] = '\0'; q = &nstr[len+2];
if (len > 0) if (len > 0)
memcpy(nstr+1, str, len); memcpy(nstr+1, str, len);
} else { } else {
@ -174,9 +180,10 @@ char *nasm_quote(const char *str, size_t len)
} }
} }
*q++ = '`'; *q++ = '`';
*q++ = '\0'; nasm_assert((size_t)(q-nstr) == qlen+2);
nasm_assert((size_t)(q-nstr) == qlen+3);
} }
*q = '\0';
*lenp = q - nstr;
return nstr; return nstr;
} }
@ -216,11 +223,16 @@ static char *emit_utf8(char *q, int32_t v)
} }
/* /*
* Quote a C string * Same as nasm_quote, but take the length of a C string;
* the lenp argument is optional.
*/ */
char *nasm_quote_cstr(const char *str) char *nasm_quote_cstr(const char *str, size_t *lenp)
{ {
return nasm_quote(str, strlen(str)); size_t len = strlen(str);
char *qstr = nasm_quote(str, &len);
if (lenp)
*lenp = len;
return qstr;
} }
/* /*

View File

@ -36,8 +36,8 @@
#include "compiler.h" #include "compiler.h"
char *nasm_quote(const char *str, size_t len); char *nasm_quote(const char *str, size_t *len);
char *nasm_quote_cstr(const char *str); char *nasm_quote_cstr(const char *str, size_t *len);
size_t nasm_unquote(char *str, char **endptr); size_t nasm_unquote(char *str, char **endptr);
char *nasm_skip_string(char *str); char *nasm_skip_string(char *str);

View File

@ -41,6 +41,19 @@
#include "compiler.h" #include "compiler.h"
#include "bytesex.h" #include "bytesex.h"
/*
* Useful construct for private values
*/
union intorptr {
int64_t i;
uint64_t u;
size_t s;
void *p;
const void *cp;
uintptr_t up;
};
typedef union intorptr intorptr;
/* /*
* Wrappers around malloc, realloc, free and a few more. nasm_malloc * Wrappers around malloc, realloc, free and a few more. nasm_malloc
* will fatal-error and die rather than return NULL; nasm_realloc will * will fatal-error and die rather than return NULL; nasm_realloc will

View File

@ -50,11 +50,6 @@ typedef union RAA_UNION RAA_UNION;
typedef struct RAA_LEAF RAA_LEAF; typedef struct RAA_LEAF RAA_LEAF;
typedef struct RAA_BRANCH RAA_BRANCH; typedef struct RAA_BRANCH RAA_BRANCH;
union intorptr {
int64_t i;
void *p;
};
struct RAA { struct RAA {
/* Last position in this RAA */ /* Last position in this RAA */
raaindex endposn; raaindex endposn;