summaryrefslogtreecommitdiffstats
path: root/ast/xml.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2016-11-02 19:11:06 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2016-11-02 19:11:06 (GMT)
commit33c55bd916dff8c4932b01c7db58f0103ac31c31 (patch)
treea4cdca3287dd2df5247ce8079c424ffa438b4c2e /ast/xml.c
parent4121637f3d41d6dc23e6543a445b5a3aed9e6ddc (diff)
downloadblt-33c55bd916dff8c4932b01c7db58f0103ac31c31.zip
blt-33c55bd916dff8c4932b01c7db58f0103ac31c31.tar.gz
blt-33c55bd916dff8c4932b01c7db58f0103ac31c31.tar.bz2
update ast
Diffstat (limited to 'ast/xml.c')
-rw-r--r--ast/xml.c7119
1 files changed, 0 insertions, 7119 deletions
diff --git a/ast/xml.c b/ast/xml.c
deleted file mode 100644
index 541132d..0000000
--- a/ast/xml.c
+++ /dev/null
@@ -1,7119 +0,0 @@
-/*
-* Name:
-* xml.c
-
-* Purpose:
-* Implement XML functions for AST.
-
-* Description:
-* This file implements the Xml module which provides generic XML
-* reading and writing functions for the XmlChan class.
-
-* Copyright:
-* Copyright (C) 1997-2006 Council for the Central Laboratory of the
-* Research Councils
-
-* Licence:
-* This program is free software: you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation, either
-* version 3 of the License, or (at your option) any later
-* version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General
-* License along with this program. If not, see
-* <http://www.gnu.org/licenses/>.
-
-* Authors:
-* DSB: David S. Berry (Starlink)
-
-* History:
-* 22-OCT-2003 (DSB):
-* Original version.
-* 12-JAN-2004 (DSB):
-* Major revisions.
-* 10-FEB-2004 (DSB):
-* - Added debug conditional code to keep track of memory leaks.
-* - Other minor bug fixes.
-* 6-FEB-2004 (DSB):
-* DefaultURI and astXmlAddURI modified to allow a blank URI to be
-* used to ignore a default namespace URI provided by an enclosing
-* element.
-* 29-NOV-2004 (DSB):
-* Added astXmlGetType method.
-* 27-JAN-2005 (DSB):
-* - Move astXmlTrace and associated code into conditional
-* compilation blokc (included if DEBUG macro is defined). This
-* speeds up the create and destruction of XmlObjects in non-DEBUG code.
-* - Renamed the private Delete function as astXmlDelete and gave
-* it protected access.
-* - Modify astXmlDelete so that it can succesfully annul objects
-* which have no parent.
-* - Include extra info in some error messages.
-* 1-MAR-2006 (DSB):
-* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM.
-* 10-DEC-2008 (DSB):
-* Allow a prefix to be included with the attribute name in
-* astXmlGetAttributeValue.
-*/
-
-
-/* Module Constants. */
-/* ----------------- */
-/* Set the name of the module we are implementing. This indicates to
- the header files that define class interfaces that they should make
- "protected" symbols available. NB, this module is not a proper AST
- class, but it defines this macro sanyway in order to get the protected
- symbols defined in memory.h */
-#define astCLASS Xml
-
-#define IND_INC 3
-
-
-/* Include files. */
-/* ============== */
-/* Interface definitions. */
-/* ---------------------- */
-#include "memory.h" /* Interface to the memory management module */
-#include "error.h" /* Interface to the error module */
-#include "xml.h" /* Interface to this module */
-#include "globals.h" /* Thread-safe global data access */
-
-/* Error code definitions. */
-/* ----------------------- */
-#include "ast_err.h" /* AST error codes */
-
-/* C header files. */
-/* --------------- */
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-
-/*
-* Name:
-* MAKE_CHECK
-
-* Type:
-* Private macro.
-
-* Purpose:
-* Implement the astXmlCheck<type>_ function for XML structures.
-
-* Synopsis:
-* #include "xml.h"
-* MAKE_CHECK(type,id)
-
-* Class Membership:
-* Defined by the xml module.
-
-* Description:
-* This macro expands to an implementation of the protected
-* astXmlCheck<type>_ function (q.v.) which validates membership of
-* a specified XML data type.
-
-* Parameters:
-* type
-* The type whose membership is to be validated (e.g. "Element" not
-* "XmlElement").
-* id
-* The constant (e.g. "AST__XMLELEM") defining the data type.
-
-* Notes:
-* - To avoid problems with some compilers, you should not leave any white
-* space around the macro arguments.
-*/
-
-/* Define the macro. */
-#define MAKE_CHECK(type,id) \
-\
-/* Declare the function */ \
-AstXml##type *astXmlCheck##type##_( void *this, int nullok, int *status ) { \
-\
-/* Local Variables: */\
- AstXml##type *result; /* The returned pointer */\
-\
-/* Check the global error status. If an error has already occurred just\
- return the supplied pointer. This is so that functions such as\
- astXmlAnnul which do not check the inherited status receive the\
- supplied pointer. */\
- if( !astOK ) return this;\
-\
-/* Initialise */\
- result = NULL;\
-\
-/* If the pointer is NULL issue an error if nullok is zero. */\
- if( !this ) {\
- if( !nullok ) astError( AST__PTRIN, "astXmlCheck"#type": Invalid "\
- "NULL pointer supplied." , status);\
-\
-/* Otherwise get the "type" component which holds a magic value for each\
- different class of structure. Compare this value against all valid \
- classes of structure. If no match is found, the pointer does not \
- identify an suitable structure, and so report an error and return \
- NULL. */\
- } else {\
- if( !astXmlCheckType( ( AstXmlObject * ) this, id ) ) {\
- astError( AST__PTRIN, "astXmlCheck"#type": Invalid pointer "\
- "supplied; pointer to AstXml"#type" required." , status);\
- } else {\
- result = (AstXml##type *) this;\
- }\
- }\
-\
-/* Return the result. */\
- return result;\
-}
-
-
-/* Module variables. */
-/* ================= */
-
-/* Define macros for accessing all items of thread-safe global data
- used by this module. */
-#ifdef THREAD_SAFE
-
-#define next_id astGLOBAL(Xml,Next_ID)
-#define gettag_buff astGLOBAL(Xml,GetTag_Buff)
-#define GLOBAL_inits globals->Next_ID = 0;
-astMAKE_INITGLOBALS(Xml)
-
-/* Set up mutexes */
-static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
-#define LOCK_MUTEX1 pthread_mutex_lock( &mutex1 );
-#define UNLOCK_MUTEX1 pthread_mutex_unlock( &mutex1 );
-
-/* If thread safety is not needed, declare globals at static variables. */
-#else
-
-static int next_id = 0;
-static char gettag_buff[ AST__XML_GETTAG_BUFF_LEN + 1 ];
-
-#define LOCK_MUTEX1
-#define UNLOCK_MUTEX1
-
-#ifdef DEBUG /* Not available in thread-safe compilations */
-static int nobj = 0;
-static AstXmlObject **existing_objects = NULL;
-#endif
-
-#endif
-
-
-/* Function prototypes. */
-/* ==================== */
-
-/* Private member functions. */
-/* ------------------------- */
-static AstXmlAttribute *FindAttribute( AstXmlElement *, const char *, int * );
-static AstXmlAttribute *NewAttribute( const char *, const char *, const char *, int * );
-static AstXmlDocument *NewDocument( int * );
-static AstXmlPrologue *NewPrologue( AstXmlDocument *, int * );
-static AstXmlNamespace *NewNamespace( const char *, const char *, int * );
-static char *AppendChar( char *, int *, char, int * );
-static char *AppendLine( char *, int *, const char *, int, int * );
-static char *RemoveEscapes( const char *, int * );
-static char *CleanText( const char *, int * );
-static const char *AddEscapes( const char *, int * );
-static const char *DefaultURI( AstXmlElement *, int * );
-static const char *Format( AstXmlObject *, int, int * );
-static char *FormatTag( AstXmlObject *, int, int * );
-static const char *ResolvePrefix( const char *, AstXmlElement *, int * );
-static int CheckType( long int, long int, int * );
-static int MatchName( AstXmlElement *, const char *, int * );
-static int Ustrcmp( const char *, const char *, int * );
-static void AddContent( AstXmlParent *, int, AstXmlContentItem *, int * );
-static void CheckName( const char *, const char *, const char *, int, int * );
-static void CheckPrefName( char *, const char *, const char *, int * );
-static void CleanXml( AstXmlObject *, long int, int * );
-static void InitXmlAttribute( AstXmlAttribute *, int, const char *, const char *, const char *, int * );
-static void InitXmlCDataSection( AstXmlCDataSection *, int, const char *, int * );
-static void InitXmlWhite( AstXmlWhite *, int, const char *, int * );
-static void InitXmlBlack( AstXmlBlack *, int, const char *, int * );
-static void InitXmlComment( AstXmlComment *, int, const char *, int * );
-static void InitXmlDocument( AstXmlDocument *, int, int * );
-static void InitXmlPrologue( AstXmlPrologue *, int, int * );
-static void InitXmlDeclPI( AstXmlDeclPI *, int, const char *, int * );
-static void InitXmlDTDec( AstXmlDTDec *, int, const char *, const char *, const char *, int * );
-static void InitXmlElement( AstXmlElement *, int, const char *, const char *, int * );
-static void InitXmlNamespace( AstXmlNamespace *, int, const char *, const char *, int * );
-static void InitXmlObject( AstXmlObject *, long int, int * );
-static void InitXmlPI( AstXmlPI *, int, const char *, const char *, int * );
-static AstXmlElement *ReadContent( AstXmlDocument **, int, int (*)( AstXmlElement *, int * ), int, char (*)( void *, int * ), void *, int, int * );
-
-#ifdef DEBUG
-static void AddObjectToList( AstXmlObject * );
-static void RemoveObjectFromList( AstXmlObject * );
-#endif
-
-/* Function implementations. */
-/* ========================= */
-
-/* Create the astXmlCheck... functiosn which check a pointer identifies
- an XML structure of a given type. */
-
-MAKE_CHECK(Document,AST__XMLDOC)
-MAKE_CHECK(Object,AST__XMLOBJECT)
-MAKE_CHECK(Element,AST__XMLELEM)
-MAKE_CHECK(Attribute,AST__XMLATTR)
-MAKE_CHECK(CDataSection,AST__XMLCDATA)
-MAKE_CHECK(Comment,AST__XMLCOM)
-MAKE_CHECK(PI,AST__XMLPI)
-MAKE_CHECK(Namespace,AST__XMLNAME)
-MAKE_CHECK(Prologue,AST__XMLPRO)
-MAKE_CHECK(DeclPI,AST__XMLDEC)
-MAKE_CHECK(DTDec,AST__XMLDTD)
-MAKE_CHECK(White,AST__XMLWHITE)
-MAKE_CHECK(Black,AST__XMLBLACK)
-MAKE_CHECK(CharData,AST__XMLCHAR)
-MAKE_CHECK(ContentItem,AST__XMLCONT)
-MAKE_CHECK(MiscItem,AST__XMLMISC)
-MAKE_CHECK(Parent,AST__XMLPAR)
-
-
-static void AddContent( AstXmlParent *this, int where, AstXmlContentItem *item, int *status ){
-/*
-* Name:
-* AddContent
-
-* Purpose:
-* Add a content item to an XmlElement.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* void AddContent( AstXmlParent *this, int where, AstXmlContentItem *item, int *status )
-
-* Description:
-* This function adds a supplied item to a specified XmlElement or
-* XmlDocument. An error is reported if the item is not appropriate.
-
-* Parameters:
-* this
-* The pointer to the element or document to be modified.
-* where
-* Ignored if "this" is an XmlElement pointer. Otherwise, "where"
-* indicates where the item should be added to the document:
-* 1 - In the prologue, after the XML declaration but before the DTD.
-* 2 - In the prologue, after the DTD but before the root element.
-* 3 - In the epilogue, after the root element.
-* item
-* Pointer to the content item to be added to the element. If
-* "this" is an XmlElement, this can be a pointer to any of the
-* following types: AstXmlElement, AstXmlWhite, AstXmlBlack,
-* AstXmlCDataSection, AstXmlComment, AstXmlPI. If "this" is a
-* document, the list is restricted to: AstXmlWhite, AstXmlComment,
-* AstXmlPI.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- AstXmlDocument *doc; /* Document pointer */
- AstXmlElement *elem; /* Element pointer */
- AstXmlPrologue *pro; /* Prologue pointer */
- int nitem; /* Number of items in the parent */
-
-/* Check the global error status and the supplied pointers. */
- if( !astOK || !this || !item ) return;
-
-/* Split for the two forms of parent. */
- if( astXmlCheckType( this, AST__XMLELEM ) ) {
- elem = (AstXmlElement *) this;
-
-/* Save the number of content items currently stored in the element. */
- nitem = ( elem->items ) ? elem->nitem : 0;
-
-/* Attempt to extend the array to hold an extra item. */
- elem->items = astGrow( elem->items, nitem + 1,
- sizeof( AstXmlContentItem * ) );
-
-/* Check the memory was allocated succesfully. */
- if( astOK ) {
-
-/* Store the supplied pointer in the array of content items. */
- elem->items[ nitem ] = item;
-
-/* Increment the number of content items in this element */
- elem->nitem = nitem + 1;
-
-/* Indicate that the item is owned by the element. */
- ( (AstXmlObject *) item )->parent = this;
- }
-
-/* Now deal with cases where we are adding an item to the prologue or
- epilogue of the document. */
- } else {
- if( !astXmlCheckType( item, AST__XMLMISC ) ){
- astError( AST__INTER, "AddContent(xml): Inappropriate attempt to "
- "add an item of type %ld to an XML document (internal "
- "AST programming error).", status, ( (AstXmlObject *) item)->type );
-
- } else if( !astXmlCheckType( this, AST__XMLDOC ) ){
- astError( AST__INTER, "AddContent(xml): Inappropriate attempt to "
- "add an item of type %ld to an XML object of type %ld "
- "(internal AST programming error).", status,
- ( (AstXmlObject *) item)->type,
- ( (AstXmlObject *) this)->type );
-
- } else {
- doc = (AstXmlDocument *) this;
-
-/* Create a prologue if necessary. */
- if( where < 3 && !doc->prolog ) doc->prolog = NewPrologue( doc, status );
- pro = doc->prolog;
-
- if( where < 2 ) {
- nitem = ( pro->misc1 ) ? pro->nmisc1 : 0;
- pro->misc1 = astGrow( pro->misc1, nitem + 1, sizeof( AstXmlMiscItem * ) );
- if( astOK ) {
- pro->misc1[ nitem ] = item;
- pro->nmisc1 = nitem + 1;
- ( (AstXmlObject *) item )->parent = (AstXmlParent *) pro;
- }
-
- } else if( where == 2 ) {
- nitem = ( pro->misc2 ) ? pro->nmisc2 : 0;
- pro->misc2 = astGrow( pro->misc2, nitem + 1, sizeof( AstXmlMiscItem * ) );
- if( astOK ) {
- pro->misc2[ nitem ] = item;
- pro->nmisc2 = nitem + 1;
- ( (AstXmlObject *) item )->parent = (AstXmlParent *) pro;
- }
-
- } else {
- nitem = ( doc->epilog ) ? doc->nepi : 0;
- doc->epilog = astGrow( doc->epilog, nitem + 1, sizeof( AstXmlMiscItem * ) );
- if( astOK ) {
- doc->epilog[ nitem ] = item;
- doc->nepi = nitem + 1;
- ( (AstXmlObject *) item )->parent = this;
- }
- }
- }
- }
-}
-
-static const char *AddEscapes( const char *text, int *status ){
-/*
-* Name:
-* AddEscapes
-
-* Purpose:
-* Replaces characters by corresponding entity references.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *AddEscapes( const char *text, int *status )
-
-* Description:
-* This function produces a dynamic copy of the supplied text in which
-* occurrences of "&", "<", ">", and "\"" are replaced by the corresponding
-* XML entity reference.
-*
-* The "&" character is only replaced by an entity reference if it is
-* followed by a non-name character (i.e. anything except a letter
-* underscore or colon). If it is followed by a name character, it is
-* assumed to mark the start of an entity reference.
-
-* Parameters:
-* text
-* A pointer to a text string.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to a dynamically allocated string containing the required
-* copy.
-
-* Notes:
-* - NULL is returned if this function is called with the global error
-* status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- char *result; /* Returned pointer */
- const char *c; /* Pointer to next supplied character */
- char *d; /* Pointer to next returned character */
-
-/* Initialise */
- result = NULL;
-
-/* Return if the pointer is NULL or if an error has occurred. */
- if( !astOK || !text ) return result;
-
-/* Allocate the maximum possible amount of memory that may be needed to
- store the returned string. */
- result = astMalloc( 6*strlen( text ) + 1 );
-
-/* Check the pointer can be used safely. */
- if( astOK ) {
-
-/* Loop round every character in the supplied text. */
- c = text - 1;
- d = result;
- while( *(++c) ) {
-
-/* We replace this character if it is a <, >, ', &, or ". */
- if( *c == '<' ) {
- strcpy( d, "&lt;" );
- d += 4;
-
- } else if( *c == '>' ) {
- strcpy( d, "&gt;" );
- d += 4;
-
- } else if( *c == '"' ) {
- strcpy( d, "&quot;" );
- d += 6;
-
- } else if( *c == '\'' ) {
- strcpy( d, "&apos;" );
- d += 6;
-
- } else if( *c == '&' ) {
- strcpy( d, "&amp;" );
- d += 5;
-
-/* Otherwise just append the supplied character. */
- } else {
- *(d++) = *c;
- }
- }
-
-/* Terminate the returned string. */
- *d = 0;
-
-/* Reallocate the string to free up any unused space. */
- result = astRealloc( result, d - result + 1 );
- }
-
-/* Return the result. */
- return (const char *) result;
-}
-
-
-#ifdef DEBUG
-static void AddObjectToList( AstXmlObject *obj ){
-/*
-* Name:
-* AddObjectToList
-
-* Purpose:
-* Adds an XmlObject to a static list of all currently active XmlObjects.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* void AddObjectToList( AstXmlObject *obj )
-
-* Description:
-* This function adds the supplied pointer to a static list of pointers,
-* and increments the number of elements in the list. This list holds
-* pointers to all the XmlObjects which currently exist.
-
-* Parameters:
-* this
-* A pointer to a new XmlObject.
-*/
-
-/* Return if the pointer is NULL or if an error has occurred. */
- if( !astOK || !obj ) return;
-
-/* Increment the number of objects in the list and increase the size of
- the list. */
- astBeginPM;
- existing_objects = astGrow( existing_objects, ++nobj, sizeof( AstXmlObject *) );
- astEndPM;
-
-/* Add the new pointer to the end of the list. */
- existing_objects[ nobj - 1 ] = obj;
-}
-#endif
-
-static char *AppendChar( char *str1, int *nc, char ch, int *status ) {
-/*
-* Name:
-* AppendChar
-
-* Purpose:
-* Append a character to a string which grows dynamically.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* char *AppendChar( char *str1, int *nc, char ch, int *status )
-
-* Description:
-* This function appends a character to a dynamically
-* allocated string, extending the dynamic string as necessary to
-* accommodate the new character (plus the final null).
-
-* Parameters:
-* str1
-* Pointer to the null-terminated dynamic string, whose memory
-* has been allocated using the AST memory allocation functions
-* defined in "memory.h". If no space has yet been allocated for
-* this string, a NULL pointer may be given and fresh space will
-* be allocated by this function.
-* nc
-* Pointer to an integer containing the number of characters in
-* the dynamic string (excluding the final null). This is used
-* to save repeated searching of this string to determine its
-* length and it defines the point where the new string will be
-* appended. Its value is updated by this function to include
-* the extra characters appended.
-*
-* If "str1" is NULL, the initial value supplied for "*nc" will
-* be ignored and zero will be used.
-* ch
-* The character which is to be appended to "str1".
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A possibly new pointer to the dynamic string with the new character
-* appended (its location in memory may have to change if it has to
-* be extended, in which case the original memory is automatically
-* freed by this function). When the string is no longer required,
-* its memory should be freed using astFree.
-
-* Notes:
-* - If this function is invoked with the global error status set
-* or if it should fail for any reason, then the returned pointer
-* will be equal to "str1" and the dynamic string contents will be
-* unchanged.
-*/
-
-/* Local Variables: */
- char *result; /* Pointer value to return */
- int len; /* Length of new string */
-
-/* Initialise. */
- result = str1;
-
-/* If the first string pointer is NULL, also initialise the character
- count to zero. */
- if ( !str1 ) *nc = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Calculate the total string length once the character has been added. */
- len = *nc + 1;
-
-/* Extend the dynamic string to the required length, including
- a final null. Save the resulting pointer, which will be
- returned. */
- result = astGrow( str1, len + 1, sizeof( char ) );
-
-/* If OK, append the second string and update the total character
- count. */
- if ( astOK ) {
- result[ *nc ] = ch;
- *nc = len;
- result[ *nc ] = 0;
- }
-
-/* Return the result pointer. */
- return result;
-}
-
-static char *AppendLine( char *str1, int *nc, const char *str2, int ind, int *status ) {
-/*
-* Name:
-* AppendLine
-
-* Purpose:
-* Append an indented new line to another string which grows dynamically.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* char *AppendLine( char *str1, int *nc, const char *str2, int ind, int *status )
-
-* Description:
-* This function appends one string to another dynamically
-* allocated string, extending the dynamic string as necessary to
-* accommodate the new characters (plus the final null).
-*
-* A newline character is inserted if necessary to ensure that the "str2"
-* string starts on a newline. If "ind" is positive, spaces are added
-* as necessary to ensure that "str2" begins with the specified number of
-* spaces.
-
-* Parameters:
-* str1
-* Pointer to the null-terminated dynamic string, whose memory
-* has been allocated using the AST memory allocation functions
-* defined in "memory.h". If no space has yet been allocated for
-* this string, a NULL pointer may be given and fresh space will
-* be allocated by this function.
-* nc
-* Pointer to an integer containing the number of characters in
-* the dynamic string (excluding the final null). This is used
-* to save repeated searching of this string to determine its
-* length and it defines the point where the new string will be
-* appended. Its value is updated by this function to include
-* the extra characters appended.
-*
-* If "str1" is NULL, the initial value supplied for "*nc" will
-* be ignored and zero will be used.
-* str2
-* Pointer to a constant null-terminated string, a copy of which
-* is to be appended to "str1".
-* ind
-* The number of spaces to use as the indentation string.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A possibly new pointer to the dynamic string with the new string
-* appended (its location in memory may have to change if it has to
-* be extended, in which case the original memory is automatically
-* freed by this function). When the string is no longer required,
-* its memory should be freed using astFree.
-
-* Notes:
-* - If this function is invoked with the global error status set
-* or if it should fail for any reason, then the returned pointer
-* will be equal to "str1" and the dynamic string contents will be
-* unchanged.
-*/
-
-/* Local Variables: */
- char *c; /* Point to next character */
- char *result; /* Pointer value to return */
- char *temp; /* Pointer to modified string */
- int j; /* Loop count */
-
-/* Initialise. */
- result = str1;
-
-/* If the first string pointer is NULL, also initialise the character
- count to zero. */
- if ( !str1 ) *nc = 0;
-
-/* Check the global error status. */
- if ( !astOK || !str2 ) return result;
-
-/* Remove any trailing white space (except for newlines) from the supplied
- string. */
- if( *nc > 0 ) {
- c = str1 + *nc - 1;
- while( isspace( *c ) && *c != '\n' ) {
- *(c--) = 0;
- (*nc)--;
- }
-
-/* If the last character in the returned string is not now a newline,
- append a newline, so long as the new item does not start with a newline. */
- if( str1[ *nc - 1 ] != '\n' ) {
- temp = AppendChar( str1, nc, '\n', status );
- } else {
- temp = str1;
- }
-
- } else {
- temp = str1;
- }
-
-/* If a fixed indentation is specified, skip over any leading spaces in
- the second string. */
- if( str2 ) {
- if( ind > 0 ) {
- while( isspace( *str2 ) ) str2++;
- }
-
-/* If the first character of the second string is a newline, ignore it. */
- if( str2[ 0 ] == '\n' ) str2++;
- }
-
-/* Append the indentation string. */
- for( j = 0; j < ind; j++ ) temp = AppendChar( temp, nc, ' ', status );
-
-/* Append the supplied string. */
- return astAppendString( temp, nc, str2 );
-}
-
-void astXmlAddAttr_( AstXmlElement *this, const char *name, const char *value,
- const char *prefix, int *status ){
-/*
-*+
-* Name:
-* astXmlAddAttr
-
-* Purpose:
-* Add an attribute to an XmlElement.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlAddAttr( AstXmlElement *this, const char *name,
-* const char *value, const char *prefix )
-
-* Description:
-* This function adds an attribute to a specified XmlElement. If the
-* element already contains an attribute with the given name amd prefix,
-* then the value of the attribute is changed to be the supplied value.
-
-* Parameters:
-* this
-* The pointer to the element to be modified.
-* name
-* Pointer to a null terminated string containing the attribute name.
-* value
-* Pointer to a null terminated string containing the attribute value.
-* prefix
-* The namespace prefix for the attribute. May be NULL or blank, in
-* which case any prefix at the start of "name" is used.
-*-
-*/
-
-/* Local Variables: */
- AstXmlAttribute *attr; /* The new attribute. */
- AstXmlAttribute *oldattr; /* Pointer to existing attribute */
- int i; /* Loop index */
- int nattr; /* Number of attributes in the element */
- int oldi; /* Index of existing attribute */
- char *my_value; /* Cleaned value text */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Initialise */
- oldattr = NULL;
-
-/* Clean the value text. */
- my_value = CleanText( value, status );
-
-/* Create a new XmlAttribute. */
- attr = NewAttribute( name, my_value, prefix, status );
-
-/* Free the memory */
- my_value = astFree( my_value );
-
-/* If OK, indicate that the attribute is owned by the element. */
- if( astOK ) {
- ( (AstXmlObject *) attr )->parent = (AstXmlParent *) this;
-
-/* Save the number of attributes currently stored in the element. */
- nattr = ( this->attrs ) ? this->nattr : 0;
-
-/* Search the existing attributes to see if an attribute with the given
- name and prefix already exists. */
- oldi = -1;
- for( i = 0; i < nattr; i++ ) {
- oldattr = this->attrs[ i ];
- if( !strcmp( oldattr->name, attr->name ) ) {
- if( !oldattr->prefix && !attr->prefix ) {
- oldi = i;
- break;
- } else if( oldattr->prefix && attr->prefix &&
- !strcmp( oldattr->prefix, attr->prefix ) ){
- oldi = i;
- break;
- }
- }
- }
-
-/* If there is an existing attribute with the same name and prefix,
- replace the old attribute with the new one created above. */
- if( oldi > -1 ){
- ((AstXmlObject *)oldattr)->parent = NULL;
- oldattr = astXmlAnnul( oldattr );
- this->attrs[ oldi ] = attr;
-
-/* Otherwise, attempt to extend the array to hold an extra attribute. */
- } else {
- this->attrs = astGrow( this->attrs, nattr + 1,
- sizeof( AstXmlAttribute * ) );
-
-/* Check all has gone OK. */
- if( astOK ) {
-
-/* Store the attribute pointer in the array of attribute pointers. */
- this->attrs[ nattr ] = attr;
-
-/* Increment the number of content items in this element */
- this->nattr = nattr + 1;
-
- }
- }
- }
-}
-
-void astXmlAddCDataSection_( AstXmlElement *this, const char *text, int *status ){
-/*
-*+
-* Name:
-* astXmlAddCDataSection
-
-* Purpose:
-* Create a new XmlCDataSection and add it to an XmlElement.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlAddCDataSection( AstXmlElement *this, const char *text )
-
-* Description:
-* This function creates a new XmlCDataSection structure representing
-* an unparsed character data (CDATA) section, and adds it into an
-* existing element.
-
-* Parameters:
-* this
-* A pointer to the element to be modified.
-* text
-* Pointer to a null terminated string containing the character data.
-
-*-
-*/
-
-/* Local Variables: */
- AstXmlCDataSection *new; /* Pointer to new structure */
- char *my_text; /* Cleaned text */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Allocate space for the new structure. */
- new = (AstXmlCDataSection *) astMalloc( sizeof( AstXmlCDataSection ) );
-
-/* Clean the text. */
- my_text = CleanText( text, status );
-
-/* Initialise it. */
- InitXmlCDataSection( new, AST__XMLCDATA, my_text, status );
-
-/* Free the memory */
- my_text = astFree( my_text );
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) {
- new = astXmlDelete( new );
-
-/* Otherwise, add the content item to the element. */
- } else {
- AddContent( (AstXmlParent *) this, 0, (AstXmlContentItem *) new, status );
- }
-}
-
-void astXmlAddCharData_( AstXmlParent *this, int where, const char *text, int *status ){
-/*
-*+
-* Name:
-* astXmlAddCharData
-
-* Purpose:
-* Create a new XmlCharData and add it to an XmlElement or XmlDocument.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlAddCharData( AstXmlParent *this, int where, const char *text )
-
-* Description:
-* This function creates a new XmlCharData structure representing
-* parsed character data, and adds it into an existing element or
-* document.
-
-* Parameters:
-* this
-* Pointer to the element or document to be modified.
-* where
-* Ignored if "this" is an XmlElement pointer. Otherwise, "where"
-* indicates where the item should be added to the document:
-* 1 - In the prologue, after the XML declaration but before the DTD.
-* 2 - In the prologue, after the DTD but before the root element.
-* 3 - In the epilogue, after the root element.
-* text
-* Pointer to a null terminated string containing the character data.
-* If "this" is a document, the text must consist entirely of white
-* space.
-
-*-
-*/
-
-/* Local Variables: */
- AstXmlCharData *new; /* Pointer to the new structure */
- char *my_text; /* Pointer to cleaned text */
- char *c; /* Pointer to next character */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Initialise */
- new = NULL;
-
-/* Clean the text by replacing "\r\n" by "\n". */
- my_text = CleanText( text, status );
-
-/* See if the text is all white. */
- c = my_text - 1;
- while( *(++c) && isspace( *c ) );
-
-/* If the string contains a non-white character, allocate memory for
- a XmlBlack structure, and initialise it to hold the supplied text.
- Otherwise, allocate memory for a XmlWhite structure, and initialise it
- to hold the supplied text. */
- if( *c ) {
- if( astXmlCheckType( this, AST__XMLDOC ) ) {
- astError( AST__XMLCM, "astXmlAddCharData(xml): Illegal attempt "
- "to add non-white character data to the prologue or "
- "epilogue of an XML document: \"%s\".", status, my_text );
- } else {
- new = (AstXmlCharData *) astMalloc( sizeof( AstXmlBlack ) );
- InitXmlBlack( (AstXmlBlack *) new, AST__XMLBLACK, my_text, status );
- }
-
- } else {
- new = (AstXmlCharData *) astMalloc( sizeof( AstXmlWhite ) );
- InitXmlWhite( (AstXmlWhite *) new, AST__XMLWHITE, my_text, status );
- }
-
-/* Free the memory holding the cleaned text */
- my_text = astFree( my_text );
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) {
- new = astXmlDelete( new );
-
-/* Otherwise, add the content item to the element. */
- } else {
- AddContent( this, where, (AstXmlContentItem *) new, status );
- }
-}
-
-void astXmlAddComment_( AstXmlParent *this, int where, const char *text, int *status ){
-/*
-*+
-* Name:
-* astXmlAddComment
-
-* Purpose:
-* Create a new XmlComment and add it to an XmlElement or XmlDocument.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlAddComment( AstXmlParent *this, int where, const char *text )
-
-* Description:
-* This function creates a new XmlComment structure representing
-* an XML comment, and adds it into an existing element or document.
-
-* Parameters:
-* this
-* Pointer to the element or document to be modified.
-* where
-* Ignored if "this" is an XmlElement pointer. Otherwise, "where"
-* indicates where the item should be added to the document:
-* 1 - In the prologue, after the XML declaration but before the DTD.
-* 2 - In the prologue, after the DTD but before the root element.
-* 3 - In the epilogue, after the root element.
-* text
-* Pointer to a null terminated string containing the comment text.
-
-*-
-*/
-
-/* Local Variables: */
- AstXmlComment *new; /* Pointer to the new structure */
- char *my_text; /* Cleaned text */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Allocate space for the new structure. */
- new = (AstXmlComment *) astMalloc( sizeof( AstXmlComment ) );
-
-/* Clean the text. */
- my_text = CleanText( text, status );
-
-/* Initialise it. */
- InitXmlComment( new, AST__XMLCOM, my_text, status );
-
-/* Free the memory */
- my_text = astFree( my_text );
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) {
- new = astXmlDelete( new );
-
-/* Otherwise, add the content item to the element. */
- } else {
- AddContent( this, where, (AstXmlContentItem *) new, status );
- }
-
-}
-
-AstXmlElement *astXmlAddElement_( AstXmlElement *this, const char *name,
- const char *prefix, int *status ){
-/*
-*+
-* Name:
-* astXmlAddElement
-
-* Purpose:
-* Create a new empty XmlElement and adds it to an XmlElement.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlElement *astXmlAddElement( AstXmlElement *this, const char *name,
-* const char *prefix )
-
-* Description:
-* This function creates a new XmlElement structure representing an
-* empty XML element with the given name and namespace prefix, and
-* adds it into an existing element.
-
-* Parameters:
-* this
-* A pointer to the element to be modified. This may be NULL.
-* name
-* The name for the element.
-* prefix
-* The namespace prefix for the element. May be NULL or blank, in
-* which case any prefix at the start of "name" is used.
-
-* Returned Value:
-* A pointer to the new structure is returned. This pointer should be
-* freed using astXmlAnnul when no longer needed.
-
-* Notes:
-* - A NULL pointer is returned if the inherited status value
-* indicates an error has occurred on entry, or if this function
-* should fail for any reason.
-*-
-*/
-
-/* Local Variables: */
- AstXmlElement *new; /* The returned pointer */
-
-/* Initialise */
- new = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return new;
-
-/* Allocate space for the new structure. */
- new = (AstXmlElement *) astMalloc( sizeof( AstXmlElement ) );
-
-/* Initialise it. */
- InitXmlElement( new, AST__XMLELEM, name, prefix, status );
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) {
- new = astXmlDelete( new );
-
-/* Otherwise, add the content item to the element. */
- } else {
- AddContent( (AstXmlParent *) this, 0, (AstXmlContentItem *) new, status );
- }
-
-/* Return the result. */
- return new;
-
-}
-
-void astXmlAddPI_( AstXmlParent *this, int where, const char *target, const char *text, int *status ){
-/*
-*+
-* Name:
-* astXmlAddPI
-
-* Purpose:
-* Create a new XmlPI and add it to an element or document.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlAddPI( AstXmlParent *this, int where, const char *target,
-* const char *text )
-
-* Description:
-* This function creates a new XmlPI structure representing an
-* XML "programming instruction", and adds it into an existing element
-* or document.
-
-* Parameters:
-* this
-* Pointer to the element or document to be modified. This should
-* be a pointer to an XmlElement or an XmlDocument.
-* where
-* Ignored if "this" is an XmlElement pointer. Otherwise, "where"
-* indicates where the PI should be added to the document:
-* 1 - In the prologue, after the XML declaration but before the DTD.
-* 2 - In the prologue, after the DTD but before the root element.
-* 3 - In the epilogue, after the root element.
-* target
-* Pointer to a null terminated string containing the PI target.
-* text
-* Pointer to a null terminated string containing the PI text.
-
-*-
-*/
-
-/* Local Variables: */
- AstXmlPI *new; /* Pointer to the new structure */
- char *my_text; /* Cleaned text */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Allocate space for the new structure. */
- new = (AstXmlPI *) astMalloc( sizeof( AstXmlPI ) );
-
-/* Clean the text. */
- my_text = CleanText( text, status );
-
-/* Initialise it. */
- InitXmlPI( new, AST__XMLPI, target, my_text, status );
-
-/* Free the memory */
- my_text = astFree( my_text );
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) {
- new = astXmlDelete( new );
-
-/* Otherwise, add the content item to the element. */
- } else {
- AddContent( this, where, (AstXmlContentItem *) new, status );
- }
-}
-
-void astXmlAddURI_( AstXmlElement *this, const char *prefix, const char *uri, int *status ){
-/*
-*+
-* Name:
-* astXmlAddURI
-
-* Purpose:
-* Add a namespace prefix definition to an XmlElement, or change the
-* default namespace.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlAddURI( AstXmlElement *this, const char *prefix,
-* const char *uri )
-
-* Description:
-* This function adds a namespace prefix definition to a specified
-* XmlElement, or changes the default namespace. If the suppliedprefix
-* is already defined in the element, the associated URI is changed to
-* the supplied URI.
-
-* Parameters:
-* this
-* The pointer to the element to be modified.
-* prefix
-* Pointer to a null terminated string containing the namespace
-* prefix. If this is NULL or blank, then the supplied URI is used
-* as the default namespace for this element and all child elements
-* (except for child elements which define their own default
-* namespace).
-* uri
-* Pointer to a null terminated string containing the namespace URI.
-* If this is NULL or blank, and "prefix" is also NULL or blank, then
-* this has the same effect of there being no default namespace within
-* the supplied element.
-*-
-*/
-
-/* Local Variables: */
- AstXmlNamespace *ns; /* The new namespace definition */
- AstXmlNamespace *oldns; /* The existing namespace definition */
- int i; /* Loop index */
- int nc; /* Length of namespace prefix */
- int nnspref; /* Number of namespace defintions in the element */
- int oldi; /* Index of existing attribute */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Initialise */
- oldns = NULL;
-
-/* Store the used length of the namespace prefix. */
- nc = prefix ? astChrLen( prefix ) : 0;
-
-/* If no namespace prefix has been supplied, just change the default
- namespace URI. */
- if( !nc ) {
- if( uri ) {
- this->defns = astStore( this->defns, uri, strlen( uri ) + 1 );
- } else {
- this->defns = astStore( this->defns, "", 1 );
- }
-
-/* Otherwise, add the namespace definition to the element. */
- } else {
-
-/* Create a new XmlNamespace. */
- ns = NewNamespace( prefix, uri, status );
-
-/* If OK, indicate that the namespace is owned by the element. */
- if( astOK ) {
- ( (AstXmlObject *) ns )->parent = (AstXmlParent *) this;
-
-/* Save the number of namespace definitions currently stored in the element. */
- nnspref = ( this->nsprefs ) ? this->nnspref : 0;
-
-/* Search the existing prefixes to see if a namespace with the given
- prefix already exists. */
- oldi = -1;
- for( i = 0; i < nnspref; i++ ) {
- oldns = this->nsprefs[ i ];
- if( !strcmp( oldns->prefix, ns->prefix ) ) {
- oldi = i;
- break;
- }
- }
-
-/* If there is an existing namespace with the same prefix, replace the old
- namespace with the new one created above. */
- if( oldi > -1 ){
- ((AstXmlObject *)oldns)->parent = NULL;
- oldns = astXmlAnnul( oldns );
- this->nsprefs[ oldi ] = ns;
-
-/* Otherwise, attempt to extend the array to hold an extra namespace definition. */
- } else {
- this->nsprefs = astGrow( this->nsprefs, nnspref + 1,
- sizeof( AstXmlNamespace * ) );
-
-/* Check all has gone OK. */
- if( astOK ) {
-
-/* Store the Namespace pointer in the array of Namespace pointers. */
- this->nsprefs[ nnspref ] = ns;
-
-/* Increment the number of namespaces in this element */
- this->nnspref = nnspref + 1;
- }
- }
- }
- }
-}
-
-void *astXmlAnnul_( AstXmlObject *this, int *status ){
-/*
-*+
-* Name:
-* astXmlAnnul
-
-* Purpose:
-* Free the resources used by an XmlObject.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void *astXmlAnnul( AstXmlObject *this )
-
-* Description:
-* This function frees the resources used to hold the XmlObject, together
-* with any child objects contained within the supplied XmlObject. A NULL
-* pointer is always returned. If the supplied object is still in use
-* (that is, if its parent XmlElement still exists) then the resources
-* are not freed, and a copy of the supplied pointer is returned.
-
-* Parameters:
-* this
-* pointer to the XmlObject to be freed.
-
-* Returned Value:
-* A NULL pointer, or the supplied pointer if the XmlObject is still
-* in use.
-
-* Notes:
-* - This function attempts to execute even if an error has already
-* occurred.
-*-
-*/
-
-/* Return if a NULL pointer has been suppplied. */
- if( !this ) return NULL;
-
-/* Return the supplied pointer if the objects parent still exists. */
- if( this->parent &&
- astXmlCheckType( this->parent, AST__XMLPAR ) ) return this;
-
-#ifdef DEBUG
-/* Remove the supplied object from the list of currently active XmlObjects. */
- RemoveObjectFromList( this );
-#endif
-
-/* Clean the objects contents, and free the memory holding the XmlObject. */
- CleanXml( this, this->type, status );
- astFree( this );
-
-/* Return a NULL pointer. */
- return NULL;
-}
-
-void *astXmlAnnulTree_( AstXmlObject *this, int *status ){
-/*
-*+
-* Name:
-* astXmlAnnulTree
-
-* Purpose:
-* Free the resources used by a tree of XmlObjects.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void *astXmlAnnulTree( AstXmlObject *this )
-
-* Description:
-* This function finds the head of the tree containing the supplied
-* XmlObject (either an XmlElement or an XmlDocument), and frees the
-* resources associated with all members of the tree. A NULL pointer
-* is always returned.
-
-* Parameters:
-* this
-* Pointer to a member of the tree of XmlObjects to be freed.
-
-* Returned Value:
-* A NULL pointer.
-
-* Notes:
-* - This function attempts to execute even if an error has already
-* occurred.
-*-
-*/
-
-/* Return if a NULL pointer has been suppplied. */
- if( !this ) return NULL;
-
-/* Find the root and annull it. This will free all children (i.e.
- the entire tree). */
- return astXmlAnnul( astXmlGetRoot( this ) );
-}
-
-AstXmlObject *astXmlCopy_( AstXmlObject *this, int *status ) {
-/*
-*+
-* Name:
-* astXmlCopy
-
-* Purpose:
-* Produce a deep copy of a supplied XmlObject.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlObject *astXmlCopy( AstXmlObject *this )
-
-* Description:
-* This function returns a pointer to a deep copy of the supplied
-* XmlObject.
-
-* Parameters:
-* this
-* Pointer to the XmlObject to copy.
-
-* Returned Value:
-* Pointer to the new copy.
-
-* Notes:
-* - NULL is returned if NULL pointer is supplied.
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-
-/* Local Variables: */
- AstXmlAttribute *attr;
- AstXmlBlack *black;
- AstXmlCDataSection *cdata;
- AstXmlComment *comm;
- AstXmlDTDec *dtd;
- AstXmlDeclPI *dec;
- AstXmlDocument *doc, *newdoc;
- AstXmlElement *elem, *newelem;
- AstXmlNamespace *ns;
- AstXmlObject *new;
- AstXmlPI *pi;
- AstXmlPrologue *pro, *newpro;
- AstXmlWhite *white;
- int i, type;
-
-/* Initialise */
- new = NULL;
-
-/* Check the global error status. */
- if( !astOK || !this ) return new;
-
-/* Initialise a new XmlObject of the required class, and copy any
- sub-objects. */
- type = this->type;
- if( type == AST__XMLELEM ){
- elem = (AstXmlElement *) this;
- new = astMalloc( sizeof( AstXmlElement ) );
- InitXmlElement( (AstXmlElement *) new, AST__XMLELEM,
- elem->name, elem->prefix, status );
-
- newelem = (AstXmlElement *) new;
-
- newelem->attrs = astMalloc( sizeof( AstXmlAttribute *) * (size_t)elem->nattr );
- newelem->nattr = elem->nattr;
- for( i = 0; i < elem->nattr; i++ ) {
- newelem->attrs[ i ] = (AstXmlAttribute *) astXmlCopy( elem->attrs[ i ] );
- ((AstXmlObject *) newelem->attrs[ i ])->parent = (AstXmlParent *) newelem;
- }
-
- newelem->items = astMalloc( sizeof( AstXmlContentItem *) * (size_t)elem->nitem );
- newelem->nitem = elem->nitem;
- for( i = 0; i < elem->nitem; i++ ) {
- newelem->items[ i ] = (AstXmlContentItem *) astXmlCopy( elem->items[ i ] );
- ((AstXmlObject *) newelem->items[ i ])->parent = (AstXmlParent *) newelem;
- }
-
- newelem->nsprefs = astMalloc( sizeof( AstXmlNamespace *) * (size_t)elem->nnspref );
- newelem->nnspref = elem->nnspref;
- for( i = 0; i < elem->nnspref; i++ ) {
- newelem->nsprefs[ i ] = (AstXmlNamespace *) astXmlCopy( elem->nsprefs[ i ] );
- ((AstXmlObject *) newelem->nsprefs[ i ])->parent = (AstXmlParent *) newelem;
- }
-
- if( elem->defns ) {
- newelem->defns = astStore( NULL, elem->defns,
- strlen( elem->defns ) + 1 );
- }
-
- newelem->complete = elem->complete;
-
-
- } else if( type == AST__XMLATTR ){
- attr = (AstXmlAttribute *) this;
- new = astMalloc( sizeof( AstXmlAttribute ) );
- InitXmlAttribute( (AstXmlAttribute *) new, AST__XMLATTR,
- attr->name, attr->value, attr->prefix, status );
-
- } else if( type == AST__XMLBLACK ){
- black = (AstXmlBlack *) this;
- new = astMalloc( sizeof( AstXmlBlack ) );
- InitXmlBlack( (AstXmlBlack *) new, AST__XMLBLACK,
- black->text, status );
-
- } else if( type == AST__XMLWHITE ){
- white = (AstXmlWhite *) this;
- new = astMalloc( sizeof( AstXmlWhite ) );
- InitXmlWhite( (AstXmlWhite *) new, AST__XMLWHITE,
- white->text, status );
-
- } else if( type == AST__XMLCDATA ){
- cdata = (AstXmlCDataSection *) this;
- new = astMalloc( sizeof( AstXmlCDataSection ) );
- InitXmlCDataSection( (AstXmlCDataSection *) new, AST__XMLCDATA,
- cdata->text, status );
-
- } else if( type == AST__XMLCOM ){
- comm = (AstXmlComment *) this;
- new = astMalloc( sizeof( AstXmlComment ) );
- InitXmlComment( (AstXmlComment *) new, AST__XMLCOM,
- comm->text, status );
-
- } else if( type == AST__XMLPI ){
- pi = (AstXmlPI *) this;
- new = astMalloc( sizeof( AstXmlPI ) );
- InitXmlPI( (AstXmlPI *) new, AST__XMLPI, pi->target, pi->text, status );
-
- } else if( type == AST__XMLNAME ){
- ns = (AstXmlNamespace *) this;
- new = astMalloc( sizeof( AstXmlNamespace ) );
- InitXmlNamespace( (AstXmlNamespace *) new, AST__XMLNAME, ns->prefix,
- ns->uri, status );
-
- } else if( type == AST__XMLDOC ){
- doc = (AstXmlDocument *) this;
- new = astMalloc( sizeof( AstXmlDocument ) );
- InitXmlDocument( (AstXmlDocument *) new, AST__XMLDOC, status );
-
- newdoc = (AstXmlDocument *) new;
-
- if( doc->prolog ) {
- newdoc->prolog = (AstXmlPrologue *) astXmlCopy( doc->prolog );
- ((AstXmlObject *) newdoc->prolog)->parent = (AstXmlParent *) newdoc;
- }
-
- if( doc->root ) {
- newdoc->root = (AstXmlElement *) astXmlCopy( doc->root );
- ((AstXmlObject *) newdoc->root)->parent = (AstXmlParent *) newdoc;
- }
-
- newdoc->epilog = astMalloc( sizeof( AstXmlMiscItem *) * (size_t)doc->nepi );
- newdoc->nepi = doc->nepi;
- for( i = 0; i < doc->nepi; i++ ) {
- newdoc->epilog[ i ] = (AstXmlMiscItem *) astXmlCopy( doc->epilog[ i ] );
- ((AstXmlObject *) newdoc->epilog[ i ])->parent = (AstXmlParent *) newdoc;
- }
-
- newdoc->current = NULL;
-
- } else if( type == AST__XMLPRO ){
- pro = (AstXmlPrologue *) this;
- new = astMalloc( sizeof( AstXmlPrologue ) );
- InitXmlPrologue( (AstXmlPrologue *) new, AST__XMLPRO, status );
-
- newpro = (AstXmlPrologue *) new;
-
- if( pro->xmldecl ) {
- newpro->xmldecl = (AstXmlDeclPI *) astXmlCopy( pro->xmldecl );
- ((AstXmlObject *) newpro->xmldecl)->parent = (AstXmlParent *) newpro;
- }
-
- if( pro->dtdec ) {
- newpro->dtdec = (AstXmlDTDec *) astXmlCopy( pro->dtdec );
- ((AstXmlObject *) newpro->dtdec)->parent = (AstXmlParent *) newpro;
- }
-
- newpro->misc1 = astMalloc( sizeof( AstXmlMiscItem *) * (size_t)pro->nmisc1 );
- newpro->nmisc1 = pro->nmisc1;
- for( i = 0; i < pro->nmisc1; i++ ) {
- newpro->misc1[ i ] = (AstXmlMiscItem *) astXmlCopy( pro->misc1[ i ] );
- ((AstXmlObject *) newpro->misc1[ i ])->parent = (AstXmlParent *) newpro;
- }
-
- newpro->misc2 = astMalloc( sizeof( AstXmlMiscItem *) * (size_t)pro->nmisc2 );
- newpro->nmisc2 = pro->nmisc2;
- for( i = 0; i < pro->nmisc2; i++ ) {
- newpro->misc2[ i ] = (AstXmlMiscItem *) astXmlCopy( pro->misc2[ i ] );
- ((AstXmlObject *) newpro->misc2[ i ])->parent = (AstXmlParent *) newpro;
- }
-
- } else if( type == AST__XMLDEC ){
- dec = (AstXmlDeclPI *) this;
- new = astMalloc( sizeof( AstXmlDeclPI ) );
- InitXmlDeclPI( (AstXmlDeclPI *) new, AST__XMLDEC, dec->text, status );
-
- } else if( type == AST__XMLDTD ){
- dtd = (AstXmlDTDec *) this;
- new = astMalloc( sizeof( AstXmlDTDec ) );
- InitXmlDTDec( (AstXmlDTDec *) new, AST__XMLDTD, dtd->name,
- dtd->external, dtd->internal, status );
-
- } else if( astOK ) {
- astError( AST__INTER, "CopyXml: Invalid object type (%d) supplied "
- "(internal AST programming error).", status, type );
- }
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) new = astXmlDelete( new );
-
-/* Return the result. */
- return new;
-}
-
-const char *astXmlFormat_( AstXmlObject *this, int *status ) {
-/*
-*+
-* Name:
-* astXmlFormat
-
-* Purpose:
-* Converts an XmlObject into a character string.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *astXmlFormat( AstXmlObject *this )
-
-* Description:
-* This function returns a pointer to a dynamically allocated string
-* containing a textual representation of the supplied XmlObject.
-
-* Parameters:
-* this
-* Pointer to the XmlObject to format.
-
-* Returned Value:
-* Pointer to a null terminated string holding the formated XmlObject.
-* This string should be freed when no longer needed using astFree.
-
-* Notes:
-* - No newlines or indentation strings are added to the returned string.
-* - NULL is returned if NULL pointer is supplied.
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
- return Format( this, -1, status );
-}
-
-const char *astXmlGetAttributeValue_( AstXmlElement *this, const char *name, int *status ){
-/*
-*+
-* Name:
-* astXmlGetAttributeValue
-
-* Purpose:
-* Return a pointer to a string holding the value of a named attribute.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *astXmlGetAttributeValue( AstXmlElement *this, const char *name )
-
-* Description:
-* This function returns a pointer to a constant string holding the
-* value of a named attribute of a supplied element. If the element
-* does not have the named attribute, a NULL pointer is returned but
-* no error is reported.
-
-* Parameters:
-* this
-* The pointer to the XmlElement.
-* name
-* Pointer to a string holding the name of the attribute. The name
-* may be preceded with a "prefix:" string, in which case the
-* prefix will also be matched. If no prefix is included, the first
-* attribute with the specified name is returned, regardless of
-* its prefix.
-
-* Returned Value:
-* Pointer to a string holding the value of the attribute within the
-* supplied element, or NULL if the attribute was not found.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-/* Local Variables: */
- const char *result; /* Returned pointer */
- AstXmlAttribute *attr; /* Pointer to the attribute */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
-/* Find the attribute. */
- attr = FindAttribute( this, name, status );
-
-/* Get its value. */
- if( attr ) result = attr->value;
-
-/* Return the result. */
- return result;
-}
-
-AstXmlContentItem *astXmlGetItem_( AstXmlElement *this, int item, int *status ){
-/*
-*+
-* Name:
-* astXmlGetItem
-
-* Purpose:
-* Return a specified item of the content of an element.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlContentItem *astXmlGetItem( AstXmlElement *this, int item )
-
-* Description:
-* This function returns a pointer to an item of the content of the
-* specified element.
-
-* Parameters:
-* this
-* The pointer to the XmlElement.
-* item
-* The index of the required item, in the range zero to "nitem-1",
-* where "nitem" is the number of items in the element as returned
-* by astXmlGetNitem. An error is reported if the specified index
-* is out of bounds.
-
-* Returned Value:
-* A pointer to the requested item.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-/* Local Variables: */
- AstXmlContentItem *result; /* The returned pointer */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
-/* Report an error if the supplie dindex is bad. */
- if( this->nitem == 0 ) {
- astError( AST__XMLIT, "astXmlGetItem(xml): The supplied item index (%d) "
- "is out of bounds. The supplied XmlObject has no content.", status,
- item );
-
- } else if( item < 0 || item >= this->nitem ) {
- astError( AST__XMLIT, "astXmlGetItem(xml): The supplied item index (%d) "
- "is out of bounds. Should be in the range 0 to %d.", status,
- item, this->nitem-1 );
- } else {
- result = this->items[ item ];
- }
-
-/* Return the result. */
- return result;
-}
-
-const char *astXmlGetName_( AstXmlObject *this, int *status ){
-/*
-*+
-* Name:
-* astXmlGetName
-
-* Purpose:
-* Return a pointer to a string holding the name of an XmlObject.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *astXmlGetName( AstXmlObject *this )
-
-* Description:
-* This function returns a pointer to a constant string holding the
-* name associated with an XmlObject. For elements and attributes, the
-* "name" value is returned. For PI elements, the "target" value is
-* returned. For namespace definitions, the "prefix" value is returned.
-* An error is reported if the supplied XmlObject is of any other class.
-
-* Parameters:
-* this
-* The pointer to the XmlObject.
-
-* Returned Value:
-* Pointer to the name string within the XML object.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-/* Local Variables: */
- const char *result; /* Returned pointer */
- int type; /* Object type */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
-/* Return the relevant component of the structure, depending on its type. */
- type = this->type;
- if( type == AST__XMLELEM ){
- result = ( (AstXmlElement *) this )->name;
-
- } else if( type == AST__XMLATTR ){
- result = ( (AstXmlAttribute *) this )->name;
-
- } else if( type == AST__XMLPI ){
- result = ( (AstXmlPI *) this )->target;
-
- } else if( type == AST__XMLNAME ){
- result = ( (AstXmlNamespace *) this )->prefix;
-
- } else {
- astError( AST__INTER, "astXmlGetName: Inappropriate object type (%d) supplied "
- "(internal AST programming error).", status, type );
- }
-
-/* Return the result. */
- return result;
-}
-
-int astXmlGetNattr_( AstXmlElement *this, int *status ){
-/*
-*+
-* Name:
-* astXmlGetNattr
-
-* Purpose:
-* Return the number of attributes held by an element.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* int astXmlGetNattr( AstXmlElement *this )
-
-* Description:
-* This function returns the number of attributes held by an element.
-
-* Parameters:
-* this
-* The pointer to the XmlElement.
-
-* Returned Value:
-* The number of attributes held by the supplied element.
-
-* Notes:
-* - Zero is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-/* Check the global error status. */
- if( !astOK ) return 0;
-
-/* Return the result. */
- return ( this->attrs ) ? this->nattr : 0;
-}
-
-int astXmlGetNitem_( AstXmlElement *this, int *status ){
-/*
-*+
-* Name:
-* astXmlGetNitem
-
-* Purpose:
-* Return the number of items within the content of an element.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* int astXmlGetNitem( AstXmlElement *this )
-
-* Description:
-* This function returns the number of items within the content of an
-* XmlElement.
-
-* Parameters:
-* this
-* The pointer to the XmlElement.
-
-* Returned Value:
-* The number of items in the content of the supplied element.
-
-* Notes:
-* - Zero is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-/* Check the global error status. */
- if( !astOK ) return 0;
-
-/* Return the result. */
- return this->nitem;
-}
-
-AstXmlParent *astXmlGetParent_( AstXmlObject *this, int *status ){
-/*
-*+
-* Name:
-* astXmlGetParent
-
-* Purpose:
-* Return a pointer to the object which contains the supplied XmlObject.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlParent *astXmlGetParent( AstXmlObject *this )
-
-* Description:
-* This function returns a pointer to the XmlParent object (either an
-* XmlElement or an XmlDocument) which contains the specified XmlObject.
-* The object can be a content item (an element, a comment, a CDATA
-* section, a PI, or character data) in which case the enclosing
-* XmlElement is returned, or an attribute or namespace definition in
-* which case the XmlElement to which object refers is returned.
-* If "this" is the root element of a document, a pointer to the
-* XmlDocument is returned.
-
-
-* Parameters:
-* this
-* The pointer to check.
-
-* Returned Value:
-* Pointer to the parent, or NULL if the object does not have a parent.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-/* Check the global error status. */
- if( !astOK ) return NULL;
-
-/* Return the result. */
- return this->parent;
-}
-
-AstXmlObject *astXmlGetRoot_( AstXmlObject *this, int *status ){
-/*
-*+
-* Name:
-* astXmlGetRoot
-
-* Purpose:
-* Return a pointer to the root XmlObject which contains the supplied
-* XmlObject.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlObject *astXmlGetRoot( AstXmlObject *this )
-
-* Description:
-* This function returns a pointer to the XmlObject which is the root of
-* the tree containing the specified XmlObject. A pointer to the
-* supplied XmlObject is returned if it has no parent.
-
-* Parameters:
-* this
-* The pointer to check.
-
-* Returned Value:
-* Pointer to the root XmlObject, or a copy of the supplied pointer if
-* the supplied XmlObject is the root.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-/* Local Variables: */
- AstXmlObject *result;
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
-/* If "this" is a document, check it has no parent. If not, return a
- pointer ot it. */
- if( astXmlCheckType( this, AST__XMLDOC ) ) {
- if( this->parent ) {
- astError( AST__INTER, "astXmlGetRoot(xml): An XmlDocument has a "
- "non-null parent of type %ld (internal AST programming "
- "error).", status, this->type );
- } else {
- result = (AstXmlObject *) this;
- }
-
-/* Otherwise... */
- } else if( this->parent ) {
- result = astXmlGetRoot( this->parent );
-
- } else {
- result = this;
- }
-
-/* Return the result. */
- return result;
-}
-
-const char *astXmlGetTag_( AstXmlObject *this, int opening, int *status ){
-/*
-*+
-* Name:
-* astXmlGetTag
-
-* Purpose:
-* Returns a string holding an XML tag describing the given XmlObject.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *astXmlGetTag( AstXmlObject *this, int opening )
-
-* Description:
-* This function returns a pointer to a static string containing an
-* XML tag describing the given XmlObject.
-
-* Parameters:
-* this
-* Pointer to the XmlObject.
-* opening
-* Indicates which tag is to be returned; the start tag or the end
-* tag. If non-zero the start tag is returned. Otherwise, the
-* end tag is returned. If the supplied XmlObject has no end
-* tag (i.e. if it is an empty element, or if it is not an element),
-* then NULL is returned but no error is reported.
-
-* Returned Value:
-* Pointer to a null terminated string holding the tag. If the tag
-* exceeds 200 characters, only the first 197 characters are returned
-* and "..." is appended to the end.
-
-* Notes:
-* - Subsequent invocations of this function will over-write the
-* buffer which used to hold the returned string.
-* - Empty elements are represented as an start tag of the form <.../>,
-* with no corresponding end tag.
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- char *result; /* The returned pointer */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
-/* If needed, get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* Get a dynamic string holding the formatted tag. */
- result = FormatTag( this, opening, status );
-
-/* If OK, copy the result into the static buffer. */
- gettag_buff[ 0 ] = 0;
- if( result ) {
- if( astOK ) {
-
- if( strlen( result ) > AST__XML_GETTAG_BUFF_LEN ) {
- strncpy( gettag_buff, result, AST__XML_GETTAG_BUFF_LEN -3 );
- strcpy( gettag_buff + AST__XML_GETTAG_BUFF_LEN - 3, "..." );
- } else {
- strncpy( gettag_buff, result, AST__XML_GETTAG_BUFF_LEN );
- }
-
- gettag_buff[ AST__XML_GETTAG_BUFF_LEN ] = 0;
- astFree( result );
- result = gettag_buff;
- } else {
- result = astFree( result );
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-const char *astXmlGetType_( AstXmlObject *this, int *status ){
-/*
-*+
-* Name:
-* astXmlGetType
-
-* Purpose:
-* Returns a string holding the type of the given XmlObject.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *astXmlGetType( AstXmlObject *this )
-
-* Description:
-* This function returns a pointer to a static string containing the
-* type of the given XmlObject.
-
-* Parameters:
-* this
-* Pointer to the XmlObject.
-
-* Returned Value:
-* Pointer to a null terminated string holding the type string.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-/* Local Variables: */
- const char *result; /* The returned pointer */
- int type; /* Element type */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
- type = this->type;
- if( type == AST__XMLELEM ) {
- result = "element";
-
- } else if( type == AST__XMLATTR ) {
- result = "attribute";
-
- } else if( type == AST__XMLCDATA ) {
- result = "CDATA section";
-
- } else if( type == AST__XMLCOM ) {
- result = "comment";
-
- } else if( type == AST__XMLPI ) {
- result = "processing instruction";
-
- } else if( type == AST__XMLNAME ) {
- result = "namespace";
-
- } else if( type == AST__XMLDOC ) {
- result = "document";
-
- } else if( type == AST__XMLPRO ) {
- result = "prologue";
-
- } else if( type == AST__XMLDEC ) {
- result = "XML delaration PI";
-
- } else if( type == AST__XMLDTD ) {
- result = "DTD";
-
- } else if( type == AST__XMLWHITE ) {
- result = "white-space character data ";
-
- } else if( type == AST__XMLBLACK ) {
- result = "non-blank character data";
-
- } else {
- result = "unknown XML object";
- }
-
-/* Return the result. */
- return result;
-}
-
-const char *astXmlGetURI_( AstXmlObject *this, int *status ){
-/*
-*+
-* Name:
-* astXmlGetURI
-
-* Purpose:
-* Return a pointer to a string holding the namespace URI of an XmlObject.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *astXmlGetURI( AstXmlObject *this )
-
-* Description:
-* This function returns a pointer to a constant string holding the
-* namespace URI associated with an XmlObject. Only attributes,
-* elements and namespaces have associated URIs, so a NULL pointer is
-* returned for any other class of XmlObject. A NULL pointer is also
-* returned if XmlObject does not belong to any namespace, or if it
-* belongs to a unknown namespace (i.e. one for which no URI is
-* available). Any namespace prefix attached to the supplied object is
-* resolved first using any "xmlns" attributes contained in the same
-* element, then using any "xmlns" attributes contained in the parent
-* element, etc.
-
-* Parameters:
-* this
-* The pointer to the XmlObject.
-
-* Returned Value:
-* Pointer to a string holding the namespace URI, or NULL.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-/* Local Variables: */
- const char *prefix; /* Namespace prefix */
- const char *result; /* Returned pointer */
- int type; /* Object type */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
-/* Do each type of object separately. */
- type = this->type;
- if( type == AST__XMLATTR ){
- prefix = ( (AstXmlAttribute *) this )->prefix;
-
-/* Attributes have no default name space. Therefore if there is no prefix,
- return NULL. If there is a prefix, resolve it within the context of
- the attributes parent element. */
- if( prefix ) {
- result = ResolvePrefix( prefix, (AstXmlElement *) this->parent, status );
- }
-
- } else if( type == AST__XMLELEM ){
- prefix = ( (AstXmlElement *) this )->prefix;
-
-/* If there is a prefix, resolve it within the context of this element. */
- if( prefix ) {
- result = ResolvePrefix( prefix, (AstXmlElement *) this, status );
-
-/* Elements do have a default name space. Therefore if there is no prefix,
- return the default name space within the context of this element. */
- } else {
- result = DefaultURI( (AstXmlElement *) this, status );
- }
-
-/* If the supplied object is a namespace, just return the associated URI. */
- } else if( type == AST__XMLNAME ){
- result = ( (AstXmlNamespace *) this )->uri;
-
- }
-
-/* Return the result. */
- return result;
-}
-
-const char *astXmlGetValue_( AstXmlObject *this, int report, int *status ){
-/*
-*+
-* Name:
-* astXmlGetValue
-
-* Purpose:
-* Return a pointer to a string holding the value of an XmlObject.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *astXmlGetValue( AstXmlObject *this, int report )
-
-* Description:
-* This function returns a pointer to a constant string holding the
-* value associated with an XmlObject. For attributes, the attribute value
-* is returned. For PI elements, the "text" value is returned. For
-* namespace definitions, the "URI" value is returned. For character
-* data, the character data is returned. For CDATA sections the "text"
-* value is returned. For comments, the "text" value is returned.
-* If the XmlObject is an element, then a non-NULL value is returned
-* only if the element contains a single content item holding character
-* data. In this case a pointer to the character data is returned.
-* A null value is returned in all other cases (but no error is
-* reported unless "report" is non-zero).
-
-* Parameters:
-* this
-* The pointer to the XmlObject.
-* report
-* Report an error if the supplied XmlObject does not have a value?
-
-* Returned Value:
-* Pointer to a string holding the value of the XML object.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-/* Local Variables: */
- AstXmlContentItem *item;/* Element content */
- const char *result; /* Returned pointer */
- int type; /* Object type */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
-/* Return the relevant component of the structure, depending on its type. */
- type = this->type;
- if( type == AST__XMLATTR ){
- result = ( (AstXmlAttribute *) this )->value;
-
- } else if( type == AST__XMLBLACK ){
- result = ( (AstXmlBlack *) this )->text;
-
- } else if( type == AST__XMLWHITE ){
- result = ( (AstXmlWhite *) this )->text;
-
- } else if( type == AST__XMLCDATA ){
- result = ( (AstXmlCDataSection *) this )->text;
-
- } else if( type == AST__XMLCOM ){
- result = ( (AstXmlComment *) this )->text;
-
- } else if( type == AST__XMLPI ){
- result = ( (AstXmlPI *) this )->text;
-
- } else if( type == AST__XMLNAME ){
- result = ( (AstXmlNamespace *) this )->uri;
-
- } else if( type == AST__XMLELEM ){
- if( astXmlGetNitem( (AstXmlElement *) this ) == 1 ) {
- item = astXmlGetItem( (AstXmlElement *) this, 0 );
- if( astXmlCheckType( item, AST__XMLCHAR ) ) {
- result = astXmlGetValue( item, report );
- }
- }
-
- if( !result && astOK && report ) {
- astError( AST__BADIN, "astRead(xml): Cannot get the value of "
- "element \"<%s>\": its contents are not pure character "
- "data.", status, astXmlGetName( this ) );
- }
-
- } else if( report ) {
- astError( AST__INTER, "astXmlGetValue(xml): Cannot get the value of "
- "an XmlObject of type %d (internal AST programming "
- "error).", status, type );
- }
-
-/* Return the result. */
- return result;
-}
-
-void astXmlInsertElement_( AstXmlElement *this, AstXmlElement *elem, int *status ){
-/*
-*+
-* Name:
-* astXmlInsertElement
-
-* Purpose:
-* Inserts an existing XmlElement into another XmlElement.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlInsertElement( AstXmlElement *this, AstXmlElement *elem )
-
-* Description:
-* This function inserts a given XmlElement "elem" into another given
-* XmlElement "this". An error is reported if "elem" already has a
-* parent.
-
-* Parameters:
-* this
-* A pointer to the element to be modified.
-* elem
-* The element to be inserted into "this".
-
-*-
-*/
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Report AN error if "elem" has already been inserted into
- another element. */
- if( ((AstXmlObject *) elem)->parent ) {
- astError( AST__INTER, "astXmlInsertElement(xml): Cannot insert \"%s\" "
- "into \"%s\" because it already has a parent (\"%s\") "
- "(internal AST programming error).", status,
- astXmlGetTag( elem, 1 ), astXmlGetTag( this, 1 ),
- astXmlGetTag( ((AstXmlObject *) elem)->parent, 1 ) );
-
-/* Otherwise, add the content item to the element. */
- } else {
- AddContent( (AstXmlParent *) this, 0, (AstXmlContentItem *) elem, status );
- }
-}
-
-void astXmlPurge_( AstXmlParent *this, int *status ) {
-/*
-*+
-* Name:
-* astXmlPurge
-
-* Purpose:
-* Remove blank content from a parent object.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlPurge( AstXmlParent *this )
-
-* Description:
-* This function removes all character data containing only whitespace
-* from the supplied document or element. It is recursive, in that it also
-* removes white space from all children elements.
-
-* Parameters:
-* this
-* Pointer to the document or element.
-
-*-
-*/
-
-/* Local Variables: */
- int i; /* Content item index */
- AstXmlContentItem *item; /* Next content item */
- AstXmlMiscItem *misc; /* Nest miscalleneous item */
- AstXmlDocument *doc; /* This document */
- AstXmlPrologue *pro; /* This document prologue */
- AstXmlElement *elem; /* This element */
-
-/* Check the global error status. */
- if( !astOK || !this ) return;
-
-/* If this is a a document.. */
- if( astXmlCheckType( this, AST__XMLDOC ) ) {
- doc = (AstXmlDocument *) this;
- astXmlPurge( doc->prolog );
- astXmlPurge( doc->root );
-
- i = -1;
- while( ++i < doc->nepi ) {
- misc = doc->epilog[ i ];
- if( astXmlCheckType( misc, AST__XMLWHITE ) ) {
- misc = astXmlDelete( misc );
- i--;
- }
- }
-
-/* If this is a prologue.. */
- } else if( astXmlCheckType( this, AST__XMLPRO ) ) {
- pro = (AstXmlPrologue *) this;
-
- i = -1;
- while( ++i < pro->nmisc1 ) {
- misc = pro->misc1[ i ];
- if( astXmlCheckType( misc, AST__XMLWHITE ) ) {
- misc = astXmlDelete( misc );
- i--;
- }
- }
-
- i = -1;
- while( ++i < pro->nmisc2 ) {
- misc = pro->misc2[ i ];
- if( astXmlCheckType( misc, AST__XMLWHITE ) ) {
- misc = astXmlDelete( misc );
- i--;
- }
- }
-
-
-/* If this is an element */
- } else if( astXmlCheckType( this, AST__XMLELEM ) ) {
- elem = (AstXmlElement *) this;
-
- i = -1;
- while( ++i < elem->nitem ) {
- item = elem->items[ i ];
-
- if( astXmlCheckType( item, AST__XMLWHITE ) ) {
- item = astXmlDelete( item );
- i--;
-
- } else if( astXmlCheckType( item, AST__XMLELEM ) ) {
- astXmlPurge( (AstXmlParent *) item );
- }
- }
- }
-}
-
-void astXmlRemoveAttr_( AstXmlElement *this, const char *name,
- const char *prefix, int *status ){
-/*
-*+
-* Name:
-* astXmlRemoveAttr
-
-* Purpose:
-* Removes an attribute from its parent element.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlRemoveAttr( AstXmlElement *this, const char *name,
-* const char *prefix )
-
-* Description:
-* This function removes a named attribute from its parent element.
-
-* Parameters:
-* this
-* The pointer to the element containing the attribute to be removed.
-* name
-* Pointer to a null terminated string containing the attribute name.
-* prefix
-* The namespace prefix for the attribute. May be NULL or blank, in
-* which case any prefix at the start of "name" is used.
-*-
-*/
-
-/* Local Variables: */
- AstXmlAttribute *attr; /* Pointer to temporary attribute structure */
- AstXmlAttribute *oldattr; /* Pointer to existing attribute */
- int i; /* Attribute index */
- int nattr; /* Number of attributes in parent */
- int oldi; /* Indexof existing attribute */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Initialise */
- oldattr = NULL;
-
-/* Create a new XmlAttribute with blank value. */
- attr = NewAttribute( name, "", prefix, status );
- if( astOK ) {
-
-/* Get the number of attributes currently stored in the element. */
- nattr = ( this->attrs ) ? this->nattr : 0;
-
-/* Search the existing attributes to see if an attribute with the given
- name and prefix already exists. */
- oldi = -1;
- for( i = 0; i < nattr; i++ ) {
- oldattr = this->attrs[ i ];
- if( !strcmp( oldattr->name, attr->name ) ) {
- if( !oldattr->prefix && !attr->prefix ) {
- oldi = i;
- break;
- } else if( oldattr->prefix && attr->prefix &&
- !strcmp( oldattr->prefix, attr->prefix ) ){
- oldi = i;
- break;
- }
- }
- }
-
-/* If there is an existing attribute with the same name and prefix,
- delete it. */
- if( oldi > -1 ) astXmlDelete( oldattr );
-
-/* Delete the temporary attribute structure. */
- attr = astXmlDelete( attr );
-
- }
-}
-
-void astXmlRemoveItem_( AstXmlContentItem *this, int *status ){
-/*
-*+
-* Name:
-* astXmlRemoveItem
-
-* Purpose:
-* Removes an item of content from its parent element or document.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlRemoveItem( AstXmlContentItem *this )
-
-* Description:
-* This function removes an item of content from its parent element,
-* or removes the root element from a document. The removed item is not
-* annulled and may be subsequently added into another element.
-
-* Parameters:
-* this
-* The pointer to the item to be removed form its parent.
-*-
-*/
-
-/* Local Variables: */
- AstXmlDocument *doc; /* Pointer to parent document */
- AstXmlElement *elem; /* Pointer to parent element */
- AstXmlParent *parent; /* Pointer to parent */
- int found; /* Was the item found within its parent? */
- int i; /* Item index */
- int j; /* Item index */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Get a pointer to the items parent element, and check it is not null. */
- parent = ( (AstXmlObject *) this )->parent;
- if( parent && astXmlCheckType( parent, AST__XMLELEM ) ) {
- elem = (AstXmlElement *) parent;
-
-/* Search through all the items within the parent element looking for the
- supplied item. */
- found = 0;
- for( i = 0; i < elem->nitem; i++ ) {
- if( elem->items[ i ] == this ) {
-
-/* When found, decrement the number of items in the element, and shuffle
- all the remaining item pointers down one slot to over-write it, then
- nullify the parent pointer in the supplied object and leave the loop. */
- (elem->nitem)--;
- for( j = i; j < elem->nitem; j++ ) {
- elem->items[ j ] = elem->items[ j + 1 ];
- }
- ( (AstXmlObject *) this )->parent = NULL;
- found = 1;
- break;
- }
- }
-
-/* Report an error if the item was not found. */
- if( !found ) {
- astError( AST__INTER, "astXmlRemoveItem: The parent of the supplied "
- "item does not contain the item (internal AST programming "
- "error)." , status);
- }
-
-/* If the parent is an XmlDocument, check the item being removed is the
- root element. */
- } else if( parent && astXmlCheckType( parent, AST__XMLDOC ) ) {
- doc = (AstXmlDocument *) parent;
- if( (AstXmlElement *) this == doc->root ) {
- ( (AstXmlObject *) this )->parent = NULL;
- doc->root = NULL;
- }
- }
-}
-
-void astXmlRemoveURI_( AstXmlElement *this, const char *prefix, int *status ){
-/*
-*+
-* Name:
-* astXmlRemoveURI
-
-* Purpose:
-* Removes an namespace prefix from its parent element.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlRemoveURI( AstXmlElement *this, const char *prefix )
-
-* Description:
-* This function removes a named namespace prefix from its parent element.
-
-* Parameters:
-* this
-* The pointer to the element containing the namespace prefix to be
-* removed.
-* prefix
-* The namespace prefix to remove.
-*-
-*/
-
-/* Local Variables: */
- AstXmlNamespace *ns; /* Temporary namespace structure */
- AstXmlNamespace *oldns; /* Pointer to existing namespace */
- int oldi; /* Index of namespace within its parent */
- int i; /* Namespace index */
- int nns; /* Number of existing namespaces */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Initialise */
- oldns = NULL;
-
-/* Create a new XmlNamespace with blank URI. */
- ns = NewNamespace( prefix, "", status );
- if( astOK ) {
-
-/* Get the number of namespace prefixes currently stored in the element. */
- nns = ( this->nsprefs ) ? this->nnspref : 0;
-
-/* Search the list of existing namespace prefixes to see if the given prefix
- is included. */
- oldi = -1;
- for( i = 0; i < nns; i++ ) {
- oldns = this->nsprefs[ i ];
- if( !strcmp( oldns->prefix, ns->prefix ) ){
- oldi = i;
- break;
- }
- }
-
-/* If the supplied namespace prefix was found in the list, delete it. */
- if( oldi > -1 ) astXmlDelete( oldns );
-
-/* Delete the temporary namespace structure. */
- ns = astXmlDelete( ns );
-
- }
-}
-
-void astXmlSetDTDec_( AstXmlDocument *this, const char *text1,
- const char *text2, const char *text3, int *status ){
-/*
-*+
-* Name:
-* astXmlSetDTDec
-
-* Purpose:
-* Set the Document Type declaration for a document.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlSetDTDEC( AstXmlDocument *this, const char *text1,
-* const char *text2, const char *text3 )
-
-* Description:
-* This function stores an Document Type declaration of the form
-*
-* <!DOCTYPE text1 text2 [text3]>
-*
-* in the supplied document. Any previous DTD is removed.
-
-* Parameters:
-* this
-* The pointer to the document.
-* text1
-* The document type name.
-* text2
-* The text defining the external elements of the document type
-* (may be NULL).
-* text3
-* The text defining the internal elements of the document type
-* (may be NULL). Do not include delimiting "[" and "]" characters.
-*-
-*/
-
-/* Local Variables: */
- AstXmlDTDec *new; /* Pointer to new DT declaration */
- AstXmlPrologue *pro; /* Pointer to prologue */
- char *my_text2; /* Cleaned text2 */
- char *my_text3; /* Cleaned text3 */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Allocate space for the new structure. */
- new = (AstXmlDTDec *) astMalloc( sizeof( AstXmlDTDec ) );
-
-/* Clean the text. */
- my_text2 = CleanText( text2, status );
- my_text3 = CleanText( text3, status );
-
-/* Initialise it. */
- InitXmlDTDec( new, AST__XMLDTD, text1, my_text2, my_text3, status );
-
-/* Free the memory */
- my_text2 = astFree( my_text2 );
- my_text3 = astFree( my_text3 );
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) {
- new = astXmlDelete( new );
-
-/* Otherwise, store it in the document, deleting any existing declaration
- first. */
- } else {
-
-/* Create a prologue if necessary. */
- if( !this->prolog ) this->prolog = NewPrologue( this, status );
-
- pro = this->prolog;
- if( pro->dtdec ) astXmlDelete( pro->dtdec );
- pro->dtdec = new;
- }
-}
-
-void astXmlSetXmlDec_( AstXmlDocument *this, const char *text, int *status ){
-/*
-*+
-* Name:
-* astXmlSetXmlDec
-
-* Purpose:
-* Set the XML declaration for a document.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void astXmlSetXmlDec( AstXmlDocument *this, const char *text )
-
-* Description:
-* This function stores an XML declaration of the form
-*
-* <?xml [text]?>
-*
-* in the supplied document. Any previous XML declaration is removed.
-
-* Parameters:
-* this
-* The pointer to the document.
-* text
-* The text to include in the XML declaration tag.
-*-
-*/
-
-/* Local Variables: */
- AstXmlDeclPI *new; /* Pointer to new XML delcaration */
- AstXmlPrologue *pro; /* Pointer to prologue */
- char *my_text; /* Cleaned text */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Allocate space for the new structure. */
- new = (AstXmlDeclPI *) astMalloc( sizeof( AstXmlDeclPI ) );
-
-/* Clean the text. */
- my_text = CleanText( text, status );
-
-/* Initialise it. */
- InitXmlDeclPI( new, AST__XMLDEC, my_text, status );
-
-/* Free the memory */
- my_text = astFree( my_text );
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) {
- new = astXmlDelete( new );
-
-/* Otherwise, store it in the document, deleting any existing declaration
- first. */
- } else {
-
-/* Create a prologue if necessary. */
- if( !this->prolog ) this->prolog = NewPrologue( this, status );
-
- pro = this->prolog;
- if( pro->xmldecl ) astXmlDelete( pro->xmldecl );
- pro->xmldecl = new;
- }
-}
-
-const char *astXmlShow_( AstXmlObject *this, int *status ) {
-/*
-*+
-* Name:
-* astXmlShow
-
-* Purpose:
-* Converts an XmlObject into a character string with indentation.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *astXmlShow( AstXmlObject *this )
-
-* Description:
-* This function returns a pointer to a dynamically allocated string
-* containing a textual representation of the supplied XmlObject.
-* Newline characters are added to the string if needed to ensure that
-* each item of content within an element starts on a new line, and all
-* tags are preceded by an indentation string consisting of a number
-* of spaces.
-
-* Parameters:
-* this
-* Pointer to the XmlObject to format.
-
-* Returned Value:
-* Pointer to a null terminated string holding the formated XmlObject.
-* This string should be freed when no longer needed using astFree.
-
-* Notes:
-* - NULL is returned if a NULL pointer is supplied.
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
- return Format( this, 0, status );
-}
-
-static void CheckName( const char *name, const char *noun, const char *method,
- int nullok, int *status ){
-/*
-* Name:
-* CheckName
-
-* Purpose:
-* Checks the supplied string is a valid XML name.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* void CheckName( const char *name, const char *noun, const char *method,
-* int nullok, int *status )
-
-* Description:
-* This function checks that the supplied string is a valid XML name,
-* and reports an error otherwise.
-
-* Parameters:
-* name
-* The name string to check
-* noun
-* A word to describe the object which the name applies to - for use in
-* error messages only.
-* method
-* The name of the calling method - for use in error messages only.
-* nullok
-* If non-zero, then a null or empty name is assumed to be
-* acceptable.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- const char *c; /* Pointer to next character to check */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the string is not null. */
- if( !name ) {
- if( !nullok ) astError( AST__XMLNM, "%s: A NULL pointer was supplied "
- "instead of an XML %s name.", status, method, noun );
- } else {
-
- c = name;
- if( *c == 0 ) {
- if( !nullok ) astError( AST__XMLNM, "%s: An empty string was supplied "
- "instead of an XML %s name.", status, method, noun );
- } else {
-
- if( !isalpha( *c ) && *c != '_' ) {
- astError( AST__XMLNM, "%s: The illegal XML %s name \"%s\" was "
- "encountered.", status, method, noun, name );
-
- } else {
- while( *(++c) ) {
- if( !isalnum( *c ) && *c != '_' && *c != '-' && *c != '.' ){
- astError( AST__XMLNM, "%s: The illegal XML %s name \"%s\" was "
- "encountered.", status, method, noun, name );
- break;
- }
- }
- }
- }
- }
-}
-
-static void CheckPrefName( char *name, const char *noun, const char *method, int *status ){
-/*
-* Name:
-* CheckPrefName
-
-* Purpose:
-* Checks the supplied string is a valid XML (prefix:)name.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* void CheckPrefName( char *name, const char *noun, const char *method, int *status )
-
-* Description:
-* This function checks that the supplied string is a valid XML
-* (prefix:)name combination and reports an error otherwise.
-
-* Parameters:
-* name
-* The string to check
-* noun
-* A word to describe the object which the name applies to - for use in
-* error messages only.
-* method
-* The name of the calling method - for use in error messages only.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- char *colon; /* Pointer to first colon */
- char *temp; /* Pointer to temporary string */
- int nc; /* Length of temporary string */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Search for a ":" character. */
- colon = strchr( name, ':' );
-
-/* If found, temporarily convert the colon into a null so that it
- terminates the prefix string. */
- if( colon ) {
- *colon = 0;
-
-/* Check the string before the colon is a valid name. */
- temp = NULL;
- temp = astAppendString( temp, &nc, noun );
- temp = astAppendString( temp, &nc, " prefix" );
- CheckName( name, temp, method, 0, status );
- temp = astFree( temp );
-
-/* Restore the colon. */
- *colon = ':';
-
-/* Check the string following the colon is a valid name. */
- CheckName( colon + 1, noun, method, 0, status );
-
-/* If not found, the whole supplied string must be a name. */
- } else {
- CheckName( name, noun, method, 0, status );
- }
-}
-
-static int CheckType( long int given, long int want, int *status ){
-/*
-* Name:
-* CheckType
-
-* Purpose:
-* Check that the supplied type identifies an object of a given class.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* int CheckType( long int given, long int want, int *status )
-
-* Description:
-* This function checks that the supplied type identifier identifies
-* a specified class of XML object, or a derived class. A flag is
-* returned indicating if the check succeeds. No error is reported if
-* the check fails.
-
-* Parameters:
-* given
-* The type value to be checked.
-* want
-* The type of the required class.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Non-zero if the check is passed, zero if not of if an error has
-* already occurred.
-
-* Notes:
-* - This function attempts to execute even if the error status is set.
-*/
-
-/* Local Variables: */
- int result; /* Returned value */
-
-/* Initialise */
- result = 0;
-
-/* Check the wanted type is recognised. Report an error if not. */
- if( want != AST__XMLOBJECT &&
- want != AST__XMLELEM &&
- want != AST__XMLATTR &&
- want != AST__XMLCHAR &&
- want != AST__XMLCDATA &&
- want != AST__XMLCOM &&
- want != AST__XMLPI &&
- want != AST__XMLNAME &&
- want != AST__XMLCONT &&
- want != AST__XMLPRO &&
- want != AST__XMLDEC &&
- want != AST__XMLDTD &&
- want != AST__XMLMISC &&
- want != AST__XMLBLACK &&
- want != AST__XMLWHITE &&
- want != AST__XMLPAR &&
- want != AST__XMLDOC ) {
- if( astOK ) {
- astError( AST__INTER, "CheckType(Xml): Unsupported XML object "
- "type (%ld) supplied for parameter \"want\" (internal "
- "AST programming error). ", status, want );
- }
-
-/* You should never be given a generic "interface" type since the
- "wanted" value comes from the "type" component of an XmlObject (an explicit
- class type should always be given). */
- } else if( given == AST__XMLPAR ||
- given == AST__XMLMISC ||
- given == AST__XMLCONT ||
- given == AST__XMLCHAR ) {
- if( astOK ) {
- astError( AST__INTER, "CheckType(Xml): Generic type (%ld) supplied for "
- "parameter \"given\" (internal AST programming error).", status,
- given );
- }
-
-/* If the above is OK, return a non-zero value if the type to be tested
- equals the wanted type. */
- } else if( want == given ) {
- result = 1;
-
-/* If any class of XmlObject is acceptable, check that he given class
- type is a valid XML class type. */
- } else if( want == AST__XMLOBJECT ) {
- result = ( given == AST__XMLELEM ||
- given == AST__XMLATTR ||
- given == AST__XMLCDATA ||
- given == AST__XMLCOM ||
- given == AST__XMLPI ||
- given == AST__XMLNAME ||
- given == AST__XMLPRO ||
- given == AST__XMLDEC ||
- given == AST__XMLDTD ||
- given == AST__XMLWHITE ||
- given == AST__XMLBLACK ||
- given == AST__XMLDOC );
-
-/* Otherwise, for "interface" types, check if the given class "implements
- the interface". */
- } else if( want == AST__XMLCONT ) {
- result = ( given == AST__XMLELEM ||
- given == AST__XMLBLACK ||
- given == AST__XMLWHITE ||
- given == AST__XMLCDATA ||
- given == AST__XMLCOM ||
- given == AST__XMLPI );
-
- } else if( want == AST__XMLMISC ) {
- result = ( given == AST__XMLWHITE ||
- given == AST__XMLCOM ||
- given == AST__XMLPI );
-
- } else if( want == AST__XMLCHAR ) {
- result = ( given == AST__XMLWHITE ||
- given == AST__XMLBLACK );
-
- } else if( want == AST__XMLPAR ) {
- result = ( given == AST__XMLDOC ||
- given == AST__XMLPRO ||
- given == AST__XMLELEM );
- }
-
-/* Return the result. */
- return result;
-}
-
-int astXmlCheckType_( void *this, long int want, int *status ){
-/*
-*+
-* Name:
-* astXmlCheckType
-
-* Purpose:
-* Check that the supplied object is of a given class.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* int astXmlCheckType( void *this, long int want )
-
-* Description:
-* This function checks that the supplied XmlObject is of a specified
-* class of XML object, or a derived class. A flag is returned indicating
-* if the check succeeds. No error is reported if the check fails.
-
-* Parameters:
-* this
-* The object to check.
-* want
-* The type of the required class.
-
-* Returned Value:
-* Non-zero if the check is passed, zero if not of if an error has
-* already occurred.
-
-* Notes:
-* - This function attempts to execute even if the error status is set.
-*-
-*/
-
- if( this ) {
- return CheckType( ((AstXmlObject *) this)->type, want, status );
- } else {
- return 0;
- }
-}
-
-static char *CleanText( const char *text, int *status ){
-/*
-* Name:
-* CleanText
-
-* Purpose:
-* Normalise end-of-lines in the supplied text.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* char *CleanText( const char *text, int *status )
-
-* Description:
-* This function returns a copy of "text in which "\r\n" has been
-* replaced by "\n" and any remaining "\r" characters have been
-* replaced by "\n".
-
-* Parameters:
-* text
-* A pointer to a text string.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to a dynamically allocated string containing the required
-* copy.
-
-* Notes:
-* - NULL is returned if this function is called with the global error
-* status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- char *d; /* Pointer to next returned character */
- char *result; /* Returned pointer */
- char *c; /* Pointer to next supplied character */
- char lc; /* Previous character */
-
-/* Initialise */
- result = NULL;
-
-/* Return if the pointer is NULL or if an error has occurred. */
- if( !astOK || !text ) return result;
-
-/* Take a copy of the supplied text */
- result = astStore( NULL, text, strlen( text ) + 1 );
-
-/* Clean the text by replacing "\r\n" by "\n". */
- c = result - 1;
- d = c;
- lc = 0;
- while( *(++c) ) {
- if( *c != '\n' || lc != '\r' ) d++;
- *d = ( lc = *c );
- }
- *(++d) = 0;
-
-/* Now further clean it by replacing "\r" by "\n". */
- c = result - 1;
- while( *(++c) ) {
- if( *c == '\r' ) *c = '\n';
- }
-
-/* Return the result. */
- return result;
-}
-
-static void CleanXml( AstXmlObject *this, long int type, int *status ){
-/*
-* Name:
-* CleanXml
-
-* Purpose:
-* Free the resources used within an XmlObject.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* void CleanXml( AstXmlObject *this, long int type, int *status )
-
-* Description:
-* This function frees the resources used internally within the
-* supplied XmlObject.
-
-* Parameters:
-* this
-* pointer to the XmlObject to be cleaned.
-* type
-* The type of XmlObject being cleaned.
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* This function attempts to execute even if an error has already
-* occurred.
-*-
-*/
-
-/* Local Variables: */
- AstXmlAttribute *attr;
- AstXmlBlack *black;
- AstXmlCDataSection *cdatasec;
- AstXmlComment *comm;
- AstXmlDTDec *dtd;
- AstXmlDeclPI *dec;
- AstXmlDocument *doc;
- AstXmlElement *elem;
- AstXmlNamespace *ns;
- AstXmlPI *pi;
- AstXmlPrologue *pro;
- AstXmlWhite *white;
-
-/* Return if a NULL pointer has been suppplied. */
- if( !this ) return;
-
-/* For the base XmlObject class, clear the object type, etc. */
- if( type == AST__XMLOBJECT ){
- this->type = AST__XMLBAD;
- this->parent = NULL;
-
-/* For each derived class of XmlObject, first clean the parent component,
- then clean any further resources. */
- } else if( type == AST__XMLELEM ){
-
- elem = (AstXmlElement *) this;
-
- elem->name = astFree( elem->name );
- elem->defns = astFree( elem->defns );
- elem->prefix = astFree( elem->prefix );
-
- while( elem->nattr > 0 ) astXmlDelete( elem->attrs[ 0 ] );
- elem->attrs = astFree( elem->attrs );
-
- while( elem->nitem > 0 ) astXmlDelete( elem->items[ 0 ] );
- elem->items = astFree( elem->items );
-
- while( elem->nnspref > 0 ) astXmlDelete( elem->nsprefs[ 0 ] );
- elem->nsprefs = astFree( elem->nsprefs );
-
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( type == AST__XMLATTR ){
- attr = (AstXmlAttribute *) this;
- attr->name = astFree( attr->name );
- attr->value = astFree( attr->value );
- attr->prefix = astFree( attr->prefix );
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( type == AST__XMLBLACK ){
- black = (AstXmlBlack *) this;
- black->text = astFree( black->text );
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( type == AST__XMLWHITE ){
- white = (AstXmlWhite *) this;
- white->text = astFree( white->text );
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( type == AST__XMLCDATA ){
- cdatasec = (AstXmlCDataSection *) this;
- cdatasec->text = astFree( cdatasec->text );
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( type == AST__XMLCOM ){
- comm = (AstXmlComment *) this;
- comm->text = astFree( comm->text );
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( type == AST__XMLPI ){
- pi = (AstXmlPI *) this;
- pi->target = astFree( pi->target );
- pi->text = astFree( pi->text );
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( type == AST__XMLNAME ){
- ns = (AstXmlNamespace *) this;
- ns->prefix = astFree( ns->prefix );
- ns->uri = astFree( ns->uri );
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( type == AST__XMLDOC ){
- doc = (AstXmlDocument *) this;
- doc->prolog = astXmlDelete( doc->prolog );
- doc->root = astXmlDelete( doc->root );
- while( doc->nepi > 0 ) astXmlDelete( doc->epilog[ 0 ] );
- doc->epilog = astFree( doc->epilog );
- doc->current = NULL;
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( type == AST__XMLPRO ){
- pro = (AstXmlPrologue *) this;
- pro->xmldecl = astXmlDelete( pro->xmldecl );
- while( pro->nmisc1 > 0 ) astXmlDelete( pro->misc1[ 0 ] );
- pro->misc1 = astFree( pro->misc1 );
- pro->dtdec = astXmlDelete( pro->dtdec );
- while( pro->nmisc2 > 0 ) astXmlDelete( pro->misc2[ 0 ] );
- pro->misc2 = astFree( pro->misc2 );
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( type == AST__XMLDEC ){
- dec = (AstXmlDeclPI *) this;
- dec->text = astFree( dec->text );
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( type == AST__XMLDTD ){
- dtd = (AstXmlDTDec *) this;
- dtd->name = astFree( dtd->name );
- dtd->external = astFree( dtd->external );
- dtd->internal = astFree( dtd->internal );
- CleanXml( this, AST__XMLOBJECT, status );
-
- } else if( astOK ) {
- astError( AST__INTER, "CleanXml: Invalid object type (%ld) supplied "
- "(internal AST programming error).", status, type );
- }
-
-}
-
-static const char *DefaultURI( AstXmlElement *elem, int *status ){
-/*
-* Name:
-* DefaultURI
-
-* Purpose:
-* Find the URI associated with the default namespace.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *DefaultURI( AstXmlElement *elem, int *status )
-
-* Description:
-* This function returns the default namespace URI defined within the
-* given element. If the element does not define a default namespace URI,
-* then this function is called recursively on the parent element. If
-* there is no parent element, NULL is returned.
-
-* Parameters:
-* elem
-* The pointer to the XmlElement.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to a string holding the URI, or NULL if not found.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*/
-
-/* Local Variables: */
- AstXmlParent *parent; /* Parent of "this" */
- const char *result; /* Returned pointer */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status, and the supplied element. */
- if( !astOK || !elem ) return result;
-
-/* If the supplied element defines a default namespace URI, return it.
- Otherwise, call this function to get the default namespace URI from the
- parent element. */
- result = elem->defns;
- if( !result ) {
- parent = ( (AstXmlObject *) elem )->parent;
- if( astXmlCheckType( parent, AST__XMLELEM ) ) {
- result = DefaultURI( (AstXmlElement *) parent, status );
- }
- }
-
-/* If the element has a blank default namespace URI, then return NULL
- since the XML namespaces specification says that "The default
- namespace can be set to the empty string. This has the same effect,
- within the scope of the declaration, of there being no default
- namespace". */
- if( result && astChrLen( result ) == 0 ) result = NULL;
-
-/* Return the result. */
- return result;
-}
-
-void *astXmlDelete_( void *obj_ptr, int *status ){
-/*
-*+
-* Name:
-* astXmlDelete
-
-* Purpose:
-* Remove the supplied XmlObject from its parent and delete it.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* void *astXmlDelete( void *obj )
-
-* Description:
-* This function removes the supplied XmlObject from its parent and
-* deletes it using astXmlAnnul.
-
-* Parameters:
-* obj
-* The pointer to the XmlObject to be deleted.
-
-* Returned Value:
-* NULL
-
-* Notes:
-* - This function attempts to execute even if an error has already
-* occurred.
-*-
-*/
-
-/* Local Variables: */
- AstXmlDocument *doc; /* Pointer to XM document */
- AstXmlElement *elem; /* Pointer to XML element */
- AstXmlObject *obj; /* Pointer to XmlObject */
- AstXmlParent *parent; /* Pointer to parent */
- AstXmlPrologue *pro; /* Pointer to XML prologue */
- int i; /* Loop counter */
- int j; /* Loop counter */
- int n; /* Number of values in list */
- int ok; /* Is obj a child of its parent? */
- void *result; /* Returned pointer */
-
-/* Initialise */
- result = NULL;
- ok = 0;
-
-/* Check we have an XmlObject. */
- if( !astXmlCheckType( obj_ptr, AST__XMLOBJECT ) ) return result;
-
-/* Get the parent of the supplied object. */
- obj = (AstXmlObject *) obj_ptr;
- parent = obj->parent;
- if( parent ) {
-
-/* First deal with cases where we are deleting items from a document. */
- if( astXmlCheckType( parent, AST__XMLDOC ) ) {
- doc = (AstXmlDocument *) parent;
-
- if( astXmlCheckType( obj, AST__XMLPRO ) ) {
- if( (AstXmlPrologue *) obj == doc->prolog ) {
- doc->prolog = NULL;
- ok = 1;
- }
-
- } else if( astXmlCheckType( obj, AST__XMLELEM ) ) {
- if( (AstXmlElement *) obj == doc->root ) {
- doc->root = NULL;
- ok = 1;
- }
-
- } else if( astXmlCheckType( obj, AST__XMLMISC ) ) {
- n = doc->nepi;
- for( i = 0; i < n; i++ ) {
- if( doc->epilog[ i ] == (AstXmlMiscItem *) obj ) {
- for( j = i + 1; j < n; j++ ) {
- doc->epilog[ j - 1 ] = doc->epilog[ j ];
- }
- doc->epilog[ --doc->nepi ] = NULL;
- ok = 1;
- break;
- }
- }
-
- } else if( astOK ) {
- astError( AST__INTER, "astXmlDelete(xml): XmlObject of type %ld has "
- "inappropriate parent of type %ld (internal AST "
- "programming error).", status, obj->type, parent->type );
- }
-
-/* Now deal with cases where we are deleting items from a prologue. */
- } else if( astXmlCheckType( parent, AST__XMLPRO ) ) {
- pro = (AstXmlPrologue *) parent;
-
- if( astXmlCheckType( obj, AST__XMLDEC ) ) {
- if( (AstXmlDeclPI *) obj == pro->xmldecl ) {
- pro->xmldecl = NULL;
- ok = 1;
- }
-
- } else if( astXmlCheckType( obj, AST__XMLDTD ) ) {
- if( (AstXmlDTDec *) obj == pro->dtdec ) {
- pro->dtdec = NULL;
- ok = 1;
- }
-
- } else if( astXmlCheckType( obj, AST__XMLMISC ) ) {
- n = pro->nmisc1;
- for( i = 0; i < n; i++ ) {
- if( pro->misc1[ i ] == (AstXmlMiscItem *) obj ) {
- for( j = i + 1; j < n; j++ ) {
- pro->misc1[ j - 1 ] = pro->misc1[ j ];
- }
- pro->misc1[ --pro->nmisc1 ] = NULL;
- ok = 1;
- break;
- }
- }
-
- if( !ok ) {
- n = pro->nmisc2;
- for( i = 0; i < n; i++ ) {
- if( pro->misc2[ i ] == (AstXmlMiscItem *) obj ) {
- for( j = i + 1; j < n; j++ ) {
- pro->misc2[ j - 1 ] = pro->misc2[ j ];
- }
- pro->misc2[ --pro->nmisc2 ] = NULL;
- ok = 1;
- break;
- }
- }
- }
-
- } else if( astOK ) {
- astError( AST__INTER, "astXmlDelete(xml): XmlObject of type %ld has "
- "inappropriate parent of type %ld (internal AST "
- "programming error).", status, obj->type, parent->type );
- }
-
-/* Now deal with cases where we are deleting items from an element. */
- } else if( astXmlCheckType( parent, AST__XMLELEM ) ) {
- elem = (AstXmlElement *) parent;
-
-/* Remove the object form the appropriate list in the parent, and
- then shuffle down the remaining entries in the list and decrement the
- size of the list. */
- if( astXmlCheckType( obj, AST__XMLATTR ) ) {
- n = elem->nattr;
- for( i = 0; i < n; i++ ) {
- if( elem->attrs[ i ] == (AstXmlAttribute *) obj ) {
- for( j = i + 1; j < n; j++ ) {
- elem->attrs[ j - 1 ] = elem->attrs[ j ];
- }
- elem->attrs[ --elem->nattr ] = NULL;
- ok = 1;
- break;
- }
- }
-
- } else if( astXmlCheckType( obj, AST__XMLNAME ) ) {
- n = elem->nnspref;
- for( i = 0; i < n; i++ ) {
- if( elem->nsprefs[ i ] == (AstXmlNamespace *) obj ) {
- for( j = i + 1; j < n; j++ ) {
- elem->nsprefs[ j - 1 ] = elem->nsprefs[ j ];
- }
- elem->nsprefs[ --elem->nnspref ] = NULL;
- ok = 1;
- break;
- }
- }
-
- } else if( astXmlCheckType( obj, AST__XMLCONT ) ) {
- n = elem->nitem;
- for( i = 0; i < n; i++ ) {
- if( elem->items[ i ] == (AstXmlContentItem *) obj ) {
- for( j = i + 1; j < n; j++ ) {
- elem->items[ j - 1 ] = elem->items[ j ];
- }
- elem->items[ --elem->nitem ] = NULL;
- ok = 1;
- break;
- }
- }
- }
-
- } else if( astOK ) {
- astError( AST__INTER, "astXmlDelete(xml): XmlObject of type %ld has "
- "inappropriate parent of type %ld (internal AST "
- "programming error).", status, obj->type, parent->type );
- }
-
-/* Nullify the parent pointer so that astXmlAnnul will delete the object. */
- obj->parent = NULL;
-
-/* If the supplied object has no parent, we can continue to annul it. */
- } else {
- ok = 1;
- }
-
-/* Report an error if required. */
- if( !ok && astOK ) {
- astError( AST__INTER, "astXmlDelete(xml): Supplied XmlObject (type %ld) "
- "is not owned by its own parent (internal AST "
- "programming error).", status, obj->type );
- }
-
-/* Delete the object. */
- result = astXmlAnnul( obj );
-
-/* Annul the object and return the resulting NULL pointer. */
- return result;
-}
-
-static AstXmlAttribute *FindAttribute( AstXmlElement *this, const char *name0,
- int *status ){
-/*
-* Name:
-* FindAttribute
-
-* Purpose:
-* Search an XmlElement for a named attribute
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlAttribute *FindAttribute( AstXmlElement *this, const char *name0,
-* int *status )
-
-* Description:
-* This function searches the supplied XmlElement for an attribute
-* with the given name. If found, a pointer to the XmlAttribute is
-* returned. Otherwise NULL is returned.
-
-* Parameters:
-* this
-* The pointer to the XmlElement.
-* name0
-* Pointer to a string holding the name of the attribute. The name
-* may be preceded with a "prefix:" string, in which case the
-* prefix will also be matched. If no prefix is included, the first
-* attribute with the specified name is returned, regardless of
-* its prefix.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to the XmlAttribute, or NULL if not found.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*/
-
-/* Local Variables: */
- AstXmlAttribute *result; /* Returned pointer */
- char name_buffer[ 50 ]; /* Buffer for name */
- char prefix_buffer[ 50 ]; /* Buffer for prefix */
- const char *colon; /* Pointer to colon in supplied string */
- const char *name1; /* Pointer to name to be checked */
- const char *name; /* Pointer to name to be searched for */
- const char *prefix1; /* Pointer to prefix to be checked */
- const char *prefix; /* Pointer to prefix to be searched for */
- int i; /* Loop count */
- size_t len; /* Length of string */
-
-/* Initialise */
- result = NULL;
- name = name0;
- prefix = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
-/* If the supplied name string contains a colon, split it up into prefix
- and name. */
- if( ( colon = strchr( name0, ':' ) ) ) {
- len = colon - name0;
-
- if( len > 49 ) {
- astError( AST__XMLNM, "FindAttribute: The XML prefix in \"%s\" "
- "is too long (> 49 characters).", status, name0 );
- } else {
- strncpy( prefix_buffer, name0, len );
- prefix_buffer[ len ] = 0;
- prefix = prefix_buffer;
- len = strlen( colon + 1 );
-
- if( len > 49 ) {
- astError( AST__XMLNM, "FindAttribute: The XML attribute name "
- "in \"%s\" is too long (> 49 characters).", status, name0 );
- } else {
- strcpy( name_buffer, colon + 1 );
- name = name_buffer;
- }
-
- }
-
- }
-
-/* Loop round all the attributes in the element. */
- for( i = 0; i < this->nattr; i++ ) {
- name1 = this->attrs[ i ]->name;
- prefix1 = this->attrs[ i ]->prefix;
-
-/* Compare the attribute name (and prefix) with the supplied name (and
- prefix). Leave the loop if they match. */
- if( !strcmp( name1, name ) &&
- ( !prefix || ( prefix1 && !strcmp( prefix1, prefix ) ) ) ) {
- result = this->attrs[ i ];
- break;
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static const char *Format( AstXmlObject *this, int ind, int *status ){
-/*
-* Name:
-* Format
-
-* Purpose:
-* Converts an XmlObject into a character string.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *Format( AstXmlObject *this, int ind, int *status )
-
-* Description:
-* This function returns a pointer to a dynamically allocated string
-* containing a textual representation of the supplied XmlObject.
-
-* Parameters:
-* this
-* Pointer to the XmlObject to format.
-* ind
-* If the XmlObject is an element, then each content item within
-* the element will be prefixed by a string containing "ind" spaces
-* (indenting the returned element itself is the responsibility of
-* the caller and so "this" is not itself indented within this function).
-* In addition, a newline character will be included at the start
-* of the prefix if required, to ensure that each new item starts
-* on a new line. If "ind" is less than zero, then no prefixes are
-* added.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to a null terminated string holding the formated XmlObject.
-* This string should be freed when no longer needed using astFree.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*/
-
-/* Local Variables: */
- AstXmlPrologue *pro; /* Pointer to XML prologue */
- AstXmlDocument *doc; /* Pointer to XML document */
- AstXmlAttribute *attrib; /* Pointer to XML attribute */
- AstXmlWhite *white; /* Pointer to character data */
- AstXmlBlack *black; /* Pointer to character data */
- AstXmlElement *elem; /* Pointer to XML element */
- AstXmlNamespace *ns; /* Pointer to XML namespace instruction */
- char *result; /* The returned pointer */
- const char *temp; /* A temporary string pointer */
- int i; /* Loop count */
- int nc; /* Length of returned string */
- int type; /* Object type */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if( !astOK || !this ) return result;
-
-/* Get the object type */
- type = this->type;
-
-/* If this is an element... */
- if( this->type == AST__XMLELEM ) {
- temp = FormatTag( this, 1, status );
- result = astAppendString( result, &nc, temp );
- temp = astFree( (void *) temp );
-
- elem = (AstXmlElement *) this;
- if( elem->nitem > 0 ) {
-
-/* Go round all the items of content. */
- for( i = 0; i < elem->nitem; i++ ) {
-
-/* Ignore whitespace elements unless we are not producing indentation. */
- if( !astXmlCheckType( elem->items[ i ], AST__XMLWHITE ) ||
- ind < 0 ) {
-
-/* Format the item */
- temp = Format( (AstXmlObject *) elem->items[ i ], ( ( ind > -1 ) ? ind + IND_INC : -1 ), status );
- if( temp ) {
-
-/* Now append the next item of content, and free its memory. */
- if( ind > -1 ) {
- result = AppendLine( result, &nc, temp,
- ( (ind > -1) ? ind + IND_INC : -1 ), status );
- } else {
- result = astAppendString( result, &nc, temp );
- }
- temp = astFree( (void *) temp );
- }
- }
- }
-
-/* Finally append the end tag. */
- temp = FormatTag( this, 0, status );
- if( ind > -1 ) {
- result = AppendLine( result, &nc, temp, ind, status );
- } else {
- result = astAppendString( result, &nc, temp );
- }
- temp = astFree( (void *) temp );
-
- }
-
-/* If this is an attribute... */
- } else if( type == AST__XMLATTR ){
- attrib = (AstXmlAttribute *) this;
-
- if( attrib->prefix ) {
- result = astAppendString( result, &nc, attrib->prefix );
- result = astAppendString( result, &nc, ":" );
- }
-
- temp = AddEscapes( attrib->value, status );
- result = astAppendString( result, &nc, attrib->name );
- result = astAppendString( result, &nc, "=\"" );
- result = astAppendString( result, &nc, temp );
- result = astAppendString( result, &nc, "\"" );
- temp = astFree( (void *) temp );
-
- } else if( type == AST__XMLWHITE ){
- white = (AstXmlWhite *) this;
- temp = AddEscapes( white->text, status );
- result = astAppendString( result, &nc, temp );
- temp = astFree( (void *) temp );
-
- } else if( type == AST__XMLBLACK ){
- black = (AstXmlBlack *) this;
- temp = AddEscapes( black->text, status );
- result = astAppendString( result, &nc, temp );
- temp = astFree( (void *) temp );
-
- } else if( type == AST__XMLCDATA ||
- type == AST__XMLCOM ||
- type == AST__XMLPI ||
- type == AST__XMLDEC ||
- type == AST__XMLDTD ){
-
- temp = FormatTag( this, 1, status );
- result = astAppendString( result, &nc, temp );
- temp = astFree( (void *) temp );
-
- } else if( type == AST__XMLNAME ){
- ns = (AstXmlNamespace *) this;
- result = astAppendString( result, &nc, "xmlns:" );
- result = astAppendString( result, &nc, ns->prefix );
- result = astAppendString( result, &nc, "=\"" );
- result = astAppendString( result, &nc, ns->uri );
- result = astAppendString( result, &nc, "\"" );
-
- } else if( type == AST__XMLPRO ){
- pro = (AstXmlPrologue *) this;
- result = astAppendString( result, &nc,
- Format( (AstXmlObject *) pro->xmldecl, ind, status ) );
-
-/* Append all the miscalleneous items before the DTD. */
- for( i = 0; i < pro->nmisc1; i++ ) {
- temp = Format( (AstXmlObject *) pro->misc1[ i ], ind, status );
- if( temp ) {
- if( ind > -1 ) {
- result = AppendLine( result, &nc, temp, ind, status );
- } else {
- result = astAppendString( result, &nc, temp );
- }
- temp = astFree( (void *) temp );
- }
- }
-
-/* Append the DTD. */
- temp = Format( (AstXmlObject *) pro->dtdec, ind, status );
- if( temp ) {
- if( ind > -1 ) {
- result = AppendLine( result, &nc, temp, ind, status );
- } else {
- result = astAppendString( result, &nc, temp );
- }
- temp = astFree( (void *) temp );
- }
-
-/* Append all the miscalleneous items after the DTD. */
- for( i = 0; i < pro->nmisc2; i++ ) {
- temp = Format( (AstXmlObject *) pro->misc2[ i ], ind, status );
- if( temp ) {
- if( ind > -1 ) {
- result = AppendLine( result, &nc, temp, ind, status );
- } else {
- result = astAppendString( result, &nc, temp );
- }
- temp = astFree( (void *) temp );
- }
- }
-
- } else if( type == AST__XMLDOC ){
- doc = (AstXmlDocument *) this;
-
-/* Format the prologue. */
- result = astAppendString( result, &nc,
- Format( (AstXmlObject *) doc->prolog, ind, status ) );
-
-/* Append the root element. */
- temp = Format( (AstXmlObject *) doc->root, ind, status );
- if( temp ) {
- if( ind > -1 ) {
- result = AppendLine( result, &nc, temp, ind, status );
- } else {
- result = astAppendString( result, &nc, temp );
- }
- temp = astFree( (void *) temp );
- }
-
-/* Append all the miscalleneous items in the epilogue. */
- for( i = 0; i < doc->nepi; i++ ) {
- temp = Format( (AstXmlObject *) doc->epilog[ i ], ind, status );
- if( temp ) {
- if( ind > -1 ) {
- result = AppendLine( result, &nc, temp, ind, status );
- } else {
- result = astAppendString( result, &nc, temp );
- }
- temp = astFree( (void *) temp );
- }
- }
-
- } else if( astOK ) {
- astError( AST__INTER, "Format(xml): Invalid object type (%d) supplied "
- "(internal AST programming error).", status, type );
- }
-
-/* Free the returned string if an error has occurred. */
- if( !astOK ) result = astFree( result );
-
-/* Return the result. */
- return result;
-}
-
-static char *FormatTag( AstXmlObject *this, int opening, int *status ){
-/*
-* Name:
-* FormatTag
-
-* Purpose:
-* Returns a string holding an XML tag describing the given XmlObject.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* char *FormatTag( AstXmlObject *this, int opening, int *status )
-
-* Description:
-* This function returns a pointer to a dynamic string containing an
-* XML tag describing the given XmlObject.
-
-* Parameters:
-* this
-* Pointer to the XmlObject.
-* opening
-* Indicates which tag is to be returned; the start tag or the end
-* tag. If non-zero the start tag is returned. Otherwise, the
-* end tag is returned. If the supplied XmlObject has no end
-* tag (i.e. if it is an empty element, or if it is not an element),
-* then NULL is returned but no error is reported.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to a dynamically allocated string holding the tag.
-
-* Notes:
-* - Empty elements are represented as an start tag of the form <.../>,
-* with no corresponding end tag.
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*-
-*/
-
-
-/* Local Variables: */
- AstXmlCDataSection *cdata;/* Pointer to XML CDATA section */
- AstXmlElement *elem; /* Pointer to XML element */
- AstXmlComment *com; /* Pointer to XML comment */
- AstXmlPI *pi; /* Pointer to XML processing instruction */
- AstXmlDTDec *dtd; /* Pointer to XML data type declaration */
- AstXmlDeclPI *xmlpi; /* XML version declaration */
- char *result; /* The returned pointer */
- const char *temp; /* A temporary string pointer */
- int i; /* Loop count */
- int nc; /* Length of returned string */
- int type; /* Object type */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
-/* Get the object type */
- type = this->type;
-
-/* If this is an element... */
- if( this->type == AST__XMLELEM ) {
- elem = (AstXmlElement *) this;
-
- if( opening ) {
- result = astAppendString( result, &nc, "<" );
- if( elem->prefix ) {
- result = astAppendString( result, &nc, elem->prefix );
- result = astAppendString( result, &nc, ":" );
- }
- result = astAppendString( result, &nc, elem->name );
-
- if( elem->defns ) {
- result = astAppendString( result, &nc, " xmlns=\"" );
- result = astAppendString( result, &nc, elem->defns );
- result = astAppendString( result, &nc, "\"" );
- }
-
- for( i = 0; i < elem->nnspref; i++ ) {
- temp = Format( (AstXmlObject *) elem->nsprefs[ i ], -1, status );
- if( temp ) {
- result = AppendChar( result, &nc, ' ', status );
- result = astAppendString( result, &nc, temp );
- temp = astFree( (void *) temp );
- }
- }
-
- for( i = 0; i < elem->nattr; i++ ) {
- temp = Format( (AstXmlObject *) elem->attrs[ i ], -1, status );
- if( temp ){
- result = AppendChar( result, &nc, ' ', status );
- result = astAppendString( result, &nc, temp );
- temp = astFree( (void *) temp );
- }
- }
-
- if( elem->nitem == 0 ) result = astAppendString( result, &nc, "/" );
- result = astAppendString( result, &nc, ">" );
-
- } else if( elem->nitem > 0 ) {
- result = astAppendString( result, &nc, "</" );
- if( elem->prefix ) {
- result = astAppendString( result, &nc, elem->prefix );
- result = astAppendString( result, &nc, ":" );
- }
- result = astAppendString( result, &nc, elem->name );
- result = astAppendString( result, &nc, ">" );
- }
-
- } else if( type == AST__XMLDTD ){
- dtd = (AstXmlDTDec *) this;
- if( opening && dtd->name && dtd->name[0] ) {
- result = astAppendString( result, &nc, "<!DOCTYPE " );
- result = astAppendString( result, &nc, dtd->name );
- if( dtd->external && dtd->external[ 0 ] ) {
- result = astAppendString( result, &nc, " " );
- result = astAppendString( result, &nc, dtd->external );
- }
- if( dtd->internal && dtd->internal[ 0 ] ) {
- result = astAppendString( result, &nc, " [" );
- result = astAppendString( result, &nc, dtd->internal );
- result = astAppendString( result, &nc, "]" );
- }
- result = astAppendString( result, &nc, ">" );
- }
-
- } else if( type == AST__XMLCDATA ){
- if( opening ) {
- cdata = (AstXmlCDataSection *) this;
- result = astAppendString( result, &nc, "<![CDATA[" );
- result = astAppendString( result, &nc, cdata->text );
- result = astAppendString( result, &nc, "]]>" );
- }
-
- } else if( type == AST__XMLCOM ){
- if( opening ) {
- com = (AstXmlComment *) this;
- result = astAppendString( result, &nc, "<!--" );
- result = astAppendString( result, &nc, com->text );
- result = astAppendString( result, &nc, "-->" );
- }
-
- } else if( type == AST__XMLPI ){
- pi = (AstXmlPI *) this;
- if( opening ) {
- result = astAppendString( result, &nc, "<?" );
- result = astAppendString( result, &nc, pi->target );
- if( pi->text && pi->text[0] ) {
- result = astAppendString( result, &nc, " " );
- result = astAppendString( result, &nc, pi->text );
- }
- result = astAppendString( result, &nc, "?>" );
- }
-
- } else if( type == AST__XMLDEC ){
- xmlpi = (AstXmlDeclPI *) this;
- if( opening && xmlpi->text && xmlpi->text[0] ) {
- result = astAppendString( result, &nc, "<?xml" );
- if( xmlpi->text && xmlpi->text[0] ) {
- result = astAppendString( result, &nc, " " );
- result = astAppendString( result, &nc, xmlpi->text );
- }
- result = astAppendString( result, &nc, "?>" );
- }
- }
-
-/* If notOK, free the rteurned string. */
- if( !astOK ) result = astFree( result );
-
-/* Return the result. */
- return result;
-}
-
-static void InitXmlAttribute( AstXmlAttribute *new, int type, const char *name,
- const char *value, const char *prefix, int *status ){
-/*
-* Name:
-* InitXmlAttribute
-
-* Purpose:
-* Initialise a new XmlAttribute.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlAttribute( AstXmlAttribute *new, int type, const char *name,
-* const char *value, const char *prefix, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlAttribute
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* name
-* The name for the attribute.
-* value
-* The value for the attribute
-* prefix
-* The namespace prefix for the attribute. May be NULL or blank, in
-* which case any prefix at the start of "name" is used.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- const char *colon; /* Pointer to colon within supplied name */
- char *newname; /* Pointer to name string (no prefix) */
- char *newpref; /* Pointer to name string */
- int nc; /* Length of prefix string */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLATTR, status ) ){
- astError( AST__INTER, "InitXmlAttribute: Supplied object type (%d) "
- "does not represent an XmlAttribute", status, type );
- }
-
-/* Ensure we have non-NULL pointers. */
- if( !name ) name = "";
- if( !value ) value = "";
-
-/* If no prefix was supplied, extract any prefix from the start of the
- supplied name. */
- newname = (char *) name;
- newpref = (char *) prefix;
- colon = NULL;
-
- if( !prefix || astChrLen( prefix ) == 0 ){
- colon = strchr( name, ':' );
- if( colon ) {
- nc = colon - name;
- newpref = astStore( NULL, name, nc + 1 );
- newpref[ nc ] = 0;
-
- nc = strlen( name ) - ( colon - name ) - 1;
- newname = astStore( NULL, colon + 1, nc + 1 );
- newname[ nc ] = 0;
- }
- }
-
-/* Check the supplied name and prefix are valid XML 'names'. */
- CheckName( newname, "attribute", "InitXmlAttribute", 0, status );
- CheckName( newpref, "attribute", "InitXmlAttribute", 1, status );
-
-/* Initialise the parent XmlObject component. */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Initialise the items specific to this class of structure. */
- new->name = astStore( NULL, newname, strlen( newname ) + 1 );
- new->value = astStore( NULL, value, strlen( value ) + 1 );
- new->prefix = NULL;
- if( newpref ) {
- nc = strlen( newpref );
- if( nc > 0 ) new->prefix = astStore( NULL, newpref, nc + 1 );
- }
-
-/* Free any name and prefix extracted from the supplied name string */
- if( colon ) {
- newname = astFree( newname );
- newpref = astFree( newpref );
- }
-}
-
-static void InitXmlCDataSection( AstXmlCDataSection *new, int type,
- const char *text, int *status ){
-/*
-* Name:
-* InitXmlCDataSection
-
-* Purpose:
-* Initialise a new XmlCDataSection.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlCDataSection( AstXmlCDataSection *new, int type,
-* const char *text, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlCDataSection
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* text
-* Pointer to a null terminated string holding the text.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLCDATA, status ) ){
- astError( AST__INTER, "InitXmlCDataSection: Supplied object type (%d) "
- "does not represent an XmlCDataSection", status, type );
- }
-
-/* Initialise the parent XmlObject component. */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Ensure we have non-NULL pointers. */
- if( !text ) text = "";
-
-/* Initialise the items specific to this class of structure. */
- new->text = astStore( NULL, text, strlen( text ) + 1 );
-}
-
-static void InitXmlWhite( AstXmlWhite *new, int type, const char *text, int *status ){
-/*
-* Name:
-* InitXmlWhite
-
-* Purpose:
-* Initialise a new XmlWhite.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlWhite( AstXmlWhite *new, int type, const char *text, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlWhite
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* text
-* Pointer to a null terminated string holding the text.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- const char *c; /* Pointer to next character */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLWHITE, status ) ){
- astError( AST__INTER, "InitXmlWhite: Supplied object type (%d) "
- "does not represent an XmlWhite", status, type );
- }
-
-/* Initialise the parent XmlObject component. */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Ensure we have non-NULL pointers. */
- if( !text ) text = "";
-
-/* Report an error if the text is not white. */
- c = text - 1;
- while( *(++c) ) {
- if( !isspace( *c ) ) {
- astError( AST__XMLCM, "InitXmlWhite(xml): Illegal XML whitespace "
- "string supplied \"%s\" - not all characters are white.", status,
- text );
- break;
- }
- }
-
-/* Initialise the items specific to this class of structure. */
- new->text = astStore( NULL, text, strlen( text ) + 1 );
-}
-
-static void InitXmlBlack( AstXmlBlack *new, int type, const char *text, int *status ){
-/*
-* Name:
-* InitXmlBlack
-
-* Purpose:
-* Initialise a new XmlBlack.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlBlack( AstXmlBlack *new, int type, const char *text, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlBlack
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* text
-* Pointer to a null terminated string holding the text.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLBLACK, status ) ){
- astError( AST__INTER, "InitXmlBlack: Supplied object type (%d) "
- "does not represent an XmlBlack", status, type );
- }
-
-/* Initialise the parent XmlObject component. */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Ensure we have non-NULL pointers. */
- if( !text ) text = "";
-
-/* Initialise the items specific to this class of structure. */
- new->text = astStore( NULL, text, strlen( text ) + 1 );
-}
-
-static void InitXmlComment( AstXmlComment *new, int type, const char *text, int *status ){
-/*
-* Name:
-* InitXmlComment
-
-* Purpose:
-* Initialise a new XmlComment.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlComment( AstXmlComment *new, int type, const char *text, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlComment
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* text
-* Pointer to a null terminated string holding the text.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLCOM, status ) ){
- astError( AST__INTER, "InitXmlComment: Supplied object type (%d) "
- "does not represent an XmlComment", status, type );
- }
-
-/* Initialise the parent XmlObject component. */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Ensure we have non-NULL pointers. */
- if( !text ) text = "";
-
-/* Initialise the items specific to this class of structure. Report an error
- if the comment is illegal. */
- if( strstr( text, "--" ) && astOK ) {
- astError( AST__XMLCM, "InitXmlCom(xml): Illegal XML comment "
- "supplied \"%s\" - comments may not contain the "
- "string \"--\".", status, text );
- new->text = NULL;
- } else {
- new->text = astStore( NULL, text, strlen( text ) + 1 );
- }
-}
-
-static void InitXmlDeclPI( AstXmlDeclPI *new, int type, const char *text, int *status ){
-/*
-* Name:
-* InitXmlDeclPI
-
-* Purpose:
-* Initialise a new XmlDeclPI.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlDeclPI( AstXmlDeclPI *new, int type, const char *text, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlDeclPI
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* text
-* Pointer to a null terminated string holding the text.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLDEC, status ) ){
- astError( AST__INTER, "InitXmlDeclPI: Supplied object type (%d) "
- "does not represent an XmlDeclPI", status, type );
- }
-
-/* Initialise the parent XmlObject component. */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Ensure we have non-NULL pointers. */
- if( !text ) text = "";
-
-/* Initialise the items specific to this class of structure. */
- new->text = astStore( NULL, text, strlen( text ) + 1 );
-}
-
-static void InitXmlDocument( AstXmlDocument *new, int type, int *status ){
-/*
-* Name:
-* InitXmlDocument
-
-* Purpose:
-* Initialise a new XmlDocument.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlDocument( AstXmlDocument *new, int type, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlDocument
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLDOC, status ) ){
- astError( AST__INTER, "InitXmlDocument: Supplied object type (%d) "
- "does not represent an XmlDocument", status, type );
- }
-
-/* Initialise the parent XmlObject */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Initialise the items specific to this class of structure. */
- new->prolog = NULL;
- new->root = NULL;
- new->epilog = NULL;
- new->nepi = 0;
- new->current = NULL;
-}
-
-static void InitXmlDTDec( AstXmlDTDec *new, int type, const char *name,
- const char *external, const char *internal, int *status ){
-/*
-* Name:
-* InitXmlDTDec
-
-* Purpose:
-* Initialise a new XmlDTDec.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* void InitXmlDTDec( AstXmlDTDec *new, int type, const char *name,
-* const char *external, const char *internal, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlDTDec
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* name
-* The document type name
-* external
-* The external SYSTEM id.
-* internal
-* The internal declaration markup text (this is not checked or
-* parsed).
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLDTD, status ) ){
- astError( AST__INTER, "InitXmlDTDec: Supplied object type (%d) "
- "does not represent an XmlDTDec", status, type );
- }
-
-/* Initialise the parent XmlObject */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Ensure we have non-NULL pointers. */
- if( !name ) name = "";
- if( !external ) external = "";
- if( !internal ) internal = "";
-
-/* Initialise the items specific to this class of structure. */
- new->name = astStore( NULL, name, strlen( name ) + 1 );
- new->external = astStore( NULL, external, strlen( external ) + 1 );
- new->internal = astStore( NULL, internal, strlen( internal ) + 1 );
-}
-
-static void InitXmlElement( AstXmlElement *new, int type, const char *name,
- const char *prefix, int *status ){
-/*
-* Name:
-* InitXmlElement
-
-* Purpose:
-* Initialise a new XmlElement.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlElement( AstXmlElement *new, int type, const char *name,
-* const char *prefix, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlElement
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* name
-* The name for the element.
-* prefix
-* The namespace prefix for the element. May be NULL or blank, in
-* which case any prefix at the start of "name" is used.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- const char *colon; /* Pointer to colon within supplied name */
- char *newname; /* Pointer to name string (no prefix) */
- char *newpref; /* Pointer to name string */
- int nc; /* Length of prefix string */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLELEM, status ) ){
- astError( AST__INTER, "InitXmlElement: Supplied object type (%d) "
- "does not represent an XmlElement", status, type );
- }
-
-/* Ensure we have non-NULL pointers. */
- if( !name ) name = "";
-
-/* If no prefix was supplied, extract any prefix from the start of the
- supplied name. */
- newname = (char *) name;
- newpref = (char *) prefix;
- colon = NULL;
-
- if( !prefix || astChrLen( prefix ) == 0 ){
- colon = strchr( name, ':' );
- if( colon ) {
- nc = colon - name;
- newpref = astStore( NULL, name, nc + 1 );
- newpref[ nc ] = 0;
-
- nc = strlen( name ) - ( colon - name ) - 1;
- newname = astStore( NULL, colon + 1, nc + 1 );
- newname[ nc ] = 0;
- }
- }
-
-/* Check the supplied name and prefix are valid XML 'names'. */
- CheckName( newname, "element", "InitXmlElement", 0, status );
- CheckName( newpref, "element", "InitXmlElement", 1, status );
-
-/* Initialise the parent XmlObject component. */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Initialise the items specific to this class of structure. */
- new->name = astStore( NULL, newname, strlen( newname ) + 1 );
- new->attrs = NULL;
- new->nattr = 0;
- new->items = NULL;
- new->nitem = 0;
- new->defns = NULL;
- new->nsprefs = NULL;
- new->nnspref = 0;
- new->complete = 0;
-
- new->prefix = NULL;
- if( newpref ) {
- nc = strlen( newpref );
- if( nc > 0 ) new->prefix = astStore( NULL, newpref, nc + 1 );
- }
-
-/* Free any name and prefix extracted from the supplied name string */
- if( colon ) {
- newname = astFree( newname );
- newpref = astFree( newpref );
- }
-}
-
-static void InitXmlNamespace( AstXmlNamespace *new, int type, const char *prefix,
- const char *uri, int *status ){
-/*
-* Name:
-* InitXmlNamespace
-
-* Purpose:
-* Initialise a new XmlNamespace.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlNamespace( AstXmlNamespace *new, int type, const char *prefix,
-* const char *uri, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlNamespace
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* prefix
-* Pointer to a null terminated string holding the namespace prefix.
-* uri
-* Pointer to a null terminated string holding the namespace URI.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLNAME, status ) ){
- astError( AST__INTER, "InitXmlNamespace: Supplied object type (%d) "
- "does not represent an XmlNamespace", status, type );
- }
-
-/* Ensure we have non-NULL pointers. */
- if( !prefix ) prefix = "";
- if( !uri ) uri = "";
-
-/* Check the supplied prefix is a valid XML 'name'. */
- CheckName( prefix, "namespace prefix", "InitXmlNamespace", 0, status );
-
-/* Initialise the parent XmlObject component. */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Initialise the items specific to this class of structure. */
- new->prefix = astStore( NULL, prefix, strlen( prefix ) + 1 );
- new->uri = astStore( NULL, uri, strlen( uri ) + 1 );
-}
-
-static void InitXmlObject( AstXmlObject *new, long int type, int *status ){
-/*
-* Name:
-* InitXmlObject
-
-* Purpose:
-* Initialise a new XmlObject.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlObject( AstXmlObject *new, long int type, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlObject
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* If needed, get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* Check the supplied object type is OK. Report an error if not. */
- if( !CheckType( type, AST__XMLOBJECT, status ) ){
- astError( AST__INTER, "InitXmlObject: Supplied object type (%ld) "
- "is not appropriate for an XmlObject", status, type );
- }
-
-/* This class of structure is the base class for XML objects so it has no
- parent class to be initialised. So just initialise the items specific to
- this class of structure. */
- new->parent = NULL;
- new->type = type;
- new->id = next_id++;
-
-#ifdef DEBUG
-/* Add the new XmlObject to the list of all XmlObjects. */
- AddObjectToList( new );
-#endif
-
-}
-
-static void InitXmlPI( AstXmlPI *new, int type, const char *target,
- const char *text, int *status ){
-/*
-* Name:
-* InitXmlPI
-
-* Purpose:
-* Initialise a new XmlPI.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlPI( AstXmlPI *new, int type, const char *target,
-* const char *text, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlPI
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* target
-* Pointer to a null terminated string holding the PI target.
-* text
-* Pointer to a null terminated string holding the PI text.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLPI, status ) ){
- astError( AST__INTER, "InitXmlPI: Supplied object type (%d) "
- "does not represent an XmlPI", status, type );
- }
-
-/* Initialise the parent XmlObject component. */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Ensure we have non-NULL pointers. */
- if( !target ) target = "";
- if( !text ) text = "";
-
-/* Initialise the items specific to this class of structure. Report an error
- if anything is illegal. */
- new->target = NULL;
- new->text = NULL;
-
- if( !Ustrcmp( target, "XML", status ) && astOK ) {
- astError( AST__XMLPT, "InitXmlPI(xml): Illegal XML PI target \"%s\""
- " supplied.", status, target );
- } else {
- new->target = astStore( NULL, target, strlen( target ) + 1 );
- new->text = astStore( NULL, text, strlen( text ) + 1 );
- }
-}
-
-static void InitXmlPrologue( AstXmlPrologue *new, int type, int *status ){
-/*
-* Name:
-* InitXmlPrologue
-
-* Purpose:
-* Initialise a new XmlPrologue.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* InitXmlPrologue( AstXmlPrologue *new, int type, int *status )
-
-* Description:
-* This function initialises supplied memory to hold an XmlPrologue
-* structure.
-
-* Parameters:
-* new
-* The memory in which to initialise the structure.
-* type
-* An identifier for the structure type.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Check the supplied object type is appropriate for the class of
- structure being initialised. If not report an error. */
- if( !CheckType( type, AST__XMLPRO, status ) ){
- astError( AST__INTER, "InitXmlPrologue: Supplied object type (%d) "
- "does not represent an XmlPrologue", status, type );
- }
-
-/* Initialise the parent XmlObject */
- InitXmlObject( (AstXmlObject *) new, type, status );
-
-/* Initialise the items specific to this class of structure. */
- new->xmldecl = NULL;
- new->misc1 = NULL;
- new->nmisc1 = 0;
- new->dtdec = NULL;
- new->misc2 = NULL;
- new->nmisc2 = 0;
-}
-
-static int MatchName( AstXmlElement *this, const char *name, int *status ){
-/*
-* Name:
-* MatchName
-
-* Purpose:
-* Check that an element has a specified name and/or prefix.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* int MatchName( AstXmlElement *this, const char *name, int *status )
-
-* Description:
-* This function checks that an element has a specified name and/or prefix.
-
-* Parameters:
-* this
-* The XmlElement to check.
-* name
-* The name for the element (may include a namespace prefix).
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* One if the supplied element has the supplie dname/prefix. Zero
-* otherwise.
-
-*/
-
-
-/* Local Variables: */
- const char *colon; /* Pointer to colon within supplied name */
- char *newname; /* Pointer to name string (no prefix) */
- char *newpref; /* Pointer to name string */
- int nc; /* Length of prefix string */
- int result; /* Returned value */
-
-/* Initialise */
- result = 0;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
-/* Extract any prefix from the start of the supplied name. */
- newpref = NULL;
- newname = (char *) name;
- colon = strchr( name, ':' );
- if( colon ) {
- nc = colon - name;
- newpref = astStore( NULL, name, nc + 1 );
- newpref[ nc ] = 0;
-
- nc = strlen( name ) - ( colon - name ) - 1;
- newname = astStore( NULL, colon + 1, nc + 1 );
- newname[ nc ] = 0;
- }
-
-/* Compare the prefix. */
- if( newpref && this->prefix ) {
- result = !strcmp( newpref, this->prefix );
-
- } else if( !newpref && !this->prefix ) {
- result = 1;
-
- } else {
- result = 0;
- }
-
-/* If the prefixes matches, compare the names */
- if( result ) {
- if( newname && this->name ) {
- result = !strcmp( newname, this->name );
-
- } else if( !newname && !this->name ) {
- result = 1;
-
- } else {
- result = 0;
- }
- }
-
-/* Free any name and prefix extracted from the supplied name string */
- if( colon ) {
- newname = astFree( newname );
- newpref = astFree( newpref );
- }
-
-/* Return the result. */
- return result;
-}
-
-static AstXmlAttribute *NewAttribute( const char *name, const char *value,
- const char *prefix, int *status ){
-/*
-* Name:
-* NewAttribute
-
-* Purpose:
-* Create a new XmlAttribute.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlAttribute *NewAttribute( const char *name, const char *value,
-* const char *prefix, int *status )
-
-* Description:
-* This function creates a new XmlAttribute structure representing an
-* XML attribute with the given name, value and namespace prefix.
-
-* Parameters:
-* name
-* Pointer to a null terminated string containing the attribute name.
-* value
-* Pointer to a null terminated string containing the attribute value.
-* prefix
-* Pointer to a null terminated string containing the attribute
-* namespace prefix (may be NULL or blank).
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to the new structure is returned.
-
-* Notes:
-* - A NULL pointer is returned if the inherited status value
-* indicates an error has occurred on entry, or if this function
-* should fail for any reason.
-*/
-
-/* Local Variables: */
- AstXmlAttribute *new; /* The returned pointer */
-
-/* Initialise */
- new = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return new;
-
-/* Allocate space for the new structure. */
- new = (AstXmlAttribute *) astMalloc( sizeof( AstXmlAttribute ) );
-
-/* Initialise it. */
- InitXmlAttribute( new, AST__XMLATTR, name, value, prefix, status );
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) new = astXmlDelete( new );
-
-/* Return the result. */
- return new;
-
-}
-
-static AstXmlDocument *NewDocument( int *status ){
-/*
-* Name:
-* NewDocument
-
-* Purpose:
-* Create a new empty XmlDocument.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlDocument *NewDocument( int *status )
-
-* Description:
-* This function creates a new empty XmlDocument structure representing
-* an entire XML Document.
-
-* Parameters:
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to the new structure is returned.
-
-* Notes:
-* - A NULL pointer is returned if the inherited status value
-* indicates an error has occurred on entry, or if this function
-* should fail for any reason.
-*/
-
-/* Local Variables: */
- AstXmlDocument *new; /* The returned pointer */
-
-/* Initialise */
- new = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return new;
-
-/* Allocate space for the new structure. */
- new = (AstXmlDocument *) astMalloc( sizeof( AstXmlDocument ) );
-
-/* Initialise it. */
- InitXmlDocument( new, AST__XMLDOC, status );
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) new = astXmlDelete( new );
-
-/* Return the result. */
- return new;
-
-}
-
-static AstXmlNamespace *NewNamespace( const char *prefix, const char *uri, int *status ){
-/*
-* Name:
-* NewNamespace
-
-* Purpose:
-* Create a new XmlNamespace.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlNamespace *NewNamespace( const char *prefix,
-* const char *uri, int *status )
-
-* Description:
-* This function creates a new XmlNamespace structure representing an
-* XML namespace with the given prefix and uri.
-
-* Parameters:
-* prefix
-* Pointer to a null terminated string containing the namespace prefix.
-* uri
-* Pointer to a null terminated string containing the associated URI.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to the new structure is returned.
-
-* Notes:
-* - A NULL pointer is returned if the inherited status value
-* indicates an error has occurred on entry, or if this function
-* should fail for any reason.
-*/
-
-/* Local Variables: */
- AstXmlNamespace *new; /* The returned pointer */
-
-/* Initialise */
- new = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return new;
-
-/* Allocate space for the new structure. */
- new = (AstXmlNamespace *) astMalloc( sizeof( AstXmlNamespace ) );
-
-/* Initialise it. */
- InitXmlNamespace( new, AST__XMLNAME, prefix, uri, status );
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) new = astXmlDelete( new );
-
-/* Return the result. */
- return new;
-
-}
-
-static AstXmlPrologue *NewPrologue( AstXmlDocument *doc, int *status ){
-/*
-* Name:
-* NewPrologue
-
-* Purpose:
-* Create a new empty XmlPrologue.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlPrologue *NewPrologue( AstXmlDocument *doc, int *status )
-
-* Description:
-* This function creates a new empty XmlPrologue structure representing
-* an entire prologue.
-
-* Parameters:
-* doc
-* A pointer to the XmlDocument to add the XmlPrologue to, or NULL.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to the new structure is returned.
-
-* Notes:
-* - A NULL pointer is returned if the inherited status value
-* indicates an error has occurred on entry, or if this function
-* should fail for any reason.
-*/
-
-/* Local Variables: */
- AstXmlPrologue *new; /* The returned pointer */
-
-/* Initialise */
- new = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return new;
-
-/* Allocate space for the new structure. */
- new = (AstXmlPrologue *) astMalloc( sizeof( AstXmlPrologue ) );
-
-/* Initialise it. */
- InitXmlPrologue( new, AST__XMLPRO, status );
-
-/* Set its parent. */
- ((AstXmlObject *) new )->parent = (AstXmlParent *) doc;
-
-/* If an error occurred, delete the new structure. */
- if( !astOK ) new = astXmlDelete( new );
-
-/* Return the result. */
- return new;
-
-}
-
-static char *RemoveEscapes( const char *text, int *status ){
-/*
-* Name:
-* RemoveEscapes
-
-* Purpose:
-* Replaces entity references by corresponding ascii characters.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* char *RemoveEscapes( const char *text, int *status )
-
-* Description:
-* This function produces a dynamic copy of the supplied text in which
-* occurrences of XML entity references are replaced by the corresponding
-* ASCII text.
-
-* Parameters:
-* text
-* A pointer to a text string.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to a dynamically allocated string containing the required
-* copy.
-
-* Notes:
-* - NULL is returned if this function is called with the global error
-* status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- char *d; /* Pointer to next returned character */
- char *result; /* Returned pointer */
- char rc; /* Replacement character */
- const char *c; /* Pointer to next supplied character */
- int nc; /* Number of characters to skip */
-
-/* Initialise */
- result = NULL;
- nc = 0;
-
-/* Return if the pointer is NULL or if an error has occurred. */
- if( !astOK || !text ) return result;
-
-/* Allocate memory to hold a copy of the supplied text. */
- result = astMalloc( strlen( text ) + 1 );
-
-/* Check the pointer can be used safely. */
- if( astOK ) {
-
-/* Loop round every character in the supplied text. */
- c = text - 1;
- d = result;
- while( *(++c) ) {
-
-/* If this character marks the start of a entity reference, replace it by
- the corresponding ascii character and shuffle the remaining text down. */
- if( !strncmp( c, "&amp;", 5 ) ) {
- rc = '&';
- nc= 4;
-
- } else if( !strncmp( c, "&lt;", 4 ) ) {
- rc = '<';
- nc= 3;
-
- } else if( !strncmp( c, "&gt;", 4 ) ) {
- rc = '>';
- nc= 3;
-
- } else if( !strncmp( c, "&apos;", 6 ) ) {
- rc = '\'';
- nc= 5;
-
- } else if( !strncmp( c, "&quot;", 6 ) ) {
- rc = '"';
- nc= 5;
-
- } else {
- rc = 0;
- }
-
- if( rc ) {
- *(d++) = rc;
- c += nc;
- } else {
- *(d++) = *c;
- }
-
- }
-
-/* Terminate the returned string. */
- *d = 0;
-
-/* Reallocate the string to free up any unused space. */
- result = astRealloc( result, d - result + 1 );
- }
-
-/* Return the result. */
- return result;
-}
-
-#ifdef DEBUG
-static void RemoveObjectFromList( AstXmlObject *obj ){
-/*
-* Name:
-* RemoveObjectFromList
-
-* Purpose:
-* Removes an XmlObject from a static list of all currently active XmlObjects.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* void RemoveObjectFromList( AstXmlObject *obj )
-
-* Description:
-* This function removes the supplied pointer from a static list of
-* pointers, and decrements the number of elements in the list. This list
-* holds pointers to all the XmlObjects which currently exist. If the
-* supplied pointer is not found in the list, this function returns
-* without action.
-
-* Parameters:
-* this
-* A pointer to the XmlObject.
-
-* Notes:
-* - This function attempts to execute even if an error has already
-* occurred.
-*/
-
-/* Local Variavles: */
- int i;
- int ii;
-
-/* Locate the supplied pointer within the list of pointers to all
- currently active XmlObjects. */
- ii = -1;
- for( i = 0; i < nobj; i++ ){
- if( existing_objects[ i ]->id == obj->id ) {
- ii = i;
- break;
- }
- }
-
-/* Check the pointer was found. */
- if( ii != -1 ) {
-
-/* Shuffle all higher index pointers down one in the list in order to fill
- the gap left by removing the supplied pointer. */
- for( ii++; ii < nobj; ii++ ){
- existing_objects[ ii - 1 ] = existing_objects[ ii ];
- }
-
-/* Decrement the number of pointers in the list. */
- nobj--;
-
-/* Nullify the pointer at the end of the list which is no longer used. */
- existing_objects[ nobj ] = NULL;
- }
-}
-#endif
-
-static const char *ResolvePrefix( const char *prefix, AstXmlElement *elem, int *status ){
-/*
-* Name:
-* ResolvePrefix
-
-* Purpose:
-* Find the URI associated with a namespace prefix.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* const char *ResolvePrefix( const char *prefix, AstXmlElement *elem, int *status)
-
-* Description:
-* This function searches the namespaces defined within the supplied
-* element for a prefix which matches the supplied prefix. If found,
-* it returns a pointer to the URI string associated with the prefix.
-* If not found, it calls this function recursively on the parent
-* element. If there is no parent element, NULL is returned.
-
-* Parameters:
-* prefix
-* Pointer to a string holding the namespace prefix.
-* elem
-* The pointer to the XmlElement.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to a string holding the URI, or NULL if not found.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-*/
-
-/* Local Variables: */
- AstXmlParent *parent; /* Parent object */
- AstXmlNamespace *ns; /* Next namespace */
- const char *result; /* Returned pointer */
- int i; /* Loop count */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status, and the supplied element. */
- if( !astOK || !elem ) return result;
-
-/* Loop round all the namespace definitions in the element. */
- for( i = 0; i < elem->nnspref; i++ ) {
- ns = elem->nsprefs[ i ];
-
-/* Compare the namespace prefix with the supplied prefix (case sensitive).
- Store a pointer to the associated URI if they match, and leave the
- loop. */
- if( !strcmp( ns->prefix, prefix ) ) {
- result = ns->uri;
- break;
- }
- }
-
-/* If no matching namespace was found, attempt to resolve the prefix
- within the context of the parent element. */
- if( !result ) {
- parent = ((AstXmlObject *) elem )->parent;
- if( astXmlCheckType( parent, AST__XMLELEM ) ) {
- result = ResolvePrefix( prefix, (AstXmlElement *) parent, status );
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static int Ustrcmp( const char *a, const char *b, int *status ){
-/*
-* Name:
-* Ustrncmp
-
-* Purpose:
-* A case blind version of strcmp.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* int Ustrcmp( const char *a, const char *b )
-
-* Description:
-* Returns 0 if there are no differences between the two strings, and 1
-* otherwise. Comparisons are case blind.
-
-* Parameters:
-* a
-* Pointer to first string.
-* b
-* Pointer to second string.
-
-* Returned Value:
-* Zero if the strings match, otherwise one.
-
-* Notes:
-* - This function does not consider the sign of the difference between
-* the two strings, whereas "strcmp" does.
-* - This function attempts to execute even if an error has occurred.
-
-*/
-
-/* Local Variables: */
- const char *aa; /* Pointer to next "a" character */
- const char *bb; /* Pointer to next "b" character */
- int ret; /* Returned value */
-
-/* Initialise the returned value to indicate that the strings match. */
- ret = 0;
-
-/* Initialise pointers to the start of each string. */
- aa = a;
- bb = b;
-
-/* Loop round each character. */
- while( 1 ){
-
-/* We leave the loop if either of the strings has been exhausted. */
- if( !(*aa ) || !(*bb) ){
-
-/* If one of the strings has not been exhausted, indicate that the
- strings are different. */
- if( *aa || *bb ) ret = 1;
-
-/* Break out of the loop. */
- break;
-
-/* If neither string has been exhausted, convert the next characters to
- upper case and compare them, incrementing the pointers to the next
- characters at the same time. If they are different, break out of the
- loop. */
- } else {
-
- if( toupper( (int) *(aa++) ) != toupper( (int) *(bb++) ) ){
- ret = 1;
- break;
- }
-
- }
-
- }
-
-/* Return the result. */
- return ret;
-
-}
-
-#ifdef DEBUG
-int astXmlTrace( int show ){
-/*
-*+
-* Name:
-* astXmlTrace
-
-* Purpose:
-* List details of XML objects currently in existence.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* int astXmlTrace( int show )
-
-* Description:
-* Lists details of XML objects currently in existence. Details are
-* written to standard output.
-
-* Parameters:
-* show
-* - 0, the ID values of all currently active XmlObjects are
-* listed. The objects themselves are unchanged.
-* - 1, each object is displayed using astXmlShow unless it has
-* already been included in the display of a previous object, and then
-* annulled. Consequently, this mode is destructive, and none of the
-* displayed XmlObjects will be acessable afterwards.
-* - 2, each object is displayed using astXmlShow whether or not it
-* has already been included in the display of a previous object.
-* The objects are left unchanged.
-* - 3, nothing is written to standard output, but the number of
-* active XmlObjects is still returned.
-
-* Returned Value:
-* The number of XMLObjects which are in existence on entry to this
-* function.
-
-*-
-*/
-
-/* Local Variables: */
- AstXmlObject *root;
- int i, result, old_status;
-
- old_status = astStatus;
- astClearStatus;
-
- result = nobj;
-
- if( show == 0 ) {
- printf( "Current list of active XmlObject identifiers: " );
- for( i = 0; i < nobj; i++ ) printf( "%d ", existing_objects[ i ]->id );
- printf("\n");
-
- } else if( show ==1 ){
- while( nobj > 0 ) {
- root = astXmlGetRoot( existing_objects[0] );
- printf( "ID = %d (type %ld)\n%s\n------------\n",
- root->id, root->type, astXmlShow( root ) );
- root = astXmlAnnulTree( root );
- }
-
- } else if( show == 2 ) {
- for( i = 0; i < nobj; i++ ) printf( "%d\n%s\n------------\n",
- existing_objects[ i ]->id,
- astXmlShow(existing_objects[ i ]) );
- printf("\n");
- }
-
- astSetStatus( old_status );
-
- return result;
-}
-#endif
-
-AstXmlElement *astXmlReadDocument_( AstXmlDocument **doc,
- int (*is_wanted)( AstXmlElement *, int * ),
- int skip, char (*source)( void *, int * ),
- void *data, int *status ){
-/*
-*+
-* Name:
-* astXmlReadDocument
-
-* Purpose:
-* Read and parse an XML document.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlElement *astXmlReadDocument( AstXmlDocument **doc,
-* int (*is_wanted)( AstXmlElement *, int * ),
-* int skip, char (*source)( void *, int * ),
-* void *data )
-
-* Description:
-* This function reads and parses text from an XML source. The text is
-* obtained by calling the supplied "source" function, which returns
-* the next character read from the external source on each invocation.
-*
-* The reading scheme combines elements of the SAX and DOM schemes in
-* an attempt to minimise memory requirements (a potential problem with
-* DOM) whilst retaining a simple interface for accessing the XML
-* elements of interest to the client (a potential problem for SAX).
-*
-* When an element start tag is encountered in the source, the client
-* is asked to indicate whether the element is of interest. This is
-* done by calling the supplied "is_wanted" function. If the client
-* indicates that the element is of interest, its contents are read
-* and a pointer to a corresponding XmlElement structure is returned.
-* Reading stops when the element has been read. If the client
-* indicates that the element is not of interest, then (if "skip" is
-* non-zero) the contents of the element are skipped over, and reading
-* continues following the element end tag. When the next element is
-* encountered the client will again be asked to indicate its interest
-* in the element. This continues until either the client indicates that
-* an element is of interest, or the end of the source is reached. If
-* "skip" is zero, then an error is reported if the first element in
-* the document is not of interest.
-*
-* The client has an option to reply that an element is not itself of
-* interest, but may possibly contain interesting elements. In this case,
-* the sub-elements within the element are read and checked in the same
-* way.
-*
-* This function returns, and no more characters are read from the
-* source, once the contents of the first "interesting" element has been
-* read.
-*
-* The function thus returns a pointer to an XmlElement containing the
-* entire contents of the first interesting element encountered in the
-* source. This function can then be invoked again to read further
-* interesting elements from the source. In this case, the XmlDocument
-* structure created by the initial invocation (see parameter "doc")
-* must be supplied, as this indicates the point in the total document
-* structure at which the previous "interesting" element was located.
-
-* Parameters:
-* doc
-* Address of a location holding a pointer to an AstXmlDocument
-* structure. The AstXmlDocument pointer should be supplied as NULL
-* when invoking this function for the first time on a document
-* source (i.e. when reading from the beginning of the document).
-* In this case a new AstXmlDocument structure will be created and a
-* pointer to it stored at the supplied address. This structure
-* holds the context which enables subsequent invocations of this
-* function to determine the point in the document structure at
-* which to store any further text read from the source. It also
-* holds the document prologue, root element, and epilogue.
-* is_wanted
-* Pointer to a function which is called to decide if the client is
-* interested in each element start tag which has just been read.
-* It has a single argument which is a pointer to the (empty) XmlElement
-* corresponding to the element start tag which has just been read.
-* It returns an integer:
-* -1 : the element is not itself of interest but it may contain
-* an interesting element, so look through the content and
-* ask the client again about any elements found inside it.
-* 0 : the element definately contains nothing of interest to
-* the client. kip its content and continue looking for new
-* elements.
-* 1 : the element is definately of interest to the client so
-* read its contents and return a pointer to it.
-* If NULL is supplied, a value of "+1" is assumed.
-* skip
-* Indicates if any uninteresting elements may proceed the first
-* element of interest. If zero, then an error is reported if the
-* first element read from the source is not of interest to the client.
-* If non-zero, then any uninteresting elements are simply skipped
-* over until an interesting element is found or the document ends.
-* source
-* Pointer to a function which is called to return the next
-* character from the source. It has a single argument which is
-* used to pass any supplied data to it. It should return zero when
-* the end of the source is reached.
-* data
-* Pointer to a structure to pass to the source function. This
-* structure may contain any data needed by the source function.
-
-* Returned Value:
-* A pointer to the first element of interest, or NULL if there are no
-* interesting elements in the source. The returned element will be a
-* descendant of "*doc". For this reason, the returned pointer need not
-* be annulled explicitly since it will be freed when the XmlDocument
-* is annulled. However, if required (e.g. to save memory) it may be
-* annulled before the document is annulled by using astXmlRemoveItem to
-* remove it from its parent, and then using astXmlAnnul to annul it.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-* - It is assumed that the read commences outside any tag (i.e.
-* in between tags or within character data).
-*-
-*/
-
-/* Local Variables: */
- AstXmlElement *result;
-
-/* Check any supplied pointer is for an XmlDocument. */
- astXmlCheckDocument( *doc, 1 );
-
-/* Read and parse the source text. Indicate that the element being read
- *may* contain items of interest to the client. Surround with a mutex
- since the supplied functions may not be thread-safe. */
- LOCK_MUTEX1;
- result = ReadContent( doc, -1, is_wanted, skip, source, data, 0, status );
- UNLOCK_MUTEX1;
-
-/* Return the result. */
- return result;
-}
-
-
-static AstXmlElement *ReadContent( AstXmlDocument **doc, int wanted,
- int (*is_wanted)( AstXmlElement *, int * ),
- int skip, char (*source)( void *, int * ),
- void *data, int depth, int *status ){
-/*
-* Name:
-* ReadContent
-
-* Purpose:
-* Read and parse an XML document.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "xml.h"
-* AstXmlElement *ReadContent( AstXmlDocument **doc, int wanted,
-* int (*is_wanted)( AstXmlElement *, int * ),
-* int skip, char (*source)( void *, int * ),
-* void *data, int depth, int *status )
-
-* Description:
-* This function reads and parses text from an XML source. The text is
-* obtained by calling the supplied "source" function, which returns
-* the next character read from the external source on each invocation.
-*
-* See astXmlReadDocument for more details.
-
-* Parameters:
-* doc
-* Address of a location holding a pointer to an AstXmlDocument
-* structure. The AstXmlDocument pointer should be supplied as NULL
-* when invoking this function for the first time on a document
-* source (i.e. when reading from the beginning of the document).
-* In this case a new AstXmlDocument structure will be created and a
-* pointer to it stored at the supplied address. This structure
-* holds the context which enables subsequent invocations of this
-* function to determine the point in the document structure at
-* which to store any further text read from the source. It also
-* holds the document prologue, root element, and epilogue.
-* wanted
-* Indicates if the content read from the XML source is of interest
-* to the client. If a positive value is supplied, all content read
-* from the source (up to the end tag which corresponds to the
-* supplied "parent") is added to the "parent" element (if supplied).
-* If zero is supplied, then all content read from the source is
-* discarded. If a negative value is supplied, then all content up
-* to the first element start tag is discarded. When the first
-* element start tag is encountered, it is passed back to the client
-* by invoking the supplied "is_wanted" function. If this function
-* returns a non-zero value, then the contents of the new element
-* is read (by calling this function recursively) and a pointer to
-* the new element is returned as the function value (reading then
-* stops and the function returns). If the "is_wanted" function returns
-* zero, then the contents of the new element is skipped over, and
-* reading continues until the next element start tag is encountered,
-* when the "is_wanted" function is again invoked.
-* is_wanted
-* Pointer to a function which is called to decide if the client is
-* interested in the element start tag which has just been read.
-* It has a single argument which is a pointer to the (empty) XmlElement
-* corresponding to the element start tag which has just been read.
-* It returns an integer:
-* -1 : the element is not itself of interest but it may contain
-* an interesting element, so look through the content and
-* ask the client again about any elements found inside it.
-* 0 : the element definately contains nothing of interest to
-* the client. kip its content and continue looking for new
-* elements.
-* 1 : the element is definately of interest to the client so
-* read its contents and return a pointer to it.
-* If NULL is supplied, a value of "+1" is assumed.
-* skip
-* Indicates if any uninteresting elements may proceed the first
-* element of interest. If zero, then an error is reported if the
-* first element read from the source is not of interest to the client.
-* If non-zero, then any uninteresting elements are simply skipped
-* over until an interesting element is found or the document ends.
-* source
-* Pointer to a function which is called to return the next
-* character from the source. It has a single argument which is
-* used to pass any supplied data to it. It should return zero when
-* the end of the source is reached.
-* data
-* Pointer to a structure to pass to the source function. This
-* structure may contain any data needed by the source function.
-* depth
-* Depth of nesting (i.e. zero if this function was invoked from
-* astXmlReadDocument, and a positive value if it was invoked
-* recursively from within itself).
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to the first element of interest, or NULL if there are no
-* interesting elements in the source. If the first element of
-* interest has already been found (as indicated by "wanted" being +1)
-* then NULL is returned. The returned element may be a child of a
-* parent element containing namespace definitions (which may itself
-* have a parent, etc). For this reason, the returned pointer should be
-* freed using astXmlAnnulTree rather than astXmlAnnul.
-
-* Notes:
-* - NULL is returned if an error has already occurred, or if this
-* function should fail for any reason.
-* - It is assumed that the read commences outside any tag (i.e.
-* in between tags or within character data).
-*/
-
-/* Local Variables; */
- AstXmlElement *answer; /* Result of reading a sub-element */
- AstXmlElement *parent; /* Pointer to current parent element */
- AstXmlElement *elem; /* A new element to be read */
- AstXmlElement *result; /* The returned pointer */
- char *cc; /* Pointer to next character */
- char *msg; /* Pointer to message buffer */
- char *text1; /* Pointer to dynamic string */
- char *text2; /* Pointer to another dynamic string */
- char *text3; /* Pointer to another dynamic string */
- char *text4; /* Pointer to another dynamic string */
- char c; /* Current character read from source */
- char lc2; /* Last but one character read */
- char lc; /* Last character read */
- char quoted; /* Character which opened current quote */
- int nc1; /* No. of characters stored in text1 */
- int nc2; /* No. of characters stored in text2 */
- int nc3; /* No. of characters stored in text2 */
- int ncmsg; /* Length of "msg" */
- int newwanted; /* Is the new element wanted? */
- int state; /* Current action being performed */
- int prolog_ok; /* OK for source to start with a prolog? */
- int where; /* Where to add the item within the document */
-
-/* Initialise */
- result = NULL;
- elem = NULL;
-
-/* Check the global error status. */
- if( !astOK ) return result;
-
-/* If no XmlDocument was supplied, assume we are commencing to read a new
- document from the begining. Create a new XmlDocument to store the
- prologue, root element and epilogue, together with a pointer to the
- "current" element, i.e. the element whose content is currently being
- read. Also, since we have not yet asked the client if it is interested
- in anything, ignore the supplied "wanted" value and use -1 to ensure
- that we ask the client when the first element start tag is encountered. */
- if( !*doc ){
- prolog_ok = 1;
- *doc = NewDocument( status );
- wanted = -1;
- } else {
- prolog_ok = 0;
- }
-
-/* Any content read from the source (except for prologue and epilogue)
- will be placed into the "parent" element. A pointer to this element is
- stored in the XmlDocument structure. The parent element will always be
- a descendant of the root element, or the root element itself. */
- parent = (*doc)->current;
-
-/* If the supplied parent has already been completed (typically because
- it was read from an empty element tag), then just return without
- action. */
- if( parent && parent->complete ) {
-
-/* If an error has occurred, or if this invocation of ReadContent was
- made recursively (rather than by the client), or if we have something
- to return, return. */
- if( !astOK || depth > 0 || result ) {
- return result;
-
-/* Otherwise, returning would result in returning a null pointer to the
- client even though the end of the document may not have been reached.
- Revert to state 0 and search for further interesting elements. */
- } else {
- if( parent != (*doc)->root ) {
- (*doc)->current = (AstXmlElement *) ( (AstXmlObject *) parent )->parent;
- } else {
- (*doc)->current = NULL;
- }
- parent = (*doc)->current;
- state = 0;
- }
- }
-
-/* Initialise the previous two characters read. */
- lc = 0;
- lc2 = 0;
-
-/* Initialise pointer to dynamically allocated strings. */
- text1 = NULL;
- text2 = NULL;
- text3 = NULL;
- msg = NULL;
-
-/* We are not in a quote. */
- quoted = 0;
-
-/* Initialise the "state" variable which indicates what we are currently
- looking for. */
- state = 0;
-
-/* Loop round reading characters from the source. */
- while( 1 ) {
- c = (*source)( data, status );
-
-/* Leave the loop if an error occurred whilst reading the character. */
- if( !astOK ) break;
-
-/* If a parent element has been supplied, (i.e. if we are currently
- reading the content of an element), or if we are not in state zero,
- report an error and leave the loop if the end of the text has been
- reached. If no parent was supplied, just leave the loop. */
- if( !c ) {
- if( parent ) {
- astError( AST__XMLWF, "astRead(XmlChan): End of XML input text "
- "reached whilst reading the content of element %s.", status,
- astXmlGetTag( parent, 1 ) );
-
- } else if( state > 1 ) {
- if( msg ) {
- astError( AST__XMLWF, "astRead(XmlChan): End of XML input text "
- "reached whilst reading the document epilogue "
- "(\"%s\").", status, msg );
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): End of XML input text "
- "reached whilst reading the document epilogue." , status);
- }
- }
- break;
- }
-
-/* Save text which is not character data for use in error messages. */
- if( state < 2 ) {
- if( msg ) msg = astFree( msg );
- } else {
- msg = AppendChar( msg, &ncmsg, c, status );
- }
-
-/* State 0: Use the first character to decide what sort of content item
- follows (character data or a tag of some form). */
- if( state == 0 ) {
- if( c != '<' ) {
- state = 1;
- text1 = AppendChar( text1, &nc1, c, status );
- } else {
- msg = AppendChar( msg, &ncmsg, '<', status );
- state = 2;
- }
-
-/* State 1: We are reading character data. The character data ends at the
- first occurrence of "<", at which point the character data is added to
- the parent if required and we continue to state 2.*/
- } else if( state == 1 ) {
- if( c != '<' ) {
- text1 = AppendChar( text1, &nc1, c, status );
- } else {
- msg = AppendChar( msg, &ncmsg, '<', status );
- if( text1 ){
-
-/* If we have a parent element, just add it to the element. */
- if( parent ) {
- if( wanted > 0 ) {
- text4 = RemoveEscapes( text1, status );
- astXmlAddCharData( (AstXmlParent *) parent, 0, text4 );
- text4 = astFree( text4 );
-
-
-/* If we are not allowed to skip over non-blank content, report an
- error if the text is not blank. */
- } else if( !skip ) {
- cc = text1 - 1;
- while( *(++cc) ) {
- if( !isspace( *cc ) ) {
- if( parent ) {
- astError( AST__BADIN, "astRead(XmlChan): Cannot interpret "
- "the input data \"%s\" within element %s.", status,
- text1, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__BADIN, "astRead(XmlChan): Cannot interpret "
- "the input data: \"%s\".", status, text1 );
- }
- break;
- }
- }
- }
-
-/* Otherwise, add it to the document prologue or epilogue. */
- } else {
- if( (*doc)->root ) {
- where = 3;
- } else if( (*doc)->prolog && (*doc)->prolog->dtdec ){
- where = 2;
- } else {
- where = 1;
- }
-
- text4 = RemoveEscapes( text1, status );
- astXmlAddCharData( (AstXmlParent *) *doc, where, text4 );
- text4 = astFree( text4 );
- }
-
- text1 = astFree( text1 );
- }
- state = 2;
- }
-
-/* State 2: We are using the character following a "<" to determine what
- type of tag is commencing. */
- } else if( state == 2 ) {
-
-/* If the character is a ">", report an error. */
- if( c == '>' ) {
- if( parent ) {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"<>\" "
- "encountered within element %s.", status, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"<>\" "
- "encountered." , status);
- }
- break;
-
-/* If the character is a "?", this must be a PI tag. */
- } else if( c == '?' ) {
- state = 3;
-
-/* If the character is a "!", it must be a comment or a CDATA section
- or a DTD. */
- } else if( c == '!' ) {
- state = 4;
-
-/* If the character is a "/", it must be an element end tag. */
- } else if( c == '/' ) {
- state = 5;
-
-/* Otherwise, this must be an element start tag. Append the character
- to "text1". */
- } else {
- state = 6;
- text1 = AppendChar( text1, &nc1, c, status );
- }
-
-/* State 3: We are reading the initial text following the opening "<?" string
- of a PI tag. The characters between the initial "<?" string and the first
- space or closing "?>" string is the target text. */
- } else if( state == 3 ) {
- if( c == '>' && lc == '?' ) {
- if( text1 ) text1[ --nc1 ] = 0;
- state = 100;
- } else if( isspace( c ) ) {
- state = 7;
- } else {
- text1 = AppendChar( text1, &nc1, c, status );
- }
-
-/* State 4: We are using the characters following the opening "<!" text to
- determine if the tag is a comment, DTD or CDATA section. */
- } else if( state == 4 ) {
- if( c == '-' ) {
- state = 8;
- } else if( c == 'D' ){
- state = 16;
- text1 = astAppendString( text1, &nc1, "<!D" );
- } else if( c == '[' ){
- state = 9;
- text1 = astAppendString( text1, &nc1, "<![" );
- } else {
- if( parent ) {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"<!%c...\" encountered within "
- "element %s.", status, c, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"<!%c...\" encountered.", status, c );
- }
- break;
- }
-
-/* State 5: We are looking for the end of an element end tag. */
- } else if( state == 5 ) {
- if( c == '>' ) {
- state = 101;
- } else {
- text1 = AppendChar( text1, &nc1, c, status );
- }
-
-/* State 6: We are looking for the (prefix:)name combination at the start of
- an element start tag. */
- } else if( state == 6 ) {
- if( c == '>' ) {
- state = ( lc != '/' ) ? 102 : 103;
- } else if( isspace( c ) ) {
- state = 104;
- } else if( c != '/' ){
- text1 = AppendChar( text1, &nc1, c, status );
- }
-
-/* State 7: We are reading the remaining text in a PI tag following the target
- text. */
- } else if( state == 7 ) {
- if( c == '>' && lc == '?' ) {
- if( text2 ) text2[ --nc2 ] = 0;
- state = 100;
- } else if( text2 || !isspace( c ) ) {
- text2 = AppendChar( text2, &nc2, c, status );
- }
-
-/* State 8: We are looking for the start of the text within a comment tag. */
- } else if( state == 8 ) {
- if( c == '-' ) {
- state = 10;
- } else {
- if( parent ) {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"<!-%c...\" encountered within "
- "element %s.", status, c, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"<!-%c...\" encountered.", status, c );
- }
- break;
- }
-
-/* State 9: We are looking for the start of the text within a CDATA tag. */
- } else if( state == 9 ) {
- if( c == '[' ) {
- if( !strcmp( text1, "<![CDATA" ) ) {
- state = 11;
- text1 = astFree( text1 );
- } else {
- if( parent ) {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"%s%c...\" encountered within "
- "element %s.", status, text1, c, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"%s%c...\" encountered.", status, text1, c );
- }
- text1 = astFree( text1 );
- break;
- }
-
- } else if( nc1 < 10 ) {
- text1 = AppendChar( text1, &nc1, c, status );
-
- } else {
- if( parent ) {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"%s%c...\" encountered within "
- "element %s.", status, text1, c, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"%s%c...\" encountered.", status, text1, c );
- }
- text1 = astFree( text1 );
- break;
- }
-
-/* State 10: We are reading the remaining text in a comment tag. When the end
- ">" is reached, check the previous 2 characters are "--" and then terminate
- the text1 string in order to remove these two characters from the comment
- text. */
- } else if( state == 10 ) {
- if( c == '>' && lc == '-' && lc2 == '-' ) {
- text1[ nc1 - 2 ] = 0;
- state = 105;
- } else {
- text1 = AppendChar( text1, &nc1, c, status );
- }
-
-/* State 11: We are reading the remaining text in a CDATA tag. */
- } else if( state == 11 ) {
- if( c == '>' && lc == ']' && lc2 == ']' ) {
- text1[ nc1 - 2 ] = 0;
- state = 106;
- } else {
- text1 = AppendChar( text1, &nc1, c, status );
- }
-
-/* State 12: We are looking for an equals sign marking the end of an
- attribute name within an element start tag. */
- } else if( state == 12 ) {
- if( c == '=' ) {
- state = 13;
-
- } else if( c == '>' ) {
- if( text1 ) {
- if( parent ) {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- " \"%s...\" encountered within element %s.", status, msg,
- astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s...\" "
- "encountered.", status, msg );
- }
- break;
- } else {
- if( lc == '/' ) {
- state = 108;
- } else {
- state = 200;
- }
- }
-
- } else if( text1 || !isspace( c ) ) {
- if( c != '/' ) text1 = AppendChar( text1, &nc1, c, status );
- }
-
-/* State 13: We are looking for a '"' or ''' marking the start of an attribute
- value within an element start tag. */
- } else if( state == 13 ) {
- if( c == '"' ) {
- state = 14;
-
- } else if( c == '\'' ) {
- state = 15;
-
- } else if( c == '>' ) {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal value for attribute "
- "\"%s\" in XML tag \"%s...\".", status, text1, msg );
- break;
- }
-
-/* State 14: We are looking for a '"' marking the end of an attribute value
- within an element start tag. */
- } else if( state == 14 ) {
- if( c == '"' ) {
- state = 107;
-
- } else if( c == '>' ) {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal value for attribute "
- "\"%s\" in XML tag \"%s...\".", status, text1, msg );
- break;
-
- } else {
- text2 = AppendChar( text2, &nc2, c, status );
- }
-
-/* State 15: We are looking for a ''' marking the end of an attribute value
- within an element start tag. */
- } else if( state == 15 ) {
- if( c == '\'' ) {
- state = 107;
-
- } else if( c == '>' ) {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal value for attribute "
- "\"%s\" in XML tag \"%s...\".", status, text1, msg );
- break;
-
- } else {
- text2 = AppendChar( text2, &nc2, c, status );
- }
-
-/* State 16: We are looking for the end of a DOCTYPE string. */
- } else if( state == 16 ) {
- if( isspace( c ) ) {
- if( !strcmp( text1, "<!DOCTYPE" ) ) {
- state = 17;
- text1 = astFree( text1 );
- } else {
- if( parent ) {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"%s%c...\" encountered within "
- "element %s.", status, text1, c, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"%s%c...\" encountered.", status, text1, c );
- }
- text1 = astFree( text1 );
- break;
- }
-
- } else if( nc1 < 15 ) {
- text1 = AppendChar( text1, &nc1, c, status );
-
- } else {
- if( parent ) {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"%s%c...\" encountered within "
- "element %s.", status, text1, c, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag "
- "starting with \"%s%c...\" encountered.", status, text1, c );
- }
- text1 = astFree( text1 );
- break;
- }
-
-/* State 17: We are looking for the start of a DOCTYPE name string. */
- } else if( state == 17 ) {
- if( !isspace( c ) ) {
- text1 = AppendChar( text1, &nc1, c, status );
- state = 18;
- }
-
-/* State 18: We are looking for the end of a DOCTYPE name string. */
- } else if( state == 18 ) {
- if( isspace( c ) ) {
- state = 19;
- } else if( c == '>' ) {
- state = 109;
- } else {
- text1 = AppendChar( text1, &nc1, c, status );
- }
-
-/* State 19: We are looking for the start of a string following a DOCTYPE
- name string. */
- } else if( state == 19 ) {
- if( !isspace( c ) ) {
- if( c == '[' ) {
- state = 20;
- } else if( c == '>' ) {
- state = 109;
- } else {
- state = 21;
- text2 = AppendChar( text2, &nc2, c, status );
- }
- }
-
-/* State 20: We are looking for the "]" marking the end of the internal
- markup of a DOCTYPE element. Avoid the contents of quoted strings (such
- as #FIXED attribute values). */
- } else if( state == 20 ) {
- text3 = AppendChar( text3, &nc3, c, status );
- if( c == '\'' ) {
- if( quoted == '\'' ) {
- quoted = 0;
- } else if( !quoted ) {
- quoted = '\'';
- }
-
- } else if( c == '"' ) {
- if( quoted == '"' ) {
- quoted = 0;
- } else if( !quoted ) {
- quoted = '"';
- }
-
- } else if( !quoted && c == ']' ) {
- text3[ --nc3 ] = 0;
- state = 22;
- }
-
-/* State 21: We are looking for the start of a DOCTYPE internal section. */
- } else if( state == 21 ) {
- if( c == '[' ) {
- state = 20;
- } else if( c == '>' ) {
- state = 109;
- } else {
- text2 = AppendChar( text2, &nc2, c, status );
- }
-
-/* State 22: We are looking for the ">" at the end of a DOCTYPE. */
- } else if( state == 22 ) {
- if( !isspace( c ) ) {
- if( c == '>' ) {
- state = 109;
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Extra text found "
- "at end of XML DOCTYPE tag \"%s\".", status, msg );
- }
- }
-
- } else {
- astError( AST__INTER, "ReadContent(xml): Illegal state (%d) encountered "
- "(AST internal programming error).", status, state );
- }
-
-/* The following states perform actions consequent on the decisons made
- above, but which must be performed before reading the next character. */
-
-/* In most cases there will be no actions to perform. Therefore check for
- this first (to avoid the time spent doing all the following usually
- irrelevant checks). */
- if( state < 23 ) {
-
-/* State 100: We have just reached the end of a PI tag. Create a new XmlPI and
- store it in the parent (if required). */
- } else if( state == 100 ) {
- if( text1 ){
-
-/* First deal with XML declaration PI's. These must be the first item in
- the source. */
- if( !strcmp( text1, "xml" ) ) {
- if( (*doc)->root || (*doc)->prolog || (*doc)->nepi > 0 ) {
- astError( AST__XMLWF, "astRead(XmlChan): An XML "
- "declaration \"%s\" was encountered within the "
- "body of the document.", status, msg );
- } else {
- astXmlSetXmlDec( *doc, text2 );
- }
-
-/* Now deal with other PI's. */
- } else {
-
-/* If we have a parent element, just add it to the element. */
- if( parent ) {
- if( wanted > 0 ) {
- astXmlAddPI( (AstXmlParent *) parent, 0, text1, text2 );
- } else if( !skip ) {
- if( parent ) {
- astError( AST__BADIN, "astRead(XmlChan): Cannot interpret "
- "the input data \"%s\" within element %s.", status,
- msg, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__BADIN, "astRead(XmlChan): Cannot interpret "
- "the input data: \"%s\".", status, msg );
- }
- break;
- }
-
-/* Otherwise, add it to the document prologue or epilogue. */
- } else {
- if( (*doc)->root ) {
- where = 3;
- } else if( (*doc)->prolog->dtdec ){
- where = 2;
- } else {
- where = 1;
- }
- astXmlAddPI( (AstXmlParent *) *doc, where, text1, text2 );
-
- }
- }
- text1 = astFree( text1 );
- if( text2 ) text2 = astFree( text2 );
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" "
- "encountered.", status, msg );
- break;
- }
- state = 0;
-
-/* State 101: We have just reached the end of an element end tag. Check that
- the (prefix:)name is legal, and matches that of the current parent,
- re-instate the parent's parent as the current element in the document,
- and leave the loop if appropriate. */
- } else if( state == 101 ) {
- if( text1 ){
- CheckPrefName( text1, "element", "astRead(XmlChan)", status );
- if( parent ) {
- if( MatchName( parent, text1, status ) ) {
- parent->complete = 1;
- if( parent != (*doc)->root ) {
- (*doc)->current = (AstXmlElement *) ( (AstXmlObject *) parent )->parent;
- } else {
- (*doc)->current = NULL;
- }
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Start tag \"%s\" "
- "closed by end tag \"%s\".", status, astXmlGetTag( parent, 1 ),
- msg );
- }
-
- } else {
- (*doc)->current = NULL;
- astError( AST__XMLWF, "astRead(XmlChan): Unmatched end tag "
- "\"%s\" encountered.", status, msg );
- }
-
- text1 = astFree( text1 );
-
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" "
- "encountered.", status, msg );
- }
-
-/* If an error has occurred, or if this invocation of ReadContent was
- made recursively (rather tnan by the client), or if we have something
- to return, break out of the loop. */
- if( !astOK || depth > 0 || result ) {
- break;
-
-/* Otherwise, breaking would result in returning a null pointer to the
- client even though the end of the document may not have been reached.
- Revert to state 0 and search for further intersting elements. */
- } else {
- parent = (*doc)->current;
- state = 0;
- }
-
-/* State 102: We have just got the (prefix:)name for an element start tag, and
- the start tag contains no attributes, etc. Create a new XmlElement, adding
- it to the supplied parent, and then proceed to state 200 to read the
- content of the element. */
- } else if( state == 102 ) {
- if( text1 ){
- elem = astXmlAddElement( parent, text1, NULL );
- text1 = astFree( text1 );
- state = 200;
-
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" "
- "encountered.", status, msg );
- break;
- }
-
-/* State 103: We have just got the (prefix:)name for an empty element tag, and
- the tag does not contain further attributes, etc. Create a new XmlElement
- and store it in the container (if any). Indicate that there is no
- content to read, and then go on to state 200. */
- } else if( state == 103 ) {
- if( text1 ){
- elem = astXmlAddElement( parent, text1, NULL );
- elem->complete = 1;
- text1 = astFree( text1 );
- state = 200;
-
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" "
- "encountered.", status, msg );
- break;
- }
-
-/* State 104: We have just got the (prefix:)name for an element start tag, but
- the start tag may contain further attributes, etc. Create a new XmlElement
- and store it in the container (if any). Then go to state 12 in which we
- look for further attributes, etc. */
- } else if( state == 104 ) {
- if( text1 ){
- elem = astXmlAddElement( parent, text1, NULL );
- text1 = astFree( text1 );
- state = 12;
-
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" "
- "encountered.", status, msg );
- break;
- }
-
-/* State 105: We have just reached the end of a comment tag. Create a new
- XmlComment and store it in the parent. */
- } else if( state == 105 ) {
- if( text1 ){
-
-/* If we have a parent element, just add it to the element. */
- if( parent ) {
- if( wanted > 0 ) {
- astXmlAddComment( (AstXmlParent *) parent, 0, text1 );
- } else if( !skip ) {
- if( parent ) {
- astError( AST__BADIN, "astRead(XmlChan): Cannot interpret "
- "the input data \"%s\" within element %s.", status,
- msg, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__BADIN, "astRead(XmlChan): Cannot interpret "
- "the input data: \"%s\".", status, msg );
- }
- break;
- }
-
-/* Otherwise, add it to the document prologue or epilogue. */
- } else {
- if( (*doc)->root ) {
- where = 3;
- } else if( (*doc)->prolog->dtdec ){
- where = 2;
- } else {
- where = 1;
- }
- astXmlAddComment( (AstXmlParent *) *doc, where, text1 );
- }
-
- text1 = astFree( text1 );
-
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" "
- "encountered.", status, msg );
- break;
- }
- state = 0;
-
-/* State 106: We have just reached the end of a CDATA tag. Create a new
- XmlCDATASection and store it in the container (if any). */
- } else if( state == 106 ) {
- if( text1 ){
- if( parent && wanted > 0 ) {
- astXmlAddCDataSection( parent, text1 );
- } else if( !skip ) {
- if( parent ) {
- astError( AST__BADIN, "astRead(XmlChan): Cannot interpret "
- "the input data \"%s\" within element %s.", status,
- msg, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__BADIN, "astRead(XmlChan): Cannot interpret "
- "the input data: \"%s\".", status, msg );
- }
- break;
- }
- text1 = astFree( text1 );
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" "
- "encountered.", status, msg );
- break;
- }
- state = 0;
-
-/* State 107: We have just reached the end of an attribute or namespace
- setting. Create a new object and store it in the element created
- earlier. */
- } else if( state == 107 ) {
- if( text1 ){
- if( !elem ) {
- astError( AST__INTER, "ReadContent(xml): Container lost at state "
- "107 (AST internal programming error).", status );
- break;
- }
-
- if( !strcmp( text1, "xmlns" ) ) {
- astXmlAddURI( elem, NULL, text2 );
-
- } else if( !strncmp( text1, "xmlns:", 6 ) ) {
- astXmlAddURI( elem, text1+6, text2 );
-
- } else {
- text4 = RemoveEscapes( text2, status );
- astXmlAddAttr( elem, text1, text4, NULL );
- text4 = astFree( text4 );
- }
-
- text1 = astFree( text1 );
- text2 = astFree( text2 );
-
- } else {
- astError( AST__XMLWF, "astRead(XmlChan): Illegal XML tag \"%s\" "
- "encountered.", status, msg );
- break;
- }
- state = 12;
-
-/* State 108: We have just reached the end of an empty element tag to which
- we have been adding attributes, etc. */
- } else if( state == 108 ) {
- if( elem ) {
- elem->complete = 1;
- state = 200;
- } else {
- astError( AST__INTER, "Parse(xml): No container in state 108 "
- "(AST internal programming error).", status );
- break;
- }
-
-/* State 109: We have just reached the end of a DOCTYPE tag. */
- } else if( state == 109 ) {
-
- if( (*doc)->root ){
- astError( AST__XMLWF, "astRead(XmlChan): An DOCTYPE tag "
- "\"%s\" was encountered within the body of the "
- "document.", status, msg );
- break;
-
- } else if( (*doc)->prolog->dtdec ){
- astError( AST__XMLWF, "astRead(XmlChan): Multiple DOCTYPE tags "
- "encountered." , status);
- break;
-
- } else {
- astXmlSetDTDec( *doc, text1, text2, text3 );
- text1 = astFree( text1 );
- text2 = astFree( text2 );
- text3 = astFree( text3 );
- state = 0;
- }
-
- } else if( state != 200 ) {
- astError( AST__INTER, "ReadContent(xml): Illegal state (%d) encountered "
- "(AST internal programming error).", status, state );
- }
-
-
-
-/* State 200: We now have now read a complete element start tag and have
- a corresponding XmlElement ("elem"), with all attributes and namespaces,
- etc (but no content). Call the "is_wanted" function to see if the client
- is interested in the element. */
- if( state == 200 ) {
-
-/* If this element is found at the root level of the document, store a
- pointer to it as the root element. Report an error if there is already
- a root element. */
- if( !parent ) {
- if( (*doc)->root ){
- if( astOK ) {
- astError( AST__XMLWF, "astRead(XmlChan): Multiple root "
- "elements encountered." , status);
- elem = astXmlDelete( elem );
- }
- break;
- } else {
- (*doc)->root = elem;
- ((AstXmlObject *) elem )->parent = (AstXmlParent *) (*doc);
- }
- }
-
-/* If we do not already know, ask the caller if it is interested in this new
- element. If no "is_wanted" function was supplied, assume all elements
- are interesting. */
- if( wanted == -1 ) {
- newwanted = is_wanted ? (*is_wanted)( elem, status ) : 1;
- } else {
- newwanted = wanted;
- }
-
-/* If it is not interested, report an error if skip is zero. */
- if( newwanted != 1 && !skip ) {
- if( parent ) {
- astError( AST__BADIN, "astRead(XmlChan): Cannot interpret "
- "the input data \"%s\" within element %s.", status,
- msg, astXmlGetTag( parent, 1 ) );
- } else {
- astError( AST__BADIN, "astRead(XmlChan): Cannot interpret "
- "the input data: \"%s\".", status, msg );
- }
- break;
- }
-
-/* Make the new element the "current" element in the document. */
- (*doc)->current = elem;
-
-/* Read the contents of the new element from the source. If the client is
- interested in the element, the read contents will be added to the
- element, otherwise they will be discarded after being read. */
- answer = ReadContent( doc, newwanted, is_wanted, skip, source,
- data, depth + 1, status );
-
-/* If the first interesting element was found inside "elem", then
- return it. If "elem" is not interesting and did not contain anything
- of interest, delete it and return the initialised NULL pointer. */
- if( newwanted < 0 ) {
- if( answer ) {
- result = answer;
- } else {
- elem = astXmlDelete( elem );
- }
-
-/* If the elem is of no interest, delete it and return the initialised
- NULL pointer. */
- } else if( newwanted == 0 ) {
- elem = astXmlDelete( elem );
-
-/* Otherwise, "elem" itself is definitely of interest. If "elem" is
- the first item of interest, return it. */
- } else if( wanted < 0 ) {
- result = elem;
- }
-
-/* If we have an answer to return, leave the loop, otherwise re-instate the
- original current element in the document and continue to read any text
- following the element. */
- if( result ) {
- break;
- } else {
- (*doc)->current = parent;
- state = 0;
- }
-
- } if( state > 22 ) {
- astError( AST__INTER, "ReadContent(xml): Illegal state (%d) encountered "
- "(AST internal programming error).", status, state );
- }
-
-/* Remember the previous two character */
- lc2 = lc;
- lc = c;
- }
-
-/* Free any dynamic strings */
- text1 = astFree( text1 );
- text2 = astFree( text2 );
- text3 = astFree( text3 );
- if( msg ) msg = astFree( msg );
-
-/* Delete the returned object if an error occurred. */
- if( !astOK ) result = astXmlDelete( result );
-
-/* Return the result. */
- return result;
-}
-
-
-