2002-01-30 19:37:32 +03:00
#!/usr/bin/python -u
#
# generate python wrappers from the XML API description
#
functions = { }
2002-01-31 02:49:06 +03:00
import string
2002-01-31 23:29:19 +03:00
#######################################################################
#
# That part if purely the API acquisition phase from the
# XML API description
#
#######################################################################
import os
2002-01-30 19:37:32 +03:00
import xmllib
try :
import sgmlop
except ImportError :
sgmlop = None # accelerator not available
debug = 0
if sgmlop :
class FastParser :
""" sgmlop based XML parser. this is typically 15x faster
than SlowParser . . . """
def __init__ ( self , target ) :
# setup callbacks
self . finish_starttag = target . start
self . finish_endtag = target . end
self . handle_data = target . data
# activate parser
self . parser = sgmlop . XMLParser ( )
self . parser . register ( self )
self . feed = self . parser . feed
self . entity = {
" amp " : " & " , " gt " : " > " , " lt " : " < " ,
" apos " : " ' " , " quot " : ' " '
}
def close ( self ) :
try :
self . parser . close ( )
finally :
self . parser = self . feed = None # nuke circular reference
def handle_entityref ( self , entity ) :
# <string> entity
try :
self . handle_data ( self . entity [ entity ] )
except KeyError :
self . handle_data ( " & %s ; " % entity )
else :
FastParser = None
class SlowParser ( xmllib . XMLParser ) :
""" slow but safe standard parser, based on the XML parser in
Python ' s standard library. " " "
def __init__ ( self , target ) :
self . unknown_starttag = target . start
self . handle_data = target . data
self . unknown_endtag = target . end
xmllib . XMLParser . __init__ ( self )
def getparser ( target = None ) :
# get the fastest available parser, and attach it to an
# unmarshalling object. return both objects.
if target == None :
target = docParser ( )
if FastParser :
return FastParser ( target ) , target
return SlowParser ( target ) , target
class docParser :
def __init__ ( self ) :
self . _methodname = None
self . _data = [ ]
self . in_function = 0
def close ( self ) :
if debug :
print " close "
def getmethodname ( self ) :
return self . _methodname
def data ( self , text ) :
if debug :
print " data %s " % text
self . _data . append ( text )
def start ( self , tag , attrs ) :
if debug :
print " start %s , %s " % ( tag , attrs )
if tag == ' function ' :
self . _data = [ ]
self . in_function = 1
self . function = None
self . function_args = [ ]
self . function_descr = None
self . function_return = None
self . function_file = None
if attrs . has_key ( ' name ' ) :
self . function = attrs [ ' name ' ]
if attrs . has_key ( ' file ' ) :
self . function_file = attrs [ ' file ' ]
elif tag == ' info ' :
self . _data = [ ]
elif tag == ' arg ' :
if self . in_function == 1 :
self . function_arg_name = None
self . function_arg_type = None
self . function_arg_info = None
if attrs . has_key ( ' name ' ) :
self . function_arg_name = attrs [ ' name ' ]
if attrs . has_key ( ' type ' ) :
self . function_arg_type = attrs [ ' type ' ]
if attrs . has_key ( ' info ' ) :
self . function_arg_info = attrs [ ' info ' ]
elif tag == ' return ' :
if self . in_function == 1 :
self . function_return_type = None
self . function_return_info = None
if attrs . has_key ( ' type ' ) :
self . function_return_type = attrs [ ' type ' ]
if attrs . has_key ( ' info ' ) :
self . function_return_info = attrs [ ' info ' ]
def end ( self , tag ) :
if debug :
print " end %s " % tag
if tag == ' function ' :
if self . function != None :
function ( self . function , self . function_descr ,
self . function_return , self . function_args ,
self . function_file )
self . in_function = 0
elif tag == ' arg ' :
if self . in_function == 1 :
self . function_args . append ( [ self . function_arg_name ,
self . function_arg_type ,
self . function_arg_info ] )
elif tag == ' return ' :
if self . in_function == 1 :
self . function_return = [ self . function_return_type ,
self . function_return_info ]
elif tag == ' info ' :
str = ' '
for c in self . _data :
str = str + c
if self . in_function == 1 :
self . function_descr = str
def function ( name , desc , ret , args , file ) :
global functions
functions [ name ] = ( desc , ret , args , file )
2002-01-31 23:29:19 +03:00
#######################################################################
#
# Some filtering rukes to drop functions/types which should not
# be exposed as-is on the Python interface
#
#######################################################################
2002-01-31 02:49:06 +03:00
2002-01-30 19:37:32 +03:00
skipped_modules = {
' xmlmemory ' : None ,
2002-01-30 23:52:23 +03:00
' DOCBparser ' : None ,
' SAX ' : None ,
' hash ' : None ,
' list ' : None ,
' threads ' : None ,
2002-01-31 23:29:19 +03:00
' xpointer ' : None ,
2002-01-30 23:52:23 +03:00
}
skipped_types = {
' int * ' : " usually a return type " ,
' xmlSAXHandlerPtr ' : " not the proper interface for SAX " ,
' htmlSAXHandlerPtr ' : " not the proper interface for SAX " ,
' xmlParserCtxtPtr ' : " not the proper interface for the parser " ,
' htmlParserCtxtPtr ' : " not the proper interface for the parser " ,
' xmlRMutexPtr ' : " thread specific, skipped " ,
' xmlMutexPtr ' : " thread specific, skipped " ,
' xmlGlobalStatePtr ' : " thread specific, skipped " ,
' xmlListPtr ' : " internal representation not suitable for python " ,
' xmlBufferPtr ' : " internal representation not suitable for python " ,
' FILE * ' : None ,
2002-01-30 19:37:32 +03:00
}
2002-01-31 23:29:19 +03:00
#######################################################################
#
# Table of remapping to/from the python type or class to the C
# counterpart.
#
#######################################################################
2002-01-30 19:37:32 +03:00
py_types = {
2002-01-30 23:52:23 +03:00
' void ' : ( None , None , None , None ) ,
' int ' : ( ' i ' , None , " int " , " int " ) ,
' long ' : ( ' i ' , None , " int " , " int " ) ,
' double ' : ( ' d ' , None , " double " , " double " ) ,
' unsigned int ' : ( ' i ' , None , " int " , " int " ) ,
' xmlChar ' : ( ' c ' , None , " int " , " int " ) ,
' unsigned char * ' : ( ' s ' , None , " charPtr " , " char * " ) ,
' char * ' : ( ' s ' , None , " charPtr " , " char * " ) ,
' const char * ' : ( ' s ' , None , " charPtr " , " char * " ) ,
' xmlChar * ' : ( ' s ' , None , " xmlCharPtr " , " xmlChar * " ) ,
' const xmlChar * ' : ( ' s ' , None , " xmlCharPtr " , " xmlChar * " ) ,
' xmlNodePtr ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' const xmlNodePtr ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' xmlNode * ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' const xmlNode * ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' xmlDtdPtr ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' const xmlDtdPtr ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' xmlDtd * ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' const xmlDtd * ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' xmlAttrPtr ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' const xmlAttrPtr ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' xmlAttr * ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' const xmlAttr * ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' xmlEntityPtr ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' const xmlEntityPtr ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' xmlEntity * ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' const xmlEntity * ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
2002-01-31 23:29:19 +03:00
' xmlElementPtr ' : ( ' O ' , " xmlElement " , " xmlElementPtr " , " xmlElementPtr " ) ,
' const xmlElementPtr ' : ( ' O ' , " xmlElement " , " xmlElementPtr " , " xmlElementPtr " ) ,
' xmlElement * ' : ( ' O ' , " xmlElement " , " xmlElementPtr " , " xmlElementPtr " ) ,
' const xmlElement * ' : ( ' O ' , " xmlElement " , " xmlElementPtr " , " xmlElementPtr " ) ,
' xmlAttributePtr ' : ( ' O ' , " xmlAttribute " , " xmlAttributePtr " , " xmlAttributePtr " ) ,
' const xmlAttributePtr ' : ( ' O ' , " xmlAttribute " , " xmlAttributePtr " , " xmlAttributePtr " ) ,
' xmlAttribute * ' : ( ' O ' , " xmlAttribute " , " xmlAttributePtr " , " xmlAttributePtr " ) ,
' const xmlAttribute * ' : ( ' O ' , " xmlAttribute " , " xmlAttributePtr " , " xmlAttributePtr " ) ,
' xmlNsPtr ' : ( ' O ' , " xmlNode " , " xmlNsPtr " , " xmlNsPtr " ) ,
' const xmlNsPtr ' : ( ' O ' , " xmlNode " , " xmlNsPtr " , " xmlNsPtr " ) ,
' xmlNs * ' : ( ' O ' , " xmlNode " , " xmlNsPtr " , " xmlNsPtr " ) ,
' const xmlNs * ' : ( ' O ' , " xmlNode " , " xmlNsPtr " , " xmlNsPtr " ) ,
2002-01-30 23:52:23 +03:00
' xmlDocPtr ' : ( ' O ' , " xmlNode " , " xmlDocPtr " , " xmlDocPtr " ) ,
' const xmlDocPtr ' : ( ' O ' , " xmlNode " , " xmlDocPtr " , " xmlDocPtr " ) ,
' xmlDoc * ' : ( ' O ' , " xmlNode " , " xmlDocPtr " , " xmlDocPtr " ) ,
' const xmlDoc * ' : ( ' O ' , " xmlNode " , " xmlDocPtr " , " xmlDocPtr " ) ,
' htmlDocPtr ' : ( ' O ' , " xmlNode " , " xmlDocPtr " , " xmlDocPtr " ) ,
' const htmlDocPtr ' : ( ' O ' , " xmlNode " , " xmlDocPtr " , " xmlDocPtr " ) ,
' htmlDoc * ' : ( ' O ' , " xmlNode " , " xmlDocPtr " , " xmlDocPtr " ) ,
' const htmlDoc * ' : ( ' O ' , " xmlNode " , " xmlDocPtr " , " xmlDocPtr " ) ,
' htmlNodePtr ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' const htmlNodePtr ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' htmlNode * ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
' const htmlNode * ' : ( ' O ' , " xmlNode " , " xmlNodePtr " , " xmlNodePtr " ) ,
2002-01-31 23:29:19 +03:00
' xmlXPathContextPtr ' : ( ' O ' , " xmlXPathContext " , " xmlXPathContextPtr " , " xmlXPathContextPtr " ) ,
' xmlXPathContext * ' : ( ' O ' , " xpathContext " , " xmlXPathContextPtr " , " xmlXPathContextPtr " ) ,
}
py_return_types = {
' xmlXPathObjectPtr ' : ( ' O ' , " foo " , " xmlXPathObjectPtr " , " xmlXPathObjectPtr " ) ,
2002-01-30 19:37:32 +03:00
}
unknown_types = { }
2002-01-31 23:29:19 +03:00
#######################################################################
#
# This part writes the C <-> Python stubs libxml2-py.[ch] and
# the table libxml2-export.c to add when registrering the Python module
#
#######################################################################
def skip_function ( name ) :
if name [ 0 : 12 ] == " xmlXPathWrap " :
return 1
# if name[0:11] == "xmlXPathNew":
# return 1
return 0
2002-01-30 23:52:23 +03:00
def print_function_wrapper ( name , output , export , include ) :
2002-01-30 19:37:32 +03:00
global py_types
global unknown_types
global functions
global skipped_modules
try :
( desc , ret , args , file ) = functions [ name ]
except :
print " failed to get function %s infos "
return
if skipped_modules . has_key ( file ) :
return 0
2002-01-31 23:29:19 +03:00
if skip_function ( name ) == 1 :
return 0
2002-01-30 19:37:32 +03:00
c_call = " " ;
format = " "
format_args = " "
c_args = " "
c_return = " "
2002-01-30 23:52:23 +03:00
c_convert = " "
2002-01-30 19:37:32 +03:00
for arg in args :
2002-01-30 23:52:23 +03:00
# This should be correct
if arg [ 1 ] [ 0 : 6 ] == " const " :
arg [ 1 ] = arg [ 1 ] [ 6 : ]
2002-01-30 19:37:32 +03:00
c_args = c_args + " %s %s ; \n " % ( arg [ 1 ] , arg [ 0 ] )
if py_types . has_key ( arg [ 1 ] ) :
2002-01-30 23:52:23 +03:00
( f , t , n , c ) = py_types [ arg [ 1 ] ]
2002-01-30 19:37:32 +03:00
if f != None :
format = format + f
if t != None :
2002-01-30 23:52:23 +03:00
format_args = format_args + " , &pyobj_ %s " % ( arg [ 0 ] )
c_args = c_args + " PyObject *pyobj_ %s ; \n " % ( arg [ 0 ] )
c_convert = c_convert + \
" %s = ( %s ) Py %s _Get(pyobj_ %s ); \n " % ( arg [ 0 ] ,
arg [ 1 ] , t , arg [ 0 ] ) ;
else :
format_args = format_args + " , & %s " % ( arg [ 0 ] )
2002-01-30 19:37:32 +03:00
if c_call != " " :
c_call = c_call + " , " ;
c_call = c_call + " %s " % ( arg [ 0 ] )
else :
2002-01-30 23:52:23 +03:00
if skipped_types . has_key ( arg [ 1 ] ) :
return 0
2002-01-30 19:37:32 +03:00
if unknown_types . has_key ( arg [ 1 ] ) :
lst = unknown_types [ arg [ 1 ] ]
lst . append ( name )
else :
unknown_types [ arg [ 1 ] ] = [ name ]
return - 1
if format != " " :
format = format + " : %s " % ( name )
if ret [ 0 ] == ' void ' :
c_call = " \n %s ( %s ); \n " % ( name , c_call ) ;
ret_convert = " Py_INCREF(Py_None); \n return(Py_None); \n "
elif py_types . has_key ( ret [ 0 ] ) :
2002-01-30 23:52:23 +03:00
( f , t , n , c ) = py_types [ ret [ 0 ] ]
2002-01-30 19:37:32 +03:00
c_return = " %s c_retval; \n " % ( ret [ 0 ] )
c_call = " \n c_retval = %s ( %s ); \n " % ( name , c_call ) ;
2002-01-30 23:52:23 +03:00
ret_convert = " py_retval = libxml_ %s Wrap(( %s ) c_retval); \n " % ( n , c )
ret_convert = ret_convert + " return(py_retval); \n "
2002-01-31 23:29:19 +03:00
elif py_return_types . has_key ( ret [ 0 ] ) :
( f , t , n , c ) = py_return_types [ ret [ 0 ] ]
c_return = " %s c_retval; \n " % ( ret [ 0 ] )
c_call = " \n c_retval = %s ( %s ); \n " % ( name , c_call ) ;
ret_convert = " py_retval = libxml_ %s Wrap(( %s ) c_retval); \n " % ( n , c )
ret_convert = ret_convert + " return(py_retval); \n "
2002-01-30 19:37:32 +03:00
else :
2002-01-30 23:52:23 +03:00
if skipped_types . has_key ( ret [ 0 ] ) :
return 0
2002-01-30 19:37:32 +03:00
if unknown_types . has_key ( ret [ 0 ] ) :
lst = unknown_types [ ret [ 0 ] ]
lst . append ( name )
else :
unknown_types [ ret [ 0 ] ] = [ name ]
return - 1
2002-01-30 23:52:23 +03:00
include . write ( " PyObject * " )
include . write ( " libxml_ %s (PyObject *self, PyObject *args); \n " % ( name ) )
export . write ( " { \" %s \" , libxml_ %s , METH_VARARGS }, \n " % ( name , name ) )
2002-01-30 19:37:32 +03:00
output . write ( " PyObject * \n " )
output . write ( " libxml_ %s (PyObject *self, PyObject *args) { \n " % ( name ) )
if ret [ 0 ] != ' void ' :
output . write ( " PyObject *py_retval; \n " )
if c_return != " " :
output . write ( c_return )
if c_args != " " :
output . write ( c_args )
if format != " " :
output . write ( " \n if (!PyArg_ParseTuple(args, \" %s \" %s )) \n " %
( format , format_args ) )
output . write ( " return(NULL); \n " )
2002-01-30 23:52:23 +03:00
if c_convert != " " :
output . write ( c_convert )
2002-01-30 19:37:32 +03:00
output . write ( c_call )
output . write ( ret_convert )
output . write ( " } \n \n " )
return 1
try :
2002-02-01 02:49:05 +03:00
f = open ( " ../doc/libxml2-api.xml " )
2002-01-30 19:37:32 +03:00
data = f . read ( )
( parser , target ) = getparser ( )
parser . feed ( data )
parser . close ( )
except IOError , msg :
print file , " : " , msg
print " Found %d functions in libxml2-api.xml " % ( len ( functions . keys ( ) ) )
nb_wrap = 0
failed = 0
skipped = 0
2002-01-30 23:52:23 +03:00
include = open ( " libxml2-py.h " , " w " )
include . write ( " /* Generated */ \n \n " )
export = open ( " libxml2-export.c " , " w " )
export . write ( " /* Generated */ \n \n " )
2002-01-30 19:37:32 +03:00
wrapper = open ( " libxml2-py.c " , " w " )
wrapper . write ( " /* Generated */ \n \n " )
wrapper . write ( " #include <Python.h> \n " )
wrapper . write ( " #include <libxml/tree.h> \n " )
wrapper . write ( " #include \" libxml_wrap.h \" \n " )
wrapper . write ( " #include \" libxml2-py.h \" \n \n " )
for function in functions . keys ( ) :
2002-01-30 23:52:23 +03:00
ret = print_function_wrapper ( function , wrapper , export , include )
2002-01-30 19:37:32 +03:00
if ret < 0 :
failed = failed + 1
2002-01-31 02:49:06 +03:00
del functions [ function ]
2002-01-30 19:37:32 +03:00
if ret == 0 :
skipped = skipped + 1
2002-01-31 02:49:06 +03:00
del functions [ function ]
if ret == 1 :
nb_wrap = nb_wrap + 1
2002-01-30 23:52:23 +03:00
include . close ( )
export . close ( )
2002-01-30 19:37:32 +03:00
wrapper . close ( )
print " Generated %d wrapper functions, %d failed, %d skipped \n " % ( nb_wrap ,
failed , skipped ) ;
print " Missing type converters: %s " % ( unknown_types . keys ( ) )
2002-01-31 02:49:06 +03:00
2002-01-31 23:29:19 +03:00
#######################################################################
#
# This part writes part of the Python front-end classes based on
# mapping rules between types and classes and also based on function
# renaming to get consistent function names at the Python level
#
#######################################################################
#
# The type automatically remapped to generated classes
#
classes_type = {
" xmlNodePtr " : ( " ._o " , " xmlNode(_obj= %s ) " , " xmlNode " ) ,
" xmlNode * " : ( " ._o " , " xmlNode(_obj= %s ) " , " xmlNode " ) ,
" xmlDocPtr " : ( " ._o " , " xmlDoc(_obj= %s ) " , " xmlDoc " ) ,
" xmlDocPtr * " : ( " ._o " , " xmlDoc(_obj= %s ) " , " xmlDoc " ) ,
" htmlDocPtr " : ( " ._o " , " xmlDoc(_obj= %s ) " , " xmlDoc " ) ,
" htmlxmlDocPtr * " : ( " ._o " , " xmlDoc(_obj= %s ) " , " xmlDoc " ) ,
" xmlAttrPtr " : ( " ._o " , " xmlAttr(_obj= %s ) " , " xmlAttr " ) ,
" xmlAttr * " : ( " ._o " , " xmlAttr(_obj= %s ) " , " xmlAttr " ) ,
" xmlNsPtr " : ( " ._o " , " xmlNs(_obj= %s ) " , " xmlNs " ) ,
" xmlNs * " : ( " ._o " , " xmlNs(_obj= %s ) " , " xmlNs " ) ,
" xmlDtdPtr " : ( " ._o " , " xmlDtd(_obj= %s ) " , " xmlDtd " ) ,
" xmlDtd * " : ( " ._o " , " xmlDtd(_obj= %s ) " , " xmlDtd " ) ,
" xmlEntityPtr " : ( " ._o " , " xmlEntity(_obj= %s ) " , " xmlEntity " ) ,
" xmlEntity * " : ( " ._o " , " xmlEntity(_obj= %s ) " , " xmlEntity " ) ,
" xmlElementPtr " : ( " ._o " , " xmlElement(_obj= %s ) " , " xmlElement " ) ,
" xmlElement * " : ( " ._o " , " xmlElement(_obj= %s ) " , " xmlElement " ) ,
" xmlAttributePtr " : ( " ._o " , " xmlAttribute(_obj= %s ) " , " xmlAttribute " ) ,
" xmlAttribute * " : ( " ._o " , " xmlAttribute(_obj= %s ) " , " xmlAttribute " ) ,
" xmlXPathContextPtr " : ( " ._o " , " xpathContext(_obj= %s ) " , " xpathContext " ) ,
}
converter_type = {
" xmlXPathObjectPtr " : " xpathObjectRet( %s ) " ,
}
primary_classes = [ " xmlNode " , " xmlDoc " ]
classes_ancestor = {
" xmlNode " : " xmlCore " ,
" xmlDoc " : " xmlCore " ,
" xmlAttr " : " xmlCore " ,
" xmlNs " : " xmlCore " ,
" xmlDtd " : " xmlCore " ,
" xmlEntity " : " xmlCore " ,
" xmlElement " : " xmlCore " ,
" xmlAttribute " : " xmlCore " ,
}
classes_destructors = {
" xpathContext " : " xmlXPathFreeContext " ,
}
2002-01-31 02:49:06 +03:00
function_classes = { }
2002-01-31 23:29:19 +03:00
function_classes [ " None " ] = [ ]
for type in classes_type . keys ( ) :
function_classes [ classes_type [ type ] [ 2 ] ] = [ ]
#
# Build the list of C types to look for ordered to start with primary classes
#
ctypes = [ ]
ctypes_processed = { }
for classe in primary_classes :
for type in classes_type . keys ( ) :
tinfo = classes_type [ type ]
if tinfo [ 2 ] == classe :
ctypes . append ( type )
ctypes_processed [ type ] = ( )
for type in classes_type . keys ( ) :
if ctypes_processed . has_key ( type ) :
continue
tinfo = classes_type [ type ]
ctypes . append ( type )
ctypes_processed [ type ] = ( )
def nameFixup ( function , classe , type ) :
listname = classe + " List "
ll = len ( listname )
l = len ( classe )
if name [ 0 : l ] == listname :
func = name [ l : ]
func = string . lower ( func [ 0 : 1 ] ) + func [ 1 : ]
elif name [ 0 : l ] == classe :
func = name [ l : ]
func = string . lower ( func [ 0 : 1 ] ) + func [ 1 : ]
elif name [ 0 : 6 ] == " xmlGet " :
func = name [ 6 : ]
func = string . lower ( func [ 0 : 1 ] ) + func [ 1 : ]
elif name [ 0 : 3 ] == " xml " :
func = name [ 3 : ]
func = string . lower ( func [ 0 : 1 ] ) + func [ 1 : ]
else :
func = name
if func [ 0 : 5 ] == " xPath " :
func = " xpath " + func [ 5 : ]
elif func [ 0 : 4 ] == " xPtr " :
func = " xpointer " + func [ 4 : ]
elif func [ 0 : 8 ] == " xInclude " :
func = " xinclude " + func [ 8 : ]
elif func [ 0 : 2 ] == " iD " :
func = " ID " + func [ 2 : ]
elif func [ 0 : 3 ] == " uRI " :
func = " URI " + func [ 3 : ]
elif func [ 0 : 4 ] == " uTF8 " :
func = " UTF8 " + func [ 4 : ]
return func
2002-01-31 02:49:06 +03:00
for name in functions . keys ( ) :
2002-01-31 23:29:19 +03:00
found = 0 ;
2002-01-31 02:49:06 +03:00
( desc , ret , args , file ) = functions [ name ]
2002-01-31 23:29:19 +03:00
for type in ctypes :
classe = classes_type [ type ] [ 2 ]
if name [ 0 : 3 ] == " xml " and len ( args ) > = 1 and args [ 0 ] [ 1 ] == type :
found = 1
func = nameFixup ( name , classe , type )
2002-01-31 02:49:06 +03:00
info = ( 0 , func , name , ret , args , file )
2002-01-31 23:29:19 +03:00
function_classes [ classe ] . append ( info )
elif name [ 0 : 3 ] == " xml " and len ( args ) > = 2 and args [ 1 ] [ 1 ] == type :
found = 1
func = nameFixup ( name , classe , type )
2002-01-31 02:49:06 +03:00
info = ( 1 , func , name , ret , args , file )
2002-01-31 23:29:19 +03:00
function_classes [ classe ] . append ( info )
elif name [ 0 : 4 ] == " html " and len ( args ) > = 1 and args [ 0 ] [ 1 ] == type :
found = 1
func = nameFixup ( name , classe , type )
2002-01-31 02:49:06 +03:00
info = ( 0 , func , name , ret , args , file )
2002-01-31 23:29:19 +03:00
function_classes [ classe ] . append ( info )
elif name [ 0 : 4 ] == " html " and len ( args ) > = 2 and args [ 1 ] [ 1 ] == type :
found = 1
func = nameFixup ( name , classe , type )
2002-01-31 02:49:06 +03:00
info = ( 1 , func , name , ret , args , file )
2002-01-31 23:29:19 +03:00
function_classes [ classe ] . append ( info )
if found == 1 :
break
if found == 1 :
continue
if name [ 0 : 8 ] == " xmlXPath " :
continue
if name [ 0 : 6 ] == " xmlStr " :
continue
if name [ 0 : 10 ] == " xmlCharStr " :
continue
func = nameFixup ( name , " None " , file )
info = ( 0 , func , name , ret , args , file )
function_classes [ ' None ' ] . append ( info )
2002-01-31 02:49:06 +03:00
classes = open ( " libxml2class.py " , " w " )
2002-01-31 23:29:19 +03:00
def functionCompare ( info1 , info2 ) :
( index1 , func1 , name1 , ret1 , args1 , file1 ) = info1
( index2 , func2 , name2 , ret2 , args2 , file2 ) = info2
if file1 < file2 :
return - 1
if file1 > file2 :
return 1
if func1 < func2 :
return - 1
if func1 > func2 :
return 1
return 0
def writeDoc ( name , args , indent , output ) :
if functions [ name ] [ 0 ] == None or functions [ name ] [ 0 ] == " " :
return
val = functions [ name ] [ 0 ]
val = string . replace ( val , " NULL " , " None " ) ;
output . write ( indent )
output . write ( ' " " " ' )
while len ( val ) > 60 :
str = val [ 0 : 60 ]
i = string . rfind ( str , " " ) ;
if i < 0 :
i = 60
str = val [ 0 : i ]
val = val [ i : ]
output . write ( str )
output . write ( ' \n ' ) ;
output . write ( indent )
output . write ( val ) ;
output . write ( ' " " " \n ' )
2002-01-31 02:49:06 +03:00
if function_classes . has_key ( " None " ) :
2002-01-31 23:29:19 +03:00
flist = function_classes [ " None " ]
flist . sort ( functionCompare )
oldfile = " "
for info in flist :
2002-01-31 02:49:06 +03:00
( index , func , name , ret , args , file ) = info
2002-01-31 23:29:19 +03:00
if file != oldfile :
classes . write ( " # \n # Functions from module %s \n # \n \n " % file )
oldfile = file
2002-01-31 02:49:06 +03:00
classes . write ( " def %s ( " % func )
n = 0
for arg in args :
if n != 0 :
classes . write ( " , " )
classes . write ( " %s " % arg [ 0 ] )
n = n + 1
classes . write ( " ): \n " )
2002-01-31 23:29:19 +03:00
writeDoc ( name , args , ' ' , classes ) ;
2002-01-31 02:49:06 +03:00
if ret [ 0 ] != " void " :
classes . write ( " ret = " ) ;
else :
classes . write ( " " ) ;
classes . write ( " _libxml. %s ( " % name )
n = 0
for arg in args :
if n != 0 :
classes . write ( " , " ) ;
classes . write ( " %s " % arg [ 0 ] )
if classes_type . has_key ( arg [ 1 ] ) :
classes . write ( classes_type [ arg [ 1 ] ] [ 0 ] )
n = n + 1
classes . write ( " ) \n " ) ;
if ret [ 0 ] != " void " :
if classes_type . has_key ( ret [ 0 ] ) :
classes . write ( " if ret == None: return None \n " ) ;
classes . write ( " return " ) ;
classes . write ( classes_type [ ret [ 0 ] ] [ 1 ] % ( " ret " ) ) ;
classes . write ( " \n " ) ;
else :
classes . write ( " return ret \n " ) ;
classes . write ( " \n " ) ;
for classname in function_classes . keys ( ) :
if classname == " None " :
pass
else :
2002-01-31 23:29:19 +03:00
if classes_ancestor . has_key ( classname ) :
classes . write ( " class %s ( %s ): \n " % ( classname ,
classes_ancestor [ classname ] ) )
2002-01-31 02:49:06 +03:00
classes . write ( " def __init__(self, _obj=None): \n " )
classes . write ( " self._o = None \n " )
2002-01-31 23:29:19 +03:00
classes . write ( " %s .__init__(self, _obj=_obj) \n \n " % (
classes_ancestor [ classname ] ) )
2002-01-31 02:49:06 +03:00
else :
2002-01-31 23:29:19 +03:00
classes . write ( " class %s : \n " % ( classname ) )
2002-01-31 02:49:06 +03:00
classes . write ( " def __init__(self, _obj=None): \n " )
classes . write ( " if _obj != None:self._o = _obj;return \n " )
classes . write ( " self._o = None \n \n " ) ;
2002-01-31 23:29:19 +03:00
if classes_destructors . has_key ( classname ) :
classes . write ( " def __del__(self): \n " )
classes . write ( " if self._o != None: \n " )
classes . write ( " _libxml. %s (self._o) \n " %
classes_destructors [ classname ] ) ;
classes . write ( " self._o = None \n \n " ) ;
2002-02-01 20:56:45 +03:00
classes . write ( " def __repr__(self): \n " )
format = " %s : %% s " % ( classname )
classes . write ( " return \" %s \" %% (self.name) \n \n " % (
format ) )
2002-01-31 23:29:19 +03:00
flist = function_classes [ classname ]
flist . sort ( functionCompare )
oldfile = " "
for info in flist :
2002-01-31 02:49:06 +03:00
( index , func , name , ret , args , file ) = info
2002-01-31 23:29:19 +03:00
if file != oldfile :
classes . write ( " # \n " )
classes . write ( " # %s functions from module %s \n " % (
classname , file ) )
classes . write ( " # \n \n " )
oldfile = file
2002-01-31 02:49:06 +03:00
classes . write ( " def %s (self " % func )
n = 0
for arg in args :
if n != index :
classes . write ( " , %s " % arg [ 0 ] )
n = n + 1
classes . write ( " ): \n " )
2002-01-31 23:29:19 +03:00
writeDoc ( name , args , ' ' , classes ) ;
2002-01-31 02:49:06 +03:00
if ret [ 0 ] != " void " :
classes . write ( " ret = " ) ;
else :
classes . write ( " " ) ;
classes . write ( " _libxml. %s ( " % name )
n = 0
for arg in args :
if n != 0 :
classes . write ( " , " ) ;
if n != index :
classes . write ( " %s " % arg [ 0 ] )
else :
classes . write ( " self " ) ;
if classes_type . has_key ( arg [ 1 ] ) :
classes . write ( classes_type [ arg [ 1 ] ] [ 0 ] )
n = n + 1
classes . write ( " ) \n " ) ;
if ret [ 0 ] != " void " :
if classes_type . has_key ( ret [ 0 ] ) :
classes . write ( " if ret == None: return None \n " ) ;
classes . write ( " return " ) ;
classes . write ( classes_type [ ret [ 0 ] ] [ 1 ] % ( " ret " ) ) ;
classes . write ( " \n " ) ;
2002-01-31 23:29:19 +03:00
elif converter_type . has_key ( ret [ 0 ] ) :
classes . write ( " if ret == None: return None \n " ) ;
classes . write ( " return " ) ;
classes . write ( converter_type [ ret [ 0 ] ] % ( " ret " ) ) ;
classes . write ( " \n " ) ;
2002-01-31 02:49:06 +03:00
else :
classes . write ( " return ret \n " ) ;
classes . write ( " \n " ) ;
classes . close ( )