From 8961fa585c59a843db3e7349fd4f4c893ff96de4 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 2 Oct 2014 15:54:31 -0400 Subject: [PATCH] Allow multiline comments before preprocessor directives. Microsoft's preprocessor allows this, even though C/C++ doesn't. --- mojoshader_internal.h | 5 +++++ mojoshader_lexer.c | 12 ++++++++++++ mojoshader_lexer.re | 12 ++++++++++++ mojoshader_preprocessor.c | 6 ------ .../output/comment-before-preprocessor-directive | 10 ++++++++++ .../comment-before-preprocessor-directive.correct | 1 + .../output/multiline-comment-no-whitespace | 1 + .../output/multiline-comment-no-whitespace.correct | 1 + .../output/multiline-comments-alone-on-line | 3 +++ .../output/multiline-comments-alone-on-line.correct | 1 + 10 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 unit_tests/preprocessor/output/comment-before-preprocessor-directive create mode 100644 unit_tests/preprocessor/output/comment-before-preprocessor-directive.correct create mode 100644 unit_tests/preprocessor/output/multiline-comment-no-whitespace create mode 100644 unit_tests/preprocessor/output/multiline-comment-no-whitespace.correct create mode 100644 unit_tests/preprocessor/output/multiline-comments-alone-on-line create mode 100644 unit_tests/preprocessor/output/multiline-comments-alone-on-line.correct diff --git a/mojoshader_internal.h b/mojoshader_internal.h index 94f400cc..0b06334d 100644 --- a/mojoshader_internal.h +++ b/mojoshader_internal.h @@ -68,6 +68,11 @@ #error glsl120 profile requires glsl profile. Fix your build. #endif +// Microsoft's preprocessor has some quirks. In some ways, it doesn't work +// like you'd expect a C preprocessor to function. +#ifndef MATCH_MICROSOFT_PREPROCESSOR +#define MATCH_MICROSOFT_PREPROCESSOR 1 +#endif // Other stuff you can disable... diff --git a/mojoshader_lexer.c b/mojoshader_lexer.c index 01bc62d9..e2faa7c4 100644 --- a/mojoshader_lexer.c +++ b/mojoshader_lexer.c @@ -1164,6 +1164,18 @@ Token preprocessor_lexer(IncludeState *s) RET(TOKEN_MULTI_COMMENT); else if (s->report_whitespace) RET(' '); + + // Microsoft's preprocessor allows multiline comments + // before a preprocessor directive, even though C/C++ + // doesn't. See if we've hit this case. + #if MATCH_MICROSOFT_PREPROCESSOR + if (s->tokenval == ((Token) '\n')) // was start of line? + { + update_state(s, eoi, cursor, token, (Token) '\n'); + goto ppdirective; // may jump back to scanner_loop. + } + #endif + goto scanner_loop; } } diff --git a/mojoshader_lexer.re b/mojoshader_lexer.re index 63e7ca3d..c54d9d77 100644 --- a/mojoshader_lexer.re +++ b/mojoshader_lexer.re @@ -172,6 +172,18 @@ multilinecomment: RET(TOKEN_MULTI_COMMENT); else if (s->report_whitespace) RET(' '); + + // Microsoft's preprocessor allows multiline comments + // before a preprocessor directive, even though C/C++ + // doesn't. See if we've hit this case. + #if MATCH_MICROSOFT_PREPROCESSOR + if (s->tokenval == ((Token) '\n')) // was start of line? + { + update_state(s, eoi, cursor, token, (Token) '\n'); + goto ppdirective; // may jump back to scanner_loop. + } + #endif + goto scanner_loop; } NEWLINE { diff --git a/mojoshader_preprocessor.c b/mojoshader_preprocessor.c index 6044aecd..5b5090ba 100644 --- a/mojoshader_preprocessor.c +++ b/mojoshader_preprocessor.c @@ -60,12 +60,6 @@ typedef struct Context void *malloc_data; } Context; -// Microsoft's preprocessor has some quirks. In some ways, it doesn't work -// like you'd expect a C preprocessor to function. -#ifndef MATCH_MICROSOFT_PREPROCESSOR -#define MATCH_MICROSOFT_PREPROCESSOR 1 -#endif - // Convenience functions for allocators... diff --git a/unit_tests/preprocessor/output/comment-before-preprocessor-directive b/unit_tests/preprocessor/output/comment-before-preprocessor-directive new file mode 100644 index 00000000..7b27a36d --- /dev/null +++ b/unit_tests/preprocessor/output/comment-before-preprocessor-directive @@ -0,0 +1,10 @@ +// This shouldn't care that there's a multiline comment before a preprocessor +// directive. It should translate to whitespace, thrown away, making the +// "#if 1" the first thing on the line, and thus valid. +// Note that this isn't legal in C/C++ preprocessing, but Microsoft's fxc.exe +// allows this quirk. +/* comment! */ #if 1 +RIGHT +#else +WRONG +#endif \ No newline at end of file diff --git a/unit_tests/preprocessor/output/comment-before-preprocessor-directive.correct b/unit_tests/preprocessor/output/comment-before-preprocessor-directive.correct new file mode 100644 index 00000000..459b9a37 --- /dev/null +++ b/unit_tests/preprocessor/output/comment-before-preprocessor-directive.correct @@ -0,0 +1 @@ +RIGHT \ No newline at end of file diff --git a/unit_tests/preprocessor/output/multiline-comment-no-whitespace b/unit_tests/preprocessor/output/multiline-comment-no-whitespace new file mode 100644 index 00000000..f252e028 --- /dev/null +++ b/unit_tests/preprocessor/output/multiline-comment-no-whitespace @@ -0,0 +1 @@ +/*comment*/RIGHT/*comment*/ \ No newline at end of file diff --git a/unit_tests/preprocessor/output/multiline-comment-no-whitespace.correct b/unit_tests/preprocessor/output/multiline-comment-no-whitespace.correct new file mode 100644 index 00000000..459b9a37 --- /dev/null +++ b/unit_tests/preprocessor/output/multiline-comment-no-whitespace.correct @@ -0,0 +1 @@ +RIGHT \ No newline at end of file diff --git a/unit_tests/preprocessor/output/multiline-comments-alone-on-line b/unit_tests/preprocessor/output/multiline-comments-alone-on-line new file mode 100644 index 00000000..d989a5c1 --- /dev/null +++ b/unit_tests/preprocessor/output/multiline-comments-alone-on-line @@ -0,0 +1,3 @@ +/*comment*/ +/*comment*/ +RIGHT diff --git a/unit_tests/preprocessor/output/multiline-comments-alone-on-line.correct b/unit_tests/preprocessor/output/multiline-comments-alone-on-line.correct new file mode 100644 index 00000000..459b9a37 --- /dev/null +++ b/unit_tests/preprocessor/output/multiline-comments-alone-on-line.correct @@ -0,0 +1 @@ +RIGHT \ No newline at end of file