1
0
mirror of https://github.com/GNOME/libxml2.git synced 2025-05-07 20:39:30 +08:00

test: Make gentest.py use Doxygen XML

This adds Python code to look up the required feature macros for a
symbol in tools/xmlmod.py.
This commit is contained in:
Nick Wellnhofer 2025-04-28 19:05:38 +02:00
parent bbe5827c94
commit 97f3ec7708
4 changed files with 61 additions and 78 deletions

View File

@ -153,10 +153,8 @@ testdso_la_SOURCES = testdso.c
testdso_la_LDFLAGS = $(AM_LDFLAGS) \
-module -no-undefined -avoid-version -rpath $(libdir)
# that one forces the rebuild when "make rebuild" is run on doc/
rebuild_testapi:
-@(if [ "$(PYTHON)" != "" ] ; then \
$(PYTHON) $(srcdir)/tools/gentest.py $(srcdir) ; fi )
cd $(srcdir) && python3 tools/gentest.py $(abs_builddir)
testapi_SOURCES=testapi.c
testapi_DEPENDENCIES = $(DEPS)
@ -204,7 +202,7 @@ CLEANFILES = missing.lst runsuite.log runxmlconf.log test.out \
EXTRA_DIST = Copyright libxml2-config.cmake.in autogen.sh \
libxml.h \
html5ent.inc iso8859x.inc \
tools/gentest.py \
tools/gentest.py tools/xmlmod.py \
tools/genChRanges.py tools/genEscape.py tools/genUnicode.py \
timsort.h \
README.zOS README.md \

View File

@ -1,7 +1,7 @@
/*
* testapi.c: libxml2 API tester program.
*
* Automatically generated by gentest.py from libxml2-api.xml
* Automatically generated by gentest.py
*
* See Copyright for the status of this software.
*/
@ -41,6 +41,7 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
xmlInitParser();
xmlSetStructuredErrorFunc(NULL, ignoreError);
xmlFreeParserInputBuffer(__xmlParserInputBufferCreateFilename(NULL, 0));
xmlAddAttributeDecl(NULL, NULL, NULL, NULL, NULL, 0, 0, NULL, NULL);
xmlFreeNode(xmlAddChild(NULL, NULL));
xmlFreeNode(xmlAddChildList(NULL, NULL));
@ -728,34 +729,6 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
#endif /* LIBXML_PUSH_ENABLED */
#endif /* LIBXML_HTML_ENABLED */
#ifdef LIBXML_HTTP_ENABLED
xmlIOHTTPClose(NULL);
xmlIOHTTPMatch(NULL);
xmlIOHTTPOpen(NULL);
xmlIOHTTPRead(NULL, NULL, 0);
xmlNanoHTTPAuthHeader(NULL);
xmlNanoHTTPCleanup();
xmlNanoHTTPClose(NULL);
xmlNanoHTTPContentLength(NULL);
xmlNanoHTTPEncoding(NULL);
xmlNanoHTTPFetch(NULL, NULL, NULL);
xmlNanoHTTPInit();
xmlNanoHTTPMethod(NULL, NULL, NULL, NULL, NULL, 0);
xmlNanoHTTPMethodRedir(NULL, NULL, NULL, NULL, NULL, NULL, 0);
xmlNanoHTTPMimeType(NULL);
xmlNanoHTTPOpen(NULL, NULL);
xmlNanoHTTPOpenRedir(NULL, NULL, NULL);
xmlNanoHTTPRead(NULL, NULL, 0);
xmlNanoHTTPRedir(NULL);
xmlNanoHTTPReturnCode(NULL);
xmlNanoHTTPScanProxy(NULL);
#ifdef LIBXML_OUTPUT_ENABLED
xmlIOHTTPOpenW(NULL, 0);
xmlNanoHTTPSave(NULL, NULL);
xmlRegisterHTTPPostCallbacks();
#endif /* LIBXML_OUTPUT_ENABLED */
#endif /* LIBXML_HTTP_ENABLED */
#ifdef LIBXML_MODULES_ENABLED
xmlModuleClose(NULL);
xmlModuleFree(NULL);
@ -764,6 +737,7 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
#endif /* LIBXML_MODULES_ENABLED */
#ifdef LIBXML_OUTPUT_ENABLED
xmlOutputBufferClose(__xmlOutputBufferCreateFilename(NULL, NULL, 0));
xmlOutputBufferClose(xmlAllocOutputBuffer(NULL));
xmlAttrSerializeTxtContent(NULL, NULL, NULL, NULL);
xmlBufNodeDump(NULL, NULL, NULL, 0, 0);

