blob: 88f88f18973b06c53f96975b7aebc812289f11bc [file] [log] [blame]
Daniel Veillard36e5cd52004-11-02 14:52:23 +00001#!/usr/bin/python -u
2#
3# generate a tester program for the API
4#
5import sys
Daniel Veillard34099b42004-11-04 17:34:35 +00006import os
Daniel Veillard36e5cd52004-11-02 14:52:23 +00007import string
8try:
9 import libxml2
10except:
11 print "libxml2 python bindings not available, skipping testapi.c generation"
12 sys.exit(0)
13
William M. Brack106cad62004-12-23 15:56:12 +000014if len(sys.argv) > 1:
15 srcPref = sys.argv[1] + '/'
16else:
17 srcPref = ''
18
Daniel Veillard36e5cd52004-11-02 14:52:23 +000019#
William M. Brack094dd862004-11-14 14:28:34 +000020# Modules we want to skip in API test
Daniel Veillard36e5cd52004-11-02 14:52:23 +000021#
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +000022skipped_modules = [ "SAX", "xlink", "threads", "globals",
Daniel Veillarda82b1822004-11-08 16:24:57 +000023 "xmlmemory", "xmlversion", "xmlexports",
24 #deprecated
25 "DOCBparser",
Daniel Veillardd005b9e2004-11-03 17:07:05 +000026]
Daniel Veillard36e5cd52004-11-02 14:52:23 +000027
28#
Daniel Veillarda521d282004-11-09 14:59:59 +000029# defines for each module
30#
31modules_defines = {
32 "HTMLparser": "LIBXML_HTML_ENABLED",
33 "catalog": "LIBXML_CATALOG_ENABLED",
34 "xmlreader": "LIBXML_READER_ENABLED",
35 "relaxng": "LIBXML_SCHEMAS_ENABLED",
36 "schemasInternals": "LIBXML_SCHEMAS_ENABLED",
37 "xmlschemas": "LIBXML_SCHEMAS_ENABLED",
38 "xmlschemastypes": "LIBXML_SCHEMAS_ENABLED",
39 "xpath": "LIBXML_XPATH_ENABLED",
40 "xpathInternals": "LIBXML_XPATH_ENABLED",
41 "xinclude": "LIBXML_XINCLUDE_ENABLED",
42 "xpointer": "LIBXML_XPTR_ENABLED",
43 "xmlregexp" : "LIBXML_REGEXP_ENABLED",
44 "xmlautomata" : "LIBXML_AUTOMATA_ENABLED",
45 "xmlsave" : "LIBXML_OUTPUT_ENABLED",
46 "DOCBparser" : "LIBXML_DOCB_ENABLED",
Daniel Veillardfc0b6f62005-01-09 17:48:02 +000047 "xmlmodule" : "LIBXML_MODULES_ENABLED",
William M. Brackba1d3172005-03-25 03:05:46 +000048 "pattern" : "LIBXML_PATTERN_ENABLED",
William M. Brackdc904f12005-10-22 02:04:26 +000049 "schematron" : "LIBXML_SCHEMATRON_ENABLED",
Daniel Veillarda521d282004-11-09 14:59:59 +000050}
51
52#
53# defines for specific functions
54#
55function_defines = {
56 "htmlDefaultSAXHandlerInit": "LIBXML_HTML_ENABLED",
57 "xmlSAX2EndElement" : "LIBXML_SAX1_ENABLED",
58 "xmlSAX2StartElement" : "LIBXML_SAX1_ENABLED",
59 "xmlSAXDefaultVersion" : "LIBXML_SAX1_ENABLED",
60 "UTF8Toisolat1" : "LIBXML_OUTPUT_ENABLED",
Daniel Veillarda521d282004-11-09 14:59:59 +000061 "xmlIOParseDTD": "LIBXML_VALID_ENABLED",
62 "xmlParseDTD": "LIBXML_VALID_ENABLED",
63 "xmlParseDoc": "LIBXML_SAX1_ENABLED",
64 "xmlParseMemory": "LIBXML_SAX1_ENABLED",
65 "xmlRecoverDoc": "LIBXML_SAX1_ENABLED",
66 "xmlParseFile": "LIBXML_SAX1_ENABLED",
67 "xmlRecoverFile": "LIBXML_SAX1_ENABLED",
68 "xmlRecoverMemory": "LIBXML_SAX1_ENABLED",
69 "xmlSAXParseFileWithData": "LIBXML_SAX1_ENABLED",
70 "xmlSAXParseMemory": "LIBXML_SAX1_ENABLED",
71 "xmlSAXUserParseMemory": "LIBXML_SAX1_ENABLED",
72 "xmlSAXParseDoc": "LIBXML_SAX1_ENABLED",
73 "xmlSAXParseDTD": "LIBXML_SAX1_ENABLED",
74 "xmlSAXUserParseFile": "LIBXML_SAX1_ENABLED",
75 "xmlParseEntity": "LIBXML_SAX1_ENABLED",
76 "xmlParseExternalEntity": "LIBXML_SAX1_ENABLED",
77 "xmlSAXParseMemoryWithData": "LIBXML_SAX1_ENABLED",
78 "xmlParseBalancedChunkMemory": "LIBXML_SAX1_ENABLED",
79 "xmlParseBalancedChunkMemoryRecover": "LIBXML_SAX1_ENABLED",
80 "xmlSetupParserForBuffer": "LIBXML_SAX1_ENABLED",
81 "xmlStopParser": "LIBXML_PUSH_ENABLED",
82 "xmlAttrSerializeTxtContent": "LIBXML_OUTPUT_ENABLED",
83 "xmlSAXParseFile": "LIBXML_SAX1_ENABLED",
84 "xmlSAXParseEntity": "LIBXML_SAX1_ENABLED",
85 "xmlNewTextChild": "LIBXML_TREE_ENABLED",
86 "xmlNewDocRawNode": "LIBXML_TREE_ENABLED",
87 "xmlNewProp": "LIBXML_TREE_ENABLED",
88 "xmlReconciliateNs": "LIBXML_TREE_ENABLED",
89 "xmlValidateNCName": "LIBXML_TREE_ENABLED",
90 "xmlValidateNMToken": "LIBXML_TREE_ENABLED",
91 "xmlValidateName": "LIBXML_TREE_ENABLED",
92 "xmlNewChild": "LIBXML_TREE_ENABLED",
93 "xmlValidateQName": "LIBXML_TREE_ENABLED",
94 "xmlSprintfElementContent": "LIBXML_OUTPUT_ENABLED",
95 "xmlValidGetPotentialChildren" : "LIBXML_VALID_ENABLED",
96 "xmlValidGetValidElements" : "LIBXML_VALID_ENABLED",
97 "docbDefaultSAXHandlerInit" : "LIBXML_DOCB_ENABLED",
Daniel Veillardd0cf7f62004-11-09 16:17:02 +000098 "xmlTextReaderPreservePattern" : "LIBXML_PATTERN_ENABLED",
Daniel Veillarda521d282004-11-09 14:59:59 +000099}
100
101#
William M. Brack094dd862004-11-14 14:28:34 +0000102# Some functions really need to be skipped for the tests.
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000103#
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000104skipped_functions = [
105# block on I/O
106"xmlFdRead", "xmlReadFd", "xmlCtxtReadFd",
107"htmlFdRead", "htmlReadFd", "htmlCtxtReadFd",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000108"xmlReaderNewFd", "xmlReaderForFd",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000109"xmlIORead", "xmlReadIO", "xmlCtxtReadIO",
110"htmlIORead", "htmlReadIO", "htmlCtxtReadIO",
Daniel Veillard27f20102004-11-05 11:50:11 +0000111"xmlReaderNewIO", "xmlBufferDump", "xmlNanoFTPConnect",
William M. Brack015ccb22005-02-13 08:18:52 +0000112"xmlNanoFTPConnectTo", "xmlNanoHTTPMethod", "xmlNanoHTTPMethodRedir",
Daniel Veillard42595322004-11-08 10:52:06 +0000113# Complex I/O APIs
114"xmlCreateIOParserCtxt", "xmlParserInputBufferCreateIO",
115"xmlRegisterInputCallbacks", "xmlReaderForIO",
116"xmlOutputBufferCreateIO", "xmlRegisterOutputCallbacks",
William M. Brack015ccb22005-02-13 08:18:52 +0000117"xmlSaveToIO", "xmlIOHTTPOpenW",
Haibo Huangcfd91dc2020-07-30 23:01:33 -0700118# library state cleanup, generate false leak information and other
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000119# troubles, heavillyb tested otherwise.
Daniel Veillardce244ad2004-11-05 10:03:46 +0000120"xmlCleanupParser", "xmlRelaxNGCleanupTypes", "xmlSetListDoc",
121"xmlSetTreeDoc", "xmlUnlinkNode",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000122# hard to avoid leaks in the tests
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000123"xmlStrcat", "xmlStrncat", "xmlCatalogAddLocal", "xmlNewTextWriterDoc",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000124"xmlXPathNewValueTree", "xmlXPathWrapString",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000125# unimplemented
126"xmlTextReaderReadInnerXml", "xmlTextReaderReadOuterXml",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000127"xmlTextReaderReadString",
128# destructor
William M. Brack015ccb22005-02-13 08:18:52 +0000129"xmlListDelete", "xmlOutputBufferClose", "xmlNanoFTPClose", "xmlNanoHTTPClose",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000130# deprecated
131"xmlCatalogGetPublic", "xmlCatalogGetSystem", "xmlEncodeEntities",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000132"xmlNewGlobalNs", "xmlHandleEntity", "xmlNamespaceParseNCName",
133"xmlNamespaceParseNSDef", "xmlNamespaceParseQName",
134"xmlParseNamespace", "xmlParseQuotedString", "xmlParserHandleReference",
135"xmlScanName",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000136"xmlDecodeEntities",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000137# allocators
138"xmlMemFree",
Daniel Veillardc2c894f2004-11-07 12:17:35 +0000139# verbosity
Daniel Veillarda82b1822004-11-08 16:24:57 +0000140"xmlCatalogSetDebug", "xmlShellPrintXPathError", "xmlShellPrintNode",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000141# Internal functions, no user space should really call them
142"xmlParseAttribute", "xmlParseAttributeListDecl", "xmlParseName",
143"xmlParseNmtoken", "xmlParseEntityValue", "xmlParseAttValue",
144"xmlParseSystemLiteral", "xmlParsePubidLiteral", "xmlParseCharData",
145"xmlParseExternalID", "xmlParseComment", "xmlParsePITarget", "xmlParsePI",
146"xmlParseNotationDecl", "xmlParseEntityDecl", "xmlParseDefaultDecl",
147"xmlParseNotationType", "xmlParseEnumerationType", "xmlParseEnumeratedType",
148"xmlParseAttributeType", "xmlParseAttributeListDecl",
149"xmlParseElementMixedContentDecl", "xmlParseElementChildrenContentDecl",
150"xmlParseElementContentDecl", "xmlParseElementDecl", "xmlParseMarkupDecl",
151"xmlParseCharRef", "xmlParseEntityRef", "xmlParseReference",
152"xmlParsePEReference", "xmlParseDocTypeDecl", "xmlParseAttribute",
153"xmlParseStartTag", "xmlParseEndTag", "xmlParseCDSect", "xmlParseContent",
154"xmlParseElement", "xmlParseVersionNum", "xmlParseVersionInfo",
155"xmlParseEncName", "xmlParseEncodingDecl", "xmlParseSDDecl",
156"xmlParseXMLDecl", "xmlParseTextDecl", "xmlParseMisc",
157"xmlParseExternalSubset", "xmlParserHandlePEReference",
158"xmlSkipBlankChars",
Elliott Hughesecdab2a2022-02-23 14:33:50 -0800159# Legacy
160"xmlCleanupPredefinedEntities", "xmlInitializePredefinedEntities",
161"xmlSetFeature", "xmlGetFeature", "xmlGetFeaturesList",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000162]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000163
164#
William M. Brack094dd862004-11-14 14:28:34 +0000165# These functions have side effects on the global state
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000166# and hence generate errors on memory allocation tests
167#
168skipped_memcheck = [ "xmlLoadCatalog", "xmlAddEncodingAlias",
169 "xmlSchemaInitTypes", "xmlNanoFTPProxy", "xmlNanoFTPScanProxy",
170 "xmlNanoHTTPScanProxy", "xmlResetLastError", "xmlCatalogConvert",
171 "xmlCatalogRemove", "xmlLoadCatalogs", "xmlCleanupCharEncodingHandlers",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000172 "xmlInitCharEncodingHandlers", "xmlCatalogCleanup",
Daniel Veillard42595322004-11-08 10:52:06 +0000173 "xmlSchemaGetBuiltInType",
Daniel Veillard1f33c4d2005-07-10 21:38:31 +0000174 "htmlParseFile", "htmlCtxtReadFile", # loads the catalogs
Daniel Veillard34e3f642008-07-29 09:02:27 +0000175 "xmlTextReaderSchemaValidate", "xmlSchemaCleanupTypes", # initialize the schemas type system
176 "xmlCatalogResolve", "xmlIOParseDTD" # loads the catalogs
Daniel Veillarda03e3652004-11-02 18:45:30 +0000177]
178
179#
180# Extra code needed for some test cases
181#
Daniel Veillard34099b42004-11-04 17:34:35 +0000182extra_pre_call = {
Daniel Veillarda521d282004-11-09 14:59:59 +0000183 "xmlSAXUserParseFile": """
184#ifdef LIBXML_SAX1_ENABLED
185 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
186#endif
187""",
188 "xmlSAXUserParseMemory": """
189#ifdef LIBXML_SAX1_ENABLED
190 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
191#endif
192""",
193 "xmlParseBalancedChunkMemory": """
194#ifdef LIBXML_SAX1_ENABLED
195 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
196#endif
197""",
198 "xmlParseBalancedChunkMemoryRecover": """
199#ifdef LIBXML_SAX1_ENABLED
200 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
201#endif
202""",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000203 "xmlParserInputBufferCreateFd":
204 "if (fd >= 0) fd = -1;",
Daniel Veillard34099b42004-11-04 17:34:35 +0000205}
Daniel Veillarda03e3652004-11-02 18:45:30 +0000206extra_post_call = {
207 "xmlAddChild":
208 "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
Daniel Veillard2cba4152008-08-27 11:45:41 +0000209 "xmlAddEntity":
210 "if (ret_val != NULL) { xmlFreeNode(ret_val) ; ret_val = NULL; }",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000211 "xmlAddChildList":
212 "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
213 "xmlAddSibling":
214 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
215 "xmlAddNextSibling":
216 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
217 "xmlAddPrevSibling":
218 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
219 "xmlDocSetRootElement":
220 "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
221 "xmlReplaceNode":
Daniel Veillardce244ad2004-11-05 10:03:46 +0000222 """if (cur != NULL) {
223 xmlUnlinkNode(cur);
224 xmlFreeNode(cur) ; cur = NULL ; }
225 if (old != NULL) {
226 xmlUnlinkNode(old);
227 xmlFreeNode(old) ; old = NULL ; }
228 ret_val = NULL;""",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000229 "xmlTextMerge":
230 """if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
Daniel Veillardce244ad2004-11-05 10:03:46 +0000231 xmlUnlinkNode(second);
Daniel Veillarda03e3652004-11-02 18:45:30 +0000232 xmlFreeNode(second) ; second = NULL ; }""",
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000233 "xmlBuildQName":
234 """if ((ret_val != NULL) && (ret_val != ncname) &&
235 (ret_val != prefix) && (ret_val != memory))
236 xmlFree(ret_val);
237 ret_val = NULL;""",
Daniel Veillardc394f732005-01-26 00:04:52 +0000238 "xmlNewDocElementContent":
239 """xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;""",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000240 "xmlDictReference": "xmlDictFree(dict);",
Daniel Veillard3d97e662004-11-04 10:49:00 +0000241 # Functions which deallocates one of their parameters
242 "xmlXPathConvertBoolean": """val = NULL;""",
243 "xmlXPathConvertNumber": """val = NULL;""",
244 "xmlXPathConvertString": """val = NULL;""",
245 "xmlSaveFileTo": """buf = NULL;""",
Daniel Veillard34099b42004-11-04 17:34:35 +0000246 "xmlSaveFormatFileTo": """buf = NULL;""",
247 "xmlIOParseDTD": "input = NULL;",
Daniel Veillardce244ad2004-11-05 10:03:46 +0000248 "xmlRemoveProp": "cur = NULL;",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000249 "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
250 "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
251 "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
252 "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000253 "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
Daniel Veillard42595322004-11-08 10:52:06 +0000254 "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000255 "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
256 "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
257 "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
258 "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
259 "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Daniel Veillard7e33dba2005-07-03 22:40:26 +0000260 "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
Daniel Veillardda3fee42008-09-01 13:08:57 +0000261 "xmlBufferSetAllocationScheme": "if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;}"
Daniel Veillarda03e3652004-11-02 18:45:30 +0000262}
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000263
264modules = []
265
266def is_skipped_module(name):
267 for mod in skipped_modules:
268 if mod == name:
269 return 1
270 return 0
271
272def is_skipped_function(name):
273 for fun in skipped_functions:
274 if fun == name:
275 return 1
276 # Do not test destructors
277 if string.find(name, 'Free') != -1:
278 return 1
279 return 0
280
281def is_skipped_memcheck(name):
282 for fun in skipped_memcheck:
283 if fun == name:
284 return 1
285 return 0
286
287missing_types = {}
288def add_missing_type(name, func):
289 try:
290 list = missing_types[name]
291 list.append(func)
292 except:
293 missing_types[name] = [func]
294
Daniel Veillardce682bc2004-11-05 17:22:25 +0000295generated_param_types = []
296def add_generated_param_type(name):
297 generated_param_types.append(name)
298
299generated_return_types = []
300def add_generated_return_type(name):
301 generated_return_types.append(name)
302
Daniel Veillard34099b42004-11-04 17:34:35 +0000303missing_functions = {}
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000304missing_functions_nr = 0
Daniel Veillard34099b42004-11-04 17:34:35 +0000305def add_missing_functions(name, module):
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000306 global missing_functions_nr
307
308 missing_functions_nr = missing_functions_nr + 1
Daniel Veillard34099b42004-11-04 17:34:35 +0000309 try:
310 list = missing_functions[module]
311 list.append(name)
312 except:
313 missing_functions[module] = [name]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000314
315#
316# Provide the type generators and destructors for the parameters
317#
318
Daniel Veillarda03e3652004-11-02 18:45:30 +0000319def type_convert(str, name, info, module, function, pos):
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000320# res = string.replace(str, " ", " ")
321# res = string.replace(str, " ", " ")
322# res = string.replace(str, " ", " ")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000323 res = string.replace(str, " *", "_ptr")
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000324# res = string.replace(str, "*", "_ptr")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000325 res = string.replace(res, " ", "_")
326 if res == 'const_char_ptr':
327 if string.find(name, "file") != -1 or \
328 string.find(name, "uri") != -1 or \
329 string.find(name, "URI") != -1 or \
330 string.find(info, "filename") != -1 or \
331 string.find(info, "URI") != -1 or \
332 string.find(info, "URL") != -1:
William M. Brack83d9c372004-11-08 02:26:08 +0000333 if string.find(function, "Save") != -1 or \
334 string.find(function, "Create") != -1 or \
William M. Brack015ccb22005-02-13 08:18:52 +0000335 string.find(function, "Write") != -1 or \
336 string.find(function, "Fetch") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000337 return('fileoutput')
338 return('filepath')
339 if res == 'void_ptr':
340 if module == 'nanoftp' and name == 'ctx':
341 return('xmlNanoFTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000342 if function == 'xmlNanoFTPNewCtxt' or \
343 function == 'xmlNanoFTPConnectTo' or \
344 function == 'xmlNanoFTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000345 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000346 if module == 'nanohttp' and name == 'ctx':
347 return('xmlNanoHTTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000348 if function == 'xmlNanoHTTPMethod' or \
349 function == 'xmlNanoHTTPMethodRedir' or \
350 function == 'xmlNanoHTTPOpen' or \
351 function == 'xmlNanoHTTPOpenRedir':
352 return('xmlNanoHTTPCtxtPtr');
353 if function == 'xmlIOHTTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000354 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000355 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000356 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000357 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000358 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000359 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000360 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000361 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000362 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000363 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000364 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000365 if res == 'xmlNodePtr' and pos != 0:
366 if (function == 'xmlAddChild' and pos == 2) or \
367 (function == 'xmlAddChildList' and pos == 2) or \
368 (function == 'xmlAddNextSibling' and pos == 2) or \
369 (function == 'xmlAddSibling' and pos == 2) or \
370 (function == 'xmlDocSetRootElement' and pos == 2) or \
371 (function == 'xmlReplaceNode' and pos == 2) or \
372 (function == 'xmlTextMerge') or \
373 (function == 'xmlAddPrevSibling' and pos == 2):
374 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000375 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000376 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000377 if res == 'xmlChar_ptr' and name == 'name' and \
378 string.find(function, "EatName") != -1:
379 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000380 if res == 'void_ptr*':
381 res = 'void_ptr_ptr'
382 if res == 'char_ptr*':
383 res = 'char_ptr_ptr'
384 if res == 'xmlChar_ptr*':
385 res = 'xmlChar_ptr_ptr'
386 if res == 'const_xmlChar_ptr*':
387 res = 'const_xmlChar_ptr_ptr'
388 if res == 'const_char_ptr*':
389 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000390 if res == 'FILE_ptr' and module == 'debugXML':
391 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000392 if res == 'int' and name == 'options':
393 if module == 'parser' or module == 'xmlreader':
394 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000395
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000396 return res
397
Daniel Veillard34099b42004-11-04 17:34:35 +0000398known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000399
Haibo Huangcfd91dc2020-07-30 23:01:33 -0700400def is_known_param_type(name):
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000401 for type in known_param_types:
402 if type == name:
403 return 1
Haibo Huangcfd91dc2020-07-30 23:01:33 -0700404 return name[-3:] == 'Ptr' or name[-4:] == '_ptr'
405
406def generate_param_type(name, rtype):
407 global test
408 for type in known_param_types:
409 if type == name:
410 return
Daniel Veillardce682bc2004-11-05 17:22:25 +0000411 for type in generated_param_types:
412 if type == name:
Haibo Huangcfd91dc2020-07-30 23:01:33 -0700413 return
Daniel Veillardce682bc2004-11-05 17:22:25 +0000414
415 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
416 if rtype[0:6] == 'const ':
417 crtype = rtype[6:]
418 else:
419 crtype = rtype
420
Daniel Veillarda521d282004-11-09 14:59:59 +0000421 define = 0
422 if modules_defines.has_key(module):
423 test.write("#ifdef %s\n" % (modules_defines[module]))
424 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000425 test.write("""
426#define gen_nb_%s 1
427static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
428 return(NULL);
429}
430static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
431}
432""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000433 if define == 1:
434 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000435 add_generated_param_type(name)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000436
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000437#
438# Provide the type destructors for the return values
439#
440
Daniel Veillard34099b42004-11-04 17:34:35 +0000441known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000442
443def is_known_return_type(name):
444 for type in known_return_types:
445 if type == name:
446 return 1
447 return 0
448
Daniel Veillard34099b42004-11-04 17:34:35 +0000449#
450# Copy the beginning of the C test program result
451#
452
William M. Brack106cad62004-12-23 15:56:12 +0000453try:
454 input = open("testapi.c", "r")
455except:
456 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000457test = open('testapi.c.new', 'w')
458
459def compare_and_save():
460 global test
461
462 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000463 try:
464 input = open("testapi.c", "r").read()
465 except:
466 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000467 test = open('testapi.c.new', "r").read()
468 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000469 try:
470 os.system("rm testapi.c; mv testapi.c.new testapi.c")
471 except:
472 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000473 print("Updated testapi.c")
474 else:
475 print("Generated testapi.c is identical")
476
477line = input.readline()
478while line != "":
479 if line == "/* CUT HERE: everything below that line is generated */\n":
480 break;
481 if line[0:15] == "#define gen_nb_":
482 type = string.split(line[15:])[0]
483 known_param_types.append(type)
484 if line[0:19] == "static void desret_":
485 type = string.split(line[19:], '(')[0]
486 known_return_types.append(type)
487 test.write(line)
488 line = input.readline()
489input.close()
490
491if line == "":
492 print "Could not find the CUT marker in testapi.c skipping generation"
493 test.close()
494 sys.exit(0)
495
496print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
497 len(known_param_types), len(known_return_types)))
498test.write("/* CUT HERE: everything below that line is generated */\n")
499
500
501#
502# Open the input API description
503#
William M. Brack106cad62004-12-23 15:56:12 +0000504doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000505if doc == None:
506 print "Failed to load doc/libxml2-api.xml"
507 sys.exit(1)
508ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000509
510#
William M. Brack094dd862004-11-14 14:28:34 +0000511# Generate a list of all function parameters and select only
512# those used in the api tests
513#
514argtypes = {}
515args = ctxt.xpathEval("/api/symbols/function/arg")
516for arg in args:
517 mod = arg.xpathEval('string(../@file)')
518 func = arg.xpathEval('string(../@name)')
519 if (mod not in skipped_modules) and (func not in skipped_functions):
520 type = arg.xpathEval('string(@type)')
521 if not argtypes.has_key(type):
522 argtypes[type] = func
523
524# similarly for return types
525rettypes = {}
526rets = ctxt.xpathEval("/api/symbols/function/return")
527for ret in rets:
528 mod = ret.xpathEval('string(../@file)')
529 func = ret.xpathEval('string(../@name)')
530 if (mod not in skipped_modules) and (func not in skipped_functions):
531 type = ret.xpathEval('string(@type)')
532 if not rettypes.has_key(type):
533 rettypes[type] = func
534
535#
Daniel Veillard57b25162004-11-06 14:50:18 +0000536# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000537# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000538#
539enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
540for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000541 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000542 name = enum.xpathEval('string(@name)')
543 #
544 # Skip any enums which are not in our filtered lists
545 #
546 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
547 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000548 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000549
Haibo Huangcfd91dc2020-07-30 23:01:33 -0700550 if argtypes.has_key(name) and is_known_param_type(name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000551 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
552 i = 0
553 vals = []
554 for value in values:
555 vname = value.xpathEval('string(@name)')
556 if vname == None:
557 continue;
558 i = i + 1
559 if i >= 5:
560 break;
561 vals.append(vname)
562 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000563 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000564 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000565 if modules_defines.has_key(module):
566 test.write("#ifdef %s\n" % (modules_defines[module]))
567 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000568 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
569 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
570 (name, name))
571 i = 1
572 for value in vals:
573 test.write(" if (no == %d) return(%s);\n" % (i, value))
574 i = i + 1
575 test.write(""" return(0);
576}
William M. Brack094dd862004-11-14 14:28:34 +0000577
578static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
579}
580
581""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000582 known_param_types.append(name)
583
William M. Brack094dd862004-11-14 14:28:34 +0000584 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000585 if define == 0 and modules_defines.has_key(module):
586 test.write("#ifdef %s\n" % (modules_defines[module]))
587 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000588 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000589}
590
William M. Brack094dd862004-11-14 14:28:34 +0000591""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000592 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000593 if define == 1:
594 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000595
596#
597# Load the interfaces
598#
Daniel Veillard57b25162004-11-06 14:50:18 +0000599headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000600for file in headers:
601 name = file.xpathEval('string(@name)')
602 if (name == None) or (name == ''):
603 continue
604
605 #
606 # Some module may be skipped because they don't really consists
607 # of user callable APIs
608 #
609 if is_skipped_module(name):
610 continue
611
612 #
613 # do not test deprecated APIs
614 #
615 desc = file.xpathEval('string(description)')
616 if string.find(desc, 'DEPRECATED') != -1:
617 print "Skipping deprecated interface %s" % name
618 continue;
619
620 test.write("#include <libxml/%s.h>\n" % name)
621 modules.append(name)
622
623#
624# Generate the callers signatures
625#
626for module in modules:
627 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000628
629#
630# Generate the top caller
631#
632
633test.write("""
634/**
635 * testlibxml2:
636 *
637 * Main entry point of the tester for the full libxml2 module,
638 * it calls all the tester entry point for each module.
639 *
640 * Returns the number of error found
641 */
642static int
643testlibxml2(void)
644{
Daniel Veillard42595322004-11-08 10:52:06 +0000645 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000646
647""")
648
649for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000650 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000651
652test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000653 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000654 function_tests, call_tests, test_ret);
655 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000656}
657
658""")
659
660#
661# How to handle a function
662#
663nb_tests = 0
664
665def generate_test(module, node):
666 global test
667 global nb_tests
668 nb_cond = 0
669 no_gen = 0
670
671 name = node.xpathEval('string(@name)')
672 if is_skipped_function(name):
673 return
674
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000675 #
676 # check we know how to handle the args and return values
Haibo Huangcfd91dc2020-07-30 23:01:33 -0700677 # and store the information for the generation
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000678 #
679 try:
680 args = node.xpathEval("arg")
681 except:
682 args = []
683 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000684 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000685 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000686 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000687 rtype = arg.xpathEval("string(@type)")
688 if rtype == 'void':
689 break;
690 info = arg.xpathEval("string(@info)")
691 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000692 type = type_convert(rtype, nam, info, module, name, n)
Haibo Huangcfd91dc2020-07-30 23:01:33 -0700693 if is_known_param_type(type) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000694 add_missing_type(type, name);
695 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000696 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
697 rtype[0:6] == 'const ':
698 crtype = rtype[6:]
699 else:
700 crtype = rtype
701 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000702
703 try:
704 rets = node.xpathEval("return")
705 except:
706 rets = []
707 t_ret = None
708 for ret in rets:
709 rtype = ret.xpathEval("string(@type)")
710 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000711 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000712 if rtype == 'void':
713 break
714 if is_known_return_type(type) == 0:
715 add_missing_type(type, name);
716 no_gen = 1
717 t_ret = (type, rtype, info)
718 break
719
Haibo Huangcfd91dc2020-07-30 23:01:33 -0700720 if no_gen == 0:
721 for t_arg in t_args:
722 (nam, type, rtype, crtype, info) = t_arg
723 generate_param_type(type, rtype)
724
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000725 test.write("""
726static int
727test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000728 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000729
730""" % (name))
731
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000732 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000733 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000734 test.write("""
735 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000736 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000737}
738
739""")
740 return
741
742 try:
743 conds = node.xpathEval("cond")
744 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000745 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000746 nb_cond = nb_cond + 1
747 except:
748 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000749
750 define = 0
751 if function_defines.has_key(name):
752 test.write("#ifdef %s\n" % (function_defines[name]))
753 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000754
755 # Declare the memory usage counter
756 no_mem = is_skipped_memcheck(name)
757 if no_mem == 0:
758 test.write(" int mem_base;\n");
759
760 # Declare the return value
761 if t_ret != None:
762 test.write(" %s ret_val;\n" % (t_ret[1]))
763
764 # Declare the arguments
765 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000766 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000767 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000768 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000769 test.write(" int n_%s;\n" % (nam))
770 test.write("\n")
771
772 # Cascade loop on of each argument list of values
773 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000774 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000775 #
776 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
777 nam, nam, type, nam))
778
779 # log the memory usage
780 if no_mem == 0:
781 test.write(" mem_base = xmlMemBlocks();\n");
782
783 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000784 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000785 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000786 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000787 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000788 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
789 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000790
Nick Wellnhoferff34ba32017-05-31 18:53:45 +0200791 # add checks to avoid out-of-bounds array access
792 i = 0;
793 for arg in t_args:
794 (nam, type, rtype, crtype, info) = arg;
795 # assume that "size", "len", and "start" parameters apply to either
796 # the nearest preceding or following char pointer
797 if type == "int" and (nam == "size" or nam == "len" or nam == "start"):
798 for j in range(i - 1, -1, -1) + range(i + 1, len(t_args)):
799 (bnam, btype) = t_args[j][:2]
800 if btype == "const_char_ptr" or btype == "const_xmlChar_ptr":
801 test.write(
802 " if ((%s != NULL) &&\n"
803 " (%s > (int) strlen((const char *) %s) + 1))\n"
804 " continue;\n"
805 % (bnam, nam, bnam))
806 break
807 i = i + 1;
808
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000809 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000810 if extra_pre_call.has_key(name):
811 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000812 if t_ret != None:
813 test.write("\n ret_val = %s(" % (name))
814 need = 0
815 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000816 (nam, type, rtype, crtype, info) = arg
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000817 if need:
818 test.write(", ")
819 else:
820 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000821 if rtype != crtype:
822 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000823 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000824 test.write(");\n")
825 if extra_post_call.has_key(name):
826 test.write(" %s\n"% (extra_post_call[name]))
827 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000828 else:
829 test.write("\n %s(" % (name));
830 need = 0;
831 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000832 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000833 if need:
834 test.write(", ")
835 else:
836 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000837 if rtype != crtype:
838 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000839 test.write("%s" % nam)
840 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000841 if extra_post_call.has_key(name):
842 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000843
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000844 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000845
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000846 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000847 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000848 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000849 (nam, type, rtype, crtype, info) = arg;
William M. Brackd46c1ca2007-02-08 23:34:34 +0000850 # This is a hack to prevent generating a destructor for the
851 # 'input' argument in xmlTextReaderSetup. There should be
852 # a better, more generic way to do this!
853 if string.find(info, 'destroy') == -1:
854 test.write(" des_%s(n_%s, " % (type, nam))
855 if rtype != crtype:
856 test.write("(%s)" % rtype)
857 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000858 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000859
860 test.write(" xmlResetLastError();\n");
861 # Check the memory usage
862 if no_mem == 0:
863 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000864 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000865 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000866 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000867""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000868 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000869 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000870 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
871 test.write(""" printf("\\n");\n""")
872 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000873
874 for arg in t_args:
875 test.write(" }\n")
876
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000877 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000878 #
879 # end of conditional
880 #
881 while nb_cond > 0:
882 test.write("#endif\n")
883 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000884 if define == 1:
885 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000886
887 nb_tests = nb_tests + 1;
888
889 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000890 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000891}
892
893""")
894
895#
896# Generate all module callers
897#
898for module in modules:
899 # gather all the functions exported by that module
900 try:
901 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
902 except:
903 print "Failed to gather functions from module %s" % (module)
904 continue;
905
906 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000907 i = 0
908 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000909 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000910 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000911 generate_test(module, function);
912
913 # header
914 test.write("""static int
915test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000916 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000917
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000918 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000919""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000920
921 # iterate over all functions in the module generating the call
922 for function in functions:
923 name = function.xpathEval('string(@name)')
924 if is_skipped_function(name):
925 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000926 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000927
928 # footer
929 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000930 if (test_ret != 0)
931 printf("Module %s: %%d errors\\n", test_ret);
932 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000933}
934""" % (module))
935
Daniel Veillardce244ad2004-11-05 10:03:46 +0000936#
937# Generate direct module caller
938#
939test.write("""static int
940test_module(const char *module) {
941""");
942for module in modules:
943 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
944 module, module))
945test.write(""" return(0);
946}
947""");
948
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000949print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000950
Daniel Veillard34099b42004-11-04 17:34:35 +0000951compare_and_save()
952
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000953missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000954for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000955 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000956 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000957
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000958 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000959 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000960
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000961def compare_missing(a, b):
962 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000963
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000964missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000965print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000966lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000967lst.write("Missing support for %d types" % (len(missing_list)))
968lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000969for miss in missing_list:
970 lst.write("%s: %d :" % (miss[1], miss[0]))
971 i = 0
972 for n in missing_types[miss[1]]:
973 i = i + 1
974 if i > 5:
975 lst.write(" ...")
976 break
977 lst.write(" %s" % (n))
978 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000979lst.write("\n")
980lst.write("\n")
981lst.write("Missing support per module");
982for module in missing_functions.keys():
983 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000984
985lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000986
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000987