Logo Search packages:      
Sourcecode: tclxml version File versions  Download package

tclexpat.c

/*
 * tclexpat.c --
 *
 *    TclXML driver for James Clark's expat XML parser
 *
 * Copyright (c) 1998-2003 Steve Ball, Zveno Pty Ltd
 *
 * See the file "LICENSE" for information on usage and
 * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * $Id: tclexpat.c,v 1.19 2004/02/20 09:15:39 balls Exp $
 *
 */

#include <tcl.h>
#include <tclxml/tclxml.h>
#include <xmlparse.h>

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT

/*
 * The structure below is used to refer to an expat parser object.
 */

typedef struct TclExpatInfo {
  XML_Parser parser;          /* The expat parser structure */
  Tcl_Interp *interp;         /* Interpreter for this instance */

  TclXML_Info *xmlinfo;       /* Generic data structure */

} TclExpatInfo;

/*
 * Prototypes for procedures defined later in this file:
 */

static ClientData TclExpatCreate _ANSI_ARGS_((Tcl_Interp *interp, 
                    TclXML_Info *xmlinfo));
static ClientData TclExpatCreateEntityParser _ANSI_ARGS_((
                    Tcl_Interp *interp, ClientData clientData));
static int  TclExpatDelete _ANSI_ARGS_((ClientData clientData));
static int  TclExpatParse _ANSI_ARGS_((ClientData clientData, 
                    char *data, int len, int final));
static int  TclExpatConfigure _ANSI_ARGS_((ClientData clientdata, 
                                     Tcl_Obj *CONST optionPtr,
                                     Tcl_Obj *CONST valuePtr));
static int  TclExpatCget _ANSI_ARGS_((ClientData clientData, 
                    int objc, Tcl_Obj *CONST objv[]));
static int  TclExpatGet _ANSI_ARGS_((ClientData clientData, 
                    int objc, Tcl_Obj *CONST objv[]));

static void TclExpatElementStartHandler _ANSI_ARGS_((
                  void *userData,
                const XML_Char *name,
                const XML_Char **atts));
static void TclExpatElementEndHandler _ANSI_ARGS_((
                    void *userData,
                const XML_Char *name));
static void TclExpatCharacterDataHandler _ANSI_ARGS_((
                    void *userData,
                const XML_Char *s,
                int len));
static void TclExpatProcessingInstructionHandler _ANSI_ARGS_((
                    void *userData,
                const XML_Char *target,
                const XML_Char *data));
static void TclExpatDefaultHandler _ANSI_ARGS_((
                    void *userData,
                const XML_Char *s,
                int len));
static void TclExpatUnparsedDeclHandler _ANSI_ARGS_((
                void *userData,
                const XML_Char *entityName,
                const XML_Char *base,
                const XML_Char *systemId,
                const XML_Char *publicId,
                const XML_Char *notationName));
static void TclExpatNotationDeclHandler _ANSI_ARGS_((
                void *userData,
                const XML_Char *notationName,
                const XML_Char *base,
                const XML_Char *systemId,
                const XML_Char *publicId));
static void TclExpatCommentHandler _ANSI_ARGS_((
                void *userData,
                const XML_Char *data));
static int  TclExpatNotStandaloneHandler _ANSI_ARGS_((
                void *userData));
static void TclExpatStartCdataSectionHandler _ANSI_ARGS_((
                void *userData));
static void TclExpatEndCdataSectionHandler _ANSI_ARGS_((
                void *userData));
static void TclExpatElementDeclHandler _ANSI_ARGS_((
                void *userData,
                const XML_Char *name,
                XML_Char ***contentspec));
static void TclExpatAttlistDeclHandler _ANSI_ARGS_((
                void *userData,
                const XML_Char *name,
                XML_Char ***attributes));
static void TclExpatStartDoctypeDeclHandler _ANSI_ARGS_((
                void *userData,
                const XML_Char *doctypeName));
static void TclExpatEndDoctypeDeclHandler _ANSI_ARGS_((
                void *userData));

static int  TclExpatExternalEntityRefHandler _ANSI_ARGS_((
     XML_Parser parser,
     const XML_Char *context,
     const XML_Char *base,
     const XML_Char *systemId,
     const XML_Char *publicId));
static int  TclExpatUnknownEncodingHandler _ANSI_ARGS_((
     void *encodingHandlerData,
     const XML_Char *name,
     XML_Encoding *info
));

