blob: dfea36af3f2a595072f499d35e6e56f38dbb64a4 [file] [log] [blame]
Daniel Dunbara83fb862009-01-15 04:24:17 +00001#!/usr/bin/python
2
3from pprint import pprint
4import random, atexit, time
5from random import randrange
6
7from Enumeration import *
8from TypeGen import *
9
10####
11
12class TypePrinter:
13 def __init__(self, output, outputHeader=None,
14 outputTests=None, outputDriver=None,
15 headerName=None, info=None):
16 self.output = output
17 self.outputHeader = outputHeader
18 self.outputTests = outputTests
19 self.outputDriver = outputDriver
20 self.writeBody = outputHeader or outputTests or outputDriver
21 self.types = {}
22 self.testValues = {}
23 self.testReturnValues = {}
Daniel Dunbar5ce61572009-01-28 02:01:23 +000024 self.layoutTests = []
Daniel Dunbara83fb862009-01-15 04:24:17 +000025
26 if info:
27 for f in (self.output,self.outputHeader,self.outputTests,self.outputDriver):
28 if f:
29 print >>f,info
30
31 if self.writeBody:
32 print >>self.output, '#include <stdio.h>\n'
33 if self.outputTests:
Daniel Dunbar9dd60b42009-02-17 23:13:43 +000034 print >>self.outputTests, '#include <stdio.h>'
35 print >>self.outputTests, '#include <string.h>'
36 print >>self.outputTests, '#include <assert.h>\n'
Daniel Dunbara83fb862009-01-15 04:24:17 +000037
38 if headerName:
39 for f in (self.output,self.outputTests,self.outputDriver):
40 if f is not None:
41 print >>f, '#include "%s"\n'%(headerName,)
42
43 if self.outputDriver:
Daniel Dunbar9dd60b42009-02-17 23:13:43 +000044 print >>self.outputDriver, '#include <stdio.h>\n'
Daniel Dunbara83fb862009-01-15 04:24:17 +000045 print >>self.outputDriver, 'int main(int argc, char **argv) {'
46
47 def finish(self):
Daniel Dunbar5ce61572009-01-28 02:01:23 +000048 if self.layoutTests:
49 print >>self.output, 'int main(int argc, char **argv) {'
50 for f in self.layoutTests:
51 print >>self.output, ' %s();' % f
52 print >>self.output, ' return 0;'
53 print >>self.output, '}'
54
Daniel Dunbara83fb862009-01-15 04:24:17 +000055 if self.outputDriver:
Daniel Dunbar9dd60b42009-02-17 23:13:43 +000056 print >>self.outputDriver, ' printf("DONE\\n");'
Daniel Dunbara83fb862009-01-15 04:24:17 +000057 print >>self.outputDriver, ' return 0;'
Daniel Dunbar5ce61572009-01-28 02:01:23 +000058 print >>self.outputDriver, '}'
Daniel Dunbara83fb862009-01-15 04:24:17 +000059
60 def getTypeName(self, T):
61 if isinstance(T,BuiltinType):
62 return T.name
63 name = self.types.get(T)
64 if name is None:
65 name = 'T%d'%(len(self.types),)
66 # Reserve slot
67 self.types[T] = None
68 if self.outputHeader:
69 print >>self.outputHeader,T.getTypedefDef(name, self)
70 else:
71 print >>self.output,T.getTypedefDef(name, self)
72 if self.outputTests:
73 print >>self.outputTests,T.getTypedefDef(name, self)
74 self.types[T] = name
75 return name
76
Daniel Dunbar5ce61572009-01-28 02:01:23 +000077 def writeLayoutTest(self, i, ty):
78 tyName = self.getTypeName(ty)
79 tyNameClean = tyName.replace(' ','_').replace('*','star')
80 fnName = 'test_%s' % tyNameClean
81
82 print >>self.output,'void %s(void) {' % fnName
83 self.printSizeOfType(' %s'%fnName, tyName, ty, self.output)
84 self.printAlignOfType(' %s'%fnName, tyName, ty, self.output)
85 self.printOffsetsOfType(' %s'%fnName, tyName, ty, self.output)
86 print >>self.output,'}'
87 print >>self.output
88
89 self.layoutTests.append(fnName)
90
Daniel Dunbara83fb862009-01-15 04:24:17 +000091 def writeFunction(self, i, FT):
92 args = ', '.join(['%s arg%d'%(self.getTypeName(t),i) for i,t in enumerate(FT.argTypes)])
93 if not args:
94 args = 'void'
95
96 if FT.returnType is None:
97 retvalName = None
98 retvalTypeName = 'void'
99 else:
100 retvalTypeName = self.getTypeName(FT.returnType)
101 if self.writeBody or self.outputTests:
102 retvalName = self.getTestReturnValue(FT.returnType)
103
104 fnName = 'fn%d'%(FT.index,)
105 if self.outputHeader:
106 print >>self.outputHeader,'%s %s(%s);'%(retvalTypeName, fnName, args)
107 elif self.outputTests:
108 print >>self.outputTests,'%s %s(%s);'%(retvalTypeName, fnName, args)
109
110 print >>self.output,'%s %s(%s)'%(retvalTypeName, fnName, args),
111 if self.writeBody:
112 print >>self.output, '{'
113
114 for i,t in enumerate(FT.argTypes):
115 self.printValueOfType(' %s'%fnName, 'arg%d'%i, t)
116
117 if retvalName is not None:
118 print >>self.output, ' return %s;'%(retvalName,)
119 print >>self.output, '}'
120 else:
121 print >>self.output, '{}'
122 print >>self.output
123
124 if self.outputDriver:
125 print >>self.outputDriver, ' { extern void test_%s(void); test_%s(); }\n'%(fnName,fnName,)
126
127 if self.outputTests:
128 if self.outputHeader:
129 print >>self.outputHeader, 'void test_%s(void);'%(fnName,)
130
131 if retvalName is None:
132 retvalTests = None
133 else:
134 retvalTests = self.getTestValuesArray(FT.returnType)
135 tests = map(self.getTestValuesArray, FT.argTypes)
136 print >>self.outputTests, 'void test_%s(void) {'%(fnName,)
137
138 if retvalTests is not None:
139 print >>self.outputTests, ' printf("%s: testing return.\\n");'%(fnName,)
140 print >>self.outputTests, ' for (int i=0; i<%d; ++i) {'%(retvalTests[1],)
141 args = ', '.join(['%s[%d]'%(t,randrange(l)) for t,l in tests])
142 print >>self.outputTests, ' %s RV;'%(retvalTypeName,)
143 print >>self.outputTests, ' %s = %s[i];'%(retvalName, retvalTests[0])
144 print >>self.outputTests, ' RV = %s(%s);'%(fnName, args)
145 self.printValueOfType(' %s_RV'%fnName, 'RV', FT.returnType, output=self.outputTests, indent=4)
Daniel Dunbar9dd60b42009-02-17 23:13:43 +0000146 self.checkTypeValues('RV', '%s[i]' % retvalTests[0], FT.returnType, output=self.outputTests, indent=4)
Daniel Dunbara83fb862009-01-15 04:24:17 +0000147 print >>self.outputTests, ' }'
148
149 if tests:
150 print >>self.outputTests, ' printf("%s: testing arguments.\\n");'%(fnName,)
151 for i,(array,length) in enumerate(tests):
152 for j in range(length):
153 args = ['%s[%d]'%(t,randrange(l)) for t,l in tests]
154 args[i] = '%s[%d]'%(array,j)
155 print >>self.outputTests, ' %s(%s);'%(fnName, ', '.join(args),)
156 print >>self.outputTests, '}'
157
158 def getTestReturnValue(self, type):
159 typeName = self.getTypeName(type)
160 info = self.testReturnValues.get(typeName)
161 if info is None:
162 name = '%s_retval'%(typeName.replace(' ','_').replace('*','star'),)
163 print >>self.output, '%s %s;'%(typeName,name)
164 if self.outputHeader:
165 print >>self.outputHeader, 'extern %s %s;'%(typeName,name)
166 elif self.outputTests:
167 print >>self.outputTests, 'extern %s %s;'%(typeName,name)
168 info = self.testReturnValues[typeName] = name
169 return info
170
171 def getTestValuesArray(self, type):
172 typeName = self.getTypeName(type)
173 info = self.testValues.get(typeName)
174 if info is None:
175 name = '%s_values'%(typeName.replace(' ','_').replace('*','star'),)
176 print >>self.outputTests, 'static %s %s[] = {'%(typeName,name)
177 length = 0
178 for item in self.getTestValues(type):
179 print >>self.outputTests, '\t%s,'%(item,)
180 length += 1
181 print >>self.outputTests,'};'
182 info = self.testValues[typeName] = (name,length)
183 return info
184
185 def getTestValues(self, t):
186 if isinstance(t, BuiltinType):
187 if t.name=='float':
188 for i in ['0.0','-1.0','1.0']:
189 yield i+'f'
190 elif t.name=='double':
191 for i in ['0.0','-1.0','1.0']:
192 yield i
193 elif t.name in ('void *'):
194 yield '(void*) 0'
195 yield '(void*) -1'
196 else:
197 yield '(%s) 0'%(t.name,)
198 yield '(%s) -1'%(t.name,)
199 yield '(%s) 1'%(t.name,)
200 elif isinstance(t, RecordType):
Daniel Dunbara83fb862009-01-15 04:24:17 +0000201 if not t.fields:
202 yield '{ }'
Daniel Dunbar900ed552009-01-29 07:36:46 +0000203 return
204 # FIXME: Use designated initializers to access non-first
205 # fields of unions.
206 if t.isUnion:
207 for v in self.getTestValues(t.fields[0]):
208 yield '{ %s }' % v
209 return
210 fieldValues = [list(self.getTestValues(f)) for f in t.fields]
Daniel Dunbara83fb862009-01-15 04:24:17 +0000211 for i,values in enumerate(fieldValues):
212 for v in values:
213 elements = map(random.choice,fieldValues)
214 elements[i] = v
215 yield '{ %s }'%(', '.join(elements))
216 elif isinstance(t, ComplexType):
217 for t in self.getTestValues(t.elementType):
Daniel Dunbar550faa32009-01-26 19:05:20 +0000218 yield '%s + %s * 1i'%(t,t)
219 elif isinstance(t, ArrayType):
Daniel Dunbara83fb862009-01-15 04:24:17 +0000220 values = list(self.getTestValues(t.elementType))
221 if not values:
222 yield '{ }'
Daniel Dunbar550faa32009-01-26 19:05:20 +0000223 for i in range(t.numElements):
Daniel Dunbara83fb862009-01-15 04:24:17 +0000224 for v in values:
Daniel Dunbar550faa32009-01-26 19:05:20 +0000225 elements = [random.choice(values) for i in range(t.numElements)]
Daniel Dunbara83fb862009-01-15 04:24:17 +0000226 elements[i] = v
227 yield '{ %s }'%(', '.join(elements))
228 else:
229 raise NotImplementedError,'Cannot make tests values of type: "%s"'%(t,)
230
Daniel Dunbar5ce61572009-01-28 02:01:23 +0000231 def printSizeOfType(self, prefix, name, t, output=None, indent=2):
232 print >>output, '%*sprintf("%s: sizeof(%s) = %%ld\\n", sizeof(%s));'%(indent, '', prefix, name, name)
233 def printAlignOfType(self, prefix, name, t, output=None, indent=2):
234 print >>output, '%*sprintf("%s: __alignof__(%s) = %%ld\\n", __alignof__(%s));'%(indent, '', prefix, name, name)
235 def printOffsetsOfType(self, prefix, name, t, output=None, indent=2):
236 if isinstance(t, RecordType):
237 for i,f in enumerate(t.fields):
238 fname = 'field%d' % i
239 print >>output, '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", __builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname)
240
Daniel Dunbara83fb862009-01-15 04:24:17 +0000241 def printValueOfType(self, prefix, name, t, output=None, indent=2):
242 if output is None:
243 output = self.output
244 if isinstance(t, BuiltinType):
245 if t.name.endswith('long long'):
246 code = 'lld'
247 elif t.name.endswith('long'):
248 code = 'ld'
249 elif t.name.split(' ')[-1] in ('_Bool','char','short','int'):
250 code = 'd'
251 elif t.name in ('float','double'):
252 code = 'f'
253 elif t.name == 'long double':
254 code = 'Lf'
255 else:
256 code = 'p'
257 print >>output, '%*sprintf("%s: %s = %%%s\\n", %s);'%(indent, '', prefix, name, code, name)
258 elif isinstance(t, RecordType):
259 if not t.fields:
260 print >>output, '%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name)
261 for i,f in enumerate(t.fields):
262 fname = '%s.field%d'%(name,i)
263 self.printValueOfType(prefix, fname, f, output=output, indent=indent)
264 elif isinstance(t, ComplexType):
265 self.printValueOfType(prefix, '(__real %s)'%name, t.elementType, output=output,indent=indent)
266 self.printValueOfType(prefix, '(__imag %s)'%name, t.elementType, output=output,indent=indent)
Daniel Dunbar550faa32009-01-26 19:05:20 +0000267 elif isinstance(t, ArrayType):
268 for i in range(t.numElements):
269 # Access in this fashion as a hackish way to portably
270 # access vectors.
Daniel Dunbare61e95f2009-01-29 08:48:06 +0000271 if t.isVector:
272 self.printValueOfType(prefix, '((%s*) &%s)[%d]'%(t.elementType,name,i), t.elementType, output=output,indent=indent)
273 else:
274 self.printValueOfType(prefix, '%s[%d]'%(name,i), t.elementType, output=output,indent=indent)
Daniel Dunbara83fb862009-01-15 04:24:17 +0000275 else:
276 raise NotImplementedError,'Cannot print value of type: "%s"'%(t,)
277
Daniel Dunbar9dd60b42009-02-17 23:13:43 +0000278 def checkTypeValues(self, nameLHS, nameRHS, t, output=None, indent=2):
279 prefix = 'foo'
280 if output is None:
281 output = self.output
282 if isinstance(t, BuiltinType):
283 print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
284 elif isinstance(t, RecordType):
285 for i,f in enumerate(t.fields):
286 self.checkTypeValues('%s.field%d'%(nameLHS,i), '%s.field%d'%(nameRHS,i),
287 f, output=output, indent=indent)
288 if t.isUnion:
289 break
290 elif isinstance(t, ComplexType):
291 self.checkTypeValues('(__real %s)'%nameLHS, '(__real %s)'%nameRHS, t.elementType, output=output,indent=indent)
292 self.checkTypeValues('(__imag %s)'%nameLHS, '(__imag %s)'%nameRHS, t.elementType, output=output,indent=indent)
293 elif isinstance(t, ArrayType):
294 for i in range(t.numElements):
295 # Access in this fashion as a hackish way to portably
296 # access vectors.
297 if t.isVector:
298 self.checkTypeValues('((%s*) &%s)[%d]'%(t.elementType,nameLHS,i),
299 '((%s*) &%s)[%d]'%(t.elementType,nameRHS,i),
300 t.elementType, output=output,indent=indent)
301 else:
302 self.checkTypeValues('%s[%d]'%(nameLHS,i), '%s[%d]'%(nameRHS,i),
303 t.elementType, output=output,indent=indent)
304 else:
305 raise NotImplementedError,'Cannot print value of type: "%s"'%(t,)
306
Daniel Dunbara83fb862009-01-15 04:24:17 +0000307import sys
308
309def main():
310 from optparse import OptionParser, OptionGroup
311 parser = OptionParser("%prog [options] {indices}")
312 parser.add_option("", "--mode", dest="mode",
313 help="autogeneration mode (random or linear) [default %default]",
314 type='choice', choices=('random','linear'), default='linear')
315 parser.add_option("", "--count", dest="count",
316 help="autogenerate COUNT functions according to MODE",
317 type=int, default=0)
318 parser.add_option("", "--min", dest="minIndex", metavar="N",
319 help="start autogeneration with the Nth function type [default %default]",
320 type=int, default=0)
321 parser.add_option("", "--max", dest="maxIndex", metavar="N",
322 help="maximum index for random autogeneration [default %default]",
323 type=int, default=10000000)
324 parser.add_option("", "--seed", dest="seed",
325 help="random number generator seed [default %default]",
326 type=int, default=1)
327 parser.add_option("", "--use-random-seed", dest="useRandomSeed",
328 help="use random value for initial random number generator seed",
329 action='store_true', default=False)
330 parser.add_option("-o", "--output", dest="output", metavar="FILE",
331 help="write output to FILE [default %default]",
332 type=str, default='-')
333 parser.add_option("-O", "--output-header", dest="outputHeader", metavar="FILE",
334 help="write header file for output to FILE [default %default]",
335 type=str, default=None)
336 parser.add_option("-T", "--output-tests", dest="outputTests", metavar="FILE",
337 help="write function tests to FILE [default %default]",
338 type=str, default=None)
339 parser.add_option("-D", "--output-driver", dest="outputDriver", metavar="FILE",
340 help="write test driver to FILE [default %default]",
341 type=str, default=None)
Daniel Dunbar5ce61572009-01-28 02:01:23 +0000342 parser.add_option("", "--test-layout", dest="testLayout", metavar="FILE",
343 help="test structure layout",
344 action='store_true', default=False)
Daniel Dunbara83fb862009-01-15 04:24:17 +0000345
346 group = OptionGroup(parser, "Type Enumeration Options")
347 # Builtins - Ints
348 group.add_option("", "--no-char", dest="useChar",
349 help="do not generate char types",
350 action="store_false", default=True)
351 group.add_option("", "--no-short", dest="useShort",
352 help="do not generate short types",
353 action="store_false", default=True)
354 group.add_option("", "--no-int", dest="useInt",
355 help="do not generate int types",
356 action="store_false", default=True)
357 group.add_option("", "--no-long", dest="useLong",
358 help="do not generate long types",
359 action="store_false", default=True)
360 group.add_option("", "--no-long-long", dest="useLongLong",
361 help="do not generate long long types",
362 action="store_false", default=True)
363 group.add_option("", "--no-unsigned", dest="useUnsigned",
364 help="do not generate unsigned integer types",
365 action="store_false", default=True)
366
367 # Other builtins
368 group.add_option("", "--no-bool", dest="useBool",
369 help="do not generate bool types",
370 action="store_false", default=True)
371 group.add_option("", "--no-float", dest="useFloat",
372 help="do not generate float types",
373 action="store_false", default=True)
374 group.add_option("", "--no-double", dest="useDouble",
375 help="do not generate double types",
376 action="store_false", default=True)
377 group.add_option("", "--no-long-double", dest="useLongDouble",
378 help="do not generate long double types",
379 action="store_false", default=True)
380 group.add_option("", "--no-void-pointer", dest="useVoidPointer",
381 help="do not generate void* types",
382 action="store_false", default=True)
383
384 # Derived types
385 group.add_option("", "--no-array", dest="useArray",
386 help="do not generate record types",
387 action="store_false", default=True)
388 group.add_option("", "--no-complex", dest="useComplex",
389 help="do not generate complex types",
390 action="store_false", default=True)
391 group.add_option("", "--no-record", dest="useRecord",
392 help="do not generate record types",
393 action="store_false", default=True)
394 group.add_option("", "--no-union", dest="recordUseUnion",
395 help="do not generate union types",
396 action="store_false", default=True)
397 group.add_option("", "--no-vector", dest="useVector",
398 help="do not generate vector types",
399 action="store_false", default=True)
400
401 # Tuning
402 group.add_option("", "--no-function-return", dest="functionUseReturn",
403 help="do not generate return types for functions",
404 action="store_false", default=True)
405 group.add_option("", "--vector-sizes", dest="vectorSizes",
406 help="comma separated list of sizes for vectors [default %default]",
Daniel Dunbar5ce61572009-01-28 02:01:23 +0000407 action="store", type=str, default='8,16', metavar="N")
Daniel Dunbara83fb862009-01-15 04:24:17 +0000408
409 group.add_option("", "--max-args", dest="functionMaxArgs",
410 help="maximum number of arguments per function [default %default]",
411 action="store", type=int, default=4, metavar="N")
412 group.add_option("", "--max-array", dest="arrayMaxSize",
413 help="maximum array size [default %default]",
414 action="store", type=int, default=4, metavar="N")
415 group.add_option("", "--max-record", dest="recordMaxSize",
416 help="maximum number of fields per record [default %default]",
417 action="store", type=int, default=4, metavar="N")
418 group.add_option("", "--max-record-depth", dest="recordMaxDepth",
419 help="maximum nested structure depth [default %default]",
420 action="store", type=int, default=None, metavar="N")
421 parser.add_option_group(group)
422 (opts, args) = parser.parse_args()
423
424 if not opts.useRandomSeed:
425 random.seed(opts.seed)
426
427 # Contruct type generator
428 builtins = []
429 ints = []
Daniel Dunbar550faa32009-01-26 19:05:20 +0000430 if opts.useChar: ints.append(('char',1))
431 if opts.useShort: ints.append(('short',2))
432 if opts.useInt: ints.append(('int',4))
433 # FIXME: Wrong size.
434 if opts.useLong: ints.append(('long',4))
435 if opts.useLongLong: ints.append(('long long',8))
Daniel Dunbara83fb862009-01-15 04:24:17 +0000436 if opts.useUnsigned:
Daniel Dunbar550faa32009-01-26 19:05:20 +0000437 ints = ([('unsigned %s'%i,s) for i,s in ints] +
438 [('signed %s'%i,s) for i,s in ints])
Daniel Dunbara83fb862009-01-15 04:24:17 +0000439 builtins.extend(ints)
440
Daniel Dunbar550faa32009-01-26 19:05:20 +0000441 if opts.useBool: builtins.append(('_Bool',1))
442 if opts.useFloat: builtins.append(('float',4))
443 if opts.useDouble: builtins.append(('double',8))
444 if opts.useLongDouble: builtins.append(('long double',16))
445 # FIXME: Wrong size.
446 if opts.useVoidPointer: builtins.append(('void*',4))
Daniel Dunbara83fb862009-01-15 04:24:17 +0000447
Daniel Dunbar550faa32009-01-26 19:05:20 +0000448 btg = FixedTypeGenerator([BuiltinType(n,s) for n,s in builtins])
449 sbtg = FixedTypeGenerator([BuiltinType('char',1),
450 BuiltinType('int',4),
Daniel Dunbar5ce61572009-01-28 02:01:23 +0000451 BuiltinType('float',4),
452 BuiltinType('double',8)])
Daniel Dunbara83fb862009-01-15 04:24:17 +0000453
454 atg = AnyTypeGenerator()
455 artg = AnyTypeGenerator()
456 def makeGenerator(atg, subgen, useRecord, useArray):
457 atg.addGenerator(btg)
458 if useRecord and opts.useRecord:
459 assert subgen
460 atg.addGenerator(RecordTypeGenerator(subgen, opts.recordUseUnion,
461 opts.recordMaxSize))
462 if opts.useComplex:
463 # FIXME: Allow overriding builtins here
464 atg.addGenerator(ComplexTypeGenerator(sbtg))
465 if useArray and opts.useArray:
466 assert subgen
467 atg.addGenerator(ArrayTypeGenerator(subgen, opts.arrayMaxSize))
468 if opts.useVector:
469 atg.addGenerator(VectorTypeGenerator(sbtg,
470 map(int, opts.vectorSizes.split(','))))
471
472
473 if opts.recordMaxDepth is None:
474 # Fully recursive, just avoid top-level arrays.
475 subTG = AnyTypeGenerator()
476 atg = AnyTypeGenerator()
477 makeGenerator(subTG, atg, True, True)
478 makeGenerator(atg, subTG, True, False)
479 else:
480 # Make a chain of type generators, each builds smaller
481 # structures.
482 base = AnyTypeGenerator()
483 makeGenerator(base, None, False, False)
484 for i in range(opts.recordMaxDepth):
485 n = AnyTypeGenerator()
486 makeGenerator(n, base, True, True)
487 base = n
488 atg = AnyTypeGenerator()
489 makeGenerator(atg, base, True, False)
490
Daniel Dunbar5ce61572009-01-28 02:01:23 +0000491 if opts.testLayout:
492 ftg = atg
493 else:
494 ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs)
Daniel Dunbara83fb862009-01-15 04:24:17 +0000495
496 # Override max,min,count if finite
497 if opts.maxIndex is None:
498 if ftg.cardinality is aleph0:
499 opts.maxIndex = 10000000
500 else:
501 opts.maxIndex = ftg.cardinality
502 opts.maxIndex = min(opts.maxIndex, ftg.cardinality)
503 opts.minIndex = max(0,min(opts.maxIndex-1, opts.minIndex))
504 if not opts.mode=='random':
505 opts.count = min(opts.count, opts.maxIndex-opts.minIndex)
506
507 if opts.output=='-':
508 output = sys.stdout
509 else:
510 output = open(opts.output,'w')
511 atexit.register(lambda: output.close())
512
513 outputHeader = None
514 if opts.outputHeader:
515 outputHeader = open(opts.outputHeader,'w')
516 atexit.register(lambda: outputHeader.close())
517
518 outputTests = None
519 if opts.outputTests:
520 outputTests = open(opts.outputTests,'w')
521 atexit.register(lambda: outputTests.close())
522
523 outputDriver = None
524 if opts.outputDriver:
525 outputDriver = open(opts.outputDriver,'w')
526 atexit.register(lambda: outputDriver.close())
527
528 info = ''
529 info += '// %s\n'%(' '.join(sys.argv),)
530 info += '// Generated: %s\n'%(time.strftime('%Y-%m-%d %H:%M'),)
531 info += '// Cardinality of function generator: %s\n'%(ftg.cardinality,)
532 info += '// Cardinality of type generator: %s\n'%(atg.cardinality,)
Daniel Dunbar5ce61572009-01-28 02:01:23 +0000533
534 if opts.testLayout:
535 info += '\n#include <stdio.h>'
Daniel Dunbara83fb862009-01-15 04:24:17 +0000536
537 P = TypePrinter(output,
538 outputHeader=outputHeader,
539 outputTests=outputTests,
540 outputDriver=outputDriver,
Daniel Dunbar5ce61572009-01-28 02:01:23 +0000541 headerName=opts.outputHeader,
Daniel Dunbara83fb862009-01-15 04:24:17 +0000542 info=info)
543
544 def write(N):
Daniel Dunbar5ce61572009-01-28 02:01:23 +0000545 try:
Daniel Dunbara83fb862009-01-15 04:24:17 +0000546 FT = ftg.get(N)
547 except RuntimeError,e:
548 if e.args[0]=='maximum recursion depth exceeded':
549 print >>sys.stderr,'WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,)
550 return
551 raise
Daniel Dunbar5ce61572009-01-28 02:01:23 +0000552 if opts.testLayout:
553 P.writeLayoutTest(N, FT)
554 else:
555 P.writeFunction(N, FT)
Daniel Dunbara83fb862009-01-15 04:24:17 +0000556
557 if args:
558 [write(int(a)) for a in args]
559
560 for i in range(opts.count):
561 if opts.mode=='linear':
562 index = opts.minIndex + i
563 else:
564 index = opts.minIndex + int((opts.maxIndex-opts.minIndex) * random.random())
565 write(index)
566
567 P.finish()
568
569if __name__=='__main__':
570 main()
571