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 )