2000-04-05 18:38:42 +00:00
/*
* xmllint . c : a small tester program for XML input .
*
* See Copyright for the status of this software .
*
* Daniel . Veillard @ w3 . org
*/
2001-04-21 16:57:29 +00:00
# include "libxml.h"
2000-04-05 18:38:42 +00:00
# include <string.h>
# include <stdarg.h>
2001-04-16 17:46:18 +00:00
# ifdef _WIN32
# ifdef _MSC_VER
# include <winsock2.h>
# pragma comment(lib, "ws2_32.lib")
# define gettimeofday(p1,p2)
# endif /* _MSC_VER */
# else /* _WIN32 */
2001-02-25 16:11:03 +00:00
# include <sys/time.h>
2001-04-16 17:46:18 +00:00
# endif /* _WIN32 */
2001-02-25 16:11:03 +00:00
2000-04-05 18:38:42 +00:00
# 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
2000-07-21 20:32:03 +00:00
# ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
2000-08-12 21:12:04 +00:00
/* seems needed for Solaris */
# ifndef MAP_FAILED
# define MAP_FAILED ((void *) -1)
# endif
2000-07-21 20:32:03 +00:00
# endif
2000-04-05 18:38:42 +00:00
# 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>
2000-10-25 19:56:55 +00:00
# include <libxml/xmlerror.h>
2000-11-06 16:43:11 +00:00
# ifdef LIBXML_XINCLUDE_ENABLED
# include <libxml/xinclude.h>
# endif
2001-05-22 15:08:55 +00:00
# ifdef LIBXML_CATALOG_ENABLED
# include <libxml/catalog.h>
# endif
2000-04-05 18:38:42 +00:00
# ifdef LIBXML_DEBUG_ENABLED
static int debug = 0 ;
static int shell = 0 ;
static int debugent = 0 ;
# endif
static int copy = 0 ;
static int recovery = 0 ;
static int noent = 0 ;
static int noout = 0 ;
static int nowrap = 0 ;
static int valid = 0 ;
static int postvalid = 0 ;
2000-10-11 15:57:05 +00:00
static char * dtdvalid = NULL ;
2000-04-05 18:38:42 +00:00
static int repeat = 0 ;
static int insert = 0 ;
static int compress = 0 ;
static int html = 0 ;
static int htmlout = 0 ;
static int push = 0 ;
2000-07-21 20:32:03 +00:00
# ifdef HAVE_SYS_MMAN_H
static int memory = 0 ;
# endif
2000-04-05 18:38:42 +00:00
static int noblanks = 0 ;
2000-04-12 13:27:38 +00:00
static int testIO = 0 ;
2000-06-28 23:40:59 +00:00
static char * encoding = NULL ;
2000-11-06 16:43:11 +00:00
# ifdef LIBXML_XINCLUDE_ENABLED
static int xinclude = 0 ;
# endif
2001-02-23 18:44:52 +00:00
static int progresult = 0 ;
2001-02-25 16:11:03 +00:00
static int timing = 0 ;
2001-04-11 07:50:02 +00:00
static int generate = 0 ;
2001-02-25 16:11:03 +00:00
static struct timeval begin , end ;
2000-04-05 18:38:42 +00:00
2000-11-25 09:54:49 +00:00
# ifdef VMS
extern int xmlDoValidityCheckingDefaultVal ;
# define xmlDoValidityCheckingDefaultValue xmlDoValidityCheckingDefaultVal
# else
2000-04-05 18:38:42 +00:00
extern int xmlDoValidityCheckingDefaultValue ;
2000-11-25 09:54:49 +00:00
# endif
2000-04-05 18:38:42 +00:00
extern int xmlGetWarningsDefaultValue ;
/************************************************************************
* *
* HTML ouput *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char buffer [ 50000 ] ;
2001-03-24 17:00:36 +00:00
static void
2000-04-05 18:38:42 +00:00
xmlHTMLEncodeSend ( void ) {
char * result ;
result = ( char * ) xmlEncodeEntitiesReentrant ( NULL , BAD_CAST buffer ) ;
if ( result ) {
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " %s " , result ) ;
2000-04-05 18:38:42 +00:00
xmlFree ( result ) ;
}
buffer [ 0 ] = 0 ;
}
/**
* xmlHTMLPrintFileInfo :
* @ input : an xmlParserInputPtr input
*
* Displays the associated file and line informations for the current input
*/
2001-03-24 17:00:36 +00:00
static void
2000-04-05 18:38:42 +00:00
xmlHTMLPrintFileInfo ( xmlParserInputPtr input ) {
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " <p> " ) ;
2000-04-05 18:38:42 +00:00
if ( input ! = NULL ) {
if ( input - > filename ) {
sprintf ( & buffer [ strlen ( buffer ) ] , " %s:%d: " , input - > filename ,
input - > line ) ;
} else {
sprintf ( & buffer [ strlen ( buffer ) ] , " Entity: line %d: " , input - > line ) ;
}
}
xmlHTMLEncodeSend ( ) ;
}
/**
* xmlHTMLPrintFileContext :
* @ input : an xmlParserInputPtr input
*
* Displays current context within the input content for error tracking
*/
2001-03-24 17:00:36 +00:00
static void
2000-04-05 18:38:42 +00:00
xmlHTMLPrintFileContext ( xmlParserInputPtr input ) {
const xmlChar * cur , * base ;
int n ;
if ( input = = NULL ) return ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " <pre> \n " ) ;
2000-04-05 18:38:42 +00:00
cur = input - > cur ;
base = input - > base ;
while ( ( cur > base ) & & ( ( * cur = = ' \n ' ) | | ( * cur = = ' \r ' ) ) ) {
cur - - ;
}
n = 0 ;
while ( ( n + + < 80 ) & & ( cur > base ) & & ( * cur ! = ' \n ' ) & & ( * cur ! = ' \r ' ) )
cur - - ;
if ( ( * cur = = ' \n ' ) | | ( * cur = = ' \r ' ) ) cur + + ;
base = cur ;
n = 0 ;
while ( ( * cur ! = 0 ) & & ( * cur ! = ' \n ' ) & & ( * cur ! = ' \r ' ) & & ( n < 79 ) ) {
sprintf ( & buffer [ strlen ( buffer ) ] , " %c " , ( unsigned char ) * cur + + ) ;
n + + ;
}
sprintf ( & buffer [ strlen ( buffer ) ] , " \n " ) ;
cur = input - > cur ;
while ( ( * cur = = ' \n ' ) | | ( * cur = = ' \r ' ) )
cur - - ;
n = 0 ;
while ( ( cur ! = base ) & & ( n + + < 80 ) ) {
sprintf ( & buffer [ strlen ( buffer ) ] , " " ) ;
base + + ;
}
sprintf ( & buffer [ strlen ( buffer ) ] , " ^ \n " ) ;
xmlHTMLEncodeSend ( ) ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " </pre> " ) ;
2000-04-05 18:38:42 +00:00
}
/**
* xmlHTMLError :
* @ ctx : an XML parser context
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Display and format an error messages , gives file , line , position and
* extra parameters .
*/
2001-03-24 17:00:36 +00:00
static void
2000-04-05 18:38:42 +00:00
xmlHTMLError ( void * ctx , const char * msg , . . . )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlParserInputPtr input ;
xmlParserInputPtr cur = NULL ;
va_list args ;
buffer [ 0 ] = 0 ;
input = ctxt - > input ;
if ( ( input ! = NULL ) & & ( input - > filename = = NULL ) & & ( ctxt - > inputNr > 1 ) ) {
cur = input ;
input = ctxt - > inputTab [ ctxt - > inputNr - 2 ] ;
}
xmlHTMLPrintFileInfo ( input ) ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " <b>error</b>: " ) ;
2000-04-05 18:38:42 +00:00
va_start ( args , msg ) ;
vsprintf ( & buffer [ strlen ( buffer ) ] , msg , args ) ;
va_end ( args ) ;
xmlHTMLEncodeSend ( ) ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " </p> \n " ) ;
2000-04-05 18:38:42 +00:00
xmlHTMLPrintFileContext ( input ) ;
xmlHTMLEncodeSend ( ) ;
}
/**
* xmlHTMLWarning :
* @ ctx : an XML parser context
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Display and format a warning messages , gives file , line , position and
* extra parameters .
*/
2001-03-24 17:00:36 +00:00
static void
2000-04-05 18:38:42 +00:00
xmlHTMLWarning ( void * ctx , const char * msg , . . . )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlParserInputPtr input ;
xmlParserInputPtr cur = NULL ;
va_list args ;
buffer [ 0 ] = 0 ;
input = ctxt - > input ;
if ( ( input ! = NULL ) & & ( input - > filename = = NULL ) & & ( ctxt - > inputNr > 1 ) ) {
cur = input ;
input = ctxt - > inputTab [ ctxt - > inputNr - 2 ] ;
}
xmlHTMLPrintFileInfo ( input ) ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " <b>warning</b>: " ) ;
2000-04-05 18:38:42 +00:00
va_start ( args , msg ) ;
vsprintf ( & buffer [ strlen ( buffer ) ] , msg , args ) ;
va_end ( args ) ;
xmlHTMLEncodeSend ( ) ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " </p> \n " ) ;
2000-04-05 18:38:42 +00:00
xmlHTMLPrintFileContext ( input ) ;
xmlHTMLEncodeSend ( ) ;
}
/**
* xmlHTMLValidityError :
* @ ctx : an XML parser context
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Display and format an validity error messages , gives file ,
* line , position and extra parameters .
*/
2001-03-24 17:00:36 +00:00
static void
2000-04-05 18:38:42 +00:00
xmlHTMLValidityError ( void * ctx , const char * msg , . . . )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlParserInputPtr input ;
va_list args ;
buffer [ 0 ] = 0 ;
input = ctxt - > input ;
if ( ( input - > filename = = NULL ) & & ( ctxt - > inputNr > 1 ) )
input = ctxt - > inputTab [ ctxt - > inputNr - 2 ] ;
xmlHTMLPrintFileInfo ( input ) ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " <b>validity error</b>: " ) ;
2000-04-05 18:38:42 +00:00
va_start ( args , msg ) ;
vsprintf ( & buffer [ strlen ( buffer ) ] , msg , args ) ;
va_end ( args ) ;
xmlHTMLEncodeSend ( ) ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " </p> \n " ) ;
2000-04-05 18:38:42 +00:00
xmlHTMLPrintFileContext ( input ) ;
xmlHTMLEncodeSend ( ) ;
}
/**
* xmlHTMLValidityWarning :
* @ ctx : an XML parser context
* @ msg : the message to display / transmit
* @ . . . : extra parameters for the message display
*
* Display and format a validity warning messages , gives file , line ,
* position and extra parameters .
*/
2001-03-24 17:00:36 +00:00
static void
2000-04-05 18:38:42 +00:00
xmlHTMLValidityWarning ( void * ctx , const char * msg , . . . )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlParserInputPtr input ;
va_list args ;
buffer [ 0 ] = 0 ;
input = ctxt - > input ;
if ( ( input - > filename = = NULL ) & & ( ctxt - > inputNr > 1 ) )
input = ctxt - > inputTab [ ctxt - > inputNr - 2 ] ;
xmlHTMLPrintFileInfo ( input ) ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " <b>validity warning</b>: " ) ;
2000-04-05 18:38:42 +00:00
va_start ( args , msg ) ;
vsprintf ( & buffer [ strlen ( buffer ) ] , msg , args ) ;
va_end ( args ) ;
xmlHTMLEncodeSend ( ) ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " </p> \n " ) ;
2000-04-05 18:38:42 +00:00
xmlHTMLPrintFileContext ( input ) ;
xmlHTMLEncodeSend ( ) ;
}
/************************************************************************
* *
* Shell Interface *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlShellReadline :
* @ prompt : the prompt value
*
* Read a string
*
* Returns a pointer to it or NULL on EOF the caller is expected to
* free the returned string .
*/
2001-03-24 17:00:36 +00:00
static char *
2000-04-05 18:38:42 +00:00
xmlShellReadline ( char * prompt ) {
# ifdef HAVE_LIBREADLINE
char * line_read ;
/* Get a line from the user. */
line_read = readline ( prompt ) ;
/* If the line has any text in it, save it on the history. */
if ( line_read & & * line_read )
add_history ( line_read ) ;
return ( line_read ) ;
# else
char line_read [ 501 ] ;
if ( prompt ! = NULL )
fprintf ( stdout , " %s " , prompt ) ;
if ( ! fgets ( line_read , 500 , stdin ) )
return ( NULL ) ;
line_read [ 500 ] = 0 ;
return ( strdup ( line_read ) ) ;
# endif
}
2000-04-12 13:27:38 +00:00
/************************************************************************
* *
* I / O Interfaces *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-24 17:00:36 +00:00
static int myRead ( FILE * f , char * buf , int len ) {
return ( fread ( buf , 1 , len , f ) ) ;
2000-04-12 13:27:38 +00:00
}
2001-03-24 17:00:36 +00:00
static void myClose ( FILE * f ) {
2001-01-03 13:32:39 +00:00
if ( f ! = stdin ) {
2000-04-12 13:27:38 +00:00
fclose ( f ) ;
2001-01-03 13:32:39 +00:00
}
2000-04-12 13:27:38 +00:00
}
2000-04-05 18:38:42 +00:00
/************************************************************************
* *
* Test processing *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-24 17:00:36 +00:00
static void parseAndPrintFile ( char * filename ) {
2000-04-05 18:38:42 +00:00
xmlDocPtr doc = NULL , tmp ;
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) )
gettimeofday ( & begin , NULL ) ;
2001-04-11 07:50:02 +00:00
if ( filename = = NULL ) {
if ( generate ) {
xmlNodePtr n ;
doc = xmlNewDoc ( BAD_CAST " 1.0 " ) ;
n = xmlNewNode ( NULL , BAD_CAST " info " ) ;
xmlNodeSetContent ( n , BAD_CAST " abc " ) ;
xmlDocSetRootElement ( doc , n ) ;
}
}
2000-04-05 18:38:42 +00:00
# ifdef LIBXML_HTML_ENABLED
2001-04-11 07:50:02 +00:00
else if ( html ) {
2000-04-05 18:38:42 +00:00
doc = htmlParseFile ( filename , NULL ) ;
2001-04-11 07:50:02 +00:00
}
2000-04-05 18:38:42 +00:00
# endif /* LIBXML_HTML_ENABLED */
2001-04-11 07:50:02 +00:00
else {
2000-04-05 18:38:42 +00:00
/*
* build an XML tree from a string ;
*/
if ( push ) {
FILE * f ;
2001-01-03 13:32:39 +00:00
/* '-' Usually means stdin -<sven@zen.org> */
if ( ( filename [ 0 ] = = ' - ' ) & & ( filename [ 1 ] = = 0 ) ) {
f = stdin ;
} else {
f = fopen ( filename , " r " ) ;
}
2000-04-05 18:38:42 +00:00
if ( f ! = NULL ) {
2000-08-29 18:29:38 +00:00
int ret ;
2000-04-05 18:38:42 +00:00
int res , size = 3 ;
char chars [ 1024 ] ;
xmlParserCtxtPtr ctxt ;
if ( repeat )
size = 1024 ;
res = fread ( chars , 1 , 4 , f ) ;
if ( res > 0 ) {
ctxt = xmlCreatePushParserCtxt ( NULL , NULL ,
chars , res , filename ) ;
while ( ( res = fread ( chars , 1 , size , f ) ) > 0 ) {
xmlParseChunk ( ctxt , chars , res , 0 ) ;
}
xmlParseChunk ( ctxt , chars , 0 , 1 ) ;
doc = ctxt - > myDoc ;
2000-08-29 18:29:38 +00:00
ret = ctxt - > wellFormed ;
2000-04-05 18:38:42 +00:00
xmlFreeParserCtxt ( ctxt ) ;
2000-08-29 18:29:38 +00:00
if ( ! ret ) {
xmlFreeDoc ( doc ) ;
doc = NULL ;
}
2000-04-05 18:38:42 +00:00
}
}
2000-04-12 13:27:38 +00:00
} else if ( testIO ) {
int ret ;
FILE * f ;
2001-01-03 13:32:39 +00:00
/* '-' Usually means stdin -<sven@zen.org> */
if ( ( filename [ 0 ] = = ' - ' ) & & ( filename [ 1 ] = = 0 ) ) {
f = stdin ;
} else {
f = fopen ( filename , " r " ) ;
}
2000-04-12 13:27:38 +00:00
if ( f ! = NULL ) {
xmlParserCtxtPtr ctxt ;
ctxt = xmlCreateIOParserCtxt ( NULL , NULL ,
( xmlInputReadCallback ) myRead ,
( xmlInputCloseCallback ) myClose ,
f , XML_CHAR_ENCODING_NONE ) ;
xmlParseDocument ( ctxt ) ;
ret = ctxt - > wellFormed ;
doc = ctxt - > myDoc ;
xmlFreeParserCtxt ( ctxt ) ;
if ( ! ret ) {
xmlFreeDoc ( doc ) ;
doc = NULL ;
}
}
2000-04-05 18:38:42 +00:00
} else if ( recovery ) {
doc = xmlRecoverFile ( filename ) ;
} else if ( htmlout ) {
int ret ;
xmlParserCtxtPtr ctxt ;
xmlSAXHandler silent , * old ;
ctxt = xmlCreateFileParserCtxt ( filename ) ;
2000-08-04 18:23:10 +00:00
if ( ctxt = = NULL ) {
/* If xmlCreateFileParseCtxt() return NULL something
strange happened so we don ' t want to do anything . Do
we want to print an error message here ?
< sven @ zen . org > */
2000-08-04 18:24:45 +00:00
doc = NULL ;
2000-08-04 18:23:10 +00:00
} else {
memcpy ( & silent , ctxt - > sax , sizeof ( silent ) ) ;
old = ctxt - > sax ;
silent . error = xmlHTMLError ;
if ( xmlGetWarningsDefaultValue )
2000-04-05 18:38:42 +00:00
silent . warning = xmlHTMLWarning ;
2000-08-04 18:23:10 +00:00
else
2000-04-05 18:38:42 +00:00
silent . warning = NULL ;
2000-08-04 18:23:10 +00:00
silent . fatalError = xmlHTMLError ;
ctxt - > sax = & silent ;
ctxt - > vctxt . error = xmlHTMLValidityError ;
if ( xmlGetWarningsDefaultValue )
2000-04-05 18:38:42 +00:00
ctxt - > vctxt . warning = xmlHTMLValidityWarning ;
2000-08-04 18:23:10 +00:00
else
2000-04-05 18:38:42 +00:00
ctxt - > vctxt . warning = NULL ;
2000-08-04 18:23:10 +00:00
xmlParseDocument ( ctxt ) ;
2000-04-05 18:38:42 +00:00
2000-08-04 18:23:10 +00:00
ret = ctxt - > wellFormed ;
doc = ctxt - > myDoc ;
ctxt - > sax = old ;
xmlFreeParserCtxt ( ctxt ) ;
if ( ! ret ) {
2000-04-05 18:38:42 +00:00
xmlFreeDoc ( doc ) ;
doc = NULL ;
2000-08-04 18:23:10 +00:00
}
2000-04-05 18:38:42 +00:00
}
2000-07-21 20:32:03 +00:00
# ifdef HAVE_SYS_MMAN_H
} else if ( memory ) {
int fd ;
struct stat info ;
const char * base ;
if ( stat ( filename , & info ) < 0 )
return ;
if ( ( fd = open ( filename , O_RDONLY ) ) < 0 )
return ;
base = mmap ( NULL , info . st_size , PROT_READ , MAP_SHARED , fd , 0 ) ;
2000-08-14 17:57:48 +00:00
if ( base = = ( void * ) MAP_FAILED )
2000-07-21 20:32:03 +00:00
return ;
doc = xmlParseMemory ( ( char * ) base , info . st_size ) ;
munmap ( ( char * ) base , info . st_size ) ;
# endif
2000-04-05 18:38:42 +00:00
} else
doc = xmlParseFile ( filename ) ;
}
2000-08-04 18:23:10 +00:00
/*
* If we don ' t have a document we might as well give up . Do we
* want an error message here ? < sven @ zen . org > */
2000-11-06 16:43:11 +00:00
if ( doc = = NULL ) {
2001-02-23 18:44:52 +00:00
progresult = 1 ;
2000-08-04 18:23:10 +00:00
return ;
2000-11-06 16:43:11 +00:00
}
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
long msec ;
gettimeofday ( & end , NULL ) ;
msec = end . tv_sec - begin . tv_sec ;
msec * = 1000 ;
msec + = ( end . tv_usec - begin . tv_usec ) / 1000 ;
fprintf ( stderr , " Parsing took %ld ms \n " , msec ) ;
}
2000-11-06 16:43:11 +00:00
# ifdef LIBXML_XINCLUDE_ENABLED
2001-02-25 16:11:03 +00:00
if ( xinclude ) {
if ( ( timing ) & & ( ! repeat ) ) {
gettimeofday ( & begin , NULL ) ;
}
2000-11-06 16:43:11 +00:00
xmlXIncludeProcess ( doc ) ;
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
long msec ;
gettimeofday ( & end , NULL ) ;
msec = end . tv_sec - begin . tv_sec ;
msec * = 1000 ;
msec + = ( end . tv_usec - begin . tv_usec ) / 1000 ;
fprintf ( stderr , " Xinclude processing took %ld ms \n " , msec ) ;
}
}
2000-11-06 16:43:11 +00:00
# endif
2000-08-04 18:23:10 +00:00
2000-04-05 18:38:42 +00:00
# ifdef LIBXML_DEBUG_ENABLED
/*
* shell interraction
*/
if ( shell )
xmlShell ( doc , filename , xmlShellReadline , stdout ) ;
# endif
/*
* test intermediate copy if needed .
*/
if ( copy ) {
tmp = doc ;
doc = xmlCopyDoc ( doc , 1 ) ;
xmlFreeDoc ( tmp ) ;
}
if ( ( insert ) & & ( ! html ) ) {
const xmlChar * list [ 256 ] ;
int nb , i ;
xmlNodePtr node ;
if ( doc - > children ! = NULL ) {
node = doc - > children ;
while ( ( node ! = NULL ) & & ( node - > last = = NULL ) ) node = node - > next ;
if ( node ! = NULL ) {
nb = xmlValidGetValidElements ( node - > last , NULL , list , 256 ) ;
if ( nb < 0 ) {
printf ( " could not get valid list of elements \n " ) ;
} else if ( nb = = 0 ) {
printf ( " No element can be indersted under root \n " ) ;
} else {
printf ( " %d element types can be indersted under root: \n " ,
nb ) ;
for ( i = 0 ; i < nb ; i + + ) {
printf ( " %s \n " , list [ i ] ) ;
}
}
}
}
} else if ( noout = = 0 ) {
/*
* print it .
*/
# ifdef LIBXML_DEBUG_ENABLED
if ( ! debug ) {
# endif
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
gettimeofday ( & begin , NULL ) ;
}
2001-04-04 00:09:00 +00:00
# ifdef HAVE_SYS_MMAN_H
2000-12-27 10:46:47 +00:00
if ( memory ) {
xmlChar * result ;
int len ;
if ( encoding ! = NULL ) {
xmlDocDumpMemoryEnc ( doc , & result , & len , encoding ) ;
} else {
xmlDocDumpMemory ( doc , & result , & len ) ;
}
if ( result = = NULL ) {
fprintf ( stderr , " Failed to save \n " ) ;
} else {
write ( 1 , result , len ) ;
xmlFree ( result ) ;
}
2001-04-04 00:09:00 +00:00
} else
# endif /* HAVE_SYS_MMAN_H */
if ( compress )
2000-04-05 18:38:42 +00:00
xmlSaveFile ( " - " , doc ) ;
2000-06-28 23:40:59 +00:00
else if ( encoding ! = NULL )
xmlSaveFileEnc ( " - " , doc , encoding ) ;
2000-04-05 18:38:42 +00:00
else
xmlDocDump ( stdout , doc ) ;
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
long msec ;
gettimeofday ( & end , NULL ) ;
msec = end . tv_sec - begin . tv_sec ;
msec * = 1000 ;
msec + = ( end . tv_usec - begin . tv_usec ) / 1000 ;
fprintf ( stderr , " Saving took %ld ms \n " , msec ) ;
}
2000-04-05 18:38:42 +00:00
# ifdef LIBXML_DEBUG_ENABLED
2000-12-27 10:46:47 +00:00
} else {
2000-04-05 18:38:42 +00:00
xmlDebugDumpDocument ( stdout , doc ) ;
2000-12-27 10:46:47 +00:00
}
2000-04-05 18:38:42 +00:00
# endif
}
/*
* A posteriori validation test
*/
2000-10-11 15:57:05 +00:00
if ( dtdvalid ! = NULL ) {
xmlDtdPtr dtd ;
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
gettimeofday ( & begin , NULL ) ;
}
2000-10-11 15:57:05 +00:00
dtd = xmlParseDTD ( NULL , ( const xmlChar * ) dtdvalid ) ;
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
long msec ;
gettimeofday ( & end , NULL ) ;
msec = end . tv_sec - begin . tv_sec ;
msec * = 1000 ;
msec + = ( end . tv_usec - begin . tv_usec ) / 1000 ;
fprintf ( stderr , " Parsing DTD took %ld ms \n " , msec ) ;
}
2000-10-11 15:57:05 +00:00
if ( dtd = = NULL ) {
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" Could not parse DTD %s \n " , dtdvalid ) ;
2001-02-23 18:44:52 +00:00
progresult = 2 ;
2000-10-11 15:57:05 +00:00
} else {
xmlValidCtxt cvp ;
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
gettimeofday ( & begin , NULL ) ;
}
2000-10-11 15:57:05 +00:00
cvp . userData = ( void * ) stderr ; cvp . error = ( xmlValidityErrorFunc ) fprintf ; cvp . warning = ( xmlValidityWarningFunc ) fprintf ;
if ( ! xmlValidateDtd ( & cvp , doc , dtd ) ) {
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" Document %s does not validate against %s \n " ,
2000-10-11 15:57:05 +00:00
filename , dtdvalid ) ;
2001-02-23 18:44:52 +00:00
progresult = 3 ;
2000-10-11 15:57:05 +00:00
}
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
long msec ;
gettimeofday ( & end , NULL ) ;
msec = end . tv_sec - begin . tv_sec ;
msec * = 1000 ;
msec + = ( end . tv_usec - begin . tv_usec ) / 1000 ;
fprintf ( stderr , " Validating against DTD took %ld ms \n " , msec ) ;
}
2000-10-11 15:57:05 +00:00
xmlFreeDtd ( dtd ) ;
}
} else if ( postvalid ) {
2000-04-05 18:38:42 +00:00
xmlValidCtxt cvp ;
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
gettimeofday ( & begin , NULL ) ;
}
2000-04-05 18:38:42 +00:00
cvp . userData = ( void * ) stderr ; cvp . error = ( xmlValidityErrorFunc ) fprintf ; cvp . warning = ( xmlValidityWarningFunc ) fprintf ;
2000-10-11 15:57:05 +00:00
if ( ! xmlValidateDocument ( & cvp , doc ) ) {
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" Document %s does not validate \n " , filename ) ;
2001-02-23 18:44:52 +00:00
progresult = 3 ;
2000-10-11 15:57:05 +00:00
}
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
long msec ;
gettimeofday ( & end , NULL ) ;
msec = end . tv_sec - begin . tv_sec ;
msec * = 1000 ;
msec + = ( end . tv_usec - begin . tv_usec ) / 1000 ;
fprintf ( stderr , " Validating took %ld ms \n " , msec ) ;
}
2000-04-05 18:38:42 +00:00
}
# ifdef LIBXML_DEBUG_ENABLED
if ( ( debugent ) & & ( ! html ) )
2000-08-26 21:40:43 +00:00
xmlDebugDumpEntities ( stderr , doc ) ;
2000-04-05 18:38:42 +00:00
# endif
/*
* free it .
*/
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
gettimeofday ( & begin , NULL ) ;
}
2000-04-05 18:38:42 +00:00
xmlFreeDoc ( doc ) ;
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( ! repeat ) ) {
long msec ;
gettimeofday ( & end , NULL ) ;
msec = end . tv_sec - begin . tv_sec ;
msec * = 1000 ;
msec + = ( end . tv_usec - begin . tv_usec ) / 1000 ;
fprintf ( stderr , " Freeing took %ld ms \n " , msec ) ;
}
2000-04-05 18:38:42 +00:00
}
2001-01-03 13:32:39 +00:00
int
main ( int argc , char * * argv ) {
2000-04-05 18:38:42 +00:00
int i , count ;
int files = 0 ;
2000-06-28 23:40:59 +00:00
LIBXML_TEST_VERSION
2000-04-05 18:38:42 +00:00
for ( i = 1 ; i < argc ; i + + ) {
# ifdef LIBXML_DEBUG_ENABLED
if ( ( ! strcmp ( argv [ i ] , " -debug " ) ) | | ( ! strcmp ( argv [ i ] , " --debug " ) ) )
debug + + ;
else if ( ( ! strcmp ( argv [ i ] , " -shell " ) ) | |
( ! strcmp ( argv [ i ] , " --shell " ) ) ) {
shell + + ;
noout = 1 ;
} else
# endif
if ( ( ! strcmp ( argv [ i ] , " -copy " ) ) | | ( ! strcmp ( argv [ i ] , " --copy " ) ) )
copy + + ;
else if ( ( ! strcmp ( argv [ i ] , " -recover " ) ) | |
( ! strcmp ( argv [ i ] , " --recover " ) ) )
recovery + + ;
else if ( ( ! strcmp ( argv [ i ] , " -noent " ) ) | |
( ! strcmp ( argv [ i ] , " --noent " ) ) )
noent + + ;
else if ( ( ! strcmp ( argv [ i ] , " -noout " ) ) | |
( ! strcmp ( argv [ i ] , " --noout " ) ) )
noout + + ;
else if ( ( ! strcmp ( argv [ i ] , " -htmlout " ) ) | |
( ! strcmp ( argv [ i ] , " --htmlout " ) ) )
htmlout + + ;
# ifdef LIBXML_HTML_ENABLED
else if ( ( ! strcmp ( argv [ i ] , " -html " ) ) | |
( ! strcmp ( argv [ i ] , " --html " ) ) ) {
html + + ;
}
# endif /* LIBXML_HTML_ENABLED */
else if ( ( ! strcmp ( argv [ i ] , " -nowrap " ) ) | |
( ! strcmp ( argv [ i ] , " --nowrap " ) ) )
nowrap + + ;
else if ( ( ! strcmp ( argv [ i ] , " -valid " ) ) | |
( ! strcmp ( argv [ i ] , " --valid " ) ) )
valid + + ;
else if ( ( ! strcmp ( argv [ i ] , " -postvalid " ) ) | |
( ! strcmp ( argv [ i ] , " --postvalid " ) ) )
postvalid + + ;
2000-10-11 15:57:05 +00:00
else if ( ( ! strcmp ( argv [ i ] , " -dtdvalid " ) ) | |
( ! strcmp ( argv [ i ] , " --dtdvalid " ) ) ) {
i + + ;
dtdvalid = argv [ i ] ;
}
2000-04-05 18:38:42 +00:00
else if ( ( ! strcmp ( argv [ i ] , " -insert " ) ) | |
( ! strcmp ( argv [ i ] , " --insert " ) ) )
insert + + ;
2001-02-25 16:11:03 +00:00
else if ( ( ! strcmp ( argv [ i ] , " -timing " ) ) | |
( ! strcmp ( argv [ i ] , " --timing " ) ) )
timing + + ;
2001-04-11 07:50:02 +00:00
else if ( ( ! strcmp ( argv [ i ] , " -auto " ) ) | |
( ! strcmp ( argv [ i ] , " --auto " ) ) )
generate + + ;
2000-04-05 18:38:42 +00:00
else if ( ( ! strcmp ( argv [ i ] , " -repeat " ) ) | |
( ! strcmp ( argv [ i ] , " --repeat " ) ) )
repeat + + ;
else if ( ( ! strcmp ( argv [ i ] , " -push " ) ) | |
( ! strcmp ( argv [ i ] , " --push " ) ) )
push + + ;
2000-07-21 20:32:03 +00:00
# ifdef HAVE_SYS_MMAN_H
else if ( ( ! strcmp ( argv [ i ] , " -memory " ) ) | |
( ! strcmp ( argv [ i ] , " --memory " ) ) )
memory + + ;
# endif
2000-04-12 13:27:38 +00:00
else if ( ( ! strcmp ( argv [ i ] , " -testIO " ) ) | |
( ! strcmp ( argv [ i ] , " --testIO " ) ) )
testIO + + ;
2000-11-06 16:43:11 +00:00
# ifdef LIBXML_XINCLUDE_ENABLED
else if ( ( ! strcmp ( argv [ i ] , " -xinclude " ) ) | |
( ! strcmp ( argv [ i ] , " --xinclude " ) ) )
xinclude + + ;
# endif
2000-04-05 18:38:42 +00:00
else if ( ( ! strcmp ( argv [ i ] , " -compress " ) ) | |
( ! strcmp ( argv [ i ] , " --compress " ) ) ) {
compress + + ;
xmlSetCompressMode ( 9 ) ;
}
else if ( ( ! strcmp ( argv [ i ] , " -nowarning " ) ) | |
( ! strcmp ( argv [ i ] , " --nowarning " ) ) ) {
xmlGetWarningsDefaultValue = 0 ;
2000-08-26 21:40:43 +00:00
xmlPedanticParserDefault ( 0 ) ;
}
else if ( ( ! strcmp ( argv [ i ] , " -pedantic " ) ) | |
( ! strcmp ( argv [ i ] , " --pedantic " ) ) ) {
xmlGetWarningsDefaultValue = 1 ;
xmlPedanticParserDefault ( 1 ) ;
2000-04-05 18:38:42 +00:00
}
2000-09-22 16:07:02 +00:00
# ifdef LIBXML_DEBUG_ENABLED
2000-08-26 21:40:43 +00:00
else if ( ( ! strcmp ( argv [ i ] , " -debugent " ) ) | |
( ! strcmp ( argv [ i ] , " --debugent " ) ) ) {
debugent + + ;
xmlParserDebugEntities = 1 ;
}
2001-05-22 15:08:55 +00:00
# endif
# ifdef LIBXML_CATALOG_ENABLED
else if ( ( ! strcmp ( argv [ i ] , " -catalogs " ) ) | |
( ! strcmp ( argv [ i ] , " --catalogs " ) ) ) {
const char * catalogs ;
catalogs = getenv ( " SGML_CATALOG_FILES " ) ;
if ( catalogs = = NULL ) {
fprintf ( stderr , " Variable $SGML_CATALOG_FILES not set \n " ) ;
} else {
xmlLoadCatalogs ( catalogs ) ;
}
}
2000-09-22 16:07:02 +00:00
# endif
2000-06-28 23:40:59 +00:00
else if ( ( ! strcmp ( argv [ i ] , " -encode " ) ) | |
( ! strcmp ( argv [ i ] , " --encode " ) ) ) {
i + + ;
encoding = argv [ i ] ;
2000-08-26 21:40:43 +00:00
/*
* OK it ' s for testing purposes
*/
xmlAddEncodingAlias ( " UTF-8 " , " DVEnc " ) ;
2000-06-28 23:40:59 +00:00
}
2000-04-05 18:38:42 +00:00
else if ( ( ! strcmp ( argv [ i ] , " -noblanks " ) ) | |
( ! strcmp ( argv [ i ] , " --noblanks " ) ) ) {
noblanks + + ;
xmlKeepBlanksDefault ( 0 ) ;
}
}
if ( noent ! = 0 ) xmlSubstituteEntitiesDefault ( 1 ) ;
if ( valid ! = 0 ) xmlDoValidityCheckingDefaultValue = 1 ;
if ( ( htmlout ) & & ( ! nowrap ) ) {
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
2000-04-05 18:38:42 +00:00
" <!DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.0 Transitional//EN \" \n " ) ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" \t \" http://www.w3.org/TR/REC-html40/loose.dtd \" > \n " ) ;
xmlGenericError ( xmlGenericErrorContext ,
2000-04-05 18:38:42 +00:00
" <html><head><title>%s output</title></head> \n " ,
argv [ 0 ] ) ;
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
2000-04-05 18:38:42 +00:00
" <body bgcolor= \" #ffffff \" ><h1 align= \" center \" >%s output</h1> \n " ,
argv [ 0 ] ) ;
}
for ( i = 1 ; i < argc ; i + + ) {
2000-06-28 23:40:59 +00:00
if ( ( ! strcmp ( argv [ i ] , " -encode " ) ) | |
( ! strcmp ( argv [ i ] , " --encode " ) ) ) {
i + + ;
continue ;
}
2000-10-11 15:57:05 +00:00
if ( ( ! strcmp ( argv [ i ] , " -dtdvalid " ) ) | |
( ! strcmp ( argv [ i ] , " --dtdvalid " ) ) ) {
i + + ;
continue ;
}
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( repeat ) )
gettimeofday ( & begin , NULL ) ;
2001-01-03 13:32:39 +00:00
/* Remember file names. "-" means stding. <sven@zen.org> */
if ( ( argv [ i ] [ 0 ] ! = ' - ' ) | | ( strcmp ( argv [ i ] , " - " ) = = 0 ) ) {
2000-04-05 18:38:42 +00:00
if ( repeat ) {
for ( count = 0 ; count < 100 * repeat ; count + + )
parseAndPrintFile ( argv [ i ] ) ;
} else
parseAndPrintFile ( argv [ i ] ) ;
files + + ;
}
2001-02-25 16:11:03 +00:00
if ( ( timing ) & & ( repeat ) ) {
long msec ;
gettimeofday ( & end , NULL ) ;
msec = end . tv_sec - begin . tv_sec ;
msec * = 1000 ;
msec + = ( end . tv_usec - begin . tv_usec ) / 1000 ;
fprintf ( stderr , " 100 iteration took %ld ms \n " , msec ) ;
}
2000-04-05 18:38:42 +00:00
}
2001-04-11 07:50:02 +00:00
if ( generate )
parseAndPrintFile ( NULL ) ;
2000-04-05 18:38:42 +00:00
if ( ( htmlout ) & & ( ! nowrap ) ) {
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " </body></html> \n " ) ;
2000-04-05 18:38:42 +00:00
}
2001-04-11 07:50:02 +00:00
if ( ( files = = 0 ) & & ( ! generate ) ) {
2001-02-25 16:11:03 +00:00
printf ( " Usage : %s [options] XMLfiles ... \n " ,
2000-04-05 18:38:42 +00:00
argv [ 0 ] ) ;
printf ( " \t Parse the XML files and output the result of the parsing \n " ) ;
# ifdef LIBXML_DEBUG_ENABLED
printf ( " \t --debug : dump a debug tree of the in-memory document \n " ) ;
printf ( " \t --shell : run a navigating shell \n " ) ;
printf ( " \t --debugent : debug the entities defined in the document \n " ) ;
# endif
printf ( " \t --copy : used to test the internal copy implementation \n " ) ;
printf ( " \t --recover : output what was parsable on broken XML documents \n " ) ;
printf ( " \t --noent : substitute entity references by their value \n " ) ;
printf ( " \t --noout : don't output the result tree \n " ) ;
printf ( " \t --htmlout : output results as HTML \n " ) ;
printf ( " \t --nowarp : do not put HTML doc wrapper \n " ) ;
printf ( " \t --valid : validate the document in addition to std well-formed check \n " ) ;
printf ( " \t --postvalid : do a posteriori validation, i.e after parsing \n " ) ;
2000-10-11 15:57:05 +00:00
printf ( " \t --dtdvalid URL : do a posteriori validation against a given DTD \n " ) ;
2001-02-25 16:11:03 +00:00
printf ( " \t --timing : print some timings \n " ) ;
2000-04-05 18:38:42 +00:00
printf ( " \t --repeat : repeat 100 times, for timing or profiling \n " ) ;
printf ( " \t --insert : ad-hoc test for valid insertions \n " ) ;
printf ( " \t --compress : turn on gzip compression of output \n " ) ;
# ifdef LIBXML_HTML_ENABLED
printf ( " \t --html : use the HTML parser \n " ) ;
# endif
printf ( " \t --push : use the push mode of the parser \n " ) ;
2000-07-21 20:32:03 +00:00
# ifdef HAVE_SYS_MMAN_H
printf ( " \t --memory : parse from memory \n " ) ;
# endif
2000-04-05 18:38:42 +00:00
printf ( " \t --nowarning : do not emit warnings from parser/validator \n " ) ;
printf ( " \t --noblanks : drop (ignorable?) blanks spaces \n " ) ;
2000-04-12 13:27:38 +00:00
printf ( " \t --testIO : test user I/O support \n " ) ;
2000-07-14 14:49:25 +00:00
printf ( " \t --encode encoding : output in the given encoding \n " ) ;
2001-05-22 15:08:55 +00:00
# ifdef LIBXML_CATALOG_ENABLED
printf ( " \t --catalogs : use the catalogs from $SGML_CATALOG_FILES \n " ) ;
# endif
2001-04-11 07:50:02 +00:00
printf ( " \t --auto : generate a small doc on the fly \n " ) ;
2000-11-06 16:43:11 +00:00
# ifdef LIBXML_XINCLUDE_ENABLED
printf ( " \t --xinclude : do XInclude processing \n " ) ;
# endif
2000-04-05 18:38:42 +00:00
}
xmlCleanupParser ( ) ;
xmlMemoryDump ( ) ;
2001-02-23 18:44:52 +00:00
return ( progresult ) ;
2000-04-05 18:38:42 +00:00
}
2000-08-04 18:23:10 +00:00