[Python-checkins] python/dist/src/Tools/bgen/bgen bgenBuffer.py, 1.7.2.2, 1.7.2.3 bgenGenerator.py, 1.11.16.2, 1.11.16.3 bgenHeapBuffer.py, 1.3.16.2, 1.3.16.3 bgenObjectDefinition.py, 1.16.2.2, 1.16.2.3 bgenStackBuffer.py, 1.2.30.1, 1.2.30.2 bgenStringBuffer.py, 1.1.30.2, 1.1.30.3 bgenType.py, 1.9.2.2, 1.9.2.3 bgenVariable.py, 1.1.30.1, 1.1.30.2 scantools.py, 1.28.2.2, 1.28.2.3

jhylton@users.sourceforge.net jhylton at users.sourceforge.net
Sun Oct 16 07:24:11 CEST 2005


Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Tools/bgen/bgen

Modified Files:
      Tag: ast-branch
	bgenBuffer.py bgenGenerator.py bgenHeapBuffer.py 
	bgenObjectDefinition.py bgenStackBuffer.py bgenStringBuffer.py 
	bgenType.py bgenVariable.py scantools.py 
Log Message:
Merge head to branch (for the last time)


Index: bgenBuffer.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenBuffer.py,v
retrieving revision 1.7.2.2
retrieving revision 1.7.2.3
diff -u -d -r1.7.2.2 -r1.7.2.3
--- bgenBuffer.py	7 Jan 2005 07:05:04 -0000	1.7.2.2
+++ bgenBuffer.py	16 Oct 2005 05:24:06 -0000	1.7.2.3
@@ -38,23 +38,33 @@
         self.sizeformat = sizeformat or type2format[sizetype]
         self.label_needed = 0
 
-    def declare(self, name):
-        self.declareBuffer(name)
-        self.declareSize(name)
+    def getArgDeclarations(self, name, reference=False, constmode=False):
+        if reference:
+            raise RuntimeError, "Cannot pass buffer types by reference"
+        return (self.getBufferDeclarations(name, constmode) +
+                self.getSizeDeclarations(name))
 
-    def declareBuffer(self, name):
-        self.declareInputBuffer(name)
-        self.declareOutputBuffer(name)
+    def getBufferDeclarations(self, name, constmode=False):
+        return self.getInputBufferDeclarations(name, constmode) + \
+                self.getOutputBufferDeclarations(name, constmode)
 
-    def declareInputBuffer(self, name):
-        Output("%s *%s__in__;", self.datatype, name)
+    def getInputBufferDeclarations(self, name, constmode=False):
+        if constmode:
+            const = "const "
+        else:
+            const = ""
+        return ["%s%s *%s__in__" % (const, self.datatype, name)]
 
-    def declareOutputBuffer(self, name):
-        Output("%s %s__out__[%s];", self.datatype, name, self.size)
+    def getOutputBufferDeclarations(self, name, constmode=False):
+        if constmode:
+            raise RuntimeError, "Cannot use const output buffer"
+        return ["%s %s__out__[%s]" % (self.datatype, name, self.size)]
 
-    def declareSize(self, name):
-        Output("%s %s__len__;", self.sizetype, name)
-        Output("int %s__in_len__;", name)
+    def getSizeDeclarations(self, name):
+        return ["%s %s__len__" %(self.sizetype, name)]
+
+    def getAuxDeclarations(self, name):
+        return ["int %s__in_len__" %(name)]
 
     def getargsFormat(self):
         return "s#"
@@ -102,14 +112,14 @@
 
 class InputOnlyBufferMixIn(InputOnlyMixIn):
 
-    def declareOutputBuffer(self, name):
-        pass
+    def getOutputBufferDeclarations(self, name, constmode=False):
+        return []
 
 
 class OutputOnlyBufferMixIn(OutputOnlyMixIn):
 
-    def declareInputBuffer(self, name):
-        pass
+    def getInputBufferDeclarations(self, name, constmode=False):
+        return []
 
 class OptionalInputBufferMixIn:
 
@@ -183,14 +193,23 @@
         FixedInputOutputBufferType.__init__(self, "sizeof(%s)" % type)
         self.typeName = self.type = type
 
-    def declareInputBuffer(self, name):
-        Output("%s *%s__in__;", self.type, name)
+    def getInputBufferDeclarations(self, name, constmode=False):
+        if constmode:
+            const = "const "
+        else:
+            const = ""
+        return ["%s%s *%s__in__" % (const, self.type, name)]
 
-    def declareSize(self, name):
-        Output("int %s__in_len__;", name)
+    def getSizeDeclarations(self, name):
+        return []
 