EXTERN int  Tclexpat_Init _ANSI_ARGS_((Tcl_Interp *interp));

/*
 *----------------------------------------------------------------------------
 *
 * Tclexpat_Init --
 *
 *    Initialisation routine for loadable module
 *
 * Results:
 *    None.
 *
 * Side effects:
 *    Registers xerces XML parser.
 *
 *----------------------------------------------------------------------------
 */

int
Tclexpat_Init (interp)
     Tcl_Interp *interp; /* Interpreter to initialise. */
{
  TclXML_ParserClassInfo *classinfo;

#ifdef USE_TCL_STUBS
  if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
    return TCL_ERROR;
  }
#endif
#ifdef USE_TCLXML_STUBS
  if (TclXML_InitStubs(interp, TCLXML_VERSION, 1) == NULL) {
    return TCL_ERROR;
  }
#endif

  classinfo = (TclXML_ParserClassInfo *) ckalloc(sizeof(TclXML_ParserClassInfo));
  classinfo->name = Tcl_NewStringObj("expat", -1);
  classinfo->create = TclExpatCreate;
  classinfo->createCmd = NULL;
  classinfo->createEntity = TclExpatCreateEntityParser;
  classinfo->createEntityCmd = NULL;
  classinfo->parse = TclExpatParse;
  classinfo->parseCmd = NULL;
  classinfo->configure = TclExpatConfigure;
  classinfo->configureCmd = NULL;
  classinfo->get = TclExpatGet;
  classinfo->getCmd = NULL;
  classinfo->destroy = TclExpatDelete;
  classinfo->destroyCmd = NULL;
  classinfo->reset = NULL;
  classinfo->resetCmd = NULL;

  if (TclXML_RegisterXMLParser(interp, classinfo) != TCL_OK) {
    Tcl_SetResult(interp, "unable to register parser", NULL);
    return TCL_ERROR;
  }

  if (Tcl_PkgProvide(interp, "xml::expat", TCLXML_VERSION) != TCL_OK) {
    return TCL_ERROR;
  }

  return TCL_OK;
}

/*
 *----------------------------------------------------------------------------
 *
 * TclExpatCreate --
 *
 *    Create an expat parser instance.
 *
 * Results:
 *    Standard Tcl result.
 *
 * Side effects:
 *    This creates an expat parser.
 *
 *----------------------------------------------------------------------------
 */

static ClientData
TclExpatCreate(interp, xmlinfo)
     Tcl_Interp *interp;
     TclXML_Info *xmlinfo;
{
  TclExpatInfo *expat;

  /*
   * Create the data structures for this parser.
   */

  if (!(expat = (TclExpatInfo *) ckalloc(sizeof(TclExpatInfo)))) {
    ckfree((char *)expat);
    Tcl_SetResult(interp, "unable to create parser", NULL);
    return NULL;
  }
  expat->interp = interp;
  expat->xmlinfo = xmlinfo;

  if (!(expat->parser = XML_ParserCreate(NULL))) {
    Tcl_SetResult(interp, "unable to create expat parser", NULL);
    ckfree((char *)expat);
    return NULL;
  }
  
  /*
   * Set all handlers for the parser.
   */

  XML_SetElementHandler(expat->parser, TclExpatElementStartHandler,
                  TclExpatElementEndHandler);
  XML_SetCharacterDataHandler(expat->parser, TclExpatCharacterDataHandler);
  XML_SetProcessingInstructionHandler(expat->parser,
        TclExpatProcessingInstructionHandler);
  XML_SetDefaultHandler(expat->parser, TclExpatDefaultHandler);

  XML_SetUnparsedEntityDeclHandler(expat->parser,
        TclExpatUnparsedDeclHandler);
  XML_SetNotationDeclHandler(expat->parser, TclExpatNotationDeclHandler);

  XML_SetExternalEntityRefHandler(expat->parser,
        TclExpatExternalEntityRefHandler);

  XML_SetUnknownEncodingHandler(expat->parser, TclExpatUnknownEncodingHandler,
        (void *) xmlinfo);
  
  /* Added by ericm@scriptics.com, 1999.6.25 */
  /* Tell expat to use the TclExpat comment handler */
  XML_SetCommentHandler(expat->parser, TclExpatCommentHandler);
  
  /* Tell expat to use the TclExpat "not standalone" handler */
  XML_SetNotStandaloneHandler(expat->parser, TclExpatNotStandaloneHandler);

#ifdef TCLXML_CDATASECTIONS
  /* Tell expat to use the TclExpat CdataSection handlers */
  XML_SetCdataSectionHandler(expat->parser, TclExpatStartCdataSectionHandler,
        TclExpatEndCdataSectionHandler);
#endif /* TCLXML_CDATASECTIONS */

  /* Tell expat to use the TclExpat Element decl handler */
  XML_SetElementDeclHandler(expat->parser, TclExpatElementDeclHandler);

  /* Tell expat to use the TclExpat Attlist decl handler */
  XML_SetAttlistDeclHandler(expat->parser, TclExpatAttlistDeclHandler);

  /* Tell expat to use the TclExpat DOCTYPE decl handlers */
  XML_SetDoctypeDeclHandler(expat->parser,
        TclExpatStartDoctypeDeclHandler,
        TclExpatEndDoctypeDeclHandler);

  XML_SetUserData(expat->parser, (void *) expat);
  
  return (ClientData) expat;
}

