diff --git a/Tools/bgen/bgen/bgenType.py b/Tools/bgen/bgen/bgenType.py index 4f3026a11ce..9d5b4f81212 100644 --- a/Tools/bgen/bgen/bgenType.py +++ b/Tools/bgen/bgen/bgenType.py @@ -19,12 +19,15 @@ class Type: self.typeName = typeName self.fmt = fmt - def declare(self, name): + def declare(self, name, reference=False): """Declare a variable of the type with a given name. Example: int.declare('spam') prints "int spam;" """ - Output("%s %s;", self.typeName, name) + if reference: + Output("%s& %s;", self.typeName, name) + else: + Output("%s %s;", self.typeName, name) def getargs(self): return self.getargsFormat(), self.getargsArgs() @@ -64,6 +67,11 @@ class Type: """ return "&" + name + def passReference(self, name): + """Return an argument for C++ pass-by-reference. + Default is to call passInput(). + """ + return self.passInput(name) def errorCheck(self, name): """Check for an error returned in the variable. @@ -172,7 +180,7 @@ class FakeType(InputOnlyType): self.substitute = substitute self.typeName = None # Don't show this argument in __doc__ string - def declare(self, name): + def declare(self, name, reference=False): pass def getargsFormat(self): @@ -236,6 +244,25 @@ class OpaqueByValueType(OpaqueType): def mkvalueArgs(self, name): return "%s, %s" % (self.new, name) + +class OpaqueByRefType(OpaqueType): + """An opaque object type, passed by reference. + + Instantiate with the type name, and optionally an object type name whose + New/Convert functions will be used. + """ + + def passInput(self, name): + return name + +# def passOutput(self, name): +# return name + + def mkvalueFormat(self): + return "O" + + def mkvalueArgs(self, name): + return "%s(%s)" % (self.new, name) class OpaqueByValueStructType(OpaqueByValueType): """Similar to OpaqueByValueType, but we also pass this to mkvalue by diff --git a/Tools/bgen/bgen/bgenVariable.py b/Tools/bgen/bgen/bgenVariable.py index 7b947ab6c14..36c287d6e5d 100644 --- a/Tools/bgen/bgen/bgenVariable.py +++ b/Tools/bgen/bgen/bgenVariable.py @@ -13,7 +13,7 @@ ModeMask = 3 # bits to keep for mode SelfMode = 4+InMode # this is 'self' -- don't declare it ReturnMode = 8+OutMode # this is the function return value ErrorMode = 16+OutMode # this is an error status -- turn it into an exception - +RefMode = 32 class Variable: @@ -39,7 +39,9 @@ class Variable: If it is "self", it is not declared. """ - if self.flags != SelfMode: + if self.flags == ReturnMode+RefMode: + self.type.declare(self.name, reference=True) + elif self.flags != SelfMode: self.type.declare(self.name) def getargsFormat(self): @@ -62,6 +64,8 @@ class Variable: """ if self.mode == InMode: return self.type.passInput(self.name) + if self.mode & RefMode: + return self.type.passReference(self.name) if self.mode in (OutMode, InOutMode): return self.type.passOutput(self.name) # XXX Shouldn't get here diff --git a/Tools/bgen/bgen/scantools.py b/Tools/bgen/bgen/scantools.py index df7ddfbe27c..7d2488efd0c 100644 --- a/Tools/bgen/bgen/scantools.py +++ b/Tools/bgen/bgen/scantools.py @@ -466,6 +466,7 @@ if missing: raise "Missing Types" if self.debug: self.report("* WHOLE LINE: %r" % (raw,)) self.processrawspec(raw) + return raw def processrawspec(self, raw): match = self.whole.search(raw) @@ -478,8 +479,8 @@ if missing: raise "Missing Types" self.report("(but type matched)") return type, name, args = match.group('type', 'name', 'args') - type = re.sub("\*", " ptr", type) - type = re.sub("[ \t]+", "_", type) + type = self.pythonizename(type) + name = self.pythonizename(name) if name in self.alreadydone: self.report("Name has already been defined: %r", name) return @@ -500,6 +501,12 @@ if missing: raise "Missing Types" self.alreadydone.append(name) self.generate(type, name, arglist) + def pythonizename(self, name): + name = re.sub("\*", " ptr", name) + name = name.strip() + name = re.sub("[ \t]+", "_", name) + return name + def extractarglist(self, args): args = args.strip() if not args or args == "void": @@ -522,9 +529,7 @@ if missing: raise "Missing Types" if array: # array matches an optional [] after the argument name type = type + " ptr " - type = re.sub("\*", " ptr ", type) - type = type.strip() - type = re.sub("[ \t]+", "_", type) + type = self.pythonizename(type) return self.modifyarg(type, name, mode) def modifyarg(self, type, name, mode): @@ -590,6 +595,7 @@ if missing: raise "Missing Types" def generate(self, type, name, arglist): self.typeused(type, 'return') classname, listname = self.destination(type, name, arglist) + if not classname or not listname: return if not self.specfile: return self.specfile.write("f = %s(%s, %r,\n" % (classname, type, name)) for atype, aname, amode in arglist: