@ -1,90 +1,79 @@
/*
//
* Test program for Mini - XML , a small XML file parsing library .
// Test program for Mini-XML, a small XML file parsing library.
*
//
* Usage :
// Usage:
*
//
* . / testmxml input . xml [ string - output . xml ] > stdio - output . xml
// ./testmxml input.xml [string-output.xml] >stdio-output.xml
* . / testmxml " <?xml ... " [ string - output . xml ] > stdio - output . xml
// ./testmxml "<?xml ..." [string-output.xml] >stdio-output.xml
*
//
* https : //www.msweet.org/mxml
// https://www.msweet.org/mxml
*
//
* Copyright © 2003 - 2019 by Michael R Sweet .
// Copyright © 2003-2024 by Michael R Sweet.
*
//
* Licensed under Apache License v2 .0 . See the file " LICENSE " for more
// Licensed under Apache License v2.0. See the file "LICENSE" for more
* information .
// information.
*/
//
/*
* Include necessary headers . . .
*/
# include "config.h"
# include "mxml-private.h"
# include "mxml-private.h"
# ifndef _WIN32
# ifndef _WIN32
# include <unistd.h>
# include <unistd.h>
# endif /* !_WIN32 */
# endif // !_WIN32
# include <fcntl.h>
# include <fcntl.h>
# ifndef O_BINARY
# ifndef O_BINARY
# define O_BINARY 0
# define O_BINARY 0
# endif /* !O_BINARY */
# endif // !O_BINARY
/*
//
* Globals . . .
// Globals...
*/
//
int event_counts [ 6 ] ;
int event_counts [ 6 ] ;
/*
//
* Local functions . . .
// Local functions...
*/
//
void sax_cb ( mxml_node_t * node , mxml_sax_event_t event , void * data ) ;
void sax_cb ( mxml_node_t * node , mxml_sax_event_t event , void * data ) ;
mxml_type_t type_cb ( mxml_node_t * node ) ;
mxml_type_t type_cb ( mxml_node_t * node ) ;
const char * whitespace_cb ( mxml_node_t * node , int where ) ;
const char * whitespace_cb ( mxml_node_t * node , int where ) ;
/*
//
* ' main ( ) ' - Main entry for test program .
// 'main()' - Main entry for test program.
*/
//
int /* O - Exit status */
int // O - Exit status
main ( int argc , /* I - Number of command-line args */
main ( int argc , // I - Number of command-line args
char * argv [ ] ) /* I - Command-line args */
char * argv [ ] ) // I - Command-line args
{
{
int i ; /* Looping var */
int i ; // Looping var
FILE * fp ; /* File to read */
FILE * fp ; // File to read
int fd ; /* File descriptor */
int fd ; // File descriptor
mxml_node_t * xml , /* <?xml ...?> node */
mxml_node_t * xml , // <?xml ...?> node
* tree , /* Element tree */
* tree , // Element tree
* node ; /* Node which should be in test.xml */
* node ; // Node which should be in test.xml
mxml_index_t * ind ; /* XML index */
mxml_index_t * ind ; // XML index
char buffer [ 16384 ] ; /* Save string */
char buffer [ 16384 ] ; // Save string
static const char * types [ ] = /* Strings for node types */
static const char * types [ ] = // Strings for node types
{
{
" MXML_ELEMENT " ,
" MXML_TYPE_ ELEMENT " ,
" MXML_INTEGER " ,
" MXML_TYPE_ INTEGER " ,
" MXML_OPAQUE " ,
" MXML_TYPE_ OPAQUE " ,
" MXML_REAL " ,
" MXML_TYPE_ REAL " ,
" MXML_TEXT "
" MXML_TYPE_T EXT "
} ;
} ;
/*
// Check arguments...
* Check arguments . . .
*/
if ( argc ! = 2 & & argc ! = 3 )
if ( argc ! = 2 & & argc ! = 3 )
{
{
fputs ( " Usage: testmxml filename.xml [string-output.xml] \n " , stderr ) ;
fputs ( " Usage: testmxml filename.xml [string-output.xml] \n " , stderr ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
/*
// Test the basic functionality...
* Test the basic functionality . . .
*/
xml = mxmlNewXML ( " 1.0 " ) ;
xml = mxmlNewXML ( " 1.0 " ) ;
tree = mxmlNewElement ( xml , " element " ) ;
tree = mxmlNewElement ( xml , " element " ) ;
@ -94,19 +83,16 @@ main(int argc, /* I - Number of command-line args */
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( tree - > type ! = MXML_ELEMENT )
if ( tree - > type ! = MXML_TYPE_ ELEMENT )
{
{
fprintf ( stderr , " ERROR: Parent has type %s (%d), expected MXML_ELEMENT. \n " ,
fprintf ( stderr , " ERROR: Parent has type %s (%d), expected MXML_TYPE_ELEMENT. \n " , tree - > type < MXML_TYPE_ELEMENT | | tree - > type > MXML_TYPE_TEXT ? " UNKNOWN " : types [ tree - > type ] , tree - > type ) ;
tree - > type < MXML_ELEMENT | | tree - > type > MXML_TEXT ?
" UNKNOWN " : types [ tree - > type ] , tree - > type ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( strcmp ( tree - > value . element . name , " element " ) )
if ( strcmp ( tree - > value . element . name , " element " ) )
{
{
fprintf ( stderr , " ERROR: Parent value is \" %s \" , expected \" element \" . \n " ,
fprintf ( stderr , " ERROR: Parent value is \" %s \" , expected \" element \" . \n " , tree - > value . element . name ) ;
tree - > value . element . name ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
@ -116,18 +102,12 @@ main(int argc, /* I - Number of command-line args */
mxmlNewReal ( tree , 123.4f ) ;
mxmlNewReal ( tree , 123.4f ) ;
mxmlNewText ( tree , 1 , " text " ) ;
mxmlNewText ( tree , 1 , " text " ) ;
mxmlLoadString ( tree , " <group type='string'>string string string</group> " ,
mxmlLoadString ( tree , " <group type='string'>string string string</group> " , MXML_NO_CALLBACK ) ;
MXML_NO_CALLBACK ) ;
mxmlLoadString ( tree , " <group type='integer'>1 2 3</group> " , MXML_INTEGER_CALLBACK ) ;
mxmlLoadString ( tree , " <group type='integer'>1 2 3</group> " ,
mxmlLoadString ( tree , " <group type='real'>1.0 2.0 3.0</group> " , MXML_REAL_CALLBACK ) ;
MXML_INTEGER_CALLBACK ) ;
mxmlLoadString ( tree , " <group>opaque opaque opaque</group> " , MXML_OPAQUE_CALLBACK ) ;
mxmlLoadString ( tree , " <group type='real'>1.0 2.0 3.0</group> " ,
mxmlLoadString ( tree , " <foo><bar><one><two>value<two>value2</two></two></one></bar></foo> " , MXML_OPAQUE_CALLBACK ) ;
MXML_REAL_CALLBACK ) ;
mxmlNewCDATA ( tree , " 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \n " ) ;
mxmlLoadString ( tree , " <group>opaque opaque opaque</group> " ,
MXML_OPAQUE_CALLBACK ) ;
mxmlLoadString ( tree , " <foo><bar><one><two>value<two>value2</two></two></one> "
" </bar></foo> " , MXML_OPAQUE_CALLBACK ) ;
mxmlNewCDATA ( tree ,
" 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \n " ) ;
mxmlNewCDATA ( tree ,
mxmlNewCDATA ( tree ,
" 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \n "
" 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \n "
" 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \n "
" 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \n "
@ -152,19 +132,16 @@ main(int argc, /* I - Number of command-line args */
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( node - > type ! = MXML_INTEGER )
if ( node - > type ! = MXML_TYPE_ INTEGER )
{
{
fprintf ( stderr , " ERROR: First child has type %s (%d), expected MXML_INTEGER. \n " ,
fprintf ( stderr , " ERROR: First child has type %s (%d), expected MXML_TYPE_INTEGER. \n " , node - > type < MXML_TYPE_ELEMENT | | node - > type > MXML_TYPE_TEXT ? " UNKNOWN " : types [ node - > type ] , node - > type ) ;
node - > type < MXML_ELEMENT | | node - > type > MXML_TEXT ?
" UNKNOWN " : types [ node - > type ] , node - > type ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( node - > value . integer ! = 123 )
if ( node - > value . integer ! = 123 )
{
{
fprintf ( stderr , " ERROR: First child value is %d, expected 123. \n " ,
fprintf ( stderr , " ERROR: First child value is %d, expected 123. \n " , node - > value . integer ) ;
node - > value . integer ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
@ -178,19 +155,16 @@ main(int argc, /* I - Number of command-line args */
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( node - > type ! = MXML_OPAQUE )
if ( node - > type ! = MXML_TYPE_ OPAQUE )
{
{
fprintf ( stderr , " ERROR: Second child has type %s (%d), expected MXML_OPAQUE. \n " ,
fprintf ( stderr , " ERROR: Second child has type %s (%d), expected MXML_TYPE_OPAQUE. \n " , node - > type < MXML_TYPE_ELEMENT | | node - > type > MXML_TYPE_TEXT ? " UNKNOWN " : types [ node - > type ] , node - > type ) ;
node - > type < MXML_ELEMENT | | node - > type > MXML_TEXT ?
" UNKNOWN " : types [ node - > type ] , node - > type ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( ! node - > value . opaque | | strcmp ( node - > value . opaque , " opaque " ) )
if ( ! node - > value . opaque | | strcmp ( node - > value . opaque , " opaque " ) )
{
{
fprintf ( stderr , " ERROR: Second child value is \" %s \" , expected \" opaque \" . \n " ,
fprintf ( stderr , " ERROR: Second child value is \" %s \" , expected \" opaque \" . \n " , node - > value . opaque ? node - > value . opaque : " (null) " ) ;
node - > value . opaque ? node - > value . opaque : " (null) " ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
@ -204,19 +178,16 @@ main(int argc, /* I - Number of command-line args */
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( node - > type ! = MXML_REAL )
if ( node - > type ! = MXML_TYPE_ REAL )
{
{
fprintf ( stderr , " ERROR: Third child has type %s (%d), expected MXML_REAL. \n " ,
fprintf ( stderr , " ERROR: Third child has type %s (%d), expected MXML_TYPE_REAL. \n " , node - > type < MXML_TYPE_ELEMENT | | node - > type > MXML_TYPE_TEXT ? " UNKNOWN " : types [ node - > type ] , node - > type ) ;
node - > type < MXML_ELEMENT | | node - > type > MXML_TEXT ?
" UNKNOWN " : types [ node - > type ] , node - > type ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( node - > value . real ! = 123.4f )
if ( node - > value . real ! = 123.4f )
{
{
fprintf ( stderr , " ERROR: Third child value is %f, expected 123.4. \n " ,
fprintf ( stderr , " ERROR: Third child value is %f, expected 123.4. \n " , node - > value . real ) ;
node - > value . real ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
@ -230,21 +201,16 @@ main(int argc, /* I - Number of command-line args */
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( node - > type ! = MXML_TEXT )
if ( node - > type ! = MXML_TYPE_T EXT )
{
{
fprintf ( stderr , " ERROR: Fourth child has type %s (%d), expected MXML_TEXT. \n " ,
fprintf ( stderr , " ERROR: Fourth child has type %s (%d), expected MXML_TYPE_TEXT. \n " , node - > type < MXML_TYPE_ELEMENT | | node - > type > MXML_TYPE_TEXT ? " UNKNOWN " : types [ node - > type ] , node - > type ) ;
node - > type < MXML_ELEMENT | | node - > type > MXML_TEXT ?
" UNKNOWN " : types [ node - > type ] , node - > type ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( ! node - > value . text . whitespace | |
if ( ! node - > value . text . whitespace | | ! node - > value . text . string | | strcmp ( node - > value . text . string , " text " ) )
! node - > value . text . string | | strcmp ( node - > value . text . string , " text " ) )
{
{
fprintf ( stderr , " ERROR: Fourth child value is %d, \" %s \" , expected 1, \" text \" . \n " ,
fprintf ( stderr , " ERROR: Fourth child value is %d, \" %s \" , expected 1, \" text \" . \n " , node - > value . text . whitespace , node - > value . text . string ? node - > value . text . string : " (null) " ) ;
node - > value . text . whitespace ,
node - > value . text . string ? node - > value . text . string : " (null) " ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
@ -260,20 +226,15 @@ main(int argc, /* I - Number of command-line args */
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( node - > type ! = MXML_ELEMENT )
if ( node - > type ! = MXML_TYPE_ ELEMENT )
{
{
fprintf ( stderr , " ERROR: Group child #%d has type %s (%d), expected MXML_ELEMENT. \n " ,
fprintf ( stderr , " ERROR: Group child #%d has type %s (%d), expected MXML_TYPE_ELEMENT. \n " , i + 1 , node - > type < MXML_TYPE_ELEMENT | | node - > type > MXML_TYPE_TEXT ? " UNKNOWN " : types [ node - > type ] , node - > type ) ;
i + 1 , node - > type < MXML_ELEMENT | | node - > type > MXML_TEXT ?
" UNKNOWN " : types [ node - > type ] , node - > type ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
}
}
/*
// Test mxmlFindPath...
* Test mxmlFindPath . . .
*/
node = mxmlFindPath ( tree , " */two " ) ;
node = mxmlFindPath ( tree , " */two " ) ;
if ( ! node )
if ( ! node )
{
{
@ -281,7 +242,7 @@ main(int argc, /* I - Number of command-line args */
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
else if ( node - > type ! = MXML_OPAQUE | | strcmp ( node - > value . opaque , " value " ) )
else if ( node - > type ! = MXML_TYPE_ OPAQUE | | strcmp ( node - > value . opaque , " value " ) )
{
{
fputs ( " ERROR: Bad value for \" */two \" . \n " , stderr ) ;
fputs ( " ERROR: Bad value for \" */two \" . \n " , stderr ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
@ -295,7 +256,7 @@ main(int argc, /* I - Number of command-line args */
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
else if ( node - > type ! = MXML_OPAQUE | | strcmp ( node - > value . opaque , " value " ) )
else if ( node - > type ! = MXML_TYPE_ OPAQUE | | strcmp ( node - > value . opaque , " value " ) )
{
{
fputs ( " ERROR: Bad value for \" foo/*/two \" . \n " , stderr ) ;
fputs ( " ERROR: Bad value for \" foo/*/two \" . \n " , stderr ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
@ -309,17 +270,14 @@ main(int argc, /* I - Number of command-line args */
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
else if ( node - > type ! = MXML_OPAQUE | | strcmp ( node - > value . opaque , " value " ) )
else if ( node - > type ! = MXML_TYPE_ OPAQUE | | strcmp ( node - > value . opaque , " value " ) )
{
{
fputs ( " ERROR: Bad value for \" foo/bar/one/two \" . \n " , stderr ) ;
fputs ( " ERROR: Bad value for \" foo/bar/one/two \" . \n " , stderr ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
/*
// Test indices...
* Test indices . . .
*/
ind = mxmlIndexNew ( tree , NULL , NULL ) ;
ind = mxmlIndexNew ( tree , NULL , NULL ) ;
if ( ! ind )
if ( ! ind )
{
{
@ -330,8 +288,7 @@ main(int argc, /* I - Number of command-line args */
if ( ind - > num_nodes ! = 13 )
if ( ind - > num_nodes ! = 13 )
{
{
fprintf ( stderr , " ERROR: Index of all nodes contains %d "
fprintf ( stderr , " ERROR: Index of all nodes contains %d nodes; expected 13. \n " , ind - > num_nodes ) ;
" nodes; expected 13. \n " , ind - > num_nodes ) ;
mxmlIndexDelete ( ind ) ;
mxmlIndexDelete ( ind ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
@ -358,8 +315,7 @@ main(int argc, /* I - Number of command-line args */
if ( ind - > num_nodes ! = 4 )
if ( ind - > num_nodes ! = 4 )
{
{
fprintf ( stderr , " ERROR: Index of groups contains %d "
fprintf ( stderr , " ERROR: Index of groups contains %d nodes; expected 4. \n " , ind - > num_nodes ) ;
" nodes; expected 4. \n " , ind - > num_nodes ) ;
mxmlIndexDelete ( ind ) ;
mxmlIndexDelete ( ind ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
@ -386,8 +342,7 @@ main(int argc, /* I - Number of command-line args */
if ( ind - > num_nodes ! = 3 )
if ( ind - > num_nodes ! = 3 )
{
{
fprintf ( stderr , " ERROR: Index of type attributes contains %d "
fprintf ( stderr , " ERROR: Index of type attributes contains %d nodes; expected 3. \n " , ind - > num_nodes ) ;
" nodes; expected 3. \n " , ind - > num_nodes ) ;
mxmlIndexDelete ( ind ) ;
mxmlIndexDelete ( ind ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
@ -414,8 +369,7 @@ main(int argc, /* I - Number of command-line args */
if ( ind - > num_nodes ! = 3 )
if ( ind - > num_nodes ! = 3 )
{
{
fprintf ( stderr , " ERROR: Index of elements and attributes contains %d "
fprintf ( stderr , " ERROR: Index of elements and attributes contains %d nodes; expected 3. \n " , ind - > num_nodes ) ;
" nodes; expected 3. \n " , ind - > num_nodes ) ;
mxmlIndexDelete ( ind ) ;
mxmlIndexDelete ( ind ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
@ -432,18 +386,16 @@ main(int argc, /* I - Number of command-line args */
mxmlIndexDelete ( ind ) ;
mxmlIndexDelete ( ind ) ;
/*
// Check the mxmlDelete() works properly...
* Check the mxmlDelete ( ) works properly . . .
*/
for ( i = 0 ; i < 12 ; i + + )
for ( i = 0 ; i < 12 ; i + + )
{
{
if ( tree - > child )
if ( tree - > child )
{
mxmlDelete ( tree - > child ) ;
mxmlDelete ( tree - > child ) ;
}
else
else
{
{
fprintf ( stderr , " ERROR: Child pointer prematurely NULL on child #%d \n " ,
fprintf ( stderr , " ERROR: Child pointer prematurely NULL on child #%d \n " , i + 1 ) ;
i + 1 ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
@ -463,12 +415,11 @@ main(int argc, /* I - Number of command-line args */
mxmlDelete ( xml ) ;
mxmlDelete ( xml ) ;
/*
// Open the file/string using the default (MXML_NO_CALLBACK) callback...
* Open the file / string using the default ( MXML_NO_CALLBACK ) callback . . .
*/
if ( argv [ 1 ] [ 0 ] = = ' < ' )
if ( argv [ 1 ] [ 0 ] = = ' < ' )
{
xml = mxmlLoadString ( NULL , argv [ 1 ] , MXML_NO_CALLBACK ) ;
xml = mxmlLoadString ( NULL , argv [ 1 ] , MXML_NO_CALLBACK ) ;
}
else if ( ( fp = fopen ( argv [ 1 ] , " rb " ) ) = = NULL )
else if ( ( fp = fopen ( argv [ 1 ] , " rb " ) ) = = NULL )
{
{
perror ( argv [ 1 ] ) ;
perror ( argv [ 1 ] ) ;
@ -476,10 +427,7 @@ main(int argc, /* I - Number of command-line args */
}
}
else
else
{
{
/*
// Read the file...
* Read the file . . .
*/
xml = mxmlLoadFile ( NULL , fp , MXML_NO_CALLBACK ) ;
xml = mxmlLoadFile ( NULL , fp , MXML_NO_CALLBACK ) ;
fclose ( fp ) ;
fclose ( fp ) ;
@ -493,13 +441,9 @@ main(int argc, /* I - Number of command-line args */
if ( ! strcmp ( argv [ 1 ] , " test.xml " ) )
if ( ! strcmp ( argv [ 1 ] , " test.xml " ) )
{
{
const char * text ; /* Text value */
const char * text ; // Text value
/*
* Verify that mxmlFindElement ( ) and indirectly mxmlWalkNext ( ) work
* properly . . .
*/
// Verify that mxmlFindElement() and indirectly mxmlWalkNext() work properly...
if ( ( node = mxmlFindPath ( xml , " group/option/keyword " ) ) = = NULL )
if ( ( node = mxmlFindPath ( xml , " group/option/keyword " ) ) = = NULL )
{
{
fputs ( " Unable to find group/option/keyword element in XML tree. \n " , stderr ) ;
fputs ( " Unable to find group/option/keyword element in XML tree. \n " , stderr ) ;
@ -507,7 +451,7 @@ main(int argc, /* I - Number of command-line args */
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( node - > type ! = MXML_TEXT )
if ( node - > type ! = MXML_TYPE_T EXT )
{
{
fputs ( " No child node of group/option/keyword. \n " , stderr ) ;
fputs ( " No child node of group/option/keyword. \n " , stderr ) ;
mxmlSaveFile ( xml , stderr , MXML_NO_CALLBACK ) ;
mxmlSaveFile ( xml , stderr , MXML_NO_CALLBACK ) ;
@ -525,12 +469,11 @@ main(int argc, /* I - Number of command-line args */
mxmlDelete ( xml ) ;
mxmlDelete ( xml ) ;
/*
// Open the file...
* Open the file . . .
*/
if ( argv [ 1 ] [ 0 ] = = ' < ' )
if ( argv [ 1 ] [ 0 ] = = ' < ' )
{
xml = mxmlLoadString ( NULL , argv [ 1 ] , type_cb ) ;
xml = mxmlLoadString ( NULL , argv [ 1 ] , type_cb ) ;
}
else if ( ( fp = fopen ( argv [ 1 ] , " rb " ) ) = = NULL )
else if ( ( fp = fopen ( argv [ 1 ] , " rb " ) ) = = NULL )
{
{
perror ( argv [ 1 ] ) ;
perror ( argv [ 1 ] ) ;
@ -538,10 +481,7 @@ main(int argc, /* I - Number of command-line args */
}
}
else
else
{
{
/*
// Read the file...
* Read the file . . .
*/
xml = mxmlLoadFile ( NULL , fp , type_cb ) ;
xml = mxmlLoadFile ( NULL , fp , type_cb ) ;
fclose ( fp ) ;
fclose ( fp ) ;
@ -555,13 +495,8 @@ main(int argc, /* I - Number of command-line args */
if ( ! strcmp ( argv [ 1 ] , " test.xml " ) )
if ( ! strcmp ( argv [ 1 ] , " test.xml " ) )
{
{
/*
// Verify that mxmlFindElement() and indirectly mxmlWalkNext() work properly...
* Verify that mxmlFindElement ( ) and indirectly mxmlWalkNext ( ) work
if ( ( node = mxmlFindElement ( xml , xml , " choice " , NULL , NULL , MXML_DESCEND ) ) = = NULL )
* properly . . .
*/
if ( ( node = mxmlFindElement ( xml , xml , " choice " , NULL , NULL ,
MXML_DESCEND ) ) = = NULL )
{
{
fputs ( " Unable to find first <choice> element in XML tree. \n " , stderr ) ;
fputs ( " Unable to find first <choice> element in XML tree. \n " , stderr ) ;
mxmlDelete ( tree ) ;
mxmlDelete ( tree ) ;
@ -576,16 +511,10 @@ main(int argc, /* I - Number of command-line args */
}
}
}
}
/*
// Print the XML tree...
* Print the XML tree . . .
*/
mxmlSaveFile ( xml , stdout , whitespace_cb ) ;
mxmlSaveFile ( xml , stdout , whitespace_cb ) ;
/*
// Save the XML tree to a string and print it...
* Save the XML tree to a string and print it . . .
*/
if ( mxmlSaveString ( xml , buffer , sizeof ( buffer ) , whitespace_cb ) > 0 )
if ( mxmlSaveString ( xml , buffer , sizeof ( buffer ) , whitespace_cb ) > 0 )
{
{
if ( argc = = 3 )
if ( argc = = 3 )
@ -596,40 +525,25 @@ main(int argc, /* I - Number of command-line args */
}
}
}
}
/*
// Delete the tree...
* Delete the tree . . .
*/
mxmlDelete ( xml ) ;
mxmlDelete ( xml ) ;
/*
// Read from/write to file descriptors...
* Read from / write to file descriptors . . .
*/
if ( argv [ 1 ] [ 0 ] ! = ' < ' )
if ( argv [ 1 ] [ 0 ] ! = ' < ' )
{
{
/*
// Open the file again...
* Open the file again . . .
*/
if ( ( fd = open ( argv [ 1 ] , O_RDONLY | O_BINARY ) ) < 0 )
if ( ( fd = open ( argv [ 1 ] , O_RDONLY | O_BINARY ) ) < 0 )
{
{
perror ( argv [ 1 ] ) ;
perror ( argv [ 1 ] ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
/*
// Read the file...
* Read the file . . .
*/
xml = mxmlLoadFd ( NULL , fd , type_cb ) ;
xml = mxmlLoadFd ( NULL , fd , type_cb ) ;
close ( fd ) ;
close ( fd ) ;
/*
// Create filename.xmlfd...
* Create filename . xmlfd . . .
*/
snprintf ( buffer , sizeof ( buffer ) , " %sfd " , argv [ 1 ] ) ;
snprintf ( buffer , sizeof ( buffer ) , " %sfd " , argv [ 1 ] ) ;
if ( ( fd = open ( buffer , O_WRONLY | O_CREAT | O_TRUNC | O_BINARY , 0666 ) ) < 0 )
if ( ( fd = open ( buffer , O_WRONLY | O_CREAT | O_TRUNC | O_BINARY , 0666 ) ) < 0 )
@ -639,29 +553,22 @@ main(int argc, /* I - Number of command-line args */
return ( 1 ) ;
return ( 1 ) ;
}
}
/*
// Write the file...
* Write the file . . .
*/
mxmlSaveFd ( xml , fd , whitespace_cb ) ;
mxmlSaveFd ( xml , fd , whitespace_cb ) ;
close ( fd ) ;
close ( fd ) ;
/*
// Delete the tree...
* Delete the tree . . .
*/
mxmlDelete ( xml ) ;
mxmlDelete ( xml ) ;
}
}
/*
// Test SAX methods...
* Test SAX methods . . .
*/
memset ( event_counts , 0 , sizeof ( event_counts ) ) ;
memset ( event_counts , 0 , sizeof ( event_counts ) ) ;
if ( argv [ 1 ] [ 0 ] = = ' < ' )
if ( argv [ 1 ] [ 0 ] = = ' < ' )
{
mxmlRelease ( mxmlSAXLoadString ( NULL , argv [ 1 ] , type_cb , sax_cb , NULL ) ) ;
mxmlRelease ( mxmlSAXLoadString ( NULL , argv [ 1 ] , type_cb , sax_cb , NULL ) ) ;
}
else if ( ( fp = fopen ( argv [ 1 ] , " rb " ) ) = = NULL )
else if ( ( fp = fopen ( argv [ 1 ] , " rb " ) ) = = NULL )
{
{
perror ( argv [ 1 ] ) ;
perror ( argv [ 1 ] ) ;
@ -669,10 +576,7 @@ main(int argc, /* I - Number of command-line args */
}
}
else
else
{
{
/*
// Read the file...
* Read the file . . .
*/
mxmlRelease ( mxmlSAXLoadFile ( NULL , fp , type_cb , sax_cb , NULL ) ) ;
mxmlRelease ( mxmlSAXLoadFile ( NULL , fp , type_cb , sax_cb , NULL ) ) ;
fclose ( fp ) ;
fclose ( fp ) ;
@ -680,56 +584,48 @@ main(int argc, /* I - Number of command-line args */
if ( ! strcmp ( argv [ 1 ] , " test.xml " ) )
if ( ! strcmp ( argv [ 1 ] , " test.xml " ) )
{
{
if ( event_counts [ MXML_SAX_CDATA ] ! = 1 )
if ( event_counts [ MXML_SAX_EVENT_ CDATA ] ! = 1 )
{
{
fprintf ( stderr , " MXML_SAX_CDATA seen %d times, expected 1 times. \n " ,
fprintf ( stderr , " MXML_SAX_EVENT_CDATA seen %d times, expected 1 times. \n " , event_counts [ MXML_SAX_EVENT_CDATA ] ) ;
event_counts [ MXML_SAX_CDATA ] ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( event_counts [ MXML_SAX_COMMENT ] ! = 1 )
if ( event_counts [ MXML_SAX_EVENT_ COMMENT ] ! = 1 )
{
{
fprintf ( stderr , " MXML_SAX_COMMENT seen %d times, expected 1 times. \n " ,
fprintf ( stderr , " MXML_SAX_EVENT_COMMENT seen %d times, expected 1 times. \n " , event_counts [ MXML_SAX_EVENT_COMMENT ] ) ;
event_counts [ MXML_SAX_COMMENT ] ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( event_counts [ MXML_SAX_DATA ] ! = 61 )
if ( event_counts [ MXML_SAX_EVENT_ DATA ] ! = 61 )
{
{
fprintf ( stderr , " MXML_SAX_DATA seen %d times, expected 61 times. \n " ,
fprintf ( stderr , " MXML_SAX_EVENT_DATA seen %d times, expected 61 times. \n " , event_counts [ MXML_SAX_EVENT_DATA ] ) ;
event_counts [ MXML_SAX_DATA ] ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( event_counts [ MXML_SAX_DIRECTIVE ] ! = 1 )
if ( event_counts [ MXML_SAX_EVENT_ DIRECTIVE ] ! = 1 )
{
{
fprintf ( stderr , " MXML_SAX_DIRECTIVE seen %d times, expected 1 times. \n " ,
fprintf ( stderr , " MXML_SAX_EVENT_DIRECTIVE seen %d times, expected 1 times. \n " , event_counts [ MXML_SAX_EVENT_DIRECTIVE ] ) ;
event_counts [ MXML_SAX_DIRECTIVE ] ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( event_counts [ MXML_SAX_ELEMENT_CLOSE ] ! = 20 )
if ( event_counts [ MXML_SAX_EVENT_E LEMENT_CLOSE ] ! = 20 )
{
{
fprintf ( stderr , " MXML_SAX_ELEMENT_CLOSE seen %d times, expected 20 times. \n " ,
fprintf ( stderr , " MXML_SAX_EVENT_ELEMENT_CLOSE seen %d times, expected 20 times. \n " , event_counts [ MXML_SAX_EVENT_ELEMENT_CLOSE ] ) ;
event_counts [ MXML_SAX_ELEMENT_CLOSE ] ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
if ( event_counts [ MXML_SAX_ELEMENT_OPEN ] ! = 20 )
if ( event_counts [ MXML_SAX_EVENT_E LEMENT_OPEN ] ! = 20 )
{
{
fprintf ( stderr , " MXML_SAX_ELEMENT_OPEN seen %d times, expected 20 times. \n " ,
fprintf ( stderr , " MXML_SAX_EVENT_ELEMENT_OPEN seen %d times, expected 20 times. \n " , event_counts [ MXML_SAX_EVENT_ELEMENT_OPEN ] ) ;
event_counts [ MXML_SAX_ELEMENT_OPEN ] ) ;
return ( 1 ) ;
return ( 1 ) ;
}
}
}
}
# ifndef _WIN32
# ifndef _WIN32
/*
// Debug hooks...
* Debug hooks . . .
*/
if ( getenv ( " TEST_DELAY " ) ! = NULL )
if ( getenv ( " TEST_DELAY " ) ! = NULL )
sleep ( atoi ( getenv ( " TEST_DELAY " ) ) ) ;
sleep ( atoi ( getenv ( " TEST_DELAY " ) ) ) ;
# ifdef __APPLE__
# ifdef __APPLE__
if ( getenv ( " TEST_LEAKS " ) ! = NULL )
if ( getenv ( " TEST_LEAKS " ) ! = NULL )
{
{
@ -739,43 +635,37 @@ main(int argc, /* I - Number of command-line args */
if ( system ( command ) )
if ( system ( command ) )
puts ( " Unable to check for leaks. " ) ;
puts ( " Unable to check for leaks. " ) ;
}
}
# endif /* __APPLE__ */
# endif // __APPLE__
# endif /* !_WIN32 */
# endif // !_WIN32
/*
* Return . . .
*/
// Return...
return ( 0 ) ;
return ( 0 ) ;
}
}
/*
//
* ' sax_cb ( ) ' - Process nodes via SAX .
// 'sax_cb()' - Process nodes via SAX.
*/
//
void
void
sax_cb ( mxml_node_t * node , /* I - Current node */
sax_cb ( mxml_node_t * node , // I - Current node
mxml_sax_event_t event , /* I - SAX event */
mxml_sax_event_t event , // I - SAX event
void * data ) /* I - SAX user data */
void * data ) // I - SAX user data
{
{
static const char * const events [ ] = /* Events */
static const char * const events [ ] = // Events
{
{
" MXML_SAX_CDATA " , /* CDATA node */
" MXML_SAX_EVENT_ CDATA " , // CDATA node
" MXML_SAX_COMMENT " , /* Comment node */
" MXML_SAX_EVENT_ COMMENT " , // Comment node
" MXML_SAX_DATA " , /* Data node */
" MXML_SAX_EVENT_ DATA " , // Data node
" MXML_SAX_DIRECTIVE " , /* Processing directive node */
" MXML_SAX_EVENT_ DIRECTIVE " , // Processing directive node
" MXML_SAX_ELEMENT_CLOSE " , /* Element closed */
" MXML_SAX_EVENT_E LEMENT_CLOSE " , // Element closed
" MXML_SAX_ELEMENT_OPEN " /* Element opened */
" MXML_SAX_EVENT_E LEMENT_OPEN " // Element opened
} ;
} ;
( void ) data ;
( void ) data ;
/*
// This SAX callback just counts the different events.
* This SAX callback just counts the different events .
*/
if ( ! node )
if ( ! node )
fprintf ( stderr , " ERROR: SAX callback for event %s has NULL node. \n " , events [ event ] ) ;
fprintf ( stderr , " ERROR: SAX callback for event %s has NULL node. \n " , events [ event ] ) ;
@ -783,83 +673,65 @@ sax_cb(mxml_node_t *node, /* I - Current node */
}
}
/*
//
* ' type_cb ( ) ' - XML data type callback for mxmlLoadFile ( ) . . .
// 'type_cb()' - XML data type callback for mxmlLoadFile()...
*/
//
mxml_type_t /* O - Data type */
mxml_type_t // O - Data type
type_cb ( mxml_node_t * node ) /* I - Element node */
type_cb ( mxml_node_t * node ) // I - Element node
{
{
const char * type ; /* Type string */
const char * type ; // Type string
/*
* You can lookup attributes and / or use the element name , hierarchy , etc . . .
*/
// You can lookup attributes and/or use the element name, hierarchy, etc...
if ( ( type = mxmlElementGetAttr ( node , " type " ) ) = = NULL )
if ( ( type = mxmlElementGetAttr ( node , " type " ) ) = = NULL )
type = node - > value . element . name ;
type = node - > value . element . name ;
if ( ! strcmp ( type , " integer " ) )
if ( ! strcmp ( type , " integer " ) )
return ( MXML_INTEGER ) ;
return ( MXML_TYPE_ INTEGER ) ;
else if ( ! strcmp ( type , " opaque " ) | | ! strcmp ( type , " pre " ) )
else if ( ! strcmp ( type , " opaque " ) | | ! strcmp ( type , " pre " ) )
return ( MXML_OPAQUE ) ;
return ( MXML_TYPE_ OPAQUE ) ;
else if ( ! strcmp ( type , " real " ) )
else if ( ! strcmp ( type , " real " ) )
return ( MXML_REAL ) ;
return ( MXML_TYPE_ REAL ) ;
else
else
return ( MXML_TEXT ) ;
return ( MXML_TYPE_T EXT ) ;
}
}
/*
//
* ' whitespace_cb ( ) ' - Let the mxmlSaveFile ( ) function know when to insert
// 'whitespace_cb()' - Let the mxmlSaveFile() function know when to insert
* newlines and tabs . . .
// newlines and tabs...
*/
//
const char * /* O - Whitespace string or NULL */
const char * // O - Whitespace string or NULL
whitespace_cb ( mxml_node_t * node , /* I - Element node */
whitespace_cb ( mxml_node_t * node , // I - Element node
int where ) /* I - Open or close tag? */
int where ) // I - Open or close tag?
{
{
mxml_node_t * parent ; /* Parent node */
mxml_node_t * parent ; // Parent node
int level ; /* Indentation level */
int level ; // Indentation level
const char * name ; /* Name of element */
const char * name ; // Name of element
static const char * tabs = " \t \t \t \t \t \t \t \t " ;
static const char * tabs = " \t \t \t \t \t \t \t \t " ;
/* Tabs for indentation */
// Tabs for indentation
/*
// We can conditionally break to a new line before or after any element.
* We can conditionally break to a new line before or after any element .
// These are just common HTML elements...
* These are just common HTML elements . . .
*/
name = node - > value . element . name ;
name = node - > value . element . name ;
if ( ! strcmp ( name , " html " ) | | ! strcmp ( name , " head " ) | | ! strcmp ( name , " body " ) | |
if ( ! strcmp ( name , " html " ) | | ! strcmp ( name , " head " ) | | ! strcmp ( name , " body " ) | | ! strcmp ( name , " pre " ) | | ! strcmp ( name , " p " ) | | ! strcmp ( name , " h1 " ) | | ! strcmp ( name , " h2 " ) | | ! strcmp ( name , " h3 " ) | | ! strcmp ( name , " h4 " ) | | ! strcmp ( name , " h5 " ) | | ! strcmp ( name , " h6 " ) )
! strcmp ( name , " pre " ) | | ! strcmp ( name , " p " ) | |
! strcmp ( name , " h1 " ) | | ! strcmp ( name , " h2 " ) | | ! strcmp ( name , " h3 " ) | |
! strcmp ( name , " h4 " ) | | ! strcmp ( name , " h5 " ) | | ! strcmp ( name , " h6 " ) )
{
{
/*
// Newlines before open and after close...
* Newlines before open and after close . . .
*/
if ( where = = MXML_WS_BEFORE_OPEN | | where = = MXML_WS_AFTER_CLOSE )
if ( where = = MXML_WS_BEFORE_OPEN | | where = = MXML_WS_AFTER_CLOSE )
return ( " \n " ) ;
return ( " \n " ) ;
}
}
else if ( ! strcmp ( name , " dl " ) | | ! strcmp ( name , " ol " ) | | ! strcmp ( name , " ul " ) )
else if ( ! strcmp ( name , " dl " ) | | ! strcmp ( name , " ol " ) | | ! strcmp ( name , " ul " ) )
{
{
/*
// Put a newline before and after list elements...
* Put a newline before and after list elements . . .
*/
return ( " \n " ) ;
return ( " \n " ) ;
}
}
else if ( ! strcmp ( name , " dd " ) | | ! strcmp ( name , " dt " ) | | ! strcmp ( name , " li " ) )
else if ( ! strcmp ( name , " dd " ) | | ! strcmp ( name , " dt " ) | | ! strcmp ( name , " li " ) )
{
{
/*
// Put a tab before <li>'s, <dd>'s, and <dt>'s, and a newline after them...
* Put a tab before < li > ' s , < dd > ' s , and < dt > ' s , and a newline after them . . .
*/
if ( where = = MXML_WS_BEFORE_OPEN )
if ( where = = MXML_WS_BEFORE_OPEN )
return ( " \t " ) ;
return ( " \t " ) ;
else if ( where = = MXML_WS_AFTER_CLOSE )
else if ( where = = MXML_WS_AFTER_CLOSE )
@ -872,13 +744,9 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */
else
else
return ( NULL ) ;
return ( NULL ) ;
}
}
else if ( where = = MXML_WS_BEFORE_OPEN | |
else if ( where = = MXML_WS_BEFORE_OPEN | | ( ( ! strcmp ( name , " choice " ) | | ! strcmp ( name , " option " ) ) & & where = = MXML_WS_BEFORE_CLOSE ) )
( ( ! strcmp ( name , " choice " ) | | ! strcmp ( name , " option " ) ) & &
where = = MXML_WS_BEFORE_CLOSE ) )
{
{
for ( level = - 1 , parent = node - > parent ;
for ( level = - 1 , parent = node - > parent ; parent ; level + + , parent = parent - > parent ) ;
parent ;
level + + , parent = parent - > parent ) ;
if ( level > 8 )
if ( level > 8 )
level = 8 ;
level = 8 ;
@ -887,17 +755,11 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */
return ( tabs + 8 - level ) ;
return ( tabs + 8 - level ) ;
}
}
else if ( where = = MXML_WS_AFTER_CLOSE | |
else if ( where = = MXML_WS_AFTER_CLOSE | | ( ( ! strcmp ( name , " group " ) | | ! strcmp ( name , " option " ) | | ! strcmp ( name , " choice " ) ) & & where = = MXML_WS_AFTER_OPEN ) )
( ( ! strcmp ( name , " group " ) | | ! strcmp ( name , " option " ) | |
! strcmp ( name , " choice " ) ) & &
where = = MXML_WS_AFTER_OPEN ) )
return ( " \n " ) ;
return ( " \n " ) ;
else if ( where = = MXML_WS_AFTER_OPEN & & ! node - > child )
else if ( where = = MXML_WS_AFTER_OPEN & & ! node - > child )
return ( " \n " ) ;
return ( " \n " ) ;
/*
// Return NULL for no added whitespace...
* Return NULL for no added whitespace . . .
*/
return ( NULL ) ;
return ( NULL ) ;
}
}