From d3f85891a7fee149ef64c4cfea956164e6e943cb Mon Sep 17 00:00:00 2001
From: John Kessenich <cepheus@frii.com>
Date: Tue, 25 Jun 2013 21:09:47 +0000
Subject: [PATCH] Support line-continuation (backslash before newline) for
 tokens and one-line comments in the preprocessor.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22168 e7fa87d3-cd2b-0410-9028-fcbf551c1848
---
 Test/comment.frag                             |  2 +-
 Test/lineContinuation.vert                    | 14 ++++++++
 Test/testlist                                 |  1 +
 .../MachineIndependent/preprocessor/scanner.c | 35 ++++++++++++++-----
 4 files changed, 43 insertions(+), 9 deletions(-)
 create mode 100644 Test/lineContinuation.vert

diff --git a/Test/comment.frag b/Test/comment.frag
index 56da9fe58..f5c565c22 100644
--- a/Test/comment.frag
+++ b/Test/comment.frag
@@ -13,7 +13,7 @@ still in a comment
 
 // a different comment
 #version 430 core
-varying vec4 v;
+in vec4 v;
 void main() {}
 
 
diff --git a/Test/lineContinuation.vert b/Test/lineContinuation.vert
new file mode 100644
index 000000000..c6222ef02
--- /dev/null
+++ b/Test/lineContinuation.vert
@@ -0,0 +1,14 @@
+#version 300 es
+
+// this file cont\
+ains no errors
+
+float f\
+oo;  // same as 'float foo;'
+
+#define MAIN void main() \
+{                        \
+gl_Position = vec4(foo); \
+} 
+
+MAIN
diff --git a/Test/testlist b/Test/testlist
index f2df38d92..6e4e0a64d 100644
--- a/Test/testlist
+++ b/Test/testlist
@@ -42,3 +42,4 @@ tokenLength.vert
 400.frag
 420.vert
 430scope.vert
+lineContinuation.vert
diff --git a/glslang/MachineIndependent/preprocessor/scanner.c b/glslang/MachineIndependent/preprocessor/scanner.c
index 039742a60..06cba8d01 100644
--- a/glslang/MachineIndependent/preprocessor/scanner.c
+++ b/glslang/MachineIndependent/preprocessor/scanner.c
@@ -382,7 +382,18 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
         case 'u': case 'v': case 'w': case 'x': case 'y':
         case 'z':            
             do {
-                if (len < MAX_SYMBOL_NAME_LEN) {
+                if (ch == '\\') {
+                    // escaped character
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                    if (ch == '\r' || ch == '\n') {
+                        int nextch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                        if (ch == '\r' && nextch == '\n')
+                            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                        else
+                            ch = nextch;
+                    } else
+                        ShPpErrorToInfoLog("can only escape newlines");
+                } else if (len < MAX_SYMBOL_NAME_LEN) {
                     symbol_name[len] = ch;
                     len++;
                     ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);					
@@ -393,7 +404,8 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
             } while ((ch >= 'a' && ch <= 'z') ||
                      (ch >= 'A' && ch <= 'Z') ||
                      (ch >= '0' && ch <= '9') ||
-                     ch == '_');
+                     ch == '_' ||
+                     ch == '\\');
             if (len > MAX_SYMBOL_NAME_LEN)
                 len = MAX_SYMBOL_NAME_LEN;
             symbol_name[len] = '\0';
@@ -664,18 +676,25 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
                 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
                 return lFloatConst(yylvalpp->symbol_name, 0, '.', yylvalpp);
             } else {
-                if (ch == '.') {
-                    return -1; // Special EOF hack
-                } else {
-                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
-                    return '.';
-                }
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '.';
             }
         case '/':
             ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
             if (ch == '/') {
                 do {
                     ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                    if (ch == '\\') {
+                        // allow an escaped newline, otherwise escapes in comments are meaningless
+                        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                        if (ch == '\r' || ch == '\n') {
+                            int nextch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                            if (ch == '\r' && nextch == '\n')
+                                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                            else
+                                ch = nextch;
+                        }
+                    }
                 } while (ch != '\n' && ch != EOF);
                 if (ch == EOF)
                     return -1;
-- 
GitLab