mirror of
				https://gitlab.gnome.org/GNOME/libxml2.git
				synced 2025-10-26 00:37:43 +03:00 
			
		
		
		
	codegen: Consolidate tools for code generation
Move tools, source files and output tables into codegen directory. Rename some files. Adjust tools to match modified files. Remove generation date and source files from output. Distribute all tools and sources.
This commit is contained in:
		
							
								
								
									
										277
									
								
								codegen/genTestApi.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										277
									
								
								codegen/genTestApi.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,277 @@ | ||||
| #!/usr/bin/env python3 | ||||
| # | ||||
| # generate a test program for the API | ||||
| # | ||||
|  | ||||
| import xml.etree.ElementTree as etree | ||||
| import os | ||||
| import re | ||||
| import sys | ||||
|  | ||||
| import xmlmod | ||||
|  | ||||
| # Globals | ||||
|  | ||||
| dtors = { | ||||
|     'htmlDoc *': 'xmlFreeDoc', | ||||
|     'htmlParserCtxt *': 'htmlFreeParserCtxt', | ||||
|     'xmlAutomata *': 'xmlFreeAutomata', | ||||
|     'xmlBuffer *': 'xmlBufferFree', | ||||
|     'xmlCatalog *': 'xmlFreeCatalog', | ||||
|     'xmlChar *': 'xmlFree', | ||||
|     'xmlDOMWrapCtxt *': 'xmlDOMWrapFreeCtxt', | ||||
|     'xmlDict *': 'xmlDictFree', | ||||
|     'xmlDoc *': 'xmlFreeDoc', | ||||
|     'xmlDtd *': 'xmlFreeDtd', | ||||
|     'xmlEntitiesTable *': 'xmlFreeEntitiesTable', | ||||
|     'xmlEnumeration *': 'xmlFreeEnumeration', | ||||
|     'xmlList *': 'xmlListDelete', | ||||
|     'xmlModule *': 'xmlModuleFree', | ||||
|     'xmlMutex *': 'xmlFreeMutex', | ||||
|     'xmlNode *': 'xmlFreeNode', | ||||
|     'xmlNodeSet *': 'xmlXPathFreeNodeSet', | ||||
|     'xmlNs *': 'xmlFreeNs', | ||||
|     'xmlOutputBuffer *': 'xmlOutputBufferClose', | ||||
|     'xmlParserCtxt *': 'xmlFreeParserCtxt', | ||||
|     'xmlParserInputBuffer *': 'xmlFreeParserInputBuffer', | ||||
|     'xmlParserInput *': 'xmlFreeInputStream', | ||||
|     'xmlRMutex *': 'xmlFreeRMutex', | ||||
|     'xmlRelaxNGValidCtxt *': 'xmlRelaxNGFreeValidCtxt', | ||||
|     'xmlSaveCtxt *': 'xmlSaveClose', | ||||
|     'xmlSchemaFacet *': 'xmlSchemaFreeFacet', | ||||
|     'xmlSchemaVal *': 'xmlSchemaFreeValue', | ||||
|     'xmlSchemaValidCtxt *': 'xmlSchemaFreeValidCtxt', | ||||
|     'xmlTextWriter *': 'xmlFreeTextWriter', | ||||
|     'xmlURI *': 'xmlFreeURI', | ||||
|     'xmlValidCtxt *': 'xmlFreeValidCtxt', | ||||
|     'xmlXPathContext *': 'xmlXPathFreeContext', | ||||
|     'xmlXPathParserContext *': 'xmlXPathFreeParserContext', | ||||
|     'xmlXPathObject *': 'xmlXPathFreeObject', | ||||
| } | ||||
|  | ||||
| blockList = { | ||||
|     # init/cleanup | ||||
|     'xmlCleanupParser': True, | ||||
|     'xmlInitParser': True, | ||||
|  | ||||
|     # arg must be non-NULL | ||||
|     'xmlMemStrdupLoc': True, | ||||
|     'xmlMemoryStrdup': True, | ||||
|  | ||||
|     # Returns void pointer which must be freed | ||||
|     'xmlMallocAtomicLoc': True, | ||||
|     'xmlMallocLoc': True, | ||||
|     'xmlMemMalloc': True, | ||||
|     'xmlMemRealloc': True, | ||||
|     'xmlReallocLoc': True, | ||||
|  | ||||
|     # Would reset the error handler | ||||
|     'xmlSetStructuredErrorFunc': True, | ||||
|  | ||||
|     # Prints errors | ||||
|     'xmlCatalogGetPublic': True, | ||||
|     'xmlCatalogGetSystem': True, | ||||
|     'xmlDebugDumpDTD': True, | ||||
|     'xmlDebugDumpDocument': True, | ||||
|     'xmlDebugDumpNode': True, | ||||
|     'xmlDebugDumpString': True, | ||||
|     'xmlParserError': True, | ||||
|     'xmlParserWarning': True, | ||||
|     'xmlParserValidityError': True, | ||||
|     'xmlParserValidityWarning': True, | ||||
|  | ||||
|     # Internal parser unctions, ctxt must be non-NULL | ||||
|     'xmlParseAttribute': True, | ||||
|     'xmlParseAttributeListDecl': True, | ||||
|     'xmlParseAttributeType': True, | ||||
|     'xmlParseCDSect': True, | ||||
|     'xmlParseCharData': True, | ||||
|     'xmlParseCharRef': True, | ||||
|     'xmlParseComment': True, | ||||
|     'xmlParseDefaultDecl': True, | ||||
|     'xmlParseDocTypeDecl': True, | ||||
|     'xmlParseEndTag': True, | ||||
|     'xmlParseElement': True, | ||||
|     'xmlParseElementChildrenContentDecl': True, | ||||
|     'xmlParseElementContentDecl': True, | ||||
|     'xmlParseElementDecl': True, | ||||
|     'xmlParseElementMixedContentDecl': True, | ||||
|     'xmlParseEncName': True, | ||||
|     'xmlParseEncodingDecl': True, | ||||
|     'xmlParseEntityDecl': True, | ||||
|     'xmlParseEntityValue': True, | ||||
|     'xmlParseEnumeratedType': True, | ||||
|     'xmlParseEnumerationType': True, | ||||
|     'xmlParseExternalID': True, | ||||
|     'xmlParseExternalSubset': True, | ||||
|     'xmlParseMarkupDecl': True, | ||||
|     'xmlParseMisc': True, | ||||
|     'xmlParseName': True, | ||||
|     'xmlParseNmtoken': True, | ||||
|     'xmlParseNotationDecl': True, | ||||
|     'xmlParseNotationType': True, | ||||
|     'xmlParsePEReference': True, | ||||
|     'xmlParsePI': True, | ||||
|     'xmlParsePITarget': True, | ||||
|     'xmlParsePubidLiteral': True, | ||||
|     'xmlParseReference': True, | ||||
|     'xmlParseSDDecl': True, | ||||
|     'xmlParseStartTag': True, | ||||
|     'xmlParseSystemLiteral': True, | ||||
|     'xmlParseTextDecl': True, | ||||
|     'xmlParseVersionInfo': True, | ||||
|     'xmlParseVersionNum': True, | ||||
|     'xmlParseXMLDecl': True, | ||||
|     'xmlParserHandlePEReference': True, | ||||
|     'xmlSkipBlankChars': True, | ||||
|  | ||||
|     # reads from stdin | ||||
|     'htmlReadFd': True, | ||||
|     'xmlReadFd': True, | ||||
|     'xmlReaderForFd': True, | ||||
| } | ||||
|  | ||||
| # Parse document | ||||
|  | ||||
| if len(sys.argv) > 1: | ||||
|     buildDir = sys.argv[1] | ||||
| else: | ||||
|     buildDir = '.' | ||||
|  | ||||
| xmlDocDir = buildDir + '/doc/xml' | ||||
|  | ||||
| filenames = {} | ||||
| functions = {} | ||||
|  | ||||
| for file in os.listdir(xmlDocDir): | ||||
|     if not file.endswith('_8h.xml'): | ||||
|         continue | ||||
|  | ||||
|     doc = etree.parse(xmlDocDir + '/' + file) | ||||
|  | ||||
|     compound = doc.find('compounddef') | ||||
|     module = compound.find('compoundname').text | ||||
|     if not module.endswith('.h'): | ||||
|         continue | ||||
|     module = module[:-2] | ||||
|  | ||||
|     for section in compound.findall('sectiondef'): | ||||
|         if section.get('kind') != 'func': | ||||
|             continue | ||||
|  | ||||
|         for func in section.findall('memberdef'): | ||||
|             name = func.find('name').text | ||||
|             if name in blockList: | ||||
|                 continue | ||||
|  | ||||
|             module1, module2 = xmlmod.findModules(module, name) | ||||
|  | ||||
|             cargs = [] | ||||
|             for arg in func.findall('param'): | ||||
|                 atype = etree.tostring(arg.find('type'), | ||||
|                     method='text', encoding='unicode').rstrip() | ||||
|                 if atype == 'void': | ||||
|                     continue | ||||
|                 if re.search(r'(Ptr|\*)$', atype): | ||||
|                     cargs.append('NULL') | ||||
|                 else: | ||||
|                     cargs.append('0') | ||||
|  | ||||
|             mfunc = functions.get(module1) | ||||
|             if mfunc is None: | ||||
|                 mfunc = {} | ||||
|                 functions[module1] = mfunc | ||||
|  | ||||
|             mmfunc = mfunc.get(module2) | ||||
|             if mmfunc is None: | ||||
|                 mmfunc = {} | ||||
|                 mfunc[module2] = mmfunc | ||||
|  | ||||
|             code = f'{name}({', '.join(cargs)})' | ||||
|  | ||||
|             rtype = etree.tostring(func.find('type'), | ||||
|                 method='text', encoding='unicode').rstrip() | ||||
|             dtor = dtors.get(rtype) | ||||
|             if dtor is not None: | ||||
|                 code = f'{dtor}({code})' | ||||
|             elif rtype == 'xmlHashTable *': | ||||
|                 code = f'xmlHashFree({code}, NULL)' | ||||
|  | ||||
|             mmfunc[name] = f'    {code};\n' | ||||
|  | ||||
| # Write output | ||||
|  | ||||
| test = open('testapi.c', 'w') | ||||
|  | ||||
| test.write("""/* | ||||
|  * testapi.c: libxml2 API tester program. | ||||
|  * | ||||
|  * Automatically generated by gentest.py | ||||
|  * | ||||
|  * See Copyright for the status of this software. | ||||
|  */ | ||||
|  | ||||
| /* Disable deprecation warnings */ | ||||
| #define XML_DEPRECATED | ||||
|  | ||||
| #include "libxml.h" | ||||
| #include <libxml/HTMLparser.h> | ||||
| #include <libxml/HTMLtree.h> | ||||
| #include <libxml/c14n.h> | ||||
| #include <libxml/catalog.h> | ||||
| #include <libxml/debugXML.h> | ||||
| #include <libxml/parserInternals.h> | ||||
| #include <libxml/pattern.h> | ||||
| #include <libxml/relaxng.h> | ||||
| #include <libxml/schematron.h> | ||||
| #include <libxml/uri.h> | ||||
| #include <libxml/xinclude.h> | ||||
| #include <libxml/xlink.h> | ||||
| #include <libxml/xmlmodule.h> | ||||
| #include <libxml/xmlreader.h> | ||||
| #include <libxml/xmlsave.h> | ||||
| #include <libxml/xmlschemas.h> | ||||
| #include <libxml/xmlschemastypes.h> | ||||
| #include <libxml/xmlwriter.h> | ||||
| #include <libxml/xpathInternals.h> | ||||
| #include <libxml/xpointer.h> | ||||
|  | ||||
| static void | ||||
| ignoreError(void *userData ATTRIBUTE_UNUSED, | ||||
|             const xmlError *error ATTRIBUTE_UNUSED) { | ||||
| } | ||||
|  | ||||
| int | ||||
| main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { | ||||
|     xmlInitParser(); | ||||
|     xmlSetStructuredErrorFunc(NULL, ignoreError); | ||||
|  | ||||
| """) | ||||
|  | ||||
| for module1 in sorted(functions.keys()): | ||||
|     mfunc = functions[module1] | ||||
|  | ||||
|     if module1 != '': | ||||
|         test.write(f'#ifdef LIBXML_{module1}_ENABLED\n') | ||||
|  | ||||
|     for module2 in sorted(mfunc.keys()): | ||||
|         mmfunc = mfunc[module2] | ||||
|  | ||||
|         if module2 != '': | ||||
|             test.write(f'#ifdef LIBXML_{module2}_ENABLED\n') | ||||
|  | ||||
|         for name in sorted(mmfunc.keys()): | ||||
|             test.write(mmfunc[name]) | ||||
|  | ||||
|         if module2 != '': | ||||
|             test.write(f'#endif /* LIBXML_{module2}_ENABLED */\n') | ||||
|  | ||||
|     if module1 != '': | ||||
|         test.write(f'#endif /* LIBXML_{module1}_ENABLED */\n') | ||||
|  | ||||
|     test.write('\n') | ||||
|  | ||||
| test.write("""    xmlCleanupParser(); | ||||
|     return 0; | ||||
| } | ||||
| """) | ||||
		Reference in New Issue
	
	Block a user