Try to make #error lexing match gcc's.
authorRyan C. Gordon <icculus@icculus.org>
Mon, 16 Feb 2009 20:30:05 -0500
changeset 635 be3b428802a1
parent 634 b7fd8aa02bf4
child 636 6923c9cfb4b9
Try to make #error lexing match gcc's.
mojoshader_internal.h
mojoshader_lexer.re
mojoshader_preprocessor.c
--- a/mojoshader_internal.h	Mon Feb 16 20:29:28 2009 -0500
+++ b/mojoshader_internal.h	Mon Feb 16 20:30:05 2009 -0500
@@ -394,6 +394,7 @@
     const char *source;
     const char *token;
     const unsigned char *lexer_marker;
+    int report_whitespace;
     unsigned int bytes_left;
     unsigned int line;
     Conditional *conditional_stack;
--- a/mojoshader_lexer.re	Mon Feb 16 20:29:28 2009 -0500
+++ b/mojoshader_lexer.re	Mon Feb 16 20:30:05 2009 -0500
@@ -144,7 +144,7 @@
     PP "endif"      { RET(TOKEN_PP_ENDIF); }
     PP "error"      { RET(TOKEN_PP_ERROR); }
 
-    WHITESPACE      { goto scanner_loop; }
+    WHITESPACE      { if (s->report_whitespace) RET(' '); goto scanner_loop; }
     NEWLINE         { s->line++; RET('\n'); }
     ANY             { goto bad_chars; }
 */
@@ -158,6 +158,8 @@
     "*\/"           {
                         if (saw_newline)
                             RET('\n');
+                        else if (s->report_whitespace)
+                            RET(' ');
                         goto scanner_loop;
                     }
     NEWLINE         {
--- a/mojoshader_preprocessor.c	Mon Feb 16 20:29:28 2009 -0500
+++ b/mojoshader_preprocessor.c	Mon Feb 16 20:30:05 2009 -0500
@@ -697,16 +697,26 @@
 } // handle_pp_line
 
 
-// !!! FIXME: this should use the lexer, apparently gcc does so.
 static void handle_pp_error(Context *ctx)
 {
     IncludeState *state = ctx->include_stack;
-    const char *data = NULL;
+    unsigned int bytes_left = 0;
+    char *ptr = ctx->failstr;
+    int avail = sizeof (ctx->failstr) - 1;
+    int cpy = 0;
     int done = 0;
 
+    const char *prefix = "#error";
+    const size_t prefixlen = strlen(prefix);
+    strcpy(ctx->failstr, prefix);
+    avail -= prefixlen;
+    ptr += prefixlen;
+
+    state->report_whitespace = 1;
     const char *source = NULL;
     while (!done)
     {
+        bytes_left = state->bytes_left;
         source = state->source;
         const Token token = preprocessor_internal_lexer(state);
         switch (token)
@@ -716,26 +726,30 @@
                 // fall through!
             case TOKEN_INCOMPLETE_COMMENT:
             case TOKEN_EOI:
+                state->bytes_left = bytes_left;
+                state->source = source;  // move back so we catch this later.
                 done = 1;
                 break;
 
+            case ' ':
+                if (!avail)
+                    break;
+                *(ptr++) = ' ';
+                avail--;
+                break;
+
             default:
-                if (data == NULL)
-                    data = state->token;  // skip #error token.
+                cpy = Min(avail, (int) (state->source-state->token));
+                if (cpy)
+                    memcpy(ptr, state->token, cpy);
+                ptr += cpy;
+                avail -= cpy;
                 break;
         } // switch
     } // while
 
-    state->source = source;  // move back so we catch this later.
-
-    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';
+    *ptr = '\0';
+    state->report_whitespace = 0;
     ctx->isfail = 1;
 } // handle_pp_error