📄 xmllint.c
字号:
/*
* xmllint.c : a small tester program for XML input.
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#include "libxml.h"
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#if defined (_WIN32) && !defined(__CYGWIN__)
#if defined (_MSC_VER) || defined(__BORLANDC__)
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define gettimeofday(p1,p2)
#endif /* _MSC_VER */
#endif /* _WIN32 */
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef __MINGW32__
#define _WINSOCKAPI_
#include <wsockcompat.h>
#include <winsock2.h>
#undef XML_SOCKLEN_T
#define XML_SOCKLEN_T unsigned int
#endif
#ifdef HAVE_SYS_TIMEB_H
#include <sys/timeb.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
/* seems needed for Solaris */
#ifndef MAP_FAILED
#define MAP_FAILED ((void *) -1)
#endif
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_LIBREADLINE
#include <readline/readline.h>
#ifdef HAVE_LIBHISTORY
#include <readline/history.h>
#endif
#endif
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/HTMLparser.h>
#include <libxml/HTMLtree.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/debugXML.h>
#include <libxml/xmlerror.h>
#ifdef LIBXML_XINCLUDE_ENABLED
#include <libxml/xinclude.h>
#endif
#ifdef LIBXML_CATALOG_ENABLED
#include <libxml/catalog.h>
#endif
#include <libxml/globals.h>
#include <libxml/xmlreader.h>
#ifdef LIBXML_SCHEMAS_ENABLED
#include <libxml/relaxng.h>
#include <libxml/xmlschemas.h>
#endif
#ifdef LIBXML_PATTERN_ENABLED
#include <libxml/pattern.h>
#endif
#ifdef LIBXML_C14N_ENABLED
#include <libxml/c14n.h>
#endif
#ifndef XML_XML_DEFAULT_CATALOG
#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
#endif
typedef enum {
XMLLINT_RETURN_OK = 0, /* No error */
XMLLINT_ERR_UNCLASS, /* Unclassified */
XMLLINT_ERR_DTD, /* Error in DTD */
XMLLINT_ERR_VALID, /* Validation error */
XMLLINT_ERR_RDFILE, /* CtxtReadFile error */
XMLLINT_ERR_SCHEMACOMP, /* Schema compilation */
XMLLINT_ERR_OUT, /* Error writing output */
XMLLINT_ERR_SCHEMAPAT, /* Error in schema pattern */
XMLLINT_ERR_RDREGIS, /* Error in Reader registration */
XMLLINT_ERR_MEM /* Out of memory error */
} xmllintReturnCode;
#ifdef LIBXML_DEBUG_ENABLED
static int shell = 0;
static int debugent = 0;
#endif
static int debug = 0;
static int maxmem = 0;
#ifdef LIBXML_TREE_ENABLED
static int copy = 0;
#endif /* LIBXML_TREE_ENABLED */
static int recovery = 0;
static int noent = 0;
static int noblanks = 0;
static int noout = 0;
static int nowrap = 0;
#ifdef LIBXML_OUTPUT_ENABLED
static int format = 0;
static const char *output = NULL;
static int compress = 0;
#endif /* LIBXML_OUTPUT_ENABLED */
#ifdef LIBXML_VALID_ENABLED
static int valid = 0;
static int postvalid = 0;
static char * dtdvalid = NULL;
static char * dtdvalidfpi = NULL;
#endif
#ifdef LIBXML_SCHEMAS_ENABLED
static char * relaxng = NULL;
static xmlRelaxNGPtr relaxngschemas = NULL;
static char * schema = NULL;
static xmlSchemaPtr wxschemas = NULL;
#endif
static int repeat = 0;
static int insert = 0;
#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
static int html = 0;
static int xmlout = 0;
#endif
static int htmlout = 0;
#ifdef LIBXML_PUSH_ENABLED
static int push = 0;
#endif /* LIBXML_PUSH_ENABLED */
#ifdef HAVE_SYS_MMAN_H
static int memory = 0;
#endif
static int testIO = 0;
static char *encoding = NULL;
#ifdef LIBXML_XINCLUDE_ENABLED
static int xinclude = 0;
#endif
static int dtdattrs = 0;
static int loaddtd = 0;
static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
static int timing = 0;
static int generate = 0;
static int dropdtd = 0;
#ifdef LIBXML_CATALOG_ENABLED
static int catalogs = 0;
static int nocatalogs = 0;
#endif
#ifdef LIBXML_C14N_ENABLED
static int canonical = 0;
static int exc_canonical = 0;
#endif
#ifdef LIBXML_READER_ENABLED
static int stream = 0;
static int walker = 0;
#endif /* LIBXML_READER_ENABLED */
static int chkregister = 0;
static int nbregister = 0;
#ifdef LIBXML_SAX1_ENABLED
static int sax1 = 0;
#endif /* LIBXML_SAX1_ENABLED */
#ifdef LIBXML_PATTERN_ENABLED
static const char *pattern = NULL;
static xmlPatternPtr patternc = NULL;
static xmlStreamCtxtPtr patstream = NULL;
#endif
static int options = 0;
static int sax = 0;
/************************************************************************
* *
* Entity loading control and customization. *
* *
************************************************************************/
#define MAX_PATHS 64
static xmlChar *paths[MAX_PATHS + 1];
static int nbpaths = 0;
static int load_trace = 0;
static
void parsePath(const xmlChar *path) {
const xmlChar *cur;
if (path == NULL)
return;
while (*path != 0) {
if (nbpaths >= MAX_PATHS) {
fprintf(stderr, "MAX_PATHS reached: too many paths\n");
return;
}
cur = path;
while ((*cur == ' ') || (*cur == ':'))
cur++;
path = cur;
while ((*cur != 0) && (*cur != ' ') && (*cur != ':'))
cur++;
if (cur != path) {
paths[nbpaths] = xmlStrndup(path, cur - path);
if (paths[nbpaths] != NULL)
nbpaths++;
path = cur;
}
}
}
xmlExternalEntityLoader defaultEntityLoader = NULL;
static xmlParserInputPtr
xmllintExternalEntityLoader(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) {
xmlParserInputPtr ret;
warningSAXFunc warning = NULL;
int i;
const char *lastsegment = URL;
const char *iter = URL;
if (nbpaths > 0) {
while (*iter != 0) {
if (*iter == '/')
lastsegment = iter + 1;
iter++;
}
}
if ((ctxt != NULL) && (ctxt->sax != NULL)) {
warning = ctxt->sax->warning;
ctxt->sax->warning = NULL;
}
if (defaultEntityLoader != NULL) {
ret = defaultEntityLoader(URL, ID, ctxt);
if (ret != NULL) {
if (warning != NULL)
ctxt->sax->warning = warning;
if (load_trace) {
fprintf \
(stderr,
"Loaded URL=\"%s\" ID=\"%s\"\n",
URL ? URL : "(null)",
ID ? ID : "(null)");
}
return(ret);
}
}
for (i = 0;i < nbpaths;i++) {
xmlChar *newURL;
newURL = xmlStrdup((const xmlChar *) paths[i]);
newURL = xmlStrcat(newURL, (const xmlChar *) "/");
newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
if (newURL != NULL) {
ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
if (ret != NULL) {
if (warning != NULL)
ctxt->sax->warning = warning;
if (load_trace) {
fprintf \
(stderr,
"Loaded URL=\"%s\" ID=\"%s\"\n",
newURL,
ID ? ID : "(null)");
}
xmlFree(newURL);
return(ret);
}
xmlFree(newURL);
}
}
if (warning != NULL) {
ctxt->sax->warning = warning;
if (URL != NULL)
warning(ctxt, "failed to load external entity \"%s\"\n", URL);
else if (ID != NULL)
warning(ctxt, "failed to load external entity \"%s\"\n", ID);
}
return(NULL);
}
/************************************************************************
* *
* Memory allocation consumption debugging *
* *
************************************************************************/
static void
OOM(void)
{
fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
progresult = XMLLINT_ERR_MEM;
}
static void
myFreeFunc(void *mem)
{
xmlMemFree(mem);
}
static void *
myMallocFunc(size_t size)
{
void *ret;
ret = xmlMemMalloc(size);
if (ret != NULL) {
if (xmlMemUsed() > maxmem) {
OOM();
xmlMemFree(ret);
return (NULL);
}
}
return (ret);
}
static void *
myReallocFunc(void *mem, size_t size)
{
void *ret;
ret = xmlMemRealloc(mem, size);
if (ret != NULL) {
if (xmlMemUsed() > maxmem) {
OOM();
xmlMemFree(ret);
return (NULL);
}
}
return (ret);
}
static char *
myStrdupFunc(const char *str)
{
char *ret;
ret = xmlMemoryStrdup(str);
if (ret != NULL) {
if (xmlMemUsed() > maxmem) {
OOM();
xmlFree(ret);
return (NULL);
}
}
return (ret);
}
/************************************************************************
* *
* Internal timing routines to remove the necessity to have *
* unix-specific function calls. *
* *
************************************************************************/
#ifndef HAVE_GETTIMEOFDAY
#ifdef HAVE_SYS_TIMEB_H
#ifdef HAVE_SYS_TIME_H
#ifdef HAVE_FTIME
static int
my_gettimeofday(struct timeval *tvp, void *tzp)
{
struct timeb timebuffer;
ftime(&timebuffer);
if (tvp) {
tvp->tv_sec = timebuffer.time;
tvp->tv_usec = timebuffer.millitm * 1000L;
}
return (0);
}
#define HAVE_GETTIMEOFDAY 1
#define gettimeofday my_gettimeofday
#endif /* HAVE_FTIME */
#endif /* HAVE_SYS_TIME_H */
#endif /* HAVE_SYS_TIMEB_H */
#endif /* !HAVE_GETTIMEOFDAY */
#if defined(HAVE_GETTIMEOFDAY)
static struct timeval begin, end;
/*
* startTimer: call where you want to start timing
*/
static void
startTimer(void)
{
gettimeofday(&begin, NULL);
}
/*
* endTimer: call where you want to stop timing and to print out a
* message about the timing performed; format is a printf
* type argument
*/
static void
endTimer(const char *fmt, ...)
{
long msec;
va_list ap;
gettimeofday(&end, NULL);
msec = end.tv_sec - begin.tv_sec;
msec *= 1000;
msec += (end.tv_usec - begin.tv_usec) / 1000;
#ifndef HAVE_STDARG_H
#error "endTimer required stdarg functions"
#endif
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, " took %ld ms\n", msec);
}
#elif defined(HAVE_TIME_H)
/*
* No gettimeofday function, so we have to make do with calling clock.
* This is obviously less accurate, but there's little we can do about
* that.
*/
#ifndef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC 100
#endif
static clock_t begin, end;
static void
startTimer(void)
{
begin = clock();
}
static void
endTimer(const char *fmt, ...)
{
long msec;
va_list ap;
end = clock();
msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
#ifndef HAVE_STDARG_H
#error "endTimer required stdarg functions"
#endif
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, " took %ld ms\n", msec);
}
#else
/*
* We don't have a gettimeofday or time.h, so we just don't do timing
*/
static void
startTimer(void)
{
/*
* Do nothing
*/
}
static void
endTimer(char *format, ...)
{
/*
* We cannot do anything because we don't have a timing function
*/
#ifdef HAVE_STDARG_H
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fprintf(stderr, " was not timed\n", msec);
#else
/* We don't have gettimeofday, time or stdarg.h, what crazy world is
* this ?!
*/
#endif
}
#endif
/************************************************************************
* *
* HTML ouput *
* *
************************************************************************/
char buffer[50000];
static void
xmlHTMLEncodeSend(void) {
char *result;
result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
if (result) {
xmlGenericError(xmlGenericErrorContext, "%s", result);
xmlFree(result);
}
buffer[0] = 0;
}
/**
* xmlHTMLPrintFileInfo:
* @input: an xmlParserInputPtr input
*
* Displays the associated file and line informations for the current input
*/
static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -