Blame gentest.py

Packit 423ecb
#!/usr/bin/python -u
Packit 423ecb
#
Packit 423ecb
# generate a tester program for the API
Packit 423ecb
#
Packit 423ecb
import sys
Packit 423ecb
import os
Packit 423ecb
import string
Packit 423ecb
try:
Packit 423ecb
    import libxml2
Packit 423ecb
except:
Packit 423ecb
    print "libxml2 python bindings not available, skipping testapi.c generation"
Packit 423ecb
    sys.exit(0)
Packit 423ecb
Packit 423ecb
if len(sys.argv) > 1:
Packit 423ecb
    srcPref = sys.argv[1] + '/'
Packit 423ecb
else:
Packit 423ecb
    srcPref = ''
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Modules we want to skip in API test
Packit 423ecb
#
Packit 423ecb
skipped_modules = [ "SAX", "xlink", "threads", "globals",
Packit 423ecb
  "xmlmemory", "xmlversion", "xmlexports",
Packit 423ecb
  #deprecated
Packit 423ecb
  "DOCBparser",
Packit 423ecb
]
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# defines for each module
Packit 423ecb
#
Packit 423ecb
modules_defines = {
Packit 423ecb
    "HTMLparser": "LIBXML_HTML_ENABLED",
Packit 423ecb
    "catalog": "LIBXML_CATALOG_ENABLED",
Packit 423ecb
    "xmlreader": "LIBXML_READER_ENABLED",
Packit 423ecb
    "relaxng": "LIBXML_SCHEMAS_ENABLED",
Packit 423ecb
    "schemasInternals": "LIBXML_SCHEMAS_ENABLED",
Packit 423ecb
    "xmlschemas": "LIBXML_SCHEMAS_ENABLED",
Packit 423ecb
    "xmlschemastypes": "LIBXML_SCHEMAS_ENABLED",
Packit 423ecb
    "xpath": "LIBXML_XPATH_ENABLED",
Packit 423ecb
    "xpathInternals": "LIBXML_XPATH_ENABLED",
Packit 423ecb
    "xinclude": "LIBXML_XINCLUDE_ENABLED",
Packit 423ecb
    "xpointer": "LIBXML_XPTR_ENABLED",
Packit 423ecb
    "xmlregexp" : "LIBXML_REGEXP_ENABLED",
Packit 423ecb
    "xmlautomata" : "LIBXML_AUTOMATA_ENABLED",
Packit 423ecb
    "xmlsave" : "LIBXML_OUTPUT_ENABLED",
Packit 423ecb
    "DOCBparser" : "LIBXML_DOCB_ENABLED",
Packit 423ecb
    "xmlmodule" : "LIBXML_MODULES_ENABLED",
Packit 423ecb
    "pattern" : "LIBXML_PATTERN_ENABLED",
Packit 423ecb
    "schematron" : "LIBXML_SCHEMATRON_ENABLED",
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# defines for specific functions
Packit 423ecb
#
Packit 423ecb
function_defines = {
Packit 423ecb
    "htmlDefaultSAXHandlerInit": "LIBXML_HTML_ENABLED",
Packit 423ecb
    "xmlSAX2EndElement" : "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlSAX2StartElement" : "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlSAXDefaultVersion" : "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "UTF8Toisolat1" : "LIBXML_OUTPUT_ENABLED",
Packit 423ecb
    "xmlCleanupPredefinedEntities": "LIBXML_LEGACY_ENABLED",
Packit 423ecb
    "xmlInitializePredefinedEntities": "LIBXML_LEGACY_ENABLED",
Packit 423ecb
    "xmlSetFeature": "LIBXML_LEGACY_ENABLED",
Packit 423ecb
    "xmlGetFeature": "LIBXML_LEGACY_ENABLED",
Packit 423ecb
    "xmlGetFeaturesList": "LIBXML_LEGACY_ENABLED",
Packit 423ecb
    "xmlIOParseDTD": "LIBXML_VALID_ENABLED",
Packit 423ecb
    "xmlParseDTD": "LIBXML_VALID_ENABLED",
Packit 423ecb
    "xmlParseDoc": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlParseMemory": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlRecoverDoc": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlParseFile": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlRecoverFile": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlRecoverMemory": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlSAXParseFileWithData": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlSAXParseMemory": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlSAXUserParseMemory": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlSAXParseDoc": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlSAXParseDTD": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlSAXUserParseFile": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlParseEntity": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlParseExternalEntity": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlSAXParseMemoryWithData": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlParseBalancedChunkMemory": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlParseBalancedChunkMemoryRecover": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlSetupParserForBuffer": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlStopParser": "LIBXML_PUSH_ENABLED",
Packit 423ecb
    "xmlAttrSerializeTxtContent": "LIBXML_OUTPUT_ENABLED",
Packit 423ecb
    "xmlSAXParseFile": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlSAXParseEntity": "LIBXML_SAX1_ENABLED",
Packit 423ecb
    "xmlNewTextChild": "LIBXML_TREE_ENABLED",
Packit 423ecb
    "xmlNewDocRawNode": "LIBXML_TREE_ENABLED",
Packit 423ecb
    "xmlNewProp": "LIBXML_TREE_ENABLED",
Packit 423ecb
    "xmlReconciliateNs": "LIBXML_TREE_ENABLED",
Packit 423ecb
    "xmlValidateNCName": "LIBXML_TREE_ENABLED",
Packit 423ecb
    "xmlValidateNMToken": "LIBXML_TREE_ENABLED",
Packit 423ecb
    "xmlValidateName": "LIBXML_TREE_ENABLED",
Packit 423ecb
    "xmlNewChild": "LIBXML_TREE_ENABLED",
Packit 423ecb
    "xmlValidateQName": "LIBXML_TREE_ENABLED",
Packit 423ecb
    "xmlSprintfElementContent": "LIBXML_OUTPUT_ENABLED",
Packit 423ecb
    "xmlValidGetPotentialChildren" : "LIBXML_VALID_ENABLED",
Packit 423ecb
    "xmlValidGetValidElements" : "LIBXML_VALID_ENABLED",
Packit 423ecb
    "docbDefaultSAXHandlerInit" : "LIBXML_DOCB_ENABLED",
Packit 423ecb
    "xmlTextReaderPreservePattern" : "LIBXML_PATTERN_ENABLED",
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Some functions really need to be skipped for the tests.
Packit 423ecb
#
Packit 423ecb
skipped_functions = [
Packit 423ecb
# block on I/O
Packit 423ecb
"xmlFdRead", "xmlReadFd", "xmlCtxtReadFd",
Packit 423ecb
"htmlFdRead", "htmlReadFd", "htmlCtxtReadFd",
Packit 423ecb
"xmlReaderNewFd", "xmlReaderForFd",
Packit 423ecb
"xmlIORead", "xmlReadIO", "xmlCtxtReadIO",
Packit 423ecb
"htmlIORead", "htmlReadIO", "htmlCtxtReadIO",
Packit 423ecb
"xmlReaderNewIO", "xmlBufferDump", "xmlNanoFTPConnect",
Packit 423ecb
"xmlNanoFTPConnectTo", "xmlNanoHTTPMethod", "xmlNanoHTTPMethodRedir",
Packit 423ecb
# Complex I/O APIs
Packit 423ecb
"xmlCreateIOParserCtxt", "xmlParserInputBufferCreateIO",
Packit 423ecb
"xmlRegisterInputCallbacks", "xmlReaderForIO",
Packit 423ecb
"xmlOutputBufferCreateIO", "xmlRegisterOutputCallbacks",
Packit 423ecb
"xmlSaveToIO", "xmlIOHTTPOpenW",
Packit 423ecb
# library state cleanup, generate false leak informations and other
Packit 423ecb
# troubles, heavillyb tested otherwise.
Packit 423ecb
"xmlCleanupParser", "xmlRelaxNGCleanupTypes", "xmlSetListDoc",
Packit 423ecb
"xmlSetTreeDoc", "xmlUnlinkNode",
Packit 423ecb
# hard to avoid leaks in the tests
Packit 423ecb
"xmlStrcat", "xmlStrncat", "xmlCatalogAddLocal", "xmlNewTextWriterDoc",
Packit 423ecb
"xmlXPathNewValueTree", "xmlXPathWrapString",
Packit 423ecb
# unimplemented
Packit 423ecb
"xmlTextReaderReadInnerXml", "xmlTextReaderReadOuterXml",
Packit 423ecb
"xmlTextReaderReadString",
Packit 423ecb
# destructor
Packit 423ecb
"xmlListDelete", "xmlOutputBufferClose", "xmlNanoFTPClose", "xmlNanoHTTPClose",
Packit 423ecb
# deprecated
Packit 423ecb
"xmlCatalogGetPublic", "xmlCatalogGetSystem", "xmlEncodeEntities",
Packit 423ecb
"xmlNewGlobalNs", "xmlHandleEntity", "xmlNamespaceParseNCName",
Packit 423ecb
"xmlNamespaceParseNSDef", "xmlNamespaceParseQName",
Packit 423ecb
"xmlParseNamespace", "xmlParseQuotedString", "xmlParserHandleReference",
Packit 423ecb
"xmlScanName",
Packit 423ecb
"xmlDecodeEntities", 
Packit 423ecb
# allocators
Packit 423ecb
"xmlMemFree",
Packit 423ecb
# verbosity
Packit 423ecb
"xmlCatalogSetDebug", "xmlShellPrintXPathError", "xmlShellPrintNode",
Packit 423ecb
# Internal functions, no user space should really call them
Packit 423ecb
"xmlParseAttribute", "xmlParseAttributeListDecl", "xmlParseName",
Packit 423ecb
"xmlParseNmtoken", "xmlParseEntityValue", "xmlParseAttValue",
Packit 423ecb
"xmlParseSystemLiteral", "xmlParsePubidLiteral", "xmlParseCharData",
Packit 423ecb
"xmlParseExternalID", "xmlParseComment", "xmlParsePITarget", "xmlParsePI",
Packit 423ecb
"xmlParseNotationDecl", "xmlParseEntityDecl", "xmlParseDefaultDecl",
Packit 423ecb
"xmlParseNotationType", "xmlParseEnumerationType", "xmlParseEnumeratedType",
Packit 423ecb
"xmlParseAttributeType", "xmlParseAttributeListDecl",
Packit 423ecb
"xmlParseElementMixedContentDecl", "xmlParseElementChildrenContentDecl",
Packit 423ecb
"xmlParseElementContentDecl", "xmlParseElementDecl", "xmlParseMarkupDecl",
Packit 423ecb
"xmlParseCharRef", "xmlParseEntityRef", "xmlParseReference",
Packit 423ecb
"xmlParsePEReference", "xmlParseDocTypeDecl", "xmlParseAttribute",
Packit 423ecb
"xmlParseStartTag", "xmlParseEndTag", "xmlParseCDSect", "xmlParseContent",
Packit 423ecb
"xmlParseElement", "xmlParseVersionNum", "xmlParseVersionInfo",
Packit 423ecb
"xmlParseEncName", "xmlParseEncodingDecl", "xmlParseSDDecl",
Packit 423ecb
"xmlParseXMLDecl", "xmlParseTextDecl", "xmlParseMisc",
Packit 423ecb
"xmlParseExternalSubset", "xmlParserHandlePEReference",
Packit 423ecb
"xmlSkipBlankChars",
Packit 423ecb
]
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# These functions have side effects on the global state
Packit 423ecb
# and hence generate errors on memory allocation tests
Packit 423ecb
#
Packit 423ecb
skipped_memcheck = [ "xmlLoadCatalog", "xmlAddEncodingAlias",
Packit 423ecb
   "xmlSchemaInitTypes", "xmlNanoFTPProxy", "xmlNanoFTPScanProxy",
Packit 423ecb
   "xmlNanoHTTPScanProxy", "xmlResetLastError", "xmlCatalogConvert",
Packit 423ecb
   "xmlCatalogRemove", "xmlLoadCatalogs", "xmlCleanupCharEncodingHandlers",
Packit 423ecb
   "xmlInitCharEncodingHandlers", "xmlCatalogCleanup",
Packit 423ecb
   "xmlSchemaGetBuiltInType",
Packit 423ecb
   "htmlParseFile", "htmlCtxtReadFile", # loads the catalogs
Packit 423ecb
   "xmlTextReaderSchemaValidate", "xmlSchemaCleanupTypes", # initialize the schemas type system
Packit 423ecb
   "xmlCatalogResolve", "xmlIOParseDTD" # loads the catalogs
Packit 423ecb
]
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Extra code needed for some test cases
Packit 423ecb
#
Packit 423ecb
extra_pre_call = {
Packit 423ecb
   "xmlSAXUserParseFile": """
Packit 423ecb
#ifdef LIBXML_SAX1_ENABLED
Packit 423ecb
        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
Packit 423ecb
#endif
Packit 423ecb
""",
Packit 423ecb
   "xmlSAXUserParseMemory": """
Packit 423ecb
#ifdef LIBXML_SAX1_ENABLED
Packit 423ecb
        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
Packit 423ecb
#endif
Packit 423ecb
""",
Packit 423ecb
   "xmlParseBalancedChunkMemory": """
Packit 423ecb
#ifdef LIBXML_SAX1_ENABLED
Packit 423ecb
        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
Packit 423ecb
#endif
Packit 423ecb
""",
Packit 423ecb
   "xmlParseBalancedChunkMemoryRecover": """
Packit 423ecb
#ifdef LIBXML_SAX1_ENABLED
Packit 423ecb
        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
Packit 423ecb
#endif
Packit 423ecb
""",
Packit 423ecb
   "xmlParserInputBufferCreateFd":
Packit 423ecb
       "if (fd >= 0) fd = -1;",
Packit 423ecb
}
Packit 423ecb
extra_post_call = {
Packit 423ecb
   "xmlAddChild": 
Packit 423ecb
       "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
Packit 423ecb
   "xmlAddEntity":
Packit 423ecb
       "if (ret_val != NULL) { xmlFreeNode(ret_val) ; ret_val = NULL; }",
Packit 423ecb
   "xmlAddChildList": 
Packit 423ecb
       "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
Packit 423ecb
   "xmlAddSibling":
Packit 423ecb
       "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
Packit 423ecb
   "xmlAddNextSibling":
Packit 423ecb
       "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
Packit 423ecb
   "xmlAddPrevSibling": 
Packit 423ecb
       "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
Packit 423ecb
   "xmlDocSetRootElement": 
Packit 423ecb
       "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
Packit 423ecb
   "xmlReplaceNode": 
Packit 423ecb
       """if (cur != NULL) {
Packit 423ecb
              xmlUnlinkNode(cur);
Packit 423ecb
              xmlFreeNode(cur) ; cur = NULL ; }
Packit 423ecb
          if (old != NULL) {
Packit 423ecb
              xmlUnlinkNode(old);
Packit 423ecb
              xmlFreeNode(old) ; old = NULL ; }
Packit 423ecb
	  ret_val = NULL;""",
Packit 423ecb
   "xmlTextMerge": 
Packit 423ecb
       """if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
Packit 423ecb
              xmlUnlinkNode(second);
Packit 423ecb
              xmlFreeNode(second) ; second = NULL ; }""",
Packit 423ecb
   "xmlBuildQName": 
Packit 423ecb
       """if ((ret_val != NULL) && (ret_val != ncname) &&
Packit 423ecb
              (ret_val != prefix) && (ret_val != memory))
Packit 423ecb
              xmlFree(ret_val);
Packit 423ecb
	  ret_val = NULL;""",
Packit 423ecb
   "xmlNewDocElementContent":
Packit 423ecb
       """xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;""",
Packit 423ecb
   "xmlDictReference": "xmlDictFree(dict);",
Packit 423ecb
   # Functions which deallocates one of their parameters
Packit 423ecb
   "xmlXPathConvertBoolean": """val = NULL;""",
Packit 423ecb
   "xmlXPathConvertNumber": """val = NULL;""",
Packit 423ecb
   "xmlXPathConvertString": """val = NULL;""",
Packit 423ecb
   "xmlSaveFileTo": """buf = NULL;""",
Packit 423ecb
   "xmlSaveFormatFileTo": """buf = NULL;""",
Packit 423ecb
   "xmlIOParseDTD": "input = NULL;",
Packit 423ecb
   "xmlRemoveProp": "cur = NULL;",
Packit 423ecb
   "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
Packit 423ecb
   "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
Packit 423ecb
   "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
Packit 423ecb
   "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
Packit 423ecb
   "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
Packit 423ecb
   "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
Packit 423ecb
   "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Packit 423ecb
   "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Packit 423ecb
   "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Packit 423ecb
   "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Packit 423ecb
   "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Packit 423ecb
   "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
Packit 423ecb
   "xmlBufferSetAllocationScheme": "if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;}"
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
modules = []
Packit 423ecb
Packit 423ecb
def is_skipped_module(name):
Packit 423ecb
    for mod in skipped_modules:
Packit 423ecb
        if mod == name:
Packit 423ecb
	    return 1
Packit 423ecb
    return 0
Packit 423ecb
Packit 423ecb
def is_skipped_function(name):
Packit 423ecb
    for fun in skipped_functions:
Packit 423ecb
        if fun == name:
Packit 423ecb
	    return 1
Packit 423ecb
    # Do not test destructors
Packit 423ecb
    if string.find(name, 'Free') != -1:
Packit 423ecb
        return 1
Packit 423ecb
    return 0
Packit 423ecb
Packit 423ecb
def is_skipped_memcheck(name):
Packit 423ecb
    for fun in skipped_memcheck:
Packit 423ecb
        if fun == name:
Packit 423ecb
	    return 1
Packit 423ecb
    return 0
Packit 423ecb
Packit 423ecb
missing_types = {}
Packit 423ecb
def add_missing_type(name, func):
Packit 423ecb
    try:
Packit 423ecb
        list = missing_types[name]
Packit 423ecb
	list.append(func)
Packit 423ecb
    except:
Packit 423ecb
        missing_types[name] = [func]
Packit 423ecb
Packit 423ecb
generated_param_types = []
Packit 423ecb
def add_generated_param_type(name):
Packit 423ecb
    generated_param_types.append(name)
Packit 423ecb
Packit 423ecb
generated_return_types = []
Packit 423ecb
def add_generated_return_type(name):
Packit 423ecb
    generated_return_types.append(name)
Packit 423ecb
Packit 423ecb
missing_functions = {}
Packit 423ecb
missing_functions_nr = 0
Packit 423ecb
def add_missing_functions(name, module):
Packit 423ecb
    global missing_functions_nr
Packit 423ecb
Packit 423ecb
    missing_functions_nr = missing_functions_nr + 1
Packit 423ecb
    try:
Packit 423ecb
        list = missing_functions[module]
Packit 423ecb
	list.append(name)
Packit 423ecb
    except:
Packit 423ecb
        missing_functions[module] = [name]
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Provide the type generators and destructors for the parameters
Packit 423ecb
#
Packit 423ecb
Packit 423ecb
def type_convert(str, name, info, module, function, pos):
Packit 423ecb
#    res = string.replace(str, "    ", " ")
Packit 423ecb
#    res = string.replace(str, "   ", " ")
Packit 423ecb
#    res = string.replace(str, "  ", " ")
Packit 423ecb
    res = string.replace(str, " *", "_ptr")
Packit 423ecb
#    res = string.replace(str, "*", "_ptr")
Packit 423ecb
    res = string.replace(res, " ", "_")
Packit 423ecb
    if res == 'const_char_ptr':
Packit 423ecb
        if string.find(name, "file") != -1 or \
Packit 423ecb
           string.find(name, "uri") != -1 or \
Packit 423ecb
           string.find(name, "URI") != -1 or \
Packit 423ecb
           string.find(info, "filename") != -1 or \
Packit 423ecb
           string.find(info, "URI") != -1 or \
Packit 423ecb
           string.find(info, "URL") != -1:
Packit 423ecb
	    if string.find(function, "Save") != -1 or \
Packit 423ecb
	       string.find(function, "Create") != -1 or \
Packit 423ecb
	       string.find(function, "Write") != -1 or \
Packit 423ecb
	       string.find(function, "Fetch") != -1:
Packit 423ecb
	        return('fileoutput')
Packit 423ecb
	    return('filepath')
Packit 423ecb
    if res == 'void_ptr':
Packit 423ecb
        if module == 'nanoftp' and name == 'ctx':
Packit 423ecb
	    return('xmlNanoFTPCtxtPtr')
Packit 423ecb
        if function == 'xmlNanoFTPNewCtxt' or \
Packit 423ecb
	   function == 'xmlNanoFTPConnectTo' or \
Packit 423ecb
	   function == 'xmlNanoFTPOpen':
Packit 423ecb
	    return('xmlNanoFTPCtxtPtr')
Packit 423ecb
        if module == 'nanohttp' and name == 'ctx':
Packit 423ecb
	    return('xmlNanoHTTPCtxtPtr')
Packit 423ecb
	if function == 'xmlNanoHTTPMethod' or \
Packit 423ecb
	   function == 'xmlNanoHTTPMethodRedir' or \
Packit 423ecb
	   function == 'xmlNanoHTTPOpen' or \
Packit 423ecb
	   function == 'xmlNanoHTTPOpenRedir':
Packit 423ecb
	    return('xmlNanoHTTPCtxtPtr');
Packit 423ecb
        if function == 'xmlIOHTTPOpen':
Packit 423ecb
	    return('xmlNanoHTTPCtxtPtr')
Packit 423ecb
	if string.find(name, "data") != -1:
Packit 423ecb
	    return('userdata')
Packit 423ecb
	if string.find(name, "user") != -1:
Packit 423ecb
	    return('userdata')
Packit 423ecb
    if res == 'xmlDoc_ptr':
Packit 423ecb
        res = 'xmlDocPtr'
Packit 423ecb
    if res == 'xmlNode_ptr':
Packit 423ecb
        res = 'xmlNodePtr'
Packit 423ecb
    if res == 'xmlDict_ptr':
Packit 423ecb
        res = 'xmlDictPtr'
Packit 423ecb
    if res == 'xmlNodePtr' and pos != 0:
Packit 423ecb
        if (function == 'xmlAddChild' and pos == 2) or \
Packit 423ecb
	   (function == 'xmlAddChildList' and pos == 2) or \
Packit 423ecb
           (function == 'xmlAddNextSibling' and pos == 2) or \
Packit 423ecb
           (function == 'xmlAddSibling' and pos == 2) or \
Packit 423ecb
           (function == 'xmlDocSetRootElement' and pos == 2) or \
Packit 423ecb
           (function == 'xmlReplaceNode' and pos == 2) or \
Packit 423ecb
           (function == 'xmlTextMerge') or \
Packit 423ecb
	   (function == 'xmlAddPrevSibling' and pos == 2):
Packit 423ecb
	    return('xmlNodePtr_in');
Packit 423ecb
    if res == 'const xmlBufferPtr':
Packit 423ecb
        res = 'xmlBufferPtr'
Packit 423ecb
    if res == 'xmlChar_ptr' and name == 'name' and \
Packit 423ecb
       string.find(function, "EatName") != -1:
Packit 423ecb
        return('eaten_name')
Packit 423ecb
    if res == 'void_ptr*':
Packit 423ecb
        res = 'void_ptr_ptr'
Packit 423ecb
    if res == 'char_ptr*':
Packit 423ecb
        res = 'char_ptr_ptr'
Packit 423ecb
    if res == 'xmlChar_ptr*':
Packit 423ecb
        res = 'xmlChar_ptr_ptr'
Packit 423ecb
    if res == 'const_xmlChar_ptr*':
Packit 423ecb
        res = 'const_xmlChar_ptr_ptr'
Packit 423ecb
    if res == 'const_char_ptr*':
Packit 423ecb
        res = 'const_char_ptr_ptr'
Packit 423ecb
    if res == 'FILE_ptr' and module == 'debugXML':
Packit 423ecb
        res = 'debug_FILE_ptr';
Packit 423ecb
    if res == 'int' and name == 'options':
Packit 423ecb
        if module == 'parser' or module == 'xmlreader':
Packit 423ecb
	    res = 'parseroptions'
Packit 423ecb
Packit 423ecb
    return res
Packit 423ecb
Packit 423ecb
known_param_types = []
Packit 423ecb
Packit 423ecb
def is_known_param_type(name, rtype):
Packit 423ecb
    global test
Packit 423ecb
    for type in known_param_types:
Packit 423ecb
        if type == name:
Packit 423ecb
	    return 1
Packit 423ecb
    for type in generated_param_types:
Packit 423ecb
        if type == name:
Packit 423ecb
	    return 1
Packit 423ecb
Packit 423ecb
    if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
Packit 423ecb
        if rtype[0:6] == 'const ':
Packit 423ecb
	    crtype = rtype[6:]
Packit 423ecb
	else:
Packit 423ecb
	    crtype = rtype
Packit 423ecb
Packit 423ecb
        define = 0
Packit 423ecb
	if modules_defines.has_key(module):
Packit 423ecb
	    test.write("#ifdef %s\n" % (modules_defines[module]))
Packit 423ecb
	    define = 1
Packit 423ecb
        test.write("""
Packit 423ecb
#define gen_nb_%s 1
Packit 423ecb
static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
Packit 423ecb
    return(NULL);
Packit 423ecb
}
Packit 423ecb
static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
Packit 423ecb
}
Packit 423ecb
""" % (name, crtype, name, name, rtype))
Packit 423ecb
        if define == 1:
Packit 423ecb
	    test.write("#endif\n\n")
Packit 423ecb
        add_generated_param_type(name)
Packit 423ecb
        return 1
Packit 423ecb
Packit 423ecb
    return 0
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Provide the type destructors for the return values
Packit 423ecb
#
Packit 423ecb
Packit 423ecb
known_return_types = []
Packit 423ecb
Packit 423ecb
def is_known_return_type(name):
Packit 423ecb
    for type in known_return_types:
Packit 423ecb
        if type == name:
Packit 423ecb
	    return 1
Packit 423ecb
    return 0
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Copy the beginning of the C test program result
Packit 423ecb
#
Packit 423ecb
Packit 423ecb
try:
Packit 423ecb
    input = open("testapi.c", "r")
Packit 423ecb
except:
Packit 423ecb
    input = open(srcPref + "testapi.c", "r")
Packit 423ecb
test = open('testapi.c.new', 'w')
Packit 423ecb
Packit 423ecb
def compare_and_save():
Packit 423ecb
    global test
Packit 423ecb
Packit 423ecb
    test.close()
Packit 423ecb
    try:
Packit 423ecb
        input = open("testapi.c", "r").read()
Packit 423ecb
    except:
Packit 423ecb
        input = ''
Packit 423ecb
    test = open('testapi.c.new', "r").read()
Packit 423ecb
    if input != test:
Packit 423ecb
        try:
Packit 423ecb
            os.system("rm testapi.c; mv testapi.c.new testapi.c")
Packit 423ecb
        except:
Packit 423ecb
	    os.system("mv testapi.c.new testapi.c")
Packit 423ecb
        print("Updated testapi.c")
Packit 423ecb
    else:
Packit 423ecb
        print("Generated testapi.c is identical")
Packit 423ecb
Packit 423ecb
line = input.readline()
Packit 423ecb
while line != "":
Packit 423ecb
    if line == "/* CUT HERE: everything below that line is generated */\n":
Packit 423ecb
        break;
Packit 423ecb
    if line[0:15] == "#define gen_nb_":
Packit 423ecb
        type = string.split(line[15:])[0]
Packit 423ecb
	known_param_types.append(type)
Packit 423ecb
    if line[0:19] == "static void desret_":
Packit 423ecb
        type = string.split(line[19:], '(')[0]
Packit 423ecb
	known_return_types.append(type)
Packit 423ecb
    test.write(line)
Packit 423ecb
    line = input.readline()
Packit 423ecb
input.close()
Packit 423ecb
Packit 423ecb
if line == "":
Packit 423ecb
    print "Could not find the CUT marker in testapi.c skipping generation"
Packit 423ecb
    test.close()
Packit 423ecb
    sys.exit(0)
Packit 423ecb
Packit 423ecb
print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
Packit 423ecb
      len(known_param_types), len(known_return_types)))
Packit 423ecb
test.write("/* CUT HERE: everything below that line is generated */\n")
Packit 423ecb
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Open the input API description
Packit 423ecb
#
Packit 423ecb
doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Packit 423ecb
if doc == None:
Packit 423ecb
    print "Failed to load doc/libxml2-api.xml"
Packit 423ecb
    sys.exit(1)
Packit 423ecb
ctxt = doc.xpathNewContext()
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Generate a list of all function parameters and select only
Packit 423ecb
# those used in the api tests
Packit 423ecb
#
Packit 423ecb
argtypes = {}
Packit 423ecb
args = ctxt.xpathEval("/api/symbols/function/arg")
Packit 423ecb
for arg in args:
Packit 423ecb
    mod = arg.xpathEval('string(../@file)')
Packit 423ecb
    func = arg.xpathEval('string(../@name)')
Packit 423ecb
    if (mod not in skipped_modules) and (func not in skipped_functions):
Packit 423ecb
	type = arg.xpathEval('string(@type)')
Packit 423ecb
	if not argtypes.has_key(type):
Packit 423ecb
	    argtypes[type] = func
Packit 423ecb
Packit 423ecb
# similarly for return types
Packit 423ecb
rettypes = {}
Packit 423ecb
rets = ctxt.xpathEval("/api/symbols/function/return")
Packit 423ecb
for ret in rets:
Packit 423ecb
    mod = ret.xpathEval('string(../@file)')
Packit 423ecb
    func = ret.xpathEval('string(../@name)')
Packit 423ecb
    if (mod not in skipped_modules) and (func not in skipped_functions):
Packit 423ecb
        type = ret.xpathEval('string(@type)')
Packit 423ecb
	if not rettypes.has_key(type):
Packit 423ecb
	    rettypes[type] = func
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Generate constructors and return type handling for all enums
Packit 423ecb
# which are used as function parameters
Packit 423ecb
#
Packit 423ecb
enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
Packit 423ecb
for enum in enums:
Packit 423ecb
    module = enum.xpathEval('string(@file)')
Packit 423ecb
    name = enum.xpathEval('string(@name)')
Packit 423ecb
    #
Packit 423ecb
    # Skip any enums which are not in our filtered lists
Packit 423ecb
    #
Packit 423ecb
    if (name == None) or ((name not in argtypes) and (name not in rettypes)):
Packit 423ecb
        continue;
Packit 423ecb
    define = 0
Packit 423ecb
Packit 423ecb
    if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Packit 423ecb
	values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
Packit 423ecb
	i = 0
Packit 423ecb
	vals = []
Packit 423ecb
	for value in values:
Packit 423ecb
	    vname = value.xpathEval('string(@name)')
Packit 423ecb
	    if vname == None:
Packit 423ecb
		continue;
Packit 423ecb
	    i = i + 1
Packit 423ecb
	    if i >= 5:
Packit 423ecb
		break;
Packit 423ecb
	    vals.append(vname)
Packit 423ecb
	if vals == []:
Packit 423ecb
	    print "Didn't find any value for enum %s" % (name)
Packit 423ecb
	    continue
Packit 423ecb
	if modules_defines.has_key(module):
Packit 423ecb
	    test.write("#ifdef %s\n" % (modules_defines[module]))
Packit 423ecb
	    define = 1
Packit 423ecb
	test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
Packit 423ecb
	test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
Packit 423ecb
	           (name, name))
