mojoshader_preprocessor.c
changeset 864 aa3bec973a21
parent 861 760e1457ffc6
child 865 4eb06464212d
--- a/mojoshader_preprocessor.c	Wed Feb 24 13:18:50 2010 -0500
+++ b/mojoshader_preprocessor.c	Wed Feb 24 14:00:25 2010 -0500
@@ -1052,7 +1052,9 @@
             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 @@
         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 @@
     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;