diff options
| -rw-r--r-- | .gitignore | 23 | ||||
| -rw-r--r-- | Makefile.am | 2 | ||||
| -rw-r--r-- | configure.in | 2 | ||||
| -rw-r--r-- | libs/.cvsignore | 5 | ||||
| -rw-r--r-- | libs/Makefile.am | 24 | ||||
| -rw-r--r-- | libs/README | 14 | ||||
| -rw-r--r-- | libs/files/domc-0.8.0.tar.gz | bin | 122571 -> 0 bytes | |||
| -rw-r--r-- | libs/files/domc-library.patch | 176 | ||||
| -rw-r--r-- | libs/files/libmba-0.8.10.tar.gz | bin | 259427 -> 0 bytes | |||
| -rw-r--r-- | libs/files/libmba-library.patch | 49 | ||||
| -rw-r--r-- | libs/prepare-libraries.sh | 29 | ||||
| -rw-r--r-- | src/Makefile.am | 13 | ||||
| -rw-r--r-- | src/dom.c | 3145 | ||||
| -rw-r--r-- | src/dom.h | 526 | ||||
| -rw-r--r-- | src/domcxx.h | 1 | ||||
| -rw-r--r-- | src/domhelpers.h | 2 | ||||
| -rw-r--r-- | src/usuals.h | 1 | ||||
| -rw-r--r-- | src/xmlfixups.cpp | 2 | ||||
| -rw-r--r-- | win32/build.bat | 3 | ||||
| -rw-r--r-- | win32/domc.dsp | 97 | ||||
| -rw-r--r-- | win32/libmba.dsp | 97 | ||||
| -rw-r--r-- | win32/rtfx.dsp | 8 | 
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 Binary files differdeleted file mode 100644 index e88f962..0000000 --- a/libs/files/domc-0.8.0.tar.gz +++ /dev/null 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(">", stream); -             break; -         case '&': --            fputs("'", stream); -+            fputs("&", stream); -             break; -         case '"': -             fputs(""", 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 Binary files differdeleted file mode 100644 index 3475caf..0000000 --- a/libs/files/libmba-0.8.10.tar.gz +++ /dev/null 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("<", stream); +            break; +        case '>': +            fputs(">", stream); +            break; +        case '&': +            fputs("'", stream); +            break; +        case '"': +            fputs(""", 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  | 
