mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-10-26 00:37:43 +03:00
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.
278 lines
7.4 KiB
Python
Executable File
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;
|
|
}
|
|
""")
|