Added support for #error directive to the preprocessor.
authorRyan C. Gordon <icculus@icculus.org>
Fri, 13 Feb 2009 02:29:17 -0500
changeset 606 63e7a66ac320
parent 605 197c9f2999b7
child 607 40d903561ff8
Added support for #error directive to the preprocessor.
mojoshader_assembler.c
mojoshader_internal.h
mojoshader_preprocessor.c
--- a/mojoshader_assembler.c	Fri Feb 13 02:28:26 2009 -0500
+++ b/mojoshader_assembler.c	Fri Feb 13 02:29:17 2009 -0500
@@ -1254,10 +1254,6 @@
     return 0;
 } // parse_condition
 
-static inline int Min(const int a, const int b)
-{
-    return ((a < b) ? a : b);
-} // Min
 
 static int parse_instruction_token(Context *ctx, Token token)
 {
--- a/mojoshader_internal.h	Fri Feb 13 02:28:26 2009 -0500
+++ b/mojoshader_internal.h	Fri Feb 13 02:29:17 2009 -0500
@@ -119,6 +119,11 @@
 #   define SWAP32(x) (x)
 #endif
 
+static inline int Min(const int a, const int b)
+{
+    return ((a < b) ? a : b);
+} // Min
+
 // This is the ID for a D3DXSHADER_CONSTANTTABLE in the bytecode comments.
 #define CTAB_ID 0x42415443  // 0x42415443 == 'CTAB'
 #define CTAB_SIZE 28  // sizeof (D3DXSHADER_CONSTANTTABLE).
--- a/mojoshader_preprocessor.c	Fri Feb 13 02:28:26 2009 -0500
+++ b/mojoshader_preprocessor.c	Fri Feb 13 02:29:17 2009 -0500
@@ -27,7 +27,7 @@
 {
     int isfail;
     int out_of_memory;
-    char failstr[128];
+    char failstr[256];
     IncludeState *include_stack;
     DefineHash *define_hashtable[256];
     int pushedback;
@@ -392,6 +392,47 @@
 } // preprocessor_outofmemory
 
 
+static void handle_pp_error(Context *ctx)
+{
+    IncludeState *state = ctx->include_stack;
+    const char *data = NULL;
+    int done = 0;
+
+    while (!done)
+    {
+        const char *source = state->source;
+        const Token token = preprocessor_internal_lexer(state);
+        switch (token)
+        {
+            case TOKEN_INCOMPLETE_COMMENT:
+                state->source = source;  // move back so we catch this later.
+                done = 1;
+                break;
+
+            case ((Token) '\n'):
+            case TOKEN_EOI:
+                done = 1;
+                break;
+
+            default:
+                if (data == NULL)
+                    data = state->token;  // skip #error token.
+                break;
+        } // switch
+    } // while
+
+    const char *prefix = "#error ";
+    const size_t prefixlen = strlen(prefix);
+    const int len = (int) (state->source - data);
+    const int cpy = Min(len, sizeof (ctx->failstr) - prefixlen);
+    strcpy(ctx->failstr, prefix);
+    if (cpy > 0)
+        memcpy(ctx->failstr + prefixlen, data, cpy);
+    ctx->failstr[cpy + prefixlen] = '\0';
+    ctx->isfail = 1;
+} // handle_pp_error
+
+
 static inline const char *_preprocessor_nexttoken(Preprocessor *_ctx,
                                              unsigned int *_len, Token *_token)
 {
@@ -426,7 +467,6 @@
         // TOKEN_PP_ELSE,
         // TOKEN_PP_ELIF,
         // TOKEN_PP_ENDIF,
-        // TOKEN_PP_ERROR,
 
         Token token = preprocessor_internal_lexer(state);
         if (token == TOKEN_EOI)
@@ -442,6 +482,12 @@
             continue;  // will return at top of loop.
         } // else if
 
+        else if (token == TOKEN_PP_ERROR)
+        {
+            handle_pp_error(ctx);
+            continue;  // will return at top of loop.
+        } // else if
+
         *_token = token;
         *_len = (unsigned int) (state->source - state->token);
         return state->token;