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