teak-llvm/clang/utils/ABITest/ABITestGen.py
Daniel Sanders 3ecaf02be9 Fix invalid test generation by utils/ABITest/ABITestGen.py when the same enum is generated more than once.
When generating records/unions, the same enum type may be generated more
than once (with different names). In these cases, the name of the enum
values are not sufficiently unique to prevent multiple declarations. E.g:
  typedef enum T3 { enum0val0 } T3;
  typedef T3 T2[3];
  typedef enum T4 { enum0val0 } T4;
  typedef union T1 { T2 field0; T4 field1; char field2; } T1;

Added a unique suffix to enum values so that multiple identical enum types do
not use the same enum value names.

One example of this bug is produced by:
  ABITestGen.py --no-unsigned --no-vector --no-complex --no-bool \
                --max-args 0 --max-record-depth 1 -o inputs/test.9921.a.c \
                -T inputs/test.9921.b.c -D inputs/test.9921.driver.c \
                --min=9921 --count=1

llvm-svn: 216166
2014-08-21 10:13:49 +00:00

673 lines
29 KiB
Python
Executable File

#!/usr/bin/env python
from pprint import pprint
import random, atexit, time
from random import randrange
import re
from Enumeration import *
from TypeGen import *
####
class TypePrinter:
def __init__(self, output, outputHeader=None,
outputTests=None, outputDriver=None,
headerName=None, info=None):
self.output = output
self.outputHeader = outputHeader
self.outputTests = outputTests
self.outputDriver = outputDriver
self.writeBody = outputHeader or outputTests or outputDriver
self.types = {}
self.testValues = {}
self.testReturnValues = {}
self.layoutTests = []
self.declarations = set()
if info:
for f in (self.output,self.outputHeader,self.outputTests,self.outputDriver):
if f:
print >>f,info
if self.writeBody:
print >>self.output, '#include <stdio.h>\n'
if self.outputTests:
print >>self.outputTests, '#include <stdio.h>'
print >>self.outputTests, '#include <string.h>'
print >>self.outputTests, '#include <assert.h>\n'
if headerName:
for f in (self.output,self.outputTests,self.outputDriver):
if f is not None:
print >>f, '#include "%s"\n'%(headerName,)
if self.outputDriver:
print >>self.outputDriver, '#include <stdio.h>'
print >>self.outputDriver, '#include <stdlib.h>\n'
print >>self.outputDriver, 'int main(int argc, char **argv) {'
print >>self.outputDriver, ' int index = -1;'
print >>self.outputDriver, ' if (argc > 1) index = atoi(argv[1]);'
def finish(self):
if self.layoutTests:
print >>self.output, 'int main(int argc, char **argv) {'
print >>self.output, ' int index = -1;'
print >>self.output, ' if (argc > 1) index = atoi(argv[1]);'
for i,f in self.layoutTests:
print >>self.output, ' if (index == -1 || index == %d)' % i
print >>self.output, ' %s();' % f
print >>self.output, ' return 0;'
print >>self.output, '}'
if self.outputDriver:
print >>self.outputDriver, ' printf("DONE\\n");'
print >>self.outputDriver, ' return 0;'
print >>self.outputDriver, '}'
def addDeclaration(self, decl):
if decl in self.declarations:
return False
self.declarations.add(decl)
if self.outputHeader:
print >>self.outputHeader, decl
else:
print >>self.output, decl
if self.outputTests:
print >>self.outputTests, decl
return True
def getTypeName(self, T):
name = self.types.get(T)
if name is None:
# Reserve slot
self.types[T] = None
self.types[T] = name = T.getTypeName(self)
return name
def writeLayoutTest(self, i, ty):
tyName = self.getTypeName(ty)
tyNameClean = tyName.replace(' ','_').replace('*','star')
fnName = 'test_%s' % tyNameClean
print >>self.output,'void %s(void) {' % fnName
self.printSizeOfType(' %s'%fnName, tyName, ty, self.output)
self.printAlignOfType(' %s'%fnName, tyName, ty, self.output)
self.printOffsetsOfType(' %s'%fnName, tyName, ty, self.output)
print >>self.output,'}'
print >>self.output
self.layoutTests.append((i,fnName))
def writeFunction(self, i, FT):
args = ', '.join(['%s arg%d'%(self.getTypeName(t),i) for i,t in enumerate(FT.argTypes)])
if not args:
args = 'void'
if FT.returnType is None:
retvalName = None
retvalTypeName = 'void'
else:
retvalTypeName = self.getTypeName(FT.returnType)
if self.writeBody or self.outputTests:
retvalName = self.getTestReturnValue(FT.returnType)
fnName = 'fn%d'%(FT.index,)
if self.outputHeader:
print >>self.outputHeader,'%s %s(%s);'%(retvalTypeName, fnName, args)
elif self.outputTests:
print >>self.outputTests,'%s %s(%s);'%(retvalTypeName, fnName, args)
print >>self.output,'%s %s(%s)'%(retvalTypeName, fnName, args),
if self.writeBody:
print >>self.output, '{'
for i,t in enumerate(FT.argTypes):
self.printValueOfType(' %s'%fnName, 'arg%d'%i, t)
if retvalName is not None:
print >>self.output, ' return %s;'%(retvalName,)
print >>self.output, '}'
else:
print >>self.output, '{}'
print >>self.output
if self.outputDriver:
print >>self.outputDriver, ' if (index == -1 || index == %d) {' % i
print >>self.outputDriver, ' extern void test_%s(void);' % fnName
print >>self.outputDriver, ' test_%s();' % fnName
print >>self.outputDriver, ' }'
if self.outputTests:
if self.outputHeader:
print >>self.outputHeader, 'void test_%s(void);'%(fnName,)
if retvalName is None:
retvalTests = None
else:
retvalTests = self.getTestValuesArray(FT.returnType)
tests = map(self.getTestValuesArray, FT.argTypes)
print >>self.outputTests, 'void test_%s(void) {'%(fnName,)
if retvalTests is not None:
print >>self.outputTests, ' printf("%s: testing return.\\n");'%(fnName,)
print >>self.outputTests, ' for (int i=0; i<%d; ++i) {'%(retvalTests[1],)
args = ', '.join(['%s[%d]'%(t,randrange(l)) for t,l in tests])
print >>self.outputTests, ' %s RV;'%(retvalTypeName,)
print >>self.outputTests, ' %s = %s[i];'%(retvalName, retvalTests[0])
print >>self.outputTests, ' RV = %s(%s);'%(fnName, args)
self.printValueOfType(' %s_RV'%fnName, 'RV', FT.returnType, output=self.outputTests, indent=4)
self.checkTypeValues('RV', '%s[i]' % retvalTests[0], FT.returnType, output=self.outputTests, indent=4)
print >>self.outputTests, ' }'
if tests:
print >>self.outputTests, ' printf("%s: testing arguments.\\n");'%(fnName,)
for i,(array,length) in enumerate(tests):
for j in range(length):
args = ['%s[%d]'%(t,randrange(l)) for t,l in tests]
args[i] = '%s[%d]'%(array,j)
print >>self.outputTests, ' %s(%s);'%(fnName, ', '.join(args),)
print >>self.outputTests, '}'
def getTestReturnValue(self, type):
typeName = self.getTypeName(type)
info = self.testReturnValues.get(typeName)
if info is None:
name = '%s_retval'%(typeName.replace(' ','_').replace('*','star'),)
print >>self.output, '%s %s;'%(typeName,name)
if self.outputHeader:
print >>self.outputHeader, 'extern %s %s;'%(typeName,name)
elif self.outputTests:
print >>self.outputTests, 'extern %s %s;'%(typeName,name)
info = self.testReturnValues[typeName] = name
return info
def getTestValuesArray(self, type):
typeName = self.getTypeName(type)
info = self.testValues.get(typeName)
if info is None:
name = '%s_values'%(typeName.replace(' ','_').replace('*','star'),)
print >>self.outputTests, 'static %s %s[] = {'%(typeName,name)
length = 0
for item in self.getTestValues(type):
print >>self.outputTests, '\t%s,'%(item,)
length += 1
print >>self.outputTests,'};'
info = self.testValues[typeName] = (name,length)
return info
def getTestValues(self, t):
if isinstance(t, BuiltinType):
if t.name=='float':
for i in ['0.0','-1.0','1.0']:
yield i+'f'
elif t.name=='double':
for i in ['0.0','-1.0','1.0']:
yield i
elif t.name in ('void *'):
yield '(void*) 0'
yield '(void*) -1'
else:
yield '(%s) 0'%(t.name,)
yield '(%s) -1'%(t.name,)
yield '(%s) 1'%(t.name,)
elif isinstance(t, EnumType):
for i in range(0, len(t.enumerators)):
yield 'enum%dval%d_%d' % (t.index, i, t.unique_id)
elif isinstance(t, RecordType):
nonPadding = [f for f in t.fields
if not f.isPaddingBitField()]
if not nonPadding:
yield '{ }'
return
# FIXME: Use designated initializers to access non-first
# fields of unions.
if t.isUnion:
for v in self.getTestValues(nonPadding[0]):
yield '{ %s }' % v
return
fieldValues = map(list, map(self.getTestValues, nonPadding))
for i,values in enumerate(fieldValues):
for v in values:
elements = map(random.choice,fieldValues)
elements[i] = v
yield '{ %s }'%(', '.join(elements))
elif isinstance(t, ComplexType):
for t in self.getTestValues(t.elementType):
yield '%s + %s * 1i'%(t,t)
elif isinstance(t, ArrayType):
values = list(self.getTestValues(t.elementType))
if not values:
yield '{ }'
for i in range(t.numElements):
for v in values:
elements = [random.choice(values) for i in range(t.numElements)]
elements[i] = v
yield '{ %s }'%(', '.join(elements))
else:
raise NotImplementedError,'Cannot make tests values of type: "%s"'%(t,)
def printSizeOfType(self, prefix, name, t, output=None, indent=2):
print >>output, '%*sprintf("%s: sizeof(%s) = %%ld\\n", (long)sizeof(%s));'%(indent, '', prefix, name, name)
def printAlignOfType(self, prefix, name, t, output=None, indent=2):
print >>output, '%*sprintf("%s: __alignof__(%s) = %%ld\\n", (long)__alignof__(%s));'%(indent, '', prefix, name, name)
def printOffsetsOfType(self, prefix, name, t, output=None, indent=2):
if isinstance(t, RecordType):
for i,f in enumerate(t.fields):
if f.isBitField():
continue
fname = 'field%d' % i
print >>output, '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", (long)__builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname)
def printValueOfType(self, prefix, name, t, output=None, indent=2):
if output is None:
output = self.output
if isinstance(t, BuiltinType):
value_expr = name
if t.name.split(' ')[-1] == '_Bool':
# Hack to work around PR5579.
value_expr = "%s ? 2 : 0" % name
if t.name.endswith('long long'):
code = 'lld'
elif t.name.endswith('long'):
code = 'ld'
elif t.name.split(' ')[-1] in ('_Bool','char','short',
'int','unsigned'):
code = 'd'
elif t.name in ('float','double'):
code = 'f'
elif t.name == 'long double':
code = 'Lf'
else:
code = 'p'
print >>output, '%*sprintf("%s: %s = %%%s\\n", %s);'%(
indent, '', prefix, name, code, value_expr)
elif isinstance(t, EnumType):
print >>output, '%*sprintf("%s: %s = %%d\\n", %s);'%(indent, '', prefix, name, name)
elif isinstance(t, RecordType):
if not t.fields:
print >>output, '%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name)
for i,f in enumerate(t.fields):
if f.isPaddingBitField():
continue
fname = '%s.field%d'%(name,i)
self.printValueOfType(prefix, fname, f, output=output, indent=indent)
elif isinstance(t, ComplexType):
self.printValueOfType(prefix, '(__real %s)'%name, t.elementType, output=output,indent=indent)
self.printValueOfType(prefix, '(__imag %s)'%name, t.elementType, output=output,indent=indent)
elif isinstance(t, ArrayType):
for i in range(t.numElements):
# Access in this fashion as a hackish way to portably
# access vectors.
if t.isVector:
self.printValueOfType(prefix, '((%s*) &%s)[%d]'%(t.elementType,name,i), t.elementType, output=output,indent=indent)
else:
self.printValueOfType(prefix, '%s[%d]'%(name,i), t.elementType, output=output,indent=indent)
else:
raise NotImplementedError,'Cannot print value of type: "%s"'%(t,)
def checkTypeValues(self, nameLHS, nameRHS, t, output=None, indent=2):
prefix = 'foo'
if output is None:
output = self.output
if isinstance(t, BuiltinType):
print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
elif isinstance(t, EnumType):
print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
elif isinstance(t, RecordType):
for i,f in enumerate(t.fields):
if f.isPaddingBitField():
continue
self.checkTypeValues('%s.field%d'%(nameLHS,i), '%s.field%d'%(nameRHS,i),
f, output=output, indent=indent)
if t.isUnion:
break
elif isinstance(t, ComplexType):
self.checkTypeValues('(__real %s)'%nameLHS, '(__real %s)'%nameRHS, t.elementType, output=output,indent=indent)
self.checkTypeValues('(__imag %s)'%nameLHS, '(__imag %s)'%nameRHS, t.elementType, output=output,indent=indent)
elif isinstance(t, ArrayType):
for i in range(t.numElements):
# Access in this fashion as a hackish way to portably
# access vectors.
if t.isVector:
self.checkTypeValues('((%s*) &%s)[%d]'%(t.elementType,nameLHS,i),
'((%s*) &%s)[%d]'%(t.elementType,nameRHS,i),
t.elementType, output=output,indent=indent)
else:
self.checkTypeValues('%s[%d]'%(nameLHS,i), '%s[%d]'%(nameRHS,i),
t.elementType, output=output,indent=indent)
else:
raise NotImplementedError,'Cannot print value of type: "%s"'%(t,)
import sys
def main():
from optparse import OptionParser, OptionGroup
parser = OptionParser("%prog [options] {indices}")
parser.add_option("", "--mode", dest="mode",
help="autogeneration mode (random or linear) [default %default]",
type='choice', choices=('random','linear'), default='linear')
parser.add_option("", "--count", dest="count",
help="autogenerate COUNT functions according to MODE",
type=int, default=0)
parser.add_option("", "--min", dest="minIndex", metavar="N",
help="start autogeneration with the Nth function type [default %default]",
type=int, default=0)
parser.add_option("", "--max", dest="maxIndex", metavar="N",
help="maximum index for random autogeneration [default %default]",
type=int, default=10000000)
parser.add_option("", "--seed", dest="seed",
help="random number generator seed [default %default]",
type=int, default=1)
parser.add_option("", "--use-random-seed", dest="useRandomSeed",
help="use random value for initial random number generator seed",
action='store_true', default=False)
parser.add_option("", "--skip", dest="skipTests",
help="add a test index to skip",
type=int, action='append', default=[])
parser.add_option("-o", "--output", dest="output", metavar="FILE",
help="write output to FILE [default %default]",
type=str, default='-')
parser.add_option("-O", "--output-header", dest="outputHeader", metavar="FILE",
help="write header file for output to FILE [default %default]",
type=str, default=None)
parser.add_option("-T", "--output-tests", dest="outputTests", metavar="FILE",
help="write function tests to FILE [default %default]",
type=str, default=None)
parser.add_option("-D", "--output-driver", dest="outputDriver", metavar="FILE",
help="write test driver to FILE [default %default]",
type=str, default=None)
parser.add_option("", "--test-layout", dest="testLayout", metavar="FILE",
help="test structure layout",
action='store_true', default=False)
group = OptionGroup(parser, "Type Enumeration Options")
# Builtins - Ints
group.add_option("", "--no-char", dest="useChar",
help="do not generate char types",
action="store_false", default=True)
group.add_option("", "--no-short", dest="useShort",
help="do not generate short types",
action="store_false", default=True)
group.add_option("", "--no-int", dest="useInt",
help="do not generate int types",
action="store_false", default=True)
group.add_option("", "--no-long", dest="useLong",
help="do not generate long types",
action="store_false", default=True)
group.add_option("", "--no-long-long", dest="useLongLong",
help="do not generate long long types",
action="store_false", default=True)
group.add_option("", "--no-unsigned", dest="useUnsigned",
help="do not generate unsigned integer types",
action="store_false", default=True)
# Other builtins
group.add_option("", "--no-bool", dest="useBool",
help="do not generate bool types",
action="store_false", default=True)
group.add_option("", "--no-float", dest="useFloat",
help="do not generate float types",
action="store_false", default=True)
group.add_option("", "--no-double", dest="useDouble",
help="do not generate double types",
action="store_false", default=True)
group.add_option("", "--no-long-double", dest="useLongDouble",
help="do not generate long double types",
action="store_false", default=True)
group.add_option("", "--no-void-pointer", dest="useVoidPointer",
help="do not generate void* types",
action="store_false", default=True)
# Enumerations
group.add_option("", "--no-enums", dest="useEnum",
help="do not generate enum types",
action="store_false", default=True)
# Derived types
group.add_option("", "--no-array", dest="useArray",
help="do not generate record types",
action="store_false", default=True)
group.add_option("", "--no-complex", dest="useComplex",
help="do not generate complex types",
action="store_false", default=True)
group.add_option("", "--no-record", dest="useRecord",
help="do not generate record types",
action="store_false", default=True)
group.add_option("", "--no-union", dest="recordUseUnion",
help="do not generate union types",
action="store_false", default=True)
group.add_option("", "--no-vector", dest="useVector",
help="do not generate vector types",
action="store_false", default=True)
group.add_option("", "--no-bit-field", dest="useBitField",
help="do not generate bit-field record members",
action="store_false", default=True)
group.add_option("", "--no-builtins", dest="useBuiltins",
help="do not use any types",
action="store_false", default=True)
# Tuning
group.add_option("", "--no-function-return", dest="functionUseReturn",
help="do not generate return types for functions",
action="store_false", default=True)
group.add_option("", "--vector-types", dest="vectorTypes",
help="comma separated list of vector types (e.g., v2i32) [default %default]",
action="store", type=str, default='v2i16, v1i64, v2i32, v4i16, v8i8, v2f32, v2i64, v4i32, v8i16, v16i8, v2f64, v4f32, v16f32', metavar="N")
group.add_option("", "--bit-fields", dest="bitFields",
help="comma separated list 'type:width' bit-field specifiers [default %default]",
action="store", type=str, default=(
"char:0,char:4,int:0,unsigned:1,int:1,int:4,int:13,int:24"))
group.add_option("", "--max-args", dest="functionMaxArgs",
help="maximum number of arguments per function [default %default]",
action="store", type=int, default=4, metavar="N")
group.add_option("", "--max-array", dest="arrayMaxSize",
help="maximum array size [default %default]",
action="store", type=int, default=4, metavar="N")
group.add_option("", "--max-record", dest="recordMaxSize",
help="maximum number of fields per record [default %default]",
action="store", type=int, default=4, metavar="N")
group.add_option("", "--max-record-depth", dest="recordMaxDepth",
help="maximum nested structure depth [default %default]",
action="store", type=int, default=None, metavar="N")
parser.add_option_group(group)
(opts, args) = parser.parse_args()
if not opts.useRandomSeed:
random.seed(opts.seed)
# Construct type generator
builtins = []
if opts.useBuiltins:
ints = []
if opts.useChar: ints.append(('char',1))
if opts.useShort: ints.append(('short',2))
if opts.useInt: ints.append(('int',4))
# FIXME: Wrong size.
if opts.useLong: ints.append(('long',4))
if opts.useLongLong: ints.append(('long long',8))
if opts.useUnsigned:
ints = ([('unsigned %s'%i,s) for i,s in ints] +
[('signed %s'%i,s) for i,s in ints])
builtins.extend(ints)
if opts.useBool: builtins.append(('_Bool',1))
if opts.useFloat: builtins.append(('float',4))
if opts.useDouble: builtins.append(('double',8))
if opts.useLongDouble: builtins.append(('long double',16))
# FIXME: Wrong size.
if opts.useVoidPointer: builtins.append(('void*',4))
btg = FixedTypeGenerator([BuiltinType(n,s) for n,s in builtins])
bitfields = []
for specifier in opts.bitFields.split(','):
if not specifier.strip():
continue
name,width = specifier.strip().split(':', 1)
bitfields.append(BuiltinType(name,None,int(width)))
bftg = FixedTypeGenerator(bitfields)
charType = BuiltinType('char',1)
shortType = BuiltinType('short',2)
intType = BuiltinType('int',4)
longlongType = BuiltinType('long long',8)
floatType = BuiltinType('float',4)
doubleType = BuiltinType('double',8)
sbtg = FixedTypeGenerator([charType, intType, floatType, doubleType])
atg = AnyTypeGenerator()
artg = AnyTypeGenerator()
def makeGenerator(atg, subgen, subfieldgen, useRecord, useArray, useBitField):
atg.addGenerator(btg)
if useBitField and opts.useBitField:
atg.addGenerator(bftg)
if useRecord and opts.useRecord:
assert subgen
atg.addGenerator(RecordTypeGenerator(subfieldgen, opts.recordUseUnion,
opts.recordMaxSize))
if opts.useComplex:
# FIXME: Allow overriding builtins here
atg.addGenerator(ComplexTypeGenerator(sbtg))
if useArray and opts.useArray:
assert subgen
atg.addGenerator(ArrayTypeGenerator(subgen, opts.arrayMaxSize))
if opts.useVector:
vTypes = []
for i,t in enumerate(opts.vectorTypes.split(',')):
m = re.match('v([1-9][0-9]*)([if][1-9][0-9]*)', t.strip())
if not m:
parser.error('Invalid vector type: %r' % t)
count,kind = m.groups()
count = int(count)
type = { 'i8' : charType,
'i16' : shortType,
'i32' : intType,
'i64' : longlongType,
'f32' : floatType,
'f64' : doubleType,
}.get(kind)
if not type:
parser.error('Invalid vector type: %r' % t)
vTypes.append(ArrayType(i, True, type, count * type.size))
atg.addGenerator(FixedTypeGenerator(vTypes))
if opts.useEnum:
atg.addGenerator(EnumTypeGenerator([None, '-1', '1', '1u'], 1, 4))
if opts.recordMaxDepth is None:
# Fully recursive, just avoid top-level arrays.
subFTG = AnyTypeGenerator()
subTG = AnyTypeGenerator()
atg = AnyTypeGenerator()
makeGenerator(subFTG, atg, atg, True, True, True)
makeGenerator(subTG, atg, subFTG, True, True, False)
makeGenerator(atg, subTG, subFTG, True, False, False)
else:
# Make a chain of type generators, each builds smaller
# structures.
base = AnyTypeGenerator()
fbase = AnyTypeGenerator()
makeGenerator(base, None, None, False, False, False)
makeGenerator(fbase, None, None, False, False, True)
for i in range(opts.recordMaxDepth):
n = AnyTypeGenerator()
fn = AnyTypeGenerator()
makeGenerator(n, base, fbase, True, True, False)
makeGenerator(fn, base, fbase, True, True, True)
base = n
fbase = fn
atg = AnyTypeGenerator()
makeGenerator(atg, base, fbase, True, False, False)
if opts.testLayout:
ftg = atg
else:
ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs)
# Override max,min,count if finite
if opts.maxIndex is None:
if ftg.cardinality is aleph0:
opts.maxIndex = 10000000
else:
opts.maxIndex = ftg.cardinality
opts.maxIndex = min(opts.maxIndex, ftg.cardinality)
opts.minIndex = max(0,min(opts.maxIndex-1, opts.minIndex))
if not opts.mode=='random':
opts.count = min(opts.count, opts.maxIndex-opts.minIndex)
if opts.output=='-':
output = sys.stdout
else:
output = open(opts.output,'w')
atexit.register(lambda: output.close())
outputHeader = None
if opts.outputHeader:
outputHeader = open(opts.outputHeader,'w')
atexit.register(lambda: outputHeader.close())
outputTests = None
if opts.outputTests:
outputTests = open(opts.outputTests,'w')
atexit.register(lambda: outputTests.close())
outputDriver = None
if opts.outputDriver:
outputDriver = open(opts.outputDriver,'w')
atexit.register(lambda: outputDriver.close())
info = ''
info += '// %s\n'%(' '.join(sys.argv),)
info += '// Generated: %s\n'%(time.strftime('%Y-%m-%d %H:%M'),)
info += '// Cardinality of function generator: %s\n'%(ftg.cardinality,)
info += '// Cardinality of type generator: %s\n'%(atg.cardinality,)
if opts.testLayout:
info += '\n#include <stdio.h>'
P = TypePrinter(output,
outputHeader=outputHeader,
outputTests=outputTests,
outputDriver=outputDriver,
headerName=opts.outputHeader,
info=info)
def write(N):
try:
FT = ftg.get(N)
except RuntimeError,e:
if e.args[0]=='maximum recursion depth exceeded':
print >>sys.stderr,'WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,)
return
raise
if opts.testLayout:
P.writeLayoutTest(N, FT)
else:
P.writeFunction(N, FT)
if args:
[write(int(a)) for a in args]
skipTests = set(opts.skipTests)
for i in range(opts.count):
if opts.mode=='linear':
index = opts.minIndex + i
else:
index = opts.minIndex + int((opts.maxIndex-opts.minIndex) * random.random())
if index in skipTests:
continue
write(index)
P.finish()
if __name__=='__main__':
main()