-    def declareOutputBuffer(self, name):
-        Output("%s %s__out__;", self.type, name)
+    def getAuxDeclarations(self, name):
+        return ["int %s__in_len__" % (name)]
+
+    def getOutputBufferDeclarations(self, name, constmode=False):
+        if constmode:
+            raise RuntimeError, "Cannot use const output buffer"
+        return ["%s %s__out__" % (self.type, name)]
 
     def getargsArgs(self, name):
         return "(char **)&%s__in__, &%s__in_len__" % (name, name)
@@ -243,8 +262,11 @@
     Instantiate with the struct type as parameter.
     """
 
-    def declareSize(self, name):
-        pass
+    def getSizeDeclarations(self, name):
+        return []
+
+    def getAuxDeclarations(self, name):
+        return []
 
     def passOutput(self, name):
         return "&%s__out__" % name
@@ -257,8 +279,11 @@
     Instantiate with the struct type as parameter.
     """
 
-    def declareSize(self, name):
-        pass
+    def getSizeDeclarations(self, name):
+        return []
+
+    def getAuxDeclarations(self, name):
+        return []
 
     def passOutput(self, name):
         return "%s__out__" % name

Index: bgenGenerator.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenGenerator.py,v
retrieving revision 1.11.16.2
retrieving revision 1.11.16.3
diff -u -d -r1.11.16.2 -r1.11.16.3
--- bgenGenerator.py	7 Jan 2005 07:05:04 -0000	1.11.16.2
+++ bgenGenerator.py	16 Oct 2005 05:24:06 -0000	1.11.16.3
@@ -15,17 +15,27 @@
 
 class BaseFunctionGenerator:
 
-    def __init__(self, name, condition=None):
+    def __init__(self, name, condition=None, callname=None, modifiers=None):
         if DEBUG: print "<--", name
         self.name = name
+        if callname:
+            self.callname = callname
+        else:
+            self.callname = name
         self.prefix = name
         self.objecttype = "PyObject" # Type of _self argument to function
         self.condition = condition
+        self.modifiers = modifiers
 
     def setprefix(self, prefix):
         self.prefix = prefix
 
+    def checkgenerate(self):
+        return True
+
     def generate(self):
+        if not self.checkgenerate():
+            return
         if DEBUG: print "-->", self.name
         if self.condition:
             Output()
@@ -50,6 +60,8 @@
         OutRbrace()
 
     def reference(self, name = None):
+        if not self.checkgenerate():
+            return
         if name is None:
             name = self.name
         docstring = self.docstring()
@@ -175,17 +187,8 @@
             arg.declare()
 
     def getargs(self):
-        fmt = ""
-        lst = ""
         sep = ",\n" + ' '*len("if (!PyArg_ParseTuple(")
-        for arg in self.argumentList:
-            if arg.flags == SelfMode:
-                continue
-            if arg.mode in (InMode, InOutMode):
-                fmt = fmt + arg.getargsFormat()
-                args = arg.getargsArgs()
-                if args:
-                    lst = lst + sep + args
+        fmt, lst = self.getargsFormatArgs(sep)
         Output("if (!PyArg_ParseTuple(_args, \"%s\"%s))", fmt, lst)
         IndentLevel()
         Output("return NULL;")
@@ -196,15 +199,32 @@
             if arg.mode in (InMode, InOutMode):
                 arg.getargsCheck()
 
+    def getargsFormatArgs(self, sep):
+        fmt = ""
+        lst = ""
+        for arg in self.argumentList:
+            if arg.flags == SelfMode:
+                continue
+            if arg.mode in (InMode, InOutMode):
+                arg.getargsPreCheck()
+                fmt = fmt + arg.getargsFormat()
+                args = arg.getargsArgs()
+                if args:
+                    lst = lst + sep + args
+        return fmt, lst
+
     def precheck(self):
         pass
 
+    def beginallowthreads(self):
+        pass
+        
+    def endallowthreads(self):
+        pass
+        
     def callit(self):
         args = ""
-        if self.rv:
-            s = "%s = %s(" % (self.rv.name, self.name)
-        else:
-            s = "%s(" % self.name
+        s = "%s%s(" % (self.getrvforcallit(), self.callname)
         sep = ",\n" + ' '*len(s)
         for arg in self.argumentList:
             if arg is self.rv:
@@ -212,26 +232,24 @@
             s = arg.passArgument()
             if args: s = sep + s
             args = args + s
+        self.beginallowthreads()
+        Output("%s%s(%s);",
+               self.getrvforcallit(), self.callname, args)
+        self.endallowthreads()
+
+    def getrvforcallit(self):
         if self.rv:
-            Output("%s = %s(%s);",
-                   self.rv.name, self.name, args)
+            return "%s = " % self.rv.name
         else:
-            Output("%s(%s);", self.name, args)
+            return ""
 
     def checkit(self):
         for arg in self.argumentList:
             arg.errorCheck()
 
     def returnvalue(self):
-        fmt = ""
-        lst = ""
         sep = ",\n" + ' '*len("return Py_BuildValue(")
-        for arg in self.argumentList:
-            if not arg: continue
-            if arg.flags == ErrorMode: continue
-            if arg.mode in (OutMode, InOutMode):
-                fmt = fmt + arg.mkvalueFormat()
-                lst = lst + sep + arg.mkvalueArgs()
+        fmt, lst = self.mkvalueFormatArgs(sep)
         if fmt == "":
             Output("Py_INCREF(Py_None);")
             Output("_res = Py_None;");
@@ -244,6 +262,17 @@
             arg.cleanup()
         Output("return _res;")
 
+    def mkvalueFormatArgs(self, sep):
+        fmt = ""
+        lst = ""
+        for arg in self.argumentList:
+            if not arg: continue
+            if arg.flags == ErrorMode: continue
+            if arg.mode in (OutMode, InOutMode):
+                arg.mkvaluePreCheck()
+                fmt = fmt + arg.mkvalueFormat()
+                lst = lst + sep + arg.mkvalueArgs()
+        return fmt, lst
 
 class MethodGenerator(FunctionGenerator):
 
@@ -256,7 +285,6 @@
         self.argumentList.append(self.itself)
         FunctionGenerator.parseArgumentList(self, args)
 
-
 def _test():
     void = None
     eggs = FunctionGenerator(void, "eggs",

Index: bgenHeapBuffer.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenHeapBuffer.py,v
retrieving revision 1.3.16.2
retrieving revision 1.3.16.3
diff -u -d -r1.3.16.2 -r1.3.16.3
--- bgenHeapBuffer.py	7 Jan 2005 07:05:04 -0000	1.3.16.2
+++ bgenHeapBuffer.py	16 Oct 2005 05:24:06 -0000	1.3.16.3
@@ -16,8 +16,10 @@
     def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None):
         FixedInputOutputBufferType.__init__(self, "0", datatype, sizetype, sizeformat)
 
-    def declareOutputBuffer(self, name):
-        Output("%s *%s__out__;", self.datatype, name)
+    def getOutputBufferDeclarations(self, name, constmode=False):
+        if constmode:
+            raise RuntimeError, "Cannot use const output buffer"
+        return ["%s *%s__out__" % (self.datatype, name)]
 
     def getargsCheck(self, name):
         Output("if ((%s__out__ = malloc(%s__in_len__)) == NULL)", name, name)
@@ -74,8 +76,8 @@
     Call from Python with buffer size.
     """
 
-    def declareInputBuffer(self, name):
-        pass
+    def getInputBufferDeclarations(self, name, constmode=False):
+        return []
 
     def getargsFormat(self):
         return "i"
@@ -109,3 +111,32 @@
 
     def passOutput(self, name):
         return "%s__out__, %s__len__, &%s__len__" % (name, name, name)
+        
+class MallocHeapOutputBufferType(HeapOutputBufferType):
+    """Output buffer allocated by the called function -- passed as (&buffer, &size).
+    
+    Instantiate without parameters.
+    Call from Python without parameters.
+    """
+
+    def getargsCheck(self, name):
+        Output("%s__out__ = NULL;", name)
+
+    def getAuxDeclarations(self, name):
+        return []
+        
+    def passOutput(self, name):
+        return "&%s__out__, &%s__len__" % (name, name)
+
+    def getargsFormat(self):
+        return ""
+
+    def getargsArgs(self, name):
+        return None
+        
+    def mkvalueFormat(self):
+        return "z#"
+        
+    def cleanup(self, name):
+        Output("if( %s__out__ ) free(%s__out__);", name, name)
+

Index: bgenObjectDefinition.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenObjectDefinition.py,v
retrieving revision 1.16.2.2
retrieving revision 1.16.2.3
diff -u -d -r1.16.2.2 -r1.16.2.3
--- bgenObjectDefinition.py	7 Jan 2005 07:05:04 -0000	1.16.2.2
+++ bgenObjectDefinition.py	16 Oct 2005 05:24:06 -0000	1.16.2.3
@@ -6,6 +6,7 @@
     basechain = "NULL"
     tp_flags = "Py_TPFLAGS_DEFAULT"
     basetype = None
+    argref = ""    # set to "*" if arg to <type>_New should be pointer
 
     def __init__(self, name, prefix, itselftype):
         """ObjectDefinition constructor.  May be extended, but do not override.
@@ -22,7 +23,6 @@
         self.itselftype = itselftype
         self.objecttype = name + 'Object'
         self.typename = name + '_Type'
-        self.argref = ""    # set to "*" if arg to <type>_New should be pointer
         self.static = "static " # set to "" to make <type>_New and <type>_Convert public
         self.modulename = None
         if hasattr(self, "assertions"):
@@ -44,12 +44,8 @@
 
         OutHeader2("Object type " + self.name)
 
-        sf = self.static and "static "
-        Output("%sPyTypeObject %s;", sf, self.typename)
-        Output()
-        Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))",
-               self.prefix, self.typename, self.typename)
-        Output()
+        self.outputCheck()
+
         Output("typedef struct %s {", self.objecttype)
         IndentLevel()
         Output("PyObject_HEAD")
@@ -84,6 +80,14 @@
 
         OutHeader2("End object type " + self.name)
 
+    def outputCheck(self):
+        sf = self.static and "static "
+        Output("%sPyTypeObject %s;", sf, self.typename)
+        Output()
+        Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))",
+               self.prefix, self.typename, self.typename)
+        Output()
+
     def outputMethodChain(self):
         Output("%sPyMethodChain %s_chain = { %s_methods, %s };",
                 self.static,    self.prefix, self.prefix, self.basechain)
@@ -113,6 +117,7 @@
         "Override this method to apply additional checks/conversions"
 
     def outputConvert(self):
+        Output()
         Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix,
                 self.itselftype)
         OutLbrace()
@@ -214,6 +219,9 @@
         Output("if (PyType_Ready(&%s) < 0) return;", self.typename)
         Output("""Py_INCREF(&%s);""", self.typename)
         Output("PyModule_AddObject(m, \"%s\", (PyObject *)&%s);", self.name, self.typename);
+        self.outputTypeObjectInitializerCompat()
+
+    def outputTypeObjectInitializerCompat(self):
         Output("/* Backward-compatible name */")
         Output("""Py_INCREF(&%s);""", self.typename);
         Output("PyModule_AddObject(m, \"%sType\", (PyObject *)&%s);", self.name, self.typename);
@@ -377,7 +385,7 @@
 
     def output_tp_init(self):
         if self.output_tp_initBody:
-            Output("static int %s_tp_init(PyObject *self, PyObject *args, PyObject *kwds)", self.prefix)
+            Output("static int %s_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)", self.prefix)
             OutLbrace()
             self.output_tp_initBody()
             OutRbrace()
@@ -399,19 +407,19 @@
         Output()
 
     def output_tp_newBody(self):
-        Output("PyObject *self;");
+        Output("PyObject *_self;");
         Output("%s itself;", self.itselftype);
         Output("char *kw[] = {\"itself\", 0};")
         Output()
-        Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;",
+        Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;",
             self.prefix);
-        Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
-        Output("((%s *)self)->ob_itself = itself;", self.objecttype)
-        Output("return self;")
+        Output("if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;")
+        Output("((%s *)_self)->ob_itself = itself;", self.objecttype)
+        Output("return _self;")
 
     def output_tp_new(self):
         if self.output_tp_newBody:
-            Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)", self.prefix)
+            Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)", self.prefix)
             OutLbrace()
             self.output_tp_newBody()
             OutRbrace()

Index: bgenStackBuffer.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenStackBuffer.py,v
retrieving revision 1.2.30.1
retrieving revision 1.2.30.2
diff -u -d -r1.2.30.1 -r1.2.30.2
--- bgenStackBuffer.py	28 Apr 2003 17:16:37 -0000	1.2.30.1
+++ bgenStackBuffer.py	16 Oct 2005 05:24:06 -0000	1.2.30.2
@@ -22,8 +22,11 @@
     Instantiate with the buffer size as parameter.
     """
 
-    def declareSize(self, name):
-        Output("int %s__len__ = %s;", name, self.size)
+    def getSizeDeclarations(self, name):
+        return []
+
+    def getAuxDeclarations(self, name):
+        return ["int %s__len__ = %s" % (name, self.size)]
 
     def passOutput(self, name):
         return "%s__out__, &%s__len__" % (name, name)

Index: bgenStringBuffer.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenStringBuffer.py,v
retrieving revision 1.1.30.2
retrieving revision 1.1.30.3
diff -u -d -r1.1.30.2 -r1.1.30.3
--- bgenStringBuffer.py	7 Jan 2005 07:05:04 -0000	1.1.30.2
+++ bgenStringBuffer.py	16 Oct 2005 05:24:06 -0000	1.1.30.3
@@ -23,8 +23,11 @@
     less common.  I'll write the classes when there is demand.)
     """
 