/*
 *----------------------------------------------------------------------
 *
 * TclExpatCreateEntity --
 *
 *    Create an expat entity parser, based on the original
 *      parser referred to by parent.
 *
 * Results:
 *    New external entity parser created and initialized.
 *
 * Side effects:
 *    The TclExpatInfo struct pointed to by expat is modified.
 *
 *----------------------------------------------------------------------
 */

static ClientData
TclExpatCreateEntityParser(interp, clientData)
     Tcl_Interp *interp;
     ClientData clientData;
{
  TclExpatInfo *parent = (TclExpatInfo *) clientData;
  TclExpatInfo *expat;

  if (!(expat = (TclExpatInfo *) ckalloc(sizeof(TclExpatInfo)))) {
    ckfree((char *)expat);
    Tcl_SetResult(interp, "unable to create parser", NULL);
    return NULL;
  }
  expat->interp = parent->interp;
  expat->xmlinfo = parent->xmlinfo;

    if (!(expat->parser = XML_ExternalEntityParserCreate(parent->parser,
          (XML_Char *) Tcl_GetUnicode(parent->xmlinfo->context), NULL))) {
      Tcl_SetResult(interp, "unable to create expat external entity parser",
            NULL);
      return NULL;
    }
  
    XML_SetUserData(expat->parser, (void *) expat);
    return (ClientData) expat;
}

