Annotation of embedaddon/libxml2/python/generator.py, revision 1.1

1.1     ! misho       1: #!/usr/bin/python -u
        !             2: #
        !             3: # generate python wrappers from the XML API description
        !             4: #
        !             5: 
        !             6: functions = {}
        !             7: enums = {} # { enumType: { enumConstant: enumValue } }
        !             8: 
        !             9: import os
        !            10: import sys
        !            11: import string
        !            12: 
        !            13: if __name__ == "__main__":
        !            14:     # launched as a script
        !            15:     srcPref = os.path.dirname(sys.argv[0])
        !            16: else:
        !            17:     # imported
        !            18:     srcPref = os.path.dirname(__file__)
        !            19: 
        !            20: #######################################################################
        !            21: #
        !            22: #  That part if purely the API acquisition phase from the
        !            23: #  XML API description
        !            24: #
        !            25: #######################################################################
        !            26: import os
        !            27: import xml.sax
        !            28: 
        !            29: debug = 0
        !            30: 
        !            31: def getparser():
        !            32:     # Attach parser to an unmarshalling object. return both objects.
        !            33:     target = docParser()
        !            34:     parser = xml.sax.make_parser()
        !            35:     parser.setContentHandler(target)
        !            36:     return parser, target
        !            37: 
        !            38: class docParser(xml.sax.handler.ContentHandler):
        !            39:     def __init__(self):
        !            40:         self._methodname = None
        !            41:         self._data = []
        !            42:         self.in_function = 0
        !            43: 
        !            44:         self.startElement = self.start
        !            45:         self.endElement = self.end
        !            46:         self.characters = self.data
        !            47: 
        !            48:     def close(self):
        !            49:         if debug:
        !            50:             print "close"
        !            51: 
        !            52:     def getmethodname(self):
        !            53:         return self._methodname
        !            54: 
        !            55:     def data(self, text):
        !            56:         if debug:
        !            57:             print "data %s" % text
        !            58:         self._data.append(text)
        !            59: 
        !            60:     def start(self, tag, attrs):
        !            61:         if debug:
        !            62:             print "start %s, %s" % (tag, attrs)
        !            63:         if tag == 'function':
        !            64:             self._data = []
        !            65:             self.in_function = 1
        !            66:             self.function = None
        !            67:             self.function_cond = None
        !            68:             self.function_args = []
        !            69:             self.function_descr = None
        !            70:             self.function_return = None
        !            71:             self.function_file = None
        !            72:             if attrs.has_key('name'):
        !            73:                 self.function = attrs['name']
        !            74:             if attrs.has_key('file'):
        !            75:                 self.function_file = attrs['file']
        !            76:         elif tag == 'cond':
        !            77:             self._data = []
        !            78:         elif tag == 'info':
        !            79:             self._data = []
        !            80:         elif tag == 'arg':
        !            81:             if self.in_function == 1:
        !            82:                 self.function_arg_name = None
        !            83:                 self.function_arg_type = None
        !            84:                 self.function_arg_info = None
        !            85:                 if attrs.has_key('name'):
        !            86:                     self.function_arg_name = attrs['name']
        !            87:                 if attrs.has_key('type'):
        !            88:                     self.function_arg_type = attrs['type']
        !            89:                 if attrs.has_key('info'):
        !            90:                     self.function_arg_info = attrs['info']
        !            91:         elif tag == 'return':
        !            92:             if self.in_function == 1:
        !            93:                 self.function_return_type = None
        !            94:                 self.function_return_info = None
        !            95:                 self.function_return_field = None
        !            96:                 if attrs.has_key('type'):
        !            97:                     self.function_return_type = attrs['type']
        !            98:                 if attrs.has_key('info'):
        !            99:                     self.function_return_info = attrs['info']
        !           100:                 if attrs.has_key('field'):
        !           101:                     self.function_return_field = attrs['field']
        !           102:         elif tag == 'enum':
        !           103:             enum(attrs['type'],attrs['name'],attrs['value'])
        !           104: 
        !           105:     def end(self, tag):
        !           106:         if debug:
        !           107:             print "end %s" % tag
        !           108:         if tag == 'function':
        !           109:             if self.function != None:
        !           110:                 function(self.function, self.function_descr,
        !           111:                          self.function_return, self.function_args,
        !           112:                          self.function_file, self.function_cond)
        !           113:                 self.in_function = 0
        !           114:         elif tag == 'arg':
        !           115:             if self.in_function == 1:
        !           116:                 self.function_args.append([self.function_arg_name,
        !           117:                                            self.function_arg_type,
        !           118:                                            self.function_arg_info])
        !           119:         elif tag == 'return':
        !           120:             if self.in_function == 1:
        !           121:                 self.function_return = [self.function_return_type,
        !           122:                                         self.function_return_info,
        !           123:                                         self.function_return_field]
        !           124:         elif tag == 'info':
        !           125:             str = ''
        !           126:             for c in self._data:
        !           127:                 str = str + c
        !           128:             if self.in_function == 1:
        !           129:                 self.function_descr = str
        !           130:         elif tag == 'cond':
        !           131:             str = ''
        !           132:             for c in self._data:
        !           133:                 str = str + c
        !           134:             if self.in_function == 1:
        !           135:                 self.function_cond = str
        !           136:                 
        !           137:                 
        !           138: def function(name, desc, ret, args, file, cond):
        !           139:     functions[name] = (desc, ret, args, file, cond)
        !           140: 
        !           141: def enum(type, name, value):
        !           142:     if not enums.has_key(type):
        !           143:         enums[type] = {}
        !           144:     enums[type][name] = value
        !           145: 
        !           146: #######################################################################
        !           147: #
        !           148: #  Some filtering rukes to drop functions/types which should not
        !           149: #  be exposed as-is on the Python interface
        !           150: #
        !           151: #######################################################################
        !           152: 
        !           153: skipped_modules = {
        !           154:     'xmlmemory': None,
        !           155:     'DOCBparser': None,
        !           156:     'SAX': None,
        !           157:     'hash': None,
        !           158:     'list': None,
        !           159:     'threads': None,
        !           160: #    'xpointer': None,
        !           161: }
        !           162: skipped_types = {
        !           163:     'int *': "usually a return type",
        !           164:     'xmlSAXHandlerPtr': "not the proper interface for SAX",
        !           165:     'htmlSAXHandlerPtr': "not the proper interface for SAX",
        !           166:     'xmlRMutexPtr': "thread specific, skipped",
        !           167:     'xmlMutexPtr': "thread specific, skipped",
        !           168:     'xmlGlobalStatePtr': "thread specific, skipped",
        !           169:     'xmlListPtr': "internal representation not suitable for python",
        !           170:     'xmlBufferPtr': "internal representation not suitable for python",
        !           171:     'FILE *': None,
        !           172: }
        !           173: 
        !           174: #######################################################################
        !           175: #
        !           176: #  Table of remapping to/from the python type or class to the C
        !           177: #  counterpart.
        !           178: #
        !           179: #######################################################################
        !           180: 
        !           181: py_types = {
        !           182:     'void': (None, None, None, None),
        !           183:     'int':  ('i', None, "int", "int"),
        !           184:     'long':  ('l', None, "long", "long"),
        !           185:     'double':  ('d', None, "double", "double"),
        !           186:     'unsigned int':  ('i', None, "int", "int"),
        !           187:     'xmlChar':  ('c', None, "int", "int"),
        !           188:     'unsigned char *':  ('z', None, "charPtr", "char *"),
        !           189:     'char *':  ('z', None, "charPtr", "char *"),
        !           190:     'const char *':  ('z', None, "charPtrConst", "const char *"),
        !           191:     'xmlChar *':  ('z', None, "xmlCharPtr", "xmlChar *"),
        !           192:     'const xmlChar *':  ('z', None, "xmlCharPtrConst", "const xmlChar *"),
        !           193:     'xmlNodePtr':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           194:     'const xmlNodePtr':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           195:     'xmlNode *':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           196:     'const xmlNode *':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           197:     'xmlDtdPtr':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           198:     'const xmlDtdPtr':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           199:     'xmlDtd *':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           200:     'const xmlDtd *':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           201:     'xmlAttrPtr':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           202:     'const xmlAttrPtr':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           203:     'xmlAttr *':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           204:     'const xmlAttr *':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           205:     'xmlEntityPtr':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           206:     'const xmlEntityPtr':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           207:     'xmlEntity *':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           208:     'const xmlEntity *':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           209:     'xmlElementPtr':  ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
        !           210:     'const xmlElementPtr':  ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
        !           211:     'xmlElement *':  ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
        !           212:     'const xmlElement *':  ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
        !           213:     'xmlAttributePtr':  ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
        !           214:     'const xmlAttributePtr':  ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
        !           215:     'xmlAttribute *':  ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
        !           216:     'const xmlAttribute *':  ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
        !           217:     'xmlNsPtr':  ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
        !           218:     'const xmlNsPtr':  ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
        !           219:     'xmlNs *':  ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
        !           220:     'const xmlNs *':  ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
        !           221:     'xmlDocPtr':  ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
        !           222:     'const xmlDocPtr':  ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
        !           223:     'xmlDoc *':  ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
        !           224:     'const xmlDoc *':  ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
        !           225:     'htmlDocPtr':  ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
        !           226:     'const htmlDocPtr':  ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
        !           227:     'htmlDoc *':  ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
        !           228:     'const htmlDoc *':  ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
        !           229:     'htmlNodePtr':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           230:     'const htmlNodePtr':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           231:     'htmlNode *':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           232:     'const htmlNode *':  ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
        !           233:     'xmlXPathContextPtr':  ('O', "xmlXPathContext", "xmlXPathContextPtr", "xmlXPathContextPtr"),
        !           234:     'xmlXPathContext *':  ('O', "xpathContext", "xmlXPathContextPtr", "xmlXPathContextPtr"),
        !           235:     'xmlXPathParserContextPtr':  ('O', "xmlXPathParserContext", "xmlXPathParserContextPtr", "xmlXPathParserContextPtr"),
        !           236:     'xmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
        !           237:     'xmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
        !           238:     'htmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
        !           239:     'htmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
        !           240:     'xmlValidCtxtPtr': ('O', "ValidCtxt", "xmlValidCtxtPtr", "xmlValidCtxtPtr"),
        !           241:     'xmlCatalogPtr': ('O', "catalog", "xmlCatalogPtr", "xmlCatalogPtr"),
        !           242:     'FILE *': ('O', "File", "FILEPtr", "FILE *"),
        !           243:     'xmlURIPtr': ('O', "URI", "xmlURIPtr", "xmlURIPtr"),
        !           244:     'xmlErrorPtr': ('O', "Error", "xmlErrorPtr", "xmlErrorPtr"),
        !           245:     'xmlOutputBufferPtr': ('O', "outputBuffer", "xmlOutputBufferPtr", "xmlOutputBufferPtr"),
        !           246:     'xmlParserInputBufferPtr': ('O', "inputBuffer", "xmlParserInputBufferPtr", "xmlParserInputBufferPtr"),
        !           247:     'xmlRegexpPtr': ('O', "xmlReg", "xmlRegexpPtr", "xmlRegexpPtr"),
        !           248:     'xmlTextReaderLocatorPtr': ('O', "xmlTextReaderLocator", "xmlTextReaderLocatorPtr", "xmlTextReaderLocatorPtr"),
        !           249:     'xmlTextReaderPtr': ('O', "xmlTextReader", "xmlTextReaderPtr", "xmlTextReaderPtr"),
        !           250:     'xmlRelaxNGPtr': ('O', "relaxNgSchema", "xmlRelaxNGPtr", "xmlRelaxNGPtr"),
        !           251:     'xmlRelaxNGParserCtxtPtr': ('O', "relaxNgParserCtxt", "xmlRelaxNGParserCtxtPtr", "xmlRelaxNGParserCtxtPtr"),
        !           252:     'xmlRelaxNGValidCtxtPtr': ('O', "relaxNgValidCtxt", "xmlRelaxNGValidCtxtPtr", "xmlRelaxNGValidCtxtPtr"),
        !           253:     'xmlSchemaPtr': ('O', "Schema", "xmlSchemaPtr", "xmlSchemaPtr"),
        !           254:     'xmlSchemaParserCtxtPtr': ('O', "SchemaParserCtxt", "xmlSchemaParserCtxtPtr", "xmlSchemaParserCtxtPtr"),
        !           255:     'xmlSchemaValidCtxtPtr': ('O', "SchemaValidCtxt", "xmlSchemaValidCtxtPtr", "xmlSchemaValidCtxtPtr"),
        !           256: }
        !           257: 
        !           258: py_return_types = {
        !           259:     'xmlXPathObjectPtr':  ('O', "foo", "xmlXPathObjectPtr", "xmlXPathObjectPtr"),
        !           260: }
        !           261: 
        !           262: unknown_types = {}
        !           263: 
        !           264: foreign_encoding_args = (
        !           265:     'htmlCreateMemoryParserCtxt',
        !           266:     'htmlCtxtReadMemory',
        !           267:     'htmlParseChunk',
        !           268:     'htmlReadMemory',
        !           269:     'xmlCreateMemoryParserCtxt',
        !           270:     'xmlCtxtReadMemory',
        !           271:     'xmlCtxtResetPush',
        !           272:     'xmlParseChunk',
        !           273:     'xmlParseMemory',
        !           274:     'xmlReadMemory',
        !           275:     'xmlRecoverMemory',
        !           276: )
        !           277: 
        !           278: #######################################################################
        !           279: #
        !           280: #  This part writes the C <-> Python stubs libxml2-py.[ch] and
        !           281: #  the table libxml2-export.c to add when registrering the Python module
        !           282: #
        !           283: #######################################################################
        !           284: 
        !           285: # Class methods which are written by hand in libxml.c but the Python-level
        !           286: # code is still automatically generated (so they are not in skip_function()).
        !           287: skip_impl = (
        !           288:     'xmlSaveFileTo',
        !           289:     'xmlSaveFormatFileTo',
        !           290: )
        !           291: 
        !           292: def skip_function(name):
        !           293:     if name[0:12] == "xmlXPathWrap":
        !           294:         return 1
        !           295:     if name == "xmlFreeParserCtxt":
        !           296:         return 1
        !           297:     if name == "xmlCleanupParser":
        !           298:         return 1
        !           299:     if name == "xmlFreeTextReader":
        !           300:         return 1
        !           301: #    if name[0:11] == "xmlXPathNew":
        !           302: #        return 1
        !           303:     # the next function is defined in libxml.c
        !           304:     if name == "xmlRelaxNGFreeValidCtxt":
        !           305:         return 1
        !           306:     if name == "xmlFreeValidCtxt":
        !           307:         return 1
        !           308:     if name == "xmlSchemaFreeValidCtxt":
        !           309:         return 1
        !           310: 
        !           311: #
        !           312: # Those are skipped because the Const version is used of the bindings
        !           313: # instead.
        !           314: #
        !           315:     if name == "xmlTextReaderBaseUri":
        !           316:         return 1
        !           317:     if name == "xmlTextReaderLocalName":
        !           318:         return 1
        !           319:     if name == "xmlTextReaderName":
        !           320:         return 1
        !           321:     if name == "xmlTextReaderNamespaceUri":
        !           322:         return 1
        !           323:     if name == "xmlTextReaderPrefix":
        !           324:         return 1
        !           325:     if name == "xmlTextReaderXmlLang":
        !           326:         return 1
        !           327:     if name == "xmlTextReaderValue":
        !           328:         return 1
        !           329:     if name == "xmlOutputBufferClose": # handled by by the superclass
        !           330:         return 1
        !           331:     if name == "xmlOutputBufferFlush": # handled by by the superclass
        !           332:         return 1
        !           333:     if name == "xmlErrMemory":
        !           334:         return 1
        !           335: 
        !           336:     if name == "xmlValidBuildContentModel":
        !           337:         return 1
        !           338:     if name == "xmlValidateElementDecl":
        !           339:         return 1
        !           340:     if name == "xmlValidateAttributeDecl":
        !           341:         return 1
        !           342: 
        !           343:     return 0
        !           344: 
        !           345: def print_function_wrapper(name, output, export, include):
        !           346:     global py_types
        !           347:     global unknown_types
        !           348:     global functions
        !           349:     global skipped_modules
        !           350: 
        !           351:     try:
        !           352:         (desc, ret, args, file, cond) = functions[name]
        !           353:     except:
        !           354:         print "failed to get function %s infos"
        !           355:         return
        !           356: 
        !           357:     if skipped_modules.has_key(file):
        !           358:         return 0
        !           359:     if skip_function(name) == 1:
        !           360:         return 0
        !           361:     if name in skip_impl:
        !           362:         # Don't delete the function entry in the caller.
        !           363:         return 1
        !           364: 
        !           365:     c_call = ""
        !           366:     format=""
        !           367:     format_args=""
        !           368:     c_args=""
        !           369:     c_return=""
        !           370:     c_convert=""
        !           371:     num_bufs=0
        !           372:     for arg in args:
        !           373:         # This should be correct
        !           374:         if arg[1][0:6] == "const ":
        !           375:             arg[1] = arg[1][6:]
        !           376:         c_args = c_args + "    %s %s;\n" % (arg[1], arg[0])
        !           377:         if py_types.has_key(arg[1]):
        !           378:             (f, t, n, c) = py_types[arg[1]]
        !           379:             if (f == 'z') and (name in foreign_encoding_args) and (num_bufs == 0):
        !           380:                 f = 't#'
        !           381:             if f != None:
        !           382:                 format = format + f
        !           383:             if t != None:
        !           384:                 format_args = format_args + ", &pyobj_%s" % (arg[0])
        !           385:                 c_args = c_args + "    PyObject *pyobj_%s;\n" % (arg[0])
        !           386:                 c_convert = c_convert + \
        !           387:                    "    %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg[0],
        !           388:                    arg[1], t, arg[0])
        !           389:             else:
        !           390:                 format_args = format_args + ", &%s" % (arg[0])
        !           391:             if f == 't#':
        !           392:                 format_args = format_args + ", &py_buffsize%d" % num_bufs
        !           393:                 c_args = c_args + "    int py_buffsize%d;\n" % num_bufs
        !           394:                 num_bufs = num_bufs + 1
        !           395:             if c_call != "":
        !           396:                 c_call = c_call + ", "
        !           397:             c_call = c_call + "%s" % (arg[0])
        !           398:         else:
        !           399:             if skipped_types.has_key(arg[1]):
        !           400:                 return 0
        !           401:             if unknown_types.has_key(arg[1]):
        !           402:                 lst = unknown_types[arg[1]]
        !           403:                 lst.append(name)
        !           404:             else:
        !           405:                 unknown_types[arg[1]] = [name]
        !           406:             return -1
        !           407:     if format != "":
        !           408:         format = format + ":%s" % (name)
        !           409: 
        !           410:     if ret[0] == 'void':
        !           411:         if file == "python_accessor":
        !           412:             if args[1][1] == "char *" or args[1][1] == "xmlChar *":
        !           413:                 c_call = "\n    if (%s->%s != NULL) xmlFree(%s->%s);\n" % (
        !           414:                                  args[0][0], args[1][0], args[0][0], args[1][0])
        !           415:                 c_call = c_call + "    %s->%s = (%s)xmlStrdup((const xmlChar *)%s);\n" % (args[0][0],
        !           416:                                  args[1][0], args[1][1], args[1][0])
        !           417:             else:
        !           418:                 c_call = "\n    %s->%s = %s;\n" % (args[0][0], args[1][0],
        !           419:                                                    args[1][0])
        !           420:         else:
        !           421:             c_call = "\n    %s(%s);\n" % (name, c_call)
        !           422:         ret_convert = "    Py_INCREF(Py_None);\n    return(Py_None);\n"
        !           423:     elif py_types.has_key(ret[0]):
        !           424:         (f, t, n, c) = py_types[ret[0]]
        !           425:         c_return = "    %s c_retval;\n" % (ret[0])
        !           426:         if file == "python_accessor" and ret[2] != None:
        !           427:             c_call = "\n    c_retval = %s->%s;\n" % (args[0][0], ret[2])
        !           428:         else:
        !           429:             c_call = "\n    c_retval = %s(%s);\n" % (name, c_call)
        !           430:         ret_convert = "    py_retval = libxml_%sWrap((%s) c_retval);\n" % (n,c)
        !           431:         ret_convert = ret_convert + "    return(py_retval);\n"
        !           432:     elif py_return_types.has_key(ret[0]):
        !           433:         (f, t, n, c) = py_return_types[ret[0]]
        !           434:         c_return = "    %s c_retval;\n" % (ret[0])
        !           435:         c_call = "\n    c_retval = %s(%s);\n" % (name, c_call)
        !           436:         ret_convert = "    py_retval = libxml_%sWrap((%s) c_retval);\n" % (n,c)
        !           437:         ret_convert = ret_convert + "    return(py_retval);\n"
        !           438:     else:
        !           439:         if skipped_types.has_key(ret[0]):
        !           440:             return 0
        !           441:         if unknown_types.has_key(ret[0]):
        !           442:             lst = unknown_types[ret[0]]
        !           443:             lst.append(name)
        !           444:         else:
        !           445:             unknown_types[ret[0]] = [name]
        !           446:         return -1
        !           447: 
        !           448:     if cond != None and cond != "":
        !           449:         include.write("#if %s\n" % cond)
        !           450:         export.write("#if %s\n" % cond)
        !           451:         output.write("#if %s\n" % cond)
        !           452: 
        !           453:     include.write("PyObject * ")
        !           454:     include.write("libxml_%s(PyObject *self, PyObject *args);\n" % (name))
        !           455: 
        !           456:     export.write("    { (char *)\"%s\", libxml_%s, METH_VARARGS, NULL },\n" %
        !           457:                  (name, name))
        !           458: 
        !           459:     if file == "python":
        !           460:         # Those have been manually generated
        !           461:         if cond != None and cond != "":
        !           462:             include.write("#endif\n")
        !           463:             export.write("#endif\n")
        !           464:             output.write("#endif\n")
        !           465:         return 1
        !           466:     if file == "python_accessor" and ret[0] != "void" and ret[2] is None:
        !           467:         # Those have been manually generated
        !           468:         if cond != None and cond != "":
        !           469:             include.write("#endif\n")
        !           470:             export.write("#endif\n")
        !           471:             output.write("#endif\n")
        !           472:         return 1
        !           473: 
        !           474:     output.write("PyObject *\n")
        !           475:     output.write("libxml_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
        !           476:     output.write(" PyObject *args")
        !           477:     if format == "":
        !           478:         output.write(" ATTRIBUTE_UNUSED")
        !           479:     output.write(") {\n")
        !           480:     if ret[0] != 'void':
        !           481:         output.write("    PyObject *py_retval;\n")
        !           482:     if c_return != "":
        !           483:         output.write(c_return)
        !           484:     if c_args != "":
        !           485:         output.write(c_args)
        !           486:     if format != "":
        !           487:         output.write("\n    if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
        !           488:                      (format, format_args))
        !           489:         output.write("        return(NULL);\n")
        !           490:     if c_convert != "":
        !           491:         output.write(c_convert)
        !           492:                                                               
        !           493:     output.write(c_call)
        !           494:     output.write(ret_convert)
        !           495:     output.write("}\n\n")
        !           496:     if cond != None and cond != "":
        !           497:         include.write("#endif /* %s */\n" % cond)
        !           498:         export.write("#endif /* %s */\n" % cond)
        !           499:         output.write("#endif /* %s */\n" % cond)
        !           500:     return 1
        !           501: 
        !           502: def buildStubs():
        !           503:     global py_types
        !           504:     global py_return_types
        !           505:     global unknown_types
        !           506: 
        !           507:     try:
        !           508:         f = open(os.path.join(srcPref,"libxml2-api.xml"))
        !           509:         data = f.read()
        !           510:         (parser, target)  = getparser()
        !           511:         parser.feed(data)
        !           512:         parser.close()
        !           513:     except IOError, msg:
        !           514:         try:
        !           515:             f = open(os.path.join(srcPref,"..","doc","libxml2-api.xml"))
        !           516:             data = f.read()
        !           517:             (parser, target)  = getparser()
        !           518:             parser.feed(data)
        !           519:             parser.close()
        !           520:         except IOError, msg:
        !           521:             print file, ":", msg
        !           522:             sys.exit(1)
        !           523: 
        !           524:     n = len(functions.keys())
        !           525:     print "Found %d functions in libxml2-api.xml" % (n)
        !           526: 
        !           527:     py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
        !           528:     try:
        !           529:         f = open(os.path.join(srcPref,"libxml2-python-api.xml"))
        !           530:         data = f.read()
        !           531:         (parser, target)  = getparser()
        !           532:         parser.feed(data)
        !           533:         parser.close()
        !           534:     except IOError, msg:
        !           535:         print file, ":", msg
        !           536: 
        !           537: 
        !           538:     print "Found %d functions in libxml2-python-api.xml" % (
        !           539:           len(functions.keys()) - n)
        !           540:     nb_wrap = 0
        !           541:     failed = 0
        !           542:     skipped = 0
        !           543: 
        !           544:     include = open("libxml2-py.h", "w")
        !           545:     include.write("/* Generated */\n\n")
        !           546:     export = open("libxml2-export.c", "w")
        !           547:     export.write("/* Generated */\n\n")
        !           548:     wrapper = open("libxml2-py.c", "w")
        !           549:     wrapper.write("/* Generated */\n\n")
        !           550:     wrapper.write("#include <Python.h>\n")
        !           551:     wrapper.write("#include <libxml/xmlversion.h>\n")
        !           552:     wrapper.write("#include <libxml/tree.h>\n")
        !           553:     wrapper.write("#include <libxml/xmlschemastypes.h>\n")
        !           554:     wrapper.write("#include \"libxml_wrap.h\"\n")
        !           555:     wrapper.write("#include \"libxml2-py.h\"\n\n")
        !           556:     for function in sorted(functions.keys()):
        !           557:         ret = print_function_wrapper(function, wrapper, export, include)
        !           558:         if ret < 0:
        !           559:             failed = failed + 1
        !           560:             del functions[function]
        !           561:         if ret == 0:
        !           562:             skipped = skipped + 1
        !           563:             del functions[function]
        !           564:         if ret == 1:
        !           565:             nb_wrap = nb_wrap + 1
        !           566:     include.close()
        !           567:     export.close()
        !           568:     wrapper.close()
        !           569: 
        !           570:     print "Generated %d wrapper functions, %d failed, %d skipped\n" % (nb_wrap,
        !           571:                                                               failed, skipped)
        !           572:     print "Missing type converters: "
        !           573:     for type in unknown_types.keys():
        !           574:         print "%s:%d " % (type, len(unknown_types[type])),
        !           575:     print
        !           576: 
        !           577: #######################################################################
        !           578: #
        !           579: #  This part writes part of the Python front-end classes based on
        !           580: #  mapping rules between types and classes and also based on function
        !           581: #  renaming to get consistent function names at the Python level
        !           582: #
        !           583: #######################################################################
        !           584: 
        !           585: #
        !           586: # The type automatically remapped to generated classes
        !           587: #
        !           588: classes_type = {
        !           589:     "xmlNodePtr": ("._o", "xmlNode(_obj=%s)", "xmlNode"),
        !           590:     "xmlNode *": ("._o", "xmlNode(_obj=%s)", "xmlNode"),
        !           591:     "xmlDocPtr": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
        !           592:     "xmlDocPtr *": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
        !           593:     "htmlDocPtr": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
        !           594:     "htmlxmlDocPtr *": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
        !           595:     "xmlAttrPtr": ("._o", "xmlAttr(_obj=%s)", "xmlAttr"),
        !           596:     "xmlAttr *": ("._o", "xmlAttr(_obj=%s)", "xmlAttr"),
        !           597:     "xmlNsPtr": ("._o", "xmlNs(_obj=%s)", "xmlNs"),
        !           598:     "xmlNs *": ("._o", "xmlNs(_obj=%s)", "xmlNs"),
        !           599:     "xmlDtdPtr": ("._o", "xmlDtd(_obj=%s)", "xmlDtd"),
        !           600:     "xmlDtd *": ("._o", "xmlDtd(_obj=%s)", "xmlDtd"),
        !           601:     "xmlEntityPtr": ("._o", "xmlEntity(_obj=%s)", "xmlEntity"),
        !           602:     "xmlEntity *": ("._o", "xmlEntity(_obj=%s)", "xmlEntity"),
        !           603:     "xmlElementPtr": ("._o", "xmlElement(_obj=%s)", "xmlElement"),
        !           604:     "xmlElement *": ("._o", "xmlElement(_obj=%s)", "xmlElement"),
        !           605:     "xmlAttributePtr": ("._o", "xmlAttribute(_obj=%s)", "xmlAttribute"),
        !           606:     "xmlAttribute *": ("._o", "xmlAttribute(_obj=%s)", "xmlAttribute"),
        !           607:     "xmlXPathContextPtr": ("._o", "xpathContext(_obj=%s)", "xpathContext"),
        !           608:     "xmlXPathContext *": ("._o", "xpathContext(_obj=%s)", "xpathContext"),
        !           609:     "xmlXPathParserContext *": ("._o", "xpathParserContext(_obj=%s)", "xpathParserContext"),
        !           610:     "xmlXPathParserContextPtr": ("._o", "xpathParserContext(_obj=%s)", "xpathParserContext"),
        !           611:     "xmlParserCtxtPtr": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
        !           612:     "xmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
        !           613:     "htmlParserCtxtPtr": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
        !           614:     "htmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
        !           615:     "xmlValidCtxtPtr": ("._o", "ValidCtxt(_obj=%s)", "ValidCtxt"),
        !           616:     "xmlCatalogPtr": ("._o", "catalog(_obj=%s)", "catalog"),
        !           617:     "xmlURIPtr": ("._o", "URI(_obj=%s)", "URI"),
        !           618:     "xmlErrorPtr": ("._o", "Error(_obj=%s)", "Error"),
        !           619:     "xmlOutputBufferPtr": ("._o", "outputBuffer(_obj=%s)", "outputBuffer"),
        !           620:     "xmlParserInputBufferPtr": ("._o", "inputBuffer(_obj=%s)", "inputBuffer"),
        !           621:     "xmlRegexpPtr": ("._o", "xmlReg(_obj=%s)", "xmlReg"),
        !           622:     "xmlTextReaderLocatorPtr": ("._o", "xmlTextReaderLocator(_obj=%s)", "xmlTextReaderLocator"),
        !           623:     "xmlTextReaderPtr": ("._o", "xmlTextReader(_obj=%s)", "xmlTextReader"),
        !           624:     'xmlRelaxNGPtr': ('._o', "relaxNgSchema(_obj=%s)", "relaxNgSchema"),
        !           625:     'xmlRelaxNGParserCtxtPtr': ('._o', "relaxNgParserCtxt(_obj=%s)", "relaxNgParserCtxt"),
        !           626:     'xmlRelaxNGValidCtxtPtr': ('._o', "relaxNgValidCtxt(_obj=%s)", "relaxNgValidCtxt"),
        !           627:     'xmlSchemaPtr': ("._o", "Schema(_obj=%s)", "Schema"),
        !           628:     'xmlSchemaParserCtxtPtr': ("._o", "SchemaParserCtxt(_obj=%s)", "SchemaParserCtxt"),
        !           629:     'xmlSchemaValidCtxtPtr': ("._o", "SchemaValidCtxt(_obj=%s)", "SchemaValidCtxt"),
        !           630: }
        !           631: 
        !           632: converter_type = {
        !           633:     "xmlXPathObjectPtr": "xpathObjectRet(%s)",
        !           634: }
        !           635: 
        !           636: primary_classes = ["xmlNode", "xmlDoc"]
        !           637: 
        !           638: classes_ancestor = {
        !           639:     "xmlNode" : "xmlCore",
        !           640:     "xmlDtd" : "xmlNode",
        !           641:     "xmlDoc" : "xmlNode",
        !           642:     "xmlAttr" : "xmlNode",
        !           643:     "xmlNs" : "xmlNode",
        !           644:     "xmlEntity" : "xmlNode",
        !           645:     "xmlElement" : "xmlNode",
        !           646:     "xmlAttribute" : "xmlNode",
        !           647:     "outputBuffer": "ioWriteWrapper",
        !           648:     "inputBuffer": "ioReadWrapper",
        !           649:     "parserCtxt": "parserCtxtCore",
        !           650:     "xmlTextReader": "xmlTextReaderCore",
        !           651:     "ValidCtxt": "ValidCtxtCore",
        !           652:     "SchemaValidCtxt": "SchemaValidCtxtCore",
        !           653:     "relaxNgValidCtxt": "relaxNgValidCtxtCore",
        !           654: }
        !           655: classes_destructors = {
        !           656:     "parserCtxt": "xmlFreeParserCtxt",
        !           657:     "catalog": "xmlFreeCatalog",
        !           658:     "URI": "xmlFreeURI",
        !           659: #    "outputBuffer": "xmlOutputBufferClose",
        !           660:     "inputBuffer": "xmlFreeParserInputBuffer",
        !           661:     "xmlReg": "xmlRegFreeRegexp",
        !           662:     "xmlTextReader": "xmlFreeTextReader",
        !           663:     "relaxNgSchema": "xmlRelaxNGFree",
        !           664:     "relaxNgParserCtxt": "xmlRelaxNGFreeParserCtxt",
        !           665:     "relaxNgValidCtxt": "xmlRelaxNGFreeValidCtxt",
        !           666:         "Schema": "xmlSchemaFree",
        !           667:         "SchemaParserCtxt": "xmlSchemaFreeParserCtxt",
        !           668:         "SchemaValidCtxt": "xmlSchemaFreeValidCtxt",
        !           669:         "ValidCtxt": "xmlFreeValidCtxt",
        !           670: }
        !           671: 
        !           672: functions_noexcept = {
        !           673:     "xmlHasProp": 1,
        !           674:     "xmlHasNsProp": 1,
        !           675:     "xmlDocSetRootElement": 1,
        !           676:     "xmlNodeGetNs": 1,
        !           677:     "xmlNodeGetNsDefs": 1,
        !           678:     "xmlNextElementSibling": 1,
        !           679:     "xmlPreviousElementSibling": 1,
        !           680:     "xmlFirstElementChild": 1,
        !           681:     "xmlLastElementChild": 1,
        !           682: }
        !           683: 
        !           684: reference_keepers = {
        !           685:     "xmlTextReader": [('inputBuffer', 'input')],
        !           686:     "relaxNgValidCtxt": [('relaxNgSchema', 'schema')],
        !           687:         "SchemaValidCtxt": [('Schema', 'schema')],
        !           688: }
        !           689: 
        !           690: function_classes = {}
        !           691: 
        !           692: function_classes["None"] = []
        !           693: 
        !           694: def nameFixup(name, classe, type, file):
        !           695:     listname = classe + "List"
        !           696:     ll = len(listname)
        !           697:     l = len(classe)
        !           698:     if name[0:l] == listname:
        !           699:         func = name[l:]
        !           700:         func = string.lower(func[0:1]) + func[1:]
        !           701:     elif name[0:12] == "xmlParserGet" and file == "python_accessor":
        !           702:         func = name[12:]
        !           703:         func = string.lower(func[0:1]) + func[1:]
        !           704:     elif name[0:12] == "xmlParserSet" and file == "python_accessor":
        !           705:         func = name[12:]
        !           706:         func = string.lower(func[0:1]) + func[1:]
        !           707:     elif name[0:10] == "xmlNodeGet" and file == "python_accessor":
        !           708:         func = name[10:]
        !           709:         func = string.lower(func[0:1]) + func[1:]
        !           710:     elif name[0:9] == "xmlURIGet" and file == "python_accessor":
        !           711:         func = name[9:]
        !           712:         func = string.lower(func[0:1]) + func[1:]
        !           713:     elif name[0:9] == "xmlURISet" and file == "python_accessor":
        !           714:         func = name[6:]
        !           715:         func = string.lower(func[0:1]) + func[1:]
        !           716:     elif name[0:11] == "xmlErrorGet" and file == "python_accessor":
        !           717:         func = name[11:]
        !           718:         func = string.lower(func[0:1]) + func[1:]
        !           719:     elif name[0:17] == "xmlXPathParserGet" and file == "python_accessor":
        !           720:         func = name[17:]
        !           721:         func = string.lower(func[0:1]) + func[1:]
        !           722:     elif name[0:11] == "xmlXPathGet" and file == "python_accessor":
        !           723:         func = name[11:]
        !           724:         func = string.lower(func[0:1]) + func[1:]
        !           725:     elif name[0:11] == "xmlXPathSet" and file == "python_accessor":
        !           726:         func = name[8:]
        !           727:         func = string.lower(func[0:1]) + func[1:]
        !           728:     elif name[0:15] == "xmlOutputBuffer" and file != "python":
        !           729:         func = name[15:]
        !           730:         func = string.lower(func[0:1]) + func[1:]
        !           731:     elif name[0:20] == "xmlParserInputBuffer" and file != "python":
        !           732:         func = name[20:]
        !           733:         func = string.lower(func[0:1]) + func[1:]
        !           734:     elif name[0:9] == "xmlRegexp" and file == "xmlregexp":
        !           735:         func = "regexp" + name[9:]
        !           736:     elif name[0:6] == "xmlReg" and file == "xmlregexp":
        !           737:         func = "regexp" + name[6:]
        !           738:     elif name[0:20] == "xmlTextReaderLocator" and file == "xmlreader":
        !           739:         func = name[20:]
        !           740:     elif name[0:18] == "xmlTextReaderConst" and file == "xmlreader":
        !           741:         func = name[18:]
        !           742:     elif name[0:13] == "xmlTextReader" and file == "xmlreader":
        !           743:         func = name[13:]
        !           744:     elif name[0:12] == "xmlReaderNew" and file == "xmlreader":
        !           745:         func = name[9:]
        !           746:     elif name[0:11] == "xmlACatalog":
        !           747:         func = name[11:]
        !           748:         func = string.lower(func[0:1]) + func[1:]
        !           749:     elif name[0:l] == classe:
        !           750:         func = name[l:]
        !           751:         func = string.lower(func[0:1]) + func[1:]
        !           752:     elif name[0:7] == "libxml_":
        !           753:         func = name[7:]
        !           754:         func = string.lower(func[0:1]) + func[1:]
        !           755:     elif name[0:6] == "xmlGet":
        !           756:         func = name[6:]
        !           757:         func = string.lower(func[0:1]) + func[1:]
        !           758:     elif name[0:3] == "xml":
        !           759:         func = name[3:]
        !           760:         func = string.lower(func[0:1]) + func[1:]
        !           761:     else:
        !           762:         func = name
        !           763:     if func[0:5] == "xPath":
        !           764:         func = "xpath" + func[5:]
        !           765:     elif func[0:4] == "xPtr":
        !           766:         func = "xpointer" + func[4:]
        !           767:     elif func[0:8] == "xInclude":
        !           768:         func = "xinclude" + func[8:]
        !           769:     elif func[0:2] == "iD":
        !           770:         func = "ID" + func[2:]
        !           771:     elif func[0:3] == "uRI":
        !           772:         func = "URI" + func[3:]
        !           773:     elif func[0:4] == "uTF8":
        !           774:         func = "UTF8" + func[4:]
        !           775:     elif func[0:3] == 'sAX':
        !           776:         func = "SAX" + func[3:]
        !           777:     return func
        !           778: 
        !           779: 
        !           780: def functionCompare(info1, info2):
        !           781:     (index1, func1, name1, ret1, args1, file1) = info1
        !           782:     (index2, func2, name2, ret2, args2, file2) = info2
        !           783:     if file1 == file2:
        !           784:         if func1 < func2:
        !           785:             return -1
        !           786:         if func1 > func2:
        !           787:             return 1
        !           788:     if file1 == "python_accessor":
        !           789:         return -1
        !           790:     if file2 == "python_accessor":
        !           791:         return 1
        !           792:     if file1 < file2:
        !           793:         return -1
        !           794:     if file1 > file2:
        !           795:         return 1
        !           796:     return 0
        !           797: 
        !           798: def writeDoc(name, args, indent, output):
        !           799:      if functions[name][0] is None or functions[name][0] == "":
        !           800:          return
        !           801:      val = functions[name][0]
        !           802:      val = string.replace(val, "NULL", "None")
        !           803:      output.write(indent)
        !           804:      output.write('"""')
        !           805:      while len(val) > 60:
        !           806:          if val[0] == " ":
        !           807:              val = val[1:]
        !           808:              continue
        !           809:          str = val[0:60]
        !           810:          i = string.rfind(str, " ")
        !           811:          if i < 0:
        !           812:              i = 60
        !           813:          str = val[0:i]
        !           814:          val = val[i:]
        !           815:          output.write(str)
        !           816:          output.write('\n  ')
        !           817:          output.write(indent)
        !           818:      output.write(val)
        !           819:      output.write(' """\n')
        !           820: 
        !           821: def buildWrappers():
        !           822:     global ctypes
        !           823:     global py_types
        !           824:     global py_return_types
        !           825:     global unknown_types
        !           826:     global functions
        !           827:     global function_classes
        !           828:     global classes_type
        !           829:     global classes_list
        !           830:     global converter_type
        !           831:     global primary_classes
        !           832:     global converter_type
        !           833:     global classes_ancestor
        !           834:     global converter_type
        !           835:     global primary_classes
        !           836:     global classes_ancestor
        !           837:     global classes_destructors
        !           838:     global functions_noexcept
        !           839: 
        !           840:     for type in classes_type.keys():
        !           841:         function_classes[classes_type[type][2]] = []
        !           842: 
        !           843:     #
        !           844:     # Build the list of C types to look for ordered to start
        !           845:     # with primary classes
        !           846:     #
        !           847:     ctypes = []
        !           848:     classes_list = []
        !           849:     ctypes_processed = {}
        !           850:     classes_processed = {}
        !           851:     for classe in primary_classes:
        !           852:         classes_list.append(classe)
        !           853:         classes_processed[classe] = ()
        !           854:         for type in classes_type.keys():
        !           855:             tinfo = classes_type[type]
        !           856:             if tinfo[2] == classe:
        !           857:                 ctypes.append(type)
        !           858:                 ctypes_processed[type] = ()
        !           859:     for type in sorted(classes_type.keys()):
        !           860:         if ctypes_processed.has_key(type):
        !           861:             continue
        !           862:         tinfo = classes_type[type]
        !           863:         if not classes_processed.has_key(tinfo[2]):
        !           864:             classes_list.append(tinfo[2])
        !           865:             classes_processed[tinfo[2]] = ()
        !           866:             
        !           867:         ctypes.append(type)
        !           868:         ctypes_processed[type] = ()
        !           869: 
        !           870:     for name in functions.keys():
        !           871:         found = 0
        !           872:         (desc, ret, args, file, cond) = functions[name]
        !           873:         for type in ctypes:
        !           874:             classe = classes_type[type][2]
        !           875: 
        !           876:             if name[0:3] == "xml" and len(args) >= 1 and args[0][1] == type:
        !           877:                 found = 1
        !           878:                 func = nameFixup(name, classe, type, file)
        !           879:                 info = (0, func, name, ret, args, file)
        !           880:                 function_classes[classe].append(info)
        !           881:             elif name[0:3] == "xml" and len(args) >= 2 and args[1][1] == type \
        !           882:                 and file != "python_accessor":
        !           883:                 found = 1
        !           884:                 func = nameFixup(name, classe, type, file)
        !           885:                 info = (1, func, name, ret, args, file)
        !           886:                 function_classes[classe].append(info)
        !           887:             elif name[0:4] == "html" and len(args) >= 1 and args[0][1] == type:
        !           888:                 found = 1
        !           889:                 func = nameFixup(name, classe, type, file)
        !           890:                 info = (0, func, name, ret, args, file)
        !           891:                 function_classes[classe].append(info)
        !           892:             elif name[0:4] == "html" and len(args) >= 2 and args[1][1] == type \
        !           893:                 and file != "python_accessor":
        !           894:                 found = 1
        !           895:                 func = nameFixup(name, classe, type, file)
        !           896:                 info = (1, func, name, ret, args, file)
        !           897:                 function_classes[classe].append(info)
        !           898:         if found == 1:
        !           899:             continue
        !           900:         if name[0:8] == "xmlXPath":
        !           901:             continue
        !           902:         if name[0:6] == "xmlStr":
        !           903:             continue
        !           904:         if name[0:10] == "xmlCharStr":
        !           905:             continue
        !           906:         func = nameFixup(name, "None", file, file)
        !           907:         info = (0, func, name, ret, args, file)
        !           908:         function_classes['None'].append(info)
        !           909:    
        !           910:     classes = open("libxml2class.py", "w")
        !           911:     txt = open("libxml2class.txt", "w")
        !           912:     txt.write("          Generated Classes for libxml2-python\n\n")
        !           913: 
        !           914:     txt.write("#\n# Global functions of the module\n#\n\n")
        !           915:     if function_classes.has_key("None"):
        !           916:         flist = function_classes["None"]
        !           917:         flist.sort(functionCompare)
        !           918:         oldfile = ""
        !           919:         for info in flist:
        !           920:             (index, func, name, ret, args, file) = info
        !           921:             if file != oldfile:
        !           922:                 classes.write("#\n# Functions from module %s\n#\n\n" % file)
        !           923:                 txt.write("\n# functions from module %s\n" % file)
        !           924:                 oldfile = file
        !           925:             classes.write("def %s(" % func)
        !           926:             txt.write("%s()\n" % func)
        !           927:             n = 0
        !           928:             for arg in args:
        !           929:                 if n != 0:
        !           930:                     classes.write(", ")
        !           931:                 classes.write("%s" % arg[0])
        !           932:                 n = n + 1
        !           933:             classes.write("):\n")
        !           934:             writeDoc(name, args, '    ', classes)
        !           935: 
        !           936:             for arg in args:
        !           937:                 if classes_type.has_key(arg[1]):
        !           938:                     classes.write("    if %s is None: %s__o = None\n" %
        !           939:                                   (arg[0], arg[0]))
        !           940:                     classes.write("    else: %s__o = %s%s\n" %
        !           941:                                   (arg[0], arg[0], classes_type[arg[1]][0]))
        !           942:             if ret[0] != "void":
        !           943:                 classes.write("    ret = ")
        !           944:             else:
        !           945:                 classes.write("    ")
        !           946:             classes.write("libxml2mod.%s(" % name)
        !           947:             n = 0
        !           948:             for arg in args:
        !           949:                 if n != 0:
        !           950:                     classes.write(", ")
        !           951:                 classes.write("%s" % arg[0])
        !           952:                 if classes_type.has_key(arg[1]):
        !           953:                     classes.write("__o")
        !           954:                 n = n + 1
        !           955:             classes.write(")\n")
        !           956:             if ret[0] != "void":
        !           957:                 if classes_type.has_key(ret[0]):
        !           958:                     #
        !           959:                     # Raise an exception
        !           960:                     #
        !           961:                     if functions_noexcept.has_key(name):
        !           962:                         classes.write("    if ret is None:return None\n")
        !           963:                     elif string.find(name, "URI") >= 0:
        !           964:                         classes.write(
        !           965:                         "    if ret is None:raise uriError('%s() failed')\n"
        !           966:                                       % (name))
        !           967:                     elif string.find(name, "XPath") >= 0:
        !           968:                         classes.write(
        !           969:                         "    if ret is None:raise xpathError('%s() failed')\n"
        !           970:                                       % (name))
        !           971:                     elif string.find(name, "Parse") >= 0:
        !           972:                         classes.write(
        !           973:                         "    if ret is None:raise parserError('%s() failed')\n"
        !           974:                                       % (name))
        !           975:                     else:
        !           976:                         classes.write(
        !           977:                         "    if ret is None:raise treeError('%s() failed')\n"
        !           978:                                       % (name))
        !           979:                     classes.write("    return ")
        !           980:                     classes.write(classes_type[ret[0]][1] % ("ret"))
        !           981:                     classes.write("\n")
        !           982:                 else:
        !           983:                     classes.write("    return ret\n")
        !           984:             classes.write("\n")
        !           985: 
        !           986:     txt.write("\n\n#\n# Set of classes of the module\n#\n\n")
        !           987:     for classname in classes_list:
        !           988:         if classname == "None":
        !           989:             pass
        !           990:         else:
        !           991:             if classes_ancestor.has_key(classname):
        !           992:                 txt.write("\n\nClass %s(%s)\n" % (classname,
        !           993:                           classes_ancestor[classname]))
        !           994:                 classes.write("class %s(%s):\n" % (classname,
        !           995:                               classes_ancestor[classname]))
        !           996:                 classes.write("    def __init__(self, _obj=None):\n")
        !           997:                 if classes_ancestor[classname] == "xmlCore" or \
        !           998:                    classes_ancestor[classname] == "xmlNode":
        !           999:                     classes.write("        if type(_obj).__name__ != ")
        !          1000:                     classes.write("'PyCObject':\n")
        !          1001:                     classes.write("            raise TypeError, ")
        !          1002:                     classes.write("'%s needs a PyCObject argument'\n" % \
        !          1003:                                 classname)
        !          1004:                 if reference_keepers.has_key(classname):
        !          1005:                     rlist = reference_keepers[classname]
        !          1006:                     for ref in rlist:
        !          1007:                         classes.write("        self.%s = None\n" % ref[1])
        !          1008:                 classes.write("        self._o = _obj\n")
        !          1009:                 classes.write("        %s.__init__(self, _obj=_obj)\n\n" % (
        !          1010:                               classes_ancestor[classname]))
        !          1011:                 if classes_ancestor[classname] == "xmlCore" or \
        !          1012:                    classes_ancestor[classname] == "xmlNode":
        !          1013:                     classes.write("    def __repr__(self):\n")
        !          1014:                     format = "<%s (%%s) object at 0x%%x>" % (classname)
        !          1015:                     classes.write("        return \"%s\" %% (self.name, long(pos_id (self)))\n\n" % (
        !          1016:                                   format))
        !          1017:             else:
        !          1018:                 txt.write("Class %s()\n" % (classname))
        !          1019:                 classes.write("class %s:\n" % (classname))
        !          1020:                 classes.write("    def __init__(self, _obj=None):\n")
        !          1021:                 if reference_keepers.has_key(classname):
        !          1022:                     list = reference_keepers[classname]
        !          1023:                     for ref in list:
        !          1024:                         classes.write("        self.%s = None\n" % ref[1])
        !          1025:                 classes.write("        if _obj != None:self._o = _obj;return\n")
        !          1026:                 classes.write("        self._o = None\n\n")
        !          1027:             destruct=None
        !          1028:             if classes_destructors.has_key(classname):
        !          1029:                 classes.write("    def __del__(self):\n")
        !          1030:                 classes.write("        if self._o != None:\n")
        !          1031:                 classes.write("            libxml2mod.%s(self._o)\n" %
        !          1032:                               classes_destructors[classname])
        !          1033:                 classes.write("        self._o = None\n\n")
        !          1034:                 destruct=classes_destructors[classname]
        !          1035:             flist = function_classes[classname]
        !          1036:             flist.sort(functionCompare)
        !          1037:             oldfile = ""
        !          1038:             for info in flist:
        !          1039:                 (index, func, name, ret, args, file) = info
        !          1040:                 #
        !          1041:                 # Do not provide as method the destructors for the class
        !          1042:                 # to avoid double free
        !          1043:                 #
        !          1044:                 if name == destruct:
        !          1045:                     continue
        !          1046:                 if file != oldfile:
        !          1047:                     if file == "python_accessor":
        !          1048:                         classes.write("    # accessors for %s\n" % (classname))
        !          1049:                         txt.write("    # accessors\n")
        !          1050:                     else:
        !          1051:                         classes.write("    #\n")
        !          1052:                         classes.write("    # %s functions from module %s\n" % (
        !          1053:                                       classname, file))
        !          1054:                         txt.write("\n    # functions from module %s\n" % file)
        !          1055:                         classes.write("    #\n\n")
        !          1056:                 oldfile = file
        !          1057:                 classes.write("    def %s(self" % func)
        !          1058:                 txt.write("    %s()\n" % func)
        !          1059:                 n = 0
        !          1060:                 for arg in args:
        !          1061:                     if n != index:
        !          1062:                         classes.write(", %s" % arg[0])
        !          1063:                     n = n + 1
        !          1064:                 classes.write("):\n")
        !          1065:                 writeDoc(name, args, '        ', classes)
        !          1066:                 n = 0
        !          1067:                 for arg in args:
        !          1068:                     if classes_type.has_key(arg[1]):
        !          1069:                         if n != index:
        !          1070:                             classes.write("        if %s is None: %s__o = None\n" %
        !          1071:                                           (arg[0], arg[0]))
        !          1072:                             classes.write("        else: %s__o = %s%s\n" %
        !          1073:                                           (arg[0], arg[0], classes_type[arg[1]][0]))
        !          1074:                     n = n + 1
        !          1075:                 if ret[0] != "void":
        !          1076:                     classes.write("        ret = ")
        !          1077:                 else:
        !          1078:                     classes.write("        ")
        !          1079:                 classes.write("libxml2mod.%s(" % name)
        !          1080:                 n = 0
        !          1081:                 for arg in args:
        !          1082:                     if n != 0:
        !          1083:                         classes.write(", ")
        !          1084:                     if n != index:
        !          1085:                         classes.write("%s" % arg[0])
        !          1086:                         if classes_type.has_key(arg[1]):
        !          1087:                             classes.write("__o")
        !          1088:                     else:
        !          1089:                         classes.write("self")
        !          1090:                         if classes_type.has_key(arg[1]):
        !          1091:                             classes.write(classes_type[arg[1]][0])
        !          1092:                     n = n + 1
        !          1093:                 classes.write(")\n")
        !          1094:                 if ret[0] != "void":
        !          1095:                     if classes_type.has_key(ret[0]):
        !          1096:                         #
        !          1097:                         # Raise an exception
        !          1098:                         #
        !          1099:                         if functions_noexcept.has_key(name):
        !          1100:                             classes.write(
        !          1101:                                 "        if ret is None:return None\n")
        !          1102:                         elif string.find(name, "URI") >= 0:
        !          1103:                             classes.write(
        !          1104:                     "        if ret is None:raise uriError('%s() failed')\n"
        !          1105:                                           % (name))
        !          1106:                         elif string.find(name, "XPath") >= 0:
        !          1107:                             classes.write(
        !          1108:                     "        if ret is None:raise xpathError('%s() failed')\n"
        !          1109:                                           % (name))
        !          1110:                         elif string.find(name, "Parse") >= 0:
        !          1111:                             classes.write(
        !          1112:                     "        if ret is None:raise parserError('%s() failed')\n"
        !          1113:                                           % (name))
        !          1114:                         else:
        !          1115:                             classes.write(
        !          1116:                     "        if ret is None:raise treeError('%s() failed')\n"
        !          1117:                                           % (name))
        !          1118: 
        !          1119:                         #
        !          1120:                         # generate the returned class wrapper for the object
        !          1121:                         #
        !          1122:                         classes.write("        __tmp = ")
        !          1123:                         classes.write(classes_type[ret[0]][1] % ("ret"))
        !          1124:                         classes.write("\n")
        !          1125: 
        !          1126:                         #
        !          1127:                         # Sometime one need to keep references of the source
        !          1128:                         # class in the returned class object.
        !          1129:                         # See reference_keepers for the list
        !          1130:                         #
        !          1131:                         tclass = classes_type[ret[0]][2]
        !          1132:                         if reference_keepers.has_key(tclass):
        !          1133:                             list = reference_keepers[tclass]
        !          1134:                             for pref in list:
        !          1135:                                 if pref[0] == classname:
        !          1136:                                     classes.write("        __tmp.%s = self\n" %
        !          1137:                                                   pref[1])
        !          1138:                         #
        !          1139:                         # return the class
        !          1140:                         #
        !          1141:                         classes.write("        return __tmp\n")
        !          1142:                     elif converter_type.has_key(ret[0]):
        !          1143:                         #
        !          1144:                         # Raise an exception
        !          1145:                         #
        !          1146:                         if functions_noexcept.has_key(name):
        !          1147:                             classes.write(
        !          1148:                                 "        if ret is None:return None")
        !          1149:                         elif string.find(name, "URI") >= 0:
        !          1150:                             classes.write(
        !          1151:                     "        if ret is None:raise uriError('%s() failed')\n"
        !          1152:                                           % (name))
        !          1153:                         elif string.find(name, "XPath") >= 0:
        !          1154:                             classes.write(
        !          1155:                     "        if ret is None:raise xpathError('%s() failed')\n"
        !          1156:                                           % (name))
        !          1157:                         elif string.find(name, "Parse") >= 0:
        !          1158:                             classes.write(
        !          1159:                     "        if ret is None:raise parserError('%s() failed')\n"
        !          1160:                                           % (name))
        !          1161:                         else:
        !          1162:                             classes.write(
        !          1163:                     "        if ret is None:raise treeError('%s() failed')\n"
        !          1164:                                           % (name))
        !          1165:                         classes.write("        return ")
        !          1166:                         classes.write(converter_type[ret[0]] % ("ret"))
        !          1167:                         classes.write("\n")
        !          1168:                     else:
        !          1169:                         classes.write("        return ret\n")
        !          1170:                 classes.write("\n")
        !          1171: 
        !          1172:     #
        !          1173:     # Generate enum constants
        !          1174:     #
        !          1175:     for type,enum in enums.items():
        !          1176:         classes.write("# %s\n" % type)
        !          1177:         items = enum.items()
        !          1178:         items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1])))
        !          1179:         for name,value in items:
        !          1180:             classes.write("%s = %s\n" % (name,value))
        !          1181:         classes.write("\n")
        !          1182: 
        !          1183:     txt.close()
        !          1184:     classes.close()
        !          1185: 
        !          1186: buildStubs()
        !          1187: buildWrappers()

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>