-    def declareSize(self, name):
-        pass
+    def getSizeDeclarations(self, name):
+        return []
+
+    def getAuxDeclarations(self, name):
+        return []
 
     def getargsFormat(self):
         return "s"

Index: bgenType.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenType.py,v
retrieving revision 1.9.2.2
retrieving revision 1.9.2.3
diff -u -d -r1.9.2.2 -r1.9.2.3
--- bgenType.py	7 Jan 2005 07:05:05 -0000	1.9.2.2
+++ bgenType.py	16 Oct 2005 05:24:06 -0000	1.9.2.3
@@ -19,12 +19,34 @@
         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)
+        for decl in self.getArgDeclarations(name, reference):
+            Output("%s;", decl)
+        for decl in self.getAuxDeclarations(name):
+            Output("%s;", decl)
+
+    def getArgDeclarations(self, name, reference=False, constmode=False):
+        """Return the main part of the declarations for this type: the items
+        that will be passed as arguments in the C/C++ function call."""
+        if reference:
+            ref = "&"
+        else:
+            ref = ""
+        if constmode:
+            const = "const "
+        else:
+            const = ""
+        return ["%s%s%s %s" % (const, self.typeName, ref, name)]
+
+    def getAuxDeclarations(self, name):
+        """Return any auxiliary declarations needed for implementing this
+        type, such as helper variables used to hold sizes, etc. These declarations
+        are not part of the C/C++ function call interface."""
+        return []
 
     def getargs(self):
         return self.getargsFormat(), self.getargsArgs()
@@ -44,11 +66,18 @@
         """
         return "&" + name
 
+    def getargsPreCheck(self, name):
+        """Perform any actions needed before calling getargs().
+
+        This could include declaring temporary variables and such.
+        """
+
     def getargsCheck(self, name):
         """Perform any needed post-[new]getargs() checks.
 
         This is type-dependent; the default does not check for errors.
-        An example would be a check for a maximum string length."""
+        An example would be a check for a maximum string length, or it
+        could do post-getargs() copying or conversion."""
 
     def passInput(self, name):
         """Return an argument for passing a variable into a call.
@@ -64,6 +93,12 @@
         """
         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.
 
@@ -96,6 +131,12 @@
         """
         return name
 
+    def mkvaluePreCheck(self, name):
+        """Perform any actions needed before calling mkvalue().
+
+        This could include declaring temporary variables and such.
+        """
+
     def cleanup(self, name):
         """Clean up if necessary.
 
@@ -172,8 +213,11 @@
         self.substitute = substitute
         self.typeName = None    # Don't show this argument in __doc__ string
 
-    def declare(self, name):
-        pass
+    def getArgDeclarations(self, name, reference=False, constmode=False):
+        return []
+
+    def getAuxDeclarations(self, name, reference=False):
+        return []
 
     def getargsFormat(self):
         return ""
@@ -237,6 +281,25 @@
     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
     address, in stead of by value.

Index: bgenVariable.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenVariable.py,v
retrieving revision 1.1.30.1
retrieving revision 1.1.30.2
diff -u -d -r1.1.30.1 -r1.1.30.2
--- bgenVariable.py	28 Apr 2003 17:16:37 -0000	1.1.30.1
+++ bgenVariable.py	16 Oct 2005 05:24:06 -0000	1.1.30.2
@@ -13,7 +13,8 @@
 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
+ConstMode  = 64
 
 class Variable:
 
@@ -39,9 +40,21 @@
 
         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 getArgDeclarations(self, constmode=False):
+        refmode = (self.flags & RefMode)
+        if constmode:
+            constmode = (self.flags & ConstMode)
+        return self.type.getArgDeclarations(self.name,
+                reference=refmode, constmode=constmode)
+
+    def getAuxDeclarations(self):
+        return self.type.getAuxDeclarations(self.name)
+
     def getargsFormat(self):
         """Call the type's getargsFormatmethod."""
         return self.type.getargsFormat()
@@ -53,6 +66,9 @@
     def getargsCheck(self):
         return self.type.getargsCheck(self.name)
 
+    def getargsPreCheck(self):
+        return self.type.getargsPreCheck(self.name)
+
     def passArgument(self):
         """Return the string required to pass the variable as argument.
 
@@ -62,6 +78,8 @@
         """
         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
@@ -83,6 +101,9 @@
         """Call the type's mkvalueArgs method."""
         return self.type.mkvalueArgs(self.name)
 
+    def mkvaluePreCheck(self):
+        return self.type.mkvaluePreCheck(self.name)
+
     def cleanup(self):
         """Call the type's cleanup method."""
         return self.type.cleanup(self.name)

Index: scantools.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/scantools.py,v
retrieving revision 1.28.2.2
retrieving revision 1.28.2.3
diff -u -d -r1.28.2.2 -r1.28.2.3
--- scantools.py	7 Jan 2005 07:05:05 -0000	1.28.2.2
+++ scantools.py	16 Oct 2005 05:24:06 -0000	1.28.2.3
@@ -32,6 +32,76 @@
 
 Error = "scantools.Error"
 
+BEGINHTMLREPORT="""<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<style type="text/css">
+.unmatched {  }
+.commentstripping { color: grey; text-decoration: line-through }
+.comment { text-decoration: line-through }
+.notcomment { color: black }
+.incomplete { color: maroon }
+.constant { color: green }
+.pyconstant { background-color: yellow }
+.blconstant { background-color: yellow; color: red }
+.declaration { color: blue }
+.pydeclaration { background-color: yellow }
+.type { font-style: italic }
+.name { font-weight: bold }
+.value { font-style: italic }
+.arglist { text-decoration: underline }
+.blacklisted { background-color: yellow; color: red }
+</style>
+<title>Bgen scan report</title>
+</head>
+<body>
+<h1>Bgen scan report</h1>
+<h2>Legend</h2>
+<p>This scan report is intended to help you debug the regular expressions
+used by the bgen scanner. It consists of the original ".h" header file(s)
+marked up to show you what the regular expressions in the bgen parser matched
+for each line. NOTE: comments in the original source files may or may not be
+shown.</p>
+<p>The typographic conventions of this file are as follows:</p>
+<dl>
+<dt>comment stripping</dt>
+<dd><pre><span class="commentstripping"><span class="notcomment">comment stripping is </span><span class="comment">/* marked up */</span><span class="notcomment"> and the line is repeated if needed</span></span></pre>
+<p>If anything here does not appear to happen correctly look at
+<tt>comment1_pat</tt> and <tt>comment2_pat</tt>.</p>
+</dd>
+<dt>constant definitions</dt>
+<dd><pre><span class="constant">#define <span class="name">name</span> <span class="value">value</span></pre>
+<p>Highlights name and value of the constant. Governed by <tt>sym_pat</tt>.</p>
+</dd>
+<dt>function declaration</dt>
+<dd><pre><span class="declaration"><span class="type">char *</span><span class="name">rindex</span><span class="arglist">(<span class="type">const char *</span><span class="name">s</span>, <span class="type">int </span><span class="name">c</span>)</span>;</span></pre>
+<p>Highlights type, name and argument list. <tt>type_pat</tt>,
+<tt>name_pat</tt> and <tt>args_pat</tt> are combined into <tt>whole_pat</tt>, which
+is what is used here.</p></dd>
+</dd>
+<dt>incomplete match for function declaration</dt>
+<dd><pre><span class="incomplete"><span class="type">char *</span>foo;</span></pre>
+<p>The beginning of this looked promising, but it did not match a function declaration.
+In other words, it matched <tt>head_pat</tt> but not <tt>whole_pat</tt>. If the next
+declaration has also been gobbled up you need to look at <tt>end_pat</tt>.</p>
+</dd>
+<dt>unrecognized input</dt>
+<dd><pre><span class="unmatched">#include "type.h"</span></pre>
+<p>If there are function declarations the scanner has missed (i.e. things
+are in this class but you want them to be declarations) you need to adapt
+<tt>head_pat</tt>.
+</dd>
+</dl>
+<h2>Output</h2>
+<pre>
+<span class="unmatched">
+"""
+ENDHTMLREPORT="""</span>
+</pre>
+</body>
+</html>
+"""
+
 class Scanner:
 
     # Set to 1 in subclass to debug your scanner patterns.
@@ -232,9 +302,11 @@
         self.specmine = 0
         self.defsmine = 0
         self.scanmine = 0
+        self.htmlmine = 0
         self.specfile = sys.stdout
         self.defsfile = None
         self.scanfile = sys.stdin
+        self.htmlfile = None
         self.lineno = 0
         self.line = ""
 
@@ -286,6 +358,7 @@
         self.closespec()
         self.closedefs()
         self.closescan()