/*
 *----------------------------------------------------------------------------
 *
 * TclExpatDelete --
 *
 *    Destroy the expat parser structure.
 *
 * Results:
 *    None.
 *
 * Side effects:
 *    Frees any memory allocated for the XML parser.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatDelete(clientData)
     ClientData clientData;
{
  TclExpatInfo *expat = (TclExpatInfo *) clientData;

  XML_ParserFree(expat->parser);
  ckfree((char *)expat);

  return TCL_OK;
}

/*
 *----------------------------------------------------------------------------
 *
 * TclExpatParse --
 *
 *    Wrapper to invoke expat parser and check return result.
 *
 * Results:
 *     TCL_OK if no errors, TCL_ERROR otherwise.
 *
 * Side effects:
 *     Sets interpreter result as appropriate.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatParse(clientData, data, len, final)
     ClientData clientData;
     char *data;
     int len;
{
  TclExpatInfo *expat = (TclExpatInfo *) clientData;
  int result;
  char s[255];

  result = XML_Parse(expat->parser, 
                 data, len, 
                 final);

  if (!result) {
    Tcl_ResetResult(expat->interp);
    sprintf(s, "%d", XML_GetCurrentLineNumber(expat->parser));
    Tcl_AppendResult(expat->interp, "error \"",
          XML_ErrorString(XML_GetErrorCode(expat->parser)),
          "\" at line ", s, " character ", NULL);
    sprintf(s, "%d", XML_GetCurrentColumnNumber(expat->parser));
    Tcl_AppendResult(expat->interp, s, NULL);

    return TCL_ERROR;
  }

  return TCL_OK;
}

/*
 *----------------------------------------------------------------------------
 *
 * TclExpatConfigure --
 *
 *    Implements instance command for expat class objects.
 *
 * Results:
 *    Depends on the method.
 *
 * Side effects:
 *    Depends on the method.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatConfigure (clientData, optionPtr, valuePtr)
     ClientData clientData;
     Tcl_Obj *CONST optionPtr;
     Tcl_Obj *CONST valuePtr;
{
  TclExpatInfo *expat = (TclExpatInfo *) clientData;
  int index, value, bool;

  static CONST84 char *switches[] = {
    "-baseurl", 
    "-defaultexpandinternalentities",
    "-paramentityparsing",
    (char *) NULL
  };
  enum switches {
    EXPAT_BASE, 
    EXPAT_DEFAULTEXPANDINTERNALENTITIES,
    EXPAT_PARAMENTITYPARSING,
  };
  static CONST84 char *paramEntityParsingValues[] = {
      "always",
      "never",
      "notstandalone"
  };
  enum paramEntityParsingValues {
      EXPAT_PARAMENTITYPARSINGALWAYS,
      EXPAT_PARAMENTITYPARSINGNEVER,
      EXPAT_PARAMENTITYPARSINGNOTSTANDALONE
  };

  if (Tcl_GetIndexFromObj(expat->interp, optionPtr, switches,
                    "switch", 0, &index) != TCL_OK) {
    Tcl_ResetResult(expat->interp);
    return TCL_OK;
  }
  switch ((enum switches) index) {

  case EXPAT_BASE:                  /* -base */

    if (XML_SetBase(expat->parser, (const XML_Char*)Tcl_GetString(valuePtr)) == 0) {
      Tcl_SetResult(expat->interp, "unable to set base URL", NULL);
      return TCL_ERROR;
    }
    break;

  case EXPAT_DEFAULTEXPANDINTERNALENTITIES: 

    /* -defaultexpandinternalentities */
    /* ericm@scriptics */
    if (Tcl_GetBooleanFromObj(expat->interp, valuePtr, &bool) != TCL_OK) {
      return TCL_ERROR;
    }
      
    XML_SetDefaultExpandInternalEntities(expat->parser, bool);

    break;

  case EXPAT_PARAMENTITYPARSING: /* -paramentityparsing */
    /* ericm@scriptics */
    if (Tcl_GetIndexFromObj(expat->interp, valuePtr, paramEntityParsingValues,
                      "value", 0, &value) != TCL_OK) {
      return TCL_ERROR;
    }
    switch ((enum paramEntityParsingValues) value) {
    case EXPAT_PARAMENTITYPARSINGALWAYS:
      XML_SetParamEntityParsing(expat->parser,
                        XML_PARAM_ENTITY_PARSING_ALWAYS);
      break;
    case EXPAT_PARAMENTITYPARSINGNEVER:
      XML_SetParamEntityParsing(expat->parser,
                        XML_PARAM_ENTITY_PARSING_NEVER);
      break;
    case EXPAT_PARAMENTITYPARSINGNOTSTANDALONE:
      XML_SetParamEntityParsing(expat->parser,
                        XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
      break;
    }
    break;

  default:
    return TCL_OK;
    break;

  }

  return TCL_OK;
}

