aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rwxr-xr-xutils/ABITest/ABITestGen.py17
-rw-r--r--utils/ABITest/TypeGen.py83
2 files changed, 98 insertions, 2 deletions
diff --git a/utils/ABITest/ABITestGen.py b/utils/ABITest/ABITestGen.py
index 63da02bcda9d..c45a0c343270 100755
--- a/utils/ABITest/ABITestGen.py
+++ b/utils/ABITest/ABITestGen.py
@@ -42,7 +42,8 @@ class TypePrinter:
print >>f, '#include "%s"\n'%(headerName,)
if self.outputDriver:
- print >>self.outputDriver, '#include <stdio.h>\n'
+ print >>self.outputDriver, '#include <stdio.h>'
+ print >>self.outputDriver, '#include <stdlib.h>\n'
print >>self.outputDriver, 'int main(int argc, char **argv) {'
print >>self.outputDriver, ' int index = -1;'
print >>self.outputDriver, ' if (argc > 1) index = atoi(argv[1]);'
@@ -206,6 +207,9 @@ class TypePrinter:
yield '(%s) 0'%(t.name,)
yield '(%s) -1'%(t.name,)
yield '(%s) 1'%(t.name,)
+ elif isinstance(t, EnumType):
+ for i in range(0, len(t.enumerators)):
+ yield 'enum%dval%d' % (t.index, i)
elif isinstance(t, RecordType):
nonPadding = [f for f in t.fields
if not f.isPaddingBitField()]
@@ -272,6 +276,8 @@ class TypePrinter:
else:
code = 'p'
print >>output, '%*sprintf("%s: %s = %%%s\\n", %s);'%(indent, '', prefix, name, code, name)
+ elif isinstance(t, EnumType):
+ print >>output, '%*sprintf("%s: %s = %%d\\n", %s);'%(indent, '', prefix, name, name)
elif isinstance(t, RecordType):
if not t.fields:
print >>output, '%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name)
@@ -300,6 +306,8 @@ class TypePrinter:
output = self.output
if isinstance(t, BuiltinType):
print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
+ elif isinstance(t, EnumType):
+ print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
elif isinstance(t, RecordType):
for i,f in enumerate(t.fields):
if f.isPaddingBitField():
@@ -402,6 +410,11 @@ def main():
help="do not generate void* types",
action="store_false", default=True)
+ # Enumerations
+ group.add_option("", "--no-enums", dest="useEnum",
+ help="do not generate enum types",
+ action="store_false", default=True)
+
# Derived types
group.add_option("", "--no-array", dest="useArray",
help="do not generate record types",
@@ -529,6 +542,8 @@ def main():
vTypes.append(ArrayType(i, True, type, count * type.size))
atg.addGenerator(FixedTypeGenerator(vTypes))
+ if opts.useEnum:
+ atg.addGenerator(EnumTypeGenerator([None, '-1', '1', '1u'], 1, 4))
if opts.recordMaxDepth is None:
# Fully recursive, just avoid top-level arrays.
diff --git a/utils/ABITest/TypeGen.py b/utils/ABITest/TypeGen.py
index d5678db6a0e8..40ea791eb515 100644
--- a/utils/ABITest/TypeGen.py
+++ b/utils/ABITest/TypeGen.py
@@ -46,6 +46,28 @@ class BuiltinType(Type):
def __str__(self):
return self.name
+class EnumType(Type):
+ def __init__(self, index, enumerators):
+ self.index = index
+ self.enumerators = enumerators
+
+ def getEnumerators(self):
+ result = ''
+ for i, init in enumerate(self.enumerators):
+ if i > 0:
+ result = result + ', '
+ result = result + 'enum%dval%d' % (self.index, i)
+ if init:
+ result = result + ' = %s' % (init)
+
+ return result
+
+ def __str__(self):
+ return 'enum { %s }' % (self.getEnumerators())
+
+ def getTypedefDef(self, name, printer):
+ return 'typedef enum %s { %s } %s;'%(name, self.getEnumerators(), name)
+
class RecordType(Type):
def __init__(self, index, isUnion, fields):
self.index = index
@@ -188,6 +210,63 @@ class FixedTypeGenerator(TypeGenerator):
def generateType(self, N):
return self.types[N]
+# Factorial
+def fact(n):
+ result = 1
+ while n > 0:
+ result = result * n
+ n = n - 1
+ return result
+
+# Compute the number of combinations (n choose k)
+def num_combinations(n, k):
+ return fact(n) / (fact(k) * fact(n - k))
+
+# Enumerate the combinations choosing k elements from the list of values
+def combinations(values, k):
+ # From ActiveState Recipe 190465: Generator for permutations,
+ # combinations, selections of a sequence
+ if k==0: yield []
+ else:
+ for i in xrange(len(values)-k+1):
+ for cc in combinations(values[i+1:],k-1):
+ yield [values[i]]+cc
+
+class EnumTypeGenerator(TypeGenerator):
+ def __init__(self, values, minEnumerators, maxEnumerators):
+ TypeGenerator.__init__(self)
+ self.values = values
+ self.minEnumerators = minEnumerators
+ self.maxEnumerators = maxEnumerators
+ self.setCardinality()
+
+ def setCardinality(self):
+ self.cardinality = 0
+ for num in range(self.minEnumerators, self.maxEnumerators + 1):
+ self.cardinality += num_combinations(len(self.values), num)
+
+ def generateType(self, n):
+ # Figure out the number of enumerators in this type
+ numEnumerators = self.minEnumerators
+ valuesCovered = 0
+ while numEnumerators < self.maxEnumerators:
+ comb = num_combinations(len(self.values), numEnumerators)
+ if valuesCovered + comb > n:
+ break
+ numEnumerators = numEnumerators + 1
+ valuesCovered += comb
+
+ # Find the requested combination of enumerators and build a
+ # type from it.
+ i = 0
+ for enumerators in combinations(self.values, numEnumerators):
+ if i == n - valuesCovered:
+ return EnumType(n, enumerators)
+
+ i = i + 1
+
+ assert False
+
class ComplexTypeGenerator(TypeGenerator):
def __init__(self, typeGen):
TypeGenerator.__init__(self)
@@ -363,10 +442,12 @@ def test():
btg = FixedTypeGenerator([BuiltinType('char', 4),
BuiltinType('int', 4)])
-
+ etg = EnumTypeGenerator([None, '-1', '1', '1u'], 0, 3)
+
atg = AnyTypeGenerator()
atg.addGenerator( btg )
atg.addGenerator( RecordTypeGenerator(fields0, False, 4) )
+ atg.addGenerator( etg )
print 'Cardinality:',atg.cardinality
for i in range(100):
if i == atg.cardinality: