summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@redhat.com>2013-04-18 22:11:33 +0200
committerStef Walter <stefw@redhat.com>2013-04-19 08:05:04 +0200
commit9fc8444f2c4aca8a551f1300d734742b7d99be00 (patch)
treece7a192feea559e1b2351bc5ac56b80e804b734b
parent22bfb1beeb9c7fbcdc814798d361e28b3b81f971 (diff)
Make build work without libmba and domcHEADmaster
-rw-r--r--.gitignore23
-rw-r--r--Makefile.am2
-rw-r--r--configure.in2
-rw-r--r--libs/.cvsignore5
-rw-r--r--libs/Makefile.am24
-rw-r--r--libs/README14
-rw-r--r--libs/files/domc-0.8.0.tar.gzbin122571 -> 0 bytes
-rw-r--r--libs/files/domc-library.patch176
-rw-r--r--libs/files/libmba-0.8.10.tar.gzbin259427 -> 0 bytes
-rw-r--r--libs/files/libmba-library.patch49
-rw-r--r--libs/prepare-libraries.sh29
-rw-r--r--src/Makefile.am13
-rw-r--r--src/dom.c3145
-rw-r--r--src/dom.h526
-rw-r--r--src/domcxx.h1
-rw-r--r--src/domhelpers.h2
-rw-r--r--src/usuals.h1
-rw-r--r--src/xmlfixups.cpp2
-rw-r--r--win32/build.bat3
-rw-r--r--win32/domc.dsp97
-rw-r--r--win32/libmba.dsp97
-rw-r--r--win32/rtfx.dsp8
22 files changed, 3708 insertions, 511 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d4fa9bb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,23 @@
+.settings
+.project
+.cproject
+
+*.o
+.deps
+.libs
+Makefile
+Makefile.in
+
+/aclocal.m4
+/autom4te.cache/
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/install-sh
+/missing
+/stamp-h1
+
+/src/rtfx
diff --git a/Makefile.am b/Makefile.am
index 75e9bdd..7c60c91 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
EXTRA_DIST = BUGS doc config.win32.h
-SUBDIRS = libs src win32
+SUBDIRS = src win32
dist-hook:
rm -rf `find $(distdir)/ -name CVS`
diff --git a/configure.in b/configure.in
index b0477c6..72b3bc0 100644
--- a/configure.in
+++ b/configure.in
@@ -83,5 +83,5 @@ AC_CHECK_TYPES(wstring, , , [
AC_CHECK_FUNCS([memset strchr strerror sprintf], ,
[echo "ERROR: Required function missing"; exit 1])
-AC_CONFIG_FILES([Makefile src/Makefile win32/Makefile libs/Makefile])
+AC_CONFIG_FILES([Makefile src/Makefile win32/Makefile])
AC_OUTPUT
diff --git a/libs/.cvsignore b/libs/.cvsignore
deleted file mode 100644
index 5f7e60a..0000000
--- a/libs/.cvsignore
+++ /dev/null
@@ -1,5 +0,0 @@
-domc
-libmba
-Makefile
-Makefile.in
-
diff --git a/libs/Makefile.am b/libs/Makefile.am
deleted file mode 100644
index 6a8c88d..0000000
--- a/libs/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-
-EXTRA_DIST = files prepare-libraries.sh libmba domc
-
-# We have to take over here and do all these things ourselves
-# as the libraries' make files aren't automake compatible
-
-all:
- chmod -R u+rw $(srcdir)/libmba
- $(MAKE) -C $(srcdir)/libmba $@
- chmod -R u+rw $(srcdir)/domc
- $(MAKE) -C $(srcdir)/domc $@
-
-clean:
- chmod -R u+rw $(srcdir)/libmba
- $(MAKE) -C $(srcdir)/libmba $@
- chmod -R u+rw $(srcdir)/domc
- $(MAKE) -C $(srcdir)/domc $@
-
-install:
-
-
-dist-hook: clean
- rm -rf `find $(distdir)/ -name CVS`
-
diff --git a/libs/README b/libs/README
deleted file mode 100644
index 234ff08..0000000
--- a/libs/README
+++ /dev/null
@@ -1,14 +0,0 @@
-
-This folder includes the DOMC library that's used by rtfx for creating an in-memory
-XML tree. It was written by Michael B. Allen:
-
-http://www.ioplex.com/~miallen/domc/
-
-Because we want to avoid too dependencies, and because DOMC is small, we build
-it here and link it in statically. The 'prepare-libraries.sh' shell script
-decompresses the library tars and patches them to work with rtfx.
-
-RTFX used to use Sablotron, but because they don't major on their DOM (all about
-XSLT) it's extremely slow when used with large in memory DOMs under certain
-conditions. Because of this in some cases it would take 10 minutes to for RTFX
-to convert a 3 or 4 meg RTF file.
diff --git a/libs/files/domc-0.8.0.tar.gz b/libs/files/domc-0.8.0.tar.gz
deleted file mode 100644
index e88f962..0000000
--- a/libs/files/domc-0.8.0.tar.gz
+++ /dev/null
Binary files differ
diff --git a/libs/files/domc-library.patch b/libs/files/domc-library.patch
deleted file mode 100644
index d50e4ac..0000000
--- a/libs/files/domc-library.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-Only in domc/: libdomc.a
-Only in domc/: libdomc.so.0.8.0
-diff -r -U3 domc-0.8.0/Makefile domc/Makefile
---- domc-0.8.0/Makefile 2004-09-09 16:31:42.000000000 -0600
-+++ domc/Makefile 2004-12-02 10:27:01.085453866 -0700
-@@ -1,7 +1,8 @@
--prefix = /usr/local
--includedir = $(prefix)/include
--libdir = $(prefix)/lib
--mandir = $(prefix)/man
-+_EXTRA = -I../libmba/src/ -L../libmba/
-+prefix = ./
-+includedir = $(prefix)
-+libdir = $(prefix)
-+mandir = $(prefix)
- CC = gcc
- LIBNAME = domc
- MAJVERSION = 0.8
-@@ -11,7 +12,7 @@
- SOVERSION = lib$(LIBNAME).so.$(MAJVERSION)
- DISTRO = $(LIBNAME)-$(MINVERSION)
- RPM_OPT_FLAGS = -O2
--CFLAGS = -Wall -W -g -DMSGNO $(RPM_OPT_FLAGS) -I$(includedir) -L$(libdir)
-+CFLAGS = -Wall -W -g -DMSGNO $(RPM_OPT_FLAGS) $(_EXTRA) -I$(includedir) -L$(libdir)
- #CFLAGS = -Wall -W -DMSGNO -I$(includedir) -L$(libdir) $(RPM_OPT_FLAGS) -ansi -pedantic -Wbad-function-cast -Wcast-align -Wcast-qual -Wchar-subscripts -Winline -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-prototypes -Wwrite-strings -Wtraditional -Wconversion -Waggregate-return -Wno-parentheses
- OBJS = src/expatls.o src/events.o src/node.o src/nodelist.o src/namednodemap.o src/dom.o src/timestamp.o src/wcwidth.o src/mbs.o
- MAN = DOM_CharacterData.3m.gz DOM_Document.3m.gz DOM_Element.3m.gz DOM_Implementation.3m.gz DOM_NamedNodeMap.3m.gz DOM_Node.3m.gz DOM_NodeList.3m.gz DOM_Text.3m.gz
-@@ -19,7 +20,7 @@
- all: $(ARNAME)($(OBJS)) $(SONAME) src/defines.h
-
- $(SONAME): $(OBJS)
-- $(CC) -shared $(OBJS) -L$(libdir) -lmba -lexpat -Wl,-h,$(SOVERSION) -o $(SONAME)
-+ $(CC) -shared $(OBJS) $(_EXTRA) -L$(libdir) -lmba -Wl,-h,$(SOVERSION) -o $(SONAME)
-
- .c.a:
- $(CC) $(CFLAGS) -c -o $*.o $<
-@@ -47,5 +48,5 @@
-
- clean:
- rm -f $(OBJS) $(ARNAME) $(SONAME) $(includedir)/domc.h $(libdir)/$(ARNAME) $(libdir)/$(SONAME) $(libdir)/$(SOVERSION) $(libdir)/lib$(LIBNAME).so $(DISTRO).zip
-- cd $(mandir)/man3 && rm -f $(MAN)
-+ # cd $(mandir)/man3 && rm -f $(MAN)
-
-diff -r -U3 domc-0.8.0/Makefile.msvc domc/Makefile.msvc
---- domc-0.8.0/Makefile.msvc 2004-08-04 17:20:02.000000000 -0600
-+++ domc/Makefile.msvc 2004-12-02 10:27:01.086453660 -0700
-@@ -1,22 +1,29 @@
- !include <win32.mak>
--LIBMBA=..\libmba-0.8.9
--EXPAT=..\Expat-1.95.5
-+LIBMBA=..\libmba
-+# EXPAT=..\Expat-1.95.5
- # For i18n support in domc the encdec library is required.
- # Specify were the encdec library is below, change HAVE_ENCDEC to 1
- # in src\defines.h and add /LIBPATH:$(ENCDEC) encdec.lib to the
- # .dll link command.
--ENCDEC=..\encdec-0.3.7
-+# ENCDEC=..\encdec-0.3.7
- OBJS=src\expatls.obj src\events.obj src\timestamp.obj src\dom.obj src\node.obj src\namednodemap.obj src\nodelist.obj src\wcwidth.obj
-
-+# Debug flags
-+# CFLAGS=$(cflags) /MLd /GZ /Gm /ZI /Od /D_DEBUG
-
--domc.dll: $(OBJS)
-- $(link) /INCREMENTAL:NO /NOLOGO /LIBPATH:$(EXPAT)\Libs /LIBPATH:$(LIBMBA) /LIBPATH:$(ENCDEC) libexpat.lib libmba.lib encdec.lib /DEF:domc.def /OUT:domc.dll -entry:_DllMainCRTStartup@12 -dll $(OBJS)
-+# Normal Flags
-+CFLAGS=$(cflags) /ML /DLIBMBA_API=extern /DDOMC_API=extern
-+
-+all: domc.lib
-+
-+# domc.dll: $(OBJS)
-+# $(link) /INCREMENTAL:NO /NOLOGO /LIBPATH:$(EXPAT)\Libs /LIBPATH:$(LIBMBA) /LIBPATH:$(ENCDEC) libexpat.lib libmba.lib encdec.lib /DEF:domc.def /OUT:domc.dll -entry:_DllMainCRTStartup@12 -dll $(OBJS)
-
- domc.lib: $(OBJS)
- $(implib) -machine:$(CPU) -out:domc.lib $(OBJS)
-
- .c.obj:
-- $(cc) $(cflags) /I$(EXPAT)\Source\lib /I$(ENCDEC)\src /I$(LIBMBA)\src /Fo$@ $*.c
-+ $(cc) $(CFLAGS) /I$(LIBMBA)\src /Fo$@ $*.c
-
- clean:
- del domc.dll domc.lib domc.exp $(OBJS)
-diff -r -U3 domc-0.8.0/src/defines.h domc/src/defines.h
---- domc-0.8.0/src/defines.h 2003-03-22 16:35:36.000000000 -0700
-+++ domc/src/defines.h 2004-12-02 10:27:01.086453660 -0700
-@@ -7,7 +7,7 @@
- #define HAVE_ENCDEC 0
- #define HAVE_STRDUP 1
- #define HAVE_STRNLEN 0
--#define HAVE_EXPAT 195
-+#define HAVE_EXPAT 0
- #define HAVE_MBSTATE 0
- #define HAVE_WCWIDTH 1
- #define HAVE_SNPRINTF 1
-@@ -21,7 +21,7 @@
- #define HAVE_ENCDEC 0
- #define HAVE_STRDUP 1
- #define HAVE_STRNLEN 0
--#define HAVE_EXPAT 195
-+#define HAVE_EXPAT 0
- #define HAVE_MBSTATE 0
- #define HAVE_WCWIDTH 0
- #define HAVE_SNPRINTF 0
-@@ -35,7 +35,7 @@
- #define HAVE_ENCDEC 0
- #define HAVE_STRDUP 1
- #define HAVE_STRNLEN 1
--#define HAVE_EXPAT 195
-+#define HAVE_EXPAT 0
- #define HAVE_MBSTATE 1
- #define HAVE_WCWIDTH 1
- #define HAVE_SNPRINTF 1
-diff -r -U3 domc-0.8.0/src/domc.h domc/src/domc.h
---- domc-0.8.0/src/domc.h 2004-09-09 15:52:10.000000000 -0600
-+++ domc/src/domc.h 2004-12-02 10:29:08.870136502 -0700
-@@ -192,6 +192,8 @@
- DOM_String *data;
- } ProcessingInstruction;
- } u;
-+ unsigned int rtfxRefCount; /* Reference counting added for RTFX */
-+ void* userData; /* User data added for RTFX */
- };
-
- DOM_Node *DOM_Node_insertBefore(DOM_Node *node, DOM_Node *newChild, DOM_Node *refChild);
-@@ -222,6 +224,7 @@
- #if FAST_NODELIST
- struct hashmap* _map;
- #endif
-+ unsigned int rtfxRefCount; /* Reference counting added for RTFX */
- };
-
- DOM_Node *DOM_NodeList_item(const DOM_NodeList *nl, int index);
-@@ -296,8 +299,10 @@
- * described in the latest W3C drafts at all.
- */
-
-+#if HAVE_EXPAT > 0
- int DOM_DocumentLS_load(DOM_DocumentLS *this, const char *uri);
- int DOM_DocumentLS_fread(DOM_DocumentLS *this, FILE *stream);
-+#endif
- int DOM_DocumentLS_save(DOM_DocumentLS *this, const char *uri, const DOM_Node *node);
- int DOM_DocumentLS_fwrite(const DOM_DocumentLS *this, FILE *stream);
-
-Only in domc/src: dom.o
-Only in domc/src: events.o
-diff -r -U3 domc-0.8.0/src/expatls.c domc/src/expatls.c
---- domc-0.8.0/src/expatls.c 2004-09-09 16:08:26.000000000 -0600
-+++ domc/src/expatls.c 2004-12-02 10:27:01.087453455 -0700
-@@ -724,7 +724,7 @@
- fputs("&gt;", stream);
- break;
- case '&':
-- fputs("&apos;", stream);
-+ fputs("&amp;", stream);
- break;
- case '"':
- fputs("&quot;", stream);
-@@ -848,11 +848,6 @@
- fputs(" version=\"", stream);
- fputds(node->u.Document.version ? node->u.Document.version : "1.0", stream);
- fputc('\"', stream);
--#ifdef CODESET
-- fputs(" encoding=\"", stream);
-- fputs(nl_langinfo(CODESET), stream);
-- fputc('\"', stream);
--#endif
- if (node->u.Document.standalone != 0) {
- fputs(" standalone=\"yes\"", stream);
- }
-Only in domc/src: expatls.o
-Only in domc/src: mbs.o
-Only in domc/src: namednodemap.o
-Only in domc/src: nodelist.o
-Only in domc/src: node.o
-Only in domc/src: timestamp.o
-Only in domc/src: wcwidth.o
diff --git a/libs/files/libmba-0.8.10.tar.gz b/libs/files/libmba-0.8.10.tar.gz
deleted file mode 100644
index 3475caf..0000000
--- a/libs/files/libmba-0.8.10.tar.gz
+++ /dev/null
Binary files differ
diff --git a/libs/files/libmba-library.patch b/libs/files/libmba-library.patch
deleted file mode 100644
index 4b59985..0000000
--- a/libs/files/libmba-library.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-diff -r -U3 libmba-0.8.10/Makefile libmba/Makefile
---- libmba-0.8.10/Makefile 2004-08-27 22:59:43.000000000 -0600
-+++ libmba/Makefile 2004-08-31 18:30:01.120125541 -0600
-@@ -1,7 +1,7 @@
--prefix = /usr/local
--includedir = $(prefix)/include
--libdir = $(prefix)/lib
--mandir = $(prefix)/man
-+prefix = ./
-+includedir = $(prefix)
-+libdir = $(prefix)
-+mandir = $(prefix)
- CC = gcc
- LIBNAME = mba
- MAJVERSION = 0.8
-@@ -60,7 +60,7 @@
- clean:
- rm -rf $(includedir)/mba
- rm -f $(OBJS) $(ARNAME) $(SONAME) $(libdir)/$(ARNAME) $(libdir)/$(SONAME) $(libdir)/$(SOVERSION) $(libdir)/lib$(LIBNAME).so $(DISTRO).zip
-- cd $(mandir)/man3 && rm -f $(MAN)
-+ # cd $(mandir)/man3 && rm -f $(MAN)
-
- sho: src/shellout.c src/mba/shellout.h
- gcc -Wall -W -DTEST -DMSGNO -lmba -lutil -o sho src/shellout.c
-diff -r -U3 libmba-0.8.10/Makefile.msvc libmba/Makefile.msvc
---- libmba-0.8.10/Makefile.msvc 2004-08-27 22:41:52.000000000 -0600
-+++ libmba/Makefile.msvc 2004-08-31 19:26:49.998837317 -0600
-@@ -3,16 +3,17 @@
- #
- # Debug options
- #
--cflags=$(cflags) /MDd /GZ /Gm /ZI /Od /Isrc /I$(EXPAT)\Source\lib /D_DEBUG /DWIN32 /D_WINDOWS /DUNICODE /D_UNICODE /D_USRDLL /DLIBMBA_EXPORTS /DUSE_WCHAR /DMSGNO
--lflags=/nologo /dll /debug /pdbtype:sept
-+# cflags=$(cflags) /MLd /GZ /Gm /ZI /Od /Isrc /I$(EXPAT)\Source\lib /D_DEBUG /DWIN32 /D_WINDOWS /DUNICODE /D_UNICODE /D_USRDLL /DLIBMBA_EXPORTS /DUSE_WCHAR /DMSGNO
-+# lflags=/nologo /dll /debug /pdbtype:sept
-
- # Production options
- #
--#cflags=$(cflags) /Isrc /I$(EXPAT)\Source\lib /DWIN32 /D_WINDOWS /DUNICODE /D_UNICODE /D_USRDLL /DLIBMBA_EXPORTS /DUSE_WCHAR /DMSGNO
--#lflags=/nologo /dll /incremental:no
-+cflags=$(cflags) /ML /Isrc /DWIN32 /D_WINDOWS /DUNICODE /D_UNICODE /D_USRDLL /DLIBMBA_API=extern /DUSE_WCHAR /DMSGNO
-+lflags=/nologo /dll /incremental:no
-
- OBJS=src\cfg.obj src\hashmap.obj src\hexdump.obj src\linkedlist.obj src\mbs.obj src\msgno.obj src\stack.obj src\pool.obj src\varray.obj src\wcwidth.obj src\csv.obj src\path.obj src\text.obj src\eval.obj src\allocator.obj src\suba.obj src\bitset.obj src\time.obj src\misc.obj
-
-+all: libmba.dll libmba.lib
-
- libmba.dll: $(OBJS)
- $(link) $(lflags) /out:libmba.dll $(OBJS)
diff --git a/libs/prepare-libraries.sh b/libs/prepare-libraries.sh
deleted file mode 100644
index b993312..0000000
--- a/libs/prepare-libraries.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-
-# Unzips, prepares and patches the domc and depending libraries
-# for use with the rtfx.
-#
-# The tar files should be in the 'files' directory as should the
-# patches.
-
-cd `dirname $0`
-
-# Delete the original directories
-rm -rf domc || exit 1
-rm -rf libmba || exit 1
-
-# Unzip the libraries
-echo "untarring dist files..."
-tar -zxf files/domc-*.tar.gz || exit 1
-tar -zxf files/libmba-*.tar.gz || exit 1
-
-# Rename the directories
-echo "renaming directories..."
-mv domc-* domc || exit 1
-mv libmba-* libmba || exit 1
-
-# Patch the directories
-echo "patching the distributions..."
-patch -p0 < files/domc-library.patch
-patch -p0 < files/libmba-library.patch
-
diff --git a/src/Makefile.am b/src/Makefile.am
index e729fb7..98542a6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,21 +1,10 @@
-INCLUDES = \
- -I$(srcdir)/../libs/domc/src/ \
- -I$(srcdir)/../libs/libmba/src/
-
bin_PROGRAMS = rtfx
rtfx_SOURCES = rtfx.cpp levelhandler.cpp levelhandler.h \
reference.h xmlcomposer.cpp xmlcomposer.h xmlcomposehelpers.cpp rtfformatting.h \
xmlcomposehelpers.h rtfparser.cpp rtfparser.h domcxx.h usuals.h utf8.cpp internal.h \
- xmlfixups.h xmlfixups.cpp domhelpers.h domhelpers.cpp tags.h
-
-rtfx_LDADD = -ldomc -lmba
-
-rtfx_LDFLAGS = \
- -L/usr/local/lib \
- -L$(srcdir)/../libs/libmba/ \
- -L$(srcdir)/../libs/domc/
+ xmlfixups.h xmlfixups.cpp domhelpers.h domhelpers.cpp tags.h dom.c domc.h dom.h
man_MANS = rtfx.1
diff --git a/src/dom.c b/src/dom.c
new file mode 100644
index 0000000..714d305
--- /dev/null
+++ b/src/dom.c
@@ -0,0 +1,3145 @@
+/* domc document object model library in c
+ * Copyright (c) 2001 Michael B. Allen <mba2000 ioplex.com>
+ *
+ * The MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* dom.c - document object model interface
+ */
+
+#include <string.h>
+#include <wchar.h>
+#include <limits.h>
+#include <stdio.h>
+
+#include "dom.h"
+
+#if defined(__sparc__)
+
+#define NL "\n"
+#define HAVE_ENCDEC 0
+#define HAVE_STRDUP 1
+#define HAVE_STRNLEN 0
+#define HAVE_EXPAT 195
+#define HAVE_MBSTATE 0
+#define HAVE_WCWIDTH 1
+#define HAVE_SNPRINTF 1
+#define HAVE_VARMACRO 1
+#define HAVE_LANGINFO 1
+#define HAVE_X11_KEYSYMS 0
+
+#elif defined(_WIN32)
+
+#define NL "\r\n"
+#define HAVE_ENCDEC 0
+#define HAVE_STRDUP 1
+#define HAVE_STRNLEN 0
+#define HAVE_EXPAT 195
+#define HAVE_MBSTATE 0
+#define HAVE_WCWIDTH 0
+#define HAVE_SNPRINTF 0
+#define HAVE_VARMACRO 0
+#define HAVE_LANGINFO 0
+#define HAVE_X11_KEYSYMS 0
+
+#else
+
+#define NL "\n"
+#define HAVE_ENCDEC 0
+#define HAVE_STRDUP 1
+#define HAVE_STRNLEN 1
+#define HAVE_EXPAT 195
+#define HAVE_MBSTATE 1
+#define HAVE_WCWIDTH 1
+#define HAVE_SNPRINTF 1
+#define HAVE_VARMACRO 1
+#define HAVE_LANGINFO 1
+#define HAVE_X11_KEYSYMS 0
+
+#endif
+
+#if defined(__GNUC__)
+#if defined(MSGNO)
+
+#if defined(__GNUC__) && (__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 95))
+
+#define MSG(fmt, args...) _msgno_printf("%s:%u:%s: " fmt, \
+ __FILE__, __LINE__, __FUNCTION__, ## args)
+#define MNO(msgno) _msgno_printf("%s:%u:%s: %s", \
+ __FILE__, __LINE__, __FUNCTION__, msgno_msg(msgno))
+#define MNF(msgno, fmt, args...) _msgno_printf("%s:%u:%s: %s" fmt, \
+ __FILE__, __LINE__, __FUNCTION__, msgno_msg(msgno), ## args)
+
+#define PMSG(fmt, args...) (_msgno_buf_idx = sprintf(_msgno_buf, \
+ "%s:%u:%s: " fmt "\n", \
+ __FILE__, __LINE__, __FUNCTION__, ## args))
+#define PMNO(msgno) (_msgno_buf_idx = sprintf(_msgno_buf, \
+ "%s:%u:%s: %s\n", \
+ __FILE__, __LINE__, __FUNCTION__, msgno_msg(msgno)))
+#define PMNF(msgno, fmt, args...) (_msgno_buf_idx = sprintf(_msgno_buf, \
+ "%s:%u:%s: %s" fmt "\n", \
+ __FILE__, __LINE__, __FUNCTION__, msgno_msg(msgno), ## args))
+
+#define AMSG(fmt, args...) (_msgno_buf_idx += sprintf(_msgno_buf + _msgno_buf_idx, \
+ " %s:%u:%s: " fmt "\n", \
+ __FILE__, __LINE__, __FUNCTION__, ## args))
+#define AMNO(msgno) (_msgno_buf_idx += sprintf(_msgno_buf + _msgno_buf_idx, \
+ " %s:%u:%s: %s\n", \
+ __FILE__, __LINE__, __FUNCTION__, msgno_msg(msgno)))
+#define AMNF(msgno, fmt, args...) (_msgno_buf_idx += sprintf(_msgno_buf + _msgno_buf_idx, \
+ " %s:%u:%s: %s" fmt "\n", \
+ __FILE__, __LINE__, __FUNCTION__, msgno_msg(msgno), ## args))
+
+#else
+
+#define MSG(fmt, args...) _msgno_printf("%s:%u: " fmt "\n", \
+ __FILE__, __LINE__ , ## args)
+#define MNO(msgno) _msgno_printf("%s:%u: %s\n", \
+ __FILE__, __LINE__, msgno_msg(msgno))
+#define MNF(msgno, fmt, args...) _msgno_printf("%s:%u: %s" fmt "\n", \
+ __FILE__, __LINE__, msgno_msg(msgno) , ## args)
+
+#define PMSG(fmt, args...) (_msgno_buf_idx = sprintf(_msgno_buf, \
+ "%s:%u: " fmt "\n", __FILE__, __LINE__ , ## args))
+#define PMNO(msgno) (_msgno_buf_idx = sprintf(_msgno_buf, \
+ "%s:%u: %s\n", __FILE__, __LINE__, msgno_msg(msgno)))
+#define PMNF(msgno, fmt, args...) (_msgno_buf_idx = sprintf(_msgno_buf, \
+ "%s:%u: %s" fmt "\n", __FILE__, __LINE__, msgno_msg(msgno) , ## args))
+
+#define AMSG(fmt, args...) (_msgno_buf_idx += sprintf(_msgno_buf + _msgno_buf_idx, \
+ " %s:%u: "fmt"\n", __FILE__, __LINE__ , ## args))
+#define AMNO(msgno) (_msgno_buf_idx += sprintf(_msgno_buf + _msgno_buf_idx, \
+ " %s:%u: %s\n", __FILE__, __LINE__, msgno_msg(msgno)))
+#define AMNF(msgno, fmt, args...) (_msgno_buf_idx += sprintf(_msgno_buf + _msgno_buf_idx, \
+ " %s:%u: %s" fmt "\n", __FILE__, __LINE__, msgno_msg(msgno) , ## args))
+
+#endif
+#else
+
+#define MSG(fmt, args...)
+#define MNO(msgno)
+#define MNF(msgno, fmt, args...)
+#define PMSG(fmt, args...)
+#define PMNO(msgno)
+#define PMNF(msgno, fmt, args...)
+#define AMSG(fmt, args...)
+#define AMNO(msgno)
+#define AMNF(msgno, fmt, args...)
+
+#endif
+#else
+#undef MSG
+#if defined(MSGNO)
+
+#define MSG msgno_hdlr
+#define MNO msgno_hdlr_mno
+#define MNF msgno_hdlr_mnf
+#define PMSG msgno_hdlr
+#define PMNO msgno_hdlr_mno
+#define PMNF msgno_hdlr_mnf
+#define AMSG msgno_hdlr
+#define AMNO msgno_hdlr_mno
+#define AMNF msgno_hdlr_mnf
+
+#else
+
+#define MSG msgno_noop_msg
+#define MNO msgno_noop_mno
+#define MNF msgno_noop_mnf
+#define PMSG msgno_noop_msg
+#define PMNO msgno_noop_mno
+#define PMNF msgno_noop_mnf
+#define AMSG msgno_noop_msg
+#define AMNO msgno_noop_mno
+#define AMNF msgno_noop_mnf
+
+#endif
+#endif
+
+#ifndef MSGNO_NUM_LISTS
+#define MSGNO_NUM_LISTS 16
+#endif
+#ifndef MSGNO_BUFSIZ
+#define MSGNO_BUFSIZ 1024
+#endif
+
+#define NULL_POINTER_ERR _builtin_codes[0].msgno
+
+struct msgno_entry _builtin_codes[2] = {
+ { (1 << 16), "A parameter was NULL" },
+ { 0, NULL }
+};
+
+static struct tbl_entry {
+ struct msgno_entry *list;
+ unsigned int num_msgs;
+} list_tbl[MSGNO_NUM_LISTS] = {
+ { _builtin_codes, 1 }
+};
+
+static unsigned int next_tbl_idx = 1;
+
+const char *
+msgno_msg(int msgno)
+{
+ struct tbl_entry *te;
+ unsigned int i;
+
+ i = msgno >> 16;
+ if (i == 0) {
+ return strerror(msgno);
+ } else if (i >= MSGNO_NUM_LISTS ||
+ (te = list_tbl + (i - 1)) == NULL) {
+ return "No such msgno list";
+ }
+
+ for (i = 0; i < te->num_msgs; i++) {
+ if (te->list[i].msgno == msgno) {
+ return te->list[i].msg;
+ }
+ }
+
+ return "No such message in msgno list";
+}
+
+int
+msgno_add_codes(struct msgno_entry *list)
+{
+ struct tbl_entry *te;
+ int next_msgno = 0, hi_bits;
+
+ if (list == NULL || list->msg == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (next_tbl_idx == MSGNO_NUM_LISTS) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ for (te = list_tbl + 1; te->list; te++) {
+ if (te->list == list) {
+ return 0; /* already in list_tbl */
+ }
+ }
+
+ hi_bits = (next_tbl_idx + 1) << 16;
+ te->list = list;
+ while (list->msg) {
+ if ((list->msgno & 0xFFFF0000)) {
+ te->list = NULL;
+ errno = ERANGE;
+ return -1;
+ }
+ if (list->msgno == 0) {
+ list->msgno = hi_bits | next_msgno++;
+ } else if (list->msgno >= next_msgno) {
+ next_msgno = list->msgno + 1;
+ list->msgno = hi_bits | list->msgno;
+ } else {
+ te->list = NULL;
+ errno = ERANGE;
+ return -1;
+ }
+ te->num_msgs++;
+ list++;
+ }
+ next_tbl_idx++;
+
+ return 0;
+}
+
+
+int
+mbslen(const char *src)
+{
+ return mbsnlen(src, -1, -1);
+}
+int
+mbsnlen(const char *src, size_t sn, int cn)
+{
+ wchar_t ucs;
+ int count, w;
+ size_t n;
+#if HAVE_MBSTATE > 0
+ mbstate_t ps;
+#endif
+
+ ucs = 1;
+ count = 0;
+
+ if (sn > INT_MAX) {
+ sn = INT_MAX;
+ }
+ if (cn < 0) {
+ cn = INT_MAX;
+ }
+
+#if HAVE_MBSTATE
+ memset(&ps, 0, sizeof(ps));
+ while (ucs && (n = mbrtowc(&ucs, src, sn, &ps)) != (size_t)-2) {
+#else
+ while (ucs && sn > 0) {
+ n = mbtowc(&ucs, src, sn);
+#endif
+ if (n == (size_t)-1) {
+ PMNO(errno);
+ return -1;
+ }
+ if ((w = wcwidth(ucs)) == -1) {
+ w = 1;
+ }
+ if (w > cn) {
+ break;
+ }
+ cn -= w;
+ sn -= n;
+ src += n;
+ count += w;
+ }
+
+ return count;
+}
+
+size_t
+mbsnsize(const char *src, size_t sn, int cn)
+{
+ wchar_t ucs;
+ int w;
+ size_t tot, n;
+#if HAVE_MBSTATE > 0
+ mbstate_t ps;
+#endif
+
+ tot = n = 0;
+ ucs = 1;
+
+ if (sn > INT_MAX) {
+ sn = INT_MAX;
+ }
+ if (cn < 0) {
+ cn = INT_MAX;
+ }
+
+#if HAVE_MBSTATE
+ memset(&ps, 0, sizeof(ps));
+ while (ucs && sn > 0 && (n = mbrtowc(&ucs, src, sn, &ps)) != (size_t)-2 && n) {
+#else
+ while (ucs && sn > 0 && (n = mbtowc(&ucs, src, sn))) {
+#endif
+ if (n == (size_t)-1) {
+ PMNO(errno);
+ return -1;
+ }
+ if ((w = wcwidth(ucs)) == -1) {
+ w = 1;
+ }
+ if (w > cn) {
+ break;
+ }
+ cn -= w;
+ sn -= n;
+ src += n;
+ tot += n;
+ }
+
+ return tot;
+}
+
+size_t
+mbssize(const char *src)
+{
+ return mbsnsize(src, -1, -1);
+}
+
+static char *
+mbsnoff(char *src, int off, size_t sn)
+{
+ wchar_t ucs;
+ size_t n;
+ int w;
+#if HAVE_MBSTATE > 0
+ mbstate_t ps;
+#endif
+
+ if (off == 0) {
+ return src;
+ }
+
+ if (sn > INT_MAX) {
+ sn = 0xFFFF;
+ }
+ if (off < 0) {
+ off = 0xFFFF;
+ }
+
+#if HAVE_MBSTATE > 0
+ memset(&ps, 0, sizeof(ps));
+ while (sn > 0 && (n = mbrtowc(&ucs, src, sn, &ps)) != (size_t)-2) {
+#else
+ while (sn > 0) {
+ n = mbtowc(&ucs, src, sn);
+#endif
+ if (n == (size_t)-1) {
+ PMNF(errno, "src=[%s]", mbstoax(src, sn, 1));
+ return NULL;
+ }
+ if (n == 0 || (w = wcwidth(ucs)) != 0) {
+ w = 1;
+ }
+ if (w > off) {
+ break;
+ }
+ if (w) off--;
+ sn -= n;
+ src += n ? n : 1;
+ }
+
+ return src;
+}
+
+
+static char *
+mbsoff(char *src, int off)
+{
+ return mbsnoff(src, off, -1);
+}
+
+static char *
+mbsndup(const char *src, size_t sn, int cn)
+{
+ size_t n;
+ char *dst;
+
+ if (src == NULL) {
+ errno = EINVAL;
+ PMNO(errno);
+ return NULL;
+ }
+ if ((n = mbsnsize(src, sn, cn)) == (size_t)-1) {
+ AMSG("");
+ return NULL;
+ }
+ if ((dst = malloc(n + 1)) == NULL) {
+ PMNO(errno);
+ return NULL;
+ }
+ memcpy(dst, src, n);
+ dst[n] = '\0';
+
+ return dst;
+}
+
+static char *
+mbsdup(const char *src)
+{
+ return mbsndup(src, -1, -1);
+}
+
+#if defined(_WIN32)
+#include <Windows.h>
+
+typedef unsigned __int64 uint64_t;
+
+uint64_t
+timestamp(void)
+{
+ FILETIME ftime;
+ uint64_t ret;
+
+ GetSystemTimeAsFileTime(&ftime);
+
+ ret = ftime.dwHighDateTime;
+ ret <<= 32Ui64;
+ ret |= ftime.dwLowDateTime;
+
+ return ret;
+}
+
+#else
+#include <sys/time.h>
+
+uint64_t
+timestamp(void)
+{
+ struct timeval tval;
+
+ if (gettimeofday(&tval, NULL) < 0) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ return 1;
+ }
+ return tval.tv_sec * 1000LL + tval.tv_usec / 1000;
+}
+
+#endif
+
+/* Forward references for node.c
+ */
+
+DOM_Node *Document_createNode(DOM_Document *doc, unsigned short nodeType);
+NodeEntry *NodeList_remove(DOM_NodeList *nl, DOM_Node *oldChild);
+NodeEntry *NodeList_append(DOM_NodeList *nl, DOM_Node *newChild);
+DOM_NodeList *Document_createNodeList(DOM_Document *doc);
+DOM_NamedNodeMap *Document_createNamedNodeMap(DOM_Document *doc);
+
+/* Forward references for events.c
+ */
+
+void updateCommonParent(DOM_Node *node);
+
+/* DOM_Exception
+ */
+
+struct msgno_entry dom_codes[] = {
+ { 1, "The index specified was out of range" },
+ { 0, "The text size is out of range" },
+ { 0, "The request violated tree hierarchy constraints" },
+ { 0, "The document context is invalid" },
+ { 0, "An inappropriate character was encountered" },
+ { 0, "The node does not support the addition of data" },
+ { 0, "No modification allowed" },
+ { 0, "The specified node was not found" },
+ { 0, "The requested operation is not supported" },
+ { 0, "The attribute is being used elsewhere" },
+ { 0, "An XML parser error occured" },
+ { 0, "Failed to create DOM object" },
+ { 0, "Character encoding error" },
+ { 0, "The event type was not specified by initialization" },
+ { 0, "A filtered list cannot be modified" },
+ { 0, NULL }
+};
+
+int _exception = 0;
+
+int *
+_DOM_Exception(void)
+{
+ return &_exception;
+}
+
+unsigned short child_matrix[] = {
+ 0x00dd, /* DOM_ELEMENT_NODE 1 */
+ 0x0014, /* DOM_ATTRIBUTE_NODE 2 */
+ 0x0000, /* DOM_TEXT_NODE 3 */
+ 0x0000, /* DOM_CDATA_SECTION_NODE 4 */
+ 0x00dd, /* DOM_ENTITY_REFERENCE_NODE 5 */
+ 0x00dd, /* DOM_ENTITY_NODE 6 */
+ 0x0000, /* DOM_PROCESSING_INSTRUCTION_NODE 7 */
+ 0x0000, /* DOM_COMMENT_NODE 8 */
+ 0x02c1, /* DOM_DOCUMENT_NODE 9 */
+ 0x0820, /* DOM_DOCUMENT_TYPE_NODE 10 */
+ 0x00dd, /* DOM_DOCUMENT_FRAGMENT_NODE 11 */
+ 0x0000 /* DOM_NOTATION_NODE 12 */
+};
+
+const char *node_names[] = {
+ "No such node type",
+ "DOM_ELEMENT_NODE",
+ "DOM_ATTRIBUTE_NODE",
+ "DOM_TEXT_NODE",
+ "DOM_CDATA_SECTION_NODE",
+ "DOM_ENTITY_REFERENCE_NODE",
+ "DOM_ENTITY_NODE",
+ "DOM_PROCESSING_INSTRUCTION_NODE",
+ "DOM_COMMENT_NODE",
+ "DOM_DOCUMENT_NODE",
+ "DOM_DOCUMENT_TYPE_NODE",
+ "DOM_DOCUMENT_FRAGMENT_NODE",
+ "DOM_NOTATION_NODE"
+};
+
+/* DOM_Implementation and DOM_ImplementationLS
+ */
+
+int
+DOM_Implementation_hasFeature(DOM_String *feature, DOM_String *version)
+{
+ feature = NULL; version = NULL;
+ return 0;
+}
+DOM_DocumentType *
+DOM_Implementation_createDocumentType(DOM_String *qualifiedName,
+ DOM_String *publicId, DOM_String *systemId)
+{
+ DOM_DocumentType *doctype;
+ DOM_NamedNodeMap *entities;
+ DOM_NamedNodeMap *notations;
+
+ if ((doctype = Document_createNode(NULL, DOM_DOCUMENT_TYPE_NODE)) == NULL) {
+ AMSG("");
+ return NULL;
+ }
+ if ((doctype->nodeName = doctype->u.DocumentType.name = strdup(qualifiedName)) == NULL ||
+ (publicId && ((doctype->u.DocumentType.publicId = strdup(publicId))) == NULL) ||
+ (systemId && ((doctype->u.DocumentType.systemId = strdup(systemId))) == NULL)) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(NULL, doctype);
+ return NULL;
+ }
+ if ((entities = Document_createNamedNodeMap(NULL)) == NULL ||
+ (notations = Document_createNamedNodeMap(NULL)) == NULL) {
+ AMNO(DOM_CREATE_FAILED);
+ DOM_Document_destroyNode(NULL, doctype);
+ return NULL;
+ }
+ entities->filter = DOM_ENTITY_NODE;
+ notations->filter = DOM_NOTATION_NODE;
+ entities->list = notations->list = doctype->childNodes;
+ doctype->u.DocumentType.entities = entities;
+ doctype->u.DocumentType.notations = notations;
+
+ return doctype;
+}
+DOM_Document *
+DOM_Implementation_createDocument(DOM_String *namespaceURI,
+ DOM_String *qualifiedName, DOM_DocumentType *doctype)
+{
+ DOM_Document *doc;
+ DOM_Element *el;
+
+ namespaceURI = NULL;
+
+ msgno_add_codes(dom_codes);
+
+ if ((doc = Document_createNode(NULL, DOM_DOCUMENT_NODE)) == NULL) {
+ AMSG("");
+ return NULL;
+ }
+ doc->nodeName = "#document";
+ if (doctype) {
+ DOM_Node_appendChild(doc, doctype);
+ }
+
+ if (qualifiedName && *qualifiedName) {
+ if ((el = DOM_Document_createElement(doc, qualifiedName)) == NULL) {
+ AMSG("");
+ DOM_Document_destroyNode(doc, doc);
+ return NULL;
+ }
+ DOM_Node_appendChild(doc, el);
+ }
+
+ return doc;
+}
+
+DOM_String *
+DOM_Element_getAttribute(const DOM_Element *element, const DOM_String *name)
+{
+ DOM_Node *node;
+ DOM_String *r = NULL;
+
+ if (element && name && element->attributes) {
+ if ((node = DOM_NamedNodeMap_getNamedItem(element->attributes, name))) {
+ if ((r = strdup(node->nodeValue)) == NULL) {
+ AMSG("");
+ return NULL;
+ }
+ } else if ((r = strdup("")) == NULL) {
+ PMNO(errno);
+ return NULL;
+ }
+ }
+
+ return r;
+}
+void
+DOM_Element_setAttribute(DOM_Element *element,
+ const DOM_String *name, const DOM_String *value)
+{
+ DOM_Attr *attr;
+ DOM_String *prevValue;
+ unsigned short attrChange;
+ DOM_MutationEvent evt;
+
+ if (element == NULL || name == NULL ||
+ value == NULL || element->attributes == NULL) {
+ return;
+ }
+
+ attr = DOM_NamedNodeMap_getNamedItem(element->attributes, name);
+ if (attr) {
+ prevValue = attr->nodeValue;
+ attrChange = DOM_MUTATION_EVENT_MODIFICATION;
+ if ((attr->nodeValue = attr->u.Attr.value = strdup(value)) == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(attr->ownerDocument, attr);
+ return;
+ }
+ } else {
+ prevValue = NULL;
+ attrChange = DOM_MUTATION_EVENT_ADDITION;
+ if ((attr = DOM_Document_createAttribute(element->ownerDocument, name)) == NULL) {
+ AMNO(DOM_CREATE_FAILED);
+ return;
+ }
+ free(attr->nodeValue);
+ if ((attr->nodeValue = attr->u.Attr.value = strdup(value)) == NULL) {
+ DOM_Exception = errno;
+ DOM_Document_destroyNode(attr->ownerDocument, attr);
+ return;
+ }
+ DOM_NamedNodeMap_setNamedItem(element->attributes, attr);
+ }
+
+ DOM_MutationEvent_initMutationEvent(&evt, "DOMAttrModified", 1, 0,
+ attr, prevValue, attr->nodeValue, attr->nodeName, attrChange);
+/*MSG("attr=%p,prevValue=[%s],newValue=[%s],attrName=%s", attr, prevValue, attr->nodeValue, attr->nodeName);
+ */
+ DOM_EventTarget_dispatchEvent(element, &evt);
+
+ updateCommonParent(element->parentNode);
+
+ free(prevValue);
+}
+void
+DOM_Element_removeAttribute(DOM_Element *element, const DOM_String *name)
+{
+ DOM_Attr *attr;
+ DOM_MutationEvent evt;
+
+ if (element == NULL || name == NULL) {
+ return;
+ }
+
+ attr = DOM_NamedNodeMap_removeNamedItem(element->attributes, name);
+
+ /* removeAttribute doesn't throw exceptions on NOT_FOUND_ERR */
+ if (DOM_Exception == DOM_NOT_FOUND_ERR)
+ DOM_Exception = 0;
+
+ if (attr) {
+ DOM_MutationEvent_initMutationEvent(&evt, "DOMAttrModified", 1, 0,
+ attr, attr->nodeValue, NULL, attr->nodeName, DOM_MUTATION_EVENT_REMOVAL);
+ DOM_EventTarget_dispatchEvent(element, &evt);
+
+ updateCommonParent(element->parentNode);
+
+ DOM_Document_destroyNode(attr->ownerDocument, attr);
+ }
+}
+DOM_Attr *
+DOM_Element_getAttributeNode(const DOM_Element *element, const DOM_String *name)
+{
+ if (element && name) {
+ return DOM_NamedNodeMap_getNamedItem(element->attributes, name);
+ }
+ return NULL;
+}
+DOM_Attr *
+DOM_Element_setAttributeNode(DOM_Element *element, DOM_Attr *newAttr)
+{
+ DOM_Node *attr;
+ DOM_MutationEvent evt;
+
+ if (element == NULL || newAttr == NULL) {
+ return NULL;
+ }
+ if (element->ownerDocument != newAttr->ownerDocument) {
+ DOM_Exception = DOM_WRONG_DOCUMENT_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ attr = DOM_NamedNodeMap_setNamedItem(element->attributes, newAttr);
+
+ if (attr) {
+ DOM_MutationEvent_initMutationEvent(&evt, "DOMAttrModified", 1, 0,
+ attr, attr->nodeValue, NULL, attr->nodeName, DOM_MUTATION_EVENT_REMOVAL);
+ DOM_EventTarget_dispatchEvent(element, &evt);
+ }
+
+ DOM_MutationEvent_initMutationEvent(&evt, "DOMAttrModified", 1, 0,
+ newAttr, NULL, newAttr->nodeValue, newAttr->nodeName, DOM_MUTATION_EVENT_ADDITION);
+ DOM_EventTarget_dispatchEvent(element, &evt);
+
+ updateCommonParent(element->parentNode);
+
+ return attr;
+}
+DOM_Attr *
+DOM_Element_removeAttributeNode(DOM_Element *element, DOM_Attr *oldAttr)
+{
+ DOM_MutationEvent evt;
+
+ if (element == NULL || oldAttr == NULL ||
+ NodeList_remove(element->attributes, oldAttr) == NULL) {
+ DOM_Exception = DOM_NOT_FOUND_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ DOM_MutationEvent_initMutationEvent(&evt, "DOMAttrModified", 1, 0,
+ oldAttr, oldAttr->nodeValue, NULL, oldAttr->nodeName, DOM_MUTATION_EVENT_REMOVAL);
+ DOM_EventTarget_dispatchEvent(element, &evt);
+
+ updateCommonParent(element->parentNode);
+
+ return oldAttr;
+}
+
+static void
+getElementsPreorder(DOM_NodeList *list, DOM_Node *node, const DOM_String *tagname)
+{
+ DOM_Node *n;
+
+ if (list && node && node->nodeType == DOM_ELEMENT_NODE && tagname) {
+ if ((tagname[0] == '*' && tagname[1] == '\0') ||
+ strcoll(tagname, node->nodeName) == 0) {
+ NodeList_append(list, node);
+ }
+ for (n = node->firstChild; n != NULL; n = n->nextSibling) {
+ getElementsPreorder(list, n, tagname);
+ }
+ }
+}
+
+DOM_NodeList *
+DOM_Element_getElementsByTagName(DOM_Element *element, const DOM_String *name)
+{
+ DOM_NodeList *list;
+ DOM_Node *n;
+
+ if (element && element->nodeType == DOM_ELEMENT_NODE && name &&
+ (list = Document_createNodeList(element->ownerDocument))) {
+ for (n = element->firstChild; n != NULL; n = n->nextSibling) {
+ getElementsPreorder(list, n, name);
+ }
+ return list;
+ }
+
+ return NULL;
+}
+void
+DOM_Element_normalize(DOM_Element *element)
+{
+ DOM_Node *node;
+ DOM_Text *last = NULL;
+
+ if (element) {
+ for (node = element->firstChild; node != NULL; node = node->nextSibling) {
+ if (node->nodeType == DOM_TEXT_NODE) {
+ if (last) {
+ DOM_CharacterData_insertData(node, 0, last->nodeValue);
+ DOM_Node_removeChild(element, last);
+ DOM_Document_destroyNode(last->ownerDocument, last);
+ }
+ last = node;
+ } else {
+ last = NULL;
+ DOM_Element_normalize(node);
+ }
+ if (DOM_Exception) {
+ AMSG("");
+ return;
+ }
+ }
+ }
+}
+
+DOM_String *
+DOM_CharacterData_substringData(DOM_CharacterData *data,
+ int offset, int count)
+{
+ DOM_String *sub;
+ int dlen;
+
+ if (data == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (offset < 0 || offset > (dlen = data->u.CharacterData.length) || count < 0) {
+ DOM_Exception = DOM_INDEX_SIZE_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (count > (dlen - offset)) {
+ count = dlen - offset;
+ }
+ if ((sub = mbsoff(data->nodeValue, offset)) == NULL ||
+ (sub = mbsndup(sub, -1, count)) == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ return sub;
+}
+void
+DOM_CharacterData_appendData(DOM_CharacterData *data, const DOM_String *arg)
+{
+ DOM_String *str, *prevValue;
+ size_t dsize, asize;
+ DOM_MutationEvent evt;
+
+ if (data == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return;
+ }
+ if (arg) {
+ dsize = mbssize(data->nodeValue);
+ asize = mbssize(arg);
+ if ((str = malloc(dsize + asize + 1)) == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ return;
+ }
+
+ memcpy(str, data->nodeValue, dsize);
+ memcpy(str + dsize, arg, asize);
+ str[dsize + asize] = '\0';
+
+ prevValue = data->nodeValue;
+ data->nodeValue = data->u.CharacterData.data = str;
+ data->u.CharacterData.length += mbslen(arg);
+
+ DOM_MutationEvent_initMutationEvent(&evt, "DOMCharacterDataModified", 1, 0,
+ NULL, prevValue, data->nodeValue, NULL, 0);
+ DOM_EventTarget_dispatchEvent(data, &evt);
+
+ updateCommonParent(data->parentNode);
+
+ free(prevValue);
+ }
+}
+void
+DOM_CharacterData_insertData(DOM_CharacterData *data,
+ int offset, const DOM_String *arg)
+{
+ DOM_String *str, *prevValue;
+ size_t dsize, asize, o;
+ DOM_MutationEvent evt;
+
+ if (data == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return;
+ }
+ if (offset < 0 || offset > data->u.CharacterData.length) {
+ DOM_Exception = DOM_INDEX_SIZE_ERR;
+ PMNO(DOM_Exception);
+ return;
+ }
+ if (arg) {
+ dsize = mbssize(data->nodeValue);
+ asize = mbssize(arg);
+ if ((str = malloc(dsize + asize + 1)) == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ return;
+ }
+
+ o = mbsoff(data->nodeValue, offset) - data->nodeValue;
+ memcpy(str, data->nodeValue, o);
+ memcpy(str + o, arg, asize);
+ memcpy(str + o + asize, data->nodeValue + o, dsize - o);
+ str[dsize + asize] = '\0';
+
+ prevValue = data->nodeValue;
+ data->nodeValue = data->u.CharacterData.data = str;
+ data->u.CharacterData.length += mbslen(arg);
+
+ DOM_MutationEvent_initMutationEvent(&evt, "DOMCharacterDataModified", 1, 0,
+ NULL, prevValue, data->nodeValue, NULL, 0);
+ DOM_EventTarget_dispatchEvent(data, &evt);
+
+ updateCommonParent(data->parentNode);
+
+ free(prevValue);
+ }
+}
+void
+DOM_CharacterData_deleteData(DOM_CharacterData *data,
+ int offset, int count)
+{
+ DOM_String *p1, *p2, *str, *prevValue;
+ int p1size, p2size, dlen;
+ DOM_MutationEvent evt;
+
+ if (data == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return;
+ }
+ if (offset < 0 || offset > (dlen = data->u.CharacterData.length)) {
+ DOM_Exception = DOM_INDEX_SIZE_ERR;
+ PMNO(DOM_Exception);
+ return;
+ }
+ if (count < 0 || (offset + count) > dlen) {
+ count = dlen - offset;
+ }
+
+ p1 = mbsoff(data->nodeValue, offset);
+ p1size = p1 - data->nodeValue;
+ p2 = mbsoff(p1, count);
+ p2size = strlen(p2);
+
+ if ((str = malloc(p1size + p2size + 1)) == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ return;
+ }
+ memcpy(str, data->nodeValue, p1size);
+ memcpy(str + p1size, p2, p2size);
+ str[p1size + p2size] = '\0';
+
+ prevValue = data->nodeValue;
+ data->nodeValue = data->u.CharacterData.data = str;
+ data->u.CharacterData.length = dlen - count;
+
+ DOM_MutationEvent_initMutationEvent(&evt, "DOMCharacterDataModified", 1, 0,
+ NULL, prevValue, data->nodeValue, NULL, 0);
+ DOM_EventTarget_dispatchEvent(data, &evt);
+
+ updateCommonParent(data->parentNode);
+
+ free(prevValue);
+}
+void
+DOM_CharacterData_replaceData(DOM_CharacterData *data, int offset, int count,
+ const DOM_String *arg)
+{
+ DOM_CharacterData_deleteData(data, offset, count);
+ DOM_CharacterData_insertData(data, offset, arg);
+}
+int
+DOM_CharacterData_getLength(DOM_CharacterData *data)
+{
+ return data ? data->u.CharacterData.length : 0;
+}
+
+DOM_Text *
+DOM_Text_splitText(DOM_Text *text, int offset)
+{
+ DOM_Text *node;
+
+ if (text == NULL || text->parentNode == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ if (offset < 0 || offset > text->u.CharacterData.length) {
+ DOM_Exception = DOM_INDEX_SIZE_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ node = DOM_Document_createTextNode(text->ownerDocument,
+ mbsoff(text->nodeValue, offset));
+ if (node == NULL) {
+ AMNO(DOM_CREATE_FAILED);
+ return NULL;
+ }
+ DOM_CharacterData_deleteData(text, offset, -1);
+ DOM_Node_insertBefore(text->parentNode, node, text->nextSibling);
+
+ return node;
+}
+
+
+DOM_Element *
+DOM_Document_createElement(DOM_Document *doc, const DOM_String *tagName)
+{
+ DOM_Element *element;
+
+ element = Document_createNode(doc, DOM_ELEMENT_NODE);
+ if (element) {
+ if ((element->nodeName = element->u.Element.tagName = strdup(tagName)) == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(doc, element);
+ return NULL;
+ }
+ if ((element->attributes = Document_createNamedNodeMap(doc)) == NULL) {
+ AMNO(DOM_CREATE_FAILED);
+ DOM_Document_destroyNode(doc, element);
+ return NULL;
+ }
+ element->attributes->_ownerElement = element; /* for Attr.ownerElement */
+ }
+
+ return element;
+}
+DOM_DocumentFragment *
+DOM_Document_createDocumentFragment(DOM_Document *doc)
+{
+ DOM_DocumentFragment *frag;
+
+ frag = Document_createNode(doc, DOM_DOCUMENT_FRAGMENT_NODE);
+ if (frag) {
+ frag->nodeName = "#document-fragment";
+ }
+
+ return frag;
+}
+DOM_Text *
+DOM_Document_createTextNode(DOM_Document *doc, const DOM_String *data)
+{
+ DOM_Text *text;
+
+ text = Document_createNode(doc, DOM_TEXT_NODE);
+ if (text) {
+ text->nodeName = "#text";
+ text->nodeValue = text->u.CharacterData.data = strdup(data);
+ if (text->nodeValue == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(doc, text);
+ return NULL;
+ }
+ text->u.CharacterData.length = mbslen(data);
+ }
+
+ return text;
+}
+DOM_Comment *
+DOM_Document_createComment(DOM_Document *doc, const DOM_String *data)
+{
+ DOM_Comment *comment;
+
+ comment = Document_createNode(doc, DOM_COMMENT_NODE);
+ if (comment) {
+ comment->nodeName = "#comment";
+ comment->nodeValue = comment->u.CharacterData.data = strdup(data);
+ if (comment->nodeValue == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(doc, comment);
+ return NULL;
+ }
+ comment->u.CharacterData.length = mbslen(data);
+ }
+
+ return comment;
+}
+DOM_CDATASection *
+DOM_Document_createCDATASection(DOM_Document *doc, const DOM_String *data)
+{
+ DOM_CDATASection *cdata;
+
+ cdata = Document_createNode(doc, DOM_CDATA_SECTION_NODE);
+ if (cdata) {
+ cdata->nodeName = "#cdata-section";
+ cdata->nodeValue = cdata->u.CharacterData.data = strdup(data);
+ if (cdata->u.CharacterData.data == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(doc, cdata);
+ return NULL;
+ }
+ cdata->u.CharacterData.length = mbslen(data);
+ }
+
+ return cdata;
+}
+DOM_ProcessingInstruction *
+DOM_Document_createProcessingInstruction(DOM_Document *doc,
+ const DOM_String *target, const DOM_String *data)
+{
+ DOM_ProcessingInstruction *pi;
+
+ pi = Document_createNode(doc, DOM_PROCESSING_INSTRUCTION_NODE);
+ if (pi) {
+ pi->nodeName = pi->u.ProcessingInstruction.target = strdup(target);
+ pi->nodeValue = pi->u.ProcessingInstruction.data = strdup(data);
+ if (pi->nodeName == NULL || pi->nodeValue == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(doc, pi);
+ return NULL;
+ }
+ }
+
+ return pi;
+}
+DOM_Attr *
+DOM_Document_createAttribute(DOM_Document *doc, const DOM_String *name)
+{
+ DOM_Attr *attr;
+
+ attr = Document_createNode(doc, DOM_ATTRIBUTE_NODE);
+ if (attr) {
+ attr->nodeName = attr->u.Attr.name = strdup(name);
+ attr->nodeValue = attr->u.Attr.value = strdup("");
+ attr->u.Attr.specified = 1;
+ if (attr->nodeName == NULL || attr->nodeValue == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(doc, attr);
+ return NULL;
+ }
+ }
+
+ return attr;
+}
+DOM_EntityReference *
+DOM_Document_createEntityReference(DOM_Document *doc, const DOM_String *name)
+{
+ DOM_EntityReference *eref;
+
+ eref = Document_createNode(doc, DOM_ENTITY_REFERENCE_NODE);
+ if (eref && (eref->nodeName = strdup(name)) == NULL) {
+ DOM_Document_destroyNode(doc, eref);
+ return NULL;
+ }
+
+ return eref;
+}
+
+DOM_NodeList *
+DOM_Document_getElementsByTagName(DOM_Document *doc, const DOM_String *tagname)
+{
+ DOM_NodeList *list;
+
+ if (doc && doc->nodeType == DOM_DOCUMENT_NODE &&
+ tagname && (list = Document_createNodeList(doc))) {
+ getElementsPreorder(list, doc->u.Document.documentElement, tagname);
+ return list;
+ }
+
+ return NULL;
+}
+DOM_DocumentType *
+DOM_Document_getDoctype(DOM_Document *doc)
+{
+ return doc ? doc->u.Document.doctype : NULL;
+}
+DOM_Element *
+DOM_Document_getDocumentElement(DOM_Document *doc)
+{
+ return doc ? doc->u.Document.documentElement : NULL;
+}
+
+/* Temporary functions */
+
+void
+printNode(DOM_Node *node, int indent)
+{
+ DOM_Node *n;
+ int i;
+
+ if (node == NULL) {
+ printf("node was null\n");
+ return;
+ }
+
+ for (i = 0; i < indent; i++) {
+ printf(" ");
+ }
+
+ printf("%s: %s=%s\n", node_names[node->nodeType], node->nodeName, node->nodeValue);
+
+ if (node->nodeType == DOM_ELEMENT_NODE && node->attributes->length) {
+ printf(" ");
+ n = DOM_NamedNodeMap_item(node->attributes, 0);
+ printf("%s=%s", n->nodeName, n->nodeValue);
+ for (i = 1; i < node->attributes->length; i++) {
+ n = DOM_NamedNodeMap_item(node->attributes, i);
+ printf(",%s=%s", n->nodeName, n->nodeValue);
+ }
+ printf("\n");
+ for (i = 0; i < indent; i++) {
+ printf(" ");
+ }
+ }
+ for (n = node->firstChild; n != NULL; n = n->nextSibling) {
+ printNode(n, indent + 1);
+ }
+}
+void
+DOM_Node_printNode2(DOM_Node *node)
+{
+ printf("\n");
+ printNode(node, 0);
+}
+void
+DOM_Node_printNode(DOM_Node *node)
+{
+ if (node == NULL) {
+ printf("node was null\n");
+ return;
+ }
+
+ printf("\nnodeName=%s,nodeValue=%s,", node->nodeName, node->nodeValue);
+ printf("\n\ttype=%u", node->nodeType);
+ printf(",parentNode->nodeName=%s,firstChild->nodeName=%s", (node->parentNode == NULL ? "(null)" : node->parentNode->nodeName), (node->firstChild == NULL ? "(null)" : node->firstChild->nodeName));
+ printf(",lastChild->nodeName=%s,\n\tchildNodes->length=%u", (node->lastChild == NULL ? "(null)" : node->lastChild->nodeName), (node->childNodes == NULL ? 0 : node->childNodes->length));
+ printf(",previousSibling->nodeName=%s,nextSibling->nodeName=%s,attributes->length=%u\n", (node->previousSibling == NULL ? "(null)" : node->previousSibling->nodeName), (node->nextSibling == NULL ? "(null)": node->nextSibling->nodeName), (node->attributes == NULL ? 0 : node->attributes->length));
+ fflush(stdout);
+}
+
+
+/* NamedNodeMap
+ */
+
+void
+DOM_Document_destroyNamedNodeMap(DOM_Document *doc, DOM_NamedNodeMap *map, int free_nodes)
+{
+ DOM_Document_destroyNodeList(doc, map, free_nodes);
+}
+DOM_NamedNodeMap *
+Document_createNamedNodeMap(DOM_Document *doc)
+{
+ return Document_createNodeList(doc);
+}
+
+DOM_Node *
+DOM_NamedNodeMap_getNamedItem(const DOM_NamedNodeMap *map, const DOM_String *name)
+{
+ NodeEntry *e;
+ unsigned short nodeType;
+
+ if (map && name) {
+ if (map->filter) {
+ nodeType = map->filter;
+ map = map->list;
+ for (e = map->first; e != NULL; e = e->next) {
+ if (e->node->nodeType == nodeType && strcoll(name, e->node->nodeName) == 0) {
+ return e->node;
+ }
+ }
+ } else {
+ for (e = map->first; e != NULL; e = e->next) {
+ if (strcoll(name, e->node->nodeName) == 0) {
+ return e->node;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+DOM_Node *
+DOM_NamedNodeMap_setNamedItem(DOM_NamedNodeMap *map, DOM_Node *arg)
+{
+ NodeEntry *e;
+
+ if (map && arg) {
+ if (map->filter) {
+ DOM_Exception = DOM_NO_MODIFICATION_ALLOWED_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (map->_ownerDocument != arg->ownerDocument) {
+ DOM_Exception = DOM_WRONG_DOCUMENT_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (arg->nodeType == DOM_ATTRIBUTE_NODE && arg->u.Attr.ownerElement &&
+ arg->u.Attr.ownerElement != map->_ownerElement) {
+ DOM_Exception = DOM_INUSE_ATTRIBUTE_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ for (e = map->first; e != NULL && strcoll(arg->nodeName, e->node->nodeName); e = e->next) {
+ ;
+ }
+ if (e) {
+ DOM_Node *tmp = e->node;
+ e->node = arg;
+ if (arg->nodeType == DOM_ATTRIBUTE_NODE) {
+ arg->u.Attr.ownerElement = map->_ownerElement;
+ tmp->u.Attr.ownerElement = NULL;
+ }
+ return tmp;
+ }
+ NodeList_append(map, arg);
+ }
+
+ return NULL;
+}
+DOM_Node *
+DOM_NamedNodeMap_removeNamedItem(DOM_NamedNodeMap *map, const DOM_String *name)
+{
+ NodeEntry *e;
+ DOM_Node *r = NULL;
+
+ if (map && name) {
+ if (map->filter) {
+ DOM_Exception = DOM_NO_MODIFICATION_ALLOWED_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ for (e = map->first; e != NULL; e = e->next) {
+ if (strcoll(name, e->node->nodeName) == 0 &&
+ NodeList_remove(map, e->node)) {
+ r = e->node;
+ free(e);
+ if (r->nodeType == DOM_ATTRIBUTE_NODE) {
+ r->u.Attr.ownerElement = NULL;
+ }
+ return r;
+ }
+ }
+ }
+
+ DOM_Exception = DOM_NOT_FOUND_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+}
+DOM_Node *
+DOM_NamedNodeMap_item(const DOM_NamedNodeMap *map, int index)
+{
+ return DOM_NodeList_item(map, index);
+}
+
+
+/* Forward references
+ */
+
+void DOM_Document_destroyNamedNodeMap(DOM_Document *doc, DOM_NamedNodeMap *nnm, int free_nodes);
+void updateCommonParent(DOM_Node *node);
+
+/* Node
+ */
+
+void
+DOM_Document_destroyNode(DOM_Document *doc, DOM_Node *node)
+{
+ if (node == NULL) {
+ return;
+ }
+
+ if (node->childNodes) {
+ DOM_Document_destroyNodeList(doc, node->childNodes, 1);
+ }
+ if (node->listeners) {
+ unsigned int i;
+
+ for (i = 0; i < node->listeners_len; i++) {
+ if (node->listeners[i]) {
+ free(node->listeners[i]->type);
+ free(node->listeners[i]);
+ }
+ }
+ free(node->listeners);
+ }
+
+ switch(node->nodeType) {
+ case DOM_ELEMENT_NODE:
+ DOM_Document_destroyNamedNodeMap(doc, node->attributes, 1);
+ free(node->nodeName);
+ break;
+ case DOM_TEXT_NODE:
+ case DOM_COMMENT_NODE:
+ case DOM_CDATA_SECTION_NODE:
+ free(node->nodeValue);
+ break;
+ case DOM_ATTRIBUTE_NODE:
+ free(node->nodeName);
+ free(node->nodeValue);
+ break;
+ case DOM_ENTITY_REFERENCE_NODE:
+ case DOM_ENTITY_NODE:
+ free(node->nodeName);
+ free(node->nodeValue);
+ free(node->u.Entity.publicId);
+ free(node->u.Entity.systemId);
+ free(node->u.Entity.notationName);
+ break;
+ case DOM_PROCESSING_INSTRUCTION_NODE:
+ free(node->nodeName);
+ free(node->nodeValue);
+ break;
+ case DOM_DOCUMENT_NODE:
+ free(node->u.Document.version);
+ free(node->u.Document.encoding);
+ break;
+ case DOM_DOCUMENT_TYPE_NODE:
+ DOM_Document_destroyNamedNodeMap(doc, node->u.DocumentType.entities, 0);
+ DOM_Document_destroyNamedNodeMap(doc, node->u.DocumentType.notations, 0);
+ free(node->u.DocumentType.publicId);
+ free(node->u.DocumentType.systemId);
+ free(node->nodeName);
+ break;
+ case DOM_NOTATION_NODE:
+ free(node->nodeName);
+ free(node->u.Notation.publicId);
+ free(node->u.Notation.systemId);
+ break;
+ }
+ free(node);
+}
+DOM_Node *
+Document_createNode(DOM_Document *doc, unsigned short nodeType)
+{
+ DOM_Node *node;
+
+ msgno_add_codes(dom_codes);
+
+ if (doc == NULL && nodeType != DOM_DOCUMENT_NODE && nodeType != DOM_DOCUMENT_TYPE_NODE) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNF(DOM_Exception, ": doc=NULL,nodeType=%u", nodeType);
+ return NULL;
+ }
+
+ node = calloc(sizeof *node, 1);
+ if (node == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ node->nodeType = nodeType;
+ node->ownerDocument = doc;
+ switch (nodeType) {
+ case DOM_DOCUMENT_NODE:
+ case DOM_DOCUMENT_TYPE_NODE:
+ /* DocumentType doesn't really have children but we need to store DTD
+ * entries other than entities and notations */
+ case DOM_ELEMENT_NODE:
+ case DOM_ATTRIBUTE_NODE:
+ case DOM_ENTITY_REFERENCE_NODE:
+ case DOM_ENTITY_NODE:
+ case DOM_DOCUMENT_FRAGMENT_NODE:
+ node->childNodes = Document_createNodeList(doc);
+ if (node->childNodes == NULL) {
+ AMNO(DOM_CREATE_FAILED);
+ DOM_Document_destroyNode(doc, node);
+ return NULL;
+ }
+ }
+
+ return node;
+}
+
+static int
+_isAncestor(DOM_Node *node, DOM_Node *parent)
+{
+ DOM_Node *p;
+
+ for (p = parent; p; p = p->parentNode) {
+ if (p == node) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+dispatchEventPreorder(DOM_Node *node, DOM_MutationEvent *evt)
+{
+ DOM_Node *n;
+
+ DOM_EventTarget_dispatchEvent(node, evt);
+
+ for (n = node->firstChild; n != NULL; n = n->nextSibling) {
+ dispatchEventPreorder(n, evt);
+ }
+}
+static void
+dispatchEventPostorder(DOM_Node *node, DOM_MutationEvent *evt)
+{
+ DOM_Node *n;
+
+ for (n = node->firstChild; n != NULL; n = n->nextSibling) {
+ dispatchEventPostorder(n, evt);
+ }
+
+ DOM_EventTarget_dispatchEvent(node, evt);
+}
+static DOM_Node *
+_removeChild(DOM_Node *node, DOM_Node *oldChild)
+{
+ NodeEntry *e;
+ DOM_MutationEvent evt;
+
+ if (NodeList_exists(node->childNodes, oldChild) == 0) {
+ return NULL;
+ }
+
+ DOM_MutationEvent_initMutationEvent(&evt,
+ "DOMNodeRemoved", 1, 0, node, NULL, NULL, NULL, 0);
+ DOM_EventTarget_dispatchEvent(oldChild, &evt);
+
+ DOM_MutationEvent_initMutationEvent(&evt,
+ "DOMNodeRemovedFromDocument", 0, 0, NULL, NULL, NULL, NULL, 0);
+ dispatchEventPostorder(oldChild, &evt);
+
+ e = NodeList_remove(node->childNodes, oldChild);
+ free(e);
+
+ if (node->firstChild == node->lastChild) {
+ node->firstChild = node->lastChild = NULL;
+ } else if (oldChild == node->firstChild) {
+ node->firstChild = oldChild->nextSibling;
+ node->firstChild->previousSibling = NULL;
+ } else if (oldChild == node->lastChild) {
+ node->lastChild = oldChild->previousSibling;
+ node->lastChild->nextSibling = NULL;
+ } else {
+ oldChild->previousSibling->nextSibling = oldChild->nextSibling;
+ oldChild->nextSibling->previousSibling = oldChild->previousSibling;
+ }
+
+ oldChild->previousSibling = NULL;
+ oldChild->nextSibling = NULL;
+ oldChild->parentNode = NULL;
+
+ if (MODIFYING_DOC_ELEM(node, oldChild)) {
+ node->u.Document.documentElement = NULL;
+ } else if (MODIFYING_DOCTYPE_ELEM(node, oldChild)) {
+ node->u.Document.doctype = NULL;
+ oldChild->ownerDocument = NULL;
+ } else {
+ updateCommonParent(node);
+ }
+
+ return oldChild;
+}
+DOM_Node *
+DOM_Node_insertBefore(DOM_Node *node, DOM_Node *newChild, DOM_Node *refChild)
+{
+ NodeEntry *e;
+ DOM_MutationEvent evt;
+
+ if (node == NULL || newChild == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (newChild->ownerDocument != node->ownerDocument &&
+ newChild->ownerDocument != node) {
+ DOM_Exception = DOM_WRONG_DOCUMENT_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (refChild != NULL && refChild->parentNode != node) {
+ DOM_Exception = DOM_HIERARCHY_REQUEST_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ if (newChild->nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
+ DOM_Node *n, *nxt;
+
+ for (n = newChild->firstChild; n != NULL; n = n->nextSibling) {
+ if (INVALID_HIER_REQ(node, n) || _isAncestor(n, node)) {
+ DOM_Exception = DOM_HIERARCHY_REQUEST_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ }
+ for (n = newChild->firstChild; n != NULL; n = nxt) {
+ nxt = n->nextSibling;
+ if (_removeChild(newChild, n) == NULL) {
+ return NULL;
+ }
+ if (DOM_Node_insertBefore(node, n, refChild) == NULL) {
+ DOM_Document_destroyNode(n->ownerDocument, n);
+ return NULL;
+ }
+ }
+ return newChild;
+ }
+ if (INVALID_HIER_REQ(node, newChild) || _isAncestor(newChild, node)) {
+ DOM_Exception = DOM_HIERARCHY_REQUEST_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ _removeChild(node, newChild);
+
+ if ((e = NodeList_insert(node->childNodes, newChild, refChild)) == NULL) {
+ return NULL;
+ }
+
+ if (node->firstChild == NULL) {
+ node->firstChild = node->lastChild = newChild;
+ newChild->previousSibling = NULL;
+ newChild->nextSibling = NULL;
+ } else if (refChild == NULL) {
+ newChild->previousSibling = node->lastChild;
+ node->lastChild->nextSibling = newChild;
+ node->lastChild = newChild;
+ newChild->nextSibling = NULL;
+ } else {
+ newChild->previousSibling = refChild->previousSibling;
+ newChild->nextSibling = refChild;
+ if (refChild == node->firstChild) {
+ node->firstChild = newChild;
+ newChild->previousSibling = NULL;
+ } else {
+ refChild->previousSibling->nextSibling = newChild;
+ }
+ refChild->previousSibling = newChild;
+ }
+ newChild->parentNode = node;
+
+ if (MODIFYING_DOC_ELEM(node, newChild)) {
+ node->u.Document.documentElement = newChild;
+ } else if (MODIFYING_DOCTYPE_ELEM(node, newChild)) {
+ node->u.Document.doctype = newChild;
+ newChild->ownerDocument = node;
+ }
+
+ DOM_MutationEvent_initMutationEvent(&evt,
+ "DOMNodeInserted", 1, 0, node, NULL, NULL, NULL, 0);
+ DOM_EventTarget_dispatchEvent(newChild, &evt);
+
+ DOM_MutationEvent_initMutationEvent(&evt,
+ "DOMNodeInsertedIntoDocument", 0, 0, NULL, NULL, NULL, NULL, 0);
+ dispatchEventPreorder(newChild, &evt);
+
+ updateCommonParent(node);
+
+ return newChild;
+}
+DOM_Node *
+DOM_Node_replaceChild(DOM_Node *node, DOM_Node *newChild, DOM_Node *oldChild)
+{
+ DOM_MutationEvent evt;
+
+ if (node == NULL || newChild == NULL || oldChild == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (newChild->ownerDocument != node->ownerDocument &&
+ newChild->ownerDocument != node) {
+ DOM_Exception = DOM_WRONG_DOCUMENT_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ if (!NodeList_exists(node->childNodes, oldChild)) {
+ DOM_Exception = DOM_NOT_FOUND_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ if (newChild->nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
+ DOM_Node *n, *nxt;
+
+ for (n = newChild->firstChild; n != NULL; n = n->nextSibling) {
+ if (INVALID_HIER_REQ(node, n) || _isAncestor(n, node)) {
+ DOM_Exception = DOM_HIERARCHY_REQUEST_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ }
+ for (n = newChild->firstChild; n != NULL; n = nxt) {
+ nxt = n->nextSibling;
+ if (_removeChild(newChild, n) == NULL) {
+ return NULL;
+ }
+ if (DOM_Node_insertBefore(node, n, oldChild) == NULL) {
+ DOM_Document_destroyNode(n->ownerDocument, n);
+ return NULL;
+ }
+ }
+
+ if (_removeChild(node, oldChild) == NULL) {
+ return NULL;
+ }
+
+ return oldChild;
+ }
+ if (INVALID_HIER_REQ(node, newChild) || _isAncestor(newChild, node)) {
+ DOM_Exception = DOM_HIERARCHY_REQUEST_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ _removeChild(node, newChild);
+
+ if (NodeList_exists(node->childNodes, oldChild) == 0) {
+ return NULL;
+ }
+
+ DOM_MutationEvent_initMutationEvent(&evt,
+ "DOMNodeRemoved", 1, 0, node, NULL, NULL, NULL, 0);
+ DOM_EventTarget_dispatchEvent(oldChild, &evt);
+
+ DOM_MutationEvent_initMutationEvent(&evt,
+ "DOMNodeRemovedFromDocument", 0, 0, NULL, NULL, NULL, NULL, 0);
+ dispatchEventPostorder(oldChild, &evt);
+
+ NodeList_replace(node->childNodes, newChild, oldChild);
+
+ node->firstChild = node->childNodes->first->node;
+ node->lastChild = node->childNodes->last->node;
+
+ if ((newChild->previousSibling = oldChild->previousSibling)) {
+ newChild->previousSibling->nextSibling = newChild;
+ }
+ if ((newChild->nextSibling = oldChild->nextSibling)) {
+ newChild->nextSibling->previousSibling = newChild;
+ }
+
+ newChild->parentNode = node;
+ oldChild->parentNode = NULL;
+ oldChild->previousSibling = NULL;
+ oldChild->nextSibling = NULL;
+
+ if (MODIFYING_DOC_ELEM(node, newChild)) {
+ node->u.Document.documentElement = newChild;
+ } else if (MODIFYING_DOCTYPE_ELEM(node, newChild)) {
+ node->u.Document.doctype = newChild;
+ newChild->ownerDocument = node;
+ }
+
+ DOM_MutationEvent_initMutationEvent(&evt,
+ "DOMNodeInserted", 1, 0, node, NULL, NULL, NULL, 0);
+ DOM_EventTarget_dispatchEvent(newChild, &evt);
+
+ DOM_MutationEvent_initMutationEvent(&evt,
+ "DOMNodeInsertedIntoDocument", 0, 0, NULL, NULL, NULL, NULL, 0);
+ dispatchEventPreorder(newChild, &evt);
+
+ updateCommonParent(node);
+
+ return oldChild;
+}
+DOM_Node *
+DOM_Node_removeChild(DOM_Node *node, DOM_Node *oldChild)
+{
+ if (node == NULL || oldChild == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (oldChild->ownerDocument != node->ownerDocument &&
+ oldChild->ownerDocument != node) {
+ DOM_Exception = DOM_WRONG_DOCUMENT_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ if ((oldChild = _removeChild(node, oldChild)) == NULL) {
+ DOM_Exception = DOM_NOT_FOUND_ERR;
+ PMNO(DOM_Exception);
+ }
+
+ return oldChild;
+}
+DOM_Node *
+DOM_Node_appendChild(DOM_Node *node, DOM_Node *newChild)
+{
+ DOM_MutationEvent evt;
+
+ if (node == NULL || newChild == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (newChild->ownerDocument != node->ownerDocument &&
+ node->nodeType != DOM_DOCUMENT_NODE &&
+ newChild->nodeType != DOM_DOCUMENT_TYPE_NODE) {
+ DOM_Exception = DOM_WRONG_DOCUMENT_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ if (newChild->nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
+ DOM_Node *n, *nxt;
+
+ for (n = newChild->firstChild; n != NULL; n = n->nextSibling) {
+ if (INVALID_HIER_REQ(node, n) || _isAncestor(n, node)) {
+ DOM_Exception = DOM_HIERARCHY_REQUEST_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ }
+ for (n = newChild->firstChild; n != NULL; n = nxt) {
+ nxt = n->nextSibling;
+ if (_removeChild(newChild, n) == NULL) {
+ return NULL;
+ }
+ if (DOM_Node_appendChild(node, n) == NULL) {
+ DOM_Document_destroyNode(n->ownerDocument, n);
+ return NULL;
+ }
+ }
+ return newChild;
+ }
+ if (INVALID_HIER_REQ(node, newChild) || _isAncestor(newChild, node)) {
+ DOM_Exception = DOM_HIERARCHY_REQUEST_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ _removeChild(node, newChild);
+
+ if (NodeList_append(node->childNodes, newChild) == NULL) {
+ return NULL;
+ }
+
+ if (node->firstChild == NULL) {
+ node->firstChild = node->lastChild = newChild;
+ newChild->previousSibling = NULL;
+ newChild->nextSibling = NULL;
+ } else {
+ node->lastChild->nextSibling = newChild;
+ newChild->previousSibling = node->lastChild;
+ node->lastChild = newChild;
+ }
+ newChild->nextSibling = NULL;
+ newChild->parentNode = node;
+
+ if (MODIFYING_DOC_ELEM(node, newChild)) {
+ node->u.Document.documentElement = newChild;
+ } else if (MODIFYING_DOCTYPE_ELEM(node, newChild)) {
+ node->u.Document.doctype = newChild;
+ newChild->ownerDocument = node;
+ }
+
+ DOM_MutationEvent_initMutationEvent(&evt,
+ "DOMNodeInserted", 1, 0, node, NULL, NULL, NULL, 0);
+ DOM_EventTarget_dispatchEvent(newChild, &evt);
+
+ DOM_MutationEvent_initMutationEvent(&evt,
+ "DOMNodeInsertedIntoDocument", 0, 0, NULL, NULL, NULL, NULL, 0);
+ dispatchEventPreorder(newChild, &evt);
+
+ updateCommonParent(node);
+
+ return newChild;
+}
+int
+DOM_Node_hasChildNodes(const DOM_Node *node)
+{
+ return node != NULL && node->firstChild;
+}
+extern const char *node_names[];
+static DOM_Node *
+Node_cloneNode(DOM_Document *ownerDocument, DOM_Node *node, int deep)
+{
+ DOM_Node *clone = NULL;
+ DOM_Node *ntmp, *ctmp;
+ NodeEntry *e;
+ DOM_String *tmp;
+
+ switch(node->nodeType) {
+ case DOM_ELEMENT_NODE:
+ clone = DOM_Document_createElement(ownerDocument, node->nodeName);
+ if (clone) {
+ for (e = node->attributes->first; e != NULL; e = e->next) {
+ if ((ctmp = Node_cloneNode(ownerDocument, e->node, deep)) == NULL ||
+ NodeList_append(clone->attributes, ctmp) == NULL) {
+ DOM_Document_destroyNode(clone->ownerDocument, ctmp);
+ DOM_Document_destroyNode(clone->ownerDocument, clone);
+ return NULL;
+ }
+ }
+ }
+ break;
+ case DOM_ATTRIBUTE_NODE:
+ if ((clone = DOM_Document_createAttribute(ownerDocument, node->nodeName))) {
+ clone->u.Attr.specified = node->u.Attr.specified;
+ free(clone->nodeValue);
+ clone->u.Attr.value = clone->nodeValue = mbsdup(node->nodeValue);
+ if (clone->u.Attr.value == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(clone->ownerDocument, clone);
+ return NULL;
+ }
+ }
+ break;
+ case DOM_COMMENT_NODE:
+ clone = DOM_Document_createComment(ownerDocument, node->nodeValue);
+ break;
+ case DOM_TEXT_NODE:
+ clone = DOM_Document_createTextNode(ownerDocument, node->nodeValue);
+ break;
+ case DOM_CDATA_SECTION_NODE:
+ clone = DOM_Document_createCDATASection(ownerDocument, node->nodeValue);
+ break;
+ case DOM_DOCUMENT_FRAGMENT_NODE:
+ clone = DOM_Document_createDocumentFragment(ownerDocument);
+ break;
+ case DOM_DOCUMENT_NODE:
+ clone = ownerDocument;
+ break;
+ case DOM_PROCESSING_INSTRUCTION_NODE:
+ clone = DOM_Document_createProcessingInstruction(ownerDocument,
+ node->u.ProcessingInstruction.target,
+ node->u.ProcessingInstruction.data);
+ break;
+ case DOM_ENTITY_NODE:
+ if ((clone = Document_createNode(ownerDocument, DOM_ENTITY_NODE))) {
+ tmp = node->nodeValue;
+ if ((clone->nodeName = mbsdup(node->nodeName)) == NULL ||
+ /* This will eventually go away as Entities should not have nodeValues
+ */
+ (clone->nodeValue = mbsdup(node->nodeValue)) == NULL ||
+ (node->u.Entity.publicId &&
+ (clone->u.Entity.publicId = mbsdup(node->u.Entity.publicId)) == NULL) ||
+ (node->u.Entity.systemId &&
+ (clone->u.Entity.systemId = mbsdup(node->u.Entity.systemId)) == NULL) ||
+ (node->u.Entity.notationName &&
+ (clone->u.Entity.notationName = mbsdup(node->u.Entity.notationName)) == NULL)) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(clone->ownerDocument, clone);
+ return NULL;
+ }
+ free(tmp);
+ }
+ break;
+ case DOM_NOTATION_NODE:
+ if ((clone = Document_createNode(ownerDocument, DOM_NOTATION_NODE))) {
+ if ((clone->nodeName = mbsdup(node->nodeName)) == NULL ||
+ (node->u.Notation.publicId &&
+ (clone->u.Notation.publicId = mbsdup(node->u.Notation.publicId)) == NULL) ||
+ (node->u.Notation.systemId &&
+ (clone->u.Notation.systemId = mbsdup(node->u.Notation.systemId)) == NULL)) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(clone->ownerDocument, clone);
+ return NULL;
+ }
+ }
+ break;
+ case DOM_DOCUMENT_TYPE_NODE:
+ if ((clone = DOM_Implementation_createDocumentType(node->nodeName, NULL, NULL))) {
+ if ((node->u.DocumentType.publicId &&
+ (clone->u.DocumentType.publicId = mbsdup(node->u.DocumentType.publicId)) == NULL) ||
+ (node->u.DocumentType.systemId &&
+ (clone->u.DocumentType.systemId = mbsdup(node->u.DocumentType.systemId)) == NULL)) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ DOM_Document_destroyNode(clone->ownerDocument, clone);
+ return NULL;
+ }
+ }
+ ownerDocument->u.Document.doctype = clone;
+ clone->ownerDocument = ownerDocument;
+ break;
+ case DOM_ENTITY_REFERENCE_NODE:
+ DOM_Exception = DOM_NOT_SUPPORTED_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ if (deep && clone && node->childNodes) {
+ for (ntmp = node->firstChild; ntmp != NULL; ntmp = ntmp->nextSibling) {
+ ctmp = Node_cloneNode(ownerDocument, ntmp, 1);
+ if (ctmp == NULL || DOM_Node_appendChild(clone, ctmp) == NULL) {
+ DOM_Document_destroyNode(clone->ownerDocument, ctmp);
+ DOM_Document_destroyNode(clone->ownerDocument, clone);
+ return NULL;
+ }
+ }
+ }
+
+ return clone;
+}
+DOM_Node *
+DOM_Node_cloneNode(DOM_Node *node, int deep)
+{
+ if (node == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (node->nodeType == DOM_DOCUMENT_NODE) {
+ DOM_Document *doc;
+ if ((doc = DOM_Implementation_createDocument(NULL, NULL, NULL)) == NULL) {
+ AMSG("");
+ return NULL;
+ }
+ return Node_cloneNode(doc, node, deep);
+ }
+ return Node_cloneNode(node->ownerDocument, node, deep);
+}
+DOM_String *
+DOM_Node_getNodeValue(DOM_Node *node)
+{
+ if (node == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ return node->nodeValue;
+}
+void
+DOM_Node_setNodeValue(DOM_Node *node, DOM_String *value)
+{
+ DOM_String *str = NULL;
+
+ if (node == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return;
+ }
+ switch(node->nodeType) {
+ case DOM_ATTRIBUTE_NODE:
+ case DOM_COMMENT_NODE:
+ case DOM_TEXT_NODE:
+ case DOM_CDATA_SECTION_NODE:
+ case DOM_PROCESSING_INSTRUCTION_NODE:
+ if ((str = mbsdup(value)) == NULL) {
+ DOM_Exception = errno;
+ AMSG("");
+ return;
+ }
+ break;
+ }
+ switch(node->nodeType) {
+ case DOM_ATTRIBUTE_NODE:
+ free(node->nodeValue);
+ node->nodeValue = node->u.Attr.value = str;
+ break;
+ case DOM_COMMENT_NODE:
+ case DOM_TEXT_NODE:
+ case DOM_CDATA_SECTION_NODE:
+ free(node->nodeValue);
+ node->nodeValue = node->u.CharacterData.data = str;
+ break;
+ case DOM_PROCESSING_INSTRUCTION_NODE:
+ free(node->nodeValue);
+ node->nodeValue = node->u.ProcessingInstruction.data = str;
+ break;
+ default:
+ return; /* No effect */
+ }
+}
+
+
+#if FAST_NODELIST
+
+/* The number of nodes required in a list before hashing starts */
+#define FAST_FILLFACTOR 16
+
+static void _removeFromMap(DOM_NodeList* nl, DOM_Node* key)
+{
+ if (nl->_map) {
+ if (hashmap_get(nl->_map, key) != NULL) {
+ void* d = NULL;
+ void* k = key;
+ hashmap_remove(nl->_map, &k, &d);
+ }
+ }
+}
+
+static int _addToMap(DOM_NodeList* nl, DOM_Node* key, NodeEntry* val)
+{
+ if (!nl->_map && nl->length > FAST_FILLFACTOR) {
+
+ nl->_map = hashmap_new(0, NULL, NULL, NULL);
+
+ /* Hash what we currently have */
+ if (nl->_map) {
+ NodeEntry *e = nl->first;
+ while (e) {
+ _addToMap(nl, e->node, e);
+ e = e->next;
+ }
+ }
+ }
+
+ if (nl->_map) {
+ _removeFromMap(nl, key);
+
+ if (hashmap_put(nl->_map, key, val) == -1) {
+ DOM_Exception = errno;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#endif
+
+static NodeEntry* _lookupNode(DOM_NodeList* nl, DOM_Node* node)
+{
+ NodeEntry* s;
+
+#if FAST_NODELIST
+ if (nl->_map)
+ s = (NodeEntry*)hashmap_get(nl->_map, node);
+ else
+#endif
+ for (s = nl->first; s != NULL && s->node != node; s = s->next) {
+ ;
+ }
+
+ return s;
+}
+
+/* NodeList
+ */
+
+DOM_NodeList *
+Document_createNodeList(DOM_Document *doc)
+{
+ DOM_NodeList *r;
+
+ if ((r = calloc(sizeof *r, 1)) == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ }
+ r->_ownerDocument = doc;
+
+ return r;
+}
+void
+DOM_Document_destroyNodeList(DOM_Document *doc, DOM_NodeList *nl, int free_nodes)
+{
+ if (nl) {
+ if (nl->filter == 0) {
+ NodeEntry *e, *tmp;
+
+ e = nl->first;
+ while (e != NULL) {
+ if (free_nodes) {
+ DOM_Document_destroyNode(doc, e->node);
+ }
+ tmp = e;
+ e = e->next;
+ free(tmp);
+ }
+ }
+
+#if FAST_NODELIST
+ if(nl->_map)
+ hashmap_del(nl->_map, NULL, NULL, NULL);
+#endif
+
+ free(nl);
+ }
+}
+
+DOM_Node *
+NodeList_itemFiltered(const DOM_NodeList *list, int index, unsigned short nodeType)
+{
+ if (list && index >= 0 && index < list->length) {
+ NodeEntry *e;
+
+ for (e = list->first; e != NULL; e = e->next) {
+ if (e->node->nodeType == nodeType) {
+ if (index == 0) {
+ return e->node;
+ }
+ index--;
+ }
+ }
+ }
+
+ return NULL;
+}
+DOM_Node *
+DOM_NodeList_item(const DOM_NodeList *list, int index)
+{
+ if (list) {
+ if (list->filter) {
+ return NodeList_itemFiltered(list->list, index, list->filter);
+ }
+
+ if (index >= 0 && index < list->length) {
+ NodeEntry *e;
+
+ for (e = list->first; e != NULL; e = e->next, index--) {
+ if (index == 0) {
+ return e->node;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+NodeEntry *
+NodeList_insert(DOM_NodeList *nl, DOM_Node *newChild, DOM_Node *refChild)
+{
+ NodeEntry *e;
+ NodeEntry *s = NULL;
+
+ if (nl == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (nl->filter) {
+ DOM_Exception = DOM_FILTERED_LIST_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ if(refChild != NULL)
+ {
+ s = _lookupNode(nl, refChild);
+ if(s == NULL || s->node != refChild) {
+ DOM_Exception = DOM_NOT_FOUND_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ }
+
+ if ((e = calloc(sizeof *e, 1)) == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+#if FAST_NODELIST
+ if (_addToMap(nl, newChild, e) == -1) {
+ PMNO(DOM_Exception);
+ free(e);
+ return NULL;
+ }
+#endif
+
+ e->node = newChild;
+ if (nl->length == 0) {
+ nl->first = nl->last = e;
+ } else if (refChild == NULL) {
+ e->prev = nl->last;
+ nl->last->next = e;
+ nl->last = e;
+ } else {
+ e->prev = s->prev;
+ e->next = s;
+ if (s == nl->first) {
+ nl->first = e;
+ } else {
+ s->prev->next = e;
+ }
+ s->prev = e;
+ }
+ nl->length++;
+
+ /* If an attribute is being added this is probably a NamedNodeMap
+ * in which case we must set the ownerElement.
+ */
+ if (newChild->nodeType == DOM_ATTRIBUTE_NODE) {
+ newChild->u.Attr.ownerElement = nl->_ownerElement;
+ }
+
+ return e;
+}
+NodeEntry *
+NodeList_replace(DOM_NodeList *nl, DOM_Node *newChild, DOM_Node *oldChild)
+{
+ NodeEntry *e;
+
+ if (nl == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (nl->filter) {
+ DOM_Exception = DOM_FILTERED_LIST_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ e = _lookupNode(nl, oldChild);
+ if (e == NULL) {
+ DOM_Exception = DOM_NOT_FOUND_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+#if FAST_NODELIST
+ _removeFromMap(nl, oldChild);
+ if(_addToMap(nl, newChild, e) == -1) {
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+#endif
+
+ e->node = newChild;
+
+ if (oldChild->nodeType == DOM_ATTRIBUTE_NODE) {
+ oldChild->u.Attr.ownerElement = NULL;
+ }
+
+ return e;
+}
+NodeEntry *
+NodeList_remove(DOM_NodeList *nl, DOM_Node *oldChild)
+{
+ NodeEntry *e;
+
+ if (nl == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (nl->filter) {
+ DOM_Exception = DOM_FILTERED_LIST_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ e = _lookupNode(nl, oldChild);
+ if (e == NULL) {
+ return NULL;
+ }
+
+#if FAST_NODELIST
+ _removeFromMap(nl, oldChild);
+#endif
+
+ if (nl->first == nl->last) {
+ nl->first = nl->last = NULL;
+ } else if (e == nl->first) {
+ nl->first = e->next;
+ nl->first->prev = NULL;
+ } else if (e == nl->last) {
+ nl->last = e->prev;
+ nl->last->next = NULL;
+ } else {
+ e->prev->next = e->next;
+ e->next->prev = e->prev;
+ }
+ nl->length--;
+
+ /* Decrement a filtered node list too? */
+
+ if (oldChild->nodeType == DOM_ATTRIBUTE_NODE) {
+ oldChild->u.Attr.ownerElement = NULL;
+ }
+
+ return e;
+}
+extern const char *node_names[];
+NodeEntry *
+NodeList_append(DOM_NodeList *nl, DOM_Node *newChild)
+{
+ NodeEntry *e;
+ DOM_DocumentType *doctype;
+
+ if (nl == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNF(DOM_Exception, ": %p", newChild);
+ return NULL;
+ }
+ if (nl->filter) {
+ DOM_Exception = DOM_FILTERED_LIST_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+ if ((e = calloc(sizeof *e, 1)) == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+
+#if FAST_NODELIST
+ if(_addToMap(nl, newChild, e) == -1) {
+ PMNO(DOM_Exception);
+ free(e);
+ return NULL;
+ }
+#endif
+
+ e->node = newChild;
+ if (nl->first == NULL) {
+ nl->first = nl->last = e;
+ } else {
+ nl->last->next = e;
+ e->prev = nl->last;
+ nl->last = e;
+ }
+
+ nl->length++;
+
+ /* If the node list is the DocumentType children and a Notation
+ * or Entity is being added we must artificially update the length
+ * member of those filtered lists
+ */
+ if (newChild->ownerDocument &&
+ (doctype = newChild->ownerDocument->u.Document.doctype) &&
+ nl == doctype->childNodes) {
+ if (newChild->nodeType == DOM_NOTATION_NODE) {
+ doctype->u.DocumentType.notations->length++;
+ } else if (newChild->nodeType == DOM_ENTITY_NODE) {
+ doctype->u.DocumentType.entities->length++;
+ }
+ }
+ /* If an attribute is being added this is probably a NamedNodeMap
+ * in which case we must set the ownerElement.
+ */
+ if (newChild->nodeType == DOM_ATTRIBUTE_NODE) {
+ newChild->u.Attr.ownerElement = nl->_ownerElement;
+ }
+
+ return e;
+}
+int
+NodeList_exists(DOM_NodeList *nl, DOM_Node *child)
+{
+ NodeEntry *e;
+
+ if (nl == NULL || nl->filter) {
+ return 0;
+ }
+
+ e = _lookupNode(nl, child);
+ return e != NULL;
+}
+
+#if HAVE_ENCDEC > 0
+#include <encdec.h>
+#elif HAVE_STRNLEN < 1
+
+static size_t
+strnlen(const char *s, size_t maxlen)
+{
+ size_t len;
+ for (len = 0; *s && len < maxlen; s++, len++);
+ return len;
+}
+
+#else
+
+size_t strnlen(const char *s, size_t maxlen);
+
+#endif
+
+/* Forward references for node.c
+ */
+
+DOM_Node *Document_createNode(DOM_Document *doc, unsigned short nodeType);
+
+static int
+fputds(const DOM_String *s, FILE *stream)
+{
+ return fputs(s, stream);
+}
+
+static void
+fputds_encoded(const DOM_String *s, FILE *stream)
+{
+ size_t l;
+
+ while (*s) {
+ l = strcspn(s, "<>&\"");
+ if (l > 0) {
+ fwrite((void*)s, 1, sizeof(DOM_String) * l, stream);
+ s += l;
+ }
+ switch (*s) {
+ case '\0':
+ break;
+ case '<':
+ fputs("&lt;", stream);
+ break;
+ case '>':
+ fputs("&gt;", stream);
+ break;
+ case '&':
+ fputs("&apos;", stream);
+ break;
+ case '"':
+ fputs("&quot;", stream);
+ break;
+ default:
+ AMSG("");
+ break;
+ };
+ if(*s)
+ ++s;
+ }
+}
+
+int
+DOM_DocumentLS_fwrite(const DOM_DocumentLS *node, FILE *stream)
+{
+ NodeEntry *e;
+ DOM_Node *c;
+
+ if (node == NULL || stream == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNF(DOM_Exception, ": node=%p,stream=%p", node, stream);
+ return -1;
+ }
+
+ if (DOM_Exception) {
+ return -1;
+ }
+
+ switch (node->nodeType) {
+ case DOM_ELEMENT_NODE:
+ fputc('<', stream);
+ fputds(node->nodeName, stream);
+ for (e = node->attributes->first; e != NULL; e = e->next) {
+ fputc(' ', stream);
+ fputds(e->node->nodeName, stream);
+ fputs("=\"", stream);
+ fputds_encoded(e->node->nodeValue, stream);
+ fputc('"', stream);
+ }
+ if (DOM_Node_hasChildNodes(node)) {
+ fputc('>', stream);
+ for (c = node->firstChild; c != NULL; c = c->nextSibling) {
+ if (DOM_DocumentLS_fwrite(c, stream) == -1) {
+ /* Don't put msgno macro here or might overrun buf */
+ return -1;
+ }
+ }
+ fputs("</", stream);
+ fputds(node->nodeName, stream);
+ fputc('>', stream);
+ } else {
+ fputs("/>", stream);
+ }
+ break;
+ case DOM_ATTRIBUTE_NODE:
+ break;
+ case DOM_TEXT_NODE:
+ fputds_encoded(node->nodeValue, stream);
+ break;
+ case DOM_CDATA_SECTION_NODE:
+ break;
+ case DOM_ENTITY_REFERENCE_NODE:
+ break;
+ case DOM_NOTATION_NODE:
+ fputs(" <!NOTATION ", stream);
+ fputds(node->nodeName, stream);
+ if (node->u.Entity.publicId) {
+ fputs(" PUBLIC \"", stream);
+ fputds(node->u.Entity.publicId, stream);
+ fputs("\" \"", stream);
+ fputds(node->u.Entity.systemId, stream);
+ fputc('"', stream);
+ } else if (node->u.Entity.systemId) {
+ fputs(" SYSTEM \"", stream);
+ fputds(node->u.Entity.systemId, stream);
+ fputc('"', stream);
+ }
+ fputs(">", stream);
+ break;
+ case DOM_ENTITY_NODE:
+ fputs(" <!ENTITY ", stream);
+ fputds(node->nodeName, stream);
+ if (node->nodeValue) {
+ fputc('"', stream);
+ fputds(node->nodeValue, stream);
+ fputc('"', stream);
+ } else {
+ if (node->u.Entity.publicId) {
+ fputs(" PUBLIC \"", stream);
+ fputds(node->u.Entity.publicId, stream);
+ fputs("\" \"", stream);
+ fputds(node->u.Entity.systemId, stream);
+ fputc('"', stream);
+ } else if (node->u.Entity.systemId) {
+ fputs(" SYSTEM \"", stream);
+ fputds(node->u.Entity.systemId, stream);
+ fputc('"', stream);
+ }
+ if (node->u.Entity.notationName) {
+ fputs(" NDATA ", stream);
+ fputds(node->u.Entity.notationName, stream);
+ }
+ }
+ fputs(">", stream);
+ break;
+ case DOM_PROCESSING_INSTRUCTION_NODE:
+ fputs("<?", stream);
+ fputds(node->u.ProcessingInstruction.target, stream);
+ fputc(' ', stream);
+ fputds_encoded(node->u.ProcessingInstruction.data, stream);
+ fputs("?>", stream);
+ break;
+ case DOM_COMMENT_NODE:
+ fputs("<!--", stream);
+ fputds_encoded(node->nodeValue, stream);
+ fputs("-->", stream);
+ break;
+ case DOM_DOCUMENT_NODE:
+ fputs("<?xml", stream);
+ fputs(" version=\"", stream);
+ fputds(node->u.Document.version ? node->u.Document.version : "1.0", stream);
+ fputc('\"', stream);
+#ifdef CODESET
+ fputs(" encoding=\"", stream);
+ fputs(nl_langinfo(CODESET), stream);
+ fputc('\"', stream);
+#endif
+ if (node->u.Document.standalone != 0) {
+ fputs(" standalone=\"yes\"", stream);
+ }
+ fputs("?>"NL, stream);
+ for (c = node->firstChild; c != NULL; c = c->nextSibling) {
+ if (DOM_DocumentLS_fwrite(c, stream) == -1) {
+ AMSG("");
+ return -1;
+ }
+ }
+ fputs(NL, stream);
+ break;
+ case DOM_DOCUMENT_TYPE_NODE:
+ fputs(NL"<!DOCTYPE ", stream);
+ fputs(node->u.DocumentType.name, stream);
+ if (node->u.DocumentType.systemId) {
+ fputs(" SYSTEM \"", stream);
+ fputds(node->u.DocumentType.systemId, stream);
+ fputc('"', stream);
+ } else if (node->u.DocumentType.publicId) {
+ fputs(" PUBLIC \"", stream);
+ fputds(node->u.DocumentType.publicId, stream);
+ fputc('"', stream);
+ }
+ if (node->u.DocumentType.internalSubset) {
+ fputs(" ["NL, stream);
+ fputds(node->u.DocumentType.internalSubset, stream);
+ fputs("]>"NL, stream);
+ } else {
+ fputs(">"NL, stream);
+ }
+ break;
+ case DOM_DOCUMENT_FRAGMENT_NODE:
+ break;
+ }
+
+ return DOM_Exception ? -1 : 0;
+}
+int
+DOM_DocumentLS_save(DOM_DocumentLS *doc, const char *uri, const DOM_Node *node)
+{
+ FILE *fd;
+
+ if ((doc == NULL && node == NULL) || uri == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNF(DOM_Exception, ": doc=%p,uri=%s,node=%p", doc, uri, node);
+ return -1;
+ }
+
+ fd = fopen(uri, "w");
+ if (fd && DOM_DocumentLS_fwrite(doc ? doc : node, fd) == 0) {
+ fclose(fd);
+ return 0;
+ }
+ DOM_Exception = errno;
+ PMNF(DOM_Exception, ": uri=%s", uri);
+
+ return -1;
+}
+
+
+/* DOM_DocumentEvent - Introduced in DOM Level 2
+ */
+
+void
+DOM_DocumentEvent_destroyEvent(DOM_DocumentEvent *doc, DOM_Event *evt)
+{
+ if (doc && evt) {
+ if (evt->type) {
+ /*free(evt->type); */
+ }
+ free(evt);
+ }
+}
+
+DOM_Event *
+DOM_DocumentEvent_createEvent(DOM_DocumentEvent *doc, const DOM_String *eventType)
+{
+ DOM_Event *evt;
+
+ if (doc == NULL || eventType == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ if (strcmp(eventType, "Events") == 0 ||
+ strcmp(eventType, "UIEvents") == 0 ||
+ strcmp(eventType, "TextEvents") == 0) {
+ evt = calloc(sizeof *evt, 1);
+ if (evt == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ } else {
+ DOM_Exception = DOM_NOT_SUPPORTED_ERR;
+ PMNO(DOM_Exception);
+ return NULL;
+ }
+ return evt;
+}
+
+/* DOM_Event - Introduced in DOM Level 2
+ */
+
+void
+DOM_Event_stopPropagation(DOM_Event *evt)
+{
+ if (evt) {
+ evt->_sp = 1;
+ }
+}
+void
+DOM_Event_preventDefault(DOM_Event *evt)
+{
+ if (evt && evt->cancelable) {
+ evt->_pd = 1;
+ }
+}
+void
+DOM_Event_initEvent(DOM_Event *evt, const DOM_String *eventTypeArg,
+ int canBubbleArg, int cancelableArg)
+{
+ if (evt == NULL || eventTypeArg == NULL || *eventTypeArg == '\0') {
+ return;
+ }
+ evt->type = eventTypeArg; /* no dup? */
+ evt->bubbles = canBubbleArg;
+ evt->cancelable = cancelableArg;
+}
+
+/* DOM_UIEvent
+ */
+
+void
+DOM_UIEvent_initUIEvent(DOM_UIEvent *evt, const DOM_String *typeArg,
+ int canBubbleArg, int cancelableArg,
+ DOM_AbstractView *viewArg, long detailArg)
+{
+ if (evt == NULL || typeArg == NULL || *typeArg == '\0') {
+ return;
+ }
+ DOM_Event_initEvent(evt, typeArg, canBubbleArg, cancelableArg);
+ evt->view = viewArg;
+ evt->detail = detailArg;
+}
+
+/* DOM_EventTarget - Introduced in DOM Level 2
+ */
+
+void
+DOM_EventTarget_addEventListener(DOM_EventTarget *target, const DOM_String *type,
+ DOM_EventListener *listener,
+ DOM_EventListener_handleEvent listener_fn,
+ int useCapture)
+{
+ ListenerEntry *e;
+ unsigned int i;
+ int opos = -1;
+
+ if (target == NULL || type == NULL || listener_fn == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return;
+ }
+
+ for (i = 0; i < target->listeners_len; i++) {
+ e = target->listeners[i]; /* skip duplicates */
+
+ if (e == NULL) {
+ if (opos == -1) {
+ opos = i; /* find open position for new entry */
+ } /* really need a hash code for this */
+ } else if (e->listener == listener && e->listener_fn == listener_fn &&
+ e->useCapture == useCapture && strcmp(e->type, type) == 0) {
+ return;
+ }
+ }
+
+ if ((e = malloc(sizeof *e)) == NULL ||
+ (e->type = mbsdup(type)) == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ free(e);
+ return;
+ }
+ e->listener = listener;
+ e->listener_fn = listener_fn;
+ e->useCapture = useCapture;
+
+ if (opos == -1) {
+ target->listeners = realloc(target->listeners,
+ sizeof *e * (target->listeners_len + 1));
+ if (target->listeners == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ free(e);
+ return;
+ }
+ target->listeners[target->listeners_len++] = e;
+ } else {
+ target->listeners[opos] = e;
+ }
+/*MSG("added listener: type=%s,target=%s,useCapture=%d\n", type, target->nodeName, useCapture);
+ */
+}
+void
+DOM_EventTarget_removeEventListener(DOM_EventTarget *target, const DOM_String *type,
+ DOM_EventListener *listener,
+ DOM_EventListener_handleEvent listener_fn,
+ int useCapture)
+{
+ ListenerEntry *e;
+ unsigned int i;
+
+ if (target == NULL || type == NULL || listener_fn == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return;
+ }
+
+ for (i = 0; i < target->listeners_len; i++) {
+ e = target->listeners[i];
+
+ if (e && e->listener == listener && e->listener_fn == listener_fn &&
+ e->useCapture == useCapture && strcmp(e->type, type) == 0) {
+ target->listeners[i] = NULL;
+ free(e->type);
+ free(e);
+ return;
+ }
+ }
+}
+static void
+trigger(DOM_EventTarget *target, DOM_Event *evt, int useCapture)
+{
+ ListenerEntry *e;
+ unsigned int j, lcount;
+
+ if (target && target->listeners_len && evt->_sp == 0) {
+ DOM_EventListener_handleEvent *cpy_of_listener_fns;
+
+ if ((cpy_of_listener_fns = malloc(target->listeners_len *
+ sizeof(*cpy_of_listener_fns))) == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ return;
+ }
+
+ lcount = target->listeners_len; /* copy listeners */
+ for (j = 0; j < lcount; j++) {
+ e = target->listeners[j];
+ cpy_of_listener_fns[j] = e ? e->listener_fn : NULL;
+ }
+
+ evt->currentTarget = target;
+ for (j = 0; j < lcount; j++) {
+ e = target->listeners[j]; /* If the entry is NULL, the listener has
+ * since been removed and is therefore skipped. If it
+ * is not NULL but the listeners do not match, then
+ * it was removed but another listener was added in
+ * its place and therefore should be skipped. However,
+ * if a listener is removed but then added again
+ * while the current set is still being processed
+ * there is a chance that it will be tiggered if it
+ * meets the criteria tested below. Regardless of
+ * the slim chances of this occuring (have to be the
+ * same listener added to the same array) it may
+ * need to be addressed.
+ */
+/*MSG("e=%p,e->listener_fn=%p,cpy_of_listener_fns[%d]=%p,e->useCapture=%d,e->type=%s,evt->type=%s", e, e->listener_fn, j, cpy_of_listener_fns[j], e->useCapture, e->type, evt->type);
+ */
+
+ if (e && e->listener_fn == cpy_of_listener_fns[j] &&
+ e->useCapture == useCapture && strcmp(e->type, evt->type) == 0) {
+ e->listener_fn(e->listener, evt); /* invoke the listener function */
+ }
+ }
+ free(cpy_of_listener_fns);
+ }
+}
+int
+DOM_EventTarget_dispatchEvent(DOM_EventTarget *target, DOM_Event *evt)
+{
+ DOM_EventTarget **targets, *t;
+ unsigned int tcount, i;
+
+ if (target == NULL || evt == NULL) {
+ DOM_Exception = NULL_POINTER_ERR;
+ PMNO(DOM_Exception);
+ return 1;
+ }
+/*MSG("type=%s,target=%s,listeners_len=%d", evt->type, target->nodeName, target->listeners_len);
+ */
+
+ if (evt->type == NULL || *evt->type == '\0') {
+ DOM_Exception = DOM_UNSPECIFIED_EVENT_TYPE_ERR;
+ PMNO(DOM_Exception);
+ return 1;
+ }
+
+ targets = NULL;
+ evt->target = target; /* post-initialization */
+ evt->timeStamp = timestamp();
+ evt->_sp = 0;
+ evt->_pd = 0;
+
+ tcount = 0; /* count targets/ancestors */
+ for (t = target->parentNode; t; t = t->parentNode) {
+ tcount++;
+ }
+ if (tcount) {
+ targets = malloc(sizeof *targets * tcount);
+ if (targets == NULL) {
+ DOM_Exception = errno;
+ PMNO(DOM_Exception);
+ return 1;
+ }
+ }
+ i = tcount; /* save state of tree in targets array */
+ for (t = target->parentNode; t; t = t->parentNode) {
+ targets[--i] = t;
+ }
+ /* Trigger capturers
+ */
+ evt->eventPhase = DOM_EVENT_CAPTURING_PHASE;
+ for (i = 0; i < tcount && evt->_sp == 0; i++) {
+ trigger(targets[i], evt, 1);
+ }
+ /* Trigger regular listeners
+ */
+ evt->eventPhase = DOM_EVENT_AT_TARGET;
+ trigger(target, evt, 0);
+
+ /* Trigger bubblers
+ */
+ evt->eventPhase = DOM_EVENT_BUBBLING_PHASE;
+ i = tcount;
+ while (i-- && evt->bubbles && evt->_sp == 0) {
+ trigger(targets[i], evt, 0);
+ }
+
+ if (targets) {
+ free(targets);
+ }
+ return !evt->_pd;
+}
+
+/* DOM_TextEvent - Introduced in DOM Level 3
+ * http://www.w3.org/TR/2002/WD-DOM-Level-3-Events-20020208/events.html
+ */
+
+
+int
+DOM_TextEvent_checkModifier(DOM_TextEvent *evt, unsigned int modifier)
+{
+ return evt->_modifiers & (1 << (modifier - 1));
+}
+void
+DOM_TextEvent_initTextEvent(DOM_TextEvent *evt, const DOM_String *typeArg,
+ int canBubbleArg, int cancelableArg,
+ DOM_AbstractView *viewArg, long detailArg,
+ DOM_String *outputStringArg,
+ unsigned int keyValArg,
+ unsigned int virtKeyValArg,
+ int visibleOutputGeneratedArg,
+ int numPadArg)
+{
+ if (evt == NULL || typeArg == NULL || *typeArg == '\0') {
+ return;
+ }
+ DOM_UIEvent_initUIEvent(evt, typeArg, canBubbleArg, cancelableArg, viewArg, detailArg);
+ evt->outputString = outputStringArg;
+ evt->keyVal = keyValArg;
+ evt->virtKeyVal = virtKeyValArg;
+ evt->visibleOutputGenerated = visibleOutputGeneratedArg;
+ evt->numPad = numPadArg;
+}
+void
+DOM_TextEvent_initModifier(DOM_TextEvent *evt, unsigned int modifier, int value)
+{
+ if (evt && modifier > 0 && modifier <= DOM_VK_RIGHT_META) {
+ if (value) {
+ evt->_modifiers |= 1 << (modifier - 1);
+ } else {
+ evt->_modifiers &= ~(1 << (modifier - 1));
+ }
+ }
+}
+
+/* MutationEvent
+ */
+
+void
+DOM_MutationEvent_initMutationEvent(DOM_MutationEvent *evt, DOM_String *typeArg,
+ int canBubbleArg, int cancelableArg,
+ DOM_Node *relatedNodeArg,
+ DOM_String *prevValueArg,
+ DOM_String *newValueArg,
+ DOM_String *attrNameArg,
+ unsigned short attrChangeArg)
+{
+ if (evt == NULL || typeArg == NULL || *typeArg == '\0') {
+ return;
+ }
+ DOM_Event_initEvent(evt, typeArg, canBubbleArg, cancelableArg);
+ evt->relatedNode = relatedNodeArg;
+ evt->prevValue = prevValueArg;
+ evt->newValue = newValueArg;
+ evt->attrName = attrNameArg;
+ evt->attrChange = attrChangeArg;
+}
+void
+updateCommonParent(DOM_Node *node)
+{
+ DOM_Node *n, *cp;
+
+ if (node == NULL || node->ownerDocument == NULL) {
+ return;
+ }
+ if (node->ownerDocument->u.Document.commonParent == NULL) {
+ node->ownerDocument->u.Document.commonParent = node;
+ return;
+ }
+
+ cp = NULL;
+ for (n = node; n; n = n->parentNode) {
+ if (n == node->ownerDocument->u.Document.commonParent) {
+ return;
+ } else if (cp == NULL && n->subtreeModified == 1) {
+ cp = n;
+ } else {
+ n->subtreeModified = 1;
+ }
+ }
+
+ node->ownerDocument->u.Document.commonParent = cp;
+}
+static void
+_clearSubtreeModified(DOM_Document *doc)
+{
+ DOM_Node *n;
+
+ for (n = doc->firstChild; n != NULL; n = n->nextSibling) {
+ if (n->subtreeModified) {
+ n->subtreeModified = 0;
+ _clearSubtreeModified(n);
+ }
+ }
+ doc->u.Document.commonParent = NULL;
+}
+void
+DOM_MutationEvent_processSubtreeModified(DOM_Document *doc)
+{
+ DOM_Node *target;
+ DOM_MutationEvent evt;
+
+ if (doc->u.Document.commonParent == NULL) {
+ return;
+ }
+
+ target = doc->u.Document.commonParent;
+ _clearSubtreeModified(doc);
+
+ DOM_MutationEvent_initMutationEvent(&evt, "DOMSubtreeModified",
+ 1, 0, NULL, NULL, NULL, NULL, 0);
+ DOM_EventTarget_dispatchEvent(target, &evt);
+}
diff --git a/src/dom.h b/src/dom.h
new file mode 100644
index 0000000..b439d60
--- /dev/null
+++ b/src/dom.h
@@ -0,0 +1,526 @@
+/* DOMC Document Object Model library in C
+ * Copyright (c) 2001 Michael B. Allen <mba2000 ioplex.com>
+ *
+ * The MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* dom.h - internal interfaces
+ */
+
+#ifndef DOM_H
+#define DOM_H
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+
+struct msgno_entry {
+ int msgno;
+ const char *msg;
+};
+
+const char *msgno_msg(int msgno);
+
+extern struct msgno_entry dom_codes[];
+
+#if defined(__sparc__)
+ #include <sys/inttypes.h>
+#elif defined(_WIN32)
+ typedef unsigned __int64 uint64_t;
+#else
+ #include <stdint.h>
+#endif
+
+/* Enable this for hashing and fast access to large child node lists */
+#define FAST_NODELIST 0
+
+#if FAST_NODELIST
+#include <mba/hashmap.h>
+#endif
+
+/* DOM_String
+ */
+
+typedef char DOM_String;
+
+/* DOM_TimeStamp - Introduced in DOM Level 2
+ */
+
+typedef uint64_t DOM_TimeStamp;
+
+/* DOM_Exception
+ */
+
+extern int *_DOM_Exception(void);
+
+#define DOM_Exception (*_DOM_Exception())
+
+/* DOM_EventException - Introduced in DOM Level 2
+ */
+
+#define DOM_UNSPECIFIED_EVENT_TYPE_ERR dom_codes[13].msgno
+
+/* DOM_Node
+ */
+
+typedef struct DOM_Node DOM_Node;
+typedef struct DOM_NodeList DOM_NodeList;
+typedef struct DOM_NodeList DOM_NamedNodeMap;
+typedef struct NodeEntry NodeEntry;
+
+typedef DOM_Node DOM_Attr;
+typedef DOM_Node DOM_Element;
+typedef DOM_Node DOM_CharacterData;
+typedef DOM_CharacterData DOM_Text;
+typedef DOM_CharacterData DOM_Comment;
+typedef DOM_Text DOM_CDATASection;
+typedef DOM_Node DOM_DocumentType;
+typedef DOM_Node DOM_Notation;
+typedef DOM_Node DOM_Entity;
+typedef DOM_Node DOM_EntityReference;
+typedef DOM_Node DOM_ProcessingInstruction;
+typedef DOM_Node DOM_DocumentFragment;
+typedef DOM_Node DOM_Document;
+typedef DOM_Document DOM_DocumentLS;
+/* Introduced in DOM Level 2: */
+typedef DOM_Node DOM_EventTarget;
+typedef struct ListenerEntry ListenerEntry;
+typedef DOM_Document DOM_DocumentEvent;
+typedef DOM_Document DOM_AbstractView;
+typedef DOM_Document DOM_DocumentView;
+
+#define DOM_ELEMENT_NODE 1
+#define DOM_ATTRIBUTE_NODE 2
+#define DOM_TEXT_NODE 3
+#define DOM_CDATA_SECTION_NODE 4
+#define DOM_ENTITY_REFERENCE_NODE 5
+#define DOM_ENTITY_NODE 6
+#define DOM_PROCESSING_INSTRUCTION_NODE 7
+#define DOM_COMMENT_NODE 8
+#define DOM_DOCUMENT_NODE 9
+#define DOM_DOCUMENT_TYPE_NODE 10
+#define DOM_DOCUMENT_FRAGMENT_NODE 11
+#define DOM_NOTATION_NODE 12
+
+/* events forward references - Introduced in DOM Level 2
+ */
+
+typedef struct DOM_Event DOM_Event;
+typedef struct DOM_Event DOM_UIEvent;
+typedef DOM_UIEvent DOM_TextEvent;
+typedef struct DOM_Event DOM_MutationEvent;
+
+typedef void DOM_EventListener;
+typedef void (*DOM_EventListener_handleEvent)(DOM_EventListener *this, DOM_Event *evt);
+
+struct ListenerEntry {
+ DOM_String *type;
+ DOM_EventListener *listener;
+ DOM_EventListener_handleEvent listener_fn;
+ int useCapture;
+};
+
+struct DOM_Node {
+ DOM_String *nodeName;
+ DOM_String *nodeValue;
+ unsigned short nodeType;
+ DOM_Node *parentNode;
+ DOM_NodeList *childNodes;
+ DOM_Node *firstChild;
+ DOM_Node *lastChild;
+ DOM_Node *previousSibling;
+ DOM_Node *nextSibling;
+ DOM_NamedNodeMap *attributes;
+ DOM_Document *ownerDocument;
+ /* Custom Fields */
+ unsigned int listeners_len;
+ ListenerEntry **listeners;
+ unsigned short subtreeModified;
+ union {
+ struct {
+ DOM_DocumentType *doctype;
+ DOM_Element *documentElement;
+ DOM_DocumentView *document;
+ DOM_AbstractView *defaultView;
+ DOM_Node *commonParent;
+ DOM_String *version;
+ DOM_String *encoding;
+ int standalone;
+ } Document;
+ struct {
+ DOM_String *name;
+ DOM_NamedNodeMap *entities;
+ DOM_NamedNodeMap *notations;
+ DOM_String *publicId;
+ DOM_String *systemId;
+ DOM_String *internalSubset;
+ } DocumentType;
+ struct {
+ DOM_String *tagName;
+ } Element;
+ struct {
+ DOM_String *name;
+ int specified;
+ DOM_String *value;
+ DOM_Element *ownerElement;
+ } Attr;
+ struct {
+ DOM_String *data;
+ int length;
+ } CharacterData;
+ struct {
+ DOM_String *publicId;
+ DOM_String *systemId;
+ } Notation;
+ struct {
+ DOM_String *publicId;
+ DOM_String *systemId;
+ DOM_String *notationName;
+ } Entity;
+ struct {
+ DOM_String *target;
+ DOM_String *data;
+ } ProcessingInstruction;
+ } u;
+ unsigned int rtfxRefCount; /* Reference counting added for RTFX */
+ void* userData; /* User data added for RTFX */
+};
+
+DOM_Node *DOM_Node_insertBefore(DOM_Node *node, DOM_Node *newChild, DOM_Node *refChild);
+DOM_Node *DOM_Node_replaceChild(DOM_Node *node, DOM_Node *newChild, DOM_Node *oldChild);
+DOM_Node *DOM_Node_removeChild(DOM_Node *node, DOM_Node *oldChild);
+DOM_Node *DOM_Node_appendChild(DOM_Node *node, DOM_Node *newChild);
+int DOM_Node_hasChildNodes(const DOM_Node *node);
+DOM_Node *DOM_Node_cloneNode(DOM_Node *node, int deep);
+DOM_String *DOM_Node_getNodeValue(DOM_Node *node);
+void DOM_Node_setNodeValue(DOM_Node *node, DOM_String *value);
+
+/* DOM_NodeList, DOM_NamedNodeMap
+ */
+
+struct NodeEntry {
+ NodeEntry *prev;
+ NodeEntry *next;
+ DOM_Node *node;
+};
+struct DOM_NodeList {
+ DOM_Document *_ownerDocument;
+ DOM_Element *_ownerElement;
+ int length;
+ NodeEntry *first;
+ NodeEntry *last;
+ unsigned short filter;
+ struct DOM_NodeList *list; /* Used for entities and notations */
+#if FAST_NODELIST
+ struct hashmap* _map;
+#endif
+ unsigned int rtfxRefCount; /* Reference counting added for RTFX */
+};
+
+DOM_Node *DOM_NodeList_item(const DOM_NodeList *nl, int index);
+
+DOM_Node *DOM_NamedNodeMap_getNamedItem(const DOM_NamedNodeMap *map, const DOM_String *name);
+DOM_Node *DOM_NamedNodeMap_setNamedItem(DOM_NamedNodeMap *map, DOM_Node *arg);
+DOM_Node *DOM_NamedNodeMap_removeNamedItem(DOM_NamedNodeMap *map, const DOM_String *name);
+DOM_Node *DOM_NamedNodeMap_item(const DOM_NamedNodeMap *map, int index);
+
+/* DOM_Implementation
+ */
+
+int DOM_Implementation_hasFeature(DOM_String *feature, DOM_String *version);
+DOM_DocumentType *DOM_Implementation_createDocumentType(DOM_String *qualifiedName,
+ DOM_String *publicId, DOM_String *systemId);
+DOM_Document *DOM_Implementation_createDocument(DOM_String *namespaceURI,
+ DOM_String *qualifiedName, DOM_DocumentType *doctype);
+
+/* DOM_Element
+ */
+
+DOM_String *DOM_Element_getAttribute(const DOM_Element *element, const DOM_String *name);
+void DOM_Element_setAttribute(DOM_Element *element, const DOM_String *name,
+ const DOM_String *value);
+void DOM_Element_removeAttribute(DOM_Element *element, const DOM_String *name);
+DOM_Attr *DOM_Element_getAttributeNode(const DOM_Element *element, const DOM_String *name);
+DOM_Attr *DOM_Element_setAttributeNode(DOM_Element *element, DOM_Attr *newAttr);
+DOM_Attr *DOM_Element_removeAttributeNode(DOM_Element *element, DOM_Attr *oldAttr);
+DOM_NodeList *DOM_Element_getElementsByTagName(DOM_Element *element, const DOM_String *name);
+void DOM_Element_normalize(DOM_Element *element);
+
+/* DOM_CharacterData
+ */
+
+DOM_String *DOM_CharacterData_substringData(DOM_CharacterData *data,
+ int offset, int count);
+void DOM_CharacterData_appendData(DOM_CharacterData *data, const DOM_String *arg);
+void DOM_CharacterData_insertData(DOM_CharacterData *data, int offset,
+ const DOM_String *arg);
+void DOM_CharacterData_deleteData(DOM_CharacterData *data, int offset, int count);
+void DOM_CharacterData_replaceData(DOM_CharacterData *data, int offset, int count,
+ const DOM_String *arg);
+int DOM_CharacterData_getLength(DOM_CharacterData *data);
+
+/* DOM_Text
+ */
+
+DOM_Text *DOM_Text_splitText(DOM_Text *text, int offset);
+
+/* DOM_Document
+ */
+
+DOM_Element *DOM_Document_createElement(DOM_Document *doc, const DOM_String *tagName);
+DOM_DocumentFragment *DOM_Document_createDocumentFragment(DOM_Document *doc);
+DOM_Text *DOM_Document_createTextNode(DOM_Document *doc, const DOM_String *data);
+DOM_Comment *DOM_Document_createComment(DOM_Document *doc, const DOM_String *data);
+DOM_CDATASection *DOM_Document_createCDATASection(DOM_Document *doc, const DOM_String *data);
+DOM_ProcessingInstruction *DOM_Document_createProcessingInstruction(DOM_Document *doc,
+ const DOM_String *target, const DOM_String *data);
+DOM_Attr *DOM_Document_createAttribute(DOM_Document *doc, const DOM_String *name);
+DOM_EntityReference *DOM_Document_createEntityReference(DOM_Document *doc,
+ const DOM_String *name);
+DOM_NodeList *DOM_Document_getElementsByTagName(DOM_Document *doc, const DOM_String *tagname);
+
+void DOM_Document_destroyNode(DOM_Document *doc, DOM_Node *node);
+void DOM_Document_destroyNodeList(DOM_Document *doc, DOM_NodeList *nl, int free_nodes);
+
+DOM_DocumentType *DOM_Document_getDoctype(DOM_Document *doc);
+DOM_Element *DOM_Document_getDocumentElement(DOM_Document *doc);
+
+/* DOM_DocumentLS - This does NOT resemble the Load/Save interfaces
+ * described in the latest W3C drafts at all.
+ */
+
+int DOM_DocumentLS_save(DOM_DocumentLS *this, const char *uri, const DOM_Node *node);
+int DOM_DocumentLS_fwrite(const DOM_DocumentLS *this, FILE *stream);
+
+/* Events - Introduced in DOM Level 2
+ * http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html
+ */
+
+/* DOM_Event - Introduced in DOM Level 2
+ */
+
+#define DOM_EVENT_CAPTURING_PHASE 1
+#define DOM_EVENT_AT_TARGET 2
+#define DOM_EVENT_BUBBLING_PHASE 3
+
+struct DOM_Event {
+ const DOM_String *type;
+ DOM_EventTarget *target;
+ DOM_EventTarget *currentTarget;
+ unsigned short eventPhase;
+ int bubbles;
+ int cancelable;
+ DOM_TimeStamp timeStamp;
+/* custom -- do not touch */
+ int _pd;
+ int _sp;
+ unsigned int _modifiers;
+/* UIEvent members */
+ DOM_AbstractView *view;
+ long detail;
+/* TextEvent members */
+ DOM_String *outputString;
+ unsigned long keyVal;
+ unsigned long virtKeyVal;
+ int visibleOutputGenerated;
+ int numPad;
+/* MutationEvent members */
+ DOM_Node *relatedNode;
+ DOM_String *prevValue;
+ DOM_String *newValue;
+ DOM_String *attrName;
+ unsigned short attrChange;
+};
+
+void DOM_Event_stopPropagation(DOM_Event *evt);
+void DOM_Event_preventDefault(DOM_Event *evt);
+void DOM_Event_initEvent(DOM_Event *evt, const DOM_String *eventTypeArg,
+ int canBubbleArg, int cancelableArg);
+
+/* DOM_DocumentEvent - Introduced in DOM Level 2
+ */
+
+DOM_Event *DOM_DocumentEvent_createEvent(DOM_DocumentEvent *doc,
+ const DOM_String *eventType);
+void DOM_DocumentEvent_destroyEvent(DOM_DocumentEvent *doc, DOM_Event *evt);
+
+/* DOM_UIEvent
+ */
+
+void DOM_UIEvent_initUIEvent(DOM_UIEvent *evt,
+ const DOM_String *typeArg,
+ int canBubbleArg,
+ int cancelableArg,
+ DOM_AbstractView *viewArg,
+ long detailArg);
+
+/* DOM_EventTarget - Introduced in DOM Level 2
+ */
+
+void DOM_EventTarget_addEventListener(DOM_EventTarget *target,
+ const DOM_String *type,
+ DOM_EventListener *listener,
+ DOM_EventListener_handleEvent listener_fn,
+ int useCapture);
+void DOM_EventTarget_removeEventListener(DOM_EventTarget *target,
+ const DOM_String *type,
+ DOM_EventListener *listener,
+ DOM_EventListener_handleEvent listener_fn,
+ int useCapture);
+int DOM_EventTarget_dispatchEvent(DOM_EventTarget *target, DOM_Event *evt);
+
+/* DOM_TextEvent - Introduced in DOM Level 3
+ * http://www.w3.org/TR/2002/WD-DOM-Level-3-Events-20020208/events.html
+ */
+
+#define DOM_VK_UNDEFINED 0x0
+#define DOM_VK_RIGHT_ALT 0x01
+#define DOM_VK_LEFT_ALT 0x02
+#define DOM_VK_LEFT_CONTROL 0x03
+#define DOM_VK_RIGHT_CONTROL 0x04
+#define DOM_VK_LEFT_SHIFT 0x05
+#define DOM_VK_RIGHT_SHIFT 0x06
+#define DOM_VK_LEFT_META 0x07
+#define DOM_VK_RIGHT_META 0x08
+#define DOM_VK_CAPS_LOCK 0x09
+#define DOM_VK_DELETE 0x0A
+#define DOM_VK_END 0x0B
+#define DOM_VK_ENTER 0x0C
+#define DOM_VK_ESCAPE 0x0D
+#define DOM_VK_HOME 0x0E
+#define DOM_VK_INSERT 0x0F
+#define DOM_VK_NUM_LOCK 0x10
+#define DOM_VK_PAUSE 0x11
+#define DOM_VK_PRINTSCREEN 0x12
+#define DOM_VK_SCROLL_LOCK 0x13
+#define DOM_VK_LEFT 0x14
+#define DOM_VK_RIGHT 0x15
+#define DOM_VK_UP 0x16
+#define DOM_VK_DOWN 0x17
+#define DOM_VK_PAGE_DOWN 0x18
+#define DOM_VK_PAGE_UP 0x19
+#define DOM_VK_F1 0x1A
+#define DOM_VK_F2 0x1B
+#define DOM_VK_F3 0x1C
+#define DOM_VK_F4 0x1D
+#define DOM_VK_F5 0x1E
+#define DOM_VK_F6 0x1F
+#define DOM_VK_F7 0x20
+#define DOM_VK_F8 0x21
+#define DOM_VK_F9 0x22
+#define DOM_VK_F10 0x23
+#define DOM_VK_F11 0x24
+#define DOM_VK_F12 0x25
+#define DOM_VK_F13 0x26
+#define DOM_VK_F14 0x27
+#define DOM_VK_F15 0x28
+#define DOM_VK_F16 0x29
+#define DOM_VK_F17 0x2A
+#define DOM_VK_F18 0x2B
+#define DOM_VK_F19 0x2C
+#define DOM_VK_F20 0x2D
+#define DOM_VK_F21 0x2E
+#define DOM_VK_F22 0x2F
+#define DOM_VK_F23 0x30
+#define DOM_VK_F24 0x31
+
+int DOM_TextEvent_checkModifier(DOM_TextEvent *evt, unsigned int modifier);
+void DOM_TextEvent_initTextEvent(DOM_TextEvent *evt, const DOM_String *typeArg,
+ int canBubbleArg, int cancelableArg,
+ DOM_AbstractView *viewArg, long detailArg,
+ DOM_String *outputStringArg,
+ unsigned int keyValArg,
+ unsigned int virtKeyValArg,
+ int visibleOutputGeneratedArg,
+ int numPadArg);
+void DOM_TextEvent_initModifier(DOM_TextEvent *evt, unsigned int modifier, int value);
+
+/* Useful X KeySym to keyVal and virtKeyVal conversion functions
+ * Add these .o's to the OBJS line in the Makefile to compile
+ */
+
+unsigned int keysym2ucs(unsigned short keysym);
+unsigned int keysym2domvk(unsigned short keysym);
+
+/* MutationEvent
+ */
+
+#define DOM_MUTATION_EVENT_MODIFICATION 1
+#define DOM_MUTATION_EVENT_ADDITION 2
+#define DOM_MUTATION_EVENT_REMOVAL 3
+
+void DOM_MutationEvent_initMutationEvent(DOM_MutationEvent *evt,
+ DOM_String *typeArg,
+ int canBubbleArg,
+ int cancelableArg,
+ DOM_Node *relatedNodeArg,
+ DOM_String *prevValueArg,
+ DOM_String *newValueArg,
+ DOM_String *attrNameArg,
+ unsigned short attrChangeArg);
+void DOM_MutationEvent_processSubtreeModified(DOM_EventTarget *subtree);
+
+/* Temporary Functions
+ */
+
+void DOM_Node_printNode(DOM_Node *node);
+void DOM_Node_printNode2(DOM_Node *node);
+
+#define DOM_INDEX_SIZE_ERR dom_codes[0].msgno
+#define DOM_DOMSTRING_SIZE_ERR dom_codes[1].msgno
+#define DOM_HIERARCHY_REQUEST_ERR dom_codes[2].msgno
+#define DOM_WRONG_DOCUMENT_ERR dom_codes[3].msgno
+#define DOM_INVALID_CHARACTER_ERR dom_codes[4].msgno
+#define DOM_NO_DATA_ALLOWED_ERR dom_codes[5].msgno
+#define DOM_NO_MODIFICATION_ALLOWED_ERR dom_codes[6].msgno
+#define DOM_NOT_FOUND_ERR dom_codes[7].msgno
+#define DOM_NOT_SUPPORTED_ERR dom_codes[8].msgno
+#define DOM_INUSE_ATTRIBUTE_ERR dom_codes[9].msgno
+#define DOM_XML_PARSER_ERR dom_codes[10].msgno
+#define DOM_CREATE_FAILED dom_codes[11].msgno
+#define DOM_CHARACTER_ENC_ERR dom_codes[12].msgno
+#define DOM_UNSPECIFIED_EVENT_TYPE_ERR dom_codes[13].msgno
+#define DOM_FILTERED_LIST_ERR dom_codes[14].msgno
+
+#define CANNOT_HAVE_CHILD_OF(p, c) !(child_matrix[(p)->nodeType - 1] & \
+ (1 << ((c)->nodeType - 1)))
+#define MODIFYING_DOC_ELEM(p, c) ((p)->nodeType == DOM_DOCUMENT_NODE && \
+ (c)->nodeType == DOM_ELEMENT_NODE)
+#define MODIFYING_DOCTYPE_ELEM(p, c) ((p)->nodeType == DOM_DOCUMENT_NODE && \
+ (c)->nodeType == DOM_DOCUMENT_TYPE_NODE)
+#define INVALID_HIER_REQ(p, c) (CANNOT_HAVE_CHILD_OF(p, c) || \
+ (MODIFYING_DOC_ELEM(p, c) && (p)->u.Document.documentElement))
+
+extern unsigned short child_matrix[];
+
+DOM_NodeList *Document_createNodeList(DOM_Document *doc);
+DOM_Node *NodeList_itemFiltered(const DOM_NodeList *list, int index, unsigned short nodeType);
+NodeEntry *NodeList_insert(DOM_NodeList *nl, DOM_Node *newChild, DOM_Node *refChild);
+NodeEntry *NodeList_replace(DOM_NodeList *nl, DOM_Node *newChild, DOM_Node *oldChild);
+NodeEntry *NodeList_remove(DOM_NodeList *nl, DOM_Node *oldChild);
+NodeEntry *NodeList_append(DOM_NodeList *nl, DOM_Node *newChild);
+int NodeList_exists(DOM_NodeList *nl, DOM_Node *child);
+
+DOM_NamedNodeMap *Document_createNamedNodeMap(DOM_Document *doc);
+
+#endif /* DOM_H */
diff --git a/src/domcxx.h b/src/domcxx.h
index 747b63f..896b761 100644
--- a/src/domcxx.h
+++ b/src/domcxx.h
@@ -54,7 +54,6 @@ namespace DOM
extern "C"
{
#define this _this
- #include "domc.h"
#include "dom.h"
#undef this
}
diff --git a/src/domhelpers.h b/src/domhelpers.h
index f042edd..65ab4e9 100644
--- a/src/domhelpers.h
+++ b/src/domhelpers.h
@@ -111,7 +111,7 @@ typedef std::stack<DOM::Node> NodeStack;
* For iterating through the elements in a document.
*/
class ElementIterator
- : public std::iterator<std::input_iterator_tag, DOM::Element, ptrdiff_t>
+ : public std::iterator<std::input_iterator_tag, DOM::Element, std::ptrdiff_t>
{
public:
ElementIterator()
diff --git a/src/usuals.h b/src/usuals.h
index 4faff55..833ecda 100644
--- a/src/usuals.h
+++ b/src/usuals.h
@@ -54,6 +54,7 @@
#endif
#include <stdlib.h>
+#include <string.h>
#ifndef ASSERT
#ifdef _DEBUG
diff --git a/src/xmlfixups.cpp b/src/xmlfixups.cpp
index 16b4b35..6ea8933 100644
--- a/src/xmlfixups.cpp
+++ b/src/xmlfixups.cpp
@@ -453,7 +453,7 @@ void XmlFixups::runPassTwo(const DOM::Document& doc)
// Mark each node as we've seen it so we don't
// do a given element twice
- if((int)el.getUserData() == PASS_TWO)
+ if((int)(unsigned long)el.getUserData() == PASS_TWO)
continue;
el.setUserData((void*)PASS_TWO);
diff --git a/win32/build.bat b/win32/build.bat
deleted file mode 100644
index 8bb6185..0000000
--- a/win32/build.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@echo off
-cd ../libs/%1/
-nmake /f Makefile.msvc %2
diff --git a/win32/domc.dsp b/win32/domc.dsp
deleted file mode 100644
index ef24010..0000000
--- a/win32/domc.dsp
+++ /dev/null
@@ -1,97 +0,0 @@
-# Microsoft Developer Studio Project File - Name="domc" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) External Target" 0x0106
-
-CFG=domc - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "domc.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "domc.mak" CFG="domc - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "domc - Win32 Release" (based on "Win32 (x86) External Target")
-!MESSAGE "domc - Win32 Debug" (based on "Win32 (x86) External Target")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-
-!IF "$(CFG)" == "domc - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Cmd_Line "NMAKE /f domc.mak"
-# PROP BASE Rebuild_Opt "/a"
-# PROP BASE Target_File "domc.exe"
-# PROP BASE Bsc_Name "domc.bsc"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Cmd_Line "build.bat domc"
-# PROP Rebuild_Opt "/a"
-# PROP Target_File "../libs/domc/domc.lib"
-# PROP Bsc_Name ""
-# PROP Target_Dir ""
-
-!ELSEIF "$(CFG)" == "domc - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Cmd_Line "NMAKE /f domc.mak"
-# PROP BASE Rebuild_Opt "/a"
-# PROP BASE Target_File "domc.exe"
-# PROP BASE Bsc_Name "domc.bsc"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Cmd_Line "build.bat domc"
-# PROP Rebuild_Opt "/a"
-# PROP Target_File "../libs/domc/domc.lib"
-# PROP Bsc_Name ""
-# PROP Target_Dir ""
-
-!ENDIF
-
-# Begin Target
-
-# Name "domc - Win32 Release"
-# Name "domc - Win32 Debug"
-
-!IF "$(CFG)" == "domc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "domc - Win32 Debug"
-
-!ENDIF
-
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/win32/libmba.dsp b/win32/libmba.dsp
deleted file mode 100644
index 08546a8..0000000
--- a/win32/libmba.dsp
+++ /dev/null
@@ -1,97 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libmba" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) External Target" 0x0106
-
-CFG=libmba - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "libmba.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "libmba.mak" CFG="libmba - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "libmba - Win32 Release" (based on "Win32 (x86) External Target")
-!MESSAGE "libmba - Win32 Debug" (based on "Win32 (x86) External Target")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-
-!IF "$(CFG)" == "libmba - Win32 Release"
-
-# PROP BASE Use_MFC
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Cmd_Line "NMAKE /f libmba.mak"
-# PROP BASE Rebuild_Opt "/a"
-# PROP BASE Target_File "libmba.exe"
-# PROP BASE Bsc_Name "libmba.bsc"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Cmd_Line "build.bat libmba"
-# PROP Rebuild_Opt "/a"
-# PROP Target_File "../libs/libmba/libmba.lib"
-# PROP Bsc_Name ""
-# PROP Target_Dir ""
-
-!ELSEIF "$(CFG)" == "libmba - Win32 Debug"
-
-# PROP BASE Use_MFC
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Cmd_Line "NMAKE /f libmba.mak"
-# PROP BASE Rebuild_Opt "/a"
-# PROP BASE Target_File "libmba.exe"
-# PROP BASE Bsc_Name "libmba.bsc"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Cmd_Line "build.bat libmba"
-# PROP Rebuild_Opt "/a"
-# PROP Target_File "../libs/libmba/libmba.lib"
-# PROP Bsc_Name ""
-# PROP Target_Dir ""
-
-!ENDIF
-
-# Begin Target
-
-# Name "libmba - Win32 Release"
-# Name "libmba - Win32 Debug"
-
-!IF "$(CFG)" == "libmba - Win32 Release"
-
-!ELSEIF "$(CFG)" == "libmba - Win32 Debug"
-
-!ENDIF
-
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/win32/rtfx.dsp b/win32/rtfx.dsp
index 18b6f56..f5f814f 100644
--- a/win32/rtfx.dsp
+++ b/win32/rtfx.dsp
@@ -124,6 +124,10 @@ SOURCE=..\src\xmlfixups.cpp
# End Group
# Begin Group "Header Files"
+SOURCE=..\src\dom.c
+# End Source File
+# Begin Source File
+
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
@@ -131,6 +135,10 @@ SOURCE=..\src\domcxx.h
# End Source File
# Begin Source File
+SOURCE=..\src\dom.h
+# End Source File
+# Begin Source File
+
SOURCE=..\src\domhelpers.h
# End Source File
# Begin Source File