ABITestGen.py 29 KB

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