/*
 *----------------------------------------------------------------------------
 *
 * TclExpatGet --
 *
 *    Returns runtime parser information, depending on option
 *      ericm@scriptics.com, 1999.6.28
 *
 * Results:
 *    Option value.
 *
 * Side effects:
 *    None.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatGet (clientData, objc, objv)
     ClientData clientData;
     int objc;
     Tcl_Obj *CONST objv[];
{
  TclExpatInfo *expat = (TclExpatInfo *) clientData;
  static CONST84 char *switches[] = {
    "-specifiedattributecount",
    "-currentbytecount",
    "-currentlinenumber",
    "-currentcolumnnumber",
    "-currentbyteindex",
    (char *) NULL
  };
  enum switches {
    EXPAT_SPECIFIEDATTRCOUNT,
    EXPAT_CURRENTBYTECOUNT,
    EXPAT_CURRENTLINENUMBER,
    EXPAT_CURRENTCOLUMNNUMBER,
    EXPAT_CURRENTBYTEINDEX
  };
  int index, doParse = 0;
  Tcl_Obj *resultPtr;

  if (objc > 1) {
    Tcl_SetResult(expat->interp, "Only one value may be requested at a time", 
              TCL_STATIC);
    return TCL_ERROR;
  }

  if (Tcl_GetIndexFromObj(expat->interp, objv[0], switches,
                    "switch", 0, &index) != TCL_OK) {
    return TCL_ERROR;
  }

  resultPtr = Tcl_GetObjResult(expat->interp);
  
  switch ((enum switches) index) {
    
    case EXPAT_SPECIFIEDATTRCOUNT:

      Tcl_SetIntObj(resultPtr, XML_GetSpecifiedAttributeCount(expat->parser));
      return TCL_OK;
      break;

    case EXPAT_CURRENTBYTECOUNT:
      
      Tcl_SetIntObj(resultPtr, XML_GetCurrentByteCount(expat->parser));
      return TCL_OK;
      break;

    case EXPAT_CURRENTLINENUMBER:
      
      Tcl_SetIntObj(resultPtr, XML_GetCurrentLineNumber(expat->parser));
      return TCL_OK;
      break;

    case EXPAT_CURRENTCOLUMNNUMBER:

      Tcl_SetIntObj(resultPtr, XML_GetCurrentColumnNumber(expat->parser));
      return TCL_OK;
      break;

    case EXPAT_CURRENTBYTEINDEX:
      
      Tcl_SetLongObj(resultPtr, XML_GetCurrentByteIndex(expat->parser));
      return TCL_OK;
      break;

    default:

      return TCL_ERROR;
      break;
  }

  return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------------
 *
 * TclExpat*Handler --
 *
 *    Called by expat for various document features.
 *
 * Results:
 *    None.
 *
 * Side Effects:
 *    Event passed to TclXML generic layer.
 *
 *----------------------------------------------------------------------------
 */

static void TclExpatElementStartHandler(userdata, name, atts)
     void *userdata;
     const XML_Char *name;
     const XML_Char **atts;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;
  Tcl_Obj *attListObj, *nameObj;
  int count;

  attListObj = Tcl_NewListObj(0, NULL);
  Tcl_IncrRefCount(attListObj);
  for (count = 0; atts[count]; count += 2) {
    Tcl_ListObjAppendElement(NULL, attListObj,
                       Tcl_NewStringObj((XML_Char*)atts[count], -1));
    Tcl_ListObjAppendElement(NULL, attListObj,
                       Tcl_NewStringObj((XML_Char*)atts[count + 1], -1));
  }

  nameObj = Tcl_NewStringObj((XML_Char *)name, -1);
  Tcl_IncrRefCount(nameObj);
  TclXML_ElementStartHandler(
        expat->xmlinfo,
      nameObj,
      NULL,
      attListObj,
      NULL);

  Tcl_DecrRefCount(nameObj);
  Tcl_DecrRefCount(attListObj);
}

static void TclExpatElementEndHandler(userdata, name)
     void *userdata;
     const XML_Char *name;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;
  Tcl_Obj *nameObj = Tcl_NewStringObj((XML_Char*)name, -1);
  Tcl_IncrRefCount(nameObj);

  TclXML_ElementEndHandler(expat->xmlinfo, nameObj);

  Tcl_DecrRefCount(nameObj);
}

static void TclExpatCharacterDataHandler(userdata, s, len)
     void *userdata;
     const XML_Char *s;
     int len;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;
  Tcl_Obj *dataObj = Tcl_NewStringObj((XML_Char*)s, len);
  Tcl_IncrRefCount(dataObj);

  TclXML_CharacterDataHandler(expat->xmlinfo, dataObj);

  Tcl_DecrRefCount(dataObj);
}

static void TclExpatProcessingInstructionHandler(userdata, target, data)
     void *userdata;
     const XML_Char *target;
     const XML_Char *data;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;
  Tcl_Obj *dataObj = Tcl_NewStringObj((XML_Char*)data, -1);
  Tcl_Obj *targetObj = Tcl_NewStringObj((XML_Char*)target, -1);
  Tcl_IncrRefCount(dataObj);
  Tcl_IncrRefCount(targetObj);

  TclXML_ProcessingInstructionHandler(expat->xmlinfo, targetObj, dataObj);

  Tcl_DecrRefCount(dataObj);
  Tcl_DecrRefCount(targetObj);
}

static void TclExpatDefaultHandler(userdata, s, len)
     void *userdata;
     const XML_Char *s;
     int len;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;
  Tcl_Obj *dataObj = Tcl_NewStringObj((XML_Char*)s, len);
  Tcl_IncrRefCount(dataObj);

  TclXML_DefaultHandler(expat->xmlinfo, dataObj);

  Tcl_DecrRefCount(dataObj);
}

