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 )