summaryrefslogtreecommitdiffstats
path: root/tclxml/tcldom-libxml2.c
diff options
context:
space:
mode:
Diffstat (limited to 'tclxml/tcldom-libxml2.c')
-rw-r--r--tclxml/tcldom-libxml2.c7178
1 files changed, 0 insertions, 7178 deletions
diff --git a/tclxml/tcldom-libxml2.c b/tclxml/tcldom-libxml2.c
deleted file mode 100644
index 79960d0..0000000
--- a/tclxml/tcldom-libxml2.c
+++ /dev/null
@@ -1,7178 +0,0 @@
-/* tcldom-libxml2.c --
- *
- * A Tcl wrapper for libxml's node tree API,
- * conformant to the TclDOM API.
- *
- * Copyright (c) 2005-2008 by Explain.
- * http://www.explain.com.au/
- * Copyright (c) 2001-2004 Zveno Pty Ltd
- * http://www.zveno.com/
- *
- * See the file "LICENSE" for information on usage and
- * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * $Id: tcldom-libxml2.c,v 1.1.1.1 2009/01/16 22:11:49 joye Exp $
- */
-
-#include <tcldom/tcldom.h>
-#include <tcldom-libxml2/tcldom-libxml2.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-#include <libxml/xmlIO.h>
-#include <libxml/HTMLtree.h>
-#include <libxml/globals.h>
-#include <libxml/xinclude.h>
-#include <libxml/parserInternals.h>
-#include <libxml/xmlschemas.h>
-#include <libxml/xmlschemastypes.h>
-#include <libxml/xmlsave.h>
-#include <string.h>
-
-#define TCL_DOES_STUBS \
- (TCL_MAJOR_VERSION > 8 || TCL_MAJOR_VERSION == 8 && (TCL_MINOR_VERSION > 1 || \
- (TCL_MINOR_VERSION == 1 && TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE)))
-
-#undef TCL_STORAGE_CLASS
-#define TCL_STORAGE_CLASS DLLEXPORT
-
-/*
- * Manage lists of Tcl_Obj's
- */
-
-typedef struct ObjList {
- Tcl_Obj *objPtr;
- struct ObjList *next;
-} ObjList;
-
-/*
- * Forward declarations for private functions.
- */
-
-static void FreeDocument _ANSI_ARGS_((ClientData clientData));
-static TclDOM_libxml2_Document * GetDOMDocument _ANSI_ARGS_((Tcl_Interp *interp,
- TclXML_libxml2_Document *tDocPtr));
-
-static void TclDOM_libxml2_DestroyNode _ANSI_ARGS_((Tcl_Interp *interp, TclDOM_libxml2_Node *tNodePtr));
-static void TclDOM_libxml2_InvalidateNode _ANSI_ARGS_((TclDOM_libxml2_Node *tNodePtr));
-
-static char * TclDOMLiveNodeListNode _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp,
- char *name1,
- char *name2,
- int flags));
-static char * TclDOMLiveNodeListDoc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp,
- char *name1,
- char *name2,
- int flags));
-static char * TclDOMLiveNamedNodeMap _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp,
- char *name1,
- char *name2,
- int flags));
-static int TclDOMSetLiveNodeListNode _ANSI_ARGS_((Tcl_Interp *interp,
- char *varname,
- xmlNodePtr nodePtr));
-static int TclDOMSetLiveNodeListDoc _ANSI_ARGS_((Tcl_Interp *interp,
- char *varname,
- xmlDocPtr docPtr));
-static int TclDOMSetLiveNamedNodeMap _ANSI_ARGS_((Tcl_Interp *interp,
- char *varname,
- xmlNodePtr nodePtr));
-
-/*
- * Forward declarations of commands
- */
-
-static int TclDOMDOMImplementationCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static int TclDOMDocumentCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static void DocumentNodeCmdDelete _ANSI_ARGS_((ClientData clientdata));
-static int TclDOMNodeCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static void TclDOMNodeCommandDelete _ANSI_ARGS_((ClientData clientdata));
-static int TclDOMElementCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static int TclDOMEventCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static void TclDOMEventCommandDelete _ANSI_ARGS_((ClientData clientdata));
-static Tcl_Obj * TclDOM_libxml2_NewEventObj _ANSI_ARGS_((Tcl_Interp *interp,
- xmlDocPtr docPtr,
- enum TclDOM_EventTypes type,
- Tcl_Obj *typeObjPtr));
-
-/*
- * Functions that implement the TclDOM_Implementation interface
- */
-
-static int TclDOM_HasFeatureCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static int TclDOMCreateCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static int TclDOMDestroyCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static int TclDOMParseCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static int TclDOMSerializeCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static int TclDOMSelectNodeCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static int TclDOMIsNodeCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static int TclDOMAdoptCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-
-/*
- * Additional features
- */
-
-static int TclDOMXIncludeCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-
-static int TclDOMPrefix2NSCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-static int TclDOMTrimCommand _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]));
-
-static void TrimDocument _ANSI_ARGS_((Tcl_Interp *interp, xmlDocPtr docPtr));
-static int AdoptDocument _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr));
-
-static int DocumentCget _ANSI_ARGS_((Tcl_Interp *interp,
- xmlDocPtr docPtr,
- Tcl_Obj *CONST objPtr));
-static int NodeCget _ANSI_ARGS_((Tcl_Interp *interp,
- xmlDocPtr docPtr,
- xmlNodePtr nodePtr,
- Tcl_Obj *CONST objPtr));
-static int NodeConfigure _ANSI_ARGS_((Tcl_Interp *interp,
- xmlNodePtr nodePtr,
- int objc,
- Tcl_Obj *CONST objPtr[]));
-static int ElementCget _ANSI_ARGS_((Tcl_Interp *interp,
- xmlNodePtr nodePtr,
- Tcl_Obj *CONST objPtr));
-
-static int TclDOM_NodeAppendChild _ANSI_ARGS_((Tcl_Interp *interp,
- xmlNodePtr nodePtr,
- xmlNodePtr newPtr));
-static int TclDOM_NodeInsertBefore _ANSI_ARGS_((Tcl_Interp *interp,
- xmlNodePtr refPtr,
- xmlNodePtr newPtr));
-
-static void PostMutationEvents _ANSI_ARGS_((Tcl_Interp *interp,
- TclXML_libxml2_Document *tDocPtr,
- xmlNodePtr nodePtr,
- xmlNodePtr refPtr,
- xmlNodePtr newPtr,
- xmlNodePtr oldParent,
- xmlNodePtr newParent));
-
-static int DTDValidate _ANSI_ARGS_((Tcl_Interp *interp,
- TclDOM_libxml2_Document *domDocPtr));
-static int SchemaCompile _ANSI_ARGS_((Tcl_Interp *interp,
- TclDOM_libxml2_Document *domDocPtr));
-static int SchemaValidate _ANSI_ARGS_((Tcl_Interp *interp,
- TclDOM_libxml2_Document *domDocPtr,
- xmlDocPtr instancePtr));
-/*
-static int RelaxNGCompile _ANSI_ARGS_((Tcl_Interp *interp,
- xmlDocPtr doc));
-static int RelaxNGValidate _ANSI_ARGS_((Tcl_Interp *interp,
- xmlRelaxNGPtr schema,
- xmlDocPtr instance));
-*/
-
-static void NodeAddObjRef _ANSI_ARGS_((TclDOM_libxml2_Node *tNodePtr,
- Tcl_Obj *objPtr));
-#if 0
-static void DumpNode _ANSI_ARGS_((TclDOM_libxml2_Node *tNodePtr));
-#endif
-
-/*
- * Other utilities
- */
-
-static Tcl_Obj * GetPath _ANSI_ARGS_((Tcl_Interp *interp,
- xmlNodePtr nodePtr));
-
-/*
- * MS VC++ oddities
- */
-
-#ifdef WIN32
-#if !defined (__CYGWIN__)
-#define vsnprintf _vsnprintf
-#define snprintf _snprintf
-#endif /* __CYGWIN__ */
-#endif /* WIN32 */
-
-/*
- * Nodes as Tcl Objects (overloaded to also support event nodes).
- */
-
-Tcl_FreeInternalRepProc NodeTypeFree;
-Tcl_DupInternalRepProc NodeTypeDup;
-Tcl_UpdateStringProc NodeTypeUpdate;
-Tcl_SetFromAnyProc NodeTypeSetFromAny;
-
-Tcl_ObjType NodeObjType = {
- "libxml2-node",
- NodeTypeFree,
- NodeTypeDup,
- NodeTypeUpdate,
- NodeTypeSetFromAny
-};
-
-/*
- * For additional checks when creating nodes.
- * These are setup at initialisation-time, but thereafter are read-only.
- */
-
-static Tcl_Obj *checkName;
-static Tcl_Obj *checkQName;
-
-/*
- * libxml2 is mostly thread-safe, but there are issues with error callbacks
- */
-
-TCL_DECLARE_MUTEX(libxml2)
-
-/*
- * Statically include the definitions of option tables:
- * Due to linking problems on Windows, using MS VC++.
- */
-
-#include "tcldom.c"
-
-/*
- *----------------------------------------------------------------------------
- *
- * Tcldom_libxml2_Init --
- *
- * Initialisation routine for module.
- * This is no longer loaded as a separate module.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Creates commands in the interpreter,
- *
- *----------------------------------------------------------------------------
- */
-
-int
-Tcldom_libxml2_Init (interp)
- Tcl_Interp *interp; /* Interpreter to initialise */
-{
-
- Tcl_MutexLock(&libxml2);
- xmlXPathInit();
- Tcl_MutexUnlock(&libxml2);
-
- /*
- * Provide a handler for nodes for structured error reporting
- */
-
- TclXML_libxml2_SetErrorNodeFunc(interp,
- (TclXML_ErrorNodeHandlerProc *) TclDOM_libxml2_CreateObjFromNode);
-
- /*
- * For each of the standard commands, register the command
- * in both the ::dom and ::dom::libxml2 Tcl namespaces -
- * they are equivalent.
- */
-
- Tcl_CreateObjCommand(interp, "dom::libxml2::DOMImplementation",
- TclDOMDOMImplementationCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::DOMImplementation",
- TclDOMDOMImplementationCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::hasfeature",
- TclDOM_HasFeatureCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::hasfeature",
- TclDOM_HasFeatureCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::document",
- TclDOMDocumentCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::document",
- TclDOMDocumentCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::node",
- TclDOMNodeCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::node",
- TclDOMNodeCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::create",
- TclDOMCreateCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::create",
- TclDOMCreateCommand, NULL, NULL);
-
- /*
- * Implemented in Tcl (for the moment)
- Tcl_CreateObjCommand(interp, "dom::libxml2::parse",
- TclDOMParseCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::parse",
- TclDOMParseCommand, NULL, NULL);
- */
- Tcl_CreateObjCommand(interp, "dom::libxml2::adoptdocument",
- TclDOMAdoptCommand, NULL, NULL);
-
- Tcl_CreateObjCommand(interp, "dom::libxml2::serialize",
- TclDOMSerializeCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::serialize",
- TclDOMSerializeCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::selectnode",
- TclDOMSelectNodeCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::selectNode",
- TclDOMSelectNodeCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::isNode",
- TclDOMIsNodeCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::isNode",
- TclDOMIsNodeCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::element",
- TclDOMElementCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::element",
- TclDOMElementCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::event",
- TclDOMEventCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::event",
- TclDOMEventCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::xinclude",
- TclDOMXIncludeCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::xinclude",
- TclDOMXIncludeCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::prefix2namespaceURI",
- TclDOMPrefix2NSCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::prefix2namespaceURI",
- TclDOMPrefix2NSCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::destroy",
- TclDOMDestroyCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::destroy",
- TclDOMDestroyCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::libxml2::trim",
- TclDOMTrimCommand, NULL, NULL);
- Tcl_CreateObjCommand(interp, "dom::trim",
- TclDOMTrimCommand, NULL, NULL);
-
- /* Setup name checking REs */
- checkName = Tcl_NewStringObj("^", -1);
- Tcl_AppendObjToObj(checkName, Tcl_GetVar2Ex(interp, "::xml::Name", NULL, 0));
- Tcl_AppendToObj(checkName, "$", -1);
- Tcl_IncrRefCount(checkName);
- checkQName = Tcl_NewStringObj("^", -1);
- Tcl_AppendObjToObj(checkQName, Tcl_GetVar2Ex(interp, "::xml::QName", NULL, 0));
- Tcl_AppendToObj(checkQName, "$", -1);
- Tcl_IncrRefCount(checkQName);
-
- TclDOM_SetVars(interp);
-
- Tcl_RegisterObjType(&NodeObjType);
-
- return TCL_OK;
-}
-
-/*
- * DOM is safe, since it is merely an in-memory representation of the document tree.
- * However, XInclude is not safe. This is still OK because XInclude uses the external
- * entity mechanism to load remote documents and TclXML/libxml2 intercepts those calls.
- */
-int
-Tcldom_libxml2_SafeInit (interp)
- Tcl_Interp *interp; /* Interpreter to initialise */
-{
- return Tcldom_libxml2_Init(interp);
-}
-
-#if 0
-void
-DumpDocNodeTable(domDocPtr)
- TclDOM_libxml2_Document *domDocPtr;
-{
- return;
-
- /*
- TclDOM_libxml2_Node *tNodePtr;
- Tcl_HashEntry *entryPtr;
- Tcl_HashSearch search;
-
- sprintf(dbgbuf, " Nodes in doc \"%s\":\n", domDocPtr->tDocPtr->token);
- Tcl_WriteChars(stderrChan, dbgbuf, -1);
-
- for (entryPtr = Tcl_FirstHashEntry(domDocPtr->nodes, &search);
- entryPtr;
- entryPtr = Tcl_NextHashEntry(&search)) {
- tNodePtr = (TclDOM_libxml2_Node *) Tcl_GetHashValue(entryPtr);
- sprintf(dbgbuf, " Hash entry \"%s\" (x%x)\n", Tcl_GetHashKey(domDocPtr->nodes, entryPtr), tNodePtr);
- Tcl_WriteChars(stderrChan, dbgbuf, -1);
- sprintf(dbgbuf, " Node \"%s\"\n", tNodePtr->token);
- Tcl_WriteChars(stderrChan, dbgbuf, -1);
- }
- */
-}
-#endif
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_HasFeatureCommand --
- *
- * Implements dom::libxml2::hasfeature command
- *
- * Results:
- * Returns boolean.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOM_HasFeatureCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 0, objv, "hasfeature feature version");
- return TCL_ERROR;
- }
-
- if (Tcl_RegExpMatchObj(interp, objv[1], Tcl_NewStringObj("create|destroy|parse|query|serialize|trim|Events|UIEvents|isNode", -1)) == 1) {
- if (Tcl_StringMatch(Tcl_GetStringFromObj(objv[2], NULL), "1.0") == 1) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- }
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMCreateCommand --
- *
- * Implements dom::libxml2::create command
- *
- * Results:
- * Creates a new document.
- *
- * Side effects:
- * Allocates memory.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOMCreateCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- Tcl_Obj *objPtr;
-
- if (objc != 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "");
- return TCL_ERROR;
- }
-
- objPtr = TclXML_libxml2_NewDocObj(interp);
- if (!objPtr) {
- return TCL_ERROR;
- }
- TclXML_libxml2_DocKeep(objPtr, TCLXML_LIBXML2_DOCUMENT_KEEP);
-
- if (AdoptDocument(interp, objPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- return TCL_OK;
-}
-int
-AdoptDocument(interp, objPtr)
- Tcl_Interp *interp;
- Tcl_Obj *objPtr;
-{
- TclXML_libxml2_Document *tDocPtr;
- TclDOM_libxml2_Document *domDocPtr;
-
- /*
- * Claim this object so the document will not be destroyed
- * underneath us.
- */
- Tcl_IncrRefCount(objPtr);
-
- if (TclXML_libxml2_GetTclDocFromObj(interp, objPtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- domDocPtr = (TclDOM_libxml2_Document *) Tcl_Alloc(sizeof(TclDOM_libxml2_Document));
- domDocPtr->interp = interp;
- domDocPtr->tDocPtr = tDocPtr;
- domDocPtr->objPtr = objPtr;
-
- domDocPtr->schema = NULL;
-
- domDocPtr->nodes = (Tcl_HashTable *) Tcl_Alloc(sizeof(Tcl_HashTable));
- Tcl_InitHashTable(domDocPtr->nodes, TCL_STRING_KEYS);
- domDocPtr->nodeCntr = 0;
-
- domDocPtr->captureListeners = (Tcl_HashTable *) Tcl_Alloc(sizeof(Tcl_HashTable));
- Tcl_InitHashTable(domDocPtr->captureListeners, TCL_ONE_WORD_KEYS);
- domDocPtr->bubbleListeners = (Tcl_HashTable *) Tcl_Alloc(sizeof(Tcl_HashTable));
- Tcl_InitHashTable(domDocPtr->bubbleListeners, TCL_ONE_WORD_KEYS);
- memset(domDocPtr->listening, 0, TCLDOM_NUM_EVENT_TYPES * sizeof(int));
-
- /*
- * When the document is eventually destroyed,
- * make sure all memory is freed.
- */
- tDocPtr->dom = (ClientData) domDocPtr;
- tDocPtr->domfree = FreeDocument;
-
- /*
- * Create a Tcl namespace for this document
- */
-
- Tcl_VarEval(interp, "namespace eval ::dom::", tDocPtr->token, " {}\n", NULL);
-
- /*
- * Create a DOM command to control the document.
- */
-
- domDocPtr->cmd = Tcl_CreateObjCommand(interp, tDocPtr->token, TclDOMDocumentCommand, (ClientData) domDocPtr, DocumentNodeCmdDelete);
-
- Tcl_SetObjResult(interp, objPtr);
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_libxml2_CreateObjFromDoc --
- *
- * Wrapper for TclXML_libxml2_CreateObjFromDoc
- *
- * Results:
- * Returns Tcl_Obj.
- *
- * Side effects:
- * Allocates memory.
- *
- *----------------------------------------------------------------------------
- */
-
-Tcl_Obj *
-TclDOM_libxml2_CreateObjFromDoc (interp, docPtr)
- Tcl_Interp *interp;
- xmlDocPtr docPtr;
-{
- Tcl_Obj *newPtr;
-
- newPtr = TclXML_libxml2_CreateObjFromDoc(docPtr);
-
- if (AdoptDocument(interp, newPtr) != TCL_OK) {
- Tcl_DecrRefCount(newPtr);
- return NULL;
- }
-
- return newPtr;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMDestroyCommand --
- *
- * Implements dom::libxml2::destroy command
- *
- * Results:
- * Frees document or node.
- *
- * Side effects:
- * Deallocates memory.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOMDestroyCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- TclXML_libxml2_Document *tDocPtr;
- TclDOM_libxml2_Node *tNodePtr;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "token");
- return TCL_ERROR;
- }
-
- if (TclXML_libxml2_GetTclDocFromObj(interp, objv[1], &tDocPtr) == TCL_OK) {
- TclDOM_libxml2_Document *domDocPtr = GetDOMDocument(interp, tDocPtr);
-
- if (domDocPtr == NULL) {
- /* This is an error! */
- TclXML_libxml2_DestroyDocument(tDocPtr);
- } else {
- Tcl_DeleteCommandFromToken(interp, domDocPtr->cmd);
- }
-
- } else if (TclDOM_libxml2_GetTclNodeFromObj(interp, objv[1], &tNodePtr) == TCL_OK) {
- TclDOM_libxml2_DestroyNode(interp, tNodePtr);
- } else if (TclDOM_libxml2_GetTclEventFromObj(interp, objv[1], &tNodePtr) == TCL_OK) {
- TclDOM_libxml2_DestroyNode(interp, tNodePtr);
- } else {
- Tcl_SetResult(interp, "not a DOM node", NULL);
- return TCL_ERROR;
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * DocumentNodeCmdDelete --
- *
- * Invoked when a DOM document's command is deleted.
- *
- * Results:
- * Frees document.
- *
- * Side effects:
- * Deallocates memory.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-DocumentNodeCmdDelete (clientData)
- ClientData clientData;
-{
- TclDOM_libxml2_Document *domDocPtr = (TclDOM_libxml2_Document *) clientData;
-
-#ifndef WIN32
- TclXML_libxml2_DestroyDocument(domDocPtr->tDocPtr);
-#endif /* not WIN32 */
-#ifdef WIN32
- /*
- * Workaround bug in TclXML/libxml2.
- * This will, of course, leak memory.
- */
-
- /* FreeDocument((ClientData) domDocPtr); */
-#endif /* WIN32 */
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * FreeDocument --
- *
- * Frees resources associated with a document.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Deallocates memory.
- *
- *----------------------------------------------------------------------------
- */
-
-#ifdef WIN32
-/*
- * Using Tcl internal functions appears to cause linking problems
- * when using MS VC++, so avoid the problem by invoking a script instead.
- */
-
-void DeleteNamespace (interp, ns)
- Tcl_Interp *interp;
- char *ns;
-{
- Tcl_Obj *cmdPtr = Tcl_NewObj();
-
- Tcl_AppendStringsToObj(cmdPtr, "namespace delete ", ns, NULL);
- Tcl_EvalObjEx(interp, cmdPtr, TCL_EVAL_GLOBAL);
- Tcl_DecrRefCount(cmdPtr);
-}
-#else /* not WIN32 */
-/*
- * Internal Tcl functions
- */
-
-#if (TCL_MAJOR_VERSION < 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 5))
-
-/*
- * SRB: 2005-12-29: This should use #include <tclInt.h>, but private sources may not be available.
- */
-
-EXTERN Tcl_Namespace * Tcl_FindNamespace _ANSI_ARGS_((Tcl_Interp * interp,
- CONST char * name,
- Tcl_Namespace * contextNsPtr,
- int flags));
-EXTERN void Tcl_DeleteNamespace _ANSI_ARGS_((Tcl_Namespace * nsPtr));
-
-#endif /* Tcl < 8.5 */
-
-void DeleteNamespace (interp, ns)
- Tcl_Interp *interp;
- char *ns;
-{
- Tcl_Namespace *namespacePtr;
- namespacePtr = Tcl_FindNamespace(interp, ns,
- (Tcl_Namespace *) NULL, 0);
- if (namespacePtr) {
- Tcl_DeleteNamespace(namespacePtr);
- } /* else internal error */
-}
-#endif /* WIN32 */
-
-void
-FreeDocument (clientData)
- ClientData clientData;
-{
- TclDOM_libxml2_Document *domDocPtr = (TclDOM_libxml2_Document *) clientData;
- char buf[1024];
-
- snprintf(buf, 1023, "::dom::%s", domDocPtr->tDocPtr->token);
- DeleteNamespace(domDocPtr->interp, buf);
-
- /*
- * Deleting the namespace deletes all of the node commands,
- * which in turn invalidates the node references.
- * So no need to do it again here.
- *
- entry = Tcl_FirstHashEntry(domDocPtr->nodes, &search);
- while (entry) {
- tNodePtr = (TclDOM_libxml2_Node *) Tcl_GetHashValue(entry);
- TclDOM_libxml2_InvalidateNode(tNodePtr);
- entry = Tcl_NextHashEntry(&search);
- }
- */
- Tcl_DeleteHashTable(domDocPtr->nodes);
- Tcl_Free((char *) domDocPtr->nodes);
-
- if (domDocPtr->schema) {
- Tcl_MutexLock(&libxml2);
- /* This also frees the copy of the document used by the schema context */
- xmlSchemaFree(domDocPtr->schema);
- Tcl_MutexUnlock(&libxml2);
- }
-
- Tcl_Free((char *) domDocPtr->captureListeners);
- Tcl_Free((char *) domDocPtr->bubbleListeners);
-
- /* Workaround win32 destroy bug, see above */
-#ifndef WIN32
- Tcl_DecrRefCount(domDocPtr->objPtr);
-#endif /* not WIN32 */
-
- Tcl_Free((char *) domDocPtr);
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * GetDOMDocument --
- *
- * Retrieves the DOM document structure associated with a libxml2 document.
- * libxslt synthesizes documents, so it is often the case that a node
- * must be processed that has not had its document "adopted".
- *
- * Results:
- * Returns pointer to DOM structure.
- *
- * Side effects:
- * Document is "adopted" if necessary.
- *
- *----------------------------------------------------------------------------
- */
-
-TclDOM_libxml2_Document *
-GetDOMDocument(interp, tDocPtr)
- Tcl_Interp *interp;
- TclXML_libxml2_Document *tDocPtr;
-{
- if (tDocPtr->dom != NULL) {
- return (TclDOM_libxml2_Document *) tDocPtr->dom;
- } else if (interp == NULL) {
- return NULL;
- } else {
- Tcl_Obj *objPtr;
-
- objPtr = TclXML_libxml2_CreateObjFromDoc(tDocPtr->docPtr);
- if (AdoptDocument(interp, objPtr) != TCL_OK) {
- Tcl_DecrRefCount(objPtr);
- return NULL;
- } else {
- return (TclDOM_libxml2_Document *) tDocPtr->dom;
- }
- }
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMParseCommand --
- *
- * Implements dom::libxml2::parse command
- *
- * Not implemented here at present - calls Tcl script
- *
- * Results:
- * Depends on method.
- *
- * Side effects:
- * Depends on method.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOMParseCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- /* Tcl_Obj *objPtr; */
- Tcl_Obj **newobjv;
- int i;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "xml ?args ...?");
- return TCL_ERROR;
- }
-
- newobjv = (Tcl_Obj **) Tcl_Alloc((objc + 1) * sizeof(Tcl_Obj *));
- newobjv[0] = Tcl_NewStringObj("::dom::libxml2::parse", -1);
- for (i = 1; i < objc; i++) {
- newobjv[i] = objv[i];
- }
- newobjv[i] = NULL;
-
- return Tcl_EvalObjv(interp, objc, newobjv, 0);
-
- /*
- if (TclXML_CreateParser(interp, objc, objv) != TCL_OK) {
- return TCL_ERROR;
- }
- parserObj = Tcl_GetObjResult(interp);
- if (TclXML_Parse(interp, parserObj, objc, objv) != TCL_OK) {
- return TCL_ERROR;
- }
-
- if (TclXML_Get(interp, parserObj, "document") != TCL_OK) {
- return TCL_ERROR;
- }
-
- Tcl_SetObjResult(interp, objPtr);
- */
-
- return TCL_OK;
-}
-int
-TclDOMAdoptCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "doc");
- return TCL_ERROR;
- }
-
- return AdoptDocument(interp, objv[1]);
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMSerializeCommand --
- *
- * Implements dom::libxml2::serialize command
- *
- * Results:
- * Depends on method.
- *
- * Side effects:
- * Depends on method.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOMSerializeCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- xmlDocPtr docPtr;
- xmlNodePtr nodePtr;
- xmlBufferPtr bufptr = NULL;
- xmlSaveCtxtPtr savectxtptr = NULL;
- xmlChar *result = NULL;
- Tcl_Obj *encodingPtr = NULL;
- int option, method = TCLDOM_SERIALIZE_METHOD_XML, indent = 0, len = 0, omitXMLDeclaration = 0, saveoptions = 0;
- char *buf, *encoding;
- Tcl_Encoding tclencoding;
- Tcl_DString *serialized;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "node ?option value ...?");
- return TCL_ERROR;
- }
-
- if (TclXML_libxml2_GetDocFromObj(interp, objv[1], &docPtr) != TCL_OK) {
- if (TclDOM_libxml2_GetNodeFromObj(interp, objv[1], &nodePtr) == TCL_OK) {
- /* Serialize just the node */
- Tcl_SetResult(interp, "not yet implemented - serialize whole document", NULL);
- return TCL_ERROR;
- } else {
- Tcl_SetResult(interp, "not a libxml2 node", NULL);
- return TCL_ERROR;
- }
- }
-
- if (objc > 2) {
- objc -= 2;
- objv += 2;
-
- while (objc) {
-
- if (objc == 1) {
- Tcl_Obj *msgPtr;
-
- msgPtr = Tcl_NewStringObj("missing value for configuration option \"", -1);
- Tcl_AppendObjToObj(msgPtr, objv[0]);
- Tcl_AppendStringsToObj(msgPtr, "\"", (char *) NULL);
- Tcl_SetObjResult(interp, msgPtr);
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[0], TclDOM_SerializeCommandOptions,
- "option", 0, &option) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum TclDOM_SerializeCommandOptions) option) {
- case TCLDOM_SERIALIZE_METHOD:
-
- buf = Tcl_GetStringFromObj(objv[1], &len);
- if (len == 0) {
- method = TCLDOM_SERIALIZE_METHOD_XML;
- } else if (Tcl_GetIndexFromObj(interp, objv[1], TclDOM_SerializeMethods,
- "method", 0, &method) != TCL_OK) {
- return TCL_ERROR;
- }
-
- break;
-
- case TCLDOM_SERIALIZE_INDENT:
-
- if (Tcl_GetBooleanFromObj(interp, objv[1], &indent) != TCL_OK) {
- return TCL_ERROR;
- }
-
- break;
-
- case TCLDOM_SERIALIZE_OMIT_XML_DECLARATION:
-
- if (Tcl_GetBooleanFromObj(interp, objv[1], &omitXMLDeclaration) != TCL_OK) {
- return TCL_ERROR;
- }
-
- break;
-
- case TCLDOM_SERIALIZE_ENCODING:
- encodingPtr = objv[1];
-
- break;
-
- default:
- Tcl_SetResult(interp, "unknown option", NULL);
- return TCL_ERROR;
- }
-
- objc -= 2;
- objv += 2;
- }
- }
-
- switch ((enum TclDOM_SerializeMethods) method) {
-
- case TCLDOM_SERIALIZE_METHOD_XML:
-
- serialized = (Tcl_DString *) Tcl_Alloc(sizeof(Tcl_DString));
- Tcl_DStringInit(serialized);
-
- if (encodingPtr) {
- encoding = Tcl_GetStringFromObj(encodingPtr, NULL);
- } else {
- encoding = "utf-8";
- }
- tclencoding = Tcl_GetEncoding(interp, encoding);
-
- Tcl_MutexLock(&libxml2);
-
- if ((bufptr = xmlBufferCreate()) == NULL) {
- Tcl_MutexUnlock(&libxml2);
- Tcl_Free((void *)serialized);
- Tcl_SetResult(interp, "unable to allocate output buffer", NULL);
- return TCL_ERROR;
- }
-
- if (indent) {
- saveoptions |= XML_SAVE_FORMAT;
- }
- if (omitXMLDeclaration) {
- saveoptions |= XML_SAVE_NO_DECL;
- }
- if ((savectxtptr = xmlSaveToBuffer(bufptr, encoding, saveoptions)) == NULL) {
- Tcl_MutexUnlock(&libxml2);
- Tcl_Free((void *)serialized);
- xmlBufferFree(bufptr);
- Tcl_SetResult(interp, "unable to create save context", NULL);
- return TCL_ERROR;
- }
-
- xmlSaveDoc(savectxtptr, docPtr);
- xmlSaveClose(savectxtptr);
-
- Tcl_MutexUnlock(&libxml2);
-
- Tcl_ExternalToUtfDString(tclencoding, (CONST char *) xmlBufferContent(bufptr), xmlBufferLength(bufptr), serialized);
- Tcl_DStringResult(interp, serialized);
-
- Tcl_MutexLock(&libxml2);
- xmlBufferFree(bufptr);
- Tcl_MutexUnlock(&libxml2);
-
- break;
-
- case TCLDOM_SERIALIZE_METHOD_HTML:
-
- Tcl_MutexLock(&libxml2);
- htmlSetMetaEncoding(docPtr, (const xmlChar *) "UTF-8");
- htmlDocDumpMemory(docPtr, &result, &len);
- Tcl_MutexUnlock(&libxml2);
- Tcl_SetObjResult(interp, Tcl_NewStringObj((CONST char *) result, len));
- xmlFree(result);
-
- break;
-
- case TCLDOM_SERIALIZE_METHOD_TEXT:
-
- nodePtr = docPtr->children;
-
- while (nodePtr != NULL) {
- if (nodePtr->type == XML_TEXT_NODE)
- Tcl_AppendResult(interp, (char *) nodePtr->content, NULL);
-
- if (nodePtr->children != NULL) {
- if ((nodePtr->children->type != XML_ENTITY_DECL) &&
- (nodePtr->children->type != XML_ENTITY_REF_NODE) &&
- (nodePtr->children->type != XML_ENTITY_NODE)) {
- nodePtr = nodePtr->children;
- continue;
- }
- }
-
- if (nodePtr->next != NULL) {
- nodePtr = nodePtr->next;
- continue;
- }
-
- do {
- nodePtr = nodePtr->parent;
- if (nodePtr == NULL)
- break;
- if (nodePtr == (xmlNodePtr) docPtr) {
- nodePtr = NULL;
- break;
- }
- if (nodePtr->next != NULL) {
- nodePtr = nodePtr->next;
- break;
- }
- } while (nodePtr != NULL);
- }
-
- break;
-
- default:
- Tcl_SetResult(interp, "internal error", NULL);
- return TCL_ERROR;
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMDOMImplementationCommand --
- *
- * Implements dom::libxml2::DOMImplementation command
- *
- * Results:
- * Depends on method.
- *
- * Side effects:
- * Depends on method.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOMDOMImplementationCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- int method;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "method ?args...?");
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[1], TclDOM_DOMImplementationCommandMethods,
- "method", 0, &method) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum TclDOM_DOMImplementationCommandMethods) method) {
- case TCLDOM_IMPL_HASFEATURE:
- return TclDOM_HasFeatureCommand(dummy, interp, objc - 1, objv + 1);
- case TCLDOM_IMPL_CREATE:
- if (objc == 2) {
- return TclDOMCreateCommand(dummy, interp, 1, objv);
- } else if (objc == 3) {
- Tcl_Obj *objPtr;
- xmlDocPtr docPtr;
- xmlNodePtr nodePtr;
-
- if (TclDOMCreateCommand(dummy, interp, 0, NULL) != TCL_OK) {
- return TCL_ERROR;
- }
- objPtr = Tcl_GetObjResult(interp);
- TclXML_libxml2_GetDocFromObj(interp, objPtr, &docPtr);
- Tcl_MutexLock(&libxml2);
- nodePtr = xmlNewDocNode(docPtr, NULL, (const xmlChar *) Tcl_GetStringFromObj(objv[2], NULL), NULL);
- Tcl_MutexUnlock(&libxml2);
- if (nodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create document element", NULL);
- return TCL_ERROR;
- }
-
- Tcl_SetObjResult(interp, objPtr);
- } else {
- Tcl_WrongNumArgs(interp, 1, objv, "create ?doc?");
- return TCL_ERROR;
- }
-
- break;
-
- case TCLDOM_IMPL_PARSE:
- return TclDOMParseCommand(dummy, interp, objc - 1, objv + 1);
-
- case TCLDOM_IMPL_SERIALIZE:
- return TclDOMSerializeCommand(dummy, interp, objc - 1, objv + 1);
-
- case TCLDOM_IMPL_SELECTNODE:
- return TclDOMSelectNodeCommand(dummy, interp, objc - 1, objv + 1);
-
- case TCLDOM_IMPL_DESTROY:
- return TclDOMDestroyCommand(dummy, interp, objc - 1, objv + 1);
-
- case TCLDOM_IMPL_ISNODE:
- return TclDOMIsNodeCommand(dummy, interp, objc - 1, objv + 1);
-
- default:
- Tcl_SetResult(interp, "method \"", NULL);
- Tcl_AppendResult(interp, Tcl_GetStringFromObj(objv[1], NULL));
- Tcl_AppendResult(interp, "\" not yet implemented", NULL);
- return TCL_ERROR;
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * [Schema|RNG][Compile|Validate] --
- *
- * Implements DTD, XML Schema and RelaxNG parsing and validation
- *
- * Results:
- * Depends on method.
- *
- * Side effects:
- * May create or destroy validation contexts.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-DTDValidate (interp, domDocPtr)
- Tcl_Interp *interp;
- TclDOM_libxml2_Document *domDocPtr;
-{
- xmlValidCtxtPtr ctxt;
-
- TclXML_libxml2_ResetError(interp);
-
- Tcl_MutexLock(&libxml2);
-
- ctxt = xmlNewValidCtxt();
- if (ctxt == NULL) {
- Tcl_MutexUnlock(&libxml2);
-
- Tcl_SetResult(interp, "unable to prepare validation context", NULL);
- return TCL_ERROR;
- }
-
- Tcl_SetResult(interp, "document is not valid", NULL);
-
- if (xmlValidateDocument(ctxt, domDocPtr->tDocPtr->docPtr) == 0) {
- Tcl_Obj *errObjPtr;
-
- Tcl_MutexUnlock(&libxml2);
-
- errObjPtr = TclXML_libxml2_GetErrorObj(interp);
-
- if (errObjPtr) {
- Tcl_IncrRefCount(errObjPtr);
- Tcl_SetObjResult(interp, errObjPtr);
- }
- return TCL_ERROR;
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- Tcl_ResetResult(interp);
-
- return TCL_OK;
-}
-
-int
-SchemaCompile (interp, domDocPtr)
- Tcl_Interp *interp;
- TclDOM_libxml2_Document *domDocPtr;
-{
- xmlDocPtr schemaDocPtr;
- xmlSchemaParserCtxtPtr ctxt = NULL;
-
- if (domDocPtr->schema) {
- /* Re-compile */
- Tcl_MutexLock(&libxml2);
- xmlSchemaFree(domDocPtr->schema);
- Tcl_MutexUnlock(&libxml2);
- domDocPtr->schema = NULL;
- }
-
- Tcl_MutexLock(&libxml2);
-
- schemaDocPtr = xmlCopyDoc(domDocPtr->tDocPtr->docPtr, 1);
-
- if (schemaDocPtr == NULL) {
- Tcl_MutexUnlock(&libxml2);
- Tcl_SetResult(interp, "unable to prepare schema document", NULL);
- return TCL_ERROR;
- }
-
- ctxt = xmlSchemaNewDocParserCtxt(schemaDocPtr);
- if (ctxt == NULL) {
- xmlFreeDoc(schemaDocPtr);
- Tcl_MutexUnlock(&libxml2);
- Tcl_SetResult(interp, "unable to create schema context", NULL);
- return TCL_ERROR;
- }
-
- TclXML_libxml2_ResetError(interp);
-
- Tcl_SetResult(interp, "unable to parse schema document", NULL);
- domDocPtr->schema = xmlSchemaParse(ctxt);
-#if 0
- xmlSchemaFreeParserCtxt(ctxt); /* This frees the doc */
-#endif
- Tcl_MutexUnlock(&libxml2);
-
- if (domDocPtr->schema == NULL) {
- Tcl_Obj * errObjPtr = TclXML_libxml2_GetErrorObj(interp);
-
- if (errObjPtr) {
- Tcl_SetObjResult(interp, errObjPtr);
- }
-
- return TCL_ERROR;
- }
-
- Tcl_ResetResult(interp);
-
- return TCL_OK;
-}
-
-int
-SchemaValidate (interp, domDocPtr, instancePtr)
- Tcl_Interp *interp;
- TclDOM_libxml2_Document *domDocPtr;
- xmlDocPtr instancePtr;
-{
- xmlSchemaValidCtxtPtr ctxt = NULL;
- Tcl_Obj *errObjPtr;
- int ret;
-
- if (domDocPtr->schema == NULL) {
- Tcl_SetResult(interp, "schema not compiled", NULL);
- return TCL_ERROR;
- }
-
- TclXML_libxml2_ResetError(interp);
-
- Tcl_MutexLock(&libxml2);
-
- ctxt = xmlSchemaNewValidCtxt(domDocPtr->schema);
-
- Tcl_SetResult(interp, "document is not valid", NULL);
-
- ret = xmlSchemaValidateDoc(ctxt, instancePtr);
- errObjPtr = TclXML_libxml2_GetErrorObj(interp);
- if (ret > 0) {
- if (errObjPtr) {
- Tcl_SetObjResult(interp, errObjPtr);
- }
- goto error;
- } else if (ret < 0) {
- Tcl_SetResult(interp, "schema processor internal error", NULL);
-
- if (errObjPtr) {
- Tcl_SetObjResult(interp, errObjPtr);
- }
- goto error;
- }
-
- xmlSchemaFreeValidCtxt(ctxt);
-
- Tcl_MutexUnlock(&libxml2);
-
- /* There may be warnings */
-
- if (errObjPtr) {
- Tcl_SetObjResult(interp, errObjPtr);
- } else {
- Tcl_ResetResult(interp);
- }
-
- return TCL_OK;
-
- error:
- if (ctxt) {
- xmlSchemaFreeValidCtxt(ctxt);
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- return TCL_ERROR;
-}
-/*
- * TODO: RelaxNG validation.
- */
-
-int
-TclDOMTrimCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- xmlDocPtr docPtr;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "doc");
- }
-
- if (TclXML_libxml2_GetDocFromObj(interp, objv[1], &docPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- TrimDocument(interp, docPtr);
-
- return TCL_OK;
-}
-
-/*
- * Remove all blank text nodes
- *
- * NB. This code mostly copied from xmlschemas.c
- */
-
-/** Copied directly from xmlschemas.c:
- *
- * xmlSchemaIsBlank:
- * @str: a string
- *
- * Check if a string is ignorable
- *
- * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
- */
-/* SRB: 2008-11-24: Updated against libxml2 2.7.2.
- */
-#define IS_BLANK_NODE(n) \
- (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
-
-/*
- * SRB: 2008-06-12: Updated against libxml2 2.6.32.
- * See also SF bug 1943963.
- */
-
-static int
-xmlSchemaIsBlank(xmlChar *str, int len) {
- if (str == NULL)
- return(1);
- if (len < 0) {
- while (*str != 0) {
- if (!(IS_BLANK_CH(*str))) return(0);
- str++;
- }
- } else {
- while ((*str != 0) && (len != 0)) {
- if (!(IS_BLANK_CH(*str))) return (0);
- str++;
- len--;
- }
- }
- return(1);
-}
-
-static void
-TrimDocument(interp, docPtr)
- Tcl_Interp *interp;
- xmlDocPtr docPtr;
-{
- xmlNodePtr root, cur, delete;
- Tcl_Obj *nodeObjPtr;
- TclDOM_libxml2_Node *tNodePtr = NULL;
-
- delete = NULL;
- root = xmlDocGetRootElement(docPtr);
- if (root == NULL) {
- return;
- }
- cur = root;
-
- while (cur != NULL) {
- if (delete != NULL) {
- nodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, delete);
- TclDOM_libxml2_GetTclNodeFromObj(interp, nodeObjPtr, &tNodePtr);
- TclDOM_libxml2_InvalidateNode(tNodePtr);
- Tcl_DecrRefCount(nodeObjPtr);
- xmlUnlinkNode(delete);
- xmlFreeNode(delete);
- delete = NULL;
- }
- if (cur->type == XML_TEXT_NODE) {
- if (IS_BLANK_NODE(cur)) {
- if (xmlNodeGetSpacePreserve(cur) != 1) {
- delete = cur;
- }
- }
- } else if ((cur->type != XML_ELEMENT_NODE) &&
- (cur->type != XML_CDATA_SECTION_NODE)) {
- delete = cur;
- goto skip_children;
- }
-
- /*
- * Skip to next node
- */
- if (cur->children != NULL) {
- if ((cur->children->type != XML_ENTITY_DECL) &&
- (cur->children->type != XML_ENTITY_REF_NODE) &&
- (cur->children->type != XML_ENTITY_NODE)) {
- cur = cur->children;
- continue;
- }
- }
- skip_children:
- if (cur->next != NULL) {
- cur = cur->next;
- continue;
- }
-
- do {
- cur = cur->parent;
- if (cur == NULL)
- break;
- if (cur == root) {
- cur = NULL;
- break;
- }
- if (cur->next != NULL) {
- cur = cur->next;
- break;
- }
- } while (cur != NULL);
- }
- if (delete != NULL) {
- nodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, delete);
- TclDOM_libxml2_GetTclNodeFromObj(interp, nodeObjPtr, &tNodePtr);
- TclDOM_libxml2_InvalidateNode(tNodePtr);
- Tcl_DecrRefCount(nodeObjPtr);
- xmlUnlinkNode(delete);
- xmlFreeNode(delete);
- delete = NULL;
- }
-
- return;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMXIncludeCommand --
- *
- * Implements dom::libxml2::xinclude command.
- *
- * Results:
- * Performs XInclude processing on a document.
- *
- * Side effects:
- * The supplied DOM tree may be modified.
- *
- *----------------------------------------------------------------------------
- */
-int
-TclDOMXIncludeCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- xmlDocPtr docPtr;
- int subs;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "doc");
- return TCL_ERROR;
- }
-
- if (TclXML_libxml2_GetDocFromObj(interp, objv[1], &docPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
- subs = xmlXIncludeProcess(docPtr);
- Tcl_MutexUnlock(&libxml2);
-
- if (subs < 0) {
- Tcl_SetResult(interp, "unable to complete XInclude processing", NULL);
- return TCL_ERROR;
- }
-
- Tcl_SetObjResult(interp, Tcl_NewIntObj(subs));
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMPrefix2NSCommand --
- *
- * Implements dom::libxml2::prefix2namespaceURI command.
- *
- * Results:
- * Returns namespace URI for a given prefix.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-int
-TclDOMPrefix2NSCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- xmlNodePtr nodePtr;
- xmlNsPtr nsPtr;
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "node prefix");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetNodeFromObj(interp, objv[1], &nodePtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- nsPtr = xmlSearchNs(nodePtr->doc, nodePtr, (const xmlChar *) Tcl_GetStringFromObj(objv[2], NULL));
-
- if (!nsPtr) {
- Tcl_SetResult(interp, "no XML Namespace declaration", NULL);
- return TCL_ERROR;
- }
-
- Tcl_SetObjResult(interp, Tcl_NewStringObj((CONST char *) nsPtr->href, -1));
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMIsNodeCommand --
- *
- * Implements dom::libxml2::isNode command.
- *
- * Results:
- * Returns boolean.
- *
- * Side effects:
- * Tcl object may be converted to internal rep.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOMIsNodeCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- xmlDocPtr docPtr;
- xmlNodePtr nodePtr;
- TclDOM_libxml2_Node *tNodePtr;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "token");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetNodeFromObj(interp, objv[1], &nodePtr) != TCL_OK) {
- if (TclXML_libxml2_GetDocFromObj(interp, objv[1], &docPtr) != TCL_OK) {
- if (TclDOM_libxml2_GetTclEventFromObj(interp, objv[1], &tNodePtr) != TCL_OK) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- }
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- }
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMSelectNodeCommand --
- *
- * Implements dom::libxml2::selectnode command.
- *
- * Results:
- * Returns result of XPath expression evaluation.
- *
- * Side effects:
- * Memory is allocated for Tcl object to return result.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOMSelectNodeCommand (dummy, interp, objc, objv)
- ClientData dummy;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- int i, len, option;
- char *path;
- Tcl_Obj *objPtr, *nsOptPtr = NULL, *nodeObjPtr;
- xmlDocPtr docPtr;
- xmlNodePtr nodePtr = NULL;
- xmlXPathContextPtr ctxt = NULL;
- xmlXPathObjectPtr xpathObj = NULL;
-
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "doc location-path ?option value...?");
- return TCL_ERROR;
- }
-
- path = Tcl_GetStringFromObj(objv[2], &len);
- if (len == 0) {
- return TCL_OK;
- }
-
- if (TclXML_libxml2_GetDocFromObj(interp, objv[1], &docPtr) != TCL_OK) {
- if (TclDOM_libxml2_GetNodeFromObj(interp, objv[1], &nodePtr) == TCL_OK) {
- docPtr = nodePtr->doc;
- } else {
- return TCL_ERROR;
- }
- }
-
- for (i = 3; i < objc; i += 2) {
- if (i == objc - 1) {
- Tcl_AppendResult(interp, "missing value for option \"", Tcl_GetStringFromObj(objv[i], NULL), "\"", NULL);
- return TCL_ERROR;
- }
- if (Tcl_GetIndexFromObj(interp, objv[i], TclDOM_SelectNodeOptions,
- "option", 0, &option) != TCL_OK) {
- goto opt_error;
- }
- switch ((enum TclDOM_SelectNodeOptions) option) {
-
- case TCLDOM_SELECTNODE_OPTION_NAMESPACES:
- if (nsOptPtr) {
- if (Tcl_ListObjAppendList(interp, nsOptPtr, objv[i + 1]) != TCL_OK) {
- Tcl_SetResult(interp, "-namespaces option value must be a list", NULL);
- goto opt_error;
- }
- } else {
- nsOptPtr = Tcl_DuplicateObj(objv[i + 1]);
- }
- if (Tcl_ListObjLength(interp, nsOptPtr, &len) != TCL_OK) {
- Tcl_SetResult(interp, "-namespaces option value must be a list", NULL);
- goto opt_error;
- } else if (len % 2 != 0) {
- Tcl_SetResult(interp, "value missing from namespaces list", NULL);
- goto opt_error;
- }
-
- break;
-
- default:
- Tcl_AppendResult(interp, "unknown option \"", Tcl_GetStringFromObj(objv[i], NULL), "\"", NULL);
- goto opt_error;
- }
- }
-
- Tcl_MutexLock(&libxml2);
- ctxt = xmlXPathNewContext(docPtr);
- if (ctxt == NULL) {
- Tcl_SetResult(interp, "unable to create XPath context", NULL);
- return TCL_ERROR;
- }
-
- if (nodePtr) {
- ctxt->node = nodePtr;
- }
-
- TclXML_libxml2_ResetError(interp);
-
- /*
- * Setup any XML Namespace prefixes given as arguments
- */
- if (nsOptPtr) {
- Tcl_ListObjLength(interp, nsOptPtr, &len);
- for (i = 0; i < len; i += 2) {
- Tcl_Obj *prefixPtr, *nsURIPtr;
-
- Tcl_ListObjIndex(interp, nsOptPtr, i, &prefixPtr);
- Tcl_ListObjIndex(interp, nsOptPtr, i + 1, &nsURIPtr);
- if (xmlXPathRegisterNs(ctxt,
- (const xmlChar *) Tcl_GetStringFromObj(prefixPtr, NULL),
- (const xmlChar *) Tcl_GetStringFromObj(nsURIPtr, NULL))) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "unable to register XML Namespace \"", Tcl_GetStringFromObj(nsURIPtr, NULL), "\"", NULL);
- goto error;
- }
- }
- }
-
- xpathObj = xmlXPathEval((const xmlChar *) path, ctxt);
-
- if (xpathObj == NULL) {
- Tcl_Obj *errObjPtr = TclXML_libxml2_GetErrorObj(interp);
-
- if (errObjPtr) {
- Tcl_SetObjResult(interp, errObjPtr);
- goto error;
- } else {
- Tcl_SetResult(interp, "error evaluating XPath location path", NULL);
- goto error;
- }
- }
-
- objPtr = Tcl_NewObj();
- switch (xpathObj->type) {
-
- case XPATH_NODESET:
- len = xmlXPathNodeSetGetLength(xpathObj->nodesetval);
- for (i = 0; i < len; i++) {
- nodePtr = xmlXPathNodeSetItem(xpathObj->nodesetval, i);
- nodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, nodePtr);
- if (nodeObjPtr != NULL) {
- Tcl_ListObjAppendElement(interp, objPtr, nodeObjPtr);
- } else {
- Tcl_MutexUnlock(&libxml2);
- Tcl_DecrRefCount(objPtr);
- return TCL_ERROR;
- }
- }
- break;
-
- case XPATH_BOOLEAN:
- Tcl_SetBooleanObj(objPtr, xpathObj->boolval);
- break;
-
- case XPATH_NUMBER:
- Tcl_SetDoubleObj(objPtr, xpathObj->floatval);
- break;
-
- case XPATH_STRING:
- Tcl_SetStringObj(objPtr,
- (CONST char *) xpathObj->stringval,
- strlen((char *) xpathObj->stringval));
- break;
-
- default:
- Tcl_SetResult(interp, "bad XPath object type", NULL);
- goto error2;
- }
-
- if (nsOptPtr) {
- Tcl_DecrRefCount(nsOptPtr);
- }
- xmlXPathFreeObject(xpathObj);
- xmlXPathFreeContext(ctxt);
-
- Tcl_MutexUnlock(&libxml2);
-
- Tcl_SetObjResult(interp, objPtr);
- return TCL_OK;
-
- opt_error:
-
- Tcl_MutexUnlock(&libxml2);
-
- if (nsOptPtr) {
- Tcl_DecrRefCount(nsOptPtr);
- return TCL_ERROR;
- }
-
- error2:
- if (nsOptPtr) {
- Tcl_DecrRefCount(nsOptPtr);
- }
- xmlXPathFreeObject(xpathObj);
- xmlXPathFreeContext(ctxt);
-
- Tcl_MutexUnlock(&libxml2);
-
- return TCL_ERROR;
-
- error:
- if (nsOptPtr) {
- Tcl_DecrRefCount(nsOptPtr);
- }
- xmlXPathFreeContext(ctxt);
-
- Tcl_MutexUnlock(&libxml2);
-
- return TCL_ERROR;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMDocumentCommand --
- *
- * Implements dom::libxml2::document command.
- *
- * Results:
- * Depends on method.
- *
- * Side effects:
- * Depends on method.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOMDocumentCommand (clientData, interp, objc, objv)
- ClientData clientData;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- TclXML_libxml2_Document *tDocPtr;
- TclDOM_libxml2_Document *domDocPtr = NULL;
- enum TclDOM_EventTypes type;
- int method, optobjc, wrongidx = 1, postMutationEvent = 0, idx, len;
- xmlDocPtr docPtr = NULL;
- xmlNodePtr nodePtr = NULL, newNodePtr = NULL;
- xmlNsPtr nsPtr = NULL;
- Tcl_Obj *nodeObjPtr = NULL, *newNodeObjPtr = NULL;
- Tcl_Obj *CONST *optobjv;
- char *buf, *bufptr, *prefix;
-
- if (clientData == NULL) {
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "method token ?args...?");
- return TCL_ERROR;
- }
-
- if (TclXML_libxml2_GetTclDocFromObj(interp, objv[2], &tDocPtr) != TCL_OK) {
- tDocPtr = NULL;
- docPtr = NULL;
- if (TclDOM_libxml2_GetNodeFromObj(interp, objv[2], &nodePtr) != TCL_OK) {
- return TCL_ERROR;
- } else {
- nodeObjPtr = objv[2];
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- }
- } else {
- docPtr = tDocPtr->docPtr;
- domDocPtr = GetDOMDocument(interp, tDocPtr);
- if (domDocPtr == NULL) {
- Tcl_SetResult(interp, "internal error", NULL);
- return TCL_ERROR;
- }
- }
-
- optobjv = objv + 3;
- optobjc = objc - 3;
- wrongidx = 3;
-
- } else {
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "method ?args...?");
- return TCL_ERROR;
- }
-
- domDocPtr = (TclDOM_libxml2_Document *) clientData;
- tDocPtr = domDocPtr->tDocPtr;
- docPtr = tDocPtr->docPtr;
-
- optobjv = objv + 2;
- optobjc = objc - 2;
- wrongidx = 2;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[1], TclDOM_DocumentCommandMethods,
- "method", 0, &method) != TCL_OK) {
- return TCL_ERROR;
- }
-
- Tcl_ResetResult(interp);
-
- switch ((enum TclDOM_DocumentCommandMethods) method) {
-
- case TCLDOM_DOCUMENT_CGET:
-
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "option");
- return TCL_ERROR;
- }
-
- if (!docPtr) {
- Tcl_SetResult(interp, "not a document", NULL);
- return TCL_ERROR;
- }
-
- return DocumentCget(interp, docPtr, optobjv[0]);
-
- break;
-
- case TCLDOM_DOCUMENT_CONFIGURE:
-
- if (!docPtr) {
- Tcl_SetResult(interp, "not a document", NULL);
- return TCL_ERROR;
- }
-
- if (optobjc == 1) {
- return DocumentCget(interp, docPtr, optobjv[0]);
- } else {
- Tcl_AppendResult(interp, "attribute \"", Tcl_GetStringFromObj(optobjv[0], NULL), "\" is read-only", NULL);
- return TCL_ERROR;
- }
-
- break;
-
- case TCLDOM_DOCUMENT_CREATEELEMENTNS:
- if (optobjc != 2) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "nsuri qualname");
- return TCL_ERROR;
- }
-
- /*
- * libxml2 doesn't check for invalid element name,
- * so must do that here.
- */
- if (Tcl_RegExpMatchObj(interp, optobjv[1], checkQName) == 0) {
- Tcl_SetResult(interp, "invalid element name", NULL);
- return TCL_ERROR;
- }
-
- /* Find localName of element */
- buf = Tcl_GetStringFromObj(optobjv[1], &len);
- for (idx = 0; buf[idx] != ':' && idx < len; idx++) ;
- if (idx == len) {
- /* no prefix was given */
- bufptr = buf;
- } else {
- /* NB. name must have a local part, since it is a valid QName */
- bufptr = &buf[idx + 1];
- }
-
- if (docPtr && clientData == NULL) {
- /* We're creating the document element, so must create the namespace too */
- xmlNodePtr old;
-
- Tcl_MutexLock(&libxml2);
- newNodePtr = xmlNewDocNode(docPtr, NULL, (const xmlChar *) bufptr, NULL);
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create element node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
- old = xmlDocSetRootElement(docPtr, newNodePtr);
- if (old) {
- xmlDocSetRootElement(docPtr, old);
- xmlFreeNode(newNodePtr);
- Tcl_SetResult(interp, "document element already exists", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- if (idx < len) {
- prefix = Tcl_Alloc(bufptr - buf);
- strncpy(prefix, buf, bufptr - buf - 1);
- prefix[bufptr - buf - 1] = '\0';
- } else {
- /* synthesize prefix for this XML Namespace */
- prefix = Tcl_Alloc(20);
- sprintf(prefix, "ns%d", domDocPtr->nodeCntr++);
- }
-
- nsPtr = xmlNewNs(newNodePtr, (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL), (const xmlChar *) prefix);
- if (nsPtr == NULL) {
- Tcl_SetResult(interp, "unable to create XML Namespace", NULL);
- Tcl_Free(prefix);
- xmlUnlinkNode(newNodePtr);
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- xmlSetNs(newNodePtr, nsPtr);
-
- Tcl_MutexUnlock(&libxml2);
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- Tcl_MutexLock(&libxml2);
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
-
- return TCL_ERROR;
- }
-
- postMutationEvent = 1;
-
- } else if (docPtr && clientData != NULL) {
- /* Create an unattached element node */
- Tcl_MutexLock(&libxml2);
- newNodePtr = xmlNewDocNode(docPtr, NULL, (const xmlChar *) bufptr, NULL);
-
- if (idx < len) {
- prefix = Tcl_Alloc(bufptr - buf);
- strncpy(prefix, buf, bufptr - buf - 1);
- prefix[bufptr - buf - 1] = '\0';
- } else {
- /* synthesize prefix for this XML Namespace */
- prefix = Tcl_Alloc(20);
- sprintf(prefix, "ns%d", domDocPtr->nodeCntr);
- }
-
- nsPtr = xmlNewNs(newNodePtr, (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL), (const xmlChar *) prefix);
- if (nsPtr == NULL) {
- Tcl_SetResult(interp, "unable to create XML Namespace", NULL);
- Tcl_Free(prefix);
- xmlUnlinkNode(newNodePtr);
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- xmlSetNs(newNodePtr, nsPtr);
-
- Tcl_MutexUnlock(&libxml2);
-
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create element node", NULL);
- return TCL_ERROR;
- }
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- Tcl_MutexLock(&libxml2);
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, newNodeObjPtr);
- }
-
- /*
- * The tree hasn't changed yet, so no events need to be fired.
- */
- postMutationEvent = 0;
-
- } else {
-
- Tcl_MutexLock(&libxml2);
- /* Find XML Namespace */
- nsPtr = xmlSearchNsByHref(nodePtr->doc,
- nodePtr,
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL));
- if (nsPtr == NULL) {
- if (idx < len) {
- prefix = Tcl_Alloc(bufptr - buf);
- strncpy(prefix, buf, bufptr - buf - 1);
- prefix[bufptr - buf - 1] = '\0';
- } else {
- prefix = Tcl_Alloc(20);
- sprintf(prefix, "ns%d", domDocPtr->nodeCntr++);
- }
-
- newNodePtr = xmlNewChild(nodePtr, NULL, (const xmlChar *) bufptr, NULL);
- nsPtr = xmlNewNs(newNodePtr,
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL),
- (const xmlChar *) prefix);
- if (nsPtr == NULL) {
- Tcl_SetResult(interp, "unable to create XML Namespace", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
- xmlSetNs(newNodePtr, nsPtr);
-
- } else {
- newNodePtr = xmlNewChild(nodePtr, nsPtr, (const xmlChar *) bufptr, NULL);
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create element node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- Tcl_MutexLock(&libxml2);
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- postMutationEvent = 1;
- }
-
- break;
-
- case TCLDOM_DOCUMENT_CREATEELEMENT:
-
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "name");
- return TCL_ERROR;
- }
-
- /*
- * libxml2 doesn't check for invalid element name,
- * so must do that here.
- */
- if (Tcl_RegExpMatchObj(interp, optobjv[0], checkName) == 0) {
- Tcl_AppendResult(interp, "invalid element name \"", Tcl_GetStringFromObj(optobjv[0], NULL), "\"", NULL);
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
-
- if (docPtr && clientData == NULL) {
- xmlNodePtr old;
- newNodePtr = xmlNewDocNode(docPtr,
- NULL,
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL),
- NULL);
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create element node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
- old = xmlDocSetRootElement(docPtr, newNodePtr);
- if (old) {
- xmlDocSetRootElement(docPtr, old);
- xmlFreeNode(newNodePtr);
- Tcl_SetResult(interp, "document element already exists", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- postMutationEvent = 1;
- } else if (docPtr && clientData != NULL) {
- /* Create an unattached element node */
- newNodePtr = xmlNewDocNode(docPtr,
- NULL,
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL),
- NULL);
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create element node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, newNodeObjPtr);
- }
-
- /*
- * The tree hasn't changed yet, so no events need to be fired.
- */
- postMutationEvent = 0;
- } else {
- newNodePtr = xmlNewChild(nodePtr,
- NULL,
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL),
- NULL);
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create element node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
- postMutationEvent = 1;
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- break;
-
- case TCLDOM_DOCUMENT_CREATEDOCUMENTFRAGMENT:
-
- if (optobjc != 0) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "");
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
-
- if (docPtr) {
- newNodePtr = xmlNewDocFragment(docPtr);
- } else {
- newNodePtr = xmlNewDocFragment(nodePtr->doc);
- }
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create document fragment", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, newNodeObjPtr);
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- /* The node hasn't been inserted into the tree yet */
- postMutationEvent = 0;
-
- break;
-
- case TCLDOM_DOCUMENT_CREATETEXTNODE:
-
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "text");
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
-
- if (docPtr) {
- char *content;
- int len;
-
- content = Tcl_GetStringFromObj(optobjv[0], &len);
- newNodePtr = xmlNewDocTextLen(docPtr, (const xmlChar *) content, len);
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create text node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, newNodeObjPtr);
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- postMutationEvent = 0;
-
- } else {
- xmlNodePtr returnNode;
- char *content;
- int len;
-
- content = Tcl_GetStringFromObj(optobjv[0], &len);
- newNodePtr = xmlNewTextLen((const xmlChar *) content, len);
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "creating text node failed", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
- returnNode = xmlAddChild(nodePtr, newNodePtr);
- if (returnNode == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_SetResult(interp, "add child failed", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- postMutationEvent = 1;
- }
-
- break;
-
- case TCLDOM_DOCUMENT_CREATECOMMENT:
-
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "data");
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
-
- if (docPtr) {
- newNodePtr = xmlNewDocComment(docPtr, (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL));
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create comment node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, newNodeObjPtr);
- }
-
- postMutationEvent = 0;
-
- } else {
- newNodePtr = xmlNewDocComment(nodePtr->doc, (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL));
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create comment node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
- xmlAddChild(nodePtr, newNodePtr);
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- postMutationEvent = 1;
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- break;
-
- case TCLDOM_DOCUMENT_CREATECDATASECTION:
-
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "text");
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
-
- if (docPtr) {
- char *content;
- int len;
-
- content = Tcl_GetStringFromObj(optobjv[0], &len);
- newNodePtr = xmlNewDocTextLen(docPtr, (const xmlChar *) content, len);
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create text node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, newNodeObjPtr);
- }
-
- postMutationEvent = 0;
-
- } else {
- char *content;
- int len;
-
- content = Tcl_GetStringFromObj(optobjv[0], &len);
- newNodePtr = xmlNewTextLen((const xmlChar *) content, len);
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create text node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
- xmlAddChild(nodePtr, newNodePtr);
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- postMutationEvent = 1;
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- break;
-
- case TCLDOM_DOCUMENT_CREATEPI:
- if (optobjc != 2) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "target data");
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
-
- newNodePtr = xmlNewPI((const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL),
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[1], NULL));
- if (newNodePtr == NULL) {
- Tcl_SetResult(interp, "unable to create processing instruction node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- if (docPtr) {
- /*
- * libxml2 does not provide 'xmlNewDocPI' so the PI must be added to the tree
- * before we wrap it in an object. We'll use the document element as a placeholder
- * for the PI node; the user may move it from there.
- */
- xmlNodePtr docElPtr = xmlDocGetRootElement(docPtr);
-
- if (docElPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- Tcl_SetResult(interp, "document element must exist before adding a PI", NULL);
- return TCL_ERROR;
- }
- xmlAddNextSibling(docElPtr, newNodePtr);
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, newNodeObjPtr);
- }
-
- postMutationEvent = 0;
-
- } else {
- xmlAddChild(nodePtr, newNodePtr);
-
- newNodeObjPtr = TclDOM_libxml2_CreateObjFromNode(interp, newNodePtr);
- if (newNodeObjPtr == NULL) {
- xmlFreeNode(newNodePtr);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- postMutationEvent = 1;
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- break;
-
- case TCLDOM_DOCUMENT_CREATEEVENT:
-
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "type");
- return TCL_ERROR;
- }
-
- if (!docPtr) {
- docPtr = nodePtr->doc;
- }
-
- if (Tcl_GetIndexFromObj(interp, optobjv[0], TclDOM_EventTypes,
- "type", TCL_EXACT, &method) == TCL_OK) {
- type = (enum TclDOM_EventTypes) method;
- } else {
- type = TCLDOM_EVENT_USERDEFINED;
- }
-
- newNodeObjPtr = TclDOM_libxml2_NewEventObj(interp, docPtr, type, optobjv[0]);
- if (newNodeObjPtr == NULL) {
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, newNodeObjPtr);
- }
-
- postMutationEvent = 0;
-
- break;
-
- case TCLDOM_DOCUMENT_SCHEMA:
-
- if (optobjc < 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "submethod ?args ...?");
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, optobjv[0], TclDOM_DocumentSchemaSubmethods,
- "submethod", 0, &method) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum TclDOM_DocumentSchemaSubmethods) method) {
- case TCLDOM_DOCUMENT_SCHEMA_COMPILE:
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "compile");
- return TCL_ERROR;
- }
- return SchemaCompile(interp, domDocPtr);
-
- case TCLDOM_DOCUMENT_SCHEMA_VALIDATE:
- if (optobjc != 2) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "validate instance");
- return TCL_ERROR;
- } else {
- xmlDocPtr instancePtr;
-
- if (TclXML_libxml2_GetDocFromObj(interp, optobjv[1], &instancePtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- return SchemaValidate(interp, domDocPtr, instancePtr);
- }
-
- break;
-
- default:
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "unknown submethod \"",
- Tcl_GetStringFromObj(optobjv[0], NULL), "\"", NULL);
- return TCL_ERROR;
- }
-
- break;
-
- case TCLDOM_DOCUMENT_DTD:
-
- if (optobjc < 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "submethod ?args...?");
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, optobjv[0], TclDOM_DocumentDTDSubmethods,
- "submethod", 0, &method) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum TclDOM_DocumentDTDSubmethods) method) {
- case TCLDOM_DOCUMENT_DTD_VALIDATE:
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "validate");
- return TCL_ERROR;
- } else {
- return DTDValidate(interp, domDocPtr);
- }
- default:
- Tcl_SetResult(interp, "unknown submethod", NULL);
- return TCL_ERROR;
- }
-
- break;
-
- case TCLDOM_DOCUMENT_CREATEATTRIBUTE:
- case TCLDOM_DOCUMENT_CREATEENTITY:
- case TCLDOM_DOCUMENT_CREATEENTITYREFERENCE:
- case TCLDOM_DOCUMENT_CREATEDOCTYPEDECL:
- default:
- Tcl_SetResult(interp, "method \"", NULL);
- Tcl_AppendResult(interp, Tcl_GetStringFromObj(objv[1], NULL), "\" not yet implemented", NULL);
- return TCL_ERROR;
- }
-
- if (postMutationEvent) {
-
- TclDOM_PostMutationEvent(interp, tDocPtr, newNodeObjPtr, TCLDOM_EVENT_DOMNODEINSERTED, NULL, Tcl_NewIntObj(1), Tcl_NewIntObj(0), objv[2], NULL, NULL, NULL, NULL);
- TclDOM_PostMutationEvent(interp, tDocPtr, newNodeObjPtr, TCLDOM_EVENT_DOMNODEINSERTEDINTODOCUMENT, NULL, Tcl_NewIntObj(0), Tcl_NewIntObj(0), NULL, NULL, NULL, NULL, NULL);
-
- if (nodePtr) {
- TclDOM_PostMutationEvent(interp, tDocPtr, nodeObjPtr, TCLDOM_EVENT_DOMSUBTREEMODIFIED, NULL, Tcl_NewIntObj(1), Tcl_NewIntObj(0), NULL, NULL, NULL, NULL, NULL);
- } else {
- /*
- * We just added the document element.
- */
- }
-
- Tcl_SetObjResult(interp, newNodeObjPtr);
- }
-
- return TCL_OK;
-}
-
-int
-DocumentCget(interp, docPtr, optObj)
- Tcl_Interp *interp;
- xmlDocPtr docPtr;
- Tcl_Obj *CONST optObj;
-{
- xmlNodePtr nodePtr;
- int option;
-
- if (Tcl_GetIndexFromObj(interp, optObj, TclDOM_DocumentCommandOptions,
- "option", 0, &option) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum TclDOM_DocumentCommandOptions) option) {
-
- case TCLDOM_DOCUMENT_DOCTYPE:
- Tcl_SetResult(interp, "cget option \"", NULL);
- Tcl_AppendResult(interp, Tcl_GetStringFromObj(optObj, NULL), NULL);
- Tcl_AppendResult(interp, "\" not yet implemented", NULL);
- return TCL_ERROR;
-
- case TCLDOM_DOCUMENT_IMPLEMENTATION:
- Tcl_SetResult(interp, "::dom::libxml2::DOMImplementation", NULL);
- break;
-
- case TCLDOM_DOCUMENT_DOCELEMENT:
-
- Tcl_MutexLock(&libxml2);
- nodePtr = xmlDocGetRootElement(docPtr);
- Tcl_MutexUnlock(&libxml2);
-
- if (nodePtr) {
- Tcl_SetObjResult(interp, TclDOM_libxml2_CreateObjFromNode(interp, nodePtr));
- } else {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
-
- break;
-
- default:
- Tcl_SetResult(interp, "unknown option", NULL);
- return TCL_ERROR;
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TriggerEventListeners --
- *
- * Iterates through the list of event listeners for
- * a node or document and fires events.
- *
- * Results:
- * Depends on listeners.
- *
- * Side effects:
- * Depends on listeners.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-TriggerEventListeners(interp, type, tokenPtr, eventObjPtr, eventPtr)
- Tcl_Interp *interp;
- Tcl_HashTable *type;
- void *tokenPtr;
- Tcl_Obj *eventObjPtr;
- TclDOM_libxml2_Event *eventPtr;
-{
- Tcl_HashEntry *entryPtr;
- Tcl_HashTable *tablePtr;
- Tcl_Obj *listenerListPtr;
- int listenerLen, listenerIdx;
- char *eventType;
-
- entryPtr = Tcl_FindHashEntry(type, tokenPtr);
- if (!entryPtr) {
- return TCL_OK;
- }
- tablePtr = (Tcl_HashTable *) Tcl_GetHashValue(entryPtr);
-
- if (eventPtr->type != TCLDOM_EVENT_USERDEFINED) {
- eventType = (char *) TclDOM_EventTypes[eventPtr->type];
- } else {
- eventType = Tcl_GetStringFromObj(eventPtr->typeObjPtr, NULL);
- }
- entryPtr = Tcl_FindHashEntry(tablePtr, eventType);
- if (!entryPtr) {
- return TCL_OK;
- }
- listenerListPtr = (Tcl_Obj *) Tcl_GetHashValue(entryPtr);
-
- /*
- * DOM L2 specifies that the ancestors are determined
- * at the moment of event dispatch, so using a static
- * list is the correct thing to do.
- */
-
- Tcl_ListObjLength(interp, listenerListPtr, &listenerLen);
- for (listenerIdx = 0; listenerIdx < listenerLen; listenerIdx++) {
- Tcl_Obj *listenerObj, *cmdPtr;
-
- Tcl_ListObjIndex(interp, listenerListPtr, listenerIdx, &listenerObj);
-
- cmdPtr = Tcl_DuplicateObj(listenerObj);
- Tcl_IncrRefCount(cmdPtr);
- if (Tcl_ListObjAppendElement(interp, cmdPtr, eventObjPtr) != TCL_OK) {
- Tcl_DecrRefCount(cmdPtr);
- return TCL_ERROR;
- }
- Tcl_Preserve((ClientData) interp);
- if (Tcl_GlobalEvalObj(interp, cmdPtr) != TCL_OK) {
- Tcl_BackgroundError(interp);
- }
- Tcl_DecrRefCount(cmdPtr);
- Tcl_Release((ClientData) interp);
- }
-
- return TCL_OK;
-}
-
-static int
-TclDOMSetLiveNodeListNode(interp, varName, nodePtr)
- Tcl_Interp *interp;
- char *varName;
- xmlNodePtr nodePtr;
-{
- Tcl_Obj *valuePtr = Tcl_NewListObj(0, NULL);
- xmlNodePtr childPtr;
-
- for (childPtr = nodePtr->children; childPtr; childPtr = childPtr->next) {
- Tcl_ListObjAppendElement(interp, valuePtr, TclDOM_libxml2_CreateObjFromNode(interp, childPtr));
- }
-
- Tcl_SetVar2Ex(interp, varName, NULL, valuePtr, TCL_GLOBAL_ONLY);
-
- return TCL_OK;
-}
-
-static int
-TclDOMSetLiveNodeListDoc(interp, varName, docPtr)
- Tcl_Interp *interp;
- char *varName;
- xmlDocPtr docPtr;
-{
- Tcl_Obj *valuePtr = Tcl_NewListObj(0, NULL);
- xmlNodePtr childPtr;
-
- for (childPtr = docPtr->children; childPtr; childPtr = childPtr->next) {
- Tcl_ListObjAppendElement(interp, valuePtr, TclDOM_libxml2_CreateObjFromNode(interp, childPtr));
- }
-
- Tcl_SetVar2Ex(interp, varName, NULL, valuePtr, TCL_GLOBAL_ONLY);
-
- return TCL_OK;
-}
-
-static char *
-TclDOMLiveNodeListNode(clientData, interp, name1, name2, flags)
- ClientData clientData;
- Tcl_Interp *interp;
- char *name1;
- char *name2;
- int flags;
-{
- xmlNodePtr nodePtr = (xmlNodePtr) clientData;
-
- if (flags & (TCL_INTERP_DESTROYED | TCL_TRACE_DESTROYED)) {
- return NULL;
- } else if (flags & TCL_TRACE_READS) {
- TclDOMSetLiveNodeListNode(interp, name1, nodePtr);
- } else if (flags & TCL_TRACE_WRITES) {
- TclDOMSetLiveNodeListNode(interp, name1, nodePtr);
- return "variable is read-only";
- } else if (flags & TCL_TRACE_UNSETS) {
- }
-
- return NULL;
-}
-static char *
-TclDOMLiveNodeListDoc(clientData, interp, name1, name2, flags)
- ClientData clientData;
- Tcl_Interp *interp;
- char *name1;
- char *name2;
- int flags;
-{
- xmlDocPtr docPtr = (xmlDocPtr) clientData;
-
- if (flags & (TCL_INTERP_DESTROYED | TCL_TRACE_DESTROYED)) {
- return NULL;
- } else if (flags & TCL_TRACE_READS) {
- TclDOMSetLiveNodeListDoc(interp, name1, docPtr);
- } else if (flags & TCL_TRACE_WRITES) {
- TclDOMSetLiveNodeListDoc(interp, name1, docPtr);
- return "variable is read-only";
- } else if (flags & TCL_TRACE_UNSETS) {
- }
-
- return NULL;
-}
-
-static int
-TclDOMSetLiveNamedNodeMap(interp, varName, nodePtr)
- Tcl_Interp *interp;
- char *varName;
- xmlNodePtr nodePtr;
-{
- xmlAttrPtr attrPtr;
-
- Tcl_UnsetVar(interp, varName, TCL_GLOBAL_ONLY);
-
- for (attrPtr = nodePtr->properties; attrPtr; attrPtr = attrPtr->next) {
-
- if (Tcl_SetVar2Ex(interp, varName, (char *) attrPtr->name, Tcl_NewStringObj((CONST char *) xmlGetProp(nodePtr, attrPtr->name), -1), TCL_GLOBAL_ONLY) == NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "unable to set attribute \"", attrPtr->name, "\"", NULL);
- return TCL_ERROR;
- }
-
- if (Tcl_TraceVar2(interp, varName, (char *) attrPtr->name, TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *) TclDOMLiveNamedNodeMap, (ClientData) nodePtr) != TCL_OK) {
- return TCL_ERROR;
- }
- }
-
- return TCL_OK;
-}
-
-static char *
-TclDOMLiveNamedNodeMap(clientData, interp, name1, name2, flags)
- ClientData clientData;
- Tcl_Interp *interp;
- char *name1;
- char *name2;
- int flags;
-{
- xmlNodePtr nodePtr = (xmlNodePtr) clientData;
-
- if (flags & (TCL_INTERP_DESTROYED | TCL_TRACE_DESTROYED)) {
- return NULL;
- } else if (flags & TCL_TRACE_READS && name2 == NULL) {
- TclDOMSetLiveNamedNodeMap(interp, name1, nodePtr);
- } else if (flags & TCL_TRACE_READS && name2 != NULL) {
- if (Tcl_SetVar2Ex(interp, name1, name2, Tcl_NewStringObj((CONST char *) xmlGetProp(nodePtr, (const xmlChar *) name2), -1), TCL_GLOBAL_ONLY) == NULL) {
- return "unable to set attribute";
- }
- } else if (flags & TCL_TRACE_WRITES) {
- TclDOMSetLiveNamedNodeMap(interp, name1, nodePtr);
- return "variable is read-only";
- } else if (flags & TCL_TRACE_UNSETS) {
- }
-
- return NULL;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMNodeCommand --
- *
- * Implements dom::libxml2::node command.
- *
- * Results:
- * Depends on method.
- *
- * Side effects:
- * Depends on method.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOMNodeCommand (clientData, interp, objc, objv)
- ClientData clientData;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- TclXML_libxml2_Document *tDocPtr;
- TclDOM_libxml2_Node *tNodePtr;
- int method, optobjc, option, wrongidx, usecapture = 0;
- char *buf;
- xmlNodePtr nodePtr = NULL, childNodePtr, refPtr, newPtr, oldParent;
- xmlDocPtr docPtr = NULL;
- Tcl_Obj *nodeObjPtr = NULL;
- Tcl_Obj *docObjPtr = NULL;
- Tcl_Obj *resultPtr;
- Tcl_Obj *CONST *optobjv;
-
- if (clientData == NULL) {
-
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "method token ?arg ...?");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetTclNodeFromObj(interp, objv[2], &tNodePtr) != TCL_OK) {
- if (TclXML_libxml2_GetTclDocFromObj(interp, objv[2], &tDocPtr) != TCL_OK) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "\"", Tcl_GetStringFromObj(objv[2], NULL), "\" is neither a DOM document nor a DOM node", NULL);
- return TCL_ERROR;
- } else {
- Tcl_ResetResult(interp);
- docObjPtr = objv[2];
- docPtr = tDocPtr->docPtr;
- nodeObjPtr = NULL;
- nodePtr = NULL;
- }
- } else {
- nodePtr = tNodePtr->ptr.nodePtr;
- nodeObjPtr = objv[2];
- docPtr = NULL;
- docObjPtr = NULL;
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- }
-
- optobjc = objc - 3;
- optobjv = objv + 3;
- wrongidx = 3;
-
- } else {
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "method ?arg ...?");
- return TCL_ERROR;
- }
-
- tNodePtr = (TclDOM_libxml2_Node *) clientData;
- nodePtr = tNodePtr->ptr.nodePtr;
- nodeObjPtr = NULL;
- docPtr = NULL;
- docObjPtr = NULL;
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- optobjc = objc - 2;
- optobjv = objv + 2;
- wrongidx = 2;
-
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[1], TclDOM_NodeCommandMethods,
- "method", 0, &method) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum TclDOM_NodeCommandMethods) method) {
-
- case TCLDOM_NODE_CGET:
-
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "option");
- return TCL_ERROR;
- }
-
- NodeCget(interp, docPtr, nodePtr, optobjv[0]);
-
- break;
-
- case TCLDOM_NODE_PATH:
-
- if (docPtr) {
- Tcl_Obj *newobjv[2];
-
- newobjv[0] = TclXML_libxml2_CreateObjFromDoc(docPtr);
- newobjv[1] = NULL;
- Tcl_SetObjResult(interp, Tcl_NewListObj(1, newobjv));
- } else {
- Tcl_SetObjResult(interp, GetPath(interp, nodePtr));
- }
-
- break;
-
- case TCLDOM_NODE_CONFIGURE:
-
- if (optobjc < 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "option ?value? ?option value ...?");
- return TCL_ERROR;
- }
-
- if (optobjc == 1) {
- return NodeCget(interp, docPtr, nodePtr, optobjv[0]);
- }
-
- if (optobjc % 2 == 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "option ?value? ?option value ...?");
- return TCL_ERROR;
- }
-
- return NodeConfigure(interp, nodePtr, optobjc, optobjv);
- break;
-
- case TCLDOM_NODE_INSERTBEFORE:
- if (optobjc < 1 || optobjc > 2) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "ref ?new?");
- return TCL_ERROR;
- } else if (docPtr) {
- /* TODO: allow comments & PIs in document prologue */
- Tcl_SetResult(interp, "document already has document element", NULL);
- return TCL_ERROR;
- } else if (optobjc == 1) {
- /* No reference child specified - new appended to child list */
- if (TclDOM_libxml2_GetNodeFromObj(interp, optobjv[0], &newPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- return TclDOM_NodeAppendChild(interp, nodePtr, newPtr);
- } else if (optobjc == 2) {
- if (TclDOM_libxml2_GetNodeFromObj(interp, optobjv[0], &newPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- if (TclDOM_libxml2_GetNodeFromObj(interp, optobjv[1], &refPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- return TclDOM_NodeInsertBefore(interp, refPtr, newPtr);
- }
-
- break;
-
- case TCLDOM_NODE_REPLACECHILD:
- if (optobjc != 2) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "new old");
- return TCL_ERROR;
- } else if (docPtr) {
- /* TODO: allow replacing comments & PIs */
- Tcl_SetResult(interp, "document already has document element", NULL);
- return TCL_ERROR;
- } else {
- if (TclDOM_libxml2_GetNodeFromObj(interp, optobjv[0], &newPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- if (TclDOM_libxml2_GetNodeFromObj(interp, optobjv[1], &refPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- oldParent = newPtr->parent;
- if (oldParent != refPtr->parent) {
- TclDOM_PostMutationEvent(interp,
- tDocPtr,
- TclDOM_libxml2_CreateObjFromNode(interp, newPtr),
- TCLDOM_EVENT_DOMNODEREMOVED,
- NULL,
- Tcl_NewIntObj(1), Tcl_NewIntObj(0),
- TclDOM_libxml2_CreateObjFromNode(interp, newPtr->parent),
- NULL, NULL, NULL, NULL);
- }
-
- Tcl_MutexLock(&libxml2);
-
- if (xmlReplaceNode(refPtr, newPtr) == NULL) {
- Tcl_SetResult(interp, "unable to replace node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- }
-
- PostMutationEvents(interp, tDocPtr, nodePtr, refPtr, newPtr, oldParent, refPtr->parent);
-
- Tcl_SetObjResult(interp, TclDOM_libxml2_CreateObjFromNode(interp, refPtr));
-
- break;
-
- case TCLDOM_NODE_REMOVECHILD:
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "child");
- return TCL_ERROR;
- } else if (docPtr) {
- /* TODO: allow removing comments & PIs */
- Tcl_SetResult(interp, "document must have document element", NULL);
- return TCL_ERROR;
- } else {
- xmlNodePtr childPtr;
- if (TclDOM_libxml2_GetNodeFromObj(interp, optobjv[0], &childPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- if (nodePtr != childPtr->parent) {
- Tcl_SetResult(interp, "not found: \"", NULL);
- Tcl_AppendResult(interp, Tcl_GetStringFromObj(optobjv[0], NULL),
- "\" is not a child", NULL);
- if (nodeObjPtr) {
- Tcl_AppendResult(interp, " of \"",
- Tcl_GetStringFromObj(nodeObjPtr, NULL), "\"", NULL);
- }
- return TCL_ERROR;
- }
- oldParent = childPtr->parent;
- TclDOM_PostMutationEvent(interp,
- tDocPtr, optobjv[0],
- TCLDOM_EVENT_DOMNODEREMOVED,
- NULL,
- Tcl_NewIntObj(1), Tcl_NewIntObj(0),
- TclDOM_libxml2_CreateObjFromNode(interp, oldParent),
- NULL, NULL, NULL, NULL);
- TclDOM_PostMutationEvent(interp,
- tDocPtr, optobjv[0],
- TCLDOM_EVENT_DOMNODEREMOVEDFROMDOCUMENT,
- NULL,
- Tcl_NewIntObj(0), Tcl_NewIntObj(0),
- NULL, NULL, NULL, NULL, NULL);
-
- Tcl_MutexLock(&libxml2);
- xmlUnlinkNode(childPtr);
- Tcl_MutexUnlock(&libxml2);
-
- Tcl_SetObjResult(interp, optobjv[0]);
- TclDOM_PostMutationEvent(interp,
- tDocPtr,
- TclDOM_libxml2_CreateObjFromNode(interp, oldParent),
- TCLDOM_EVENT_DOMSUBTREEMODIFIED,
- NULL,
- Tcl_NewIntObj(1), Tcl_NewIntObj(0), NULL, NULL, NULL, NULL, NULL);
- }
-
- break;
-
- case TCLDOM_NODE_APPENDCHILD:
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "child");
- return TCL_ERROR;
- } else if (docPtr) {
- xmlNodePtr oldPtr;
-
- if (TclDOM_libxml2_GetNodeFromObj(interp, optobjv[0], &childNodePtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
-
- /* TODO: allow appending comments & PIs */
- oldPtr = xmlDocSetRootElement(docPtr, childNodePtr);
- if (oldPtr) {
- xmlDocSetRootElement(docPtr, oldPtr);
- Tcl_SetResult(interp, "document element already exists", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- Tcl_SetObjResult(interp, optobjv[0]);
-
- } else {
- if (TclDOM_libxml2_GetNodeFromObj(interp, optobjv[0], &childNodePtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- return TclDOM_NodeAppendChild(interp, nodePtr, childNodePtr);
- }
-
- break;
-
- case TCLDOM_NODE_HASCHILDNODES:
- if (docPtr) {
- if (docPtr->children) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- }
- } else {
- if (nodePtr->children) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- }
- }
-
- break;
-
- case TCLDOM_NODE_ISSAMENODE:
- /* DOM Level 3 method */
-
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "ref");
- return TCL_ERROR;
- }
-
- if (docPtr) {
- xmlDocPtr docRefPtr;
-
- if (TclXML_libxml2_GetDocFromObj(interp, optobjv[0], &docRefPtr) != TCL_OK) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
-
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(docPtr == docRefPtr));
-
- } else {
- if (TclDOM_libxml2_GetNodeFromObj(interp, optobjv[0], &refPtr) != TCL_OK) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
-
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(nodePtr == refPtr));
- }
-
- break;
-
- case TCLDOM_NODE_CLONENODE:
- if (optobjc != 0 && optobjc != 2) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "?-deep boolean?");
- return TCL_ERROR;
- } else if (docPtr) {
- Tcl_SetResult(interp, "documents cannot be cloned", NULL);
- return TCL_ERROR;
- } else {
- int deep = 0;
- xmlNodePtr copyPtr;
-
- if (optobjc == 2) {
- if (Tcl_RegExpMatchObj(interp, optobjv[0], Tcl_NewStringObj("-de?e?p?", -1)) == 0) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "invalid option \"", Tcl_GetStringFromObj(optobjv[0], NULL), "\", must be \"-deep\"", NULL);
- return TCL_ERROR;
- }
- if (Tcl_GetBooleanFromObj(interp, optobjv[1], &deep) != TCL_OK) {
- return TCL_ERROR;
- }
- }
-
- Tcl_MutexLock(&libxml2);
- copyPtr = xmlDocCopyNode(nodePtr, nodePtr->doc, deep);
- Tcl_MutexUnlock(&libxml2);
-
- if (copyPtr == NULL) {
- Tcl_SetResult(interp, "unable to copy node", NULL);
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, TclDOM_libxml2_CreateObjFromNode(interp, copyPtr));
- }
- break;
-
- case TCLDOM_NODE_PARENT:
-
- if (docPtr) {
- break;
- }
-
- if (nodePtr->parent) {
- Tcl_SetObjResult(interp, TclDOM_libxml2_CreateObjFromNode(interp, nodePtr->parent));
- } else {
- Tcl_SetObjResult(interp, TclXML_libxml2_CreateObjFromDoc(nodePtr->doc));
- }
-
- break;
-
- case TCLDOM_NODE_CHILDREN:
-
- resultPtr = Tcl_NewListObj(0, NULL);
-
- if (docPtr) {
- childNodePtr = docPtr->children;
- } else {
- childNodePtr = nodePtr->children;
- }
-
- while (childNodePtr) {
- Tcl_ListObjAppendElement(interp, resultPtr, TclDOM_libxml2_CreateObjFromNode(interp, childNodePtr));
- childNodePtr = childNodePtr->next;
- }
-
- Tcl_SetObjResult(interp, resultPtr);
-
- break;
-
- case TCLDOM_NODE_ADDEVENTLISTENER:
-
- /* TODO: type optional, missing type returns all types that have a listener */
-
- if (optobjc < 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "type ?listener? ?-usecapture boolean?");
- return TCL_ERROR;
- } else {
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr, *listenerPtr = NULL;
- void *tokenPtr = NULL;
-
- if (nodePtr) {
- tokenPtr = (void *) nodePtr;
- } else {
- tokenPtr = (void *) docPtr;
- }
-
- if (Tcl_GetIndexFromObj(interp, optobjv[0], TclDOM_EventTypes,
- "type", TCL_EXACT, &option) == TCL_OK) {
- type = (enum TclDOM_EventTypes) option;
- } else {
- type = TCLDOM_EVENT_USERDEFINED;
- }
- typeObjPtr = optobjv[0];
- Tcl_ResetResult(interp);
- optobjc -= 1;
- optobjv += 1;
-
- if (optobjc > 0 && *Tcl_GetStringFromObj(optobjv[0], NULL) != '-') {
- listenerPtr = optobjv[0];
- optobjc -= 1;
- optobjv += 1;
- } /* else we will return the registered listener */
-
- while (optobjc) {
- if (optobjc == 1) {
- Tcl_SetResult(interp, "missing value", NULL);
- return TCL_ERROR;
- }
- if (Tcl_GetIndexFromObj(interp, optobjv[0], TclDOM_NodeCommandAddEventListenerOptions,
- "option", 0, &option) != TCL_OK) {
- return TCL_ERROR;
- }
- switch ((enum TclDOM_NodeCommandAddEventListenerOptions) option) {
- case TCLDOM_NODE_ADDEVENTLISTENER_USECAPTURE:
-
- if (Tcl_GetBooleanFromObj(interp, optobjv[1], &usecapture) != TCL_OK) {
- return TCL_ERROR;
- }
-
- break;
-
- default:
- Tcl_SetResult(interp, "unknown option", NULL);
- return TCL_ERROR;
- }
-
- optobjc -= 2;
- optobjv += 2;
- }
-
- if (nodePtr) {
- docObjPtr = TclXML_libxml2_CreateObjFromDoc(nodePtr->doc);
- } else {
- docObjPtr = TclXML_libxml2_CreateObjFromDoc(docPtr);
- }
- TclXML_libxml2_GetTclDocFromObj(interp, docObjPtr, &tDocPtr);
-
- if (listenerPtr == NULL) {
- listenerPtr = TclDOM_GetEventListener(interp, tDocPtr, tokenPtr, type, typeObjPtr, usecapture);
- if (listenerPtr) {
- Tcl_SetObjResult(interp, listenerPtr);
- } else {
- Tcl_SetResult(interp, "unable to find listeners", NULL);
- return TCL_ERROR;
- }
- } else {
- return TclDOM_AddEventListener(interp, tDocPtr, tokenPtr, type, typeObjPtr, listenerPtr, usecapture);
- }
- }
-
- break;
-
-
- case TCLDOM_NODE_REMOVEEVENTLISTENER:
-
- if (optobjc < 2) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "type listener ?-usecapture boolean?");
- return TCL_ERROR;
- } else {
- Tcl_Obj *typeObjPtr, *listenerPtr;
- void *tokenPtr = NULL;
- TclXML_libxml2_Document *tDocPtr;
- enum TclDOM_EventTypes type;
-
- if (nodePtr) {
- tokenPtr = (void *) nodePtr;
- } else {
- tokenPtr = (void *) docPtr;
- }
-
- typeObjPtr = optobjv[0];
- if (Tcl_GetIndexFromObj(interp, optobjv[0], TclDOM_EventTypes,
- "type", TCL_EXACT, &option) == TCL_OK) {
- type = (enum TclDOM_EventTypes) option;
- } else {
- type = TCLDOM_EVENT_USERDEFINED;
- }
- listenerPtr = optobjv[1];
-
- optobjc -= 2;
- optobjv += 2;
- while (optobjc) {
- if (Tcl_GetIndexFromObj(interp, optobjv[0], TclDOM_NodeCommandAddEventListenerOptions,
- "option", 0, &option) != TCL_OK) {
- return TCL_ERROR;
- }
- switch ((enum TclDOM_NodeCommandAddEventListenerOptions) option) {
- case TCLDOM_NODE_ADDEVENTLISTENER_USECAPTURE:
-
- if (Tcl_GetBooleanFromObj(interp, optobjv[1], &usecapture) != TCL_OK) {
- return TCL_ERROR;
- }
-
- break;
-
- default:
- Tcl_SetResult(interp, "unknown option", NULL);
- return TCL_ERROR;
- }
-
- optobjc -= 2;
- optobjv += 2;
- }
-
- if (nodePtr) {
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- } else {
- docObjPtr = TclXML_libxml2_CreateObjFromDoc(docPtr);
- if (TclXML_libxml2_GetTclDocFromObj(interp, docObjPtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- }
-
- return TclDOM_RemoveEventListener(interp, tDocPtr, tokenPtr, type, typeObjPtr, listenerPtr, usecapture);
- }
-
- break;
-
- case TCLDOM_NODE_DISPATCHEVENT:
-
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "event");
- return TCL_ERROR;
- } else {
- TclDOM_libxml2_Event *eventPtr;
-
- if (TclDOM_libxml2_GetEventFromObj(interp, optobjv[0], &eventPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- if (nodeObjPtr) {
- return TclDOM_DispatchEvent(interp, nodeObjPtr, optobjv[0], eventPtr);
- } else if (nodePtr) {
- return TclDOM_DispatchEvent(interp, TclDOM_libxml2_CreateObjFromNode(interp, nodePtr), optobjv[0], eventPtr);
- } else if (docObjPtr) {
- return TclDOM_DispatchEvent(interp, docObjPtr, optobjv[0], eventPtr);
- } else {
- Tcl_SetResult(interp, "unable to dispatch event", NULL);
- return TCL_ERROR;
- }
- }
-
- break;
-
- case TCLDOM_NODE_STRINGVALUE:
-
- if (optobjc != 0) {
- Tcl_WrongNumArgs(interp, wrongidx, objv, "");
- return TCL_ERROR;
- }
-
- Tcl_ResetResult(interp);
-
- Tcl_MutexLock(&libxml2);
-
- if (nodePtr) {
- buf = (char *) xmlNodeGetContent(nodePtr);
- Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
- xmlFree (buf);
- } else if (docPtr) {
- nodePtr = xmlDocGetRootElement(docPtr);
- if (nodePtr) {
- buf = (char *) xmlNodeGetContent(nodePtr);
- Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
- xmlFree (buf);
- } else {
- nodePtr = docPtr->children;
- while (nodePtr != NULL) {
- if (nodePtr->type == XML_TEXT_NODE) {
- Tcl_AppendResult(interp, (char *) nodePtr->content, NULL);
- }
- nodePtr = nodePtr->next;
- }
- }
- } else {
- Tcl_SetResult(interp, "cannot determine string value: internal error", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- break;
-
- case TCLDOM_NODE_SELECTNODE:
-
- Tcl_ResetResult(interp);
-
- return TclDOMSelectNodeCommand(clientData, interp, objc - 1, objv + 1);
-
- break;
-
- default:
- Tcl_SetResult(interp, "method \"", NULL);
- Tcl_AppendResult(interp, Tcl_GetStringFromObj(objv[1], NULL), "\" not yet implemented", NULL);
- return TCL_ERROR;
- }
-
- return TCL_OK;
-}
-int
-NodeCget(interp, docPtr, nodePtr, optPtr)
- Tcl_Interp *interp;
- xmlDocPtr docPtr;
- xmlNodePtr nodePtr;
- Tcl_Obj *CONST optPtr;
-{
- TclXML_libxml2_Document *tDocPtr;
- TclDOM_libxml2_Document *domDocPtr;
- Tcl_Obj *objPtr;
- xmlNodePtr childNodePtr;
- int option;
- char varname[100];
- Tcl_Obj *livePtr;
-
- if (Tcl_GetIndexFromObj(interp, optPtr, TclDOM_NodeCommandOptions,
- "option", 0, &option) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum TclDOM_NodeCommandOptions) option) {
-
- case TCLDOM_NODE_NODETYPE:
-
- if (docPtr) {
- Tcl_SetResult(interp, "document", NULL);
- break;
- }
-
- switch (nodePtr->type) {
- case XML_ELEMENT_NODE:
- Tcl_SetResult(interp, "element", NULL);
- break;
- case XML_ATTRIBUTE_NODE:
- Tcl_SetResult(interp, "attribute", NULL);
- break;
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- Tcl_SetResult(interp, "textNode", NULL);
- break;
- case XML_ENTITY_REF_NODE:
- Tcl_SetResult(interp, "entityReference", NULL);
- break;
- case XML_ENTITY_NODE:
- Tcl_SetResult(interp, "entity", NULL);
- break;
- case XML_PI_NODE:
- Tcl_SetResult(interp, "processingInstruction", NULL);
- break;
- case XML_COMMENT_NODE:
- Tcl_SetResult(interp, "comment", NULL);
- break;
- case XML_DOCUMENT_NODE:
- Tcl_SetResult(interp, "document", NULL);
- break;
- case XML_DOCUMENT_TYPE_NODE:
- Tcl_SetResult(interp, "docType", NULL);
- break;
- case XML_DOCUMENT_FRAG_NODE:
- Tcl_SetResult(interp, "documentFragment", NULL);
- break;
- case XML_NOTATION_NODE:
- Tcl_SetResult(interp, "notation", NULL);
- break;
- case XML_HTML_DOCUMENT_NODE:
- Tcl_SetResult(interp, "HTMLdocument", NULL);
- break;
- case XML_DTD_NODE:
- Tcl_SetResult(interp, "dtd", NULL);
- break;
- case XML_ELEMENT_DECL:
- Tcl_SetResult(interp, "elementDecl", NULL);
- break;
- case XML_ATTRIBUTE_DECL:
- Tcl_SetResult(interp, "attributeDecl", NULL);
- break;
- case XML_ENTITY_DECL:
- Tcl_SetResult(interp, "entityDecl", NULL);
- break;
- case XML_NAMESPACE_DECL:
- Tcl_SetResult(interp, "namespaceDecl", NULL);
- break;
- case XML_XINCLUDE_START:
- Tcl_SetResult(interp, "xincludeStart", NULL);
- break;
- case XML_XINCLUDE_END:
- Tcl_SetResult(interp, "xincludeEnd", NULL);
- break;
- default:
- Tcl_SetResult(interp, "unknown", NULL);
- }
-
- break;
-
- case TCLDOM_NODE_LOCALNAME:
- case TCLDOM_NODE_NODENAME:
-
- /* This isn't quite right: nodeName should return the expanded name */
-
- if (docPtr) {
- Tcl_SetResult(interp, "#document", NULL);
- break;
- }
- /* libxml2 doesn't maintain the correct DOM node name */
- switch (nodePtr->type) {
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NOTATION_NODE:
- Tcl_SetObjResult(interp, Tcl_NewStringObj((CONST char *) nodePtr->name, -1));
- break;
- case XML_TEXT_NODE:
- Tcl_SetResult(interp, "#text", NULL);
- break;
- case XML_CDATA_SECTION_NODE:
- Tcl_SetResult(interp, "#cdata-section", NULL);
- break;
- case XML_COMMENT_NODE:
- Tcl_SetResult(interp, "#comment", NULL);
- break;
- case XML_DOCUMENT_NODE:
- /* Already handled above */
- Tcl_SetResult(interp, "#document", NULL);
- break;
- case XML_DOCUMENT_FRAG_NODE:
- Tcl_SetResult(interp, "#document-fragment", NULL);
- break;
- case XML_HTML_DOCUMENT_NODE:
- /* Not standard DOM */
- Tcl_SetResult(interp, "#HTML-document", NULL);
- break;
- case XML_DTD_NODE:
- /* Not standard DOM */
- Tcl_SetResult(interp, "#dtd", NULL);
- break;
- case XML_ELEMENT_DECL:
- /* Not standard DOM */
- Tcl_SetResult(interp, "#element-declaration", NULL);
- break;
- case XML_ATTRIBUTE_DECL:
- /* Not standard DOM */
- Tcl_SetResult(interp, "#attribute-declaration", NULL);
- break;
- case XML_ENTITY_DECL:
- /* Not standard DOM */
- Tcl_SetResult(interp, "#entity-declaration", NULL);
- break;
- case XML_NAMESPACE_DECL:
- /* Not standard DOM */
- Tcl_SetResult(interp, "#namespace-declaration", NULL);
- break;
- case XML_XINCLUDE_START:
- /* Not standard DOM */
- Tcl_SetResult(interp, "#xinclude-start", NULL);
- break;
- case XML_XINCLUDE_END:
- /* Not standard DOM */
- Tcl_SetResult(interp, "#xinclude-end", NULL);
- break;
- default:
- Tcl_SetResult(interp, "#unknown", NULL);
- }
-
- break;
-
- case TCLDOM_NODE_NODEVALUE:
-
- if (docPtr) {
- break;
- }
-
- Tcl_MutexLock(&libxml2);
-
- if (XML_GET_CONTENT(nodePtr) != NULL) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj((CONST char *) XML_GET_CONTENT(nodePtr), -1));
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- break;
-
- case TCLDOM_NODE_OWNERDOCUMENT:
-
- if (docPtr) {
- Tcl_SetObjResult(interp, TclXML_libxml2_CreateObjFromDoc(docPtr));
- break;
- }
-
- Tcl_SetObjResult(interp, TclXML_libxml2_CreateObjFromDoc(nodePtr->doc));
-
- break;
-
- case TCLDOM_NODE_PARENTNODE:
-
- if (docPtr) {
- Tcl_ResetResult(interp);
- break;
- }
-
- if (nodePtr->parent) {
- if (nodePtr->parent->type == XML_DOCUMENT_NODE ||
- nodePtr->parent->type == XML_HTML_DOCUMENT_NODE) {
- Tcl_SetObjResult(interp, TclXML_libxml2_CreateObjFromDoc(nodePtr->doc));
- } else {
- Tcl_SetObjResult(interp, TclDOM_libxml2_CreateObjFromNode(interp, nodePtr->parent));
- }
- } else {
- Tcl_SetObjResult(interp, TclXML_libxml2_CreateObjFromDoc(nodePtr->doc));
- }
-
- break;
-
- case TCLDOM_NODE_CHILDNODES:
-
- /* Set up live NodeList variable */
-
- if (docPtr) {
- objPtr = TclXML_libxml2_CreateObjFromDoc(docPtr);
- if (TclXML_libxml2_GetTclDocFromObj(interp, objPtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- } else {
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- }
- domDocPtr = GetDOMDocument(interp, tDocPtr);
- if (domDocPtr == NULL) {
- Tcl_SetResult(interp, "internal error", NULL);
- return TCL_ERROR;
- }
- sprintf(varname, "::dom::%s::nodelist.%d", tDocPtr->token, domDocPtr->nodeCntr++);
- livePtr = Tcl_GetVar2Ex(interp, varname, NULL, TCL_GLOBAL_ONLY);
- if (!livePtr) {
- Tcl_Obj *nodelistPtr = Tcl_NewListObj(0, NULL);
-
- Tcl_SetVar2Ex(interp, varname, NULL, nodelistPtr, TCL_GLOBAL_ONLY);
- Tcl_IncrRefCount(nodelistPtr);
-
- if (docPtr) {
- if (Tcl_TraceVar(interp, varname, TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *) TclDOMLiveNodeListDoc, (ClientData) docPtr) != TCL_OK) {
- Tcl_DecrRefCount(nodelistPtr);
- return TCL_ERROR;
- } else {
- TclDOMLiveNodeListDoc((ClientData) tDocPtr->docPtr, interp, varname, NULL, TCL_TRACE_READS);
- }
- } else {
- if (Tcl_TraceVar(interp, varname, TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *) TclDOMLiveNodeListNode, (ClientData) nodePtr) != TCL_OK) {
- Tcl_DecrRefCount(nodelistPtr);
- return TCL_ERROR;
- } else {
- TclDOMLiveNodeListNode((ClientData) nodePtr, interp, varname, NULL, TCL_TRACE_READS);
- }
- }
- }
-
- Tcl_SetObjResult(interp, Tcl_NewStringObj(varname, -1));
-
- break;
-
- case TCLDOM_NODE_FIRSTCHILD:
-
- /*
- * Handle case where no children are present
- * Bug #1089114 w/- patch by dwcollins
- */
-
- if (docPtr) {
- childNodePtr = docPtr->children;
- } else {
- childNodePtr = nodePtr->children;
- }
-
- if (childNodePtr != NULL) {
- Tcl_SetObjResult(interp,
- TclDOM_libxml2_CreateObjFromNode(interp, childNodePtr));
- }
-
- break;
-
- case TCLDOM_NODE_LASTCHILD:
-
- if (docPtr) {
- childNodePtr = docPtr->last;
- } else {
- Tcl_MutexLock(&libxml2);
- childNodePtr = xmlGetLastChild(nodePtr);
- Tcl_MutexUnlock(&libxml2);
- }
- if (childNodePtr != NULL) {
- Tcl_SetObjResult(interp, TclDOM_libxml2_CreateObjFromNode(interp, childNodePtr));
- }
-
- break;
-
- case TCLDOM_NODE_NEXTSIBLING:
- if (!docPtr && nodePtr->next) {
- Tcl_SetObjResult(interp, TclDOM_libxml2_CreateObjFromNode(interp, nodePtr->next));
- }
-
- break;
-
- case TCLDOM_NODE_PREVIOUSSIBLING:
- if (!docPtr && nodePtr->prev) {
- Tcl_SetObjResult(interp, TclDOM_libxml2_CreateObjFromNode(interp, nodePtr->prev));
- }
-
- break;
-
- case TCLDOM_NODE_ATTRIBUTES:
-
- if (docPtr) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- } else if (nodePtr->type != XML_ELEMENT_NODE) {
- Tcl_SetResult(interp, "wrong object type", NULL);
- return TCL_ERROR;
- } else {
- /* Set up live NamedNodeMap variable */
-
- /* If there's already a variable, return it */
- objPtr = TclXML_libxml2_CreateObjFromDoc(nodePtr->doc);
- TclXML_libxml2_GetTclDocFromObj(interp, objPtr, &tDocPtr);
- domDocPtr = GetDOMDocument(interp, tDocPtr);
- if (domDocPtr == NULL) {
- Tcl_SetResult(interp, "internal error", NULL);
- return TCL_ERROR;
- }
- sprintf(varname, "::dom::%s::att%d", tDocPtr->token, domDocPtr->nodeCntr++);
- livePtr = Tcl_GetVar2Ex(interp, varname, NULL, TCL_GLOBAL_ONLY);
- if (!livePtr) {
- if (TclDOMSetLiveNamedNodeMap(interp, varname, (ClientData) nodePtr) != TCL_OK) {
- Tcl_UnsetVar(interp, varname, TCL_GLOBAL_ONLY);
- return TCL_ERROR;
- }
-
- if (Tcl_TraceVar(interp, varname, TCL_TRACE_ARRAY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *) TclDOMLiveNamedNodeMap, (ClientData) nodePtr) != TCL_OK) {
- Tcl_UnsetVar(interp, varname, TCL_GLOBAL_ONLY);
- return TCL_ERROR;
- }
- }
-
- Tcl_SetObjResult(interp, Tcl_NewStringObj(varname, -1));
-
- }
-
- break;
-
- case TCLDOM_NODE_NAMESPACEURI:
-
- if (!docPtr && nodePtr->ns) {
- if (nodePtr->ns->href) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj((CONST char *) nodePtr->ns->href, -1));
- }
- }
-
- break;
-
- case TCLDOM_NODE_PREFIX:
-
- if (!docPtr && nodePtr->ns) {
- if (nodePtr->ns->prefix) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj((CONST char *) nodePtr->ns->prefix, -1));
- }
- }
-
- break;
-
- default:
- Tcl_SetResult(interp, "unknown option or not yet implemented", NULL);
- return TCL_ERROR;
- }
-
- return TCL_OK;
-}
-int
-NodeConfigure(interp, nodePtr, objc, objv)
- Tcl_Interp *interp;
- xmlNodePtr nodePtr;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- TclXML_libxml2_Document *tDocPtr;
- Tcl_Obj *objPtr;
- char *buf;
- int option, len;
-
- while (objc) {
- if (objc == 1) {
- Tcl_SetResult(interp, "missing value", NULL);
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[0], TclDOM_NodeCommandOptions,
- "option", 0, &option) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum TclDOM_NodeCommandOptions) option) {
- case TCLDOM_NODE_NODETYPE:
- case TCLDOM_NODE_NODENAME:
- case TCLDOM_NODE_PARENTNODE:
- case TCLDOM_NODE_CHILDNODES:
- case TCLDOM_NODE_FIRSTCHILD:
- case TCLDOM_NODE_LASTCHILD:
- case TCLDOM_NODE_PREVIOUSSIBLING:
- case TCLDOM_NODE_NEXTSIBLING:
- case TCLDOM_NODE_ATTRIBUTES:
- case TCLDOM_NODE_NAMESPACEURI:
- case TCLDOM_NODE_PREFIX:
- case TCLDOM_NODE_LOCALNAME:
- case TCLDOM_NODE_OWNERDOCUMENT:
-
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "attribute \"", Tcl_GetStringFromObj(objv[0], NULL), "\" is read-only", NULL);
- return TCL_ERROR;
-
- case TCLDOM_NODE_NODEVALUE:
-
- if (!nodePtr) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
-
- switch (nodePtr->type) {
- case XML_ELEMENT_NODE:
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_ENTITY_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- /*
- * DOM defines these nodes as not having a node value.
- * libxml2 clobbers existing content if the value is set,
- * so don't do it!
- */
- Tcl_ResetResult(interp);
- return TCL_OK;
-
- default:
- /* fall-through */
- break;
- }
-
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
-
- objPtr = Tcl_NewStringObj((CONST char *) xmlNodeGetContent(nodePtr), -1);
-
- buf = Tcl_GetStringFromObj(objv[1], &len);
- xmlNodeSetContentLen(nodePtr, (const xmlChar *) buf, len);
-
- Tcl_MutexUnlock(&libxml2);
-
- TclDOM_PostMutationEvent(interp,
- tDocPtr, TclDOM_libxml2_CreateObjFromNode(interp, nodePtr),
- TCLDOM_EVENT_DOMCHARACTERDATAMODIFIED, NULL,
- Tcl_NewIntObj(1), Tcl_NewIntObj(0), NULL, objPtr, objv[1], NULL, NULL);
-
- Tcl_DecrRefCount(objPtr);
-
- break;
-
- case TCLDOM_NODE_CDATASECTION:
-
- break;
- }
-
- objc -= 2;
- objv += 2;
-
- }
-
- return TCL_OK;
-}
-
-int
-TclDOM_NodeAppendChild(interp, nodePtr, childPtr)
- Tcl_Interp *interp;
- xmlNodePtr nodePtr;
- xmlNodePtr childPtr;
-{
- TclXML_libxml2_Document *tDocPtr;
- xmlNodePtr oldParent;
- xmlNodePtr oldSibling;
-
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- oldParent = childPtr->parent;
- oldSibling = childPtr->next;
-
- if (oldParent && oldParent != nodePtr) {
- TclDOM_PostMutationEvent(interp,
- tDocPtr,
- TclDOM_libxml2_CreateObjFromNode(interp, childPtr),
- TCLDOM_EVENT_DOMNODEREMOVED, NULL,
- Tcl_NewIntObj(1), Tcl_NewIntObj(0),
- TclDOM_libxml2_CreateObjFromNode(interp, oldParent),
- NULL, NULL, NULL, NULL);
- }
-
- Tcl_MutexLock(&libxml2);
-
- /* Although xmlAddChild claims to release the child from its previous context,
- * that doesn't appear to actually happen.
- */
- xmlUnlinkNode(childPtr);
- if (xmlAddChild(nodePtr, childPtr) == NULL) {
- if (oldSibling) {
- xmlAddPrevSibling(oldSibling, childPtr);
- } else {
- xmlAddChild(oldParent, childPtr);
- }
-
- Tcl_SetResult(interp, "unable to insert node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- PostMutationEvents(interp, tDocPtr, nodePtr, childPtr, childPtr, oldParent, childPtr->parent);
-
- Tcl_SetObjResult(interp, TclDOM_libxml2_CreateObjFromNode(interp, childPtr));
-
- return TCL_OK;
-}
-
-int
-TclDOM_NodeInsertBefore(interp, refPtr, newPtr)
- Tcl_Interp *interp;
- xmlNodePtr refPtr;
- xmlNodePtr newPtr;
-{
- TclXML_libxml2_Document *tDocPtr;
- xmlNodePtr oldParent;
-
- if (TclXML_libxml2_GetTclDocFromNode(interp, refPtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- oldParent = newPtr->parent;
- if (oldParent != refPtr->parent) {
- TclDOM_PostMutationEvent(interp,
- tDocPtr,
- TclDOM_libxml2_CreateObjFromNode(interp, refPtr),
- TCLDOM_EVENT_DOMNODEREMOVED, NULL,
- Tcl_NewIntObj(1), Tcl_NewIntObj(0),
- TclDOM_libxml2_CreateObjFromNode(interp, newPtr->parent),
- NULL, NULL, NULL, NULL);
- }
-
- Tcl_MutexLock(&libxml2);
-
- if (xmlAddPrevSibling(refPtr, newPtr) == NULL) {
- Tcl_SetResult(interp, "unable to insert node", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- Tcl_MutexUnlock(&libxml2);
-
- PostMutationEvents(interp, tDocPtr, refPtr, refPtr, newPtr, oldParent, refPtr->parent);
-
- return TCL_OK;
-}
-
-void PostMutationEvents(interp, tDocPtr, nodePtr, refPtr, newPtr, oldParent, newParent)
- Tcl_Interp *interp;
- TclXML_libxml2_Document *tDocPtr;
- xmlNodePtr nodePtr;
- xmlNodePtr refPtr;
- xmlNodePtr newPtr;
- xmlNodePtr oldParent;
- xmlNodePtr newParent;
-{
- /* If parent has changed, notify old parent */
- if (oldParent != NULL && oldParent != newParent) {
- TclDOM_PostMutationEvent(interp,
- tDocPtr,
- TclDOM_libxml2_CreateObjFromNode(interp, oldParent),
- TCLDOM_EVENT_DOMSUBTREEMODIFIED, NULL,
- Tcl_NewIntObj(1), Tcl_NewIntObj(0),
- NULL, NULL, NULL, NULL, NULL);
- }
- /* Notify new parent */
- if (newParent != NULL) {
- TclDOM_PostMutationEvent(interp,
- tDocPtr,
- TclDOM_libxml2_CreateObjFromNode(interp, newParent),
- TCLDOM_EVENT_DOMSUBTREEMODIFIED, NULL,
- Tcl_NewIntObj(1), Tcl_NewIntObj(0),
- NULL, NULL, NULL, NULL, NULL);
- }
-
- /* Inserted event */
- if (newPtr != NULL) {
- TclDOM_PostMutationEvent(interp,
- tDocPtr,
- TclDOM_libxml2_CreateObjFromNode(interp, newPtr),
- TCLDOM_EVENT_DOMNODEINSERTED, NULL,
- Tcl_NewIntObj(1), Tcl_NewIntObj(0),
- NULL, NULL, NULL, NULL, NULL);
- }
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_AddEventListener --
- *
- * Register an event listener.
- *
- * Results:
- * Success code.
- *
- * Side effects:
- * Event listener stored.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOM_AddEventListener(interp, tDocPtr, tokenPtr, type, typeObjPtr, listenerPtr, capturer)
- Tcl_Interp *interp;
- TclXML_libxml2_Document *tDocPtr;
- void *tokenPtr; /* xmlNodePtr or xmlDocPtr */
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr;
- Tcl_Obj *listenerPtr;
- int capturer;
-{
- TclDOM_libxml2_Document *domDocPtr;
- Tcl_HashTable *tablePtr;
- Tcl_HashEntry *entryPtr;
- int new;
-
- domDocPtr = GetDOMDocument(interp, tDocPtr);
- if (domDocPtr == NULL) {
- Tcl_SetResult(interp, "internal error", NULL);
- return TCL_ERROR;
- }
-
- if (capturer) {
- tablePtr = domDocPtr->captureListeners;
- } else {
- tablePtr = domDocPtr->bubbleListeners;
- }
-
- entryPtr = Tcl_CreateHashEntry(tablePtr, tokenPtr, &new);
- if (new) {
- tablePtr = (Tcl_HashTable *) Tcl_Alloc(sizeof(Tcl_HashTable));
- Tcl_InitHashTable(tablePtr, TCL_STRING_KEYS);
- Tcl_SetHashValue(entryPtr, (char *) tablePtr);
- } else {
- tablePtr = (Tcl_HashTable *) Tcl_GetHashValue(entryPtr);
- }
-
- if (type == TCLDOM_EVENT_USERDEFINED) {
- entryPtr = Tcl_CreateHashEntry(tablePtr, Tcl_GetStringFromObj(typeObjPtr, NULL), &new);
- } else {
- entryPtr = Tcl_CreateHashEntry(tablePtr, TclDOM_EventTypes[type], &new);
- }
- if (new) {
- Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL);
-
- Tcl_IncrRefCount(listenerPtr);
- Tcl_IncrRefCount(listPtr);
- Tcl_ListObjAppendElement(interp, listPtr, listenerPtr);
- Tcl_SetHashValue(entryPtr, (char *) listPtr);
-
- } else {
- Tcl_Obj *listPtr = (Tcl_Obj *) Tcl_GetHashValue(entryPtr);
- Tcl_Obj *curPtr;
- int idx, len, listenerLen, len2, listlen;
- char *listenerBuf, *buf2;
-
- if (Tcl_ListObjLength(interp, listPtr, &len) != TCL_OK) {
- Tcl_SetResult(interp, "internal error - bad list", NULL);
- return TCL_ERROR;
- }
- listenerBuf = Tcl_GetStringFromObj(listenerPtr, &listenerLen);
-
- new = 0;
- for (idx = 0; idx < len; idx++) {
- Tcl_ListObjIndex(interp, listPtr, idx, &curPtr);
- buf2 = Tcl_GetStringFromObj(curPtr, &len2);
-
- if (listenerLen == len2 &&
- !strncmp(listenerBuf, buf2, listenerLen)) {
- new = 1;
- break;
- }
- }
-
- if (Tcl_ListObjLength(interp, listPtr, &listlen) != TCL_OK) {
- return TCL_ERROR;
- }
-
- Tcl_ListObjReplace(interp, listPtr, idx, new, 1, &listenerPtr);
-
- }
-
- /*
- * Performance optimization:
- * Keep track of which event types have listeners registered.
- * If there are no listeners for an event type, then there's
- * no point in dispatching that type of event.
- * NB. This does not keep track of user-defined events types.
- */
-
- if (type != TCLDOM_EVENT_USERDEFINED) {
- domDocPtr->listening[type]++;
- } /* else this is a user-defined event type - it won't be tracked */
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_GetEventListener --
- *
- * Find the listener registered for an event type.
- *
- * Results:
- * Event listener returned.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Tcl_Obj *
-TclDOM_GetEventListener(interp,tDocPtr, tokenPtr, type, typeObjPtr, capturer)
- Tcl_Interp *interp;
- TclXML_libxml2_Document *tDocPtr;
- void *tokenPtr;
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr;
- int capturer;
-{
- TclDOM_libxml2_Document *domDocPtr;
- Tcl_HashTable *tablePtr;
- Tcl_HashEntry *entryPtr;
-
- domDocPtr = GetDOMDocument(interp, tDocPtr);
- if (domDocPtr == NULL) {
- Tcl_SetResult(interp, "internal error", NULL);
- return NULL;
- }
-
- if (capturer) {
- tablePtr = domDocPtr->captureListeners;
- } else {
- tablePtr = domDocPtr->bubbleListeners;
- }
-
- entryPtr = Tcl_FindHashEntry(tablePtr, tokenPtr);
- if (entryPtr) {
- tablePtr = (Tcl_HashTable *) Tcl_GetHashValue(entryPtr);
-
- if (type == TCLDOM_EVENT_USERDEFINED) {
- entryPtr = Tcl_FindHashEntry(tablePtr, Tcl_GetStringFromObj(typeObjPtr, NULL));
- } else {
- entryPtr = Tcl_FindHashEntry(tablePtr, TclDOM_EventTypes[type]);
- }
- if (entryPtr) {
- return (Tcl_Obj *) Tcl_GetHashValue(entryPtr);
- }
- }
-
- return Tcl_NewObj();
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_RemoveEventListener --
- *
- * Deregister an event listener.
- *
- * Results:
- * Success code.
- *
- * Side effects:
- * May free Tcl objects.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOM_RemoveEventListener(interp, tDocPtr, tokenPtr, type, typeObjPtr, listenerPtr, capturer)
- Tcl_Interp *interp;
- TclXML_libxml2_Document *tDocPtr;
- void *tokenPtr;
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr;
- Tcl_Obj *listenerPtr;
- int capturer;
-{
- TclDOM_libxml2_Document *domDocPtr;
- Tcl_HashTable *tablePtr;
- Tcl_HashEntry *entryPtr;
-
- domDocPtr = GetDOMDocument(interp, tDocPtr);
- if (domDocPtr == NULL) {
- Tcl_SetResult(interp, "internal error", NULL);
- return TCL_ERROR;
- }
-
- if (capturer) {
- tablePtr = domDocPtr->captureListeners;
- } else {
- tablePtr = domDocPtr->bubbleListeners;
- }
-
- entryPtr = Tcl_FindHashEntry(tablePtr, tokenPtr);
- if (entryPtr) {
- tablePtr = (Tcl_HashTable *) Tcl_GetHashValue(entryPtr);
-
- if (type == TCLDOM_EVENT_USERDEFINED) {
- entryPtr = Tcl_FindHashEntry(tablePtr, Tcl_GetStringFromObj(typeObjPtr, NULL));
- } else {
- entryPtr = Tcl_FindHashEntry(tablePtr, TclDOM_EventTypes[type]);
- }
- if (entryPtr) {
- Tcl_Obj *listPtr = (Tcl_Obj *) Tcl_GetHashValue(entryPtr);
- Tcl_Obj *curPtr;
- int idx, listenerLen, len, len2, found;
- char *listenerBuf, *buf2;
-
- if (Tcl_ListObjLength(interp, listPtr, &len) != TCL_OK) {
- Tcl_SetResult(interp, "internal error - bad list", NULL);
- return TCL_ERROR;
- }
- listenerBuf = Tcl_GetStringFromObj(listenerPtr, &listenerLen);
- found = 0;
- for (idx = 0; idx < len; idx++) {
- Tcl_ListObjIndex(interp, listPtr, idx, &curPtr);
- buf2 = Tcl_GetStringFromObj(curPtr, &len2);
- if (listenerLen == len2 &&
- !strncmp(listenerBuf, buf2, listenerLen)) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- Tcl_SetResult(interp, "listener not found", NULL);
- return TCL_ERROR;
- } else {
- Tcl_ListObjReplace(interp, listPtr, idx, 1, 0, NULL);
-
- /*
- * Keep track of which event types have listeners registered.
- */
-
- if (type != TCLDOM_EVENT_USERDEFINED) {
- domDocPtr->listening[type]--;
- } /* else user-defined event type - not being tracked */
- }
- } else {
- Tcl_SetResult(interp, "no listeners registered", NULL);
- return TCL_ERROR;
- }
- } else {
- Tcl_SetResult(interp, "no listeners registered", NULL);
- return TCL_ERROR;
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * HasListener --
- *
- * Check whether an event listener is registered for an event type.
- *
- * Results:
- * Returns boolean.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HasListener(interp, tDocPtr, eventType)
- Tcl_Interp *interp;
- TclXML_libxml2_Document *tDocPtr;
- enum TclDOM_EventTypes eventType;
-{
- TclDOM_libxml2_Document *domDocPtr = GetDOMDocument(interp, tDocPtr);
-
- if (domDocPtr == NULL) {
- return 0;
- }
-
- if (eventType == TCLDOM_EVENT_USERDEFINED) {
- /*
- * We don't know whether there is a listener or not,
- * so play it safe.
- */
- return 1;
- }
-
- if (domDocPtr->listening[eventType] > 0) {
- return 1;
- }
-
- return 0;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_DispatchEvent --
- *
- * Dispatch an event object.
- *
- * Results:
- * Event propagates through the DOM tree.
- *
- * Side effects:
- * Depends on event listeners.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOM_DispatchEvent(interp, nodeObjPtr, eventObjPtr, eventPtr)
- Tcl_Interp *interp;
- Tcl_Obj *nodeObjPtr;
- Tcl_Obj *eventObjPtr;
- TclDOM_libxml2_Event *eventPtr;
-{
- xmlNodePtr nodePtr;
- xmlDocPtr docPtr;
- TclXML_libxml2_Document *tDocPtr;
- TclDOM_libxml2_Document *domDocPtr;
- char *phase;
- Tcl_Obj *docObjPtr, *pathPtr = NULL;
- int idx, len, cancelable;
- void *tokenPtr;
-
- if (TclDOM_libxml2_GetNodeFromObj(interp, nodeObjPtr, &nodePtr) != TCL_OK) {
- if (TclXML_libxml2_GetTclDocFromObj(interp, nodeObjPtr, &tDocPtr) != TCL_OK) {
- Tcl_SetResult(interp, "unrecognised token", NULL);
- return TCL_ERROR;
- } else {
- docObjPtr = nodeObjPtr;
- docPtr = tDocPtr->docPtr;
- nodeObjPtr = NULL;
- nodePtr = NULL;
- tokenPtr = (void *) docPtr;
- }
- } else {
- docPtr = nodePtr->doc;
- docObjPtr = TclXML_libxml2_CreateObjFromDoc(docPtr);
- if (TclXML_libxml2_GetTclDocFromObj(interp, docObjPtr, &tDocPtr) != TCL_OK) {
- Tcl_SetResult(interp, "unknown document", NULL);
- return TCL_ERROR;
- }
- tokenPtr = (void *) nodePtr;
- }
- Tcl_ResetResult(interp);
-
- /*
- * Performance optimization:
- * If there are no listeners registered for this event type,
- * then there is no point in propagating the event.
- */
- if (!HasListener(interp, tDocPtr, eventPtr->type)) {
- return TCL_OK;
- }
-
- domDocPtr = GetDOMDocument(interp, tDocPtr);
- if (domDocPtr == NULL) {
- Tcl_SetResult(interp, "internal error", NULL);
- return TCL_ERROR;
- }
-
- phase = Tcl_GetStringFromObj(eventPtr->eventPhase, &len);
-
- if (!len) {
- /*
- * This is the initial dispatch of the event.
- * First trigger any capturing event listeners
- * Starting from the root, proceed downward
- */
-
- Tcl_SetStringObj(eventPtr->eventPhase, "capturing_phase", -1);
- eventPtr->target = nodeObjPtr;
- Tcl_IncrRefCount(nodeObjPtr);
-
- if (nodePtr) {
- pathPtr = GetPath(interp, nodePtr);
- } else {
- pathPtr = Tcl_NewObj();
- }
- if (eventPtr->currentNode) {
- Tcl_DecrRefCount(eventPtr->currentNode);
- }
- eventPtr->currentNode = docObjPtr;
- Tcl_IncrRefCount(docObjPtr);
- if (TriggerEventListeners(interp, domDocPtr->captureListeners, (void *) docPtr, eventObjPtr, eventPtr) != TCL_OK) {
- Tcl_DecrRefCount(pathPtr);
- return TCL_ERROR;
- }
-
- if (Tcl_GetBooleanFromObj(interp, eventPtr->cancelable, &cancelable) != TCL_OK) {
- Tcl_DecrRefCount(pathPtr);
- return TCL_ERROR;
- }
- if (cancelable && eventPtr->stopPropagation) {
- goto stop_propagation;
- }
-
- Tcl_ListObjLength(interp, pathPtr, &len);
- Tcl_ListObjReplace(interp, pathPtr, len - 1, 1, 0, NULL);
- Tcl_ListObjReplace(interp, pathPtr, 0, 1, 0, NULL);
- Tcl_ListObjLength(interp, pathPtr, &len);
- for (idx = 0; idx < len; idx++) {
- Tcl_Obj *ancestorObjPtr;
- xmlNodePtr ancestorPtr;
-
- Tcl_ListObjIndex(interp, pathPtr, idx, &ancestorObjPtr);
- if (eventPtr->currentNode) {
- Tcl_DecrRefCount(eventPtr->currentNode);
- }
- eventPtr->currentNode = ancestorObjPtr;
- Tcl_IncrRefCount(ancestorObjPtr);
- if (TclDOM_libxml2_GetNodeFromObj(interp, ancestorObjPtr, &ancestorPtr) != TCL_OK) {
- Tcl_SetResult(interp, "cannot find ancestor node \"", NULL);
- Tcl_AppendResult(interp, Tcl_GetStringFromObj(ancestorObjPtr, NULL), "\"", NULL);
- return TCL_ERROR;
- }
-
- if (TriggerEventListeners(interp, domDocPtr->captureListeners, (void *) ancestorPtr, eventObjPtr, eventPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- /*
- * A listener may stop propagation,
- * but we check here to let all of the
- * listeners at that level complete.
- */
-
- if (Tcl_GetBooleanFromObj(interp, eventPtr->cancelable, &cancelable) != TCL_OK) {
- Tcl_DecrRefCount(ancestorObjPtr);
- return TCL_ERROR;
- }
- if (cancelable && eventPtr->stopPropagation) {
- Tcl_DecrRefCount(ancestorObjPtr);
- goto stop_propagation;
- }
-
- Tcl_DecrRefCount(ancestorObjPtr);
-
- }
-
- /* Prepare for the next phase */
-
- if (Tcl_IsShared(eventPtr->eventPhase)) {
- Tcl_DecrRefCount(eventPtr->eventPhase);
- eventPtr->eventPhase = Tcl_NewStringObj("at_target", -1);
- Tcl_IncrRefCount(eventPtr->eventPhase);
- } else {
- Tcl_SetStringObj(eventPtr->eventPhase, "at_target", -1);
- }
- }
-
- if (eventPtr->currentNode) {
- Tcl_DecrRefCount(eventPtr->currentNode);
- }
- if (nodePtr) {
- eventPtr->currentNode = nodeObjPtr;
- tokenPtr = (void *) nodePtr;
- } else {
- eventPtr->currentNode = docObjPtr;
- tokenPtr = (void *) docPtr;
- }
- Tcl_IncrRefCount(eventPtr->currentNode);
-
- if (TriggerEventListeners(interp, domDocPtr->bubbleListeners, tokenPtr, eventObjPtr, eventPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- if (Tcl_IsShared(eventPtr->eventPhase)) {
- Tcl_DecrRefCount(eventPtr->eventPhase);
- eventPtr->eventPhase = Tcl_NewStringObj("bubbling_phase", -1);
- Tcl_IncrRefCount(eventPtr->eventPhase);
- } else {
- Tcl_SetStringObj(eventPtr->eventPhase, "bubbling_phase", -1);
- }
-
- if (Tcl_GetBooleanFromObj(interp, eventPtr->cancelable, &cancelable) != TCL_OK) {
- return TCL_ERROR;
- }
- if (cancelable && eventPtr->stopPropagation) {
- /* Do no more */
- } else if (nodePtr && nodePtr->parent && nodePtr->parent != (xmlNodePtr) nodePtr->doc) {
- Tcl_Obj *objPtr;
-
- objPtr = TclDOM_libxml2_CreateObjFromNode(interp, nodePtr->parent);
- if (objPtr == NULL) {
- return TCL_ERROR;
- }
- return TclDOM_DispatchEvent(interp,
- objPtr,
- eventObjPtr, eventPtr);
- } else if (nodePtr && nodePtr->parent) {
- Tcl_Obj *objPtr;
-
- objPtr = TclXML_libxml2_CreateObjFromDoc(nodePtr->doc);
- if (objPtr == NULL) {
- return TCL_ERROR;
- }
- return TclDOM_DispatchEvent(interp,
- objPtr,
- eventObjPtr, eventPtr);
- }
-
-stop_propagation:
- eventPtr->dispatched = 1;
-
- if (pathPtr) {
- Tcl_DecrRefCount(pathPtr);
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMElementCommand --
- *
- * Implements dom::libxml2::element command.
- *
- * Results:
- * Depends on method.
- *
- * Side effects:
- * Depends on method.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOMElementCommand (clientData, interp, objc, objv)
- ClientData clientData;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- int method, optobjc;
- Tcl_Obj *CONST *optobjv;
- xmlNodePtr nodePtr;
- TclXML_libxml2_Document *tDocPtr;
- char *value;
- xmlAttrPtr attrPtr;
- xmlNsPtr nsPtr;
-
- if (clientData == NULL) {
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "method ?args...?");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetNodeFromObj(interp, objv[2], &nodePtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- optobjv = objv + 3;
- optobjc = objc - 3;
-
- } else {
-
- nodePtr = (xmlNodePtr) clientData;
-
- optobjv = objv + 2;
- optobjc = objc - 2;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[1], TclDOM_ElementCommandMethods,
- "method", 0, &method) != TCL_OK) {
- return TCL_ERROR;
- }
-
- /* Should check that the node is of element type */
-
- Tcl_ResetResult(interp);
-
- switch ((enum TclDOM_ElementCommandMethods) method) {
-
- case TCLDOM_ELEMENT_CGET:
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "option");
- return TCL_ERROR;
- }
-
- return ElementCget(interp, nodePtr, optobjv[0]);
-
- break;
-
- case TCLDOM_ELEMENT_CONFIGURE:
-
- if (optobjc == 1) {
- return ElementCget(interp, nodePtr, optobjv[0]);
- } else {
- Tcl_AppendResult(interp, "option \"", Tcl_GetStringFromObj(optobjv[0], NULL), "\" cannot be modified", NULL);
- return TCL_ERROR;
- }
-
- break;
-
- case TCLDOM_ELEMENT_GETATTRIBUTE:
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "attr");
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
- value = (char *) xmlGetProp(nodePtr, (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL));
- Tcl_MutexUnlock(&libxml2);
-
- if (value) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(value, -1));
- }
-
- break;
-
- case TCLDOM_ELEMENT_GETATTRIBUTENS:
- if (optobjc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "ns attr");
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
- value = (char *) xmlGetNsProp(nodePtr,
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[1], NULL),
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL));
- Tcl_MutexUnlock(&libxml2);
-
- if (value) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(value, -1));
- }
-
- break;
-
- case TCLDOM_ELEMENT_SETATTRIBUTE:
- if (optobjc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "attr value");
- return TCL_ERROR;
- }
-
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
- value = (char *) xmlGetProp(nodePtr, (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL));
- attrPtr = xmlSetProp(nodePtr,
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL),
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[1], NULL));
- Tcl_MutexUnlock(&libxml2);
-
- if (!attrPtr) {
- Tcl_SetResult(interp, "unable to set attribute", NULL);
- return TCL_ERROR;
- }
-
- TclDOM_PostMutationEvent(interp, tDocPtr, objv[2], TCLDOM_EVENT_DOMATTRMODIFIED, NULL, Tcl_NewIntObj(1), Tcl_NewIntObj(0), NULL, Tcl_NewStringObj(value, -1), optobjv[1], optobjv[0], value == NULL? Tcl_NewStringObj("modification", -1) : Tcl_NewStringObj("addition", -1));
-
- Tcl_SetObjResult(interp, optobjv[1]);
-
- break;
-
- case TCLDOM_ELEMENT_SETATTRIBUTENS:
- if (optobjc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "ns attr value");
- return TCL_ERROR;
- }
-
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- Tcl_MutexLock(&libxml2);
-
- nsPtr = xmlSearchNsByHref(nodePtr->doc, nodePtr, (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL));
- if (!nsPtr) {
- Tcl_SetResult(interp, "no XML Namespace declaration for namespace", NULL);
- Tcl_MutexUnlock(&libxml2);
- return TCL_ERROR;
- }
-
- value = (char *) xmlGetNsProp(nodePtr,
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[1], NULL),
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[2], NULL));
- attrPtr = xmlSetNsProp(nodePtr,
- nsPtr,
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[1], NULL),
- (const xmlChar *) Tcl_GetStringFromObj(optobjv[3], NULL));
-
- Tcl_MutexUnlock(&libxml2);
-
- if (!attrPtr) {
- Tcl_SetResult(interp, "unable to set attribute", NULL);
- return TCL_ERROR;
- }
-
- TclDOM_PostMutationEvent(interp, tDocPtr, objv[2], TCLDOM_EVENT_DOMATTRMODIFIED, NULL, Tcl_NewIntObj(1), Tcl_NewIntObj(0), NULL, Tcl_NewStringObj(value, -1), optobjv[3], optobjv[2], value == NULL? Tcl_NewStringObj("modification", -1) : Tcl_NewStringObj("addition", -1));
-
- break;
-
- case TCLDOM_ELEMENT_REMOVEATTRIBUTE:
-
- if (optobjc != 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "attr");
- return TCL_ERROR;
- }
-
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- /* It doesn't matter if this fails due to a non-existant attribute */
- Tcl_MutexLock(&libxml2);
- xmlUnsetProp(nodePtr, (const xmlChar *) Tcl_GetStringFromObj(optobjv[0], NULL));
- Tcl_MutexUnlock(&libxml2);
-
- TclDOM_PostMutationEvent(interp, tDocPtr, objv[2], TCLDOM_EVENT_DOMATTRMODIFIED, NULL, Tcl_NewIntObj(1), Tcl_NewIntObj(0), NULL, NULL, NULL, optobjv[2], Tcl_NewStringObj("removed", -1));
-
- break;
-
- default:
- Tcl_SetResult(interp, "method \"", NULL);
- Tcl_AppendResult(interp, Tcl_GetStringFromObj(objv[1], NULL), "\" not yet implemented", NULL);
- return TCL_ERROR;
- }
-
- return TCL_OK;
-}
-
-int
-ElementCget(interp, nodePtr, optObj)
- Tcl_Interp *interp;
- xmlNodePtr nodePtr;
- Tcl_Obj *CONST optObj;
-{
- int option;
-
- if (Tcl_GetIndexFromObj(interp, optObj, TclDOM_ElementCommandOptions,
- "option", 0, &option) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum TclDOM_ElementCommandOptions) option) {
- case TCLDOM_ELEMENT_TAGNAME:
- Tcl_SetObjResult(interp, Tcl_NewStringObj((CONST char *) nodePtr->name, -1));
- break;
-
- case TCLDOM_ELEMENT_EMPTY:
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- break;
-
- default:
- Tcl_SetResult(interp, "unknown option", NULL);
- return TCL_ERROR;
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_InitEvent --
- *
- * Initializes an event object.
- *
- * Results:
- * Tcl_Obj references stored.
- *
- * Side effects:
- * Tcl_Obj's reference count changed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-TclDOM_InitEvent(eventPtr, type, typeObjPtr, bubblesPtr, cancelablePtr)
- TclDOM_libxml2_Event *eventPtr;
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr;
- Tcl_Obj *bubblesPtr;
- Tcl_Obj *cancelablePtr;
-{
- if (type != TCLDOM_EVENT_USERDEFINED) {
- if (eventPtr->type != type) {
- if (eventPtr->typeObjPtr) {
- Tcl_DecrRefCount(eventPtr->typeObjPtr);
- eventPtr->typeObjPtr = NULL;
- }
- eventPtr->type = type;
- }
- } else {
- char *oldType, *newType;
- int oldLen, newLen;
-
- oldType = Tcl_GetStringFromObj(eventPtr->typeObjPtr, &oldLen);
- newType = Tcl_GetStringFromObj(typeObjPtr, &newLen);
- if (oldLen != newLen ||
- strncmp(oldType, newType, oldLen)) {
- Tcl_DecrRefCount(eventPtr->typeObjPtr);
- eventPtr->typeObjPtr = typeObjPtr;
- Tcl_IncrRefCount(typeObjPtr);
- eventPtr->type = TCLDOM_EVENT_USERDEFINED;
- }
- }
-
- if (bubblesPtr && eventPtr->bubbles != bubblesPtr) {
- Tcl_DecrRefCount(eventPtr->bubbles);
- eventPtr->bubbles = bubblesPtr;
- Tcl_IncrRefCount(eventPtr->bubbles);
- }
- if (cancelablePtr && eventPtr->cancelable != cancelablePtr) {
- Tcl_DecrRefCount(eventPtr->cancelable);
- eventPtr->cancelable = cancelablePtr;
- Tcl_IncrRefCount(eventPtr->cancelable);
- }
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_InitUIEvent --
- *
- * Initializes an event object.
- *
- * Results:
- * Tcl_Obj references stored.
- *
- * Side effects:
- * Tcl_Obj's reference count changed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-TclDOM_InitUIEvent(eventPtr, type, typeObjPtr, bubblesPtr, cancelablePtr, viewPtr, detailPtr)
- TclDOM_libxml2_Event *eventPtr;
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr;
- Tcl_Obj *bubblesPtr;
- Tcl_Obj *cancelablePtr;
- Tcl_Obj *viewPtr;
- Tcl_Obj *detailPtr;
-{
- TclDOM_InitEvent(eventPtr, type, typeObjPtr, bubblesPtr, cancelablePtr);
-
- if (viewPtr && eventPtr->view != viewPtr) {
- Tcl_DecrRefCount(eventPtr->view);
- eventPtr->view = viewPtr;
- Tcl_IncrRefCount(eventPtr->view);
- }
- if (detailPtr && eventPtr->detail != detailPtr) {
- Tcl_DecrRefCount(eventPtr->detail);
- eventPtr->detail = detailPtr;
- Tcl_IncrRefCount(eventPtr->detail);
- } else if (detailPtr == NULL) {
- Tcl_DecrRefCount(eventPtr->detail);
- eventPtr->detail = Tcl_NewObj();
- }
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_InitMouseEvent --
- *
- * Initializes an event object.
- *
- * Results:
- * Tcl_Obj references stored.
- *
- * Side effects:
- * Tcl_Obj's reference count changed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-TclDOM_InitMouseEvent(eventPtr, type, typeObjPtr, bubblesPtr, cancelablePtr, viewPtr, detailPtr, screenXPtr, screenYPtr, clientXPtr, clientYPtr, ctrlKeyPtr, altKeyPtr, shiftKeyPtr, metaKeyPtr, buttonPtr, relatedNodePtr)
- TclDOM_libxml2_Event *eventPtr;
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr;
- Tcl_Obj *bubblesPtr;
- Tcl_Obj *cancelablePtr;
- Tcl_Obj *viewPtr;
- Tcl_Obj *detailPtr;
- Tcl_Obj *screenXPtr;
- Tcl_Obj *screenYPtr;
- Tcl_Obj *clientXPtr;
- Tcl_Obj *clientYPtr;
- Tcl_Obj *ctrlKeyPtr;
- Tcl_Obj *altKeyPtr;
- Tcl_Obj *shiftKeyPtr;
- Tcl_Obj *metaKeyPtr;
- Tcl_Obj *buttonPtr;
- Tcl_Obj *relatedNodePtr;
-{
- TclDOM_InitUIEvent(eventPtr, type, typeObjPtr, bubblesPtr, cancelablePtr, viewPtr, detailPtr);
-
- if (screenXPtr && eventPtr->screenX != screenXPtr) {
- Tcl_DecrRefCount(eventPtr->screenX);
- eventPtr->screenX = screenXPtr;
- Tcl_IncrRefCount(eventPtr->screenX);
- }
- if (screenYPtr && eventPtr->screenY != screenYPtr) {
- Tcl_DecrRefCount(eventPtr->screenY);
- eventPtr->screenY = screenYPtr;
- Tcl_IncrRefCount(eventPtr->screenY);
- }
-
- if (clientXPtr && eventPtr->clientX != clientXPtr) {
- Tcl_DecrRefCount(eventPtr->clientX);
- eventPtr->clientX = clientXPtr;
- Tcl_IncrRefCount(eventPtr->clientX);
- }
- if (clientYPtr && eventPtr->clientY != clientYPtr) {
- Tcl_DecrRefCount(eventPtr->clientY);
- eventPtr->clientY = clientYPtr;
- Tcl_IncrRefCount(eventPtr->clientY);
- }
-
- if (ctrlKeyPtr && eventPtr->ctrlKey != ctrlKeyPtr) {
- Tcl_DecrRefCount(eventPtr->ctrlKey);
- eventPtr->ctrlKey = ctrlKeyPtr;
- Tcl_IncrRefCount(eventPtr->ctrlKey);
- }
- if (altKeyPtr && eventPtr->altKey != altKeyPtr) {
- Tcl_DecrRefCount(eventPtr->altKey);
- eventPtr->altKey = altKeyPtr;
- Tcl_IncrRefCount(eventPtr->altKey);
- }
- if (shiftKeyPtr && eventPtr->shiftKey != shiftKeyPtr) {
- Tcl_DecrRefCount(eventPtr->shiftKey);
- eventPtr->shiftKey = shiftKeyPtr;
- Tcl_IncrRefCount(eventPtr->shiftKey);
- }
- if (metaKeyPtr && eventPtr->metaKey != metaKeyPtr) {
- Tcl_DecrRefCount(eventPtr->metaKey);
- eventPtr->metaKey = metaKeyPtr;
- Tcl_IncrRefCount(eventPtr->metaKey);
- }
- if (buttonPtr && eventPtr->button != buttonPtr) {
- Tcl_DecrRefCount(eventPtr->button);
- eventPtr->button = buttonPtr;
- Tcl_IncrRefCount(eventPtr->button);
- }
-
- if (relatedNodePtr && eventPtr->relatedNode != relatedNodePtr) {
- Tcl_DecrRefCount(eventPtr->relatedNode);
- eventPtr->relatedNode = relatedNodePtr;
- Tcl_IncrRefCount(eventPtr->relatedNode);
- }
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_InitMutationEvent --
- *
- * Initializes an event object.
- *
- * Results:
- * Tcl_Obj references stored.
- *
- * Side effects:
- * Tcl_Obj's reference count changed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-TclDOM_InitMutationEvent(eventPtr, type, typeObjPtr, bubblesPtr, cancelablePtr, relatedNodePtr, prevValuePtr, newValuePtr, attrNamePtr, attrChangePtr)
- TclDOM_libxml2_Event *eventPtr;
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr;
- Tcl_Obj *bubblesPtr;
- Tcl_Obj *cancelablePtr;
- Tcl_Obj *relatedNodePtr;
- Tcl_Obj *prevValuePtr;
- Tcl_Obj *newValuePtr;
- Tcl_Obj *attrNamePtr;
- Tcl_Obj *attrChangePtr;
-{
- TclDOM_InitEvent(eventPtr, type, typeObjPtr, bubblesPtr, cancelablePtr);
-
- if (relatedNodePtr && eventPtr->relatedNode != relatedNodePtr) {
- Tcl_DecrRefCount(eventPtr->relatedNode);
- eventPtr->relatedNode = relatedNodePtr;
- Tcl_IncrRefCount(eventPtr->relatedNode);
- }
-
- if (prevValuePtr && eventPtr->prevValue != prevValuePtr) {
- Tcl_DecrRefCount(eventPtr->prevValue);
- eventPtr->prevValue = prevValuePtr;
- Tcl_IncrRefCount(eventPtr->prevValue);
- }
- if (newValuePtr && eventPtr->newValue != newValuePtr) {
- Tcl_DecrRefCount(eventPtr->newValue);
- eventPtr->newValue = newValuePtr;
- Tcl_IncrRefCount(eventPtr->newValue);
- }
- if (attrNamePtr && eventPtr->attrName != attrNamePtr) {
- Tcl_DecrRefCount(eventPtr->attrName);
- eventPtr->attrName = attrNamePtr;
- Tcl_IncrRefCount(eventPtr->attrName);
- }
- if (attrChangePtr && eventPtr->attrChange != attrChangePtr) {
- Tcl_DecrRefCount(eventPtr->attrChange);
- eventPtr->attrChange = attrChangePtr;
- Tcl_IncrRefCount(eventPtr->attrChange);
- }
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_PostUIEvent --
- *
- * Post an event and cleanup afterward.
- *
- * Results:
- * Event created and propagated.
- *
- * Side effects:
- * Depends on event listeners.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOM_PostUIEvent(interp, tDocPtr, nodeObjPtr, type, typeObjPtr, bubblesPtr, cancelablePtr, viewPtr, detailPtr)
- Tcl_Interp *interp;
- TclXML_libxml2_Document *tDocPtr;
- Tcl_Obj *nodeObjPtr;
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr;
- Tcl_Obj *bubblesPtr;
- Tcl_Obj *cancelablePtr;
- Tcl_Obj *viewPtr;
- Tcl_Obj *detailPtr;
-{
- Tcl_Obj *eventObj;
- TclDOM_libxml2_Event *eventPtr = NULL;
- int result;
-
- /*
- * Performance optimisation: if there are no event listeners for this
- * event type then don't bother creating an event.
- */
- if (!HasListener(interp, tDocPtr, type)) {
- return TCL_OK;
- }
-
- eventObj = TclDOM_libxml2_NewEventObj(interp, tDocPtr->docPtr, type, typeObjPtr);
- if (eventObj == NULL) {
- Tcl_SetResult(interp, "unable to create event", NULL);
- return TCL_ERROR;
- }
-
- TclDOM_libxml2_GetEventFromObj(interp, eventObj, &eventPtr);
-
- TclDOM_InitUIEvent(eventPtr, type, typeObjPtr, bubblesPtr, cancelablePtr, viewPtr, detailPtr);
-
- Tcl_ResetResult(interp);
- result = TclDOM_DispatchEvent(interp, nodeObjPtr, eventObj, eventPtr);
-
- TclDOM_libxml2_DestroyNode(interp, eventPtr->tNodePtr);
-
- return result;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_PostMouseEvent --
- *
- * Post an event and cleanup afterward.
- *
- * Results:
- * Event created and propagated.
- *
- * Side effects:
- * Depends on event listeners.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOM_PostMouseEvent(interp, tDocPtr, nodeObjPtr, type, typeObjPtr, bubblesPtr, cancelablePtr, relatedNodePtr, viewPtr, detailPtr, screenXPtr, screenYPtr, clientXPtr, clientYPtr, ctrlKeyPtr, altKeyPtr, shiftKeyPtr, metaKeyPtr, buttonPtr)
- Tcl_Interp *interp;
- TclXML_libxml2_Document *tDocPtr;
- Tcl_Obj *nodeObjPtr;
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr;
- Tcl_Obj *bubblesPtr;
- Tcl_Obj *cancelablePtr;
- Tcl_Obj *relatedNodePtr;
- Tcl_Obj *viewPtr;
- Tcl_Obj *detailPtr;
- Tcl_Obj *screenXPtr;
- Tcl_Obj *screenYPtr;
- Tcl_Obj *clientXPtr;
- Tcl_Obj *clientYPtr;
- Tcl_Obj *ctrlKeyPtr;
- Tcl_Obj *altKeyPtr;
- Tcl_Obj *shiftKeyPtr;
- Tcl_Obj *metaKeyPtr;
- Tcl_Obj *buttonPtr;
-{
- Tcl_Obj *eventObj;
- TclDOM_libxml2_Event *eventPtr = NULL;
- int result;
-
- /*
- * Performance optimisation: if there are no event listeners for this
- * event type then don't bother creating an event.
- */
- if (!HasListener(interp, tDocPtr, type)) {
- return TCL_OK;
- }
-
- eventObj = TclDOM_libxml2_NewEventObj(interp, tDocPtr->docPtr, type, typeObjPtr);
- if (eventObj == NULL) {
- Tcl_SetResult(interp, "unable to create event", NULL);
- return TCL_ERROR;
- }
-
- TclDOM_libxml2_GetEventFromObj(interp, eventObj, &eventPtr);
-
- TclDOM_InitMouseEvent(eventPtr, type, typeObjPtr, bubblesPtr, cancelablePtr,
- viewPtr, detailPtr,
- screenXPtr, screenYPtr, clientXPtr, clientYPtr,
- ctrlKeyPtr, altKeyPtr, shiftKeyPtr, metaKeyPtr,
- buttonPtr, relatedNodePtr);
-
- Tcl_ResetResult(interp);
- result = TclDOM_DispatchEvent(interp, nodeObjPtr, eventObj, eventPtr);
-
- TclDOM_libxml2_DestroyNode(interp, eventPtr->tNodePtr);
-
- return result;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_PostMutationEvent --
- *
- * Post an event and cleanup afterward.
- *
- * Results:
- * Event created and propagated.
- *
- * Side effects:
- * Depends on event listeners.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOM_PostMutationEvent(interp, tDocPtr, nodeObjPtr, type, typeObjPtr, bubblesPtr, cancelablePtr, relatedNodePtr, prevValuePtr, newValuePtr, attrNamePtr, attrChangePtr)
- Tcl_Interp *interp;
- TclXML_libxml2_Document *tDocPtr;
- Tcl_Obj *nodeObjPtr;
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr;
- Tcl_Obj *bubblesPtr;
- Tcl_Obj *cancelablePtr;
- Tcl_Obj *relatedNodePtr;
- Tcl_Obj *prevValuePtr;
- Tcl_Obj *newValuePtr;
- Tcl_Obj *attrNamePtr;
- Tcl_Obj *attrChangePtr;
-{
- Tcl_Obj *eventObj;
- TclDOM_libxml2_Event *eventPtr = NULL;
- int result;
-
- /*
- * Performance optimisation: if there are no event listeners for this
- * event type then don't bother creating an event.
- */
- if (!HasListener(interp, tDocPtr, type)) {
- return TCL_OK;
- }
-
- eventObj = TclDOM_libxml2_NewEventObj(interp, tDocPtr->docPtr, type, typeObjPtr);
- if (eventObj == NULL) {
- Tcl_SetResult(interp, "unable to create event", NULL);
- return TCL_ERROR;
- }
-
- TclDOM_libxml2_GetEventFromObj(interp, eventObj, &eventPtr);
-
- TclDOM_InitMutationEvent(eventPtr, type, typeObjPtr, bubblesPtr, cancelablePtr, relatedNodePtr, prevValuePtr, newValuePtr, attrNamePtr, attrChangePtr);
-
- Tcl_ResetResult(interp);
- result = TclDOM_DispatchEvent(interp, nodeObjPtr, eventObj, eventPtr);
-
- TclDOM_libxml2_DestroyNode(interp, eventPtr->tNodePtr);
-
- return result;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMEventCommand --
- *
- * Implements dom::libxml2::event command.
- *
- * Results:
- * Depends on method.
- *
- * Side effects:
- * Depends on method.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOMEventCommand (clientData, interp, objc, objv)
- ClientData clientData;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- int method, option;
- TclXML_libxml2_Document *tDocPtr;
- TclDOM_libxml2_Node *tNodePtr;
- TclDOM_libxml2_Event *eventPtr;
- xmlNodePtr nodePtr;
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr = NULL;
- Tcl_Obj *nodeObj;
- Tcl_Obj *bubblesPtr, *cancelablePtr, *viewPtr, *detailPtr;
- Tcl_Obj *relatedNodePtr, *screenXPtr, *screenYPtr, *clientXPtr, *clientYPtr;
- Tcl_Obj *ctrlKeyPtr, *shiftKeyPtr, *metaKeyPtr, *buttonPtr;
- Tcl_Obj *prevValuePtr, *newValuePtr, *attrNamePtr, *attrChangePtr;
-
- if (objc < 2) {
- if (clientData == NULL) {
- Tcl_WrongNumArgs(interp, 1, objv, "method token ?args...?");
- } else {
- Tcl_WrongNumArgs(interp, 1, objv, "method ?args...?");
- }
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[1], TclDOM_EventCommandMethods,
- "method", 0, &method) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum TclDOM_EventCommandMethods) method) {
-
- case TCLDOM_EVENT_CGET:
-
- if (clientData) {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "cget option");
- return TCL_ERROR;
- }
- tNodePtr = (TclDOM_libxml2_Node *) clientData;
- if (tNodePtr->type != TCLDOM_LIBXML2_NODE_EVENT) {
- Tcl_SetResult(interp, "bad event node", NULL);
- return TCL_ERROR;
- }
- eventPtr = tNodePtr->ptr.eventPtr;
- objc -= 2;
- objv += 2;
- } else {
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "cget event option");
- return TCL_ERROR;
- }
- if (TclDOM_libxml2_GetEventFromObj(interp, objv[2], &eventPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- objc -= 3;
- objv += 3;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[0], TclDOM_EventCommandOptions,
- "option", 0, &option) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum TclDOM_EventCommandOptions) option) {
- case TCLDOM_EVENT_ALTKEY:
- Tcl_SetObjResult(interp, eventPtr->altKey);
- break;
- case TCLDOM_EVENT_ATTRNAME:
- Tcl_SetObjResult(interp, eventPtr->attrName);
- break;
- case TCLDOM_EVENT_ATTRCHANGE:
- Tcl_SetObjResult(interp, eventPtr->attrChange);
- break;
- case TCLDOM_EVENT_BUBBLES:
- Tcl_SetObjResult(interp, eventPtr->bubbles);
- break;
- case TCLDOM_EVENT_BUTTON:
- Tcl_SetObjResult(interp, eventPtr->button);
- break;
- case TCLDOM_EVENT_CANCELABLE:
- Tcl_SetObjResult(interp, eventPtr->cancelable);
- break;
- case TCLDOM_EVENT_CLIENTX:
- Tcl_SetObjResult(interp, eventPtr->clientX);
- break;
- case TCLDOM_EVENT_CLIENTY:
- Tcl_SetObjResult(interp, eventPtr->clientY);
- break;
- case TCLDOM_EVENT_CTRLKEY:
- Tcl_SetObjResult(interp, eventPtr->ctrlKey);
- break;
- case TCLDOM_EVENT_CURRENTNODE:
- Tcl_SetObjResult(interp, eventPtr->currentNode);
- break;
- case TCLDOM_EVENT_DETAIL:
- Tcl_SetObjResult(interp, eventPtr->detail);
- break;
- case TCLDOM_EVENT_EVENTPHASE:
- Tcl_SetObjResult(interp, eventPtr->eventPhase);
- break;
- case TCLDOM_EVENT_METAKEY:
- Tcl_SetObjResult(interp, eventPtr->metaKey);
- break;
- case TCLDOM_EVENT_NEWVALUE:
- Tcl_SetObjResult(interp, eventPtr->newValue);
- break;
- case TCLDOM_EVENT_PREVVALUE:
- Tcl_SetObjResult(interp, eventPtr->prevValue);
- break;
- case TCLDOM_EVENT_RELATEDNODE:
- Tcl_SetObjResult(interp, eventPtr->relatedNode);
- break;
- case TCLDOM_EVENT_SCREENX:
- Tcl_SetObjResult(interp, eventPtr->screenX);
- break;
- case TCLDOM_EVENT_SCREENY:
- Tcl_SetObjResult(interp, eventPtr->screenY);
- break;
- case TCLDOM_EVENT_SHIFTKEY:
- Tcl_SetObjResult(interp, eventPtr->shiftKey);
- break;
- case TCLDOM_EVENT_TARGET:
- Tcl_SetObjResult(interp, eventPtr->target);
- break;
- case TCLDOM_EVENT_TIMESTAMP:
- Tcl_SetObjResult(interp, eventPtr->timeStamp);
- break;
- case TCLDOM_EVENT_TYPE:
- if (eventPtr->type == TCLDOM_EVENT_USERDEFINED) {
- Tcl_SetObjResult(interp, eventPtr->typeObjPtr);
- } else {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(TclDOM_EventTypes[eventPtr->type], -1));
- }
- break;
- case TCLDOM_EVENT_VIEW:
- Tcl_SetObjResult(interp, eventPtr->view);
- break;
- default:
- Tcl_SetResult(interp, "unknown option", NULL);
- return TCL_ERROR;
- }
-
- break;
-
- case TCLDOM_EVENT_CONFIGURE:
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 3, objv, "configure option ?value?");
- return TCL_ERROR;
- }
-
- /* No event options are writable */
- Tcl_SetResult(interp, "option cannot be modified", NULL);
- return TCL_ERROR;
-
- break;
-
- case TCLDOM_EVENT_STOPPROPAGATION:
-
- if (clientData) {
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "");
- return TCL_ERROR;
- }
-
- tNodePtr = (TclDOM_libxml2_Node *) clientData;
- if (tNodePtr->type != TCLDOM_LIBXML2_NODE_EVENT) {
- Tcl_SetResult(interp, "bad event node", NULL);
- return TCL_ERROR;
- }
- eventPtr = tNodePtr->ptr.eventPtr;
- } else {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, "");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetEventFromObj(interp, objv[2], &eventPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- }
-
- eventPtr->stopPropagation = 1;
-
- break;
-
- case TCLDOM_EVENT_PREVENTDEFAULT:
-
- if (clientData) {
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "");
- return TCL_ERROR;
- }
-
- tNodePtr = (TclDOM_libxml2_Node *) clientData;
- if (tNodePtr->type != TCLDOM_LIBXML2_NODE_EVENT) {
- Tcl_SetResult(interp, "bad event node", NULL);
- return TCL_ERROR;
- }
- eventPtr = tNodePtr->ptr.eventPtr;
- } else {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, "");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetEventFromObj(interp, objv[2], &eventPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- }
-
- eventPtr->preventDefault = 1;
-
- break;
-
- case TCLDOM_EVENT_INITEVENT:
-
- if (clientData) {
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 2, objv, "type bubbles cancelable");
- return TCL_ERROR;
- }
-
- tNodePtr = (TclDOM_libxml2_Node *) clientData;
- if (tNodePtr->type != TCLDOM_LIBXML2_NODE_EVENT) {
- Tcl_SetResult(interp, "bad event node", NULL);
- return TCL_ERROR;
- }
- eventPtr = tNodePtr->ptr.eventPtr;
- objc -= 2;
- objv += 2;
- } else {
- if (objc != 6) {
- Tcl_WrongNumArgs(interp, 3, objv, "type bubbles cancelable");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetEventFromObj(interp, objv[2], &eventPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- objc -= 3;
- objv += 3;
- }
-
- if (eventPtr->dispatched) {
- Tcl_SetResult(interp, "event has been dispatched", NULL);
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[0], TclDOM_EventTypes,
- "type", TCL_EXACT, &option) == TCL_OK) {
- type = (enum TclDOM_EventTypes) option;
- } else {
- type = TCLDOM_EVENT_USERDEFINED;
- }
- Tcl_ResetResult(interp);
-
- TclDOM_InitEvent(eventPtr, type, objv[0], objv[1], objv[2]);
-
- break;
-
- case TCLDOM_EVENT_INITUIEVENT:
-
- if (clientData) {
- if (objc < 6 || objc > 7) {
- Tcl_WrongNumArgs(interp, 2, objv, "type bubbles cancelable view ?detail?");
- return TCL_ERROR;
- }
-
- tNodePtr = (TclDOM_libxml2_Node *) clientData;
- if (tNodePtr->type != TCLDOM_LIBXML2_NODE_EVENT) {
- Tcl_SetResult(interp, "bad event node", NULL);
- return TCL_ERROR;
- }
- eventPtr = tNodePtr->ptr.eventPtr;
-
- objc -= 2;
- objv += 2;
- } else {
- if (objc < 7 || objc > 8) {
- Tcl_WrongNumArgs(interp, 3, objv, "type bubbles cancelable view ?detail?");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetEventFromObj(interp, objv[2], &eventPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- objc -= 3;
- objv += 3;
- }
-
- if (eventPtr->dispatched) {
- Tcl_SetResult(interp, "event has been dispatched", NULL);
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[0], TclDOM_EventTypes,
- "type", TCL_EXACT, &option) == TCL_OK) {
- type = (enum TclDOM_EventTypes) option;
- } else {
- type = TCLDOM_EVENT_USERDEFINED;
- }
- Tcl_ResetResult(interp);
-
- TclDOM_InitUIEvent(eventPtr, type, objv[0], objv[1], objv[2], objv[3], objc == 5 ? objv[4] : NULL);
-
- break;
-
- case TCLDOM_EVENT_INITMOUSEEVENT:
-
- if (clientData) {
- if (objc != 17) {
- Tcl_WrongNumArgs(interp, 2, objv, "type bubbles cancelable view detail screenX screenY clientX clientY ctrlKey altKey shiftKey metaKey button relatedNode");
- return TCL_ERROR;
- }
-
- tNodePtr = (TclDOM_libxml2_Node *) clientData;
- if (tNodePtr->type != TCLDOM_LIBXML2_NODE_EVENT) {
- Tcl_SetResult(interp, "bad event node", NULL);
- return TCL_ERROR;
- }
- eventPtr = tNodePtr->ptr.eventPtr;
-
- objc -= 2;
- objv += 2;
- } else {
- if (objc != 18) {
- Tcl_WrongNumArgs(interp, 3, objv, "type bubbles cancelable view detail screenX screenY clientX clientY ctrlKey altKey shiftKey metaKey button relatedNode");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetEventFromObj(interp, objv[2], &eventPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- objc -= 3;
- objv += 3;
- }
-
- if (eventPtr->dispatched) {
- Tcl_SetResult(interp, "event has been dispatched", NULL);
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[0], TclDOM_EventTypes,
- "type", TCL_EXACT, &option) == TCL_OK) {
- type = (enum TclDOM_EventTypes) option;
- } else {
- type = TCLDOM_EVENT_USERDEFINED;
- }
- Tcl_ResetResult(interp);
-
- TclDOM_InitMouseEvent(eventPtr, type, objv[0], objv[1], objv[2], objv[3], objv[4], objv[5], objv[6], objv[7], objv[8], objv[9], objv[10], objv[11], objv[12], objv[13], objv[14]);
-
- break;
-
- case TCLDOM_EVENT_INITMUTATIONEVENT:
-
- if (clientData) {
- if (objc != 10) {
- Tcl_WrongNumArgs(interp, 2, objv, "type bubbles cancelable relatedNode prevValue newValue attrName attrChange");
- return TCL_ERROR;
- }
-
- tNodePtr = (TclDOM_libxml2_Node *) clientData;
- if (tNodePtr->type != TCLDOM_LIBXML2_NODE_EVENT) {
- Tcl_SetResult(interp, "bad event node", NULL);
- return TCL_ERROR;
- }
- eventPtr = tNodePtr->ptr.eventPtr;
-
- objc -= 2;
- objv += 2;
- } else {
- if (objc != 11) {
- Tcl_WrongNumArgs(interp, 3, objv, "type bubbles cancelable relatedNode prevValue newValue attrName attrChange");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetEventFromObj(interp, objv[2], &eventPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- objc -= 3;
- objv += 3;
- }
-
- if (eventPtr->dispatched) {
- Tcl_SetResult(interp, "event has been dispatched", NULL);
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[0], TclDOM_EventTypes,
- "type", TCL_EXACT, &option) == TCL_OK) {
- type = (enum TclDOM_EventTypes) option;
- } else {
- type = TCLDOM_EVENT_USERDEFINED;
- }
- Tcl_ResetResult(interp);
-
- TclDOM_InitMutationEvent(eventPtr, type, objv[0], objv[1], objv[2], objv[3], objv[4], objv[5], objv[6], objv[7]);
-
- break;
-
- case TCLDOM_EVENT_POSTUIEVENT:
-
- if (clientData) {
- Tcl_SetResult(interp, "bad method for event", NULL);
- return TCL_ERROR;
- }
-
- if (objc < 4) {
- Tcl_WrongNumArgs(interp, 1, objv, "postUIEvent node type ?args ...?");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetNodeFromObj(interp, objv[2], &nodePtr) != TCL_OK) {
- return TCL_ERROR;
- }
- nodeObj = objv[2];
-
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[3], TclDOM_EventTypes,
- "type", TCL_EXACT, &option) == TCL_OK) {
- type = (enum TclDOM_EventTypes) option;
- } else {
- type = TCLDOM_EVENT_USERDEFINED;
- }
- typeObjPtr = objv[3];
- Tcl_ResetResult(interp);
-
- bubblesPtr = Tcl_GetVar2Ex(interp, "::dom::bubbles", Tcl_GetStringFromObj(objv[3], NULL), TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
- if (!bubblesPtr) {
- return TCL_ERROR;
- }
- Tcl_IncrRefCount(bubblesPtr);
- cancelablePtr = Tcl_GetVar2Ex(interp, "::dom::cancelable", Tcl_GetStringFromObj(objv[3], NULL), TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
- if (!cancelablePtr) {
- Tcl_DecrRefCount(bubblesPtr);
- return TCL_ERROR;
- }
- Tcl_IncrRefCount(cancelablePtr);
-
- viewPtr = Tcl_NewObj();
- detailPtr = Tcl_NewObj();
-
- objc -= 4;
- objv += 4;
- while (objc) {
-
- if (objc == 1) {
- Tcl_SetResult(interp, "value missing", NULL);
- Tcl_DecrRefCount(bubblesPtr);
- Tcl_DecrRefCount(cancelablePtr);
- Tcl_DecrRefCount(viewPtr);
- Tcl_DecrRefCount(detailPtr);
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[0], TclDOM_EventCommandOptions,
- "option", 0, &option) != TCL_OK) {
- Tcl_DecrRefCount(bubblesPtr);
- Tcl_DecrRefCount(cancelablePtr);
- Tcl_DecrRefCount(viewPtr);
- Tcl_DecrRefCount(detailPtr);
- return TCL_ERROR;
- }
- switch ((enum TclDOM_EventCommandOptions) option) {
- case TCLDOM_EVENT_BUBBLES:
- Tcl_DecrRefCount(bubblesPtr);
- bubblesPtr = objv[1];
- Tcl_IncrRefCount(bubblesPtr);
- break;
- case TCLDOM_EVENT_CANCELABLE:
- Tcl_DecrRefCount(cancelablePtr);
- cancelablePtr = objv[1];
- Tcl_IncrRefCount(cancelablePtr);
- break;
- case TCLDOM_EVENT_VIEW:
- Tcl_DecrRefCount(viewPtr);
- viewPtr = objv[1];
- Tcl_IncrRefCount(viewPtr);
- break;
- case TCLDOM_EVENT_DETAIL:
- Tcl_DecrRefCount(detailPtr);
- detailPtr = objv[1];
- Tcl_IncrRefCount(detailPtr);
- break;
- default:
- Tcl_SetResult(interp, "bad option", NULL);
- Tcl_DecrRefCount(bubblesPtr);
- Tcl_DecrRefCount(cancelablePtr);
- Tcl_DecrRefCount(viewPtr);
- Tcl_DecrRefCount(detailPtr);
- return TCL_ERROR;
- }
-
- objc -= 2;
- objv += 2;
- }
-
- if (TclDOM_PostUIEvent(interp, tDocPtr, nodeObj, type, typeObjPtr, bubblesPtr, cancelablePtr, viewPtr, detailPtr) != TCL_OK) {
- Tcl_DecrRefCount(bubblesPtr);
- Tcl_DecrRefCount(cancelablePtr);
- Tcl_DecrRefCount(viewPtr);
- Tcl_DecrRefCount(detailPtr);
- return TCL_ERROR;
- }
-
- break;
-
- case TCLDOM_EVENT_POSTMOUSEEVENT:
-
- if (clientData) {
- Tcl_SetResult(interp, "bad method for event", NULL);
- return TCL_ERROR;
- }
-
- if (objc < 4) {
- Tcl_WrongNumArgs(interp, 1, objv, "postMouseEvent node type ?args ...?");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetNodeFromObj(interp, objv[2], &nodePtr) != TCL_OK) {
- return TCL_ERROR;
- }
- nodeObj = objv[2];
-
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[3], TclDOM_EventTypes,
- "type", TCL_EXACT, &option) == TCL_OK) {
- type = (enum TclDOM_EventTypes) option;
- } else {
- type = TCLDOM_EVENT_USERDEFINED;
- }
- typeObjPtr = objv[3];
- Tcl_ResetResult(interp);
-
- bubblesPtr = Tcl_GetVar2Ex(interp, "::dom::bubbles", Tcl_GetStringFromObj(objv[3], NULL), TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
- if (!bubblesPtr) {
- return TCL_ERROR;
- }
- Tcl_IncrRefCount(bubblesPtr);
- cancelablePtr = Tcl_GetVar2Ex(interp, "::dom::cancelable", Tcl_GetStringFromObj(objv[3], NULL), TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
- if (!cancelablePtr) {
- Tcl_DecrRefCount(bubblesPtr);
- return TCL_ERROR;
- }
- Tcl_IncrRefCount(cancelablePtr);
-
- viewPtr = Tcl_NewObj();
- detailPtr = Tcl_NewObj();
- relatedNodePtr = Tcl_NewObj();
- screenXPtr = Tcl_NewObj();
- screenYPtr = Tcl_NewObj();
- clientXPtr = Tcl_NewObj();
- clientYPtr = Tcl_NewObj();
- ctrlKeyPtr = Tcl_NewObj();
- shiftKeyPtr = Tcl_NewObj();
- metaKeyPtr = Tcl_NewObj();
- buttonPtr = Tcl_NewObj();
-
- objc -= 4;
- objv += 4;
- while (objc) {
-
- if (objc == 1) {
- Tcl_SetResult(interp, "value missing", NULL);
- goto mouse_error;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[0], TclDOM_EventCommandOptions,
- "option", 0, &option) != TCL_OK) {
- goto mouse_error;
- }
- switch ((enum TclDOM_EventCommandOptions) option) {
- case TCLDOM_EVENT_BUBBLES:
- Tcl_DecrRefCount(bubblesPtr);
- bubblesPtr = objv[1];
- Tcl_IncrRefCount(bubblesPtr);
- break;
- case TCLDOM_EVENT_CANCELABLE:
- Tcl_DecrRefCount(cancelablePtr);
- cancelablePtr = objv[1];
- Tcl_IncrRefCount(cancelablePtr);
- break;
- case TCLDOM_EVENT_RELATEDNODE:
- Tcl_DecrRefCount(relatedNodePtr);
- relatedNodePtr = objv[1];
- Tcl_IncrRefCount(relatedNodePtr);
- break;
- case TCLDOM_EVENT_VIEW:
- Tcl_DecrRefCount(viewPtr);
- viewPtr = objv[1];
- Tcl_IncrRefCount(viewPtr);
- break;
- case TCLDOM_EVENT_DETAIL:
- Tcl_DecrRefCount(detailPtr);
- detailPtr = objv[1];
- Tcl_IncrRefCount(detailPtr);
- break;
- case TCLDOM_EVENT_SCREENX:
- Tcl_DecrRefCount(screenXPtr);
- screenXPtr = objv[1];
- Tcl_IncrRefCount(screenXPtr);
- break;
- case TCLDOM_EVENT_SCREENY:
- Tcl_DecrRefCount(screenYPtr);
- screenYPtr = objv[1];
- Tcl_IncrRefCount(screenYPtr);
- break;
- case TCLDOM_EVENT_CLIENTX:
- Tcl_DecrRefCount(clientXPtr);
- clientXPtr = objv[1];
- Tcl_IncrRefCount(clientXPtr);
- break;
- case TCLDOM_EVENT_CLIENTY:
- Tcl_DecrRefCount(clientYPtr);
- clientYPtr = objv[1];
- Tcl_IncrRefCount(clientYPtr);
- break;
- case TCLDOM_EVENT_CTRLKEY:
- Tcl_DecrRefCount(ctrlKeyPtr);
- ctrlKeyPtr = objv[1];
- Tcl_IncrRefCount(ctrlKeyPtr);
- break;
- case TCLDOM_EVENT_SHIFTKEY:
- Tcl_DecrRefCount(shiftKeyPtr);
- shiftKeyPtr = objv[1];
- Tcl_IncrRefCount(shiftKeyPtr);
- break;
- case TCLDOM_EVENT_METAKEY:
- Tcl_DecrRefCount(metaKeyPtr);
- metaKeyPtr = objv[1];
- Tcl_IncrRefCount(metaKeyPtr);
- break;
- case TCLDOM_EVENT_BUTTON:
- Tcl_DecrRefCount(buttonPtr);
- buttonPtr = objv[1];
- Tcl_IncrRefCount(buttonPtr);
- break;
- default:
- Tcl_SetResult(interp, "bad option", NULL);
- goto mouse_error;
- }
-
- objc -= 2;
- objv += 2;
- }
-
- if (TclDOM_PostMouseEvent(interp, tDocPtr, nodeObj, type, typeObjPtr, bubblesPtr, cancelablePtr, relatedNodePtr, viewPtr, detailPtr, screenXPtr, screenYPtr, clientXPtr, clientYPtr, ctrlKeyPtr, shiftKeyPtr, metaKeyPtr, buttonPtr, relatedNodePtr) != TCL_OK) {
- goto mouse_error;
- }
-
- break;
-
-mouse_error:
- Tcl_DecrRefCount(bubblesPtr);
- Tcl_DecrRefCount(cancelablePtr);
- Tcl_DecrRefCount(viewPtr);
- Tcl_DecrRefCount(detailPtr);
- Tcl_DecrRefCount(relatedNodePtr);
- Tcl_DecrRefCount(screenXPtr);
- Tcl_DecrRefCount(screenYPtr);
- Tcl_DecrRefCount(clientXPtr);
- Tcl_DecrRefCount(clientYPtr);
- Tcl_DecrRefCount(ctrlKeyPtr);
- Tcl_DecrRefCount(shiftKeyPtr);
- Tcl_DecrRefCount(metaKeyPtr);
- Tcl_DecrRefCount(buttonPtr);
-
- return TCL_ERROR;
-
- case TCLDOM_EVENT_POSTMUTATIONEVENT:
-
- if (clientData) {
- Tcl_SetResult(interp, "bad method for event", NULL);
- return TCL_ERROR;
- }
-
- if (objc < 4) {
- Tcl_WrongNumArgs(interp, 1, objv, "postMutationEvent node type ?args ...?");
- return TCL_ERROR;
- }
-
- if (TclDOM_libxml2_GetNodeFromObj(interp, objv[2], &nodePtr) != TCL_OK) {
- return TCL_ERROR;
- }
- nodeObj = objv[2];
-
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[3], TclDOM_EventTypes,
- "type", TCL_EXACT, &option) == TCL_OK) {
- type = (enum TclDOM_EventTypes) option;
- } else {
- type = TCLDOM_EVENT_USERDEFINED;
- }
- typeObjPtr = objv[3];
- Tcl_ResetResult(interp);
-
- bubblesPtr = Tcl_GetVar2Ex(interp, "::dom::bubbles", Tcl_GetStringFromObj(objv[3], NULL), TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
- if (!bubblesPtr) {
- return TCL_ERROR;
- }
- Tcl_IncrRefCount(bubblesPtr);
- cancelablePtr = Tcl_GetVar2Ex(interp, "::dom::cancelable", Tcl_GetStringFromObj(objv[3], NULL), TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
- if (!cancelablePtr) {
- Tcl_DecrRefCount(bubblesPtr);
- return TCL_ERROR;
- }
- Tcl_IncrRefCount(cancelablePtr);
-
- relatedNodePtr = Tcl_NewObj();
- prevValuePtr = Tcl_NewObj();
- newValuePtr = Tcl_NewObj();
- attrNamePtr = Tcl_NewObj();
- attrChangePtr = Tcl_NewObj();
-
- objc -= 4;
- objv += 4;
- while (objc) {
-
- if (objc == 1) {
- Tcl_SetResult(interp, "value missing", NULL);
- goto mutation_error;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[0], TclDOM_EventCommandOptions,
- "option", 0, &option) != TCL_OK) {
- goto mutation_error;
- }
- switch ((enum TclDOM_EventCommandOptions) option) {
- case TCLDOM_EVENT_BUBBLES:
- Tcl_DecrRefCount(bubblesPtr);
- bubblesPtr = objv[1];
- Tcl_IncrRefCount(bubblesPtr);
- break;
- case TCLDOM_EVENT_CANCELABLE:
- Tcl_DecrRefCount(cancelablePtr);
- cancelablePtr = objv[1];
- Tcl_IncrRefCount(cancelablePtr);
- break;
- case TCLDOM_EVENT_RELATEDNODE:
- Tcl_DecrRefCount(relatedNodePtr);
- relatedNodePtr = objv[1];
- Tcl_IncrRefCount(relatedNodePtr);
- break;
- case TCLDOM_EVENT_PREVVALUE:
- Tcl_DecrRefCount(prevValuePtr);
- prevValuePtr = objv[1];
- Tcl_IncrRefCount(prevValuePtr);
- break;
- case TCLDOM_EVENT_NEWVALUE:
- Tcl_DecrRefCount(newValuePtr);
- newValuePtr = objv[1];
- Tcl_IncrRefCount(newValuePtr);
- break;
- case TCLDOM_EVENT_ATTRNAME:
- Tcl_DecrRefCount(attrNamePtr);
- attrNamePtr = objv[1];
- Tcl_IncrRefCount(attrNamePtr);
- break;
- case TCLDOM_EVENT_ATTRCHANGE:
- Tcl_DecrRefCount(attrChangePtr);
- attrChangePtr = objv[1];
- Tcl_IncrRefCount(attrChangePtr);
- break;
- default:
- Tcl_SetResult(interp, "bad option", NULL);
- goto mutation_error;
- }
-
- objc -= 2;
- objv += 2;
- }
-
- if (TclDOM_PostMutationEvent(interp, tDocPtr, nodeObj, type, typeObjPtr, bubblesPtr, cancelablePtr, relatedNodePtr, prevValuePtr, newValuePtr, attrNamePtr, attrChangePtr) != TCL_OK) {
- goto mutation_error;
- }
-
- break;
-
-mutation_error:
- Tcl_DecrRefCount(bubblesPtr);
- Tcl_DecrRefCount(cancelablePtr);
- Tcl_DecrRefCount(relatedNodePtr);
- Tcl_DecrRefCount(prevValuePtr);
- Tcl_DecrRefCount(newValuePtr);
- Tcl_DecrRefCount(attrNamePtr);
- Tcl_DecrRefCount(attrChangePtr);
-
- return TCL_ERROR;
-
- default:
-
- Tcl_SetResult(interp, "unknown method", NULL);
- return TCL_ERROR;
-
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * GetPath --
- *
- * Constructs a list of ancestor nodes.
- *
- * Results:
- * Returns list as a Tcl_Obj.
- *
- * Side effects:
- * Allocates Tcl_Obj structures.
- *
- *----------------------------------------------------------------------------
- */
-
-static Tcl_Obj *
-GetPath (interp, nodePtr)
- Tcl_Interp *interp;
- xmlNodePtr nodePtr;
-{
- Tcl_Obj *listPtr, *resultPtr;
- Tcl_Obj *objv[2];
-
- if (nodePtr) {
- if (nodePtr->type == XML_DOCUMENT_NODE) {
- objv[0] = TclXML_libxml2_CreateObjFromDoc((xmlDocPtr) nodePtr);
- } else {
- objv[0] = TclDOM_libxml2_CreateObjFromNode(interp, nodePtr);
- }
- objv[1] = NULL;
-
- listPtr = Tcl_NewListObj(1, objv);
- if (nodePtr->parent) {
- resultPtr = GetPath(interp, nodePtr->parent);
- Tcl_ListObjAppendList(interp, resultPtr, listPtr);
- } else {
- resultPtr = listPtr;
- }
- return resultPtr;
- } else {
- return Tcl_NewObj();
- }
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * Node (and event) Tcl Object management
- *
- *----------------------------------------------------------------------------
- */
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_libxml2_CreateObjFromNode --
- *
- * Create a Tcl_Obj to wrap a tree node.
- *
- * Results:
- * Returns Tcl_Obj*.
- *
- * Side effects:
- * Allocates object. Creates node command.
- *
- *----------------------------------------------------------------------------
- */
-
-Tcl_Obj *
-TclDOM_libxml2_CreateObjFromNode (interp, nodePtr)
- Tcl_Interp *interp;
- xmlNodePtr nodePtr;
-{
- TclDOM_libxml2_Node *tNodePtr;
- TclXML_libxml2_Document *tDocPtr;
- TclDOM_libxml2_Document *domDocPtr;
- Tcl_Obj *objPtr;
- Tcl_HashEntry *entry;
- int new;
-
- if (TclXML_libxml2_GetTclDocFromNode(interp, nodePtr, &tDocPtr) != TCL_OK) {
- Tcl_SetResult(interp, "unable to find document for node", NULL);
- return NULL;
- }
- if ((domDocPtr = GetDOMDocument(interp, tDocPtr)) == NULL) {
- Tcl_SetResult(interp, "internal error", NULL);
- return NULL;
- }
-
- tNodePtr = (TclDOM_libxml2_Node *) Tcl_Alloc(sizeof(TclDOM_libxml2_Node));
- tNodePtr->ptr.nodePtr = nodePtr;
- tNodePtr->type = TCLDOM_LIBXML2_NODE_NODE;
- tNodePtr->objs = NULL;
- tNodePtr->token = Tcl_Alloc(30);
- sprintf(tNodePtr->token, "::dom::%s::node%d", tDocPtr->token, domDocPtr->nodeCntr++);
-
- entry = Tcl_CreateHashEntry(domDocPtr->nodes, tNodePtr->token, &new);
- if (!new) {
- Tcl_Free((char *) tNodePtr->token);
- Tcl_Free((char *) tNodePtr);
- Tcl_SetResult(interp, "internal error", NULL);
- return NULL;
- }
- Tcl_SetHashValue(entry, (void *) tNodePtr);
-
- tNodePtr->cmd = Tcl_CreateObjCommand(interp, tNodePtr->token, TclDOMNodeCommand, (ClientData) tNodePtr, TclDOMNodeCommandDelete);
-
- objPtr = Tcl_NewObj();
- objPtr->internalRep.otherValuePtr = (VOID *) tNodePtr;
- objPtr->typePtr = &NodeObjType;
-
- objPtr->bytes = Tcl_Alloc(strlen(tNodePtr->token) + 1);
- strcpy(objPtr->bytes, tNodePtr->token);
- objPtr->length = strlen(objPtr->bytes);
-
- NodeAddObjRef(tNodePtr, objPtr);
-
- return objPtr;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * NodeAddObjRef --
- *
- * Add an object reference to a node wrapper.
- *
- * Results:
- * Adds a reference to the Tcl_Obj for the node.
- *
- * Side effects:
- * Allocates memory.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-NodeAddObjRef(tNodePtr, objPtr)
- TclDOM_libxml2_Node *tNodePtr;
- Tcl_Obj *objPtr;
-{
- ObjList *listPtr;
-
- listPtr = (ObjList *) Tcl_Alloc(sizeof(ObjList));
- listPtr->next = tNodePtr->objs;
- listPtr->objPtr = objPtr;
-
- tNodePtr->objs = (void *) listPtr;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMNodeCommandDelete --
- *
- * Invoked when a DOM node's Tcl command is deleted.
- *
- * Results:
- * Invalidates the Tcl_Obj for the node, but doesn't actually destroy the node.
- *
- * Side effects:
- * Frees memory.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-TclDOMNodeCommandDelete (clientData)
- ClientData clientData;
-{
- TclDOM_libxml2_Node *tNodePtr = (TclDOM_libxml2_Node *) clientData;
-
- TclDOM_libxml2_InvalidateNode(tNodePtr);
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_libxml2_GetNodeFromObj --
- *
- * Gets an xmlNodePtr from a Tcl_Obj.
- *
- * Results:
- * Returns success code.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOM_libxml2_GetNodeFromObj (interp, objPtr, nodePtrPtr)
- Tcl_Interp *interp;
- Tcl_Obj *objPtr;
- xmlNodePtr *nodePtrPtr;
-{
- TclDOM_libxml2_Node *tNodePtr;
-
- if (TclDOM_libxml2_GetTclNodeFromObj(interp, objPtr, &tNodePtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- *nodePtrPtr = tNodePtr->ptr.nodePtr;
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_libxml2_GetTclNodeFromObj --
- *
- * Gets the TclDOM node structure from a Tcl_Obj.
- *
- * Results:
- * Returns success code.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOM_libxml2_GetTclNodeFromObj (interp, objPtr, tNodePtrPtr)
- Tcl_Interp *interp;
- Tcl_Obj *objPtr;
- TclDOM_libxml2_Node **tNodePtrPtr;
-{
- TclDOM_libxml2_Node *tNodePtr;
-
- if (objPtr->typePtr == &NodeObjType) {
- tNodePtr = (TclDOM_libxml2_Node *) objPtr->internalRep.otherValuePtr;
- } else if (NodeTypeSetFromAny(interp, objPtr) == TCL_OK) {
- tNodePtr = (TclDOM_libxml2_Node *) objPtr->internalRep.otherValuePtr;
- } else {
- return TCL_ERROR;
- }
-
- if (tNodePtr->type != TCLDOM_LIBXML2_NODE_NODE) {
- return TCL_ERROR;
- }
-
- *tNodePtrPtr = tNodePtr;
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_libxml2_GetEventFromObj --
- *
- * Gets an eventPtr from a Tcl_Obj.
- *
- * Results:
- * Returns success code.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOM_libxml2_GetEventFromObj (interp, objPtr, eventPtrPtr)
- Tcl_Interp *interp;
- Tcl_Obj *objPtr;
- TclDOM_libxml2_Event **eventPtrPtr;
-{
- TclDOM_libxml2_Node *tNodePtr;
-
- if (TclDOM_libxml2_GetTclEventFromObj(interp, objPtr, &tNodePtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
- *eventPtrPtr = tNodePtr->ptr.eventPtr;
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_libxml2_GetTclEventFromObj --
- *
- * Gets the node structure for an event from a Tcl_Obj.
- *
- * Results:
- * Returns success code.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-TclDOM_libxml2_GetTclEventFromObj (interp, objPtr, nodePtrPtr)
- Tcl_Interp *interp;
- Tcl_Obj *objPtr;
- TclDOM_libxml2_Node **nodePtrPtr;
-{
- TclDOM_libxml2_Node *tNodePtr;
-
- if (objPtr->typePtr == &NodeObjType) {
- tNodePtr = (TclDOM_libxml2_Node *) objPtr->internalRep.otherValuePtr;
- } else if (NodeTypeSetFromAny(interp, objPtr) == TCL_OK) {
- tNodePtr = (TclDOM_libxml2_Node *) objPtr->internalRep.otherValuePtr;
- } else {
- return TCL_ERROR;
- }
-
- if (tNodePtr->type != TCLDOM_LIBXML2_NODE_EVENT) {
- return TCL_ERROR;
- }
-
- *nodePtrPtr = tNodePtr;
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_libxml2_DestroyNode --
- *
- * Destroys a node
- *
- * Results:
- * Frees node.
- *
- * Side effects:
- * Deallocates memory.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-TclDOM_libxml2_DeleteNode(clientData)
- ClientData clientData;
-{
- TclDOM_libxml2_Node *tNodePtr = (TclDOM_libxml2_Node *) clientData;
- TclDOM_libxml2_Event *eventPtr;
- TclXML_libxml2_Document *tDocPtr;
- TclDOM_libxml2_Document *domDocPtr;
- Tcl_Obj *objPtr;
- xmlNodePtr nodePtr;
- Tcl_HashEntry *entry;
-
- if (tNodePtr->type == TCLDOM_LIBXML2_NODE_NODE) {
- nodePtr = tNodePtr->ptr.nodePtr;
- objPtr = TclXML_libxml2_CreateObjFromDoc(nodePtr->doc);
- TclXML_libxml2_GetTclDocFromObj(NULL, objPtr, &tDocPtr);
- domDocPtr = GetDOMDocument(NULL, tDocPtr);
- if (domDocPtr == NULL) {
- /* internal error */
- return;
- }
- } else {
- eventPtr = tNodePtr->ptr.eventPtr;
- domDocPtr = eventPtr->ownerDocument;
- Tcl_Free((char *) eventPtr);
- }
-
- entry = Tcl_FindHashEntry(domDocPtr->nodes, tNodePtr->token);
- if (entry) {
- Tcl_DeleteHashEntry(entry);
- } else {
- fprintf(stderr, "cannot delete node hash entry!\n");
- }
-
- TclDOM_libxml2_InvalidateNode(tNodePtr);
-
- if (tNodePtr->appfree) {
- (tNodePtr->appfree)(tNodePtr->apphook);
- }
-
- Tcl_Free((char *) tNodePtr);
-}
-
-void
-TclDOM_libxml2_DestroyNode (interp, tNodePtr)
- Tcl_Interp *interp;
- TclDOM_libxml2_Node *tNodePtr;
-{
- Tcl_DeleteCommandFromToken(interp, tNodePtr->cmd);
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_libxml2_InvalidateNode --
- *
- * Invalidates the internal representation of any Tcl_obj that refers to
- * this node. NB. This does not destroy the node, or delete the node command.
- *
- * Results:
- * Tcl_Obj internal reps changed.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-TclDOM_libxml2_InvalidateNode (tNodePtr)
- TclDOM_libxml2_Node *tNodePtr;
-{
- ObjList *listPtr, *nextPtr;
-
- for (listPtr = (ObjList *) tNodePtr->objs; listPtr;) {
-
- listPtr->objPtr->internalRep.otherValuePtr = NULL;
- listPtr->objPtr->typePtr = NULL;
-
- nextPtr = listPtr->next;
- Tcl_Free((char *) listPtr);
- listPtr = nextPtr;
- }
-
- tNodePtr->objs = NULL;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * Node object type management
- *
- *----------------------------------------------------------------------------
- */
-
-/*
- * NodeTypeSetFromAny --
- *
- * Sets the internal representation from the string rep.
- *
- * Results:
- * Success code.
- *
- * Side effects:
- * Changes internal rep.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-NodeTypeSetFromAny(interp, objPtr)
- Tcl_Interp *interp;
- Tcl_Obj *objPtr;
-{
- Tcl_Obj *docObjPtr;
- TclXML_libxml2_Document *tDocPtr;
- TclDOM_libxml2_Document *domDocPtr;
- Tcl_HashEntry *entry;
- char *id, doc[21], node[21];
- int i, idlen, len;
-
- /* Parse string rep for doc and node ids */
- id = Tcl_GetStringFromObj(objPtr, &idlen);
- /* node tokens are prefixed with "::dom::" */
- if (idlen < 7 || strncmp("::dom::", id, 7) != 0) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "malformed node token \"", id, "\"", NULL);
- return TCL_ERROR;
- }
- for (i = 0; i < idlen && id[i + 7] != ':' && i < 21; i++) {
- if (!((id[i + 7] >= 'a' && id[i + 7] <= 'z') || (id[i + 7] >= '0' && id[i + 7] <= '9'))) {
- /* only lowercase chars and digits are found in a token */
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "malformed node token \"", id, "\"", NULL);
- return TCL_ERROR;
- }
- doc[i] = id[i + 7];
- }
- if (i == idlen || id[i + 7] != ':') {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "malformed node token \"", id, "\"", NULL);
- return TCL_ERROR;
- }
- doc[i] = '\0';
- i++;
-
- if (i == idlen || id[i + 7] != ':') {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "malformed node token \"", id, "\"", NULL);
- return TCL_ERROR;
- }
- i++;
- for (len = i + 7, i = 0; i + len < idlen && i < 21; i++) {
- node[i] = id[len + i];
- }
- node[i] = '\0';
-
- docObjPtr = Tcl_NewStringObj(doc, -1);
- if (TclXML_libxml2_GetTclDocFromObj(interp, docObjPtr, &tDocPtr) != TCL_OK) {
- Tcl_DecrRefCount(docObjPtr);
- Tcl_SetResult(interp, "invalid node token", NULL);
- return TCL_ERROR;
- }
- domDocPtr = GetDOMDocument(interp, tDocPtr);
- if (domDocPtr == NULL) {
- Tcl_SetResult(interp, "internal error", NULL);
- return TCL_ERROR;
- }
-
- entry = Tcl_FindHashEntry(domDocPtr->nodes, id);
- if (entry) {
- TclDOM_libxml2_Node *tNodePtr;
-
- if (objPtr->typePtr != NULL && objPtr->typePtr->freeIntRepProc != NULL) {
- objPtr->typePtr->freeIntRepProc(objPtr);
- }
-
- tNodePtr = (TclDOM_libxml2_Node *) Tcl_GetHashValue(entry);
- objPtr->internalRep.otherValuePtr = (void *) tNodePtr;
- objPtr->typePtr = &NodeObjType;
- NodeAddObjRef(tNodePtr, objPtr);
-
- } else {
- Tcl_DecrRefCount(docObjPtr);
- Tcl_SetResult(interp, "not a DOM node", NULL);
- return TCL_ERROR;
- }
-
- Tcl_DecrRefCount(docObjPtr);
-
- return TCL_OK;
-}
-
-void
-NodeTypeUpdate(objPtr)
- Tcl_Obj *objPtr;
-{
- TclDOM_libxml2_Node *tNodePtr = (TclDOM_libxml2_Node *) objPtr->internalRep.otherValuePtr;
-
- objPtr->bytes = Tcl_Alloc(strlen(tNodePtr->token) + 1);
- strcpy(objPtr->bytes, tNodePtr->token);
- objPtr->length = strlen(objPtr->bytes);
-}
-
-void
-NodeTypeDup(srcPtr, dstPtr)
- Tcl_Obj *srcPtr;
- Tcl_Obj *dstPtr;
-{
- TclDOM_libxml2_Node *tNodePtr = (TclDOM_libxml2_Node *) srcPtr->internalRep.otherValuePtr;
-
- if (dstPtr->typePtr != NULL && dstPtr->typePtr->freeIntRepProc != NULL) {
- dstPtr->typePtr->freeIntRepProc(dstPtr);
- }
-
- Tcl_InvalidateStringRep(dstPtr);
-
- dstPtr->internalRep.otherValuePtr = (ClientData) tNodePtr;
- dstPtr->typePtr = srcPtr->typePtr;
-
- NodeAddObjRef(tNodePtr, dstPtr);
-}
-
-/*
- * Unlike documents, nodes are not destroyed just because they have no Tcl_Obj's
- * referring to them.
- */
-
-void
-NodeTypeFree(objPtr)
- Tcl_Obj *objPtr;
-{
- TclDOM_libxml2_Node *tNodePtr = (TclDOM_libxml2_Node *) objPtr->internalRep.otherValuePtr;
- ObjList *listPtr = tNodePtr->objs;
- ObjList *prevPtr = NULL;
-
- while (listPtr) {
- if (listPtr->objPtr == objPtr) {
- break;
- }
- prevPtr = listPtr;
- listPtr = listPtr->next;
- }
-
- if (listPtr == NULL) {
- /* internal error */
- } else if (prevPtr == NULL) {
- tNodePtr->objs = listPtr->next;
- } else {
- prevPtr->next = listPtr->next;
- }
- Tcl_Free((char *) listPtr);
-
- objPtr->internalRep.otherValuePtr = NULL;
- objPtr->typePtr = NULL;
-}
-#if 0
-static void
-DumpNode(tNodePtr)
-TclDOM_libxml2_Node *tNodePtr;
-{
- ObjList *listPtr;
-
- fprintf(stderr, " node token \"%s\" type %d ptr x%x\n",
- tNodePtr->token, tNodePtr->type,
- tNodePtr->ptr.nodePtr);
- listPtr = (ObjList *) tNodePtr->objs;
- if (listPtr) {
- fprintf(stderr, " objects:");
- while (listPtr) {
- fprintf(stderr, " objPtr x%x", listPtr->objPtr);
- listPtr = listPtr->next;
- fprintf(stderr, "\n");
- }
- } else {
- fprintf(stderr, " no objects\n");
- }
-}
-#endif
-
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOM_libxml2_NewEventObj --
- *
- * Create a Tcl_Obj for an event.
- *
- * Results:
- * Returns Tcl_Obj*.
- *
- * Side effects:
- * Allocates object.
- *
- *----------------------------------------------------------------------------
- */
-
-Tcl_Obj *
-TclDOM_libxml2_NewEventObj (interp, docPtr, type, typeObjPtr)
- Tcl_Interp *interp;
- xmlDocPtr docPtr;
- enum TclDOM_EventTypes type;
- Tcl_Obj *typeObjPtr; /* NULL for standard types */
-{
- Tcl_Obj *objPtr, *docObjPtr;
- TclDOM_libxml2_Node *tNodePtr;
- TclDOM_libxml2_Event *eventPtr;
- TclXML_libxml2_Document *tDocPtr;
- TclDOM_libxml2_Document *domDocPtr;
- Tcl_HashEntry *entry;
- int new;
-
- docObjPtr = TclXML_libxml2_CreateObjFromDoc(docPtr);
- TclXML_libxml2_GetTclDocFromObj(interp, docObjPtr, &tDocPtr);
- domDocPtr = GetDOMDocument(interp, tDocPtr);
- if (domDocPtr == NULL) {
- Tcl_SetResult(interp, "internal error", NULL);
- return NULL;
- }
-
- tNodePtr = (TclDOM_libxml2_Node *) Tcl_Alloc(sizeof(TclDOM_libxml2_Node));
- tNodePtr->token = Tcl_Alloc(30);
- sprintf(tNodePtr->token, "::dom::%s::event%d", tDocPtr->token, domDocPtr->nodeCntr++);
- tNodePtr->type = TCLDOM_LIBXML2_NODE_EVENT;
- tNodePtr->objs = NULL;
- tNodePtr->apphook = NULL;
- tNodePtr->appfree = NULL;
-
- entry = Tcl_CreateHashEntry(domDocPtr->nodes, tNodePtr->token, &new);
- if (!new) {
- Tcl_Free((char *) tNodePtr->token);
- Tcl_Free((char *) tNodePtr);
- return NULL;
- }
- Tcl_SetHashValue(entry, (void *) tNodePtr);
-
- tNodePtr->cmd = Tcl_CreateObjCommand(interp, tNodePtr->token, TclDOMEventCommand, (ClientData) tNodePtr, TclDOMEventCommandDelete);
-
- eventPtr = (TclDOM_libxml2_Event *) Tcl_Alloc(sizeof(TclDOM_libxml2_Event));
- eventPtr->ownerDocument = domDocPtr;
- eventPtr->tNodePtr = tNodePtr;
-
- /*
- * Overload the node pointer to refer to the event structure.
- */
- tNodePtr->ptr.eventPtr = eventPtr;
-
- objPtr = Tcl_NewObj();
- objPtr->internalRep.otherValuePtr = (VOID *) tNodePtr;
- objPtr->typePtr = &NodeObjType;
-
- objPtr->bytes = Tcl_Alloc(strlen(tNodePtr->token) + 1);
- strcpy(objPtr->bytes, tNodePtr->token);
- objPtr->length = strlen(objPtr->bytes);
-
- NodeAddObjRef(tNodePtr, objPtr);
-
- eventPtr->type = type;
- if (type == TCLDOM_EVENT_USERDEFINED) {
- eventPtr->typeObjPtr = typeObjPtr;
- Tcl_IncrRefCount(eventPtr->typeObjPtr);
- } else {
- eventPtr->typeObjPtr = NULL;
- }
-
- eventPtr->stopPropagation = 0;
- eventPtr->preventDefault = 0;
- eventPtr->dispatched = 0;
-
- eventPtr->altKey = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->altKey);
- eventPtr->attrName = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->attrName);
- eventPtr->attrChange = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->attrChange);
- eventPtr->bubbles = Tcl_NewIntObj(1);
- Tcl_IncrRefCount(eventPtr->bubbles);
- eventPtr->button = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->button);
- eventPtr->cancelable = Tcl_NewIntObj(1);
- Tcl_IncrRefCount(eventPtr->cancelable);
- eventPtr->clientX = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->clientX);
- eventPtr->clientY = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->clientY);
- eventPtr->ctrlKey = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->ctrlKey);
- eventPtr->currentNode = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->currentNode);
- eventPtr->detail = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->detail);
- eventPtr->eventPhase = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->eventPhase);
- eventPtr->metaKey = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->metaKey);
- eventPtr->newValue = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->newValue);
- eventPtr->prevValue = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->prevValue);
- eventPtr->relatedNode = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->relatedNode);
- eventPtr->screenX = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->screenX);
- eventPtr->screenY = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->screenY);
- eventPtr->shiftKey = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->shiftKey);
- eventPtr->target = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->target);
-
- /* Timestamping of DOM events is not available in Tcl 8.3.x.
- * The required API (Tcl_GetTime) is public only since 8.4.0.
- */
-
- eventPtr->timeStamp = Tcl_NewLongObj(0);
-#if (TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION > 3))
- {
- Tcl_Time time;
-
- Tcl_GetTime(&time);
- Tcl_SetLongObj(eventPtr->timeStamp, time.sec*1000 + time.usec/1000);
- }
-#endif
- Tcl_IncrRefCount(eventPtr->timeStamp);
-
- eventPtr->view = Tcl_NewObj();
- Tcl_IncrRefCount(eventPtr->view);
-
- return objPtr;
-}
-/*
- *----------------------------------------------------------------------------
- *
- * TclDOMEventCommandDelete --
- *
- * Invoked when a DOM event node's Tcl command is deleted.
- *
- * Results:
- * Destroy the node.
- *
- * Side effects:
- * Frees memory.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-TclDOMEventCommandDelete (clientData)
-ClientData clientData;
-{
- TclDOM_libxml2_Node *tNodePtr = (TclDOM_libxml2_Node *) clientData;
- TclDOM_libxml2_Event *eventPtr;
-
- if (tNodePtr->type != TCLDOM_LIBXML2_NODE_EVENT) {
- return; /* internal error. should this panic? */
- }
- eventPtr = tNodePtr->ptr.eventPtr;
-
- if (eventPtr->typeObjPtr) {
- Tcl_DecrRefCount(eventPtr->typeObjPtr);
- }
- if (eventPtr->altKey) {
- Tcl_DecrRefCount(eventPtr->altKey);
- }
- if (eventPtr->attrName) {
- Tcl_DecrRefCount(eventPtr->attrName);
- }
- if (eventPtr->attrChange) {
- Tcl_DecrRefCount(eventPtr->attrChange);
- }
- if (eventPtr->bubbles) {
- Tcl_DecrRefCount(eventPtr->bubbles);
- }
- if (eventPtr->button) {
- Tcl_DecrRefCount(eventPtr->button);
- }
- if (eventPtr->cancelable) {
- Tcl_DecrRefCount(eventPtr->cancelable);
- }
- if (eventPtr->clientX) {
- Tcl_DecrRefCount(eventPtr->clientX);
- }
- if (eventPtr->clientY) {
- Tcl_DecrRefCount(eventPtr->clientY);
- }
- if (eventPtr->ctrlKey) {
- Tcl_DecrRefCount(eventPtr->ctrlKey);
- }
- if (eventPtr->currentNode) {
- Tcl_DecrRefCount(eventPtr->currentNode);
- }
- if (eventPtr->detail) {
- Tcl_DecrRefCount(eventPtr->detail);
- }
- if (eventPtr->eventPhase) {
- Tcl_DecrRefCount(eventPtr->eventPhase);
- }
- if (eventPtr->metaKey) {
- Tcl_DecrRefCount(eventPtr->metaKey);
- }
- if (eventPtr->newValue) {
- Tcl_DecrRefCount(eventPtr->newValue);
- }
- if (eventPtr->prevValue) {
- Tcl_DecrRefCount(eventPtr->prevValue);
- }
- if (eventPtr->relatedNode) {
- Tcl_DecrRefCount(eventPtr->relatedNode);
- }
- if (eventPtr->screenX) {
- Tcl_DecrRefCount(eventPtr->screenX);
- }
- if (eventPtr->screenY) {
- Tcl_DecrRefCount(eventPtr->screenY);
- }
- if (eventPtr->shiftKey) {
- Tcl_DecrRefCount(eventPtr->shiftKey);
- }
- if (eventPtr->target) {
- Tcl_DecrRefCount(eventPtr->target);
- }
- if (eventPtr->timeStamp) {
- Tcl_DecrRefCount(eventPtr->timeStamp);
- }
- if (eventPtr->view) {
- Tcl_DecrRefCount(eventPtr->view);
- }
-
- /* Invalidates all referring objects and frees all data structures */
- TclDOM_libxml2_DeleteNode((ClientData) tNodePtr);
-}
-