2001-02-23 20:55:21 +03:00
/*
* debugXML . c : This is a set of routines used for debugging the tree
* produced by the XML parser .
*
* See Copyright for the status of this software .
*
2001-06-24 16:13:24 +04:00
* Daniel Veillard < daniel @ veillard . com >
2001-02-23 20:55:21 +03:00
*/
2002-03-18 22:37:11 +03:00
# define IN_LIBXML
2001-04-21 20:57:29 +04:00
# include "libxml.h"
2001-02-23 20:55:21 +03:00
# ifdef LIBXML_DEBUG_ENABLED
# include <string.h>
# include <stdlib.h>
2022-03-02 02:29:17 +03:00
2001-02-23 20:55:21 +03:00
# include <libxml/xmlmemory.h>
# include <libxml/tree.h>
# include <libxml/parser.h>
2001-08-01 19:53:47 +04:00
# include <libxml/parserInternals.h>
2001-02-23 20:55:21 +03:00
# include <libxml/debugXML.h>
# include <libxml/HTMLtree.h>
# include <libxml/HTMLparser.h>
# include <libxml/xmlerror.h>
2002-02-10 16:20:39 +03:00
# include <libxml/xpathInternals.h>
2003-04-27 19:59:00 +04:00
# include <libxml/uri.h>
2004-02-21 14:53:09 +03:00
# ifdef LIBXML_SCHEMAS_ENABLED
# include <libxml/relaxng.h>
# endif
2001-02-23 20:55:21 +03:00
2022-08-26 02:22:33 +03:00
# include "private/error.h"
2005-08-25 18:03:56 +04:00
# define DUMP_TEXT_TYPE 1
2004-10-04 18:09:17 +04:00
typedef struct _xmlDebugCtxt xmlDebugCtxt ;
typedef xmlDebugCtxt * xmlDebugCtxtPtr ;
struct _xmlDebugCtxt {
FILE * output ; /* the output file */
char shift [ 101 ] ; /* used for indenting */
int depth ; /* current depth */
xmlDocPtr doc ; /* current document */
2004-10-07 17:14:19 +04:00
xmlNodePtr node ; /* current node */
2016-04-13 17:56:07 +03:00
xmlDictPtr dict ; /* the doc dictionary */
2004-10-04 18:09:17 +04:00
int check ; /* do just checkings */
2004-10-07 17:14:19 +04:00
int errors ; /* number of errors found */
2016-04-13 17:56:07 +03:00
int nodict ; /* if the document has no dictionary */
2005-08-25 18:03:56 +04:00
int options ; /* options */
2004-10-04 18:09:17 +04:00
} ;
static void xmlCtxtDumpNodeList ( xmlDebugCtxtPtr ctxt , xmlNodePtr node ) ;
static void
xmlCtxtDumpInitCtxt ( xmlDebugCtxtPtr ctxt )
2001-07-18 23:30:27 +04:00
{
2001-02-23 20:55:21 +03:00
int i ;
2001-07-18 23:30:27 +04:00
2004-10-04 18:09:17 +04:00
ctxt - > depth = 0 ;
ctxt - > check = 0 ;
2004-10-07 17:14:19 +04:00
ctxt - > errors = 0 ;
2004-10-04 18:09:17 +04:00
ctxt - > output = stdout ;
2004-10-26 20:06:51 +04:00
ctxt - > doc = NULL ;
ctxt - > node = NULL ;
ctxt - > dict = NULL ;
2004-10-27 21:29:04 +04:00
ctxt - > nodict = 0 ;
2005-08-25 18:18:56 +04:00
ctxt - > options = 0 ;
2004-10-04 18:09:17 +04:00
for ( i = 0 ; i < 100 ; i + + )
ctxt - > shift [ i ] = ' ' ;
ctxt - > shift [ 100 ] = 0 ;
}
2004-10-10 00:39:04 +04:00
static void
2004-10-15 22:25:33 +04:00
xmlCtxtDumpCleanCtxt ( xmlDebugCtxtPtr ctxt ATTRIBUTE_UNUSED )
2004-10-10 00:39:04 +04:00
{
2004-10-15 22:25:33 +04:00
/* remove the ATTRIBUTE_UNUSED when this is added */
2004-10-10 00:39:04 +04:00
}
/**
2004-10-11 16:28:34 +04:00
* xmlNsCheckScope :
* @ node : the node
* @ ns : the namespace node
2004-10-10 00:39:04 +04:00
*
2004-10-11 16:28:34 +04:00
* Check that a given namespace is in scope on a node .
2004-10-10 00:39:04 +04:00
*
2012-09-11 09:26:36 +04:00
* Returns 1 if in scope , - 1 in case of argument error ,
2004-10-11 16:28:34 +04:00
* - 2 if the namespace is not in scope , and - 3 if not on
* an ancestor node .
2004-10-10 00:39:04 +04:00
*/
static int
2004-10-11 16:28:34 +04:00
xmlNsCheckScope ( xmlNodePtr node , xmlNsPtr ns )
2004-10-10 00:39:04 +04:00
{
2004-10-11 16:28:34 +04:00
xmlNsPtr cur ;
2004-10-10 00:39:04 +04:00
2004-10-11 16:28:34 +04:00
if ( ( node = = NULL ) | | ( ns = = NULL ) )
return ( - 1 ) ;
if ( ( node - > type ! = XML_ELEMENT_NODE ) & &
( node - > type ! = XML_ATTRIBUTE_NODE ) & &
( node - > type ! = XML_DOCUMENT_NODE ) & &
( node - > type ! = XML_TEXT_NODE ) & &
( node - > type ! = XML_HTML_DOCUMENT_NODE ) & &
( node - > type ! = XML_XINCLUDE_START ) )
return ( - 2 ) ;
2004-10-10 00:39:04 +04:00
2004-10-11 16:28:34 +04:00
while ( ( node ! = NULL ) & &
( ( node - > type = = XML_ELEMENT_NODE ) | |
( node - > type = = XML_ATTRIBUTE_NODE ) | |
( node - > type = = XML_TEXT_NODE ) | |
( node - > type = = XML_XINCLUDE_START ) ) ) {
if ( ( node - > type = = XML_ELEMENT_NODE ) | |
( node - > type = = XML_XINCLUDE_START ) ) {
cur = node - > nsDef ;
while ( cur ! = NULL ) {
if ( cur = = ns )
return ( 1 ) ;
if ( xmlStrEqual ( cur - > prefix , ns - > prefix ) )
return ( - 2 ) ;
cur = cur - > next ;
}
}
node = node - > parent ;
2004-10-10 00:39:04 +04:00
}
2024-03-17 18:23:31 +03:00
/* the xml namespace may be declared on the document node */
if ( ( node ! = NULL ) & &
( ( node - > type = = XML_DOCUMENT_NODE ) | |
( node - > type = = XML_HTML_DOCUMENT_NODE ) ) ) {
xmlNsPtr oldNs = ( ( xmlDocPtr ) node ) - > oldNs ;
if ( oldNs = = ns )
return ( 1 ) ;
}
2004-10-11 16:28:34 +04:00
return ( - 3 ) ;
2004-10-10 00:39:04 +04:00
}
2004-10-11 16:28:34 +04:00
2004-10-04 18:09:17 +04:00
static void
xmlCtxtDumpSpaces ( xmlDebugCtxtPtr ctxt )
{
if ( ctxt - > check )
return ;
if ( ( ctxt - > output ! = NULL ) & & ( ctxt - > depth > 0 ) ) {
if ( ctxt - > depth < 50 )
2009-06-04 13:22:45 +04:00
fprintf ( ctxt - > output , " %s " , & ctxt - > shift [ 100 - 2 * ctxt - > depth ] ) ;
2004-10-04 18:09:17 +04:00
else
2009-06-04 13:22:45 +04:00
fprintf ( ctxt - > output , " %s " , ctxt - > shift ) ;
2004-10-04 18:09:17 +04:00
}
}
2004-10-07 17:14:19 +04:00
/**
* xmlDebugErr :
* @ ctxt : a debug context
* @ error : the error code
*
* Handle a debug error .
*/
static void
xmlDebugErr ( xmlDebugCtxtPtr ctxt , int error , const char * msg )
{
ctxt - > errors + + ;
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output , " ERROR %d: %s " , error , msg ) ;
2004-10-07 17:14:19 +04:00
}
2016-05-13 10:13:17 +03:00
static void LIBXML_ATTR_FORMAT ( 3 , 0 )
2004-10-07 17:14:19 +04:00
xmlDebugErr2 ( xmlDebugCtxtPtr ctxt , int error , const char * msg , int extra )
{
ctxt - > errors + + ;
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output , " ERROR %d: " , error ) ;
fprintf ( ctxt - > output , msg , extra ) ;
2004-10-07 17:14:19 +04:00
}
2016-05-13 10:13:17 +03:00
static void LIBXML_ATTR_FORMAT ( 3 , 0 )
2004-10-15 18:50:10 +04:00
xmlDebugErr3 ( xmlDebugCtxtPtr ctxt , int error , const char * msg , const char * extra )
2004-10-07 17:14:19 +04:00
{
ctxt - > errors + + ;
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output , " ERROR %d: " , error ) ;
fprintf ( ctxt - > output , msg , extra ) ;
2004-10-07 17:14:19 +04:00
}
2004-10-11 16:28:34 +04:00
/**
* xmlCtxtNsCheckScope :
* @ ctxt : the debugging context
* @ node : the node
* @ ns : the namespace node
*
* Report if a given namespace is is not in scope .
*/
static void
xmlCtxtNsCheckScope ( xmlDebugCtxtPtr ctxt , xmlNodePtr node , xmlNsPtr ns )
{
int ret ;
ret = xmlNsCheckScope ( node , ns ) ;
if ( ret = = - 2 ) {
if ( ns - > prefix = = NULL )
xmlDebugErr ( ctxt , XML_CHECK_NS_SCOPE ,
" Reference to default namespace not in scope \n " ) ;
else
xmlDebugErr3 ( ctxt , XML_CHECK_NS_SCOPE ,
" Reference to namespace '%s' not in scope \n " ,
( char * ) ns - > prefix ) ;
}
if ( ret = = - 3 ) {
if ( ns - > prefix = = NULL )
xmlDebugErr ( ctxt , XML_CHECK_NS_ANCESTOR ,
" Reference to default namespace not on ancestor \n " ) ;
else
xmlDebugErr3 ( ctxt , XML_CHECK_NS_ANCESTOR ,
" Reference to namespace '%s' not on ancestor \n " ,
( char * ) ns - > prefix ) ;
}
}
2004-10-15 18:50:10 +04:00
/**
* xmlCtxtCheckString :
* @ ctxt : the debug context
* @ str : the string
*
* Do debugging on the string , currently it just checks the UTF - 8 content
*/
static void
xmlCtxtCheckString ( xmlDebugCtxtPtr ctxt , const xmlChar * str )
{
if ( str = = NULL ) return ;
if ( ctxt - > check ) {
if ( ! xmlCheckUTF8 ( str ) ) {
2004-10-26 20:06:51 +04:00
xmlDebugErr3 ( ctxt , XML_CHECK_NOT_UTF8 ,
2004-10-15 18:50:10 +04:00
" String is not UTF-8 %s " , ( const char * ) str ) ;
}
}
}
2004-10-26 20:06:51 +04:00
/**
* xmlCtxtCheckName :
* @ ctxt : the debug context
* @ name : the name
*
2016-04-13 17:56:07 +03:00
* Do debugging on the name , for example the dictionary status and
2004-10-26 20:06:51 +04:00
* conformance to the Name production .
*/
static void
xmlCtxtCheckName ( xmlDebugCtxtPtr ctxt , const xmlChar * name )
{
if ( ctxt - > check ) {
if ( name = = NULL ) {
xmlDebugErr ( ctxt , XML_CHECK_NO_NAME , " Name is NULL " ) ;
return ;
}
2013-06-14 23:11:27 +04:00
# if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
2004-10-26 20:06:51 +04:00
if ( xmlValidateName ( name , 0 ) ) {
xmlDebugErr3 ( ctxt , XML_CHECK_NOT_NCNAME ,
" Name is not an NCName '%s' " , ( const char * ) name ) ;
}
2013-06-14 23:11:27 +04:00
# endif
2004-10-26 20:06:51 +04:00
if ( ( ctxt - > dict ! = NULL ) & &
2009-07-29 13:34:50 +04:00
( ! xmlDictOwns ( ctxt - > dict , name ) ) & &
( ( ctxt - > doc = = NULL ) | |
( ( ctxt - > doc - > parseFlags & ( XML_PARSE_SAX1 | XML_PARSE_NODICT ) ) = = 0 ) ) ) {
2004-10-26 20:06:51 +04:00
xmlDebugErr3 ( ctxt , XML_CHECK_OUTSIDE_DICT ,
2016-04-13 17:56:07 +03:00
" Name is not from the document dictionary '%s' " ,
2004-10-26 20:06:51 +04:00
( const char * ) name ) ;
}
}
}
2004-10-07 17:14:19 +04:00
static void
xmlCtxtGenericNodeCheck ( xmlDebugCtxtPtr ctxt , xmlNodePtr node ) {
2004-10-26 20:06:51 +04:00
xmlDocPtr doc ;
xmlDictPtr dict ;
doc = node - > doc ;
2004-10-07 17:14:19 +04:00
if ( node - > parent = = NULL )
xmlDebugErr ( ctxt , XML_CHECK_NO_PARENT ,
" Node has no parent \n " ) ;
2004-10-26 20:06:51 +04:00
if ( node - > doc = = NULL ) {
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NO_DOC ,
" Node has no doc \n " ) ;
2004-10-26 20:06:51 +04:00
dict = NULL ;
} else {
dict = doc - > dict ;
if ( ( dict = = NULL ) & & ( ctxt - > nodict = = 0 ) ) {
2004-10-27 21:29:04 +04:00
#if 0
2019-09-30 18:04:54 +03:00
/* deactivated right now as it raises too many errors */
2004-10-27 21:29:04 +04:00
if ( doc - > type = = XML_DOCUMENT_NODE )
xmlDebugErr ( ctxt , XML_CHECK_NO_DICT ,
2016-04-13 17:56:07 +03:00
" Document has no dictionary \n " ) ;
2004-10-27 21:29:04 +04:00
# endif
2004-10-26 20:06:51 +04:00
ctxt - > nodict = 1 ;
}
if ( ctxt - > doc = = NULL )
ctxt - > doc = doc ;
if ( ctxt - > dict = = NULL ) {
ctxt - > dict = dict ;
}
}
2004-10-07 17:14:19 +04:00
if ( ( node - > parent ! = NULL ) & & ( node - > doc ! = node - > parent - > doc ) & &
( ! xmlStrEqual ( node - > name , BAD_CAST " pseudoroot " ) ) )
xmlDebugErr ( ctxt , XML_CHECK_WRONG_DOC ,
" Node doc differs from parent's one \n " ) ;
if ( node - > prev = = NULL ) {
if ( node - > type = = XML_ATTRIBUTE_NODE ) {
if ( ( node - > parent ! = NULL ) & &
( node ! = ( xmlNodePtr ) node - > parent - > properties ) )
xmlDebugErr ( ctxt , XML_CHECK_NO_PREV ,
" Attr has no prev and not first of attr list \n " ) ;
2012-09-11 09:26:36 +04:00
2004-10-07 17:14:19 +04:00
} else if ( ( node - > parent ! = NULL ) & & ( node - > parent - > children ! = node ) )
xmlDebugErr ( ctxt , XML_CHECK_NO_PREV ,
" Node has no prev and not first of parent list \n " ) ;
} else {
if ( node - > prev - > next ! = node )
xmlDebugErr ( ctxt , XML_CHECK_WRONG_PREV ,
" Node prev->next : back link wrong \n " ) ;
}
if ( node - > next = = NULL ) {
if ( ( node - > parent ! = NULL ) & & ( node - > type ! = XML_ATTRIBUTE_NODE ) & &
2008-03-25 19:52:41 +03:00
( node - > parent - > last ! = node ) & &
( node - > parent - > type = = XML_ELEMENT_NODE ) )
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NO_NEXT ,
" Node has no next and not last of parent list \n " ) ;
} else {
if ( node - > next - > prev ! = node )
xmlDebugErr ( ctxt , XML_CHECK_WRONG_NEXT ,
" Node next->prev : forward link wrong \n " ) ;
2004-10-11 16:28:34 +04:00
if ( node - > next - > parent ! = node - > parent )
xmlDebugErr ( ctxt , XML_CHECK_WRONG_PARENT ,
" Node next->prev : forward link wrong \n " ) ;
2004-10-07 17:14:19 +04:00
}
2004-10-11 16:28:34 +04:00
if ( node - > type = = XML_ELEMENT_NODE ) {
xmlNsPtr ns ;
ns = node - > nsDef ;
while ( ns ! = NULL ) {
xmlCtxtNsCheckScope ( ctxt , node , ns ) ;
ns = ns - > next ;
}
if ( node - > ns ! = NULL )
xmlCtxtNsCheckScope ( ctxt , node , node - > ns ) ;
} else if ( node - > type = = XML_ATTRIBUTE_NODE ) {
if ( node - > ns ! = NULL )
xmlCtxtNsCheckScope ( ctxt , node , node - > ns ) ;
}
2004-10-15 18:50:10 +04:00
if ( ( node - > type ! = XML_ELEMENT_NODE ) & &
2004-10-15 22:25:33 +04:00
( node - > type ! = XML_ATTRIBUTE_NODE ) & &
2005-06-30 17:04:44 +04:00
( node - > type ! = XML_ELEMENT_DECL ) & &
2004-10-15 22:25:33 +04:00
( node - > type ! = XML_ATTRIBUTE_DECL ) & &
( node - > type ! = XML_DTD_NODE ) & &
( node - > type ! = XML_HTML_DOCUMENT_NODE ) & &
( node - > type ! = XML_DOCUMENT_NODE ) ) {
2004-10-15 18:50:10 +04:00
if ( node - > content ! = NULL )
2004-10-15 22:25:33 +04:00
xmlCtxtCheckString ( ctxt , ( const xmlChar * ) node - > content ) ;
2004-10-15 18:50:10 +04:00
}
2004-10-26 20:06:51 +04:00
switch ( node - > type ) {
case XML_ELEMENT_NODE :
case XML_ATTRIBUTE_NODE :
xmlCtxtCheckName ( ctxt , node - > name ) ;
break ;
case XML_TEXT_NODE :
if ( ( node - > name = = xmlStringText ) | |
( node - > name = = xmlStringTextNoenc ) )
break ;
/* some case of entity substitution can lead to this */
if ( ( ctxt - > dict ! = NULL ) & &
2004-10-27 21:29:04 +04:00
( node - > name = = xmlDictLookup ( ctxt - > dict , BAD_CAST " nbktext " ,
7 ) ) )
2004-10-26 20:06:51 +04:00
break ;
xmlDebugErr3 ( ctxt , XML_CHECK_WRONG_NAME ,
" Text node has wrong name '%s' " ,
( const char * ) node - > name ) ;
break ;
case XML_COMMENT_NODE :
if ( node - > name = = xmlStringComment )
break ;
xmlDebugErr3 ( ctxt , XML_CHECK_WRONG_NAME ,
" Comment node has wrong name '%s' " ,
( const char * ) node - > name ) ;
break ;
case XML_PI_NODE :
xmlCtxtCheckName ( ctxt , node - > name ) ;
break ;
case XML_CDATA_SECTION_NODE :
if ( node - > name = = NULL )
break ;
xmlDebugErr3 ( ctxt , XML_CHECK_NAME_NOT_NULL ,
" CData section has non NULL name '%s' " ,
( const char * ) node - > name ) ;
break ;
case XML_ENTITY_REF_NODE :
case XML_ENTITY_NODE :
case XML_DOCUMENT_TYPE_NODE :
case XML_DOCUMENT_FRAG_NODE :
case XML_NOTATION_NODE :
case XML_DTD_NODE :
case XML_ELEMENT_DECL :
case XML_ATTRIBUTE_DECL :
case XML_ENTITY_DECL :
case XML_NAMESPACE_DECL :
case XML_XINCLUDE_START :
case XML_XINCLUDE_END :
case XML_DOCUMENT_NODE :
case XML_HTML_DOCUMENT_NODE :
break ;
}
2004-10-07 17:14:19 +04:00
}
2004-10-04 18:09:17 +04:00
static void
xmlCtxtDumpString ( xmlDebugCtxtPtr ctxt , const xmlChar * str )
{
int i ;
2004-10-15 18:50:10 +04:00
if ( ctxt - > check ) {
2004-10-04 18:09:17 +04:00
return ;
2004-10-15 18:50:10 +04:00
}
2004-10-04 18:09:17 +04:00
/* TODO: check UTF8 content of the string */
2001-02-23 20:55:21 +03:00
if ( str = = NULL ) {
2004-10-04 18:09:17 +04:00
fprintf ( ctxt - > output , " (NULL) " ) ;
2001-07-18 23:30:27 +04:00
return ;
2001-02-23 20:55:21 +03:00
}
2001-07-18 23:30:27 +04:00
for ( i = 0 ; i < 40 ; i + + )
if ( str [ i ] = = 0 )
return ;
2003-10-18 20:20:14 +04:00
else if ( IS_BLANK_CH ( str [ i ] ) )
2004-10-04 18:09:17 +04:00
fputc ( ' ' , ctxt - > output ) ;
2001-07-18 23:30:27 +04:00
else if ( str [ i ] > = 0x80 )
2004-10-04 18:09:17 +04:00
fprintf ( ctxt - > output , " #%X " , str [ i ] ) ;
2001-07-18 23:30:27 +04:00
else
2004-10-04 18:09:17 +04:00
fputc ( str [ i ] , ctxt - > output ) ;
fprintf ( ctxt - > output , " ... " ) ;
2001-02-23 20:55:21 +03:00
}
2001-03-24 20:00:36 +03:00
static void
2004-10-04 18:09:17 +04:00
xmlCtxtDumpDtdNode ( xmlDebugCtxtPtr ctxt , xmlDtdPtr dtd )
{
xmlCtxtDumpSpaces ( ctxt ) ;
2001-02-23 20:55:21 +03:00
2002-01-23 00:44:25 +03:00
if ( dtd = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " DTD node is NULL \n " ) ;
return ;
2002-01-23 00:44:25 +03:00
}
2001-02-23 20:55:21 +03:00
if ( dtd - > type ! = XML_DTD_NODE ) {
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NOT_DTD ,
" Node is not a DTD " ) ;
2004-10-04 18:09:17 +04:00
return ;
}
if ( ! ctxt - > check ) {
if ( dtd - > name ! = NULL )
fprintf ( ctxt - > output , " DTD(%s) " , ( char * ) dtd - > name ) ;
else
fprintf ( ctxt - > output , " DTD " ) ;
if ( dtd - > ExternalID ! = NULL )
fprintf ( ctxt - > output , " , PUBLIC %s " , ( char * ) dtd - > ExternalID ) ;
if ( dtd - > SystemID ! = NULL )
fprintf ( ctxt - > output , " , SYSTEM %s " , ( char * ) dtd - > SystemID ) ;
fprintf ( ctxt - > output , " \n " ) ;
2001-02-23 20:55:21 +03:00
}
/*
* Do a bit of checking
*/
2004-10-07 17:14:19 +04:00
xmlCtxtGenericNodeCheck ( ctxt , ( xmlNodePtr ) dtd ) ;
2001-02-23 20:55:21 +03:00
}
2001-03-24 20:00:36 +03:00
static void
2004-10-04 18:09:17 +04:00
xmlCtxtDumpAttrDecl ( xmlDebugCtxtPtr ctxt , xmlAttributePtr attr )
{
xmlCtxtDumpSpaces ( ctxt ) ;
2001-02-23 20:55:21 +03:00
2002-01-23 00:44:25 +03:00
if ( attr = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " Attribute declaration is NULL \n " ) ;
return ;
2002-01-23 00:44:25 +03:00
}
2001-02-23 20:55:21 +03:00
if ( attr - > type ! = XML_ATTRIBUTE_DECL ) {
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NOT_ATTR_DECL ,
" Node is not an attribute declaration " ) ;
2004-10-04 18:09:17 +04:00
return ;
2001-02-23 20:55:21 +03:00
}
2004-10-04 18:09:17 +04:00
if ( attr - > name ! = NULL ) {
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " ATTRDECL(%s) " , ( char * ) attr - > name ) ;
} else
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NO_NAME ,
" Node attribute declaration has no name " ) ;
2004-10-04 18:09:17 +04:00
if ( attr - > elem ! = NULL ) {
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " for %s " , ( char * ) attr - > elem ) ;
} else
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NO_ELEM ,
" Node attribute declaration has no element name " ) ;
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
switch ( attr - > atype ) {
case XML_ATTRIBUTE_CDATA :
fprintf ( ctxt - > output , " CDATA " ) ;
break ;
case XML_ATTRIBUTE_ID :
fprintf ( ctxt - > output , " ID " ) ;
break ;
case XML_ATTRIBUTE_IDREF :
fprintf ( ctxt - > output , " IDREF " ) ;
break ;
case XML_ATTRIBUTE_IDREFS :
fprintf ( ctxt - > output , " IDREFS " ) ;
break ;
case XML_ATTRIBUTE_ENTITY :
fprintf ( ctxt - > output , " ENTITY " ) ;
break ;
case XML_ATTRIBUTE_ENTITIES :
fprintf ( ctxt - > output , " ENTITIES " ) ;
break ;
case XML_ATTRIBUTE_NMTOKEN :
fprintf ( ctxt - > output , " NMTOKEN " ) ;
break ;
case XML_ATTRIBUTE_NMTOKENS :
fprintf ( ctxt - > output , " NMTOKENS " ) ;
break ;
case XML_ATTRIBUTE_ENUMERATION :
fprintf ( ctxt - > output , " ENUMERATION " ) ;
break ;
case XML_ATTRIBUTE_NOTATION :
fprintf ( ctxt - > output , " NOTATION " ) ;
break ;
}
if ( attr - > tree ! = NULL ) {
int indx ;
xmlEnumerationPtr cur = attr - > tree ;
for ( indx = 0 ; indx < 5 ; indx + + ) {
if ( indx ! = 0 )
fprintf ( ctxt - > output , " |%s " , ( char * ) cur - > name ) ;
else
fprintf ( ctxt - > output , " (%s " , ( char * ) cur - > name ) ;
cur = cur - > next ;
if ( cur = = NULL )
break ;
}
if ( cur = = NULL )
fprintf ( ctxt - > output , " ) " ) ;
else
fprintf ( ctxt - > output , " ...) " ) ;
}
switch ( attr - > def ) {
case XML_ATTRIBUTE_NONE :
break ;
case XML_ATTRIBUTE_REQUIRED :
fprintf ( ctxt - > output , " REQUIRED " ) ;
break ;
case XML_ATTRIBUTE_IMPLIED :
fprintf ( ctxt - > output , " IMPLIED " ) ;
break ;
case XML_ATTRIBUTE_FIXED :
fprintf ( ctxt - > output , " FIXED " ) ;
break ;
}
if ( attr - > defaultValue ! = NULL ) {
fprintf ( ctxt - > output , " \" " ) ;
xmlCtxtDumpString ( ctxt , attr - > defaultValue ) ;
fprintf ( ctxt - > output , " \" " ) ;
}
fprintf ( ctxt - > output , " \n " ) ;
2001-02-23 20:55:21 +03:00
}
/*
* Do a bit of checking
*/
2004-10-07 17:14:19 +04:00
xmlCtxtGenericNodeCheck ( ctxt , ( xmlNodePtr ) attr ) ;
2001-02-23 20:55:21 +03:00
}
2001-03-24 20:00:36 +03:00
static void
2004-10-04 18:09:17 +04:00
xmlCtxtDumpElemDecl ( xmlDebugCtxtPtr ctxt , xmlElementPtr elem )
{
xmlCtxtDumpSpaces ( ctxt ) ;
2001-02-23 20:55:21 +03:00
2002-01-23 00:44:25 +03:00
if ( elem = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " Element declaration is NULL \n " ) ;
return ;
2002-01-23 00:44:25 +03:00
}
2001-02-23 20:55:21 +03:00
if ( elem - > type ! = XML_ELEMENT_DECL ) {
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NOT_ELEM_DECL ,
" Node is not an element declaration " ) ;
2004-10-04 18:09:17 +04:00
return ;
2001-02-23 20:55:21 +03:00
}
if ( elem - > name ! = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
fprintf ( ctxt - > output , " ELEMDECL( " ) ;
xmlCtxtDumpString ( ctxt , elem - > name ) ;
fprintf ( ctxt - > output , " ) " ) ;
}
2001-02-23 20:55:21 +03:00
} else
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NO_NAME ,
" Element declaration has no name " ) ;
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
switch ( elem - > etype ) {
case XML_ELEMENT_TYPE_UNDEFINED :
fprintf ( ctxt - > output , " , UNDEFINED " ) ;
break ;
case XML_ELEMENT_TYPE_EMPTY :
fprintf ( ctxt - > output , " , EMPTY " ) ;
break ;
case XML_ELEMENT_TYPE_ANY :
fprintf ( ctxt - > output , " , ANY " ) ;
break ;
case XML_ELEMENT_TYPE_MIXED :
fprintf ( ctxt - > output , " , MIXED " ) ;
break ;
case XML_ELEMENT_TYPE_ELEMENT :
fprintf ( ctxt - > output , " , MIXED " ) ;
break ;
}
if ( ( elem - > type ! = XML_ELEMENT_NODE ) & & ( elem - > content ! = NULL ) ) {
char buf [ 5001 ] ;
buf [ 0 ] = 0 ;
xmlSnprintfElementContent ( buf , 5000 , elem - > content , 1 ) ;
buf [ 5000 ] = 0 ;
fprintf ( ctxt - > output , " %s " , buf ) ;
}
fprintf ( ctxt - > output , " \n " ) ;
2001-02-23 20:55:21 +03:00
}
/*
* Do a bit of checking
*/
2004-10-07 17:14:19 +04:00
xmlCtxtGenericNodeCheck ( ctxt , ( xmlNodePtr ) elem ) ;
2001-02-23 20:55:21 +03:00
}
2001-03-24 20:00:36 +03:00
static void
2004-10-04 18:09:17 +04:00
xmlCtxtDumpEntityDecl ( xmlDebugCtxtPtr ctxt , xmlEntityPtr ent )
{
xmlCtxtDumpSpaces ( ctxt ) ;
2001-02-23 20:55:21 +03:00
2002-01-23 00:44:25 +03:00
if ( ent = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " Entity declaration is NULL \n " ) ;
return ;
2002-01-23 00:44:25 +03:00
}
2001-02-23 20:55:21 +03:00
if ( ent - > type ! = XML_ENTITY_DECL ) {
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NOT_ENTITY_DECL ,
" Node is not an entity declaration " ) ;
2004-10-04 18:09:17 +04:00
return ;
2001-02-23 20:55:21 +03:00
}
if ( ent - > name ! = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
fprintf ( ctxt - > output , " ENTITYDECL( " ) ;
xmlCtxtDumpString ( ctxt , ent - > name ) ;
fprintf ( ctxt - > output , " ) " ) ;
}
2001-02-23 20:55:21 +03:00
} else
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NO_NAME ,
" Entity declaration has no name " ) ;
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
switch ( ent - > etype ) {
case XML_INTERNAL_GENERAL_ENTITY :
fprintf ( ctxt - > output , " , internal \n " ) ;
break ;
case XML_EXTERNAL_GENERAL_PARSED_ENTITY :
fprintf ( ctxt - > output , " , external parsed \n " ) ;
break ;
case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY :
fprintf ( ctxt - > output , " , unparsed \n " ) ;
break ;
case XML_INTERNAL_PARAMETER_ENTITY :
fprintf ( ctxt - > output , " , parameter \n " ) ;
break ;
case XML_EXTERNAL_PARAMETER_ENTITY :
fprintf ( ctxt - > output , " , external parameter \n " ) ;
break ;
case XML_INTERNAL_PREDEFINED_ENTITY :
fprintf ( ctxt - > output , " , predefined \n " ) ;
break ;
}
if ( ent - > ExternalID ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " ExternalID=%s \n " ,
( char * ) ent - > ExternalID ) ;
}
if ( ent - > SystemID ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " SystemID=%s \n " ,
( char * ) ent - > SystemID ) ;
}
if ( ent - > URI ! = NULL ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " URI=%s \n " , ( char * ) ent - > URI ) ;
}
if ( ent - > content ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " content= " ) ;
xmlCtxtDumpString ( ctxt , ent - > content ) ;
fprintf ( ctxt - > output , " \n " ) ;
}
2001-02-23 20:55:21 +03:00
}
/*
* Do a bit of checking
*/
2004-10-07 17:14:19 +04:00
xmlCtxtGenericNodeCheck ( ctxt , ( xmlNodePtr ) ent ) ;
2001-02-23 20:55:21 +03:00
}
2001-03-24 20:00:36 +03:00
static void
2004-10-04 18:09:17 +04:00
xmlCtxtDumpNamespace ( xmlDebugCtxtPtr ctxt , xmlNsPtr ns )
{
xmlCtxtDumpSpaces ( ctxt ) ;
2002-01-23 00:44:25 +03:00
if ( ns = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " namespace node is NULL \n " ) ;
return ;
2002-01-23 00:44:25 +03:00
}
2001-02-23 20:55:21 +03:00
if ( ns - > type ! = XML_NAMESPACE_DECL ) {
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NOT_NS_DECL ,
" Node is not a namespace declaration " ) ;
2004-10-04 18:09:17 +04:00
return ;
2001-02-23 20:55:21 +03:00
}
if ( ns - > href = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ns - > prefix ! = NULL )
2004-10-07 17:14:19 +04:00
xmlDebugErr3 ( ctxt , XML_CHECK_NO_HREF ,
" Incomplete namespace %s href=NULL \n " ,
2004-10-04 18:09:17 +04:00
( char * ) ns - > prefix ) ;
else
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_NO_HREF ,
" Incomplete default namespace href=NULL \n " ) ;
2001-02-23 20:55:21 +03:00
} else {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
if ( ns - > prefix ! = NULL )
fprintf ( ctxt - > output , " namespace %s href= " ,
( char * ) ns - > prefix ) ;
else
fprintf ( ctxt - > output , " default namespace href= " ) ;
2001-02-23 20:55:21 +03:00
2004-10-04 18:09:17 +04:00
xmlCtxtDumpString ( ctxt , ns - > href ) ;
fprintf ( ctxt - > output , " \n " ) ;
}
2001-02-23 20:55:21 +03:00
}
}
2001-03-24 20:00:36 +03:00
static void
2004-10-04 18:09:17 +04:00
xmlCtxtDumpNamespaceList ( xmlDebugCtxtPtr ctxt , xmlNsPtr ns )
{
2001-02-23 20:55:21 +03:00
while ( ns ! = NULL ) {
2004-10-04 18:09:17 +04:00
xmlCtxtDumpNamespace ( ctxt , ns ) ;
ns = ns - > next ;
2001-02-23 20:55:21 +03:00
}
}
2001-03-24 20:00:36 +03:00
static void
2004-10-04 18:09:17 +04:00
xmlCtxtDumpEntity ( xmlDebugCtxtPtr ctxt , xmlEntityPtr ent )
{
xmlCtxtDumpSpaces ( ctxt ) ;
2001-02-23 20:55:21 +03:00
2002-01-23 00:44:25 +03:00
if ( ent = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " Entity is NULL \n " ) ;
return ;
2001-02-23 20:55:21 +03:00
}
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
switch ( ent - > etype ) {
case XML_INTERNAL_GENERAL_ENTITY :
fprintf ( ctxt - > output , " INTERNAL_GENERAL_ENTITY " ) ;
break ;
case XML_EXTERNAL_GENERAL_PARSED_ENTITY :
fprintf ( ctxt - > output , " EXTERNAL_GENERAL_PARSED_ENTITY " ) ;
break ;
case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY :
fprintf ( ctxt - > output , " EXTERNAL_GENERAL_UNPARSED_ENTITY " ) ;
break ;
case XML_INTERNAL_PARAMETER_ENTITY :
fprintf ( ctxt - > output , " INTERNAL_PARAMETER_ENTITY " ) ;
break ;
case XML_EXTERNAL_PARAMETER_ENTITY :
fprintf ( ctxt - > output , " EXTERNAL_PARAMETER_ENTITY " ) ;
break ;
default :
fprintf ( ctxt - > output , " ENTITY_%d ! " , ( int ) ent - > etype ) ;
}
fprintf ( ctxt - > output , " %s \n " , ent - > name ) ;
if ( ent - > ExternalID ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " ExternalID=%s \n " ,
( char * ) ent - > ExternalID ) ;
}
if ( ent - > SystemID ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " SystemID=%s \n " , ( char * ) ent - > SystemID ) ;
}
if ( ent - > URI ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " URI=%s \n " , ( char * ) ent - > URI ) ;
}
if ( ent - > content ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " content= " ) ;
xmlCtxtDumpString ( ctxt , ent - > content ) ;
fprintf ( ctxt - > output , " \n " ) ;
}
2001-02-23 20:55:21 +03:00
}
}
2001-07-18 23:30:27 +04:00
/**
2004-10-04 18:09:17 +04:00
* xmlCtxtDumpAttr :
2001-07-18 23:30:27 +04:00
* @ output : the FILE * for the output
* @ attr : the attribute
* @ depth : the indentation level .
*
* Dumps debug information for the attribute
*/
2004-10-04 18:09:17 +04:00
static void
xmlCtxtDumpAttr ( xmlDebugCtxtPtr ctxt , xmlAttrPtr attr )
{
xmlCtxtDumpSpaces ( ctxt ) ;
2001-02-23 20:55:21 +03:00
2002-01-23 00:44:25 +03:00
if ( attr = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " Attr is NULL " ) ;
return ;
}
if ( ! ctxt - > check ) {
fprintf ( ctxt - > output , " ATTRIBUTE " ) ;
2004-10-07 17:14:19 +04:00
xmlCtxtDumpString ( ctxt , attr - > name ) ;
2004-10-04 18:09:17 +04:00
fprintf ( ctxt - > output , " \n " ) ;
if ( attr - > children ! = NULL ) {
ctxt - > depth + + ;
xmlCtxtDumpNodeList ( ctxt , attr - > children ) ;
ctxt - > depth - - ;
}
2002-01-23 00:44:25 +03:00
}
2004-10-07 17:14:19 +04:00
if ( attr - > name = = NULL )
xmlDebugErr ( ctxt , XML_CHECK_NO_NAME ,
" Attribute has no name " ) ;
2001-02-23 20:55:21 +03:00
/*
* Do a bit of checking
*/
2004-10-07 17:14:19 +04:00
xmlCtxtGenericNodeCheck ( ctxt , ( xmlNodePtr ) attr ) ;
2001-02-23 20:55:21 +03:00
}
2001-07-18 23:30:27 +04:00
/**
2004-10-04 18:09:17 +04:00
* xmlCtxtDumpAttrList :
2001-07-18 23:30:27 +04:00
* @ output : the FILE * for the output
* @ attr : the attribute list
* @ depth : the indentation level .
*
* Dumps debug information for the attribute list
*/
2004-10-04 18:09:17 +04:00
static void
xmlCtxtDumpAttrList ( xmlDebugCtxtPtr ctxt , xmlAttrPtr attr )
2001-07-18 23:30:27 +04:00
{
2001-02-23 20:55:21 +03:00
while ( attr ! = NULL ) {
2004-10-04 18:09:17 +04:00
xmlCtxtDumpAttr ( ctxt , attr ) ;
2001-07-18 23:30:27 +04:00
attr = attr - > next ;
2001-02-23 20:55:21 +03:00
}
}
2001-07-18 23:30:27 +04:00
/**
2004-10-04 18:09:17 +04:00
* xmlCtxtDumpOneNode :
2001-07-18 23:30:27 +04:00
* @ output : the FILE * for the output
* @ node : the node
* @ depth : the indentation level .
*
* Dumps debug information for the element node , it is not recursive
*/
2004-10-04 18:09:17 +04:00
static void
xmlCtxtDumpOneNode ( xmlDebugCtxtPtr ctxt , xmlNodePtr node )
2001-07-18 23:30:27 +04:00
{
2002-01-23 00:44:25 +03:00
if ( node = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " node is NULL \n " ) ;
}
return ;
2002-01-23 00:44:25 +03:00
}
2004-10-07 17:14:19 +04:00
ctxt - > node = node ;
2001-02-23 20:55:21 +03:00
switch ( node - > type ) {
2001-07-18 23:30:27 +04:00
case XML_ELEMENT_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " ELEMENT " ) ;
if ( ( node - > ns ! = NULL ) & & ( node - > ns - > prefix ! = NULL ) ) {
xmlCtxtDumpString ( ctxt , node - > ns - > prefix ) ;
fprintf ( ctxt - > output , " : " ) ;
}
xmlCtxtDumpString ( ctxt , node - > name ) ;
fprintf ( ctxt - > output , " \n " ) ;
2001-07-18 23:30:27 +04:00
}
break ;
case XML_ATTRIBUTE_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " Error, ATTRIBUTE found here \n " ) ;
2004-12-18 00:38:09 +03:00
xmlCtxtGenericNodeCheck ( ctxt , node ) ;
return ;
2001-07-18 23:30:27 +04:00
case XML_TEXT_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
if ( node - > name = = ( const xmlChar * ) xmlStringTextNoenc )
2005-08-25 17:19:21 +04:00
fprintf ( ctxt - > output , " TEXT no enc " ) ;
2004-10-04 18:09:17 +04:00
else
2005-08-25 17:19:21 +04:00
fprintf ( ctxt - > output , " TEXT " ) ;
2005-08-25 18:03:56 +04:00
if ( ctxt - > options & DUMP_TEXT_TYPE ) {
if ( node - > content = = ( xmlChar * ) & ( node - > properties ) )
fprintf ( ctxt - > output , " compact \n " ) ;
else if ( xmlDictOwns ( ctxt - > dict , node - > content ) = = 1 )
fprintf ( ctxt - > output , " interned \n " ) ;
else
fprintf ( ctxt - > output , " \n " ) ;
} else
2005-08-25 17:19:21 +04:00
fprintf ( ctxt - > output , " \n " ) ;
2004-10-04 18:09:17 +04:00
}
2001-07-18 23:30:27 +04:00
break ;
case XML_CDATA_SECTION_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " CDATA_SECTION \n " ) ;
}
2001-07-18 23:30:27 +04:00
break ;
case XML_ENTITY_REF_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " ENTITY_REF(%s) \n " ,
( char * ) node - > name ) ;
}
2001-07-18 23:30:27 +04:00
break ;
case XML_ENTITY_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " ENTITY \n " ) ;
}
2001-07-18 23:30:27 +04:00
break ;
case XML_PI_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " PI %s \n " , ( char * ) node - > name ) ;
}
2001-07-18 23:30:27 +04:00
break ;
case XML_COMMENT_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " COMMENT \n " ) ;
}
2001-07-18 23:30:27 +04:00
break ;
case XML_DOCUMENT_NODE :
case XML_HTML_DOCUMENT_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
}
2004-12-18 00:38:09 +03:00
fprintf ( ctxt - > output , " Error, DOCUMENT found here \n " ) ;
xmlCtxtGenericNodeCheck ( ctxt , node ) ;
return ;
2001-07-18 23:30:27 +04:00
case XML_DOCUMENT_TYPE_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " DOCUMENT_TYPE \n " ) ;
}
2001-07-18 23:30:27 +04:00
break ;
case XML_DOCUMENT_FRAG_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " DOCUMENT_FRAG \n " ) ;
}
2001-07-18 23:30:27 +04:00
break ;
case XML_NOTATION_NODE :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " NOTATION \n " ) ;
}
2001-07-18 23:30:27 +04:00
break ;
case XML_DTD_NODE :
2004-10-04 18:09:17 +04:00
xmlCtxtDumpDtdNode ( ctxt , ( xmlDtdPtr ) node ) ;
2001-07-18 23:30:27 +04:00
return ;
case XML_ELEMENT_DECL :
2004-10-04 18:09:17 +04:00
xmlCtxtDumpElemDecl ( ctxt , ( xmlElementPtr ) node ) ;
2001-07-18 23:30:27 +04:00
return ;
case XML_ATTRIBUTE_DECL :
2004-10-04 18:09:17 +04:00
xmlCtxtDumpAttrDecl ( ctxt , ( xmlAttributePtr ) node ) ;
2001-07-18 23:30:27 +04:00
return ;
2001-02-23 20:55:21 +03:00
case XML_ENTITY_DECL :
2004-10-04 18:09:17 +04:00
xmlCtxtDumpEntityDecl ( ctxt , ( xmlEntityPtr ) node ) ;
2001-07-18 23:30:27 +04:00
return ;
2001-02-23 20:55:21 +03:00
case XML_NAMESPACE_DECL :
2004-10-04 18:09:17 +04:00
xmlCtxtDumpNamespace ( ctxt , ( xmlNsPtr ) node ) ;
2001-07-18 23:30:27 +04:00
return ;
2001-02-23 20:55:21 +03:00
case XML_XINCLUDE_START :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " INCLUDE START \n " ) ;
}
2001-07-18 23:30:27 +04:00
return ;
2001-02-23 20:55:21 +03:00
case XML_XINCLUDE_END :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " INCLUDE END \n " ) ;
}
2001-07-18 23:30:27 +04:00
return ;
default :
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
xmlCtxtDumpSpaces ( ctxt ) ;
2004-10-07 17:14:19 +04:00
xmlDebugErr2 ( ctxt , XML_CHECK_UNKNOWN_NODE ,
" Unknown node type %d \n " , node - > type ) ;
2001-07-18 23:30:27 +04:00
return ;
2001-02-23 20:55:21 +03:00
}
if ( node - > doc = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
}
fprintf ( ctxt - > output , " PBM: doc == NULL !!! \n " ) ;
2001-02-23 20:55:21 +03:00
}
2004-10-04 18:09:17 +04:00
ctxt - > depth + + ;
2005-08-25 17:19:21 +04:00
if ( ( node - > type = = XML_ELEMENT_NODE ) & & ( node - > nsDef ! = NULL ) )
2004-10-04 18:09:17 +04:00
xmlCtxtDumpNamespaceList ( ctxt , node - > nsDef ) ;
2005-08-25 17:19:21 +04:00
if ( ( node - > type = = XML_ELEMENT_NODE ) & & ( node - > properties ! = NULL ) )
2004-10-04 18:09:17 +04:00
xmlCtxtDumpAttrList ( ctxt , node - > properties ) ;
2001-02-23 20:55:21 +03:00
if ( node - > type ! = XML_ENTITY_REF_NODE ) {
2001-07-18 23:30:27 +04:00
if ( ( node - > type ! = XML_ELEMENT_NODE ) & & ( node - > content ! = NULL ) ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " content= " ) ;
xmlCtxtDumpString ( ctxt , node - > content ) ;
fprintf ( ctxt - > output , " \n " ) ;
}
2001-07-18 23:30:27 +04:00
}
2001-02-23 20:55:21 +03:00
} else {
xmlEntityPtr ent ;
2001-07-18 23:30:27 +04:00
ent = xmlGetDocEntity ( node - > doc , node - > name ) ;
if ( ent ! = NULL )
2004-10-04 18:09:17 +04:00
xmlCtxtDumpEntity ( ctxt , ent ) ;
2001-02-23 20:55:21 +03:00
}
2004-10-04 18:09:17 +04:00
ctxt - > depth - - ;
2001-02-23 20:55:21 +03:00
/*
* Do a bit of checking
*/
2004-10-07 17:14:19 +04:00
xmlCtxtGenericNodeCheck ( ctxt , node ) ;
2001-02-23 20:55:21 +03:00
}
2001-07-18 23:30:27 +04:00
/**
2004-10-04 18:09:17 +04:00
* xmlCtxtDumpNode :
2001-07-18 23:30:27 +04:00
* @ output : the FILE * for the output
* @ node : the node
* @ depth : the indentation level .
*
* Dumps debug information for the element node , it is recursive
*/
2004-10-04 18:09:17 +04:00
static void
xmlCtxtDumpNode ( xmlDebugCtxtPtr ctxt , xmlNodePtr node )
2001-07-18 23:30:27 +04:00
{
2002-01-23 00:44:25 +03:00
if ( node = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
xmlCtxtDumpSpaces ( ctxt ) ;
fprintf ( ctxt - > output , " node is NULL \n " ) ;
}
return ;
}
xmlCtxtDumpOneNode ( ctxt , node ) ;
2012-09-11 09:26:36 +04:00
if ( ( node - > type ! = XML_NAMESPACE_DECL ) & &
2005-09-07 02:16:57 +04:00
( node - > children ! = NULL ) & & ( node - > type ! = XML_ENTITY_REF_NODE ) ) {
2004-10-04 18:09:17 +04:00
ctxt - > depth + + ;
xmlCtxtDumpNodeList ( ctxt , node - > children ) ;
ctxt - > depth - - ;
}
2001-02-23 20:55:21 +03:00
}
2001-07-18 23:30:27 +04:00
/**
2004-10-04 18:09:17 +04:00
* xmlCtxtDumpNodeList :
2001-07-18 23:30:27 +04:00
* @ output : the FILE * for the output
* @ node : the node list
* @ depth : the indentation level .
*
* Dumps debug information for the list of element node , it is recursive
*/
2004-10-04 18:09:17 +04:00
static void
xmlCtxtDumpNodeList ( xmlDebugCtxtPtr ctxt , xmlNodePtr node )
2001-07-18 23:30:27 +04:00
{
2001-02-23 20:55:21 +03:00
while ( node ! = NULL ) {
2004-10-04 18:09:17 +04:00
xmlCtxtDumpNode ( ctxt , node ) ;
2001-07-18 23:30:27 +04:00
node = node - > next ;
2001-02-23 20:55:21 +03:00
}
}
2004-10-04 18:09:17 +04:00
static void
2004-10-07 17:14:19 +04:00
xmlCtxtDumpDocHead ( xmlDebugCtxtPtr ctxt , xmlDocPtr doc )
2001-07-18 23:30:27 +04:00
{
2001-02-23 20:55:21 +03:00
if ( doc = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " DOCUMENT == NULL ! \n " ) ;
2001-07-18 23:30:27 +04:00
return ;
2001-02-23 20:55:21 +03:00
}
2004-10-07 17:14:19 +04:00
ctxt - > node = ( xmlNodePtr ) doc ;
2001-02-23 20:55:21 +03:00
switch ( doc - > type ) {
2001-07-18 23:30:27 +04:00
case XML_ELEMENT_NODE :
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_FOUND_ELEMENT ,
" Misplaced ELEMENT node \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_ATTRIBUTE_NODE :
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_FOUND_ATTRIBUTE ,
" Misplaced ATTRIBUTE node \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_TEXT_NODE :
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_FOUND_TEXT ,
" Misplaced TEXT node \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_CDATA_SECTION_NODE :
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_FOUND_CDATA ,
" Misplaced CDATA node \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_ENTITY_REF_NODE :
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_FOUND_ENTITYREF ,
" Misplaced ENTITYREF node \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_ENTITY_NODE :
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_FOUND_ENTITY ,
" Misplaced ENTITY node \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_PI_NODE :
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_FOUND_PI ,
" Misplaced PI node \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_COMMENT_NODE :
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_FOUND_COMMENT ,
" Misplaced COMMENT node \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_DOCUMENT_NODE :
2004-10-07 17:14:19 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " DOCUMENT \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_HTML_DOCUMENT_NODE :
2004-10-07 17:14:19 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " HTML DOCUMENT \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_DOCUMENT_TYPE_NODE :
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_FOUND_DOCTYPE ,
" Misplaced DOCTYPE node \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_DOCUMENT_FRAG_NODE :
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_FOUND_FRAGMENT ,
" Misplaced FRAGMENT node \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
case XML_NOTATION_NODE :
2004-10-07 17:14:19 +04:00
xmlDebugErr ( ctxt , XML_CHECK_FOUND_NOTATION ,
" Misplaced NOTATION node \n " ) ;
2001-07-18 23:30:27 +04:00
break ;
default :
2004-10-07 17:14:19 +04:00
xmlDebugErr2 ( ctxt , XML_CHECK_UNKNOWN_NODE ,
" Unknown node type %d \n " , doc - > type ) ;
2001-02-23 20:55:21 +03:00
}
2004-10-07 17:14:19 +04:00
}
/**
* xmlCtxtDumpDocumentHead :
* @ output : the FILE * for the output
* @ doc : the document
*
2019-09-30 18:04:54 +03:00
* Dumps debug information concerning the document , not recursive
2004-10-07 17:14:19 +04:00
*/
static void
xmlCtxtDumpDocumentHead ( xmlDebugCtxtPtr ctxt , xmlDocPtr doc )
{
2004-11-08 19:24:57 +03:00
if ( doc = = NULL ) return ;
2004-10-07 17:14:19 +04:00
xmlCtxtDumpDocHead ( ctxt , doc ) ;
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
if ( doc - > name ! = NULL ) {
fprintf ( ctxt - > output , " name= " ) ;
xmlCtxtDumpString ( ctxt , BAD_CAST doc - > name ) ;
fprintf ( ctxt - > output , " \n " ) ;
}
if ( doc - > version ! = NULL ) {
fprintf ( ctxt - > output , " version= " ) ;
xmlCtxtDumpString ( ctxt , doc - > version ) ;
fprintf ( ctxt - > output , " \n " ) ;
}
if ( doc - > encoding ! = NULL ) {
fprintf ( ctxt - > output , " encoding= " ) ;
xmlCtxtDumpString ( ctxt , doc - > encoding ) ;
fprintf ( ctxt - > output , " \n " ) ;
}
if ( doc - > URL ! = NULL ) {
fprintf ( ctxt - > output , " URL= " ) ;
xmlCtxtDumpString ( ctxt , doc - > URL ) ;
fprintf ( ctxt - > output , " \n " ) ;
}
if ( doc - > standalone )
fprintf ( ctxt - > output , " standalone=true \n " ) ;
2001-02-23 20:55:21 +03:00
}
2001-07-18 23:30:27 +04:00
if ( doc - > oldNs ! = NULL )
2004-10-04 18:09:17 +04:00
xmlCtxtDumpNamespaceList ( ctxt , doc - > oldNs ) ;
2001-02-23 20:55:21 +03:00
}
2001-07-18 23:30:27 +04:00
/**
2004-10-04 18:09:17 +04:00
* xmlCtxtDumpDocument :
2001-07-18 23:30:27 +04:00
* @ output : the FILE * for the output
* @ doc : the document
*
* Dumps debug information for the document , it ' s recursive
*/
2004-10-04 18:09:17 +04:00
static void
xmlCtxtDumpDocument ( xmlDebugCtxtPtr ctxt , xmlDocPtr doc )
2001-07-18 23:30:27 +04:00
{
2001-02-23 20:55:21 +03:00
if ( doc = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " DOCUMENT == NULL ! \n " ) ;
2001-07-18 23:30:27 +04:00
return ;
2001-02-23 20:55:21 +03:00
}
2004-10-04 18:09:17 +04:00
xmlCtxtDumpDocumentHead ( ctxt , doc ) ;
2001-02-23 20:55:21 +03:00
if ( ( ( doc - > type = = XML_DOCUMENT_NODE ) | |
2004-10-04 18:09:17 +04:00
( doc - > type = = XML_HTML_DOCUMENT_NODE ) )
& & ( doc - > children ! = NULL ) ) {
ctxt - > depth + + ;
xmlCtxtDumpNodeList ( ctxt , doc - > children ) ;
ctxt - > depth - - ;
2001-02-23 20:55:21 +03:00
}
}
2001-03-24 20:00:36 +03:00
static void
2017-11-09 18:42:47 +03:00
xmlCtxtDumpEntityCallback ( void * payload , void * data ,
const xmlChar * name ATTRIBUTE_UNUSED )
2004-10-04 18:09:17 +04:00
{
2017-11-09 18:42:47 +03:00
xmlEntityPtr cur = ( xmlEntityPtr ) payload ;
xmlDebugCtxtPtr ctxt = ( xmlDebugCtxtPtr ) data ;
2002-01-23 00:44:25 +03:00
if ( cur = = NULL ) {
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " Entity is NULL " ) ;
return ;
2002-01-23 00:44:25 +03:00
}
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check ) {
fprintf ( ctxt - > output , " %s : " , ( char * ) cur - > name ) ;
switch ( cur - > etype ) {
case XML_INTERNAL_GENERAL_ENTITY :
fprintf ( ctxt - > output , " INTERNAL GENERAL, " ) ;
break ;
case XML_EXTERNAL_GENERAL_PARSED_ENTITY :
fprintf ( ctxt - > output , " EXTERNAL PARSED, " ) ;
break ;
case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY :
fprintf ( ctxt - > output , " EXTERNAL UNPARSED, " ) ;
break ;
case XML_INTERNAL_PARAMETER_ENTITY :
fprintf ( ctxt - > output , " INTERNAL PARAMETER, " ) ;
break ;
case XML_EXTERNAL_PARAMETER_ENTITY :
fprintf ( ctxt - > output , " EXTERNAL PARAMETER, " ) ;
break ;
default :
2004-10-07 17:14:19 +04:00
xmlDebugErr2 ( ctxt , XML_CHECK_ENTITY_TYPE ,
" Unknown entity type %d \n " , cur - > etype ) ;
2004-10-04 18:09:17 +04:00
}
if ( cur - > ExternalID ! = NULL )
fprintf ( ctxt - > output , " ID \" %s \" " , ( char * ) cur - > ExternalID ) ;
if ( cur - > SystemID ! = NULL )
fprintf ( ctxt - > output , " SYSTEM \" %s \" " , ( char * ) cur - > SystemID ) ;
if ( cur - > orig ! = NULL )
fprintf ( ctxt - > output , " \n orig \" %s \" " , ( char * ) cur - > orig ) ;
if ( ( cur - > type ! = XML_ELEMENT_NODE ) & & ( cur - > content ! = NULL ) )
fprintf ( ctxt - > output , " \n content \" %s \" " ,
( char * ) cur - > content ) ;
fprintf ( ctxt - > output , " \n " ) ;
2001-02-23 20:55:21 +03:00
}
}
2001-07-18 23:30:27 +04:00
/**
2004-10-04 18:09:17 +04:00
* xmlCtxtDumpEntities :
2001-07-18 23:30:27 +04:00
* @ output : the FILE * for the output
* @ doc : the document
*
* Dumps debug information for all the entities in use by the document
*/
2004-10-04 18:09:17 +04:00
static void
xmlCtxtDumpEntities ( xmlDebugCtxtPtr ctxt , xmlDocPtr doc )
2001-07-18 23:30:27 +04:00
{
2004-11-08 19:24:57 +03:00
if ( doc = = NULL ) return ;
2004-10-07 17:14:19 +04:00
xmlCtxtDumpDocHead ( ctxt , doc ) ;
2001-02-23 20:55:21 +03:00
if ( ( doc - > intSubset ! = NULL ) & & ( doc - > intSubset - > entities ! = NULL ) ) {
2001-07-18 23:30:27 +04:00
xmlEntitiesTablePtr table = ( xmlEntitiesTablePtr )
doc - > intSubset - > entities ;
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " Entities in internal subset \n " ) ;
2017-11-09 18:42:47 +03:00
xmlHashScan ( table , xmlCtxtDumpEntityCallback , ctxt ) ;
2001-02-23 20:55:21 +03:00
} else
2004-10-04 18:09:17 +04:00
fprintf ( ctxt - > output , " No entities in internal subset \n " ) ;
2001-02-23 20:55:21 +03:00
if ( ( doc - > extSubset ! = NULL ) & & ( doc - > extSubset - > entities ! = NULL ) ) {
2001-07-18 23:30:27 +04:00
xmlEntitiesTablePtr table = ( xmlEntitiesTablePtr )
doc - > extSubset - > entities ;
2004-10-04 18:09:17 +04:00
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " Entities in external subset \n " ) ;
2017-11-09 18:42:47 +03:00
xmlHashScan ( table , xmlCtxtDumpEntityCallback , ctxt ) ;
2004-10-04 18:09:17 +04:00
} else if ( ! ctxt - > check )
fprintf ( ctxt - > output , " No entities in external subset \n " ) ;
}
/**
* xmlCtxtDumpDTD :
* @ output : the FILE * for the output
* @ dtd : the DTD
*
* Dumps debug information for the DTD
*/
static void
xmlCtxtDumpDTD ( xmlDebugCtxtPtr ctxt , xmlDtdPtr dtd )
{
if ( dtd = = NULL ) {
if ( ! ctxt - > check )
fprintf ( ctxt - > output , " DTD is NULL \n " ) ;
return ;
}
2004-10-07 17:14:19 +04:00
xmlCtxtDumpDtdNode ( ctxt , dtd ) ;
2004-10-04 18:09:17 +04:00
if ( dtd - > children = = NULL )
fprintf ( ctxt - > output , " DTD is empty \n " ) ;
else {
ctxt - > depth + + ;
xmlCtxtDumpNodeList ( ctxt , dtd - > children ) ;
ctxt - > depth - - ;
}
}
2004-10-07 17:14:19 +04:00
2004-10-04 18:09:17 +04:00
/************************************************************************
* *
2004-10-07 17:14:19 +04:00
* Public entry points for dump *
2004-10-04 18:09:17 +04:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlDebugDumpString :
* @ output : the FILE * for the output
* @ str : the string
*
2020-03-08 19:19:42 +03:00
* Dumps information about the string , shorten it if necessary
2004-10-04 18:09:17 +04:00
*/
void
xmlDebugDumpString ( FILE * output , const xmlChar * str )
{
int i ;
if ( output = = NULL )
output = stdout ;
if ( str = = NULL ) {
fprintf ( output , " (NULL) " ) ;
return ;
}
for ( i = 0 ; i < 40 ; i + + )
if ( str [ i ] = = 0 )
return ;
else if ( IS_BLANK_CH ( str [ i ] ) )
fputc ( ' ' , output ) ;
else if ( str [ i ] > = 0x80 )
fprintf ( output , " #%X " , str [ i ] ) ;
else
fputc ( str [ i ] , output ) ;
fprintf ( output , " ... " ) ;
}
/**
* xmlDebugDumpAttr :
* @ output : the FILE * for the output
* @ attr : the attribute
* @ depth : the indentation level .
*
* Dumps debug information for the attribute
*/
void
xmlDebugDumpAttr ( FILE * output , xmlAttrPtr attr , int depth ) {
xmlDebugCtxt ctxt ;
2004-11-08 19:24:57 +03:00
if ( output = = NULL ) return ;
2004-10-04 18:09:17 +04:00
xmlCtxtDumpInitCtxt ( & ctxt ) ;
ctxt . output = output ;
ctxt . depth = depth ;
xmlCtxtDumpAttr ( & ctxt , attr ) ;
2004-10-10 00:39:04 +04:00
xmlCtxtDumpCleanCtxt ( & ctxt ) ;
2004-10-04 18:09:17 +04:00
}
/**
* xmlDebugDumpEntities :
* @ output : the FILE * for the output
* @ doc : the document
*
* Dumps debug information for all the entities in use by the document
*/
void
xmlDebugDumpEntities ( FILE * output , xmlDocPtr doc )
{
xmlDebugCtxt ctxt ;
2004-11-08 19:24:57 +03:00
if ( output = = NULL ) return ;
2004-10-04 18:09:17 +04:00
xmlCtxtDumpInitCtxt ( & ctxt ) ;
ctxt . output = output ;
xmlCtxtDumpEntities ( & ctxt , doc ) ;
2004-10-10 00:39:04 +04:00
xmlCtxtDumpCleanCtxt ( & ctxt ) ;
2004-10-04 18:09:17 +04:00
}
/**
* xmlDebugDumpAttrList :
* @ output : the FILE * for the output
* @ attr : the attribute list
* @ depth : the indentation level .
*
* Dumps debug information for the attribute list
*/
void
xmlDebugDumpAttrList ( FILE * output , xmlAttrPtr attr , int depth )
{
xmlDebugCtxt ctxt ;
2004-11-08 19:24:57 +03:00
if ( output = = NULL ) return ;
2004-10-04 18:09:17 +04:00
xmlCtxtDumpInitCtxt ( & ctxt ) ;
ctxt . output = output ;
ctxt . depth = depth ;
xmlCtxtDumpAttrList ( & ctxt , attr ) ;
2004-10-10 00:39:04 +04:00
xmlCtxtDumpCleanCtxt ( & ctxt ) ;
2001-02-23 20:55:21 +03:00
}
2004-10-04 18:09:17 +04:00
/**
* xmlDebugDumpOneNode :
* @ output : the FILE * for the output
* @ node : the node
* @ depth : the indentation level .
*
* Dumps debug information for the element node , it is not recursive
*/
void
xmlDebugDumpOneNode ( FILE * output , xmlNodePtr node , int depth )
{
xmlDebugCtxt ctxt ;
2004-11-08 19:24:57 +03:00
if ( output = = NULL ) return ;
2004-10-04 18:09:17 +04:00
xmlCtxtDumpInitCtxt ( & ctxt ) ;
ctxt . output = output ;
ctxt . depth = depth ;
xmlCtxtDumpOneNode ( & ctxt , node ) ;
2004-10-10 00:39:04 +04:00
xmlCtxtDumpCleanCtxt ( & ctxt ) ;
2004-10-04 18:09:17 +04:00
}
/**
* xmlDebugDumpNode :
* @ output : the FILE * for the output
* @ node : the node
* @ depth : the indentation level .
*
* Dumps debug information for the element node , it is recursive
*/
void
xmlDebugDumpNode ( FILE * output , xmlNodePtr node , int depth )
{
xmlDebugCtxt ctxt ;
if ( output = = NULL )
output = stdout ;
xmlCtxtDumpInitCtxt ( & ctxt ) ;
ctxt . output = output ;
ctxt . depth = depth ;
xmlCtxtDumpNode ( & ctxt , node ) ;
2004-10-10 00:39:04 +04:00
xmlCtxtDumpCleanCtxt ( & ctxt ) ;
2004-10-04 18:09:17 +04:00
}
/**
* xmlDebugDumpNodeList :
* @ output : the FILE * for the output
* @ node : the node list
* @ depth : the indentation level .
*
* Dumps debug information for the list of element node , it is recursive
*/
void
xmlDebugDumpNodeList ( FILE * output , xmlNodePtr node , int depth )
{
xmlDebugCtxt ctxt ;
if ( output = = NULL )
output = stdout ;
xmlCtxtDumpInitCtxt ( & ctxt ) ;
ctxt . output = output ;
ctxt . depth = depth ;
xmlCtxtDumpNodeList ( & ctxt , node ) ;
2004-10-10 00:39:04 +04:00
xmlCtxtDumpCleanCtxt ( & ctxt ) ;
2004-10-04 18:09:17 +04:00
}
/**
* xmlDebugDumpDocumentHead :
* @ output : the FILE * for the output
* @ doc : the document
*
2019-09-30 18:04:54 +03:00
* Dumps debug information concerning the document , not recursive
2004-10-04 18:09:17 +04:00
*/
void
xmlDebugDumpDocumentHead ( FILE * output , xmlDocPtr doc )
{
xmlDebugCtxt ctxt ;
if ( output = = NULL )
output = stdout ;
xmlCtxtDumpInitCtxt ( & ctxt ) ;
2005-08-25 18:03:56 +04:00
ctxt . options | = DUMP_TEXT_TYPE ;
2004-10-04 18:09:17 +04:00
ctxt . output = output ;
xmlCtxtDumpDocumentHead ( & ctxt , doc ) ;
2004-10-10 00:39:04 +04:00
xmlCtxtDumpCleanCtxt ( & ctxt ) ;
2004-10-04 18:09:17 +04:00
}
/**
* xmlDebugDumpDocument :
* @ output : the FILE * for the output
* @ doc : the document
*
* Dumps debug information for the document , it ' s recursive
*/
void
xmlDebugDumpDocument ( FILE * output , xmlDocPtr doc )
{
xmlDebugCtxt ctxt ;
if ( output = = NULL )
output = stdout ;
xmlCtxtDumpInitCtxt ( & ctxt ) ;
2005-08-25 18:03:56 +04:00
ctxt . options | = DUMP_TEXT_TYPE ;
2004-10-04 18:09:17 +04:00
ctxt . output = output ;
xmlCtxtDumpDocument ( & ctxt , doc ) ;
2004-10-10 00:39:04 +04:00
xmlCtxtDumpCleanCtxt ( & ctxt ) ;
2004-10-04 18:09:17 +04:00
}
/**
* xmlDebugDumpDTD :
* @ output : the FILE * for the output
* @ dtd : the DTD
*
* Dumps debug information for the DTD
*/
void
xmlDebugDumpDTD ( FILE * output , xmlDtdPtr dtd )
{
xmlDebugCtxt ctxt ;
if ( output = = NULL )
output = stdout ;
xmlCtxtDumpInitCtxt ( & ctxt ) ;
2005-08-25 18:03:56 +04:00
ctxt . options | = DUMP_TEXT_TYPE ;
2004-10-04 18:09:17 +04:00
ctxt . output = output ;
xmlCtxtDumpDTD ( & ctxt , dtd ) ;
2004-10-10 00:39:04 +04:00
xmlCtxtDumpCleanCtxt ( & ctxt ) ;
2004-10-04 18:09:17 +04:00
}
2004-10-07 17:14:19 +04:00
/************************************************************************
* *
* Public entry points for checkings *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlDebugCheckDocument :
* @ output : the FILE * for the output
* @ doc : the document
*
* Check the document for potential content problems , and output
* the errors to @ output
*
* Returns the number of errors found
*/
int
xmlDebugCheckDocument ( FILE * output , xmlDocPtr doc )
{
xmlDebugCtxt ctxt ;
if ( output = = NULL )
output = stdout ;
xmlCtxtDumpInitCtxt ( & ctxt ) ;
ctxt . output = output ;
ctxt . check = 1 ;
xmlCtxtDumpDocument ( & ctxt , doc ) ;
2004-10-10 00:39:04 +04:00
xmlCtxtDumpCleanCtxt ( & ctxt ) ;
2004-10-07 17:14:19 +04:00
return ( ctxt . errors ) ;
}
2004-10-04 18:09:17 +04:00
/************************************************************************
* *
* Helpers for Shell *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-31 19:16:02 +03:00
/**
* xmlLsCountNode :
* @ node : the node to count
*
* Count the children of @ node .
*
* Returns the number of children of @ node .
*/
int
xmlLsCountNode ( xmlNodePtr node ) {
2001-02-23 20:55:21 +03:00
int ret = 0 ;
xmlNodePtr list = NULL ;
2012-09-11 09:26:36 +04:00
2002-01-23 00:44:25 +03:00
if ( node = = NULL )
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
switch ( node - > type ) {
case XML_ELEMENT_NODE :
list = node - > children ;
break ;
case XML_DOCUMENT_NODE :
case XML_HTML_DOCUMENT_NODE :
list = ( ( xmlDocPtr ) node ) - > children ;
break ;
case XML_ATTRIBUTE_NODE :
list = ( ( xmlAttrPtr ) node ) - > children ;
break ;
case XML_TEXT_NODE :
case XML_CDATA_SECTION_NODE :
case XML_PI_NODE :
case XML_COMMENT_NODE :
if ( node - > content ! = NULL ) {
ret = xmlStrlen ( node - > content ) ;
}
break ;
case XML_ENTITY_REF_NODE :
case XML_DOCUMENT_TYPE_NODE :
case XML_ENTITY_NODE :
case XML_DOCUMENT_FRAG_NODE :
case XML_NOTATION_NODE :
case XML_DTD_NODE :
case XML_ELEMENT_DECL :
case XML_ATTRIBUTE_DECL :
case XML_ENTITY_DECL :
case XML_NAMESPACE_DECL :
case XML_XINCLUDE_START :
case XML_XINCLUDE_END :
ret = 1 ;
break ;
}
2012-09-11 09:26:36 +04:00
for ( ; list ! = NULL ; ret + + )
2001-02-23 20:55:21 +03:00
list = list - > next ;
return ( ret ) ;
}
2001-12-31 19:16:02 +03:00
/**
* xmlLsOneNode :
* @ output : the FILE * for the output
* @ node : the node to dump
*
* Dump to @ output the type and name of @ node .
*/
2001-10-11 13:12:24 +04:00
void
2001-07-18 23:30:27 +04:00
xmlLsOneNode ( FILE * output , xmlNodePtr node ) {
2004-11-08 19:24:57 +03:00
if ( output = = NULL ) return ;
2002-01-23 00:44:25 +03:00
if ( node = = NULL ) {
fprintf ( output , " NULL \n " ) ;
return ;
}
2001-02-23 20:55:21 +03:00
switch ( node - > type ) {
case XML_ELEMENT_NODE :
fprintf ( output , " - " ) ;
break ;
case XML_ATTRIBUTE_NODE :
fprintf ( output , " a " ) ;
break ;
case XML_TEXT_NODE :
fprintf ( output , " t " ) ;
break ;
case XML_CDATA_SECTION_NODE :
2002-03-13 13:03:35 +03:00
fprintf ( output , " C " ) ;
2001-02-23 20:55:21 +03:00
break ;
case XML_ENTITY_REF_NODE :
fprintf ( output , " e " ) ;
break ;
case XML_ENTITY_NODE :
fprintf ( output , " E " ) ;
break ;
case XML_PI_NODE :
fprintf ( output , " p " ) ;
break ;
case XML_COMMENT_NODE :
fprintf ( output , " c " ) ;
break ;
case XML_DOCUMENT_NODE :
fprintf ( output , " d " ) ;
break ;
case XML_HTML_DOCUMENT_NODE :
fprintf ( output , " h " ) ;
break ;
case XML_DOCUMENT_TYPE_NODE :
fprintf ( output , " T " ) ;
break ;
case XML_DOCUMENT_FRAG_NODE :
fprintf ( output , " F " ) ;
break ;
case XML_NOTATION_NODE :
fprintf ( output , " N " ) ;
break ;
2002-01-14 20:11:53 +03:00
case XML_NAMESPACE_DECL :
fprintf ( output , " n " ) ;
break ;
2001-02-23 20:55:21 +03:00
default :
fprintf ( output , " ? " ) ;
}
2002-01-14 20:11:53 +03:00
if ( node - > type ! = XML_NAMESPACE_DECL ) {
if ( node - > properties ! = NULL )
fprintf ( output , " a " ) ;
2012-09-11 09:26:36 +04:00
else
2002-01-14 20:11:53 +03:00
fprintf ( output , " - " ) ;
2012-09-11 09:26:36 +04:00
if ( node - > nsDef ! = NULL )
2002-01-14 20:11:53 +03:00
fprintf ( output , " n " ) ;
2012-09-11 09:26:36 +04:00
else
2002-01-14 20:11:53 +03:00
fprintf ( output , " - " ) ;
}
2001-02-23 20:55:21 +03:00
fprintf ( output , " %8d " , xmlLsCountNode ( node ) ) ;
switch ( node - > type ) {
case XML_ELEMENT_NODE :
2012-05-07 13:04:04 +04:00
if ( node - > name ! = NULL ) {
if ( ( node - > ns ! = NULL ) & & ( node - > ns - > prefix ! = NULL ) )
fprintf ( output , " %s: " , node - > ns - > prefix ) ;
2003-03-22 00:22:48 +03:00
fprintf ( output , " %s " , ( const char * ) node - > name ) ;
2012-05-07 13:04:04 +04:00
}
2001-02-23 20:55:21 +03:00
break ;
case XML_ATTRIBUTE_NODE :
if ( node - > name ! = NULL )
2003-03-22 00:22:48 +03:00
fprintf ( output , " %s " , ( const char * ) node - > name ) ;
2001-02-23 20:55:21 +03:00
break ;
case XML_TEXT_NODE :
if ( node - > content ! = NULL ) {
xmlDebugDumpString ( output , node - > content ) ;
}
break ;
case XML_CDATA_SECTION_NODE :
break ;
case XML_ENTITY_REF_NODE :
if ( node - > name ! = NULL )
2003-03-22 00:22:48 +03:00
fprintf ( output , " %s " , ( const char * ) node - > name ) ;
2001-02-23 20:55:21 +03:00
break ;
case XML_ENTITY_NODE :
if ( node - > name ! = NULL )
2003-03-22 00:22:48 +03:00
fprintf ( output , " %s " , ( const char * ) node - > name ) ;
2001-02-23 20:55:21 +03:00
break ;
case XML_PI_NODE :
if ( node - > name ! = NULL )
2003-03-22 00:22:48 +03:00
fprintf ( output , " %s " , ( const char * ) node - > name ) ;
2001-02-23 20:55:21 +03:00
break ;
case XML_COMMENT_NODE :
break ;
case XML_DOCUMENT_NODE :
break ;
case XML_HTML_DOCUMENT_NODE :
break ;
case XML_DOCUMENT_TYPE_NODE :
break ;
case XML_DOCUMENT_FRAG_NODE :
break ;
case XML_NOTATION_NODE :
break ;
2002-01-14 20:11:53 +03:00
case XML_NAMESPACE_DECL : {
xmlNsPtr ns = ( xmlNsPtr ) node ;
if ( ns - > prefix = = NULL )
2004-09-18 08:52:08 +04:00
fprintf ( output , " default -> %s " , ( char * ) ns - > href ) ;
2002-01-14 20:11:53 +03:00
else
2004-09-18 08:52:08 +04:00
fprintf ( output , " %s -> %s " , ( char * ) ns - > prefix ,
( char * ) ns - > href ) ;
2002-01-14 20:11:53 +03:00
break ;
}
2001-02-23 20:55:21 +03:00
default :
if ( node - > name ! = NULL )
2003-03-22 00:22:48 +03:00
fprintf ( output , " %s " , ( const char * ) node - > name ) ;
2001-02-23 20:55:21 +03:00
}
fprintf ( output , " \n " ) ;
}
2001-10-11 13:12:24 +04:00
/**
* xmlBoolToText :
2001-12-31 19:16:02 +03:00
* @ boolval : a bool to turn into text
2001-10-11 13:12:24 +04:00
*
2012-09-11 09:26:36 +04:00
* Convenient way to turn bool into text
2001-12-31 19:16:02 +03:00
*
* Returns a pointer to either " True " or " False "
*/
2001-10-11 13:12:24 +04:00
const char *
2001-11-01 11:38:12 +03:00
xmlBoolToText ( int boolval )
2001-10-11 13:12:24 +04:00
{
2001-11-01 11:38:12 +03:00
if ( boolval )
2001-10-11 13:12:24 +04:00
return ( " True " ) ;
else
return ( " False " ) ;
}
2004-11-09 19:17:02 +03:00
# ifdef LIBXML_XPATH_ENABLED
2001-02-23 20:55:21 +03:00
/****************************************************************
* *
2012-09-11 09:26:36 +04:00
* The XML shell related functions *
2001-02-23 20:55:21 +03:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-11 13:12:24 +04:00
2001-02-23 20:55:21 +03:00
/*
* TODO : Improvement / cleanups for the XML shell
* - allow to shell out an editor on a subpart
* - cleanup function registrations ( with help ) and calling
* - provide registration routines
*/
2001-10-11 13:12:24 +04:00
/**
2001-12-31 19:16:02 +03:00
* xmlShellPrintXPathError :
2001-10-11 13:12:24 +04:00
* @ errorType : valid xpath error id
2001-12-31 19:16:02 +03:00
* @ arg : the argument that cause xpath to fail
2001-10-11 13:12:24 +04:00
*
* Print the xpath error to libxml default error channel
*/
void
xmlShellPrintXPathError ( int errorType , const char * arg )
{
const char * default_arg = " Result " ;
if ( ! arg )
arg = default_arg ;
switch ( errorType ) {
case XPATH_UNDEFINED :
2023-12-18 23:09:39 +03:00
fprintf ( stderr ,
2001-10-11 13:12:24 +04:00
" %s: no such node \n " , arg ) ;
break ;
case XPATH_BOOLEAN :
2023-12-18 23:09:39 +03:00
fprintf ( stderr ,
2001-10-11 13:12:24 +04:00
" %s is a Boolean \n " , arg ) ;
break ;
case XPATH_NUMBER :
2023-12-18 23:09:39 +03:00
fprintf ( stderr ,
2001-10-11 13:12:24 +04:00
" %s is a number \n " , arg ) ;
break ;
case XPATH_STRING :
2023-12-18 23:09:39 +03:00
fprintf ( stderr ,
2001-10-11 13:12:24 +04:00
" %s is a string \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# ifdef LIBXML_XPTR_LOCS_ENABLED
2001-10-11 13:12:24 +04:00
case XPATH_POINT :
2023-12-18 23:09:39 +03:00
fprintf ( stderr ,
2001-10-11 13:12:24 +04:00
" %s is a point \n " , arg ) ;
break ;
case XPATH_RANGE :
2023-12-18 23:09:39 +03:00
fprintf ( stderr ,
2001-10-11 13:12:24 +04:00
" %s is a range \n " , arg ) ;
break ;
case XPATH_LOCATIONSET :
2023-12-18 23:09:39 +03:00
fprintf ( stderr ,
2001-10-11 13:12:24 +04:00
" %s is a range \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# endif /* LIBXML_XPTR_LOCS_ENABLED */
2001-10-11 13:12:24 +04:00
case XPATH_USERS :
2023-12-18 23:09:39 +03:00
fprintf ( stderr ,
2001-10-11 13:12:24 +04:00
" %s is user-defined \n " , arg ) ;
break ;
case XPATH_XSLT_TREE :
2023-12-18 23:09:39 +03:00
fprintf ( stderr ,
2001-10-11 13:12:24 +04:00
" %s is an XSLT value tree \n " , arg ) ;
break ;
}
2004-11-08 19:24:57 +03:00
#if 0
2023-12-18 23:09:39 +03:00
fprintf ( stderr ,
2001-10-11 13:12:24 +04:00
" Try casting the result string function (xpath builtin) \n " ,
arg ) ;
2004-11-08 19:24:57 +03:00
# endif
2001-10-11 13:12:24 +04:00
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-10-11 13:12:24 +04:00
/**
2002-10-09 01:26:42 +04:00
* xmlShellPrintNodeCtxt :
* @ ctxt : a non - null shell context
* @ node : a non - null node to print to the output FILE
2001-10-11 13:12:24 +04:00
*
2002-10-09 01:26:42 +04:00
* Print node to the output FILE
2001-10-11 13:12:24 +04:00
*/
2002-10-09 01:26:42 +04:00
static void
xmlShellPrintNodeCtxt ( xmlShellCtxtPtr ctxt , xmlNodePtr node )
2001-10-11 13:12:24 +04:00
{
2002-10-09 14:20:30 +04:00
FILE * fp ;
if ( ! node )
2001-10-11 13:12:24 +04:00
return ;
2002-10-09 14:20:30 +04:00
if ( ctxt = = NULL )
fp = stdout ;
else
fp = ctxt - > output ;
2001-10-11 13:12:24 +04:00
if ( node - > type = = XML_DOCUMENT_NODE )
2002-10-09 14:20:30 +04:00
xmlDocDump ( fp , ( xmlDocPtr ) node ) ;
2001-10-11 13:12:24 +04:00
else if ( node - > type = = XML_ATTRIBUTE_NODE )
2002-10-09 14:20:30 +04:00
xmlDebugDumpAttrList ( fp , ( xmlAttrPtr ) node , 0 ) ;
2001-10-11 13:12:24 +04:00
else
2002-10-09 14:20:30 +04:00
xmlElemDump ( fp , node - > doc , node ) ;
2001-10-11 13:12:24 +04:00
2002-10-09 14:20:30 +04:00
fprintf ( fp , " \n " ) ;
2001-10-11 13:12:24 +04:00
}
2002-10-09 01:26:42 +04:00
/**
* xmlShellPrintNode :
* @ node : a non - null node to print to the output FILE
*
* Print node to the output FILE
*/
void
xmlShellPrintNode ( xmlNodePtr node )
{
xmlShellPrintNodeCtxt ( NULL , node ) ;
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-10-11 13:12:24 +04:00
/**
2002-10-09 01:26:42 +04:00
* xmlShellPrintXPathResultCtxt :
* @ ctxt : a valid shell context
2002-01-22 21:15:52 +03:00
* @ list : a valid result generated by an xpath evaluation
2001-10-11 13:12:24 +04:00
*
2002-10-09 01:26:42 +04:00
* Prints result to the output FILE
2001-10-11 13:12:24 +04:00
*/
2002-10-09 01:26:42 +04:00
static void
xmlShellPrintXPathResultCtxt ( xmlShellCtxtPtr ctxt , xmlXPathObjectPtr list )
2001-10-11 13:12:24 +04:00
{
2002-10-09 01:26:42 +04:00
if ( ! ctxt )
return ;
2001-10-11 13:12:24 +04:00
if ( list ! = NULL ) {
switch ( list - > type ) {
case XPATH_NODESET : {
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-10-11 13:12:24 +04:00
int indx ;
if ( list - > nodesetval ) {
for ( indx = 0 ; indx < list - > nodesetval - > nodeNr ;
indx + + ) {
2002-10-09 01:26:42 +04:00
xmlShellPrintNodeCtxt ( ctxt ,
list - > nodesetval - > nodeTab [ indx ] ) ;
2001-10-11 13:12:24 +04:00
}
} else {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Empty node set \n " ) ;
}
break ;
2003-09-29 17:20:24 +04:00
# else
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2003-09-29 17:20:24 +04:00
" Node set \n " ) ;
# endif /* LIBXML_OUTPUT_ENABLED */
2001-10-11 13:12:24 +04:00
}
case XPATH_BOOLEAN :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Is a Boolean:%s \n " ,
xmlBoolToText ( list - > boolval ) ) ;
break ;
case XPATH_NUMBER :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Is a number:%0g \n " , list - > floatval ) ;
break ;
case XPATH_STRING :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Is a string:%s \n " , list - > stringval ) ;
break ;
default :
xmlShellPrintXPathError ( list - > type , NULL ) ;
}
}
}
2002-10-09 01:26:42 +04:00
/**
* xmlShellPrintXPathResult :
* @ list : a valid result generated by an xpath evaluation
*
* Prints result to the output FILE
*/
void
xmlShellPrintXPathResult ( xmlXPathObjectPtr list )
{
xmlShellPrintXPathResultCtxt ( NULL , list ) ;
}
2001-02-23 20:55:21 +03:00
/**
* xmlShellList :
* @ ctxt : the shell context
* @ arg : unused
* @ node : a node
* @ node2 : unused
*
* Implements the XML shell function " ls "
* Does an Unix like listing of the given node ( like a directory )
*
* Returns 0
*/
2001-10-11 13:12:24 +04:00
int
2002-10-09 01:26:42 +04:00
xmlShellList ( xmlShellCtxtPtr ctxt ,
2001-10-11 13:12:24 +04:00
char * arg ATTRIBUTE_UNUSED , xmlNodePtr node ,
xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
2001-02-23 20:55:21 +03:00
xmlNodePtr cur ;
2002-10-09 01:26:42 +04:00
if ( ! ctxt )
return ( 0 ) ;
2002-01-23 00:44:25 +03:00
if ( node = = NULL ) {
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " NULL \n " ) ;
2002-01-23 00:44:25 +03:00
return ( 0 ) ;
}
2001-02-23 20:55:21 +03:00
if ( ( node - > type = = XML_DOCUMENT_NODE ) | |
( node - > type = = XML_HTML_DOCUMENT_NODE ) ) {
cur = ( ( xmlDocPtr ) node ) - > children ;
2002-01-14 20:11:53 +03:00
} else if ( node - > type = = XML_NAMESPACE_DECL ) {
2002-10-09 01:26:42 +04:00
xmlLsOneNode ( ctxt - > output , node ) ;
2002-01-14 20:11:53 +03:00
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
} else if ( node - > children ! = NULL ) {
cur = node - > children ;
} else {
2002-10-09 01:26:42 +04:00
xmlLsOneNode ( ctxt - > output , node ) ;
2001-10-11 13:12:24 +04:00
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
while ( cur ! = NULL ) {
2002-10-09 01:26:42 +04:00
xmlLsOneNode ( ctxt - > output , cur ) ;
2001-10-11 13:12:24 +04:00
cur = cur - > next ;
2001-02-23 20:55:21 +03:00
}
2001-10-11 13:12:24 +04:00
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
2001-07-09 20:01:19 +04:00
/**
* xmlShellBase :
* @ ctxt : the shell context
* @ arg : unused
* @ node : a node
* @ node2 : unused
*
* Implements the XML shell function " base "
* dumps the current XML base of the node
*
* Returns 0
*/
2001-10-11 13:12:24 +04:00
int
2002-10-09 01:26:42 +04:00
xmlShellBase ( xmlShellCtxtPtr ctxt ,
2001-10-11 13:12:24 +04:00
char * arg ATTRIBUTE_UNUSED , xmlNodePtr node ,
xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
2001-07-09 20:01:19 +04:00
xmlChar * base ;
2002-10-09 01:26:42 +04:00
if ( ! ctxt )
return 0 ;
2002-01-23 00:44:25 +03:00
if ( node = = NULL ) {
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " NULL \n " ) ;
2002-01-23 00:44:25 +03:00
return ( 0 ) ;
2012-09-11 09:26:36 +04:00
}
2001-07-09 20:01:19 +04:00
base = xmlNodeGetBase ( node - > doc , node ) ;
if ( base = = NULL ) {
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " No base found !!! \n " ) ;
2001-07-09 20:01:19 +04:00
} else {
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " %s \n " , base ) ;
2001-10-11 13:12:24 +04:00
xmlFree ( base ) ;
2001-07-09 20:01:19 +04:00
}
2001-10-11 13:12:24 +04:00
return ( 0 ) ;
2001-07-09 20:01:19 +04:00
}
2004-03-04 20:09:47 +03:00
# ifdef LIBXML_TREE_ENABLED
2002-01-17 11:46:58 +03:00
/**
* xmlShellSetBase :
* @ ctxt : the shell context
* @ arg : the new base
* @ node : a node
* @ node2 : unused
*
* Implements the XML shell function " setbase "
* change the current XML base of the node
*
* Returns 0
*/
static int
xmlShellSetBase ( xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED ,
char * arg ATTRIBUTE_UNUSED , xmlNodePtr node ,
xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
xmlNodeSetBase ( node , ( xmlChar * ) arg ) ;
return ( 0 ) ;
}
2004-03-04 18:59:36 +03:00
# endif
2002-01-17 11:46:58 +03:00
2004-06-16 18:08:33 +04:00
# ifdef LIBXML_XPATH_ENABLED
/**
* xmlShellRegisterNamespace :
* @ ctxt : the shell context
* @ arg : a string in prefix = nsuri format
* @ node : unused
* @ node2 : unused
*
* Implements the XML shell function " setns "
* register / unregister a prefix = namespace pair
* on the XPath context
*
* Returns 0 on success and a negative value otherwise .
*/
static int
xmlShellRegisterNamespace ( xmlShellCtxtPtr ctxt , char * arg ,
xmlNodePtr node ATTRIBUTE_UNUSED , xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
xmlChar * nsListDup ;
xmlChar * prefix ;
xmlChar * href ;
xmlChar * next ;
nsListDup = xmlStrdup ( ( xmlChar * ) arg ) ;
next = nsListDup ;
while ( next ! = NULL ) {
/* skip spaces */
/*while((*next) == ' ') next++;*/
if ( ( * next ) = = ' \0 ' ) break ;
/* find prefix */
prefix = next ;
next = ( xmlChar * ) xmlStrchr ( next , ' = ' ) ;
if ( next = = NULL ) {
fprintf ( ctxt - > output , " setns: prefix=[nsuri] required \n " ) ;
xmlFree ( nsListDup ) ;
return ( - 1 ) ;
}
* ( next + + ) = ' \0 ' ;
/* find href */
href = next ;
next = ( xmlChar * ) xmlStrchr ( next , ' ' ) ;
if ( next ! = NULL ) {
* ( next + + ) = ' \0 ' ;
}
/* do register namespace */
if ( xmlXPathRegisterNs ( ctxt - > pctxt , prefix , href ) ! = 0 ) {
fprintf ( ctxt - > output , " Error: unable to register NS with prefix= \" %s \" and href= \" %s \" \n " , prefix , href ) ;
xmlFree ( nsListDup ) ;
return ( - 1 ) ;
}
}
xmlFree ( nsListDup ) ;
return ( 0 ) ;
}
2005-07-04 13:27:40 +04:00
/**
* xmlShellRegisterRootNamespaces :
* @ ctxt : the shell context
* @ arg : unused
* @ node : the root element
* @ node2 : unused
*
* Implements the XML shell function " setrootns "
* which registers all namespaces declarations found on the root element .
*
* Returns 0 on success and a negative value otherwise .
*/
static int
xmlShellRegisterRootNamespaces ( xmlShellCtxtPtr ctxt , char * arg ATTRIBUTE_UNUSED ,
xmlNodePtr root , xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
xmlNsPtr ns ;
if ( ( root = = NULL ) | | ( root - > type ! = XML_ELEMENT_NODE ) | |
( root - > nsDef = = NULL ) | | ( ctxt = = NULL ) | | ( ctxt - > pctxt = = NULL ) )
return ( - 1 ) ;
ns = root - > nsDef ;
while ( ns ! = NULL ) {
if ( ns - > prefix = = NULL )
xmlXPathRegisterNs ( ctxt - > pctxt , BAD_CAST " defaultns " , ns - > href ) ;
else
xmlXPathRegisterNs ( ctxt - > pctxt , ns - > prefix , ns - > href ) ;
ns = ns - > next ;
}
return ( 0 ) ;
}
2004-06-16 18:08:33 +04:00
# endif
2002-10-22 18:25:25 +04:00
/**
* xmlShellGrep :
* @ ctxt : the shell context
* @ arg : the string or regular expression to find
* @ node : a node
* @ node2 : unused
*
* Implements the XML shell function " grep "
2020-03-08 19:19:42 +03:00
* dumps information about the node ( namespace , attributes , content ) .
2002-10-22 18:25:25 +04:00
*
* Returns 0
*/
2002-10-22 21:35:37 +04:00
static int
2002-10-22 18:25:25 +04:00
xmlShellGrep ( xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED ,
char * arg , xmlNodePtr node , xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
if ( ! ctxt )
return ( 0 ) ;
if ( node = = NULL )
return ( 0 ) ;
if ( arg = = NULL )
return ( 0 ) ;
# ifdef LIBXML_REGEXP_ENABLED
if ( ( xmlStrchr ( ( xmlChar * ) arg , ' ? ' ) ) | |
( xmlStrchr ( ( xmlChar * ) arg , ' * ' ) ) | |
( xmlStrchr ( ( xmlChar * ) arg , ' . ' ) ) | |
( xmlStrchr ( ( xmlChar * ) arg , ' [ ' ) ) ) {
}
# endif
while ( node ! = NULL ) {
if ( node - > type = = XML_COMMENT_NODE ) {
2002-10-22 21:35:37 +04:00
if ( xmlStrstr ( node - > content , ( xmlChar * ) arg ) ) {
2002-10-22 18:25:25 +04:00
fprintf ( ctxt - > output , " %s : " , xmlGetNodePath ( node ) ) ;
xmlShellList ( ctxt , NULL , node , NULL ) ;
}
} else if ( node - > type = = XML_TEXT_NODE ) {
2002-10-22 21:35:37 +04:00
if ( xmlStrstr ( node - > content , ( xmlChar * ) arg ) ) {
2002-10-22 18:25:25 +04:00
fprintf ( ctxt - > output , " %s : " , xmlGetNodePath ( node - > parent ) ) ;
2002-10-22 21:35:37 +04:00
xmlShellList ( ctxt , NULL , node - > parent , NULL ) ;
2002-10-22 18:25:25 +04:00
}
}
/*
* Browse the full subtree , deep first
*/
if ( ( node - > type = = XML_DOCUMENT_NODE ) | |
( node - > type = = XML_HTML_DOCUMENT_NODE ) ) {
node = ( ( xmlDocPtr ) node ) - > children ;
} else if ( ( node - > children ! = NULL )
& & ( node - > type ! = XML_ENTITY_REF_NODE ) ) {
/* deep first */
node = node - > children ;
} else if ( node - > next ! = NULL ) {
/* then siblings */
node = node - > next ;
} else {
/* go up to parents->next if needed */
while ( node ! = NULL ) {
if ( node - > parent ! = NULL ) {
node = node - > parent ;
}
if ( node - > next ! = NULL ) {
node = node - > next ;
break ;
}
if ( node - > parent = = NULL ) {
node = NULL ;
break ;
}
}
}
}
return ( 0 ) ;
}
2001-02-23 20:55:21 +03:00
/**
* xmlShellDir :
* @ ctxt : the shell context
* @ arg : unused
* @ node : a node
* @ node2 : unused
*
* Implements the XML shell function " dir "
2020-03-08 19:19:42 +03:00
* dumps information about the node ( namespace , attributes , content ) .
2001-02-23 20:55:21 +03:00
*
* Returns 0
*/
2001-10-11 13:12:24 +04:00
int
xmlShellDir ( xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED ,
char * arg ATTRIBUTE_UNUSED , xmlNodePtr node ,
xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
2002-10-09 01:26:42 +04:00
if ( ! ctxt )
return ( 0 ) ;
2002-01-23 00:44:25 +03:00
if ( node = = NULL ) {
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " NULL \n " ) ;
2002-01-23 00:44:25 +03:00
return ( 0 ) ;
2012-09-11 09:26:36 +04:00
}
2001-02-23 20:55:21 +03:00
if ( ( node - > type = = XML_DOCUMENT_NODE ) | |
( node - > type = = XML_HTML_DOCUMENT_NODE ) ) {
2002-10-09 01:26:42 +04:00
xmlDebugDumpDocumentHead ( ctxt - > output , ( xmlDocPtr ) node ) ;
2001-02-23 20:55:21 +03:00
} else if ( node - > type = = XML_ATTRIBUTE_NODE ) {
2002-10-09 01:26:42 +04:00
xmlDebugDumpAttr ( ctxt - > output , ( xmlAttrPtr ) node , 0 ) ;
2001-02-23 20:55:21 +03:00
} else {
2002-10-09 01:26:42 +04:00
xmlDebugDumpOneNode ( ctxt - > output , node , 0 ) ;
2001-02-23 20:55:21 +03:00
}
2001-10-11 13:12:24 +04:00
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
2004-08-16 04:39:03 +04:00
/**
* xmlShellSetContent :
* @ ctxt : the shell context
* @ value : the content as a string
* @ node : a node
* @ node2 : unused
*
* Implements the XML shell function " dir "
2020-03-08 19:19:42 +03:00
* dumps information about the node ( namespace , attributes , content ) .
2004-08-16 04:39:03 +04:00
*
* Returns 0
*/
static int
xmlShellSetContent ( xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED ,
char * value , xmlNodePtr node ,
xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
xmlNodePtr results ;
xmlParserErrors ret ;
if ( ! ctxt )
return ( 0 ) ;
if ( node = = NULL ) {
fprintf ( ctxt - > output , " NULL \n " ) ;
return ( 0 ) ;
}
if ( value = = NULL ) {
fprintf ( ctxt - > output , " NULL \n " ) ;
return ( 0 ) ;
}
ret = xmlParseInNodeContext ( node , value , strlen ( value ) , 0 , & results ) ;
if ( ret = = XML_ERR_OK ) {
if ( node - > children ! = NULL ) {
xmlFreeNodeList ( node - > children ) ;
node - > children = NULL ;
node - > last = NULL ;
}
xmlAddChildList ( node , results ) ;
} else {
fprintf ( ctxt - > output , " failed to parse content \n " ) ;
}
return ( 0 ) ;
}
2023-12-18 23:09:39 +03:00
static void
xmlShellPrintf ( void * ctx , const char * msg , . . . ) {
xmlShellCtxtPtr sctxt = ctx ;
va_list ap ;
va_start ( ap , msg ) ;
vfprintf ( sctxt - > output , msg , ap ) ;
va_end ( ap ) ;
}
2004-02-21 14:53:09 +03:00
# ifdef LIBXML_SCHEMAS_ENABLED
/**
* xmlShellRNGValidate :
* @ ctxt : the shell context
* @ schemas : the path to the Relax - NG schemas
* @ node : a node
* @ node2 : unused
*
* Implements the XML shell function " relaxng "
* validating the instance against a Relax - NG schemas
*
* Returns 0
*/
static int
xmlShellRNGValidate ( xmlShellCtxtPtr sctxt , char * schemas ,
xmlNodePtr node ATTRIBUTE_UNUSED ,
xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
xmlRelaxNGPtr relaxngschemas ;
xmlRelaxNGParserCtxtPtr ctxt ;
xmlRelaxNGValidCtxtPtr vctxt ;
int ret ;
ctxt = xmlRelaxNGNewParserCtxt ( schemas ) ;
2023-12-18 23:09:39 +03:00
xmlRelaxNGSetParserErrors ( ctxt , xmlShellPrintf , xmlShellPrintf , sctxt ) ;
2004-02-21 14:53:09 +03:00
relaxngschemas = xmlRelaxNGParse ( ctxt ) ;
xmlRelaxNGFreeParserCtxt ( ctxt ) ;
if ( relaxngschemas = = NULL ) {
2023-12-18 23:09:39 +03:00
fprintf ( sctxt - > output ,
2004-02-21 14:53:09 +03:00
" Relax-NG schema %s failed to compile \n " , schemas ) ;
return ( - 1 ) ;
}
vctxt = xmlRelaxNGNewValidCtxt ( relaxngschemas ) ;
2023-12-18 23:09:39 +03:00
xmlRelaxNGSetValidErrors ( vctxt , xmlShellPrintf , xmlShellPrintf , sctxt ) ;
2004-02-21 14:53:09 +03:00
ret = xmlRelaxNGValidateDoc ( vctxt , sctxt - > doc ) ;
if ( ret = = 0 ) {
2023-12-18 23:09:39 +03:00
fprintf ( sctxt - > output , " %s validates \n " , sctxt - > filename ) ;
2004-02-21 14:53:09 +03:00
} else if ( ret > 0 ) {
2023-12-18 23:09:39 +03:00
fprintf ( sctxt - > output , " %s fails to validate \n " , sctxt - > filename ) ;
2004-02-21 14:53:09 +03:00
} else {
2023-12-18 23:09:39 +03:00
fprintf ( sctxt - > output , " %s validation generated an internal error \n " ,
2004-02-21 14:53:09 +03:00
sctxt - > filename ) ;
}
xmlRelaxNGFreeValidCtxt ( vctxt ) ;
if ( relaxngschemas ! = NULL )
xmlRelaxNGFree ( relaxngschemas ) ;
return ( 0 ) ;
}
# endif
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03:00
/**
* xmlShellCat :
* @ ctxt : the shell context
* @ arg : unused
* @ node : a node
* @ node2 : unused
*
* Implements the XML shell function " cat "
* dumps the serialization node content ( XML or HTML ) .
*
* Returns 0
*/
2001-10-11 13:12:24 +04:00
int
xmlShellCat ( xmlShellCtxtPtr ctxt , char * arg ATTRIBUTE_UNUSED ,
xmlNodePtr node , xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
2002-10-09 01:26:42 +04:00
if ( ! ctxt )
return ( 0 ) ;
2002-01-23 00:44:25 +03:00
if ( node = = NULL ) {
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " NULL \n " ) ;
2002-01-23 00:44:25 +03:00
return ( 0 ) ;
2012-09-11 09:26:36 +04:00
}
2001-02-23 20:55:21 +03:00
if ( ctxt - > doc - > type = = XML_HTML_DOCUMENT_NODE ) {
# ifdef LIBXML_HTML_ENABLED
2001-10-11 13:12:24 +04:00
if ( node - > type = = XML_HTML_DOCUMENT_NODE )
2002-10-09 01:26:42 +04:00
htmlDocDump ( ctxt - > output , ( htmlDocPtr ) node ) ;
2001-10-11 13:12:24 +04:00
else
2002-10-09 01:26:42 +04:00
htmlNodeDumpFile ( ctxt - > output , ctxt - > doc , node ) ;
2001-02-23 20:55:21 +03:00
# else
2001-10-11 13:12:24 +04:00
if ( node - > type = = XML_DOCUMENT_NODE )
2002-10-09 01:26:42 +04:00
xmlDocDump ( ctxt - > output , ( xmlDocPtr ) node ) ;
2001-10-11 13:12:24 +04:00
else
2002-10-09 01:26:42 +04:00
xmlElemDump ( ctxt - > output , ctxt - > doc , node ) ;
2001-02-23 20:55:21 +03:00
# endif /* LIBXML_HTML_ENABLED */
} else {
2001-10-11 13:12:24 +04:00
if ( node - > type = = XML_DOCUMENT_NODE )
2002-10-09 01:26:42 +04:00
xmlDocDump ( ctxt - > output , ( xmlDocPtr ) node ) ;
2001-10-11 13:12:24 +04:00
else
2002-10-09 01:26:42 +04:00
xmlElemDump ( ctxt - > output , ctxt - > doc , node ) ;
2001-02-23 20:55:21 +03:00
}
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " \n " ) ;
2001-10-11 13:12:24 +04:00
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
/**
* xmlShellLoad :
* @ ctxt : the shell context
* @ filename : the file name
* @ node : unused
* @ node2 : unused
*
* Implements the XML shell function " load "
* loads a new document specified by the filename
*
* Returns 0 or - 1 if loading failed
*/
2001-10-11 13:12:24 +04:00
int
xmlShellLoad ( xmlShellCtxtPtr ctxt , char * filename ,
xmlNodePtr node ATTRIBUTE_UNUSED ,
xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
2001-02-23 20:55:21 +03:00
xmlDocPtr doc ;
int html = 0 ;
2004-11-08 19:24:57 +03:00
if ( ( ctxt = = NULL ) | | ( filename = = NULL ) ) return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
if ( ctxt - > doc ! = NULL )
2001-10-11 13:12:24 +04:00
html = ( ctxt - > doc - > type = = XML_HTML_DOCUMENT_NODE ) ;
2001-02-23 20:55:21 +03:00
if ( html ) {
# ifdef LIBXML_HTML_ENABLED
2001-10-11 13:12:24 +04:00
doc = htmlParseFile ( filename , NULL ) ;
# else
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " HTML support not compiled in \n " ) ;
2001-10-11 13:12:24 +04:00
doc = NULL ;
2001-02-23 20:55:21 +03:00
# endif /* LIBXML_HTML_ENABLED */
} else {
2004-03-25 12:35:49 +03:00
doc = xmlReadFile ( filename , NULL , 0 ) ;
2001-02-23 20:55:21 +03:00
}
if ( doc ! = NULL ) {
if ( ctxt - > loaded = = 1 ) {
2001-10-11 13:12:24 +04:00
xmlFreeDoc ( ctxt - > doc ) ;
}
ctxt - > loaded = 1 ;
2001-02-23 20:55:21 +03:00
# ifdef LIBXML_XPATH_ENABLED
2001-10-11 13:12:24 +04:00
xmlXPathFreeContext ( ctxt - > pctxt ) ;
2001-02-23 20:55:21 +03:00
# endif /* LIBXML_XPATH_ENABLED */
2001-10-11 13:12:24 +04:00
xmlFree ( ctxt - > filename ) ;
ctxt - > doc = doc ;
ctxt - > node = ( xmlNodePtr ) doc ;
2001-02-23 20:55:21 +03:00
# ifdef LIBXML_XPATH_ENABLED
2001-10-11 13:12:24 +04:00
ctxt - > pctxt = xmlXPathNewContext ( doc ) ;
2001-02-23 20:55:21 +03:00
# endif /* LIBXML_XPATH_ENABLED */
2003-04-23 17:56:44 +04:00
ctxt - > filename = ( char * ) xmlCanonicPath ( ( xmlChar * ) filename ) ;
2001-02-23 20:55:21 +03:00
} else
2001-10-11 13:12:24 +04:00
return ( - 1 ) ;
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03:00
/**
* xmlShellWrite :
* @ ctxt : the shell context
* @ filename : the file name
* @ node : a node in the tree
* @ node2 : unused
*
* Implements the XML shell function " write "
2001-12-31 19:16:02 +03:00
* Write the current node to the filename , it saves the serialization
2001-02-23 20:55:21 +03:00
* of the subtree under the @ node specified
*
* Returns 0 or - 1 in case of error
*/
2001-10-11 13:12:24 +04:00
int
2001-02-23 20:55:21 +03:00
xmlShellWrite ( xmlShellCtxtPtr ctxt , char * filename , xmlNodePtr node ,
2001-10-11 13:12:24 +04:00
xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
2001-02-23 20:55:21 +03:00
if ( node = = NULL )
2001-10-11 13:12:24 +04:00
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
if ( ( filename = = NULL ) | | ( filename [ 0 ] = = 0 ) ) {
2001-10-11 13:12:24 +04:00
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
}
# ifdef W_OK
if ( access ( ( char * ) filename , W_OK ) ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Cannot write to %s \n " , filename ) ;
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
}
2001-10-11 13:12:24 +04:00
# endif
switch ( node - > type ) {
2001-02-23 20:55:21 +03:00
case XML_DOCUMENT_NODE :
2001-10-11 13:12:24 +04:00
if ( xmlSaveFile ( ( char * ) filename , ctxt - > doc ) < - 1 ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Failed to write to %s \n " , filename ) ;
return ( - 1 ) ;
}
break ;
2001-02-23 20:55:21 +03:00
case XML_HTML_DOCUMENT_NODE :
# ifdef LIBXML_HTML_ENABLED
2001-10-11 13:12:24 +04:00
if ( htmlSaveFile ( ( char * ) filename , ctxt - > doc ) < 0 ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Failed to write to %s \n " , filename ) ;
return ( - 1 ) ;
}
2001-02-23 20:55:21 +03:00
# else
2001-10-11 13:12:24 +04:00
if ( xmlSaveFile ( ( char * ) filename , ctxt - > doc ) < - 1 ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Failed to write to %s \n " , filename ) ;
return ( - 1 ) ;
}
2001-02-23 20:55:21 +03:00
# endif /* LIBXML_HTML_ENABLED */
2001-10-11 13:12:24 +04:00
break ;
default : {
FILE * f ;
f = fopen ( ( char * ) filename , " w " ) ;
if ( f = = NULL ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Failed to write to %s \n " , filename ) ;
return ( - 1 ) ;
}
xmlElemDump ( f , ctxt - > doc , node ) ;
fclose ( f ) ;
}
2001-02-23 20:55:21 +03:00
}
2001-10-11 13:12:24 +04:00
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlShellSave :
* @ ctxt : the shell context
2001-12-31 19:16:02 +03:00
* @ filename : the file name ( optional )
2001-02-23 20:55:21 +03:00
* @ node : unused
* @ node2 : unused
*
* Implements the XML shell function " save "
* Write the current document to the filename , or it ' s original name
*
* Returns 0 or - 1 in case of error
*/
2001-10-11 13:12:24 +04:00
int
xmlShellSave ( xmlShellCtxtPtr ctxt , char * filename ,
xmlNodePtr node ATTRIBUTE_UNUSED ,
xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
2004-11-08 19:24:57 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > doc = = NULL ) )
2001-10-11 13:12:24 +04:00
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
if ( ( filename = = NULL ) | | ( filename [ 0 ] = = 0 ) )
filename = ctxt - > filename ;
2004-11-08 19:24:57 +03:00
if ( filename = = NULL )
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
# ifdef W_OK
if ( access ( ( char * ) filename , W_OK ) ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Cannot save to %s \n " , filename ) ;
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
}
# endif
2001-10-11 13:12:24 +04:00
switch ( ctxt - > doc - > type ) {
2001-02-23 20:55:21 +03:00
case XML_DOCUMENT_NODE :
2001-10-11 13:12:24 +04:00
if ( xmlSaveFile ( ( char * ) filename , ctxt - > doc ) < 0 ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Failed to save to %s \n " , filename ) ;
}
break ;
2001-02-23 20:55:21 +03:00
case XML_HTML_DOCUMENT_NODE :
# ifdef LIBXML_HTML_ENABLED
2001-10-11 13:12:24 +04:00
if ( htmlSaveFile ( ( char * ) filename , ctxt - > doc ) < 0 ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Failed to save to %s \n " , filename ) ;
}
2001-02-23 20:55:21 +03:00
# else
2001-10-11 13:12:24 +04:00
if ( xmlSaveFile ( ( char * ) filename , ctxt - > doc ) < 0 ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Failed to save to %s \n " , filename ) ;
}
2001-02-23 20:55:21 +03:00
# endif /* LIBXML_HTML_ENABLED */
2001-10-11 13:12:24 +04:00
break ;
default :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" To save to subparts of a document use the 'write' command \n " ) ;
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
}
2001-10-11 13:12:24 +04:00
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
2004-02-25 14:52:31 +03:00
# ifdef LIBXML_VALID_ENABLED
2001-02-23 20:55:21 +03:00
/**
* xmlShellValidate :
* @ ctxt : the shell context
2001-12-31 19:16:02 +03:00
* @ dtd : the DTD URI ( optional )
2001-02-23 20:55:21 +03:00
* @ node : unused
* @ node2 : unused
*
* Implements the XML shell function " validate "
* Validate the document , if a DTD path is provided , then the validation
* is done against the given DTD .
*
* Returns 0 or - 1 in case of error
*/
2001-10-11 13:12:24 +04:00
int
xmlShellValidate ( xmlShellCtxtPtr ctxt , char * dtd ,
xmlNodePtr node ATTRIBUTE_UNUSED ,
xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
2001-02-23 20:55:21 +03:00
xmlValidCtxt vctxt ;
int res = - 1 ;
2004-11-08 19:24:57 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > doc = = NULL ) ) return ( - 1 ) ;
2022-12-01 16:23:09 +03:00
memset ( & vctxt , 0 , sizeof ( vctxt ) ) ;
2023-12-18 23:09:39 +03:00
vctxt . error = xmlShellPrintf ;
vctxt . warning = xmlShellPrintf ;
vctxt . userData = ctxt ;
2001-02-23 20:55:21 +03:00
if ( ( dtd = = NULL ) | | ( dtd [ 0 ] = = 0 ) ) {
res = xmlValidateDocument ( & vctxt , ctxt - > doc ) ;
} else {
xmlDtdPtr subset ;
2001-10-11 13:12:24 +04:00
subset = xmlParseDTD ( NULL , ( xmlChar * ) dtd ) ;
if ( subset ! = NULL ) {
2001-02-23 20:55:21 +03:00
res = xmlValidateDtd ( & vctxt , ctxt - > doc , subset ) ;
2001-10-11 13:12:24 +04:00
xmlFreeDtd ( subset ) ;
}
2001-02-23 20:55:21 +03:00
}
2001-10-11 13:12:24 +04:00
return ( res ) ;
2001-02-23 20:55:21 +03:00
}
2004-02-25 14:52:31 +03:00
# endif /* LIBXML_VALID_ENABLED */
2001-02-23 20:55:21 +03:00
/**
* xmlShellDu :
* @ ctxt : the shell context
* @ arg : unused
* @ tree : a node defining a subtree
* @ node2 : unused
*
* Implements the XML shell function " du "
* show the structure of the subtree under node @ tree
* If @ tree is null , the command works on the current node .
*
* Returns 0 or - 1 in case of error
*/
2001-10-11 13:12:24 +04:00
int
2002-10-09 01:26:42 +04:00
xmlShellDu ( xmlShellCtxtPtr ctxt ,
2001-10-11 13:12:24 +04:00
char * arg ATTRIBUTE_UNUSED , xmlNodePtr tree ,
xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
2001-02-23 20:55:21 +03:00
xmlNodePtr node ;
2001-10-11 13:12:24 +04:00
int indent = 0 , i ;
2001-02-23 20:55:21 +03:00
2002-10-09 01:26:42 +04:00
if ( ! ctxt )
return ( - 1 ) ;
2001-10-11 13:12:24 +04:00
if ( tree = = NULL )
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
node = tree ;
while ( node ! = NULL ) {
if ( ( node - > type = = XML_DOCUMENT_NODE ) | |
( node - > type = = XML_HTML_DOCUMENT_NODE ) ) {
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " / \n " ) ;
2001-10-11 13:12:24 +04:00
} else if ( node - > type = = XML_ELEMENT_NODE ) {
for ( i = 0 ; i < indent ; i + + )
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " " ) ;
2012-05-07 13:04:04 +04:00
if ( ( node - > ns ) & & ( node - > ns - > prefix ) )
fprintf ( ctxt - > output , " %s: " , node - > ns - > prefix ) ;
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " %s \n " , node - > name ) ;
2001-10-11 13:12:24 +04:00
} else {
}
2001-02-23 20:55:21 +03:00
2001-10-11 13:12:24 +04:00
/*
* Browse the full subtree , deep first
*/
2001-02-23 20:55:21 +03:00
if ( ( node - > type = = XML_DOCUMENT_NODE ) | |
( node - > type = = XML_HTML_DOCUMENT_NODE ) ) {
2001-10-11 13:12:24 +04:00
node = ( ( xmlDocPtr ) node ) - > children ;
} else if ( ( node - > children ! = NULL )
& & ( node - > type ! = XML_ENTITY_REF_NODE ) ) {
/* deep first */
node = node - > children ;
indent + + ;
} else if ( ( node ! = tree ) & & ( node - > next ! = NULL ) ) {
/* then siblings */
node = node - > next ;
} else if ( node ! = tree ) {
/* go up to parents->next if needed */
while ( node ! = tree ) {
if ( node - > parent ! = NULL ) {
node = node - > parent ;
indent - - ;
}
if ( ( node ! = tree ) & & ( node - > next ! = NULL ) ) {
node = node - > next ;
break ;
}
if ( node - > parent = = NULL ) {
node = NULL ;
break ;
}
if ( node = = tree ) {
node = NULL ;
break ;
}
}
/* exit condition */
if ( node = = tree )
node = NULL ;
} else
node = NULL ;
}
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlShellPwd :
* @ ctxt : the shell context
* @ buffer : the output buffer
2012-09-11 09:26:36 +04:00
* @ node : a node
2001-02-23 20:55:21 +03:00
* @ node2 : unused
*
* Implements the XML shell function " pwd "
* Show the full path from the root to the node , if needed building
* thumblers when similar elements exists at a given ancestor level .
* The output is compatible with XPath commands .
*
* Returns 0 or - 1 in case of error
*/
2001-10-11 13:12:24 +04:00
int
xmlShellPwd ( xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED , char * buffer ,
xmlNodePtr node , xmlNodePtr node2 ATTRIBUTE_UNUSED )
{
2001-11-10 13:08:57 +03:00
xmlChar * path ;
2001-02-23 20:55:21 +03:00
2004-11-08 19:24:57 +03:00
if ( ( node = = NULL ) | | ( buffer = = NULL ) )
2001-10-11 13:12:24 +04:00
return ( - 1 ) ;
2001-11-10 13:08:57 +03:00
path = xmlGetNodePath ( node ) ;
if ( path = = NULL )
return ( - 1 ) ;
/*
* This test prevents buffer overflow , because this routine
* is only called by xmlShell , in which the second argument is
* 500 chars long .
* It is a dirty hack before a cleaner solution is found .
* Documentation should mention that the second argument must
* be at least 500 chars long , and could be stripped if too long .
*/
snprintf ( buffer , 499 , " %s " , path ) ;
buffer [ 499 ] = ' 0 ' ;
xmlFree ( path ) ;
2001-10-11 13:12:24 +04:00
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
/**
2002-12-10 18:19:08 +03:00
* xmlShell :
2001-02-23 20:55:21 +03:00
* @ doc : the initial document
* @ filename : the output buffer
* @ input : the line reading function
2002-10-09 01:26:42 +04:00
* @ output : the output FILE * , defaults to stdout if NULL
2001-02-23 20:55:21 +03:00
*
2012-09-11 09:26:36 +04:00
* Implements the XML shell
2001-02-23 20:55:21 +03:00
* This allow to load , validate , view , modify and save a document
* using a environment similar to a UNIX commandline .
*/
void
2024-05-05 16:20:15 +03:00
xmlShell ( xmlDocPtr doc , const char * filename , xmlShellReadlineFunc input ,
2001-10-11 13:12:24 +04:00
FILE * output )
{
2001-02-23 20:55:21 +03:00
char prompt [ 500 ] = " / > " ;
char * cmdline = NULL , * cur ;
char command [ 100 ] ;
char arg [ 400 ] ;
int i ;
xmlShellCtxtPtr ctxt ;
xmlXPathObjectPtr list ;
if ( doc = = NULL )
return ;
if ( filename = = NULL )
return ;
if ( input = = NULL )
return ;
if ( output = = NULL )
2002-10-09 01:26:42 +04:00
output = stdout ;
2001-02-23 20:55:21 +03:00
ctxt = ( xmlShellCtxtPtr ) xmlMalloc ( sizeof ( xmlShellCtxt ) ) ;
2001-10-11 13:12:24 +04:00
if ( ctxt = = NULL )
2001-02-23 20:55:21 +03:00
return ;
ctxt - > loaded = 0 ;
ctxt - > doc = doc ;
ctxt - > input = input ;
ctxt - > output = output ;
ctxt - > filename = ( char * ) xmlStrdup ( ( xmlChar * ) filename ) ;
2001-10-11 13:12:24 +04:00
ctxt - > node = ( xmlNodePtr ) ctxt - > doc ;
2001-02-23 20:55:21 +03:00
# ifdef LIBXML_XPATH_ENABLED
ctxt - > pctxt = xmlXPathNewContext ( ctxt - > doc ) ;
if ( ctxt - > pctxt = = NULL ) {
2001-10-11 13:12:24 +04:00
xmlFree ( ctxt ) ;
return ;
2001-02-23 20:55:21 +03:00
}
# endif /* LIBXML_XPATH_ENABLED */
while ( 1 ) {
if ( ctxt - > node = = ( xmlNodePtr ) ctxt - > doc )
2002-06-14 21:07:10 +04:00
snprintf ( prompt , sizeof ( prompt ) , " %s > " , " / " ) ;
2012-05-07 13:04:04 +04:00
else if ( ( ctxt - > node ! = NULL ) & & ( ctxt - > node - > name ) & &
( ctxt - > node - > ns ) & & ( ctxt - > node - > ns - > prefix ) )
snprintf ( prompt , sizeof ( prompt ) , " %s:%s > " ,
( ctxt - > node - > ns - > prefix ) , ctxt - > node - > name ) ;
2003-07-06 21:57:42 +04:00
else if ( ( ctxt - > node ! = NULL ) & & ( ctxt - > node - > name ) )
2001-10-11 13:12:24 +04:00
snprintf ( prompt , sizeof ( prompt ) , " %s > " , ctxt - > node - > name ) ;
2001-02-23 20:55:21 +03:00
else
2002-06-14 21:07:10 +04:00
snprintf ( prompt , sizeof ( prompt ) , " ? > " ) ;
2001-02-23 20:55:21 +03:00
prompt [ sizeof ( prompt ) - 1 ] = 0 ;
2001-10-11 13:12:24 +04:00
/*
* Get a new command line
*/
2001-02-23 20:55:21 +03:00
cmdline = ctxt - > input ( prompt ) ;
2001-10-11 13:12:24 +04:00
if ( cmdline = = NULL )
break ;
/*
* Parse the command itself
*/
cur = cmdline ;
while ( ( * cur = = ' ' ) | | ( * cur = = ' \t ' ) )
cur + + ;
i = 0 ;
while ( ( * cur ! = ' ' ) & & ( * cur ! = ' \t ' ) & &
( * cur ! = ' \n ' ) & & ( * cur ! = ' \r ' ) ) {
if ( * cur = = 0 )
break ;
command [ i + + ] = * cur + + ;
}
command [ i ] = 0 ;
if ( i = = 0 )
continue ;
2001-02-23 20:55:21 +03:00
2001-10-11 13:12:24 +04:00
/*
* Parse the argument
*/
while ( ( * cur = = ' ' ) | | ( * cur = = ' \t ' ) )
cur + + ;
i = 0 ;
while ( ( * cur ! = ' \n ' ) & & ( * cur ! = ' \r ' ) & & ( * cur ! = 0 ) ) {
if ( * cur = = 0 )
break ;
arg [ i + + ] = * cur + + ;
}
arg [ i ] = 0 ;
/*
* start interpreting the command
*/
2001-02-23 20:55:21 +03:00
if ( ! strcmp ( command , " exit " ) )
2001-10-11 13:12:24 +04:00
break ;
2001-02-23 20:55:21 +03:00
if ( ! strcmp ( command , " quit " ) )
2001-10-11 13:12:24 +04:00
break ;
2001-02-23 20:55:21 +03:00
if ( ! strcmp ( command , " bye " ) )
2001-10-11 13:12:24 +04:00
break ;
2001-11-08 16:53:05 +03:00
if ( ! strcmp ( command , " help " ) ) {
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " \t base display XML base of the node \n " ) ;
fprintf ( ctxt - > output , " \t setbase URI change the XML base of the node \n " ) ;
fprintf ( ctxt - > output , " \t bye leave shell \n " ) ;
fprintf ( ctxt - > output , " \t cat [node] display node or current node \n " ) ;
fprintf ( ctxt - > output , " \t cd [path] change directory to path or to root \n " ) ;
2020-03-08 19:19:42 +03:00
fprintf ( ctxt - > output , " \t dir [path] dumps information about the node (namespace, attributes, content) \n " ) ;
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " \t du [path] show the structure of the subtree under path or the current node \n " ) ;
fprintf ( ctxt - > output , " \t exit leave shell \n " ) ;
fprintf ( ctxt - > output , " \t help display this help \n " ) ;
fprintf ( ctxt - > output , " \t free display memory usage \n " ) ;
fprintf ( ctxt - > output , " \t load [name] load a new document with name \n " ) ;
fprintf ( ctxt - > output , " \t ls [path] list contents of path or the current directory \n " ) ;
2004-08-16 16:34:50 +04:00
fprintf ( ctxt - > output , " \t set xml_fragment replace the current node content with the fragment parsed in context \n " ) ;
2002-01-23 01:12:19 +03:00
# ifdef LIBXML_XPATH_ENABLED
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " \t xpath expr evaluate the XPath expression in that context and print the result \n " ) ;
2004-06-16 18:08:33 +04:00
fprintf ( ctxt - > output , " \t setns nsreg register a namespace to a prefix in the XPath evaluation context \n " ) ;
fprintf ( ctxt - > output , " \t format for nsreg is: prefix=[nsuri] (i.e. prefix= unsets a prefix) \n " ) ;
2005-07-04 13:27:40 +04:00
fprintf ( ctxt - > output , " \t setrootns register all namespace found on the root element \n " ) ;
fprintf ( ctxt - > output , " \t the default namespace if any uses 'defaultns' prefix \n " ) ;
2002-01-23 01:12:19 +03:00
# endif /* LIBXML_XPATH_ENABLED */
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " \t pwd display current working directory \n " ) ;
2012-05-07 15:53:19 +04:00
fprintf ( ctxt - > output , " \t whereis display absolute path of [path] or current working directory \n " ) ;
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " \t quit leave shell \n " ) ;
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " \t save [name] save this document to name or the original name \n " ) ;
fprintf ( ctxt - > output , " \t write [name] write the current node to the filename \n " ) ;
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2004-02-25 14:52:31 +03:00
# ifdef LIBXML_VALID_ENABLED
2003-09-29 17:20:24 +04:00
fprintf ( ctxt - > output , " \t validate check the document for errors \n " ) ;
2004-02-25 14:52:31 +03:00
# endif /* LIBXML_VALID_ENABLED */
2004-02-21 14:53:09 +03:00
# ifdef LIBXML_SCHEMAS_ENABLED
2017-06-17 17:15:09 +03:00
fprintf ( ctxt - > output , " \t relaxng rng validate the document against the Relax-NG schemas \n " ) ;
2004-02-21 14:53:09 +03:00
# endif
2002-10-22 18:25:25 +04:00
fprintf ( ctxt - > output , " \t grep string search for a string in the subtree \n " ) ;
2004-02-25 14:52:31 +03:00
# ifdef LIBXML_VALID_ENABLED
2001-11-08 16:53:05 +03:00
} else if ( ! strcmp ( command , " validate " ) ) {
2001-10-11 13:12:24 +04:00
xmlShellValidate ( ctxt , arg , NULL , NULL ) ;
2004-02-25 14:52:31 +03:00
# endif /* LIBXML_VALID_ENABLED */
2001-10-11 13:12:24 +04:00
} else if ( ! strcmp ( command , " load " ) ) {
xmlShellLoad ( ctxt , arg , NULL , NULL ) ;
2004-02-21 14:53:09 +03:00
# ifdef LIBXML_SCHEMAS_ENABLED
} else if ( ! strcmp ( command , " relaxng " ) ) {
xmlShellRNGValidate ( ctxt , arg , NULL , NULL ) ;
# endif
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-10-11 13:12:24 +04:00
} else if ( ! strcmp ( command , " save " ) ) {
xmlShellSave ( ctxt , arg , NULL , NULL ) ;
} else if ( ! strcmp ( command , " write " ) ) {
2013-07-22 10:24:16 +04:00
if ( arg [ 0 ] = = 0 )
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2004-11-08 19:24:57 +03:00
" Write command requires a filename argument \n " ) ;
else
2010-11-04 12:48:25 +03:00
xmlShellWrite ( ctxt , arg , ctxt - > node , NULL ) ;
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2002-10-22 18:25:25 +04:00
} else if ( ! strcmp ( command , " grep " ) ) {
xmlShellGrep ( ctxt , arg , ctxt - > node , NULL ) ;
2001-10-11 13:12:24 +04:00
} else if ( ! strcmp ( command , " pwd " ) ) {
char dir [ 500 ] ;
if ( ! xmlShellPwd ( ctxt , dir , ctxt - > node , NULL ) )
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " %s \n " , dir ) ;
2001-10-11 13:12:24 +04:00
} else if ( ! strcmp ( command , " du " ) ) {
2012-05-07 13:04:04 +04:00
if ( arg [ 0 ] = = 0 ) {
xmlShellDu ( ctxt , NULL , ctxt - > node , NULL ) ;
} else {
ctxt - > pctxt - > node = ctxt - > node ;
# ifdef LIBXML_XPATH_ENABLED
ctxt - > pctxt - > node = ctxt - > node ;
list = xmlXPathEval ( ( xmlChar * ) arg , ctxt - > pctxt ) ;
# else
list = NULL ;
# endif /* LIBXML_XPATH_ENABLED */
if ( list ! = NULL ) {
switch ( list - > type ) {
case XPATH_UNDEFINED :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 13:04:04 +04:00
" %s: no such node \n " , arg ) ;
break ;
case XPATH_NODESET : {
int indx ;
if ( list - > nodesetval = = NULL )
break ;
for ( indx = 0 ;
indx < list - > nodesetval - > nodeNr ;
indx + + )
xmlShellDu ( ctxt , NULL ,
list - > nodesetval - >
nodeTab [ indx ] , NULL ) ;
break ;
}
case XPATH_BOOLEAN :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 13:04:04 +04:00
" %s is a Boolean \n " , arg ) ;
break ;
case XPATH_NUMBER :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 13:04:04 +04:00
" %s is a number \n " , arg ) ;
break ;
case XPATH_STRING :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 13:04:04 +04:00
" %s is a string \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# ifdef LIBXML_XPTR_LOCS_ENABLED
2012-05-07 13:04:04 +04:00
case XPATH_POINT :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 13:04:04 +04:00
" %s is a point \n " , arg ) ;
break ;
case XPATH_RANGE :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 13:04:04 +04:00
" %s is a range \n " , arg ) ;
break ;
case XPATH_LOCATIONSET :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 13:04:04 +04:00
" %s is a range \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# endif /* LIBXML_XPTR_LOCS_ENABLED */
2012-05-07 13:04:04 +04:00
case XPATH_USERS :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 13:04:04 +04:00
" %s is user-defined \n " , arg ) ;
break ;
case XPATH_XSLT_TREE :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 13:04:04 +04:00
" %s is an XSLT value tree \n " ,
arg ) ;
break ;
}
# ifdef LIBXML_XPATH_ENABLED
xmlXPathFreeObject ( list ) ;
# endif
} else {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 13:04:04 +04:00
" %s: no such node \n " , arg ) ;
}
ctxt - > pctxt - > node = NULL ;
}
2001-10-11 13:12:24 +04:00
} else if ( ! strcmp ( command , " base " ) ) {
xmlShellBase ( ctxt , NULL , ctxt - > node , NULL ) ;
2004-08-16 04:39:03 +04:00
} else if ( ! strcmp ( command , " set " ) ) {
xmlShellSetContent ( ctxt , arg , ctxt - > node , NULL ) ;
2002-01-23 01:12:19 +03:00
# ifdef LIBXML_XPATH_ENABLED
2004-06-16 18:08:33 +04:00
} else if ( ! strcmp ( command , " setns " ) ) {
if ( arg [ 0 ] = = 0 ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2004-06-16 18:08:33 +04:00
" setns: prefix=[nsuri] required \n " ) ;
} else {
xmlShellRegisterNamespace ( ctxt , arg , NULL , NULL ) ;
}
2005-07-04 13:27:40 +04:00
} else if ( ! strcmp ( command , " setrootns " ) ) {
xmlNodePtr root ;
root = xmlDocGetRootElement ( ctxt - > doc ) ;
xmlShellRegisterRootNamespaces ( ctxt , NULL , root , NULL ) ;
2002-01-23 01:12:19 +03:00
} else if ( ! strcmp ( command , " xpath " ) ) {
if ( arg [ 0 ] = = 0 ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2002-01-23 01:12:19 +03:00
" xpath: expression required \n " ) ;
} else {
ctxt - > pctxt - > node = ctxt - > node ;
list = xmlXPathEval ( ( xmlChar * ) arg , ctxt - > pctxt ) ;
2002-10-09 01:26:42 +04:00
xmlXPathDebugDumpObject ( ctxt - > output , list , 0 ) ;
2002-01-23 01:12:19 +03:00
xmlXPathFreeObject ( list ) ;
}
# endif /* LIBXML_XPATH_ENABLED */
2004-03-04 18:59:36 +03:00
# ifdef LIBXML_TREE_ENABLED
2002-01-17 11:46:58 +03:00
} else if ( ! strcmp ( command , " setbase " ) ) {
xmlShellSetBase ( ctxt , arg , ctxt - > node , NULL ) ;
2004-03-04 18:59:36 +03:00
# endif
2001-10-11 13:12:24 +04:00
} else if ( ( ! strcmp ( command , " ls " ) ) | | ( ! strcmp ( command , " dir " ) ) ) {
int dir = ( ! strcmp ( command , " dir " ) ) ;
if ( arg [ 0 ] = = 0 ) {
if ( dir )
xmlShellDir ( ctxt , NULL , ctxt - > node , NULL ) ;
else
xmlShellList ( ctxt , NULL , ctxt - > node , NULL ) ;
} else {
ctxt - > pctxt - > node = ctxt - > node ;
2001-02-23 20:55:21 +03:00
# ifdef LIBXML_XPATH_ENABLED
2001-10-11 13:12:24 +04:00
ctxt - > pctxt - > node = ctxt - > node ;
list = xmlXPathEval ( ( xmlChar * ) arg , ctxt - > pctxt ) ;
2001-02-23 20:55:21 +03:00
# else
2001-10-11 13:12:24 +04:00
list = NULL ;
2001-02-23 20:55:21 +03:00
# endif /* LIBXML_XPATH_ENABLED */
2001-10-11 13:12:24 +04:00
if ( list ! = NULL ) {
switch ( list - > type ) {
case XPATH_UNDEFINED :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s: no such node \n " , arg ) ;
break ;
case XPATH_NODESET : {
int indx ;
2001-11-07 16:33:59 +03:00
if ( list - > nodesetval = = NULL )
break ;
2001-10-11 13:12:24 +04:00
for ( indx = 0 ;
indx < list - > nodesetval - > nodeNr ;
indx + + ) {
if ( dir )
xmlShellDir ( ctxt , NULL ,
list - > nodesetval - >
nodeTab [ indx ] , NULL ) ;
else
xmlShellList ( ctxt , NULL ,
list - > nodesetval - >
nodeTab [ indx ] , NULL ) ;
}
break ;
}
case XPATH_BOOLEAN :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a Boolean \n " , arg ) ;
break ;
case XPATH_NUMBER :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a number \n " , arg ) ;
break ;
case XPATH_STRING :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a string \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# ifdef LIBXML_XPTR_LOCS_ENABLED
2001-10-11 13:12:24 +04:00
case XPATH_POINT :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a point \n " , arg ) ;
2012-05-07 15:53:19 +04:00
break ;
case XPATH_RANGE :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 15:53:19 +04:00
" %s is a range \n " , arg ) ;
break ;
case XPATH_LOCATIONSET :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 15:53:19 +04:00
" %s is a range \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# endif /* LIBXML_XPTR_LOCS_ENABLED */
2012-05-07 15:53:19 +04:00
case XPATH_USERS :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 15:53:19 +04:00
" %s is user-defined \n " , arg ) ;
break ;
case XPATH_XSLT_TREE :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 15:53:19 +04:00
" %s is an XSLT value tree \n " ,
arg ) ;
break ;
}
# ifdef LIBXML_XPATH_ENABLED
xmlXPathFreeObject ( list ) ;
# endif
} else {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 15:53:19 +04:00
" %s: no such node \n " , arg ) ;
}
ctxt - > pctxt - > node = NULL ;
}
} else if ( ! strcmp ( command , " whereis " ) ) {
char dir [ 500 ] ;
if ( arg [ 0 ] = = 0 ) {
if ( ! xmlShellPwd ( ctxt , dir , ctxt - > node , NULL ) )
fprintf ( ctxt - > output , " %s \n " , dir ) ;
} else {
ctxt - > pctxt - > node = ctxt - > node ;
# ifdef LIBXML_XPATH_ENABLED
list = xmlXPathEval ( ( xmlChar * ) arg , ctxt - > pctxt ) ;
# else
list = NULL ;
# endif /* LIBXML_XPATH_ENABLED */
if ( list ! = NULL ) {
switch ( list - > type ) {
case XPATH_UNDEFINED :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 15:53:19 +04:00
" %s: no such node \n " , arg ) ;
break ;
case XPATH_NODESET : {
int indx ;
if ( list - > nodesetval = = NULL )
break ;
for ( indx = 0 ;
indx < list - > nodesetval - > nodeNr ;
indx + + ) {
if ( ! xmlShellPwd ( ctxt , dir , list - > nodesetval - >
nodeTab [ indx ] , NULL ) )
fprintf ( ctxt - > output , " %s \n " , dir ) ;
}
break ;
}
case XPATH_BOOLEAN :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 15:53:19 +04:00
" %s is a Boolean \n " , arg ) ;
break ;
case XPATH_NUMBER :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 15:53:19 +04:00
" %s is a number \n " , arg ) ;
break ;
case XPATH_STRING :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 15:53:19 +04:00
" %s is a string \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# ifdef LIBXML_XPTR_LOCS_ENABLED
2012-05-07 15:53:19 +04:00
case XPATH_POINT :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2012-05-07 15:53:19 +04:00
" %s is a point \n " , arg ) ;
2001-10-11 13:12:24 +04:00
break ;
case XPATH_RANGE :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a range \n " , arg ) ;
break ;
case XPATH_LOCATIONSET :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a range \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# endif /* LIBXML_XPTR_LOCS_ENABLED */
2001-10-11 13:12:24 +04:00
case XPATH_USERS :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is user-defined \n " , arg ) ;
break ;
case XPATH_XSLT_TREE :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is an XSLT value tree \n " ,
arg ) ;
break ;
}
2001-04-27 21:13:01 +04:00
# ifdef LIBXML_XPATH_ENABLED
2001-10-11 13:12:24 +04:00
xmlXPathFreeObject ( list ) ;
2001-04-27 21:13:01 +04:00
# endif
2001-10-11 13:12:24 +04:00
} else {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s: no such node \n " , arg ) ;
}
ctxt - > pctxt - > node = NULL ;
}
} else if ( ! strcmp ( command , " cd " ) ) {
if ( arg [ 0 ] = = 0 ) {
ctxt - > node = ( xmlNodePtr ) ctxt - > doc ;
} else {
2001-02-23 20:55:21 +03:00
# ifdef LIBXML_XPATH_ENABLED
2014-07-14 13:59:31 +04:00
int l ;
2001-10-11 13:12:24 +04:00
ctxt - > pctxt - > node = ctxt - > node ;
2014-07-14 13:59:31 +04:00
l = strlen ( arg ) ;
if ( ( l > = 2 ) & & ( arg [ l - 1 ] = = ' / ' ) )
arg [ l - 1 ] = 0 ;
2001-10-11 13:12:24 +04:00
list = xmlXPathEval ( ( xmlChar * ) arg , ctxt - > pctxt ) ;
2001-02-23 20:55:21 +03:00
# else
2001-10-11 13:12:24 +04:00
list = NULL ;
2001-02-23 20:55:21 +03:00
# endif /* LIBXML_XPATH_ENABLED */
2001-10-11 13:12:24 +04:00
if ( list ! = NULL ) {
switch ( list - > type ) {
case XPATH_UNDEFINED :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s: no such node \n " , arg ) ;
break ;
case XPATH_NODESET :
2001-11-07 16:33:59 +03:00
if ( list - > nodesetval ! = NULL ) {
if ( list - > nodesetval - > nodeNr = = 1 ) {
ctxt - > node = list - > nodesetval - > nodeTab [ 0 ] ;
2003-07-06 21:57:42 +04:00
if ( ( ctxt - > node ! = NULL ) & &
( ctxt - > node - > type = =
XML_NAMESPACE_DECL ) ) {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2003-07-06 21:57:42 +04:00
" cannot cd to namespace \n " ) ;
ctxt - > node = NULL ;
}
2001-11-07 16:33:59 +03:00
} else
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-11-07 16:33:59 +03:00
" %s is a %d Node Set \n " ,
arg ,
list - > nodesetval - > nodeNr ) ;
2001-10-11 13:12:24 +04:00
} else
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-11-07 16:33:59 +03:00
" %s is an empty Node Set \n " ,
arg ) ;
2001-10-11 13:12:24 +04:00
break ;
case XPATH_BOOLEAN :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a Boolean \n " , arg ) ;
break ;
case XPATH_NUMBER :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a number \n " , arg ) ;
break ;
case XPATH_STRING :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a string \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# ifdef LIBXML_XPTR_LOCS_ENABLED
2001-10-11 13:12:24 +04:00
case XPATH_POINT :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a point \n " , arg ) ;
break ;
case XPATH_RANGE :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a range \n " , arg ) ;
break ;
case XPATH_LOCATIONSET :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a range \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# endif /* LIBXML_XPTR_LOCS_ENABLED */
2001-10-11 13:12:24 +04:00
case XPATH_USERS :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is user-defined \n " , arg ) ;
break ;
case XPATH_XSLT_TREE :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is an XSLT value tree \n " ,
arg ) ;
break ;
}
2001-04-27 21:13:01 +04:00
# ifdef LIBXML_XPATH_ENABLED
2001-10-11 13:12:24 +04:00
xmlXPathFreeObject ( list ) ;
2001-04-27 21:13:01 +04:00
# endif
2001-10-11 13:12:24 +04:00
} else {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s: no such node \n " , arg ) ;
}
ctxt - > pctxt - > node = NULL ;
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-10-11 13:12:24 +04:00
} else if ( ! strcmp ( command , " cat " ) ) {
if ( arg [ 0 ] = = 0 ) {
xmlShellCat ( ctxt , NULL , ctxt - > node , NULL ) ;
} else {
ctxt - > pctxt - > node = ctxt - > node ;
2001-02-23 20:55:21 +03:00
# ifdef LIBXML_XPATH_ENABLED
2001-10-11 13:12:24 +04:00
ctxt - > pctxt - > node = ctxt - > node ;
list = xmlXPathEval ( ( xmlChar * ) arg , ctxt - > pctxt ) ;
2001-02-23 20:55:21 +03:00
# else
2001-10-11 13:12:24 +04:00
list = NULL ;
2001-02-23 20:55:21 +03:00
# endif /* LIBXML_XPATH_ENABLED */
2001-10-11 13:12:24 +04:00
if ( list ! = NULL ) {
switch ( list - > type ) {
case XPATH_UNDEFINED :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s: no such node \n " , arg ) ;
break ;
case XPATH_NODESET : {
int indx ;
2001-11-07 16:33:59 +03:00
if ( list - > nodesetval = = NULL )
break ;
2001-10-11 13:12:24 +04:00
for ( indx = 0 ;
indx < list - > nodesetval - > nodeNr ;
indx + + ) {
if ( i > 0 )
2002-10-09 01:26:42 +04:00
fprintf ( ctxt - > output , " ------- \n " ) ;
2001-10-11 13:12:24 +04:00
xmlShellCat ( ctxt , NULL ,
list - > nodesetval - >
nodeTab [ indx ] , NULL ) ;
}
break ;
}
case XPATH_BOOLEAN :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a Boolean \n " , arg ) ;
break ;
case XPATH_NUMBER :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a number \n " , arg ) ;
break ;
case XPATH_STRING :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a string \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# ifdef LIBXML_XPTR_LOCS_ENABLED
2001-10-11 13:12:24 +04:00
case XPATH_POINT :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a point \n " , arg ) ;
break ;
case XPATH_RANGE :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a range \n " , arg ) ;
break ;
case XPATH_LOCATIONSET :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is a range \n " , arg ) ;
break ;
2022-04-21 00:17:14 +03:00
# endif /* LIBXML_XPTR_LOCS_ENABLED */
2001-10-11 13:12:24 +04:00
case XPATH_USERS :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is user-defined \n " , arg ) ;
break ;
case XPATH_XSLT_TREE :
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s is an XSLT value tree \n " ,
arg ) ;
break ;
}
2001-04-27 21:13:01 +04:00
# ifdef LIBXML_XPATH_ENABLED
2001-10-11 13:12:24 +04:00
xmlXPathFreeObject ( list ) ;
2001-04-27 21:13:01 +04:00
# endif
2001-10-11 13:12:24 +04:00
} else {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" %s: no such node \n " , arg ) ;
}
ctxt - > pctxt - > node = NULL ;
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-10-11 13:12:24 +04:00
} else {
2023-12-18 23:09:39 +03:00
fprintf ( ctxt - > output ,
2001-10-11 13:12:24 +04:00
" Unknown command %s \n " , command ) ;
}
free ( cmdline ) ; /* not xmlFree here ! */
2008-02-22 01:31:55 +03:00
cmdline = NULL ;
2001-02-23 20:55:21 +03:00
}
# ifdef LIBXML_XPATH_ENABLED
xmlXPathFreeContext ( ctxt - > pctxt ) ;
# endif /* LIBXML_XPATH_ENABLED */
if ( ctxt - > loaded ) {
xmlFreeDoc ( ctxt - > doc ) ;
}
2001-07-09 20:01:19 +04:00
if ( ctxt - > filename ! = NULL )
2001-10-11 13:12:24 +04:00
xmlFree ( ctxt - > filename ) ;
2001-02-23 20:55:21 +03:00
xmlFree ( ctxt ) ;
if ( cmdline ! = NULL )
2001-10-11 13:12:24 +04:00
free ( cmdline ) ; /* not xmlFree here ! */
2001-02-23 20:55:21 +03:00
}
2004-11-09 19:17:02 +03:00
# endif /* LIBXML_XPATH_ENABLED */
2022-02-20 20:46:42 +03:00
2001-02-23 20:55:21 +03:00
# endif /* LIBXML_DEBUG_ENABLED */