From 3c97be45678eb9fc8b59bad28d995260afb820ed Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 24 Feb 2010 14:00:25 -0500 Subject: [PATCH] Check for "##" at the start and end of macro definitions. --- mojoshader_preprocessor.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/mojoshader_preprocessor.c b/mojoshader_preprocessor.c index a1e4e676..7cf7a129 100644 --- a/mojoshader_preprocessor.c +++ b/mojoshader_preprocessor.c @@ -1052,7 +1052,9 @@ static void handle_pp_define(Context *ctx) case TOKEN_INCOMPLETE_COMMENT: case TOKEN_EOI: pushback(state); // move back so we catch this later. - // fall through! + done = 1; + break; + case ((Token) '\n'): done = 1; break; @@ -1077,11 +1079,39 @@ static void handle_pp_define(Context *ctx) ctx->out_of_memory = (definition == NULL); } // if + size_t buflen = buffer.total_bytes + 1; free_buffer(&buffer, ctx->free, d); if (ctx->out_of_memory) goto handle_pp_define_failed; + int hashhash_error = 0; + if ((buflen > 2) && (definition[0] == '#') && (definition[1] == '#')) + { + hashhash_error = 1; + buflen -= 2; + memmove(definition, definition + 2, buflen); + } // if + + if (buflen > 2) + { + char *ptr = (definition + buflen) - 2; + if (*ptr == ' ') + { + ptr--; + buflen--; + } // if + if ((buflen > 2) && (ptr[0] == '#') && (ptr[-1] == '#')) + { + hashhash_error = 1; + buflen -= 2; + ptr[-1] = '\0'; + } // if + } // if + + if (hashhash_error) + fail(ctx, "'##' cannot appear at either end of a macro expansion"); + assert(done); if (!add_define(ctx, sym, definition, idents, params)) @@ -1196,11 +1226,11 @@ static int handle_pp_identifier(Context *ctx) memcpy(sym, state->token, state->tokenlen); sym[state->tokenlen] = '\0'; - // IncludeState defines take precedence over Context defines. + // IncludeState defines (macro args) take precedence over Context defines. const Define *def = state->defines; while (def) { - assert(def->paramcount == 0); + assert(def->paramcount == 0); // args can't have args! if (strcmp(def->identifier, sym) == 0) break; def = def->next;