Packit 423ecb
	i = 1
Packit 423ecb
	for value in vals:
Packit 423ecb
	    test.write("    if (no == %d) return(%s);\n" % (i, value))
Packit 423ecb
	    i = i + 1
Packit 423ecb
	test.write("""    return(0);
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
""" % (name, name));
Packit 423ecb
	known_param_types.append(name)
Packit 423ecb
Packit 423ecb
    if (is_known_return_type(name) == 0) and (name in rettypes):
Packit 423ecb
	if define == 0 and modules_defines.has_key(module):
Packit 423ecb
	    test.write("#ifdef %s\n" % (modules_defines[module]))
Packit 423ecb
	    define = 1
Packit 423ecb
        test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
""" % (name, name))
Packit 423ecb
	known_return_types.append(name)
Packit 423ecb
    if define == 1:
Packit 423ecb
        test.write("#endif\n\n")
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Load the interfaces
Packit 423ecb
# 
Packit 423ecb
headers = ctxt.xpathEval("/api/files/file")
Packit 423ecb
for file in headers:
Packit 423ecb
    name = file.xpathEval('string(@name)')
Packit 423ecb
    if (name == None) or (name == ''):
Packit 423ecb
        continue
Packit 423ecb
Packit 423ecb
    #
Packit 423ecb
    # Some module may be skipped because they don't really consists
Packit 423ecb
    # of user callable APIs
Packit 423ecb
    #
Packit 423ecb
    if is_skipped_module(name):
Packit 423ecb
        continue
Packit 423ecb
Packit 423ecb
    #
Packit 423ecb
    # do not test deprecated APIs
Packit 423ecb
    #
Packit 423ecb
    desc = file.xpathEval('string(description)')
Packit 423ecb
    if string.find(desc, 'DEPRECATED') != -1:
Packit 423ecb
        print "Skipping deprecated interface %s" % name
Packit 423ecb
	continue;
Packit 423ecb
Packit 423ecb
    test.write("#include <libxml/%s.h>\n" % name)
Packit 423ecb
    modules.append(name)
Packit 423ecb
        
Packit 423ecb
#
Packit 423ecb
# Generate the callers signatures
Packit 423ecb
# 
Packit 423ecb
for module in modules:
Packit 423ecb
    test.write("static int test_%s(void);\n" % module);
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Generate the top caller
Packit 423ecb
# 
Packit 423ecb
Packit 423ecb
test.write("""
Packit 423ecb
/**
Packit 423ecb
 * testlibxml2:
Packit 423ecb
 *
Packit 423ecb
 * Main entry point of the tester for the full libxml2 module,
Packit 423ecb
 * it calls all the tester entry point for each module.
Packit 423ecb
 *
Packit 423ecb
 * Returns the number of error found
Packit 423ecb
 */
Packit 423ecb
static int
Packit 423ecb
testlibxml2(void)
Packit 423ecb
{
Packit 423ecb
    int test_ret = 0;
Packit 423ecb
Packit 423ecb
""")
Packit 423ecb
Packit 423ecb
for module in modules:
Packit 423ecb
    test.write("    test_ret += test_%s();\n" % module)
Packit 423ecb
Packit 423ecb
test.write("""
Packit 423ecb
    printf("Total: %d functions, %d tests, %d errors\\n",
Packit 423ecb
           function_tests, call_tests, test_ret);
Packit 423ecb
    return(test_ret);
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
""")
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# How to handle a function
Packit 423ecb
# 
Packit 423ecb
nb_tests = 0
Packit 423ecb
Packit 423ecb
def generate_test(module, node):
Packit 423ecb
    global test
Packit 423ecb
    global nb_tests
Packit 423ecb
    nb_cond = 0
Packit 423ecb
    no_gen = 0
Packit 423ecb
Packit 423ecb
    name = node.xpathEval('string(@name)')
Packit 423ecb
    if is_skipped_function(name):
Packit 423ecb
        return
Packit 423ecb
Packit 423ecb
    #
Packit 423ecb
    # check we know how to handle the args and return values
Packit 423ecb
    # and store the informations for the generation
Packit 423ecb
    #
Packit 423ecb
    try:
Packit 423ecb
	args = node.xpathEval("arg")
Packit 423ecb
    except:
Packit 423ecb
        args = []
Packit 423ecb
    t_args = []
Packit 423ecb
    n = 0
Packit 423ecb
    for arg in args:
Packit 423ecb
        n = n + 1
Packit 423ecb
        rtype = arg.xpathEval("string(@type)")
Packit 423ecb
	if rtype == 'void':
Packit 423ecb
	    break;
Packit 423ecb
	info = arg.xpathEval("string(@info)")
Packit 423ecb
	nam = arg.xpathEval("string(@name)")
Packit 423ecb
        type = type_convert(rtype, nam, info, module, name, n)
Packit 423ecb
	if is_known_param_type(type, rtype) == 0:
Packit 423ecb
	    add_missing_type(type, name);
Packit 423ecb
	    no_gen = 1
Packit 423ecb
        if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
Packit 423ecb
	    rtype[0:6] == 'const ':
Packit 423ecb
	    crtype = rtype[6:]
Packit 423ecb
	else:
Packit 423ecb
	    crtype = rtype
Packit 423ecb
	t_args.append((nam, type, rtype, crtype, info))
Packit 423ecb
    
Packit 423ecb
    try:
Packit 423ecb
	rets = node.xpathEval("return")
Packit 423ecb
    except:
Packit 423ecb
        rets = []
Packit 423ecb
    t_ret = None
Packit 423ecb
    for ret in rets:
Packit 423ecb
        rtype = ret.xpathEval("string(@type)")
Packit 423ecb
	info = ret.xpathEval("string(@info)")
Packit 423ecb
        type = type_convert(rtype, 'return', info, module, name, 0)
Packit 423ecb
	if rtype == 'void':
Packit 423ecb
	    break
Packit 423ecb
	if is_known_return_type(type) == 0:
Packit 423ecb
	    add_missing_type(type, name);
Packit 423ecb
	    no_gen = 1
Packit 423ecb
	t_ret = (type, rtype, info)
Packit 423ecb
	break
Packit 423ecb
Packit 423ecb
    test.write("""
Packit 423ecb
static int
Packit 423ecb
test_%s(void) {
Packit 423ecb
    int test_ret = 0;
Packit 423ecb
Packit 423ecb
""" % (name))
Packit 423ecb
Packit 423ecb
    if no_gen == 1:
Packit 423ecb
        add_missing_functions(name, module)
Packit 423ecb
	test.write("""
Packit 423ecb
    /* missing type support */
Packit 423ecb
    return(test_ret);
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
""")
Packit 423ecb
        return
Packit 423ecb
Packit 423ecb
    try:
Packit 423ecb
	conds = node.xpathEval("cond")
Packit 423ecb
	for cond in conds:
Packit 423ecb
	    test.write("#if %s\n" % (cond.get_content()))
Packit 423ecb
	    nb_cond = nb_cond + 1
Packit 423ecb
    except:
Packit 423ecb
        pass
Packit 423ecb
Packit 423ecb
    define = 0
Packit 423ecb
    if function_defines.has_key(name):
Packit 423ecb
        test.write("#ifdef %s\n" % (function_defines[name]))
Packit 423ecb
	define = 1
Packit 423ecb
    
Packit 423ecb
    # Declare the memory usage counter
Packit 423ecb
    no_mem = is_skipped_memcheck(name)
Packit 423ecb
    if no_mem == 0:
Packit 423ecb
	test.write("    int mem_base;\n");
Packit 423ecb
Packit 423ecb
    # Declare the return value
Packit 423ecb
    if t_ret != None:
Packit 423ecb
        test.write("    %s ret_val;\n" % (t_ret[1]))
Packit 423ecb
Packit 423ecb
    # Declare the arguments
Packit 423ecb
    for arg in t_args:
Packit 423ecb
        (nam, type, rtype, crtype, info) = arg;
Packit 423ecb
	# add declaration
Packit 423ecb
	test.write("    %s %s; /* %s */\n" % (crtype, nam, info))
Packit 423ecb
	test.write("    int n_%s;\n" % (nam))
Packit 423ecb
    test.write("\n")
Packit 423ecb
Packit 423ecb
    # Cascade loop on of each argument list of values
Packit 423ecb
    for arg in t_args:
Packit 423ecb
        (nam, type, rtype, crtype, info) = arg;
Packit 423ecb
	#
Packit 423ecb
	test.write("    for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
Packit 423ecb
	           nam, nam, type, nam))
Packit 423ecb
    
Packit 423ecb
    # log the memory usage
Packit 423ecb
    if no_mem == 0:
Packit 423ecb
	test.write("        mem_base = xmlMemBlocks();\n");
Packit 423ecb
Packit 423ecb
    # prepare the call
Packit 423ecb
    i = 0;
Packit 423ecb
    for arg in t_args:
Packit 423ecb
        (nam, type, rtype, crtype, info) = arg;
Packit 423ecb
	#
Packit 423ecb
	test.write("        %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
Packit 423ecb
	i = i + 1;
Packit 423ecb
Packit 423ecb
    # add checks to avoid out-of-bounds array access
Packit 423ecb
    i = 0;
Packit 423ecb
    for arg in t_args:
Packit 423ecb
        (nam, type, rtype, crtype, info) = arg;
Packit 423ecb
        # assume that "size", "len", and "start" parameters apply to either
Packit 423ecb
        # the nearest preceding or following char pointer
Packit 423ecb
        if type == "int" and (nam == "size" or nam == "len" or nam == "start"):
Packit 423ecb
            for j in range(i - 1, -1, -1) + range(i + 1, len(t_args)):
Packit 423ecb
                (bnam, btype) = t_args[j][:2]
Packit 423ecb
                if btype == "const_char_ptr" or btype == "const_xmlChar_ptr":
Packit 423ecb
                    test.write(
Packit 423ecb
                        "        if ((%s != NULL) &&\n"
Packit 423ecb
                        "            (%s > (int) strlen((const char *) %s) + 1))\n"
Packit 423ecb
                        "            continue;\n"
Packit 423ecb
                        % (bnam, nam, bnam))
Packit 423ecb
                    break
Packit 423ecb
	i = i + 1;
Packit 423ecb
Packit 423ecb
    # do the call, and clanup the result
Packit 423ecb
    if extra_pre_call.has_key(name):
Packit 423ecb
	test.write("        %s\n"% (extra_pre_call[name]))
Packit 423ecb
    if t_ret != None:
Packit 423ecb
	test.write("\n        ret_val = %s(" % (name))
Packit 423ecb
	need = 0
Packit 423ecb
	for arg in t_args:
Packit 423ecb
	    (nam, type, rtype, crtype, info) = arg
Packit 423ecb
	    if need:
Packit 423ecb
	        test.write(", ")
Packit 423ecb
	    else:
Packit 423ecb
	        need = 1
Packit 423ecb
	    if rtype != crtype:
Packit 423ecb
	        test.write("(%s)" % rtype)
Packit 423ecb
	    test.write("%s" % nam);
Packit 423ecb
	test.write(");\n")
Packit 423ecb
	if extra_post_call.has_key(name):
Packit 423ecb
	    test.write("        %s\n"% (extra_post_call[name]))
Packit 423ecb
	test.write("        desret_%s(ret_val);\n" % t_ret[0])
Packit 423ecb
    else:
Packit 423ecb
	test.write("\n        %s(" % (name));
Packit 423ecb
	need = 0;
Packit 423ecb
	for arg in t_args:
Packit 423ecb
	    (nam, type, rtype, crtype, info) = arg;
Packit 423ecb
	    if need:
Packit 423ecb
	        test.write(", ")
Packit 423ecb
	    else:
Packit 423ecb
	        need = 1
Packit 423ecb
	    if rtype != crtype:
Packit 423ecb
	        test.write("(%s)" % rtype)
Packit 423ecb
	    test.write("%s" % nam)
Packit 423ecb
	test.write(");\n")
Packit 423ecb
	if extra_post_call.has_key(name):
Packit 423ecb
	    test.write("        %s\n"% (extra_post_call[name]))
Packit 423ecb
Packit 423ecb
    test.write("        call_tests++;\n");
Packit 423ecb
Packit 423ecb
    # Free the arguments
Packit 423ecb
    i = 0;
Packit 423ecb
    for arg in t_args:
Packit 423ecb
        (nam, type, rtype, crtype, info) = arg;
Packit 423ecb
	# This is a hack to prevent generating a destructor for the
Packit 423ecb
	# 'input' argument in xmlTextReaderSetup.  There should be
Packit 423ecb
	# a better, more generic way to do this!
Packit 423ecb
	if string.find(info, 'destroy') == -1:
Packit 423ecb
	    test.write("        des_%s(n_%s, " % (type, nam))
Packit 423ecb
	    if rtype != crtype:
Packit 423ecb
	        test.write("(%s)" % rtype)
Packit 423ecb
	    test.write("%s, %d);\n" % (nam, i))
Packit 423ecb
	i = i + 1;
Packit 423ecb
Packit 423ecb
    test.write("        xmlResetLastError();\n");
Packit 423ecb
    # Check the memory usage
Packit 423ecb
    if no_mem == 0:
Packit 423ecb
	test.write("""        if (mem_base != xmlMemBlocks()) {
Packit 423ecb
            printf("Leak of %%d blocks found in %s",
Packit 423ecb
	           xmlMemBlocks() - mem_base);
Packit 423ecb
	    test_ret++;
Packit 423ecb
""" % (name));
Packit 423ecb
	for arg in t_args:
Packit 423ecb
	    (nam, type, rtype, crtype, info) = arg;
Packit 423ecb
	    test.write("""            printf(" %%d", n_%s);\n""" % (nam))
Packit 423ecb
	test.write("""            printf("\\n");\n""")
Packit 423ecb
	test.write("        }\n")
Packit 423ecb
Packit 423ecb
    for arg in t_args:
Packit 423ecb
	test.write("    }\n")
Packit 423ecb
Packit 423ecb
    test.write("    function_tests++;\n")
Packit 423ecb
    #
Packit 423ecb
    # end of conditional
Packit 423ecb
    #
Packit 423ecb
    while nb_cond > 0:
Packit 423ecb
        test.write("#endif\n")
Packit 423ecb
	nb_cond = nb_cond -1
Packit 423ecb
    if define == 1:
Packit 423ecb
        test.write("#endif\n")
Packit 423ecb
Packit 423ecb
    nb_tests = nb_tests + 1;
Packit 423ecb
Packit 423ecb
    test.write("""
Packit 423ecb
    return(test_ret);
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
""")
Packit 423ecb
    
Packit 423ecb
#
Packit 423ecb
# Generate all module callers
Packit 423ecb
#
Packit 423ecb
for module in modules:
Packit 423ecb
    # gather all the functions exported by that module
Packit 423ecb
    try:
Packit 423ecb
	functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
Packit 423ecb
    except:
Packit 423ecb
        print "Failed to gather functions from module %s" % (module)
Packit 423ecb
	continue;
Packit 423ecb
Packit 423ecb
    # iterate over all functions in the module generating the test
Packit 423ecb
    i = 0
Packit 423ecb
    nb_tests_old = nb_tests
Packit 423ecb
    for function in functions:
Packit 423ecb
        i = i + 1
Packit 423ecb
        generate_test(module, function);
Packit 423ecb
Packit 423ecb
    # header
Packit 423ecb
    test.write("""static int
Packit 423ecb
test_%s(void) {
Packit 423ecb
    int test_ret = 0;
Packit 423ecb
Packit 423ecb
    if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Packit 423ecb
""" % (module, module, nb_tests - nb_tests_old, i))
Packit 423ecb
Packit 423ecb
    # iterate over all functions in the module generating the call
Packit 423ecb
    for function in functions:
Packit 423ecb
        name = function.xpathEval('string(@name)')
Packit 423ecb
	if is_skipped_function(name):
Packit 423ecb
	    continue
Packit 423ecb
	test.write("    test_ret += test_%s();\n" % (name))
Packit 423ecb
Packit 423ecb
    # footer
Packit 423ecb
    test.write("""
Packit 423ecb
    if (test_ret != 0)
Packit 423ecb
	printf("Module %s: %%d errors\\n", test_ret);
Packit 423ecb
    return(test_ret);
Packit 423ecb
}
Packit 423ecb
""" % (module))
Packit 423ecb
Packit 423ecb
#
Packit 423ecb
# Generate direct module caller
Packit 423ecb
#
Packit 423ecb
test.write("""static int
Packit 423ecb
test_module(const char *module) {
Packit 423ecb
""");
Packit 423ecb
for module in modules:
Packit 423ecb
    test.write("""    if (!strcmp(module, "%s")) return(test_%s());\n""" % (
Packit 423ecb
        module, module))
Packit 423ecb
test.write("""    return(0);
Packit 423ecb
}
Packit 423ecb
""");
Packit 423ecb
Packit 423ecb
print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Packit 423ecb
Packit 423ecb
compare_and_save()
Packit 423ecb
Packit 423ecb
missing_list = []
Packit 423ecb
for missing in missing_types.keys():
Packit 423ecb
    if missing == 'va_list' or missing == '...':
Packit 423ecb
        continue;
Packit 423ecb
Packit 423ecb
    n = len(missing_types[missing])
Packit 423ecb
    missing_list.append((n, missing))
Packit 423ecb
Packit 423ecb
def compare_missing(a, b):
Packit 423ecb
    return b[0] - a[0]
Packit 423ecb
Packit 423ecb
missing_list.sort(compare_missing)
Packit 423ecb
print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Packit 423ecb
lst = open("missing.lst", "w")
Packit 423ecb
lst.write("Missing support for %d types" % (len(missing_list)))
Packit 423ecb
lst.write("\n")
Packit 423ecb
for miss in missing_list:
Packit 423ecb
    lst.write("%s: %d :" % (miss[1], miss[0]))
Packit 423ecb
    i = 0
Packit 423ecb
    for n in missing_types[miss[1]]:
Packit 423ecb
        i = i + 1
Packit 423ecb
        if i > 5:
Packit 423ecb
	    lst.write(" ...")
Packit 423ecb
	    break
Packit 423ecb
	lst.write(" %s" % (n))
Packit 423ecb
    lst.write("\n")
Packit 423ecb
lst.write("\n")
Packit 423ecb
lst.write("\n")
Packit 423ecb
lst.write("Missing support per module");
Packit 423ecb
for module in missing_functions.keys():
Packit 423ecb
    lst.write("module %s:\n   %s\n" % (module, missing_functions[module]))
Packit 423ecb
Packit 423ecb
lst.close()
Packit 423ecb
Packit 423ecb