Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/lib/libc_preprocessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,14 @@ addToLibrary({
var evaluated = exprTree();
stack.push(!!evaluated * stack[stack.length-1]);
break;
case 'elif':
var tokens = tokenize(expandMacros(expression, 0));
var exprTree = buildExprTree(tokens);
var evaluated = exprTree();
// If the previous #if / #elif block was executed, output NaN so that all further #elif and #else blocks will
// short to false.
stack[stack.length-1] = !!evaluated * (stack[stack.length-1] ? NaN : 1-stack[stack.length-1]);
break;
case 'ifdef': stack.push(!!defs[expression] * stack[stack.length-1]); break;
case 'ifndef': stack.push(!defs[expression] * stack[stack.length-1]); break;
case 'else': stack[stack.length-1] = (1-stack[stack.length-1]) * stack[stack.length-2]; break;
Expand Down
5 changes: 5 additions & 0 deletions test/test_c_preprocessor.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ EM_JS(void, test_c_preprocessor, (void), {

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

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
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
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
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

if (numFailed) throw numFailed + ' tests failed!';
});

Expand Down