static void TclExpatUnparsedDeclHandler(userdata, entityName, base, systemId, publicId, notationName)
     void *userdata;
     const XML_Char *entityName;
     const XML_Char *base;
     const XML_Char *systemId;
     const XML_Char *publicId;
     const XML_Char *notationName;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;
  Tcl_Obj *entityObj, *baseObj, *systemIdObj, *publicIdObj, *notationNameObj;

  entityObj = Tcl_NewStringObj((XML_Char*)entityName, -1);
  baseObj = Tcl_NewStringObj((XML_Char*)base, -1);
  systemIdObj = Tcl_NewStringObj((XML_Char*)systemId, -1);
  publicIdObj = Tcl_NewStringObj((XML_Char*)publicId, -1);
  notationNameObj = Tcl_NewStringObj((XML_Char*)notationName, -1);
  
  Tcl_IncrRefCount(entityObj);
  Tcl_IncrRefCount(baseObj);
  Tcl_IncrRefCount(systemIdObj);
  Tcl_IncrRefCount(publicIdObj);
  Tcl_IncrRefCount(notationNameObj);

  TclXML_UnparsedDeclHandler(expat->xmlinfo, 
          entityObj, baseObj, systemIdObj, publicIdObj, notationNameObj);

  Tcl_DecrRefCount(entityObj);
  Tcl_DecrRefCount(baseObj);
  Tcl_DecrRefCount(systemIdObj);
  Tcl_DecrRefCount(publicIdObj);
  Tcl_DecrRefCount(notationNameObj);
}

static void TclExpatNotationDeclHandler(userdata, notationName, base, systemId, publicId)
     void *userdata;
     const XML_Char *notationName;
     const XML_Char *base;
     const XML_Char *systemId;
     const XML_Char *publicId;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;
  Tcl_Obj *notationNameObj, *baseObj, *systemIdObj, *publicIdObj;

  notationNameObj = Tcl_NewStringObj((XML_Char*)notationName, -1);
  baseObj = Tcl_NewStringObj((XML_Char*)base, -1);
  systemIdObj = Tcl_NewStringObj((XML_Char*)systemId, -1);
  publicIdObj = Tcl_NewStringObj((XML_Char*)publicId, -1);

  Tcl_IncrRefCount(notationNameObj);
  Tcl_IncrRefCount(baseObj);
  Tcl_IncrRefCount(systemIdObj);
  Tcl_IncrRefCount(publicIdObj);

  TclXML_NotationDeclHandler(expat->xmlinfo, 
          notationNameObj, baseObj, systemIdObj, publicIdObj);

  Tcl_DecrRefCount(notationNameObj);
  Tcl_DecrRefCount(baseObj);
  Tcl_DecrRefCount(systemIdObj);
  Tcl_DecrRefCount(publicIdObj);
}

static void TclExpatCommentHandler(userdata, data)
     void *userdata;
     const XML_Char *data;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;
  Tcl_Obj *dataObj = Tcl_NewStringObj((XML_Char*)data, -1);
  Tcl_IncrRefCount(dataObj);

  TclXML_CommentHandler(expat->xmlinfo, dataObj);

  Tcl_DecrRefCount(dataObj);
}

static int TclExpatNotStandaloneHandler(userdata)
     void *userdata;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;

  return TclXML_NotStandaloneHandler(expat->xmlinfo);
}

static void TclExpatStartCdataSectionHandler(userdata)
     void *userdata;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;

  /*
   * TclXML makes no distinction between PCDATA and CDATA
   */
}

static void
TclExpatEndCdataSectionHandler(userdata)
     void *userdata;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;

  /*
   * TclXML makes no distinction between PCDATA and CDATA
   */
}

