Skip to content

Commit dc6f22f

Browse files
authored
Implement missing #elif support to the preprocess_c_code() function. (#26054)
Support for `#elif` was documented in a comment to `preprocess_c_code()`, but looks like it was forgotten to actually implement. Add an implementation for it.
1 parent 7a5d93b commit dc6f22f

File tree

2 files changed

+13
-0
lines changed

2 files changed

+13
-0
lines changed

src/lib/libc_preprocessor.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,14 @@ addToLibrary({
255255
var evaluated = exprTree();
256256
stack.push(!!evaluated * stack[stack.length-1]);
257257
break;
258+
case 'elif':
259+
var tokens = tokenize(expandMacros(expression, 0));
260+
var exprTree = buildExprTree(tokens);
261+
var evaluated = exprTree();
262+
// If the previous #if / #elif block was executed, output NaN so that all further #elif and #else blocks will
263+
// short to false.
264+
stack[stack.length-1] = !!evaluated * (stack[stack.length-1] ? NaN : 1-stack[stack.length-1]);
265+
break;
258266
case 'ifdef': stack.push(!!defs[expression] * stack[stack.length-1]); break;
259267
case 'ifndef': stack.push(!defs[expression] * stack[stack.length-1]); break;
260268
case 'else': stack[stack.length-1] = (1-stack[stack.length-1]) * stack[stack.length-2]; break;

test/test_c_preprocessor.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ EM_JS(void, test_c_preprocessor, (void), {
191191

192192
test('#line 162 "foo.glsl"\n', '#line 162 "foo.glsl"\n'); // Test that #line directives are retained in the output
193193

194+
test('#define FOO 1\n#ifdef FOO\nA\n#elif defined(BAR)\nB\n#elif defined(BAZ)\nC\n#else\nD\n#endif', "A\n"); // Test #elif support, taking #ifdef path
195+
test('#define BAR 1\n#ifdef FOO\nA\n#elif defined(BAR)\nB\n#elif defined(BAZ)\nC\n#else\nD\n#endif', "B\n"); // Test #elif support, taking first #elif path
196+
test('#define BAZ 1\n#ifdef FOO\nA\n#elif defined(BAR)\nB\n#elif defined(BAZ)\nC\n#else\nD\n#endif', "C\n"); // Test #elif support, taking a second #elif path
197+
test( '#ifdef FOO\nA\n#elif defined(BAR)\nB\n#elif defined(BAZ)\nC\n#else\nD\n#endif', "D\n"); // Test #elif support, taking the final #else path
198+
194199
if (numFailed) throw numFailed + ' tests failed!';
195200
});
196201

0 commit comments

Comments
 (0)