diff options
Diffstat (limited to 'clang/utils/ABITest/ABITestGen.py')
-rwxr-xr-x | clang/utils/ABITest/ABITestGen.py | 672 |
1 files changed, 672 insertions, 0 deletions
diff --git a/clang/utils/ABITest/ABITestGen.py b/clang/utils/ABITest/ABITestGen.py new file mode 100755 index 0000000..62925e7 --- /dev/null +++ b/clang/utils/ABITest/ABITestGen.py @@ -0,0 +1,672 @@ +#!/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' % (t.index, i) + 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) + + # Contruct 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() + |