blob: e4a89325cdcbcffae997ba4c4d0e5c883d32e376 [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",
61 "xmlCleanupPredefinedEntities": "LIBXML_LEGACY_ENABLED",
62 "xmlInitializePredefinedEntities": "LIBXML_LEGACY_ENABLED",
63 "xmlSetFeature": "LIBXML_LEGACY_ENABLED",
64 "xmlGetFeature": "LIBXML_LEGACY_ENABLED",
65 "xmlGetFeaturesList": "LIBXML_LEGACY_ENABLED",
66 "xmlIOParseDTD": "LIBXML_VALID_ENABLED",
67 "xmlParseDTD": "LIBXML_VALID_ENABLED",
68 "xmlParseDoc": "LIBXML_SAX1_ENABLED",
69 "xmlParseMemory": "LIBXML_SAX1_ENABLED",
70 "xmlRecoverDoc": "LIBXML_SAX1_ENABLED",
71 "xmlParseFile": "LIBXML_SAX1_ENABLED",
72 "xmlRecoverFile": "LIBXML_SAX1_ENABLED",
73 "xmlRecoverMemory": "LIBXML_SAX1_ENABLED",
74 "xmlSAXParseFileWithData": "LIBXML_SAX1_ENABLED",
75 "xmlSAXParseMemory": "LIBXML_SAX1_ENABLED",
76 "xmlSAXUserParseMemory": "LIBXML_SAX1_ENABLED",
77 "xmlSAXParseDoc": "LIBXML_SAX1_ENABLED",
78 "xmlSAXParseDTD": "LIBXML_SAX1_ENABLED",
79 "xmlSAXUserParseFile": "LIBXML_SAX1_ENABLED",
80 "xmlParseEntity": "LIBXML_SAX1_ENABLED",
81 "xmlParseExternalEntity": "LIBXML_SAX1_ENABLED",
82 "xmlSAXParseMemoryWithData": "LIBXML_SAX1_ENABLED",
83 "xmlParseBalancedChunkMemory": "LIBXML_SAX1_ENABLED",
84 "xmlParseBalancedChunkMemoryRecover": "LIBXML_SAX1_ENABLED",
85 "xmlSetupParserForBuffer": "LIBXML_SAX1_ENABLED",
86 "xmlStopParser": "LIBXML_PUSH_ENABLED",
87 "xmlAttrSerializeTxtContent": "LIBXML_OUTPUT_ENABLED",
88 "xmlSAXParseFile": "LIBXML_SAX1_ENABLED",
89 "xmlSAXParseEntity": "LIBXML_SAX1_ENABLED",
90 "xmlNewTextChild": "LIBXML_TREE_ENABLED",
91 "xmlNewDocRawNode": "LIBXML_TREE_ENABLED",
92 "xmlNewProp": "LIBXML_TREE_ENABLED",
93 "xmlReconciliateNs": "LIBXML_TREE_ENABLED",
94 "xmlValidateNCName": "LIBXML_TREE_ENABLED",
95 "xmlValidateNMToken": "LIBXML_TREE_ENABLED",
96 "xmlValidateName": "LIBXML_TREE_ENABLED",
97 "xmlNewChild": "LIBXML_TREE_ENABLED",
98 "xmlValidateQName": "LIBXML_TREE_ENABLED",
99 "xmlSprintfElementContent": "LIBXML_OUTPUT_ENABLED",
100 "xmlValidGetPotentialChildren" : "LIBXML_VALID_ENABLED",
101 "xmlValidGetValidElements" : "LIBXML_VALID_ENABLED",
102 "docbDefaultSAXHandlerInit" : "LIBXML_DOCB_ENABLED",
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000103 "xmlTextReaderPreservePattern" : "LIBXML_PATTERN_ENABLED",
Daniel Veillarda521d282004-11-09 14:59:59 +0000104}
105
106#
William M. Brack094dd862004-11-14 14:28:34 +0000107# Some functions really need to be skipped for the tests.
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000108#
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000109skipped_functions = [
110# block on I/O
111"xmlFdRead", "xmlReadFd", "xmlCtxtReadFd",
112"htmlFdRead", "htmlReadFd", "htmlCtxtReadFd",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000113"xmlReaderNewFd", "xmlReaderForFd",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000114"xmlIORead", "xmlReadIO", "xmlCtxtReadIO",
115"htmlIORead", "htmlReadIO", "htmlCtxtReadIO",
Daniel Veillard27f20102004-11-05 11:50:11 +0000116"xmlReaderNewIO", "xmlBufferDump", "xmlNanoFTPConnect",
William M. Brack015ccb22005-02-13 08:18:52 +0000117"xmlNanoFTPConnectTo", "xmlNanoHTTPMethod", "xmlNanoHTTPMethodRedir",
Daniel Veillard42595322004-11-08 10:52:06 +0000118# Complex I/O APIs
119"xmlCreateIOParserCtxt", "xmlParserInputBufferCreateIO",
120"xmlRegisterInputCallbacks", "xmlReaderForIO",
121"xmlOutputBufferCreateIO", "xmlRegisterOutputCallbacks",
William M. Brack015ccb22005-02-13 08:18:52 +0000122"xmlSaveToIO", "xmlIOHTTPOpenW",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000123# library state cleanup, generate false leak informations and other
124# troubles, heavillyb tested otherwise.
Daniel Veillardce244ad2004-11-05 10:03:46 +0000125"xmlCleanupParser", "xmlRelaxNGCleanupTypes", "xmlSetListDoc",
126"xmlSetTreeDoc", "xmlUnlinkNode",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000127# hard to avoid leaks in the tests
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000128"xmlStrcat", "xmlStrncat", "xmlCatalogAddLocal", "xmlNewTextWriterDoc",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000129"xmlXPathNewValueTree", "xmlXPathWrapString",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000130# unimplemented
131"xmlTextReaderReadInnerXml", "xmlTextReaderReadOuterXml",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000132"xmlTextReaderReadString",
133# destructor
William M. Brack015ccb22005-02-13 08:18:52 +0000134"xmlListDelete", "xmlOutputBufferClose", "xmlNanoFTPClose", "xmlNanoHTTPClose",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000135# deprecated
136"xmlCatalogGetPublic", "xmlCatalogGetSystem", "xmlEncodeEntities",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000137"xmlNewGlobalNs", "xmlHandleEntity", "xmlNamespaceParseNCName",
138"xmlNamespaceParseNSDef", "xmlNamespaceParseQName",
139"xmlParseNamespace", "xmlParseQuotedString", "xmlParserHandleReference",
140"xmlScanName",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000141"xmlDecodeEntities",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000142# allocators
143"xmlMemFree",
Daniel Veillardc2c894f2004-11-07 12:17:35 +0000144# verbosity
Daniel Veillarda82b1822004-11-08 16:24:57 +0000145"xmlCatalogSetDebug", "xmlShellPrintXPathError", "xmlShellPrintNode",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000146# Internal functions, no user space should really call them
147"xmlParseAttribute", "xmlParseAttributeListDecl", "xmlParseName",
148"xmlParseNmtoken", "xmlParseEntityValue", "xmlParseAttValue",
149"xmlParseSystemLiteral", "xmlParsePubidLiteral", "xmlParseCharData",
150"xmlParseExternalID", "xmlParseComment", "xmlParsePITarget", "xmlParsePI",
151"xmlParseNotationDecl", "xmlParseEntityDecl", "xmlParseDefaultDecl",
152"xmlParseNotationType", "xmlParseEnumerationType", "xmlParseEnumeratedType",
153"xmlParseAttributeType", "xmlParseAttributeListDecl",
154"xmlParseElementMixedContentDecl", "xmlParseElementChildrenContentDecl",
155"xmlParseElementContentDecl", "xmlParseElementDecl", "xmlParseMarkupDecl",
156"xmlParseCharRef", "xmlParseEntityRef", "xmlParseReference",
157"xmlParsePEReference", "xmlParseDocTypeDecl", "xmlParseAttribute",
158"xmlParseStartTag", "xmlParseEndTag", "xmlParseCDSect", "xmlParseContent",
159"xmlParseElement", "xmlParseVersionNum", "xmlParseVersionInfo",
160"xmlParseEncName", "xmlParseEncodingDecl", "xmlParseSDDecl",
161"xmlParseXMLDecl", "xmlParseTextDecl", "xmlParseMisc",
162"xmlParseExternalSubset", "xmlParserHandlePEReference",
163"xmlSkipBlankChars",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000164]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000165
166#
William M. Brack094dd862004-11-14 14:28:34 +0000167# These functions have side effects on the global state
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000168# and hence generate errors on memory allocation tests
169#
170skipped_memcheck = [ "xmlLoadCatalog", "xmlAddEncodingAlias",
171 "xmlSchemaInitTypes", "xmlNanoFTPProxy", "xmlNanoFTPScanProxy",
172 "xmlNanoHTTPScanProxy", "xmlResetLastError", "xmlCatalogConvert",
173 "xmlCatalogRemove", "xmlLoadCatalogs", "xmlCleanupCharEncodingHandlers",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000174 "xmlInitCharEncodingHandlers", "xmlCatalogCleanup",
Daniel Veillard42595322004-11-08 10:52:06 +0000175 "xmlSchemaGetBuiltInType",
Daniel Veillard1f33c4d2005-07-10 21:38:31 +0000176 "htmlParseFile", "htmlCtxtReadFile", # loads the catalogs
Daniel Veillard34e3f642008-07-29 09:02:27 +0000177 "xmlTextReaderSchemaValidate", "xmlSchemaCleanupTypes", # initialize the schemas type system
178 "xmlCatalogResolve", "xmlIOParseDTD" # loads the catalogs
Daniel Veillarda03e3652004-11-02 18:45:30 +0000179]
180
181#
182# Extra code needed for some test cases
183#
Daniel Veillard34099b42004-11-04 17:34:35 +0000184extra_pre_call = {
Daniel Veillarda521d282004-11-09 14:59:59 +0000185 "xmlSAXUserParseFile": """
186#ifdef LIBXML_SAX1_ENABLED
187 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
188#endif
189""",
190 "xmlSAXUserParseMemory": """
191#ifdef LIBXML_SAX1_ENABLED
192 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
193#endif
194""",
195 "xmlParseBalancedChunkMemory": """
196#ifdef LIBXML_SAX1_ENABLED
197 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
198#endif
199""",
200 "xmlParseBalancedChunkMemoryRecover": """
201#ifdef LIBXML_SAX1_ENABLED
202 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
203#endif
204""",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000205 "xmlParserInputBufferCreateFd":
206 "if (fd >= 0) fd = -1;",
Daniel Veillard34099b42004-11-04 17:34:35 +0000207}
Daniel Veillarda03e3652004-11-02 18:45:30 +0000208extra_post_call = {
209 "xmlAddChild":
210 "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
Daniel Veillard2cba4152008-08-27 11:45:41 +0000211 "xmlAddEntity":
212 "if (ret_val != NULL) { xmlFreeNode(ret_val) ; ret_val = NULL; }",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000213 "xmlAddChildList":
214 "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
215 "xmlAddSibling":
216 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
217 "xmlAddNextSibling":
218 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
219 "xmlAddPrevSibling":
220 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
221 "xmlDocSetRootElement":
222 "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
223 "xmlReplaceNode":
Daniel Veillardce244ad2004-11-05 10:03:46 +0000224 """if (cur != NULL) {
225 xmlUnlinkNode(cur);
226 xmlFreeNode(cur) ; cur = NULL ; }
227 if (old != NULL) {
228 xmlUnlinkNode(old);
229 xmlFreeNode(old) ; old = NULL ; }
230 ret_val = NULL;""",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000231 "xmlTextMerge":
232 """if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
Daniel Veillardce244ad2004-11-05 10:03:46 +0000233 xmlUnlinkNode(second);
Daniel Veillarda03e3652004-11-02 18:45:30 +0000234 xmlFreeNode(second) ; second = NULL ; }""",
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000235 "xmlBuildQName":
236 """if ((ret_val != NULL) && (ret_val != ncname) &&
237 (ret_val != prefix) && (ret_val != memory))
238 xmlFree(ret_val);
239 ret_val = NULL;""",
Daniel Veillardc394f732005-01-26 00:04:52 +0000240 "xmlNewDocElementContent":
241 """xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;""",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000242 "xmlDictReference": "xmlDictFree(dict);",
Daniel Veillard3d97e662004-11-04 10:49:00 +0000243 # Functions which deallocates one of their parameters
244 "xmlXPathConvertBoolean": """val = NULL;""",
245 "xmlXPathConvertNumber": """val = NULL;""",
246 "xmlXPathConvertString": """val = NULL;""",
247 "xmlSaveFileTo": """buf = NULL;""",
Daniel Veillard34099b42004-11-04 17:34:35 +0000248 "xmlSaveFormatFileTo": """buf = NULL;""",
249 "xmlIOParseDTD": "input = NULL;",
Daniel Veillardce244ad2004-11-05 10:03:46 +0000250 "xmlRemoveProp": "cur = NULL;",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000251 "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
252 "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
253 "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
254 "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000255 "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
Daniel Veillard42595322004-11-08 10:52:06 +0000256 "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000257 "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
258 "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
259 "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
260 "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
261 "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Daniel Veillard7e33dba2005-07-03 22:40:26 +0000262 "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
Daniel Veillardda3fee42008-09-01 13:08:57 +0000263 "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 +0000264}
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000265
266modules = []
267
268def is_skipped_module(name):
269 for mod in skipped_modules:
270 if mod == name:
271 return 1
272 return 0
273
274def is_skipped_function(name):
275 for fun in skipped_functions:
276 if fun == name:
277 return 1
278 # Do not test destructors
279 if string.find(name, 'Free') != -1:
280 return 1
281 return 0
282
283def is_skipped_memcheck(name):
284 for fun in skipped_memcheck:
285 if fun == name:
286 return 1
287 return 0
288
289missing_types = {}
290def add_missing_type(name, func):
291 try:
292 list = missing_types[name]
293 list.append(func)
294 except:
295 missing_types[name] = [func]
296
Daniel Veillardce682bc2004-11-05 17:22:25 +0000297generated_param_types = []
298def add_generated_param_type(name):
299 generated_param_types.append(name)
300
301generated_return_types = []
302def add_generated_return_type(name):
303 generated_return_types.append(name)
304
Daniel Veillard34099b42004-11-04 17:34:35 +0000305missing_functions = {}
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000306missing_functions_nr = 0
Daniel Veillard34099b42004-11-04 17:34:35 +0000307def add_missing_functions(name, module):
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000308 global missing_functions_nr
309
310 missing_functions_nr = missing_functions_nr + 1
Daniel Veillard34099b42004-11-04 17:34:35 +0000311 try:
312 list = missing_functions[module]
313 list.append(name)
314 except:
315 missing_functions[module] = [name]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000316
317#
318# Provide the type generators and destructors for the parameters
319#
320
Daniel Veillarda03e3652004-11-02 18:45:30 +0000321def type_convert(str, name, info, module, function, pos):
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000322# res = string.replace(str, " ", " ")
323# res = string.replace(str, " ", " ")
324# res = string.replace(str, " ", " ")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000325 res = string.replace(str, " *", "_ptr")
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000326# res = string.replace(str, "*", "_ptr")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000327 res = string.replace(res, " ", "_")
328 if res == 'const_char_ptr':
329 if string.find(name, "file") != -1 or \
330 string.find(name, "uri") != -1 or \
331 string.find(name, "URI") != -1 or \
332 string.find(info, "filename") != -1 or \
333 string.find(info, "URI") != -1 or \
334 string.find(info, "URL") != -1:
William M. Brack83d9c372004-11-08 02:26:08 +0000335 if string.find(function, "Save") != -1 or \
336 string.find(function, "Create") != -1 or \
William M. Brack015ccb22005-02-13 08:18:52 +0000337 string.find(function, "Write") != -1 or \
338 string.find(function, "Fetch") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000339 return('fileoutput')
340 return('filepath')
341 if res == 'void_ptr':
342 if module == 'nanoftp' and name == 'ctx':
343 return('xmlNanoFTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000344 if function == 'xmlNanoFTPNewCtxt' or \
345 function == 'xmlNanoFTPConnectTo' or \
346 function == 'xmlNanoFTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000347 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000348 if module == 'nanohttp' and name == 'ctx':
349 return('xmlNanoHTTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000350 if function == 'xmlNanoHTTPMethod' or \
351 function == 'xmlNanoHTTPMethodRedir' or \
352 function == 'xmlNanoHTTPOpen' or \
353 function == 'xmlNanoHTTPOpenRedir':
354 return('xmlNanoHTTPCtxtPtr');
355 if function == 'xmlIOHTTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000356 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000357 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000358 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000359 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000360 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000361 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000362 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000363 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000364 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000365 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000366 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000367 if res == 'xmlNodePtr' and pos != 0:
368 if (function == 'xmlAddChild' and pos == 2) or \
369 (function == 'xmlAddChildList' and pos == 2) or \
370 (function == 'xmlAddNextSibling' and pos == 2) or \
371 (function == 'xmlAddSibling' and pos == 2) or \
372 (function == 'xmlDocSetRootElement' and pos == 2) or \
373 (function == 'xmlReplaceNode' and pos == 2) or \
374 (function == 'xmlTextMerge') or \
375 (function == 'xmlAddPrevSibling' and pos == 2):
376 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000377 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000378 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000379 if res == 'xmlChar_ptr' and name == 'name' and \
380 string.find(function, "EatName") != -1:
381 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000382 if res == 'void_ptr*':
383 res = 'void_ptr_ptr'
384 if res == 'char_ptr*':
385 res = 'char_ptr_ptr'
386 if res == 'xmlChar_ptr*':
387 res = 'xmlChar_ptr_ptr'
388 if res == 'const_xmlChar_ptr*':
389 res = 'const_xmlChar_ptr_ptr'
390 if res == 'const_char_ptr*':
391 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000392 if res == 'FILE_ptr' and module == 'debugXML':
393 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000394 if res == 'int' and name == 'options':
395 if module == 'parser' or module == 'xmlreader':
396 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000397
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000398 return res
399
Daniel Veillard34099b42004-11-04 17:34:35 +0000400known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000401
Daniel Veillardce682bc2004-11-05 17:22:25 +0000402def is_known_param_type(name, rtype):
403 global test
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000404 for type in known_param_types:
405 if type == name:
406 return 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000407 for type in generated_param_types:
408 if type == name:
409 return 1
410
411 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
412 if rtype[0:6] == 'const ':
413 crtype = rtype[6:]
414 else:
415 crtype = rtype
416
Daniel Veillarda521d282004-11-09 14:59:59 +0000417 define = 0
418 if modules_defines.has_key(module):
419 test.write("#ifdef %s\n" % (modules_defines[module]))
420 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000421 test.write("""
422#define gen_nb_%s 1
423static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
424 return(NULL);
425}
426static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
427}
428""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000429 if define == 1:
430 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000431 add_generated_param_type(name)
432 return 1
433
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000434 return 0
435
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000436#
437# Provide the type destructors for the return values
438#
439
Daniel Veillard34099b42004-11-04 17:34:35 +0000440known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000441
442def is_known_return_type(name):
443 for type in known_return_types:
444 if type == name:
445 return 1
446 return 0
447
Daniel Veillard34099b42004-11-04 17:34:35 +0000448#
449# Copy the beginning of the C test program result
450#
451
William M. Brack106cad62004-12-23 15:56:12 +0000452try:
453 input = open("testapi.c", "r")
454except:
455 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000456test = open('testapi.c.new', 'w')
457
458def compare_and_save():
459 global test
460
461 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000462 try:
463 input = open("testapi.c", "r").read()
464 except:
465 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000466 test = open('testapi.c.new', "r").read()
467 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000468 try:
469 os.system("rm testapi.c; mv testapi.c.new testapi.c")
470 except:
471 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000472 print("Updated testapi.c")
473 else:
474 print("Generated testapi.c is identical")
475
476line = input.readline()
477while line != "":
478 if line == "/* CUT HERE: everything below that line is generated */\n":
479 break;
480 if line[0:15] == "#define gen_nb_":
481 type = string.split(line[15:])[0]
482 known_param_types.append(type)
483 if line[0:19] == "static void desret_":
484 type = string.split(line[19:], '(')[0]
485 known_return_types.append(type)
486 test.write(line)
487 line = input.readline()
488input.close()
489
490if line == "":
491 print "Could not find the CUT marker in testapi.c skipping generation"
492 test.close()
493 sys.exit(0)
494
495print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
496 len(known_param_types), len(known_return_types)))
497test.write("/* CUT HERE: everything below that line is generated */\n")
498
499
500#
501# Open the input API description
502#
William M. Brack106cad62004-12-23 15:56:12 +0000503doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000504if doc == None:
505 print "Failed to load doc/libxml2-api.xml"
506 sys.exit(1)
507ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000508
509#
William M. Brack094dd862004-11-14 14:28:34 +0000510# Generate a list of all function parameters and select only
511# those used in the api tests
512#
513argtypes = {}
514args = ctxt.xpathEval("/api/symbols/function/arg")
515for arg in args:
516 mod = arg.xpathEval('string(../@file)')
517 func = arg.xpathEval('string(../@name)')
518 if (mod not in skipped_modules) and (func not in skipped_functions):
519 type = arg.xpathEval('string(@type)')
520 if not argtypes.has_key(type):
521 argtypes[type] = func
522
523# similarly for return types
524rettypes = {}
525rets = ctxt.xpathEval("/api/symbols/function/return")
526for ret in rets:
527 mod = ret.xpathEval('string(../@file)')
528 func = ret.xpathEval('string(../@name)')
529 if (mod not in skipped_modules) and (func not in skipped_functions):
530 type = ret.xpathEval('string(@type)')
531 if not rettypes.has_key(type):
532 rettypes[type] = func
533
534#
Daniel Veillard57b25162004-11-06 14:50:18 +0000535# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000536# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000537#
538enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
539for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000540 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000541 name = enum.xpathEval('string(@name)')
542 #
543 # Skip any enums which are not in our filtered lists
544 #
545 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
546 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000547 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000548
William M. Brack094dd862004-11-14 14:28:34 +0000549 if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000550 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
551 i = 0
552 vals = []
553 for value in values:
554 vname = value.xpathEval('string(@name)')
555 if vname == None:
556 continue;
557 i = i + 1
558 if i >= 5:
559 break;
560 vals.append(vname)
561 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000562 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000563 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000564 if modules_defines.has_key(module):
565 test.write("#ifdef %s\n" % (modules_defines[module]))
566 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000567 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
568 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
569 (name, name))
570 i = 1
571 for value in vals:
572 test.write(" if (no == %d) return(%s);\n" % (i, value))
573 i = i + 1
574 test.write(""" return(0);
575}
William M. Brack094dd862004-11-14 14:28:34 +0000576
577static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
578}
579
580""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000581 known_param_types.append(name)
582
William M. Brack094dd862004-11-14 14:28:34 +0000583 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000584 if define == 0 and modules_defines.has_key(module):
585 test.write("#ifdef %s\n" % (modules_defines[module]))
586 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000587 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000588}
589
William M. Brack094dd862004-11-14 14:28:34 +0000590""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000591 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000592 if define == 1:
593 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000594
595#
596# Load the interfaces
597#
Daniel Veillard57b25162004-11-06 14:50:18 +0000598headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000599for file in headers:
600 name = file.xpathEval('string(@name)')
601 if (name == None) or (name == ''):
602 continue
603
604 #
605 # Some module may be skipped because they don't really consists
606 # of user callable APIs
607 #
608 if is_skipped_module(name):
609 continue
610
611 #
612 # do not test deprecated APIs
613 #
614 desc = file.xpathEval('string(description)')
615 if string.find(desc, 'DEPRECATED') != -1:
616 print "Skipping deprecated interface %s" % name
617 continue;
618
619 test.write("#include <libxml/%s.h>\n" % name)
620 modules.append(name)
621
622#
623# Generate the callers signatures
624#
625for module in modules:
626 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000627
628#
629# Generate the top caller
630#
631
632test.write("""
633/**
634 * testlibxml2:
635 *
636 * Main entry point of the tester for the full libxml2 module,
637 * it calls all the tester entry point for each module.
638 *
639 * Returns the number of error found
640 */
641static int
642testlibxml2(void)
643{
Daniel Veillard42595322004-11-08 10:52:06 +0000644 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000645
646""")
647
648for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000649 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000650
651test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000652 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000653 function_tests, call_tests, test_ret);
654 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000655}
656
657""")
658
659#
660# How to handle a function
661#
662nb_tests = 0
663
664def generate_test(module, node):
665 global test
666 global nb_tests
667 nb_cond = 0
668 no_gen = 0
669
670 name = node.xpathEval('string(@name)')
671 if is_skipped_function(name):
672 return
673
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000674 #
675 # check we know how to handle the args and return values
676 # and store the informations for the generation
677 #
678 try:
679 args = node.xpathEval("arg")
680 except:
681 args = []
682 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000683 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000684 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000685 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000686 rtype = arg.xpathEval("string(@type)")
687 if rtype == 'void':
688 break;
689 info = arg.xpathEval("string(@info)")
690 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000691 type = type_convert(rtype, nam, info, module, name, n)
Daniel Veillardce682bc2004-11-05 17:22:25 +0000692 if is_known_param_type(type, rtype) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000693 add_missing_type(type, name);
694 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000695 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
696 rtype[0:6] == 'const ':
697 crtype = rtype[6:]
698 else:
699 crtype = rtype
700 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000701
702 try:
703 rets = node.xpathEval("return")
704 except:
705 rets = []
706 t_ret = None
707 for ret in rets:
708 rtype = ret.xpathEval("string(@type)")
709 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000710 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000711 if rtype == 'void':
712 break
713 if is_known_return_type(type) == 0:
714 add_missing_type(type, name);
715 no_gen = 1
716 t_ret = (type, rtype, info)
717 break
718
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000719 test.write("""
720static int
721test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000722 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000723
724""" % (name))
725
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000726 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000727 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000728 test.write("""
729 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000730 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000731}
732
733""")
734 return
735
736 try:
737 conds = node.xpathEval("cond")
738 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000739 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000740 nb_cond = nb_cond + 1
741 except:
742 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000743
744 define = 0
745 if function_defines.has_key(name):
746 test.write("#ifdef %s\n" % (function_defines[name]))
747 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000748
749 # Declare the memory usage counter
750 no_mem = is_skipped_memcheck(name)
751 if no_mem == 0:
752 test.write(" int mem_base;\n");
753
754 # Declare the return value
755 if t_ret != None:
756 test.write(" %s ret_val;\n" % (t_ret[1]))
757
758 # Declare the arguments
759 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000760 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000761 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000762 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000763 test.write(" int n_%s;\n" % (nam))
764 test.write("\n")
765
766 # Cascade loop on of each argument list of values
767 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000768 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000769 #
770 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
771 nam, nam, type, nam))
772
773 # log the memory usage
774 if no_mem == 0:
775 test.write(" mem_base = xmlMemBlocks();\n");
776
777 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000778 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000779 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000780 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000781 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000782 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
783 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000784
Nick Wellnhoferff34ba32017-05-31 18:53:45 +0200785 # add checks to avoid out-of-bounds array access
786 i = 0;
787 for arg in t_args:
788 (nam, type, rtype, crtype, info) = arg;
789 # assume that "size", "len", and "start" parameters apply to either
790 # the nearest preceding or following char pointer
791 if type == "int" and (nam == "size" or nam == "len" or nam == "start"):
792 for j in range(i - 1, -1, -1) + range(i + 1, len(t_args)):
793 (bnam, btype) = t_args[j][:2]
794 if btype == "const_char_ptr" or btype == "const_xmlChar_ptr":
795 test.write(
796 " if ((%s != NULL) &&\n"
797 " (%s > (int) strlen((const char *) %s) + 1))\n"
798 " continue;\n"
799 % (bnam, nam, bnam))
800 break
801 i = i + 1;
802
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000803 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000804 if extra_pre_call.has_key(name):
805 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000806 if t_ret != None:
807 test.write("\n ret_val = %s(" % (name))
808 need = 0
809 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000810 (nam, type, rtype, crtype, info) = arg
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000811 if need:
812 test.write(", ")
813 else:
814 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000815 if rtype != crtype:
816 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000817 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000818 test.write(");\n")
819 if extra_post_call.has_key(name):
820 test.write(" %s\n"% (extra_post_call[name]))
821 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000822 else:
823 test.write("\n %s(" % (name));
824 need = 0;
825 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000826 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000827 if need:
828 test.write(", ")
829 else:
830 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000831 if rtype != crtype:
832 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000833 test.write("%s" % nam)
834 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000835 if extra_post_call.has_key(name):
836 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000837
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000838 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000839
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000840 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000841 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000842 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000843 (nam, type, rtype, crtype, info) = arg;
William M. Brackd46c1ca2007-02-08 23:34:34 +0000844 # This is a hack to prevent generating a destructor for the
845 # 'input' argument in xmlTextReaderSetup. There should be
846 # a better, more generic way to do this!
847 if string.find(info, 'destroy') == -1:
848 test.write(" des_%s(n_%s, " % (type, nam))
849 if rtype != crtype:
850 test.write("(%s)" % rtype)
851 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000852 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000853
854 test.write(" xmlResetLastError();\n");
855 # Check the memory usage
856 if no_mem == 0:
857 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000858 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000859 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000860 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000861""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000862 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000863 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000864 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
865 test.write(""" printf("\\n");\n""")
866 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000867
868 for arg in t_args:
869 test.write(" }\n")
870
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000871 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000872 #
873 # end of conditional
874 #
875 while nb_cond > 0:
876 test.write("#endif\n")
877 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000878 if define == 1:
879 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000880
881 nb_tests = nb_tests + 1;
882
883 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000884 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000885}
886
887""")
888
889#
890# Generate all module callers
891#
892for module in modules:
893 # gather all the functions exported by that module
894 try:
895 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
896 except:
897 print "Failed to gather functions from module %s" % (module)
898 continue;
899
900 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000901 i = 0
902 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000903 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000904 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000905 generate_test(module, function);
906
907 # header
908 test.write("""static int
909test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000910 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000911
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000912 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000913""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000914
915 # iterate over all functions in the module generating the call
916 for function in functions:
917 name = function.xpathEval('string(@name)')
918 if is_skipped_function(name):
919 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000920 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000921
922 # footer
923 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000924 if (test_ret != 0)
925 printf("Module %s: %%d errors\\n", test_ret);
926 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000927}
928""" % (module))
929
Daniel Veillardce244ad2004-11-05 10:03:46 +0000930#
931# Generate direct module caller
932#
933test.write("""static int
934test_module(const char *module) {
935""");
936for module in modules:
937 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
938 module, module))
939test.write(""" return(0);
940}
941""");
942
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000943print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000944
Daniel Veillard34099b42004-11-04 17:34:35 +0000945compare_and_save()
946
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000947missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000948for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000949 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000950 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000951
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000952 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000953 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000954
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000955def compare_missing(a, b):
956 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000957
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000958missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000959print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000960lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000961lst.write("Missing support for %d types" % (len(missing_list)))
962lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000963for miss in missing_list:
964 lst.write("%s: %d :" % (miss[1], miss[0]))
965 i = 0
966 for n in missing_types[miss[1]]:
967 i = i + 1
968 if i > 5:
969 lst.write(" ...")
970 break
971 lst.write(" %s" % (n))
972 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000973lst.write("\n")
974lst.write("\n")
975lst.write("Missing support per module");
976for module in missing_functions.keys():
977 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000978
979lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000980
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000981