blob: 4538eb86fb130b5fb75fe7fe5372b3ed441659be [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
177 "xmlTextReaderSchemaValidate", "xmlSchemaCleanupTypes" # initialize the schemas type system
Daniel Veillarda03e3652004-11-02 18:45:30 +0000178]
179
180#
181# Extra code needed for some test cases
182#
Daniel Veillard34099b42004-11-04 17:34:35 +0000183extra_pre_call = {
Daniel Veillarda521d282004-11-09 14:59:59 +0000184 "xmlSAXUserParseFile": """
185#ifdef LIBXML_SAX1_ENABLED
186 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
187#endif
188""",
189 "xmlSAXUserParseMemory": """
190#ifdef LIBXML_SAX1_ENABLED
191 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
192#endif
193""",
194 "xmlParseBalancedChunkMemory": """
195#ifdef LIBXML_SAX1_ENABLED
196 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
197#endif
198""",
199 "xmlParseBalancedChunkMemoryRecover": """
200#ifdef LIBXML_SAX1_ENABLED
201 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
202#endif
203""",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000204 "xmlParserInputBufferCreateFd":
205 "if (fd >= 0) fd = -1;",
Daniel Veillard34099b42004-11-04 17:34:35 +0000206}
Daniel Veillarda03e3652004-11-02 18:45:30 +0000207extra_post_call = {
208 "xmlAddChild":
209 "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
210 "xmlAddChildList":
211 "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
212 "xmlAddSibling":
213 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
214 "xmlAddNextSibling":
215 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
216 "xmlAddPrevSibling":
217 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
218 "xmlDocSetRootElement":
219 "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
220 "xmlReplaceNode":
Daniel Veillardce244ad2004-11-05 10:03:46 +0000221 """if (cur != NULL) {
222 xmlUnlinkNode(cur);
223 xmlFreeNode(cur) ; cur = NULL ; }
224 if (old != NULL) {
225 xmlUnlinkNode(old);
226 xmlFreeNode(old) ; old = NULL ; }
227 ret_val = NULL;""",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000228 "xmlTextMerge":
229 """if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
Daniel Veillardce244ad2004-11-05 10:03:46 +0000230 xmlUnlinkNode(second);
Daniel Veillarda03e3652004-11-02 18:45:30 +0000231 xmlFreeNode(second) ; second = NULL ; }""",
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000232 "xmlBuildQName":
233 """if ((ret_val != NULL) && (ret_val != ncname) &&
234 (ret_val != prefix) && (ret_val != memory))
235 xmlFree(ret_val);
236 ret_val = NULL;""",
Daniel Veillardc394f732005-01-26 00:04:52 +0000237 "xmlNewDocElementContent":
238 """xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;""",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000239 "xmlDictReference": "xmlDictFree(dict);",
Daniel Veillard3d97e662004-11-04 10:49:00 +0000240 # Functions which deallocates one of their parameters
241 "xmlXPathConvertBoolean": """val = NULL;""",
242 "xmlXPathConvertNumber": """val = NULL;""",
243 "xmlXPathConvertString": """val = NULL;""",
244 "xmlSaveFileTo": """buf = NULL;""",
Daniel Veillard34099b42004-11-04 17:34:35 +0000245 "xmlSaveFormatFileTo": """buf = NULL;""",
246 "xmlIOParseDTD": "input = NULL;",
Daniel Veillardce244ad2004-11-05 10:03:46 +0000247 "xmlRemoveProp": "cur = NULL;",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000248 "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
249 "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
250 "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
251 "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000252 "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
Daniel Veillard42595322004-11-08 10:52:06 +0000253 "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000254 "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
255 "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
256 "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
257 "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
258 "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Daniel Veillard7e33dba2005-07-03 22:40:26 +0000259 "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000260}
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000261
262modules = []
263
264def is_skipped_module(name):
265 for mod in skipped_modules:
266 if mod == name:
267 return 1
268 return 0
269
270def is_skipped_function(name):
271 for fun in skipped_functions:
272 if fun == name:
273 return 1
274 # Do not test destructors
275 if string.find(name, 'Free') != -1:
276 return 1
277 return 0
278
279def is_skipped_memcheck(name):
280 for fun in skipped_memcheck:
281 if fun == name:
282 return 1
283 return 0
284
285missing_types = {}
286def add_missing_type(name, func):
287 try:
288 list = missing_types[name]
289 list.append(func)
290 except:
291 missing_types[name] = [func]
292
Daniel Veillardce682bc2004-11-05 17:22:25 +0000293generated_param_types = []
294def add_generated_param_type(name):
295 generated_param_types.append(name)
296
297generated_return_types = []
298def add_generated_return_type(name):
299 generated_return_types.append(name)
300
Daniel Veillard34099b42004-11-04 17:34:35 +0000301missing_functions = {}
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000302missing_functions_nr = 0
Daniel Veillard34099b42004-11-04 17:34:35 +0000303def add_missing_functions(name, module):
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000304 global missing_functions_nr
305
306 missing_functions_nr = missing_functions_nr + 1
Daniel Veillard34099b42004-11-04 17:34:35 +0000307 try:
308 list = missing_functions[module]
309 list.append(name)
310 except:
311 missing_functions[module] = [name]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000312
313#
314# Provide the type generators and destructors for the parameters
315#
316
Daniel Veillarda03e3652004-11-02 18:45:30 +0000317def type_convert(str, name, info, module, function, pos):
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000318# res = string.replace(str, " ", " ")
319# res = string.replace(str, " ", " ")
320# res = string.replace(str, " ", " ")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000321 res = string.replace(str, " *", "_ptr")
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000322# res = string.replace(str, "*", "_ptr")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000323 res = string.replace(res, " ", "_")
324 if res == 'const_char_ptr':
325 if string.find(name, "file") != -1 or \
326 string.find(name, "uri") != -1 or \
327 string.find(name, "URI") != -1 or \
328 string.find(info, "filename") != -1 or \
329 string.find(info, "URI") != -1 or \
330 string.find(info, "URL") != -1:
William M. Brack83d9c372004-11-08 02:26:08 +0000331 if string.find(function, "Save") != -1 or \
332 string.find(function, "Create") != -1 or \
William M. Brack015ccb22005-02-13 08:18:52 +0000333 string.find(function, "Write") != -1 or \
334 string.find(function, "Fetch") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000335 return('fileoutput')
336 return('filepath')
337 if res == 'void_ptr':
338 if module == 'nanoftp' and name == 'ctx':
339 return('xmlNanoFTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000340 if function == 'xmlNanoFTPNewCtxt' or \
341 function == 'xmlNanoFTPConnectTo' or \
342 function == 'xmlNanoFTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000343 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000344 if module == 'nanohttp' and name == 'ctx':
345 return('xmlNanoHTTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000346 if function == 'xmlNanoHTTPMethod' or \
347 function == 'xmlNanoHTTPMethodRedir' or \
348 function == 'xmlNanoHTTPOpen' or \
349 function == 'xmlNanoHTTPOpenRedir':
350 return('xmlNanoHTTPCtxtPtr');
351 if function == 'xmlIOHTTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000352 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000353 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000354 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000355 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000356 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000357 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000358 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000359 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000360 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000361 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000362 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000363 if res == 'xmlNodePtr' and pos != 0:
364 if (function == 'xmlAddChild' and pos == 2) or \
365 (function == 'xmlAddChildList' and pos == 2) or \
366 (function == 'xmlAddNextSibling' and pos == 2) or \
367 (function == 'xmlAddSibling' and pos == 2) or \
368 (function == 'xmlDocSetRootElement' and pos == 2) or \
369 (function == 'xmlReplaceNode' and pos == 2) or \
370 (function == 'xmlTextMerge') or \
371 (function == 'xmlAddPrevSibling' and pos == 2):
372 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000373 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000374 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000375 if res == 'xmlChar_ptr' and name == 'name' and \
376 string.find(function, "EatName") != -1:
377 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000378 if res == 'void_ptr*':
379 res = 'void_ptr_ptr'
380 if res == 'char_ptr*':
381 res = 'char_ptr_ptr'
382 if res == 'xmlChar_ptr*':
383 res = 'xmlChar_ptr_ptr'
384 if res == 'const_xmlChar_ptr*':
385 res = 'const_xmlChar_ptr_ptr'
386 if res == 'const_char_ptr*':
387 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000388 if res == 'FILE_ptr' and module == 'debugXML':
389 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000390 if res == 'int' and name == 'options':
391 if module == 'parser' or module == 'xmlreader':
392 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000393
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000394 return res
395
Daniel Veillard34099b42004-11-04 17:34:35 +0000396known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000397
Daniel Veillardce682bc2004-11-05 17:22:25 +0000398def is_known_param_type(name, rtype):
399 global test
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000400 for type in known_param_types:
401 if type == name:
402 return 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000403 for type in generated_param_types:
404 if type == name:
405 return 1
406
407 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
408 if rtype[0:6] == 'const ':
409 crtype = rtype[6:]
410 else:
411 crtype = rtype
412
Daniel Veillarda521d282004-11-09 14:59:59 +0000413 define = 0
414 if modules_defines.has_key(module):
415 test.write("#ifdef %s\n" % (modules_defines[module]))
416 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000417 test.write("""
418#define gen_nb_%s 1
419static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
420 return(NULL);
421}
422static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
423}
424""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000425 if define == 1:
426 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000427 add_generated_param_type(name)
428 return 1
429
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000430 return 0
431
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000432#
433# Provide the type destructors for the return values
434#
435
Daniel Veillard34099b42004-11-04 17:34:35 +0000436known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000437
438def is_known_return_type(name):
439 for type in known_return_types:
440 if type == name:
441 return 1
442 return 0
443
Daniel Veillard34099b42004-11-04 17:34:35 +0000444#
445# Copy the beginning of the C test program result
446#
447
William M. Brack106cad62004-12-23 15:56:12 +0000448try:
449 input = open("testapi.c", "r")
450except:
451 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000452test = open('testapi.c.new', 'w')
453
454def compare_and_save():
455 global test
456
457 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000458 try:
459 input = open("testapi.c", "r").read()
460 except:
461 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000462 test = open('testapi.c.new', "r").read()
463 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000464 try:
465 os.system("rm testapi.c; mv testapi.c.new testapi.c")
466 except:
467 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000468 print("Updated testapi.c")
469 else:
470 print("Generated testapi.c is identical")
471
472line = input.readline()
473while line != "":
474 if line == "/* CUT HERE: everything below that line is generated */\n":
475 break;
476 if line[0:15] == "#define gen_nb_":
477 type = string.split(line[15:])[0]
478 known_param_types.append(type)
479 if line[0:19] == "static void desret_":
480 type = string.split(line[19:], '(')[0]
481 known_return_types.append(type)
482 test.write(line)
483 line = input.readline()
484input.close()
485
486if line == "":
487 print "Could not find the CUT marker in testapi.c skipping generation"
488 test.close()
489 sys.exit(0)
490
491print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
492 len(known_param_types), len(known_return_types)))
493test.write("/* CUT HERE: everything below that line is generated */\n")
494
495
496#
497# Open the input API description
498#
William M. Brack106cad62004-12-23 15:56:12 +0000499doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000500if doc == None:
501 print "Failed to load doc/libxml2-api.xml"
502 sys.exit(1)
503ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000504
505#
William M. Brack094dd862004-11-14 14:28:34 +0000506# Generate a list of all function parameters and select only
507# those used in the api tests
508#
509argtypes = {}
510args = ctxt.xpathEval("/api/symbols/function/arg")
511for arg in args:
512 mod = arg.xpathEval('string(../@file)')
513 func = arg.xpathEval('string(../@name)')
514 if (mod not in skipped_modules) and (func not in skipped_functions):
515 type = arg.xpathEval('string(@type)')
516 if not argtypes.has_key(type):
517 argtypes[type] = func
518
519# similarly for return types
520rettypes = {}
521rets = ctxt.xpathEval("/api/symbols/function/return")
522for ret in rets:
523 mod = ret.xpathEval('string(../@file)')
524 func = ret.xpathEval('string(../@name)')
525 if (mod not in skipped_modules) and (func not in skipped_functions):
526 type = ret.xpathEval('string(@type)')
527 if not rettypes.has_key(type):
528 rettypes[type] = func
529
530#
Daniel Veillard57b25162004-11-06 14:50:18 +0000531# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000532# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000533#
534enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
535for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000536 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000537 name = enum.xpathEval('string(@name)')
538 #
539 # Skip any enums which are not in our filtered lists
540 #
541 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
542 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000543 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000544
William M. Brack094dd862004-11-14 14:28:34 +0000545 if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000546 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
547 i = 0
548 vals = []
549 for value in values:
550 vname = value.xpathEval('string(@name)')
551 if vname == None:
552 continue;
553 i = i + 1
554 if i >= 5:
555 break;
556 vals.append(vname)
557 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000558 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000559 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000560 if modules_defines.has_key(module):
561 test.write("#ifdef %s\n" % (modules_defines[module]))
562 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000563 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
564 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
565 (name, name))
566 i = 1
567 for value in vals:
568 test.write(" if (no == %d) return(%s);\n" % (i, value))
569 i = i + 1
570 test.write(""" return(0);
571}
William M. Brack094dd862004-11-14 14:28:34 +0000572
573static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
574}
575
576""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000577 known_param_types.append(name)
578
William M. Brack094dd862004-11-14 14:28:34 +0000579 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000580 if define == 0 and modules_defines.has_key(module):
581 test.write("#ifdef %s\n" % (modules_defines[module]))
582 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000583 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000584}
585
William M. Brack094dd862004-11-14 14:28:34 +0000586""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000587 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000588 if define == 1:
589 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000590
591#
592# Load the interfaces
593#
Daniel Veillard57b25162004-11-06 14:50:18 +0000594headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000595for file in headers:
596 name = file.xpathEval('string(@name)')
597 if (name == None) or (name == ''):
598 continue
599
600 #
601 # Some module may be skipped because they don't really consists
602 # of user callable APIs
603 #
604 if is_skipped_module(name):
605 continue
606
607 #
608 # do not test deprecated APIs
609 #
610 desc = file.xpathEval('string(description)')
611 if string.find(desc, 'DEPRECATED') != -1:
612 print "Skipping deprecated interface %s" % name
613 continue;
614
615 test.write("#include <libxml/%s.h>\n" % name)
616 modules.append(name)
617
618#
619# Generate the callers signatures
620#
621for module in modules:
622 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000623
624#
625# Generate the top caller
626#
627
628test.write("""
629/**
630 * testlibxml2:
631 *
632 * Main entry point of the tester for the full libxml2 module,
633 * it calls all the tester entry point for each module.
634 *
635 * Returns the number of error found
636 */
637static int
638testlibxml2(void)
639{
Daniel Veillard42595322004-11-08 10:52:06 +0000640 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000641
642""")
643
644for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000645 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000646
647test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000648 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000649 function_tests, call_tests, test_ret);
650 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000651}
652
653""")
654
655#
656# How to handle a function
657#
658nb_tests = 0
659
660def generate_test(module, node):
661 global test
662 global nb_tests
663 nb_cond = 0
664 no_gen = 0
665
666 name = node.xpathEval('string(@name)')
667 if is_skipped_function(name):
668 return
669
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000670 #
671 # check we know how to handle the args and return values
672 # and store the informations for the generation
673 #
674 try:
675 args = node.xpathEval("arg")
676 except:
677 args = []
678 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000679 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000680 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000681 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000682 rtype = arg.xpathEval("string(@type)")
683 if rtype == 'void':
684 break;
685 info = arg.xpathEval("string(@info)")
686 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000687 type = type_convert(rtype, nam, info, module, name, n)
Daniel Veillardce682bc2004-11-05 17:22:25 +0000688 if is_known_param_type(type, rtype) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000689 add_missing_type(type, name);
690 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000691 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
692 rtype[0:6] == 'const ':
693 crtype = rtype[6:]
694 else:
695 crtype = rtype
696 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000697
698 try:
699 rets = node.xpathEval("return")
700 except:
701 rets = []
702 t_ret = None
703 for ret in rets:
704 rtype = ret.xpathEval("string(@type)")
705 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000706 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000707 if rtype == 'void':
708 break
709 if is_known_return_type(type) == 0:
710 add_missing_type(type, name);
711 no_gen = 1
712 t_ret = (type, rtype, info)
713 break
714
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000715 test.write("""
716static int
717test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000718 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000719
720""" % (name))
721
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000722 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000723 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000724 test.write("""
725 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000726 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000727}
728
729""")
730 return
731
732 try:
733 conds = node.xpathEval("cond")
734 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000735 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000736 nb_cond = nb_cond + 1
737 except:
738 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000739
740 define = 0
741 if function_defines.has_key(name):
742 test.write("#ifdef %s\n" % (function_defines[name]))
743 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000744
745 # Declare the memory usage counter
746 no_mem = is_skipped_memcheck(name)
747 if no_mem == 0:
748 test.write(" int mem_base;\n");
749
750 # Declare the return value
751 if t_ret != None:
752 test.write(" %s ret_val;\n" % (t_ret[1]))
753
754 # Declare the arguments
755 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000756 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000757 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000758 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000759 test.write(" int n_%s;\n" % (nam))
760 test.write("\n")
761
762 # Cascade loop on of each argument list of values
763 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000764 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000765 #
766 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
767 nam, nam, type, nam))
768
769 # log the memory usage
770 if no_mem == 0:
771 test.write(" mem_base = xmlMemBlocks();\n");
772
773 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000774 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000775 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000776 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000777 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000778 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
779 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000780
781 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000782 if extra_pre_call.has_key(name):
783 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000784 if t_ret != None:
785 test.write("\n ret_val = %s(" % (name))
786 need = 0
787 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000788 (nam, type, rtype, crtype, info) = arg
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000789 if need:
790 test.write(", ")
791 else:
792 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000793 if rtype != crtype:
794 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000795 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000796 test.write(");\n")
797 if extra_post_call.has_key(name):
798 test.write(" %s\n"% (extra_post_call[name]))
799 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000800 else:
801 test.write("\n %s(" % (name));
802 need = 0;
803 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000804 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000805 if need:
806 test.write(", ")
807 else:
808 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000809 if rtype != crtype:
810 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000811 test.write("%s" % nam)
812 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000813 if extra_post_call.has_key(name):
814 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000815
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000816 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000817
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000818 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000819 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000820 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000821 (nam, type, rtype, crtype, info) = arg;
William M. Brackd46c1ca2007-02-08 23:34:34 +0000822 # This is a hack to prevent generating a destructor for the
823 # 'input' argument in xmlTextReaderSetup. There should be
824 # a better, more generic way to do this!
825 if string.find(info, 'destroy') == -1:
826 test.write(" des_%s(n_%s, " % (type, nam))
827 if rtype != crtype:
828 test.write("(%s)" % rtype)
829 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000830 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000831
832 test.write(" xmlResetLastError();\n");
833 # Check the memory usage
834 if no_mem == 0:
835 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000836 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000837 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000838 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000839""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000840 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000841 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000842 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
843 test.write(""" printf("\\n");\n""")
844 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000845
846 for arg in t_args:
847 test.write(" }\n")
848
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000849 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000850 #
851 # end of conditional
852 #
853 while nb_cond > 0:
854 test.write("#endif\n")
855 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000856 if define == 1:
857 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000858
859 nb_tests = nb_tests + 1;
860
861 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000862 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000863}
864
865""")
866
867#
868# Generate all module callers
869#
870for module in modules:
871 # gather all the functions exported by that module
872 try:
873 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
874 except:
875 print "Failed to gather functions from module %s" % (module)
876 continue;
877
878 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000879 i = 0
880 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000881 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000882 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000883 generate_test(module, function);
884
885 # header
886 test.write("""static int
887test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000888 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000889
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000890 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000891""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000892
893 # iterate over all functions in the module generating the call
894 for function in functions:
895 name = function.xpathEval('string(@name)')
896 if is_skipped_function(name):
897 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000898 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000899
900 # footer
901 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000902 if (test_ret != 0)
903 printf("Module %s: %%d errors\\n", test_ret);
904 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000905}
906""" % (module))
907
Daniel Veillardce244ad2004-11-05 10:03:46 +0000908#
909# Generate direct module caller
910#
911test.write("""static int
912test_module(const char *module) {
913""");
914for module in modules:
915 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
916 module, module))
917test.write(""" return(0);
918}
919""");
920
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000921print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000922
Daniel Veillard34099b42004-11-04 17:34:35 +0000923compare_and_save()
924
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000925missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000926for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000927 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000928 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000929
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000930 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000931 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000932
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000933def compare_missing(a, b):
934 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000935
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000936missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000937print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000938lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000939lst.write("Missing support for %d types" % (len(missing_list)))
940lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000941for miss in missing_list:
942 lst.write("%s: %d :" % (miss[1], miss[0]))
943 i = 0
944 for n in missing_types[miss[1]]:
945 i = i + 1
946 if i > 5:
947 lst.write(" ...")
948 break
949 lst.write(" %s" % (n))
950 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000951lst.write("\n")
952lst.write("\n")
953lst.write("Missing support per module");
954for module in missing_functions.keys():
955 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000956
957lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000958
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000959