blob: 234685ca87dc852829bccaa6079040ee636a9afb [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",
William M. Brack015ccb22005-02-13 08:18:52 +0000115"xmlNanoFTPConnectTo", "xmlNanoHTTPMethod", "xmlNanoHTTPMethodRedir",
Daniel Veillard42595322004-11-08 10:52:06 +0000116# Complex I/O APIs
117"xmlCreateIOParserCtxt", "xmlParserInputBufferCreateIO",
118"xmlRegisterInputCallbacks", "xmlReaderForIO",
119"xmlOutputBufferCreateIO", "xmlRegisterOutputCallbacks",
William M. Brack015ccb22005-02-13 08:18:52 +0000120"xmlSaveToIO", "xmlIOHTTPOpenW",
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
William M. Brack015ccb22005-02-13 08:18:52 +0000132"xmlListDelete", "xmlOutputBufferClose", "xmlNanoFTPClose", "xmlNanoHTTPClose",
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 \
William M. Brack015ccb22005-02-13 08:18:52 +0000329 string.find(function, "Write") != -1 or \
330 string.find(function, "Fetch") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000331 return('fileoutput')
332 return('filepath')
333 if res == 'void_ptr':
334 if module == 'nanoftp' and name == 'ctx':
335 return('xmlNanoFTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000336 if function == 'xmlNanoFTPNewCtxt' or \
337 function == 'xmlNanoFTPConnectTo' or \
338 function == 'xmlNanoFTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000339 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000340 if module == 'nanohttp' and name == 'ctx':
341 return('xmlNanoHTTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000342 if function == 'xmlNanoHTTPMethod' or \
343 function == 'xmlNanoHTTPMethodRedir' or \
344 function == 'xmlNanoHTTPOpen' or \
345 function == 'xmlNanoHTTPOpenRedir':
346 return('xmlNanoHTTPCtxtPtr');
347 if function == 'xmlIOHTTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000348 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000349 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000350 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000351 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000352 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000353 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000354 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000355 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000356 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000357 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000358 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000359 if res == 'xmlNodePtr' and pos != 0:
360 if (function == 'xmlAddChild' and pos == 2) or \
361 (function == 'xmlAddChildList' and pos == 2) or \
362 (function == 'xmlAddNextSibling' and pos == 2) or \
363 (function == 'xmlAddSibling' and pos == 2) or \
364 (function == 'xmlDocSetRootElement' and pos == 2) or \
365 (function == 'xmlReplaceNode' and pos == 2) or \
366 (function == 'xmlTextMerge') or \
367 (function == 'xmlAddPrevSibling' and pos == 2):
368 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000369 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000370 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000371 if res == 'xmlChar_ptr' and name == 'name' and \
372 string.find(function, "EatName") != -1:
373 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000374 if res == 'void_ptr*':
375 res = 'void_ptr_ptr'
376 if res == 'char_ptr*':
377 res = 'char_ptr_ptr'
378 if res == 'xmlChar_ptr*':
379 res = 'xmlChar_ptr_ptr'
380 if res == 'const_xmlChar_ptr*':
381 res = 'const_xmlChar_ptr_ptr'
382 if res == 'const_char_ptr*':
383 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000384 if res == 'FILE_ptr' and module == 'debugXML':
385 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000386 if res == 'int' and name == 'options':
387 if module == 'parser' or module == 'xmlreader':
388 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000389
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000390 return res
391
Daniel Veillard34099b42004-11-04 17:34:35 +0000392known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000393
Daniel Veillardce682bc2004-11-05 17:22:25 +0000394def is_known_param_type(name, rtype):
395 global test
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000396 for type in known_param_types:
397 if type == name:
398 return 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000399 for type in generated_param_types:
400 if type == name:
401 return 1
402
403 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
404 if rtype[0:6] == 'const ':
405 crtype = rtype[6:]
406 else:
407 crtype = rtype
408
Daniel Veillarda521d282004-11-09 14:59:59 +0000409 define = 0
410 if modules_defines.has_key(module):
411 test.write("#ifdef %s\n" % (modules_defines[module]))
412 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000413 test.write("""
414#define gen_nb_%s 1
415static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
416 return(NULL);
417}
418static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
419}
420""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000421 if define == 1:
422 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000423 add_generated_param_type(name)
424 return 1
425
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000426 return 0
427
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000428#
429# Provide the type destructors for the return values
430#
431
Daniel Veillard34099b42004-11-04 17:34:35 +0000432known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000433
434def is_known_return_type(name):
435 for type in known_return_types:
436 if type == name:
437 return 1
438 return 0
439
Daniel Veillard34099b42004-11-04 17:34:35 +0000440#
441# Copy the beginning of the C test program result
442#
443
William M. Brack106cad62004-12-23 15:56:12 +0000444try:
445 input = open("testapi.c", "r")
446except:
447 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000448test = open('testapi.c.new', 'w')
449
450def compare_and_save():
451 global test
452
453 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000454 try:
455 input = open("testapi.c", "r").read()
456 except:
457 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000458 test = open('testapi.c.new', "r").read()
459 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000460 try:
461 os.system("rm testapi.c; mv testapi.c.new testapi.c")
462 except:
463 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000464 print("Updated testapi.c")
465 else:
466 print("Generated testapi.c is identical")
467
468line = input.readline()
469while line != "":
470 if line == "/* CUT HERE: everything below that line is generated */\n":
471 break;
472 if line[0:15] == "#define gen_nb_":
473 type = string.split(line[15:])[0]
474 known_param_types.append(type)
475 if line[0:19] == "static void desret_":
476 type = string.split(line[19:], '(')[0]
477 known_return_types.append(type)
478 test.write(line)
479 line = input.readline()
480input.close()
481
482if line == "":
483 print "Could not find the CUT marker in testapi.c skipping generation"
484 test.close()
485 sys.exit(0)
486
487print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
488 len(known_param_types), len(known_return_types)))
489test.write("/* CUT HERE: everything below that line is generated */\n")
490
491
492#
493# Open the input API description
494#
William M. Brack106cad62004-12-23 15:56:12 +0000495doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000496if doc == None:
497 print "Failed to load doc/libxml2-api.xml"
498 sys.exit(1)
499ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000500
501#
William M. Brack094dd862004-11-14 14:28:34 +0000502# Generate a list of all function parameters and select only
503# those used in the api tests
504#
505argtypes = {}
506args = ctxt.xpathEval("/api/symbols/function/arg")
507for arg in args:
508 mod = arg.xpathEval('string(../@file)')
509 func = arg.xpathEval('string(../@name)')
510 if (mod not in skipped_modules) and (func not in skipped_functions):
511 type = arg.xpathEval('string(@type)')
512 if not argtypes.has_key(type):
513 argtypes[type] = func
514
515# similarly for return types
516rettypes = {}
517rets = ctxt.xpathEval("/api/symbols/function/return")
518for ret in rets:
519 mod = ret.xpathEval('string(../@file)')
520 func = ret.xpathEval('string(../@name)')
521 if (mod not in skipped_modules) and (func not in skipped_functions):
522 type = ret.xpathEval('string(@type)')
523 if not rettypes.has_key(type):
524 rettypes[type] = func
525
526#
Daniel Veillard57b25162004-11-06 14:50:18 +0000527# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000528# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000529#
530enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
531for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000532 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000533 name = enum.xpathEval('string(@name)')
534 #
535 # Skip any enums which are not in our filtered lists
536 #
537 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
538 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000539 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000540
William M. Brack094dd862004-11-14 14:28:34 +0000541 if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000542 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
543 i = 0
544 vals = []
545 for value in values:
546 vname = value.xpathEval('string(@name)')
547 if vname == None:
548 continue;
549 i = i + 1
550 if i >= 5:
551 break;
552 vals.append(vname)
553 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000554 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000555 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000556 if modules_defines.has_key(module):
557 test.write("#ifdef %s\n" % (modules_defines[module]))
558 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000559 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
560 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
561 (name, name))
562 i = 1
563 for value in vals:
564 test.write(" if (no == %d) return(%s);\n" % (i, value))
565 i = i + 1
566 test.write(""" return(0);
567}
William M. Brack094dd862004-11-14 14:28:34 +0000568
569static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
570}
571
572""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000573 known_param_types.append(name)
574
William M. Brack094dd862004-11-14 14:28:34 +0000575 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000576 if define == 0 and modules_defines.has_key(module):
577 test.write("#ifdef %s\n" % (modules_defines[module]))
578 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000579 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000580}
581
William M. Brack094dd862004-11-14 14:28:34 +0000582""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000583 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000584 if define == 1:
585 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000586
587#
588# Load the interfaces
589#
Daniel Veillard57b25162004-11-06 14:50:18 +0000590headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000591for file in headers:
592 name = file.xpathEval('string(@name)')
593 if (name == None) or (name == ''):
594 continue
595
596 #
597 # Some module may be skipped because they don't really consists
598 # of user callable APIs
599 #
600 if is_skipped_module(name):
601 continue
602
603 #
604 # do not test deprecated APIs
605 #
606 desc = file.xpathEval('string(description)')
607 if string.find(desc, 'DEPRECATED') != -1:
608 print "Skipping deprecated interface %s" % name
609 continue;
610
611 test.write("#include <libxml/%s.h>\n" % name)
612 modules.append(name)
613
614#
615# Generate the callers signatures
616#
617for module in modules:
618 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000619
620#
621# Generate the top caller
622#
623
624test.write("""
625/**
626 * testlibxml2:
627 *
628 * Main entry point of the tester for the full libxml2 module,
629 * it calls all the tester entry point for each module.
630 *
631 * Returns the number of error found
632 */
633static int
634testlibxml2(void)
635{
Daniel Veillard42595322004-11-08 10:52:06 +0000636 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000637
638""")
639
640for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000641 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000642
643test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000644 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000645 function_tests, call_tests, test_ret);
646 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000647}
648
649""")
650
651#
652# How to handle a function
653#
654nb_tests = 0
655
656def generate_test(module, node):
657 global test
658 global nb_tests
659 nb_cond = 0
660 no_gen = 0
661
662 name = node.xpathEval('string(@name)')
663 if is_skipped_function(name):
664 return
665
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000666 #
667 # check we know how to handle the args and return values
668 # and store the informations for the generation
669 #
670 try:
671 args = node.xpathEval("arg")
672 except:
673 args = []
674 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000675 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000676 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000677 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000678 rtype = arg.xpathEval("string(@type)")
679 if rtype == 'void':
680 break;
681 info = arg.xpathEval("string(@info)")
682 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000683 type = type_convert(rtype, nam, info, module, name, n)
Daniel Veillardce682bc2004-11-05 17:22:25 +0000684 if is_known_param_type(type, rtype) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000685 add_missing_type(type, name);
686 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000687 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
688 rtype[0:6] == 'const ':
689 crtype = rtype[6:]
690 else:
691 crtype = rtype
692 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000693
694 try:
695 rets = node.xpathEval("return")
696 except:
697 rets = []
698 t_ret = None
699 for ret in rets:
700 rtype = ret.xpathEval("string(@type)")
701 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000702 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000703 if rtype == 'void':
704 break
705 if is_known_return_type(type) == 0:
706 add_missing_type(type, name);
707 no_gen = 1
708 t_ret = (type, rtype, info)
709 break
710
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000711 test.write("""
712static int
713test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000714 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000715
716""" % (name))
717
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000718 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000719 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000720 test.write("""
721 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000722 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000723}
724
725""")
726 return
727
728 try:
729 conds = node.xpathEval("cond")
730 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000731 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000732 nb_cond = nb_cond + 1
733 except:
734 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000735
736 define = 0
737 if function_defines.has_key(name):
738 test.write("#ifdef %s\n" % (function_defines[name]))
739 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000740
741 # Declare the memory usage counter
742 no_mem = is_skipped_memcheck(name)
743 if no_mem == 0:
744 test.write(" int mem_base;\n");
745
746 # Declare the return value
747 if t_ret != None:
748 test.write(" %s ret_val;\n" % (t_ret[1]))
749
750 # Declare the arguments
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 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000754 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000755 test.write(" int n_%s;\n" % (nam))
756 test.write("\n")
757
758 # Cascade loop on of each argument list of values
759 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000760 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000761 #
762 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
763 nam, nam, type, nam))
764
765 # log the memory usage
766 if no_mem == 0:
767 test.write(" mem_base = xmlMemBlocks();\n");
768
769 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000770 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000771 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000772 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000773 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000774 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
775 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000776
777 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000778 if extra_pre_call.has_key(name):
779 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000780 if t_ret != None:
781 test.write("\n ret_val = %s(" % (name))
782 need = 0
783 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000784 (nam, type, rtype, crtype, info) = arg
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000785 if need:
786 test.write(", ")
787 else:
788 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000789 if rtype != crtype:
790 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000791 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000792 test.write(");\n")
793 if extra_post_call.has_key(name):
794 test.write(" %s\n"% (extra_post_call[name]))
795 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000796 else:
797 test.write("\n %s(" % (name));
798 need = 0;
799 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000800 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000801 if need:
802 test.write(", ")
803 else:
804 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000805 if rtype != crtype:
806 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000807 test.write("%s" % nam)
808 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000809 if extra_post_call.has_key(name):
810 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000811
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000812 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000813
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000814 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000815 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000816 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000817 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000818 #
William M. Brackf13f77f2004-11-12 16:03:48 +0000819 test.write(" des_%s(n_%s, " % (type, nam))
820 if rtype != crtype:
821 test.write("(%s)" % rtype)
822 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000823 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000824
825 test.write(" xmlResetLastError();\n");
826 # Check the memory usage
827 if no_mem == 0:
828 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000829 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000830 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000831 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000832""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000833 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000834 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000835 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
836 test.write(""" printf("\\n");\n""")
837 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000838
839 for arg in t_args:
840 test.write(" }\n")
841
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000842 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000843 #
844 # end of conditional
845 #
846 while nb_cond > 0:
847 test.write("#endif\n")
848 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000849 if define == 1:
850 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000851
852 nb_tests = nb_tests + 1;
853
854 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000855 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000856}
857
858""")
859
860#
861# Generate all module callers
862#
863for module in modules:
864 # gather all the functions exported by that module
865 try:
866 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
867 except:
868 print "Failed to gather functions from module %s" % (module)
869 continue;
870
871 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000872 i = 0
873 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000874 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000875 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000876 generate_test(module, function);
877
878 # header
879 test.write("""static int
880test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000881 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000882
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000883 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000884""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000885
886 # iterate over all functions in the module generating the call
887 for function in functions:
888 name = function.xpathEval('string(@name)')
889 if is_skipped_function(name):
890 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000891 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000892
893 # footer
894 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000895 if (test_ret != 0)
896 printf("Module %s: %%d errors\\n", test_ret);
897 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000898}
899""" % (module))
900
Daniel Veillardce244ad2004-11-05 10:03:46 +0000901#
902# Generate direct module caller
903#
904test.write("""static int
905test_module(const char *module) {
906""");
907for module in modules:
908 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
909 module, module))
910test.write(""" return(0);
911}
912""");
913
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000914print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000915
Daniel Veillard34099b42004-11-04 17:34:35 +0000916compare_and_save()
917
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000918missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000919for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000920 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000921 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000922
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000923 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000924 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000925
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000926def compare_missing(a, b):
927 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000928
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000929missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000930print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000931lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000932lst.write("Missing support for %d types" % (len(missing_list)))
933lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000934for miss in missing_list:
935 lst.write("%s: %d :" % (miss[1], miss[0]))
936 i = 0
937 for n in missing_types[miss[1]]:
938 i = i + 1
939 if i > 5:
940 lst.write(" ...")
941 break
942 lst.write(" %s" % (n))
943 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000944lst.write("\n")
945lst.write("\n")
946lst.write("Missing support per module");
947for module in missing_functions.keys():
948 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000949
950lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000951
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000952