/*
 *----------------------------------------------------------------------------
 *
 * TclExpatExternalEntityRefHandler --
 *
 *    Called by expat for processing external entity references.
 *
 * Results:
 *    None.
 *
 * Side Effects:
 *    Callback script is invoked.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatExternalEntityRefHandler(parser, context, base, systemId, publicId)
     XML_Parser parser;
     const XML_Char *context;
     const XML_Char *base;
     const XML_Char *systemId;
     const XML_Char *publicId;
{
  TclExpatInfo *expat = (TclExpatInfo *) XML_GetUserData(parser);
  Tcl_Obj *contextObj, *baseObj, *systemIdObj, *publicIdObj;

  contextObj = Tcl_NewStringObj((XML_Char*)context, -1);
  baseObj = Tcl_NewStringObj((XML_Char*)base, -1);
  systemIdObj = Tcl_NewStringObj((XML_Char*)systemId, -1);
  publicIdObj = Tcl_NewStringObj((XML_Char*)publicId, -1);

  Tcl_IncrRefCount(contextObj);
  Tcl_IncrRefCount(baseObj);
  Tcl_IncrRefCount(systemIdObj);
  Tcl_IncrRefCount(publicIdObj);

  TclXML_ExternalEntityRefHandler((ClientData) expat->xmlinfo, 
          contextObj, baseObj, systemIdObj, publicIdObj);

  Tcl_DecrRefCount(contextObj);
  Tcl_DecrRefCount(baseObj);
  Tcl_DecrRefCount(systemIdObj);
  Tcl_DecrRefCount(publicIdObj);

  return 1;
}

/*
 *----------------------------------------------------------------------------
 *
 * TclExpatUnknownEncodingHandler --
 *
 *    Called by parser instance for processing a reference to a character in an 
 *    unknown encoding.
 *
 * Results:
 *    None.
 *
 * Side Effects:
 *    Callback script is invoked.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatUnknownEncodingHandler(encodingHandlerData, name, info)
     void *encodingHandlerData;
     const XML_Char *name;
     XML_Encoding *info;
{
  int result;
  Tcl_Obj *nameObj = Tcl_NewStringObj((XML_Char*)name, -1);
  Tcl_IncrRefCount(nameObj);

  result = TclXML_UnknownEncodingHandler(
                 encodingHandlerData, 
             nameObj,
             (ClientData) info);

  Tcl_DecrRefCount(nameObj);

  return result;
}

static void TclExpatElementDeclHandler(userdata, name, contentspec)
     void *userdata;
     const XML_Char *name;
     XML_Char ***contentspec;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;
  Tcl_Obj *contentspecObj, *nameObj;
  int count;

  contentspecObj = Tcl_NewListObj(0, NULL);
  Tcl_IncrRefCount(contentspecObj);

  for (count = 0; contentspec[0][count] != NULL; count++) {
    Tcl_ListObjAppendElement(expat->interp, contentspecObj, 
            Tcl_NewStringObj(contentspec[0][count], -1));
  }

  nameObj = Tcl_NewStringObj((XML_Char*)name, -1);
  Tcl_IncrRefCount(nameObj);

  TclXML_ElementDeclHandler(expat->xmlinfo, nameObj, contentspecObj);

  Tcl_DecrRefCount(nameObj);
  Tcl_DecrRefCount(contentspecObj);
}

static void TclExpatAttlistDeclHandler(userdata, name, attributes)
     void *userdata;
     const XML_Char *name;
     XML_Char ***attributes;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;
  Tcl_Obj *attdefnObj, *nameObj;
  int count;

  attdefnObj = Tcl_NewListObj(0, NULL);
  Tcl_IncrRefCount(attdefnObj);

  for (count = 0; (*attributes)[count] != NULL; count++) {
    Tcl_ListObjAppendElement(expat->interp, attdefnObj,
                       Tcl_NewStringObj((*attributes)[count], -1));
  }

  nameObj = Tcl_NewStringObj((XML_Char*)name, -1);
  Tcl_IncrRefCount(nameObj);
  TclXML_AttlistDeclHandler(
        expat->xmlinfo,
      nameObj,
      attdefnObj);

  Tcl_DecrRefCount(nameObj);
  Tcl_DecrRefCount(attdefnObj);
}

static void TclExpatStartDoctypeDeclHandler(userdata, name)
     void *userdata;
     const XML_Char *name;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;
  Tcl_Obj *nameObj = Tcl_NewStringObj((XML_Char*)name, -1);
  Tcl_IncrRefCount(nameObj);

  TclXML_StartDoctypeDeclHandler(expat->xmlinfo, nameObj);

  Tcl_DecrRefCount(nameObj);
}

static void TclExpatEndDoctypeDeclHandler(userdata)
     void *userdata;
{
  TclExpatInfo *expat = (TclExpatInfo *) userdata;

  TclXML_EndDoctypeDeclHandler(expat->xmlinfo);
}

Generated by  Doxygen 1.6.0   Back to index