View File

@ -4,6 +4,7 @@
#
import xml.etree.ElementTree as etree
import os
import re
import sys
@ -133,70 +134,79 @@ blockList = {
# Parse document
if len(sys.argv) > 1:
srcPref = sys.argv[1] + '/'
buildDir = sys.argv[1]
else:
srcPref = ''
buildDir = '.'
doc = etree.parse(srcPref + 'doc/libxml2-api.xml')
# Create map of symbols to filenames
xmlDocDir = buildDir + '/doc/xml'
filenames = {}
for file in doc.find('files').findall('file'):
filename = file.get('name')
for export in file.findall('exports'):
filenames[export.get('symbol')] = filename
# Process functions
functions = {}
for func in doc.find('symbols').findall('function'):
name = func.get('name')
if name in blockList:
for file in os.listdir(xmlDocDir):
if not file.endswith('_8h.xml'):
continue
module1, module2 = xmlmod.findModules(filenames[name], name)
doc = etree.parse(xmlDocDir + '/' + file)
cargs = []
for arg in func.findall('arg'):
atype = arg.get('type')
if re.search(r'(Ptr|\*)$', atype):
cargs.append('NULL')
else:
cargs.append('0')
compound = doc.find('compounddef')
module = compound.find('compoundname').text
if not module.endswith('.h'):
continue
module = module[:-2]
mfunc = functions.get(module1)
if mfunc is None:
mfunc = {}
functions[module1] = mfunc
for section in compound.findall('sectiondef'):
if section.get('kind') != 'func':
continue
mmfunc = mfunc.get(module2)
if mmfunc is None:
mmfunc = []
mfunc[module2] = mmfunc
for func in section.findall('memberdef'):
name = func.find('name').text
if name in blockList:
continue
code = f'{name}({', '.join(cargs)})'
module1, module2 = xmlmod.findModules(module, name)
rtype = func.find('return').get('type')
dtor = dtors.get(rtype)
if dtor is not None:
code = f'{dtor}({code})'
elif rtype == 'xmlHashTablePtr':
code = f'xmlHashFree({code}, NULL)'
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')
mmfunc.append(f' {code};')
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 == 'xmlHashTablePtr':
code = f'xmlHashFree({code}, NULL)'
mmfunc[name] = f' {code};\n'
# Write output
test = open(srcPref + 'testapi.c', 'w')
test = open('testapi.c', 'w')
test.write("""/*
* testapi.c: libxml2 API tester program.
*
* Automatically generated by gentest.py from libxml2-api.xml
* Automatically generated by gentest.py
*
* See Copyright for the status of this software.
*/
@ -250,8 +260,8 @@ for module1 in sorted(functions.keys()):
if module2 != '':
test.write(f'#ifdef LIBXML_{module2}_ENABLED\n')
for code in mmfunc:
test.write(code + '\n')
for name in sorted(mmfunc.keys()):
test.write(mmfunc[name])
if module2 != '':
test.write(f'#endif /* LIBXML_{module2}_ENABLED */\n')

View File

@ -42,6 +42,7 @@ symbolMap1 = {
'xmlRegisterHTTPPostCallbacks': 'HTTP',
'__xmlOutputBufferCreateFilename': 'OUTPUT',
'xmlAttrSerializeTxtContent': 'OUTPUT',
'xmlUTF8ToIsolat1': 'OUTPUT',
'xmlSprintfElementContent': 'OUTPUT',