blob: cd72ce9c3f57f25c8aa203c6406f0f50ed3ed1b6 [file] [log] [blame]
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001#!/usr/bin/python -u
2#
3# generate python wrappers from the XML API description
4#
5
6functions = {}
Daniel Veillard4f4a27f2004-01-14 23:50:34 +00007enums = {} # { enumType: { enumConstant: enumValue } }
Daniel Veillardd2897fd2002-01-30 16:37:32 +00008
Daniel Veillard0fea6f42002-02-22 22:51:13 +00009import sys
Daniel Veillard36ed5292002-01-30 23:49:06 +000010import string
Daniel Veillard1971ee22002-01-31 20:29:19 +000011
William M. Brack106cad62004-12-23 15:56:12 +000012if len(sys.argv) > 1:
13 srcPref = sys.argv[1] + '/'
14else:
15 srcPref = ''
16
Daniel Veillard1971ee22002-01-31 20:29:19 +000017#######################################################################
18#
19# That part if purely the API acquisition phase from the
20# XML API description
21#
22#######################################################################
23import os
Daniel Veillardd2897fd2002-01-30 16:37:32 +000024import xmllib
25try:
26 import sgmlop
27except ImportError:
28 sgmlop = None # accelerator not available
29
30debug = 0
31
32if sgmlop:
33 class FastParser:
Daniel Veillard01a6d412002-02-11 18:42:20 +000034 """sgmlop based XML parser. this is typically 15x faster
35 than SlowParser..."""
Daniel Veillardd2897fd2002-01-30 16:37:32 +000036
Daniel Veillard01a6d412002-02-11 18:42:20 +000037 def __init__(self, target):
Daniel Veillardd2897fd2002-01-30 16:37:32 +000038
Daniel Veillard01a6d412002-02-11 18:42:20 +000039 # setup callbacks
40 self.finish_starttag = target.start
41 self.finish_endtag = target.end
42 self.handle_data = target.data
Daniel Veillardd2897fd2002-01-30 16:37:32 +000043
Daniel Veillard01a6d412002-02-11 18:42:20 +000044 # activate parser
45 self.parser = sgmlop.XMLParser()
46 self.parser.register(self)
47 self.feed = self.parser.feed
48 self.entity = {
49 "amp": "&", "gt": ">", "lt": "<",
50 "apos": "'", "quot": '"'
51 }
Daniel Veillardd2897fd2002-01-30 16:37:32 +000052
Daniel Veillard01a6d412002-02-11 18:42:20 +000053 def close(self):
54 try:
55 self.parser.close()
56 finally:
57 self.parser = self.feed = None # nuke circular reference
Daniel Veillardd2897fd2002-01-30 16:37:32 +000058
Daniel Veillard01a6d412002-02-11 18:42:20 +000059 def handle_entityref(self, entity):
60 # <string> entity
61 try:
62 self.handle_data(self.entity[entity])
63 except KeyError:
64 self.handle_data("&%s;" % entity)
Daniel Veillardd2897fd2002-01-30 16:37:32 +000065
66else:
67 FastParser = None
68
69
70class SlowParser(xmllib.XMLParser):
71 """slow but safe standard parser, based on the XML parser in
72 Python's standard library."""
73
74 def __init__(self, target):
Daniel Veillard01a6d412002-02-11 18:42:20 +000075 self.unknown_starttag = target.start
76 self.handle_data = target.data
77 self.unknown_endtag = target.end
78 xmllib.XMLParser.__init__(self)
Daniel Veillardd2897fd2002-01-30 16:37:32 +000079
80def getparser(target = None):
81 # get the fastest available parser, and attach it to an
82 # unmarshalling object. return both objects.
Daniel Veillard6f46f6c2002-08-01 12:22:24 +000083 if target is None:
Daniel Veillard01a6d412002-02-11 18:42:20 +000084 target = docParser()
Daniel Veillardd2897fd2002-01-30 16:37:32 +000085 if FastParser:
Daniel Veillard01a6d412002-02-11 18:42:20 +000086 return FastParser(target), target
Daniel Veillardd2897fd2002-01-30 16:37:32 +000087 return SlowParser(target), target
88
89class docParser:
90 def __init__(self):
91 self._methodname = None
Daniel Veillard01a6d412002-02-11 18:42:20 +000092 self._data = []
93 self.in_function = 0
Daniel Veillardd2897fd2002-01-30 16:37:32 +000094
95 def close(self):
96 if debug:
Daniel Veillard01a6d412002-02-11 18:42:20 +000097 print "close"
Daniel Veillardd2897fd2002-01-30 16:37:32 +000098
99 def getmethodname(self):
100 return self._methodname
101
102 def data(self, text):
103 if debug:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000104 print "data %s" % text
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000105 self._data.append(text)
106
107 def start(self, tag, attrs):
108 if debug:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000109 print "start %s, %s" % (tag, attrs)
110 if tag == 'function':
111 self._data = []
112 self.in_function = 1
113 self.function = None
114 self.function_args = []
115 self.function_descr = None
116 self.function_return = None
117 self.function_file = None
118 if attrs.has_key('name'):
119 self.function = attrs['name']
120 if attrs.has_key('file'):
121 self.function_file = attrs['file']
122 elif tag == 'info':
123 self._data = []
124 elif tag == 'arg':
125 if self.in_function == 1:
126 self.function_arg_name = None
127 self.function_arg_type = None
128 self.function_arg_info = None
129 if attrs.has_key('name'):
130 self.function_arg_name = attrs['name']
131 if attrs.has_key('type'):
132 self.function_arg_type = attrs['type']
133 if attrs.has_key('info'):
134 self.function_arg_info = attrs['info']
135 elif tag == 'return':
136 if self.in_function == 1:
137 self.function_return_type = None
138 self.function_return_info = None
139 self.function_return_field = None
140 if attrs.has_key('type'):
141 self.function_return_type = attrs['type']
142 if attrs.has_key('info'):
143 self.function_return_info = attrs['info']
144 if attrs.has_key('field'):
145 self.function_return_field = attrs['field']
Daniel Veillard4f4a27f2004-01-14 23:50:34 +0000146 elif tag == 'enum':
147 enum(attrs['type'],attrs['name'],attrs['value'])
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000148
149 def end(self, tag):
150 if debug:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000151 print "end %s" % tag
152 if tag == 'function':
153 if self.function != None:
154 function(self.function, self.function_descr,
155 self.function_return, self.function_args,
156 self.function_file)
157 self.in_function = 0
158 elif tag == 'arg':
159 if self.in_function == 1:
160 self.function_args.append([self.function_arg_name,
161 self.function_arg_type,
162 self.function_arg_info])
163 elif tag == 'return':
164 if self.in_function == 1:
165 self.function_return = [self.function_return_type,
166 self.function_return_info,
167 self.function_return_field]
168 elif tag == 'info':
169 str = ''
170 for c in self._data:
171 str = str + c
172 if self.in_function == 1:
173 self.function_descr = str
174
175
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000176def function(name, desc, ret, args, file):
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000177 functions[name] = (desc, ret, args, file)
178
Daniel Veillard4f4a27f2004-01-14 23:50:34 +0000179def enum(type, name, value):
180 if not enums.has_key(type):
181 enums[type] = {}
182 enums[type][name] = value
183
Daniel Veillard1971ee22002-01-31 20:29:19 +0000184#######################################################################
185#
186# Some filtering rukes to drop functions/types which should not
187# be exposed as-is on the Python interface
188#
189#######################################################################
Daniel Veillard36ed5292002-01-30 23:49:06 +0000190
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000191skipped_modules = {
192 'xmlmemory': None,
Daniel Veillard96fe0952002-01-30 20:52:23 +0000193 'DOCBparser': None,
194 'SAX': None,
195 'hash': None,
196 'list': None,
197 'threads': None,
Daniel Veillardff12c492003-01-23 16:42:55 +0000198# 'xpointer': None,
Daniel Veillard96fe0952002-01-30 20:52:23 +0000199}
200skipped_types = {
201 'int *': "usually a return type",
202 'xmlSAXHandlerPtr': "not the proper interface for SAX",
203 'htmlSAXHandlerPtr': "not the proper interface for SAX",
Daniel Veillard96fe0952002-01-30 20:52:23 +0000204 'xmlRMutexPtr': "thread specific, skipped",
205 'xmlMutexPtr': "thread specific, skipped",
206 'xmlGlobalStatePtr': "thread specific, skipped",
207 'xmlListPtr': "internal representation not suitable for python",
208 'xmlBufferPtr': "internal representation not suitable for python",
209 'FILE *': None,
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000210}
Daniel Veillard1971ee22002-01-31 20:29:19 +0000211
212#######################################################################
213#
214# Table of remapping to/from the python type or class to the C
215# counterpart.
216#
217#######################################################################
218
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000219py_types = {
Daniel Veillard96fe0952002-01-30 20:52:23 +0000220 'void': (None, None, None, None),
221 'int': ('i', None, "int", "int"),
222 'long': ('i', None, "int", "int"),
223 'double': ('d', None, "double", "double"),
224 'unsigned int': ('i', None, "int", "int"),
225 'xmlChar': ('c', None, "int", "int"),
Daniel Veillard253aa2c2002-02-02 09:17:16 +0000226 'unsigned char *': ('z', None, "charPtr", "char *"),
227 'char *': ('z', None, "charPtr", "char *"),
Daniel Veillardc575b992002-02-08 13:28:40 +0000228 'const char *': ('z', None, "charPtrConst", "const char *"),
Daniel Veillard253aa2c2002-02-02 09:17:16 +0000229 'xmlChar *': ('z', None, "xmlCharPtr", "xmlChar *"),
Daniel Veillardc575b992002-02-08 13:28:40 +0000230 'const xmlChar *': ('z', None, "xmlCharPtrConst", "const xmlChar *"),
Daniel Veillard96fe0952002-01-30 20:52:23 +0000231 'xmlNodePtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
232 'const xmlNodePtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
233 'xmlNode *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
234 'const xmlNode *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
235 'xmlDtdPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
236 'const xmlDtdPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
237 'xmlDtd *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
238 'const xmlDtd *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
239 'xmlAttrPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
240 'const xmlAttrPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
241 'xmlAttr *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
242 'const xmlAttr *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
243 'xmlEntityPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
244 'const xmlEntityPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
245 'xmlEntity *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
246 'const xmlEntity *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
Daniel Veillard1971ee22002-01-31 20:29:19 +0000247 'xmlElementPtr': ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
248 'const xmlElementPtr': ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
249 'xmlElement *': ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
250 'const xmlElement *': ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
251 'xmlAttributePtr': ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
252 'const xmlAttributePtr': ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
253 'xmlAttribute *': ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
254 'const xmlAttribute *': ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
255 'xmlNsPtr': ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
256 'const xmlNsPtr': ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
257 'xmlNs *': ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
258 'const xmlNs *': ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
Daniel Veillard96fe0952002-01-30 20:52:23 +0000259 'xmlDocPtr': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
260 'const xmlDocPtr': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
261 'xmlDoc *': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
262 'const xmlDoc *': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
263 'htmlDocPtr': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
264 'const htmlDocPtr': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
265 'htmlDoc *': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
266 'const htmlDoc *': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
267 'htmlNodePtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
268 'const htmlNodePtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
269 'htmlNode *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
270 'const htmlNode *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
Daniel Veillard1971ee22002-01-31 20:29:19 +0000271 'xmlXPathContextPtr': ('O', "xmlXPathContext", "xmlXPathContextPtr", "xmlXPathContextPtr"),
272 'xmlXPathContext *': ('O', "xpathContext", "xmlXPathContextPtr", "xmlXPathContextPtr"),
Daniel Veillard7db38712002-02-07 16:39:11 +0000273 'xmlXPathParserContextPtr': ('O', "xmlXPathParserContext", "xmlXPathParserContextPtr", "xmlXPathParserContextPtr"),
Daniel Veillard3ce52572002-02-03 15:08:05 +0000274 'xmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
275 'xmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
276 'htmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
277 'htmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
Daniel Veillard850ce9b2004-11-10 11:55:47 +0000278 'xmlValidCtxtPtr': ('O', "ValidCtxt", "xmlValidCtxtPtr", "xmlValidCtxtPtr"),
Daniel Veillard7db38712002-02-07 16:39:11 +0000279 'xmlCatalogPtr': ('O', "catalog", "xmlCatalogPtr", "xmlCatalogPtr"),
280 'FILE *': ('O', "File", "FILEPtr", "FILE *"),
Daniel Veillard6361da02002-02-23 10:10:33 +0000281 'xmlURIPtr': ('O', "URI", "xmlURIPtr", "xmlURIPtr"),
Daniel Veillard46da4642004-01-06 22:54:57 +0000282 'xmlErrorPtr': ('O', "Error", "xmlErrorPtr", "xmlErrorPtr"),
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000283 'xmlOutputBufferPtr': ('O', "outputBuffer", "xmlOutputBufferPtr", "xmlOutputBufferPtr"),
284 'xmlParserInputBufferPtr': ('O', "inputBuffer", "xmlParserInputBufferPtr", "xmlParserInputBufferPtr"),
Daniel Veillardbd9afb52002-09-25 22:25:35 +0000285 'xmlRegexpPtr': ('O', "xmlReg", "xmlRegexpPtr", "xmlRegexpPtr"),
Daniel Veillard417be3a2003-01-20 21:26:34 +0000286 'xmlTextReaderLocatorPtr': ('O', "xmlTextReaderLocator", "xmlTextReaderLocatorPtr", "xmlTextReaderLocatorPtr"),
Daniel Veillard0eb38c72002-12-14 23:00:35 +0000287 'xmlTextReaderPtr': ('O', "xmlTextReader", "xmlTextReaderPtr", "xmlTextReaderPtr"),
Daniel Veillard591b4be2003-02-09 23:33:36 +0000288 'xmlRelaxNGPtr': ('O', "relaxNgSchema", "xmlRelaxNGPtr", "xmlRelaxNGPtr"),
289 'xmlRelaxNGParserCtxtPtr': ('O', "relaxNgParserCtxt", "xmlRelaxNGParserCtxtPtr", "xmlRelaxNGParserCtxtPtr"),
290 'xmlRelaxNGValidCtxtPtr': ('O', "relaxNgValidCtxt", "xmlRelaxNGValidCtxtPtr", "xmlRelaxNGValidCtxtPtr"),
Daniel Veillard259f0df2004-08-18 09:13:18 +0000291 'xmlSchemaPtr': ('O', "Schema", "xmlSchemaPtr", "xmlSchemaPtr"),
292 'xmlSchemaParserCtxtPtr': ('O', "SchemaParserCtxt", "xmlSchemaParserCtxtPtr", "xmlSchemaParserCtxtPtr"),
293 'xmlSchemaValidCtxtPtr': ('O', "SchemaValidCtxt", "xmlSchemaValidCtxtPtr", "xmlSchemaValidCtxtPtr"),
Daniel Veillard1971ee22002-01-31 20:29:19 +0000294}
295
296py_return_types = {
297 'xmlXPathObjectPtr': ('O', "foo", "xmlXPathObjectPtr", "xmlXPathObjectPtr"),
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000298}
299
300unknown_types = {}
301
William M. Brack106cad62004-12-23 15:56:12 +0000302foreign_encoding_args = (
303 'xmlCreateMemoryParserCtxt',
304)
305
Daniel Veillard1971ee22002-01-31 20:29:19 +0000306#######################################################################
307#
308# This part writes the C <-> Python stubs libxml2-py.[ch] and
309# the table libxml2-export.c to add when registrering the Python module
310#
311#######################################################################
312
Daniel Veillard263ec862004-10-04 10:26:54 +0000313# Class methods which are written by hand in libxml.c but the Python-level
314# code is still automatically generated (so they are not in skip_function()).
315skip_impl = (
316 'xmlSaveFileTo',
317 'xmlSaveFormatFileTo',
318)
319
Daniel Veillard1971ee22002-01-31 20:29:19 +0000320def skip_function(name):
321 if name[0:12] == "xmlXPathWrap":
322 return 1
Daniel Veillarde6227e02003-01-14 11:42:39 +0000323 if name == "xmlFreeParserCtxt":
324 return 1
Daniel Veillardf93a8662004-07-01 12:56:30 +0000325 if name == "xmlCleanupParser":
326 return 1
Daniel Veillard26f70262003-01-16 22:45:08 +0000327 if name == "xmlFreeTextReader":
328 return 1
Daniel Veillard1971ee22002-01-31 20:29:19 +0000329# if name[0:11] == "xmlXPathNew":
330# return 1
Daniel Veillardc2664642003-07-29 20:44:53 +0000331 # the next function is defined in libxml.c
332 if name == "xmlRelaxNGFreeValidCtxt":
333 return 1
Daniel Veillard198c1bf2003-10-20 17:07:41 +0000334#
335# Those are skipped because the Const version is used of the bindings
336# instead.
337#
338 if name == "xmlTextReaderBaseUri":
339 return 1
340 if name == "xmlTextReaderLocalName":
341 return 1
342 if name == "xmlTextReaderName":
343 return 1
344 if name == "xmlTextReaderNamespaceUri":
345 return 1
346 if name == "xmlTextReaderPrefix":
347 return 1
348 if name == "xmlTextReaderXmlLang":
349 return 1
350 if name == "xmlTextReaderValue":
351 return 1
Daniel Veillard6cbd6c02003-12-04 12:31:49 +0000352 if name == "xmlOutputBufferClose": # handled by by the superclass
353 return 1
354 if name == "xmlOutputBufferFlush": # handled by by the superclass
355 return 1
William M. Brackf7eb7942003-12-31 07:59:17 +0000356 if name == "xmlErrMemory":
357 return 1
Daniel Veillard850ce9b2004-11-10 11:55:47 +0000358
359 if name == "xmlValidBuildContentModel":
360 return 1
361 if name == "xmlValidateElementDecl":
362 return 1
363 if name == "xmlValidateAttributeDecl":
364 return 1
365
Daniel Veillard1971ee22002-01-31 20:29:19 +0000366 return 0
367
Daniel Veillard96fe0952002-01-30 20:52:23 +0000368def print_function_wrapper(name, output, export, include):
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000369 global py_types
370 global unknown_types
371 global functions
372 global skipped_modules
373
374 try:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000375 (desc, ret, args, file) = functions[name]
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000376 except:
377 print "failed to get function %s infos"
378 return
379
380 if skipped_modules.has_key(file):
381 return 0
Daniel Veillard1971ee22002-01-31 20:29:19 +0000382 if skip_function(name) == 1:
383 return 0
Daniel Veillard263ec862004-10-04 10:26:54 +0000384 if name in skip_impl:
385 # Don't delete the function entry in the caller.
386 return 1
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000387
388 c_call = "";
389 format=""
390 format_args=""
391 c_args=""
392 c_return=""
Daniel Veillard96fe0952002-01-30 20:52:23 +0000393 c_convert=""
William M. Brack106cad62004-12-23 15:56:12 +0000394 num_bufs=0
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000395 for arg in args:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000396 # This should be correct
397 if arg[1][0:6] == "const ":
398 arg[1] = arg[1][6:]
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000399 c_args = c_args + " %s %s;\n" % (arg[1], arg[0])
Daniel Veillard01a6d412002-02-11 18:42:20 +0000400 if py_types.has_key(arg[1]):
401 (f, t, n, c) = py_types[arg[1]]
William M. Brack106cad62004-12-23 15:56:12 +0000402 if name == 'xmlCreateMemoryParserCtxt':
403 print "processing special case"
404 if (f == 'z') and (name in foreign_encoding_args):
405 f = 't#'
406 print "changed 'f'"
Daniel Veillard01a6d412002-02-11 18:42:20 +0000407 if f != None:
408 format = format + f
409 if t != None:
410 format_args = format_args + ", &pyobj_%s" % (arg[0])
411 c_args = c_args + " PyObject *pyobj_%s;\n" % (arg[0])
412 c_convert = c_convert + \
413 " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg[0],
414 arg[1], t, arg[0]);
415 else:
416 format_args = format_args + ", &%s" % (arg[0])
William M. Brack106cad62004-12-23 15:56:12 +0000417 if f == 't#':
418 format_args = format_args + ", &py_buffsize%d" % num_bufs
419 c_args = c_args + " int py_buffsize%d;\n" % num_bufs
420 num_bufs = num_bufs + 1
Daniel Veillard01a6d412002-02-11 18:42:20 +0000421 if c_call != "":
422 c_call = c_call + ", ";
423 c_call = c_call + "%s" % (arg[0])
424 else:
425 if skipped_types.has_key(arg[1]):
426 return 0
427 if unknown_types.has_key(arg[1]):
428 lst = unknown_types[arg[1]]
429 lst.append(name)
430 else:
431 unknown_types[arg[1]] = [name]
432 return -1
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000433 if format != "":
434 format = format + ":%s" % (name)
435
436 if ret[0] == 'void':
Daniel Veillard01a6d412002-02-11 18:42:20 +0000437 if file == "python_accessor":
Daniel Veillard6361da02002-02-23 10:10:33 +0000438 if args[1][1] == "char *" or args[1][1] == "xmlChar *":
439 c_call = "\n if (%s->%s != NULL) xmlFree(%s->%s);\n" % (
440 args[0][0], args[1][0], args[0][0], args[1][0])
William M. Bracka71a8ef2003-08-06 04:43:55 +0000441 c_call = c_call + " %s->%s = (%s)xmlStrdup((const xmlChar *)%s);\n" % (args[0][0],
442 args[1][0], args[1][1], args[1][0])
Daniel Veillard6361da02002-02-23 10:10:33 +0000443 else:
444 c_call = "\n %s->%s = %s;\n" % (args[0][0], args[1][0],
445 args[1][0])
Daniel Veillard01a6d412002-02-11 18:42:20 +0000446 else:
447 c_call = "\n %s(%s);\n" % (name, c_call);
448 ret_convert = " Py_INCREF(Py_None);\n return(Py_None);\n"
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000449 elif py_types.has_key(ret[0]):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000450 (f, t, n, c) = py_types[ret[0]]
451 c_return = " %s c_retval;\n" % (ret[0])
452 if file == "python_accessor" and ret[2] != None:
453 c_call = "\n c_retval = %s->%s;\n" % (args[0][0], ret[2])
454 else:
455 c_call = "\n c_retval = %s(%s);\n" % (name, c_call);
456 ret_convert = " py_retval = libxml_%sWrap((%s) c_retval);\n" % (n,c)
457 ret_convert = ret_convert + " return(py_retval);\n"
Daniel Veillard1971ee22002-01-31 20:29:19 +0000458 elif py_return_types.has_key(ret[0]):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000459 (f, t, n, c) = py_return_types[ret[0]]
460 c_return = " %s c_retval;\n" % (ret[0])
Daniel Veillard1971ee22002-01-31 20:29:19 +0000461 c_call = "\n c_retval = %s(%s);\n" % (name, c_call);
Daniel Veillard01a6d412002-02-11 18:42:20 +0000462 ret_convert = " py_retval = libxml_%sWrap((%s) c_retval);\n" % (n,c)
463 ret_convert = ret_convert + " return(py_retval);\n"
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000464 else:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000465 if skipped_types.has_key(ret[0]):
466 return 0
467 if unknown_types.has_key(ret[0]):
468 lst = unknown_types[ret[0]]
469 lst.append(name)
470 else:
471 unknown_types[ret[0]] = [name]
472 return -1
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000473
Daniel Veillard42766c02002-08-22 20:52:17 +0000474 if file == "debugXML":
475 include.write("#ifdef LIBXML_DEBUG_ENABLED\n");
476 export.write("#ifdef LIBXML_DEBUG_ENABLED\n");
477 output.write("#ifdef LIBXML_DEBUG_ENABLED\n");
Daniel Veillard656ce942004-04-30 23:11:45 +0000478 elif file == "HTMLtree" or file == "HTMLparser" or name[0:4] == "html":
Daniel Veillard42766c02002-08-22 20:52:17 +0000479 include.write("#ifdef LIBXML_HTML_ENABLED\n");
480 export.write("#ifdef LIBXML_HTML_ENABLED\n");
481 output.write("#ifdef LIBXML_HTML_ENABLED\n");
482 elif file == "c14n":
483 include.write("#ifdef LIBXML_C14N_ENABLED\n");
484 export.write("#ifdef LIBXML_C14N_ENABLED\n");
485 output.write("#ifdef LIBXML_C14N_ENABLED\n");
486 elif file == "xpathInternals" or file == "xpath":
487 include.write("#ifdef LIBXML_XPATH_ENABLED\n");
488 export.write("#ifdef LIBXML_XPATH_ENABLED\n");
489 output.write("#ifdef LIBXML_XPATH_ENABLED\n");
490 elif file == "xpointer":
491 include.write("#ifdef LIBXML_XPTR_ENABLED\n");
492 export.write("#ifdef LIBXML_XPTR_ENABLED\n");
493 output.write("#ifdef LIBXML_XPTR_ENABLED\n");
494 elif file == "xinclude":
495 include.write("#ifdef LIBXML_XINCLUDE_ENABLED\n");
496 export.write("#ifdef LIBXML_XINCLUDE_ENABLED\n");
497 output.write("#ifdef LIBXML_XINCLUDE_ENABLED\n");
Daniel Veillardbd9afb52002-09-25 22:25:35 +0000498 elif file == "xmlregexp":
499 include.write("#ifdef LIBXML_REGEXP_ENABLED\n");
500 export.write("#ifdef LIBXML_REGEXP_ENABLED\n");
501 output.write("#ifdef LIBXML_REGEXP_ENABLED\n");
Daniel Veillard71531f32003-02-05 13:19:53 +0000502 elif file == "xmlschemas" or file == "xmlschemastypes" or \
503 file == "relaxng":
504 include.write("#ifdef LIBXML_SCHEMAS_ENABLED\n");
505 export.write("#ifdef LIBXML_SCHEMAS_ENABLED\n");
506 output.write("#ifdef LIBXML_SCHEMAS_ENABLED\n");
Daniel Veillard42766c02002-08-22 20:52:17 +0000507
Daniel Veillard96fe0952002-01-30 20:52:23 +0000508 include.write("PyObject * ")
Daniel Veillardd2379012002-03-15 22:24:56 +0000509 include.write("libxml_%s(PyObject *self, PyObject *args);\n" % (name));
Daniel Veillard9589d452002-02-02 10:28:17 +0000510
Daniel Veillardd2379012002-03-15 22:24:56 +0000511 export.write(" { (char *)\"%s\", libxml_%s, METH_VARARGS, NULL },\n" %
Daniel Veillard5e5c2d02002-02-09 18:03:01 +0000512 (name, name))
Daniel Veillard9589d452002-02-02 10:28:17 +0000513
514 if file == "python":
515 # Those have been manually generated
Daniel Veillard656ce942004-04-30 23:11:45 +0000516 if name[0:4] == "html":
517 include.write("#endif /* LIBXML_HTML_ENABLED */\n");
518 export.write("#endif /* LIBXML_HTML_ENABLED */\n");
519 output.write("#endif /* LIBXML_HTML_ENABLED */\n");
Daniel Veillard01a6d412002-02-11 18:42:20 +0000520 return 1
Daniel Veillard6f46f6c2002-08-01 12:22:24 +0000521 if file == "python_accessor" and ret[0] != "void" and ret[2] is None:
Daniel Veillard36eea2d2002-02-04 00:17:01 +0000522 # Those have been manually generated
Daniel Veillard656ce942004-04-30 23:11:45 +0000523 if name[0:4] == "html":
524 include.write("#endif /* LIBXML_HTML_ENABLED */\n");
525 export.write("#endif /* LIBXML_HTML_ENABLED */\n");
526 output.write("#endif /* LIBXML_HTML_ENABLED */\n");
Daniel Veillard01a6d412002-02-11 18:42:20 +0000527 return 1
Daniel Veillard9589d452002-02-02 10:28:17 +0000528
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000529 output.write("PyObject *\n")
William M. Brack6bf4d6f2003-11-04 23:29:16 +0000530 output.write("libxml_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
531 output.write(" PyObject *args")
Daniel Veillardd2379012002-03-15 22:24:56 +0000532 if format == "":
William M. Brack6bf4d6f2003-11-04 23:29:16 +0000533 output.write(" ATTRIBUTE_UNUSED")
534 output.write(") {\n")
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000535 if ret[0] != 'void':
Daniel Veillard01a6d412002-02-11 18:42:20 +0000536 output.write(" PyObject *py_retval;\n")
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000537 if c_return != "":
Daniel Veillard01a6d412002-02-11 18:42:20 +0000538 output.write(c_return)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000539 if c_args != "":
Daniel Veillard01a6d412002-02-11 18:42:20 +0000540 output.write(c_args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000541 if format != "":
Daniel Veillardd2379012002-03-15 22:24:56 +0000542 output.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
Daniel Veillard01a6d412002-02-11 18:42:20 +0000543 (format, format_args))
544 output.write(" return(NULL);\n")
Daniel Veillard96fe0952002-01-30 20:52:23 +0000545 if c_convert != "":
Daniel Veillard01a6d412002-02-11 18:42:20 +0000546 output.write(c_convert)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000547
548 output.write(c_call)
549 output.write(ret_convert)
550 output.write("}\n\n")
Daniel Veillard42766c02002-08-22 20:52:17 +0000551 if file == "debugXML":
552 include.write("#endif /* LIBXML_DEBUG_ENABLED */\n");
553 export.write("#endif /* LIBXML_DEBUG_ENABLED */\n");
554 output.write("#endif /* LIBXML_DEBUG_ENABLED */\n");
Daniel Veillard656ce942004-04-30 23:11:45 +0000555 elif file == "HTMLtree" or file == "HTMLparser" or name[0:4] == "html":
Daniel Veillard42766c02002-08-22 20:52:17 +0000556 include.write("#endif /* LIBXML_HTML_ENABLED */\n");
557 export.write("#endif /* LIBXML_HTML_ENABLED */\n");
558 output.write("#endif /* LIBXML_HTML_ENABLED */\n");
559 elif file == "c14n":
560 include.write("#endif /* LIBXML_C14N_ENABLED */\n");
561 export.write("#endif /* LIBXML_C14N_ENABLED */\n");
562 output.write("#endif /* LIBXML_C14N_ENABLED */\n");
563 elif file == "xpathInternals" or file == "xpath":
564 include.write("#endif /* LIBXML_XPATH_ENABLED */\n");
565 export.write("#endif /* LIBXML_XPATH_ENABLED */\n");
566 output.write("#endif /* LIBXML_XPATH_ENABLED */\n");
567 elif file == "xpointer":
568 include.write("#endif /* LIBXML_XPTR_ENABLED */\n");
569 export.write("#endif /* LIBXML_XPTR_ENABLED */\n");
570 output.write("#endif /* LIBXML_XPTR_ENABLED */\n");
571 elif file == "xinclude":
572 include.write("#endif /* LIBXML_XINCLUDE_ENABLED */\n");
573 export.write("#endif /* LIBXML_XINCLUDE_ENABLED */\n");
574 output.write("#endif /* LIBXML_XINCLUDE_ENABLED */\n");
Daniel Veillardbd9afb52002-09-25 22:25:35 +0000575 elif file == "xmlregexp":
576 include.write("#endif /* LIBXML_REGEXP_ENABLED */\n");
577 export.write("#endif /* LIBXML_REGEXP_ENABLED */\n");
578 output.write("#endif /* LIBXML_REGEXP_ENABLED */\n");
Daniel Veillard71531f32003-02-05 13:19:53 +0000579 elif file == "xmlschemas" or file == "xmlschemastypes" or \
580 file == "relaxng":
581 include.write("#endif /* LIBXML_SCHEMAS_ENABLED */\n");
582 export.write("#endif /* LIBXML_SCHEMAS_ENABLED */\n");
583 output.write("#endif /* LIBXML_SCHEMAS_ENABLED */\n");
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000584 return 1
585
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000586def buildStubs():
587 global py_types
588 global py_return_types
589 global unknown_types
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000590
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000591 try:
William M. Brack106cad62004-12-23 15:56:12 +0000592 f = open(srcPref + "libxml2-api.xml")
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000593 data = f.read()
594 (parser, target) = getparser()
595 parser.feed(data)
596 parser.close()
597 except IOError, msg:
598 try:
William M. Brack106cad62004-12-23 15:56:12 +0000599 f = open(srcPref + "../doc/libxml2-api.xml")
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000600 data = f.read()
601 (parser, target) = getparser()
602 parser.feed(data)
603 parser.close()
604 except IOError, msg:
605 print file, ":", msg
606 sys.exit(1)
Daniel Veillard9589d452002-02-02 10:28:17 +0000607
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000608 n = len(functions.keys())
609 print "Found %d functions in libxml2-api.xml" % (n)
610
611 py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
612 try:
William M. Brack106cad62004-12-23 15:56:12 +0000613 f = open(srcPref + "libxml2-python-api.xml")
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000614 data = f.read()
615 (parser, target) = getparser()
616 parser.feed(data)
617 parser.close()
618 except IOError, msg:
619 print file, ":", msg
Daniel Veillard9589d452002-02-02 10:28:17 +0000620
621
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000622 print "Found %d functions in libxml2-python-api.xml" % (
623 len(functions.keys()) - n)
624 nb_wrap = 0
625 failed = 0
626 skipped = 0
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000627
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000628 include = open("libxml2-py.h", "w")
629 include.write("/* Generated */\n\n")
630 export = open("libxml2-export.c", "w")
631 export.write("/* Generated */\n\n")
632 wrapper = open("libxml2-py.c", "w")
633 wrapper.write("/* Generated */\n\n")
634 wrapper.write("#include <Python.h>\n")
Daniel Veillardd2379012002-03-15 22:24:56 +0000635 wrapper.write("#include <libxml/xmlversion.h>\n")
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000636 wrapper.write("#include <libxml/tree.h>\n")
William M. Bracka71a8ef2003-08-06 04:43:55 +0000637 wrapper.write("#include <libxml/xmlschemastypes.h>\n")
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000638 wrapper.write("#include \"libxml_wrap.h\"\n")
639 wrapper.write("#include \"libxml2-py.h\"\n\n")
640 for function in functions.keys():
641 ret = print_function_wrapper(function, wrapper, export, include)
642 if ret < 0:
643 failed = failed + 1
644 del functions[function]
645 if ret == 0:
646 skipped = skipped + 1
647 del functions[function]
648 if ret == 1:
649 nb_wrap = nb_wrap + 1
650 include.close()
651 export.close()
652 wrapper.close()
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000653
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000654 print "Generated %d wrapper functions, %d failed, %d skipped\n" % (nb_wrap,
655 failed, skipped);
656 print "Missing type converters: "
657 for type in unknown_types.keys():
658 print "%s:%d " % (type, len(unknown_types[type])),
659 print
Daniel Veillard36ed5292002-01-30 23:49:06 +0000660
Daniel Veillard1971ee22002-01-31 20:29:19 +0000661#######################################################################
662#
663# This part writes part of the Python front-end classes based on
664# mapping rules between types and classes and also based on function
665# renaming to get consistent function names at the Python level
666#
667#######################################################################
668
669#
670# The type automatically remapped to generated classes
671#
672classes_type = {
673 "xmlNodePtr": ("._o", "xmlNode(_obj=%s)", "xmlNode"),
674 "xmlNode *": ("._o", "xmlNode(_obj=%s)", "xmlNode"),
675 "xmlDocPtr": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
676 "xmlDocPtr *": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
677 "htmlDocPtr": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
678 "htmlxmlDocPtr *": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
679 "xmlAttrPtr": ("._o", "xmlAttr(_obj=%s)", "xmlAttr"),
680 "xmlAttr *": ("._o", "xmlAttr(_obj=%s)", "xmlAttr"),
681 "xmlNsPtr": ("._o", "xmlNs(_obj=%s)", "xmlNs"),
682 "xmlNs *": ("._o", "xmlNs(_obj=%s)", "xmlNs"),
683 "xmlDtdPtr": ("._o", "xmlDtd(_obj=%s)", "xmlDtd"),
684 "xmlDtd *": ("._o", "xmlDtd(_obj=%s)", "xmlDtd"),
685 "xmlEntityPtr": ("._o", "xmlEntity(_obj=%s)", "xmlEntity"),
686 "xmlEntity *": ("._o", "xmlEntity(_obj=%s)", "xmlEntity"),
687 "xmlElementPtr": ("._o", "xmlElement(_obj=%s)", "xmlElement"),
688 "xmlElement *": ("._o", "xmlElement(_obj=%s)", "xmlElement"),
689 "xmlAttributePtr": ("._o", "xmlAttribute(_obj=%s)", "xmlAttribute"),
690 "xmlAttribute *": ("._o", "xmlAttribute(_obj=%s)", "xmlAttribute"),
691 "xmlXPathContextPtr": ("._o", "xpathContext(_obj=%s)", "xpathContext"),
Daniel Veillard7db38712002-02-07 16:39:11 +0000692 "xmlXPathContext *": ("._o", "xpathContext(_obj=%s)", "xpathContext"),
693 "xmlXPathParserContext *": ("._o", "xpathParserContext(_obj=%s)", "xpathParserContext"),
694 "xmlXPathParserContextPtr": ("._o", "xpathParserContext(_obj=%s)", "xpathParserContext"),
Daniel Veillard3ce52572002-02-03 15:08:05 +0000695 "xmlParserCtxtPtr": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
696 "xmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
Daniel Veillard3cd72402002-05-13 10:33:30 +0000697 "htmlParserCtxtPtr": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
698 "htmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
Daniel Veillard850ce9b2004-11-10 11:55:47 +0000699 "xmlValidCtxtPtr": ("._o", "ValidCtxt(_obj=%s)", "ValidCtxt"),
Daniel Veillard7db38712002-02-07 16:39:11 +0000700 "xmlCatalogPtr": ("._o", "catalog(_obj=%s)", "catalog"),
Daniel Veillard6361da02002-02-23 10:10:33 +0000701 "xmlURIPtr": ("._o", "URI(_obj=%s)", "URI"),
Daniel Veillard46da4642004-01-06 22:54:57 +0000702 "xmlErrorPtr": ("._o", "Error(_obj=%s)", "Error"),
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000703 "xmlOutputBufferPtr": ("._o", "outputBuffer(_obj=%s)", "outputBuffer"),
704 "xmlParserInputBufferPtr": ("._o", "inputBuffer(_obj=%s)", "inputBuffer"),
Daniel Veillardbd9afb52002-09-25 22:25:35 +0000705 "xmlRegexpPtr": ("._o", "xmlReg(_obj=%s)", "xmlReg"),
Daniel Veillard417be3a2003-01-20 21:26:34 +0000706 "xmlTextReaderLocatorPtr": ("._o", "xmlTextReaderLocator(_obj=%s)", "xmlTextReaderLocator"),
Daniel Veillard0eb38c72002-12-14 23:00:35 +0000707 "xmlTextReaderPtr": ("._o", "xmlTextReader(_obj=%s)", "xmlTextReader"),
Daniel Veillard591b4be2003-02-09 23:33:36 +0000708 'xmlRelaxNGPtr': ('._o', "relaxNgSchema(_obj=%s)", "relaxNgSchema"),
709 'xmlRelaxNGParserCtxtPtr': ('._o', "relaxNgParserCtxt(_obj=%s)", "relaxNgParserCtxt"),
710 'xmlRelaxNGValidCtxtPtr': ('._o', "relaxNgValidCtxt(_obj=%s)", "relaxNgValidCtxt"),
Daniel Veillard259f0df2004-08-18 09:13:18 +0000711 'xmlSchemaPtr': ("._o", "Schema(_obj=%s)", "Schema"),
712 'xmlSchemaParserCtxtPtr': ("._o", "SchemaParserCtxt(_obj=%s)", "SchemaParserCtxt"),
713 'xmlSchemaValidCtxtPtr': ("._o", "SchemaValidCtxt(_obj=%s)", "SchemaValidCtxt"),
Daniel Veillard1971ee22002-01-31 20:29:19 +0000714}
715
716converter_type = {
717 "xmlXPathObjectPtr": "xpathObjectRet(%s)",
718}
719
720primary_classes = ["xmlNode", "xmlDoc"]
721
722classes_ancestor = {
723 "xmlNode" : "xmlCore",
Daniel Veillard253aa2c2002-02-02 09:17:16 +0000724 "xmlDtd" : "xmlNode",
725 "xmlDoc" : "xmlNode",
726 "xmlAttr" : "xmlNode",
727 "xmlNs" : "xmlNode",
728 "xmlEntity" : "xmlNode",
729 "xmlElement" : "xmlNode",
730 "xmlAttribute" : "xmlNode",
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000731 "outputBuffer": "ioWriteWrapper",
732 "inputBuffer": "ioReadWrapper",
Daniel Veillarde6227e02003-01-14 11:42:39 +0000733 "parserCtxt": "parserCtxtCore",
Daniel Veillard26f70262003-01-16 22:45:08 +0000734 "xmlTextReader": "xmlTextReaderCore",
Daniel Veillard1971ee22002-01-31 20:29:19 +0000735}
736classes_destructors = {
Daniel Veillard3ce52572002-02-03 15:08:05 +0000737 "parserCtxt": "xmlFreeParserCtxt",
Daniel Veillard7db38712002-02-07 16:39:11 +0000738 "catalog": "xmlFreeCatalog",
Daniel Veillard6361da02002-02-23 10:10:33 +0000739 "URI": "xmlFreeURI",
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000740# "outputBuffer": "xmlOutputBufferClose",
741 "inputBuffer": "xmlFreeParserInputBuffer",
Daniel Veillardbd9afb52002-09-25 22:25:35 +0000742 "xmlReg": "xmlRegFreeRegexp",
Daniel Veillard0eb38c72002-12-14 23:00:35 +0000743 "xmlTextReader": "xmlFreeTextReader",
Daniel Veillard591b4be2003-02-09 23:33:36 +0000744 "relaxNgSchema": "xmlRelaxNGFree",
745 "relaxNgParserCtxt": "xmlRelaxNGFreeParserCtxt",
746 "relaxNgValidCtxt": "xmlRelaxNGFreeValidCtxt",
Daniel Veillard259f0df2004-08-18 09:13:18 +0000747 "Schema": "xmlSchemaFree",
748 "SchemaParserCtxt": "xmlSchemaFreeParserCtxt",
749 "SchemaValidCtxt": "xmlSchemaFreeValidCtxt",
Daniel Veillard850ce9b2004-11-10 11:55:47 +0000750 "ValidCtxt": "xmlFreeValidCtxt",
Daniel Veillard1971ee22002-01-31 20:29:19 +0000751}
752
Daniel Veillardef6c46f2002-03-07 22:21:56 +0000753functions_noexcept = {
754 "xmlHasProp": 1,
755 "xmlHasNsProp": 1,
Daniel Veillard3b87b6b2003-01-10 15:21:50 +0000756 "xmlDocSetRootElement": 1,
William M. Brackdbbcf8e2004-12-17 22:50:53 +0000757 "xmlNodeGetNs": 1,
758 "xmlNodeGetNsDefs": 1,
Daniel Veillardef6c46f2002-03-07 22:21:56 +0000759}
760
Daniel Veillarddc85f282002-12-31 11:18:37 +0000761reference_keepers = {
762 "xmlTextReader": [('inputBuffer', 'input')],
Daniel Veillard591b4be2003-02-09 23:33:36 +0000763 "relaxNgValidCtxt": [('relaxNgSchema', 'schema')],
Daniel Veillard259f0df2004-08-18 09:13:18 +0000764 "SchemaValidCtxt": [('Schema', 'schema')],
Daniel Veillarddc85f282002-12-31 11:18:37 +0000765}
766
Daniel Veillard36ed5292002-01-30 23:49:06 +0000767function_classes = {}
Daniel Veillard1971ee22002-01-31 20:29:19 +0000768
769function_classes["None"] = []
Daniel Veillard1971ee22002-01-31 20:29:19 +0000770
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000771def nameFixup(name, classe, type, file):
Daniel Veillard1971ee22002-01-31 20:29:19 +0000772 listname = classe + "List"
773 ll = len(listname)
774 l = len(classe)
775 if name[0:l] == listname:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000776 func = name[l:]
777 func = string.lower(func[0:1]) + func[1:]
Daniel Veillard3ce52572002-02-03 15:08:05 +0000778 elif name[0:12] == "xmlParserGet" and file == "python_accessor":
779 func = name[12:]
780 func = string.lower(func[0:1]) + func[1:]
Daniel Veillard26f1dcc2002-02-03 16:53:19 +0000781 elif name[0:12] == "xmlParserSet" and file == "python_accessor":
782 func = name[12:]
783 func = string.lower(func[0:1]) + func[1:]
Daniel Veillard36eea2d2002-02-04 00:17:01 +0000784 elif name[0:10] == "xmlNodeGet" and file == "python_accessor":
785 func = name[10:]
786 func = string.lower(func[0:1]) + func[1:]
Daniel Veillard6361da02002-02-23 10:10:33 +0000787 elif name[0:9] == "xmlURIGet" and file == "python_accessor":
788 func = name[9:]
789 func = string.lower(func[0:1]) + func[1:]
790 elif name[0:9] == "xmlURISet" and file == "python_accessor":
791 func = name[6:]
792 func = string.lower(func[0:1]) + func[1:]
Daniel Veillard46da4642004-01-06 22:54:57 +0000793 elif name[0:11] == "xmlErrorGet" and file == "python_accessor":
794 func = name[11:]
795 func = string.lower(func[0:1]) + func[1:]
Daniel Veillardc575b992002-02-08 13:28:40 +0000796 elif name[0:17] == "xmlXPathParserGet" and file == "python_accessor":
797 func = name[17:]
798 func = string.lower(func[0:1]) + func[1:]
799 elif name[0:11] == "xmlXPathGet" and file == "python_accessor":
800 func = name[11:]
801 func = string.lower(func[0:1]) + func[1:]
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000802 elif name[0:11] == "xmlXPathSet" and file == "python_accessor":
803 func = name[8:]
804 func = string.lower(func[0:1]) + func[1:]
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000805 elif name[0:15] == "xmlOutputBuffer" and file != "python":
806 func = name[15:]
807 func = string.lower(func[0:1]) + func[1:]
808 elif name[0:20] == "xmlParserInputBuffer" and file != "python":
809 func = name[20:]
810 func = string.lower(func[0:1]) + func[1:]
Daniel Veillardd4cb1e82002-09-26 09:34:23 +0000811 elif name[0:9] == "xmlRegexp" and file == "xmlregexp":
Daniel Veillardbd9afb52002-09-25 22:25:35 +0000812 func = "regexp" + name[9:]
Daniel Veillardd4cb1e82002-09-26 09:34:23 +0000813 elif name[0:6] == "xmlReg" and file == "xmlregexp":
Daniel Veillardbd9afb52002-09-25 22:25:35 +0000814 func = "regexp" + name[6:]
Daniel Veillard417be3a2003-01-20 21:26:34 +0000815 elif name[0:20] == "xmlTextReaderLocator" and file == "xmlreader":
816 func = name[20:]
Daniel Veillard198c1bf2003-10-20 17:07:41 +0000817 elif name[0:18] == "xmlTextReaderConst" and file == "xmlreader":
818 func = name[18:]
Daniel Veillard0eb38c72002-12-14 23:00:35 +0000819 elif name[0:13] == "xmlTextReader" and file == "xmlreader":
820 func = name[13:]
Daniel Veillard198c1bf2003-10-20 17:07:41 +0000821 elif name[0:12] == "xmlReaderNew" and file == "xmlreader":
822 func = name[9:]
Daniel Veillard7db38712002-02-07 16:39:11 +0000823 elif name[0:11] == "xmlACatalog":
824 func = name[11:]
825 func = string.lower(func[0:1]) + func[1:]
Daniel Veillard1971ee22002-01-31 20:29:19 +0000826 elif name[0:l] == classe:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000827 func = name[l:]
828 func = string.lower(func[0:1]) + func[1:]
Daniel Veillard9589d452002-02-02 10:28:17 +0000829 elif name[0:7] == "libxml_":
Daniel Veillard01a6d412002-02-11 18:42:20 +0000830 func = name[7:]
831 func = string.lower(func[0:1]) + func[1:]
Daniel Veillard1971ee22002-01-31 20:29:19 +0000832 elif name[0:6] == "xmlGet":
Daniel Veillard01a6d412002-02-11 18:42:20 +0000833 func = name[6:]
834 func = string.lower(func[0:1]) + func[1:]
Daniel Veillard1971ee22002-01-31 20:29:19 +0000835 elif name[0:3] == "xml":
Daniel Veillard01a6d412002-02-11 18:42:20 +0000836 func = name[3:]
837 func = string.lower(func[0:1]) + func[1:]
Daniel Veillard36ed5292002-01-30 23:49:06 +0000838 else:
Daniel Veillard1971ee22002-01-31 20:29:19 +0000839 func = name
840 if func[0:5] == "xPath":
841 func = "xpath" + func[5:]
842 elif func[0:4] == "xPtr":
843 func = "xpointer" + func[4:]
844 elif func[0:8] == "xInclude":
845 func = "xinclude" + func[8:]
846 elif func[0:2] == "iD":
847 func = "ID" + func[2:]
848 elif func[0:3] == "uRI":
849 func = "URI" + func[3:]
850 elif func[0:4] == "uTF8":
851 func = "UTF8" + func[4:]
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000852 elif func[0:3] == 'sAX':
853 func = "SAX" + func[3:]
Daniel Veillard1971ee22002-01-31 20:29:19 +0000854 return func
Daniel Veillard36ed5292002-01-30 23:49:06 +0000855
Daniel Veillard36ed5292002-01-30 23:49:06 +0000856
Daniel Veillard1971ee22002-01-31 20:29:19 +0000857def functionCompare(info1, info2):
858 (index1, func1, name1, ret1, args1, file1) = info1
859 (index2, func2, name2, ret2, args2, file2) = info2
Daniel Veillard26f1dcc2002-02-03 16:53:19 +0000860 if file1 == file2:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000861 if func1 < func2:
862 return -1
863 if func1 > func2:
864 return 1
Daniel Veillard3ce52572002-02-03 15:08:05 +0000865 if file1 == "python_accessor":
866 return -1
867 if file2 == "python_accessor":
868 return 1
Daniel Veillard1971ee22002-01-31 20:29:19 +0000869 if file1 < file2:
870 return -1
871 if file1 > file2:
872 return 1
Daniel Veillard1971ee22002-01-31 20:29:19 +0000873 return 0
874
875def writeDoc(name, args, indent, output):
Daniel Veillard6f46f6c2002-08-01 12:22:24 +0000876 if functions[name][0] is None or functions[name][0] == "":
Daniel Veillard1971ee22002-01-31 20:29:19 +0000877 return
878 val = functions[name][0]
879 val = string.replace(val, "NULL", "None");
880 output.write(indent)
881 output.write('"""')
882 while len(val) > 60:
883 str = val[0:60]
Daniel Veillard01a6d412002-02-11 18:42:20 +0000884 i = string.rfind(str, " ");
885 if i < 0:
886 i = 60
Daniel Veillard1971ee22002-01-31 20:29:19 +0000887 str = val[0:i]
Daniel Veillard01a6d412002-02-11 18:42:20 +0000888 val = val[i:]
889 output.write(str)
890 output.write('\n ');
891 output.write(indent)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000892 output.write(val);
Daniel Veillardd076a202002-11-20 13:28:31 +0000893 output.write(' """\n')
Daniel Veillard1971ee22002-01-31 20:29:19 +0000894
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000895def buildWrappers():
896 global ctypes
897 global py_types
898 global py_return_types
899 global unknown_types
900 global functions
901 global function_classes
902 global classes_type
903 global classes_list
904 global converter_type
905 global primary_classes
906 global converter_type
907 global classes_ancestor
908 global converter_type
909 global primary_classes
910 global classes_ancestor
911 global classes_destructors
Daniel Veillardef6c46f2002-03-07 22:21:56 +0000912 global functions_noexcept
Daniel Veillard36eea2d2002-02-04 00:17:01 +0000913
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000914 for type in classes_type.keys():
915 function_classes[classes_type[type][2]] = []
Daniel Veillard36ed5292002-01-30 23:49:06 +0000916
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000917 #
918 # Build the list of C types to look for ordered to start
919 # with primary classes
920 #
921 ctypes = []
922 classes_list = []
923 ctypes_processed = {}
924 classes_processed = {}
925 for classe in primary_classes:
926 classes_list.append(classe)
927 classes_processed[classe] = ()
928 for type in classes_type.keys():
929 tinfo = classes_type[type]
930 if tinfo[2] == classe:
931 ctypes.append(type)
932 ctypes_processed[type] = ()
933 for type in classes_type.keys():
934 if ctypes_processed.has_key(type):
935 continue
936 tinfo = classes_type[type]
937 if not classes_processed.has_key(tinfo[2]):
938 classes_list.append(tinfo[2])
939 classes_processed[tinfo[2]] = ()
940
941 ctypes.append(type)
942 ctypes_processed[type] = ()
Daniel Veillard36ed5292002-01-30 23:49:06 +0000943
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000944 for name in functions.keys():
945 found = 0;
946 (desc, ret, args, file) = functions[name]
947 for type in ctypes:
948 classe = classes_type[type][2]
949
950 if name[0:3] == "xml" and len(args) >= 1 and args[0][1] == type:
951 found = 1
952 func = nameFixup(name, classe, type, file)
953 info = (0, func, name, ret, args, file)
954 function_classes[classe].append(info)
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000955 elif name[0:3] == "xml" and len(args) >= 2 and args[1][1] == type \
956 and file != "python_accessor":
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000957 found = 1
958 func = nameFixup(name, classe, type, file)
959 info = (1, func, name, ret, args, file)
960 function_classes[classe].append(info)
961 elif name[0:4] == "html" and len(args) >= 1 and args[0][1] == type:
962 found = 1
963 func = nameFixup(name, classe, type, file)
964 info = (0, func, name, ret, args, file)
965 function_classes[classe].append(info)
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000966 elif name[0:4] == "html" and len(args) >= 2 and args[1][1] == type \
967 and file != "python_accessor":
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000968 found = 1
969 func = nameFixup(name, classe, type, file)
970 info = (1, func, name, ret, args, file)
971 function_classes[classe].append(info)
Daniel Veillard0fea6f42002-02-22 22:51:13 +0000972 if found == 1:
973 continue
974 if name[0:8] == "xmlXPath":
975 continue
976 if name[0:6] == "xmlStr":
977 continue
978 if name[0:10] == "xmlCharStr":
979 continue
980 func = nameFixup(name, "None", file, file)
981 info = (0, func, name, ret, args, file)
982 function_classes['None'].append(info)
983
984 classes = open("libxml2class.py", "w")
985 txt = open("libxml2class.txt", "w")
986 txt.write(" Generated Classes for libxml2-python\n\n")
987
988 txt.write("#\n# Global functions of the module\n#\n\n")
989 if function_classes.has_key("None"):
990 flist = function_classes["None"]
991 flist.sort(functionCompare)
992 oldfile = ""
993 for info in flist:
994 (index, func, name, ret, args, file) = info
995 if file != oldfile:
996 classes.write("#\n# Functions from module %s\n#\n\n" % file)
997 txt.write("\n# functions from module %s\n" % file)
998 oldfile = file
999 classes.write("def %s(" % func)
1000 txt.write("%s()\n" % func);
1001 n = 0
1002 for arg in args:
1003 if n != 0:
1004 classes.write(", ")
1005 classes.write("%s" % arg[0])
1006 n = n + 1
1007 classes.write("):\n")
1008 writeDoc(name, args, ' ', classes);
1009
1010 for arg in args:
1011 if classes_type.has_key(arg[1]):
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001012 classes.write(" if %s is None: %s__o = None\n" %
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001013 (arg[0], arg[0]))
1014 classes.write(" else: %s__o = %s%s\n" %
1015 (arg[0], arg[0], classes_type[arg[1]][0]))
1016 if ret[0] != "void":
1017 classes.write(" ret = ");
1018 else:
1019 classes.write(" ");
1020 classes.write("libxml2mod.%s(" % name)
1021 n = 0
1022 for arg in args:
1023 if n != 0:
1024 classes.write(", ");
1025 classes.write("%s" % arg[0])
1026 if classes_type.has_key(arg[1]):
1027 classes.write("__o");
1028 n = n + 1
1029 classes.write(")\n");
1030 if ret[0] != "void":
1031 if classes_type.has_key(ret[0]):
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001032 #
1033 # Raise an exception
1034 #
Daniel Veillardef6c46f2002-03-07 22:21:56 +00001035 if functions_noexcept.has_key(name):
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001036 classes.write(" if ret is None:return None\n");
Daniel Veillardef6c46f2002-03-07 22:21:56 +00001037 elif string.find(name, "URI") >= 0:
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001038 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001039 " if ret is None:raise uriError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001040 % (name))
1041 elif string.find(name, "XPath") >= 0:
1042 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001043 " if ret is None:raise xpathError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001044 % (name))
1045 elif string.find(name, "Parse") >= 0:
1046 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001047 " if ret is None:raise parserError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001048 % (name))
1049 else:
1050 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001051 " if ret is None:raise treeError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001052 % (name))
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001053 classes.write(" return ");
1054 classes.write(classes_type[ret[0]][1] % ("ret"));
1055 classes.write("\n");
1056 else:
1057 classes.write(" return ret\n");
1058 classes.write("\n");
1059
1060 txt.write("\n\n#\n# Set of classes of the module\n#\n\n")
1061 for classname in classes_list:
1062 if classname == "None":
1063 pass
1064 else:
1065 if classes_ancestor.has_key(classname):
1066 txt.write("\n\nClass %s(%s)\n" % (classname,
1067 classes_ancestor[classname]))
1068 classes.write("class %s(%s):\n" % (classname,
1069 classes_ancestor[classname]))
1070 classes.write(" def __init__(self, _obj=None):\n")
William M. Brackc68d78d2004-07-16 10:39:30 +00001071 if classes_ancestor[classname] == "xmlCore" or \
1072 classes_ancestor[classname] == "xmlNode":
1073 classes.write(" if type(_obj).__name__ != ")
1074 classes.write("'PyCObject':\n")
1075 classes.write(" raise TypeError, ")
1076 classes.write("'%s needs a PyCObject argument'\n" % \
1077 classname)
Daniel Veillarddc85f282002-12-31 11:18:37 +00001078 if reference_keepers.has_key(classname):
1079 rlist = reference_keepers[classname]
1080 for ref in rlist:
1081 classes.write(" self.%s = None\n" % ref[1])
Daniel Veillard6cbd6c02003-12-04 12:31:49 +00001082 classes.write(" self._o = _obj\n")
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001083 classes.write(" %s.__init__(self, _obj=_obj)\n\n" % (
1084 classes_ancestor[classname]))
1085 if classes_ancestor[classname] == "xmlCore" or \
1086 classes_ancestor[classname] == "xmlNode":
1087 classes.write(" def __repr__(self):\n")
Daniel Veillardba5e18a2002-03-05 09:36:43 +00001088 format = "<%s (%%s) object at 0x%%x>" % (classname)
1089 classes.write(" return \"%s\" %% (self.name, id (self))\n\n" % (
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001090 format))
1091 else:
1092 txt.write("Class %s()\n" % (classname))
1093 classes.write("class %s:\n" % (classname))
1094 classes.write(" def __init__(self, _obj=None):\n")
Daniel Veillarddc85f282002-12-31 11:18:37 +00001095 if reference_keepers.has_key(classname):
1096 list = reference_keepers[classname]
1097 for ref in list:
1098 classes.write(" self.%s = None\n" % ref[1])
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001099 classes.write(" if _obj != None:self._o = _obj;return\n")
1100 classes.write(" self._o = None\n\n");
Daniel Veillardd69cc812004-07-01 09:36:26 +00001101 destruct=None
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001102 if classes_destructors.has_key(classname):
1103 classes.write(" def __del__(self):\n")
1104 classes.write(" if self._o != None:\n")
1105 classes.write(" libxml2mod.%s(self._o)\n" %
1106 classes_destructors[classname]);
1107 classes.write(" self._o = None\n\n");
Daniel Veillardd69cc812004-07-01 09:36:26 +00001108 destruct=classes_destructors[classname]
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001109 flist = function_classes[classname]
1110 flist.sort(functionCompare)
1111 oldfile = ""
1112 for info in flist:
1113 (index, func, name, ret, args, file) = info
Daniel Veillardd69cc812004-07-01 09:36:26 +00001114 #
1115 # Do not provide as method the destructors for the class
1116 # to avoid double free
1117 #
1118 if name == destruct:
1119 continue;
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001120 if file != oldfile:
1121 if file == "python_accessor":
1122 classes.write(" # accessors for %s\n" % (classname))
1123 txt.write(" # accessors\n")
1124 else:
1125 classes.write(" #\n")
1126 classes.write(" # %s functions from module %s\n" % (
1127 classname, file))
1128 txt.write("\n # functions from module %s\n" % file)
1129 classes.write(" #\n\n")
1130 oldfile = file
1131 classes.write(" def %s(self" % func)
1132 txt.write(" %s()\n" % func);
1133 n = 0
1134 for arg in args:
1135 if n != index:
1136 classes.write(", %s" % arg[0])
1137 n = n + 1
1138 classes.write("):\n")
1139 writeDoc(name, args, ' ', classes);
1140 n = 0
1141 for arg in args:
1142 if classes_type.has_key(arg[1]):
1143 if n != index:
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001144 classes.write(" if %s is None: %s__o = None\n" %
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001145 (arg[0], arg[0]))
1146 classes.write(" else: %s__o = %s%s\n" %
1147 (arg[0], arg[0], classes_type[arg[1]][0]))
1148 n = n + 1
1149 if ret[0] != "void":
1150 classes.write(" ret = ");
1151 else:
1152 classes.write(" ");
1153 classes.write("libxml2mod.%s(" % name)
1154 n = 0
1155 for arg in args:
1156 if n != 0:
1157 classes.write(", ");
1158 if n != index:
1159 classes.write("%s" % arg[0])
1160 if classes_type.has_key(arg[1]):
1161 classes.write("__o");
1162 else:
1163 classes.write("self");
1164 if classes_type.has_key(arg[1]):
1165 classes.write(classes_type[arg[1]][0])
1166 n = n + 1
1167 classes.write(")\n");
1168 if ret[0] != "void":
1169 if classes_type.has_key(ret[0]):
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001170 #
1171 # Raise an exception
1172 #
Daniel Veillardef6c46f2002-03-07 22:21:56 +00001173 if functions_noexcept.has_key(name):
1174 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001175 " if ret is None:return None\n");
Daniel Veillardef6c46f2002-03-07 22:21:56 +00001176 elif string.find(name, "URI") >= 0:
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001177 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001178 " if ret is None:raise uriError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001179 % (name))
1180 elif string.find(name, "XPath") >= 0:
1181 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001182 " if ret is None:raise xpathError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001183 % (name))
1184 elif string.find(name, "Parse") >= 0:
1185 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001186 " if ret is None:raise parserError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001187 % (name))
1188 else:
1189 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001190 " if ret is None:raise treeError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001191 % (name))
Daniel Veillarddc85f282002-12-31 11:18:37 +00001192
1193 #
1194 # generate the returned class wrapper for the object
1195 #
1196 classes.write(" __tmp = ");
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001197 classes.write(classes_type[ret[0]][1] % ("ret"));
1198 classes.write("\n");
Daniel Veillarddc85f282002-12-31 11:18:37 +00001199
1200 #
1201 # Sometime one need to keep references of the source
1202 # class in the returned class object.
1203 # See reference_keepers for the list
1204 #
1205 tclass = classes_type[ret[0]][2]
1206 if reference_keepers.has_key(tclass):
1207 list = reference_keepers[tclass]
1208 for pref in list:
Daniel Veillardfebcca42003-02-16 15:44:18 +00001209 if pref[0] == classname:
Daniel Veillarddc85f282002-12-31 11:18:37 +00001210 classes.write(" __tmp.%s = self\n" %
1211 pref[1])
1212 #
1213 # return the class
1214 #
1215 classes.write(" return __tmp\n");
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001216 elif converter_type.has_key(ret[0]):
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001217 #
1218 # Raise an exception
1219 #
Daniel Veillardef6c46f2002-03-07 22:21:56 +00001220 if functions_noexcept.has_key(name):
1221 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001222 " if ret is None:return None");
Daniel Veillardef6c46f2002-03-07 22:21:56 +00001223 elif string.find(name, "URI") >= 0:
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001224 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001225 " if ret is None:raise uriError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001226 % (name))
1227 elif string.find(name, "XPath") >= 0:
1228 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001229 " if ret is None:raise xpathError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001230 % (name))
1231 elif string.find(name, "Parse") >= 0:
1232 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001233 " if ret is None:raise parserError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001234 % (name))
1235 else:
1236 classes.write(
Daniel Veillard6f46f6c2002-08-01 12:22:24 +00001237 " if ret is None:raise treeError('%s() failed')\n"
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001238 % (name))
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001239 classes.write(" return ");
1240 classes.write(converter_type[ret[0]] % ("ret"));
1241 classes.write("\n");
1242 else:
1243 classes.write(" return ret\n");
1244 classes.write("\n");
1245
Daniel Veillard4f4a27f2004-01-14 23:50:34 +00001246 #
1247 # Generate enum constants
1248 #
1249 for type,enum in enums.items():
1250 classes.write("# %s\n" % type)
1251 items = enum.items()
1252 items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1])))
1253 for name,value in items:
1254 classes.write("%s = %s\n" % (name,value))
1255 classes.write("\n");
1256
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001257 txt.close()
1258 classes.close()
1259
Daniel Veillard0fea6f42002-02-22 22:51:13 +00001260buildStubs()
1261buildWrappers()