blob: 1379246319cb0a49ba2eb543a075af208f3b1736 [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 ; }",
211 "xmlAddChildList":
212 "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
213 "xmlAddSibling":
214 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
215 "xmlAddNextSibling":
216 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
217 "xmlAddPrevSibling":
218 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
219 "xmlDocSetRootElement":
220 "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
221 "xmlReplaceNode":
Daniel Veillardce244ad2004-11-05 10:03:46 +0000222 """if (cur != NULL) {
223 xmlUnlinkNode(cur);
224 xmlFreeNode(cur) ; cur = NULL ; }
225 if (old != NULL) {
226 xmlUnlinkNode(old);
227 xmlFreeNode(old) ; old = NULL ; }
228 ret_val = NULL;""",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000229 "xmlTextMerge":
230 """if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
Daniel Veillardce244ad2004-11-05 10:03:46 +0000231 xmlUnlinkNode(second);
Daniel Veillarda03e3652004-11-02 18:45:30 +0000232 xmlFreeNode(second) ; second = NULL ; }""",
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000233 "xmlBuildQName":
234 """if ((ret_val != NULL) && (ret_val != ncname) &&
235 (ret_val != prefix) && (ret_val != memory))
236 xmlFree(ret_val);
237 ret_val = NULL;""",
Daniel Veillardc394f732005-01-26 00:04:52 +0000238 "xmlNewDocElementContent":
239 """xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;""",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000240 "xmlDictReference": "xmlDictFree(dict);",
Daniel Veillard3d97e662004-11-04 10:49:00 +0000241 # Functions which deallocates one of their parameters
242 "xmlXPathConvertBoolean": """val = NULL;""",
243 "xmlXPathConvertNumber": """val = NULL;""",
244 "xmlXPathConvertString": """val = NULL;""",
245 "xmlSaveFileTo": """buf = NULL;""",
Daniel Veillard34099b42004-11-04 17:34:35 +0000246 "xmlSaveFormatFileTo": """buf = NULL;""",
247 "xmlIOParseDTD": "input = NULL;",
Daniel Veillardce244ad2004-11-05 10:03:46 +0000248 "xmlRemoveProp": "cur = NULL;",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000249 "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
250 "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
251 "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
252 "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000253 "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
Daniel Veillard42595322004-11-08 10:52:06 +0000254 "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000255 "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
256 "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
257 "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
258 "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
259 "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Daniel Veillard7e33dba2005-07-03 22:40:26 +0000260 "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000261}
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000262
263modules = []
264
265def is_skipped_module(name):
266 for mod in skipped_modules:
267 if mod == name:
268 return 1
269 return 0
270
271def is_skipped_function(name):
272 for fun in skipped_functions:
273 if fun == name:
274 return 1
275 # Do not test destructors
276 if string.find(name, 'Free') != -1:
277 return 1
278 return 0
279
280def is_skipped_memcheck(name):
281 for fun in skipped_memcheck:
282 if fun == name:
283 return 1
284 return 0
285
286missing_types = {}
287def add_missing_type(name, func):
288 try:
289 list = missing_types[name]
290 list.append(func)
291 except:
292 missing_types[name] = [func]
293
Daniel Veillardce682bc2004-11-05 17:22:25 +0000294generated_param_types = []
295def add_generated_param_type(name):
296 generated_param_types.append(name)
297
298generated_return_types = []
299def add_generated_return_type(name):
300 generated_return_types.append(name)
301
Daniel Veillard34099b42004-11-04 17:34:35 +0000302missing_functions = {}
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000303missing_functions_nr = 0
Daniel Veillard34099b42004-11-04 17:34:35 +0000304def add_missing_functions(name, module):
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000305 global missing_functions_nr
306
307 missing_functions_nr = missing_functions_nr + 1
Daniel Veillard34099b42004-11-04 17:34:35 +0000308 try:
309 list = missing_functions[module]
310 list.append(name)
311 except:
312 missing_functions[module] = [name]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000313
314#
315# Provide the type generators and destructors for the parameters
316#
317
Daniel Veillarda03e3652004-11-02 18:45:30 +0000318def type_convert(str, name, info, module, function, pos):
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000319# res = string.replace(str, " ", " ")
320# res = string.replace(str, " ", " ")
321# res = string.replace(str, " ", " ")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000322 res = string.replace(str, " *", "_ptr")
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000323# res = string.replace(str, "*", "_ptr")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000324 res = string.replace(res, " ", "_")
325 if res == 'const_char_ptr':
326 if string.find(name, "file") != -1 or \
327 string.find(name, "uri") != -1 or \
328 string.find(name, "URI") != -1 or \
329 string.find(info, "filename") != -1 or \
330 string.find(info, "URI") != -1 or \
331 string.find(info, "URL") != -1:
William M. Brack83d9c372004-11-08 02:26:08 +0000332 if string.find(function, "Save") != -1 or \
333 string.find(function, "Create") != -1 or \
William M. Brack015ccb22005-02-13 08:18:52 +0000334 string.find(function, "Write") != -1 or \
335 string.find(function, "Fetch") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000336 return('fileoutput')
337 return('filepath')
338 if res == 'void_ptr':
339 if module == 'nanoftp' and name == 'ctx':
340 return('xmlNanoFTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000341 if function == 'xmlNanoFTPNewCtxt' or \
342 function == 'xmlNanoFTPConnectTo' or \
343 function == 'xmlNanoFTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000344 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000345 if module == 'nanohttp' and name == 'ctx':
346 return('xmlNanoHTTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000347 if function == 'xmlNanoHTTPMethod' or \
348 function == 'xmlNanoHTTPMethodRedir' or \
349 function == 'xmlNanoHTTPOpen' or \
350 function == 'xmlNanoHTTPOpenRedir':
351 return('xmlNanoHTTPCtxtPtr');
352 if function == 'xmlIOHTTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000353 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000354 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000355 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000356 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000357 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000358 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000359 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000360 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000361 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000362 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000363 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000364 if res == 'xmlNodePtr' and pos != 0:
365 if (function == 'xmlAddChild' and pos == 2) or \
366 (function == 'xmlAddChildList' and pos == 2) or \
367 (function == 'xmlAddNextSibling' and pos == 2) or \
368 (function == 'xmlAddSibling' and pos == 2) or \
369 (function == 'xmlDocSetRootElement' and pos == 2) or \
370 (function == 'xmlReplaceNode' and pos == 2) or \
371 (function == 'xmlTextMerge') or \
372 (function == 'xmlAddPrevSibling' and pos == 2):
373 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000374 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000375 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000376 if res == 'xmlChar_ptr' and name == 'name' and \
377 string.find(function, "EatName") != -1:
378 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000379 if res == 'void_ptr*':
380 res = 'void_ptr_ptr'
381 if res == 'char_ptr*':
382 res = 'char_ptr_ptr'
383 if res == 'xmlChar_ptr*':
384 res = 'xmlChar_ptr_ptr'
385 if res == 'const_xmlChar_ptr*':
386 res = 'const_xmlChar_ptr_ptr'
387 if res == 'const_char_ptr*':
388 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000389 if res == 'FILE_ptr' and module == 'debugXML':
390 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000391 if res == 'int' and name == 'options':
392 if module == 'parser' or module == 'xmlreader':
393 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000394
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000395 return res
396
Daniel Veillard34099b42004-11-04 17:34:35 +0000397known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000398
Daniel Veillardce682bc2004-11-05 17:22:25 +0000399def is_known_param_type(name, rtype):
400 global test
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000401 for type in known_param_types:
402 if type == name:
403 return 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000404 for type in generated_param_types:
405 if type == name:
406 return 1
407
408 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
409 if rtype[0:6] == 'const ':
410 crtype = rtype[6:]
411 else:
412 crtype = rtype
413
Daniel Veillarda521d282004-11-09 14:59:59 +0000414 define = 0
415 if modules_defines.has_key(module):
416 test.write("#ifdef %s\n" % (modules_defines[module]))
417 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000418 test.write("""
419#define gen_nb_%s 1
420static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
421 return(NULL);
422}
423static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
424}
425""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000426 if define == 1:
427 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000428 add_generated_param_type(name)
429 return 1
430
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000431 return 0
432
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000433#
434# Provide the type destructors for the return values
435#
436
Daniel Veillard34099b42004-11-04 17:34:35 +0000437known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000438
439def is_known_return_type(name):
440 for type in known_return_types:
441 if type == name:
442 return 1
443 return 0
444
Daniel Veillard34099b42004-11-04 17:34:35 +0000445#
446# Copy the beginning of the C test program result
447#
448
William M. Brack106cad62004-12-23 15:56:12 +0000449try:
450 input = open("testapi.c", "r")
451except:
452 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000453test = open('testapi.c.new', 'w')
454
455def compare_and_save():
456 global test
457
458 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000459 try:
460 input = open("testapi.c", "r").read()
461 except:
462 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000463 test = open('testapi.c.new', "r").read()
464 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000465 try:
466 os.system("rm testapi.c; mv testapi.c.new testapi.c")
467 except:
468 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000469 print("Updated testapi.c")
470 else:
471 print("Generated testapi.c is identical")
472
473line = input.readline()
474while line != "":
475 if line == "/* CUT HERE: everything below that line is generated */\n":
476 break;
477 if line[0:15] == "#define gen_nb_":
478 type = string.split(line[15:])[0]
479 known_param_types.append(type)
480 if line[0:19] == "static void desret_":
481 type = string.split(line[19:], '(')[0]
482 known_return_types.append(type)
483 test.write(line)
484 line = input.readline()
485input.close()
486
487if line == "":
488 print "Could not find the CUT marker in testapi.c skipping generation"
489 test.close()
490 sys.exit(0)
491
492print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
493 len(known_param_types), len(known_return_types)))
494test.write("/* CUT HERE: everything below that line is generated */\n")
495
496
497#
498# Open the input API description
499#
William M. Brack106cad62004-12-23 15:56:12 +0000500doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000501if doc == None:
502 print "Failed to load doc/libxml2-api.xml"
503 sys.exit(1)
504ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000505
506#
William M. Brack094dd862004-11-14 14:28:34 +0000507# Generate a list of all function parameters and select only
508# those used in the api tests
509#
510argtypes = {}
511args = ctxt.xpathEval("/api/symbols/function/arg")
512for arg in args:
513 mod = arg.xpathEval('string(../@file)')
514 func = arg.xpathEval('string(../@name)')
515 if (mod not in skipped_modules) and (func not in skipped_functions):
516 type = arg.xpathEval('string(@type)')
517 if not argtypes.has_key(type):
518 argtypes[type] = func
519
520# similarly for return types
521rettypes = {}
522rets = ctxt.xpathEval("/api/symbols/function/return")
523for ret in rets:
524 mod = ret.xpathEval('string(../@file)')
525 func = ret.xpathEval('string(../@name)')
526 if (mod not in skipped_modules) and (func not in skipped_functions):
527 type = ret.xpathEval('string(@type)')
528 if not rettypes.has_key(type):
529 rettypes[type] = func
530
531#
Daniel Veillard57b25162004-11-06 14:50:18 +0000532# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000533# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000534#
535enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
536for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000537 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000538 name = enum.xpathEval('string(@name)')
539 #
540 # Skip any enums which are not in our filtered lists
541 #
542 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
543 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000544 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000545
William M. Brack094dd862004-11-14 14:28:34 +0000546 if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000547 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
548 i = 0
549 vals = []
550 for value in values:
551 vname = value.xpathEval('string(@name)')
552 if vname == None:
553 continue;
554 i = i + 1
555 if i >= 5:
556 break;
557 vals.append(vname)
558 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000559 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000560 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000561 if modules_defines.has_key(module):
562 test.write("#ifdef %s\n" % (modules_defines[module]))
563 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000564 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
565 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
566 (name, name))
567 i = 1
568 for value in vals:
569 test.write(" if (no == %d) return(%s);\n" % (i, value))
570 i = i + 1
571 test.write(""" return(0);
572}
William M. Brack094dd862004-11-14 14:28:34 +0000573
574static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
575}
576
577""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000578 known_param_types.append(name)
579
William M. Brack094dd862004-11-14 14:28:34 +0000580 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000581 if define == 0 and modules_defines.has_key(module):
582 test.write("#ifdef %s\n" % (modules_defines[module]))
583 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000584 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000585}
586
William M. Brack094dd862004-11-14 14:28:34 +0000587""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000588 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000589 if define == 1:
590 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000591
592#
593# Load the interfaces
594#
Daniel Veillard57b25162004-11-06 14:50:18 +0000595headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000596for file in headers:
597 name = file.xpathEval('string(@name)')
598 if (name == None) or (name == ''):
599 continue
600
601 #
602 # Some module may be skipped because they don't really consists
603 # of user callable APIs
604 #
605 if is_skipped_module(name):
606 continue
607
608 #
609 # do not test deprecated APIs
610 #
611 desc = file.xpathEval('string(description)')
612 if string.find(desc, 'DEPRECATED') != -1:
613 print "Skipping deprecated interface %s" % name
614 continue;
615
616 test.write("#include <libxml/%s.h>\n" % name)
617 modules.append(name)
618
619#
620# Generate the callers signatures
621#
622for module in modules:
623 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000624
625#
626# Generate the top caller
627#
628
629test.write("""
630/**
631 * testlibxml2:
632 *
633 * Main entry point of the tester for the full libxml2 module,
634 * it calls all the tester entry point for each module.
635 *
636 * Returns the number of error found
637 */
638static int
639testlibxml2(void)
640{
Daniel Veillard42595322004-11-08 10:52:06 +0000641 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000642
643""")
644
645for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000646 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000647
648test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000649 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000650 function_tests, call_tests, test_ret);
651 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000652}
653
654""")
655
656#
657# How to handle a function
658#
659nb_tests = 0
660
661def generate_test(module, node):
662 global test
663 global nb_tests
664 nb_cond = 0
665 no_gen = 0
666
667 name = node.xpathEval('string(@name)')
668 if is_skipped_function(name):
669 return
670
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000671 #
672 # check we know how to handle the args and return values
673 # and store the informations for the generation
674 #
675 try:
676 args = node.xpathEval("arg")
677 except:
678 args = []
679 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000680 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000681 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000682 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000683 rtype = arg.xpathEval("string(@type)")
684 if rtype == 'void':
685 break;
686 info = arg.xpathEval("string(@info)")
687 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000688 type = type_convert(rtype, nam, info, module, name, n)
Daniel Veillardce682bc2004-11-05 17:22:25 +0000689 if is_known_param_type(type, rtype) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000690 add_missing_type(type, name);
691 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000692 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
693 rtype[0:6] == 'const ':
694 crtype = rtype[6:]
695 else:
696 crtype = rtype
697 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000698
699 try:
700 rets = node.xpathEval("return")
701 except:
702 rets = []
703 t_ret = None
704 for ret in rets:
705 rtype = ret.xpathEval("string(@type)")
706 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000707 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000708 if rtype == 'void':
709 break
710 if is_known_return_type(type) == 0:
711 add_missing_type(type, name);
712 no_gen = 1
713 t_ret = (type, rtype, info)
714 break
715
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000716 test.write("""
717static int
718test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000719 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000720
721""" % (name))
722
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000723 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000724 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000725 test.write("""
726 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000727 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000728}
729
730""")
731 return
732
733 try:
734 conds = node.xpathEval("cond")
735 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000736 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000737 nb_cond = nb_cond + 1
738 except:
739 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000740
741 define = 0
742 if function_defines.has_key(name):
743 test.write("#ifdef %s\n" % (function_defines[name]))
744 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000745
746 # Declare the memory usage counter
747 no_mem = is_skipped_memcheck(name)
748 if no_mem == 0:
749 test.write(" int mem_base;\n");
750
751 # Declare the return value
752 if t_ret != None:
753 test.write(" %s ret_val;\n" % (t_ret[1]))
754
755 # Declare the arguments
756 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000757 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000758 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000759 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000760 test.write(" int n_%s;\n" % (nam))
761 test.write("\n")
762
763 # Cascade loop on of each argument list of values
764 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000765 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000766 #
767 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
768 nam, nam, type, nam))
769
770 # log the memory usage
771 if no_mem == 0:
772 test.write(" mem_base = xmlMemBlocks();\n");
773
774 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000775 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000776 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000777 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000778 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000779 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
780 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000781
782 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000783 if extra_pre_call.has_key(name):
784 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000785 if t_ret != None:
786 test.write("\n ret_val = %s(" % (name))
787 need = 0
788 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000789 (nam, type, rtype, crtype, info) = arg
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000790 if need:
791 test.write(", ")
792 else:
793 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000794 if rtype != crtype:
795 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000796 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000797 test.write(");\n")
798 if extra_post_call.has_key(name):
799 test.write(" %s\n"% (extra_post_call[name]))
800 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000801 else:
802 test.write("\n %s(" % (name));
803 need = 0;
804 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000805 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000806 if need:
807 test.write(", ")
808 else:
809 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000810 if rtype != crtype:
811 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000812 test.write("%s" % nam)
813 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000814 if extra_post_call.has_key(name):
815 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000816
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000817 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000818
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000819 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000820 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000821 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000822 (nam, type, rtype, crtype, info) = arg;
William M. Brackd46c1ca2007-02-08 23:34:34 +0000823 # This is a hack to prevent generating a destructor for the
824 # 'input' argument in xmlTextReaderSetup. There should be
825 # a better, more generic way to do this!
826 if string.find(info, 'destroy') == -1:
827 test.write(" des_%s(n_%s, " % (type, nam))
828 if rtype != crtype:
829 test.write("(%s)" % rtype)
830 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000831 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000832
833 test.write(" xmlResetLastError();\n");
834 # Check the memory usage
835 if no_mem == 0:
836 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000837 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000838 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000839 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000840""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000841 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000842 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000843 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
844 test.write(""" printf("\\n");\n""")
845 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000846
847 for arg in t_args:
848 test.write(" }\n")
849
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000850 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000851 #
852 # end of conditional
853 #
854 while nb_cond > 0:
855 test.write("#endif\n")
856 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000857 if define == 1:
858 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000859
860 nb_tests = nb_tests + 1;
861
862 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000863 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000864}
865
866""")
867
868#
869# Generate all module callers
870#
871for module in modules:
872 # gather all the functions exported by that module
873 try:
874 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
875 except:
876 print "Failed to gather functions from module %s" % (module)
877 continue;
878
879 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000880 i = 0
881 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000882 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000883 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000884 generate_test(module, function);
885
886 # header
887 test.write("""static int
888test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000889 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000890
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000891 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000892""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000893
894 # iterate over all functions in the module generating the call
895 for function in functions:
896 name = function.xpathEval('string(@name)')
897 if is_skipped_function(name):
898 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000899 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000900
901 # footer
902 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000903 if (test_ret != 0)
904 printf("Module %s: %%d errors\\n", test_ret);
905 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000906}
907""" % (module))
908
Daniel Veillardce244ad2004-11-05 10:03:46 +0000909#
910# Generate direct module caller
911#
912test.write("""static int
913test_module(const char *module) {
914""");
915for module in modules:
916 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
917 module, module))
918test.write(""" return(0);
919}
920""");
921
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000922print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000923
Daniel Veillard34099b42004-11-04 17:34:35 +0000924compare_and_save()
925
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000926missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000927for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000928 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000929 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000930
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000931 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000932 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000933
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000934def compare_missing(a, b):
935 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000936
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000937missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000938print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000939lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000940lst.write("Missing support for %d types" % (len(missing_list)))
941lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000942for miss in missing_list:
943 lst.write("%s: %d :" % (miss[1], miss[0]))
944 i = 0
945 for n in missing_types[miss[1]]:
946 i = i + 1
947 if i > 5:
948 lst.write(" ...")
949 break
950 lst.write(" %s" % (n))
951 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000952lst.write("\n")
953lst.write("\n")
954lst.write("Missing support per module");
955for module in missing_functions.keys():
956 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000957
958lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000959
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000960