1#!/usr/bin/env python 2 3from pprint import pprint 4import random, atexit, time 5from random import randrange 6import re 7 8from Enumeration import * 9from TypeGen import * 10 11#### 12 13class TypePrinter: 14 def __init__(self, output, outputHeader=None, 15 outputTests=None, outputDriver=None, 16 headerName=None, info=None): 17 self.output = output 18 self.outputHeader = outputHeader 19 self.outputTests = outputTests 20 self.outputDriver = outputDriver 21 self.writeBody = outputHeader or outputTests or outputDriver 22 self.types = {} 23 self.testValues = {} 24 self.testReturnValues = {} 25 self.layoutTests = [] 26 self.declarations = set() 27 28 if info: 29 for f in (self.output,self.outputHeader,self.outputTests,self.outputDriver): 30 if f: 31 print >>f,info 32 33 if self.writeBody: 34 print >>self.output, '#include <stdio.h>\n' 35 if self.outputTests: 36 print >>self.outputTests, '#include <stdio.h>' 37 print >>self.outputTests, '#include <string.h>' 38 print >>self.outputTests, '#include <assert.h>\n' 39 40 if headerName: 41 for f in (self.output,self.outputTests,self.outputDriver): 42 if f is not None: 43 print >>f, '#include "%s"\n'%(headerName,) 44 45 if self.outputDriver: 46 print >>self.outputDriver, '#include <stdio.h>' 47 print >>self.outputDriver, '#include <stdlib.h>\n' 48 print >>self.outputDriver, 'int main(int argc, char **argv) {' 49 print >>self.outputDriver, ' int index = -1;' 50 print >>self.outputDriver, ' if (argc > 1) index = atoi(argv[1]);' 51 52 def finish(self): 53 if self.layoutTests: 54 print >>self.output, 'int main(int argc, char **argv) {' 55 print >>self.output, ' int index = -1;' 56 print >>self.output, ' if (argc > 1) index = atoi(argv[1]);' 57 for i,f in self.layoutTests: 58 print >>self.output, ' if (index == -1 || index == %d)' % i 59 print >>self.output, ' %s();' % f 60 print >>self.output, ' return 0;' 61 print >>self.output, '}' 62 63 if self.outputDriver: 64 print >>self.outputDriver, ' printf("DONE\\n");' 65 print >>self.outputDriver, ' return 0;' 66 print >>self.outputDriver, '}' 67 68 def addDeclaration(self, decl): 69 if decl in self.declarations: 70 return False 71 72 self.declarations.add(decl) 73 if self.outputHeader: 74 print >>self.outputHeader, decl 75 else: 76 print >>self.output, decl 77 if self.outputTests: 78 print >>self.outputTests, decl 79 return True 80 81 def getTypeName(self, T): 82 name = self.types.get(T) 83 if name is None: 84 # Reserve slot 85 self.types[T] = None 86 self.types[T] = name = T.getTypeName(self) 87 return name 88 89 def writeLayoutTest(self, i, ty): 90 tyName = self.getTypeName(ty) 91 tyNameClean = tyName.replace(' ','_').replace('*','star') 92 fnName = 'test_%s' % tyNameClean 93 94 print >>self.output,'void %s(void) {' % fnName 95 self.printSizeOfType(' %s'%fnName, tyName, ty, self.output) 96 self.printAlignOfType(' %s'%fnName, tyName, ty, self.output) 97 self.printOffsetsOfType(' %s'%fnName, tyName, ty, self.output) 98 print >>self.output,'}' 99 print >>self.output 100 101 self.layoutTests.append((i,fnName)) 102 103 def writeFunction(self, i, FT): 104 args = ', '.join(['%s arg%d'%(self.getTypeName(t),i) for i,t in enumerate(FT.argTypes)]) 105 if not args: 106 args = 'void' 107 108 if FT.returnType is None: 109 retvalName = None 110 retvalTypeName = 'void' 111 else: 112 retvalTypeName = self.getTypeName(FT.returnType) 113 if self.writeBody or self.outputTests: 114 retvalName = self.getTestReturnValue(FT.returnType) 115 116 fnName = 'fn%d'%(FT.index,) 117 if self.outputHeader: 118 print >>self.outputHeader,'%s %s(%s);'%(retvalTypeName, fnName, args) 119 elif self.outputTests: 120 print >>self.outputTests,'%s %s(%s);'%(retvalTypeName, fnName, args) 121 122 print >>self.output,'%s %s(%s)'%(retvalTypeName, fnName, args), 123 if self.writeBody: 124 print >>self.output, '{' 125 126 for i,t in enumerate(FT.argTypes): 127 self.printValueOfType(' %s'%fnName, 'arg%d'%i, t) 128 129 if retvalName is not None: 130 print >>self.output, ' return %s;'%(retvalName,) 131 print >>self.output, '}' 132 else: 133 print >>self.output, '{}' 134 print >>self.output 135 136 if self.outputDriver: 137 print >>self.outputDriver, ' if (index == -1 || index == %d) {' % i 138 print >>self.outputDriver, ' extern void test_%s(void);' % fnName 139 print >>self.outputDriver, ' test_%s();' % fnName 140 print >>self.outputDriver, ' }' 141 142 if self.outputTests: 143 if self.outputHeader: 144 print >>self.outputHeader, 'void test_%s(void);'%(fnName,) 145 146 if retvalName is None: 147 retvalTests = None 148 else: 149 retvalTests = self.getTestValuesArray(FT.returnType) 150 tests = map(self.getTestValuesArray, FT.argTypes) 151 print >>self.outputTests, 'void test_%s(void) {'%(fnName,) 152 153 if retvalTests is not None: 154 print >>self.outputTests, ' printf("%s: testing return.\\n");'%(fnName,) 155 print >>self.outputTests, ' for (int i=0; i<%d; ++i) {'%(retvalTests[1],) 156 args = ', '.join(['%s[%d]'%(t,randrange(l)) for t,l in tests]) 157 print >>self.outputTests, ' %s RV;'%(retvalTypeName,) 158 print >>self.outputTests, ' %s = %s[i];'%(retvalName, retvalTests[0]) 159 print >>self.outputTests, ' RV = %s(%s);'%(fnName, args) 160 self.printValueOfType(' %s_RV'%fnName, 'RV', FT.returnType, output=self.outputTests, indent=4) 161 self.checkTypeValues('RV', '%s[i]' % retvalTests[0], FT.returnType, output=self.outputTests, indent=4) 162 print >>self.outputTests, ' }' 163 164 if tests: 165 print >>self.outputTests, ' printf("%s: testing arguments.\\n");'%(fnName,) 166 for i,(array,length) in enumerate(tests): 167 for j in range(length): 168 args = ['%s[%d]'%(t,randrange(l)) for t,l in tests] 169 args[i] = '%s[%d]'%(array,j) 170 print >>self.outputTests, ' %s(%s);'%(fnName, ', '.join(args),) 171 print >>self.outputTests, '}' 172 173 def getTestReturnValue(self, type): 174 typeName = self.getTypeName(type) 175 info = self.testReturnValues.get(typeName) 176 if info is None: 177 name = '%s_retval'%(typeName.replace(' ','_').replace('*','star'),) 178 print >>self.output, '%s %s;'%(typeName,name) 179 if self.outputHeader: 180 print >>self.outputHeader, 'extern %s %s;'%(typeName,name) 181 elif self.outputTests: 182 print >>self.outputTests, 'extern %s %s;'%(typeName,name) 183 info = self.testReturnValues[typeName] = name 184 return info 185 186 def getTestValuesArray(self, type): 187 typeName = self.getTypeName(type) 188 info = self.testValues.get(typeName) 189 if info is None: 190 name = '%s_values'%(typeName.replace(' ','_').replace('*','star'),) 191 print >>self.outputTests, 'static %s %s[] = {'%(typeName,name) 192 length = 0 193 for item in self.getTestValues(type): 194 print >>self.outputTests, '\t%s,'%(item,) 195 length += 1 196 print >>self.outputTests,'};' 197 info = self.testValues[typeName] = (name,length) 198 return info 199 200 def getTestValues(self, t): 201 if isinstance(t, BuiltinType): 202 if t.name=='float': 203 for i in ['0.0','-1.0','1.0']: 204 yield i+'f' 205 elif t.name=='double': 206 for i in ['0.0','-1.0','1.0']: 207 yield i 208 elif t.name in ('void *'): 209 yield '(void*) 0' 210 yield '(void*) -1' 211 else: 212 yield '(%s) 0'%(t.name,) 213 yield '(%s) -1'%(t.name,) 214 yield '(%s) 1'%(t.name,) 215 elif isinstance(t, EnumType): 216 for i in range(0, len(t.enumerators)): 217 yield 'enum%dval%d_%d' % (t.index, i, t.unique_id) 218 elif isinstance(t, RecordType): 219 nonPadding = [f for f in t.fields 220 if not f.isPaddingBitField()] 221 222 if not nonPadding: 223 yield '{ }' 224 return 225 226 # FIXME: Use designated initializers to access non-first 227 # fields of unions. 228 if t.isUnion: 229 for v in self.getTestValues(nonPadding[0]): 230 yield '{ %s }' % v 231 return 232 233 fieldValues = map(list, map(self.getTestValues, nonPadding)) 234 for i,values in enumerate(fieldValues): 235 for v in values: 236 elements = map(random.choice,fieldValues) 237 elements[i] = v 238 yield '{ %s }'%(', '.join(elements)) 239 240 elif isinstance(t, ComplexType): 241 for t in self.getTestValues(t.elementType): 242 yield '%s + %s * 1i'%(t,t) 243 elif isinstance(t, ArrayType): 244 values = list(self.getTestValues(t.elementType)) 245 if not values: 246 yield '{ }' 247 for i in range(t.numElements): 248 for v in values: 249 elements = [random.choice(values) for i in range(t.numElements)] 250 elements[i] = v 251 yield '{ %s }'%(', '.join(elements)) 252 else: 253 raise NotImplementedError,'Cannot make tests values of type: "%s"'%(t,) 254 255 def printSizeOfType(self, prefix, name, t, output=None, indent=2): 256 print >>output, '%*sprintf("%s: sizeof(%s) = %%ld\\n", (long)sizeof(%s));'%(indent, '', prefix, name, name) 257 def printAlignOfType(self, prefix, name, t, output=None, indent=2): 258 print >>output, '%*sprintf("%s: __alignof__(%s) = %%ld\\n", (long)__alignof__(%s));'%(indent, '', prefix, name, name) 259 def printOffsetsOfType(self, prefix, name, t, output=None, indent=2): 260 if isinstance(t, RecordType): 261 for i,f in enumerate(t.fields): 262 if f.isBitField(): 263 continue 264 fname = 'field%d' % i 265 print >>output, '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", (long)__builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname) 266 267 def printValueOfType(self, prefix, name, t, output=None, indent=2): 268 if output is None: 269 output = self.output 270 if isinstance(t, BuiltinType): 271 value_expr = name 272 if t.name.split(' ')[-1] == '_Bool': 273 # Hack to work around PR5579. 274 value_expr = "%s ? 2 : 0" % name 275 276 if t.name.endswith('long long'): 277 code = 'lld' 278 elif t.name.endswith('long'): 279 code = 'ld' 280 elif t.name.split(' ')[-1] in ('_Bool','char','short', 281 'int','unsigned'): 282 code = 'd' 283 elif t.name in ('float','double'): 284 code = 'f' 285 elif t.name == 'long double': 286 code = 'Lf' 287 else: 288 code = 'p' 289 print >>output, '%*sprintf("%s: %s = %%%s\\n", %s);'%( 290 indent, '', prefix, name, code, value_expr) 291 elif isinstance(t, EnumType): 292 print >>output, '%*sprintf("%s: %s = %%d\\n", %s);'%(indent, '', prefix, name, name) 293 elif isinstance(t, RecordType): 294 if not t.fields: 295 print >>output, '%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name) 296 for i,f in enumerate(t.fields): 297 if f.isPaddingBitField(): 298 continue 299 fname = '%s.field%d'%(name,i) 300 self.printValueOfType(prefix, fname, f, output=output, indent=indent) 301 elif isinstance(t, ComplexType): 302 self.printValueOfType(prefix, '(__real %s)'%name, t.elementType, output=output,indent=indent) 303 self.printValueOfType(prefix, '(__imag %s)'%name, t.elementType, output=output,indent=indent) 304 elif isinstance(t, ArrayType): 305 for i in range(t.numElements): 306 # Access in this fashion as a hackish way to portably 307 # access vectors. 308 if t.isVector: 309 self.printValueOfType(prefix, '((%s*) &%s)[%d]'%(t.elementType,name,i), t.elementType, output=output,indent=indent) 310 else: 311 self.printValueOfType(prefix, '%s[%d]'%(name,i), t.elementType, output=output,indent=indent) 312 else: 313 raise NotImplementedError,'Cannot print value of type: "%s"'%(t,) 314 315 def checkTypeValues(self, nameLHS, nameRHS, t, output=None, indent=2): 316 prefix = 'foo' 317 if output is None: 318 output = self.output 319 if isinstance(t, BuiltinType): 320 print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS) 321 elif isinstance(t, EnumType): 322 print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS) 323 elif isinstance(t, RecordType): 324 for i,f in enumerate(t.fields): 325 if f.isPaddingBitField(): 326 continue 327 self.checkTypeValues('%s.field%d'%(nameLHS,i), '%s.field%d'%(nameRHS,i), 328 f, output=output, indent=indent) 329 if t.isUnion: 330 break 331 elif isinstance(t, ComplexType): 332 self.checkTypeValues('(__real %s)'%nameLHS, '(__real %s)'%nameRHS, t.elementType, output=output,indent=indent) 333 self.checkTypeValues('(__imag %s)'%nameLHS, '(__imag %s)'%nameRHS, t.elementType, output=output,indent=indent) 334 elif isinstance(t, ArrayType): 335 for i in range(t.numElements): 336 # Access in this fashion as a hackish way to portably 337 # access vectors. 338 if t.isVector: 339 self.checkTypeValues('((%s*) &%s)[%d]'%(t.elementType,nameLHS,i), 340 '((%s*) &%s)[%d]'%(t.elementType,nameRHS,i), 341 t.elementType, output=output,indent=indent) 342 else: 343 self.checkTypeValues('%s[%d]'%(nameLHS,i), '%s[%d]'%(nameRHS,i), 344 t.elementType, output=output,indent=indent) 345 else: 346 raise NotImplementedError,'Cannot print value of type: "%s"'%(t,) 347 348import sys 349 350def main(): 351 from optparse import OptionParser, OptionGroup 352 parser = OptionParser("%prog [options] {indices}") 353 parser.add_option("", "--mode", dest="mode", 354 help="autogeneration mode (random or linear) [default %default]", 355 type='choice', choices=('random','linear'), default='linear') 356 parser.add_option("", "--count", dest="count", 357 help="autogenerate COUNT functions according to MODE", 358 type=int, default=0) 359 parser.add_option("", "--min", dest="minIndex", metavar="N", 360 help="start autogeneration with the Nth function type [default %default]", 361 type=int, default=0) 362 parser.add_option("", "--max", dest="maxIndex", metavar="N", 363 help="maximum index for random autogeneration [default %default]", 364 type=int, default=10000000) 365 parser.add_option("", "--seed", dest="seed", 366 help="random number generator seed [default %default]", 367 type=int, default=1) 368 parser.add_option("", "--use-random-seed", dest="useRandomSeed", 369 help="use random value for initial random number generator seed", 370 action='store_true', default=False) 371 parser.add_option("", "--skip", dest="skipTests", 372 help="add a test index to skip", 373 type=int, action='append', default=[]) 374 parser.add_option("-o", "--output", dest="output", metavar="FILE", 375 help="write output to FILE [default %default]", 376 type=str, default='-') 377 parser.add_option("-O", "--output-header", dest="outputHeader", metavar="FILE", 378 help="write header file for output to FILE [default %default]", 379 type=str, default=None) 380 parser.add_option("-T", "--output-tests", dest="outputTests", metavar="FILE", 381 help="write function tests to FILE [default %default]", 382 type=str, default=None) 383 parser.add_option("-D", "--output-driver", dest="outputDriver", metavar="FILE", 384 help="write test driver to FILE [default %default]", 385 type=str, default=None) 386 parser.add_option("", "--test-layout", dest="testLayout", metavar="FILE", 387 help="test structure layout", 388 action='store_true', default=False) 389 390 group = OptionGroup(parser, "Type Enumeration Options") 391 # Builtins - Ints 392 group.add_option("", "--no-char", dest="useChar", 393 help="do not generate char types", 394 action="store_false", default=True) 395 group.add_option("", "--no-short", dest="useShort", 396 help="do not generate short types", 397 action="store_false", default=True) 398 group.add_option("", "--no-int", dest="useInt", 399 help="do not generate int types", 400 action="store_false", default=True) 401 group.add_option("", "--no-long", dest="useLong", 402 help="do not generate long types", 403 action="store_false", default=True) 404 group.add_option("", "--no-long-long", dest="useLongLong", 405 help="do not generate long long types", 406 action="store_false", default=True) 407 group.add_option("", "--no-unsigned", dest="useUnsigned", 408 help="do not generate unsigned integer types", 409 action="store_false", default=True) 410 411 # Other builtins 412 group.add_option("", "--no-bool", dest="useBool", 413 help="do not generate bool types", 414 action="store_false", default=True) 415 group.add_option("", "--no-float", dest="useFloat", 416 help="do not generate float types", 417 action="store_false", default=True) 418 group.add_option("", "--no-double", dest="useDouble", 419 help="do not generate double types", 420 action="store_false", default=True) 421 group.add_option("", "--no-long-double", dest="useLongDouble", 422 help="do not generate long double types", 423 action="store_false", default=True) 424 group.add_option("", "--no-void-pointer", dest="useVoidPointer", 425 help="do not generate void* types", 426 action="store_false", default=True) 427 428 # Enumerations 429 group.add_option("", "--no-enums", dest="useEnum", 430 help="do not generate enum types", 431 action="store_false", default=True) 432 433 # Derived types 434 group.add_option("", "--no-array", dest="useArray", 435 help="do not generate record types", 436 action="store_false", default=True) 437 group.add_option("", "--no-complex", dest="useComplex", 438 help="do not generate complex types", 439 action="store_false", default=True) 440 group.add_option("", "--no-record", dest="useRecord", 441 help="do not generate record types", 442 action="store_false", default=True) 443 group.add_option("", "--no-union", dest="recordUseUnion", 444 help="do not generate union types", 445 action="store_false", default=True) 446 group.add_option("", "--no-vector", dest="useVector", 447 help="do not generate vector types", 448 action="store_false", default=True) 449 group.add_option("", "--no-bit-field", dest="useBitField", 450 help="do not generate bit-field record members", 451 action="store_false", default=True) 452 group.add_option("", "--no-builtins", dest="useBuiltins", 453 help="do not use any types", 454 action="store_false", default=True) 455 456 # Tuning 457 group.add_option("", "--no-function-return", dest="functionUseReturn", 458 help="do not generate return types for functions", 459 action="store_false", default=True) 460 group.add_option("", "--vector-types", dest="vectorTypes", 461 help="comma separated list of vector types (e.g., v2i32) [default %default]", 462 action="store", type=str, default='v2i16, v1i64, v2i32, v4i16, v8i8, v2f32, v2i64, v4i32, v8i16, v16i8, v2f64, v4f32, v16f32', metavar="N") 463 group.add_option("", "--bit-fields", dest="bitFields", 464 help="comma separated list 'type:width' bit-field specifiers [default %default]", 465 action="store", type=str, default=( 466 "char:0,char:4,int:0,unsigned:1,int:1,int:4,int:13,int:24")) 467 group.add_option("", "--max-args", dest="functionMaxArgs", 468 help="maximum number of arguments per function [default %default]", 469 action="store", type=int, default=4, metavar="N") 470 group.add_option("", "--max-array", dest="arrayMaxSize", 471 help="maximum array size [default %default]", 472 action="store", type=int, default=4, metavar="N") 473 group.add_option("", "--max-record", dest="recordMaxSize", 474 help="maximum number of fields per record [default %default]", 475 action="store", type=int, default=4, metavar="N") 476 group.add_option("", "--max-record-depth", dest="recordMaxDepth", 477 help="maximum nested structure depth [default %default]", 478 action="store", type=int, default=None, metavar="N") 479 parser.add_option_group(group) 480 (opts, args) = parser.parse_args() 481 482 if not opts.useRandomSeed: 483 random.seed(opts.seed) 484 485 # Construct type generator 486 builtins = [] 487 if opts.useBuiltins: 488 ints = [] 489 if opts.useChar: ints.append(('char',1)) 490 if opts.useShort: ints.append(('short',2)) 491 if opts.useInt: ints.append(('int',4)) 492 # FIXME: Wrong size. 493 if opts.useLong: ints.append(('long',4)) 494 if opts.useLongLong: ints.append(('long long',8)) 495 if opts.useUnsigned: 496 ints = ([('unsigned %s'%i,s) for i,s in ints] + 497 [('signed %s'%i,s) for i,s in ints]) 498 builtins.extend(ints) 499 500 if opts.useBool: builtins.append(('_Bool',1)) 501 if opts.useFloat: builtins.append(('float',4)) 502 if opts.useDouble: builtins.append(('double',8)) 503 if opts.useLongDouble: builtins.append(('long double',16)) 504 # FIXME: Wrong size. 505 if opts.useVoidPointer: builtins.append(('void*',4)) 506 507 btg = FixedTypeGenerator([BuiltinType(n,s) for n,s in builtins]) 508 509 bitfields = [] 510 for specifier in opts.bitFields.split(','): 511 if not specifier.strip(): 512 continue 513 name,width = specifier.strip().split(':', 1) 514 bitfields.append(BuiltinType(name,None,int(width))) 515 bftg = FixedTypeGenerator(bitfields) 516 517 charType = BuiltinType('char',1) 518 shortType = BuiltinType('short',2) 519 intType = BuiltinType('int',4) 520 longlongType = BuiltinType('long long',8) 521 floatType = BuiltinType('float',4) 522 doubleType = BuiltinType('double',8) 523 sbtg = FixedTypeGenerator([charType, intType, floatType, doubleType]) 524 525 atg = AnyTypeGenerator() 526 artg = AnyTypeGenerator() 527 def makeGenerator(atg, subgen, subfieldgen, useRecord, useArray, useBitField): 528 atg.addGenerator(btg) 529 if useBitField and opts.useBitField: 530 atg.addGenerator(bftg) 531 if useRecord and opts.useRecord: 532 assert subgen 533 atg.addGenerator(RecordTypeGenerator(subfieldgen, opts.recordUseUnion, 534 opts.recordMaxSize)) 535 if opts.useComplex: 536 # FIXME: Allow overriding builtins here 537 atg.addGenerator(ComplexTypeGenerator(sbtg)) 538 if useArray and opts.useArray: 539 assert subgen 540 atg.addGenerator(ArrayTypeGenerator(subgen, opts.arrayMaxSize)) 541 if opts.useVector: 542 vTypes = [] 543 for i,t in enumerate(opts.vectorTypes.split(',')): 544 m = re.match('v([1-9][0-9]*)([if][1-9][0-9]*)', t.strip()) 545 if not m: 546 parser.error('Invalid vector type: %r' % t) 547 count,kind = m.groups() 548 count = int(count) 549 type = { 'i8' : charType, 550 'i16' : shortType, 551 'i32' : intType, 552 'i64' : longlongType, 553 'f32' : floatType, 554 'f64' : doubleType, 555 }.get(kind) 556 if not type: 557 parser.error('Invalid vector type: %r' % t) 558 vTypes.append(ArrayType(i, True, type, count * type.size)) 559 560 atg.addGenerator(FixedTypeGenerator(vTypes)) 561 if opts.useEnum: 562 atg.addGenerator(EnumTypeGenerator([None, '-1', '1', '1u'], 1, 4)) 563 564 if opts.recordMaxDepth is None: 565 # Fully recursive, just avoid top-level arrays. 566 subFTG = AnyTypeGenerator() 567 subTG = AnyTypeGenerator() 568 atg = AnyTypeGenerator() 569 makeGenerator(subFTG, atg, atg, True, True, True) 570 makeGenerator(subTG, atg, subFTG, True, True, False) 571 makeGenerator(atg, subTG, subFTG, True, False, False) 572 else: 573 # Make a chain of type generators, each builds smaller 574 # structures. 575 base = AnyTypeGenerator() 576 fbase = AnyTypeGenerator() 577 makeGenerator(base, None, None, False, False, False) 578 makeGenerator(fbase, None, None, False, False, True) 579 for i in range(opts.recordMaxDepth): 580 n = AnyTypeGenerator() 581 fn = AnyTypeGenerator() 582 makeGenerator(n, base, fbase, True, True, False) 583 makeGenerator(fn, base, fbase, True, True, True) 584 base = n 585 fbase = fn 586 atg = AnyTypeGenerator() 587 makeGenerator(atg, base, fbase, True, False, False) 588 589 if opts.testLayout: 590 ftg = atg 591 else: 592 ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs) 593 594 # Override max,min,count if finite 595 if opts.maxIndex is None: 596 if ftg.cardinality is aleph0: 597 opts.maxIndex = 10000000 598 else: 599 opts.maxIndex = ftg.cardinality 600 opts.maxIndex = min(opts.maxIndex, ftg.cardinality) 601 opts.minIndex = max(0,min(opts.maxIndex-1, opts.minIndex)) 602 if not opts.mode=='random': 603 opts.count = min(opts.count, opts.maxIndex-opts.minIndex) 604 605 if opts.output=='-': 606 output = sys.stdout 607 else: 608 output = open(opts.output,'w') 609 atexit.register(lambda: output.close()) 610 611 outputHeader = None 612 if opts.outputHeader: 613 outputHeader = open(opts.outputHeader,'w') 614 atexit.register(lambda: outputHeader.close()) 615 616 outputTests = None 617 if opts.outputTests: 618 outputTests = open(opts.outputTests,'w') 619 atexit.register(lambda: outputTests.close()) 620 621 outputDriver = None 622 if opts.outputDriver: 623 outputDriver = open(opts.outputDriver,'w') 624 atexit.register(lambda: outputDriver.close()) 625 626 info = '' 627 info += '// %s\n'%(' '.join(sys.argv),) 628 info += '// Generated: %s\n'%(time.strftime('%Y-%m-%d %H:%M'),) 629 info += '// Cardinality of function generator: %s\n'%(ftg.cardinality,) 630 info += '// Cardinality of type generator: %s\n'%(atg.cardinality,) 631 632 if opts.testLayout: 633 info += '\n#include <stdio.h>' 634 635 P = TypePrinter(output, 636 outputHeader=outputHeader, 637 outputTests=outputTests, 638 outputDriver=outputDriver, 639 headerName=opts.outputHeader, 640 info=info) 641 642 def write(N): 643 try: 644 FT = ftg.get(N) 645 except RuntimeError,e: 646 if e.args[0]=='maximum recursion depth exceeded': 647 print >>sys.stderr,'WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,) 648 return 649 raise 650 if opts.testLayout: 651 P.writeLayoutTest(N, FT) 652 else: 653 P.writeFunction(N, FT) 654 655 if args: 656 [write(int(a)) for a in args] 657 658 skipTests = set(opts.skipTests) 659 for i in range(opts.count): 660 if opts.mode=='linear': 661 index = opts.minIndex + i 662 else: 663 index = opts.minIndex + int((opts.maxIndex-opts.minIndex) * random.random()) 664 if index in skipTests: 665 continue 666 write(index) 667 668 P.finish() 669 670if __name__=='__main__': 671 main() 672 673