1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-26 00:37:43 +03:00
Files
libxml2/codegen/genTestApi.py
Nick Wellnhofer 258d870629 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.
2025-05-16 18:03:12 +02:00

278 lines
7.4 KiB
Python
Executable File

#!/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;
}
""")