VirtualBox

source: vbox/trunk/src/libs/libxml2-2.13.2/python/generator.py@ 105681

最後變更 在這個檔案從105681是 105420,由 vboxsync 提交於 4 月 前

libxml2-2.12.6: Applied and adjusted our libxml2 changes to 2.12.6. bugref:10730

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:executable 設為 *
檔案大小: 52.5 KB
 
1#!/usr/bin/env python3
2#
3# generate python wrappers from the XML API description
4#
5
6functions = {}
7enums = {} # { enumType: { enumConstant: enumValue } }
8
9import os
10import sys
11import string
12
13if __name__ == "__main__":
14 # launched as a script
15 srcPref = os.path.dirname(sys.argv[0])
16else:
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#######################################################################
26import os
27import xml.sax
28
29debug = 0
30
31def 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
38class 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 'name' in attrs.keys():
73 self.function = attrs['name']
74 if 'file' in attrs.keys():
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 'name' in attrs.keys():
86 self.function_arg_name = attrs['name']
87 if 'type' in attrs.keys():
88 self.function_arg_type = attrs['type']
89 if 'info' in attrs.keys():
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 'type' in attrs.keys():
97 self.function_return_type = attrs['type']
98 if 'info' in attrs.keys():
99 self.function_return_info = attrs['info']
100 if 'field' in attrs.keys():
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
138def function(name, desc, ret, args, file, cond):
139 functions[name] = (desc, ret, args, file, cond)
140
141def enum(type, name, value):
142 if type not in enums:
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
153skipped_modules = {
154 'xmlmemory': None,
155 'SAX': None,
156 'hash': None,
157 'list': None,
158 'threads': None,
159# 'xpointer': None,
160}
161skipped_types = {
162 'int *': "usually a return type",
163 'xmlSAXHandlerPtr': "not the proper interface for SAX",
164 'htmlSAXHandlerPtr': "not the proper interface for SAX",
165 'xmlRMutexPtr': "thread specific, skipped",
166 'xmlMutexPtr': "thread specific, skipped",
167 'xmlGlobalStatePtr': "thread specific, skipped",
168 'xmlListPtr': "internal representation not suitable for python",
169 'xmlBufferPtr': "internal representation not suitable for python",
170 'FILE *': None,
171}
172
173#######################################################################
174#
175# Table of remapping to/from the python type or class to the C
176# counterpart.
177#
178#######################################################################
179
180py_types = {
181 'void': (None, None, None, None),
182 'int': ('i', None, "int", "int"),
183 'long': ('l', None, "long", "long"),
184 'double': ('d', None, "double", "double"),
185 'unsigned int': ('i', None, "int", "int"),
186 'xmlChar': ('c', None, "int", "int"),
187 'unsigned char *': ('z', None, "charPtr", "char *"),
188 'char *': ('z', None, "charPtr", "char *"),
189 'const char *': ('z', None, "charPtrConst", "const char *"),
190 'xmlChar *': ('z', None, "xmlCharPtr", "xmlChar *"),
191 'const xmlChar *': ('z', None, "xmlCharPtrConst", "const xmlChar *"),
192 'xmlNodePtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
193 'const xmlNodePtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
194 'xmlNode *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
195 'const xmlNode *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
196 'xmlDtdPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
197 'const xmlDtdPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
198 'xmlDtd *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
199 'const xmlDtd *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
200 'xmlAttrPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
201 'const xmlAttrPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
202 'xmlAttr *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
203 'const xmlAttr *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
204 'xmlEntityPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
205 'const xmlEntityPtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
206 'xmlEntity *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
207 'const xmlEntity *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
208 'xmlElementPtr': ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
209 'const xmlElementPtr': ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
210 'xmlElement *': ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
211 'const xmlElement *': ('O', "xmlElement", "xmlElementPtr", "xmlElementPtr"),
212 'xmlAttributePtr': ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
213 'const xmlAttributePtr': ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
214 'xmlAttribute *': ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
215 'const xmlAttribute *': ('O', "xmlAttribute", "xmlAttributePtr", "xmlAttributePtr"),
216 'xmlNsPtr': ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
217 'const xmlNsPtr': ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
218 'xmlNs *': ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
219 'const xmlNs *': ('O', "xmlNode", "xmlNsPtr", "xmlNsPtr"),
220 'xmlDocPtr': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
221 'const xmlDocPtr': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
222 'xmlDoc *': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
223 'const xmlDoc *': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
224 'htmlDocPtr': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
225 'const htmlDocPtr': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
226 'htmlDoc *': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
227 'const htmlDoc *': ('O', "xmlNode", "xmlDocPtr", "xmlDocPtr"),
228 'htmlNodePtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
229 'const htmlNodePtr': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
230 'htmlNode *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
231 'const htmlNode *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
232 'xmlXPathContextPtr': ('O', "xmlXPathContext", "xmlXPathContextPtr", "xmlXPathContextPtr"),
233 'xmlXPathContext *': ('O', "xpathContext", "xmlXPathContextPtr", "xmlXPathContextPtr"),
234 'xmlXPathParserContextPtr': ('O', "xmlXPathParserContext", "xmlXPathParserContextPtr", "xmlXPathParserContextPtr"),
235 'xmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
236 'xmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
237 'htmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
238 'htmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
239 'xmlValidCtxtPtr': ('O', "ValidCtxt", "xmlValidCtxtPtr", "xmlValidCtxtPtr"),
240 'xmlCatalogPtr': ('O', "catalog", "xmlCatalogPtr", "xmlCatalogPtr"),
241 'FILE *': ('O', "File", "FILEPtr", "FILE *"),
242 'xmlURIPtr': ('O', "URI", "xmlURIPtr", "xmlURIPtr"),
243 'const xmlError *': ('O', "Error", "xmlErrorPtr", "const xmlError *"),
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
258py_return_types = {
259 'xmlXPathObjectPtr': ('O', "foo", "xmlXPathObjectPtr", "xmlXPathObjectPtr"),
260}
261
262unknown_types = {}
263
264foreign_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()).
287skip_impl = (
288 'xmlSaveFileTo',
289 'xmlSaveFormatFileTo',
290)
291
292deprecated_funcs = {
293 'htmlDefaultSAXHandlerInit': True,
294 'htmlHandleOmittedElem': True,
295 'htmlInitAutoClose': True,
296 'htmlParseCharRef': True,
297 'htmlParseElement': True,
298 'namePop': True,
299 'namePush': True,
300 'nodePop': True,
301 'nodePush': True,
302 'xmlCheckFilename': True,
303 'xmlCheckLanguageID': True,
304 'xmlCleanupCharEncodingHandlers': True,
305 'xmlCleanupGlobals': True,
306 'xmlDefaultSAXHandlerInit': True,
307 'xmlDecodeEntities': True,
308 'xmlDictCleanup': True,
309 'xmlEncodeEntities': True,
310 'xmlFileMatch': True,
311 'xmlGetCompressMode': True,
312 'xmlHandleEntity': True,
313 'xmlInitCharEncodingHandlers': True,
314 'xmlInitGlobals': True,
315 'xmlInitializeDict': True,
316 'xmlInitializePredefinedEntities': True,
317 'xmlIOFTPMatch': True,
318 'xmlIOHTTPMatch': True,
319 'xmlIsRef': True,
320 'xmlKeepBlanksDefault': True,
321 'xmlLineNumbersDefault': True,
322 'xmlNamespaceParseNCName': True,
323 'xmlNamespaceParseNSDef': True,
324 'xmlNanoFTPCleanup': True,
325 'xmlNanoFTPInit': True,
326 'xmlNanoFTPProxy': True,
327 'xmlNanoFTPScanProxy': True,
328 'xmlNanoHTTPCleanup': True,
329 'xmlNanoHTTPInit': True,
330 'xmlNanoHTTPScanProxy': True,
331 'xmlNewGlobalNs': True,
332 'xmlNextChar': True,
333 'xmlNormalizeWindowsPath': True,
334 'xmlParseAttValue': True,
335 'xmlParseAttributeListDecl': True,
336 'xmlParseCDSect': True,
337 'xmlParseCharData': True,
338 'xmlParseCharRef': True,
339 'xmlParseComment': True,
340 'xmlParseDocTypeDecl': True,
341 'xmlParseElement': True,
342 'xmlParseElementDecl': True,
343 'xmlParseEncName': True,
344 'xmlParseEncodingDecl': True,
345 'xmlParseEndTag': True,
346 'xmlParseEntity': True,
347 'xmlParseEntityDecl': True,
348 'xmlParseEntityRef': True,
349 'xmlParseMarkupDecl': True,
350 'xmlParseMisc': True,
351 'xmlParseName': True,
352 'xmlParseNamespace': True,
353 'xmlParseNmtoken': True,
354 'xmlParseNotationDecl': True,
355 'xmlParsePEReference': True,
356 'xmlParsePI': True,
357 'xmlParsePITarget': True,
358 'xmlParsePubidLiteral': True,
359 'xmlParseQuotedString': True,
360 'xmlParseReference': True,
361 'xmlParseSDDecl': True,
362 'xmlParseStartTag': True,
363 'xmlParseSystemLiteral': True,
364 'xmlParseTextDecl': True,
365 'xmlParseVersionInfo': True,
366 'xmlParseVersionNum': True,
367 'xmlParseXMLDecl': True,
368 'xmlParserHandlePEReference': True,
369 'xmlParserHandleReference': True,
370 'xmlPedanticParserDefault': True,
371 'xmlRecoverDoc': True,
372 'xmlRecoverFile': True,
373 'xmlRecoverMemory': True,
374 'xmlRegisterHTTPPostCallbacks': True,
375 'xmlRelaxNGCleanupTypes': True,
376 'xmlRelaxNGInitTypes': True,
377 'xmlRemoveRef': True,
378 'xmlSAXDefaultVersion': True,
379 'xmlScanName': True,
380 'xmlSchemaCleanupTypes': True,
381 'xmlSchemaInitTypes': True,
382 'xmlSetCompressMode': True,
383 'xmlSetupParserForBuffer': True,
384 'xmlSkipBlankChars': True,
385 'xmlStringDecodeEntities': True,
386 'xmlStringLenDecodeEntities': True,
387 'xmlSubstituteEntitiesDefault': True,
388 'xmlThrDefDefaultBufferSize': True,
389 'xmlThrDefDoValidityCheckingDefaultValue': True,
390 'xmlThrDefGetWarningsDefaultValue': True,
391 'xmlThrDefIndentTreeOutput': True,
392 'xmlThrDefKeepBlanksDefaultValue': True,
393 'xmlThrDefLineNumbersDefaultValue': True,
394 'xmlThrDefLoadExtDtdDefaultValue': True,
395 'xmlThrDefParserDebugEntities': True,
396 'xmlThrDefPedanticParserDefaultValue': True,
397 'xmlThrDefSaveNoEmptyTags': True,
398 'xmlThrDefSubstituteEntitiesDefaultValue': True,
399 'xmlThrDefTreeIndentString': True,
400 'xmlValidCtxtNormalizeAttributeValue': True,
401 'xmlValidNormalizeAttributeValue': True,
402 'xmlValidateAttributeValue': True,
403 'xmlValidateDocumentFinal': True,
404 'xmlValidateDtdFinal': True,
405 'xmlValidateNotationUse': True,
406 'xmlValidateOneAttribute': True,
407 'xmlValidateOneElement': True,
408 'xmlValidateOneNamespace': True,
409 'xmlValidatePopElement': True,
410 'xmlValidatePushCData': True,
411 'xmlValidatePushElement': True,
412 'xmlValidateRoot': True,
413 'xmlValidate': True,
414 'xmlXPathInit': True,
415 'xmlXPtrEvalRangePredicate': True,
416 'xmlXPtrNewCollapsedRange': True,
417 'xmlXPtrNewLocationSetNodes': True,
418 'xmlXPtrNewRange': True,
419 'xmlXPtrNewRangeNodes': True,
420 'xmlXPtrRangeToFunction': True,
421}
422
423def skip_function(name):
424 if name[0:12] == "xmlXPathWrap":
425 return 1
426 if name == "xmlFreeParserCtxt":
427 return 1
428 if name == "xmlCleanupParser":
429 return 1
430 if name == "xmlFreeTextReader":
431 return 1
432# if name[0:11] == "xmlXPathNew":
433# return 1
434 # the next function is defined in libxml.c
435 if name == "xmlRelaxNGFreeValidCtxt":
436 return 1
437 if name == "xmlFreeValidCtxt":
438 return 1
439 if name == "xmlSchemaFreeValidCtxt":
440 return 1
441
442#
443# Those are skipped because the Const version is used of the bindings
444# instead.
445#
446 if name == "xmlTextReaderBaseUri":
447 return 1
448 if name == "xmlTextReaderLocalName":
449 return 1
450 if name == "xmlTextReaderName":
451 return 1
452 if name == "xmlTextReaderNamespaceUri":
453 return 1
454 if name == "xmlTextReaderPrefix":
455 return 1
456 if name == "xmlTextReaderXmlLang":
457 return 1
458 if name == "xmlTextReaderValue":
459 return 1
460 if name == "xmlOutputBufferClose": # handled by by the superclass
461 return 1
462 if name == "xmlOutputBufferFlush": # handled by by the superclass
463 return 1
464 if name == "xmlErrMemory":
465 return 1
466
467 if name == "xmlValidBuildContentModel":
468 return 1
469 if name == "xmlValidateElementDecl":
470 return 1
471 if name == "xmlValidateAttributeDecl":
472 return 1
473 if name == "xmlPopInputCallbacks":
474 return 1
475
476 return 0
477
478def print_function_wrapper(name, output, export, include):
479 global py_types
480 global unknown_types
481 global functions
482 global skipped_modules
483
484 try:
485 (desc, ret, args, file, cond) = functions[name]
486 except:
487 print("failed to get function %s infos")
488 return
489
490 if file in skipped_modules:
491 return 0
492 if skip_function(name) == 1:
493 return 0
494 if name in skip_impl:
495 # Don't delete the function entry in the caller.
496 return 1
497
498 if name.startswith('xmlUCSIs'):
499 is_deprecated = name != 'xmlUCSIsBlock' and name != 'xmlUCSIsCat'
500 else:
501 is_deprecated = name in deprecated_funcs
502
503 c_call = ""
504 format=""
505 format_args=""
506 c_args=""
507 c_return=""
508 c_convert=""
509 c_release=""
510 num_bufs=0
511 for arg in args:
512 # This should be correct
513 if arg[1][0:6] == "const ":
514 arg[1] = arg[1][6:]
515 c_args = c_args + " %s %s;\n" % (arg[1], arg[0])
516 if arg[1] in py_types:
517 (f, t, n, c) = py_types[arg[1]]
518 if (f == 'z') and (name in foreign_encoding_args) and (num_bufs == 0):
519 f = 's#'
520 if f != None:
521 format = format + f
522 if t != None:
523 format_args = format_args + ", &pyobj_%s" % (arg[0])
524 c_args = c_args + " PyObject *pyobj_%s;\n" % (arg[0])
525 c_convert = c_convert + \
526 " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg[0],
527 arg[1], t, arg[0])
528 else:
529 format_args = format_args + ", &%s" % (arg[0])
530 if f == 's#':
531 format_args = format_args + ", &py_buffsize%d" % num_bufs
532 c_args = c_args + " Py_ssize_t py_buffsize%d;\n" % num_bufs
533 num_bufs = num_bufs + 1
534 if c_call != "":
535 c_call = c_call + ", "
536 c_call = c_call + "%s" % (arg[0])
537 if t == "File":
538 c_release = c_release + \
539 " PyFile_Release(%s);\n" % (arg[0])
540 else:
541 if arg[1] in skipped_types:
542 return 0
543 if arg[1] in unknown_types:
544 lst = unknown_types[arg[1]]
545 lst.append(name)
546 else:
547 unknown_types[arg[1]] = [name]
548 return -1
549 if format != "":
550 format = format + ":%s" % (name)
551
552 if ret[0] == 'void':
553 if file == "python_accessor":
554 if args[1][1] == "char *" or args[1][1] == "xmlChar *":
555 c_call = "\n if (%s->%s != NULL) xmlFree(%s->%s);\n" % (
556 args[0][0], args[1][0], args[0][0], args[1][0])
557 c_call = c_call + " %s->%s = (%s)xmlStrdup((const xmlChar *)%s);\n" % (args[0][0],
558 args[1][0], args[1][1], args[1][0])
559 else:
560 c_call = "\n %s->%s = %s;\n" % (args[0][0], args[1][0],
561 args[1][0])
562 else:
563 c_call = "\n %s(%s);\n" % (name, c_call)
564 ret_convert = " Py_INCREF(Py_None);\n return(Py_None);\n"
565 elif ret[0] in py_types:
566 (f, t, n, c) = py_types[ret[0]]
567 c_return = c_return + " %s c_retval;\n" % (ret[0])
568 if file == "python_accessor" and ret[2] != None:
569 c_call = "\n c_retval = %s->%s;\n" % (args[0][0], ret[2])
570 else:
571 c_call = "\n c_retval = %s(%s);\n" % (name, c_call)
572 ret_convert = " py_retval = libxml_%sWrap((%s) c_retval);\n" % (n,c)
573 ret_convert = ret_convert + " return(py_retval);\n"
574 elif ret[0] in py_return_types:
575 (f, t, n, c) = py_return_types[ret[0]]
576 c_return = c_return + " %s c_retval;\n" % (ret[0])
577 c_call = "\n c_retval = %s(%s);\n" % (name, c_call)
578 ret_convert = " py_retval = libxml_%sWrap((%s) c_retval);\n" % (n,c)
579 ret_convert = ret_convert + " return(py_retval);\n"
580 else:
581 if ret[0] in skipped_types:
582 return 0
583 if ret[0] in unknown_types:
584 lst = unknown_types[ret[0]]
585 lst.append(name)
586 else:
587 unknown_types[ret[0]] = [name]
588 return -1
589
590 if cond != None and cond != "":
591 include.write("#if %s\n" % cond)
592 export.write("#if %s\n" % cond)
593 output.write("#if %s\n" % cond)
594
595 include.write("PyObject * ")
596 include.write("libxml_%s(PyObject *self, PyObject *args);\n" % (name))
597
598 export.write(" { (char *)\"%s\", libxml_%s, METH_VARARGS, NULL },\n" %
599 (name, name))
600
601 if file == "python":
602 # Those have been manually generated
603 if cond != None and cond != "":
604 include.write("#endif\n")
605 export.write("#endif\n")
606 output.write("#endif\n")
607 return 1
608 if file == "python_accessor" and ret[0] != "void" and ret[2] is None:
609 # Those have been manually generated
610 if cond != None and cond != "":
611 include.write("#endif\n")
612 export.write("#endif\n")
613 output.write("#endif\n")
614 return 1
615
616 if is_deprecated:
617 output.write("XML_IGNORE_DEPRECATION_WARNINGS\n")
618 output.write("PyObject *\n")
619 output.write("libxml_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
620 output.write(" PyObject *args")
621 if format == "":
622 output.write(" ATTRIBUTE_UNUSED")
623 output.write(") {\n")
624 if ret[0] != 'void':
625 output.write(" PyObject *py_retval;\n")
626 if c_return != "":
627 output.write(c_return)
628 if c_args != "":
629 output.write(c_args)
630 if is_deprecated:
631 output.write("\n if (libxml_deprecationWarning(\"%s\") == -1)\n" %
632 name)
633 output.write(" return(NULL);\n")
634 if format != "":
635 output.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
636 (format, format_args))
637 output.write(" return(NULL);\n")
638 if c_convert != "":
639 output.write(c_convert)
640
641 output.write(c_call)
642 if c_release != "":
643 output.write(c_release)
644 output.write(ret_convert)
645 output.write("}\n")
646 if is_deprecated:
647 output.write("XML_POP_WARNINGS\n")
648 output.write("\n")
649
650 if cond != None and cond != "":
651 include.write("#endif /* %s */\n" % cond)
652 export.write("#endif /* %s */\n" % cond)
653 output.write("#endif /* %s */\n" % cond)
654 return 1
655
656def buildStubs():
657 global py_types
658 global py_return_types
659 global unknown_types
660
661 try:
662 f = open(os.path.join(srcPref,"libxml2-api.xml"))
663 data = f.read()
664 (parser, target) = getparser()
665 parser.feed(data)
666 parser.close()
667 except IOError as msg:
668 try:
669 f = open(os.path.join(srcPref,"..","doc","libxml2-api.xml"))
670 data = f.read()
671 (parser, target) = getparser()
672 parser.feed(data)
673 parser.close()
674 except IOError as msg:
675 print(file, ":", msg)
676 sys.exit(1)
677
678 n = len(list(functions.keys()))
679 print("Found %d functions in libxml2-api.xml" % (n))
680
681 py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
682 try:
683 f = open(os.path.join(srcPref,"libxml2-python-api.xml"))
684 data = f.read()
685 (parser, target) = getparser()
686 parser.feed(data)
687 parser.close()
688 except IOError as msg:
689 print(file, ":", msg)
690
691
692 print("Found %d functions in libxml2-python-api.xml" % (
693 len(list(functions.keys())) - n))
694 nb_wrap = 0
695 failed = 0
696 skipped = 0
697
698 include = open("libxml2-py.h", "w")
699 include.write("/* Generated */\n\n")
700 export = open("libxml2-export.c", "w")
701 export.write("/* Generated */\n\n")
702 wrapper = open("libxml2-py.c", "w")
703 wrapper.write("/* Generated */\n\n")
704 wrapper.write("#define PY_SSIZE_T_CLEAN\n")
705 wrapper.write("#include <Python.h>\n")
706 wrapper.write("#include <libxml/xmlversion.h>\n")
707 wrapper.write("#include <libxml/tree.h>\n")
708 wrapper.write("#include <libxml/xmlschemastypes.h>\n")
709 wrapper.write("#include \"libxml_wrap.h\"\n")
710 wrapper.write("#include \"libxml2-py.h\"\n\n")
711 for function in sorted(functions.keys()):
712 ret = print_function_wrapper(function, wrapper, export, include)
713 if ret < 0:
714 failed = failed + 1
715 del functions[function]
716 if ret == 0:
717 skipped = skipped + 1
718 del functions[function]
719 if ret == 1:
720 nb_wrap = nb_wrap + 1
721 include.close()
722 export.close()
723 wrapper.close()
724
725 print("Generated %d wrapper functions, %d failed, %d skipped" % (nb_wrap,
726 failed, skipped))
727# print("Missing type converters: ")
728# for type in list(unknown_types.keys()):
729# print("%s:%d " % (type, len(unknown_types[type])))
730# print()
731
732#######################################################################
733#
734# This part writes part of the Python front-end classes based on
735# mapping rules between types and classes and also based on function
736# renaming to get consistent function names at the Python level
737#
738#######################################################################
739
740#
741# The type automatically remapped to generated classes
742#
743classes_type = {
744 "xmlNodePtr": ("._o", "xmlNode(_obj=%s)", "xmlNode"),
745 "xmlNode *": ("._o", "xmlNode(_obj=%s)", "xmlNode"),
746 "xmlDocPtr": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
747 "xmlDoc *": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
748 "htmlDocPtr": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
749 "htmlxmlDocPtr *": ("._o", "xmlDoc(_obj=%s)", "xmlDoc"),
750 "xmlAttrPtr": ("._o", "xmlAttr(_obj=%s)", "xmlAttr"),
751 "xmlAttr *": ("._o", "xmlAttr(_obj=%s)", "xmlAttr"),
752 "xmlNsPtr": ("._o", "xmlNs(_obj=%s)", "xmlNs"),
753 "xmlNs *": ("._o", "xmlNs(_obj=%s)", "xmlNs"),
754 "xmlDtdPtr": ("._o", "xmlDtd(_obj=%s)", "xmlDtd"),
755 "xmlDtd *": ("._o", "xmlDtd(_obj=%s)", "xmlDtd"),
756 "xmlEntityPtr": ("._o", "xmlEntity(_obj=%s)", "xmlEntity"),
757 "xmlEntity *": ("._o", "xmlEntity(_obj=%s)", "xmlEntity"),
758 "xmlElementPtr": ("._o", "xmlElement(_obj=%s)", "xmlElement"),
759 "xmlElement *": ("._o", "xmlElement(_obj=%s)", "xmlElement"),
760 "xmlAttributePtr": ("._o", "xmlAttribute(_obj=%s)", "xmlAttribute"),
761 "xmlAttribute *": ("._o", "xmlAttribute(_obj=%s)", "xmlAttribute"),
762 "xmlXPathContextPtr": ("._o", "xpathContext(_obj=%s)", "xpathContext"),
763 "xmlXPathContext *": ("._o", "xpathContext(_obj=%s)", "xpathContext"),
764 "xmlXPathParserContext *": ("._o", "xpathParserContext(_obj=%s)", "xpathParserContext"),
765 "xmlXPathParserContextPtr": ("._o", "xpathParserContext(_obj=%s)", "xpathParserContext"),
766 "xmlParserCtxtPtr": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
767 "xmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
768 "htmlParserCtxtPtr": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
769 "htmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
770 "xmlValidCtxtPtr": ("._o", "ValidCtxt(_obj=%s)", "ValidCtxt"),
771 "xmlCatalogPtr": ("._o", "catalog(_obj=%s)", "catalog"),
772 "xmlURIPtr": ("._o", "URI(_obj=%s)", "URI"),
773 "const xmlError *": ("._o", "Error(_obj=%s)", "Error"),
774 "xmlErrorPtr": ("._o", "Error(_obj=%s)", "Error"),
775 "xmlOutputBufferPtr": ("._o", "outputBuffer(_obj=%s)", "outputBuffer"),
776 "xmlParserInputBufferPtr": ("._o", "inputBuffer(_obj=%s)", "inputBuffer"),
777 "xmlRegexpPtr": ("._o", "xmlReg(_obj=%s)", "xmlReg"),
778 "xmlTextReaderLocatorPtr": ("._o", "xmlTextReaderLocator(_obj=%s)", "xmlTextReaderLocator"),
779 "xmlTextReaderPtr": ("._o", "xmlTextReader(_obj=%s)", "xmlTextReader"),
780 'xmlRelaxNGPtr': ('._o', "relaxNgSchema(_obj=%s)", "relaxNgSchema"),
781 'xmlRelaxNGParserCtxtPtr': ('._o', "relaxNgParserCtxt(_obj=%s)", "relaxNgParserCtxt"),
782 'xmlRelaxNGValidCtxtPtr': ('._o', "relaxNgValidCtxt(_obj=%s)", "relaxNgValidCtxt"),
783 'xmlSchemaPtr': ("._o", "Schema(_obj=%s)", "Schema"),
784 'xmlSchemaParserCtxtPtr': ("._o", "SchemaParserCtxt(_obj=%s)", "SchemaParserCtxt"),
785 'xmlSchemaValidCtxtPtr': ("._o", "SchemaValidCtxt(_obj=%s)", "SchemaValidCtxt"),
786}
787
788converter_type = {
789 "xmlXPathObjectPtr": "xpathObjectRet(%s)",
790}
791
792primary_classes = ["xmlNode", "xmlDoc"]
793
794classes_ancestor = {
795 "xmlNode" : "xmlCore",
796 "xmlDtd" : "xmlNode",
797 "xmlDoc" : "xmlNode",
798 "xmlAttr" : "xmlNode",
799 "xmlNs" : "xmlNode",
800 "xmlEntity" : "xmlNode",
801 "xmlElement" : "xmlNode",
802 "xmlAttribute" : "xmlNode",
803 "outputBuffer": "ioWriteWrapper",
804 "inputBuffer": "ioReadWrapper",
805 "parserCtxt": "parserCtxtCore",
806 "xmlTextReader": "xmlTextReaderCore",
807 "ValidCtxt": "ValidCtxtCore",
808 "SchemaValidCtxt": "SchemaValidCtxtCore",
809 "relaxNgValidCtxt": "relaxNgValidCtxtCore",
810}
811classes_destructors = {
812 "parserCtxt": "xmlFreeParserCtxt",
813 "catalog": "xmlFreeCatalog",
814 "URI": "xmlFreeURI",
815# "outputBuffer": "xmlOutputBufferClose",
816 "inputBuffer": "xmlFreeParserInputBuffer",
817 "xmlReg": "xmlRegFreeRegexp",
818 "xmlTextReader": "xmlFreeTextReader",
819 "relaxNgSchema": "xmlRelaxNGFree",
820 "relaxNgParserCtxt": "xmlRelaxNGFreeParserCtxt",
821 "relaxNgValidCtxt": "xmlRelaxNGFreeValidCtxt",
822 "Schema": "xmlSchemaFree",
823 "SchemaParserCtxt": "xmlSchemaFreeParserCtxt",
824 "SchemaValidCtxt": "xmlSchemaFreeValidCtxt",
825 "ValidCtxt": "xmlFreeValidCtxt",
826}
827
828functions_noexcept = {
829 "xmlHasProp": 1,
830 "xmlHasNsProp": 1,
831 "xmlDocSetRootElement": 1,
832 "xmlNodeGetNs": 1,
833 "xmlNodeGetNsDefs": 1,
834 "xmlNextElementSibling": 1,
835 "xmlPreviousElementSibling": 1,
836 "xmlFirstElementChild": 1,
837 "xmlLastElementChild": 1,
838}
839
840reference_keepers = {
841 "xmlTextReader": [('inputBuffer', 'input')],
842 "relaxNgValidCtxt": [('relaxNgSchema', 'schema')],
843 "SchemaValidCtxt": [('Schema', 'schema')],
844}
845
846function_classes = {}
847
848function_classes["None"] = []
849
850def nameFixup(name, classe, type, file):
851 listname = classe + "List"
852 ll = len(listname)
853 l = len(classe)
854 if name[0:l] == listname:
855 func = name[l:]
856 func = func[0:1].lower() + func[1:]
857 elif name[0:12] == "xmlParserGet" and file == "python_accessor":
858 func = name[12:]
859 func = func[0:1].lower() + func[1:]
860 elif name[0:12] == "xmlParserSet" and file == "python_accessor":
861 func = name[12:]
862 func = func[0:1].lower() + func[1:]
863 elif name[0:10] == "xmlNodeGet" and file == "python_accessor":
864 func = name[10:]
865 func = func[0:1].lower() + func[1:]
866 elif name[0:9] == "xmlURIGet" and file == "python_accessor":
867 func = name[9:]
868 func = func[0:1].lower() + func[1:]
869 elif name[0:9] == "xmlURISet" and file == "python_accessor":
870 func = name[6:]
871 func = func[0:1].lower() + func[1:]
872 elif name[0:11] == "xmlErrorGet" and file == "python_accessor":
873 func = name[11:]
874 func = func[0:1].lower() + func[1:]
875 elif name[0:17] == "xmlXPathParserGet" and file == "python_accessor":
876 func = name[17:]
877 func = func[0:1].lower() + func[1:]
878 elif name[0:11] == "xmlXPathGet" and file == "python_accessor":
879 func = name[11:]
880 func = func[0:1].lower() + func[1:]
881 elif name[0:11] == "xmlXPathSet" and file == "python_accessor":
882 func = name[8:]
883 func = func[0:1].lower() + func[1:]
884 elif name[0:15] == "xmlOutputBuffer" and file != "python":
885 func = name[15:]
886 func = func[0:1].lower() + func[1:]
887 elif name[0:20] == "xmlParserInputBuffer" and file != "python":
888 func = name[20:]
889 func = func[0:1].lower() + func[1:]
890 elif name[0:9] == "xmlRegexp" and file == "xmlregexp":
891 func = "regexp" + name[9:]
892 elif name[0:6] == "xmlReg" and file == "xmlregexp":
893 func = "regexp" + name[6:]
894 elif name[0:20] == "xmlTextReaderLocator" and file == "xmlreader":
895 func = name[20:]
896 elif name[0:18] == "xmlTextReaderConst" and file == "xmlreader":
897 func = name[18:]
898 elif name[0:13] == "xmlTextReader" and file == "xmlreader":
899 func = name[13:]
900 elif name[0:12] == "xmlReaderNew" and file == "xmlreader":
901 func = name[9:]
902 elif name[0:11] == "xmlACatalog":
903 func = name[11:]
904 func = func[0:1].lower() + func[1:]
905 elif name[0:l] == classe:
906 func = name[l:]
907 func = func[0:1].lower() + func[1:]
908 elif name[0:7] == "libxml_":
909 func = name[7:]
910 func = func[0:1].lower() + func[1:]
911 elif name[0:6] == "xmlGet":
912 func = name[6:]
913 func = func[0:1].lower() + func[1:]
914 elif name[0:3] == "xml":
915 func = name[3:]
916 func = func[0:1].lower() + func[1:]
917 else:
918 func = name
919 if func[0:5] == "xPath":
920 func = "xpath" + func[5:]
921 elif func[0:4] == "xPtr":
922 func = "xpointer" + func[4:]
923 elif func[0:8] == "xInclude":
924 func = "xinclude" + func[8:]
925 elif func[0:2] == "iD":
926 func = "ID" + func[2:]
927 elif func[0:3] == "uRI":
928 func = "URI" + func[3:]
929 elif func[0:4] == "uTF8":
930 func = "UTF8" + func[4:]
931 elif func[0:3] == 'sAX':
932 func = "SAX" + func[3:]
933 return func
934
935
936def functionCompare(info1, info2):
937 (index1, func1, name1, ret1, args1, file1) = info1
938 (index2, func2, name2, ret2, args2, file2) = info2
939 if file1 == file2:
940 if func1 < func2:
941 return -1
942 if func1 > func2:
943 return 1
944 if file1 == "python_accessor":
945 return -1
946 if file2 == "python_accessor":
947 return 1
948 if file1 < file2:
949 return -1
950 if file1 > file2:
951 return 1
952 return 0
953
954def cmp_to_key(mycmp):
955 'Convert a cmp= function into a key= function'
956 class K(object):
957 def __init__(self, obj, *args):
958 self.obj = obj
959 def __lt__(self, other):
960 return mycmp(self.obj, other.obj) < 0
961 def __gt__(self, other):
962 return mycmp(self.obj, other.obj) > 0
963 def __eq__(self, other):
964 return mycmp(self.obj, other.obj) == 0
965 def __le__(self, other):
966 return mycmp(self.obj, other.obj) <= 0
967 def __ge__(self, other):
968 return mycmp(self.obj, other.obj) >= 0
969 def __ne__(self, other):
970 return mycmp(self.obj, other.obj) != 0
971 return K
972def writeDoc(name, args, indent, output):
973 if functions[name][0] is None or functions[name][0] == "":
974 return
975 val = functions[name][0]
976 val = val.replace("NULL", "None")
977 output.write(indent)
978 output.write('"""')
979 while len(val) > 60:
980 if val[0] == " ":
981 val = val[1:]
982 continue
983 str = val[0:60]
984 i = str.rfind(" ")
985 if i < 0:
986 i = 60
987 str = val[0:i]
988 val = val[i:]
989 output.write(str)
990 output.write('\n ')
991 output.write(indent)
992 output.write(val)
993 output.write(' """\n')
994
995def buildWrappers():
996 global ctypes
997 global py_types
998 global py_return_types
999 global unknown_types
1000 global functions
1001 global function_classes
1002 global classes_type
1003 global classes_list
1004 global converter_type
1005 global primary_classes
1006 global converter_type
1007 global classes_ancestor
1008 global converter_type
1009 global primary_classes
1010 global classes_ancestor
1011 global classes_destructors
1012 global functions_noexcept
1013
1014 for type in classes_type.keys():
1015 function_classes[classes_type[type][2]] = []
1016
1017 #
1018 # Build the list of C types to look for ordered to start
1019 # with primary classes
1020 #
1021 ctypes = []
1022 classes_list = []
1023 ctypes_processed = {}
1024 classes_processed = {}
1025 for classe in primary_classes:
1026 classes_list.append(classe)
1027 classes_processed[classe] = ()
1028 for type in classes_type.keys():
1029 tinfo = classes_type[type]
1030 if tinfo[2] == classe:
1031 ctypes.append(type)
1032 ctypes_processed[type] = ()
1033 for type in sorted(classes_type.keys()):
1034 if type in ctypes_processed:
1035 continue
1036 tinfo = classes_type[type]
1037 if tinfo[2] not in classes_processed:
1038 classes_list.append(tinfo[2])
1039 classes_processed[tinfo[2]] = ()
1040
1041 ctypes.append(type)
1042 ctypes_processed[type] = ()
1043
1044 for name in functions.keys():
1045 found = 0
1046 (desc, ret, args, file, cond) = functions[name]
1047 for type in ctypes:
1048 classe = classes_type[type][2]
1049
1050 if name[0:3] == "xml" and len(args) >= 1 and args[0][1] == type:
1051 found = 1
1052 func = nameFixup(name, classe, type, file)
1053 info = (0, func, name, ret, args, file)
1054 function_classes[classe].append(info)
1055 elif name[0:3] == "xml" and len(args) >= 2 and args[1][1] == type \
1056 and file != "python_accessor":
1057 found = 1
1058 func = nameFixup(name, classe, type, file)
1059 info = (1, func, name, ret, args, file)
1060 function_classes[classe].append(info)
1061 elif name[0:4] == "html" and len(args) >= 1 and args[0][1] == type:
1062 found = 1
1063 func = nameFixup(name, classe, type, file)
1064 info = (0, func, name, ret, args, file)
1065 function_classes[classe].append(info)
1066 elif name[0:4] == "html" and len(args) >= 2 and args[1][1] == type \
1067 and file != "python_accessor":
1068 found = 1
1069 func = nameFixup(name, classe, type, file)
1070 info = (1, func, name, ret, args, file)
1071 function_classes[classe].append(info)
1072 if found == 1:
1073 continue
1074 if name[0:8] == "xmlXPath":
1075 continue
1076 if name[0:6] == "xmlStr":
1077 continue
1078 if name[0:10] == "xmlCharStr":
1079 continue
1080 func = nameFixup(name, "None", file, file)
1081 info = (0, func, name, ret, args, file)
1082 function_classes['None'].append(info)
1083
1084 classes = open("libxml2class.py", "w")
1085 txt = open("libxml2class.txt", "w")
1086 txt.write(" Generated Classes for libxml2-python\n\n")
1087
1088 txt.write("#\n# Global functions of the module\n#\n\n")
1089 if "None" in function_classes:
1090 flist = function_classes["None"]
1091 flist = sorted(flist, key=cmp_to_key(functionCompare))
1092 oldfile = ""
1093 for info in flist:
1094 (index, func, name, ret, args, file) = info
1095 if file != oldfile:
1096 classes.write("#\n# Functions from module %s\n#\n\n" % file)
1097 txt.write("\n# functions from module %s\n" % file)
1098 oldfile = file
1099 classes.write("def %s(" % func)
1100 txt.write("%s()\n" % func)
1101 n = 0
1102 for arg in args:
1103 if n != 0:
1104 classes.write(", ")
1105 classes.write("%s" % arg[0])
1106 n = n + 1
1107 classes.write("):\n")
1108 writeDoc(name, args, ' ', classes)
1109
1110 for arg in args:
1111 if arg[1] in classes_type:
1112 classes.write(" if %s is None: %s__o = None\n" %
1113 (arg[0], arg[0]))
1114 classes.write(" else: %s__o = %s%s\n" %
1115 (arg[0], arg[0], classes_type[arg[1]][0]))
1116 if arg[1] in py_types:
1117 (f, t, n, c) = py_types[arg[1]]
1118 if t == "File":
1119 classes.write(" if %s is not None: %s.flush()\n" % (
1120 arg[0], arg[0]))
1121
1122 if ret[0] != "void":
1123 classes.write(" ret = ")
1124 else:
1125 classes.write(" ")
1126 classes.write("libxml2mod.%s(" % name)
1127 n = 0
1128 for arg in args:
1129 if n != 0:
1130 classes.write(", ")
1131 classes.write("%s" % arg[0])
1132 if arg[1] in classes_type:
1133 classes.write("__o")
1134 n = n + 1
1135 classes.write(")\n")
1136
1137# This may be needed to reposition the I/O, but likely to cause more harm
1138# than good. Those changes in Python3 really break the model.
1139# for arg in args:
1140# if arg[1] in py_types:
1141# (f, t, n, c) = py_types[arg[1]]
1142# if t == "File":
1143# classes.write(" if %s is not None: %s.seek(0,0)\n"%(
1144# arg[0], arg[0]))
1145
1146 if ret[0] != "void":
1147 if ret[0] in classes_type:
1148 #
1149 # Raise an exception
1150 #
1151 if name in functions_noexcept:
1152 classes.write(" if ret is None:return None\n")
1153 elif name.find("URI") >= 0:
1154 classes.write(
1155 " if ret is None:raise uriError('%s() failed')\n"
1156 % (name))
1157 elif name.find("XPath") >= 0:
1158 classes.write(
1159 " if ret is None:raise xpathError('%s() failed')\n"
1160 % (name))
1161 elif name.find("Parse") >= 0:
1162 classes.write(
1163 " if ret is None:raise parserError('%s() failed')\n"
1164 % (name))
1165 else:
1166 classes.write(
1167 " if ret is None:raise treeError('%s() failed')\n"
1168 % (name))
1169 classes.write(" return ")
1170 classes.write(classes_type[ret[0]][1] % ("ret"))
1171 classes.write("\n")
1172 else:
1173 classes.write(" return ret\n")
1174 classes.write("\n")
1175
1176 txt.write("\n\n#\n# Set of classes of the module\n#\n\n")
1177 for classname in classes_list:
1178 if classname == "None":
1179 pass
1180 else:
1181 if classname in classes_ancestor:
1182 txt.write("\n\nClass %s(%s)\n" % (classname,
1183 classes_ancestor[classname]))
1184 classes.write("class %s(%s):\n" % (classname,
1185 classes_ancestor[classname]))
1186 classes.write(" def __init__(self, _obj=None):\n")
1187 if classes_ancestor[classname] == "xmlCore" or \
1188 classes_ancestor[classname] == "xmlNode":
1189 classes.write(" if checkWrapper(_obj) != 0:")
1190 classes.write(" raise TypeError")
1191 classes.write("('%s got a wrong wrapper object type')\n" % \
1192 classname)
1193 if classname in reference_keepers:
1194 rlist = reference_keepers[classname]
1195 for ref in rlist:
1196 classes.write(" self.%s = None\n" % ref[1])
1197 classes.write(" self._o = _obj\n")
1198 classes.write(" %s.__init__(self, _obj=_obj)\n\n" % (
1199 classes_ancestor[classname]))
1200 if classes_ancestor[classname] == "xmlCore" or \
1201 classes_ancestor[classname] == "xmlNode":
1202 classes.write(" def __repr__(self):\n")
1203 format = "<%s (%%s) object at 0x%%x>" % (classname)
1204 classes.write(" return \"%s\" %% (self.name, int(pos_id (self)))\n\n" % (
1205 format))
1206 else:
1207 txt.write("Class %s()\n" % (classname))
1208 classes.write("class %s:\n" % (classname))
1209 classes.write(" def __init__(self, _obj=None):\n")
1210 if classname in reference_keepers:
1211 list = reference_keepers[classname]
1212 for ref in list:
1213 classes.write(" self.%s = None\n" % ref[1])
1214 classes.write(" if _obj != None:self._o = _obj;return\n")
1215 classes.write(" self._o = None\n\n")
1216 destruct=None
1217 if classname in classes_destructors:
1218 classes.write(" def __del__(self):\n")
1219 classes.write(" if self._o != None:\n")
1220 classes.write(" libxml2mod.%s(self._o)\n" %
1221 classes_destructors[classname])
1222 classes.write(" self._o = None\n\n")
1223 destruct=classes_destructors[classname]
1224 flist = function_classes[classname]
1225 flist = sorted(flist, key=cmp_to_key(functionCompare))
1226 oldfile = ""
1227 for info in flist:
1228 (index, func, name, ret, args, file) = info
1229 #
1230 # Do not provide as method the destructors for the class
1231 # to avoid double free
1232 #
1233 if name == destruct:
1234 continue
1235 if file != oldfile:
1236 if file == "python_accessor":
1237 classes.write(" # accessors for %s\n" % (classname))
1238 txt.write(" # accessors\n")
1239 else:
1240 classes.write(" #\n")
1241 classes.write(" # %s functions from module %s\n" % (
1242 classname, file))
1243 txt.write("\n # functions from module %s\n" % file)
1244 classes.write(" #\n\n")
1245 oldfile = file
1246 classes.write(" def %s(self" % func)
1247 txt.write(" %s()\n" % func)
1248 n = 0
1249 for arg in args:
1250 if n != index:
1251 classes.write(", %s" % arg[0])
1252 n = n + 1
1253 classes.write("):\n")
1254 writeDoc(name, args, ' ', classes)
1255 n = 0
1256 for arg in args:
1257 if arg[1] in classes_type:
1258 if n != index:
1259 classes.write(" if %s is None: %s__o = None\n" %
1260 (arg[0], arg[0]))
1261 classes.write(" else: %s__o = %s%s\n" %
1262 (arg[0], arg[0], classes_type[arg[1]][0]))
1263 n = n + 1
1264 if ret[0] != "void":
1265 classes.write(" ret = ")
1266 else:
1267 classes.write(" ")
1268 classes.write("libxml2mod.%s(" % name)
1269 n = 0
1270 for arg in args:
1271 if n != 0:
1272 classes.write(", ")
1273 if n != index:
1274 classes.write("%s" % arg[0])
1275 if arg[1] in classes_type:
1276 classes.write("__o")
1277 else:
1278 classes.write("self")
1279 if arg[1] in classes_type:
1280 classes.write(classes_type[arg[1]][0])
1281 n = n + 1
1282 classes.write(")\n")
1283 if ret[0] != "void":
1284 if ret[0] in classes_type:
1285 #
1286 # Raise an exception
1287 #
1288 if name in functions_noexcept:
1289 classes.write(
1290 " if ret is None:return None\n")
1291 elif name.find("URI") >= 0:
1292 classes.write(
1293 " if ret is None:raise uriError('%s() failed')\n"
1294 % (name))
1295 elif name.find("XPath") >= 0:
1296 classes.write(
1297 " if ret is None:raise xpathError('%s() failed')\n"
1298 % (name))
1299 elif name.find("Parse") >= 0:
1300 classes.write(
1301 " if ret is None:raise parserError('%s() failed')\n"
1302 % (name))
1303 else:
1304 classes.write(
1305 " if ret is None:raise treeError('%s() failed')\n"
1306 % (name))
1307
1308 #
1309 # generate the returned class wrapper for the object
1310 #
1311 classes.write(" __tmp = ")
1312 classes.write(classes_type[ret[0]][1] % ("ret"))
1313 classes.write("\n")
1314
1315 #
1316 # Sometime one need to keep references of the source
1317 # class in the returned class object.
1318 # See reference_keepers for the list
1319 #
1320 tclass = classes_type[ret[0]][2]
1321 if tclass in reference_keepers:
1322 list = reference_keepers[tclass]
1323 for pref in list:
1324 if pref[0] == classname:
1325 classes.write(" __tmp.%s = self\n" %
1326 pref[1])
1327 #
1328 # return the class
1329 #
1330 classes.write(" return __tmp\n")
1331 elif ret[0] in converter_type:
1332 #
1333 # Raise an exception
1334 #
1335 if name in functions_noexcept:
1336 classes.write(
1337 " if ret is None:return None")
1338 elif name.find("URI") >= 0:
1339 classes.write(
1340 " if ret is None:raise uriError('%s() failed')\n"
1341 % (name))
1342 elif name.find("XPath") >= 0:
1343 classes.write(
1344 " if ret is None:raise xpathError('%s() failed')\n"
1345 % (name))
1346 elif name.find("Parse") >= 0:
1347 classes.write(
1348 " if ret is None:raise parserError('%s() failed')\n"
1349 % (name))
1350 else:
1351 classes.write(
1352 " if ret is None:raise treeError('%s() failed')\n"
1353 % (name))
1354 classes.write(" return ")
1355 classes.write(converter_type[ret[0]] % ("ret"))
1356 classes.write("\n")
1357 else:
1358 classes.write(" return ret\n")
1359 classes.write("\n")
1360
1361 #
1362 # Generate enum constants
1363 #
1364 for type,enum in enums.items():
1365 classes.write("# %s\n" % type)
1366 items = enum.items()
1367 items = sorted(items, key=(lambda i: int(i[1])))
1368 for name,value in items:
1369 classes.write("%s = %s\n" % (name,value))
1370 classes.write("\n")
1371
1372 txt.close()
1373 classes.close()
1374
1375buildStubs()
1376buildWrappers()
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette