blob: 12dd718f7852749c895bfe8e3e09534db8452318 [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",
Daniel Veillarda521d282004-11-09 14:59:59 +000048}
49
50#
51# defines for specific functions
52#
53function_defines = {
54 "htmlDefaultSAXHandlerInit": "LIBXML_HTML_ENABLED",
55 "xmlSAX2EndElement" : "LIBXML_SAX1_ENABLED",
56 "xmlSAX2StartElement" : "LIBXML_SAX1_ENABLED",
57 "xmlSAXDefaultVersion" : "LIBXML_SAX1_ENABLED",
58 "UTF8Toisolat1" : "LIBXML_OUTPUT_ENABLED",
59 "xmlCleanupPredefinedEntities": "LIBXML_LEGACY_ENABLED",
60 "xmlInitializePredefinedEntities": "LIBXML_LEGACY_ENABLED",
61 "xmlSetFeature": "LIBXML_LEGACY_ENABLED",
62 "xmlGetFeature": "LIBXML_LEGACY_ENABLED",
63 "xmlGetFeaturesList": "LIBXML_LEGACY_ENABLED",
64 "xmlIOParseDTD": "LIBXML_VALID_ENABLED",
65 "xmlParseDTD": "LIBXML_VALID_ENABLED",
66 "xmlParseDoc": "LIBXML_SAX1_ENABLED",
67 "xmlParseMemory": "LIBXML_SAX1_ENABLED",
68 "xmlRecoverDoc": "LIBXML_SAX1_ENABLED",
69 "xmlParseFile": "LIBXML_SAX1_ENABLED",
70 "xmlRecoverFile": "LIBXML_SAX1_ENABLED",
71 "xmlRecoverMemory": "LIBXML_SAX1_ENABLED",
72 "xmlSAXParseFileWithData": "LIBXML_SAX1_ENABLED",
73 "xmlSAXParseMemory": "LIBXML_SAX1_ENABLED",
74 "xmlSAXUserParseMemory": "LIBXML_SAX1_ENABLED",
75 "xmlSAXParseDoc": "LIBXML_SAX1_ENABLED",
76 "xmlSAXParseDTD": "LIBXML_SAX1_ENABLED",
77 "xmlSAXUserParseFile": "LIBXML_SAX1_ENABLED",
78 "xmlParseEntity": "LIBXML_SAX1_ENABLED",
79 "xmlParseExternalEntity": "LIBXML_SAX1_ENABLED",
80 "xmlSAXParseMemoryWithData": "LIBXML_SAX1_ENABLED",
81 "xmlParseBalancedChunkMemory": "LIBXML_SAX1_ENABLED",
82 "xmlParseBalancedChunkMemoryRecover": "LIBXML_SAX1_ENABLED",
83 "xmlSetupParserForBuffer": "LIBXML_SAX1_ENABLED",
84 "xmlStopParser": "LIBXML_PUSH_ENABLED",
85 "xmlAttrSerializeTxtContent": "LIBXML_OUTPUT_ENABLED",
86 "xmlSAXParseFile": "LIBXML_SAX1_ENABLED",
87 "xmlSAXParseEntity": "LIBXML_SAX1_ENABLED",
88 "xmlNewTextChild": "LIBXML_TREE_ENABLED",
89 "xmlNewDocRawNode": "LIBXML_TREE_ENABLED",
90 "xmlNewProp": "LIBXML_TREE_ENABLED",
91 "xmlReconciliateNs": "LIBXML_TREE_ENABLED",
92 "xmlValidateNCName": "LIBXML_TREE_ENABLED",
93 "xmlValidateNMToken": "LIBXML_TREE_ENABLED",
94 "xmlValidateName": "LIBXML_TREE_ENABLED",
95 "xmlNewChild": "LIBXML_TREE_ENABLED",
96 "xmlValidateQName": "LIBXML_TREE_ENABLED",
97 "xmlSprintfElementContent": "LIBXML_OUTPUT_ENABLED",
98 "xmlValidGetPotentialChildren" : "LIBXML_VALID_ENABLED",
99 "xmlValidGetValidElements" : "LIBXML_VALID_ENABLED",
100 "docbDefaultSAXHandlerInit" : "LIBXML_DOCB_ENABLED",
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000101 "xmlTextReaderPreservePattern" : "LIBXML_PATTERN_ENABLED",
Daniel Veillarda521d282004-11-09 14:59:59 +0000102}
103
104#
William M. Brack094dd862004-11-14 14:28:34 +0000105# Some functions really need to be skipped for the tests.
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000106#
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000107skipped_functions = [
108# block on I/O
109"xmlFdRead", "xmlReadFd", "xmlCtxtReadFd",
110"htmlFdRead", "htmlReadFd", "htmlCtxtReadFd",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000111"xmlReaderNewFd", "xmlReaderForFd",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000112"xmlIORead", "xmlReadIO", "xmlCtxtReadIO",
113"htmlIORead", "htmlReadIO", "htmlCtxtReadIO",
Daniel Veillard27f20102004-11-05 11:50:11 +0000114"xmlReaderNewIO", "xmlBufferDump", "xmlNanoFTPConnect",
115"xmlNanoFTPConnectTo",
Daniel Veillard42595322004-11-08 10:52:06 +0000116# Complex I/O APIs
117"xmlCreateIOParserCtxt", "xmlParserInputBufferCreateIO",
118"xmlRegisterInputCallbacks", "xmlReaderForIO",
119"xmlOutputBufferCreateIO", "xmlRegisterOutputCallbacks",
120"xmlSaveToIO",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000121# library state cleanup, generate false leak informations and other
122# troubles, heavillyb tested otherwise.
Daniel Veillardce244ad2004-11-05 10:03:46 +0000123"xmlCleanupParser", "xmlRelaxNGCleanupTypes", "xmlSetListDoc",
124"xmlSetTreeDoc", "xmlUnlinkNode",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000125# hard to avoid leaks in the tests
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000126"xmlStrcat", "xmlStrncat", "xmlCatalogAddLocal", "xmlNewTextWriterDoc",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000127"xmlXPathNewValueTree", "xmlXPathWrapString",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000128# unimplemented
129"xmlTextReaderReadInnerXml", "xmlTextReaderReadOuterXml",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000130"xmlTextReaderReadString",
131# destructor
Daniel Veillard27f20102004-11-05 11:50:11 +0000132"xmlListDelete", "xmlOutputBufferClose", "xmlNanoFTPClose",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000133# deprecated
134"xmlCatalogGetPublic", "xmlCatalogGetSystem", "xmlEncodeEntities",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000135"xmlNewGlobalNs", "xmlHandleEntity", "xmlNamespaceParseNCName",
136"xmlNamespaceParseNSDef", "xmlNamespaceParseQName",
137"xmlParseNamespace", "xmlParseQuotedString", "xmlParserHandleReference",
138"xmlScanName",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000139"xmlDecodeEntities",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000140# allocators
141"xmlMemFree",
Daniel Veillardc2c894f2004-11-07 12:17:35 +0000142# verbosity
Daniel Veillarda82b1822004-11-08 16:24:57 +0000143"xmlCatalogSetDebug", "xmlShellPrintXPathError", "xmlShellPrintNode",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000144# Internal functions, no user space should really call them
145"xmlParseAttribute", "xmlParseAttributeListDecl", "xmlParseName",
146"xmlParseNmtoken", "xmlParseEntityValue", "xmlParseAttValue",
147"xmlParseSystemLiteral", "xmlParsePubidLiteral", "xmlParseCharData",
148"xmlParseExternalID", "xmlParseComment", "xmlParsePITarget", "xmlParsePI",
149"xmlParseNotationDecl", "xmlParseEntityDecl", "xmlParseDefaultDecl",
150"xmlParseNotationType", "xmlParseEnumerationType", "xmlParseEnumeratedType",
151"xmlParseAttributeType", "xmlParseAttributeListDecl",
152"xmlParseElementMixedContentDecl", "xmlParseElementChildrenContentDecl",
153"xmlParseElementContentDecl", "xmlParseElementDecl", "xmlParseMarkupDecl",
154"xmlParseCharRef", "xmlParseEntityRef", "xmlParseReference",
155"xmlParsePEReference", "xmlParseDocTypeDecl", "xmlParseAttribute",
156"xmlParseStartTag", "xmlParseEndTag", "xmlParseCDSect", "xmlParseContent",
157"xmlParseElement", "xmlParseVersionNum", "xmlParseVersionInfo",
158"xmlParseEncName", "xmlParseEncodingDecl", "xmlParseSDDecl",
159"xmlParseXMLDecl", "xmlParseTextDecl", "xmlParseMisc",
160"xmlParseExternalSubset", "xmlParserHandlePEReference",
161"xmlSkipBlankChars",
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 Veillard29614c72004-11-26 10:47:26 +0000174 "htmlParseFile", "htmlCtxtReadFile" # loads the catalogs
Daniel Veillarda03e3652004-11-02 18:45:30 +0000175]
176
177#
178# Extra code needed for some test cases
179#
Daniel Veillard34099b42004-11-04 17:34:35 +0000180extra_pre_call = {
Daniel Veillarda521d282004-11-09 14:59:59 +0000181 "xmlSAXUserParseFile": """
182#ifdef LIBXML_SAX1_ENABLED
183 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
184#endif
185""",
186 "xmlSAXUserParseMemory": """
187#ifdef LIBXML_SAX1_ENABLED
188 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
189#endif
190""",
191 "xmlParseBalancedChunkMemory": """
192#ifdef LIBXML_SAX1_ENABLED
193 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
194#endif
195""",
196 "xmlParseBalancedChunkMemoryRecover": """
197#ifdef LIBXML_SAX1_ENABLED
198 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
199#endif
200""",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000201 "xmlParserInputBufferCreateFd":
202 "if (fd >= 0) fd = -1;",
Daniel Veillard34099b42004-11-04 17:34:35 +0000203}
Daniel Veillarda03e3652004-11-02 18:45:30 +0000204extra_post_call = {
205 "xmlAddChild":
206 "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
207 "xmlAddChildList":
208 "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
209 "xmlAddSibling":
210 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
211 "xmlAddNextSibling":
212 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
213 "xmlAddPrevSibling":
214 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
215 "xmlDocSetRootElement":
216 "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
217 "xmlReplaceNode":
Daniel Veillardce244ad2004-11-05 10:03:46 +0000218 """if (cur != NULL) {
219 xmlUnlinkNode(cur);
220 xmlFreeNode(cur) ; cur = NULL ; }
221 if (old != NULL) {
222 xmlUnlinkNode(old);
223 xmlFreeNode(old) ; old = NULL ; }
224 ret_val = NULL;""",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000225 "xmlTextMerge":
226 """if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
Daniel Veillardce244ad2004-11-05 10:03:46 +0000227 xmlUnlinkNode(second);
Daniel Veillarda03e3652004-11-02 18:45:30 +0000228 xmlFreeNode(second) ; second = NULL ; }""",
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000229 "xmlBuildQName":
230 """if ((ret_val != NULL) && (ret_val != ncname) &&
231 (ret_val != prefix) && (ret_val != memory))
232 xmlFree(ret_val);
233 ret_val = NULL;""",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000234 "xmlDictReference": "xmlDictFree(dict);",
Daniel Veillard3d97e662004-11-04 10:49:00 +0000235 # Functions which deallocates one of their parameters
236 "xmlXPathConvertBoolean": """val = NULL;""",
237 "xmlXPathConvertNumber": """val = NULL;""",
238 "xmlXPathConvertString": """val = NULL;""",
239 "xmlSaveFileTo": """buf = NULL;""",
Daniel Veillard34099b42004-11-04 17:34:35 +0000240 "xmlSaveFormatFileTo": """buf = NULL;""",
241 "xmlIOParseDTD": "input = NULL;",
Daniel Veillardce244ad2004-11-05 10:03:46 +0000242 "xmlRemoveProp": "cur = NULL;",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000243 "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
244 "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
245 "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
246 "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000247 "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
Daniel Veillard42595322004-11-08 10:52:06 +0000248 "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000249 "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
250 "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
251 "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
252 "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
253 "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000254}
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000255
256modules = []
257
258def is_skipped_module(name):
259 for mod in skipped_modules:
260 if mod == name:
261 return 1
262 return 0
263
264def is_skipped_function(name):
265 for fun in skipped_functions:
266 if fun == name:
267 return 1
268 # Do not test destructors
269 if string.find(name, 'Free') != -1:
270 return 1
271 return 0
272
273def is_skipped_memcheck(name):
274 for fun in skipped_memcheck:
275 if fun == name:
276 return 1
277 return 0
278
279missing_types = {}
280def add_missing_type(name, func):
281 try:
282 list = missing_types[name]
283 list.append(func)
284 except:
285 missing_types[name] = [func]
286
Daniel Veillardce682bc2004-11-05 17:22:25 +0000287generated_param_types = []
288def add_generated_param_type(name):
289 generated_param_types.append(name)
290
291generated_return_types = []
292def add_generated_return_type(name):
293 generated_return_types.append(name)
294
Daniel Veillard34099b42004-11-04 17:34:35 +0000295missing_functions = {}
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000296missing_functions_nr = 0
Daniel Veillard34099b42004-11-04 17:34:35 +0000297def add_missing_functions(name, module):
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000298 global missing_functions_nr
299
300 missing_functions_nr = missing_functions_nr + 1
Daniel Veillard34099b42004-11-04 17:34:35 +0000301 try:
302 list = missing_functions[module]
303 list.append(name)
304 except:
305 missing_functions[module] = [name]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000306
307#
308# Provide the type generators and destructors for the parameters
309#
310
Daniel Veillarda03e3652004-11-02 18:45:30 +0000311def type_convert(str, name, info, module, function, pos):
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000312# res = string.replace(str, " ", " ")
313# res = string.replace(str, " ", " ")
314# res = string.replace(str, " ", " ")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000315 res = string.replace(str, " *", "_ptr")
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000316# res = string.replace(str, "*", "_ptr")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000317 res = string.replace(res, " ", "_")
318 if res == 'const_char_ptr':
319 if string.find(name, "file") != -1 or \
320 string.find(name, "uri") != -1 or \
321 string.find(name, "URI") != -1 or \
322 string.find(info, "filename") != -1 or \
323 string.find(info, "URI") != -1 or \
324 string.find(info, "URL") != -1:
William M. Brack83d9c372004-11-08 02:26:08 +0000325 if string.find(function, "Save") != -1 or \
326 string.find(function, "Create") != -1 or \
327 string.find(function, "Write") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000328 return('fileoutput')
329 return('filepath')
330 if res == 'void_ptr':
331 if module == 'nanoftp' and name == 'ctx':
332 return('xmlNanoFTPCtxtPtr')
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000333 if function == 'xmlNanoFTPNewCtxt':
334 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000335 if module == 'nanohttp' and name == 'ctx':
336 return('xmlNanoHTTPCtxtPtr')
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000337 if function == 'xmlIOHTTPOpenW':
338 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000339 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000340 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000341 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000342 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000343 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000344 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000345 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000346 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000347 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000348 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000349 if res == 'xmlNodePtr' and pos != 0:
350 if (function == 'xmlAddChild' and pos == 2) or \
351 (function == 'xmlAddChildList' and pos == 2) or \
352 (function == 'xmlAddNextSibling' and pos == 2) or \
353 (function == 'xmlAddSibling' and pos == 2) or \
354 (function == 'xmlDocSetRootElement' and pos == 2) or \
355 (function == 'xmlReplaceNode' and pos == 2) or \
356 (function == 'xmlTextMerge') or \
357 (function == 'xmlAddPrevSibling' and pos == 2):
358 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000359 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000360 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000361 if res == 'xmlChar_ptr' and name == 'name' and \
362 string.find(function, "EatName") != -1:
363 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000364 if res == 'void_ptr*':
365 res = 'void_ptr_ptr'
366 if res == 'char_ptr*':
367 res = 'char_ptr_ptr'
368 if res == 'xmlChar_ptr*':
369 res = 'xmlChar_ptr_ptr'
370 if res == 'const_xmlChar_ptr*':
371 res = 'const_xmlChar_ptr_ptr'
372 if res == 'const_char_ptr*':
373 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000374 if res == 'FILE_ptr' and module == 'debugXML':
375 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000376 if res == 'int' and name == 'options':
377 if module == 'parser' or module == 'xmlreader':
378 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000379
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000380 return res
381
Daniel Veillard34099b42004-11-04 17:34:35 +0000382known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000383
Daniel Veillardce682bc2004-11-05 17:22:25 +0000384def is_known_param_type(name, rtype):
385 global test
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000386 for type in known_param_types:
387 if type == name:
388 return 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000389 for type in generated_param_types:
390 if type == name:
391 return 1
392
393 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
394 if rtype[0:6] == 'const ':
395 crtype = rtype[6:]
396 else:
397 crtype = rtype
398
Daniel Veillarda521d282004-11-09 14:59:59 +0000399 define = 0
400 if modules_defines.has_key(module):
401 test.write("#ifdef %s\n" % (modules_defines[module]))
402 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000403 test.write("""
404#define gen_nb_%s 1
405static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
406 return(NULL);
407}
408static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
409}
410""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000411 if define == 1:
412 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000413 add_generated_param_type(name)
414 return 1
415
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000416 return 0
417
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000418#
419# Provide the type destructors for the return values
420#
421
Daniel Veillard34099b42004-11-04 17:34:35 +0000422known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000423
424def is_known_return_type(name):
425 for type in known_return_types:
426 if type == name:
427 return 1
428 return 0
429
Daniel Veillard34099b42004-11-04 17:34:35 +0000430#
431# Copy the beginning of the C test program result
432#
433
William M. Brack106cad62004-12-23 15:56:12 +0000434try:
435 input = open("testapi.c", "r")
436except:
437 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000438test = open('testapi.c.new', 'w')
439
440def compare_and_save():
441 global test
442
443 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000444 try:
445 input = open("testapi.c", "r").read()
446 except:
447 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000448 test = open('testapi.c.new', "r").read()
449 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000450 try:
451 os.system("rm testapi.c; mv testapi.c.new testapi.c")
452 except:
453 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000454 print("Updated testapi.c")
455 else:
456 print("Generated testapi.c is identical")
457
458line = input.readline()
459while line != "":
460 if line == "/* CUT HERE: everything below that line is generated */\n":
461 break;
462 if line[0:15] == "#define gen_nb_":
463 type = string.split(line[15:])[0]
464 known_param_types.append(type)
465 if line[0:19] == "static void desret_":
466 type = string.split(line[19:], '(')[0]
467 known_return_types.append(type)
468 test.write(line)
469 line = input.readline()
470input.close()
471
472if line == "":
473 print "Could not find the CUT marker in testapi.c skipping generation"
474 test.close()
475 sys.exit(0)
476
477print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
478 len(known_param_types), len(known_return_types)))
479test.write("/* CUT HERE: everything below that line is generated */\n")
480
481
482#
483# Open the input API description
484#
William M. Brack106cad62004-12-23 15:56:12 +0000485doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000486if doc == None:
487 print "Failed to load doc/libxml2-api.xml"
488 sys.exit(1)
489ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000490
491#
William M. Brack094dd862004-11-14 14:28:34 +0000492# Generate a list of all function parameters and select only
493# those used in the api tests
494#
495argtypes = {}
496args = ctxt.xpathEval("/api/symbols/function/arg")
497for arg in args:
498 mod = arg.xpathEval('string(../@file)')
499 func = arg.xpathEval('string(../@name)')
500 if (mod not in skipped_modules) and (func not in skipped_functions):
501 type = arg.xpathEval('string(@type)')
502 if not argtypes.has_key(type):
503 argtypes[type] = func
504
505# similarly for return types
506rettypes = {}
507rets = ctxt.xpathEval("/api/symbols/function/return")
508for ret in rets:
509 mod = ret.xpathEval('string(../@file)')
510 func = ret.xpathEval('string(../@name)')
511 if (mod not in skipped_modules) and (func not in skipped_functions):
512 type = ret.xpathEval('string(@type)')
513 if not rettypes.has_key(type):
514 rettypes[type] = func
515
516#
Daniel Veillard57b25162004-11-06 14:50:18 +0000517# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000518# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000519#
520enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
521for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000522 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000523 name = enum.xpathEval('string(@name)')
524 #
525 # Skip any enums which are not in our filtered lists
526 #
527 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
528 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000529 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000530
William M. Brack094dd862004-11-14 14:28:34 +0000531 if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000532 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
533 i = 0
534 vals = []
535 for value in values:
536 vname = value.xpathEval('string(@name)')
537 if vname == None:
538 continue;
539 i = i + 1
540 if i >= 5:
541 break;
542 vals.append(vname)
543 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000544 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000545 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000546 if modules_defines.has_key(module):
547 test.write("#ifdef %s\n" % (modules_defines[module]))
548 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000549 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
550 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
551 (name, name))
552 i = 1
553 for value in vals:
554 test.write(" if (no == %d) return(%s);\n" % (i, value))
555 i = i + 1
556 test.write(""" return(0);
557}
William M. Brack094dd862004-11-14 14:28:34 +0000558
559static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
560}
561
562""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000563 known_param_types.append(name)
564
William M. Brack094dd862004-11-14 14:28:34 +0000565 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000566 if define == 0 and modules_defines.has_key(module):
567 test.write("#ifdef %s\n" % (modules_defines[module]))
568 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000569 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000570}
571
William M. Brack094dd862004-11-14 14:28:34 +0000572""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000573 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000574 if define == 1:
575 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000576
577#
578# Load the interfaces
579#
Daniel Veillard57b25162004-11-06 14:50:18 +0000580headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000581for file in headers:
582 name = file.xpathEval('string(@name)')
583 if (name == None) or (name == ''):
584 continue
585
586 #
587 # Some module may be skipped because they don't really consists
588 # of user callable APIs
589 #
590 if is_skipped_module(name):
591 continue
592
593 #
594 # do not test deprecated APIs
595 #
596 desc = file.xpathEval('string(description)')
597 if string.find(desc, 'DEPRECATED') != -1:
598 print "Skipping deprecated interface %s" % name
599 continue;
600
601 test.write("#include <libxml/%s.h>\n" % name)
602 modules.append(name)
603
604#
605# Generate the callers signatures
606#
607for module in modules:
608 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000609
610#
611# Generate the top caller
612#
613
614test.write("""
615/**
616 * testlibxml2:
617 *
618 * Main entry point of the tester for the full libxml2 module,
619 * it calls all the tester entry point for each module.
620 *
621 * Returns the number of error found
622 */
623static int
624testlibxml2(void)
625{
Daniel Veillard42595322004-11-08 10:52:06 +0000626 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000627
628""")
629
630for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000631 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000632
633test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000634 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000635 function_tests, call_tests, test_ret);
636 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000637}
638
639""")
640
641#
642# How to handle a function
643#
644nb_tests = 0
645
646def generate_test(module, node):
647 global test
648 global nb_tests
649 nb_cond = 0
650 no_gen = 0
651
652 name = node.xpathEval('string(@name)')
653 if is_skipped_function(name):
654 return
655
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000656 #
657 # check we know how to handle the args and return values
658 # and store the informations for the generation
659 #
660 try:
661 args = node.xpathEval("arg")
662 except:
663 args = []
664 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000665 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000666 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000667 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000668 rtype = arg.xpathEval("string(@type)")
669 if rtype == 'void':
670 break;
671 info = arg.xpathEval("string(@info)")
672 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000673 type = type_convert(rtype, nam, info, module, name, n)
Daniel Veillardce682bc2004-11-05 17:22:25 +0000674 if is_known_param_type(type, rtype) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000675 add_missing_type(type, name);
676 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000677 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
678 rtype[0:6] == 'const ':
679 crtype = rtype[6:]
680 else:
681 crtype = rtype
682 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000683
684 try:
685 rets = node.xpathEval("return")
686 except:
687 rets = []
688 t_ret = None
689 for ret in rets:
690 rtype = ret.xpathEval("string(@type)")
691 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000692 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000693 if rtype == 'void':
694 break
695 if is_known_return_type(type) == 0:
696 add_missing_type(type, name);
697 no_gen = 1
698 t_ret = (type, rtype, info)
699 break
700
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000701 test.write("""
702static int
703test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000704 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000705
706""" % (name))
707
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000708 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000709 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000710 test.write("""
711 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000712 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000713}
714
715""")
716 return
717
718 try:
719 conds = node.xpathEval("cond")
720 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000721 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000722 nb_cond = nb_cond + 1
723 except:
724 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000725
726 define = 0
727 if function_defines.has_key(name):
728 test.write("#ifdef %s\n" % (function_defines[name]))
729 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000730
731 # Declare the memory usage counter
732 no_mem = is_skipped_memcheck(name)
733 if no_mem == 0:
734 test.write(" int mem_base;\n");
735
736 # Declare the return value
737 if t_ret != None:
738 test.write(" %s ret_val;\n" % (t_ret[1]))
739
740 # Declare the arguments
741 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000742 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000743 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000744 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000745 test.write(" int n_%s;\n" % (nam))
746 test.write("\n")
747
748 # Cascade loop on of each argument list of values
749 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000750 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000751 #
752 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
753 nam, nam, type, nam))
754
755 # log the memory usage
756 if no_mem == 0:
757 test.write(" mem_base = xmlMemBlocks();\n");
758
759 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000760 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000761 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000762 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000763 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000764 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
765 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000766
767 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000768 if extra_pre_call.has_key(name):
769 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000770 if t_ret != None:
771 test.write("\n ret_val = %s(" % (name))
772 need = 0
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 if need:
776 test.write(", ")
777 else:
778 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000779 if rtype != crtype:
780 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000781 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000782 test.write(");\n")
783 if extra_post_call.has_key(name):
784 test.write(" %s\n"% (extra_post_call[name]))
785 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000786 else:
787 test.write("\n %s(" % (name));
788 need = 0;
789 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000790 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000791 if need:
792 test.write(", ")
793 else:
794 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000795 if rtype != crtype:
796 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000797 test.write("%s" % nam)
798 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000799 if extra_post_call.has_key(name):
800 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000801
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000802 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000803
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000804 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000805 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000806 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000807 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000808 #
William M. Brackf13f77f2004-11-12 16:03:48 +0000809 test.write(" des_%s(n_%s, " % (type, nam))
810 if rtype != crtype:
811 test.write("(%s)" % rtype)
812 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000813 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000814
815 test.write(" xmlResetLastError();\n");
816 # Check the memory usage
817 if no_mem == 0:
818 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000819 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000820 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000821 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000822""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000823 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000824 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000825 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
826 test.write(""" printf("\\n");\n""")
827 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000828
829 for arg in t_args:
830 test.write(" }\n")
831
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000832 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000833 #
834 # end of conditional
835 #
836 while nb_cond > 0:
837 test.write("#endif\n")
838 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000839 if define == 1:
840 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000841
842 nb_tests = nb_tests + 1;
843
844 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000845 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000846}
847
848""")
849
850#
851# Generate all module callers
852#
853for module in modules:
854 # gather all the functions exported by that module
855 try:
856 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
857 except:
858 print "Failed to gather functions from module %s" % (module)
859 continue;
860
861 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000862 i = 0
863 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000864 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000865 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000866 generate_test(module, function);
867
868 # header
869 test.write("""static int
870test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000871 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000872
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000873 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000874""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000875
876 # iterate over all functions in the module generating the call
877 for function in functions:
878 name = function.xpathEval('string(@name)')
879 if is_skipped_function(name):
880 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000881 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000882
883 # footer
884 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000885 if (test_ret != 0)
886 printf("Module %s: %%d errors\\n", test_ret);
887 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000888}
889""" % (module))
890
Daniel Veillardce244ad2004-11-05 10:03:46 +0000891#
892# Generate direct module caller
893#
894test.write("""static int
895test_module(const char *module) {
896""");
897for module in modules:
898 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
899 module, module))
900test.write(""" return(0);
901}
902""");
903
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000904print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000905
Daniel Veillard34099b42004-11-04 17:34:35 +0000906compare_and_save()
907
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000908missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000909for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000910 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000911 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000912
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000913 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000914 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000915
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000916def compare_missing(a, b):
917 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000918
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000919missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000920print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000921lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000922lst.write("Missing support for %d types" % (len(missing_list)))
923lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000924for miss in missing_list:
925 lst.write("%s: %d :" % (miss[1], miss[0]))
926 i = 0
927 for n in missing_types[miss[1]]:
928 i = i + 1
929 if i > 5:
930 lst.write(" ...")
931 break
932 lst.write(" %s" % (n))
933 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000934lst.write("\n")
935lst.write("\n")
936lst.write("Missing support per module");
937for module in missing_functions.keys():
938 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000939
940lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000941
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000942