📄 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_SCHEMATRON_ENABLED#include <libxml/schematron.h>#endif#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#ifdef LIBXML_OUTPUT_ENABLED#include <libxml/xmlsave.h>#endif#ifndef XML_XML_DEFAULT_CATALOG#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"#endiftypedef 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_ENABLEDstatic int shell = 0;static int debugent = 0;#endifstatic int debug = 0;static int maxmem = 0;#ifdef LIBXML_TREE_ENABLEDstatic 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_ENABLEDstatic int format = 0;static const char *output = NULL;static int compress = 0;static int oldout = 0;#endif /* LIBXML_OUTPUT_ENABLED */#ifdef LIBXML_VALID_ENABLEDstatic int valid = 0;static int postvalid = 0;static char * dtdvalid = NULL;static char * dtdvalidfpi = NULL;#endif#ifdef LIBXML_SCHEMAS_ENABLEDstatic char * relaxng = NULL;static xmlRelaxNGPtr relaxngschemas = NULL;static char * schema = NULL;static xmlSchemaPtr wxschemas = NULL;#endif#ifdef LIBXML_SCHEMATRON_ENABLEDstatic char * schematron = NULL;static xmlSchematronPtr wxschematron = NULL;#endifstatic int repeat = 0;static int insert = 0;#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)static int html = 0;static int xmlout = 0;#endifstatic int htmlout = 0;#ifdef LIBXML_PUSH_ENABLEDstatic int push = 0;#endif /* LIBXML_PUSH_ENABLED */#ifdef HAVE_SYS_MMAN_Hstatic int memory = 0;#endifstatic int testIO = 0;static char *encoding = NULL;#ifdef LIBXML_XINCLUDE_ENABLEDstatic int xinclude = 0;#endifstatic 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_ENABLEDstatic int catalogs = 0;static int nocatalogs = 0;#endif#ifdef LIBXML_C14N_ENABLEDstatic int canonical = 0;static int exc_canonical = 0;#endif#ifdef LIBXML_READER_ENABLEDstatic int stream = 0;static int walker = 0;#endif /* LIBXML_READER_ENABLED */static int chkregister = 0;static int nbregister = 0;#ifdef LIBXML_SAX1_ENABLEDstatic int sax1 = 0;#endif /* LIBXML_SAX1_ENABLED */#ifdef LIBXML_PATTERN_ENABLEDstatic const char *pattern = NULL;static xmlPatternPtr patternc = NULL;static xmlStreamCtxtPtr patstream = NULL;#endifstatic int options = XML_PARSE_COMPACT;static int sax = 0;/************************************************************************ * * * Entity loading control and customization. * * * ************************************************************************/#define MAX_PATHS 64#ifdef _WIN32# define PATH_SEPARATOR ';'#else# define PATH_SEPARATOR ':'#endifstatic xmlChar *paths[MAX_PATHS + 1];static int nbpaths = 0;static int load_trace = 0;staticvoid 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 == PATH_SEPARATOR)) cur++; path = cur; while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR)) cur++; if (cur != path) { paths[nbpaths] = xmlStrndup(path, cur - path); if (paths[nbpaths] != NULL) nbpaths++; path = cur; } }}static xmlExternalEntityLoader defaultEntityLoader = NULL;static xmlParserInputPtr xmllintExternalEntityLoader(const char *URL, const char *ID, xmlParserCtxtPtr ctxt) { xmlParserInputPtr ret; warningSAXFunc warning = NULL; errorSAXFunc err = 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; err = ctxt->sax->error; ctxt->sax->warning = NULL; ctxt->sax->error = NULL; } if (defaultEntityLoader != NULL) { ret = defaultEntityLoader(URL, ID, ctxt); if (ret != NULL) { if (warning != NULL) ctxt->sax->warning = warning; if (err != NULL) ctxt->sax->error = err; 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 (err != NULL) ctxt->sax->error = err; if (load_trace) { fprintf \ (stderr, "Loaded URL=\"%s\" ID=\"%s\"\n", newURL, ID ? ID : "(null)"); } xmlFree(newURL); return(ret); } xmlFree(newURL); } } if (err != NULL) ctxt->sax->error = err; 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 voidOOM(void){ fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem); progresult = XMLLINT_ERR_MEM;}static voidmyFreeFunc(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_FTIMEstatic intmy_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 voidstartTimer(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 XMLCDECLendTimer(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#endifstatic clock_t begin, end;static voidstartTimer(void){ begin = clock();}static void XMLCDECLendTimer(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 voidstartTimer(void){ /* * Do nothing */}static void XMLCDECLendTimer(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 * * * ************************************************************************/static char buffer[50000];static voidxmlHTMLEncodeSend(void) { char *result; result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer); if (result) { xmlGenericError(xmlGenericErrorContext, "%s", result); xmlFree(result); } buffer[0] = 0;}/** * xmlHTMLPrintFileInfo:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -