mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 06:08:35 +00:00
594 lines
21 KiB
Python
Executable File
594 lines
21 KiB
Python
Executable File
#!/usr/bin/env python
|
|
'''Usage: %s [OPTIONS] <input file(s)>
|
|
Generate test source file for CxxTest.
|
|
|
|
-v, --version Write CxxTest version
|
|
-o, --output=NAME Write output to file NAME
|
|
--runner=CLASS Create a main() function that runs CxxTest::CLASS
|
|
--gui=CLASS Like --runner, with GUI component
|
|
--error-printer Same as --runner=ErrorPrinter
|
|
--abort-on-fail Abort tests on failed asserts (like xUnit)
|
|
--have-std Use standard library (even if not found in tests)
|
|
--no-std Don\'t use standard library (even if found in tests)
|
|
--have-eh Use exception handling (even if not found in tests)
|
|
--no-eh Don\'t use exception handling (even if found in tests)
|
|
--longlong=[TYPE] Use TYPE (default: long long) as long long
|
|
--template=TEMPLATE Use TEMPLATE file to generate the test runner
|
|
--include=HEADER Include HEADER in test runner before other headers
|
|
--root Write CxxTest globals
|
|
--part Don\'t write CxxTest globals
|
|
--no-static-init Don\'t rely on static initialization
|
|
'''
|
|
|
|
import re
|
|
import sys
|
|
import getopt
|
|
import glob
|
|
import string
|
|
|
|
# Global variables
|
|
suites = []
|
|
suite = None
|
|
inBlock = 0
|
|
|
|
outputFileName = None
|
|
runner = None
|
|
gui = None
|
|
root = None
|
|
part = None
|
|
noStaticInit = None
|
|
templateFileName = None
|
|
headers = []
|
|
|
|
haveExceptionHandling = 0
|
|
noExceptionHandling = 0
|
|
haveStandardLibrary = 0
|
|
noStandardLibrary = 0
|
|
abortOnFail = 0
|
|
factor = 0
|
|
longlong = 0
|
|
|
|
def main():
|
|
'''The main program'''
|
|
files = parseCommandline()
|
|
scanInputFiles( files )
|
|
writeOutput()
|
|
|
|
def usage( problem = None ):
|
|
'''Print usage info and exit'''
|
|
if problem is None:
|
|
print( usageString() )
|
|
sys.exit(0)
|
|
else:
|
|
sys.stderr.write( usageString() )
|
|
abort( problem )
|
|
|
|
def usageString():
|
|
'''Construct program usage string'''
|
|
return __doc__ % sys.argv[0]
|
|
|
|
def abort( problem ):
|
|
'''Print error message and exit'''
|
|
sys.stderr.write( '\n' )
|
|
sys.stderr.write( problem )
|
|
sys.stderr.write( '\n\n' )
|
|
sys.exit(2)
|
|
|
|
def parseCommandline():
|
|
'''Analyze command line arguments'''
|
|
try:
|
|
options, patterns = getopt.getopt( sys.argv[1:], 'o:r:',
|
|
['version', 'output=', 'runner=', 'gui=',
|
|
'error-printer', 'abort-on-fail', 'have-std', 'no-std',
|
|
'have-eh', 'no-eh', 'template=', 'include=',
|
|
'root', 'part', 'no-static-init', 'factor', 'longlong='] )
|
|
except getopt.error as problem:
|
|
usage( problem )
|
|
setOptions( options )
|
|
return setFiles( patterns )
|
|
|
|
def setOptions( options ):
|
|
'''Set options specified on command line'''
|
|
global outputFileName, templateFileName, runner, gui, haveStandardLibrary, factor, longlong
|
|
global haveExceptionHandling, noExceptionHandling, abortOnFail, headers, root, part, noStaticInit
|
|
for o, a in options:
|
|
if o in ('-v', '--version'):
|
|
printVersion()
|
|
elif o in ('-o', '--output'):
|
|
outputFileName = a
|
|
elif o == '--template':
|
|
templateFileName = a
|
|
elif o == '--runner':
|
|
runner = a
|
|
elif o == '--gui':
|
|
gui = a
|
|
elif o == '--include':
|
|
if not re.match( r'^["<].*[>"]$', a ):
|
|
a = ('"%s"' % a)
|
|
headers.append( a )
|
|
elif o == '--error-printer':
|
|
runner = 'ErrorPrinter'
|
|
haveStandardLibrary = 1
|
|
elif o == '--abort-on-fail':
|
|
abortOnFail = 1
|
|
elif o == '--have-std':
|
|
haveStandardLibrary = 1
|
|
elif o == '--no-std':
|
|
noStandardLibrary = 1
|
|
elif o == '--have-eh':
|
|
haveExceptionHandling = 1
|
|
elif o == '--no-eh':
|
|
noExceptionHandling = 1
|
|
elif o == '--root':
|
|
root = 1
|
|
elif o == '--part':
|
|
part = 1
|
|
elif o == '--no-static-init':
|
|
noStaticInit = 1
|
|
elif o == '--factor':
|
|
factor = 1
|
|
elif o == '--longlong':
|
|
if a:
|
|
longlong = a
|
|
else:
|
|
longlong = 'long long'
|
|
|
|
if noStaticInit and (root or part):
|
|
abort( '--no-static-init cannot be used with --root/--part' )
|
|
|
|
if gui and not runner:
|
|
runner = 'StdioPrinter'
|
|
|
|
def printVersion():
|
|
'''Print CxxTest version and exit'''
|
|
sys.stdout.write( "This is CxxTest version 3.10.1.\n" )
|
|
sys.exit(0)
|
|
|
|
def setFiles( patterns ):
|
|
'''Set input files specified on command line'''
|
|
files = expandWildcards( patterns )
|
|
if len(files) == 0 and not root:
|
|
usage( "No input files found" )
|
|
return files
|
|
|
|
def expandWildcards( patterns ):
|
|
'''Expand all wildcards in an array (glob)'''
|
|
fileNames = []
|
|
for pathName in patterns:
|
|
patternFiles = glob.glob( pathName )
|
|
for fileName in patternFiles:
|
|
fileNames.append( fixBackslashes( fileName ) )
|
|
return fileNames
|
|
|
|
def fixBackslashes( fileName ):
|
|
'''Convert backslashes to slashes in file name'''
|
|
return re.sub( r'\\', '/', fileName, 0 )
|
|
|
|
def scanInputFiles(files):
|
|
'''Scan all input files for test suites'''
|
|
for file in files:
|
|
scanInputFile(file)
|
|
global suites
|
|
if len(suites) == 0 and not root:
|
|
abort( 'No tests defined' )
|
|
|
|
def scanInputFile(fileName):
|
|
'''Scan single input file for test suites'''
|
|
file = open(fileName)
|
|
lineNo = 0
|
|
while 1:
|
|
line = file.readline()
|
|
if not line:
|
|
break
|
|
lineNo = lineNo + 1
|
|
|
|
scanInputLine( fileName, lineNo, line )
|
|
closeSuite()
|
|
file.close()
|
|
|
|
def scanInputLine( fileName, lineNo, line ):
|
|
'''Scan single input line for interesting stuff'''
|
|
scanLineForExceptionHandling( line )
|
|
scanLineForStandardLibrary( line )
|
|
|
|
scanLineForSuiteStart( fileName, lineNo, line )
|
|
|
|
global suite
|
|
if suite:
|
|
scanLineInsideSuite( suite, lineNo, line )
|
|
|
|
def scanLineInsideSuite( suite, lineNo, line ):
|
|
'''Analyze line which is part of a suite'''
|
|
global inBlock
|
|
if lineBelongsToSuite( suite, lineNo, line ):
|
|
scanLineForTest( suite, lineNo, line )
|
|
scanLineForCreate( suite, lineNo, line )
|
|
scanLineForDestroy( suite, lineNo, line )
|
|
|
|
def lineBelongsToSuite( suite, lineNo, line ):
|
|
'''Returns whether current line is part of the current suite.
|
|
This can be false when we are in a generated suite outside of CXXTEST_CODE() blocks
|
|
If the suite is generated, adds the line to the list of lines'''
|
|
if not suite['generated']:
|
|
return 1
|
|
|
|
global inBlock
|
|
if not inBlock:
|
|
inBlock = lineStartsBlock( line )
|
|
if inBlock:
|
|
inBlock = addLineToBlock( suite, lineNo, line )
|
|
return inBlock
|
|
|
|
|
|
std_re = re.compile( r"\b(std\s*::|CXXTEST_STD|using\s+namespace\s+std\b|^\s*\#\s*include\s+<[a-z0-9]+>)" )
|
|
def scanLineForStandardLibrary( line ):
|
|
'''Check if current line uses standard library'''
|
|
global haveStandardLibrary, noStandardLibrary
|
|
if not haveStandardLibrary and std_re.search(line):
|
|
if not noStandardLibrary:
|
|
haveStandardLibrary = 1
|
|
|
|
exception_re = re.compile( r"\b(throw|try|catch|TSM?_ASSERT_THROWS[A-Z_]*)\b" )
|
|
def scanLineForExceptionHandling( line ):
|
|
'''Check if current line uses exception handling'''
|
|
global haveExceptionHandling, noExceptionHandling
|
|
if not haveExceptionHandling and exception_re.search(line):
|
|
if not noExceptionHandling:
|
|
haveExceptionHandling = 1
|
|
|
|
suite_re = re.compile( r'\bclass\s+(\w+)\s*:\s*public\s+((::)?\s*CxxTest\s*::\s*)?TestSuite\b' )
|
|
generatedSuite_re = re.compile( r'\bCXXTEST_SUITE\s*\(\s*(\w*)\s*\)' )
|
|
def scanLineForSuiteStart( fileName, lineNo, line ):
|
|
'''Check if current line starts a new test suite'''
|
|
m = suite_re.search( line )
|
|
if m:
|
|
startSuite( m.group(1), fileName, lineNo, 0 )
|
|
m = generatedSuite_re.search( line )
|
|
if m:
|
|
sys.stdout.write( "%s:%s: Warning: Inline test suites are deprecated.\n" % (fileName, lineNo) )
|
|
startSuite( m.group(1), fileName, lineNo, 1 )
|
|
|
|
def startSuite( name, file, line, generated ):
|
|
'''Start scanning a new suite'''
|
|
global suite
|
|
closeSuite()
|
|
suite = { 'name' : name,
|
|
'file' : file,
|
|
'cfile' : cstr(file),
|
|
'line' : line,
|
|
'generated' : generated,
|
|
'object' : 'suite_%s' % name,
|
|
'dobject' : 'suiteDescription_%s' % name,
|
|
'tlist' : 'Tests_%s' % name,
|
|
'tests' : [],
|
|
'lines' : [] }
|
|
|
|
def lineStartsBlock( line ):
|
|
'''Check if current line starts a new CXXTEST_CODE() block'''
|
|
return re.search( r'\bCXXTEST_CODE\s*\(', line ) is not None
|
|
|
|
test_re = re.compile( r'^([^/]|/[^/])*\bvoid\s+([Tt]est\w+)\s*\(\s*(void)?\s*\)' )
|
|
def scanLineForTest( suite, lineNo, line ):
|
|
'''Check if current line starts a test'''
|
|
m = test_re.search( line )
|
|
if m:
|
|
addTest( suite, m.group(2), lineNo )
|
|
|
|
def addTest( suite, name, line ):
|
|
'''Add a test function to the current suite'''
|
|
test = { 'name' : name,
|
|
'suite' : suite,
|
|
'class' : 'TestDescription_%s_%s' % (suite['name'], name),
|
|
'object' : 'testDescription_%s_%s' % (suite['name'], name),
|
|
'line' : line,
|
|
}
|
|
suite['tests'].append( test )
|
|
|
|
def addLineToBlock( suite, lineNo, line ):
|
|
'''Append the line to the current CXXTEST_CODE() block'''
|
|
line = fixBlockLine( suite, lineNo, line )
|
|
line = re.sub( r'^.*\{\{', '', line )
|
|
|
|
e = re.search( r'\}\}', line )
|
|
if e:
|
|
line = line[:e.start()]
|
|
suite['lines'].append( line )
|
|
return e is None
|
|
|
|
def fixBlockLine( suite, lineNo, line):
|
|
'''Change all [E]TS_ macros used in a line to _[E]TS_ macros with the correct file/line'''
|
|
return re.sub( r'\b(E?TSM?_(ASSERT[A-Z_]*|FAIL))\s*\(',
|
|
r'_\1(%s,%s,' % (suite['cfile'], lineNo),
|
|
line, 0 )
|
|
|
|
create_re = re.compile( r'\bstatic\s+\w+\s*\*\s*createSuite\s*\(\s*(void)?\s*\)' )
|
|
def scanLineForCreate( suite, lineNo, line ):
|
|
'''Check if current line defines a createSuite() function'''
|
|
if create_re.search( line ):
|
|
addSuiteCreateDestroy( suite, 'create', lineNo )
|
|
|
|
destroy_re = re.compile( r'\bstatic\s+void\s+destroySuite\s*\(\s*\w+\s*\*\s*\w*\s*\)' )
|
|
def scanLineForDestroy( suite, lineNo, line ):
|
|
'''Check if current line defines a destroySuite() function'''
|
|
if destroy_re.search( line ):
|
|
addSuiteCreateDestroy( suite, 'destroy', lineNo )
|
|
|
|
def cstr( str ):
|
|
'''Convert a string to its C representation'''
|
|
return '"' + str.replace( '\\', '\\\\' ) + '"'
|
|
|
|
|
|
def addSuiteCreateDestroy( suite, which, line ):
|
|
'''Add createSuite()/destroySuite() to current suite'''
|
|
if suite.has_key(which):
|
|
abort( '%s:%s: %sSuite() already declared' % ( suite['file'], str(line), which ) )
|
|
suite[which] = line
|
|
|
|
def closeSuite():
|
|
'''Close current suite and add it to the list if valid'''
|
|
global suite
|
|
if suite is not None:
|
|
if len(suite['tests']) != 0:
|
|
verifySuite(suite)
|
|
rememberSuite(suite)
|
|
suite = None
|
|
|
|
def verifySuite(suite):
|
|
'''Verify current suite is legal'''
|
|
if 'create' in suite and not 'destroy' in suite:
|
|
abort( '%s:%s: Suite %s has createSuite() but no destroySuite()' %
|
|
(suite['file'], suite['create'], suite['name']) )
|
|
if 'destroy' in suite and not 'create' in suite:
|
|
abort( '%s:%s: Suite %s has destroySuite() but no createSuite()' %
|
|
(suite['file'], suite['destroy'], suite['name']) )
|
|
|
|
def rememberSuite(suite):
|
|
'''Add current suite to list'''
|
|
global suites
|
|
suites.append( suite )
|
|
|
|
def writeOutput():
|
|
'''Create output file'''
|
|
if templateFileName:
|
|
writeTemplateOutput()
|
|
else:
|
|
writeSimpleOutput()
|
|
|
|
def writeSimpleOutput():
|
|
'''Create output not based on template'''
|
|
output = startOutputFile()
|
|
writePreamble( output )
|
|
writeMain( output )
|
|
writeWorld( output )
|
|
output.close()
|
|
|
|
include_re = re.compile( r"\s*\#\s*include\s+<cxxtest/" )
|
|
preamble_re = re.compile( r"^\s*<CxxTest\s+preamble>\s*$" )
|
|
world_re = re.compile( r"^\s*<CxxTest\s+world>\s*$" )
|
|
def writeTemplateOutput():
|
|
'''Create output based on template file'''
|
|
template = open(templateFileName)
|
|
output = startOutputFile()
|
|
while 1:
|
|
line = template.readline()
|
|
if not line:
|
|
break;
|
|
if include_re.search( line ):
|
|
writePreamble( output )
|
|
output.write( line )
|
|
elif preamble_re.search( line ):
|
|
writePreamble( output )
|
|
elif world_re.search( line ):
|
|
writeWorld( output )
|
|
else:
|
|
output.write( line )
|
|
template.close()
|
|
output.close()
|
|
|
|
def startOutputFile():
|
|
'''Create output file and write header'''
|
|
if outputFileName is not None:
|
|
output = open( outputFileName, 'w' )
|
|
else:
|
|
output = sys.stdout
|
|
output.write( "/* Generated file, do not edit */\n\n" )
|
|
return output
|
|
|
|
wrotePreamble = 0
|
|
def writePreamble( output ):
|
|
'''Write the CxxTest header (#includes and #defines)'''
|
|
global wrotePreamble, headers, longlong
|
|
if wrotePreamble: return
|
|
output.write( "#ifndef CXXTEST_RUNNING\n" )
|
|
output.write( "#define CXXTEST_RUNNING\n" )
|
|
output.write( "#endif\n" )
|
|
output.write( "\n" )
|
|
if haveStandardLibrary:
|
|
output.write( "#define _CXXTEST_HAVE_STD\n" )
|
|
if haveExceptionHandling:
|
|
output.write( "#define _CXXTEST_HAVE_EH\n" )
|
|
if abortOnFail:
|
|
output.write( "#define _CXXTEST_ABORT_TEST_ON_FAIL\n" )
|
|
if longlong:
|
|
output.write( "#define _CXXTEST_LONGLONG %s\n" % longlong )
|
|
if factor:
|
|
output.write( "#define _CXXTEST_FACTOR\n" )
|
|
for header in headers:
|
|
output.write( "#include %s\n" % header )
|
|
output.write( "#include <cxxtest/TestListener.h>\n" )
|
|
output.write( "#include <cxxtest/TestTracker.h>\n" )
|
|
output.write( "#include <cxxtest/TestRunner.h>\n" )
|
|
output.write( "#include <cxxtest/RealDescriptions.h>\n" )
|
|
if runner:
|
|
output.write( "#include <cxxtest/%s.h>\n" % runner )
|
|
if gui:
|
|
output.write( "#include <cxxtest/%s.h>\n" % gui )
|
|
output.write( "\n" )
|
|
wrotePreamble = 1
|
|
|
|
def writeMain( output ):
|
|
'''Write the main() function for the test runner'''
|
|
if gui:
|
|
output.write( 'int main( int argc, char *argv[] ) {\n' )
|
|
if noStaticInit:
|
|
output.write( ' CxxTest::initialize();\n' )
|
|
output.write( ' return CxxTest::GuiTuiRunner<CxxTest::%s, CxxTest::%s>( argc, argv ).run();\n' % (gui, runner) )
|
|
output.write( '}\n' )
|
|
elif runner:
|
|
output.write( 'int main() {\n' )
|
|
if noStaticInit:
|
|
output.write( ' CxxTest::initialize();\n' )
|
|
output.write( ' return CxxTest::%s().run();\n' % runner )
|
|
output.write( '}\n' )
|
|
|
|
wroteWorld = 0
|
|
def writeWorld( output ):
|
|
'''Write the world definitions'''
|
|
global wroteWorld, part
|
|
if wroteWorld: return
|
|
writePreamble( output )
|
|
writeSuites( output )
|
|
if root or not part:
|
|
writeRoot( output )
|
|
if noStaticInit:
|
|
writeInitialize( output )
|
|
wroteWorld = 1
|
|
|
|
def writeSuites(output):
|
|
'''Write all TestDescriptions and SuiteDescriptions'''
|
|
for suite in suites:
|
|
writeInclude( output, suite['file'] )
|
|
if isGenerated(suite):
|
|
generateSuite( output, suite )
|
|
if isDynamic(suite):
|
|
writeSuitePointer( output, suite )
|
|
else:
|
|
writeSuiteObject( output, suite )
|
|
writeTestList( output, suite )
|
|
writeSuiteDescription( output, suite )
|
|
writeTestDescriptions( output, suite )
|
|
|
|
def isGenerated(suite):
|
|
'''Checks whether a suite class should be created'''
|
|
return suite['generated']
|
|
|
|
def isDynamic(suite):
|
|
'''Checks whether a suite is dynamic'''
|
|
return 'create' in suite
|
|
|
|
lastIncluded = ''
|
|
def writeInclude(output, file):
|
|
'''Add #include "file" statement'''
|
|
global lastIncluded
|
|
if file == lastIncluded: return
|
|
output.writelines( [ '#include "', file, '"\n\n' ] )
|
|
lastIncluded = file
|
|
|
|
def generateSuite( output, suite ):
|
|
'''Write a suite declared with CXXTEST_SUITE()'''
|
|
output.write( 'class %s : public CxxTest::TestSuite {\n' % suite['name'] )
|
|
output.write( 'public:\n' )
|
|
for line in suite['lines']:
|
|
output.write(line)
|
|
output.write( '};\n\n' )
|
|
|
|
def writeSuitePointer( output, suite ):
|
|
'''Create static suite pointer object for dynamic suites'''
|
|
if noStaticInit:
|
|
output.write( 'static %s *%s;\n\n' % (suite['name'], suite['object']) )
|
|
else:
|
|
output.write( 'static %s *%s = 0;\n\n' % (suite['name'], suite['object']) )
|
|
|
|
def writeSuiteObject( output, suite ):
|
|
'''Create static suite object for non-dynamic suites'''
|
|
output.writelines( [ "static ", suite['name'], " ", suite['object'], ";\n\n" ] )
|
|
|
|
def writeTestList( output, suite ):
|
|
'''Write the head of the test linked list for a suite'''
|
|
if noStaticInit:
|
|
output.write( 'static CxxTest::List %s;\n' % suite['tlist'] )
|
|
else:
|
|
output.write( 'static CxxTest::List %s = { 0, 0 };\n' % suite['tlist'] )
|
|
|
|
def writeTestDescriptions( output, suite ):
|
|
'''Write all test descriptions for a suite'''
|
|
for test in suite['tests']:
|
|
writeTestDescription( output, suite, test )
|
|
|
|
def writeTestDescription( output, suite, test ):
|
|
'''Write test description object'''
|
|
output.write( 'static class %s : public CxxTest::RealTestDescription {\n' % test['class'] )
|
|
output.write( 'public:\n' )
|
|
if not noStaticInit:
|
|
output.write( ' %s() : CxxTest::RealTestDescription( %s, %s, %s, "%s" ) {}\n' %
|
|
(test['class'], suite['tlist'], suite['dobject'], test['line'], test['name']) )
|
|
output.write( ' void runTest() { %s }\n' % runBody( suite, test ) )
|
|
output.write( '} %s;\n\n' % test['object'] )
|
|
|
|
def runBody( suite, test ):
|
|
'''Body of TestDescription::run()'''
|
|
if isDynamic(suite): return dynamicRun( suite, test )
|
|
else: return staticRun( suite, test )
|
|
|
|
def dynamicRun( suite, test ):
|
|
'''Body of TestDescription::run() for test in a dynamic suite'''
|
|
return 'if ( ' + suite['object'] + ' ) ' + suite['object'] + '->' + test['name'] + '();'
|
|
|
|
def staticRun( suite, test ):
|
|
'''Body of TestDescription::run() for test in a non-dynamic suite'''
|
|
return suite['object'] + '.' + test['name'] + '();'
|
|
|
|
def writeSuiteDescription( output, suite ):
|
|
'''Write SuiteDescription object'''
|
|
if isDynamic( suite ):
|
|
writeDynamicDescription( output, suite )
|
|
else:
|
|
writeStaticDescription( output, suite )
|
|
|
|
def writeDynamicDescription( output, suite ):
|
|
'''Write SuiteDescription for a dynamic suite'''
|
|
output.write( 'CxxTest::DynamicSuiteDescription<%s> %s' % (suite['name'], suite['dobject']) )
|
|
if not noStaticInit:
|
|
output.write( '( %s, %s, "%s", %s, %s, %s, %s )' %
|
|
(suite['cfile'], suite['line'], suite['name'], suite['tlist'],
|
|
suite['object'], suite['create'], suite['destroy']) )
|
|
output.write( ';\n\n' )
|
|
|
|
def writeStaticDescription( output, suite ):
|
|
'''Write SuiteDescription for a static suite'''
|
|
output.write( 'CxxTest::StaticSuiteDescription %s' % suite['dobject'] )
|
|
if not noStaticInit:
|
|
output.write( '( %s, %s, "%s", %s, %s )' %
|
|
(suite['cfile'], suite['line'], suite['name'], suite['object'], suite['tlist']) )
|
|
output.write( ';\n\n' )
|
|
|
|
def writeRoot(output):
|
|
'''Write static members of CxxTest classes'''
|
|
output.write( '#include <cxxtest/Root.cpp>\n' )
|
|
|
|
def writeInitialize(output):
|
|
'''Write CxxTest::initialize(), which replaces static initialization'''
|
|
output.write( 'namespace CxxTest {\n' )
|
|
output.write( ' void initialize()\n' )
|
|
output.write( ' {\n' )
|
|
for suite in suites:
|
|
output.write( ' %s.initialize();\n' % suite['tlist'] )
|
|
if isDynamic(suite):
|
|
output.write( ' %s = 0;\n' % suite['object'] )
|
|
output.write( ' %s.initialize( %s, %s, "%s", %s, %s, %s, %s );\n' %
|
|
(suite['dobject'], suite['cfile'], suite['line'], suite['name'],
|
|
suite['tlist'], suite['object'], suite['create'], suite['destroy']) )
|
|
else:
|
|
output.write( ' %s.initialize( %s, %s, "%s", %s, %s );\n' %
|
|
(suite['dobject'], suite['cfile'], suite['line'], suite['name'],
|
|
suite['object'], suite['tlist']) )
|
|
|
|
for test in suite['tests']:
|
|
output.write( ' %s.initialize( %s, %s, %s, "%s" );\n' %
|
|
(test['object'], suite['tlist'], suite['dobject'], test['line'], test['name']) )
|
|
|
|
output.write( ' }\n' )
|
|
output.write( '}\n' )
|
|
|
|
main()
|