blob: af76b049aa7121dff51e110db021ad44d1d0791e [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 Veillard1f33c4d2005-07-10 21:38:31 +0000175 "htmlParseFile", "htmlCtxtReadFile", # loads the catalogs
176 "xmlTextReaderSchemaValidate", "xmlSchemaCleanupTypes" # initialize the schemas type system
Daniel Veillarda03e3652004-11-02 18:45:30 +0000177]
178
179#
180# Extra code needed for some test cases
181#
Daniel Veillard34099b42004-11-04 17:34:35 +0000182extra_pre_call = {
Daniel Veillarda521d282004-11-09 14:59:59 +0000183 "xmlSAXUserParseFile": """
184#ifdef LIBXML_SAX1_ENABLED
185 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
186#endif
187""",
188 "xmlSAXUserParseMemory": """
189#ifdef LIBXML_SAX1_ENABLED
190 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
191#endif
192""",
193 "xmlParseBalancedChunkMemory": """
194#ifdef LIBXML_SAX1_ENABLED
195 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
196#endif
197""",
198 "xmlParseBalancedChunkMemoryRecover": """
199#ifdef LIBXML_SAX1_ENABLED
200 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
201#endif
202""",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000203 "xmlParserInputBufferCreateFd":
204 "if (fd >= 0) fd = -1;",
Daniel Veillard34099b42004-11-04 17:34:35 +0000205}
Daniel Veillarda03e3652004-11-02 18:45:30 +0000206extra_post_call = {
207 "xmlAddChild":
208 "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
209 "xmlAddChildList":
210 "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
211 "xmlAddSibling":
212 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
213 "xmlAddNextSibling":
214 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
215 "xmlAddPrevSibling":
216 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
217 "xmlDocSetRootElement":
218 "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
219 "xmlReplaceNode":
Daniel Veillardce244ad2004-11-05 10:03:46 +0000220 """if (cur != NULL) {
221 xmlUnlinkNode(cur);
222 xmlFreeNode(cur) ; cur = NULL ; }
223 if (old != NULL) {
224 xmlUnlinkNode(old);
225 xmlFreeNode(old) ; old = NULL ; }
226 ret_val = NULL;""",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000227 "xmlTextMerge":
228 """if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
Daniel Veillardce244ad2004-11-05 10:03:46 +0000229 xmlUnlinkNode(second);
Daniel Veillarda03e3652004-11-02 18:45:30 +0000230 xmlFreeNode(second) ; second = NULL ; }""",
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000231 "xmlBuildQName":
232 """if ((ret_val != NULL) && (ret_val != ncname) &&
233 (ret_val != prefix) && (ret_val != memory))
234 xmlFree(ret_val);
235 ret_val = NULL;""",
Daniel Veillardc394f732005-01-26 00:04:52 +0000236 "xmlNewDocElementContent":
237 """xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;""",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000238 "xmlDictReference": "xmlDictFree(dict);",
Daniel Veillard3d97e662004-11-04 10:49:00 +0000239 # Functions which deallocates one of their parameters
240 "xmlXPathConvertBoolean": """val = NULL;""",
241 "xmlXPathConvertNumber": """val = NULL;""",
242 "xmlXPathConvertString": """val = NULL;""",
243 "xmlSaveFileTo": """buf = NULL;""",
Daniel Veillard34099b42004-11-04 17:34:35 +0000244 "xmlSaveFormatFileTo": """buf = NULL;""",
245 "xmlIOParseDTD": "input = NULL;",
Daniel Veillardce244ad2004-11-05 10:03:46 +0000246 "xmlRemoveProp": "cur = NULL;",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000247 "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
248 "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
249 "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
250 "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000251 "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
Daniel Veillard42595322004-11-08 10:52:06 +0000252 "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000253 "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
254 "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
255 "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
256 "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
257 "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Daniel Veillard7e33dba2005-07-03 22:40:26 +0000258 "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000259}
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000260
261modules = []
262
263def is_skipped_module(name):
264 for mod in skipped_modules:
265 if mod == name:
266 return 1
267 return 0
268
269def is_skipped_function(name):
270 for fun in skipped_functions:
271 if fun == name:
272 return 1
273 # Do not test destructors
274 if string.find(name, 'Free') != -1:
275 return 1
276 return 0
277
278def is_skipped_memcheck(name):
279 for fun in skipped_memcheck:
280 if fun == name:
281 return 1
282 return 0
283
284missing_types = {}
285def add_missing_type(name, func):
286 try:
287 list = missing_types[name]
288 list.append(func)
289 except:
290 missing_types[name] = [func]
291
Daniel Veillardce682bc2004-11-05 17:22:25 +0000292generated_param_types = []
293def add_generated_param_type(name):
294 generated_param_types.append(name)
295
296generated_return_types = []
297def add_generated_return_type(name):
298 generated_return_types.append(name)
299
Daniel Veillard34099b42004-11-04 17:34:35 +0000300missing_functions = {}
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000301missing_functions_nr = 0
Daniel Veillard34099b42004-11-04 17:34:35 +0000302def add_missing_functions(name, module):
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000303 global missing_functions_nr
304
305 missing_functions_nr = missing_functions_nr + 1
Daniel Veillard34099b42004-11-04 17:34:35 +0000306 try:
307 list = missing_functions[module]
308 list.append(name)
309 except:
310 missing_functions[module] = [name]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000311
312#
313# Provide the type generators and destructors for the parameters
314#
315
Daniel Veillarda03e3652004-11-02 18:45:30 +0000316def type_convert(str, name, info, module, function, pos):
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000317# res = string.replace(str, " ", " ")
318# res = string.replace(str, " ", " ")
319# res = string.replace(str, " ", " ")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000320 res = string.replace(str, " *", "_ptr")
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000321# res = string.replace(str, "*", "_ptr")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000322 res = string.replace(res, " ", "_")
323 if res == 'const_char_ptr':
324 if string.find(name, "file") != -1 or \
325 string.find(name, "uri") != -1 or \
326 string.find(name, "URI") != -1 or \
327 string.find(info, "filename") != -1 or \
328 string.find(info, "URI") != -1 or \
329 string.find(info, "URL") != -1:
William M. Brack83d9c372004-11-08 02:26:08 +0000330 if string.find(function, "Save") != -1 or \
331 string.find(function, "Create") != -1 or \
William M. Brack015ccb22005-02-13 08:18:52 +0000332 string.find(function, "Write") != -1 or \
333 string.find(function, "Fetch") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000334 return('fileoutput')
335 return('filepath')
336 if res == 'void_ptr':
337 if module == 'nanoftp' and name == 'ctx':
338 return('xmlNanoFTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000339 if function == 'xmlNanoFTPNewCtxt' or \
340 function == 'xmlNanoFTPConnectTo' or \
341 function == 'xmlNanoFTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000342 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000343 if module == 'nanohttp' and name == 'ctx':
344 return('xmlNanoHTTPCtxtPtr')
William M. Brack015ccb22005-02-13 08:18:52 +0000345 if function == 'xmlNanoHTTPMethod' or \
346 function == 'xmlNanoHTTPMethodRedir' or \
347 function == 'xmlNanoHTTPOpen' or \
348 function == 'xmlNanoHTTPOpenRedir':
349 return('xmlNanoHTTPCtxtPtr');
350 if function == 'xmlIOHTTPOpen':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000351 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000352 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000353 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000354 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000355 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000356 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000357 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000358 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000359 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000360 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000361 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000362 if res == 'xmlNodePtr' and pos != 0:
363 if (function == 'xmlAddChild' and pos == 2) or \
364 (function == 'xmlAddChildList' and pos == 2) or \
365 (function == 'xmlAddNextSibling' and pos == 2) or \
366 (function == 'xmlAddSibling' and pos == 2) or \
367 (function == 'xmlDocSetRootElement' and pos == 2) or \
368 (function == 'xmlReplaceNode' and pos == 2) or \
369 (function == 'xmlTextMerge') or \
370 (function == 'xmlAddPrevSibling' and pos == 2):
371 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000372 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000373 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000374 if res == 'xmlChar_ptr' and name == 'name' and \
375 string.find(function, "EatName") != -1:
376 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000377 if res == 'void_ptr*':
378 res = 'void_ptr_ptr'
379 if res == 'char_ptr*':
380 res = 'char_ptr_ptr'
381 if res == 'xmlChar_ptr*':
382 res = 'xmlChar_ptr_ptr'
383 if res == 'const_xmlChar_ptr*':
384 res = 'const_xmlChar_ptr_ptr'
385 if res == 'const_char_ptr*':
386 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000387 if res == 'FILE_ptr' and module == 'debugXML':
388 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000389 if res == 'int' and name == 'options':
390 if module == 'parser' or module == 'xmlreader':
391 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000392
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000393 return res
394
Daniel Veillard34099b42004-11-04 17:34:35 +0000395known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000396
Daniel Veillardce682bc2004-11-05 17:22:25 +0000397def is_known_param_type(name, rtype):
398 global test
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000399 for type in known_param_types:
400 if type == name:
401 return 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000402 for type in generated_param_types:
403 if type == name:
404 return 1
405
406 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
407 if rtype[0:6] == 'const ':
408 crtype = rtype[6:]
409 else:
410 crtype = rtype
411
Daniel Veillarda521d282004-11-09 14:59:59 +0000412 define = 0
413 if modules_defines.has_key(module):
414 test.write("#ifdef %s\n" % (modules_defines[module]))
415 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000416 test.write("""
417#define gen_nb_%s 1
418static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
419 return(NULL);
420}
421static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
422}
423""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000424 if define == 1:
425 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000426 add_generated_param_type(name)
427 return 1
428
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000429 return 0
430
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000431#
432# Provide the type destructors for the return values
433#
434
Daniel Veillard34099b42004-11-04 17:34:35 +0000435known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000436
437def is_known_return_type(name):
438 for type in known_return_types:
439 if type == name:
440 return 1
441 return 0
442
Daniel Veillard34099b42004-11-04 17:34:35 +0000443#
444# Copy the beginning of the C test program result
445#
446
William M. Brack106cad62004-12-23 15:56:12 +0000447try:
448 input = open("testapi.c", "r")
449except:
450 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000451test = open('testapi.c.new', 'w')
452
453def compare_and_save():
454 global test
455
456 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000457 try:
458 input = open("testapi.c", "r").read()
459 except:
460 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000461 test = open('testapi.c.new', "r").read()
462 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000463 try:
464 os.system("rm testapi.c; mv testapi.c.new testapi.c")
465 except:
466 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000467 print("Updated testapi.c")
468 else:
469 print("Generated testapi.c is identical")
470
471line = input.readline()
472while line != "":
473 if line == "/* CUT HERE: everything below that line is generated */\n":
474 break;
475 if line[0:15] == "#define gen_nb_":
476 type = string.split(line[15:])[0]
477 known_param_types.append(type)
478 if line[0:19] == "static void desret_":
479 type = string.split(line[19:], '(')[0]
480 known_return_types.append(type)
481 test.write(line)
482 line = input.readline()
483input.close()
484
485if line == "":
486 print "Could not find the CUT marker in testapi.c skipping generation"
487 test.close()
488 sys.exit(0)
489
490print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
491 len(known_param_types), len(known_return_types)))
492test.write("/* CUT HERE: everything below that line is generated */\n")
493
494
495#
496# Open the input API description
497#
William M. Brack106cad62004-12-23 15:56:12 +0000498doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000499if doc == None:
500 print "Failed to load doc/libxml2-api.xml"
501 sys.exit(1)
502ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000503
504#
William M. Brack094dd862004-11-14 14:28:34 +0000505# Generate a list of all function parameters and select only
506# those used in the api tests
507#
508argtypes = {}
509args = ctxt.xpathEval("/api/symbols/function/arg")
510for arg in args:
511 mod = arg.xpathEval('string(../@file)')
512 func = arg.xpathEval('string(../@name)')
513 if (mod not in skipped_modules) and (func not in skipped_functions):
514 type = arg.xpathEval('string(@type)')
515 if not argtypes.has_key(type):
516 argtypes[type] = func
517
518# similarly for return types
519rettypes = {}
520rets = ctxt.xpathEval("/api/symbols/function/return")
521for ret in rets:
522 mod = ret.xpathEval('string(../@file)')
523 func = ret.xpathEval('string(../@name)')
524 if (mod not in skipped_modules) and (func not in skipped_functions):
525 type = ret.xpathEval('string(@type)')
526 if not rettypes.has_key(type):
527 rettypes[type] = func
528
529#
Daniel Veillard57b25162004-11-06 14:50:18 +0000530# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000531# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000532#
533enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
534for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000535 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000536 name = enum.xpathEval('string(@name)')
537 #
538 # Skip any enums which are not in our filtered lists
539 #
540 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
541 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000542 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000543
William M. Brack094dd862004-11-14 14:28:34 +0000544 if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000545 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
546 i = 0
547 vals = []
548 for value in values:
549 vname = value.xpathEval('string(@name)')
550 if vname == None:
551 continue;
552 i = i + 1
553 if i >= 5:
554 break;
555 vals.append(vname)
556 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000557 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000558 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000559 if modules_defines.has_key(module):
560 test.write("#ifdef %s\n" % (modules_defines[module]))
561 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000562 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
563 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
564 (name, name))
565 i = 1
566 for value in vals:
567 test.write(" if (no == %d) return(%s);\n" % (i, value))
568 i = i + 1
569 test.write(""" return(0);
570}
William M. Brack094dd862004-11-14 14:28:34 +0000571
572static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
573}
574
575""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000576 known_param_types.append(name)
577
William M. Brack094dd862004-11-14 14:28:34 +0000578 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000579 if define == 0 and modules_defines.has_key(module):
580 test.write("#ifdef %s\n" % (modules_defines[module]))
581 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000582 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000583}
584
William M. Brack094dd862004-11-14 14:28:34 +0000585""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000586 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000587 if define == 1:
588 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000589
590#
591# Load the interfaces
592#
Daniel Veillard57b25162004-11-06 14:50:18 +0000593headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000594for file in headers:
595 name = file.xpathEval('string(@name)')
596 if (name == None) or (name == ''):
597 continue
598
599 #
600 # Some module may be skipped because they don't really consists
601 # of user callable APIs
602 #
603 if is_skipped_module(name):
604 continue
605
606 #
607 # do not test deprecated APIs
608 #
609 desc = file.xpathEval('string(description)')
610 if string.find(desc, 'DEPRECATED') != -1:
611 print "Skipping deprecated interface %s" % name
612 continue;
613
614 test.write("#include <libxml/%s.h>\n" % name)
615 modules.append(name)
616
617#
618# Generate the callers signatures
619#
620for module in modules:
621 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000622
623#
624# Generate the top caller
625#
626
627test.write("""
628/**
629 * testlibxml2:
630 *
631 * Main entry point of the tester for the full libxml2 module,
632 * it calls all the tester entry point for each module.
633 *
634 * Returns the number of error found
635 */
636static int
637testlibxml2(void)
638{
Daniel Veillard42595322004-11-08 10:52:06 +0000639 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000640
641""")
642
643for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000644 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000645
646test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000647 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000648 function_tests, call_tests, test_ret);
649 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000650}
651
652""")
653
654#
655# How to handle a function
656#
657nb_tests = 0
658
659def generate_test(module, node):
660 global test
661 global nb_tests
662 nb_cond = 0
663 no_gen = 0
664
665 name = node.xpathEval('string(@name)')
666 if is_skipped_function(name):
667 return
668
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000669 #
670 # check we know how to handle the args and return values
671 # and store the informations for the generation
672 #
673 try:
674 args = node.xpathEval("arg")
675 except:
676 args = []
677 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000678 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000679 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000680 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000681 rtype = arg.xpathEval("string(@type)")
682 if rtype == 'void':
683 break;
684 info = arg.xpathEval("string(@info)")
685 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000686 type = type_convert(rtype, nam, info, module, name, n)
Daniel Veillardce682bc2004-11-05 17:22:25 +0000687 if is_known_param_type(type, rtype) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000688 add_missing_type(type, name);
689 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000690 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
691 rtype[0:6] == 'const ':
692 crtype = rtype[6:]
693 else:
694 crtype = rtype
695 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000696
697 try:
698 rets = node.xpathEval("return")
699 except:
700 rets = []
701 t_ret = None
702 for ret in rets:
703 rtype = ret.xpathEval("string(@type)")
704 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000705 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000706 if rtype == 'void':
707 break
708 if is_known_return_type(type) == 0:
709 add_missing_type(type, name);
710 no_gen = 1
711 t_ret = (type, rtype, info)
712 break
713
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000714 test.write("""
715static int
716test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000717 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000718
719""" % (name))
720
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000721 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000722 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000723 test.write("""
724 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000725 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000726}
727
728""")
729 return
730
731 try:
732 conds = node.xpathEval("cond")
733 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000734 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000735 nb_cond = nb_cond + 1
736 except:
737 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000738
739 define = 0
740 if function_defines.has_key(name):
741 test.write("#ifdef %s\n" % (function_defines[name]))
742 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000743
744 # Declare the memory usage counter
745 no_mem = is_skipped_memcheck(name)
746 if no_mem == 0:
747 test.write(" int mem_base;\n");
748
749 # Declare the return value
750 if t_ret != None:
751 test.write(" %s ret_val;\n" % (t_ret[1]))
752
753 # Declare the arguments
754 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000755 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000756 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000757 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000758 test.write(" int n_%s;\n" % (nam))
759 test.write("\n")
760
761 # Cascade loop on of each argument list of values
762 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000763 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000764 #
765 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
766 nam, nam, type, nam))
767
768 # log the memory usage
769 if no_mem == 0:
770 test.write(" mem_base = xmlMemBlocks();\n");
771
772 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000773 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000774 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000775 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000776 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000777 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
778 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000779
780 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000781 if extra_pre_call.has_key(name):
782 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000783 if t_ret != None:
784 test.write("\n ret_val = %s(" % (name))
785 need = 0
786 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000787 (nam, type, rtype, crtype, info) = arg
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000788 if need:
789 test.write(", ")
790 else:
791 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000792 if rtype != crtype:
793 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000794 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000795 test.write(");\n")
796 if extra_post_call.has_key(name):
797 test.write(" %s\n"% (extra_post_call[name]))
798 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000799 else:
800 test.write("\n %s(" % (name));
801 need = 0;
802 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000803 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000804 if need:
805 test.write(", ")
806 else:
807 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000808 if rtype != crtype:
809 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000810 test.write("%s" % nam)
811 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000812 if extra_post_call.has_key(name):
813 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000814
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000815 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000816
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000817 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000818 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000819 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000820 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000821 #
William M. Brackf13f77f2004-11-12 16:03:48 +0000822 test.write(" des_%s(n_%s, " % (type, nam))
823 if rtype != crtype:
824 test.write("(%s)" % rtype)
825 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000826 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000827
828 test.write(" xmlResetLastError();\n");
829 # Check the memory usage
830 if no_mem == 0:
831 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000832 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000833 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000834 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000835""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000836 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000837 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000838 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
839 test.write(""" printf("\\n");\n""")
840 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000841
842 for arg in t_args:
843 test.write(" }\n")
844
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000845 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000846 #
847 # end of conditional
848 #
849 while nb_cond > 0:
850 test.write("#endif\n")
851 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000852 if define == 1:
853 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000854
855 nb_tests = nb_tests + 1;
856
857 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000858 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000859}
860
861""")
862
863#
864# Generate all module callers
865#
866for module in modules:
867 # gather all the functions exported by that module
868 try:
869 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
870 except:
871 print "Failed to gather functions from module %s" % (module)
872 continue;
873
874 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000875 i = 0
876 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000877 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000878 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000879 generate_test(module, function);
880
881 # header
882 test.write("""static int
883test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000884 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000885
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000886 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000887""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000888
889 # iterate over all functions in the module generating the call
890 for function in functions:
891 name = function.xpathEval('string(@name)')
892 if is_skipped_function(name):
893 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000894 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000895
896 # footer
897 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000898 if (test_ret != 0)
899 printf("Module %s: %%d errors\\n", test_ret);
900 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000901}
902""" % (module))
903
Daniel Veillardce244ad2004-11-05 10:03:46 +0000904#
905# Generate direct module caller
906#
907test.write("""static int
908test_module(const char *module) {
909""");
910for module in modules:
911 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
912 module, module))
913test.write(""" return(0);
914}
915""");
916
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000917print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000918
Daniel Veillard34099b42004-11-04 17:34:35 +0000919compare_and_save()
920
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000921missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000922for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000923 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000924 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000925
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000926 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000927 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000928
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000929def compare_missing(a, b):
930 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000931
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000932missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000933print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000934lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000935lst.write("Missing support for %d types" % (len(missing_list)))
936lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000937for miss in missing_list:
938 lst.write("%s: %d :" % (miss[1], miss[0]))
939 i = 0
940 for n in missing_types[miss[1]]:
941 i = i + 1
942 if i > 5:
943 lst.write(" ...")
944 break
945 lst.write(" %s" % (n))
946 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000947lst.write("\n")
948lst.write("\n")
949lst.write("Missing support per module");
950for module in missing_functions.keys():
951 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000952
953lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000954
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000955