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