blob: 17c9f592997412335e28a88e28b5d7f545cdc478 [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",
William M. Brackdc904f12005-10-22 02:04:26 +000049 "schematron" : "LIBXML_SCHEMATRON_ENABLED",
Daniel Veillarda521d282004-11-09 14:59:59 +000050}
51
52#
53# defines for specific functions
54#
55function_defines = {
56 "htmlDefaultSAXHandlerInit": "LIBXML_HTML_ENABLED",
57 "xmlSAX2EndElement" : "LIBXML_SAX1_ENABLED",
58 "xmlSAX2StartElement" : "LIBXML_SAX1_ENABLED",
59 "xmlSAXDefaultVersion" : "LIBXML_SAX1_ENABLED",
60 "UTF8Toisolat1" : "LIBXML_OUTPUT_ENABLED",
61 "xmlCleanupPredefinedEntities": "LIBXML_LEGACY_ENABLED",
62 "xmlInitializePredefinedEntities": "LIBXML_LEGACY_ENABLED",
63 "xmlSetFeature": "LIBXML_LEGACY_ENABLED",
64 "xmlGetFeature": "LIBXML_LEGACY_ENABLED",
65 "xmlGetFeaturesList": "LIBXML_LEGACY_ENABLED",
66 "xmlIOParseDTD": "LIBXML_VALID_ENABLED",
67 "xmlParseDTD": "LIBXML_VALID_ENABLED",
68 "xmlParseDoc": "LIBXML_SAX1_ENABLED",
69 "xmlParseMemory": "LIBXML_SAX1_ENABLED",
70 "xmlRecoverDoc": "LIBXML_SAX1_ENABLED",
71 "xmlParseFile": "LIBXML_SAX1_ENABLED",
72 "xmlRecoverFile": "LIBXML_SAX1_ENABLED",
73 "xmlRecoverMemory": "LIBXML_SAX1_ENABLED",
74 "xmlSAXParseFileWithData": "LIBXML_SAX1_ENABLED",
75 "xmlSAXParseMemory": "LIBXML_SAX1_ENABLED",
76 "xmlSAXUserParseMemory": "LIBXML_SAX1_ENABLED",
77 "xmlSAXParseDoc": "LIBXML_SAX1_ENABLED",
78 "xmlSAXParseDTD": "LIBXML_SAX1_ENABLED",
79 "xmlSAXUserParseFile": "LIBXML_SAX1_ENABLED",
80 "xmlParseEntity": "LIBXML_SAX1_ENABLED",
81 "xmlParseExternalEntity": "LIBXML_SAX1_ENABLED",
82 "xmlSAXParseMemoryWithData": "LIBXML_SAX1_ENABLED",
83 "xmlParseBalancedChunkMemory": "LIBXML_SAX1_ENABLED",
84 "xmlParseBalancedChunkMemoryRecover": "LIBXML_SAX1_ENABLED",
85 "xmlSetupParserForBuffer": "LIBXML_SAX1_ENABLED",
86 "xmlStopParser": "LIBXML_PUSH_ENABLED",
87 "xmlAttrSerializeTxtContent": "LIBXML_OUTPUT_ENABLED",
88 "xmlSAXParseFile": "LIBXML_SAX1_ENABLED",
89 "xmlSAXParseEntity": "LIBXML_SAX1_ENABLED",
90 "xmlNewTextChild": "LIBXML_TREE_ENABLED",
91 "xmlNewDocRawNode": "LIBXML_TREE_ENABLED",
92 "xmlNewProp": "LIBXML_TREE_ENABLED",
93 "xmlReconciliateNs": "LIBXML_TREE_ENABLED",
94 "xmlValidateNCName": "LIBXML_TREE_ENABLED",
95 "xmlValidateNMToken": "LIBXML_TREE_ENABLED",
96 "xmlValidateName": "LIBXML_TREE_ENABLED",
97 "xmlNewChild": "LIBXML_TREE_ENABLED",
98 "xmlValidateQName": "LIBXML_TREE_ENABLED",
99 "xmlSprintfElementContent": "LIBXML_OUTPUT_ENABLED",
100 "xmlValidGetPotentialChildren" : "LIBXML_VALID_ENABLED",
101 "xmlValidGetValidElements" : "LIBXML_VALID_ENABLED",
102 "docbDefaultSAXHandlerInit" : "LIBXML_DOCB_ENABLED",
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000103 "xmlTextReaderPreservePattern" : "LIBXML_PATTERN_ENABLED",
Daniel Veillarda521d282004-11-09 14:59:59 +0000104}
105
106#
William M. Brack094dd862004-11-14 14:28:34 +0000107# Some functions really need to be skipped for the tests.
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000108#
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000109skipped_functions = [
110# block on I/O
111"xmlFdRead", "xmlReadFd", "xmlCtxtReadFd",
112"htmlFdRead", "htmlReadFd", "htmlCtxtReadFd",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000113"xmlReaderNewFd", "xmlReaderForFd",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000114"xmlIORead", "xmlReadIO", "xmlCtxtReadIO",
115"htmlIORead", "htmlReadIO", "htmlCtxtReadIO",
Daniel Veillard27f20102004-11-05 11:50:11 +0000116"xmlReaderNewIO", "xmlBufferDump", "xmlNanoFTPConnect",
William M. Brack015ccb22005-02-13 08:18:52 +0000117"xmlNanoFTPConnectTo", "xmlNanoHTTPMethod", "xmlNanoHTTPMethodRedir",
Daniel Veillard42595322004-11-08 10:52:06 +0000118# Complex I/O APIs
119"xmlCreateIOParserCtxt", "xmlParserInputBufferCreateIO",
120"xmlRegisterInputCallbacks", "xmlReaderForIO",
121"xmlOutputBufferCreateIO", "xmlRegisterOutputCallbacks",
William M. Brack015ccb22005-02-13 08:18:52 +0000122"xmlSaveToIO", "xmlIOHTTPOpenW",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000123# library state cleanup, generate false leak informations and other
124# troubles, heavillyb tested otherwise.
Daniel Veillardce244ad2004-11-05 10:03:46 +0000125"xmlCleanupParser", "xmlRelaxNGCleanupTypes", "xmlSetListDoc",
126"xmlSetTreeDoc", "xmlUnlinkNode",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000127# hard to avoid leaks in the tests
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000128"xmlStrcat", "xmlStrncat", "xmlCatalogAddLocal", "xmlNewTextWriterDoc",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000129"xmlXPathNewValueTree", "xmlXPathWrapString",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000130# unimplemented
131"xmlTextReaderReadInnerXml", "xmlTextReaderReadOuterXml",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000132"xmlTextReaderReadString",
133# destructor
William M. Brack015ccb22005-02-13 08:18:52 +0000134"xmlListDelete", "xmlOutputBufferClose", "xmlNanoFTPClose", "xmlNanoHTTPClose",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000135# deprecated
136"xmlCatalogGetPublic", "xmlCatalogGetSystem", "xmlEncodeEntities",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000137"xmlNewGlobalNs", "xmlHandleEntity", "xmlNamespaceParseNCName",
138"xmlNamespaceParseNSDef", "xmlNamespaceParseQName",
139"xmlParseNamespace", "xmlParseQuotedString", "xmlParserHandleReference",
140"xmlScanName",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000141"xmlDecodeEntities",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000142# allocators
143"xmlMemFree",
Daniel Veillardc2c894f2004-11-07 12:17:35 +0000144# verbosity
Daniel Veillarda82b1822004-11-08 16:24:57 +0000145"xmlCatalogSetDebug", "xmlShellPrintXPathError", "xmlShellPrintNode",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000146# Internal functions, no user space should really call them
147"xmlParseAttribute", "xmlParseAttributeListDecl", "xmlParseName",
148"xmlParseNmtoken", "xmlParseEntityValue", "xmlParseAttValue",
149"xmlParseSystemLiteral", "xmlParsePubidLiteral", "xmlParseCharData",
150"xmlParseExternalID", "xmlParseComment", "xmlParsePITarget", "xmlParsePI",
151"xmlParseNotationDecl", "xmlParseEntityDecl", "xmlParseDefaultDecl",
152"xmlParseNotationType", "xmlParseEnumerationType", "xmlParseEnumeratedType",
153"xmlParseAttributeType", "xmlParseAttributeListDecl",
154"xmlParseElementMixedContentDecl", "xmlParseElementChildrenContentDecl",
155"xmlParseElementContentDecl", "xmlParseElementDecl", "xmlParseMarkupDecl",
156"xmlParseCharRef", "xmlParseEntityRef", "xmlParseReference",
157"xmlParsePEReference", "xmlParseDocTypeDecl", "xmlParseAttribute",
158"xmlParseStartTag", "xmlParseEndTag", "xmlParseCDSect", "xmlParseContent",
159"xmlParseElement", "xmlParseVersionNum", "xmlParseVersionInfo",
160"xmlParseEncName", "xmlParseEncodingDecl", "xmlParseSDDecl",
161"xmlParseXMLDecl", "xmlParseTextDecl", "xmlParseMisc",
162"xmlParseExternalSubset", "xmlParserHandlePEReference",
163"xmlSkipBlankChars",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000164]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000165
166#
William M. Brack094dd862004-11-14 14:28:34 +0000167# These functions have side effects on the global state
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000168# and hence generate errors on memory allocation tests
169#
170skipped_memcheck = [ "xmlLoadCatalog", "xmlAddEncodingAlias",
171 "xmlSchemaInitTypes", "xmlNanoFTPProxy", "xmlNanoFTPScanProxy",
172 "xmlNanoHTTPScanProxy", "xmlResetLastError", "xmlCatalogConvert",
173 "xmlCatalogRemove", "xmlLoadCatalogs", "xmlCleanupCharEncodingHandlers",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000174 "xmlInitCharEncodingHandlers", "xmlCatalogCleanup",
Daniel Veillard42595322004-11-08 10:52:06 +0000175 "xmlSchemaGetBuiltInType",
Daniel Veillard1f33c4d2005-07-10 21:38:31 +0000176 "htmlParseFile", "htmlCtxtReadFile", # loads the catalogs
Daniel Veillard34e3f642008-07-29 09:02:27 +0000177 "xmlTextReaderSchemaValidate", "xmlSchemaCleanupTypes", # initialize the schemas type system
178 "xmlCatalogResolve", "xmlIOParseDTD" # loads the catalogs
Daniel Veillarda03e3652004-11-02 18:45:30 +0000179]
180
181#
182# Extra code needed for some test cases
183#
Daniel Veillard34099b42004-11-04 17:34:35 +0000184extra_pre_call = {
Daniel Veillarda521d282004-11-09 14:59:59 +0000185 "xmlSAXUserParseFile": """
186#ifdef LIBXML_SAX1_ENABLED
187 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
188#endif
189""",
190 "xmlSAXUserParseMemory": """
191#ifdef LIBXML_SAX1_ENABLED
192 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
193#endif
194""",
195 "xmlParseBalancedChunkMemory": """
196#ifdef LIBXML_SAX1_ENABLED
197 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
198#endif
199""",
200 "xmlParseBalancedChunkMemoryRecover": """
201#ifdef LIBXML_SAX1_ENABLED
202 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
203#endif
204""",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000205 "xmlParserInputBufferCreateFd":
206 "if (fd >= 0) fd = -1;",
Daniel Veillard34099b42004-11-04 17:34:35 +0000207}
Daniel Veillarda03e3652004-11-02 18:45:30 +0000208extra_post_call = {
209 "xmlAddChild":
210 "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
Daniel Veillard2cba4152008-08-27 11:45:41 +0000211 "xmlAddEntity":
212 "if (ret_val != NULL) { xmlFreeNode(ret_val) ; ret_val = NULL; }",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000213 "xmlAddChildList":
214 "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
215 "xmlAddSibling":
216 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
217 "xmlAddNextSibling":
218 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
219 "xmlAddPrevSibling":
220 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
221 "xmlDocSetRootElement":
222 "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
223 "xmlReplaceNode":
Daniel Veillardce244ad2004-11-05 10:03:46 +0000224 """if (cur != NULL) {
225 xmlUnlinkNode(cur);
226 xmlFreeNode(cur) ; cur = NULL ; }
227 if (old != NULL) {
228 xmlUnlinkNode(old);
229 xmlFreeNode(old) ; old = NULL ; }
230 ret_val = NULL;""",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000231 "xmlTextMerge":
232 """if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
Daniel Veillardce244ad2004-11-05 10:03:46 +0000233 xmlUnlinkNode(second);
Daniel Veillarda03e3652004-11-02 18:45:30 +0000234 xmlFreeNode(second) ; second = NULL ; }""",
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000235 "xmlBuildQName":
236 """if ((ret_val != NULL) && (ret_val != ncname) &&
237 (ret_val != prefix) && (ret_val != memory))
238 xmlFree(ret_val);
239 ret_val = NULL;""",
Daniel Veillardc394f732005-01-26 00:04:52 +0000240 "xmlNewDocElementContent":
241 """xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;""",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000242 "xmlDictReference": "xmlDictFree(dict);",
Daniel Veillard3d97e662004-11-04 10:49:00 +0000243 # Functions which deallocates one of their parameters
244 "xmlXPathConvertBoolean": """val = NULL;""",
245 "xmlXPathConvertNumber": """val = NULL;""",
246 "xmlXPathConvertString": """val = NULL;""",
247 "xmlSaveFileTo": """buf = NULL;""",
Daniel Veillard34099b42004-11-04 17:34:35 +0000248 "xmlSaveFormatFileTo": """buf = NULL;""",
249 "xmlIOParseDTD": "input = NULL;",
Daniel Veillardce244ad2004-11-05 10:03:46 +0000250 "xmlRemoveProp": "cur = NULL;",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000251 "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
252 "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
253 "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
254 "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000255 "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
Daniel Veillard42595322004-11-08 10:52:06 +0000256 "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000257 "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
258 "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
259 "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
260 "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
261 "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Daniel Veillard7e33dba2005-07-03 22:40:26 +0000262 "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000263}
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000264
265modules = []
266
267def is_skipped_module(name):
268 for mod in skipped_modules:
269 if mod == name:
270 return 1
271 return 0
272
273def is_skipped_function(name):
274 for fun in skipped_functions:
275 if fun == name:
276 return 1
277 # Do not test destructors
278 if string.find(name, 'Free') != -1:
279 return 1
280 return 0
281
282def is_skipped_memcheck(name):
283 for fun in skipped_memcheck:
284 if fun == name:
285 return 1
286 return 0
287
288missing_types = {}
289def add_missing_type(name, func):
290 try:
291 list = missing_types[name]
292 list.append(func)
293 except:
294 missing_types[name] = [func]
295
Daniel Veillardce682bc2004-11-05 17:22:25 +0000296generated_param_types = []
297def add_generated_param_type(name):
298 generated_param_types.append(name)
299
300generated_return_types = []
301def add_generated_return_type(name):
302 generated_return_types.append(name)
303
Daniel Veillard34099b42004-11-04 17:34:35 +0000304missing_functions = {}
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000305missing_functions_nr = 0
Daniel Veillard34099b42004-11-04 17:34:35 +0000306def add_missing_functions(name, module):
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000307 global missing_functions_nr
308
309 missing_functions_nr = missing_functions_nr + 1
Daniel Veillard34099b42004-11-04 17:34:35 +0000310 try:
311 list = missing_functions[module]
312 list.append(name)
313 except:
314 missing_functions[module] = [name]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000315
316#
317# Provide the type generators and destructors for the parameters
318#
319
Daniel Veillarda03e3652004-11-02 18:45:30 +0000320def type_convert(str, name, info, module, function, pos):
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000321# res = string.replace(str, " ", " ")
322# res = string.replace(str, " ", " ")
323# res = string.replace(str, " ", " ")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000324 res = string.replace(str, " *", "_ptr")
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000325# res = string.replace(str, "*", "_ptr")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000326 res = string.replace(res, " ", "_")
327 if res == 'const_char_ptr':
328 if string.find(name, "file") != -1 or \
329 string.find(name, "uri") != -1 or \
330 string.find(name, "URI") != -1 or \
331 string.find(info, "filename") != -1 or \
332 string.find(info, "URI") != -1 or \
333 string.find(info, "URL") != -1:
William M. Brack83d9c372004-11-08 02:26:08 +0000334 if string.find(function, "Save") != -1 or \
335 string.find(function, "Create") != -1 or \
William M. Brack015ccb22005-02-13 08:18:52 +0000336 string.find(function, "Write") != -1 or \
337 string.find(function, "Fetch") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000338 return('fileoutput')
339 return('filepath')
340 if res == 'void_ptr':
341 if module == 'nanoftp' and name == 'ctx':
342 return('xmlNanoFTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000343 if function == 'xmlNanoFTPNewCtxt' or \
344 function == 'xmlNanoFTPConnectTo' or \
345 function == 'xmlNanoFTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000346 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000347 if module == 'nanohttp' and name == 'ctx':
348 return('xmlNanoHTTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000349 if function == 'xmlNanoHTTPMethod' or \
350 function == 'xmlNanoHTTPMethodRedir' or \
351 function == 'xmlNanoHTTPOpen' or \
352 function == 'xmlNanoHTTPOpenRedir':
353 return('xmlNanoHTTPCtxtPtr');
354 if function == 'xmlIOHTTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000355 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000356 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000357 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000358 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000359 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000360 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000361 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000362 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000363 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000364 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000365 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000366 if res == 'xmlNodePtr' and pos != 0:
367 if (function == 'xmlAddChild' and pos == 2) or \
368 (function == 'xmlAddChildList' and pos == 2) or \
369 (function == 'xmlAddNextSibling' and pos == 2) or \
370 (function == 'xmlAddSibling' and pos == 2) or \
371 (function == 'xmlDocSetRootElement' and pos == 2) or \
372 (function == 'xmlReplaceNode' and pos == 2) or \
373 (function == 'xmlTextMerge') or \
374 (function == 'xmlAddPrevSibling' and pos == 2):
375 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000376 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000377 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000378 if res == 'xmlChar_ptr' and name == 'name' and \
379 string.find(function, "EatName") != -1:
380 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000381 if res == 'void_ptr*':
382 res = 'void_ptr_ptr'
383 if res == 'char_ptr*':
384 res = 'char_ptr_ptr'
385 if res == 'xmlChar_ptr*':
386 res = 'xmlChar_ptr_ptr'
387 if res == 'const_xmlChar_ptr*':
388 res = 'const_xmlChar_ptr_ptr'
389 if res == 'const_char_ptr*':
390 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000391 if res == 'FILE_ptr' and module == 'debugXML':
392 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000393 if res == 'int' and name == 'options':
394 if module == 'parser' or module == 'xmlreader':
395 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000396
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000397 return res
398
Daniel Veillard34099b42004-11-04 17:34:35 +0000399known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000400
Daniel Veillardce682bc2004-11-05 17:22:25 +0000401def is_known_param_type(name, rtype):
402 global test
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000403 for type in known_param_types:
404 if type == name:
405 return 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000406 for type in generated_param_types:
407 if type == name:
408 return 1
409
410 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
411 if rtype[0:6] == 'const ':
412 crtype = rtype[6:]
413 else:
414 crtype = rtype
415
Daniel Veillarda521d282004-11-09 14:59:59 +0000416 define = 0
417 if modules_defines.has_key(module):
418 test.write("#ifdef %s\n" % (modules_defines[module]))
419 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000420 test.write("""
421#define gen_nb_%s 1
422static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
423 return(NULL);
424}
425static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
426}
427""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000428 if define == 1:
429 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000430 add_generated_param_type(name)
431 return 1
432
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000433 return 0
434
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000435#
436# Provide the type destructors for the return values
437#
438
Daniel Veillard34099b42004-11-04 17:34:35 +0000439known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000440
441def is_known_return_type(name):
442 for type in known_return_types:
443 if type == name:
444 return 1
445 return 0
446
Daniel Veillard34099b42004-11-04 17:34:35 +0000447#
448# Copy the beginning of the C test program result
449#
450
William M. Brack106cad62004-12-23 15:56:12 +0000451try:
452 input = open("testapi.c", "r")
453except:
454 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000455test = open('testapi.c.new', 'w')
456
457def compare_and_save():
458 global test
459
460 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000461 try:
462 input = open("testapi.c", "r").read()
463 except:
464 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000465 test = open('testapi.c.new', "r").read()
466 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000467 try:
468 os.system("rm testapi.c; mv testapi.c.new testapi.c")
469 except:
470 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000471 print("Updated testapi.c")
472 else:
473 print("Generated testapi.c is identical")
474
475line = input.readline()
476while line != "":
477 if line == "/* CUT HERE: everything below that line is generated */\n":
478 break;
479 if line[0:15] == "#define gen_nb_":
480 type = string.split(line[15:])[0]
481 known_param_types.append(type)
482 if line[0:19] == "static void desret_":
483 type = string.split(line[19:], '(')[0]
484 known_return_types.append(type)
485 test.write(line)
486 line = input.readline()
487input.close()
488
489if line == "":
490 print "Could not find the CUT marker in testapi.c skipping generation"
491 test.close()
492 sys.exit(0)
493
494print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
495 len(known_param_types), len(known_return_types)))
496test.write("/* CUT HERE: everything below that line is generated */\n")
497
498
499#
500# Open the input API description
501#
William M. Brack106cad62004-12-23 15:56:12 +0000502doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000503if doc == None:
504 print "Failed to load doc/libxml2-api.xml"
505 sys.exit(1)
506ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000507
508#
William M. Brack094dd862004-11-14 14:28:34 +0000509# Generate a list of all function parameters and select only
510# those used in the api tests
511#
512argtypes = {}
513args = ctxt.xpathEval("/api/symbols/function/arg")
514for arg in args:
515 mod = arg.xpathEval('string(../@file)')
516 func = arg.xpathEval('string(../@name)')
517 if (mod not in skipped_modules) and (func not in skipped_functions):
518 type = arg.xpathEval('string(@type)')
519 if not argtypes.has_key(type):
520 argtypes[type] = func
521
522# similarly for return types
523rettypes = {}
524rets = ctxt.xpathEval("/api/symbols/function/return")
525for ret in rets:
526 mod = ret.xpathEval('string(../@file)')
527 func = ret.xpathEval('string(../@name)')
528 if (mod not in skipped_modules) and (func not in skipped_functions):
529 type = ret.xpathEval('string(@type)')
530 if not rettypes.has_key(type):
531 rettypes[type] = func
532
533#
Daniel Veillard57b25162004-11-06 14:50:18 +0000534# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000535# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000536#
537enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
538for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000539 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000540 name = enum.xpathEval('string(@name)')
541 #
542 # Skip any enums which are not in our filtered lists
543 #
544 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
545 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000546 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000547
William M. Brack094dd862004-11-14 14:28:34 +0000548 if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000549 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
550 i = 0
551 vals = []
552 for value in values:
553 vname = value.xpathEval('string(@name)')
554 if vname == None:
555 continue;
556 i = i + 1
557 if i >= 5:
558 break;
559 vals.append(vname)
560 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000561 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000562 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000563 if modules_defines.has_key(module):
564 test.write("#ifdef %s\n" % (modules_defines[module]))
565 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000566 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
567 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
568 (name, name))
569 i = 1
570 for value in vals:
571 test.write(" if (no == %d) return(%s);\n" % (i, value))
572 i = i + 1
573 test.write(""" return(0);
574}
William M. Brack094dd862004-11-14 14:28:34 +0000575
576static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
577}
578
579""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000580 known_param_types.append(name)
581
William M. Brack094dd862004-11-14 14:28:34 +0000582 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000583 if define == 0 and modules_defines.has_key(module):
584 test.write("#ifdef %s\n" % (modules_defines[module]))
585 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000586 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000587}
588
William M. Brack094dd862004-11-14 14:28:34 +0000589""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000590 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000591 if define == 1:
592 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000593
594#
595# Load the interfaces
596#
Daniel Veillard57b25162004-11-06 14:50:18 +0000597headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000598for file in headers:
599 name = file.xpathEval('string(@name)')
600 if (name == None) or (name == ''):
601 continue
602
603 #
604 # Some module may be skipped because they don't really consists
605 # of user callable APIs
606 #
607 if is_skipped_module(name):
608 continue
609
610 #
611 # do not test deprecated APIs
612 #
613 desc = file.xpathEval('string(description)')
614 if string.find(desc, 'DEPRECATED') != -1:
615 print "Skipping deprecated interface %s" % name
616 continue;
617
618 test.write("#include <libxml/%s.h>\n" % name)
619 modules.append(name)
620
621#
622# Generate the callers signatures
623#
624for module in modules:
625 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000626
627#
628# Generate the top caller
629#
630
631test.write("""
632/**
633 * testlibxml2:
634 *
635 * Main entry point of the tester for the full libxml2 module,
636 * it calls all the tester entry point for each module.
637 *
638 * Returns the number of error found
639 */
640static int
641testlibxml2(void)
642{
Daniel Veillard42595322004-11-08 10:52:06 +0000643 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000644
645""")
646
647for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000648 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000649
650test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000651 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000652 function_tests, call_tests, test_ret);
653 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000654}
655
656""")
657
658#
659# How to handle a function
660#
661nb_tests = 0
662
663def generate_test(module, node):
664 global test
665 global nb_tests
666 nb_cond = 0
667 no_gen = 0
668
669 name = node.xpathEval('string(@name)')
670 if is_skipped_function(name):
671 return
672
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000673 #
674 # check we know how to handle the args and return values
675 # and store the informations for the generation
676 #
677 try:
678 args = node.xpathEval("arg")
679 except:
680 args = []
681 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000682 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000683 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000684 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000685 rtype = arg.xpathEval("string(@type)")
686 if rtype == 'void':
687 break;
688 info = arg.xpathEval("string(@info)")
689 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000690 type = type_convert(rtype, nam, info, module, name, n)
Daniel Veillardce682bc2004-11-05 17:22:25 +0000691 if is_known_param_type(type, rtype) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000692 add_missing_type(type, name);
693 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000694 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
695 rtype[0:6] == 'const ':
696 crtype = rtype[6:]
697 else:
698 crtype = rtype
699 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000700
701 try:
702 rets = node.xpathEval("return")
703 except:
704 rets = []
705 t_ret = None
706 for ret in rets:
707 rtype = ret.xpathEval("string(@type)")
708 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000709 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000710 if rtype == 'void':
711 break
712 if is_known_return_type(type) == 0:
713 add_missing_type(type, name);
714 no_gen = 1
715 t_ret = (type, rtype, info)
716 break
717
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000718 test.write("""
719static int
720test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000721 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000722
723""" % (name))
724
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000725 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000726 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000727 test.write("""
728 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000729 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000730}
731
732""")
733 return
734
735 try:
736 conds = node.xpathEval("cond")
737 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000738 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000739 nb_cond = nb_cond + 1
740 except:
741 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000742
743 define = 0
744 if function_defines.has_key(name):
745 test.write("#ifdef %s\n" % (function_defines[name]))
746 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000747
748 # Declare the memory usage counter
749 no_mem = is_skipped_memcheck(name)
750 if no_mem == 0:
751 test.write(" int mem_base;\n");
752
753 # Declare the return value
754 if t_ret != None:
755 test.write(" %s ret_val;\n" % (t_ret[1]))
756
757 # Declare the arguments
758 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000759 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000760 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000761 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000762 test.write(" int n_%s;\n" % (nam))
763 test.write("\n")
764
765 # Cascade loop on of each argument list of values
766 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000767 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000768 #
769 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
770 nam, nam, type, nam))
771
772 # log the memory usage
773 if no_mem == 0:
774 test.write(" mem_base = xmlMemBlocks();\n");
775
776 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000777 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000778 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000779 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000780 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000781 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
782 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000783
784 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000785 if extra_pre_call.has_key(name):
786 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000787 if t_ret != None:
788 test.write("\n ret_val = %s(" % (name))
789 need = 0
790 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000791 (nam, type, rtype, crtype, info) = arg
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000792 if need:
793 test.write(", ")
794 else:
795 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000796 if rtype != crtype:
797 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000798 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000799 test.write(");\n")
800 if extra_post_call.has_key(name):
801 test.write(" %s\n"% (extra_post_call[name]))
802 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000803 else:
804 test.write("\n %s(" % (name));
805 need = 0;
806 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000807 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000808 if need:
809 test.write(", ")
810 else:
811 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000812 if rtype != crtype:
813 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000814 test.write("%s" % nam)
815 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000816 if extra_post_call.has_key(name):
817 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000818
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000819 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000820
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000821 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000822 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000823 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000824 (nam, type, rtype, crtype, info) = arg;
William M. Brackd46c1ca2007-02-08 23:34:34 +0000825 # This is a hack to prevent generating a destructor for the
826 # 'input' argument in xmlTextReaderSetup. There should be
827 # a better, more generic way to do this!
828 if string.find(info, 'destroy') == -1:
829 test.write(" des_%s(n_%s, " % (type, nam))
830 if rtype != crtype:
831 test.write("(%s)" % rtype)
832 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000833 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000834
835 test.write(" xmlResetLastError();\n");
836 # Check the memory usage
837 if no_mem == 0:
838 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000839 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000840 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000841 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000842""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000843 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000844 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000845 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
846 test.write(""" printf("\\n");\n""")
847 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000848
849 for arg in t_args:
850 test.write(" }\n")
851
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000852 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000853 #
854 # end of conditional
855 #
856 while nb_cond > 0:
857 test.write("#endif\n")
858 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000859 if define == 1:
860 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000861
862 nb_tests = nb_tests + 1;
863
864 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000865 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000866}
867
868""")
869
870#
871# Generate all module callers
872#
873for module in modules:
874 # gather all the functions exported by that module
875 try:
876 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
877 except:
878 print "Failed to gather functions from module %s" % (module)
879 continue;
880
881 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000882 i = 0
883 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000884 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000885 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000886 generate_test(module, function);
887
888 # header
889 test.write("""static int
890test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000891 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000892
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000893 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000894""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000895
896 # iterate over all functions in the module generating the call
897 for function in functions:
898 name = function.xpathEval('string(@name)')
899 if is_skipped_function(name):
900 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000901 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000902
903 # footer
904 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000905 if (test_ret != 0)
906 printf("Module %s: %%d errors\\n", test_ret);
907 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000908}
909""" % (module))
910
Daniel Veillardce244ad2004-11-05 10:03:46 +0000911#
912# Generate direct module caller
913#
914test.write("""static int
915test_module(const char *module) {
916""");
917for module in modules:
918 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
919 module, module))
920test.write(""" return(0);
921}
922""");
923
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000924print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000925
Daniel Veillard34099b42004-11-04 17:34:35 +0000926compare_and_save()
927
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000928missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000929for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000930 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000931 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000932
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000933 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000934 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000935
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000936def compare_missing(a, b):
937 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000938
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000939missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000940print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000941lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000942lst.write("Missing support for %d types" % (len(missing_list)))
943lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000944for miss in missing_list:
945 lst.write("%s: %d :" % (miss[1], miss[0]))
946 i = 0
947 for n in missing_types[miss[1]]:
948 i = i + 1
949 if i > 5:
950 lst.write(" ...")
951 break
952 lst.write(" %s" % (n))
953 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000954lst.write("\n")
955lst.write("\n")
956lst.write("Missing support per module");
957for module in missing_functions.keys():
958 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000959
960lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000961
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000962