scripts: test.py/bench.py: Added ifndef attribute for tests/benches

As you might expect, this is the inverse of ifdef, and is useful for
supporting opt-out flags.

I don't think ifdef + ifndef is powerful enough to handle _all_
compile-time corner cases, but they at least provide convenient handling
for the most common flags. Worst case, tests/benches can always include
explicit #if/#ifdef/#ifndef statements in the code itself.
This commit is contained in:
Christopher Haster
2025-06-24 13:23:43 -05:00
parent db1f941e90
commit 213dba6f6d
2 changed files with 64 additions and 12 deletions

View File

@ -88,6 +88,9 @@ class TestCase:
self.ifdef = config.pop('ifdef', [])
if not isinstance(self.ifdef, list):
self.ifdef = [self.ifdef]
self.ifndef = config.pop('ifndef', [])
if not isinstance(self.ifndef, list):
self.ifndef = [self.ifndef]
self.code = config.pop('code')
self.code_lineno = config.pop('code_lineno', None)
self.in_ = config.pop('in',
@ -230,6 +233,9 @@ class TestSuite:
self.ifdef = config.pop('ifdef', [])
if not isinstance(self.ifdef, list):
self.ifdef = [self.ifdef]
self.ifndef = config.pop('ifndef', [])
if not isinstance(self.ifndef, list):
self.ifndef = [self.ifndef]
self.code = config.pop('code', None)
self.code_lineno = min(
@ -397,9 +403,11 @@ def compile(test_paths, **args):
# the test defines
def write_case_functions(f, suite, case):
# write any ifdef prologues
if case.ifdef:
if case.ifdef or case.ifndef:
for ifdef in case.ifdef:
f.writeln('#ifdef %s' % ifdef)
for ifndef in case.ifndef:
f.writeln('#ifndef %s' % ifndef)
f.writeln()
# create case define functions
@ -458,16 +466,20 @@ def compile(test_paths, **args):
f.writeln()
# write any ifdef epilogues
if case.ifdef:
if case.ifdef or case.ifndef:
for ifdef in case.ifdef:
f.writeln('#endif')
for ifndef in case.ifndef:
f.writeln('#endif')
f.writeln()
if not args.get('source'):
# write any ifdef prologues
if suite.ifdef:
if suite.ifdef or suite.ifndef:
for ifdef in suite.ifdef:
f.writeln('#ifdef %s' % ifdef)
for ifndef in suite.ifndef:
f.writeln('#ifndef %s' % ifndef)
f.writeln()
# write any suite defines
@ -508,9 +520,11 @@ def compile(test_paths, **args):
f.writeln()
# write any ifdef epilogues
if suite.ifdef:
if suite.ifdef or suite.ifndef:
for ifdef in suite.ifdef:
f.writeln('#endif')
for ifndef in suite.ifndef:
f.writeln('#endif')
f.writeln()
# create suite struct
@ -526,6 +540,8 @@ def compile(test_paths, **args):
or 0))
for ifdef in suite.ifdef:
f.writeln(4*' '+'#ifdef %s' % ifdef)
for ifndef in suite.ifndef:
f.writeln(4*' '+'#ifndef %s' % ifndef)
# create suite defines
if suite.defines:
f.writeln(4*' '+'.defines = (const test_define_t[]){')
@ -536,6 +552,8 @@ def compile(test_paths, **args):
f.writeln(4*' '+'.define_count = %d,' % len(suite.defines))
for ifdef in suite.ifdef:
f.writeln(4*' '+'#endif')
for ifndef in suite.ifndef:
f.writeln(4*' '+'#endif')
if suite.cases:
f.writeln(4*' '+'.cases = (const struct test_case[]){')
for case in suite.cases:
@ -554,6 +572,8 @@ def compile(test_paths, **args):
or 0))
for ifdef in it.chain(suite.ifdef, case.ifdef):
f.writeln(12*' '+'#ifdef %s' % ifdef)
for ifndef in it.chain(suite.ifndef, case.ifndef):
f.writeln(12*' '+'#ifndef %s' % ifndef)
# create case defines
if case.defines:
f.writeln(12*' '+'.defines'
@ -585,6 +605,8 @@ def compile(test_paths, **args):
case.name))
for ifdef in it.chain(suite.ifdef, case.ifdef):
f.writeln(12*' '+'#endif')
for ifndef in it.chain(suite.ifndef, case.ifndef):
f.writeln(12*' '+'#endif')
f.writeln(8*' '+'},')
f.writeln(4*' '+'},')
f.writeln(4*' '+'.case_count = %d,' % len(suite.cases))
@ -618,9 +640,11 @@ def compile(test_paths, **args):
# write any internal tests
for suite in suites:
# any ifdef prologues
if suite.ifdef:
if suite.ifdef or suite.ifndef:
for ifdef in suite.ifdef:
f.writeln('#ifdef %s' % ifdef)
for ifndef in suite.ifndef:
f.writeln('#ifndef %s' % ifndef)
f.writeln()
# any suite code
@ -640,9 +664,11 @@ def compile(test_paths, **args):
write_case_functions(f, suite, case)
# any ifdef epilogues
if suite.ifdef:
if suite.ifdef or suite.ifndef:
for ifdef in suite.ifdef:
f.writeln('#endif')
for ifndef in suite.ifndef:
f.writeln('#endif')
f.writeln()
# declare our test suites