1201788c5659239effc07cd9445669d5422a71a9aEli Friedman#!/usr/bin/env python
2a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
3a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarfrom pprint import pprint
4a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarimport random, atexit, time
5a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarfrom random import randrange
6640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbarimport re
7a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
8a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarfrom Enumeration import *
9a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarfrom TypeGen import *
10a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
11a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar####
12a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
13a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass TypePrinter:
14a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, output, outputHeader=None,
15a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                 outputTests=None, outputDriver=None,
16a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                 headerName=None, info=None):
17a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.output = output
18a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.outputHeader = outputHeader
19a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.outputTests = outputTests
20a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.outputDriver = outputDriver
21a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.writeBody = outputHeader or outputTests or outputDriver
22a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.types = {}
23a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.testValues = {}
24a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.testReturnValues = {}
2551ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        self.layoutTests = []
266ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar        self.declarations = set()
27a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
28a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if info:
29a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for f in (self.output,self.outputHeader,self.outputTests,self.outputDriver):
30a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                if f:
31a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    print >>f,info
32a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
33a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.writeBody:
34a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.output, '#include <stdio.h>\n'
35a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if self.outputTests:
3638db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                print >>self.outputTests, '#include <stdio.h>'
3738db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                print >>self.outputTests, '#include <string.h>'
3838db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                print >>self.outputTests, '#include <assert.h>\n'
39a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
40a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if headerName:
41a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for f in (self.output,self.outputTests,self.outputDriver):
42a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                if f is not None:
43a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    print >>f, '#include "%s"\n'%(headerName,)
44a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
45a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.outputDriver:
46fdcc64fe7aeccb4b826a26aec8f2a33f2bbe54d6Douglas Gregor            print >>self.outputDriver, '#include <stdio.h>'
47fdcc64fe7aeccb4b826a26aec8f2a33f2bbe54d6Douglas Gregor            print >>self.outputDriver, '#include <stdlib.h>\n'
48a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.outputDriver, 'int main(int argc, char **argv) {'
499daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar            print >>self.outputDriver, '  int index = -1;'
509daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar            print >>self.outputDriver, '  if (argc > 1) index = atoi(argv[1]);'
51a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
52a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def finish(self):
5351ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        if self.layoutTests:
5451ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar            print >>self.output, 'int main(int argc, char **argv) {'
559daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar            print >>self.output, '  int index = -1;'
569daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar            print >>self.output, '  if (argc > 1) index = atoi(argv[1]);'
579daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar            for i,f in self.layoutTests:
589daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar                print >>self.output, '  if (index == -1 || index == %d)' % i
599daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar                print >>self.output, '    %s();' % f
6051ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar            print >>self.output, '  return 0;'
6151ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar            print >>self.output, '}'
6251ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar
63a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.outputDriver:
6438db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar            print >>self.outputDriver, '  printf("DONE\\n");'
65a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.outputDriver, '  return 0;'
6651ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar            print >>self.outputDriver, '}'
67a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
686ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar    def addDeclaration(self, decl):
696ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar        if decl in self.declarations:
706ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar            return False
716ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar
726ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar        self.declarations.add(decl)
736ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar        if self.outputHeader:
746ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar            print >>self.outputHeader, decl
756ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar        else:
766ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar            print >>self.output, decl
776ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar            if self.outputTests:
786ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar                print >>self.outputTests, decl
796ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar        return True
806ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar
81a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTypeName(self, T):
82a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        name = self.types.get(T)
83a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if name is None:
84a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            # Reserve slot
85a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            self.types[T] = None
866ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar            self.types[T] = name = T.getTypeName(self)
87a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return name
88a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
8951ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar    def writeLayoutTest(self, i, ty):
9051ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        tyName = self.getTypeName(ty)
9151ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        tyNameClean = tyName.replace(' ','_').replace('*','star')
9251ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        fnName = 'test_%s' % tyNameClean
9351ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar
9451ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        print >>self.output,'void %s(void) {' % fnName
9551ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        self.printSizeOfType('    %s'%fnName, tyName, ty, self.output)
9651ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        self.printAlignOfType('    %s'%fnName, tyName, ty, self.output)
9751ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        self.printOffsetsOfType('    %s'%fnName, tyName, ty, self.output)
9851ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        print >>self.output,'}'
9951ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        print >>self.output
10051ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar
1019daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar        self.layoutTests.append((i,fnName))
10251ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar
103a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def writeFunction(self, i, FT):
104a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        args = ', '.join(['%s arg%d'%(self.getTypeName(t),i) for i,t in enumerate(FT.argTypes)])
105a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if not args:
106a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            args = 'void'
107a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
108a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if FT.returnType is None:
109a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            retvalName = None
110a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            retvalTypeName = 'void'
111a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
112a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            retvalTypeName = self.getTypeName(FT.returnType)
113a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if self.writeBody or self.outputTests:
114a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                retvalName = self.getTestReturnValue(FT.returnType)
115a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
116a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        fnName = 'fn%d'%(FT.index,)
117a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.outputHeader:
118a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.outputHeader,'%s %s(%s);'%(retvalTypeName, fnName, args)
119a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        elif self.outputTests:
120a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.outputTests,'%s %s(%s);'%(retvalTypeName, fnName, args)
121a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
122a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        print >>self.output,'%s %s(%s)'%(retvalTypeName, fnName, args),
123a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.writeBody:
124a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.output, '{'
125a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
126a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for i,t in enumerate(FT.argTypes):
127a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                self.printValueOfType('    %s'%fnName, 'arg%d'%i, t)
128a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
129a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if retvalName is not None:
130a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.output, '  return %s;'%(retvalName,)
131a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.output, '}'
132a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
133a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.output, '{}'
134a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        print >>self.output
135a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
136a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.outputDriver:
1379daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar            print >>self.outputDriver, '  if (index == -1 || index == %d) {' % i
1389daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar            print >>self.outputDriver, '    extern void test_%s(void);' % fnName
1399daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar            print >>self.outputDriver, '    test_%s();' % fnName
1409daf29a87644c97f4219a8f7f6fe035fb0372be3Daniel Dunbar            print >>self.outputDriver, '   }'
141a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
142a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.outputTests:
143a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if self.outputHeader:
144a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.outputHeader, 'void test_%s(void);'%(fnName,)
145a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
146a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if retvalName is None:
147a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                retvalTests = None
148a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            else:
149a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                retvalTests = self.getTestValuesArray(FT.returnType)
150a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            tests = map(self.getTestValuesArray, FT.argTypes)
151a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.outputTests, 'void test_%s(void) {'%(fnName,)
152a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
153a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if retvalTests is not None:
154a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.outputTests, '  printf("%s: testing return.\\n");'%(fnName,)
155a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.outputTests, '  for (int i=0; i<%d; ++i) {'%(retvalTests[1],)
156a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                args = ', '.join(['%s[%d]'%(t,randrange(l)) for t,l in tests])
157a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.outputTests, '    %s RV;'%(retvalTypeName,)
158a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.outputTests, '    %s = %s[i];'%(retvalName, retvalTests[0])
159a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.outputTests, '    RV = %s(%s);'%(fnName, args)
160a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                self.printValueOfType('  %s_RV'%fnName, 'RV', FT.returnType, output=self.outputTests, indent=4)
16138db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                self.checkTypeValues('RV', '%s[i]' % retvalTests[0], FT.returnType, output=self.outputTests, indent=4)
162a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.outputTests, '  }'
163a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
164a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if tests:
165a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.outputTests, '  printf("%s: testing arguments.\\n");'%(fnName,)
166a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for i,(array,length) in enumerate(tests):
167a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                for j in range(length):
168a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    args = ['%s[%d]'%(t,randrange(l)) for t,l in tests]
169a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    args[i] = '%s[%d]'%(array,j)
170a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    print >>self.outputTests, '  %s(%s);'%(fnName, ', '.join(args),)
171a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.outputTests, '}'
172a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
173a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTestReturnValue(self, type):
174a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        typeName = self.getTypeName(type)
175a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        info = self.testReturnValues.get(typeName)
176a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if info is None:
177a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            name = '%s_retval'%(typeName.replace(' ','_').replace('*','star'),)
178a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.output, '%s %s;'%(typeName,name)
179a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if self.outputHeader:
180a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.outputHeader, 'extern %s %s;'%(typeName,name)
181a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            elif self.outputTests:
182a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.outputTests, 'extern %s %s;'%(typeName,name)
183a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            info = self.testReturnValues[typeName] = name
184a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return info
185a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
186a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTestValuesArray(self, type):
187a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        typeName = self.getTypeName(type)
188a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        info = self.testValues.get(typeName)
189a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if info is None:
190a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            name = '%s_values'%(typeName.replace(' ','_').replace('*','star'),)
191a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.outputTests, 'static %s %s[] = {'%(typeName,name)
192a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            length = 0
193a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for item in self.getTestValues(type):
194a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>self.outputTests, '\t%s,'%(item,)
195a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                length += 1
196a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            print >>self.outputTests,'};'
197a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            info = self.testValues[typeName] = (name,length)
198a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return info
199a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
200a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTestValues(self, t):
201a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if isinstance(t, BuiltinType):
202a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if t.name=='float':
203a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                for i in ['0.0','-1.0','1.0']:
204a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    yield i+'f'
205a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            elif t.name=='double':
206a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                for i in ['0.0','-1.0','1.0']:
207a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    yield i
208a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            elif t.name in ('void *'):
209a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                yield '(void*) 0'
210a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                yield '(void*) -1'
211a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            else:
212a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                yield '(%s) 0'%(t.name,)
213a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                yield '(%s) -1'%(t.name,)
214a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                yield '(%s) 1'%(t.name,)
21543ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor        elif isinstance(t, EnumType):
21643ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor            for i in range(0, len(t.enumerators)):
21743ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor                yield 'enum%dval%d' % (t.index, i)
218a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        elif isinstance(t, RecordType):
2199c7e5fbf0585e9abe72381ca5393c8897f98ecdbDaniel Dunbar            nonPadding = [f for f in t.fields
2209c7e5fbf0585e9abe72381ca5393c8897f98ecdbDaniel Dunbar                          if not f.isPaddingBitField()]
2219c7e5fbf0585e9abe72381ca5393c8897f98ecdbDaniel Dunbar
2229c7e5fbf0585e9abe72381ca5393c8897f98ecdbDaniel Dunbar            if not nonPadding:
223a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                yield '{ }'
2247700dca76b833927b6dc9b92f050be6e6ba93038Daniel Dunbar                return
2259c7e5fbf0585e9abe72381ca5393c8897f98ecdbDaniel Dunbar
2267700dca76b833927b6dc9b92f050be6e6ba93038Daniel Dunbar            # FIXME: Use designated initializers to access non-first
2277700dca76b833927b6dc9b92f050be6e6ba93038Daniel Dunbar            # fields of unions.
2287700dca76b833927b6dc9b92f050be6e6ba93038Daniel Dunbar            if t.isUnion:
2299c7e5fbf0585e9abe72381ca5393c8897f98ecdbDaniel Dunbar                for v in self.getTestValues(nonPadding[0]):
2309c7e5fbf0585e9abe72381ca5393c8897f98ecdbDaniel Dunbar                    yield '{ %s }' % v
2317700dca76b833927b6dc9b92f050be6e6ba93038Daniel Dunbar                return
2329c7e5fbf0585e9abe72381ca5393c8897f98ecdbDaniel Dunbar
2339c7e5fbf0585e9abe72381ca5393c8897f98ecdbDaniel Dunbar            fieldValues = map(list, map(self.getTestValues, nonPadding))
234a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for i,values in enumerate(fieldValues):
235a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                for v in values:
236a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    elements = map(random.choice,fieldValues)
237a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    elements[i] = v
238a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    yield '{ %s }'%(', '.join(elements))
2399c7e5fbf0585e9abe72381ca5393c8897f98ecdbDaniel Dunbar
240a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        elif isinstance(t, ComplexType):
241a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for t in self.getTestValues(t.elementType):
242789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar                yield '%s + %s * 1i'%(t,t)
243789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar        elif isinstance(t, ArrayType):
244a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            values = list(self.getTestValues(t.elementType))
245a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if not values:
246a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                yield '{ }'
247789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar            for i in range(t.numElements):
248a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                for v in values:
249789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar                    elements = [random.choice(values) for i in range(t.numElements)]
250a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    elements[i] = v
251a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    yield '{ %s }'%(', '.join(elements))
252a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
253a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            raise NotImplementedError,'Cannot make tests values of type: "%s"'%(t,)
254a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
25551ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar    def printSizeOfType(self, prefix, name, t, output=None, indent=2):
2567020cf4faf2440b35f9c8daa7e16a65c5cafaca0Eli Friedman        print >>output, '%*sprintf("%s: sizeof(%s) = %%ld\\n", (long)sizeof(%s));'%(indent, '', prefix, name, name)
25751ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar    def printAlignOfType(self, prefix, name, t, output=None, indent=2):
2587020cf4faf2440b35f9c8daa7e16a65c5cafaca0Eli Friedman        print >>output, '%*sprintf("%s: __alignof__(%s) = %%ld\\n", (long)__alignof__(%s));'%(indent, '', prefix, name, name)
25951ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar    def printOffsetsOfType(self, prefix, name, t, output=None, indent=2):
26051ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        if isinstance(t, RecordType):
26151ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar            for i,f in enumerate(t.fields):
2627020cf4faf2440b35f9c8daa7e16a65c5cafaca0Eli Friedman                if f.isBitField():
26398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                    continue
26451ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar                fname = 'field%d' % i
2657020cf4faf2440b35f9c8daa7e16a65c5cafaca0Eli Friedman                print >>output, '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", (long)__builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname)
26651ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar
267a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def printValueOfType(self, prefix, name, t, output=None, indent=2):
268a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if output is None:
269a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            output = self.output
270a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if isinstance(t, BuiltinType):
271ec2a646ea5659ff1231818fe4c5f72402398b403Daniel Dunbar            value_expr = name
272ec2a646ea5659ff1231818fe4c5f72402398b403Daniel Dunbar            if t.name.split(' ')[-1] == '_Bool':
273ec2a646ea5659ff1231818fe4c5f72402398b403Daniel Dunbar                # Hack to work around PR5579.
274ec2a646ea5659ff1231818fe4c5f72402398b403Daniel Dunbar                value_expr = "%s ? 2 : 0" % name
275ec2a646ea5659ff1231818fe4c5f72402398b403Daniel Dunbar
276a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if t.name.endswith('long long'):
277a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                code = 'lld'
278a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            elif t.name.endswith('long'):
279a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                code = 'ld'
280586e4707d71aff4e184e0999970e446d7f39cc44Daniel Dunbar            elif t.name.split(' ')[-1] in ('_Bool','char','short',
281586e4707d71aff4e184e0999970e446d7f39cc44Daniel Dunbar                                           'int','unsigned'):
282a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                code = 'd'
283a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            elif t.name in ('float','double'):
284a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                code = 'f'
285a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            elif t.name == 'long double':
286a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                code = 'Lf'
287a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            else:
288a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                code = 'p'
289ec2a646ea5659ff1231818fe4c5f72402398b403Daniel Dunbar            print >>output, '%*sprintf("%s: %s = %%%s\\n", %s);'%(
290ec2a646ea5659ff1231818fe4c5f72402398b403Daniel Dunbar                indent, '', prefix, name, code, value_expr)
29143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor        elif isinstance(t, EnumType):
29243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor            print >>output, '%*sprintf("%s: %s = %%d\\n", %s);'%(indent, '', prefix, name, name)
293a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        elif isinstance(t, RecordType):
294a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if not t.fields:
295a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>output, '%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name)
296a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for i,f in enumerate(t.fields):
29798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                if f.isPaddingBitField():
29898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                    continue
299a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                fname = '%s.field%d'%(name,i)
300a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                self.printValueOfType(prefix, fname, f, output=output, indent=indent)
301a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        elif isinstance(t, ComplexType):
302a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            self.printValueOfType(prefix, '(__real %s)'%name, t.elementType, output=output,indent=indent)
303a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            self.printValueOfType(prefix, '(__imag %s)'%name, t.elementType, output=output,indent=indent)
304789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar        elif isinstance(t, ArrayType):
305789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar            for i in range(t.numElements):
306789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar                # Access in this fashion as a hackish way to portably
307789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar                # access vectors.
308e8c55b407d8fc494d814d5fda256a47f27ace3a5Daniel Dunbar                if t.isVector:
309e8c55b407d8fc494d814d5fda256a47f27ace3a5Daniel Dunbar                    self.printValueOfType(prefix, '((%s*) &%s)[%d]'%(t.elementType,name,i), t.elementType, output=output,indent=indent)
310e8c55b407d8fc494d814d5fda256a47f27ace3a5Daniel Dunbar                else:
311e8c55b407d8fc494d814d5fda256a47f27ace3a5Daniel Dunbar                    self.printValueOfType(prefix, '%s[%d]'%(name,i), t.elementType, output=output,indent=indent)
312a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
313a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            raise NotImplementedError,'Cannot print value of type: "%s"'%(t,)
314a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
31538db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar    def checkTypeValues(self, nameLHS, nameRHS, t, output=None, indent=2):
31638db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar        prefix = 'foo'
31738db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar        if output is None:
31838db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar            output = self.output
31938db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar        if isinstance(t, BuiltinType):
32038db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar            print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
32143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor        elif isinstance(t, EnumType):
32243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor            print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
32338db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar        elif isinstance(t, RecordType):
32438db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar            for i,f in enumerate(t.fields):
32598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                if f.isPaddingBitField():
32698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                    continue
32738db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                self.checkTypeValues('%s.field%d'%(nameLHS,i), '%s.field%d'%(nameRHS,i),
32838db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                                     f, output=output, indent=indent)
32938db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                if t.isUnion:
33038db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                    break
33138db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar        elif isinstance(t, ComplexType):
33238db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar            self.checkTypeValues('(__real %s)'%nameLHS, '(__real %s)'%nameRHS, t.elementType, output=output,indent=indent)
33338db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar            self.checkTypeValues('(__imag %s)'%nameLHS, '(__imag %s)'%nameRHS, t.elementType, output=output,indent=indent)
33438db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar        elif isinstance(t, ArrayType):
33538db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar            for i in range(t.numElements):
33638db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                # Access in this fashion as a hackish way to portably
33738db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                # access vectors.
33838db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                if t.isVector:
33938db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                    self.checkTypeValues('((%s*) &%s)[%d]'%(t.elementType,nameLHS,i),
34038db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                                         '((%s*) &%s)[%d]'%(t.elementType,nameRHS,i),
34138db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                                         t.elementType, output=output,indent=indent)
34238db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                else:
34338db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                    self.checkTypeValues('%s[%d]'%(nameLHS,i), '%s[%d]'%(nameRHS,i),
34438db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar                                         t.elementType, output=output,indent=indent)
34538db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar        else:
34638db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar            raise NotImplementedError,'Cannot print value of type: "%s"'%(t,)
34738db555e51aedd0f545524c5c0f6f7744066a36cDaniel Dunbar
348a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarimport sys
349a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
350a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbardef main():
351a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    from optparse import OptionParser, OptionGroup
352a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser = OptionParser("%prog [options] {indices}")
353a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser.add_option("", "--mode", dest="mode",
354a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      help="autogeneration mode (random or linear) [default %default]",
355a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      type='choice', choices=('random','linear'), default='linear')
356a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser.add_option("", "--count", dest="count",
357a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      help="autogenerate COUNT functions according to MODE",
358a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      type=int, default=0)
359a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser.add_option("", "--min", dest="minIndex", metavar="N",
360a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      help="start autogeneration with the Nth function type  [default %default]",
361a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      type=int, default=0)
362a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser.add_option("", "--max", dest="maxIndex", metavar="N",
363a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      help="maximum index for random autogeneration  [default %default]",
364a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      type=int, default=10000000)
365a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser.add_option("", "--seed", dest="seed",
366a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      help="random number generator seed [default %default]",
367a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      type=int, default=1)
368a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser.add_option("", "--use-random-seed", dest="useRandomSeed",
369a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      help="use random value for initial random number generator seed",
370a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      action='store_true', default=False)
3718012bf9e5e49685a68533c2cba1764c4acead2a2Daniel Dunbar    parser.add_option("", "--skip", dest="skipTests",
3728012bf9e5e49685a68533c2cba1764c4acead2a2Daniel Dunbar                      help="add a test index to skip",
3738012bf9e5e49685a68533c2cba1764c4acead2a2Daniel Dunbar                      type=int, action='append', default=[])
374a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser.add_option("-o", "--output", dest="output", metavar="FILE",
375a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      help="write output to FILE  [default %default]",
376a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      type=str, default='-')
377a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser.add_option("-O", "--output-header", dest="outputHeader", metavar="FILE",
378a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      help="write header file for output to FILE  [default %default]",
379a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      type=str, default=None)
380a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser.add_option("-T", "--output-tests", dest="outputTests", metavar="FILE",
381a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      help="write function tests to FILE  [default %default]",
382a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      type=str, default=None)
383a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser.add_option("-D", "--output-driver", dest="outputDriver", metavar="FILE",
384a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      help="write test driver to FILE  [default %default]",
385a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                      type=str, default=None)
38651ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar    parser.add_option("", "--test-layout", dest="testLayout", metavar="FILE",
38751ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar                      help="test structure layout",
38851ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar                      action='store_true', default=False)
389a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
390a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group = OptionGroup(parser, "Type Enumeration Options")
391a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    # Builtins - Ints
392a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-char", dest="useChar",
393a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate char types",
394a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
395a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-short", dest="useShort",
396a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate short types",
397a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
398a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-int", dest="useInt",
399a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate int types",
400a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
401a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-long", dest="useLong",
402a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate long types",
403a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
404a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-long-long", dest="useLongLong",
405a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate long long types",
406a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
407a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-unsigned", dest="useUnsigned",
408a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate unsigned integer types",
409a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
410a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
411a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    # Other builtins
412a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-bool", dest="useBool",
413a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate bool types",
414a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
415a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-float", dest="useFloat",
416a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate float types",
417a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
418a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-double", dest="useDouble",
419a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate double types",
420a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
421a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-long-double", dest="useLongDouble",
422a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate long double types",
423a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
424a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-void-pointer", dest="useVoidPointer",
425a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate void* types",
426a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
427a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
42843ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor    # Enumerations
42943ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor    group.add_option("", "--no-enums", dest="useEnum",
43043ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor                     help="do not generate enum types",
43143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor                     action="store_false", default=True)
43243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor
433a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    # Derived types
434a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-array", dest="useArray",
435a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate record types",
436a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
437a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-complex", dest="useComplex",
438a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate complex types",
439a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
440a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-record", dest="useRecord",
441a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate record types",
442a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
443a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-union", dest="recordUseUnion",
444a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate union types",
445a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
446a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-vector", dest="useVector",
447a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate vector types",
448a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
44998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    group.add_option("", "--no-bit-field", dest="useBitField",
45098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                     help="do not generate bit-field record members",
45198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                     action="store_false", default=True)
45298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    group.add_option("", "--no-builtins", dest="useBuiltins",
45398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                     help="do not use any types",
45498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                     action="store_false", default=True)
455a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
456a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    # Tuning
457a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--no-function-return", dest="functionUseReturn",
458a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="do not generate return types for functions",
459a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store_false", default=True)
460640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar    group.add_option("", "--vector-types", dest="vectorTypes",
461640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                     help="comma separated list of vector types (e.g., v2i32) [default %default]",
462db85a63cc3643655bea26b468761f27a560e4364Daniel Dunbar                     action="store", type=str, default='v2i16, v1i64, v2i32, v4i16, v8i8, v2f32, v2i64, v4i32, v8i16, v16i8, v2f64, v4f32, v16f32', metavar="N")
46398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    group.add_option("", "--bit-fields", dest="bitFields",
46498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                     help="comma separated list 'type:width' bit-field specifiers [default %default]",
465586e4707d71aff4e184e0999970e446d7f39cc44Daniel Dunbar                     action="store", type=str, default=(
466586e4707d71aff4e184e0999970e446d7f39cc44Daniel Dunbar            "char:0,char:4,int:0,unsigned:1,int:1,int:4,int:13,int:24"))
467a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--max-args", dest="functionMaxArgs",
468a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="maximum number of arguments per function [default %default]",
469a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store", type=int, default=4, metavar="N")
470a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--max-array", dest="arrayMaxSize",
471a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="maximum array size [default %default]",
472a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store", type=int, default=4, metavar="N")
473a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--max-record", dest="recordMaxSize",
474a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="maximum number of fields per record [default %default]",
475a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store", type=int, default=4, metavar="N")
476a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    group.add_option("", "--max-record-depth", dest="recordMaxDepth",
477a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     help="maximum nested structure depth [default %default]",
478a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                     action="store", type=int, default=None, metavar="N")
479a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    parser.add_option_group(group)
480a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    (opts, args) = parser.parse_args()
481a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
482a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    if not opts.useRandomSeed:
483a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        random.seed(opts.seed)
484a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
485a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    # Contruct type generator
486a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    builtins = []
48798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    if opts.useBuiltins:
48898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        ints = []
48998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if opts.useChar: ints.append(('char',1))
49098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if opts.useShort: ints.append(('short',2))
49198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if opts.useInt: ints.append(('int',4))
49298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        # FIXME: Wrong size.
49398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if opts.useLong: ints.append(('long',4))
49498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if opts.useLongLong: ints.append(('long long',8))
49598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if opts.useUnsigned:
49698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            ints = ([('unsigned %s'%i,s) for i,s in ints] +
49798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                    [('signed %s'%i,s) for i,s in ints])
49898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        builtins.extend(ints)
49998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar
50098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if opts.useBool: builtins.append(('_Bool',1))
50198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if opts.useFloat: builtins.append(('float',4))
50298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if opts.useDouble: builtins.append(('double',8))
50398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if opts.useLongDouble: builtins.append(('long double',16))
50498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        # FIXME: Wrong size.
50598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if opts.useVoidPointer:  builtins.append(('void*',4))
506a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
507789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar    btg = FixedTypeGenerator([BuiltinType(n,s) for n,s in builtins])
50898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar
50998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    bitfields = []
51098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    for specifier in opts.bitFields.split(','):
51198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if not specifier.strip():
51298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            continue
51398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        name,width = specifier.strip().split(':', 1)
51498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        bitfields.append(BuiltinType(name,None,int(width)))
51598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    bftg = FixedTypeGenerator(bitfields)
51698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar
517640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar    charType = BuiltinType('char',1)
518640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar    shortType = BuiltinType('short',2)
519640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar    intType = BuiltinType('int',4)
520640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar    longlongType = BuiltinType('long long',8)
521640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar    floatType = BuiltinType('float',4)
522640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar    doubleType = BuiltinType('double',8)
523640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar    sbtg = FixedTypeGenerator([charType, intType, floatType, doubleType])
524a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
525a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    atg = AnyTypeGenerator()
526a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    artg = AnyTypeGenerator()
52798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    def makeGenerator(atg, subgen, subfieldgen, useRecord, useArray, useBitField):
528a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        atg.addGenerator(btg)
52998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if useBitField and opts.useBitField:
53098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            atg.addGenerator(bftg)
531a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if useRecord and opts.useRecord:
532a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            assert subgen
53398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            atg.addGenerator(RecordTypeGenerator(subfieldgen, opts.recordUseUnion,
534a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                                                 opts.recordMaxSize))
535a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if opts.useComplex:
536a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            # FIXME: Allow overriding builtins here
537a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            atg.addGenerator(ComplexTypeGenerator(sbtg))
538a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if useArray and opts.useArray:
539a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            assert subgen
540a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            atg.addGenerator(ArrayTypeGenerator(subgen, opts.arrayMaxSize))
541a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if opts.useVector:
542640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar            vTypes = []
543640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar            for i,t in enumerate(opts.vectorTypes.split(',')):
544640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                m = re.match('v([1-9][0-9]*)([if][1-9][0-9]*)', t.strip())
545640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                if not m:
546640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                    parser.error('Invalid vector type: %r' % t)
547640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                count,kind = m.groups()
548640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                count = int(count)
549640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                type = { 'i8'  : charType,
550640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                         'i16' : shortType,
551640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                         'i32' : intType,
552640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                         'i64' : longlongType,
553640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                         'f32' : floatType,
554640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                         'f64' : doubleType,
555640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                         }.get(kind)
556640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                if not type:
557640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                    parser.error('Invalid vector type: %r' % t)
558640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar                vTypes.append(ArrayType(i, True, type, count * type.size))
559640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar
560640cdd4be7aca168f7c91db9e1b86370a512eb0eDaniel Dunbar            atg.addGenerator(FixedTypeGenerator(vTypes))
56143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor        if opts.useEnum:
56243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor            atg.addGenerator(EnumTypeGenerator([None, '-1', '1', '1u'], 1, 4))
563a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
564a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    if opts.recordMaxDepth is None:
565a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        # Fully recursive, just avoid top-level arrays.
56698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        subFTG = AnyTypeGenerator()
567a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        subTG = AnyTypeGenerator()
568a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        atg = AnyTypeGenerator()
56998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        makeGenerator(subFTG, atg, atg, True, True, True)
57098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        makeGenerator(subTG, atg, subFTG, True, True, False)
57198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        makeGenerator(atg, subTG, subFTG, True, False, False)
572a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    else:
573a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        # Make a chain of type generators, each builds smaller
574a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        # structures.
575a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        base = AnyTypeGenerator()
57698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        fbase = AnyTypeGenerator()
57798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        makeGenerator(base, None, None, False, False, False)
57898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        makeGenerator(fbase, None, None, False, False, True)
579a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        for i in range(opts.recordMaxDepth):
580a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            n = AnyTypeGenerator()
58198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            fn = AnyTypeGenerator()
58298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            makeGenerator(n, base, fbase, True, True, False)
58398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            makeGenerator(fn, base, fbase, True, True, True)
584a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            base = n
58598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            fbase = fn
586a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        atg = AnyTypeGenerator()
58798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        makeGenerator(atg, base, fbase, True, False, False)
588a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
58951ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar    if opts.testLayout:
59051ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        ftg = atg
59151ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar    else:
59251ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs)
593a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
594a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    # Override max,min,count if finite
595a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    if opts.maxIndex is None:
596a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if ftg.cardinality is aleph0:
597a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            opts.maxIndex = 10000000
598a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
599a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            opts.maxIndex = ftg.cardinality
600a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    opts.maxIndex = min(opts.maxIndex, ftg.cardinality)
601a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    opts.minIndex = max(0,min(opts.maxIndex-1, opts.minIndex))
602a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    if not opts.mode=='random':
603a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        opts.count = min(opts.count, opts.maxIndex-opts.minIndex)
604a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
605a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    if opts.output=='-':
606a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        output = sys.stdout
607a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    else:
608a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        output = open(opts.output,'w')
609a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        atexit.register(lambda: output.close())
610a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
611a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    outputHeader = None
612a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    if opts.outputHeader:
613a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        outputHeader = open(opts.outputHeader,'w')
614a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        atexit.register(lambda: outputHeader.close())
615a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
616a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    outputTests = None
617a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    if opts.outputTests:
618a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        outputTests = open(opts.outputTests,'w')
619a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        atexit.register(lambda: outputTests.close())
620a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
621a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    outputDriver = None
622a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    if opts.outputDriver:
623a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        outputDriver = open(opts.outputDriver,'w')
624a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        atexit.register(lambda: outputDriver.close())
625a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
626a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    info = ''
627a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    info += '// %s\n'%(' '.join(sys.argv),)
628a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    info += '// Generated: %s\n'%(time.strftime('%Y-%m-%d %H:%M'),)
629a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    info += '// Cardinality of function generator: %s\n'%(ftg.cardinality,)
630a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    info += '// Cardinality of type generator: %s\n'%(atg.cardinality,)
63151ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar
63251ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar    if opts.testLayout:
63351ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        info += '\n#include <stdio.h>'
634a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
635a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    P = TypePrinter(output,
636a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    outputHeader=outputHeader,
637a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    outputTests=outputTests,
638a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    outputDriver=outputDriver,
63951ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar                    headerName=opts.outputHeader,
640a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                    info=info)
641a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
642a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def write(N):
64351ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        try:
644a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            FT = ftg.get(N)
645a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        except RuntimeError,e:
646a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if e.args[0]=='maximum recursion depth exceeded':
647a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                print >>sys.stderr,'WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,)
648a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                return
649a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            raise
65051ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        if opts.testLayout:
65151ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar            P.writeLayoutTest(N, FT)
65251ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar        else:
65351ae63c2378b866ad879b2adb00d460f7af7434bDaniel Dunbar            P.writeFunction(N, FT)
654a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
655a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    if args:
656a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        [write(int(a)) for a in args]
657a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
6588012bf9e5e49685a68533c2cba1764c4acead2a2Daniel Dunbar    skipTests = set(opts.skipTests)
659a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    for i in range(opts.count):
660a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if opts.mode=='linear':
661a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            index = opts.minIndex + i
662a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
663a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            index = opts.minIndex + int((opts.maxIndex-opts.minIndex) * random.random())
6648012bf9e5e49685a68533c2cba1764c4acead2a2Daniel Dunbar        if index in skipTests:
6658012bf9e5e49685a68533c2cba1764c4acead2a2Daniel Dunbar            continue
666a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        write(index)
667a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
668a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    P.finish()
669a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
670a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarif __name__=='__main__':
671a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    main()
672a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
673