blob: 465fdd79b05ab0585f23dbf24b29200fc7932432 [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 Veillard7e33dba2005-07-03 22:40:26 +0000257 "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000258}
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000259
260modules = []
261
262def is_skipped_module(name):
263 for mod in skipped_modules:
264 if mod == name:
265 return 1
266 return 0
267
268def is_skipped_function(name):
269 for fun in skipped_functions:
270 if fun == name:
271 return 1
272 # Do not test destructors
273 if string.find(name, 'Free') != -1:
274 return 1
275 return 0
276
277def is_skipped_memcheck(name):
278 for fun in skipped_memcheck:
279 if fun == name:
280 return 1
281 return 0
282
283missing_types = {}
284def add_missing_type(name, func):
285 try:
286 list = missing_types[name]
287 list.append(func)
288 except:
289 missing_types[name] = [func]
290
Daniel Veillardce682bc2004-11-05 17:22:25 +0000291generated_param_types = []
292def add_generated_param_type(name):
293 generated_param_types.append(name)
294
295generated_return_types = []
296def add_generated_return_type(name):
297 generated_return_types.append(name)
298
Daniel Veillard34099b42004-11-04 17:34:35 +0000299missing_functions = {}
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000300missing_functions_nr = 0
Daniel Veillard34099b42004-11-04 17:34:35 +0000301def add_missing_functions(name, module):
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000302 global missing_functions_nr
303
304 missing_functions_nr = missing_functions_nr + 1
Daniel Veillard34099b42004-11-04 17:34:35 +0000305 try:
306 list = missing_functions[module]
307 list.append(name)
308 except:
309 missing_functions[module] = [name]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000310
311#
312# Provide the type generators and destructors for the parameters
313#
314
Daniel Veillarda03e3652004-11-02 18:45:30 +0000315def type_convert(str, name, info, module, function, pos):
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000316# res = string.replace(str, " ", " ")
317# res = string.replace(str, " ", " ")
318# res = string.replace(str, " ", " ")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000319 res = string.replace(str, " *", "_ptr")
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000320# res = string.replace(str, "*", "_ptr")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000321 res = string.replace(res, " ", "_")
322 if res == 'const_char_ptr':
323 if string.find(name, "file") != -1 or \
324 string.find(name, "uri") != -1 or \
325 string.find(name, "URI") != -1 or \
326 string.find(info, "filename") != -1 or \
327 string.find(info, "URI") != -1 or \
328 string.find(info, "URL") != -1:
William M. Brack83d9c372004-11-08 02:26:08 +0000329 if string.find(function, "Save") != -1 or \
330 string.find(function, "Create") != -1 or \
William M. Brack015ccb22005-02-13 08:18:52 +0000331 string.find(function, "Write") != -1 or \
332 string.find(function, "Fetch") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000333 return('fileoutput')
334 return('filepath')
335 if res == 'void_ptr':
336 if module == 'nanoftp' and name == 'ctx':
337 return('xmlNanoFTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000338 if function == 'xmlNanoFTPNewCtxt' or \
339 function == 'xmlNanoFTPConnectTo' or \
340 function == 'xmlNanoFTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000341 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000342 if module == 'nanohttp' and name == 'ctx':
343 return('xmlNanoHTTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000344 if function == 'xmlNanoHTTPMethod' or \
345 function == 'xmlNanoHTTPMethodRedir' or \
346 function == 'xmlNanoHTTPOpen' or \
347 function == 'xmlNanoHTTPOpenRedir':
348 return('xmlNanoHTTPCtxtPtr');
349 if function == 'xmlIOHTTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000350 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000351 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000352 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000353 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000354 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000355 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000356 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000357 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000358 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000359 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000360 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000361 if res == 'xmlNodePtr' and pos != 0:
362 if (function == 'xmlAddChild' and pos == 2) or \
363 (function == 'xmlAddChildList' and pos == 2) or \
364 (function == 'xmlAddNextSibling' and pos == 2) or \
365 (function == 'xmlAddSibling' and pos == 2) or \
366 (function == 'xmlDocSetRootElement' and pos == 2) or \
367 (function == 'xmlReplaceNode' and pos == 2) or \
368 (function == 'xmlTextMerge') or \
369 (function == 'xmlAddPrevSibling' and pos == 2):
370 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000371 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000372 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000373 if res == 'xmlChar_ptr' and name == 'name' and \
374 string.find(function, "EatName") != -1:
375 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000376 if res == 'void_ptr*':
377 res = 'void_ptr_ptr'
378 if res == 'char_ptr*':
379 res = 'char_ptr_ptr'
380 if res == 'xmlChar_ptr*':
381 res = 'xmlChar_ptr_ptr'
382 if res == 'const_xmlChar_ptr*':
383 res = 'const_xmlChar_ptr_ptr'
384 if res == 'const_char_ptr*':
385 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000386 if res == 'FILE_ptr' and module == 'debugXML':
387 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000388 if res == 'int' and name == 'options':
389 if module == 'parser' or module == 'xmlreader':
390 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000391
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000392 return res
393
Daniel Veillard34099b42004-11-04 17:34:35 +0000394known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000395
Daniel Veillardce682bc2004-11-05 17:22:25 +0000396def is_known_param_type(name, rtype):
397 global test
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000398 for type in known_param_types:
399 if type == name:
400 return 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000401 for type in generated_param_types:
402 if type == name:
403 return 1
404
405 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
406 if rtype[0:6] == 'const ':
407 crtype = rtype[6:]
408 else:
409 crtype = rtype
410
Daniel Veillarda521d282004-11-09 14:59:59 +0000411 define = 0
412 if modules_defines.has_key(module):
413 test.write("#ifdef %s\n" % (modules_defines[module]))
414 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000415 test.write("""
416#define gen_nb_%s 1
417static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
418 return(NULL);
419}
420static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
421}
422""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000423 if define == 1:
424 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000425 add_generated_param_type(name)
426 return 1
427
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000428 return 0
429
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000430#
431# Provide the type destructors for the return values
432#
433
Daniel Veillard34099b42004-11-04 17:34:35 +0000434known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000435
436def is_known_return_type(name):
437 for type in known_return_types:
438 if type == name:
439 return 1
440 return 0
441
Daniel Veillard34099b42004-11-04 17:34:35 +0000442#
443# Copy the beginning of the C test program result
444#
445
William M. Brack106cad62004-12-23 15:56:12 +0000446try:
447 input = open("testapi.c", "r")
448except:
449 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000450test = open('testapi.c.new', 'w')
451
452def compare_and_save():
453 global test
454
455 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000456 try:
457 input = open("testapi.c", "r").read()
458 except:
459 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000460 test = open('testapi.c.new', "r").read()
461 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000462 try:
463 os.system("rm testapi.c; mv testapi.c.new testapi.c")
464 except:
465 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000466 print("Updated testapi.c")
467 else:
468 print("Generated testapi.c is identical")
469
470line = input.readline()
471while line != "":
472 if line == "/* CUT HERE: everything below that line is generated */\n":
473 break;
474 if line[0:15] == "#define gen_nb_":
475 type = string.split(line[15:])[0]
476 known_param_types.append(type)
477 if line[0:19] == "static void desret_":
478 type = string.split(line[19:], '(')[0]
479 known_return_types.append(type)
480 test.write(line)
481 line = input.readline()
482input.close()
483
484if line == "":
485 print "Could not find the CUT marker in testapi.c skipping generation"
486 test.close()
487 sys.exit(0)
488
489print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
490 len(known_param_types), len(known_return_types)))
491test.write("/* CUT HERE: everything below that line is generated */\n")
492
493
494#
495# Open the input API description
496#
William M. Brack106cad62004-12-23 15:56:12 +0000497doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000498if doc == None:
499 print "Failed to load doc/libxml2-api.xml"
500 sys.exit(1)
501ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000502
503#
William M. Brack094dd862004-11-14 14:28:34 +0000504# Generate a list of all function parameters and select only
505# those used in the api tests
506#
507argtypes = {}
508args = ctxt.xpathEval("/api/symbols/function/arg")
509for arg in args:
510 mod = arg.xpathEval('string(../@file)')
511 func = arg.xpathEval('string(../@name)')
512 if (mod not in skipped_modules) and (func not in skipped_functions):
513 type = arg.xpathEval('string(@type)')
514 if not argtypes.has_key(type):
515 argtypes[type] = func
516
517# similarly for return types
518rettypes = {}
519rets = ctxt.xpathEval("/api/symbols/function/return")
520for ret in rets:
521 mod = ret.xpathEval('string(../@file)')
522 func = ret.xpathEval('string(../@name)')
523 if (mod not in skipped_modules) and (func not in skipped_functions):
524 type = ret.xpathEval('string(@type)')
525 if not rettypes.has_key(type):
526 rettypes[type] = func
527
528#
Daniel Veillard57b25162004-11-06 14:50:18 +0000529# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000530# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000531#
532enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
533for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000534 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000535 name = enum.xpathEval('string(@name)')
536 #
537 # Skip any enums which are not in our filtered lists
538 #
539 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
540 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000541 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000542
William M. Brack094dd862004-11-14 14:28:34 +0000543 if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000544 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
545 i = 0
546 vals = []
547 for value in values:
548 vname = value.xpathEval('string(@name)')
549 if vname == None:
550 continue;
551 i = i + 1
552 if i >= 5:
553 break;
554 vals.append(vname)
555 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000556 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000557 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000558 if modules_defines.has_key(module):
559 test.write("#ifdef %s\n" % (modules_defines[module]))
560 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000561 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
562 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
563 (name, name))
564 i = 1
565 for value in vals:
566 test.write(" if (no == %d) return(%s);\n" % (i, value))
567 i = i + 1
568 test.write(""" return(0);
569}
William M. Brack094dd862004-11-14 14:28:34 +0000570
571static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
572}
573
574""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000575 known_param_types.append(name)
576
William M. Brack094dd862004-11-14 14:28:34 +0000577 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000578 if define == 0 and modules_defines.has_key(module):
579 test.write("#ifdef %s\n" % (modules_defines[module]))
580 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000581 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000582}
583
William M. Brack094dd862004-11-14 14:28:34 +0000584""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000585 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000586 if define == 1:
587 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000588
589#
590# Load the interfaces
591#
Daniel Veillard57b25162004-11-06 14:50:18 +0000592headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000593for file in headers:
594 name = file.xpathEval('string(@name)')
595 if (name == None) or (name == ''):
596 continue
597
598 #
599 # Some module may be skipped because they don't really consists
600 # of user callable APIs
601 #
602 if is_skipped_module(name):
603 continue
604
605 #
606 # do not test deprecated APIs
607 #
608 desc = file.xpathEval('string(description)')
609 if string.find(desc, 'DEPRECATED') != -1:
610 print "Skipping deprecated interface %s" % name
611 continue;
612
613 test.write("#include <libxml/%s.h>\n" % name)
614 modules.append(name)
615
616#
617# Generate the callers signatures
618#
619for module in modules:
620 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000621
622#
623# Generate the top caller
624#
625
626test.write("""
627/**
628 * testlibxml2:
629 *
630 * Main entry point of the tester for the full libxml2 module,
631 * it calls all the tester entry point for each module.
632 *
633 * Returns the number of error found
634 */
635static int
636testlibxml2(void)
637{
Daniel Veillard42595322004-11-08 10:52:06 +0000638 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000639
640""")
641
642for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000643 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000644
645test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000646 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000647 function_tests, call_tests, test_ret);
648 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000649}
650
651""")
652
653#
654# How to handle a function
655#
656nb_tests = 0
657
658def generate_test(module, node):
659 global test
660 global nb_tests
661 nb_cond = 0
662 no_gen = 0
663
664 name = node.xpathEval('string(@name)')
665 if is_skipped_function(name):
666 return
667
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000668 #
669 # check we know how to handle the args and return values
670 # and store the informations for the generation
671 #
672 try:
673 args = node.xpathEval("arg")
674 except:
675 args = []
676 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000677 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000678 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000679 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000680 rtype = arg.xpathEval("string(@type)")
681 if rtype == 'void':
682 break;
683 info = arg.xpathEval("string(@info)")
684 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000685 type = type_convert(rtype, nam, info, module, name, n)
Daniel Veillardce682bc2004-11-05 17:22:25 +0000686 if is_known_param_type(type, rtype) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000687 add_missing_type(type, name);
688 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000689 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
690 rtype[0:6] == 'const ':
691 crtype = rtype[6:]
692 else:
693 crtype = rtype
694 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000695
696 try:
697 rets = node.xpathEval("return")
698 except:
699 rets = []
700 t_ret = None
701 for ret in rets:
702 rtype = ret.xpathEval("string(@type)")
703 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000704 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000705 if rtype == 'void':
706 break
707 if is_known_return_type(type) == 0:
708 add_missing_type(type, name);
709 no_gen = 1
710 t_ret = (type, rtype, info)
711 break
712
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000713 test.write("""
714static int
715test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000716 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000717
718""" % (name))
719
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000720 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000721 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000722 test.write("""
723 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000724 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000725}
726
727""")
728 return
729
730 try:
731 conds = node.xpathEval("cond")
732 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000733 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000734 nb_cond = nb_cond + 1
735 except:
736 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000737
738 define = 0
739 if function_defines.has_key(name):
740 test.write("#ifdef %s\n" % (function_defines[name]))
741 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000742
743 # Declare the memory usage counter
744 no_mem = is_skipped_memcheck(name)
745 if no_mem == 0:
746 test.write(" int mem_base;\n");
747
748 # Declare the return value
749 if t_ret != None:
750 test.write(" %s ret_val;\n" % (t_ret[1]))
751
752 # Declare the arguments
753 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000754 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000755 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000756 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000757 test.write(" int n_%s;\n" % (nam))
758 test.write("\n")
759
760 # Cascade loop on of each argument list of values
761 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000762 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000763 #
764 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
765 nam, nam, type, nam))
766
767 # log the memory usage
768 if no_mem == 0:
769 test.write(" mem_base = xmlMemBlocks();\n");
770
771 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000772 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000773 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000774 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000775 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000776 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
777 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000778
779 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000780 if extra_pre_call.has_key(name):
781 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000782 if t_ret != None:
783 test.write("\n ret_val = %s(" % (name))
784 need = 0
785 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000786 (nam, type, rtype, crtype, info) = arg
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000787 if need:
788 test.write(", ")
789 else:
790 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000791 if rtype != crtype:
792 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000793 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000794 test.write(");\n")
795 if extra_post_call.has_key(name):
796 test.write(" %s\n"% (extra_post_call[name]))
797 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000798 else:
799 test.write("\n %s(" % (name));
800 need = 0;
801 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000802 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000803 if need:
804 test.write(", ")
805 else:
806 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000807 if rtype != crtype:
808 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000809 test.write("%s" % nam)
810 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000811 if extra_post_call.has_key(name):
812 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000813
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000814 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000815
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000816 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000817 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000818 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000819 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000820 #
William M. Brackf13f77f2004-11-12 16:03:48 +0000821 test.write(" des_%s(n_%s, " % (type, nam))
822 if rtype != crtype:
823 test.write("(%s)" % rtype)
824 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000825 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000826
827 test.write(" xmlResetLastError();\n");
828 # Check the memory usage
829 if no_mem == 0:
830 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000831 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000832 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000833 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000834""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000835 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000836 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000837 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
838 test.write(""" printf("\\n");\n""")
839 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000840
841 for arg in t_args:
842 test.write(" }\n")
843
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000844 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000845 #
846 # end of conditional
847 #
848 while nb_cond > 0:
849 test.write("#endif\n")
850 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000851 if define == 1:
852 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000853
854 nb_tests = nb_tests + 1;
855
856 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000857 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000858}
859
860""")
861
862#
863# Generate all module callers
864#
865for module in modules:
866 # gather all the functions exported by that module
867 try:
868 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
869 except:
870 print "Failed to gather functions from module %s" % (module)
871 continue;
872
873 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000874 i = 0
875 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000876 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000877 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000878 generate_test(module, function);
879
880 # header
881 test.write("""static int
882test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000883 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000884
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000885 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000886""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000887
888 # iterate over all functions in the module generating the call
889 for function in functions:
890 name = function.xpathEval('string(@name)')
891 if is_skipped_function(name):
892 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000893 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000894
895 # footer
896 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000897 if (test_ret != 0)
898 printf("Module %s: %%d errors\\n", test_ret);
899 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000900}
901""" % (module))
902
Daniel Veillardce244ad2004-11-05 10:03:46 +0000903#
904# Generate direct module caller
905#
906test.write("""static int
907test_module(const char *module) {
908""");
909for module in modules:
910 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
911 module, module))
912test.write(""" return(0);
913}
914""");
915
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000916print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000917
Daniel Veillard34099b42004-11-04 17:34:35 +0000918compare_and_save()
919
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000920missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000921for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000922 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000923 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000924
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000925 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000926 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000927
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000928def compare_missing(a, b):
929 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000930
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000931missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000932print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000933lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000934lst.write("Missing support for %d types" % (len(missing_list)))
935lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000936for miss in missing_list:
937 lst.write("%s: %d :" % (miss[1], miss[0]))
938 i = 0
939 for n in missing_types[miss[1]]:
940 i = i + 1
941 if i > 5:
942 lst.write(" ...")
943 break
944 lst.write(" %s" % (n))
945 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000946lst.write("\n")
947lst.write("\n")
948lst.write("Missing support per module");
949for module in missing_functions.keys():
950 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000951
952lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000953
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000954