Starlink-AST
view release on metacpan or search on metacpan
ast/src/xml.c view on Meta::CPAN
* 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;
}
ast/src/xml.c view on Meta::CPAN
/* 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:
ast/src/xml.c view on Meta::CPAN
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:
( run in 1.346 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )