1# Copyright 2015 The Shaderc Authors. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import expect
16from environment import Directory, File
17from glslc_test_framework import inside_glslc_testsuite
18
19
20@inside_glslc_testsuite('#line')
21class TestPoundVersion310InIncludingFile(
22    expect.ReturnCodeIsZero, expect.StdoutMatch, expect.StderrMatch):
23    """Tests that #line directives follows the behavior of version 310
24    (specifying the line number for the next line) when we find a
25    #version 310 directive in the including file."""
26
27    environment = Directory('.', [
28        File('a.vert', '#version 310 es\n#include "b.glsl"\n'),
29        File('b.glsl', 'void main() {}\n')])
30    glslc_args = ['-E', 'a.vert']
31
32    expected_stderr = ''
33    expected_stdout = \
34"""#version 310 es
35#extension GL_GOOGLE_include_directive : enable
36#line 1 "a.vert"
37
38#line 1 "b.glsl"
39void main(){ }
40#line 3 "a.vert"
41
42"""
43
44
45@inside_glslc_testsuite('#line')
46class TestPoundVersion150InIncludingFile(
47    expect.ReturnCodeIsZero, expect.StdoutMatch, expect.StderrMatch):
48    """Tests that #line directives follows the behavior of version 150
49    (specifying the line number for itself) when we find a #version 150
50    directive in the including file."""
51
52    environment = Directory('.', [
53        File('a.vert', '#version 150\n#include "b.glsl"\n'),
54        File('b.glsl', 'void main() {}\n')])
55    glslc_args = ['-E', 'a.vert']
56
57    expected_stderr = ''
58    expected_stdout = \
59"""#version 150
60#extension GL_GOOGLE_include_directive : enable
61#line 0 "a.vert"
62
63#line 0 "b.glsl"
64void main(){ }
65#line 2 "a.vert"
66
67"""
68
69
70@inside_glslc_testsuite('#line')
71class TestPoundVersionSyntaxErrorInIncludingFile(expect.ErrorMessageSubstr):
72    """Tests that error message for #version directive has the correct
73    filename and line number."""
74
75    environment = Directory('.', [
76        File('a.vert', '#version abc def\n#include "b.glsl"\n'),
77        File('b.glsl', 'void main() {}\n')])
78    glslc_args = ['-E', 'a.vert']
79
80    expected_error_substr = [
81        "a.vert:1: error: '#version' : must occur first in shader\n",
82        "a.vert:1: error: '#version' : must be followed by version number\n",
83        "a.vert:1: error: '#version' : bad profile name; use es, core, or "
84        "compatibility\n",
85    ]
86
87
88# TODO(antiagainst): now #version in included files results in an error.
89# Fix this after #version in included files are supported.
90@inside_glslc_testsuite('#line')
91class TestPoundVersion310InIncludedFile(expect.ErrorMessageSubstr):
92    """Tests that #line directives follows the behavior of version 310
93    (specifying the line number for the next line) when we find a
94    #version 310 directive in the included file."""
95
96    environment = Directory('.', [
97        File('a.vert', '#include "b.glsl"\nvoid main() {}'),
98        File('b.glsl', '#version 310 es\n')])
99    glslc_args = ['-E', 'a.vert']
100
101    expected_error_substr = [
102        "b.glsl:1: error: '#version' : must occur first in shader\n"
103    ]
104
105
106# TODO(antiagainst): now #version in included files results in an error.
107# Fix this after #version in included files are supported.
108@inside_glslc_testsuite('#line')
109class TestPoundVersion150InIncludedFile(expect.ErrorMessageSubstr):
110    """Tests that #line directives follows the behavior of version 150
111    (specifying the line number for itself) when we find a #version 150
112    directive in the included file."""
113
114    environment = Directory('.', [
115        File('a.vert', '#include "b.glsl"\nvoid main() {}'),
116        File('b.glsl', '#version 150\n')])
117    glslc_args = ['-E', 'a.vert']
118
119    expected_error_substr = [
120        "b.glsl:1: error: '#version' : must occur first in shader\n"
121    ]
122
123
124@inside_glslc_testsuite('#line')
125class TestSpaceAroundPoundVersion310InIncludingFile(
126    expect.ReturnCodeIsZero, expect.StdoutMatch, expect.StderrMatch):
127    """Tests that spaces around #version & #include directive doesn't matter."""
128
129    environment = Directory('.', [
130        File('a.vert', '\t #  \t version   310 \t  es\n#\tinclude  "b.glsl"\n'),
131        File('b.glsl', 'void main() {}\n')])
132    glslc_args = ['-E', 'a.vert']
133
134    expected_stderr = ''
135    expected_stdout = \
136"""#version 310 es
137#extension GL_GOOGLE_include_directive : enable
138#line 1 "a.vert"
139
140#line 1 "b.glsl"
141void main(){ }
142#line 3 "a.vert"
143
144"""
145
146
147@inside_glslc_testsuite('#line')
148class TestSpaceAroundPoundVersion150InIncludingFile(
149    expect.ReturnCodeIsZero, expect.StdoutMatch, expect.StderrMatch):
150    """Tests that spaces around #version & #include directive doesn't matter."""
151
152    environment = Directory('.', [
153        File('a.vert', '  \t #\t\tversion\t   150\t \n# include \t "b.glsl"\n'),
154        File('b.glsl', 'void main() {}\n')])
155    glslc_args = ['-E', 'a.vert']
156
157    expected_stderr = ''
158    expected_stdout = \
159"""#version 150
160#extension GL_GOOGLE_include_directive : enable
161#line 0 "a.vert"
162
163#line 0 "b.glsl"
164void main(){ }
165#line 2 "a.vert"
166
167"""
168
169
170@inside_glslc_testsuite('#line')
171class TestPoundLineWithForcedVersion310(
172    expect.ReturnCodeIsZero, expect.StdoutMatch, expect.StderrMatch):
173    """Tests that #line directives follows the behavior for the version
174    specified via command-line."""
175
176    environment = Directory('.', [
177        File('a.vert', '#include "b.glsl"\n'),
178        File('b.glsl', 'void main() {}\n')])
179    glslc_args = ['-E', '-std=310es', 'a.vert']
180
181    expected_stderr = ''
182    expected_stdout = \
183"""#extension GL_GOOGLE_include_directive : enable
184#line 1 "a.vert"
185#line 1 "b.glsl"
186void main(){ }
187#line 2 "a.vert"
188
189"""
190
191
192@inside_glslc_testsuite('#line')
193class TestPoundLineWithForcedVersion150(
194    expect.ReturnCodeIsZero, expect.StdoutMatch, expect.StderrMatch):
195    """Tests that #line directives follows the behavior for the version
196    specified via command-line."""
197
198    environment = Directory('.', [
199        File('a.vert', '#include "b.glsl"\n'),
200        File('b.glsl', 'void main() {}\n')])
201    glslc_args = ['-E', '-std=150', 'a.vert']
202
203    expected_stderr = ''
204    expected_stdout = \
205"""#extension GL_GOOGLE_include_directive : enable
206#line 0 "a.vert"
207#line 0 "b.glsl"
208void main(){ }
209#line 1 "a.vert"
210
211"""
212
213
214@inside_glslc_testsuite('#line')
215class TestPoundLineWithForcedDifferentVersion(
216    expect.ReturnCodeIsZero, expect.StdoutMatch, expect.StderrMatch):
217    """Tests that #line directives follows the behavior for the version
218    specified via command-line, even if there is a version specification
219    in the source code."""
220
221    environment = Directory('.', [
222        File('a.vert', '#version 150\n#include "b.glsl"\n'),
223        File('b.glsl', 'void main() {}\n')])
224    glslc_args = ['-E', '-std=310es', 'a.vert']
225
226    expected_stderr = ''
227    expected_stdout = \
228"""#version 150
229#extension GL_GOOGLE_include_directive : enable
230#line 1 "a.vert"
231
232#line 1 "b.glsl"
233void main(){ }
234#line 3 "a.vert"
235
236"""
237
238
239@inside_glslc_testsuite('#line')
240class TestErrorsFromMultipleFiles(expect.ErrorMessage):
241    """Tests that errors from different files have the correct error message
242    filename specification."""
243    including_file = '''#version 310 es
244#include "error.glsl"
245int no_return() {}
246#include "main.glsl"
247'''
248
249    environment = Directory('.', [
250        File('a.vert', including_file),
251        File('error.glsl', 'int unknown_identifier(int) { return a; }'),
252        File('main.glsl', 'void main() {\n  int b = 1.5;\n}')])
253    glslc_args = ['-c', 'a.vert']
254
255    expected_error = [
256        "error.glsl:1: error: 'a' : undeclared identifier\n",
257        "error.glsl:1: error: 'return' : type does not match, or is not "
258        "convertible to, the function's return type\n",
259        "a.vert:3: error: '' : function does not return a value: no_return\n",
260        "main.glsl:2: error: '=' :  cannot convert from ' const float' to "
261        "' temp highp int'\n",
262        "4 errors generated.\n"]
263
264
265@inside_glslc_testsuite('#line')
266class TestExplicitPoundLineWithPoundInclude(
267    expect.ReturnCodeIsZero, expect.StdoutMatch, expect.StderrMatch):
268    """Tests that #line works correctly in the presence of #include (which
269    itself will generate some #line directives."""
270    including_file = '''#version 310 es
271#line 10000 "injected.glsl"
272int plus1(int a) { return a + 1; }
273#include "inc.glsl"
274int plus2(int a) { return a + 2; }
275#line 55555
276#include "main.glsl"
277'''
278
279    environment = Directory('.', [
280        File('a.vert', including_file),
281        File('inc.glsl', 'int inc(int a) { return a + 1; }'),
282        File('main.glsl', 'void main() {\n  gl_Position = vec4(1.);\n}')])
283    glslc_args = ['-E', 'a.vert']
284
285    expected_stderr = ''
286    expected_stdout = '''#version 310 es
287#extension GL_GOOGLE_include_directive : enable
288#line 1 "a.vert"
289
290#line 10000 "injected.glsl"
291int plus1(int a){ return a + 1;}
292#line 1 "inc.glsl"
293 int inc(int a){ return a + 1;}
294#line 10002 "injected.glsl"
295 int plus2(int a){ return a + 2;}
296#line 55555
297#line 1 "main.glsl"
298 void main(){
299  gl_Position = vec4(1.);
300}
301#line 55556 "injected.glsl"
302
303'''
304