xref: /aosp_15_r20/external/libxml2/tools/gentest.py (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*7c568831SAndroid Build Coastguard Worker#
3*7c568831SAndroid Build Coastguard Worker# generate a tester program for the API
4*7c568831SAndroid Build Coastguard Worker#
5*7c568831SAndroid Build Coastguard Workerimport sys
6*7c568831SAndroid Build Coastguard Workerimport os
7*7c568831SAndroid Build Coastguard Workerimport string
8*7c568831SAndroid Build Coastguard Workertry:
9*7c568831SAndroid Build Coastguard Worker    import libxml2
10*7c568831SAndroid Build Coastguard Workerexcept:
11*7c568831SAndroid Build Coastguard Worker    print("libxml2 python bindings not available, skipping testapi.c generation")
12*7c568831SAndroid Build Coastguard Worker    sys.exit(0)
13*7c568831SAndroid Build Coastguard Worker
14*7c568831SAndroid Build Coastguard Workerif len(sys.argv) > 1:
15*7c568831SAndroid Build Coastguard Worker    srcPref = sys.argv[1] + '/'
16*7c568831SAndroid Build Coastguard Workerelse:
17*7c568831SAndroid Build Coastguard Worker    srcPref = ''
18*7c568831SAndroid Build Coastguard Worker
19*7c568831SAndroid Build Coastguard Worker#
20*7c568831SAndroid Build Coastguard Worker# Modules we want to skip in API test
21*7c568831SAndroid Build Coastguard Worker#
22*7c568831SAndroid Build Coastguard Workerskipped_modules = [ "SAX", "xlink", "threads", "globals",
23*7c568831SAndroid Build Coastguard Worker  "xmlmemory", "xmlversion", "xmlexports", "xmlunicode", "nanoftp",
24*7c568831SAndroid Build Coastguard Worker]
25*7c568831SAndroid Build Coastguard Worker
26*7c568831SAndroid Build Coastguard Worker#
27*7c568831SAndroid Build Coastguard Worker# defines for each module
28*7c568831SAndroid Build Coastguard Worker#
29*7c568831SAndroid Build Coastguard Workermodules_defines = {
30*7c568831SAndroid Build Coastguard Worker    "HTMLparser": "LIBXML_HTML_ENABLED",
31*7c568831SAndroid Build Coastguard Worker    "catalog": "LIBXML_CATALOG_ENABLED",
32*7c568831SAndroid Build Coastguard Worker    "xmlreader": "LIBXML_READER_ENABLED",
33*7c568831SAndroid Build Coastguard Worker    "relaxng": "LIBXML_SCHEMAS_ENABLED",
34*7c568831SAndroid Build Coastguard Worker    "schemasInternals": "LIBXML_SCHEMAS_ENABLED",
35*7c568831SAndroid Build Coastguard Worker    "xmlschemas": "LIBXML_SCHEMAS_ENABLED",
36*7c568831SAndroid Build Coastguard Worker    "xmlschemastypes": "LIBXML_SCHEMAS_ENABLED",
37*7c568831SAndroid Build Coastguard Worker    "xpath": "LIBXML_XPATH_ENABLED",
38*7c568831SAndroid Build Coastguard Worker    "xpathInternals": "LIBXML_XPATH_ENABLED",
39*7c568831SAndroid Build Coastguard Worker    "xinclude": "LIBXML_XINCLUDE_ENABLED",
40*7c568831SAndroid Build Coastguard Worker    "xpointer": "LIBXML_XPTR_ENABLED",
41*7c568831SAndroid Build Coastguard Worker    "xmlregexp" : "LIBXML_REGEXP_ENABLED",
42*7c568831SAndroid Build Coastguard Worker    "xmlautomata" : "LIBXML_AUTOMATA_ENABLED",
43*7c568831SAndroid Build Coastguard Worker    "xmlsave" : "LIBXML_OUTPUT_ENABLED",
44*7c568831SAndroid Build Coastguard Worker    "xmlmodule" : "LIBXML_MODULES_ENABLED",
45*7c568831SAndroid Build Coastguard Worker    "pattern" : "LIBXML_PATTERN_ENABLED",
46*7c568831SAndroid Build Coastguard Worker    "schematron" : "LIBXML_SCHEMATRON_ENABLED",
47*7c568831SAndroid Build Coastguard Worker}
48*7c568831SAndroid Build Coastguard Worker
49*7c568831SAndroid Build Coastguard Worker#
50*7c568831SAndroid Build Coastguard Worker# defines for specific functions
51*7c568831SAndroid Build Coastguard Worker#
52*7c568831SAndroid Build Coastguard Workerfunction_defines = {
53*7c568831SAndroid Build Coastguard Worker    "htmlDefaultSAXHandlerInit": "LIBXML_HTML_ENABLED",
54*7c568831SAndroid Build Coastguard Worker    "xmlSAX2EndElement" : "LIBXML_SAX1_ENABLED",
55*7c568831SAndroid Build Coastguard Worker    "xmlSAX2StartElement" : "LIBXML_SAX1_ENABLED",
56*7c568831SAndroid Build Coastguard Worker    "xmlSAXDefaultVersion" : "LIBXML_SAX1_ENABLED",
57*7c568831SAndroid Build Coastguard Worker    "UTF8Toisolat1" : "LIBXML_OUTPUT_ENABLED",
58*7c568831SAndroid Build Coastguard Worker    "xmlIOParseDTD": "LIBXML_VALID_ENABLED",
59*7c568831SAndroid Build Coastguard Worker    "xmlParseDTD": "LIBXML_VALID_ENABLED",
60*7c568831SAndroid Build Coastguard Worker    "xmlParseDoc": "LIBXML_SAX1_ENABLED",
61*7c568831SAndroid Build Coastguard Worker    "xmlParseMemory": "LIBXML_SAX1_ENABLED",
62*7c568831SAndroid Build Coastguard Worker    "xmlRecoverDoc": "LIBXML_SAX1_ENABLED",
63*7c568831SAndroid Build Coastguard Worker    "xmlParseFile": "LIBXML_SAX1_ENABLED",
64*7c568831SAndroid Build Coastguard Worker    "xmlRecoverFile": "LIBXML_SAX1_ENABLED",
65*7c568831SAndroid Build Coastguard Worker    "xmlRecoverMemory": "LIBXML_SAX1_ENABLED",
66*7c568831SAndroid Build Coastguard Worker    "xmlSAXParseFileWithData": "LIBXML_SAX1_ENABLED",
67*7c568831SAndroid Build Coastguard Worker    "xmlSAXParseMemory": "LIBXML_SAX1_ENABLED",
68*7c568831SAndroid Build Coastguard Worker    "xmlSAXUserParseMemory": "LIBXML_SAX1_ENABLED",
69*7c568831SAndroid Build Coastguard Worker    "xmlSAXParseDoc": "LIBXML_SAX1_ENABLED",
70*7c568831SAndroid Build Coastguard Worker    "xmlSAXParseDTD": "LIBXML_SAX1_ENABLED",
71*7c568831SAndroid Build Coastguard Worker    "xmlSAXUserParseFile": "LIBXML_SAX1_ENABLED",
72*7c568831SAndroid Build Coastguard Worker    "xmlParseEntity": "LIBXML_SAX1_ENABLED",
73*7c568831SAndroid Build Coastguard Worker    "xmlParseExternalEntity": "LIBXML_SAX1_ENABLED",
74*7c568831SAndroid Build Coastguard Worker    "xmlSAXParseMemoryWithData": "LIBXML_SAX1_ENABLED",
75*7c568831SAndroid Build Coastguard Worker    "xmlParseBalancedChunkMemory": "LIBXML_SAX1_ENABLED",
76*7c568831SAndroid Build Coastguard Worker    "xmlParseBalancedChunkMemoryRecover": "LIBXML_SAX1_ENABLED",
77*7c568831SAndroid Build Coastguard Worker    "xmlSetupParserForBuffer": "LIBXML_SAX1_ENABLED",
78*7c568831SAndroid Build Coastguard Worker    "xmlStopParser": "LIBXML_PUSH_ENABLED",
79*7c568831SAndroid Build Coastguard Worker    "xmlAttrSerializeTxtContent": "LIBXML_OUTPUT_ENABLED",
80*7c568831SAndroid Build Coastguard Worker    "xmlSAXParseFile": "LIBXML_SAX1_ENABLED",
81*7c568831SAndroid Build Coastguard Worker    "xmlSAXParseEntity": "LIBXML_SAX1_ENABLED",
82*7c568831SAndroid Build Coastguard Worker    "xmlSprintfElementContent": "LIBXML_OUTPUT_ENABLED",
83*7c568831SAndroid Build Coastguard Worker    "xmlValidGetPotentialChildren" : "LIBXML_VALID_ENABLED",
84*7c568831SAndroid Build Coastguard Worker    "xmlValidGetValidElements" : "LIBXML_VALID_ENABLED",
85*7c568831SAndroid Build Coastguard Worker    "xmlTextReaderPreservePattern" : "LIBXML_PATTERN_ENABLED",
86*7c568831SAndroid Build Coastguard Worker}
87*7c568831SAndroid Build Coastguard Worker
88*7c568831SAndroid Build Coastguard Worker#
89*7c568831SAndroid Build Coastguard Worker# Some functions really need to be skipped for the tests.
90*7c568831SAndroid Build Coastguard Worker#
91*7c568831SAndroid Build Coastguard Workerskipped_functions = [
92*7c568831SAndroid Build Coastguard Worker# block on I/O
93*7c568831SAndroid Build Coastguard Worker"xmlFdRead", "xmlReadFd", "xmlCtxtReadFd",
94*7c568831SAndroid Build Coastguard Worker"htmlFdRead", "htmlReadFd", "htmlCtxtReadFd",
95*7c568831SAndroid Build Coastguard Worker"xmlReaderNewFd", "xmlReaderForFd",
96*7c568831SAndroid Build Coastguard Worker"xmlIORead", "xmlReadIO", "xmlCtxtReadIO",
97*7c568831SAndroid Build Coastguard Worker"htmlIORead", "htmlReadIO", "htmlCtxtReadIO",
98*7c568831SAndroid Build Coastguard Worker"xmlReaderNewIO", "xmlBufferDump",
99*7c568831SAndroid Build Coastguard Worker"xmlNanoHTTPMethod", "xmlNanoHTTPMethodRedir",
100*7c568831SAndroid Build Coastguard Worker# Complex I/O APIs
101*7c568831SAndroid Build Coastguard Worker"xmlCreateIOParserCtxt", "xmlParserInputBufferCreateIO",
102*7c568831SAndroid Build Coastguard Worker"xmlRegisterInputCallbacks", "xmlReaderForIO",
103*7c568831SAndroid Build Coastguard Worker"xmlOutputBufferCreateIO", "xmlRegisterOutputCallbacks",
104*7c568831SAndroid Build Coastguard Worker"xmlSaveToIO", "xmlIOHTTPOpenW",
105*7c568831SAndroid Build Coastguard Worker# library state cleanup, generate false leak information and other
106*7c568831SAndroid Build Coastguard Worker# troubles, heavillyb tested otherwise.
107*7c568831SAndroid Build Coastguard Worker"xmlCleanupParser", "xmlRelaxNGCleanupTypes", "xmlSetListDoc",
108*7c568831SAndroid Build Coastguard Worker"xmlSetTreeDoc", "xmlUnlinkNode",
109*7c568831SAndroid Build Coastguard Worker# hard to avoid leaks in the tests
110*7c568831SAndroid Build Coastguard Worker"xmlStrcat", "xmlStrncat", "xmlCatalogAddLocal", "xmlNewTextWriterDoc",
111*7c568831SAndroid Build Coastguard Worker"xmlXPathNewValueTree", "xmlXPathWrapString",
112*7c568831SAndroid Build Coastguard Worker# unimplemented
113*7c568831SAndroid Build Coastguard Worker"xmlTextReaderReadInnerXml", "xmlTextReaderReadOuterXml",
114*7c568831SAndroid Build Coastguard Worker"xmlTextReaderReadString",
115*7c568831SAndroid Build Coastguard Worker# destructor
116*7c568831SAndroid Build Coastguard Worker"xmlListDelete", "xmlOutputBufferClose", "xmlNanoHTTPClose",
117*7c568831SAndroid Build Coastguard Worker# deprecated
118*7c568831SAndroid Build Coastguard Worker"xmlCatalogGetPublic", "xmlCatalogGetSystem", "xmlEncodeEntities",
119*7c568831SAndroid Build Coastguard Worker"xmlNewGlobalNs", "xmlHandleEntity", "xmlNamespaceParseNCName",
120*7c568831SAndroid Build Coastguard Worker"xmlNamespaceParseNSDef", "xmlNamespaceParseQName",
121*7c568831SAndroid Build Coastguard Worker"xmlParseNamespace", "xmlParseQuotedString", "xmlParserHandleReference",
122*7c568831SAndroid Build Coastguard Worker"xmlScanName",
123*7c568831SAndroid Build Coastguard Worker"xmlDecodeEntities",
124*7c568831SAndroid Build Coastguard Worker# allocators
125*7c568831SAndroid Build Coastguard Worker"xmlMemFree",
126*7c568831SAndroid Build Coastguard Worker# verbosity
127*7c568831SAndroid Build Coastguard Worker"xmlCatalogSetDebug", "xmlShellPrintXPathError", "xmlShellPrintNode",
128*7c568831SAndroid Build Coastguard Worker# Internal functions, no user space should really call them
129*7c568831SAndroid Build Coastguard Worker"xmlParseAttribute", "xmlParseAttributeListDecl", "xmlParseName",
130*7c568831SAndroid Build Coastguard Worker"xmlParseNmtoken", "xmlParseEntityValue", "xmlParseAttValue",
131*7c568831SAndroid Build Coastguard Worker"xmlParseSystemLiteral", "xmlParsePubidLiteral", "xmlParseCharData",
132*7c568831SAndroid Build Coastguard Worker"xmlParseExternalID", "xmlParseComment", "xmlParsePITarget", "xmlParsePI",
133*7c568831SAndroid Build Coastguard Worker"xmlParseNotationDecl", "xmlParseEntityDecl", "xmlParseDefaultDecl",
134*7c568831SAndroid Build Coastguard Worker"xmlParseNotationType", "xmlParseEnumerationType", "xmlParseEnumeratedType",
135*7c568831SAndroid Build Coastguard Worker"xmlParseAttributeType", "xmlParseAttributeListDecl",
136*7c568831SAndroid Build Coastguard Worker"xmlParseElementMixedContentDecl", "xmlParseElementChildrenContentDecl",
137*7c568831SAndroid Build Coastguard Worker"xmlParseElementContentDecl", "xmlParseElementDecl", "xmlParseMarkupDecl",
138*7c568831SAndroid Build Coastguard Worker"xmlParseCharRef", "xmlParseEntityRef", "xmlParseReference",
139*7c568831SAndroid Build Coastguard Worker"xmlParsePEReference", "xmlParseDocTypeDecl", "xmlParseAttribute",
140*7c568831SAndroid Build Coastguard Worker"xmlParseStartTag", "xmlParseEndTag", "xmlParseCDSect", "xmlParseContent",
141*7c568831SAndroid Build Coastguard Worker"xmlParseElement", "xmlParseVersionNum", "xmlParseVersionInfo",
142*7c568831SAndroid Build Coastguard Worker"xmlParseEncName", "xmlParseEncodingDecl", "xmlParseSDDecl",
143*7c568831SAndroid Build Coastguard Worker"xmlParseXMLDecl", "xmlParseTextDecl", "xmlParseMisc",
144*7c568831SAndroid Build Coastguard Worker"xmlParseExternalSubset", "xmlParserHandlePEReference",
145*7c568831SAndroid Build Coastguard Worker"xmlSkipBlankChars",
146*7c568831SAndroid Build Coastguard Worker# Legacy
147*7c568831SAndroid Build Coastguard Worker"xmlCleanupPredefinedEntities", "xmlInitializePredefinedEntities",
148*7c568831SAndroid Build Coastguard Worker"xmlSetFeature", "xmlGetFeature", "xmlGetFeaturesList",
149*7c568831SAndroid Build Coastguard Worker# Shouldn't free result
150*7c568831SAndroid Build Coastguard Worker"xmlCtxtGetDict",
151*7c568831SAndroid Build Coastguard Worker]
152*7c568831SAndroid Build Coastguard Worker
153*7c568831SAndroid Build Coastguard Worker#
154*7c568831SAndroid Build Coastguard Worker# These functions have side effects on the global state
155*7c568831SAndroid Build Coastguard Worker# and hence generate errors on memory allocation tests
156*7c568831SAndroid Build Coastguard Worker#
157*7c568831SAndroid Build Coastguard Workerskipped_memcheck = [ "xmlLoadCatalog", "xmlAddEncodingAlias",
158*7c568831SAndroid Build Coastguard Worker   "xmlSchemaInitTypes",
159*7c568831SAndroid Build Coastguard Worker   "xmlNanoHTTPScanProxy", "xmlResetLastError", "xmlCatalogConvert",
160*7c568831SAndroid Build Coastguard Worker   "xmlCatalogRemove", "xmlLoadCatalogs", "xmlCleanupCharEncodingHandlers",
161*7c568831SAndroid Build Coastguard Worker   "xmlInitCharEncodingHandlers", "xmlCatalogCleanup",
162*7c568831SAndroid Build Coastguard Worker   "xmlSchemaGetBuiltInType",
163*7c568831SAndroid Build Coastguard Worker   "htmlParseFile", "htmlCtxtReadFile", # loads the catalogs
164*7c568831SAndroid Build Coastguard Worker   "xmlTextReaderSchemaValidate", "xmlSchemaCleanupTypes", # initialize the schemas type system
165*7c568831SAndroid Build Coastguard Worker   "xmlCatalogResolve", "xmlIOParseDTD" # loads the catalogs
166*7c568831SAndroid Build Coastguard Worker]
167*7c568831SAndroid Build Coastguard Worker
168*7c568831SAndroid Build Coastguard Worker#
169*7c568831SAndroid Build Coastguard Worker# Extra code needed for some test cases
170*7c568831SAndroid Build Coastguard Worker#
171*7c568831SAndroid Build Coastguard Workerextra_pre_call = {
172*7c568831SAndroid Build Coastguard Worker   "xmlSAXUserParseFile": """
173*7c568831SAndroid Build Coastguard Worker#ifdef LIBXML_SAX1_ENABLED
174*7c568831SAndroid Build Coastguard Worker        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
175*7c568831SAndroid Build Coastguard Worker#endif
176*7c568831SAndroid Build Coastguard Worker""",
177*7c568831SAndroid Build Coastguard Worker   "xmlSAXUserParseMemory": """
178*7c568831SAndroid Build Coastguard Worker#ifdef LIBXML_SAX1_ENABLED
179*7c568831SAndroid Build Coastguard Worker        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
180*7c568831SAndroid Build Coastguard Worker#endif
181*7c568831SAndroid Build Coastguard Worker""",
182*7c568831SAndroid Build Coastguard Worker   "xmlParseBalancedChunkMemory": """
183*7c568831SAndroid Build Coastguard Worker#ifdef LIBXML_SAX1_ENABLED
184*7c568831SAndroid Build Coastguard Worker        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
185*7c568831SAndroid Build Coastguard Worker#endif
186*7c568831SAndroid Build Coastguard Worker""",
187*7c568831SAndroid Build Coastguard Worker   "xmlParseBalancedChunkMemoryRecover": """
188*7c568831SAndroid Build Coastguard Worker#ifdef LIBXML_SAX1_ENABLED
189*7c568831SAndroid Build Coastguard Worker        if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
190*7c568831SAndroid Build Coastguard Worker#endif
191*7c568831SAndroid Build Coastguard Worker""",
192*7c568831SAndroid Build Coastguard Worker   "xmlParserInputBufferCreateFd":
193*7c568831SAndroid Build Coastguard Worker       "if (fd >= 0) fd = -1;",
194*7c568831SAndroid Build Coastguard Worker   "xmlSAXDefaultVersion": """
195*7c568831SAndroid Build Coastguard Worker        {
196*7c568831SAndroid Build Coastguard Worker            int original_version = xmlSAXDefaultVersion(2);
197*7c568831SAndroid Build Coastguard Worker""",
198*7c568831SAndroid Build Coastguard Worker}
199*7c568831SAndroid Build Coastguard Workerextra_post_call = {
200*7c568831SAndroid Build Coastguard Worker   "xmlAddChild":
201*7c568831SAndroid Build Coastguard Worker       "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
202*7c568831SAndroid Build Coastguard Worker   "xmlAddChildList":
203*7c568831SAndroid Build Coastguard Worker       "if (ret_val == NULL) { xmlFreeNodeList(cur) ; cur = NULL ; }",
204*7c568831SAndroid Build Coastguard Worker   "xmlAddSibling":
205*7c568831SAndroid Build Coastguard Worker       "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
206*7c568831SAndroid Build Coastguard Worker   "xmlAddNextSibling":
207*7c568831SAndroid Build Coastguard Worker       "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
208*7c568831SAndroid Build Coastguard Worker   "xmlAddPrevSibling":
209*7c568831SAndroid Build Coastguard Worker       "if (ret_val == NULL) { xmlFreeNode(cur) ; cur = NULL ; }",
210*7c568831SAndroid Build Coastguard Worker   "xmlDocSetRootElement":
211*7c568831SAndroid Build Coastguard Worker       "if (doc == NULL) { xmlFreeNode(root) ; root = NULL ; }",
212*7c568831SAndroid Build Coastguard Worker   "xmlReplaceNode":
213*7c568831SAndroid Build Coastguard Worker       """if (cur != NULL) {
214*7c568831SAndroid Build Coastguard Worker              xmlUnlinkNode(cur);
215*7c568831SAndroid Build Coastguard Worker              xmlFreeNode(cur) ; cur = NULL ; }
216*7c568831SAndroid Build Coastguard Worker          if (old != NULL) {
217*7c568831SAndroid Build Coastguard Worker              xmlUnlinkNode(old);
218*7c568831SAndroid Build Coastguard Worker              xmlFreeNode(old) ; old = NULL ; }
219*7c568831SAndroid Build Coastguard Worker\t  ret_val = NULL;""",
220*7c568831SAndroid Build Coastguard Worker   "xmlTextMerge":
221*7c568831SAndroid Build Coastguard Worker       """if (ret_val == NULL) {
222*7c568831SAndroid Build Coastguard Worker              xmlUnlinkNode(second);
223*7c568831SAndroid Build Coastguard Worker              xmlFreeNode(second) ; second = NULL ;
224*7c568831SAndroid Build Coastguard Worker              ret_val = first; }""",
225*7c568831SAndroid Build Coastguard Worker   "xmlBuildQName":
226*7c568831SAndroid Build Coastguard Worker       """if ((ret_val != NULL) && (ret_val != ncname) &&
227*7c568831SAndroid Build Coastguard Worker              (ret_val != prefix) && (ret_val != memory))
228*7c568831SAndroid Build Coastguard Worker              xmlFree(ret_val);
229*7c568831SAndroid Build Coastguard Worker\t  ret_val = NULL;""",
230*7c568831SAndroid Build Coastguard Worker   "xmlNewDocElementContent":
231*7c568831SAndroid Build Coastguard Worker       """xmlFreeDocElementContent(doc, ret_val); ret_val = NULL;""",
232*7c568831SAndroid Build Coastguard Worker   "xmlDictReference": "xmlDictFree(dict);",
233*7c568831SAndroid Build Coastguard Worker   # Functions which deallocates one of their parameters
234*7c568831SAndroid Build Coastguard Worker   "xmlXPathConvertBoolean": """val = NULL;""",
235*7c568831SAndroid Build Coastguard Worker   "xmlXPathConvertNumber": """val = NULL;""",
236*7c568831SAndroid Build Coastguard Worker   "xmlXPathConvertString": """val = NULL;""",
237*7c568831SAndroid Build Coastguard Worker   "xmlSaveFileTo": """buf = NULL;""",
238*7c568831SAndroid Build Coastguard Worker   "xmlSaveFormatFileTo": """buf = NULL;""",
239*7c568831SAndroid Build Coastguard Worker   "xmlIOParseDTD": "input = NULL;",
240*7c568831SAndroid Build Coastguard Worker   "xmlRemoveProp": "cur = NULL;",
241*7c568831SAndroid Build Coastguard Worker   "xmlNewNs": "if ((node == NULL) && (ret_val != NULL)) xmlFreeNs(ret_val);",
242*7c568831SAndroid Build Coastguard Worker   "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
243*7c568831SAndroid Build Coastguard Worker   "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
244*7c568831SAndroid Build Coastguard Worker   "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
245*7c568831SAndroid Build Coastguard Worker   "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
246*7c568831SAndroid Build Coastguard Worker   "xmlNewIOInputStream": "if (ret_val != NULL) buf = NULL;",
247*7c568831SAndroid Build Coastguard Worker   "htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
248*7c568831SAndroid Build Coastguard Worker   "htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
249*7c568831SAndroid Build Coastguard Worker   "xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
250*7c568831SAndroid Build Coastguard Worker   "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
251*7c568831SAndroid Build Coastguard Worker   "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
252*7c568831SAndroid Build Coastguard Worker   "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
253*7c568831SAndroid Build Coastguard Worker   "xmlSAXDefaultVersion": """
254*7c568831SAndroid Build Coastguard Worker            (void)xmlSAXDefaultVersion(original_version);
255*7c568831SAndroid Build Coastguard Worker        }
256*7c568831SAndroid Build Coastguard Worker""",
257*7c568831SAndroid Build Coastguard Worker}
258*7c568831SAndroid Build Coastguard Worker
259*7c568831SAndroid Build Coastguard Workermodules = []
260*7c568831SAndroid Build Coastguard Worker
261*7c568831SAndroid Build Coastguard Workerdef is_skipped_module(name):
262*7c568831SAndroid Build Coastguard Worker    for mod in skipped_modules:
263*7c568831SAndroid Build Coastguard Worker        if mod == name:
264*7c568831SAndroid Build Coastguard Worker            return 1
265*7c568831SAndroid Build Coastguard Worker    return 0
266*7c568831SAndroid Build Coastguard Worker
267*7c568831SAndroid Build Coastguard Workerdef is_skipped_function(name):
268*7c568831SAndroid Build Coastguard Worker    for fun in skipped_functions:
269*7c568831SAndroid Build Coastguard Worker        if fun == name:
270*7c568831SAndroid Build Coastguard Worker            return 1
271*7c568831SAndroid Build Coastguard Worker    # Do not test destructors
272*7c568831SAndroid Build Coastguard Worker    if name.find('Free') != -1:
273*7c568831SAndroid Build Coastguard Worker        return 1
274*7c568831SAndroid Build Coastguard Worker    return 0
275*7c568831SAndroid Build Coastguard Worker
276*7c568831SAndroid Build Coastguard Workerdef is_skipped_memcheck(name):
277*7c568831SAndroid Build Coastguard Worker    for fun in skipped_memcheck:
278*7c568831SAndroid Build Coastguard Worker        if fun == name:
279*7c568831SAndroid Build Coastguard Worker            return 1
280*7c568831SAndroid Build Coastguard Worker    return 0
281*7c568831SAndroid Build Coastguard Worker
282*7c568831SAndroid Build Coastguard Workermissing_types = {}
283*7c568831SAndroid Build Coastguard Workerdef add_missing_type(name, func):
284*7c568831SAndroid Build Coastguard Worker    try:
285*7c568831SAndroid Build Coastguard Worker        list = missing_types[name]
286*7c568831SAndroid Build Coastguard Worker        list.append(func)
287*7c568831SAndroid Build Coastguard Worker    except:
288*7c568831SAndroid Build Coastguard Worker        missing_types[name] = [func]
289*7c568831SAndroid Build Coastguard Worker
290*7c568831SAndroid Build Coastguard Workergenerated_param_types = []
291*7c568831SAndroid Build Coastguard Workerdef add_generated_param_type(name):
292*7c568831SAndroid Build Coastguard Worker    generated_param_types.append(name)
293*7c568831SAndroid Build Coastguard Worker
294*7c568831SAndroid Build Coastguard Workergenerated_return_types = []
295*7c568831SAndroid Build Coastguard Workerdef add_generated_return_type(name):
296*7c568831SAndroid Build Coastguard Worker    generated_return_types.append(name)
297*7c568831SAndroid Build Coastguard Worker
298*7c568831SAndroid Build Coastguard Workermissing_functions = {}
299*7c568831SAndroid Build Coastguard Workermissing_functions_nr = 0
300*7c568831SAndroid Build Coastguard Workerdef add_missing_functions(name, module):
301*7c568831SAndroid Build Coastguard Worker    global missing_functions_nr
302*7c568831SAndroid Build Coastguard Worker
303*7c568831SAndroid Build Coastguard Worker    missing_functions_nr = missing_functions_nr + 1
304*7c568831SAndroid Build Coastguard Worker    try:
305*7c568831SAndroid Build Coastguard Worker        list = missing_functions[module]
306*7c568831SAndroid Build Coastguard Worker        list.append(name)
307*7c568831SAndroid Build Coastguard Worker    except:
308*7c568831SAndroid Build Coastguard Worker        missing_functions[module] = [name]
309*7c568831SAndroid Build Coastguard Worker
310*7c568831SAndroid Build Coastguard Worker#
311*7c568831SAndroid Build Coastguard Worker# Provide the type generators and destructors for the parameters
312*7c568831SAndroid Build Coastguard Worker#
313*7c568831SAndroid Build Coastguard Worker
314*7c568831SAndroid Build Coastguard Workerdef type_convert(str, name, info, module, function, pos):
315*7c568831SAndroid Build Coastguard Worker#    res = str.replace("    ", " ")
316*7c568831SAndroid Build Coastguard Worker#    res = str.replace("   ", " ")
317*7c568831SAndroid Build Coastguard Worker#    res = str.replace("  ", " ")
318*7c568831SAndroid Build Coastguard Worker    res = str.replace(" *", "_ptr")
319*7c568831SAndroid Build Coastguard Worker#    res = str.replace("*", "_ptr")
320*7c568831SAndroid Build Coastguard Worker    res = res.replace(" ", "_")
321*7c568831SAndroid Build Coastguard Worker    if res == 'const_char_ptr':
322*7c568831SAndroid Build Coastguard Worker        if name.find("file") != -1 or \
323*7c568831SAndroid Build Coastguard Worker           name.find("uri") != -1 or \
324*7c568831SAndroid Build Coastguard Worker           name.find("URI") != -1 or \
325*7c568831SAndroid Build Coastguard Worker           info.find("filename") != -1 or \
326*7c568831SAndroid Build Coastguard Worker           info.find("URI") != -1 or \
327*7c568831SAndroid Build Coastguard Worker           info.find("URL") != -1:
328*7c568831SAndroid Build Coastguard Worker            if function.find("Save") != -1 or \
329*7c568831SAndroid Build Coastguard Worker               function.find("Create") != -1 or \
330*7c568831SAndroid Build Coastguard Worker               function.find("Write") != -1 or \
331*7c568831SAndroid Build Coastguard Worker               function.find("Fetch") != -1:
332*7c568831SAndroid Build Coastguard Worker                return('fileoutput')
333*7c568831SAndroid Build Coastguard Worker            return('filepath')
334*7c568831SAndroid Build Coastguard Worker    if res == 'void_ptr':
335*7c568831SAndroid Build Coastguard Worker        if module == 'nanohttp' and name == 'ctx':
336*7c568831SAndroid Build Coastguard Worker            return('xmlNanoHTTPCtxtPtr')
337*7c568831SAndroid Build Coastguard Worker        if function == 'xmlNanoHTTPMethod' or \
338*7c568831SAndroid Build Coastguard Worker           function == 'xmlNanoHTTPMethodRedir' or \
339*7c568831SAndroid Build Coastguard Worker           function == 'xmlNanoHTTPOpen' or \
340*7c568831SAndroid Build Coastguard Worker           function == 'xmlNanoHTTPOpenRedir':
341*7c568831SAndroid Build Coastguard Worker            return('xmlNanoHTTPCtxtPtr');
342*7c568831SAndroid Build Coastguard Worker        if function == 'xmlIOHTTPOpen':
343*7c568831SAndroid Build Coastguard Worker            return('xmlNanoHTTPCtxtPtr')
344*7c568831SAndroid Build Coastguard Worker        if name.find("data") != -1:
345*7c568831SAndroid Build Coastguard Worker            return('userdata')
346*7c568831SAndroid Build Coastguard Worker        if name.find("user") != -1:
347*7c568831SAndroid Build Coastguard Worker            return('userdata')
348*7c568831SAndroid Build Coastguard Worker    if res == 'xmlDoc_ptr':
349*7c568831SAndroid Build Coastguard Worker        res = 'xmlDocPtr'
350*7c568831SAndroid Build Coastguard Worker    if res == 'xmlNode_ptr':
351*7c568831SAndroid Build Coastguard Worker        res = 'xmlNodePtr'
352*7c568831SAndroid Build Coastguard Worker    if res == 'xmlDict_ptr':
353*7c568831SAndroid Build Coastguard Worker        res = 'xmlDictPtr'
354*7c568831SAndroid Build Coastguard Worker    if res == 'xmlNodePtr' and pos != 0:
355*7c568831SAndroid Build Coastguard Worker        if (function == 'xmlAddChild' and pos == 2) or \
356*7c568831SAndroid Build Coastguard Worker           (function == 'xmlAddChildList' and pos == 2) or \
357*7c568831SAndroid Build Coastguard Worker           (function == 'xmlAddNextSibling' and pos == 2) or \
358*7c568831SAndroid Build Coastguard Worker           (function == 'xmlAddSibling' and pos == 2) or \
359*7c568831SAndroid Build Coastguard Worker           (function == 'xmlDocSetRootElement' and pos == 2) or \
360*7c568831SAndroid Build Coastguard Worker           (function == 'xmlReplaceNode' and pos == 2) or \
361*7c568831SAndroid Build Coastguard Worker           (function == 'xmlTextMerge') or \
362*7c568831SAndroid Build Coastguard Worker           (function == 'xmlAddPrevSibling' and pos == 2):
363*7c568831SAndroid Build Coastguard Worker            return('xmlNodePtr_in');
364*7c568831SAndroid Build Coastguard Worker    if res == 'const xmlBufferPtr':
365*7c568831SAndroid Build Coastguard Worker        res = 'xmlBufferPtr'
366*7c568831SAndroid Build Coastguard Worker    if res == 'xmlChar_ptr' and name == 'name' and \
367*7c568831SAndroid Build Coastguard Worker       function.find("EatName") != -1:
368*7c568831SAndroid Build Coastguard Worker        return('eaten_name')
369*7c568831SAndroid Build Coastguard Worker    if res == 'void_ptr*':
370*7c568831SAndroid Build Coastguard Worker        res = 'void_ptr_ptr'
371*7c568831SAndroid Build Coastguard Worker    if res == 'char_ptr*':
372*7c568831SAndroid Build Coastguard Worker        res = 'char_ptr_ptr'
373*7c568831SAndroid Build Coastguard Worker    if res == 'xmlChar_ptr*':
374*7c568831SAndroid Build Coastguard Worker        res = 'xmlChar_ptr_ptr'
375*7c568831SAndroid Build Coastguard Worker    if res == 'const_xmlChar_ptr*':
376*7c568831SAndroid Build Coastguard Worker        res = 'const_xmlChar_ptr_ptr'
377*7c568831SAndroid Build Coastguard Worker    if res == 'const_char_ptr*':
378*7c568831SAndroid Build Coastguard Worker        res = 'const_char_ptr_ptr'
379*7c568831SAndroid Build Coastguard Worker    if res == 'FILE_ptr' and module == 'debugXML':
380*7c568831SAndroid Build Coastguard Worker        res = 'debug_FILE_ptr';
381*7c568831SAndroid Build Coastguard Worker    if res == 'int' and name == 'options':
382*7c568831SAndroid Build Coastguard Worker        if module == 'parser' or module == 'xmlreader':
383*7c568831SAndroid Build Coastguard Worker            res = 'parseroptions'
384*7c568831SAndroid Build Coastguard Worker
385*7c568831SAndroid Build Coastguard Worker    return res
386*7c568831SAndroid Build Coastguard Worker
387*7c568831SAndroid Build Coastguard Workerknown_param_types = []
388*7c568831SAndroid Build Coastguard Worker
389*7c568831SAndroid Build Coastguard Workerdef is_known_param_type(name):
390*7c568831SAndroid Build Coastguard Worker    for type in known_param_types:
391*7c568831SAndroid Build Coastguard Worker        if type == name:
392*7c568831SAndroid Build Coastguard Worker            return 1
393*7c568831SAndroid Build Coastguard Worker    return name[-3:] == 'Ptr' or name[-4:] == '_ptr'
394*7c568831SAndroid Build Coastguard Worker
395*7c568831SAndroid Build Coastguard Workerdef generate_param_type(name, rtype):
396*7c568831SAndroid Build Coastguard Worker    global test
397*7c568831SAndroid Build Coastguard Worker    for type in known_param_types:
398*7c568831SAndroid Build Coastguard Worker        if type == name:
399*7c568831SAndroid Build Coastguard Worker            return
400*7c568831SAndroid Build Coastguard Worker    for type in generated_param_types:
401*7c568831SAndroid Build Coastguard Worker        if type == name:
402*7c568831SAndroid Build Coastguard Worker            return
403*7c568831SAndroid Build Coastguard Worker
404*7c568831SAndroid Build Coastguard Worker    if name[-3:] == 'Ptr' or name[-4:] == '_ptr':
405*7c568831SAndroid Build Coastguard Worker        define = 0
406*7c568831SAndroid Build Coastguard Worker        if module in modules_defines:
407*7c568831SAndroid Build Coastguard Worker            test.write("#ifdef %s\n" % (modules_defines[module]))
408*7c568831SAndroid Build Coastguard Worker            define = 1
409*7c568831SAndroid Build Coastguard Worker        test.write("""
410*7c568831SAndroid Build Coastguard Worker#define gen_nb_%s 1
411*7c568831SAndroid Build Coastguard Worker#define gen_%s(no, nr) NULL
412*7c568831SAndroid Build Coastguard Worker#define des_%s(no, val, nr)
413*7c568831SAndroid Build Coastguard Worker""" % (name, name, name))
414*7c568831SAndroid Build Coastguard Worker        if define == 1:
415*7c568831SAndroid Build Coastguard Worker            test.write("#endif\n\n")
416*7c568831SAndroid Build Coastguard Worker        add_generated_param_type(name)
417*7c568831SAndroid Build Coastguard Worker
418*7c568831SAndroid Build Coastguard Worker#
419*7c568831SAndroid Build Coastguard Worker# Provide the type destructors for the return values
420*7c568831SAndroid Build Coastguard Worker#
421*7c568831SAndroid Build Coastguard Worker
422*7c568831SAndroid Build Coastguard Workerknown_return_types = []
423*7c568831SAndroid Build Coastguard Worker
424*7c568831SAndroid Build Coastguard Workerdef is_known_return_type(name):
425*7c568831SAndroid Build Coastguard Worker    for type in known_return_types:
426*7c568831SAndroid Build Coastguard Worker        if type == name:
427*7c568831SAndroid Build Coastguard Worker            return 1
428*7c568831SAndroid Build Coastguard Worker    return 0
429*7c568831SAndroid Build Coastguard Worker
430*7c568831SAndroid Build Coastguard Worker#
431*7c568831SAndroid Build Coastguard Worker# Copy the beginning of the C test program result
432*7c568831SAndroid Build Coastguard Worker#
433*7c568831SAndroid Build Coastguard Worker
434*7c568831SAndroid Build Coastguard Workertry:
435*7c568831SAndroid Build Coastguard Worker    input = open("testapi.c", "r")
436*7c568831SAndroid Build Coastguard Workerexcept:
437*7c568831SAndroid Build Coastguard Worker    input = open(srcPref + "testapi.c", "r")
438*7c568831SAndroid Build Coastguard Workertest = open('testapi.c.new', 'w')
439*7c568831SAndroid Build Coastguard Worker
440*7c568831SAndroid Build Coastguard Workerdef compare_and_save():
441*7c568831SAndroid Build Coastguard Worker    global test
442*7c568831SAndroid Build Coastguard Worker
443*7c568831SAndroid Build Coastguard Worker    test.close()
444*7c568831SAndroid Build Coastguard Worker    try:
445*7c568831SAndroid Build Coastguard Worker        input = open("testapi.c", "r").read()
446*7c568831SAndroid Build Coastguard Worker    except:
447*7c568831SAndroid Build Coastguard Worker        input = ''
448*7c568831SAndroid Build Coastguard Worker    test = open('testapi.c.new', "r").read()
449*7c568831SAndroid Build Coastguard Worker    if input != test:
450*7c568831SAndroid Build Coastguard Worker        try:
451*7c568831SAndroid Build Coastguard Worker            os.system("rm testapi.c; mv testapi.c.new testapi.c")
452*7c568831SAndroid Build Coastguard Worker        except:
453*7c568831SAndroid Build Coastguard Worker            os.system("mv testapi.c.new testapi.c")
454*7c568831SAndroid Build Coastguard Worker        print("Updated testapi.c")
455*7c568831SAndroid Build Coastguard Worker    else:
456*7c568831SAndroid Build Coastguard Worker        print("Generated testapi.c is identical")
457*7c568831SAndroid Build Coastguard Worker
458*7c568831SAndroid Build Coastguard Workerline = input.readline()
459*7c568831SAndroid Build Coastguard Workerwhile line != "":
460*7c568831SAndroid Build Coastguard Worker    if line == "/* CUT HERE: everything below that line is generated */\n":
461*7c568831SAndroid Build Coastguard Worker        break;
462*7c568831SAndroid Build Coastguard Worker    if line[0:15] == "#define gen_nb_":
463*7c568831SAndroid Build Coastguard Worker        type = line[15:].split()[0]
464*7c568831SAndroid Build Coastguard Worker        known_param_types.append(type)
465*7c568831SAndroid Build Coastguard Worker    if line[0:19] == "static void desret_":
466*7c568831SAndroid Build Coastguard Worker        type = line[19:].split('(')[0]
467*7c568831SAndroid Build Coastguard Worker        known_return_types.append(type)
468*7c568831SAndroid Build Coastguard Worker    test.write(line)
469*7c568831SAndroid Build Coastguard Worker    line = input.readline()
470*7c568831SAndroid Build Coastguard Workerinput.close()
471*7c568831SAndroid Build Coastguard Worker
472*7c568831SAndroid Build Coastguard Workerif line == "":
473*7c568831SAndroid Build Coastguard Worker    print("Could not find the CUT marker in testapi.c skipping generation")
474*7c568831SAndroid Build Coastguard Worker    test.close()
475*7c568831SAndroid Build Coastguard Worker    sys.exit(0)
476*7c568831SAndroid Build Coastguard Worker
477*7c568831SAndroid Build Coastguard Workerprint("Scanned testapi.c: found %d parameters types and %d return types\n" % (
478*7c568831SAndroid Build Coastguard Worker      len(known_param_types), len(known_return_types)))
479*7c568831SAndroid Build Coastguard Workertest.write("/* CUT HERE: everything below that line is generated */\n")
480*7c568831SAndroid Build Coastguard Worker
481*7c568831SAndroid Build Coastguard Worker
482*7c568831SAndroid Build Coastguard Worker#
483*7c568831SAndroid Build Coastguard Worker# Open the input API description
484*7c568831SAndroid Build Coastguard Worker#
485*7c568831SAndroid Build Coastguard Workerdoc = libxml2.readFile(srcPref + 'doc/libxml2-api.xml', None, 0)
486*7c568831SAndroid Build Coastguard Workerif doc == None:
487*7c568831SAndroid Build Coastguard Worker    print("Failed to load doc/libxml2-api.xml")
488*7c568831SAndroid Build Coastguard Worker    sys.exit(1)
489*7c568831SAndroid Build Coastguard Workerctxt = doc.xpathNewContext()
490*7c568831SAndroid Build Coastguard Worker
491*7c568831SAndroid Build Coastguard Worker#
492*7c568831SAndroid Build Coastguard Worker# Generate a list of all function parameters and select only
493*7c568831SAndroid Build Coastguard Worker# those used in the api tests
494*7c568831SAndroid Build Coastguard Worker#
495*7c568831SAndroid Build Coastguard Workerargtypes = {}
496*7c568831SAndroid Build Coastguard Workerargs = ctxt.xpathEval("/api/symbols/function/arg")
497*7c568831SAndroid Build Coastguard Workerfor arg in args:
498*7c568831SAndroid Build Coastguard Worker    mod = arg.xpathEval('string(../@file)')
499*7c568831SAndroid Build Coastguard Worker    func = arg.xpathEval('string(../@name)')
500*7c568831SAndroid Build Coastguard Worker    if (mod not in skipped_modules) and (func not in skipped_functions):
501*7c568831SAndroid Build Coastguard Worker        type = arg.xpathEval('string(@type)')
502*7c568831SAndroid Build Coastguard Worker        if type not in argtypes:
503*7c568831SAndroid Build Coastguard Worker            argtypes[type] = func
504*7c568831SAndroid Build Coastguard Worker
505*7c568831SAndroid Build Coastguard Worker# similarly for return types
506*7c568831SAndroid Build Coastguard Workerrettypes = {}
507*7c568831SAndroid Build Coastguard Workerrets = ctxt.xpathEval("/api/symbols/function/return")
508*7c568831SAndroid Build Coastguard Workerfor ret in rets:
509*7c568831SAndroid Build Coastguard Worker    mod = ret.xpathEval('string(../@file)')
510*7c568831SAndroid Build Coastguard Worker    func = ret.xpathEval('string(../@name)')
511*7c568831SAndroid Build Coastguard Worker    if (mod not in skipped_modules) and (func not in skipped_functions):
512*7c568831SAndroid Build Coastguard Worker        type = ret.xpathEval('string(@type)')
513*7c568831SAndroid Build Coastguard Worker        if type not in rettypes:
514*7c568831SAndroid Build Coastguard Worker            rettypes[type] = func
515*7c568831SAndroid Build Coastguard Worker
516*7c568831SAndroid Build Coastguard Worker#
517*7c568831SAndroid Build Coastguard Worker# Generate constructors and return type handling for all enums
518*7c568831SAndroid Build Coastguard Worker# which are used as function parameters
519*7c568831SAndroid Build Coastguard Worker#
520*7c568831SAndroid Build Coastguard Workerenums = ctxt.xpathEval("/api/symbols/typedef[@type='enum']")
521*7c568831SAndroid Build Coastguard Workerfor enum in enums:
522*7c568831SAndroid Build Coastguard Worker    module = enum.xpathEval('string(@file)')
523*7c568831SAndroid Build Coastguard Worker    name = enum.xpathEval('string(@name)')
524*7c568831SAndroid Build Coastguard Worker    #
525*7c568831SAndroid Build Coastguard Worker    # Skip any enums which are not in our filtered lists
526*7c568831SAndroid Build Coastguard Worker    #
527*7c568831SAndroid Build Coastguard Worker    if (name == None) or ((name not in argtypes) and (name not in rettypes)):
528*7c568831SAndroid Build Coastguard Worker        continue;
529*7c568831SAndroid Build Coastguard Worker    define = 0
530*7c568831SAndroid Build Coastguard Worker
531*7c568831SAndroid Build Coastguard Worker    if (name in argtypes) and is_known_param_type(name) == 0:
532*7c568831SAndroid Build Coastguard Worker        values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
533*7c568831SAndroid Build Coastguard Worker        i = 0
534*7c568831SAndroid Build Coastguard Worker        vals = []
535*7c568831SAndroid Build Coastguard Worker        for value in values:
536*7c568831SAndroid Build Coastguard Worker            vname = value.xpathEval('string(@name)')
537*7c568831SAndroid Build Coastguard Worker            if vname == None:
538*7c568831SAndroid Build Coastguard Worker                continue;
539*7c568831SAndroid Build Coastguard Worker            i = i + 1
540*7c568831SAndroid Build Coastguard Worker            if i >= 5:
541*7c568831SAndroid Build Coastguard Worker                break;
542*7c568831SAndroid Build Coastguard Worker            vals.append(vname)
543*7c568831SAndroid Build Coastguard Worker        if vals == []:
544*7c568831SAndroid Build Coastguard Worker            print("Didn't find any value for enum %s" % (name))
545*7c568831SAndroid Build Coastguard Worker            continue
546*7c568831SAndroid Build Coastguard Worker        if module in modules_defines:
547*7c568831SAndroid Build Coastguard Worker            test.write("#ifdef %s\n" % (modules_defines[module]))
548*7c568831SAndroid Build Coastguard Worker            define = 1
549*7c568831SAndroid Build Coastguard Worker        test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
550*7c568831SAndroid Build Coastguard Worker        test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
551*7c568831SAndroid Build Coastguard Worker                   (name, name))
552*7c568831SAndroid Build Coastguard Worker        i = 1
553*7c568831SAndroid Build Coastguard Worker        for value in vals:
554*7c568831SAndroid Build Coastguard Worker            test.write("    if (no == %d) return(%s);\n" % (i, value))
555*7c568831SAndroid Build Coastguard Worker            i = i + 1
556*7c568831SAndroid Build Coastguard Worker        test.write("""    return(0);
557*7c568831SAndroid Build Coastguard Worker}
558*7c568831SAndroid Build Coastguard Worker
559*7c568831SAndroid Build Coastguard Workerstatic void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
560*7c568831SAndroid Build Coastguard Worker}
561*7c568831SAndroid Build Coastguard Worker
562*7c568831SAndroid Build Coastguard Worker""" % (name, name));
563*7c568831SAndroid Build Coastguard Worker        known_param_types.append(name)
564*7c568831SAndroid Build Coastguard Worker
565*7c568831SAndroid Build Coastguard Worker    if (is_known_return_type(name) == 0) and (name in rettypes):
566*7c568831SAndroid Build Coastguard Worker        if define == 0 and (module in modules_defines):
567*7c568831SAndroid Build Coastguard Worker            test.write("#ifdef %s\n" % (modules_defines[module]))
568*7c568831SAndroid Build Coastguard Worker            define = 1
569*7c568831SAndroid Build Coastguard Worker        test.write("""static void desret_%s(%s val ATTRIBUTE_UNUSED) {
570*7c568831SAndroid Build Coastguard Worker}
571*7c568831SAndroid Build Coastguard Worker
572*7c568831SAndroid Build Coastguard Worker""" % (name, name))
573*7c568831SAndroid Build Coastguard Worker        known_return_types.append(name)
574*7c568831SAndroid Build Coastguard Worker    if define == 1:
575*7c568831SAndroid Build Coastguard Worker        test.write("#endif\n\n")
576*7c568831SAndroid Build Coastguard Worker
577*7c568831SAndroid Build Coastguard Worker#
578*7c568831SAndroid Build Coastguard Worker# Load the interfaces
579*7c568831SAndroid Build Coastguard Worker#
580*7c568831SAndroid Build Coastguard Workerheaders = ctxt.xpathEval("/api/files/file")
581*7c568831SAndroid Build Coastguard Workerfor file in headers:
582*7c568831SAndroid Build Coastguard Worker    name = file.xpathEval('string(@name)')
583*7c568831SAndroid Build Coastguard Worker    if (name == None) or (name == ''):
584*7c568831SAndroid Build Coastguard Worker        continue
585*7c568831SAndroid Build Coastguard Worker
586*7c568831SAndroid Build Coastguard Worker    #
587*7c568831SAndroid Build Coastguard Worker    # Some module may be skipped because they don't really consists
588*7c568831SAndroid Build Coastguard Worker    # of user callable APIs
589*7c568831SAndroid Build Coastguard Worker    #
590*7c568831SAndroid Build Coastguard Worker    if is_skipped_module(name):
591*7c568831SAndroid Build Coastguard Worker        continue
592*7c568831SAndroid Build Coastguard Worker
593*7c568831SAndroid Build Coastguard Worker    #
594*7c568831SAndroid Build Coastguard Worker    # do not test deprecated APIs
595*7c568831SAndroid Build Coastguard Worker    #
596*7c568831SAndroid Build Coastguard Worker    desc = file.xpathEval('string(description)')
597*7c568831SAndroid Build Coastguard Worker    if desc.find('DEPRECATED') != -1:
598*7c568831SAndroid Build Coastguard Worker        print("Skipping deprecated interface %s" % name)
599*7c568831SAndroid Build Coastguard Worker        continue;
600*7c568831SAndroid Build Coastguard Worker
601*7c568831SAndroid Build Coastguard Worker    test.write("#include <libxml/%s.h>\n" % name)
602*7c568831SAndroid Build Coastguard Worker    modules.append(name)
603*7c568831SAndroid Build Coastguard Worker
604*7c568831SAndroid Build Coastguard Worker#
605*7c568831SAndroid Build Coastguard Worker# Generate the callers signatures
606*7c568831SAndroid Build Coastguard Worker#
607*7c568831SAndroid Build Coastguard Workerfor module in modules:
608*7c568831SAndroid Build Coastguard Worker    test.write("static int test_%s(void);\n" % module);
609*7c568831SAndroid Build Coastguard Worker
610*7c568831SAndroid Build Coastguard Worker#
611*7c568831SAndroid Build Coastguard Worker# Generate the top caller
612*7c568831SAndroid Build Coastguard Worker#
613*7c568831SAndroid Build Coastguard Worker
614*7c568831SAndroid Build Coastguard Workertest.write("""
615*7c568831SAndroid Build Coastguard Worker/**
616*7c568831SAndroid Build Coastguard Worker * testlibxml2:
617*7c568831SAndroid Build Coastguard Worker *
618*7c568831SAndroid Build Coastguard Worker * Main entry point of the tester for the full libxml2 module,
619*7c568831SAndroid Build Coastguard Worker * it calls all the tester entry point for each module.
620*7c568831SAndroid Build Coastguard Worker *
621*7c568831SAndroid Build Coastguard Worker * Returns the number of error found
622*7c568831SAndroid Build Coastguard Worker */
623*7c568831SAndroid Build Coastguard Workerstatic int
624*7c568831SAndroid Build Coastguard Workertestlibxml2(void)
625*7c568831SAndroid Build Coastguard Worker{
626*7c568831SAndroid Build Coastguard Worker    int test_ret = 0;
627*7c568831SAndroid Build Coastguard Worker
628*7c568831SAndroid Build Coastguard Worker""")
629*7c568831SAndroid Build Coastguard Worker
630*7c568831SAndroid Build Coastguard Workerfor module in modules:
631*7c568831SAndroid Build Coastguard Worker    test.write("    test_ret += test_%s();\n" % module)
632*7c568831SAndroid Build Coastguard Worker
633*7c568831SAndroid Build Coastguard Workertest.write("""
634*7c568831SAndroid Build Coastguard Worker    printf("Total: %d functions, %d tests, %d errors\\n",
635*7c568831SAndroid Build Coastguard Worker           function_tests, call_tests, test_ret);
636*7c568831SAndroid Build Coastguard Worker    return(test_ret);
637*7c568831SAndroid Build Coastguard Worker}
638*7c568831SAndroid Build Coastguard Worker
639*7c568831SAndroid Build Coastguard Worker""")
640*7c568831SAndroid Build Coastguard Worker
641*7c568831SAndroid Build Coastguard Worker#
642*7c568831SAndroid Build Coastguard Worker# How to handle a function
643*7c568831SAndroid Build Coastguard Worker#
644*7c568831SAndroid Build Coastguard Workernb_tests = 0
645*7c568831SAndroid Build Coastguard Worker
646*7c568831SAndroid Build Coastguard Workerdef generate_test(module, node):
647*7c568831SAndroid Build Coastguard Worker    global test
648*7c568831SAndroid Build Coastguard Worker    global nb_tests
649*7c568831SAndroid Build Coastguard Worker    nb_cond = 0
650*7c568831SAndroid Build Coastguard Worker    no_gen = 0
651*7c568831SAndroid Build Coastguard Worker
652*7c568831SAndroid Build Coastguard Worker    name = node.xpathEval('string(@name)')
653*7c568831SAndroid Build Coastguard Worker    if is_skipped_function(name):
654*7c568831SAndroid Build Coastguard Worker        return
655*7c568831SAndroid Build Coastguard Worker
656*7c568831SAndroid Build Coastguard Worker    #
657*7c568831SAndroid Build Coastguard Worker    # check we know how to handle the args and return values
658*7c568831SAndroid Build Coastguard Worker    # and store the information for the generation
659*7c568831SAndroid Build Coastguard Worker    #
660*7c568831SAndroid Build Coastguard Worker    try:
661*7c568831SAndroid Build Coastguard Worker        args = node.xpathEval("arg")
662*7c568831SAndroid Build Coastguard Worker    except:
663*7c568831SAndroid Build Coastguard Worker        args = []
664*7c568831SAndroid Build Coastguard Worker    t_args = []
665*7c568831SAndroid Build Coastguard Worker    n = 0
666*7c568831SAndroid Build Coastguard Worker    for arg in args:
667*7c568831SAndroid Build Coastguard Worker        n = n + 1
668*7c568831SAndroid Build Coastguard Worker        rtype = arg.xpathEval("string(@type)")
669*7c568831SAndroid Build Coastguard Worker        if rtype == 'void':
670*7c568831SAndroid Build Coastguard Worker            break;
671*7c568831SAndroid Build Coastguard Worker        info = arg.xpathEval("string(@info)")
672*7c568831SAndroid Build Coastguard Worker        nam = arg.xpathEval("string(@name)")
673*7c568831SAndroid Build Coastguard Worker        type = type_convert(rtype, nam, info, module, name, n)
674*7c568831SAndroid Build Coastguard Worker        if is_known_param_type(type) == 0:
675*7c568831SAndroid Build Coastguard Worker            add_missing_type(type, name);
676*7c568831SAndroid Build Coastguard Worker            no_gen = 1
677*7c568831SAndroid Build Coastguard Worker        t_args.append((nam, type, rtype, info))
678*7c568831SAndroid Build Coastguard Worker
679*7c568831SAndroid Build Coastguard Worker    try:
680*7c568831SAndroid Build Coastguard Worker        rets = node.xpathEval("return")
681*7c568831SAndroid Build Coastguard Worker    except:
682*7c568831SAndroid Build Coastguard Worker        rets = []
683*7c568831SAndroid Build Coastguard Worker    t_ret = None
684*7c568831SAndroid Build Coastguard Worker    for ret in rets:
685*7c568831SAndroid Build Coastguard Worker        rtype = ret.xpathEval("string(@type)")
686*7c568831SAndroid Build Coastguard Worker        info = ret.xpathEval("string(@info)")
687*7c568831SAndroid Build Coastguard Worker        type = type_convert(rtype, 'return', info, module, name, 0)
688*7c568831SAndroid Build Coastguard Worker        if rtype == 'void':
689*7c568831SAndroid Build Coastguard Worker            break
690*7c568831SAndroid Build Coastguard Worker        if is_known_return_type(type) == 0:
691*7c568831SAndroid Build Coastguard Worker            add_missing_type(type, name);
692*7c568831SAndroid Build Coastguard Worker            no_gen = 1
693*7c568831SAndroid Build Coastguard Worker        t_ret = (type, rtype, info)
694*7c568831SAndroid Build Coastguard Worker        break
695*7c568831SAndroid Build Coastguard Worker
696*7c568831SAndroid Build Coastguard Worker    if no_gen == 0:
697*7c568831SAndroid Build Coastguard Worker        for t_arg in t_args:
698*7c568831SAndroid Build Coastguard Worker            (nam, type, rtype, info) = t_arg
699*7c568831SAndroid Build Coastguard Worker            generate_param_type(type, rtype)
700*7c568831SAndroid Build Coastguard Worker
701*7c568831SAndroid Build Coastguard Worker    test.write("""
702*7c568831SAndroid Build Coastguard Workerstatic int
703*7c568831SAndroid Build Coastguard Workertest_%s(void) {
704*7c568831SAndroid Build Coastguard Worker    int test_ret = 0;
705*7c568831SAndroid Build Coastguard Worker
706*7c568831SAndroid Build Coastguard Worker""" % (name))
707*7c568831SAndroid Build Coastguard Worker
708*7c568831SAndroid Build Coastguard Worker    if no_gen == 1:
709*7c568831SAndroid Build Coastguard Worker        add_missing_functions(name, module)
710*7c568831SAndroid Build Coastguard Worker        test.write("""
711*7c568831SAndroid Build Coastguard Worker    /* missing type support */
712*7c568831SAndroid Build Coastguard Worker    return(test_ret);
713*7c568831SAndroid Build Coastguard Worker}
714*7c568831SAndroid Build Coastguard Worker
715*7c568831SAndroid Build Coastguard Worker""")
716*7c568831SAndroid Build Coastguard Worker        return
717*7c568831SAndroid Build Coastguard Worker
718*7c568831SAndroid Build Coastguard Worker    try:
719*7c568831SAndroid Build Coastguard Worker        conds = node.xpathEval("cond")
720*7c568831SAndroid Build Coastguard Worker        for cond in conds:
721*7c568831SAndroid Build Coastguard Worker            test.write("#if %s\n" % (cond.get_content()))
722*7c568831SAndroid Build Coastguard Worker            nb_cond = nb_cond + 1
723*7c568831SAndroid Build Coastguard Worker    except:
724*7c568831SAndroid Build Coastguard Worker        pass
725*7c568831SAndroid Build Coastguard Worker
726*7c568831SAndroid Build Coastguard Worker    define = 0
727*7c568831SAndroid Build Coastguard Worker    if name in function_defines:
728*7c568831SAndroid Build Coastguard Worker        test.write("#ifdef %s\n" % (function_defines[name]))
729*7c568831SAndroid Build Coastguard Worker        define = 1
730*7c568831SAndroid Build Coastguard Worker
731*7c568831SAndroid Build Coastguard Worker    # Declare the memory usage counter
732*7c568831SAndroid Build Coastguard Worker    no_mem = is_skipped_memcheck(name)
733*7c568831SAndroid Build Coastguard Worker    if no_mem == 0:
734*7c568831SAndroid Build Coastguard Worker        test.write("    int mem_base;\n");
735*7c568831SAndroid Build Coastguard Worker
736*7c568831SAndroid Build Coastguard Worker    # Declare the return value
737*7c568831SAndroid Build Coastguard Worker    if t_ret != None:
738*7c568831SAndroid Build Coastguard Worker        test.write("    %s ret_val;\n" % (t_ret[1]))
739*7c568831SAndroid Build Coastguard Worker
740*7c568831SAndroid Build Coastguard Worker    # Declare the arguments
741*7c568831SAndroid Build Coastguard Worker    for arg in t_args:
742*7c568831SAndroid Build Coastguard Worker        (nam, type, rtype, info) = arg;
743*7c568831SAndroid Build Coastguard Worker        # add declaration
744*7c568831SAndroid Build Coastguard Worker        test.write("    %s %s; /* %s */\n" % (rtype, nam, info))
745*7c568831SAndroid Build Coastguard Worker        test.write("    int n_%s;\n" % (nam))
746*7c568831SAndroid Build Coastguard Worker    test.write("\n")
747*7c568831SAndroid Build Coastguard Worker
748*7c568831SAndroid Build Coastguard Worker    # Cascade loop on of each argument list of values
749*7c568831SAndroid Build Coastguard Worker    for arg in t_args:
750*7c568831SAndroid Build Coastguard Worker        (nam, type, rtype, info) = arg;
751*7c568831SAndroid Build Coastguard Worker        #
752*7c568831SAndroid Build Coastguard Worker        test.write("    for (n_%s = 0;n_%s < gen_nb_%s;n_%s++) {\n" % (
753*7c568831SAndroid Build Coastguard Worker                   nam, nam, type, nam))
754*7c568831SAndroid Build Coastguard Worker
755*7c568831SAndroid Build Coastguard Worker    # log the memory usage
756*7c568831SAndroid Build Coastguard Worker    if no_mem == 0:
757*7c568831SAndroid Build Coastguard Worker        test.write("        mem_base = xmlMemBlocks();\n");
758*7c568831SAndroid Build Coastguard Worker
759*7c568831SAndroid Build Coastguard Worker    # prepare the call
760*7c568831SAndroid Build Coastguard Worker    i = 0;
761*7c568831SAndroid Build Coastguard Worker    for arg in t_args:
762*7c568831SAndroid Build Coastguard Worker        (nam, type, rtype, info) = arg;
763*7c568831SAndroid Build Coastguard Worker        #
764*7c568831SAndroid Build Coastguard Worker        test.write("        %s = gen_%s(n_%s, %d);\n" % (nam, type, nam, i))
765*7c568831SAndroid Build Coastguard Worker        i = i + 1;
766*7c568831SAndroid Build Coastguard Worker
767*7c568831SAndroid Build Coastguard Worker    # add checks to avoid out-of-bounds array access
768*7c568831SAndroid Build Coastguard Worker    i = 0;
769*7c568831SAndroid Build Coastguard Worker    for arg in t_args:
770*7c568831SAndroid Build Coastguard Worker        (nam, type, rtype, info) = arg;
771*7c568831SAndroid Build Coastguard Worker        # assume that "size", "len", and "start" parameters apply to either
772*7c568831SAndroid Build Coastguard Worker        # the nearest preceding or following char pointer
773*7c568831SAndroid Build Coastguard Worker        if type == "int" and (nam == "size" or nam == "len" or nam == "start"):
774*7c568831SAndroid Build Coastguard Worker            for j in (list(range(i - 1, -1, -1)) + list(range(i + 1, len(t_args)))):
775*7c568831SAndroid Build Coastguard Worker                (bnam, btype) = t_args[j][:2]
776*7c568831SAndroid Build Coastguard Worker                if btype == "const_char_ptr" or btype == "const_xmlChar_ptr":
777*7c568831SAndroid Build Coastguard Worker                    test.write(
778*7c568831SAndroid Build Coastguard Worker                        "        if ((%s != NULL) &&\n"
779*7c568831SAndroid Build Coastguard Worker                        "            (%s > xmlStrlen(BAD_CAST %s)))\n"
780*7c568831SAndroid Build Coastguard Worker                        "            %s = 0;\n"
781*7c568831SAndroid Build Coastguard Worker                        % (bnam, nam, bnam, nam))
782*7c568831SAndroid Build Coastguard Worker                    break
783*7c568831SAndroid Build Coastguard Worker        i = i + 1;
784*7c568831SAndroid Build Coastguard Worker
785*7c568831SAndroid Build Coastguard Worker    # do the call, and clanup the result
786*7c568831SAndroid Build Coastguard Worker    if name in extra_pre_call:
787*7c568831SAndroid Build Coastguard Worker        test.write("        %s\n"% (extra_pre_call[name]))
788*7c568831SAndroid Build Coastguard Worker    if t_ret != None:
789*7c568831SAndroid Build Coastguard Worker        test.write("\n        ret_val = %s(" % (name))
790*7c568831SAndroid Build Coastguard Worker        need = 0
791*7c568831SAndroid Build Coastguard Worker        for arg in t_args:
792*7c568831SAndroid Build Coastguard Worker            (nam, type, rtype, info) = arg
793*7c568831SAndroid Build Coastguard Worker            if need:
794*7c568831SAndroid Build Coastguard Worker                test.write(", ")
795*7c568831SAndroid Build Coastguard Worker            else:
796*7c568831SAndroid Build Coastguard Worker                need = 1
797*7c568831SAndroid Build Coastguard Worker            test.write("%s" % nam);
798*7c568831SAndroid Build Coastguard Worker        test.write(");\n")
799*7c568831SAndroid Build Coastguard Worker        if name in extra_post_call:
800*7c568831SAndroid Build Coastguard Worker            test.write("        %s\n"% (extra_post_call[name]))
801*7c568831SAndroid Build Coastguard Worker        test.write("        desret_%s(ret_val);\n" % t_ret[0])
802*7c568831SAndroid Build Coastguard Worker    else:
803*7c568831SAndroid Build Coastguard Worker        test.write("\n        %s(" % (name));
804*7c568831SAndroid Build Coastguard Worker        need = 0;
805*7c568831SAndroid Build Coastguard Worker        for arg in t_args:
806*7c568831SAndroid Build Coastguard Worker            (nam, type, rtype, info) = arg;
807*7c568831SAndroid Build Coastguard Worker            if need:
808*7c568831SAndroid Build Coastguard Worker                test.write(", ")
809*7c568831SAndroid Build Coastguard Worker            else:
810*7c568831SAndroid Build Coastguard Worker                need = 1
811*7c568831SAndroid Build Coastguard Worker            test.write("%s" % nam)
812*7c568831SAndroid Build Coastguard Worker        test.write(");\n")
813*7c568831SAndroid Build Coastguard Worker        if name in extra_post_call:
814*7c568831SAndroid Build Coastguard Worker            test.write("        %s\n"% (extra_post_call[name]))
815*7c568831SAndroid Build Coastguard Worker
816*7c568831SAndroid Build Coastguard Worker    test.write("        call_tests++;\n");
817*7c568831SAndroid Build Coastguard Worker
818*7c568831SAndroid Build Coastguard Worker    # Free the arguments
819*7c568831SAndroid Build Coastguard Worker    i = 0;
820*7c568831SAndroid Build Coastguard Worker    for arg in t_args:
821*7c568831SAndroid Build Coastguard Worker        (nam, type, rtype, info) = arg;
822*7c568831SAndroid Build Coastguard Worker        # This is a hack to prevent generating a destructor for the
823*7c568831SAndroid Build Coastguard Worker        # 'input' argument in xmlTextReaderSetup.  There should be
824*7c568831SAndroid Build Coastguard Worker        # a better, more generic way to do this!
825*7c568831SAndroid Build Coastguard Worker        if info.find('destroy') == -1:
826*7c568831SAndroid Build Coastguard Worker            test.write("        des_%s(n_%s, " % (type, nam))
827*7c568831SAndroid Build Coastguard Worker            test.write("%s, %d);\n" % (nam, i))
828*7c568831SAndroid Build Coastguard Worker        i = i + 1;
829*7c568831SAndroid Build Coastguard Worker
830*7c568831SAndroid Build Coastguard Worker    test.write("        xmlResetLastError();\n");
831*7c568831SAndroid Build Coastguard Worker    # Check the memory usage
832*7c568831SAndroid Build Coastguard Worker    if no_mem == 0:
833*7c568831SAndroid Build Coastguard Worker        test.write("""        if (mem_base != xmlMemBlocks()) {
834*7c568831SAndroid Build Coastguard Worker            printf("Leak of %%d blocks found in %s",
835*7c568831SAndroid Build Coastguard Worker\t           xmlMemBlocks() - mem_base);
836*7c568831SAndroid Build Coastguard Worker\t    test_ret++;
837*7c568831SAndroid Build Coastguard Worker""" % (name));
838*7c568831SAndroid Build Coastguard Worker        for arg in t_args:
839*7c568831SAndroid Build Coastguard Worker            (nam, type, rtype, info) = arg;
840*7c568831SAndroid Build Coastguard Worker            test.write("""            printf(" %%d", n_%s);\n""" % (nam))
841*7c568831SAndroid Build Coastguard Worker        test.write("""            printf("\\n");\n""")
842*7c568831SAndroid Build Coastguard Worker        test.write("        }\n")
843*7c568831SAndroid Build Coastguard Worker
844*7c568831SAndroid Build Coastguard Worker    for arg in t_args:
845*7c568831SAndroid Build Coastguard Worker        test.write("    }\n")
846*7c568831SAndroid Build Coastguard Worker
847*7c568831SAndroid Build Coastguard Worker    test.write("    function_tests++;\n")
848*7c568831SAndroid Build Coastguard Worker    #
849*7c568831SAndroid Build Coastguard Worker    # end of conditional
850*7c568831SAndroid Build Coastguard Worker    #
851*7c568831SAndroid Build Coastguard Worker    while nb_cond > 0:
852*7c568831SAndroid Build Coastguard Worker        test.write("#endif\n")
853*7c568831SAndroid Build Coastguard Worker        nb_cond = nb_cond -1
854*7c568831SAndroid Build Coastguard Worker    if define == 1:
855*7c568831SAndroid Build Coastguard Worker        test.write("#endif\n")
856*7c568831SAndroid Build Coastguard Worker
857*7c568831SAndroid Build Coastguard Worker    nb_tests = nb_tests + 1;
858*7c568831SAndroid Build Coastguard Worker
859*7c568831SAndroid Build Coastguard Worker    test.write("""
860*7c568831SAndroid Build Coastguard Worker    return(test_ret);
861*7c568831SAndroid Build Coastguard Worker}
862*7c568831SAndroid Build Coastguard Worker
863*7c568831SAndroid Build Coastguard Worker""")
864*7c568831SAndroid Build Coastguard Worker
865*7c568831SAndroid Build Coastguard Worker#
866*7c568831SAndroid Build Coastguard Worker# Generate all module callers
867*7c568831SAndroid Build Coastguard Worker#
868*7c568831SAndroid Build Coastguard Workerfor module in modules:
869*7c568831SAndroid Build Coastguard Worker    # gather all the functions exported by that module
870*7c568831SAndroid Build Coastguard Worker    try:
871*7c568831SAndroid Build Coastguard Worker        functions = ctxt.xpathEval("/api/symbols/function[@file='%s']" % (module))
872*7c568831SAndroid Build Coastguard Worker    except:
873*7c568831SAndroid Build Coastguard Worker        print("Failed to gather functions from module %s" % (module))
874*7c568831SAndroid Build Coastguard Worker        continue;
875*7c568831SAndroid Build Coastguard Worker
876*7c568831SAndroid Build Coastguard Worker    # iterate over all functions in the module generating the test
877*7c568831SAndroid Build Coastguard Worker    i = 0
878*7c568831SAndroid Build Coastguard Worker    nb_tests_old = nb_tests
879*7c568831SAndroid Build Coastguard Worker    for function in functions:
880*7c568831SAndroid Build Coastguard Worker        i = i + 1
881*7c568831SAndroid Build Coastguard Worker        generate_test(module, function);
882*7c568831SAndroid Build Coastguard Worker
883*7c568831SAndroid Build Coastguard Worker    # header
884*7c568831SAndroid Build Coastguard Worker    test.write("""static int
885*7c568831SAndroid Build Coastguard Workertest_%s(void) {
886*7c568831SAndroid Build Coastguard Worker    int test_ret = 0;
887*7c568831SAndroid Build Coastguard Worker
888*7c568831SAndroid Build Coastguard Worker    if (quiet == 0) printf("Testing %s : %d of %d functions ...\\n");
889*7c568831SAndroid Build Coastguard Worker""" % (module, module, nb_tests - nb_tests_old, i))
890*7c568831SAndroid Build Coastguard Worker
891*7c568831SAndroid Build Coastguard Worker    # iterate over all functions in the module generating the call
892*7c568831SAndroid Build Coastguard Worker    for function in functions:
893*7c568831SAndroid Build Coastguard Worker        name = function.xpathEval('string(@name)')
894*7c568831SAndroid Build Coastguard Worker        if is_skipped_function(name):
895*7c568831SAndroid Build Coastguard Worker            continue
896*7c568831SAndroid Build Coastguard Worker        test.write("    test_ret += test_%s();\n" % (name))
897*7c568831SAndroid Build Coastguard Worker
898*7c568831SAndroid Build Coastguard Worker    # footer
899*7c568831SAndroid Build Coastguard Worker    test.write("""
900*7c568831SAndroid Build Coastguard Worker    if (test_ret != 0)
901*7c568831SAndroid Build Coastguard Worker\tprintf("Module %s: %%d errors\\n", test_ret);
902*7c568831SAndroid Build Coastguard Worker    return(test_ret);
903*7c568831SAndroid Build Coastguard Worker}
904*7c568831SAndroid Build Coastguard Worker""" % (module))
905*7c568831SAndroid Build Coastguard Worker
906*7c568831SAndroid Build Coastguard Worker#
907*7c568831SAndroid Build Coastguard Worker# Generate direct module caller
908*7c568831SAndroid Build Coastguard Worker#
909*7c568831SAndroid Build Coastguard Workertest.write("""static int
910*7c568831SAndroid Build Coastguard Workertest_module(const char *module) {
911*7c568831SAndroid Build Coastguard Worker""");
912*7c568831SAndroid Build Coastguard Workerfor module in modules:
913*7c568831SAndroid Build Coastguard Worker    test.write("""    if (!strcmp(module, "%s")) return(test_%s());\n""" % (
914*7c568831SAndroid Build Coastguard Worker        module, module))
915*7c568831SAndroid Build Coastguard Workertest.write("""    return(0);
916*7c568831SAndroid Build Coastguard Worker}
917*7c568831SAndroid Build Coastguard Worker""");
918*7c568831SAndroid Build Coastguard Worker
919*7c568831SAndroid Build Coastguard Workerprint("Generated test for %d modules and %d functions" %(len(modules), nb_tests))
920*7c568831SAndroid Build Coastguard Worker
921*7c568831SAndroid Build Coastguard Workercompare_and_save()
922*7c568831SAndroid Build Coastguard Worker
923*7c568831SAndroid Build Coastguard Workermissing_list = []
924*7c568831SAndroid Build Coastguard Workerfor missing in missing_types.keys():
925*7c568831SAndroid Build Coastguard Worker    if missing == 'va_list' or missing == '...':
926*7c568831SAndroid Build Coastguard Worker        continue;
927*7c568831SAndroid Build Coastguard Worker
928*7c568831SAndroid Build Coastguard Worker    n = len(missing_types[missing])
929*7c568831SAndroid Build Coastguard Worker    missing_list.append((n, missing))
930*7c568831SAndroid Build Coastguard Worker
931*7c568831SAndroid Build Coastguard Workermissing_list.sort(key=lambda a: a[0])
932*7c568831SAndroid Build Coastguard Workerprint("Missing support for %d functions and %d types see missing.lst" % (missing_functions_nr, len(missing_list)))
933*7c568831SAndroid Build Coastguard Workerlst = open("missing.lst", "w")
934*7c568831SAndroid Build Coastguard Workerlst.write("Missing support for %d types" % (len(missing_list)))
935*7c568831SAndroid Build Coastguard Workerlst.write("\n")
936*7c568831SAndroid Build Coastguard Workerfor miss in missing_list:
937*7c568831SAndroid Build Coastguard Worker    lst.write("%s: %d :" % (miss[1], miss[0]))
938*7c568831SAndroid Build Coastguard Worker    i = 0
939*7c568831SAndroid Build Coastguard Worker    for n in missing_types[miss[1]]:
940*7c568831SAndroid Build Coastguard Worker        i = i + 1
941*7c568831SAndroid Build Coastguard Worker        if i > 5:
942*7c568831SAndroid Build Coastguard Worker            lst.write(" ...")
943*7c568831SAndroid Build Coastguard Worker            break
944*7c568831SAndroid Build Coastguard Worker        lst.write(" %s" % (n))
945*7c568831SAndroid Build Coastguard Worker    lst.write("\n")
946*7c568831SAndroid Build Coastguard Workerlst.write("\n")
947*7c568831SAndroid Build Coastguard Workerlst.write("\n")
948*7c568831SAndroid Build Coastguard Workerlst.write("Missing support per module");
949*7c568831SAndroid Build Coastguard Workerfor module in missing_functions.keys():
950*7c568831SAndroid Build Coastguard Worker    lst.write("module %s:\n   %s\n" % (module, missing_functions[module]))
951*7c568831SAndroid Build Coastguard Worker
952*7c568831SAndroid Build Coastguard Workerlst.close()
953*7c568831SAndroid Build Coastguard Worker
954*7c568831SAndroid Build Coastguard Worker
955