+        self.closehtml()
 
     def closespec(self):
         tmp = self.specmine and self.specfile
@@ -302,6 +375,12 @@
         self.scanfile = None
         if tmp: tmp.close()
 
+    def closehtml(self):
+        if self.htmlfile: self.htmlfile.write(ENDHTMLREPORT)
+        tmp = self.htmlmine and self.htmlfile
+        self.htmlfile = None
+        if tmp: tmp.close()
+
     def setoutput(self, spec, defs = None):
         self.closespec()
         self.closedefs()
@@ -324,6 +403,19 @@
             self.defsfile = file
             self.defsmine = mine
 
+    def sethtmloutput(self, htmlfile):
+        self.closehtml()
+        if htmlfile:
+            if type(htmlfile) == StringType:
+                file = self.openoutput(htmlfile)
+                mine = 1
+            else:
+                file = htmlfile
+                mine = 0
+            self.htmlfile = file
+            self.htmlmine = mine
+            self.htmlfile.write(BEGINHTMLREPORT)
+
     def openoutput(self, filename):
         try:
             file = open(filename, 'w')
@@ -408,11 +500,17 @@
                     self.report("LINE: %r" % (line,))
                 match = self.comment1.match(line)
                 if match:
+                    self.htmlreport(line, klass='commentstripping', ranges=[(
+                        match.start('rest'), match.end('rest'), 'notcomment')])
                     line = match.group('rest')
                     if self.debug:
                         self.report("\tafter comment1: %r" % (line,))
                 match = self.comment2.match(line)
                 while match:
+                    if match:
+                        self.htmlreport(line, klass='commentstripping', ranges=[
+                            (match.start('rest1'), match.end('rest1'), 'notcomment'),
+                            (match.start('rest2'), match.end('rest2'), 'notcomment')])
                     line = match.group('rest1')+match.group('rest2')
                     if self.debug:
                         self.report("\tafter comment2: %r" % (line,))
@@ -422,7 +520,7 @@
                     if match:
                         if self.debug:
                             self.report("\tmatches sym.")
-                        self.dosymdef(match)
+                        self.dosymdef(match, line)
                         continue
                 match = self.head.match(line)
                 if match:
@@ -430,19 +528,26 @@
                         self.report("\tmatches head.")
                     self.dofuncspec()
                     continue
+                self.htmlreport(line, klass='unmatched')
         except EOFError:
             self.error("Uncaught EOF error")
         self.reportusedtypes()
 
-    def dosymdef(self, match):
+    def dosymdef(self, match, line):
         name, defn = match.group('name', 'defn')
+        self.htmlreport(line, klass='constant', ranges=[
+            (match.start('name'), match.end('name'), 'name'),
+            (match.start('defn'), match.end('defn'), 'value')])
         defn = escape8bit(defn)
         if self.debug:
             self.report("\tsym: name=%r, defn=%r" % (name, defn))
         if not name in self.blacklistnames:
-            self.defsfile.write("%s = %s\n" % (name, defn))
+            oline = "%s = %s\n" % (name, defn)
+            self.defsfile.write(oline)
+            self.htmlreport(oline, klass="pyconstant")
         else:
             self.defsfile.write("# %s = %s\n" % (name, defn))
+            self.htmlreport("** no output: name is blacklisted", klass="blconstant")
         # XXXX No way to handle greylisted names
 
     def dofuncspec(self):
@@ -466,25 +571,37 @@
         if self.debug:
             self.report("* WHOLE LINE: %r" % (raw,))
         self.processrawspec(raw)
+        return raw
 
     def processrawspec(self, raw):
         match = self.whole.search(raw)
         if not match:
             self.report("Bad raw spec: %r", raw)
             if self.debug:
-                if not self.type.search(raw):
+                match = self.type.search(raw)
+                if not match:
                     self.report("(Type already doesn't match)")
+                    self.htmlreport(raw, klass='incomplete', ranges=[(
+                        match.start('type'), match.end('type'), 'type')])
                 else:
                     self.report("(but type matched)")
+                    self.htmlreport(raw, klass='incomplete')
             return
         type, name, args = match.group('type', 'name', 'args')
-        type = re.sub("\*", " ptr", type)
-        type = re.sub("[ \t]+", "_", type)
-        if name in self.alreadydone:
-            self.report("Name has already been defined: %r", name)
+        ranges=[
+                (match.start('type'), match.end('type'), 'type'),
+                (match.start('name'), match.end('name'), 'name'),
+                (match.start('args'), match.end('args'), 'arglist')]
+        self.htmlreport(raw, klass='declaration', ranges=ranges)
+        modifiers = self.getmodifiers(match)
+        type = self.pythonizename(type)
+        name = self.pythonizename(name)
+        if self.checkduplicate(name):
+            self.htmlreport("*** no output generated: duplicate name", klass="blacklisted")
             return
         self.report("==> %s %s <==", type, name)
         if self.blacklisted(type, name):
