blob: c8e675d1a3850da7b90eb799ed33a59eeec95db0 [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 Veillardc394f732005-01-26 00:04:52 +0000234 "xmlNewDocElementContent":
235 """xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;""",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000236 "xmlDictReference": "xmlDictFree(dict);",
Daniel Veillard3d97e662004-11-04 10:49:00 +0000237 # Functions which deallocates one of their parameters
238 "xmlXPathConvertBoolean": """val = NULL;""",
239 "xmlXPathConvertNumber": """val = NULL;""",
240 "xmlXPathConvertString": """val = NULL;""",
241 "xmlSaveFileTo": """buf = NULL;""",
Daniel Veillard34099b42004-11-04 17:34:35 +0000242 "xmlSaveFormatFileTo": """buf = NULL;""",
243 "xmlIOParseDTD": "input = NULL;",
Daniel Veillardce244ad2004-11-05 10:03:46 +0000244 "xmlRemoveProp": "cur = NULL;",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000245 "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
246 "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
247 "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
248 "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000249 "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
Daniel Veillard42595322004-11-08 10:52:06 +0000250 "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000251 "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
252 "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
253 "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
254 "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
255 "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000256}
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000257
258modules = []
259
260def is_skipped_module(name):
261 for mod in skipped_modules:
262 if mod == name:
263 return 1
264 return 0
265
266def is_skipped_function(name):
267 for fun in skipped_functions:
268 if fun == name:
269 return 1
270 # Do not test destructors
271 if string.find(name, 'Free') != -1:
272 return 1
273 return 0
274
275def is_skipped_memcheck(name):
276 for fun in skipped_memcheck:
277 if fun == name:
278 return 1
279 return 0
280
281missing_types = {}
282def add_missing_type(name, func):
283 try:
284 list = missing_types[name]
285 list.append(func)
286 except:
287 missing_types[name] = [func]
288
Daniel Veillardce682bc2004-11-05 17:22:25 +0000289generated_param_types = []
290def add_generated_param_type(name):
291 generated_param_types.append(name)
292
293generated_return_types = []
294def add_generated_return_type(name):
295 generated_return_types.append(name)
296
Daniel Veillard34099b42004-11-04 17:34:35 +0000297missing_functions = {}
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000298missing_functions_nr = 0
Daniel Veillard34099b42004-11-04 17:34:35 +0000299def add_missing_functions(name, module):
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000300 global missing_functions_nr
301
302 missing_functions_nr = missing_functions_nr + 1
Daniel Veillard34099b42004-11-04 17:34:35 +0000303 try:
304 list = missing_functions[module]
305 list.append(name)
306 except:
307 missing_functions[module] = [name]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000308
309#
310# Provide the type generators and destructors for the parameters
311#
312
Daniel Veillarda03e3652004-11-02 18:45:30 +0000313def type_convert(str, name, info, module, function, pos):
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000314# res = string.replace(str, " ", " ")
315# res = string.replace(str, " ", " ")
316# res = string.replace(str, " ", " ")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000317 res = string.replace(str, " *", "_ptr")
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000318# res = string.replace(str, "*", "_ptr")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000319 res = string.replace(res, " ", "_")
320 if res == 'const_char_ptr':
321 if string.find(name, "file") != -1 or \
322 string.find(name, "uri") != -1 or \
323 string.find(name, "URI") != -1 or \
324 string.find(info, "filename") != -1 or \
325 string.find(info, "URI") != -1 or \
326 string.find(info, "URL") != -1:
William M. Brack83d9c372004-11-08 02:26:08 +0000327 if string.find(function, "Save") != -1 or \
328 string.find(function, "Create") != -1 or \
329 string.find(function, "Write") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000330 return('fileoutput')
331 return('filepath')
332 if res == 'void_ptr':
333 if module == 'nanoftp' and name == 'ctx':
334 return('xmlNanoFTPCtxtPtr')
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000335 if function == 'xmlNanoFTPNewCtxt':
336 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000337 if module == 'nanohttp' and name == 'ctx':
338 return('xmlNanoHTTPCtxtPtr')
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000339 if function == 'xmlIOHTTPOpenW':
340 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000341 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000342 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000343 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000344 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000345 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000346 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000347 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000348 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000349 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000350 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000351 if res == 'xmlNodePtr' and pos != 0:
352 if (function == 'xmlAddChild' and pos == 2) or \
353 (function == 'xmlAddChildList' and pos == 2) or \
354 (function == 'xmlAddNextSibling' and pos == 2) or \
355 (function == 'xmlAddSibling' and pos == 2) or \
356 (function == 'xmlDocSetRootElement' and pos == 2) or \
357 (function == 'xmlReplaceNode' and pos == 2) or \
358 (function == 'xmlTextMerge') or \
359 (function == 'xmlAddPrevSibling' and pos == 2):
360 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000361 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000362 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000363 if res == 'xmlChar_ptr' and name == 'name' and \
364 string.find(function, "EatName") != -1:
365 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000366 if res == 'void_ptr*':
367 res = 'void_ptr_ptr'
368 if res == 'char_ptr*':
369 res = 'char_ptr_ptr'
370 if res == 'xmlChar_ptr*':
371 res = 'xmlChar_ptr_ptr'
372 if res == 'const_xmlChar_ptr*':
373 res = 'const_xmlChar_ptr_ptr'
374 if res == 'const_char_ptr*':
375 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000376 if res == 'FILE_ptr' and module == 'debugXML':
377 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000378 if res == 'int' and name == 'options':
379 if module == 'parser' or module == 'xmlreader':
380 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000381
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000382 return res
383
Daniel Veillard34099b42004-11-04 17:34:35 +0000384known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000385
Daniel Veillardce682bc2004-11-05 17:22:25 +0000386def is_known_param_type(name, rtype):
387 global test
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000388 for type in known_param_types:
389 if type == name:
390 return 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000391 for type in generated_param_types:
392 if type == name:
393 return 1
394
395 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
396 if rtype[0:6] == 'const ':
397 crtype = rtype[6:]
398 else:
399 crtype = rtype
400
Daniel Veillarda521d282004-11-09 14:59:59 +0000401 define = 0
402 if modules_defines.has_key(module):
403 test.write("#ifdef %s\n" % (modules_defines[module]))
404 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000405 test.write("""
406#define gen_nb_%s 1
407static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
408 return(NULL);
409}
410static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
411}
412""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000413 if define == 1:
414 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000415 add_generated_param_type(name)
416 return 1
417
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000418 return 0
419
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000420#
421# Provide the type destructors for the return values
422#
423
Daniel Veillard34099b42004-11-04 17:34:35 +0000424known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000425
426def is_known_return_type(name):
427 for type in known_return_types:
428 if type == name:
429 return 1
430 return 0
431
Daniel Veillard34099b42004-11-04 17:34:35 +0000432#
433# Copy the beginning of the C test program result
434#
435
William M. Brack106cad62004-12-23 15:56:12 +0000436try:
437 input = open("testapi.c", "r")
438except:
439 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000440test = open('testapi.c.new', 'w')
441
442def compare_and_save():
443 global test
444
445 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000446 try:
447 input = open("testapi.c", "r").read()
448 except:
449 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000450 test = open('testapi.c.new', "r").read()
451 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000452 try:
453 os.system("rm testapi.c; mv testapi.c.new testapi.c")
454 except:
455 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000456 print("Updated testapi.c")
457 else:
458 print("Generated testapi.c is identical")
459
460line = input.readline()
461while line != "":
462 if line == "/* CUT HERE: everything below that line is generated */\n":
463 break;
464 if line[0:15] == "#define gen_nb_":
465 type = string.split(line[15:])[0]
466 known_param_types.append(type)
467 if line[0:19] == "static void desret_":
468 type = string.split(line[19:], '(')[0]
469 known_return_types.append(type)
470 test.write(line)
471 line = input.readline()
472input.close()
473
474if line == "":
475 print "Could not find the CUT marker in testapi.c skipping generation"
476 test.close()
477 sys.exit(0)
478
479print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
480 len(known_param_types), len(known_return_types)))
481test.write("/* CUT HERE: everything below that line is generated */\n")
482
483
484#
485# Open the input API description
486#
William M. Brack106cad62004-12-23 15:56:12 +0000487doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000488if doc == None:
489 print "Failed to load doc/libxml2-api.xml"
490 sys.exit(1)
491ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000492
493#
William M. Brack094dd862004-11-14 14:28:34 +0000494# Generate a list of all function parameters and select only
495# those used in the api tests
496#
497argtypes = {}
498args = ctxt.xpathEval("/api/symbols/function/arg")
499for arg in args:
500 mod = arg.xpathEval('string(../@file)')
501 func = arg.xpathEval('string(../@name)')
502 if (mod not in skipped_modules) and (func not in skipped_functions):
503 type = arg.xpathEval('string(@type)')
504 if not argtypes.has_key(type):
505 argtypes[type] = func
506
507# similarly for return types
508rettypes = {}
509rets = ctxt.xpathEval("/api/symbols/function/return")
510for ret in rets:
511 mod = ret.xpathEval('string(../@file)')
512 func = ret.xpathEval('string(../@name)')
513 if (mod not in skipped_modules) and (func not in skipped_functions):
514 type = ret.xpathEval('string(@type)')
515 if not rettypes.has_key(type):
516 rettypes[type] = func
517
518#
Daniel Veillard57b25162004-11-06 14:50:18 +0000519# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000520# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000521#
522enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
523for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000524 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000525 name = enum.xpathEval('string(@name)')
526 #
527 # Skip any enums which are not in our filtered lists
528 #
529 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
530 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000531 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000532
William M. Brack094dd862004-11-14 14:28:34 +0000533 if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000534 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
535 i = 0
536 vals = []
537 for value in values:
538 vname = value.xpathEval('string(@name)')
539 if vname == None:
540 continue;
541 i = i + 1
542 if i >= 5:
543 break;
544 vals.append(vname)
545 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000546 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000547 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000548 if modules_defines.has_key(module):
549 test.write("#ifdef %s\n" % (modules_defines[module]))
550 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000551 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
552 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
553 (name, name))
554 i = 1
555 for value in vals:
556 test.write(" if (no == %d) return(%s);\n" % (i, value))
557 i = i + 1
558 test.write(""" return(0);
559}
William M. Brack094dd862004-11-14 14:28:34 +0000560
561static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
562}
563
564""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000565 known_param_types.append(name)
566
William M. Brack094dd862004-11-14 14:28:34 +0000567 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000568 if define == 0 and modules_defines.has_key(module):
569 test.write("#ifdef %s\n" % (modules_defines[module]))
570 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000571 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000572}
573
William M. Brack094dd862004-11-14 14:28:34 +0000574""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000575 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000576 if define == 1:
577 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000578
579#
580# Load the interfaces
581#
Daniel Veillard57b25162004-11-06 14:50:18 +0000582headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000583for file in headers:
584 name = file.xpathEval('string(@name)')
585 if (name == None) or (name == ''):
586 continue
587
588 #
589 # Some module may be skipped because they don't really consists
590 # of user callable APIs
591 #
592 if is_skipped_module(name):
593 continue
594
595 #
596 # do not test deprecated APIs
597 #
598 desc = file.xpathEval('string(description)')
599 if string.find(desc, 'DEPRECATED') != -1:
600 print "Skipping deprecated interface %s" % name
601 continue;
602
603 test.write("#include <libxml/%s.h>\n" % name)
604 modules.append(name)
605
606#
607# Generate the callers signatures
608#
609for module in modules:
610 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000611
612#
613# Generate the top caller
614#
615
616test.write("""
617/**
618 * testlibxml2:
619 *
620 * Main entry point of the tester for the full libxml2 module,
621 * it calls all the tester entry point for each module.
622 *
623 * Returns the number of error found
624 */
625static int
626testlibxml2(void)
627{
Daniel Veillard42595322004-11-08 10:52:06 +0000628 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000629
630""")
631
632for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000633 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000634
635test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000636 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000637 function_tests, call_tests, test_ret);
638 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000639}
640
641""")
642
643#
644# How to handle a function
645#
646nb_tests = 0
647
648def generate_test(module, node):
649 global test
650 global nb_tests
651 nb_cond = 0
652 no_gen = 0
653
654 name = node.xpathEval('string(@name)')
655 if is_skipped_function(name):
656 return
657
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000658 #
659 # check we know how to handle the args and return values
660 # and store the informations for the generation
661 #
662 try:
663 args = node.xpathEval("arg")
664 except:
665 args = []
666 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000667 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000668 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000669 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000670 rtype = arg.xpathEval("string(@type)")
671 if rtype == 'void':
672 break;
673 info = arg.xpathEval("string(@info)")
674 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000675 type = type_convert(rtype, nam, info, module, name, n)
Daniel Veillardce682bc2004-11-05 17:22:25 +0000676 if is_known_param_type(type, rtype) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000677 add_missing_type(type, name);
678 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000679 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
680 rtype[0:6] == 'const ':
681 crtype = rtype[6:]
682 else:
683 crtype = rtype
684 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000685
686 try:
687 rets = node.xpathEval("return")
688 except:
689 rets = []
690 t_ret = None
691 for ret in rets:
692 rtype = ret.xpathEval("string(@type)")
693 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000694 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000695 if rtype == 'void':
696 break
697 if is_known_return_type(type) == 0:
698 add_missing_type(type, name);
699 no_gen = 1
700 t_ret = (type, rtype, info)
701 break
702
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000703 test.write("""
704static int
705test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000706 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000707
708""" % (name))
709
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000710 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000711 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000712 test.write("""
713 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000714 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000715}
716
717""")
718 return
719
720 try:
721 conds = node.xpathEval("cond")
722 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000723 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000724 nb_cond = nb_cond + 1
725 except:
726 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000727
728 define = 0
729 if function_defines.has_key(name):
730 test.write("#ifdef %s\n" % (function_defines[name]))
731 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000732
733 # Declare the memory usage counter
734 no_mem = is_skipped_memcheck(name)
735 if no_mem == 0:
736 test.write(" int mem_base;\n");
737
738 # Declare the return value
739 if t_ret != None:
740 test.write(" %s ret_val;\n" % (t_ret[1]))
741
742 # Declare the arguments
743 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000744 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000745 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000746 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000747 test.write(" int n_%s;\n" % (nam))
748 test.write("\n")
749
750 # Cascade loop on of each argument list of values
751 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000752 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000753 #
754 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
755 nam, nam, type, nam))
756
757 # log the memory usage
758 if no_mem == 0:
759 test.write(" mem_base = xmlMemBlocks();\n");
760
761 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000762 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000763 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 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000766 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
767 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000768
769 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000770 if extra_pre_call.has_key(name):
771 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000772 if t_ret != None:
773 test.write("\n ret_val = %s(" % (name))
774 need = 0
775 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 if need:
778 test.write(", ")
779 else:
780 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000781 if rtype != crtype:
782 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000783 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000784 test.write(");\n")
785 if extra_post_call.has_key(name):
786 test.write(" %s\n"% (extra_post_call[name]))
787 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000788 else:
789 test.write("\n %s(" % (name));
790 need = 0;
791 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000792 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000793 if need:
794 test.write(", ")
795 else:
796 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000797 if rtype != crtype:
798 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000799 test.write("%s" % nam)
800 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000801 if extra_post_call.has_key(name):
802 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000803
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000804 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000805
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000806 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000807 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000808 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000809 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000810 #
William M. Brackf13f77f2004-11-12 16:03:48 +0000811 test.write(" des_%s(n_%s, " % (type, nam))
812 if rtype != crtype:
813 test.write("(%s)" % rtype)
814 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000815 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000816
817 test.write(" xmlResetLastError();\n");
818 # Check the memory usage
819 if no_mem == 0:
820 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000821 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000822 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000823 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000824""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000825 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000826 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000827 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
828 test.write(""" printf("\\n");\n""")
829 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000830
831 for arg in t_args:
832 test.write(" }\n")
833
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000834 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000835 #
836 # end of conditional
837 #
838 while nb_cond > 0:
839 test.write("#endif\n")
840 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000841 if define == 1:
842 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000843
844 nb_tests = nb_tests + 1;
845
846 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000847 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000848}
849
850""")
851
852#
853# Generate all module callers
854#
855for module in modules:
856 # gather all the functions exported by that module
857 try:
858 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
859 except:
860 print "Failed to gather functions from module %s" % (module)
861 continue;
862
863 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000864 i = 0
865 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000866 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000867 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000868 generate_test(module, function);
869
870 # header
871 test.write("""static int
872test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000873 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000874
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000875 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000876""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000877
878 # iterate over all functions in the module generating the call
879 for function in functions:
880 name = function.xpathEval('string(@name)')
881 if is_skipped_function(name):
882 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000883 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000884
885 # footer
886 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000887 if (test_ret != 0)
888 printf("Module %s: %%d errors\\n", test_ret);
889 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000890}
891""" % (module))
892
Daniel Veillardce244ad2004-11-05 10:03:46 +0000893#
894# Generate direct module caller
895#
896test.write("""static int
897test_module(const char *module) {
898""");
899for module in modules:
900 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
901 module, module))
902test.write(""" return(0);
903}
904""");
905
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000906print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000907
Daniel Veillard34099b42004-11-04 17:34:35 +0000908compare_and_save()
909
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000910missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000911for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000912 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000913 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000914
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000915 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000916 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000917
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000918def compare_missing(a, b):
919 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000920
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000921missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000922print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000923lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000924lst.write("Missing support for %d types" % (len(missing_list)))
925lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000926for miss in missing_list:
927 lst.write("%s: %d :" % (miss[1], miss[0]))
928 i = 0
929 for n in missing_types[miss[1]]:
930 i = i + 1
931 if i > 5:
932 lst.write(" ...")
933 break
934 lst.write(" %s" % (n))
935 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000936lst.write("\n")
937lst.write("\n")
938lst.write("Missing support per module");
939for module in missing_functions.keys():
940 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000941
942lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000943
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000944