From f42842a59eb46e79c355f1892793c254c74dc340 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 16 Feb 2009 20:30:05 -0500 Subject: [PATCH] Try to make #error lexing match gcc's. --- mojoshader_internal.h | 1 + mojoshader_lexer.re | 4 +++- mojoshader_preprocessor.c | 42 ++++++++++++++++++++++++++------------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/mojoshader_internal.h b/mojoshader_internal.h index 995c4ba0..6a7cb8c9 100644 --- a/mojoshader_internal.h +++ b/mojoshader_internal.h @@ -394,6 +394,7 @@ typedef struct IncludeState const char *source; const char *token; const unsigned char *lexer_marker; + int report_whitespace; unsigned int bytes_left; unsigned int line; Conditional *conditional_stack; diff --git a/mojoshader_lexer.re b/mojoshader_lexer.re index 12ea15ef..fb678397 100644 --- a/mojoshader_lexer.re +++ b/mojoshader_lexer.re @@ -144,7 +144,7 @@ scanner_loop: 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 @@ multilinecomment: "*\/" { if (saw_newline) RET('\n'); + else if (s->report_whitespace) + RET(' '); goto scanner_loop; } NEWLINE { diff --git a/mojoshader_preprocessor.c b/mojoshader_preprocessor.c index 1360735d..95d5bf82 100644 --- a/mojoshader_preprocessor.c +++ b/mojoshader_preprocessor.c @@ -697,16 +697,26 @@ static void handle_pp_line(Context *ctx) } // 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 @@ static void handle_pp_error(Context *ctx) // 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