X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=specs%2Fstdapi.py;h=c652736a8383e9156e5bd7e88af34dde79760382;hb=999284fd424cbf7dde024f949cdece0f308d41db;hp=cde94cb6fa522a583f0deb31edce660901d6c9cb;hpb=3223b1d6ce831bed7db99651f787cf0e827bd8b1;p=apitrace diff --git a/specs/stdapi.py b/specs/stdapi.py index cde94cb..c652736 100644 --- a/specs/stdapi.py +++ b/specs/stdapi.py @@ -129,6 +129,8 @@ UInt32 = Literal("uint32_t", "UInt") Int64 = Literal("int64_t", "SInt") UInt64 = Literal("uint64_t", "UInt") +IntPtr = Literal("intptr_t", "SInt") +UIntPtr = Literal("uintptr_t", "UInt") class Const(Type): @@ -290,33 +292,18 @@ class Struct(Type): Struct.__id += 1 self.name = name - self.members = [] - - # Eliminate anonymous unions - for type, name in members: - if name is not None: - self.members.append((type, name)) - else: - assert isinstance(type, Union) - assert type.name is None - self.members.extend(type.members) + self.members = members def visit(self, visitor, *args, **kwargs): return visitor.visitStruct(self, *args, **kwargs) -class Union(Type): - - __id = 0 - - def __init__(self, name, members): - Type.__init__(self, name) - - self.id = Union.__id - Union.__id += 1 - - self.name = name - self.members = members +def Union(kindExpr, kindTypes, contextLess=True): + switchTypes = [] + for kindCase, kindType, kindMemberName in kindTypes: + switchType = Struct(None, [(kindType, kindMemberName)]) + switchTypes.append((kindCase, switchType)) + return Polymorphic(kindExpr, switchTypes, contextLess=contextLess) class Alias(Type): @@ -353,13 +340,7 @@ def InOut(type, name): class Function: - # 0-3 are reserved to memcpy, malloc, free, and realloc - __id = 4 - def __init__(self, type, name, args, call = '', fail = None, sideeffects=True, internal=False): - self.id = Function.__id - Function.__id += 1 - self.type = type self.name = name @@ -404,6 +385,12 @@ class Function: def argNames(self): return [arg.name for arg in self.args] + def getArgByName(self, name): + for arg in self.args: + if arg.name == name: + return arg + return None + def StdFunction(*args, **kwargs): kwargs.setdefault('call', '__stdcall') @@ -458,7 +445,8 @@ class Interface(Type): class Method(Function): - def __init__(self, type, name, args, call = '__stdcall', const=False, sideeffects=True): + def __init__(self, type, name, args, call = '', const=False, sideeffects=True): + assert call == '__stdcall' Function.__init__(self, type, name, args, call = call, sideeffects=sideeffects) for index in range(len(self.args)): self.args[index].index = index + 1 @@ -512,8 +500,12 @@ def OpaqueBlob(type, size): class Polymorphic(Type): - def __init__(self, switchExpr, switchTypes, defaultType, contextLess=True): - Type.__init__(self, defaultType.expr) + def __init__(self, switchExpr, switchTypes, defaultType=None, contextLess=True): + if defaultType is None: + Type.__init__(self, None) + contextLess = False + else: + Type.__init__(self, defaultType.expr) self.switchExpr = switchExpr self.switchTypes = switchTypes self.defaultType = defaultType @@ -523,8 +515,12 @@ class Polymorphic(Type): return visitor.visitPolymorphic(self, *args, **kwargs) def iterSwitch(self): - cases = [['default']] - types = [self.defaultType] + cases = [] + types = [] + + if self.defaultType is not None: + cases.append(['default']) + types.append(self.defaultType) for expr, type in self.switchTypes: case = 'case %s' % expr @@ -723,7 +719,10 @@ class Rebuilder(Visitor): def visitPolymorphic(self, polymorphic): switchExpr = polymorphic.switchExpr switchTypes = [(expr, self.visit(type)) for expr, type in polymorphic.switchTypes] - defaultType = self.visit(polymorphic.defaultType) + if polymorphic.defaultType is None: + defaultType = None + else: + defaultType = self.visit(polymorphic.defaultType) return Polymorphic(switchExpr, switchTypes, defaultType, polymorphic.contextLess) @@ -813,9 +812,10 @@ class Traverser(Visitor): self.visit(method.type, *args, **kwargs) def visitPolymorphic(self, polymorphic, *args, **kwargs): - self.visit(polymorphic.defaultType, *args, **kwargs) for expr, type in polymorphic.switchTypes: self.visit(type, *args, **kwargs) + if polymorphic.defaultType is not None: + self.visit(polymorphic.defaultType, *args, **kwargs) class Collector(Traverser): @@ -833,12 +833,52 @@ class Collector(Traverser): self.types.append(type) +class ExpanderMixin: + '''Mixin class that provides a bunch of methods to expand C expressions + from the specifications.''' -class API: - '''API abstraction. + __structs = None + __indices = None - Essentially, a collection of types, functions, and interfaces. - ''' + def expand(self, expr): + # Expand a C expression, replacing certain variables + if not isinstance(expr, basestring): + return expr + variables = {} + + if self.__structs is not None: + variables['self'] = '(%s)' % self.__structs[0] + if self.__indices is not None: + variables['i'] = self.__indices[0] + + expandedExpr = expr.format(**variables) + if expandedExpr != expr and 0: + sys.stderr.write(" %r -> %r\n" % (expr, expandedExpr)) + return expandedExpr + + def visitMember(self, member, structInstance, *args, **kwargs): + memberType, memberName = member + if memberName is None: + # Anonymous structure/union member + memberInstance = structInstance + else: + memberInstance = '(%s).%s' % (structInstance, memberName) + self.__structs = (structInstance, self.__structs) + try: + return self.visit(memberType, memberInstance, *args, **kwargs) + finally: + _, self.__structs = self.__structs + + def visitElement(self, elementIndex, elementType, *args, **kwargs): + self.__indices = (elementIndex, self.__indices) + try: + return self.visit(elementType, *args, **kwargs) + finally: + _, self.__indices = self.__indices + + +class Module: + '''A collection of functions.''' def __init__(self, name = None): self.name = name @@ -846,50 +886,73 @@ class API: self.functions = [] self.interfaces = [] + def addFunctions(self, functions): + self.functions.extend(functions) + + def addInterfaces(self, interfaces): + self.interfaces.extend(interfaces) + + def mergeModule(self, module): + self.headers.extend(module.headers) + self.functions.extend(module.functions) + self.interfaces.extend(module.interfaces) + + def getFunctionByName(self, name): + for function in self.functions: + if function.name == name: + return function + return None + + +class API: + '''API abstraction. + + Essentially, a collection of types, functions, and interfaces. + ''' + + def __init__(self, modules = None): + self.modules = [] + if modules is not None: + self.modules.extend(modules) + def getAllTypes(self): collector = Collector() - for function in self.functions: - for arg in function.args: - collector.visit(arg.type) - collector.visit(function.type) - for interface in self.interfaces: - collector.visit(interface) - for method in interface.iterMethods(): - for arg in method.args: + for module in self.modules: + for function in module.functions: + for arg in function.args: collector.visit(arg.type) - collector.visit(method.type) + collector.visit(function.type) + for interface in module.interfaces: + collector.visit(interface) + for method in interface.iterMethods(): + for arg in method.args: + collector.visit(arg.type) + collector.visit(method.type) return collector.types + def getAllFunctions(self): + functions = [] + for module in self.modules: + functions.extend(module.functions) + return functions + def getAllInterfaces(self): types = self.getAllTypes() interfaces = [type for type in types if isinstance(type, Interface)] - for interface in self.interfaces: - if interface not in interfaces: - interfaces.append(interface) + for module in self.modules: + for interface in module.interfaces: + if interface not in interfaces: + interfaces.append(interface) return interfaces - def addFunction(self, function): - self.functions.append(function) - - def addFunctions(self, functions): - for function in functions: - self.addFunction(function) - - def addInterface(self, interface): - self.interfaces.append(interface) - - def addInterfaces(self, interfaces): - self.interfaces.extend(interfaces) - - def addApi(self, api): - self.headers.extend(api.headers) - self.addFunctions(api.functions) - self.addInterfaces(api.interfaces) + def addModule(self, module): + self.modules.append(module) def getFunctionByName(self, name): - for function in self.functions: - if function.name == name: - return function + for module in self.modules: + for function in module.functions: + if function.name == name: + return function return None