+            self.htmlreport("*** no output generated: function name or return type blacklisted", klass="blacklisted")
             self.report("*** %s %s blacklisted", type, name)
             return
         returnlist = [(type, name, 'ReturnMode')]
@@ -493,12 +610,31 @@
         arglist = self.extractarglist(args)
         arglist = self.repairarglist(name, arglist)
         if self.unmanageable(type, name, arglist):
+            self.htmlreport("*** no output generated: some argument blacklisted", klass="blacklisted")
             ##for arg in arglist:
             ##  self.report("    %r", arg)
             self.report("*** %s %s unmanageable", type, name)
             return
+        if modifiers:
+            self.generate(type, name, arglist, modifiers)
+        else:
+            self.generate(type, name, arglist)
+
+    def getmodifiers(self, match):
+        return []
+
+    def checkduplicate(self, name):
+        if name in self.alreadydone:
+            self.report("Name has already been defined: %r", name)
+            return True
         self.alreadydone.append(name)
-        self.generate(type, name, arglist)
+        return False
+
+    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()
@@ -522,9 +658,7 @@
         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):
@@ -587,23 +721,42 @@
         ##self.report("new: %r", new)
         return new
 
-    def generate(self, type, name, arglist):
-        self.typeused(type, 'return')
-        classname, listname = self.destination(type, name, arglist)
-        if not self.specfile: return
-        self.specfile.write("f = %s(%s, %r,\n" % (classname, type, name))
+    def generate(self, tp, name, arglist, modifiers=[]):
+
+        self.typeused(tp, 'return')
+        if modifiers:
+            classname, listname = self.destination(tp, name, arglist, modifiers)
+        else:
+            classname, listname = self.destination(tp, name, arglist)
+        if not classname or not listname:
+            self.htmlreport("*** no output generated: self.destination() returned None", klass="blacklisted")
+            return
+        if not self.specfile:
+            self.htmlreport("*** no output generated: no output file specified", klass="blacklisted")
+            return
+        self.specfile.write("f = %s(%s, %r,\n" % (classname, tp, name))
         for atype, aname, amode in arglist:
             self.typeused(atype, amode)
             self.specfile.write("    (%s, %r, %s),\n" %
                                 (atype, aname, amode))
         if self.greydictnames.has_key(name):
             self.specfile.write("    condition=%r,\n"%(self.greydictnames[name],))
+        self.generatemodifiers(classname, name, modifiers)
         self.specfile.write(")\n")
         self.specfile.write("%s.append(f)\n\n" % listname)
+        if self.htmlfile:
+            oline = "Adding to %s:\n%s(returntype=%s, name=%r" % (listname, classname, tp, name)
+            for atype, aname, amode in arglist:
+                oline += ",\n    (%s, %r, %s)" % (atype, aname, amode)
+            oline += ")\n"
+            self.htmlreport(oline, klass="pydeclaration")
 
     def destination(self, type, name, arglist):
         return "FunctionGenerator", "functions"
 
+    def generatemodifiers(self, classname, name, modifiers):
+        pass
+
     def blacklisted(self, type, name):
         if type in self.blacklisttypes:
             ##self.report("return type %s is blacklisted", type)
@@ -620,6 +773,34 @@
                 return 1
         return 0
 
+    def htmlreport(self, line, klass=None, ranges=None):
+        if not self.htmlfile: return
+        if ranges is None:
+            ranges = []
+        if klass:
+            ranges.insert(0, (0, len(line), klass))
+        oline = ''
+        i = 0
+        for c in line:
+            for b, e, name in ranges:
+                if b == i:
+                    oline += '<span class="%s">' % name
+                if e == i:
+                    oline += '</span>'
+            i += 1
+
+            if c == '<': oline += '&lt;'
+            elif c == '>': oline += '&gt;'
+            else: oline += c
+        for b, e, name in ranges:
+            if b >= i:
+                oline += '<span class="%s">' % name
+            if e >= i:
+                oline += '</span>'
+        if not line or line[-1] != '\n':
+            oline += '\n'
+        self.htmlfile.write(oline)
+
 class Scanner_PreUH3(Scanner):
     """Scanner for Universal Headers before release 3"""
     def initpatterns(self):



More information about the Python-checkins mailing list