blob: e4ede36458c56d6a5e4303167885224e17d3b105 [file] [log] [blame]
Daniel Veillard36e5cd52004-11-02 14:52:23 +00001#!/usr/bin/python -u
2#
3# generate a tester program for the API
4#
5import sys
Daniel Veillard34099b42004-11-04 17:34:35 +00006import os
Daniel Veillard36e5cd52004-11-02 14:52:23 +00007import string
8try:
9 import libxml2
10except:
11 print "libxml2 python bindings not available, skipping testapi.c generation"
12 sys.exit(0)
13
William M. Brack106cad62004-12-23 15:56:12 +000014if len(sys.argv) > 1:
15 srcPref = sys.argv[1] + '/'
16else:
17 srcPref = ''
18
Daniel Veillard36e5cd52004-11-02 14:52:23 +000019#
William M. Brack094dd862004-11-14 14:28:34 +000020# Modules we want to skip in API test
Daniel Veillard36e5cd52004-11-02 14:52:23 +000021#
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +000022skipped_modules = [ "SAX", "xlink", "threads", "globals",
Daniel Veillarda82b1822004-11-08 16:24:57 +000023 "xmlmemory", "xmlversion", "xmlexports",
24 #deprecated
25 "DOCBparser",
Daniel Veillardd005b9e2004-11-03 17:07:05 +000026]
Daniel Veillard36e5cd52004-11-02 14:52:23 +000027
28#
Daniel Veillarda521d282004-11-09 14:59:59 +000029# defines for each module
30#
31modules_defines = {
32 "HTMLparser": "LIBXML_HTML_ENABLED",
33 "catalog": "LIBXML_CATALOG_ENABLED",
34 "xmlreader": "LIBXML_READER_ENABLED",
35 "relaxng": "LIBXML_SCHEMAS_ENABLED",
36 "schemasInternals": "LIBXML_SCHEMAS_ENABLED",
37 "xmlschemas": "LIBXML_SCHEMAS_ENABLED",
38 "xmlschemastypes": "LIBXML_SCHEMAS_ENABLED",
39 "xpath": "LIBXML_XPATH_ENABLED",
40 "xpathInternals": "LIBXML_XPATH_ENABLED",
41 "xinclude": "LIBXML_XINCLUDE_ENABLED",
42 "xpointer": "LIBXML_XPTR_ENABLED",
43 "xmlregexp" : "LIBXML_REGEXP_ENABLED",
44 "xmlautomata" : "LIBXML_AUTOMATA_ENABLED",
45 "xmlsave" : "LIBXML_OUTPUT_ENABLED",
46 "DOCBparser" : "LIBXML_DOCB_ENABLED",
Daniel Veillardfc0b6f62005-01-09 17:48:02 +000047 "xmlmodule" : "LIBXML_MODULES_ENABLED",
William M. Brackba1d3172005-03-25 03:05:46 +000048 "pattern" : "LIBXML_PATTERN_ENABLED",
Daniel Veillarda521d282004-11-09 14:59:59 +000049}
50
51#
52# defines for specific functions
53#
54function_defines = {
55 "htmlDefaultSAXHandlerInit": "LIBXML_HTML_ENABLED",
56 "xmlSAX2EndElement" : "LIBXML_SAX1_ENABLED",
57 "xmlSAX2StartElement" : "LIBXML_SAX1_ENABLED",
58 "xmlSAXDefaultVersion" : "LIBXML_SAX1_ENABLED",
59 "UTF8Toisolat1" : "LIBXML_OUTPUT_ENABLED",
60 "xmlCleanupPredefinedEntities": "LIBXML_LEGACY_ENABLED",
61 "xmlInitializePredefinedEntities": "LIBXML_LEGACY_ENABLED",
62 "xmlSetFeature": "LIBXML_LEGACY_ENABLED",
63 "xmlGetFeature": "LIBXML_LEGACY_ENABLED",
64 "xmlGetFeaturesList": "LIBXML_LEGACY_ENABLED",
65 "xmlIOParseDTD": "LIBXML_VALID_ENABLED",
66 "xmlParseDTD": "LIBXML_VALID_ENABLED",
67 "xmlParseDoc": "LIBXML_SAX1_ENABLED",
68 "xmlParseMemory": "LIBXML_SAX1_ENABLED",
69 "xmlRecoverDoc": "LIBXML_SAX1_ENABLED",
70 "xmlParseFile": "LIBXML_SAX1_ENABLED",
71 "xmlRecoverFile": "LIBXML_SAX1_ENABLED",
72 "xmlRecoverMemory": "LIBXML_SAX1_ENABLED",
73 "xmlSAXParseFileWithData": "LIBXML_SAX1_ENABLED",
74 "xmlSAXParseMemory": "LIBXML_SAX1_ENABLED",
75 "xmlSAXUserParseMemory": "LIBXML_SAX1_ENABLED",
76 "xmlSAXParseDoc": "LIBXML_SAX1_ENABLED",
77 "xmlSAXParseDTD": "LIBXML_SAX1_ENABLED",
78 "xmlSAXUserParseFile": "LIBXML_SAX1_ENABLED",
79 "xmlParseEntity": "LIBXML_SAX1_ENABLED",
80 "xmlParseExternalEntity": "LIBXML_SAX1_ENABLED",
81 "xmlSAXParseMemoryWithData": "LIBXML_SAX1_ENABLED",
82 "xmlParseBalancedChunkMemory": "LIBXML_SAX1_ENABLED",
83 "xmlParseBalancedChunkMemoryRecover": "LIBXML_SAX1_ENABLED",
84 "xmlSetupParserForBuffer": "LIBXML_SAX1_ENABLED",
85 "xmlStopParser": "LIBXML_PUSH_ENABLED",
86 "xmlAttrSerializeTxtContent": "LIBXML_OUTPUT_ENABLED",
87 "xmlSAXParseFile": "LIBXML_SAX1_ENABLED",
88 "xmlSAXParseEntity": "LIBXML_SAX1_ENABLED",
89 "xmlNewTextChild": "LIBXML_TREE_ENABLED",
90 "xmlNewDocRawNode": "LIBXML_TREE_ENABLED",
91 "xmlNewProp": "LIBXML_TREE_ENABLED",
92 "xmlReconciliateNs": "LIBXML_TREE_ENABLED",
93 "xmlValidateNCName": "LIBXML_TREE_ENABLED",
94 "xmlValidateNMToken": "LIBXML_TREE_ENABLED",
95 "xmlValidateName": "LIBXML_TREE_ENABLED",
96 "xmlNewChild": "LIBXML_TREE_ENABLED",
97 "xmlValidateQName": "LIBXML_TREE_ENABLED",
98 "xmlSprintfElementContent": "LIBXML_OUTPUT_ENABLED",
99 "xmlValidGetPotentialChildren" : "LIBXML_VALID_ENABLED",
100 "xmlValidGetValidElements" : "LIBXML_VALID_ENABLED",
101 "docbDefaultSAXHandlerInit" : "LIBXML_DOCB_ENABLED",
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000102 "xmlTextReaderPreservePattern" : "LIBXML_PATTERN_ENABLED",
Daniel Veillarda521d282004-11-09 14:59:59 +0000103}
104
105#
William M. Brack094dd862004-11-14 14:28:34 +0000106# Some functions really need to be skipped for the tests.
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000107#
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000108skipped_functions = [
109# block on I/O
110"xmlFdRead", "xmlReadFd", "xmlCtxtReadFd",
111"htmlFdRead", "htmlReadFd", "htmlCtxtReadFd",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000112"xmlReaderNewFd", "xmlReaderForFd",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000113"xmlIORead", "xmlReadIO", "xmlCtxtReadIO",
114"htmlIORead", "htmlReadIO", "htmlCtxtReadIO",
Daniel Veillard27f20102004-11-05 11:50:11 +0000115"xmlReaderNewIO", "xmlBufferDump", "xmlNanoFTPConnect",
William M. Brack015ccb22005-02-13 08:18:52 +0000116"xmlNanoFTPConnectTo", "xmlNanoHTTPMethod", "xmlNanoHTTPMethodRedir",
Daniel Veillard42595322004-11-08 10:52:06 +0000117# Complex I/O APIs
118"xmlCreateIOParserCtxt", "xmlParserInputBufferCreateIO",
119"xmlRegisterInputCallbacks", "xmlReaderForIO",
120"xmlOutputBufferCreateIO", "xmlRegisterOutputCallbacks",
William M. Brack015ccb22005-02-13 08:18:52 +0000121"xmlSaveToIO", "xmlIOHTTPOpenW",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000122# library state cleanup, generate false leak informations and other
123# troubles, heavillyb tested otherwise.
Daniel Veillardce244ad2004-11-05 10:03:46 +0000124"xmlCleanupParser", "xmlRelaxNGCleanupTypes", "xmlSetListDoc",
125"xmlSetTreeDoc", "xmlUnlinkNode",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000126# hard to avoid leaks in the tests
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000127"xmlStrcat", "xmlStrncat", "xmlCatalogAddLocal", "xmlNewTextWriterDoc",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000128"xmlXPathNewValueTree", "xmlXPathWrapString",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000129# unimplemented
130"xmlTextReaderReadInnerXml", "xmlTextReaderReadOuterXml",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000131"xmlTextReaderReadString",
132# destructor
William M. Brack015ccb22005-02-13 08:18:52 +0000133"xmlListDelete", "xmlOutputBufferClose", "xmlNanoFTPClose", "xmlNanoHTTPClose",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000134# deprecated
135"xmlCatalogGetPublic", "xmlCatalogGetSystem", "xmlEncodeEntities",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000136"xmlNewGlobalNs", "xmlHandleEntity", "xmlNamespaceParseNCName",
137"xmlNamespaceParseNSDef", "xmlNamespaceParseQName",
138"xmlParseNamespace", "xmlParseQuotedString", "xmlParserHandleReference",
139"xmlScanName",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000140"xmlDecodeEntities",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000141# allocators
142"xmlMemFree",
Daniel Veillardc2c894f2004-11-07 12:17:35 +0000143# verbosity
Daniel Veillarda82b1822004-11-08 16:24:57 +0000144"xmlCatalogSetDebug", "xmlShellPrintXPathError", "xmlShellPrintNode",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000145# Internal functions, no user space should really call them
146"xmlParseAttribute", "xmlParseAttributeListDecl", "xmlParseName",
147"xmlParseNmtoken", "xmlParseEntityValue", "xmlParseAttValue",
148"xmlParseSystemLiteral", "xmlParsePubidLiteral", "xmlParseCharData",
149"xmlParseExternalID", "xmlParseComment", "xmlParsePITarget", "xmlParsePI",
150"xmlParseNotationDecl", "xmlParseEntityDecl", "xmlParseDefaultDecl",
151"xmlParseNotationType", "xmlParseEnumerationType", "xmlParseEnumeratedType",
152"xmlParseAttributeType", "xmlParseAttributeListDecl",
153"xmlParseElementMixedContentDecl", "xmlParseElementChildrenContentDecl",
154"xmlParseElementContentDecl", "xmlParseElementDecl", "xmlParseMarkupDecl",
155"xmlParseCharRef", "xmlParseEntityRef", "xmlParseReference",
156"xmlParsePEReference", "xmlParseDocTypeDecl", "xmlParseAttribute",
157"xmlParseStartTag", "xmlParseEndTag", "xmlParseCDSect", "xmlParseContent",
158"xmlParseElement", "xmlParseVersionNum", "xmlParseVersionInfo",
159"xmlParseEncName", "xmlParseEncodingDecl", "xmlParseSDDecl",
160"xmlParseXMLDecl", "xmlParseTextDecl", "xmlParseMisc",
161"xmlParseExternalSubset", "xmlParserHandlePEReference",
162"xmlSkipBlankChars",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000163]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000164
165#
William M. Brack094dd862004-11-14 14:28:34 +0000166# These functions have side effects on the global state
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000167# and hence generate errors on memory allocation tests
168#
169skipped_memcheck = [ "xmlLoadCatalog", "xmlAddEncodingAlias",
170 "xmlSchemaInitTypes", "xmlNanoFTPProxy", "xmlNanoFTPScanProxy",
171 "xmlNanoHTTPScanProxy", "xmlResetLastError", "xmlCatalogConvert",
172 "xmlCatalogRemove", "xmlLoadCatalogs", "xmlCleanupCharEncodingHandlers",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000173 "xmlInitCharEncodingHandlers", "xmlCatalogCleanup",
Daniel Veillard42595322004-11-08 10:52:06 +0000174 "xmlSchemaGetBuiltInType",
Daniel Veillard29614c72004-11-26 10:47:26 +0000175 "htmlParseFile", "htmlCtxtReadFile" # loads the catalogs
Daniel Veillarda03e3652004-11-02 18:45:30 +0000176]
177
178#
179# Extra code needed for some test cases
180#
Daniel Veillard34099b42004-11-04 17:34:35 +0000181extra_pre_call = {
Daniel Veillarda521d282004-11-09 14:59:59 +0000182 "xmlSAXUserParseFile": """
183#ifdef LIBXML_SAX1_ENABLED
184 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
185#endif
186""",
187 "xmlSAXUserParseMemory": """
188#ifdef LIBXML_SAX1_ENABLED
189 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
190#endif
191""",
192 "xmlParseBalancedChunkMemory": """
193#ifdef LIBXML_SAX1_ENABLED
194 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
195#endif
196""",
197 "xmlParseBalancedChunkMemoryRecover": """
198#ifdef LIBXML_SAX1_ENABLED
199 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
200#endif
201""",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000202 "xmlParserInputBufferCreateFd":
203 "if (fd >= 0) fd = -1;",
Daniel Veillard34099b42004-11-04 17:34:35 +0000204}
Daniel Veillarda03e3652004-11-02 18:45:30 +0000205extra_post_call = {
206 "xmlAddChild":
207 "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
208 "xmlAddChildList":
209 "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
210 "xmlAddSibling":
211 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
212 "xmlAddNextSibling":
213 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
214 "xmlAddPrevSibling":
215 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
216 "xmlDocSetRootElement":
217 "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
218 "xmlReplaceNode":
Daniel Veillardce244ad2004-11-05 10:03:46 +0000219 """if (cur != NULL) {
220 xmlUnlinkNode(cur);
221 xmlFreeNode(cur) ; cur = NULL ; }
222 if (old != NULL) {
223 xmlUnlinkNode(old);
224 xmlFreeNode(old) ; old = NULL ; }
225 ret_val = NULL;""",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000226 "xmlTextMerge":
227 """if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
Daniel Veillardce244ad2004-11-05 10:03:46 +0000228 xmlUnlinkNode(second);
Daniel Veillarda03e3652004-11-02 18:45:30 +0000229 xmlFreeNode(second) ; second = NULL ; }""",
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000230 "xmlBuildQName":
231 """if ((ret_val != NULL) && (ret_val != ncname) &&
232 (ret_val != prefix) && (ret_val != memory))
233 xmlFree(ret_val);
234 ret_val = NULL;""",
Daniel Veillardc394f732005-01-26 00:04:52 +0000235 "xmlNewDocElementContent":
236 """xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;""",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000237 "xmlDictReference": "xmlDictFree(dict);",
Daniel Veillard3d97e662004-11-04 10:49:00 +0000238 # Functions which deallocates one of their parameters
239 "xmlXPathConvertBoolean": """val = NULL;""",
240 "xmlXPathConvertNumber": """val = NULL;""",
241 "xmlXPathConvertString": """val = NULL;""",
242 "xmlSaveFileTo": """buf = NULL;""",
Daniel Veillard34099b42004-11-04 17:34:35 +0000243 "xmlSaveFormatFileTo": """buf = NULL;""",
244 "xmlIOParseDTD": "input = NULL;",
Daniel Veillardce244ad2004-11-05 10:03:46 +0000245 "xmlRemoveProp": "cur = NULL;",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000246 "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
247 "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
248 "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
249 "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000250 "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
Daniel Veillard42595322004-11-08 10:52:06 +0000251 "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000252 "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
253 "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
254 "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
255 "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
256 "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000257}
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000258
259modules = []
260
261def is_skipped_module(name):
262 for mod in skipped_modules:
263 if mod == name:
264 return 1
265 return 0
266
267def is_skipped_function(name):
268 for fun in skipped_functions:
269 if fun == name:
270 return 1
271 # Do not test destructors
272 if string.find(name, 'Free') != -1:
273 return 1
274 return 0
275
276def is_skipped_memcheck(name):
277 for fun in skipped_memcheck:
278 if fun == name:
279 return 1
280 return 0
281
282missing_types = {}
283def add_missing_type(name, func):
284 try:
285 list = missing_types[name]
286 list.append(func)
287 except:
288 missing_types[name] = [func]
289
Daniel Veillardce682bc2004-11-05 17:22:25 +0000290generated_param_types = []
291def add_generated_param_type(name):
292 generated_param_types.append(name)
293
294generated_return_types = []
295def add_generated_return_type(name):
296 generated_return_types.append(name)
297
Daniel Veillard34099b42004-11-04 17:34:35 +0000298missing_functions = {}
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000299missing_functions_nr = 0
Daniel Veillard34099b42004-11-04 17:34:35 +0000300def add_missing_functions(name, module):
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000301 global missing_functions_nr
302
303 missing_functions_nr = missing_functions_nr + 1
Daniel Veillard34099b42004-11-04 17:34:35 +0000304 try:
305 list = missing_functions[module]
306 list.append(name)
307 except:
308 missing_functions[module] = [name]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000309
310#
311# Provide the type generators and destructors for the parameters
312#
313
Daniel Veillarda03e3652004-11-02 18:45:30 +0000314def type_convert(str, name, info, module, function, pos):
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000315# res = string.replace(str, " ", " ")
316# res = string.replace(str, " ", " ")
317# res = string.replace(str, " ", " ")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000318 res = string.replace(str, " *", "_ptr")
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000319# res = string.replace(str, "*", "_ptr")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000320 res = string.replace(res, " ", "_")
321 if res == 'const_char_ptr':
322 if string.find(name, "file") != -1 or \
323 string.find(name, "uri") != -1 or \
324 string.find(name, "URI") != -1 or \
325 string.find(info, "filename") != -1 or \
326 string.find(info, "URI") != -1 or \
327 string.find(info, "URL") != -1:
William M. Brack83d9c372004-11-08 02:26:08 +0000328 if string.find(function, "Save") != -1 or \
329 string.find(function, "Create") != -1 or \
William M. Brack015ccb22005-02-13 08:18:52 +0000330 string.find(function, "Write") != -1 or \
331 string.find(function, "Fetch") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000332 return('fileoutput')
333 return('filepath')
334 if res == 'void_ptr':
335 if module == 'nanoftp' and name == 'ctx':
336 return('xmlNanoFTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000337 if function == 'xmlNanoFTPNewCtxt' or \
338 function == 'xmlNanoFTPConnectTo' or \
339 function == 'xmlNanoFTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000340 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000341 if module == 'nanohttp' and name == 'ctx':
342 return('xmlNanoHTTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000343 if function == 'xmlNanoHTTPMethod' or \
344 function == 'xmlNanoHTTPMethodRedir' or \
345 function == 'xmlNanoHTTPOpen' or \
346 function == 'xmlNanoHTTPOpenRedir':
347 return('xmlNanoHTTPCtxtPtr');
348 if function == 'xmlIOHTTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000349 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000350 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000351 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000352 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000353 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000354 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000355 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000356 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000357 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000358 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000359 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000360 if res == 'xmlNodePtr' and pos != 0:
361 if (function == 'xmlAddChild' and pos == 2) or \
362 (function == 'xmlAddChildList' and pos == 2) or \
363 (function == 'xmlAddNextSibling' and pos == 2) or \
364 (function == 'xmlAddSibling' and pos == 2) or \
365 (function == 'xmlDocSetRootElement' and pos == 2) or \
366 (function == 'xmlReplaceNode' and pos == 2) or \
367 (function == 'xmlTextMerge') or \
368 (function == 'xmlAddPrevSibling' and pos == 2):
369 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000370 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000371 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000372 if res == 'xmlChar_ptr' and name == 'name' and \
373 string.find(function, "EatName") != -1:
374 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000375 if res == 'void_ptr*':
376 res = 'void_ptr_ptr'
377 if res == 'char_ptr*':
378 res = 'char_ptr_ptr'
379 if res == 'xmlChar_ptr*':
380 res = 'xmlChar_ptr_ptr'
381 if res == 'const_xmlChar_ptr*':
382 res = 'const_xmlChar_ptr_ptr'
383 if res == 'const_char_ptr*':
384 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000385 if res == 'FILE_ptr' and module == 'debugXML':
386 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000387 if res == 'int' and name == 'options':
388 if module == 'parser' or module == 'xmlreader':
389 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000390
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000391 return res
392
Daniel Veillard34099b42004-11-04 17:34:35 +0000393known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000394
Daniel Veillardce682bc2004-11-05 17:22:25 +0000395def is_known_param_type(name, rtype):
396 global test
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000397 for type in known_param_types:
398 if type == name:
399 return 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000400 for type in generated_param_types:
401 if type == name:
402 return 1
403
404 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
405 if rtype[0:6] == 'const ':
406 crtype = rtype[6:]
407 else:
408 crtype = rtype
409
Daniel Veillarda521d282004-11-09 14:59:59 +0000410 define = 0
411 if modules_defines.has_key(module):
412 test.write("#ifdef %s\n" % (modules_defines[module]))
413 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000414 test.write("""
415#define gen_nb_%s 1
416static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
417 return(NULL);
418}
419static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
420}
421""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000422 if define == 1:
423 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000424 add_generated_param_type(name)
425 return 1
426
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000427 return 0
428
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000429#
430# Provide the type destructors for the return values
431#
432
Daniel Veillard34099b42004-11-04 17:34:35 +0000433known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000434
435def is_known_return_type(name):
436 for type in known_return_types:
437 if type == name:
438 return 1
439 return 0
440
Daniel Veillard34099b42004-11-04 17:34:35 +0000441#
442# Copy the beginning of the C test program result
443#
444
William M. Brack106cad62004-12-23 15:56:12 +0000445try:
446 input = open("testapi.c", "r")
447except:
448 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000449test = open('testapi.c.new', 'w')
450
451def compare_and_save():
452 global test
453
454 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000455 try:
456 input = open("testapi.c", "r").read()
457 except:
458 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000459 test = open('testapi.c.new', "r").read()
460 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000461 try:
462 os.system("rm testapi.c; mv testapi.c.new testapi.c")
463 except:
464 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000465 print("Updated testapi.c")
466 else:
467 print("Generated testapi.c is identical")
468
469line = input.readline()
470while line != "":
471 if line == "/* CUT HERE: everything below that line is generated */\n":
472 break;
473 if line[0:15] == "#define gen_nb_":
474 type = string.split(line[15:])[0]
475 known_param_types.append(type)
476 if line[0:19] == "static void desret_":
477 type = string.split(line[19:], '(')[0]
478 known_return_types.append(type)
479 test.write(line)
480 line = input.readline()
481input.close()
482
483if line == "":
484 print "Could not find the CUT marker in testapi.c skipping generation"
485 test.close()
486 sys.exit(0)
487
488print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
489 len(known_param_types), len(known_return_types)))
490test.write("/* CUT HERE: everything below that line is generated */\n")
491
492
493#
494# Open the input API description
495#
William M. Brack106cad62004-12-23 15:56:12 +0000496doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000497if doc == None:
498 print "Failed to load doc/libxml2-api.xml"
499 sys.exit(1)
500ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000501
502#
William M. Brack094dd862004-11-14 14:28:34 +0000503# Generate a list of all function parameters and select only
504# those used in the api tests
505#
506argtypes = {}
507args = ctxt.xpathEval("/api/symbols/function/arg")
508for arg in args:
509 mod = arg.xpathEval('string(../@file)')
510 func = arg.xpathEval('string(../@name)')
511 if (mod not in skipped_modules) and (func not in skipped_functions):
512 type = arg.xpathEval('string(@type)')
513 if not argtypes.has_key(type):
514 argtypes[type] = func
515
516# similarly for return types
517rettypes = {}
518rets = ctxt.xpathEval("/api/symbols/function/return")
519for ret in rets:
520 mod = ret.xpathEval('string(../@file)')
521 func = ret.xpathEval('string(../@name)')
522 if (mod not in skipped_modules) and (func not in skipped_functions):
523 type = ret.xpathEval('string(@type)')
524 if not rettypes.has_key(type):
525 rettypes[type] = func
526
527#
Daniel Veillard57b25162004-11-06 14:50:18 +0000528# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000529# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000530#
531enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
532for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000533 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000534 name = enum.xpathEval('string(@name)')
535 #
536 # Skip any enums which are not in our filtered lists
537 #
538 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
539 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000540 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000541
William M. Brack094dd862004-11-14 14:28:34 +0000542 if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000543 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
544 i = 0
545 vals = []
546 for value in values:
547 vname = value.xpathEval('string(@name)')
548 if vname == None:
549 continue;
550 i = i + 1
551 if i >= 5:
552 break;
553 vals.append(vname)
554 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000555 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000556 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000557 if modules_defines.has_key(module):
558 test.write("#ifdef %s\n" % (modules_defines[module]))
559 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000560 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
561 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
562 (name, name))
563 i = 1
564 for value in vals:
565 test.write(" if (no == %d) return(%s);\n" % (i, value))
566 i = i + 1
567 test.write(""" return(0);
568}
William M. Brack094dd862004-11-14 14:28:34 +0000569
570static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
571}
572
573""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000574 known_param_types.append(name)
575
William M. Brack094dd862004-11-14 14:28:34 +0000576 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000577 if define == 0 and modules_defines.has_key(module):
578 test.write("#ifdef %s\n" % (modules_defines[module]))
579 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000580 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000581}
582
William M. Brack094dd862004-11-14 14:28:34 +0000583""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000584 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000585 if define == 1:
586 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000587
588#
589# Load the interfaces
590#
Daniel Veillard57b25162004-11-06 14:50:18 +0000591headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000592for file in headers:
593 name = file.xpathEval('string(@name)')
594 if (name == None) or (name == ''):
595 continue
596
597 #
598 # Some module may be skipped because they don't really consists
599 # of user callable APIs
600 #
601 if is_skipped_module(name):
602 continue
603
604 #
605 # do not test deprecated APIs
606 #
607 desc = file.xpathEval('string(description)')
608 if string.find(desc, 'DEPRECATED') != -1:
609 print "Skipping deprecated interface %s" % name
610 continue;
611
612 test.write("#include <libxml/%s.h>\n" % name)
613 modules.append(name)
614
615#
616# Generate the callers signatures
617#
618for module in modules:
619 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000620
621#
622# Generate the top caller
623#
624
625test.write("""
626/**
627 * testlibxml2:
628 *
629 * Main entry point of the tester for the full libxml2 module,
630 * it calls all the tester entry point for each module.
631 *
632 * Returns the number of error found
633 */
634static int
635testlibxml2(void)
636{
Daniel Veillard42595322004-11-08 10:52:06 +0000637 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000638
639""")
640
641for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000642 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000643
644test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000645 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000646 function_tests, call_tests, test_ret);
647 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000648}
649
650""")
651
652#
653# How to handle a function
654#
655nb_tests = 0
656
657def generate_test(module, node):
658 global test
659 global nb_tests
660 nb_cond = 0
661 no_gen = 0
662
663 name = node.xpathEval('string(@name)')
664 if is_skipped_function(name):
665 return
666
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000667 #
668 # check we know how to handle the args and return values
669 # and store the informations for the generation
670 #
671 try:
672 args = node.xpathEval("arg")
673 except:
674 args = []
675 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000676 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000677 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000678 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000679 rtype = arg.xpathEval("string(@type)")
680 if rtype == 'void':
681 break;
682 info = arg.xpathEval("string(@info)")
683 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000684 type = type_convert(rtype, nam, info, module, name, n)
Daniel Veillardce682bc2004-11-05 17:22:25 +0000685 if is_known_param_type(type, rtype) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000686 add_missing_type(type, name);
687 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000688 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
689 rtype[0:6] == 'const ':
690 crtype = rtype[6:]
691 else:
692 crtype = rtype
693 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000694
695 try:
696 rets = node.xpathEval("return")
697 except:
698 rets = []
699 t_ret = None
700 for ret in rets:
701 rtype = ret.xpathEval("string(@type)")
702 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000703 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000704 if rtype == 'void':
705 break
706 if is_known_return_type(type) == 0:
707 add_missing_type(type, name);
708 no_gen = 1
709 t_ret = (type, rtype, info)
710 break
711
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000712 test.write("""
713static int
714test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000715 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000716
717""" % (name))
718
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000719 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000720 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000721 test.write("""
722 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000723 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000724}
725
726""")
727 return
728
729 try:
730 conds = node.xpathEval("cond")
731 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000732 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000733 nb_cond = nb_cond + 1
734 except:
735 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000736
737 define = 0
738 if function_defines.has_key(name):
739 test.write("#ifdef %s\n" % (function_defines[name]))
740 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000741
742 # Declare the memory usage counter
743 no_mem = is_skipped_memcheck(name)
744 if no_mem == 0:
745 test.write(" int mem_base;\n");
746
747 # Declare the return value
748 if t_ret != None:
749 test.write(" %s ret_val;\n" % (t_ret[1]))
750
751 # Declare the arguments
752 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000753 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000754 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000755 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000756 test.write(" int n_%s;\n" % (nam))
757 test.write("\n")
758
759 # Cascade loop on of each argument list of values
760 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000761 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000762 #
763 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
764 nam, nam, type, nam))
765
766 # log the memory usage
767 if no_mem == 0:
768 test.write(" mem_base = xmlMemBlocks();\n");
769
770 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000771 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000772 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000773 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000774 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000775 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
776 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000777
778 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000779 if extra_pre_call.has_key(name):
780 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000781 if t_ret != None:
782 test.write("\n ret_val = %s(" % (name))
783 need = 0
784 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000785 (nam, type, rtype, crtype, info) = arg
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000786 if need:
787 test.write(", ")
788 else:
789 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000790 if rtype != crtype:
791 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000792 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000793 test.write(");\n")
794 if extra_post_call.has_key(name):
795 test.write(" %s\n"% (extra_post_call[name]))
796 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000797 else:
798 test.write("\n %s(" % (name));
799 need = 0;
800 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000801 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000802 if need:
803 test.write(", ")
804 else:
805 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000806 if rtype != crtype:
807 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000808 test.write("%s" % nam)
809 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000810 if extra_post_call.has_key(name):
811 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000812
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000813 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000814
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000815 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000816 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000817 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000818 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000819 #
William M. Brackf13f77f2004-11-12 16:03:48 +0000820 test.write(" des_%s(n_%s, " % (type, nam))
821 if rtype != crtype:
822 test.write("(%s)" % rtype)
823 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000824 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000825
826 test.write(" xmlResetLastError();\n");
827 # Check the memory usage
828 if no_mem == 0:
829 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000830 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000831 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000832 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000833""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000834 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000835 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000836 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
837 test.write(""" printf("\\n");\n""")
838 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000839
840 for arg in t_args:
841 test.write(" }\n")
842
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000843 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000844 #
845 # end of conditional
846 #
847 while nb_cond > 0:
848 test.write("#endif\n")
849 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000850 if define == 1:
851 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000852
853 nb_tests = nb_tests + 1;
854
855 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000856 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000857}
858
859""")
860
861#
862# Generate all module callers
863#
864for module in modules:
865 # gather all the functions exported by that module
866 try:
867 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
868 except:
869 print "Failed to gather functions from module %s" % (module)
870 continue;
871
872 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000873 i = 0
874 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000875 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000876 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000877 generate_test(module, function);
878
879 # header
880 test.write("""static int
881test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000882 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000883
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000884 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000885""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000886
887 # iterate over all functions in the module generating the call
888 for function in functions:
889 name = function.xpathEval('string(@name)')
890 if is_skipped_function(name):
891 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000892 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000893
894 # footer
895 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000896 if (test_ret != 0)
897 printf("Module %s: %%d errors\\n", test_ret);
898 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000899}
900""" % (module))
901
Daniel Veillardce244ad2004-11-05 10:03:46 +0000902#
903# Generate direct module caller
904#
905test.write("""static int
906test_module(const char *module) {
907""");
908for module in modules:
909 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
910 module, module))
911test.write(""" return(0);
912}
913""");
914
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000915print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000916
Daniel Veillard34099b42004-11-04 17:34:35 +0000917compare_and_save()
918
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000919missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000920for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000921 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000922 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000923
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000924 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000925 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000926
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000927def compare_missing(a, b):
928 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000929
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000930missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000931print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000932lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000933lst.write("Missing support for %d types" % (len(missing_list)))
934lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000935for miss in missing_list:
936 lst.write("%s: %d :" % (miss[1], miss[0]))
937 i = 0
938 for n in missing_types[miss[1]]:
939 i = i + 1
940 if i > 5:
941 lst.write(" ...")
942 break
943 lst.write(" %s" % (n))
944 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000945lst.write("\n")
946lst.write("\n")
947lst.write("Missing support per module");
948for module in missing_functions.keys():
949 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000950
951lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000952
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000953