blob: c48c7b930fa81afa56094a855cc7adf77e0fdaec [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",
47}
48
49#
50# defines for specific functions
51#
52function_defines = {
53 "htmlDefaultSAXHandlerInit": "LIBXML_HTML_ENABLED",
54 "xmlSAX2EndElement" : "LIBXML_SAX1_ENABLED",
55 "xmlSAX2StartElement" : "LIBXML_SAX1_ENABLED",
56 "xmlSAXDefaultVersion" : "LIBXML_SAX1_ENABLED",
57 "UTF8Toisolat1" : "LIBXML_OUTPUT_ENABLED",
58 "xmlCleanupPredefinedEntities": "LIBXML_LEGACY_ENABLED",
59 "xmlInitializePredefinedEntities": "LIBXML_LEGACY_ENABLED",
60 "xmlSetFeature": "LIBXML_LEGACY_ENABLED",
61 "xmlGetFeature": "LIBXML_LEGACY_ENABLED",
62 "xmlGetFeaturesList": "LIBXML_LEGACY_ENABLED",
63 "xmlIOParseDTD": "LIBXML_VALID_ENABLED",
64 "xmlParseDTD": "LIBXML_VALID_ENABLED",
65 "xmlParseDoc": "LIBXML_SAX1_ENABLED",
66 "xmlParseMemory": "LIBXML_SAX1_ENABLED",
67 "xmlRecoverDoc": "LIBXML_SAX1_ENABLED",
68 "xmlParseFile": "LIBXML_SAX1_ENABLED",
69 "xmlRecoverFile": "LIBXML_SAX1_ENABLED",
70 "xmlRecoverMemory": "LIBXML_SAX1_ENABLED",
71 "xmlSAXParseFileWithData": "LIBXML_SAX1_ENABLED",
72 "xmlSAXParseMemory": "LIBXML_SAX1_ENABLED",
73 "xmlSAXUserParseMemory": "LIBXML_SAX1_ENABLED",
74 "xmlSAXParseDoc": "LIBXML_SAX1_ENABLED",
75 "xmlSAXParseDTD": "LIBXML_SAX1_ENABLED",
76 "xmlSAXUserParseFile": "LIBXML_SAX1_ENABLED",
77 "xmlParseEntity": "LIBXML_SAX1_ENABLED",
78 "xmlParseExternalEntity": "LIBXML_SAX1_ENABLED",
79 "xmlSAXParseMemoryWithData": "LIBXML_SAX1_ENABLED",
80 "xmlParseBalancedChunkMemory": "LIBXML_SAX1_ENABLED",
81 "xmlParseBalancedChunkMemoryRecover": "LIBXML_SAX1_ENABLED",
82 "xmlSetupParserForBuffer": "LIBXML_SAX1_ENABLED",
83 "xmlStopParser": "LIBXML_PUSH_ENABLED",
84 "xmlAttrSerializeTxtContent": "LIBXML_OUTPUT_ENABLED",
85 "xmlSAXParseFile": "LIBXML_SAX1_ENABLED",
86 "xmlSAXParseEntity": "LIBXML_SAX1_ENABLED",
87 "xmlNewTextChild": "LIBXML_TREE_ENABLED",
88 "xmlNewDocRawNode": "LIBXML_TREE_ENABLED",
89 "xmlNewProp": "LIBXML_TREE_ENABLED",
90 "xmlReconciliateNs": "LIBXML_TREE_ENABLED",
91 "xmlValidateNCName": "LIBXML_TREE_ENABLED",
92 "xmlValidateNMToken": "LIBXML_TREE_ENABLED",
93 "xmlValidateName": "LIBXML_TREE_ENABLED",
94 "xmlNewChild": "LIBXML_TREE_ENABLED",
95 "xmlValidateQName": "LIBXML_TREE_ENABLED",
96 "xmlSprintfElementContent": "LIBXML_OUTPUT_ENABLED",
97 "xmlValidGetPotentialChildren" : "LIBXML_VALID_ENABLED",
98 "xmlValidGetValidElements" : "LIBXML_VALID_ENABLED",
99 "docbDefaultSAXHandlerInit" : "LIBXML_DOCB_ENABLED",
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000100 "xmlTextReaderPreservePattern" : "LIBXML_PATTERN_ENABLED",
Daniel Veillarda521d282004-11-09 14:59:59 +0000101}
102
103#
William M. Brack094dd862004-11-14 14:28:34 +0000104# Some functions really need to be skipped for the tests.
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000105#
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000106skipped_functions = [
107# block on I/O
108"xmlFdRead", "xmlReadFd", "xmlCtxtReadFd",
109"htmlFdRead", "htmlReadFd", "htmlCtxtReadFd",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000110"xmlReaderNewFd", "xmlReaderForFd",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000111"xmlIORead", "xmlReadIO", "xmlCtxtReadIO",
112"htmlIORead", "htmlReadIO", "htmlCtxtReadIO",
Daniel Veillard27f20102004-11-05 11:50:11 +0000113"xmlReaderNewIO", "xmlBufferDump", "xmlNanoFTPConnect",
114"xmlNanoFTPConnectTo",
Daniel Veillard42595322004-11-08 10:52:06 +0000115# Complex I/O APIs
116"xmlCreateIOParserCtxt", "xmlParserInputBufferCreateIO",
117"xmlRegisterInputCallbacks", "xmlReaderForIO",
118"xmlOutputBufferCreateIO", "xmlRegisterOutputCallbacks",
119"xmlSaveToIO",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000120# library state cleanup, generate false leak informations and other
121# troubles, heavillyb tested otherwise.
Daniel Veillardce244ad2004-11-05 10:03:46 +0000122"xmlCleanupParser", "xmlRelaxNGCleanupTypes", "xmlSetListDoc",
123"xmlSetTreeDoc", "xmlUnlinkNode",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000124# hard to avoid leaks in the tests
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000125"xmlStrcat", "xmlStrncat", "xmlCatalogAddLocal", "xmlNewTextWriterDoc",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000126"xmlXPathNewValueTree", "xmlXPathWrapString",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000127# unimplemented
128"xmlTextReaderReadInnerXml", "xmlTextReaderReadOuterXml",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000129"xmlTextReaderReadString",
130# destructor
Daniel Veillard27f20102004-11-05 11:50:11 +0000131"xmlListDelete", "xmlOutputBufferClose", "xmlNanoFTPClose",
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000132# deprecated
133"xmlCatalogGetPublic", "xmlCatalogGetSystem", "xmlEncodeEntities",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000134"xmlNewGlobalNs", "xmlHandleEntity", "xmlNamespaceParseNCName",
135"xmlNamespaceParseNSDef", "xmlNamespaceParseQName",
136"xmlParseNamespace", "xmlParseQuotedString", "xmlParserHandleReference",
137"xmlScanName",
Daniel Veillarda82b1822004-11-08 16:24:57 +0000138"xmlDecodeEntities",
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000139# allocators
140"xmlMemFree",
Daniel Veillardc2c894f2004-11-07 12:17:35 +0000141# verbosity
Daniel Veillarda82b1822004-11-08 16:24:57 +0000142"xmlCatalogSetDebug", "xmlShellPrintXPathError", "xmlShellPrintNode",
Daniel Veillard2a4fb5a2004-11-08 14:02:18 +0000143# Internal functions, no user space should really call them
144"xmlParseAttribute", "xmlParseAttributeListDecl", "xmlParseName",
145"xmlParseNmtoken", "xmlParseEntityValue", "xmlParseAttValue",
146"xmlParseSystemLiteral", "xmlParsePubidLiteral", "xmlParseCharData",
147"xmlParseExternalID", "xmlParseComment", "xmlParsePITarget", "xmlParsePI",
148"xmlParseNotationDecl", "xmlParseEntityDecl", "xmlParseDefaultDecl",
149"xmlParseNotationType", "xmlParseEnumerationType", "xmlParseEnumeratedType",
150"xmlParseAttributeType", "xmlParseAttributeListDecl",
151"xmlParseElementMixedContentDecl", "xmlParseElementChildrenContentDecl",
152"xmlParseElementContentDecl", "xmlParseElementDecl", "xmlParseMarkupDecl",
153"xmlParseCharRef", "xmlParseEntityRef", "xmlParseReference",
154"xmlParsePEReference", "xmlParseDocTypeDecl", "xmlParseAttribute",
155"xmlParseStartTag", "xmlParseEndTag", "xmlParseCDSect", "xmlParseContent",
156"xmlParseElement", "xmlParseVersionNum", "xmlParseVersionInfo",
157"xmlParseEncName", "xmlParseEncodingDecl", "xmlParseSDDecl",
158"xmlParseXMLDecl", "xmlParseTextDecl", "xmlParseMisc",
159"xmlParseExternalSubset", "xmlParserHandlePEReference",
160"xmlSkipBlankChars",
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000161]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000162
163#
William M. Brack094dd862004-11-14 14:28:34 +0000164# These functions have side effects on the global state
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000165# and hence generate errors on memory allocation tests
166#
167skipped_memcheck = [ "xmlLoadCatalog", "xmlAddEncodingAlias",
168 "xmlSchemaInitTypes", "xmlNanoFTPProxy", "xmlNanoFTPScanProxy",
169 "xmlNanoHTTPScanProxy", "xmlResetLastError", "xmlCatalogConvert",
170 "xmlCatalogRemove", "xmlLoadCatalogs", "xmlCleanupCharEncodingHandlers",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000171 "xmlInitCharEncodingHandlers", "xmlCatalogCleanup",
Daniel Veillard42595322004-11-08 10:52:06 +0000172 "xmlSchemaGetBuiltInType",
Daniel Veillard29614c72004-11-26 10:47:26 +0000173 "htmlParseFile", "htmlCtxtReadFile" # loads the catalogs
Daniel Veillarda03e3652004-11-02 18:45:30 +0000174]
175
176#
177# Extra code needed for some test cases
178#
Daniel Veillard34099b42004-11-04 17:34:35 +0000179extra_pre_call = {
Daniel Veillarda521d282004-11-09 14:59:59 +0000180 "xmlSAXUserParseFile": """
181#ifdef LIBXML_SAX1_ENABLED
182 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
183#endif
184""",
185 "xmlSAXUserParseMemory": """
186#ifdef LIBXML_SAX1_ENABLED
187 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
188#endif
189""",
190 "xmlParseBalancedChunkMemory": """
191#ifdef LIBXML_SAX1_ENABLED
192 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
193#endif
194""",
195 "xmlParseBalancedChunkMemoryRecover": """
196#ifdef LIBXML_SAX1_ENABLED
197 if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
198#endif
199""",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000200 "xmlParserInputBufferCreateFd":
201 "if (fd >= 0) fd = -1;",
Daniel Veillard34099b42004-11-04 17:34:35 +0000202}
Daniel Veillarda03e3652004-11-02 18:45:30 +0000203extra_post_call = {
204 "xmlAddChild":
205 "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
206 "xmlAddChildList":
207 "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
208 "xmlAddSibling":
209 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
210 "xmlAddNextSibling":
211 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
212 "xmlAddPrevSibling":
213 "if (ret_val == NULL) { xmlFreeNode(elem) ; elem = NULL ; }",
214 "xmlDocSetRootElement":
215 "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
216 "xmlReplaceNode":
Daniel Veillardce244ad2004-11-05 10:03:46 +0000217 """if (cur != NULL) {
218 xmlUnlinkNode(cur);
219 xmlFreeNode(cur) ; cur = NULL ; }
220 if (old != NULL) {
221 xmlUnlinkNode(old);
222 xmlFreeNode(old) ; old = NULL ; }
223 ret_val = NULL;""",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000224 "xmlTextMerge":
225 """if ((first != NULL) && (first->type != XML_TEXT_NODE)) {
Daniel Veillardce244ad2004-11-05 10:03:46 +0000226 xmlUnlinkNode(second);
Daniel Veillarda03e3652004-11-02 18:45:30 +0000227 xmlFreeNode(second) ; second = NULL ; }""",
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000228 "xmlBuildQName":
229 """if ((ret_val != NULL) && (ret_val != ncname) &&
230 (ret_val != prefix) && (ret_val != memory))
231 xmlFree(ret_val);
232 ret_val = NULL;""",
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000233 "xmlDictReference": "xmlDictFree(dict);",
Daniel Veillard3d97e662004-11-04 10:49:00 +0000234 # Functions which deallocates one of their parameters
235 "xmlXPathConvertBoolean": """val = NULL;""",
236 "xmlXPathConvertNumber": """val = NULL;""",
237 "xmlXPathConvertString": """val = NULL;""",
238 "xmlSaveFileTo": """buf = NULL;""",
Daniel Veillard34099b42004-11-04 17:34:35 +0000239 "xmlSaveFormatFileTo": """buf = NULL;""",
240 "xmlIOParseDTD": "input = NULL;",
Daniel Veillardce244ad2004-11-05 10:03:46 +0000241 "xmlRemoveProp": "cur = NULL;",
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000242 "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
243 "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
244 "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
245 "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000246 "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
Daniel Veillard42595322004-11-08 10:52:06 +0000247 "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
Daniel Veillarda521d282004-11-09 14:59:59 +0000248 "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
249 "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
250 "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
251 "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
252 "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
Daniel Veillarda03e3652004-11-02 18:45:30 +0000253}
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000254
255modules = []
256
257def is_skipped_module(name):
258 for mod in skipped_modules:
259 if mod == name:
260 return 1
261 return 0
262
263def is_skipped_function(name):
264 for fun in skipped_functions:
265 if fun == name:
266 return 1
267 # Do not test destructors
268 if string.find(name, 'Free') != -1:
269 return 1
270 return 0
271
272def is_skipped_memcheck(name):
273 for fun in skipped_memcheck:
274 if fun == name:
275 return 1
276 return 0
277
278missing_types = {}
279def add_missing_type(name, func):
280 try:
281 list = missing_types[name]
282 list.append(func)
283 except:
284 missing_types[name] = [func]
285
Daniel Veillardce682bc2004-11-05 17:22:25 +0000286generated_param_types = []
287def add_generated_param_type(name):
288 generated_param_types.append(name)
289
290generated_return_types = []
291def add_generated_return_type(name):
292 generated_return_types.append(name)
293
Daniel Veillard34099b42004-11-04 17:34:35 +0000294missing_functions = {}
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000295missing_functions_nr = 0
Daniel Veillard34099b42004-11-04 17:34:35 +0000296def add_missing_functions(name, module):
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000297 global missing_functions_nr
298
299 missing_functions_nr = missing_functions_nr + 1
Daniel Veillard34099b42004-11-04 17:34:35 +0000300 try:
301 list = missing_functions[module]
302 list.append(name)
303 except:
304 missing_functions[module] = [name]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000305
306#
307# Provide the type generators and destructors for the parameters
308#
309
Daniel Veillarda03e3652004-11-02 18:45:30 +0000310def type_convert(str, name, info, module, function, pos):
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000311# res = string.replace(str, " ", " ")
312# res = string.replace(str, " ", " ")
313# res = string.replace(str, " ", " ")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000314 res = string.replace(str, " *", "_ptr")
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000315# res = string.replace(str, "*", "_ptr")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000316 res = string.replace(res, " ", "_")
317 if res == 'const_char_ptr':
318 if string.find(name, "file") != -1 or \
319 string.find(name, "uri") != -1 or \
320 string.find(name, "URI") != -1 or \
321 string.find(info, "filename") != -1 or \
322 string.find(info, "URI") != -1 or \
323 string.find(info, "URL") != -1:
William M. Brack83d9c372004-11-08 02:26:08 +0000324 if string.find(function, "Save") != -1 or \
325 string.find(function, "Create") != -1 or \
326 string.find(function, "Write") != -1:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000327 return('fileoutput')
328 return('filepath')
329 if res == 'void_ptr':
330 if module == 'nanoftp' and name == 'ctx':
331 return('xmlNanoFTPCtxtPtr')
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000332 if function == 'xmlNanoFTPNewCtxt':
333 return('xmlNanoFTPCtxtPtr')
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000334 if module == 'nanohttp' and name == 'ctx':
335 return('xmlNanoHTTPCtxtPtr')
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000336 if function == 'xmlIOHTTPOpenW':
337 return('xmlNanoHTTPCtxtPtr')
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000338 if string.find(name, "data") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000339 return('userdata')
Daniel Veillardd005b9e2004-11-03 17:07:05 +0000340 if string.find(name, "user") != -1:
William M. Brack094dd862004-11-14 14:28:34 +0000341 return('userdata')
Daniel Veillard3d97e662004-11-04 10:49:00 +0000342 if res == 'xmlDoc_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000343 res = 'xmlDocPtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000344 if res == 'xmlNode_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000345 res = 'xmlNodePtr'
Daniel Veillard3d97e662004-11-04 10:49:00 +0000346 if res == 'xmlDict_ptr':
William M. Brack094dd862004-11-14 14:28:34 +0000347 res = 'xmlDictPtr'
Daniel Veillarda03e3652004-11-02 18:45:30 +0000348 if res == 'xmlNodePtr' and pos != 0:
349 if (function == 'xmlAddChild' and pos == 2) or \
350 (function == 'xmlAddChildList' and pos == 2) or \
351 (function == 'xmlAddNextSibling' and pos == 2) or \
352 (function == 'xmlAddSibling' and pos == 2) or \
353 (function == 'xmlDocSetRootElement' and pos == 2) or \
354 (function == 'xmlReplaceNode' and pos == 2) or \
355 (function == 'xmlTextMerge') or \
356 (function == 'xmlAddPrevSibling' and pos == 2):
357 return('xmlNodePtr_in');
Daniel Veillard34099b42004-11-04 17:34:35 +0000358 if res == 'const xmlBufferPtr':
William M. Brack094dd862004-11-14 14:28:34 +0000359 res = 'xmlBufferPtr'
Daniel Veillard27f20102004-11-05 11:50:11 +0000360 if res == 'xmlChar_ptr' and name == 'name' and \
361 string.find(function, "EatName") != -1:
362 return('eaten_name')
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000363 if res == 'void_ptr*':
364 res = 'void_ptr_ptr'
365 if res == 'char_ptr*':
366 res = 'char_ptr_ptr'
367 if res == 'xmlChar_ptr*':
368 res = 'xmlChar_ptr_ptr'
369 if res == 'const_xmlChar_ptr*':
370 res = 'const_xmlChar_ptr_ptr'
371 if res == 'const_char_ptr*':
372 res = 'const_char_ptr_ptr'
Daniel Veillarda82b1822004-11-08 16:24:57 +0000373 if res == 'FILE_ptr' and module == 'debugXML':
374 res = 'debug_FILE_ptr';
Daniel Veillard6128c012004-11-08 17:16:15 +0000375 if res == 'int' and name == 'options':
376 if module == 'parser' or module == 'xmlreader':
377 res = 'parseroptions'
William M. Brack094dd862004-11-14 14:28:34 +0000378
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000379 return res
380
Daniel Veillard34099b42004-11-04 17:34:35 +0000381known_param_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000382
Daniel Veillardce682bc2004-11-05 17:22:25 +0000383def is_known_param_type(name, rtype):
384 global test
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000385 for type in known_param_types:
386 if type == name:
387 return 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000388 for type in generated_param_types:
389 if type == name:
390 return 1
391
392 if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
393 if rtype[0:6] == 'const ':
394 crtype = rtype[6:]
395 else:
396 crtype = rtype
397
Daniel Veillarda521d282004-11-09 14:59:59 +0000398 define = 0
399 if modules_defines.has_key(module):
400 test.write("#ifdef %s\n" % (modules_defines[module]))
401 define = 1
Daniel Veillardce682bc2004-11-05 17:22:25 +0000402 test.write("""
403#define gen_nb_%s 1
404static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
405 return(NULL);
406}
407static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
408}
409""" % (name, crtype, name, name, rtype))
Daniel Veillarda521d282004-11-09 14:59:59 +0000410 if define == 1:
411 test.write("#endif\n\n")
Daniel Veillardce682bc2004-11-05 17:22:25 +0000412 add_generated_param_type(name)
413 return 1
414
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000415 return 0
416
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000417#
418# Provide the type destructors for the return values
419#
420
Daniel Veillard34099b42004-11-04 17:34:35 +0000421known_return_types = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000422
423def is_known_return_type(name):
424 for type in known_return_types:
425 if type == name:
426 return 1
427 return 0
428
Daniel Veillard34099b42004-11-04 17:34:35 +0000429#
430# Copy the beginning of the C test program result
431#
432
William M. Brack106cad62004-12-23 15:56:12 +0000433try:
434 input = open("testapi.c", "r")
435except:
436 input = open(srcPref + "testapi.c", "r")
Daniel Veillard34099b42004-11-04 17:34:35 +0000437test = open('testapi.c.new', 'w')
438
439def compare_and_save():
440 global test
441
442 test.close()
William M. Brack106cad62004-12-23 15:56:12 +0000443 try:
444 input = open("testapi.c", "r").read()
445 except:
446 input = ''
Daniel Veillard34099b42004-11-04 17:34:35 +0000447 test = open('testapi.c.new', "r").read()
448 if input != test:
William M. Brack106cad62004-12-23 15:56:12 +0000449 try:
450 os.system("rm testapi.c; mv testapi.c.new testapi.c")
451 except:
452 os.system("mv testapi.c.new testapi.c")
Daniel Veillard34099b42004-11-04 17:34:35 +0000453 print("Updated testapi.c")
454 else:
455 print("Generated testapi.c is identical")
456
457line = input.readline()
458while line != "":
459 if line == "/* CUT HERE: everything below that line is generated */\n":
460 break;
461 if line[0:15] == "#define gen_nb_":
462 type = string.split(line[15:])[0]
463 known_param_types.append(type)
464 if line[0:19] == "static void desret_":
465 type = string.split(line[19:], '(')[0]
466 known_return_types.append(type)
467 test.write(line)
468 line = input.readline()
469input.close()
470
471if line == "":
472 print "Could not find the CUT marker in testapi.c skipping generation"
473 test.close()
474 sys.exit(0)
475
476print("Scanned testapi.c: found %d parameters types and %d return types\n" % (
477 len(known_param_types), len(known_return_types)))
478test.write("/* CUT HERE: everything below that line is generated */\n")
479
480
481#
482# Open the input API description
483#
William M. Brack106cad62004-12-23 15:56:12 +0000484doc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
Daniel Veillard34099b42004-11-04 17:34:35 +0000485if doc == None:
486 print "Failed to load doc/libxml2-api.xml"
487 sys.exit(1)
488ctxt = doc.xpathNewContext()
Daniel Veillard57b25162004-11-06 14:50:18 +0000489
490#
William M. Brack094dd862004-11-14 14:28:34 +0000491# Generate a list of all function parameters and select only
492# those used in the api tests
493#
494argtypes = {}
495args = ctxt.xpathEval("/api/symbols/function/arg")
496for arg in args:
497 mod = arg.xpathEval('string(../@file)')
498 func = arg.xpathEval('string(../@name)')
499 if (mod not in skipped_modules) and (func not in skipped_functions):
500 type = arg.xpathEval('string(@type)')
501 if not argtypes.has_key(type):
502 argtypes[type] = func
503
504# similarly for return types
505rettypes = {}
506rets = ctxt.xpathEval("/api/symbols/function/return")
507for ret in rets:
508 mod = ret.xpathEval('string(../@file)')
509 func = ret.xpathEval('string(../@name)')
510 if (mod not in skipped_modules) and (func not in skipped_functions):
511 type = ret.xpathEval('string(@type)')
512 if not rettypes.has_key(type):
513 rettypes[type] = func
514
515#
Daniel Veillard57b25162004-11-06 14:50:18 +0000516# Generate constructors and return type handling for all enums
William M. Brack094dd862004-11-14 14:28:34 +0000517# which are used as function parameters
Daniel Veillard57b25162004-11-06 14:50:18 +0000518#
519enums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
520for enum in enums:
Daniel Veillarda521d282004-11-09 14:59:59 +0000521 module = enum.xpathEval('string(@file)')
William M. Brack094dd862004-11-14 14:28:34 +0000522 name = enum.xpathEval('string(@name)')
523 #
524 # Skip any enums which are not in our filtered lists
525 #
526 if (name == None) or ((name not in argtypes) and (name not in rettypes)):
527 continue;
Daniel Veillarda521d282004-11-09 14:59:59 +0000528 define = 0
Daniel Veillard57b25162004-11-06 14:50:18 +0000529
William M. Brack094dd862004-11-14 14:28:34 +0000530 if argtypes.has_key(name) and is_known_param_type(name, name) == 0:
Daniel Veillard57b25162004-11-06 14:50:18 +0000531 values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
532 i = 0
533 vals = []
534 for value in values:
535 vname = value.xpathEval('string(@name)')
536 if vname == None:
537 continue;
538 i = i + 1
539 if i >= 5:
540 break;
541 vals.append(vname)
542 if vals == []:
William M. Brack094dd862004-11-14 14:28:34 +0000543 print "Didn't find any value for enum %s" % (name)
Daniel Veillard57b25162004-11-06 14:50:18 +0000544 continue
Daniel Veillarda521d282004-11-09 14:59:59 +0000545 if modules_defines.has_key(module):
546 test.write("#ifdef %s\n" % (modules_defines[module]))
547 define = 1
Daniel Veillard57b25162004-11-06 14:50:18 +0000548 test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
549 test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
550 (name, name))
551 i = 1
552 for value in vals:
553 test.write(" if (no == %d) return(%s);\n" % (i, value))
554 i = i + 1
555 test.write(""" return(0);
556}
William M. Brack094dd862004-11-14 14:28:34 +0000557
558static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
559}
560
561""" % (name, name));
Daniel Veillard57b25162004-11-06 14:50:18 +0000562 known_param_types.append(name)
563
William M. Brack094dd862004-11-14 14:28:34 +0000564 if (is_known_return_type(name) == 0) and (name in rettypes):
Daniel Veillarda521d282004-11-09 14:59:59 +0000565 if define == 0 and modules_defines.has_key(module):
566 test.write("#ifdef %s\n" % (modules_defines[module]))
567 define = 1
William M. Brack094dd862004-11-14 14:28:34 +0000568 test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
Daniel Veillard57b25162004-11-06 14:50:18 +0000569}
570
William M. Brack094dd862004-11-14 14:28:34 +0000571""" % (name, name))
Daniel Veillard57b25162004-11-06 14:50:18 +0000572 known_return_types.append(name)
Daniel Veillarda521d282004-11-09 14:59:59 +0000573 if define == 1:
574 test.write("#endif\n\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000575
576#
577# Load the interfaces
578#
Daniel Veillard57b25162004-11-06 14:50:18 +0000579headers = ctxt.xpathEval("/api/files/file")
Daniel Veillard34099b42004-11-04 17:34:35 +0000580for file in headers:
581 name = file.xpathEval('string(@name)')
582 if (name == None) or (name == ''):
583 continue
584
585 #
586 # Some module may be skipped because they don't really consists
587 # of user callable APIs
588 #
589 if is_skipped_module(name):
590 continue
591
592 #
593 # do not test deprecated APIs
594 #
595 desc = file.xpathEval('string(description)')
596 if string.find(desc, 'DEPRECATED') != -1:
597 print "Skipping deprecated interface %s" % name
598 continue;
599
600 test.write("#include <libxml/%s.h>\n" % name)
601 modules.append(name)
602
603#
604# Generate the callers signatures
605#
606for module in modules:
607 test.write("static int test_%s(void);\n" % module);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000608
609#
610# Generate the top caller
611#
612
613test.write("""
614/**
615 * testlibxml2:
616 *
617 * Main entry point of the tester for the full libxml2 module,
618 * it calls all the tester entry point for each module.
619 *
620 * Returns the number of error found
621 */
622static int
623testlibxml2(void)
624{
Daniel Veillard42595322004-11-08 10:52:06 +0000625 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000626
627""")
628
629for module in modules:
Daniel Veillard42595322004-11-08 10:52:06 +0000630 test.write(" test_ret += test_%s();\n" % module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000631
632test.write("""
Daniel Veillard3d97e662004-11-04 10:49:00 +0000633 printf("Total: %d functions, %d tests, %d errors\\n",
Daniel Veillard42595322004-11-08 10:52:06 +0000634 function_tests, call_tests, test_ret);
635 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000636}
637
638""")
639
640#
641# How to handle a function
642#
643nb_tests = 0
644
645def generate_test(module, node):
646 global test
647 global nb_tests
648 nb_cond = 0
649 no_gen = 0
650
651 name = node.xpathEval('string(@name)')
652 if is_skipped_function(name):
653 return
654
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000655 #
656 # check we know how to handle the args and return values
657 # and store the informations for the generation
658 #
659 try:
660 args = node.xpathEval("arg")
661 except:
662 args = []
663 t_args = []
Daniel Veillarda03e3652004-11-02 18:45:30 +0000664 n = 0
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000665 for arg in args:
Daniel Veillarda03e3652004-11-02 18:45:30 +0000666 n = n + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000667 rtype = arg.xpathEval("string(@type)")
668 if rtype == 'void':
669 break;
670 info = arg.xpathEval("string(@info)")
671 nam = arg.xpathEval("string(@name)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000672 type = type_convert(rtype, nam, info, module, name, n)
Daniel Veillardce682bc2004-11-05 17:22:25 +0000673 if is_known_param_type(type, rtype) == 0:
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000674 add_missing_type(type, name);
675 no_gen = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000676 if (type[-3:] == 'Ptr' or type[-4:] == '_ptr') and \
677 rtype[0:6] == 'const ':
678 crtype = rtype[6:]
679 else:
680 crtype = rtype
681 t_args.append((nam, type, rtype, crtype, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000682
683 try:
684 rets = node.xpathEval("return")
685 except:
686 rets = []
687 t_ret = None
688 for ret in rets:
689 rtype = ret.xpathEval("string(@type)")
690 info = ret.xpathEval("string(@info)")
Daniel Veillarda03e3652004-11-02 18:45:30 +0000691 type = type_convert(rtype, 'return', info, module, name, 0)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000692 if rtype == 'void':
693 break
694 if is_known_return_type(type) == 0:
695 add_missing_type(type, name);
696 no_gen = 1
697 t_ret = (type, rtype, info)
698 break
699
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000700 test.write("""
701static int
702test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000703 int test_ret = 0;
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000704
705""" % (name))
706
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000707 if no_gen == 1:
Daniel Veillard34099b42004-11-04 17:34:35 +0000708 add_missing_functions(name, module)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000709 test.write("""
710 /* missing type support */
Daniel Veillard42595322004-11-08 10:52:06 +0000711 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000712}
713
714""")
715 return
716
717 try:
718 conds = node.xpathEval("cond")
719 for cond in conds:
William M. Brack21e4ef22005-01-02 09:53:13 +0000720 test.write("#if %s\n" % (cond.get_content()))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000721 nb_cond = nb_cond + 1
722 except:
723 pass
Daniel Veillarda521d282004-11-09 14:59:59 +0000724
725 define = 0
726 if function_defines.has_key(name):
727 test.write("#ifdef %s\n" % (function_defines[name]))
728 define = 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000729
730 # Declare the memory usage counter
731 no_mem = is_skipped_memcheck(name)
732 if no_mem == 0:
733 test.write(" int mem_base;\n");
734
735 # Declare the return value
736 if t_ret != None:
737 test.write(" %s ret_val;\n" % (t_ret[1]))
738
739 # Declare the arguments
740 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000741 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000742 # add declaration
Daniel Veillardce682bc2004-11-05 17:22:25 +0000743 test.write(" %s %s; /* %s */\n" % (crtype, nam, info))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000744 test.write(" int n_%s;\n" % (nam))
745 test.write("\n")
746
747 # Cascade loop on of each argument list of values
748 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000749 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000750 #
751 test.write(" for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
752 nam, nam, type, nam))
753
754 # log the memory usage
755 if no_mem == 0:
756 test.write(" mem_base = xmlMemBlocks();\n");
757
758 # prepare the call
Daniel Veillard3d97e662004-11-04 10:49:00 +0000759 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000760 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000761 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000762 #
Daniel Veillard3d97e662004-11-04 10:49:00 +0000763 test.write(" %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
764 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000765
766 # do the call, and clanup the result
Daniel Veillard34099b42004-11-04 17:34:35 +0000767 if extra_pre_call.has_key(name):
768 test.write(" %s\n"% (extra_pre_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000769 if t_ret != None:
770 test.write("\n ret_val = %s(" % (name))
771 need = 0
772 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000773 (nam, type, rtype, crtype, info) = arg
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000774 if need:
775 test.write(", ")
776 else:
777 need = 1
William M. Brackf13f77f2004-11-12 16:03:48 +0000778 if rtype != crtype:
779 test.write("(%s)" % rtype)
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000780 test.write("%s" % nam);
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000781 test.write(");\n")
782 if extra_post_call.has_key(name):
783 test.write(" %s\n"% (extra_post_call[name]))
784 test.write(" desret_%s(ret_val);\n" % t_ret[0])
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000785 else:
786 test.write("\n %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)
797 test.write(");\n")
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000798 if extra_post_call.has_key(name):
799 test.write(" %s\n"% (extra_post_call[name]))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000800
Daniel Veillard8a32fe42004-11-02 22:10:16 +0000801 test.write(" call_tests++;\n");
Daniel Veillarda03e3652004-11-02 18:45:30 +0000802
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000803 # Free the arguments
Daniel Veillard3d97e662004-11-04 10:49:00 +0000804 i = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000805 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000806 (nam, type, rtype, crtype, info) = arg;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000807 #
William M. Brackf13f77f2004-11-12 16:03:48 +0000808 test.write(" des_%s(n_%s, " % (type, nam))
809 if rtype != crtype:
810 test.write("(%s)" % rtype)
811 test.write("%s, %d);\n" % (nam, i))
Daniel Veillard3d97e662004-11-04 10:49:00 +0000812 i = i + 1;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000813
814 test.write(" xmlResetLastError();\n");
815 # Check the memory usage
816 if no_mem == 0:
817 test.write(""" if (mem_base != xmlMemBlocks()) {
Daniel Veillarda03e3652004-11-02 18:45:30 +0000818 printf("Leak of %%d blocks found in %s",
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000819 xmlMemBlocks() - mem_base);
Daniel Veillard42595322004-11-08 10:52:06 +0000820 test_ret++;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000821""" % (name));
Daniel Veillarda03e3652004-11-02 18:45:30 +0000822 for arg in t_args:
William M. Brackf13f77f2004-11-12 16:03:48 +0000823 (nam, type, rtype, crtype, info) = arg;
Daniel Veillarda03e3652004-11-02 18:45:30 +0000824 test.write(""" printf(" %%d", n_%s);\n""" % (nam))
825 test.write(""" printf("\\n");\n""")
826 test.write(" }\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000827
828 for arg in t_args:
829 test.write(" }\n")
830
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000831 test.write(" function_tests++;\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000832 #
833 # end of conditional
834 #
835 while nb_cond > 0:
836 test.write("#endif\n")
837 nb_cond = nb_cond -1
Daniel Veillarda521d282004-11-09 14:59:59 +0000838 if define == 1:
839 test.write("#endif\n")
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000840
841 nb_tests = nb_tests + 1;
842
843 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000844 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000845}
846
847""")
848
849#
850# Generate all module callers
851#
852for module in modules:
853 # gather all the functions exported by that module
854 try:
855 functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
856 except:
857 print "Failed to gather functions from module %s" % (module)
858 continue;
859
860 # iterate over all functions in the module generating the test
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000861 i = 0
862 nb_tests_old = nb_tests
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000863 for function in functions:
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000864 i = i + 1
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000865 generate_test(module, function);
866
867 # header
868 test.write("""static int
869test_%s(void) {
Daniel Veillard42595322004-11-08 10:52:06 +0000870 int test_ret = 0;
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000871
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000872 if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000873""" % (module, module, nb_tests - nb_tests_old, i))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000874
875 # iterate over all functions in the module generating the call
876 for function in functions:
877 name = function.xpathEval('string(@name)')
878 if is_skipped_function(name):
879 continue
Daniel Veillard42595322004-11-08 10:52:06 +0000880 test.write(" test_ret += test_%s();\n" % (name))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000881
882 # footer
883 test.write("""
Daniel Veillard42595322004-11-08 10:52:06 +0000884 if (test_ret != 0)
885 printf("Module %s: %%d errors\\n", test_ret);
886 return(test_ret);
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000887}
888""" % (module))
889
Daniel Veillardce244ad2004-11-05 10:03:46 +0000890#
891# Generate direct module caller
892#
893test.write("""static int
894test_module(const char *module) {
895""");
896for module in modules:
897 test.write(""" if (!strcmp(module, "%s")) return(test_%s());\n""" % (
898 module, module))
899test.write(""" return(0);
900}
901""");
902
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000903print "Generated test for %d modules and %d functions" %(len(modules), nb_tests)
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000904
Daniel Veillard34099b42004-11-04 17:34:35 +0000905compare_and_save()
906
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000907missing_list = []
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000908for missing in missing_types.keys():
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000909 if missing == 'va_list' or missing == '...':
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000910 continue;
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000911
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000912 n = len(missing_types[missing])
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000913 missing_list.append((n, missing))
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000914
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000915def compare_missing(a, b):
916 return b[0] - a[0]
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000917
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000918missing_list.sort(compare_missing)
Daniel Veillard0ea9c9f2004-11-05 14:30:41 +0000919print "Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000920lst = open("missing.lst", "w")
Daniel Veillard34099b42004-11-04 17:34:35 +0000921lst.write("Missing support for %d types" % (len(missing_list)))
922lst.write("\n")
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000923for miss in missing_list:
924 lst.write("%s: %d :" % (miss[1], miss[0]))
925 i = 0
926 for n in missing_types[miss[1]]:
927 i = i + 1
928 if i > 5:
929 lst.write(" ...")
930 break
931 lst.write(" %s" % (n))
932 lst.write("\n")
Daniel Veillard34099b42004-11-04 17:34:35 +0000933lst.write("\n")
934lst.write("\n")
935lst.write("Missing support per module");
936for module in missing_functions.keys():
937 lst.write("module %s:\n %s\n" % (module, missing_functions[module]))
Daniel Veillard1ba06bb2004-11-04 12:32:18 +0000938
939lst.close()
Daniel Veillardb1b3a3e2004-11-03 23:25:47 +0000940
Daniel Veillard36e5cd52004-11-02 14:52:23 +0000941