177a1fe945b3d0f1efa22e9d36a8ea7e272dd93c2Eli Friedman#!/usr/bin/env python
2a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
3a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbarfrom pprint import pprint
4a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbarimport random, atexit, time
5a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbarfrom random import randrange
60f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbarimport re
7a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
8a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbarfrom Enumeration import *
9a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbarfrom TypeGen import *
10a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
11a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar####
12a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
13a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbarclass TypePrinter:
14a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    def __init__(self, output, outputHeader=None,
15a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                 outputTests=None, outputDriver=None,
16a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                 headerName=None, info=None):
17a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        self.output = output
18a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        self.outputHeader = outputHeader
19a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        self.outputTests = outputTests
20a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        self.outputDriver = outputDriver
21a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        self.writeBody = outputHeader or outputTests or outputDriver
22a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        self.types = {}
23a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        self.testValues = {}
24a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        self.testReturnValues = {}
255ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        self.layoutTests = []
267b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar        self.declarations = set()
27a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
28a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if info:
29a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            for f in (self.output,self.outputHeader,self.outputTests,self.outputDriver):
30a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                if f:
31a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    print >>f,info
32a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
33a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if self.writeBody:
34a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.output, '#include <stdio.h>\n'
35a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if self.outputTests:
369dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                print >>self.outputTests, '#include <stdio.h>'
379dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                print >>self.outputTests, '#include <string.h>'
389dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                print >>self.outputTests, '#include <assert.h>\n'
39a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
40a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if headerName:
41a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            for f in (self.output,self.outputTests,self.outputDriver):
42a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                if f is not None:
43a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    print >>f, '#include "%s"\n'%(headerName,)
44a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
45a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if self.outputDriver:
46c6277a0a42f7fc4f1b5df6fb83c0af2f14245e9bDouglas Gregor            print >>self.outputDriver, '#include <stdio.h>'
47c6277a0a42f7fc4f1b5df6fb83c0af2f14245e9bDouglas Gregor            print >>self.outputDriver, '#include <stdlib.h>\n'
48a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.outputDriver, 'int main(int argc, char **argv) {'
49484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar            print >>self.outputDriver, '  int index = -1;'
50484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar            print >>self.outputDriver, '  if (argc > 1) index = atoi(argv[1]);'
51a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
52a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    def finish(self):
535ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        if self.layoutTests:
545ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar            print >>self.output, 'int main(int argc, char **argv) {'
55484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar            print >>self.output, '  int index = -1;'
56484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar            print >>self.output, '  if (argc > 1) index = atoi(argv[1]);'
57484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar            for i,f in self.layoutTests:
58484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar                print >>self.output, '  if (index == -1 || index == %d)' % i
59484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar                print >>self.output, '    %s();' % f
605ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar            print >>self.output, '  return 0;'
615ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar            print >>self.output, '}'
625ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar
63a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if self.outputDriver:
649dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar            print >>self.outputDriver, '  printf("DONE\\n");'
65a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.outputDriver, '  return 0;'
665ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar            print >>self.outputDriver, '}'
67a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
687b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar    def addDeclaration(self, decl):
697b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar        if decl in self.declarations:
707b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar            return False
717b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar
727b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar        self.declarations.add(decl)
737b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar        if self.outputHeader:
747b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar            print >>self.outputHeader, decl
757b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar        else:
767b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar            print >>self.output, decl
777b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar            if self.outputTests:
787b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar                print >>self.outputTests, decl
797b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar        return True
807b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar
81a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    def getTypeName(self, T):
82a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        name = self.types.get(T)
83a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if name is None:
84a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            # Reserve slot
85a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            self.types[T] = None
867b1ab134383b0ecb1a3c9042e5da227e94c111caDaniel Dunbar            self.types[T] = name = T.getTypeName(self)
87a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        return name
88a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
895ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar    def writeLayoutTest(self, i, ty):
905ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        tyName = self.getTypeName(ty)
915ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        tyNameClean = tyName.replace(' ','_').replace('*','star')
925ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        fnName = 'test_%s' % tyNameClean
935ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar
945ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        print >>self.output,'void %s(void) {' % fnName
955ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        self.printSizeOfType('    %s'%fnName, tyName, ty, self.output)
965ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        self.printAlignOfType('    %s'%fnName, tyName, ty, self.output)
975ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        self.printOffsetsOfType('    %s'%fnName, tyName, ty, self.output)
985ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        print >>self.output,'}'
995ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        print >>self.output
1005ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar
101484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar        self.layoutTests.append((i,fnName))
1025ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar
103a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    def writeFunction(self, i, FT):
104a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        args = ', '.join(['%s arg%d'%(self.getTypeName(t),i) for i,t in enumerate(FT.argTypes)])
105a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if not args:
106a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            args = 'void'
107a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
108a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if FT.returnType is None:
109a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            retvalName = None
110a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            retvalTypeName = 'void'
111a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        else:
112a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            retvalTypeName = self.getTypeName(FT.returnType)
113a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if self.writeBody or self.outputTests:
114a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                retvalName = self.getTestReturnValue(FT.returnType)
115a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
116a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        fnName = 'fn%d'%(FT.index,)
117a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if self.outputHeader:
118a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.outputHeader,'%s %s(%s);'%(retvalTypeName, fnName, args)
119a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        elif self.outputTests:
120a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.outputTests,'%s %s(%s);'%(retvalTypeName, fnName, args)
121a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
122a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        print >>self.output,'%s %s(%s)'%(retvalTypeName, fnName, args),
123a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if self.writeBody:
124a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.output, '{'
125a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
126a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            for i,t in enumerate(FT.argTypes):
127a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                self.printValueOfType('    %s'%fnName, 'arg%d'%i, t)
128a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
129a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if retvalName is not None:
130a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.output, '  return %s;'%(retvalName,)
131a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.output, '}'
132a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        else:
133a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.output, '{}'
134a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        print >>self.output
135a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
136a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if self.outputDriver:
137484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar            print >>self.outputDriver, '  if (index == -1 || index == %d) {' % i
138484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar            print >>self.outputDriver, '    extern void test_%s(void);' % fnName
139484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar            print >>self.outputDriver, '    test_%s();' % fnName
140484c7cad9bf5caefd3b0912aa778457fd46c2804Daniel Dunbar            print >>self.outputDriver, '   }'
141a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
142a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if self.outputTests:
143a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if self.outputHeader:
144a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.outputHeader, 'void test_%s(void);'%(fnName,)
145a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
146a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if retvalName is None:
147a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                retvalTests = None
148a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            else:
149a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                retvalTests = self.getTestValuesArray(FT.returnType)
150a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            tests = map(self.getTestValuesArray, FT.argTypes)
151a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.outputTests, 'void test_%s(void) {'%(fnName,)
152a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
153a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if retvalTests is not None:
154a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.outputTests, '  printf("%s: testing return.\\n");'%(fnName,)
155a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.outputTests, '  for (int i=0; i<%d; ++i) {'%(retvalTests[1],)
156a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                args = ', '.join(['%s[%d]'%(t,randrange(l)) for t,l in tests])
157a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.outputTests, '    %s RV;'%(retvalTypeName,)
158a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.outputTests, '    %s = %s[i];'%(retvalName, retvalTests[0])
159a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.outputTests, '    RV = %s(%s);'%(fnName, args)
160a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                self.printValueOfType('  %s_RV'%fnName, 'RV', FT.returnType, output=self.outputTests, indent=4)
1619dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                self.checkTypeValues('RV', '%s[i]' % retvalTests[0], FT.returnType, output=self.outputTests, indent=4)
162a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.outputTests, '  }'
163a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
164a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if tests:
165a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.outputTests, '  printf("%s: testing arguments.\\n");'%(fnName,)
166a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            for i,(array,length) in enumerate(tests):
167a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                for j in range(length):
168a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    args = ['%s[%d]'%(t,randrange(l)) for t,l in tests]
169a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    args[i] = '%s[%d]'%(array,j)
170a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    print >>self.outputTests, '  %s(%s);'%(fnName, ', '.join(args),)
171a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.outputTests, '}'
172a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
173a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    def getTestReturnValue(self, type):
174a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        typeName = self.getTypeName(type)
175a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        info = self.testReturnValues.get(typeName)
176a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if info is None:
177a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            name = '%s_retval'%(typeName.replace(' ','_').replace('*','star'),)
178a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.output, '%s %s;'%(typeName,name)
179a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if self.outputHeader:
180a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.outputHeader, 'extern %s %s;'%(typeName,name)
181a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            elif self.outputTests:
182a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.outputTests, 'extern %s %s;'%(typeName,name)
183a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            info = self.testReturnValues[typeName] = name
184a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        return info
185a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
186a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    def getTestValuesArray(self, type):
187a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        typeName = self.getTypeName(type)
188a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        info = self.testValues.get(typeName)
189a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if info is None:
190a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            name = '%s_values'%(typeName.replace(' ','_').replace('*','star'),)
191a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.outputTests, 'static %s %s[] = {'%(typeName,name)
192a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            length = 0
193a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            for item in self.getTestValues(type):
194a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>self.outputTests, '\t%s,'%(item,)
195a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                length += 1
196a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            print >>self.outputTests,'};'
197a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            info = self.testValues[typeName] = (name,length)
198a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        return info
199a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
200a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    def getTestValues(self, t):
201a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if isinstance(t, BuiltinType):
202a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if t.name=='float':
203a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                for i in ['0.0','-1.0','1.0']:
204a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    yield i+'f'
205a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            elif t.name=='double':
206a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                for i in ['0.0','-1.0','1.0']:
207a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    yield i
208a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            elif t.name in ('void *'):
209a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                yield '(void*) 0'
210a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                yield '(void*) -1'
211a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            else:
212a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                yield '(%s) 0'%(t.name,)
213a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                yield '(%s) -1'%(t.name,)
214a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                yield '(%s) 1'%(t.name,)
215aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor        elif isinstance(t, EnumType):
216aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor            for i in range(0, len(t.enumerators)):
217aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor                yield 'enum%dval%d' % (t.index, i)
218a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        elif isinstance(t, RecordType):
21948df17b8bfcd7a53f147ce00679a1b3976da179cDaniel Dunbar            nonPadding = [f for f in t.fields
22048df17b8bfcd7a53f147ce00679a1b3976da179cDaniel Dunbar                          if not f.isPaddingBitField()]
22148df17b8bfcd7a53f147ce00679a1b3976da179cDaniel Dunbar
22248df17b8bfcd7a53f147ce00679a1b3976da179cDaniel Dunbar            if not nonPadding:
223a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                yield '{ }'
224900ed55727a5dd2a59412df00ea1513b851cd49aDaniel Dunbar                return
22548df17b8bfcd7a53f147ce00679a1b3976da179cDaniel Dunbar
226900ed55727a5dd2a59412df00ea1513b851cd49aDaniel Dunbar            # FIXME: Use designated initializers to access non-first
227900ed55727a5dd2a59412df00ea1513b851cd49aDaniel Dunbar            # fields of unions.
228900ed55727a5dd2a59412df00ea1513b851cd49aDaniel Dunbar            if t.isUnion:
22948df17b8bfcd7a53f147ce00679a1b3976da179cDaniel Dunbar                for v in self.getTestValues(nonPadding[0]):
23048df17b8bfcd7a53f147ce00679a1b3976da179cDaniel Dunbar                    yield '{ %s }' % v
231900ed55727a5dd2a59412df00ea1513b851cd49aDaniel Dunbar                return
23248df17b8bfcd7a53f147ce00679a1b3976da179cDaniel Dunbar
23348df17b8bfcd7a53f147ce00679a1b3976da179cDaniel Dunbar            fieldValues = map(list, map(self.getTestValues, nonPadding))
234a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            for i,values in enumerate(fieldValues):
235a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                for v in values:
236a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    elements = map(random.choice,fieldValues)
237a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    elements[i] = v
238a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    yield '{ %s }'%(', '.join(elements))
23948df17b8bfcd7a53f147ce00679a1b3976da179cDaniel Dunbar
240a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        elif isinstance(t, ComplexType):
241a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            for t in self.getTestValues(t.elementType):
242550faa3a6bb394eaa4013fcff0582434f4e924afDaniel Dunbar                yield '%s + %s * 1i'%(t,t)
243550faa3a6bb394eaa4013fcff0582434f4e924afDaniel Dunbar        elif isinstance(t, ArrayType):
244a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            values = list(self.getTestValues(t.elementType))
245a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if not values:
246a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                yield '{ }'
247550faa3a6bb394eaa4013fcff0582434f4e924afDaniel Dunbar            for i in range(t.numElements):
248a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                for v in values:
249550faa3a6bb394eaa4013fcff0582434f4e924afDaniel Dunbar                    elements = [random.choice(values) for i in range(t.numElements)]
250a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    elements[i] = v
251a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    yield '{ %s }'%(', '.join(elements))
252a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        else:
253a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            raise NotImplementedError,'Cannot make tests values of type: "%s"'%(t,)
254a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
2555ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar    def printSizeOfType(self, prefix, name, t, output=None, indent=2):
25698a7170db80e43195068a2710088fd5532924c77Eli Friedman        print >>output, '%*sprintf("%s: sizeof(%s) = %%ld\\n", (long)sizeof(%s));'%(indent, '', prefix, name, name)
2575ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar    def printAlignOfType(self, prefix, name, t, output=None, indent=2):
25898a7170db80e43195068a2710088fd5532924c77Eli Friedman        print >>output, '%*sprintf("%s: __alignof__(%s) = %%ld\\n", (long)__alignof__(%s));'%(indent, '', prefix, name, name)
2595ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar    def printOffsetsOfType(self, prefix, name, t, output=None, indent=2):
2605ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        if isinstance(t, RecordType):
2615ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar            for i,f in enumerate(t.fields):
26298a7170db80e43195068a2710088fd5532924c77Eli Friedman                if f.isBitField():
263122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar                    continue
2645ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar                fname = 'field%d' % i
26598a7170db80e43195068a2710088fd5532924c77Eli Friedman                print >>output, '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", (long)__builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname)
2665ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar
267a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    def printValueOfType(self, prefix, name, t, output=None, indent=2):
268a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if output is None:
269a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            output = self.output
270a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if isinstance(t, BuiltinType):
2713dbe0b76efdd33b2ba96a1fe532a52e5926e09a4Daniel Dunbar            value_expr = name
2723dbe0b76efdd33b2ba96a1fe532a52e5926e09a4Daniel Dunbar            if t.name.split(' ')[-1] == '_Bool':
2733dbe0b76efdd33b2ba96a1fe532a52e5926e09a4Daniel Dunbar                # Hack to work around PR5579.
2743dbe0b76efdd33b2ba96a1fe532a52e5926e09a4Daniel Dunbar                value_expr = "%s ? 2 : 0" % name
2753dbe0b76efdd33b2ba96a1fe532a52e5926e09a4Daniel Dunbar
276a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if t.name.endswith('long long'):
277a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                code = 'lld'
278a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            elif t.name.endswith('long'):
279a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                code = 'ld'
2803d2fd8d4676494ff08b617ee2b3104780b04e4f3Daniel Dunbar            elif t.name.split(' ')[-1] in ('_Bool','char','short',
2813d2fd8d4676494ff08b617ee2b3104780b04e4f3Daniel Dunbar                                           'int','unsigned'):
282a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                code = 'd'
283a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            elif t.name in ('float','double'):
284a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                code = 'f'
285a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            elif t.name == 'long double':
286a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                code = 'Lf'
287a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            else:
288a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                code = 'p'
2893dbe0b76efdd33b2ba96a1fe532a52e5926e09a4Daniel Dunbar            print >>output, '%*sprintf("%s: %s = %%%s\\n", %s);'%(
2903dbe0b76efdd33b2ba96a1fe532a52e5926e09a4Daniel Dunbar                indent, '', prefix, name, code, value_expr)
291aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor        elif isinstance(t, EnumType):
292aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor            print >>output, '%*sprintf("%s: %s = %%d\\n", %s);'%(indent, '', prefix, name, name)
293a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        elif isinstance(t, RecordType):
294a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if not t.fields:
295a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>output, '%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name)
296a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            for i,f in enumerate(t.fields):
297122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar                if f.isPaddingBitField():
298122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar                    continue
299a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                fname = '%s.field%d'%(name,i)
300a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                self.printValueOfType(prefix, fname, f, output=output, indent=indent)
301a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        elif isinstance(t, ComplexType):
302a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            self.printValueOfType(prefix, '(__real %s)'%name, t.elementType, output=output,indent=indent)
303a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            self.printValueOfType(prefix, '(__imag %s)'%name, t.elementType, output=output,indent=indent)
304550faa3a6bb394eaa4013fcff0582434f4e924afDaniel Dunbar        elif isinstance(t, ArrayType):
305550faa3a6bb394eaa4013fcff0582434f4e924afDaniel Dunbar            for i in range(t.numElements):
306550faa3a6bb394eaa4013fcff0582434f4e924afDaniel Dunbar                # Access in this fashion as a hackish way to portably
307550faa3a6bb394eaa4013fcff0582434f4e924afDaniel Dunbar                # access vectors.
308e61e95fdcd2bdf6293becd96c343ab3635cc4a68Daniel Dunbar                if t.isVector:
309e61e95fdcd2bdf6293becd96c343ab3635cc4a68Daniel Dunbar                    self.printValueOfType(prefix, '((%s*) &%s)[%d]'%(t.elementType,name,i), t.elementType, output=output,indent=indent)
310e61e95fdcd2bdf6293becd96c343ab3635cc4a68Daniel Dunbar                else:
311e61e95fdcd2bdf6293becd96c343ab3635cc4a68Daniel Dunbar                    self.printValueOfType(prefix, '%s[%d]'%(name,i), t.elementType, output=output,indent=indent)
312a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        else:
313a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            raise NotImplementedError,'Cannot print value of type: "%s"'%(t,)
314a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
3159dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar    def checkTypeValues(self, nameLHS, nameRHS, t, output=None, indent=2):
3169dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar        prefix = 'foo'
3179dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar        if output is None:
3189dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar            output = self.output
3199dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar        if isinstance(t, BuiltinType):
3209dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar            print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
321aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor        elif isinstance(t, EnumType):
322aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor            print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
3239dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar        elif isinstance(t, RecordType):
3249dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar            for i,f in enumerate(t.fields):
325122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar                if f.isPaddingBitField():
326122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar                    continue
3279dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                self.checkTypeValues('%s.field%d'%(nameLHS,i), '%s.field%d'%(nameRHS,i),
3289dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                                     f, output=output, indent=indent)
3299dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                if t.isUnion:
3309dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                    break
3319dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar        elif isinstance(t, ComplexType):
3329dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar            self.checkTypeValues('(__real %s)'%nameLHS, '(__real %s)'%nameRHS, t.elementType, output=output,indent=indent)
3339dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar            self.checkTypeValues('(__imag %s)'%nameLHS, '(__imag %s)'%nameRHS, t.elementType, output=output,indent=indent)
3349dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar        elif isinstance(t, ArrayType):
3359dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar            for i in range(t.numElements):
3369dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                # Access in this fashion as a hackish way to portably
3379dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                # access vectors.
3389dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                if t.isVector:
3399dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                    self.checkTypeValues('((%s*) &%s)[%d]'%(t.elementType,nameLHS,i),
3409dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                                         '((%s*) &%s)[%d]'%(t.elementType,nameRHS,i),
3419dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                                         t.elementType, output=output,indent=indent)
3429dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                else:
3439dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                    self.checkTypeValues('%s[%d]'%(nameLHS,i), '%s[%d]'%(nameRHS,i),
3449dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar                                         t.elementType, output=output,indent=indent)
3459dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar        else:
3469dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar            raise NotImplementedError,'Cannot print value of type: "%s"'%(t,)
3479dd60b4526ccfab13cf0976999bf5f90b3423f43Daniel Dunbar
348a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbarimport sys
349a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
350a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbardef main():
351a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    from optparse import OptionParser, OptionGroup
352a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser = OptionParser("%prog [options] {indices}")
353a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser.add_option("", "--mode", dest="mode",
354a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      help="autogeneration mode (random or linear) [default %default]",
355a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      type='choice', choices=('random','linear'), default='linear')
356a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser.add_option("", "--count", dest="count",
357a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      help="autogenerate COUNT functions according to MODE",
358a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      type=int, default=0)
359a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser.add_option("", "--min", dest="minIndex", metavar="N",
360a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      help="start autogeneration with the Nth function type  [default %default]",
361a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      type=int, default=0)
362a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser.add_option("", "--max", dest="maxIndex", metavar="N",
363a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      help="maximum index for random autogeneration  [default %default]",
364a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      type=int, default=10000000)
365a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser.add_option("", "--seed", dest="seed",
366a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      help="random number generator seed [default %default]",
367a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      type=int, default=1)
368a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser.add_option("", "--use-random-seed", dest="useRandomSeed",
369a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      help="use random value for initial random number generator seed",
370a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      action='store_true', default=False)
3711ca717b766163f0aecdebd5aa1d1fac91fcab8ecDaniel Dunbar    parser.add_option("", "--skip", dest="skipTests",
3721ca717b766163f0aecdebd5aa1d1fac91fcab8ecDaniel Dunbar                      help="add a test index to skip",
3731ca717b766163f0aecdebd5aa1d1fac91fcab8ecDaniel Dunbar                      type=int, action='append', default=[])
374a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser.add_option("-o", "--output", dest="output", metavar="FILE",
375a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      help="write output to FILE  [default %default]",
376a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      type=str, default='-')
377a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser.add_option("-O", "--output-header", dest="outputHeader", metavar="FILE",
378a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      help="write header file for output to FILE  [default %default]",
379a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      type=str, default=None)
380a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser.add_option("-T", "--output-tests", dest="outputTests", metavar="FILE",
381a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      help="write function tests to FILE  [default %default]",
382a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      type=str, default=None)
383a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser.add_option("-D", "--output-driver", dest="outputDriver", metavar="FILE",
384a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      help="write test driver to FILE  [default %default]",
385a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                      type=str, default=None)
3865ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar    parser.add_option("", "--test-layout", dest="testLayout", metavar="FILE",
3875ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar                      help="test structure layout",
3885ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar                      action='store_true', default=False)
389a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
390a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group = OptionGroup(parser, "Type Enumeration Options")
391a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    # Builtins - Ints
392a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-char", dest="useChar",
393a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate char types",
394a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
395a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-short", dest="useShort",
396a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate short types",
397a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
398a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-int", dest="useInt",
399a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate int types",
400a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
401a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-long", dest="useLong",
402a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate long types",
403a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
404a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-long-long", dest="useLongLong",
405a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate long long types",
406a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
407a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-unsigned", dest="useUnsigned",
408a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate unsigned integer types",
409a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
410a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
411a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    # Other builtins
412a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-bool", dest="useBool",
413a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate bool types",
414a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
415a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-float", dest="useFloat",
416a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate float types",
417a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
418a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-double", dest="useDouble",
419a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate double types",
420a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
421a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-long-double", dest="useLongDouble",
422a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate long double types",
423a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
424a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-void-pointer", dest="useVoidPointer",
425a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate void* types",
426a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
427a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
428aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor    # Enumerations
429aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor    group.add_option("", "--no-enums", dest="useEnum",
430aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor                     help="do not generate enum types",
431aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor                     action="store_false", default=True)
432aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor
433a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    # Derived types
434a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-array", dest="useArray",
435a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate record types",
436a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
437a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-complex", dest="useComplex",
438a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate complex types",
439a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
440a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-record", dest="useRecord",
441a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate record types",
442a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
443a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-union", dest="recordUseUnion",
444a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate union types",
445a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
446a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-vector", dest="useVector",
447a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate vector types",
448a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
449122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar    group.add_option("", "--no-bit-field", dest="useBitField",
450122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar                     help="do not generate bit-field record members",
451122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar                     action="store_false", default=True)
452122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar    group.add_option("", "--no-builtins", dest="useBuiltins",
453122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar                     help="do not use any types",
454122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar                     action="store_false", default=True)
455a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
456a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    # Tuning
457a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--no-function-return", dest="functionUseReturn",
458a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="do not generate return types for functions",
459a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store_false", default=True)
4600f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar    group.add_option("", "--vector-types", dest="vectorTypes",
4610f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                     help="comma separated list of vector types (e.g., v2i32) [default %default]",
462ec1abb9bd70f67a0a93bb5c9ffeafc184cb551d0Daniel Dunbar                     action="store", type=str, default='v2i16, v1i64, v2i32, v4i16, v8i8, v2f32, v2i64, v4i32, v8i16, v16i8, v2f64, v4f32, v16f32', metavar="N")
463122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar    group.add_option("", "--bit-fields", dest="bitFields",
464122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar                     help="comma separated list 'type:width' bit-field specifiers [default %default]",
4653d2fd8d4676494ff08b617ee2b3104780b04e4f3Daniel Dunbar                     action="store", type=str, default=(
4663d2fd8d4676494ff08b617ee2b3104780b04e4f3Daniel Dunbar            "char:0,char:4,int:0,unsigned:1,int:1,int:4,int:13,int:24"))
467a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--max-args", dest="functionMaxArgs",
468a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="maximum number of arguments per function [default %default]",
469a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store", type=int, default=4, metavar="N")
470a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--max-array", dest="arrayMaxSize",
471a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="maximum array size [default %default]",
472a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store", type=int, default=4, metavar="N")
473a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--max-record", dest="recordMaxSize",
474a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="maximum number of fields per record [default %default]",
475a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store", type=int, default=4, metavar="N")
476a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    group.add_option("", "--max-record-depth", dest="recordMaxDepth",
477a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     help="maximum nested structure depth [default %default]",
478a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                     action="store", type=int, default=None, metavar="N")
479a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    parser.add_option_group(group)
480a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    (opts, args) = parser.parse_args()
481a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
482a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    if not opts.useRandomSeed:
483a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        random.seed(opts.seed)
484a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
485e575359c34a9248c55ec0c03a8fc945f1ee4cb01Benjamin Kramer    # Construct type generator
486a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    builtins = []
487122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar    if opts.useBuiltins:
488122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        ints = []
489122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if opts.useChar: ints.append(('char',1))
490122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if opts.useShort: ints.append(('short',2))
491122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if opts.useInt: ints.append(('int',4))
492122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        # FIXME: Wrong size.
493122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if opts.useLong: ints.append(('long',4))
494122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if opts.useLongLong: ints.append(('long long',8))
495122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if opts.useUnsigned:
496122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar            ints = ([('unsigned %s'%i,s) for i,s in ints] +
497122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar                    [('signed %s'%i,s) for i,s in ints])
498122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        builtins.extend(ints)
499122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar
500122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if opts.useBool: builtins.append(('_Bool',1))
501122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if opts.useFloat: builtins.append(('float',4))
502122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if opts.useDouble: builtins.append(('double',8))
503122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if opts.useLongDouble: builtins.append(('long double',16))
504122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        # FIXME: Wrong size.
505122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if opts.useVoidPointer:  builtins.append(('void*',4))
506a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
507550faa3a6bb394eaa4013fcff0582434f4e924afDaniel Dunbar    btg = FixedTypeGenerator([BuiltinType(n,s) for n,s in builtins])
508122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar
509122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar    bitfields = []
510122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar    for specifier in opts.bitFields.split(','):
511122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if not specifier.strip():
512122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar            continue
513122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        name,width = specifier.strip().split(':', 1)
514122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        bitfields.append(BuiltinType(name,None,int(width)))
515122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar    bftg = FixedTypeGenerator(bitfields)
516122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar
5170f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar    charType = BuiltinType('char',1)
5180f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar    shortType = BuiltinType('short',2)
5190f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar    intType = BuiltinType('int',4)
5200f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar    longlongType = BuiltinType('long long',8)
5210f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar    floatType = BuiltinType('float',4)
5220f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar    doubleType = BuiltinType('double',8)
5230f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar    sbtg = FixedTypeGenerator([charType, intType, floatType, doubleType])
524a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
525a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    atg = AnyTypeGenerator()
526a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    artg = AnyTypeGenerator()
527122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar    def makeGenerator(atg, subgen, subfieldgen, useRecord, useArray, useBitField):
528a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        atg.addGenerator(btg)
529122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        if useBitField and opts.useBitField:
530122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar            atg.addGenerator(bftg)
531a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if useRecord and opts.useRecord:
532a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            assert subgen
533122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar            atg.addGenerator(RecordTypeGenerator(subfieldgen, opts.recordUseUnion,
534a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                                                 opts.recordMaxSize))
535a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if opts.useComplex:
536a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            # FIXME: Allow overriding builtins here
537a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            atg.addGenerator(ComplexTypeGenerator(sbtg))
538a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if useArray and opts.useArray:
539a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            assert subgen
540a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            atg.addGenerator(ArrayTypeGenerator(subgen, opts.arrayMaxSize))
541a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if opts.useVector:
5420f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar            vTypes = []
5430f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar            for i,t in enumerate(opts.vectorTypes.split(',')):
5440f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                m = re.match('v([1-9][0-9]*)([if][1-9][0-9]*)', t.strip())
5450f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                if not m:
5460f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                    parser.error('Invalid vector type: %r' % t)
5470f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                count,kind = m.groups()
5480f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                count = int(count)
5490f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                type = { 'i8'  : charType,
5500f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                         'i16' : shortType,
5510f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                         'i32' : intType,
5520f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                         'i64' : longlongType,
5530f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                         'f32' : floatType,
5540f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                         'f64' : doubleType,
5550f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                         }.get(kind)
5560f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                if not type:
5570f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                    parser.error('Invalid vector type: %r' % t)
5580f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar                vTypes.append(ArrayType(i, True, type, count * type.size))
5590f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar
5600f1730d220cb76a90159a42acd050c4d44dc18d8Daniel Dunbar            atg.addGenerator(FixedTypeGenerator(vTypes))
561aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor        if opts.useEnum:
562aa74a1e49f7c4b89539830290f76fe2c3e97187fDouglas Gregor            atg.addGenerator(EnumTypeGenerator([None, '-1', '1', '1u'], 1, 4))
563a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
564a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    if opts.recordMaxDepth is None:
565a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        # Fully recursive, just avoid top-level arrays.
566122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        subFTG = AnyTypeGenerator()
567a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        subTG = AnyTypeGenerator()
568a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        atg = AnyTypeGenerator()
569122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        makeGenerator(subFTG, atg, atg, True, True, True)
570122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        makeGenerator(subTG, atg, subFTG, True, True, False)
571122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        makeGenerator(atg, subTG, subFTG, True, False, False)
572a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    else:
573a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        # Make a chain of type generators, each builds smaller
574a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        # structures.
575a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        base = AnyTypeGenerator()
576122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        fbase = AnyTypeGenerator()
577122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        makeGenerator(base, None, None, False, False, False)
578122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        makeGenerator(fbase, None, None, False, False, True)
579a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        for i in range(opts.recordMaxDepth):
580a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            n = AnyTypeGenerator()
581122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar            fn = AnyTypeGenerator()
582122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar            makeGenerator(n, base, fbase, True, True, False)
583122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar            makeGenerator(fn, base, fbase, True, True, True)
584a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            base = n
585122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar            fbase = fn
586a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        atg = AnyTypeGenerator()
587122ed24b4f1ce0f7a3c37991932933ef8ced3a43Daniel Dunbar        makeGenerator(atg, base, fbase, True, False, False)
588a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
5895ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar    if opts.testLayout:
5905ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        ftg = atg
5915ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar    else:
5925ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs)
593a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
594a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    # Override max,min,count if finite
595a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    if opts.maxIndex is None:
596a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if ftg.cardinality is aleph0:
597a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            opts.maxIndex = 10000000
598a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        else:
599a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            opts.maxIndex = ftg.cardinality
600a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    opts.maxIndex = min(opts.maxIndex, ftg.cardinality)
601a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    opts.minIndex = max(0,min(opts.maxIndex-1, opts.minIndex))
602a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    if not opts.mode=='random':
603a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        opts.count = min(opts.count, opts.maxIndex-opts.minIndex)
604a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
605a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    if opts.output=='-':
606a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        output = sys.stdout
607a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    else:
608a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        output = open(opts.output,'w')
609a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        atexit.register(lambda: output.close())
610a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
611a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    outputHeader = None
612a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    if opts.outputHeader:
613a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        outputHeader = open(opts.outputHeader,'w')
614a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        atexit.register(lambda: outputHeader.close())
615a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
616a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    outputTests = None
617a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    if opts.outputTests:
618a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        outputTests = open(opts.outputTests,'w')
619a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        atexit.register(lambda: outputTests.close())
620a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
621a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    outputDriver = None
622a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    if opts.outputDriver:
623a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        outputDriver = open(opts.outputDriver,'w')
624a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        atexit.register(lambda: outputDriver.close())
625a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
626a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    info = ''
627a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    info += '// %s\n'%(' '.join(sys.argv),)
628a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    info += '// Generated: %s\n'%(time.strftime('%Y-%m-%d %H:%M'),)
629a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    info += '// Cardinality of function generator: %s\n'%(ftg.cardinality,)
630a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    info += '// Cardinality of type generator: %s\n'%(atg.cardinality,)
6315ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar
6325ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar    if opts.testLayout:
6335ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        info += '\n#include <stdio.h>'
634a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
635a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    P = TypePrinter(output,
636a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    outputHeader=outputHeader,
637a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    outputTests=outputTests,
638a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    outputDriver=outputDriver,
6395ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar                    headerName=opts.outputHeader,
640a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                    info=info)
641a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
642a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    def write(N):
6435ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        try:
644a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            FT = ftg.get(N)
645a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        except RuntimeError,e:
646a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            if e.args[0]=='maximum recursion depth exceeded':
647a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                print >>sys.stderr,'WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,)
648a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar                return
649a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            raise
6505ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        if opts.testLayout:
6515ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar            P.writeLayoutTest(N, FT)
6525ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar        else:
6535ce61575adde60a826576446d2e9e953c54e1e99Daniel Dunbar            P.writeFunction(N, FT)
654a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
655a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    if args:
656a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        [write(int(a)) for a in args]
657a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
6581ca717b766163f0aecdebd5aa1d1fac91fcab8ecDaniel Dunbar    skipTests = set(opts.skipTests)
659a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    for i in range(opts.count):
660a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        if opts.mode=='linear':
661a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            index = opts.minIndex + i
662a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        else:
663a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar            index = opts.minIndex + int((opts.maxIndex-opts.minIndex) * random.random())
6641ca717b766163f0aecdebd5aa1d1fac91fcab8ecDaniel Dunbar        if index in skipTests:
6651ca717b766163f0aecdebd5aa1d1fac91fcab8ecDaniel Dunbar            continue
666a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar        write(index)
667a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
668a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    P.finish()
669a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
670a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbarif __name__=='__main__':
671a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar    main()
672a83fb8647bfca3aa9bd7049f817979f092244e83Daniel Dunbar
673