diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/Makefile.am | 152 | ||||
-rw-r--r-- | util/Makefile.in | 839 | ||||
-rw-r--r-- | util/rarian-example.c | 122 | ||||
-rw-r--r-- | util/rarian-sk-config.in | 78 | ||||
-rw-r--r-- | util/rarian-sk-extract.in | 31 | ||||
-rw-r--r-- | util/rarian-sk-gen-uuid.c | 70 | ||||
-rw-r--r-- | util/rarian-sk-get-cl.cpp | 236 | ||||
-rw-r--r-- | util/rarian-sk-get-content-list.in | 23 | ||||
-rw-r--r-- | util/rarian-sk-get-extended-content-list.in | 23 | ||||
-rw-r--r-- | util/rarian-sk-get-scripts.in | 13 | ||||
-rw-r--r-- | util/rarian-sk-install.in | 30 | ||||
-rw-r--r-- | util/rarian-sk-migrate.cpp | 313 | ||||
-rw-r--r-- | util/rarian-sk-preinstall.cpp | 141 | ||||
-rw-r--r-- | util/rarian-sk-rebuild.in | 38 | ||||
-rwxr-xr-x | util/rarian-sk-update.in | 425 | ||||
-rw-r--r-- | util/tinystr.cpp | 115 | ||||
-rw-r--r-- | util/tinystr.h | 319 | ||||
-rw-r--r-- | util/tinyxml.cpp | 1799 | ||||
-rw-r--r-- | util/tinyxml.h | 1520 | ||||
-rw-r--r-- | util/tinyxmlerror.cpp | 52 | ||||
-rw-r--r-- | util/tinyxmlparser.cpp | 1580 |
21 files changed, 7919 insertions, 0 deletions
diff --git a/util/Makefile.am b/util/Makefile.am new file mode 100644 index 0000000..9967a65 --- /dev/null +++ b/util/Makefile.am @@ -0,0 +1,152 @@ +INCLUDES = \ + -I$(srcdir)/../librarian +LDADD = \ + ../librarian/librarian.la + +if ENABLE_SK_COMPAT +bin_SCRIPTS = \ + rarian-sk-update \ + rarian-sk-install \ + rarian-sk-rebuild \ + rarian-sk-config \ + rarian-sk-get-scripts \ + rarian-sk-get-content-list \ + rarian-sk-get-extended-content-list +endif + +DISTCLEANFILES= rarian-sk-update \ + rarian-sk-install \ + rarian-sk-rebuild \ + rarian-sk-config \ + rarian-sk-get-scripts \ + rarian-sk-get-content-list \ + rarian-sk-get-extended-content-list + +bin_PROGRAMS = \ + rarian-example + +if ENABLE_SK_COMPAT +bin_PROGRAMS += rarian-sk-migrate \ + rarian-sk-preinstall \ + rarian-sk-gen-uuid \ + rarian-sk-get-cl + +if ENABLE_EXTRACT +bin_SCRIPTS += rarian-sk-extract +endif +endif + +if ENABLE_SK_COMPAT +rarian_sk_migrate_SOURCES = \ + rarian-sk-migrate.cpp \ + tinystr.cpp \ + tinyxml.cpp \ + tinyxmlerror.cpp \ + tinyxmlparser.cpp \ + tinystr.h \ + tinyxml.h \ + ../librarian/rarian-reg-full.h \ + ../librarian/rarian-reg-full.c + +rarian_sk_preinstall_SOURCES = \ + rarian-sk-preinstall.cpp \ + tinystr.cpp \ + tinyxml.cpp \ + tinyxmlerror.cpp \ + tinyxmlparser.cpp \ + tinystr.h \ + tinyxml.h + +rarian_sk_get_cl_SOURCES = \ + rarian-sk-get-cl.cpp \ + tinystr.cpp \ + tinyxml.cpp \ + tinyxmlerror.cpp \ + tinyxmlparser.cpp \ + tinystr.h \ + tinyxml.h + +rarian_sk_get_cl_CXXFLAGS = -DDATADIR=\""$(datadir)"\" -DLOCALSTATEDIR=\""$(localstatedir)"\" + +rarian_sk_gen_uuid_SOURCES = \ + rarian-sk-gen-uuid.c +endif + +rarian_example_SOURCES = \ + rarian-example.c + +if ENABLE_INSTALL +install-exec-hook: +if ENABLE_SK_COMPAT + @echo Moving Files if needed + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-config ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-config; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-config ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-config $(DESTDIR)$(bindir)/scrollkeeper-config.real; fi +if ENABLE_EXTRACT + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-extract ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-extract; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-extract ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-extract $(DESTDIR)$(bindir)/scrollkeeper-extract.real; fi +endif + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-gen-seriesid ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-gen-seriesid; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-gen-seriesid ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-gen-seriesid $(DESTDIR)$(bindir)/scrollkeeper-gen-seriesid.real; fi + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-cl ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-cl; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-cl ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-get-cl $(DESTDIR)$(bindir)/scrollkeeper-get-cl.real; fi + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-content-list ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-content-list; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-content-list ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-get-content-list $(DESTDIR)$(bindir)/scrollkeeper-get-content-list.real; fi + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-extended-content-list ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-extended-content-list; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-extended-content-list ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-get-extended-content-list $(DESTDIR)$(bindir)/scrollkeeper-get-extended-content-list.real; fi + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-index-from-docpath ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-index-from-docpath; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-index-from-docpath ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-get-index-from-docpath $(DESTDIR)$(bindir)/scrollkeeper-get-index-from-docpath.real; fi + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-docpath ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-docpath; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-docpath ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-docpath $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-docpath.real; fi + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-id ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-id; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-id ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-id $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-id.real; fi + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-install ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-install; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-install ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-install $(DESTDIR)$(bindir)/scrollkeeper-install.real; fi + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-preinstall ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-preinstall; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-preinstall ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-preinstall $(DESTDIR)$(bindir)/scrollkeeper-preinstall.real; fi + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-rebuilddb ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-rebuilddb; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-rebuilddb ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-rebuilddb $(DESTDIR)$(bindir)/scrollkeeper-rebuilddb.real; fi + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-uninstall ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-uninstall; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-uninstall ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-uninstall $(DESTDIR)$(bindir)/scrollkeeper-uninstall.real; fi + @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-update ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-update; \ + elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-update ]; then \ + mv $(DESTDIR)$(bindir)/scrollkeeper-update $(DESTDIR)$(bindir)/scrollkeeper-update.real; fi + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-config scrollkeeper-config +if ENABLE_EXTRACT + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-extract scrollkeeper-extract +endif + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-gen-uuid scrollkeeper-gen-seriesid + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-cl scrollkeeper-get-cl + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-content-list scrollkeeper-get-content-list + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-extended-content-list scrollkeeper-get-extended-content-list + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-scripts scrollkeeper-get-index-from-docpath + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-scripts scrollkeeper-get-toc-from-docpath + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-scripts scrollkeeper-get-toc-from-id + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-install scrollkeeper-install + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-preinstall scrollkeeper-preinstall + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-rebuild scrollkeeper-rebuilddb + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-install scrollkeeper-uninstall + @cd $(DESTDIR)$(bindir); ln -s rarian-sk-update scrollkeeper-update + @mkdir -p $(DESTDIR)/$(localstatedir)/lib/rarian +if ENABLE_SKDB_UPDATE + @echo "Translating current database" + @$(DESTDIR)$(bindir)/rarian-sk-update +endif +endif + +else +install-exec-hook: + @echo WARNING: Installed in UNINSTALLED mode. Prepare for things to be broken!!!!! +endif diff --git a/util/Makefile.in b/util/Makefile.in new file mode 100644 index 0000000..fff6158 --- /dev/null +++ b/util/Makefile.in @@ -0,0 +1,839 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = rarian-example$(EXEEXT) $(am__EXEEXT_1) +@ENABLE_SK_COMPAT_TRUE@am__append_1 = rarian-sk-migrate \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-preinstall \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-gen-uuid \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-get-cl + +@ENABLE_EXTRACT_TRUE@@ENABLE_SK_COMPAT_TRUE@am__append_2 = rarian-sk-extract +subdir = util +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/rarian-sk-config.in $(srcdir)/rarian-sk-extract.in \ + $(srcdir)/rarian-sk-get-content-list.in \ + $(srcdir)/rarian-sk-get-extended-content-list.in \ + $(srcdir)/rarian-sk-get-scripts.in \ + $(srcdir)/rarian-sk-install.in $(srcdir)/rarian-sk-rebuild.in \ + $(srcdir)/rarian-sk-update.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = rarian-sk-update rarian-sk-install \ + rarian-sk-rebuild rarian-sk-config rarian-sk-get-scripts \ + rarian-sk-extract rarian-sk-get-content-list \ + rarian-sk-get-extended-content-list +@ENABLE_SK_COMPAT_TRUE@am__EXEEXT_1 = rarian-sk-migrate$(EXEEXT) \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-preinstall$(EXEEXT) \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-gen-uuid$(EXEEXT) \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-get-cl$(EXEEXT) +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_rarian_example_OBJECTS = rarian-example.$(OBJEXT) +rarian_example_OBJECTS = $(am_rarian_example_OBJECTS) +rarian_example_LDADD = $(LDADD) +rarian_example_DEPENDENCIES = ../librarian/librarian.la +am__rarian_sk_gen_uuid_SOURCES_DIST = rarian-sk-gen-uuid.c +@ENABLE_SK_COMPAT_TRUE@am_rarian_sk_gen_uuid_OBJECTS = \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-gen-uuid.$(OBJEXT) +rarian_sk_gen_uuid_OBJECTS = $(am_rarian_sk_gen_uuid_OBJECTS) +rarian_sk_gen_uuid_LDADD = $(LDADD) +rarian_sk_gen_uuid_DEPENDENCIES = ../librarian/librarian.la +am__rarian_sk_get_cl_SOURCES_DIST = rarian-sk-get-cl.cpp tinystr.cpp \ + tinyxml.cpp tinyxmlerror.cpp tinyxmlparser.cpp tinystr.h \ + tinyxml.h +@ENABLE_SK_COMPAT_TRUE@am_rarian_sk_get_cl_OBJECTS = rarian_sk_get_cl-rarian-sk-get-cl.$(OBJEXT) \ +@ENABLE_SK_COMPAT_TRUE@ rarian_sk_get_cl-tinystr.$(OBJEXT) \ +@ENABLE_SK_COMPAT_TRUE@ rarian_sk_get_cl-tinyxml.$(OBJEXT) \ +@ENABLE_SK_COMPAT_TRUE@ rarian_sk_get_cl-tinyxmlerror.$(OBJEXT) \ +@ENABLE_SK_COMPAT_TRUE@ rarian_sk_get_cl-tinyxmlparser.$(OBJEXT) +rarian_sk_get_cl_OBJECTS = $(am_rarian_sk_get_cl_OBJECTS) +rarian_sk_get_cl_LDADD = $(LDADD) +rarian_sk_get_cl_DEPENDENCIES = ../librarian/librarian.la +rarian_sk_get_cl_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__rarian_sk_migrate_SOURCES_DIST = rarian-sk-migrate.cpp tinystr.cpp \ + tinyxml.cpp tinyxmlerror.cpp tinyxmlparser.cpp tinystr.h \ + tinyxml.h ../librarian/rarian-reg-full.h \ + ../librarian/rarian-reg-full.c +@ENABLE_SK_COMPAT_TRUE@am_rarian_sk_migrate_OBJECTS = \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-migrate.$(OBJEXT) \ +@ENABLE_SK_COMPAT_TRUE@ tinystr.$(OBJEXT) tinyxml.$(OBJEXT) \ +@ENABLE_SK_COMPAT_TRUE@ tinyxmlerror.$(OBJEXT) \ +@ENABLE_SK_COMPAT_TRUE@ tinyxmlparser.$(OBJEXT) \ +@ENABLE_SK_COMPAT_TRUE@ rarian-reg-full.$(OBJEXT) +rarian_sk_migrate_OBJECTS = $(am_rarian_sk_migrate_OBJECTS) +rarian_sk_migrate_LDADD = $(LDADD) +rarian_sk_migrate_DEPENDENCIES = ../librarian/librarian.la +am__rarian_sk_preinstall_SOURCES_DIST = rarian-sk-preinstall.cpp \ + tinystr.cpp tinyxml.cpp tinyxmlerror.cpp tinyxmlparser.cpp \ + tinystr.h tinyxml.h +@ENABLE_SK_COMPAT_TRUE@am_rarian_sk_preinstall_OBJECTS = \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-preinstall.$(OBJEXT) \ +@ENABLE_SK_COMPAT_TRUE@ tinystr.$(OBJEXT) tinyxml.$(OBJEXT) \ +@ENABLE_SK_COMPAT_TRUE@ tinyxmlerror.$(OBJEXT) \ +@ENABLE_SK_COMPAT_TRUE@ tinyxmlparser.$(OBJEXT) +rarian_sk_preinstall_OBJECTS = $(am_rarian_sk_preinstall_OBJECTS) +rarian_sk_preinstall_LDADD = $(LDADD) +rarian_sk_preinstall_DEPENDENCIES = ../librarian/librarian.la +binSCRIPT_INSTALL = $(INSTALL_SCRIPT) +SCRIPTS = $(bin_SCRIPTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(rarian_example_SOURCES) $(rarian_sk_gen_uuid_SOURCES) \ + $(rarian_sk_get_cl_SOURCES) $(rarian_sk_migrate_SOURCES) \ + $(rarian_sk_preinstall_SOURCES) +DIST_SOURCES = $(rarian_example_SOURCES) \ + $(am__rarian_sk_gen_uuid_SOURCES_DIST) \ + $(am__rarian_sk_get_cl_SOURCES_DIST) \ + $(am__rarian_sk_migrate_SOURCES_DIST) \ + $(am__rarian_sk_preinstall_SOURCES_DIST) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASH = @BASH@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONVERT_DIR = @CONVERT_DIR@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_INSTALL = @ENABLE_INSTALL@ +ENABLE_OMF_READ = @ENABLE_OMF_READ@ +ENABLE_SKDB_UPDATE = @ENABLE_SKDB_UPDATE@ +ENABLE_SK_COMPAT = @ENABLE_SK_COMPAT@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +have_bash = @have_bash@ +have_xslt = @have_xslt@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I$(srcdir)/../librarian + +LDADD = \ + ../librarian/librarian.la + +@ENABLE_SK_COMPAT_TRUE@bin_SCRIPTS = rarian-sk-update \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-install rarian-sk-rebuild \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-config rarian-sk-get-scripts \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-get-content-list \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-get-extended-content-list \ +@ENABLE_SK_COMPAT_TRUE@ $(am__append_2) +DISTCLEANFILES = rarian-sk-update \ + rarian-sk-install \ + rarian-sk-rebuild \ + rarian-sk-config \ + rarian-sk-get-scripts \ + rarian-sk-get-content-list \ + rarian-sk-get-extended-content-list + +@ENABLE_SK_COMPAT_TRUE@rarian_sk_migrate_SOURCES = \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-migrate.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinystr.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinyxml.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinyxmlerror.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinyxmlparser.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinystr.h \ +@ENABLE_SK_COMPAT_TRUE@ tinyxml.h \ +@ENABLE_SK_COMPAT_TRUE@ ../librarian/rarian-reg-full.h \ +@ENABLE_SK_COMPAT_TRUE@ ../librarian/rarian-reg-full.c + +@ENABLE_SK_COMPAT_TRUE@rarian_sk_preinstall_SOURCES = \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-preinstall.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinystr.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinyxml.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinyxmlerror.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinyxmlparser.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinystr.h \ +@ENABLE_SK_COMPAT_TRUE@ tinyxml.h + +@ENABLE_SK_COMPAT_TRUE@rarian_sk_get_cl_SOURCES = \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-get-cl.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinystr.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinyxml.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinyxmlerror.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinyxmlparser.cpp \ +@ENABLE_SK_COMPAT_TRUE@ tinystr.h \ +@ENABLE_SK_COMPAT_TRUE@ tinyxml.h + +@ENABLE_SK_COMPAT_TRUE@rarian_sk_get_cl_CXXFLAGS = -DDATADIR=\""$(datadir)"\" -DLOCALSTATEDIR=\""$(localstatedir)"\" +@ENABLE_SK_COMPAT_TRUE@rarian_sk_gen_uuid_SOURCES = \ +@ENABLE_SK_COMPAT_TRUE@ rarian-sk-gen-uuid.c + +rarian_example_SOURCES = \ + rarian-example.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cpp .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu util/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu util/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +rarian-sk-update: $(top_builddir)/config.status $(srcdir)/rarian-sk-update.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +rarian-sk-install: $(top_builddir)/config.status $(srcdir)/rarian-sk-install.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +rarian-sk-rebuild: $(top_builddir)/config.status $(srcdir)/rarian-sk-rebuild.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +rarian-sk-config: $(top_builddir)/config.status $(srcdir)/rarian-sk-config.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +rarian-sk-get-scripts: $(top_builddir)/config.status $(srcdir)/rarian-sk-get-scripts.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +rarian-sk-extract: $(top_builddir)/config.status $(srcdir)/rarian-sk-extract.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +rarian-sk-get-content-list: $(top_builddir)/config.status $(srcdir)/rarian-sk-get-content-list.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +rarian-sk-get-extended-content-list: $(top_builddir)/config.status $(srcdir)/rarian-sk-get-extended-content-list.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +rarian-example$(EXEEXT): $(rarian_example_OBJECTS) $(rarian_example_DEPENDENCIES) + @rm -f rarian-example$(EXEEXT) + $(LINK) $(rarian_example_OBJECTS) $(rarian_example_LDADD) $(LIBS) +rarian-sk-gen-uuid$(EXEEXT): $(rarian_sk_gen_uuid_OBJECTS) $(rarian_sk_gen_uuid_DEPENDENCIES) + @rm -f rarian-sk-gen-uuid$(EXEEXT) + $(LINK) $(rarian_sk_gen_uuid_OBJECTS) $(rarian_sk_gen_uuid_LDADD) $(LIBS) +rarian-sk-get-cl$(EXEEXT): $(rarian_sk_get_cl_OBJECTS) $(rarian_sk_get_cl_DEPENDENCIES) + @rm -f rarian-sk-get-cl$(EXEEXT) + $(rarian_sk_get_cl_LINK) $(rarian_sk_get_cl_OBJECTS) $(rarian_sk_get_cl_LDADD) $(LIBS) +rarian-sk-migrate$(EXEEXT): $(rarian_sk_migrate_OBJECTS) $(rarian_sk_migrate_DEPENDENCIES) + @rm -f rarian-sk-migrate$(EXEEXT) + $(CXXLINK) $(rarian_sk_migrate_OBJECTS) $(rarian_sk_migrate_LDADD) $(LIBS) +rarian-sk-preinstall$(EXEEXT): $(rarian_sk_preinstall_OBJECTS) $(rarian_sk_preinstall_DEPENDENCIES) + @rm -f rarian-sk-preinstall$(EXEEXT) + $(CXXLINK) $(rarian_sk_preinstall_OBJECTS) $(rarian_sk_preinstall_LDADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f $$d$$p; then \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \ + else :; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rarian-example.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rarian-reg-full.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rarian-sk-gen-uuid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rarian-sk-migrate.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rarian-sk-preinstall.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rarian_sk_get_cl-rarian-sk-get-cl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rarian_sk_get_cl-tinystr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rarian_sk_get_cl-tinyxml.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rarian_sk_get_cl-tinyxmlerror.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rarian_sk_get_cl-tinyxmlparser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinystr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinyxml.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinyxmlerror.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinyxmlparser.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +rarian-reg-full.o: ../librarian/rarian-reg-full.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rarian-reg-full.o -MD -MP -MF $(DEPDIR)/rarian-reg-full.Tpo -c -o rarian-reg-full.o `test -f '../librarian/rarian-reg-full.c' || echo '$(srcdir)/'`../librarian/rarian-reg-full.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rarian-reg-full.Tpo $(DEPDIR)/rarian-reg-full.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../librarian/rarian-reg-full.c' object='rarian-reg-full.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rarian-reg-full.o `test -f '../librarian/rarian-reg-full.c' || echo '$(srcdir)/'`../librarian/rarian-reg-full.c + +rarian-reg-full.obj: ../librarian/rarian-reg-full.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rarian-reg-full.obj -MD -MP -MF $(DEPDIR)/rarian-reg-full.Tpo -c -o rarian-reg-full.obj `if test -f '../librarian/rarian-reg-full.c'; then $(CYGPATH_W) '../librarian/rarian-reg-full.c'; else $(CYGPATH_W) '$(srcdir)/../librarian/rarian-reg-full.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rarian-reg-full.Tpo $(DEPDIR)/rarian-reg-full.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../librarian/rarian-reg-full.c' object='rarian-reg-full.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rarian-reg-full.obj `if test -f '../librarian/rarian-reg-full.c'; then $(CYGPATH_W) '../librarian/rarian-reg-full.c'; else $(CYGPATH_W) '$(srcdir)/../librarian/rarian-reg-full.c'; fi` + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +rarian_sk_get_cl-rarian-sk-get-cl.o: rarian-sk-get-cl.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -MT rarian_sk_get_cl-rarian-sk-get-cl.o -MD -MP -MF $(DEPDIR)/rarian_sk_get_cl-rarian-sk-get-cl.Tpo -c -o rarian_sk_get_cl-rarian-sk-get-cl.o `test -f 'rarian-sk-get-cl.cpp' || echo '$(srcdir)/'`rarian-sk-get-cl.cpp +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rarian_sk_get_cl-rarian-sk-get-cl.Tpo $(DEPDIR)/rarian_sk_get_cl-rarian-sk-get-cl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='rarian-sk-get-cl.cpp' object='rarian_sk_get_cl-rarian-sk-get-cl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -c -o rarian_sk_get_cl-rarian-sk-get-cl.o `test -f 'rarian-sk-get-cl.cpp' || echo '$(srcdir)/'`rarian-sk-get-cl.cpp + +rarian_sk_get_cl-rarian-sk-get-cl.obj: rarian-sk-get-cl.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -MT rarian_sk_get_cl-rarian-sk-get-cl.obj -MD -MP -MF $(DEPDIR)/rarian_sk_get_cl-rarian-sk-get-cl.Tpo -c -o rarian_sk_get_cl-rarian-sk-get-cl.obj `if test -f 'rarian-sk-get-cl.cpp'; then $(CYGPATH_W) 'rarian-sk-get-cl.cpp'; else $(CYGPATH_W) '$(srcdir)/rarian-sk-get-cl.cpp'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rarian_sk_get_cl-rarian-sk-get-cl.Tpo $(DEPDIR)/rarian_sk_get_cl-rarian-sk-get-cl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='rarian-sk-get-cl.cpp' object='rarian_sk_get_cl-rarian-sk-get-cl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -c -o rarian_sk_get_cl-rarian-sk-get-cl.obj `if test -f 'rarian-sk-get-cl.cpp'; then $(CYGPATH_W) 'rarian-sk-get-cl.cpp'; else $(CYGPATH_W) '$(srcdir)/rarian-sk-get-cl.cpp'; fi` + +rarian_sk_get_cl-tinystr.o: tinystr.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -MT rarian_sk_get_cl-tinystr.o -MD -MP -MF $(DEPDIR)/rarian_sk_get_cl-tinystr.Tpo -c -o rarian_sk_get_cl-tinystr.o `test -f 'tinystr.cpp' || echo '$(srcdir)/'`tinystr.cpp +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rarian_sk_get_cl-tinystr.Tpo $(DEPDIR)/rarian_sk_get_cl-tinystr.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='tinystr.cpp' object='rarian_sk_get_cl-tinystr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -c -o rarian_sk_get_cl-tinystr.o `test -f 'tinystr.cpp' || echo '$(srcdir)/'`tinystr.cpp + +rarian_sk_get_cl-tinystr.obj: tinystr.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -MT rarian_sk_get_cl-tinystr.obj -MD -MP -MF $(DEPDIR)/rarian_sk_get_cl-tinystr.Tpo -c -o rarian_sk_get_cl-tinystr.obj `if test -f 'tinystr.cpp'; then $(CYGPATH_W) 'tinystr.cpp'; else $(CYGPATH_W) '$(srcdir)/tinystr.cpp'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rarian_sk_get_cl-tinystr.Tpo $(DEPDIR)/rarian_sk_get_cl-tinystr.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='tinystr.cpp' object='rarian_sk_get_cl-tinystr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -c -o rarian_sk_get_cl-tinystr.obj `if test -f 'tinystr.cpp'; then $(CYGPATH_W) 'tinystr.cpp'; else $(CYGPATH_W) '$(srcdir)/tinystr.cpp'; fi` + +rarian_sk_get_cl-tinyxml.o: tinyxml.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -MT rarian_sk_get_cl-tinyxml.o -MD -MP -MF $(DEPDIR)/rarian_sk_get_cl-tinyxml.Tpo -c -o rarian_sk_get_cl-tinyxml.o `test -f 'tinyxml.cpp' || echo '$(srcdir)/'`tinyxml.cpp +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rarian_sk_get_cl-tinyxml.Tpo $(DEPDIR)/rarian_sk_get_cl-tinyxml.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='tinyxml.cpp' object='rarian_sk_get_cl-tinyxml.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -c -o rarian_sk_get_cl-tinyxml.o `test -f 'tinyxml.cpp' || echo '$(srcdir)/'`tinyxml.cpp + +rarian_sk_get_cl-tinyxml.obj: tinyxml.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -MT rarian_sk_get_cl-tinyxml.obj -MD -MP -MF $(DEPDIR)/rarian_sk_get_cl-tinyxml.Tpo -c -o rarian_sk_get_cl-tinyxml.obj `if test -f 'tinyxml.cpp'; then $(CYGPATH_W) 'tinyxml.cpp'; else $(CYGPATH_W) '$(srcdir)/tinyxml.cpp'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rarian_sk_get_cl-tinyxml.Tpo $(DEPDIR)/rarian_sk_get_cl-tinyxml.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='tinyxml.cpp' object='rarian_sk_get_cl-tinyxml.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -c -o rarian_sk_get_cl-tinyxml.obj `if test -f 'tinyxml.cpp'; then $(CYGPATH_W) 'tinyxml.cpp'; else $(CYGPATH_W) '$(srcdir)/tinyxml.cpp'; fi` + +rarian_sk_get_cl-tinyxmlerror.o: tinyxmlerror.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -MT rarian_sk_get_cl-tinyxmlerror.o -MD -MP -MF $(DEPDIR)/rarian_sk_get_cl-tinyxmlerror.Tpo -c -o rarian_sk_get_cl-tinyxmlerror.o `test -f 'tinyxmlerror.cpp' || echo '$(srcdir)/'`tinyxmlerror.cpp +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rarian_sk_get_cl-tinyxmlerror.Tpo $(DEPDIR)/rarian_sk_get_cl-tinyxmlerror.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='tinyxmlerror.cpp' object='rarian_sk_get_cl-tinyxmlerror.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -c -o rarian_sk_get_cl-tinyxmlerror.o `test -f 'tinyxmlerror.cpp' || echo '$(srcdir)/'`tinyxmlerror.cpp + +rarian_sk_get_cl-tinyxmlerror.obj: tinyxmlerror.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -MT rarian_sk_get_cl-tinyxmlerror.obj -MD -MP -MF $(DEPDIR)/rarian_sk_get_cl-tinyxmlerror.Tpo -c -o rarian_sk_get_cl-tinyxmlerror.obj `if test -f 'tinyxmlerror.cpp'; then $(CYGPATH_W) 'tinyxmlerror.cpp'; else $(CYGPATH_W) '$(srcdir)/tinyxmlerror.cpp'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rarian_sk_get_cl-tinyxmlerror.Tpo $(DEPDIR)/rarian_sk_get_cl-tinyxmlerror.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='tinyxmlerror.cpp' object='rarian_sk_get_cl-tinyxmlerror.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -c -o rarian_sk_get_cl-tinyxmlerror.obj `if test -f 'tinyxmlerror.cpp'; then $(CYGPATH_W) 'tinyxmlerror.cpp'; else $(CYGPATH_W) '$(srcdir)/tinyxmlerror.cpp'; fi` + +rarian_sk_get_cl-tinyxmlparser.o: tinyxmlparser.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -MT rarian_sk_get_cl-tinyxmlparser.o -MD -MP -MF $(DEPDIR)/rarian_sk_get_cl-tinyxmlparser.Tpo -c -o rarian_sk_get_cl-tinyxmlparser.o `test -f 'tinyxmlparser.cpp' || echo '$(srcdir)/'`tinyxmlparser.cpp +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rarian_sk_get_cl-tinyxmlparser.Tpo $(DEPDIR)/rarian_sk_get_cl-tinyxmlparser.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='tinyxmlparser.cpp' object='rarian_sk_get_cl-tinyxmlparser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -c -o rarian_sk_get_cl-tinyxmlparser.o `test -f 'tinyxmlparser.cpp' || echo '$(srcdir)/'`tinyxmlparser.cpp + +rarian_sk_get_cl-tinyxmlparser.obj: tinyxmlparser.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -MT rarian_sk_get_cl-tinyxmlparser.obj -MD -MP -MF $(DEPDIR)/rarian_sk_get_cl-tinyxmlparser.Tpo -c -o rarian_sk_get_cl-tinyxmlparser.obj `if test -f 'tinyxmlparser.cpp'; then $(CYGPATH_W) 'tinyxmlparser.cpp'; else $(CYGPATH_W) '$(srcdir)/tinyxmlparser.cpp'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rarian_sk_get_cl-tinyxmlparser.Tpo $(DEPDIR)/rarian_sk_get_cl-tinyxmlparser.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='tinyxmlparser.cpp' object='rarian_sk_get_cl-tinyxmlparser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rarian_sk_get_cl_CXXFLAGS) $(CXXFLAGS) -c -o rarian_sk_get_cl-tinyxmlparser.obj `if test -f 'tinyxmlparser.cpp'; then $(CYGPATH_W) 'tinyxmlparser.cpp'; else $(CYGPATH_W) '$(srcdir)/tinyxmlparser.cpp'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(SCRIPTS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: install-binPROGRAMS install-binSCRIPTS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS + +.MAKE: install-am install-exec-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-binSCRIPTS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-exec-hook install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-binSCRIPTS + + +@ENABLE_INSTALL_TRUE@install-exec-hook: +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @echo Moving Files if needed +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-config ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-config; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-config ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-config $(DESTDIR)$(bindir)/scrollkeeper-config.real; fi +@ENABLE_EXTRACT_TRUE@@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-extract ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-extract; \ +@ENABLE_EXTRACT_TRUE@@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-extract ]; then \ +@ENABLE_EXTRACT_TRUE@@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-extract $(DESTDIR)$(bindir)/scrollkeeper-extract.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-gen-seriesid ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-gen-seriesid; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-gen-seriesid ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-gen-seriesid $(DESTDIR)$(bindir)/scrollkeeper-gen-seriesid.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-cl ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-cl; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-cl ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-get-cl $(DESTDIR)$(bindir)/scrollkeeper-get-cl.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-content-list ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-content-list; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-content-list ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-get-content-list $(DESTDIR)$(bindir)/scrollkeeper-get-content-list.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-extended-content-list ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-extended-content-list; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-extended-content-list ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-get-extended-content-list $(DESTDIR)$(bindir)/scrollkeeper-get-extended-content-list.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-index-from-docpath ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-index-from-docpath; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-index-from-docpath ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-get-index-from-docpath $(DESTDIR)$(bindir)/scrollkeeper-get-index-from-docpath.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-docpath ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-docpath; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-docpath ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-docpath $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-docpath.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-id ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-id; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-id ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-id $(DESTDIR)$(bindir)/scrollkeeper-get-toc-from-id.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-install ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-install; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-install ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-install $(DESTDIR)$(bindir)/scrollkeeper-install.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-preinstall ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-preinstall; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-preinstall ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-preinstall $(DESTDIR)$(bindir)/scrollkeeper-preinstall.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-rebuilddb ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-rebuilddb; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-rebuilddb ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-rebuilddb $(DESTDIR)$(bindir)/scrollkeeper-rebuilddb.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-uninstall ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-uninstall; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-uninstall ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-uninstall $(DESTDIR)$(bindir)/scrollkeeper-uninstall.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @if [ -h $(DESTDIR)$(bindir)/scrollkeeper-update ]; then rm $(DESTDIR)$(bindir)/scrollkeeper-update; \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ elif [ -e $(DESTDIR)$(bindir)/scrollkeeper-update ]; then \ +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ mv $(DESTDIR)$(bindir)/scrollkeeper-update $(DESTDIR)$(bindir)/scrollkeeper-update.real; fi +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-config scrollkeeper-config +@ENABLE_EXTRACT_TRUE@@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-extract scrollkeeper-extract +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-gen-uuid scrollkeeper-gen-seriesid +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-cl scrollkeeper-get-cl +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-content-list scrollkeeper-get-content-list +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-extended-content-list scrollkeeper-get-extended-content-list +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-scripts scrollkeeper-get-index-from-docpath +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-scripts scrollkeeper-get-toc-from-docpath +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-get-scripts scrollkeeper-get-toc-from-id +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-install scrollkeeper-install +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-preinstall scrollkeeper-preinstall +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-rebuild scrollkeeper-rebuilddb +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-install scrollkeeper-uninstall +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @cd $(DESTDIR)$(bindir); ln -s rarian-sk-update scrollkeeper-update +@ENABLE_INSTALL_TRUE@@ENABLE_SK_COMPAT_TRUE@ @mkdir -p $(DESTDIR)/$(localstatedir)/lib/rarian +@ENABLE_INSTALL_TRUE@@ENABLE_SKDB_UPDATE_TRUE@@ENABLE_SK_COMPAT_TRUE@ @echo "Translating current database" +@ENABLE_INSTALL_TRUE@@ENABLE_SKDB_UPDATE_TRUE@@ENABLE_SK_COMPAT_TRUE@ @$(DESTDIR)$(bindir)/rarian-sk-update + +@ENABLE_INSTALL_FALSE@install-exec-hook: +@ENABLE_INSTALL_FALSE@ @echo WARNING: Installed in UNINSTALLED mode. Prepare for things to be broken!!!!! +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/util/rarian-example.c b/util/rarian-example.c new file mode 100644 index 0000000..d203a19 --- /dev/null +++ b/util/rarian-example.c @@ -0,0 +1,122 @@ +/* + * rarian-example.c + * This file is part of Rarian + * + * Copyright (C) 2006 - Don Scorgie + * + * Rarian is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Rarian is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rarian; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include <stdio.h> +#include <stdlib.h> +#define I_KNOW_RARIAN_0_8_IS_UNSTABLE +#include <rarian.h> + +void +print_section (RrnSect *sect, int depth) +{ + int i=0; + RrnSect *child; + for (i=0; i < depth; i++) { + printf (" "); + } + printf ("Child: %s\n", sect->name); + for (i=0; i < depth; i++) { + printf (" "); + } + printf ("-> %s\n\n", sect->uri); + child = sect->children; + + while (child) { + print_section (child, depth+1); + child = child->next; + } + +} + +int +for_each_cb (RrnReg *reg, void * user_data) +{ + RrnSect *sect; + char **cats; + if (!reg) { + printf ("Error: No reg passed in!\n"); + exit (6); + } + printf ("Document: %s\n", reg->name); + printf ("-> %s\n", reg->uri); + printf ("-> ghelp:%s\n", reg->ghelp_name); + cats = reg->categories; + if (cats && *cats) + printf ("Categories:\n"); + while (cats && *cats) { + printf ("-> %s\n", *cats); + cats++; + } + printf ("\n"); + + sect = reg->children; + while (sect) { + print_section (sect, 1); + sect = sect->next; + } + + return TRUE; +} + +info_for_each (RrnInfoEntry *entry, void *data) +{ + if (entry->section) + printf ("Info page: %s\n\tPath: %s#%s\n\tComment: %s\n", + entry->doc_name, entry->base_filename, + entry->section, entry->comment); + else + printf ("Info page: %s\n\tPath: %s\n\tComment: %s\n", + entry->doc_name, entry->base_filename, + entry->comment); + return TRUE; +} + +man_for_each (RrnManEntry *entry, void *data) +{ + printf ("Man page %s\n", entry->name); + printf ("\tPath: %s\n", entry->path); + return TRUE; +} + +int +main(int argc, char *argv[]) +{ + char **cats = rrn_info_get_categories (); + char **iter = cats; + + rrn_man_for_each ((RrnManForeachFunc) man_for_each, NULL); + + while (iter && *iter) { + printf ("Info category: %s\n", *iter); + iter++; + } + + rrn_info_for_each ((RrnInfoForeachFunc) info_for_each, NULL); + + rrn_for_each((RrnForeachFunc) for_each_cb, NULL); + + rrn_shutdown (); + rrn_info_shutdown (); + rrn_man_shutdown (); + + return 0; +} diff --git a/util/rarian-sk-config.in b/util/rarian-sk-config.in new file mode 100644 index 0000000..c0ffbf0 --- /dev/null +++ b/util/rarian-sk-config.in @@ -0,0 +1,78 @@ +#!@BASH@ + +# Yet another simple wrapper for scrollkeeper wierdness +# This one emulates scrollkeeper-config, +# bugs and all. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +convert_dir=@CONVERT_DIR@ +statedir=@localstatedir@/lib/rarian +datarootdir=@datarootdir@ +datadir=@datadir@ +output_dir=${datadir}/help +package_version=@PACKAGE_VERSION@ +omf_read_enabled=@ENABLE_OMF_READ@ + + +print_help() +{ + echo "Usage: `basename $0` [OPTION]" + echo "(Rarian replacement for scrollkeeper-config)" + echo "" + echo "OPTION is one of:" + echo "" + echo -e " --help\t\tDisplay this message and exit" + echo -e " --version\t\tDisplay version for this package" + echo -e " --prefix\t\tPrint install directory" + echo -e " --localstatedir\t\tprint localstatedir used at package build time" + echo -e " --pkglocalstatedir\t\tprintscrollkeeper data directory" + echo -e " --pkgdatadir\t\tprint scrollkeeper home directory" + echo -e " --omfdir\t\t print OMF files directories (one per line)" + + + + +} + +if [[ $# != 1 ]] +then + print_help + exit +fi + +case "$1" in + --help ) + print_help + ;; + --version ) + echo $package_version \(Rarian replacement for scrollkeeper-config\) + ;; + --prefix ) + echo $prefix + ;; + --localstatedir ) + echo $statedir + ;; + --pkglocalstatedir ) + echo $statedir + ;; + --pkgdatadir ) + echo $datadir/librarian + ;; + --omfdir ) + if [ $omf_read_enabled = 0 ] + then + for x in $(grep -e '^0:@:' $statedir/rarian-update-mtimes > /dev/null 2>&1) + do + echo ${x##0:@:} + done + else + echo $datadir/omf + fi + ;; + * ) + print_help + ;; + esac diff --git a/util/rarian-sk-extract.in b/util/rarian-sk-extract.in new file mode 100644 index 0000000..c7adaef --- /dev/null +++ b/util/rarian-sk-extract.in @@ -0,0 +1,31 @@ +#!@BASH@ + +# Wrapper around xsltproc to mimic scrollkeeper-extract. +# +# Note that scrollkeeper internally uses libxslt for +# this, so this method is cheaper and achieves the same result + +print_usage() +{ + echo -e "Usage: " + echo -e "`basename $0` <xml file> <stylesheet 1> <output file 1> <stylesheet 2> <output file 2> ..." +} + +if [[ $# < 2 ]] +then + print_usage + exit 0 +fi + +infile=$1 +shift 1 + +while true; do + xsltproc --xinclude --xincludestyle $1 $infile > $2 + #echo "xml: $infile style: $1 out: $2" + shift 2 + if [[ $# < 2 ]]; + then + break + fi +done
\ No newline at end of file diff --git a/util/rarian-sk-gen-uuid.c b/util/rarian-sk-gen-uuid.c new file mode 100644 index 0000000..2fa0a31 --- /dev/null +++ b/util/rarian-sk-gen-uuid.c @@ -0,0 +1,70 @@ +/* + * rarian-sk-gen-uuid.c + * This file is part of Rarian + * + * Copyright (C) 2006 - Don scorgie + * + * Rarian is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Rarian is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rarian; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include <time.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +int main (int argc, char *argv[]) +{ + int i; + char *rand_string;//[38]; + char *tmp; + unsigned int r; + + r = time(NULL); + + tmp = malloc (sizeof(char) *2); + rand_string = malloc (sizeof(char) * 39); + *rand_string = '0'; + + srand (r); + for (i=0; i<8; i++) { + sprintf(tmp, "%x", (int) (((rand()*1.0) / (RAND_MAX*1.0)) * 16)); + strcat (rand_string, tmp); + } + rand_string[i] = '-'; + for (i=9; i < 13; i++) { + sprintf(tmp, "%x", (int) (((rand()*1.0) / (RAND_MAX*1.0)) * 16)); + strcat (rand_string, tmp); + } + rand_string[i] = '-'; + for (i=14; i < 18; i++) { + sprintf(tmp, "%x", (int) (((rand()*1.0) / (RAND_MAX*1.0)) * 16)); + strcat (rand_string, tmp); + } + rand_string[i] = '-'; + for (i=19; i < 23; i++) { + sprintf(tmp, "%x", (int) (((rand()*1.0) / (RAND_MAX*1.0)) * 16)); + strcat (rand_string, tmp); + } + rand_string[i] = '-'; + for (i=24; i < 37; i++) { + sprintf(tmp, "%x", (int) (((rand()*1.0) / (RAND_MAX*1.0)) * 16)); + strcat (rand_string, tmp); + } + + rand_string[i] = '0'; + printf ("%s\n", rand_string); + return 0; +} diff --git a/util/rarian-sk-get-cl.cpp b/util/rarian-sk-get-cl.cpp new file mode 100644 index 0000000..776b64c --- /dev/null +++ b/util/rarian-sk-get-cl.cpp @@ -0,0 +1,236 @@ +/* + * rarian-sk-get-cl.cpp + * This file is part of Rarian + * + * Copyright (C) 2006 - Don scorgie + * + * Rarian is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Rarian is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rarian; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#define I_KNOW_RARIAN_0_8_IS_UNSTABLE +#include <rarian.h> +#include <rarian-utils.h> +#include <tinyxml.h> +#include <sys/stat.h> +#include <sys/types.h> + +static char *cat = NULL; +static TiXmlElement *docs = NULL; +static int id = 0; + +void +print_usage (char *proc_name) +{ + printf ("Usage: %s <LOCALE> <CAT TREE NAME>\n", proc_name); + exit (0); +} + +void +get_attribute (TiXmlElement *elem) +{ + TiXmlAttribute* pAttrib=elem->FirstAttribute(); + if (strcmp (pAttrib->Value(), "")) { + char *new_cat = NULL; + char *iter = NULL; + char *st_iter = NULL; + char *tmp = NULL; + + cat = strdup (pAttrib->Value()); + /* Fix category to mimic scrollkeeper */ + new_cat = (char *) calloc (sizeof(char), strlen (cat)); + + st_iter = cat; + iter = cat; + while (iter && *iter) { + while (iter && *iter && *iter != '|') { + iter++; + } + tmp = rrn_strndup (st_iter, (iter-st_iter)); + if (*new_cat) { + strcat (new_cat, tmp); + } else { + strcpy (new_cat, tmp); + } + free (tmp); + if (*iter == '|') + iter++; + else + break; + st_iter = iter; + } + elem->SetAttribute("categorycode", new_cat); + + } +} + +int +get_docs (RrnReg *reg, TiXmlNode *pParent) +{ + if (reg->omf_location) { + TiXmlElement * doc = new TiXmlElement ("doc"); + TiXmlElement * entry; + TiXmlElement * text; + char *tmp; + + doc->SetAttribute ("id", id); + id++; + + /* doctitle */ + entry = new TiXmlElement ("doctitle"); + entry->LinkEndChild (new TiXmlText (reg->name)); + doc->LinkEndChild (entry); + + /* docomf */ + entry = new TiXmlElement ("docomf"); + entry->LinkEndChild (new TiXmlText (reg->omf_location)); + doc->LinkEndChild (entry); + + /* docsource */ + tmp = reg->uri + 7;// Remove file:// + entry = new TiXmlElement ("docsource"); + entry->LinkEndChild (new TiXmlText (tmp)); + doc->LinkEndChild (entry); + + /* docformat */ + entry = new TiXmlElement ("docformat"); + entry->LinkEndChild (new TiXmlText (reg->type)); + doc->LinkEndChild (entry); + + /* docseriesid */ + tmp = reg->identifier + 17;// remove org.scrollkeeper. + entry = new TiXmlElement ("docseriesid"); + entry->LinkEndChild (new TiXmlText (tmp)); + doc->LinkEndChild (entry); + pParent->LinkEndChild (doc); + + } + + return 0; +} + +void +process_node (TiXmlNode *pParent) +{ + TiXmlNode* pChild; + TiXmlText* pText; + int t = pParent->Type(); + int num; + + switch ( t ) + { + case TiXmlNode::DOCUMENT: + break; + + case TiXmlNode::ELEMENT: + if (!strcmp (pParent->Value(), "sect")) { + get_attribute (pParent->ToElement()); + rrn_for_each_in_category ((RrnForeachFunc) get_docs, cat, pParent); + free (cat); + + } + default: + break; + } + + for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) + { + process_node ( pChild); + } +} + + +/* Find a suitable file to dump out output to. + * for now, we're always going to the same file + */ +char * +find_dump_name () +{ + char *filename = NULL; + char *user = getenv ("USERNAME"); + char *basepath = NULL; + int i=0; + int last = 0; + unsigned int lasttime = 0; + int init = 1; + + if (!user) { + /* if USERNAME isn't set, we use the "default" username: UNKNOWN */ + user = strdup ("UNKNOWN"); + } + + basepath = (char *) malloc (sizeof(char) * (strlen(user) + 18 /*/tmp/scrollkeeper.*/ + 1)); + sprintf (basepath, "/tmp/scrollkeeper-%s", user); + mkdir(basepath, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + + + filename = (char *) malloc (sizeof(char) * (strlen(user) + 18 /*/tmp/scrollkeeper.*/ + 10 /*contents.0*/) + 1); + + for (i=0 ;i<5; i++) { + struct stat sbuf; + sprintf (filename, "/tmp/scrollkeeper-%s/contents.%d", user, i); + if (stat(filename,&sbuf) == -1) { + last = i; + break; + } + if (sbuf.st_mtime < lasttime || init) { + init = 0; + last = i; + lasttime = sbuf.st_mtime; + } + } + sprintf (filename, "/tmp/scrollkeeper-%s/contents.%d", user, last); + + return filename; +} + +int main (int argc, char * argv[]) +{ + int skip = 0; + + if (argc < 3 || argc > 4) { + print_usage (argv[0]); + } + if (!strcmp(argv[1], "-v")) { + skip = 1; + } + + if (strcmp (argv[2+skip], "scrollkeeper_extended_cl.xml") && + strcmp (argv[2+skip], "scrollkeeper_cl.xml")) { + print_usage (argv[0]); + } + bool loadok; + + rrn_set_language (argv[1+skip]); + + TiXmlDocument doc (DATADIR"/librarian/rarian-sk-cl.xml"); + loadok = doc.LoadFile(TIXML_ENCODING_UTF8); + + if (!loadok) { + fprintf (stderr, "ERROR: Cannot parse template file. Aborting.\n"); + exit (2); + } + + TiXmlNode *pParent = doc.FirstChildElement(); + + process_node (pParent); + + char *filename = find_dump_name (); + doc.SaveFile(filename); + printf ("%s\n", filename); + + exit (0); + +} diff --git a/util/rarian-sk-get-content-list.in b/util/rarian-sk-get-content-list.in new file mode 100644 index 0000000..b123774 --- /dev/null +++ b/util/rarian-sk-get-content-list.in @@ -0,0 +1,23 @@ +#! /bin/sh + +# Simple wrapper to make calling scrollkeeper-get-cl easier +# Copied and edited from scrollkeeper source tree + +usage() +{ + cat <<EOF +Usage: `basename $0` <LOCALE> +EOF + + exit $1 +} + +if test $# -ne 1; then + usage 1 +fi + +# Assume we're installed in the same place as get-cl +# If it ain't in the normal path, this is needed +`dirname $0`/rarian-sk-get-cl $1 scrollkeeper_cl.xml + +exit $?
\ No newline at end of file diff --git a/util/rarian-sk-get-extended-content-list.in b/util/rarian-sk-get-extended-content-list.in new file mode 100644 index 0000000..a20444a --- /dev/null +++ b/util/rarian-sk-get-extended-content-list.in @@ -0,0 +1,23 @@ +#! /bin/sh + +# Simple wrapper to make calling scrollkeeper-get-cl (extended) easier +# Copied and edited from scrollkeeper source tree + +usage() +{ + cat <<EOF +Usage: `basename $0` <LOCALE> +EOF + + exit $1 +} + +if test $# -ne 1; then + usage 1 +fi + +# Assume we're installed in the same place as get-cl +# If it ain't in the normal path, this is needed +`dirname $0`/rarian-sk-get-cl $1 scrollkeeper_extended_cl.xml + +exit $?
\ No newline at end of file diff --git a/util/rarian-sk-get-scripts.in b/util/rarian-sk-get-scripts.in new file mode 100644 index 0000000..eec1980 --- /dev/null +++ b/util/rarian-sk-get-scripts.in @@ -0,0 +1,13 @@ +#!/bin/sh + +# More zero-effect scripts. The scripts these replace seem to +# not do anything on my machine (any files they try and access +# don't exist). Therefore, they get ignored for now, since +# I've never even seen them used. Ever. Sigh. + +# replaces: +# scrollkeeper-get-index-from-index-from-docpath +# scrollkeeper-get-toc-from-docpath +# scrollkeeper-get-toc-from-id + +exit
\ No newline at end of file diff --git a/util/rarian-sk-install.in b/util/rarian-sk-install.in new file mode 100644 index 0000000..ba514d0 --- /dev/null +++ b/util/rarian-sk-install.in @@ -0,0 +1,30 @@ +#!/bin/sh + +# A simple replacement for scrollkeeper-install / scrollkeeper-uninstall +# scrollkeeper-preinstall +# The real program install program is called from scrollkeeper-update +# The real uninstall program isn't used. Ever. +# scrollkeeper-preinstall is another random program. I've read the +# source and still can't figure out exactly what it does. It seems +# to do some stuff that should be really done by configure scripts +# (replacing the docpath with another) + +# In the New World Order, these are unneccessary, so we just ignore +# them and exit happily. + +# However, since these are installed and available for use, we +# have to "emulate" them by (basically) returning true. +# Don't ever ask me why scrollkeeper works the way it does. I'll +# bore you to tears. + +# Anyway, if you've read this far, the license for this file is simple: +# Use it however you want. Seriously, if you want to give me credit +# for an empty file, go ahead. Use it any way you want. I offer +# no guarentees about functioning correctly, however since the script +# is simpler than "Hello World", I don't think it'll go wrong. + +# We ignore all user input and return +# Update. + + +exit 0
\ No newline at end of file diff --git a/util/rarian-sk-migrate.cpp b/util/rarian-sk-migrate.cpp new file mode 100644 index 0000000..4294eb3 --- /dev/null +++ b/util/rarian-sk-migrate.cpp @@ -0,0 +1,313 @@ +/* + * rarian-sk-migrate.cpp + * This file is part of Rarian + * + * Copyright (C) 2006 - Don scorgie + * + * Rarian is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Rarian is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rarian; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + + +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <unistd.h> + +#include <tinyxml.h> +#define I_KNOW_RARIAN_0_8_IS_UNSTABLE +#include <rarian.h> +#include <rarian-reg-full.h> + +#include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <time.h> + +static RrnRegFull *reg = NULL; +static RrnReg *tmp_reg = NULL; +static char *lang; +static char *sk_series; +static char *new_series; +static char *type; +static char *categories; + +static bool am_parsing = false; + +enum ElemType { + REG_NAME, + REG_URI, + REG_DESC, + REG_LANG, + REG_SERIES, + REG_TYPE, + REG_CATEGORIES +}; + +void +dump_extended_keyfile (char *path, char *base) +{ + RrnListEntry *iter; + + printf ("# File generated from scrollkeeper files %s/%s-*.omf\n", path, base); + printf ("# This should be replaced by the new keyfile at some point"); + + printf ("\n[Document]\n\n"); + + iter = reg->name; + while (iter) { + if (!iter->lang || !strcmp (iter->lang, "C")) { + printf ("Name=%s\n", iter->text); + } else { + printf ("Name[%s]=%s\n", iter->lang, iter->text); + } + iter = iter->next; + } + iter = reg->comment; + while (iter) { + if (!iter->lang || !strcmp (iter->lang, "C")) { + printf ("Comment=%s\n", iter->text); + } else { + printf ("Comment[%s]=%s\n", iter->lang, iter->text); + } + iter = iter->next; + } + iter = reg->uri; + while (iter) { + if (!iter->lang || !strcmp (iter->lang, "C")) { + printf ("DocPath=%s\n", iter->text); + } else { + printf ("DocPath[%s]=%s\n", iter->lang, iter->text); + } + iter = iter->next; + } + if (type) { + printf ("DocType=%s\n", type); + } else { + printf ("DocType=\n"); + } + if (new_series) { + printf ("DocIdentifier=%s\n", new_series); + } else { + fprintf (stderr, "ERROR: new series is undefined!\n"); + } + if (categories) { + printf ("Categories=%s\n", categories); + } + if (new_series) { + printf ("x-DocHeritage=%s\n", new_series); + } + printf ("x-Scrollkeeper-omf-loc=%s/%s-*.omf\n", path, base); + +} + + +void +add_info () +{ + if (!lang) { + lang = strdup ("C"); + } + reg->uri = rrn_full_add_field (reg->uri, tmp_reg->uri, lang); + reg->comment = rrn_full_add_field (reg->comment, tmp_reg->comment, lang); + reg->name = rrn_full_add_field (reg->name, tmp_reg->name, lang); + +} + +void +get_attribute (TiXmlElement *elem, ElemType e) +{ + TiXmlAttribute* pAttrib=elem->FirstAttribute(); + if (e == REG_URI && strcmp (pAttrib->Value(), "")) { + tmp_reg->uri = strdup (pAttrib->Value()); + } else if (e == REG_URI && !strcmp(pAttrib->Value(), "")){ + tmp_reg->uri = strdup (""); + } else if (e == REG_LANG) { + if (strcmp (pAttrib->Value(), "")) { + lang = strdup (pAttrib->Value()); + } + } else if (e == REG_SERIES) { + if (strcmp (pAttrib->Value(), "")) { + if (!sk_series) { + sk_series = strdup (pAttrib->Value()); + } + } + } else if (e == REG_TYPE && strcmp (pAttrib->Value(), "")) { + if (!type) { + type = strdup (pAttrib->Value()); + } + } else if (e == REG_TYPE && !strcmp (pAttrib->Value(), "")) { + /* Do nothing */ + } else if (e == REG_CATEGORIES && strcmp (pAttrib->Value(), "")) { + if (!categories) { + categories = strdup (pAttrib->Value()); + } + } else if (e == REG_CATEGORIES && !strcmp (pAttrib->Value(), "")) { + /* Do Nothing */ + } else { + printf ("ERROR: Trying to get attribute from unknown entry type. Exiting\n"); + exit (7); + } +} + +void +get_text (TiXmlNode* pElement, ElemType e) +{ + + if (!pElement) { + if (e == REG_NAME) { + tmp_reg->name = strdup (" "); + } else { + tmp_reg->comment = strdup (" "); + } + return; + } + if (e == REG_NAME) { + tmp_reg->name = strdup (pElement->Value()); + } else if (e == REG_DESC ) { + tmp_reg->comment = strdup (pElement->Value()); + } + +} + +void +process_node (TiXmlNode *pParent) +{ + TiXmlNode* pChild; + TiXmlText* pText; + int t = pParent->Type(); + int num; + ElemType e; + + + switch ( t ) + { + case TiXmlNode::DOCUMENT: + break; + + case TiXmlNode::ELEMENT: + if (!strcmp (pParent->Value(), "omf")) { + am_parsing = true; + } else if (!am_parsing) { + printf ("ERROR: Does not appear to be a valid OMF file. Aborting\n"); + exit (6); + } + if (!strcmp (pParent->Value(), "title")) { + e = REG_NAME; + get_text (pParent->FirstChild(), e); + } else if (!strcmp (pParent->Value(), "description")) { + e = REG_DESC; + get_text (pParent->FirstChild(), e); + } else if (!strcmp (pParent->Value(), "identifier")) { + e = REG_URI; + get_attribute (pParent->ToElement(), e); + } else if (!strcmp (pParent->Value(), "language")) { + e = REG_LANG; + get_attribute (pParent->ToElement(), e); + } else if (!strcmp (pParent->Value(), "relation")) { + e = REG_SERIES; + get_attribute (pParent->ToElement(), e); + } else if (!strcmp (pParent->Value(), "format")) { + e = REG_TYPE; + get_attribute (pParent->ToElement(), e); + } else if (!strcmp (pParent->Value(), "subject")) { + e = REG_CATEGORIES; + get_attribute (pParent->ToElement(), e); + } + break; + default: + break; + } + + for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) + { + process_node ( pChild); + } +} + +void +process_file (char *path, char *fname) +{ + char *name = NULL; + int size = 0; + bool loadok; + + size += strlen (path); + size += strlen (fname); + size += 2; + + tmp_reg = rrn_reg_new (); + + name = (char *) malloc (sizeof (char) * size); + sprintf (name, "%s/%s", path, fname); + + TiXmlDocument doc (name); + loadok = doc.LoadFile(TIXML_ENCODING_UTF8); + + if (!loadok) { + fprintf (stderr, "ERROR: Cannot parse %s. Is it valid?\n", name); + exit (2); + } + + TiXmlNode *pParent = doc.FirstChildElement(); + + process_node (pParent); + + add_info (); + + rrn_reg_free (tmp_reg); + free (name); +} + +int main (int argc, char * argv[]) +{ + DIR * dirp = NULL; + struct dirent * dp = NULL; + struct stat buf; + char *path = NULL; + + if (argc != 3 || access (argv[1], R_OK)) { + fprintf (stderr, "ERROR: Cannot access directory %s\n", argv[1]); + } + reg = rrn_reg_new_full (); + + dirp = opendir (argv[1]); + while (1) { + if ((dp = readdir(dirp)) != NULL) { + stat(dp->d_name,&buf); + if (buf.st_mode == S_IFREG && !strncmp (dp->d_name, argv[2], strlen (argv[2]))) { + process_file (argv[1], dp->d_name); + } + } else { + break; + } + } + + if (sk_series) { + new_series = (char *) malloc (sizeof (char) * 255); + sprintf (new_series, "org.scrollkeeper.%s", sk_series); + } else { + time_t t1; + + time(&t1); + + new_series = (char *) malloc (sizeof (char) * 255); + sprintf (new_series, "org.scrollkeeper.undefined.%d", (long) t1); + } + dump_extended_keyfile (argv[1], argv[2]); + + exit (0); +} diff --git a/util/rarian-sk-preinstall.cpp b/util/rarian-sk-preinstall.cpp new file mode 100644 index 0000000..0bbff67 --- /dev/null +++ b/util/rarian-sk-preinstall.cpp @@ -0,0 +1,141 @@ +/* + * rarian-sk-preinstall.cpp + * This file is part of Rarian + * + * Copyright (C) 2006 - Don scorgie + * + * Rarian is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Rarian is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rarian; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + + +#include <tinyxml.h> + +#include <stdio.h> + +static char *new_url = NULL; + +static bool am_parsing = false; + +void +print_usage (char *proc_name) +{ + printf ("Usage: %s [-n] <INSTALLED_DOC_NAME> <OLD OMF FILE> <NEW OMF FILENAME>\n", proc_name); + printf ("\nExample: %s /usr/share/help/beanstalk.xml beanstalk.omf new-beanstalk.omf\n", proc_name); + printf ("The -n flag is now ignored (it is no longer needed).\n"); + exit (0); +} + +void +get_attribute (TiXmlElement *elem) +{ + TiXmlAttribute* pAttrib=elem->FirstAttribute(); + if (strcmp (pAttrib->Value(), "")) { + + elem->SetAttribute("url", new_url); + } +} + +void +process_node (TiXmlNode *pParent) +{ + TiXmlNode* pChild; + TiXmlText* pText; + int t = pParent->Type(); + int num; + + switch ( t ) + { + case TiXmlNode::DOCUMENT: + break; + + case TiXmlNode::ELEMENT: + if (!strcmp (pParent->Value(), "omf")) { + am_parsing = true; + } else if (!am_parsing) { + printf ("ERROR: Does not appear to be a valid OMF file. Aborting\n"); + exit (6); + } + if (!strcmp (pParent->Value(), "identifier")) { + get_attribute (pParent->ToElement()); + } + default: + break; + } + + for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) + { + process_node ( pChild); + } +} + +void +process_new_url (char *input) +{ + if (!strncmp (input, "file:", 5)) { + new_url = strdup (input); + } else { + int i = 0; + char *t = input; + + while (*t == '/') { + i++; + t++; + } + if (i == 1) { + /* Normal path. Add file:/ to the start */ + new_url = (char *) malloc (sizeof(char) * (strlen (input) + 7)); + sprintf (new_url, "file:/%s", input); + } else { + /* Don't know what to do. Just copy and append file: to it */ + new_url = (char *) malloc (sizeof(char) * (strlen(input) + 6)); + sprintf (new_url, "file:%s", input); + } + } +} + +int main (int argc, char * argv[]) +{ + int skip = 0; + if (argc < 3 || argc > 4) { + print_usage (argv[0]); + } + + if (!strcmp(argv[1], "-n")) + skip = 1; + + process_new_url (argv[1+skip]); + + + bool loadok; + + TiXmlDocument doc (argv[2+skip]); + loadok = doc.LoadFile(TIXML_ENCODING_UTF8); + + if (!loadok) { + fprintf (stderr, "ERROR: Cannot parse %s. Is it valid?\n", argv[2+skip]); + exit (2); + } + + TiXmlNode *pParent = doc.FirstChildElement(); + + process_node (pParent); + + doc.SaveFile(argv[3+skip]); + + free (new_url); + + exit (0); +} diff --git a/util/rarian-sk-rebuild.in b/util/rarian-sk-rebuild.in new file mode 100644 index 0000000..f79e9b0 --- /dev/null +++ b/util/rarian-sk-rebuild.in @@ -0,0 +1,38 @@ +#!@BASH@ + +# Another simple wrapper script. This time for scrollkeeper-rebuilddb +# This one is slightly more complex in that we have to run a command! +# We also need to pull out the paths from the relevant place first. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +convert_dir=@CONVERT_DIR@ +datarootdir=@datarootdir@ +statedir=@localstatedir@/lib/rarian +datadir=@datadir@ +output_dir=${datadir}/help +package_version=@PACKAGE_VERSION@ +convert_string="REPLACEME" + +if [ ! @ENABLE_OMF_READ@ ] +then + +if [ -e $statedir/rarian-update-mtimes ] +then + for x in $(grep -e '^0:@:' $statedir/rarian-update-mtimes) + do + if [[ $convert_string != "REPLACEME" ]] + then + convert_string=$convert_string:${x##0:@:} + else + convert_string=${x##0:@:} + fi + done +else + convert_string=$convert_dir +fi + +$bindir/rarian-sk-update -v --clean-index -o $convert_string + +fi
\ No newline at end of file diff --git a/util/rarian-sk-update.in b/util/rarian-sk-update.in new file mode 100755 index 0000000..8a26a9a --- /dev/null +++ b/util/rarian-sk-update.in @@ -0,0 +1,425 @@ +#!@BASH@ + +# This script is designed to replace scrollkeeper-update +# It iterates through all the directories specified using -o <dir_list> +# If these aren't specified, the default convert_dir is used +# (typically /usr/share/omf) and checks whether the last-modified time for +# the directory has changed from the previous run. +# The previous timings are stored in output_dir/.rarian-update-mtimes +# in the file format: +# <mtime>:@:<dir_name>:@:<converted filenames> +# For top-level directories, the mtime is '0' +# When multiple scrolls are generated from a single omf subdir, +# the scroll names are seperated by a semi-colon. + +# I'll annotate the rest of the scirpt +# If you want more info, please ping me and I'll try and help. + + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +statedir=@localstatedir@/lib/rarian +convert_dir=@CONVERT_DIR@ +datarootdir=@datarootdir@ +datadir=@datadir@ +output_dir=${datadir}/help +package_version=@PACKAGE_VERSION@ +real_convert[0]=$convert_dir +skip_omf_translate=@ENABLE_OMF_READ@ + +# Print the version info for this file +print_version() +{ + echo "`basename $0` version 0.9" + echo "This script is distributed as part of Rarian v$package_version" + echo "Use '`basename $0` --help' for options and instructions for running" + echo "" + echo "Have a nice day!" + + exit 0 +} + +# Standard help message +print_usage() +{ + echo "Usage: `basename $0` [OPTIONS]" + echo "Update Rarian scrolls archive from scrollkeeper omf files." + echo "Note: This script is a replacement for scrollkeeper-update, but" + echo "does not update the scrollkeeper internal database." + echo "" + echo "Options:" + echo -e "-o DIR\t\t\t\tUse the specified omf directories for" + echo -e "\t\t\t\tconversion. Multiple directories can be " + echo -e "\t\t\t\tspecified using colon (:) separator." + echo -e "-r DIR\t\t\t\tUse the specified directory for the"\ + "resulting" + echo -e "\t\t\t\tscrolls. If the directory doesn't exist, it" + echo -e "\t\t\t\twill be created at run time." + echo -e "\t\t\t\t Note: Multiple output paths are not supported" + echo -e "--c\t\t\t\tRebuild the index entirely. This will rebuild" + echo -e "\t\t\t\tall scroll files and may take a long time." + echo -e "-v\t\t\t\tTurn Verbosity on." + echo -e "-p\t\t\t\tSpecify a different place to store the mtimes file." + echo -e "-q\t\t\t\tRun silently (default)." + echo -e "-h, -?\t\t\t\tPrint this help message and exit." + echo "" + echo "Using this script without option will use the default omf directory" + echo "'$convert_dir' and the default output directory '$output_dir'" + + echo "" + if [ $skip_omf_translate != 0 ] + then + echo "NOTE (2): This script doesn't do anything and is " + echo "only provided for scrollkeeper compatibility" + fi + exit 0 +} + +# Nice print function to call when we're in verbose mode. +# In normal mode, it's a no-op. +print_verbose() +{ + if [ $verbose ] + then + echo "$1" + fi +} + + +# Process_dir handles the calling of the migration program +# It calls the program with the correct parameters +# and moves the results to the correct place. +process_dir() +{ + fname_list="" + old_basename="" + for f in $1/*.omf; do + bname=$(basename $f) + bname=${bname%-*.omf} + if [[ $bname != $old_basename ]] + then + old_basename=$bname + filename=$bname.document + fname_list=$fname_list$filename";" + if $bindir/rarian-sk-migrate $(dirname $f) ${bname%-*.omf} > $tmpdir/tmp.rarian + then + cp $tmpdir/tmp.rarian $output_dir/$filename + rm $tmpdir/tmp.rarian + else + echo "Error: Cannot process file "$f". See "$tmpdir"/tmp.rarian for the reason." + exit 5 + fi + fi + done + echo -e `stat -c %Y $1`':@:'$1':@:'$fname_list >> $tmpdir/rarian-updates +} + +# Split up the omf dirs specified on the command line +# I've never seen this used in practice, but +# better safe than sorry +split_omf_dirs () +{ + let counter=0 + while [ $convert_dir ] + do + entry=`echo $convert_dir | cut -d ':' -f 1` + convert_dir=${convert_dir#$entry} + convert_dir=${convert_dir#:} + real_convert[$counter]=$entry + let counter+=1 + done + +} + +# Determine whether the directory defined within the index file +# was specified in the convert_dirs +am_adding_dir () +{ + let counter=0 + am_processing="0" + for i in ${real_convert[@]} + do + if [[ $fname == $i ]] + then + real_convert[$counter]="0" + am_processing="1" + return + fi + let counter+=1 + done +} + +# The directory wasn't specified. This does nothing except cat the +# relevant lines from the old file to the new one +skip_directory () +{ + read line + time=`echo $line | awk -F ":@:" '{print $1}'` + while [[ $time -ne 0 ]] + do + echo $line + echo $line >> $tmpdir/rarian-updates + read line + time=`echo $line | awk -F ":@:" '{print $1}'` + done +} + +# Go through the given directory and add all subdirs (containing omfs) +# to the index file (and convert the omf's to scrolls) +add_all_files () +{ + for i in $(ls $fname); + do + if [ -d $fname/$i ] + then + print_verbose "$fname/$i is new and will be added" + process_dir $fname/$i + fi + done + read line +} + +# If the given directory actually exists within the omf dir +dirs_contains () +{ + let counter=0 + am_processing="0" + for i in ${entries[@]} + do + if [[ $1 == $i ]] + then + entries[$counter]="0" + am_processing="1" + return + fi + let counter+=1 + done +} + +# The meat. Goes through and checks each directory mtime against the +# cached version. If they're different, regenerate the scroll. +# If the dir has been removed, delete. +process_directory () +{ + let counter=0 + for i in $(ls $fname) + do + entries[$counter]="$fname/$i" + let counter+=1 + done + + read line + + old_time=`echo $line | awk -F ":@:" '{print $1}'` + + while [[ $old_time && $old_time != "0" ]] + do + name=`echo $line | awk -F ":@:" '{print $2}'` + + dirs_contains $name + + if [[ $am_processing != "0" ]] + then + new_time=`stat -c %Y $name` + if [[ $new_time -ne $old_time ]] + then + print_verbose "Directory $name has changed. Updating." + process_dir $name + else + echo $line >> $tmpdir/rarian-updates + fi + else + filenames=`echo $line | awk -F ":@:" '{print $3}'` + while [[ $filenames ]] + do + entry=`echo $filenames | cut -d ';' -f 1` + print_verbose "Directory resonsible for $entry has been removed. Deleting" + filenames=${filenames#$entry} + filenames=${filenames#;} + mv $entry $tmpdir + done + + fi + + read line + old_time=`echo $line | awk -F ":@:" '{print $1}'` + done + + for i in ${entries[@]} + do + if [[ $i != "0" ]] + then + print_verbose "Directory $i is new and will be added." + process_dir $i + fi + done +} + + + +# Beginning of the main chunk of the script + +# Sorry for the stupid naming of options. +# They are inherited from scrollkeeper :( + +# We use TEMP as set -- seems to nuke the return value of getopt +TEMP=`getopt -u -n$(basename $0) -o "o:r:p:vqnhV" \ + -- "$@"` \ + || print_usage + +if [ $? != 0 ] ; then + print_usage + exit 0 +fi + +eval set -- "$TEMP" + +while true; do + case "$1" in + -o ) + convert_dir=$2 + update_output_dir=1 + shift 2 + ;; + -r ) + output_dir=$2 + overload_update=1 + shift 2 + ;; + -v ) + verbose=1 + shift + ;; + -q ) + shift + ;; + -c ) + clean_index=1 + shift + ;; + -h | -\? ) + print_usage + ;; + -n ) + # Scrollkeeper compat. Actually do nothing + shift + ;; + -p ) + statedir=$2 + shift 2 + ;; + -V | --version ) + print_version + ;; + * ) + break + ;; + esac +done + +if [ $verbose ] +then + echo "Verbosity turned on" +fi + +if [ $skip_omf_translate = 0 ] +then + +split_omf_dirs + +if [ $update_output_dir ] && [ ! $overload_update ] +then + # We assume here that people are sensible and put the + # omf files in <prefix>/share/omf + # Also assumes only a single omf path + print_verbose "Using non-installed location" + output_dir=`dirname $real_convert[0]`/help +fi + +print_verbose "Outputting to $output_dir" + +if [ $clean_index ] +then + print_verbose "Removing index file $statedir/rarian-update-mtimes" + rm $statedir/rarian-update-mtimes > /dev/null 2>&1 +fi + + +tmpdir=/tmp/rarian-$RANDOM +mkdir $tmpdir + +if [ ! -d $output_dir ] +then + mkdir -p $output_dir +fi + +if [ ! -d $statedir ] +then + mkdir -p $statedir +fi + + +res=$(touch $statedir/rarian-update-mtimes > /dev/null 2>&1) + +if [ $? -ne 0 ] +then + echo "Error: Unable to write to the output directory $output_dir." + echo "write permission is needed in order to run" + echo "this script. If you don't have it, things" + echo "break. Please run this script with the correct" + echo "permissions (normally root). Exiting." + exit 3 +fi + +exec < $statedir/rarian-update-mtimes + +read line +fname=`echo $line | awk -F ":@:" '{print $2}'` + + +while [[ $fname != "" ]] +do + print_verbose "Processing directory $fname" + echo "0:@:$fname" >> $tmpdir/rarian-updates + am_adding_dir $fname + if [[ ! $(ls $fname 2>&1) ]] + then + print_verbose "Previous directory $fname no longer exists" + else + if [[ $am_processing != "0" ]] + then + process_directory + else + skip_directory + fi + fname=`echo $line | awk -F ":@:" '{print $2}'` + fi +done + +for i in ${real_convert[@]} +do + if [[ $i != "0" ]] + then + res=$(ls $i 2>/dev/null) + if [[ ! $res ]] + then + print_verbose "Path $i does not exist. Ignoring" + else + + print_verbose "Adding contents of directory $i" + fname=$i + echo "0:@:$fname" >> $tmpdir/rarian-updates + add_all_files + fi + fi +done + +rm -f $statedir/rarian-update-mtimes +if [ -e $tmpdir/rarian-updates ] +then + mv $tmpdir/rarian-updates $statedir/rarian-update-mtimes +fi +rm -rf $tmpdir + +fi # ENABLE_OMF_READ
\ No newline at end of file diff --git a/util/tinystr.cpp b/util/tinystr.cpp new file mode 100644 index 0000000..4125242 --- /dev/null +++ b/util/tinystr.cpp @@ -0,0 +1,115 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +/* + * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005. + */ + + +#ifndef TIXML_USE_STL + +#include "tinystr.h" + +// Error value for find primitive +const TiXmlString::size_type TiXmlString::npos = static_cast< size_type >(-1); + +// Null rep. +TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, '\0' }; + + +void TiXmlString::reserve (size_type cap) +{ + if (cap > capacity()) + { + TiXmlString tmp; + tmp.init(length(), cap); + memcpy(tmp.start(), data(), length()); + swap(tmp); + } +} + + +TiXmlString& TiXmlString::assign(const char* str, size_type len) +{ + size_type cap = capacity(); + if (len > cap || cap > 3*(len + 8)) + { + TiXmlString tmp; + tmp.init(len); + memcpy(tmp.start(), str, len); + swap(tmp); + } + else + { + memmove(start(), str, len); + set_size(len); + } + return *this; +} + + +TiXmlString& TiXmlString::append(const char* str, size_type len) +{ + size_type newsize = length() + len; + if (newsize > capacity()) + { + reserve (newsize + capacity()); + } + memmove(finish(), str, len); + set_size(newsize); + return *this; +} + + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) +{ + TiXmlString tmp; + tmp.reserve(a.length() + b.length()); + tmp += a; + tmp += b; + return tmp; +} + +TiXmlString operator + (const TiXmlString & a, const char* b) +{ + TiXmlString tmp; + TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) ); + tmp.reserve(a.length() + b_len); + tmp += a; + tmp.append(b, b_len); + return tmp; +} + +TiXmlString operator + (const char* a, const TiXmlString & b) +{ + TiXmlString tmp; + TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) ); + tmp.reserve(a_len + b.length()); + tmp.append(a, a_len); + tmp += b; + return tmp; +} + + +#endif // TIXML_USE_STL diff --git a/util/tinystr.h b/util/tinystr.h new file mode 100644 index 0000000..6e3b999 --- /dev/null +++ b/util/tinystr.h @@ -0,0 +1,319 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +/* + * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005. + * + * - completely rewritten. compact, clean, and fast implementation. + * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems) + * - fixed reserve() to work as per specification. + * - fixed buggy compares operator==(), operator<(), and operator>() + * - fixed operator+=() to take a const ref argument, following spec. + * - added "copy" constructor with length, and most compare operators. + * - added swap(), clear(), size(), capacity(), operator+(). + */ + +#ifndef TIXML_USE_STL + +#ifndef TIXML_STRING_INCLUDED +#define TIXML_STRING_INCLUDED + +#include <assert.h> +#include <string.h> + +/* The support for explicit isn't that universal, and it isn't really + required - it is used to check that the TiXmlString class isn't incorrectly + used. Be nice to old compilers and macro it here: +*/ +#if defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + #define TIXML_EXPLICIT explicit +#elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + #define TIXML_EXPLICIT explicit +#else + #define TIXML_EXPLICIT +#endif + + +/* + TiXmlString is an emulation of a subset of the std::string template. + Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. + Only the member functions relevant to the TinyXML project have been implemented. + The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase + a string and there's no more room, we allocate a buffer twice as big as we need. +*/ +class TiXmlString +{ + public : + // The size type used + typedef size_t size_type; + + // Error value for find primitive + static const size_type npos; // = -1; + + + // TiXmlString empty constructor + TiXmlString () : rep_(&nullrep_) + { + } + + // TiXmlString copy constructor + TiXmlString ( const TiXmlString & copy) + { + init(copy.length()); + memcpy(start(), copy.data(), length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * copy) + { + init( static_cast<size_type>( strlen(copy) )); + memcpy(start(), copy, length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) + { + init(len); + memcpy(start(), str, len); + } + + // TiXmlString destructor + ~TiXmlString () + { + quit(); + } + + // = operator + TiXmlString& operator = (const char * copy) + { + return assign( copy, (size_type)strlen(copy)); + } + + // = operator + TiXmlString& operator = (const TiXmlString & copy) + { + return assign(copy.start(), copy.length()); + } + + + // += operator. Maps to append + TiXmlString& operator += (const char * suffix) + { + return append(suffix, static_cast<size_type>( strlen(suffix) )); + } + + // += operator. Maps to append + TiXmlString& operator += (char single) + { + return append(&single, 1); + } + + // += operator. Maps to append + TiXmlString& operator += (const TiXmlString & suffix) + { + return append(suffix.data(), suffix.length()); + } + + + // Convert a TiXmlString into a null-terminated char * + const char * c_str () const { return rep_->str; } + + // Convert a TiXmlString into a char * (need not be null terminated). + const char * data () const { return rep_->str; } + + // Return the length of a TiXmlString + size_type length () const { return rep_->size; } + + // Alias for length() + size_type size () const { return rep_->size; } + + // Checks if a TiXmlString is empty + bool empty () const { return rep_->size == 0; } + + // Return capacity of string + size_type capacity () const { return rep_->capacity; } + + + // single char extraction + const char& at (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // [] operator + char& operator [] (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // find a char in a string. Return TiXmlString::npos if not found + size_type find (char lookup) const + { + return find(lookup, 0); + } + + // find a char in a string from an offset. Return TiXmlString::npos if not found + size_type find (char tofind, size_type offset) const + { + if (offset >= length()) return npos; + + for (const char* p = c_str() + offset; *p != '\0'; ++p) + { + if (*p == tofind) return static_cast< size_type >( p - c_str() ); + } + return npos; + } + + void clear () + { + //Lee: + //The original was just too strange, though correct: + // TiXmlString().swap(*this); + //Instead use the quit & re-init: + quit(); + init(0,0); + } + + /* Function to reserve a big amount of data when we know we'll need it. Be aware that this + function DOES NOT clear the content of the TiXmlString if any exists. + */ + void reserve (size_type cap); + + TiXmlString& assign (const char* str, size_type len); + + TiXmlString& append (const char* str, size_type len); + + void swap (TiXmlString& other) + { + Rep* r = rep_; + rep_ = other.rep_; + other.rep_ = r; + } + + private: + + void init(size_type sz) { init(sz, sz); } + void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } + char* start() const { return rep_->str; } + char* finish() const { return rep_->str + rep_->size; } + + struct Rep + { + size_type size, capacity; + char str[1]; + }; + + void init(size_type sz, size_type cap) + { + if (cap) + { + // Lee: the original form: + // rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap)); + // doesn't work in some cases of new being overloaded. Switching + // to the normal allocation, although use an 'int' for systems + // that are overly picky about structure alignment. + const size_type bytesNeeded = sizeof(Rep) + cap; + const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); + rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] ); + + rep_->str[ rep_->size = sz ] = '\0'; + rep_->capacity = cap; + } + else + { + rep_ = &nullrep_; + } + } + + void quit() + { + if (rep_ != &nullrep_) + { + // The rep_ is really an array of ints. (see the allocator, above). + // Cast it back before delete, so the compiler won't incorrectly call destructors. + delete [] ( reinterpret_cast<int*>( rep_ ) ); + } + } + + Rep * rep_; + static Rep nullrep_; + +} ; + + +inline bool operator == (const TiXmlString & a, const TiXmlString & b) +{ + return ( a.length() == b.length() ) // optimization on some platforms + && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare +} +inline bool operator < (const TiXmlString & a, const TiXmlString & b) +{ + return strcmp(a.c_str(), b.c_str()) < 0; +} + +inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } +inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; } +inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } +inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } + +inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } +inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } +inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } +inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); +TiXmlString operator + (const TiXmlString & a, const char* b); +TiXmlString operator + (const char* a, const TiXmlString & b); + + +/* + TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. + Only the operators that we need for TinyXML have been developped. +*/ +class TiXmlOutStream : public TiXmlString +{ +public : + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const TiXmlString & in) + { + *this += in; + return *this; + } + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const char * in) + { + *this += in; + return *this; + } + +} ; + +#endif // TIXML_STRING_INCLUDED +#endif // TIXML_USE_STL diff --git a/util/tinyxml.cpp b/util/tinyxml.cpp new file mode 100644 index 0000000..6a83291 --- /dev/null +++ b/util/tinyxml.cpp @@ -0,0 +1,1799 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include <ctype.h> +#include "tinyxml.h" + +#ifdef TIXML_USE_STL +#include <sstream> +#include <iostream> +#endif + + +bool TiXmlBase::condenseWhiteSpace = true; + +void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream ) +{ + TIXML_STRING buffer; + PutString( str, &buffer ); + (*stream) << buffer; +} + +void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString ) +{ + int i=0; + + while( i<(int)str.length() ) + { + unsigned char c = (unsigned char) str[i]; + + if ( c == '&' + && i < ( (int)str.length() - 2 ) + && str[i+1] == '#' + && str[i+2] == 'x' ) + { + // Hexadecimal character reference. + // Pass through unchanged. + // © -- copyright symbol, for example. + // + // The -1 is a bug fix from Rob Laveaux. It keeps + // an overflow from happening if there is no ';'. + // There are actually 2 ways to exit this loop - + // while fails (error case) and break (semicolon found). + // However, there is no mechanism (currently) for + // this function to return an error. + while ( i<(int)str.length()-1 ) + { + outString->append( str.c_str() + i, 1 ); + ++i; + if ( str[i] == ';' ) + break; + } + } + else if ( c == '&' ) + { + outString->append( entity[0].str, entity[0].strLength ); + ++i; + } + else if ( c == '<' ) + { + outString->append( entity[1].str, entity[1].strLength ); + ++i; + } + else if ( c == '>' ) + { + outString->append( entity[2].str, entity[2].strLength ); + ++i; + } + else if ( c == '\"' ) + { + outString->append( entity[3].str, entity[3].strLength ); + ++i; + } + else if ( c == '\'' ) + { + outString->append( entity[4].str, entity[4].strLength ); + ++i; + } + else if ( c < 32 ) + { + // Easy pass at non-alpha/numeric/symbol + // Below 32 is symbolic. + char buf[ 32 ]; + + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); + #else + sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); + #endif + + //*ME: warning C4267: convert 'size_t' to 'int' + //*ME: Int-Cast to make compiler happy ... + outString->append( buf, (int)strlen( buf ) ); + ++i; + } + else + { + //char realc = (char) c; + //outString->append( &realc, 1 ); + *outString += (char) c; // somewhat more efficient function call. + ++i; + } + } +} + + +// <-- Strange class for a bug fix. Search for STL_STRING_BUG +TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str ) +{ + buffer = new char[ str.length()+1 ]; + if ( buffer ) + { + strcpy( buffer, str.c_str() ); + } +} + + +TiXmlBase::StringToBuffer::~StringToBuffer() +{ + delete [] buffer; +} +// End strange bug fix. --> + + +TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() +{ + parent = 0; + type = _type; + firstChild = 0; + lastChild = 0; + prev = 0; + next = 0; +} + + +TiXmlNode::~TiXmlNode() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } +} + + +void TiXmlNode::CopyTo( TiXmlNode* target ) const +{ + target->SetValue (value.c_str() ); + target->userData = userData; +} + + +void TiXmlNode::Clear() +{ + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; + + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } + + firstChild = 0; + lastChild = 0; +} + + +TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) +{ + assert( node->parent == 0 || node->parent == this ); + assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); + + node->parent = this; + + node->prev = lastChild; + node->next = 0; + + if ( lastChild ) + lastChild->next = node; + else + firstChild = node; // it was an empty list. + + lastChild = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) +{ + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + + return LinkEndChild( node ); +} + + +TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) +{ + if ( !beforeThis || beforeThis->parent != this ) + return 0; + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->next = beforeThis; + node->prev = beforeThis->prev; + if ( beforeThis->prev ) + { + beforeThis->prev->next = node; + } + else + { + assert( firstChild == beforeThis ); + firstChild = node; + } + beforeThis->prev = node; + return node; +} + + +TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) +{ + if ( !afterThis || afterThis->parent != this ) + return 0; + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->prev = afterThis; + node->next = afterThis->next; + if ( afterThis->next ) + { + afterThis->next->prev = node; + } + else + { + assert( lastChild == afterThis ); + lastChild = node; + } + afterThis->next = node; + return node; +} + + +TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) +{ + if ( replaceThis->parent != this ) + return 0; + + TiXmlNode* node = withThis.Clone(); + if ( !node ) + return 0; + + node->next = replaceThis->next; + node->prev = replaceThis->prev; + + if ( replaceThis->next ) + replaceThis->next->prev = node; + else + lastChild = node; + + if ( replaceThis->prev ) + replaceThis->prev->next = node; + else + firstChild = node; + + delete replaceThis; + node->parent = this; + return node; +} + + +bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) +{ + if ( removeThis->parent != this ) + { + assert( 0 ); + return false; + } + + if ( removeThis->next ) + removeThis->next->prev = removeThis->prev; + else + lastChild = removeThis->prev; + + if ( removeThis->prev ) + removeThis->prev->next = removeThis->next; + else + firstChild = removeThis->next; + + delete removeThis; + return true; +} + +const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = firstChild; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +TiXmlNode* TiXmlNode::FirstChild( const char * _value ) +{ + TiXmlNode* node; + for ( node = firstChild; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + + +const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = lastChild; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + +TiXmlNode* TiXmlNode::LastChild( const char * _value ) +{ + TiXmlNode* node; + for ( node = lastChild; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + +const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild(); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling(); + } +} + +TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous ) +{ + if ( !previous ) + { + return FirstChild(); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling(); + } +} + +const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const +{ + if ( !previous ) + { + return FirstChild( val ); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling( val ); + } +} + +TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous ) +{ + if ( !previous ) + { + return FirstChild( val ); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling( val ); + } +} + +const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = next; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + +TiXmlNode* TiXmlNode::NextSibling( const char * _value ) +{ + TiXmlNode* node; + for ( node = next; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + +const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const +{ + const TiXmlNode* node; + for ( node = prev; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + +TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) +{ + TiXmlNode* node; + for ( node = prev; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; +} + +void TiXmlElement::RemoveAttribute( const char * name ) +{ + TIXML_STRING str( name ); + TiXmlAttribute* node = attributeSet.Find( str ); + if ( node ) + { + attributeSet.Remove( node ); + delete node; + } +} + +const TiXmlElement* TiXmlNode::FirstChildElement() const +{ + const TiXmlNode* node; + + for ( node = FirstChild(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +TiXmlElement* TiXmlNode::FirstChildElement() +{ + TiXmlNode* node; + + for ( node = FirstChild(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const +{ + const TiXmlNode* node; + + for ( node = FirstChild( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) +{ + TiXmlNode* node; + + for ( node = FirstChild( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +const TiXmlElement* TiXmlNode::NextSiblingElement() const +{ + const TiXmlNode* node; + + for ( node = NextSibling(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +TiXmlElement* TiXmlNode::NextSiblingElement() +{ + TiXmlNode* node; + + for ( node = NextSibling(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const +{ + const TiXmlNode* node; + + for ( node = NextSibling( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + +TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) +{ + TiXmlNode* node; + + for ( node = NextSibling( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; +} + + +const TiXmlDocument* TiXmlNode::GetDocument() const +{ + const TiXmlNode* node; + + for( node = this; node; node = node->parent ) + { + if ( node->ToDocument() ) + return node->ToDocument(); + } + return 0; +} + +TiXmlDocument* TiXmlNode::GetDocument() +{ + TiXmlNode* node; + + for( node = this; node; node = node->parent ) + { + if ( node->ToDocument() ) + return node->ToDocument(); + } + return 0; +} + +TiXmlElement::TiXmlElement (const char * _value) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} + + +#ifdef TIXML_USE_STL +TiXmlElement::TiXmlElement( const std::string& _value ) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + value = _value; +} +#endif + + +TiXmlElement::TiXmlElement( const TiXmlElement& copy) + : TiXmlNode( TiXmlNode::ELEMENT ) +{ + firstChild = lastChild = 0; + copy.CopyTo( this ); +} + + +void TiXmlElement::operator=( const TiXmlElement& base ) +{ + ClearThis(); + base.CopyTo( this ); +} + + +TiXmlElement::~TiXmlElement() +{ + ClearThis(); +} + + +void TiXmlElement::ClearThis() +{ + Clear(); + while( attributeSet.First() ) + { + TiXmlAttribute* node = attributeSet.First(); + attributeSet.Remove( node ); + delete node; + } +} + + +const char * TiXmlElement::Attribute( const char * name ) const +{ + TIXML_STRING str( name ); + const TiXmlAttribute* node = attributeSet.Find( str ); + + if ( node ) + return node->Value(); + + return 0; +} + + +const char * TiXmlElement::Attribute( const char * name, int* i ) const +{ + const char * s = Attribute( name ); + if ( i ) + { + if ( s ) + *i = atoi( s ); + else + *i = 0; + } + return s; +} + + +const char * TiXmlElement::Attribute( const char * name, double* d ) const +{ + const char * s = Attribute( name ); + if ( d ) + { + if ( s ) + *d = atof( s ); + else + *d = 0; + } + return s; +} + + +int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const +{ + TIXML_STRING str( name ); + const TiXmlAttribute* node = attributeSet.Find( str ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + return node->QueryIntValue( ival ); +} + + +int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const +{ + TIXML_STRING str( name ); + const TiXmlAttribute* node = attributeSet.Find( str ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + return node->QueryDoubleValue( dval ); +} + + +void TiXmlElement::SetAttribute( const char * name, int val ) +{ + char buf[64]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%d", val ); + #else + sprintf( buf, "%d", val ); + #endif + SetAttribute( name, buf ); +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetAttribute( const std::string& name, int val ) +{ + std::ostringstream oss; + oss << val; + SetAttribute( name, oss.str() ); +} +#endif + + +void TiXmlElement::SetDoubleAttribute( const char * name, double val ) +{ + char buf[256]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%f", val ); + #else + sprintf( buf, "%f", val ); + #endif + SetAttribute( name, buf ); +} + + +void TiXmlElement::SetAttribute( const char * cname, const char * cvalue ) +{ + TIXML_STRING _name( cname ); + TIXML_STRING _value( cvalue ); + + TiXmlAttribute* node = attributeSet.Find( _name ); + if ( node ) + { + node->SetValue( cvalue ); + return; + } + + TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue ); + if ( attrib ) + { + attributeSet.Add( attrib ); + } + else + { + TiXmlDocument* document = GetDocument(); + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); + } +} + + +#ifdef TIXML_USE_STL +void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value ) +{ + TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + { + node->SetValue( _value ); + return; + } + + TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); + if ( attrib ) + { + attributeSet.Add( attrib ); + } + else + { + TiXmlDocument* document = GetDocument(); + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); + } +} +#endif + + +void TiXmlElement::Print( FILE* cfile, int depth ) const +{ + int i; + for ( i=0; i<depth; i++ ) + { + fprintf( cfile, " " ); + } + + fprintf( cfile, "<%s", value.c_str() ); + + const TiXmlAttribute* attrib; + for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) + { + fprintf( cfile, " " ); + attrib->Print( cfile, depth ); + } + + // There are 3 different formatting approaches: + // 1) An element without children is printed as a <foo /> node + // 2) An element with only a text child is printed as <foo> text </foo> + // 3) An element with children is printed on multiple lines. + TiXmlNode* node; + if ( !firstChild ) + { + fprintf( cfile, " />" ); + } + else if ( firstChild == lastChild && firstChild->ToText() ) + { + fprintf( cfile, ">" ); + firstChild->Print( cfile, depth + 1 ); + fprintf( cfile, "</%s>", value.c_str() ); + } + else + { + fprintf( cfile, ">" ); + + for ( node = firstChild; node; node=node->NextSibling() ) + { + if ( !node->ToText() ) + { + fprintf( cfile, "\n" ); + } + node->Print( cfile, depth+1 ); + } + fprintf( cfile, "\n" ); + for( i=0; i<depth; ++i ) + fprintf( cfile, " " ); + fprintf( cfile, "</%s>", value.c_str() ); + } +} + +void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const +{ + (*stream) << "<" << value; + + const TiXmlAttribute* attrib; + for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) + { + (*stream) << " "; + attrib->StreamOut( stream ); + } + + // If this node has children, give it a closing tag. Else + // make it an empty tag. + TiXmlNode* node; + if ( firstChild ) + { + (*stream) << ">"; + + for ( node = firstChild; node; node=node->NextSibling() ) + { + node->StreamOut( stream ); + } + (*stream) << "</" << value << ">"; + } + else + { + (*stream) << " />"; + } +} + + +void TiXmlElement::CopyTo( TiXmlElement* target ) const +{ + // superclass: + TiXmlNode::CopyTo( target ); + + // Element class: + // Clone the attributes, then clone the children. + const TiXmlAttribute* attribute = 0; + for( attribute = attributeSet.First(); + attribute; + attribute = attribute->Next() ) + { + target->SetAttribute( attribute->Name(), attribute->Value() ); + } + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + + +TiXmlNode* TiXmlElement::Clone() const +{ + TiXmlElement* clone = new TiXmlElement( Value() ); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +const char* TiXmlElement::GetText() const +{ + const TiXmlNode* child = this->FirstChild(); + if ( child ) { + const TiXmlText* childText = child->ToText(); + if ( childText ) { + return childText->Value(); + } + } + return 0; +} + + +TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + ClearError(); +} + +TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + value = documentName; + ClearError(); +} + + +#ifdef TIXML_USE_STL +TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + tabsize = 4; + useMicrosoftBOM = false; + value = documentName; + ClearError(); +} +#endif + + +TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT ) +{ + copy.CopyTo( this ); +} + + +void TiXmlDocument::operator=( const TiXmlDocument& copy ) +{ + Clear(); + copy.CopyTo( this ); +} + + +bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) +{ + // See STL_STRING_BUG below. + StringToBuffer buf( value ); + + if ( buf.buffer && LoadFile( buf.buffer, encoding ) ) + return true; + + return false; +} + + +bool TiXmlDocument::SaveFile() const +{ + // See STL_STRING_BUG below. + StringToBuffer buf( value ); + + if ( buf.buffer && SaveFile( buf.buffer ) ) + return true; + + return false; +} + +bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding ) +{ + // There was a really terrifying little bug here. The code: + // value = filename + // in the STL case, cause the assignment method of the std::string to + // be called. What is strange, is that the std::string had the same + // address as it's c_str() method, and so bad things happen. Looks + // like a bug in the Microsoft STL implementation. + // See STL_STRING_BUG above. + // Fixed with the StringToBuffer class. + value = filename; + + // reading in binary mode so that tinyxml can normalize the EOL + FILE* file = fopen( value.c_str (), "rb" ); + + if ( file ) + { + bool result = LoadFile( file, encoding ); + fclose( file ); + return result; + } + else + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } +} + +bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) +{ + if ( !file ) + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // Delete the existing data: + Clear(); + location.Clear(); + + // Get the file size, so we can pre-allocate the string. HUGE speed impact. + long length = 0; + fseek( file, 0, SEEK_END ); + length = ftell( file ); + fseek( file, 0, SEEK_SET ); + + // Strange case, but good to handle up front. + if ( length == 0 ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // If we have a file, assume it is all one big XML file, and read it in. + // The document parser may decide the document ends sooner than the entire file, however. + TIXML_STRING data; + data.reserve( length ); + + // Subtle bug here. TinyXml did use fgets. But from the XML spec: + // 2.11 End-of-Line Handling + // <snip> + // <quote> + // ...the XML processor MUST behave as if it normalized all line breaks in external + // parsed entities (including the document entity) on input, before parsing, by translating + // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to + // a single #xA character. + // </quote> + // + // It is not clear fgets does that, and certainly isn't clear it works cross platform. + // Generally, you expect fgets to translate from the convention of the OS to the c/unix + // convention, and not work generally. + + /* + while( fgets( buf, sizeof(buf), file ) ) + { + data += buf; + } + */ + + char* buf = new char[ length+1 ]; + buf[0] = 0; + + if ( fread( buf, length, 1, file ) != 1 ) { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + const char* lastPos = buf; + const char* p = buf; + + buf[length] = 0; + while( *p ) { + assert( p < (buf+length) ); + if ( *p == 0xa ) { + // Newline character. No special rules for this. Append all the characters + // since the last string, and include the newline. + data.append( lastPos, (p-lastPos+1) ); // append, include the newline + ++p; // move past the newline + lastPos = p; // and point to the new buffer (may be 0) + assert( p <= (buf+length) ); + } + else if ( *p == 0xd ) { + // Carriage return. Append what we have so far, then + // handle moving forward in the buffer. + if ( (p-lastPos) > 0 ) { + data.append( lastPos, p-lastPos ); // do not add the CR + } + data += (char)0xa; // a proper newline + + if ( *(p+1) == 0xa ) { + // Carriage return - new line sequence + p += 2; + lastPos = p; + assert( p <= (buf+length) ); + } + else { + // it was followed by something else...that is presumably characters again. + ++p; + lastPos = p; + assert( p <= (buf+length) ); + } + } + else { + ++p; + } + } + // Handle any left over characters. + if ( p-lastPos ) { + data.append( lastPos, p-lastPos ); + } + delete [] buf; + buf = 0; + + Parse( data.c_str(), 0, encoding ); + + if ( Error() ) + return false; + else + return true; +} + + +bool TiXmlDocument::SaveFile( const char * filename ) const +{ + // The old c stuff lives on... + FILE* fp = fopen( filename, "w" ); + if ( fp ) + { + bool result = SaveFile( fp ); + fclose( fp ); + return result; + } + return false; +} + + +bool TiXmlDocument::SaveFile( FILE* fp ) const +{ + if ( useMicrosoftBOM ) + { + const unsigned char TIXML_UTF_LEAD_0 = 0xefU; + const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; + const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + + fputc( TIXML_UTF_LEAD_0, fp ); + fputc( TIXML_UTF_LEAD_1, fp ); + fputc( TIXML_UTF_LEAD_2, fp ); + } + Print( fp, 0 ); + return true; +} + + +void TiXmlDocument::CopyTo( TiXmlDocument* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->error = error; + target->errorDesc = errorDesc.c_str (); + + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } +} + + +TiXmlNode* TiXmlDocument::Clone() const +{ + TiXmlDocument* clone = new TiXmlDocument(); + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlDocument::Print( FILE* cfile, int depth ) const +{ + const TiXmlNode* node; + for ( node=FirstChild(); node; node=node->NextSibling() ) + { + node->Print( cfile, depth ); + fprintf( cfile, "\n" ); + } +} + +void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const +{ + const TiXmlNode* node; + for ( node=FirstChild(); node; node=node->NextSibling() ) + { + node->StreamOut( out ); + + // Special rule for streams: stop after the root element. + // The stream in code will only read one element, so don't + // write more than one. + if ( node->ToElement() ) + break; + } +} + + +const TiXmlAttribute* TiXmlAttribute::Next() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} + +TiXmlAttribute* TiXmlAttribute::Next() +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; +} + +const TiXmlAttribute* TiXmlAttribute::Previous() const +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} + +TiXmlAttribute* TiXmlAttribute::Previous() +{ + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; +} + +void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const +{ + TIXML_STRING n, v; + + PutString( name, &n ); + PutString( value, &v ); + + if (value.find ('\"') == TIXML_STRING::npos) + fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); + else + fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); +} + + +void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const +{ + if (value.find( '\"' ) != TIXML_STRING::npos) + { + PutString( name, stream ); + (*stream) << "=" << "'"; + PutString( value, stream ); + (*stream) << "'"; + } + else + { + PutString( name, stream ); + (*stream) << "=" << "\""; + PutString( value, stream ); + (*stream) << "\""; + } +} + +int TiXmlAttribute::QueryIntValue( int* ival ) const +{ + if ( sscanf( value.c_str(), "%d", ival ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +int TiXmlAttribute::QueryDoubleValue( double* dval ) const +{ + if ( sscanf( value.c_str(), "%lf", dval ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; +} + +void TiXmlAttribute::SetIntValue( int _value ) +{ + char buf [64]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); + #else + sprintf (buf, "%d", _value); + #endif + SetValue (buf); +} + +void TiXmlAttribute::SetDoubleValue( double _value ) +{ + char buf [256]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value); + #else + sprintf (buf, "%lf", _value); + #endif + SetValue (buf); +} + +int TiXmlAttribute::IntValue() const +{ + return atoi (value.c_str ()); +} + +double TiXmlAttribute::DoubleValue() const +{ + return atof (value.c_str ()); +} + + +TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT ) +{ + copy.CopyTo( this ); +} + + +void TiXmlComment::operator=( const TiXmlComment& base ) +{ + Clear(); + base.CopyTo( this ); +} + + +void TiXmlComment::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i<depth; i++ ) + { + fputs( " ", cfile ); + } + fprintf( cfile, "<!--%s-->", value.c_str() ); +} + +void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const +{ + (*stream) << "<!--"; + //PutString( value, stream ); + (*stream) << value; + (*stream) << "-->"; +} + + +void TiXmlComment::CopyTo( TiXmlComment* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +TiXmlNode* TiXmlComment::Clone() const +{ + TiXmlComment* clone = new TiXmlComment(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlText::Print( FILE* cfile, int depth ) const +{ + if ( cdata ) + { + int i; + fprintf( cfile, "\n" ); + for ( i=0; i<depth; i++ ) { + fprintf( cfile, " " ); + } + fprintf( cfile, "<![CDATA[" ); + fprintf( cfile, "%s", value.c_str() ); // unformatted output + fprintf( cfile, "]]>\n" ); + } + else + { + TIXML_STRING buffer; + PutString( value, &buffer ); + fprintf( cfile, "%s", buffer.c_str() ); + } +} + + +void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const +{ + if ( cdata ) + { + (*stream) << "<![CDATA[" << value << "]]>"; + } + else + { + PutString( value, stream ); + } +} + + +void TiXmlText::CopyTo( TiXmlText* target ) const +{ + TiXmlNode::CopyTo( target ); + target->cdata = cdata; +} + + +TiXmlNode* TiXmlText::Clone() const +{ + TiXmlText* clone = 0; + clone = new TiXmlText( "" ); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlDeclaration::TiXmlDeclaration( const char * _version, + const char * _encoding, + const char * _standalone ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} + + +#ifdef TIXML_USE_STL +TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + version = _version; + encoding = _encoding; + standalone = _standalone; +} +#endif + + +TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) + : TiXmlNode( TiXmlNode::DECLARATION ) +{ + copy.CopyTo( this ); +} + + +void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) +{ + Clear(); + copy.CopyTo( this ); +} + + +void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const +{ + fprintf (cfile, "<?xml "); + + if ( !version.empty() ) + fprintf (cfile, "version=\"%s\" ", version.c_str ()); + if ( !encoding.empty() ) + fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ()); + if ( !standalone.empty() ) + fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ()); + fprintf (cfile, "?>"); +} + +void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const +{ + (*stream) << "<?xml "; + + if ( !version.empty() ) + { + (*stream) << "version=\""; + PutString( version, stream ); + (*stream) << "\" "; + } + if ( !encoding.empty() ) + { + (*stream) << "encoding=\""; + PutString( encoding, stream ); + (*stream ) << "\" "; + } + if ( !standalone.empty() ) + { + (*stream) << "standalone=\""; + PutString( standalone, stream ); + (*stream) << "\" "; + } + (*stream) << "?>"; +} + + +void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const +{ + TiXmlNode::CopyTo( target ); + + target->version = version; + target->encoding = encoding; + target->standalone = standalone; +} + + +TiXmlNode* TiXmlDeclaration::Clone() const +{ + TiXmlDeclaration* clone = new TiXmlDeclaration(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +void TiXmlUnknown::Print( FILE* cfile, int depth ) const +{ + for ( int i=0; i<depth; i++ ) + fprintf( cfile, " " ); + fprintf( cfile, "<%s>", value.c_str() ); +} + + +void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const +{ + (*stream) << "<" << value << ">"; // Don't use entities here! It is unknown. +} + + +void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const +{ + TiXmlNode::CopyTo( target ); +} + + +TiXmlNode* TiXmlUnknown::Clone() const +{ + TiXmlUnknown* clone = new TiXmlUnknown(); + + if ( !clone ) + return 0; + + CopyTo( clone ); + return clone; +} + + +TiXmlAttributeSet::TiXmlAttributeSet() +{ + sentinel.next = &sentinel; + sentinel.prev = &sentinel; +} + + +TiXmlAttributeSet::~TiXmlAttributeSet() +{ + assert( sentinel.next == &sentinel ); + assert( sentinel.prev == &sentinel ); +} + + +void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) +{ + assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. + + addMe->next = &sentinel; + addMe->prev = sentinel.prev; + + sentinel.prev->next = addMe; + sentinel.prev = addMe; +} + +void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) +{ + TiXmlAttribute* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node == removeMe ) + { + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + return; + } + } + assert( 0 ); // we tried to remove a non-linked attribute. +} + +const TiXmlAttribute* TiXmlAttributeSet::Find( const TIXML_STRING& name ) const +{ + const TiXmlAttribute* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; +} + +TiXmlAttribute* TiXmlAttributeSet::Find( const TIXML_STRING& name ) +{ + TiXmlAttribute* node; + + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; +} + +#ifdef TIXML_USE_STL +TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base) +{ + TIXML_STRING tag; + tag.reserve( 8 * 1000 ); + base.StreamIn( &in, &tag ); + + base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); + return in; +} +#endif + + +TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base) +{ + base.StreamOut (& out); + return out; +} + + +#ifdef TIXML_USE_STL +std::string & operator<< (std::string& out, const TiXmlNode& base ) +{ + std::ostringstream os_stream( std::ostringstream::out ); + base.StreamOut( &os_stream ); + + out.append( os_stream.str() ); + return out; +} +#endif + + +TiXmlHandle TiXmlHandle::FirstChild() const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const +{ + if ( node ) + { + TiXmlNode* child = node->FirstChild( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement() const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const +{ + if ( node ) + { + TiXmlElement* child = node->FirstChildElement( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild(); + for ( i=0; + child && i<count; + child = child->NextSibling(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild( value ); + for ( i=0; + child && i<count; + child = child->NextSibling( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement(); + for ( i=0; + child && i<count; + child = child->NextSiblingElement(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} + + +TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const +{ + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement( value ); + for ( i=0; + child && i<count; + child = child->NextSiblingElement( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); +} diff --git a/util/tinyxml.h b/util/tinyxml.h new file mode 100644 index 0000000..091575a --- /dev/null +++ b/util/tinyxml.h @@ -0,0 +1,1520 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TINYXML_INCLUDED +#define TINYXML_INCLUDED + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4530 ) +#pragma warning( disable : 4786 ) +#endif + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +// Help out windows: +#if defined( _DEBUG ) && !defined( DEBUG ) +#define DEBUG +#endif + +#ifdef TIXML_USE_STL + #include <string> + #include <iostream> + #define TIXML_STRING std::string + #define TIXML_ISTREAM std::istream + #define TIXML_OSTREAM std::ostream +#else + #include "tinystr.h" + #define TIXML_STRING TiXmlString + #define TIXML_OSTREAM TiXmlOutStream +#endif + +// Deprecated library function hell. Compilers want to use the +// new safe versions. This probably doesn't fully address the problem, +// but it gets closer. There are too many compilers for me to fully +// test. If you get compilation troubles, undefine TIXML_SAFE + +#define TIXML_SAFE // TinyXml isn't fully buffer overrun protected, safe code. This is work in progress. +#ifdef TIXML_SAFE + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + // Microsoft visual studio, version 2005 and higher. + #define TIXML_SNPRINTF _snprintf_s + #define TIXML_SNSCANF _snscanf_s + #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + //#pragma message( "Using _sn* functions." ) + #define TIXML_SNPRINTF _snprintf + #define TIXML_SNSCANF _snscanf + #elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_SNSCANF snscanf + #endif +#endif + +class TiXmlDocument; +class TiXmlElement; +class TiXmlComment; +class TiXmlUnknown; +class TiXmlAttribute; +class TiXmlText; +class TiXmlDeclaration; +class TiXmlParsingData; + +const int TIXML_MAJOR_VERSION = 2; +const int TIXML_MINOR_VERSION = 4; +const int TIXML_PATCH_VERSION = 3; + +/* Internal structure for tracking location of items + in the XML file. +*/ +struct TiXmlCursor +{ + TiXmlCursor() { Clear(); } + void Clear() { row = col = -1; } + + int row; // 0 based. + int col; // 0 based. +}; + + +// Only used by Attribute::Query functions +enum +{ + TIXML_SUCCESS, + TIXML_NO_ATTRIBUTE, + TIXML_WRONG_TYPE +}; + + +// Used by the parsing routines. +enum TiXmlEncoding +{ + TIXML_ENCODING_UNKNOWN, + TIXML_ENCODING_UTF8, + TIXML_ENCODING_LEGACY +}; + +const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; + +/** TiXmlBase is a base class for every class in TinyXml. + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim +*/ +class TiXmlBase +{ + friend class TiXmlNode; + friend class TiXmlElement; + friend class TiXmlDocument; + +public: + TiXmlBase() : userData(0) {} + virtual ~TiXmlBase() {} + + /** All TinyXml classes can print themselves to a filestream. + This is a formatted print, and will insert tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + values is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocument::Load(), + TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocument::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + + void SetUserData( void* user ) { userData = user; } + void* GetUserData() { return userData; } + + // Table that returs, for a given lead byte, the total number of bytes + // in the UTF-8 sequence. + static const int utf8ByteTable[256]; + + virtual const char* Parse( const char* p, + TiXmlParsingData* data, + TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; + + enum + { + TIXML_NO_ERROR = 0, + TIXML_ERROR, + TIXML_ERROR_OPENING_FILE, + TIXML_ERROR_OUT_OF_MEMORY, + TIXML_ERROR_PARSING_ELEMENT, + TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXML_ERROR_READING_ELEMENT_VALUE, + TIXML_ERROR_READING_ATTRIBUTES, + TIXML_ERROR_PARSING_EMPTY, + TIXML_ERROR_READING_END_TAG, + TIXML_ERROR_PARSING_UNKNOWN, + TIXML_ERROR_PARSING_COMMENT, + TIXML_ERROR_PARSING_DECLARATION, + TIXML_ERROR_DOCUMENT_EMPTY, + TIXML_ERROR_EMBEDDED_NULL, + TIXML_ERROR_PARSING_CDATA, + + TIXML_ERROR_STRING_COUNT + }; + +protected: + + // See STL_STRING_BUG + // Utility class to overcome a bug. + class StringToBuffer + { + public: + StringToBuffer( const TIXML_STRING& str ); + ~StringToBuffer(); + char* buffer; + }; + + static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); + inline static bool IsWhiteSpace( char c ) + { + return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); + } + inline static bool IsWhiteSpace( int c ) + { + if ( c < 256 ) + return IsWhiteSpace( (char) c ); + return false; // Again, only truly correct for English/Latin...but usually works. + } + + virtual void StreamOut (TIXML_OSTREAM *) const = 0; + + #ifdef TIXML_USE_STL + static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ); + static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ); + #endif + + /* Reads an XML name into the string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const char* ReadText( const char* in, // where to start + TIXML_STRING* text, // the string read + bool ignoreWhiteSpace, // whether to keep the white space + const char* endTag, // what ends this text + bool ignoreCase, // whether to ignore case in the end tag + TiXmlEncoding encoding ); // the current encoding + + // If an entity has been found, transform it into a character. + static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); + + // Get a character, while interpreting entities. + // The length can be from 0 to 4 bytes. + inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) + { + assert( p ); + if ( encoding == TIXML_ENCODING_UTF8 ) + { + *length = utf8ByteTable[ *((unsigned char*)p) ]; + assert( *length >= 0 && *length < 5 ); + } + else + { + *length = 1; + } + + if ( *length == 1 ) + { + if ( *p == '&' ) + return GetEntity( p, _value, length, encoding ); + *_value = *p; + return p+1; + } + else if ( *length ) + { + //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), + // and the null terminator isn't needed + for( int i=0; p[i] && i<*length; ++i ) { + _value[i] = p[i]; + } + return p + (*length); + } + else + { + // Not valid text. + return 0; + } + } + + // Puts a string to a stream, expanding entities as it goes. + // Note this should not contian the '<', '>', etc, or they will be transformed into entities! + static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out ); + + static void PutString( const TIXML_STRING& str, TIXML_STRING* out ); + + // Return true if the next characters in the stream are any of the endTag sequences. + // Ignore case only works for english, and should only be relied on when comparing + // to English words: StringEqual( p, "version", true ) is fine. + static bool StringEqual( const char* p, + const char* endTag, + bool ignoreCase, + TiXmlEncoding encoding ); + + static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; + + TiXmlCursor location; + + /// Field containing a generic user pointer + void* userData; + + // None of these methods are reliable for any language except English. + // Good for approximation, not great for accuracy. + static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); + static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); + inline static int ToLower( int v, TiXmlEncoding encoding ) + { + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( v < 128 ) return tolower( v ); + return v; + } + else + { + return tolower( v ); + } + } + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + +private: + TiXmlBase( const TiXmlBase& ); // not implemented. + void operator=( const TiXmlBase& base ); // not allowed. + + struct Entity + { + const char* str; + unsigned int strLength; + char chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; +}; + + +/** The parent class for everything in the Document Object Model. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNode + can be queried, and it can be cast to its more defined type. +*/ +class TiXmlNode : public TiXmlBase +{ + friend class TiXmlDocument; + friend class TiXmlElement; + +public: + #ifdef TIXML_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::istream& operator >> (std::istream& in, TiXmlNode& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElement (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocument will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); + + /// Appends the XML node or attribute to a std::string. + friend std::string& operator<< (std::string& out, const TiXmlNode& base ); + + #else + // Used internally, not part of the public API. + friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base); + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + DOCUMENT, + ELEMENT, + COMMENT, + UNKNOWN, + TEXT, + DECLARATION, + TYPECOUNT + }; + + virtual ~TiXmlNode(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNode. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + + The subclasses will wrap this function. + */ + const char *Value() const { return value.c_str (); } + + #ifdef TIXML_USE_STL + /** Return Value() as a std::string. If you only use STL, + this is more efficient than calling Value(). + Only available in STL mode. + */ + const std::string& ValueStr() const { return value; } + #endif + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + void SetValue(const char * _value) { value = _value;} + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNode* Parent() { return parent; } + const TiXmlNode* Parent() const { return parent; } + + const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNode* FirstChild() { return firstChild; } + const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + TiXmlNode* FirstChild( const char * value ); ///< The first child of this node with the matching 'value'. Will be null if none found. + + const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNode* LastChild() { return lastChild; } + const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + TiXmlNode* LastChild( const char * value ); + + #ifdef TIXML_USE_STL + const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( TiXmlNode* previous ); + + /// This flavor of IterateChildren searches for children with a particular 'value' + const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ); + + #ifdef TIXML_USE_STL + const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + #endif + + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); + + + /** Add a new node related to this. Adds a child past the LastChild. + + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. + + @sa InsertEndChild + */ + TiXmlNode* LinkEndChild( TiXmlNode* addThis ); + + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); + + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); + + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); + + /// Delete a child of this node. + bool RemoveChild( TiXmlNode* removeThis ); + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling() const { return prev; } + TiXmlNode* PreviousSibling() { return prev; } + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling( const char * ) const; + TiXmlNode* PreviousSibling( const char * ); + + #ifdef TIXML_USE_STL + const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Navigate to a sibling node. + const TiXmlNode* NextSibling() const { return next; } + TiXmlNode* NextSibling() { return next; } + + /// Navigate to a sibling node with the given 'value'. + const TiXmlNode* NextSibling( const char * ) const; + TiXmlNode* NextSibling( const char * ); + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement() const; + TiXmlElement* NextSiblingElement(); + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement( const char * ) const; + TiXmlElement* NextSiblingElement( const char * ); + + #ifdef TIXML_USE_STL + const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement() const; + TiXmlElement* FirstChildElement(); + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement( const char * value ) const; + TiXmlElement* FirstChildElement( const char * value ); + + #ifdef TIXML_USE_STL + const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: DOCUMENT, ELEMENT, COMMENT, + UNKNOWN, TEXT, and DECLARATION. + */ + int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + const TiXmlDocument* GetDocument() const; + TiXmlDocument* GetDocument(); + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + /** Create an exact duplicate of this node and return it. The memory must be deleted + by the caller. + */ + virtual TiXmlNode* Clone() const = 0; + +protected: + TiXmlNode( NodeType _type ); + + // Copy to the allocated object. Shared functionality between Clone, Copy constructor, + // and the assignment operator. + void CopyTo( TiXmlNode* target ) const; + + #ifdef TIXML_USE_STL + // The real work of the input operator. + virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0; + #endif + + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); + + TiXmlNode* parent; + NodeType type; + + TiXmlNode* firstChild; + TiXmlNode* lastChild; + + TIXML_STRING value; + + TiXmlNode* prev; + TiXmlNode* next; + +private: + TiXmlNode( const TiXmlNode& ); // not implemented. + void operator=( const TiXmlNode& base ); // not allowed. +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. +*/ +class TiXmlAttribute : public TiXmlBase +{ + friend class TiXmlAttributeSet; + +public: + /// Construct an empty attribute. + TiXmlAttribute() : TiXmlBase() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlAttribute( const std::string& _name, const std::string& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttribute( const char * _name, const char * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const char* Name() const { return name.c_str (); } ///< Return the name of this attribute. + const char* Value() const { return value.c_str (); } ///< Return the value of this attribute. + int IntValue() const; ///< Return the value of this attribute, converted to an integer. + double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + // Get the tinyxml string representation + const TIXML_STRING& NameTStr() const { return name; } + + /** QueryIntValue examines the value string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* _value ) const; + /// QueryDoubleValue examines the value string. See QueryIntValue(). + int QueryDoubleValue( double* _value ) const; + + void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const char* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int _value ); ///< Set the value from an integer. + void SetDoubleValue( double _value ); ///< Set the value from a double. + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetName( const std::string& _name ) { name = _name; } + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + const TiXmlAttribute* Next() const; + TiXmlAttribute* Next(); + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + const TiXmlAttribute* Previous() const; + TiXmlAttribute* Previous(); + + bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } + + /* Attribute parsing starts: first letter of the name + returns: the next char after the value end quote + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + // Prints this Attribute to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual void StreamOut( TIXML_OSTREAM * out ) const; + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocument* doc ) { document = doc; } + +private: + TiXmlAttribute( const TiXmlAttribute& ); // not implemented. + void operator=( const TiXmlAttribute& base ); // not allowed. + + TiXmlDocument* document; // A pointer back to a document, for error reporting. + TIXML_STRING name; + TIXML_STRING value; + TiXmlAttribute* prev; + TiXmlAttribute* next; +}; + + +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. + + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. +*/ +class TiXmlAttributeSet +{ +public: + TiXmlAttributeSet(); + ~TiXmlAttributeSet(); + + void Add( TiXmlAttribute* attribute ); + void Remove( TiXmlAttribute* attribute ); + + const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + + const TiXmlAttribute* Find( const TIXML_STRING& name ) const; + TiXmlAttribute* Find( const TIXML_STRING& name ); + +private: + //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), + //*ME: this class must be also use a hidden/disabled copy-constructor !!! + TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed + void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) + + TiXmlAttribute sentinel; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TiXmlElement : public TiXmlNode +{ +public: + /// Construct an element. + TiXmlElement (const char * in_value); + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlElement( const std::string& _value ); + #endif + + TiXmlElement( const TiXmlElement& ); + + void operator=( const TiXmlElement& base ); + + virtual ~TiXmlElement(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const char* Attribute( const char* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const char* Attribute( const char* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const char* Attribute( const char* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. If the attribute + does not exist, then TIXML_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const char* name, int* _value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const char* name, double* _value ) const; + /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). + int QueryFloatAttribute( const char* name, float* _value ) const { + double d; + int result = QueryDoubleAttribute( name, &d ); + if ( result == TIXML_SUCCESS ) { + *_value = (float)d; + } + return result; + } + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char* name, const char * _value ); + + #ifdef TIXML_USE_STL + const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); } + const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); } + const char* Attribute( const std::string& name, double* d ) const { return Attribute( name.c_str(), d ); } + int QueryIntAttribute( const std::string& name, int* _value ) const { return QueryIntAttribute( name.c_str(), _value ); } + int QueryDoubleAttribute( const std::string& name, double* _value ) const { return QueryDoubleAttribute( name.c_str(), _value ); } + + /// STL std::string form. + void SetAttribute( const std::string& name, const std::string& _value ); + ///< STL std::string form. + void SetAttribute( const std::string& name, int _value ); + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char * name, int value ); + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetDoubleAttribute( const char * name, double value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const char * name ); + #ifdef TIXML_USE_STL + void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. + #endif + + const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } + const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the TiXmlText child + and accessing it directly. + + If the first child of 'this' is a TiXmlText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + <foo>This is text</foo> + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + <foo><b>This is text</b></foo> + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + <foo>This is <b>text</b></foo> + @endverbatim + GetText() will return "This is ". + + WARNING: GetText() accesses a child node - don't become confused with the + similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are + safe type casts on the referenced node. + */ + const char* GetText() const; + + /// Creates a new Element and returns it - the returned element is a copy. + virtual TiXmlNode* Clone() const; + // Print the Element to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: next char past '<' + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + +protected: + + void CopyTo( TiXmlElement* target ) const; + void ClearThis(); // like clear, but initializes 'this' object as well + + // Used to be public [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut( TIXML_OSTREAM * out ) const; + + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + +private: + + TiXmlAttributeSet attributeSet; +}; + + +/** An XML comment. +*/ +class TiXmlComment : public TiXmlNode +{ +public: + /// Constructs an empty comment. + TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} + TiXmlComment( const TiXmlComment& ); + void operator=( const TiXmlComment& base ); + + virtual ~TiXmlComment() {} + + /// Returns a copy of this Comment. + virtual TiXmlNode* Clone() const; + /// Write this Comment to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: at the ! of the !-- + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + +protected: + void CopyTo( TiXmlComment* target ) const; + + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut( TIXML_OSTREAM * out ) const; + +private: + +}; + + +/** XML text. A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCDATA() and query it with CDATA(). +*/ +class TiXmlText : public TiXmlNode +{ + friend class TiXmlElement; +public: + /** Constructor for text element. By default, it is treated as + normal, encoded text. If you want it be output as a CDATA text + element, set the parameter _cdata to 'true' + */ + TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + virtual ~TiXmlText() {} + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + #endif + + TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } + void operator=( const TiXmlText& base ) { base.CopyTo( this ); } + + /// Write this text object to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /// Queries whether this represents text using a CDATA section. + bool CDATA() { return cdata; } + /// Turns on or off a CDATA representation of text. + void SetCDATA( bool _cdata ) { cdata = _cdata; } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + +protected : + /// [internal use] Creates a new Element and returns it. + virtual TiXmlNode* Clone() const; + void CopyTo( TiXmlText* target ) const; + + virtual void StreamOut ( TIXML_OSTREAM * out ) const; + bool Blank() const; // returns true if all white space and new lines + // [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + +private: + bool cdata; // true if this should be input and output as a CDATA style text element +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + <?xml version="1.0" standalone="yes"?> + @endverbatim + + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. + + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. +*/ +class TiXmlDeclaration : public TiXmlNode +{ +public: + /// Construct an empty declaration. + TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} + +#ifdef TIXML_USE_STL + /// Constructor. + TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ); +#endif + + /// Construct. + TiXmlDeclaration( const char* _version, + const char* _encoding, + const char* _standalone ); + + TiXmlDeclaration( const TiXmlDeclaration& copy ); + void operator=( const TiXmlDeclaration& copy ); + + virtual ~TiXmlDeclaration() {} + + /// Version. Will return an empty string if none was found. + const char *Version() const { return version.c_str (); } + /// Encoding. Will return an empty string if none was found. + const char *Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const char *Standalone() const { return standalone.c_str (); } + + /// Creates a copy of this Declaration and returns it. + virtual TiXmlNode* Clone() const; + /// Print this declaration to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + +protected: + void CopyTo( TiXmlDeclaration* target ) const; + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut ( TIXML_OSTREAM * out) const; + +private: + + TIXML_STRING version; + TIXML_STRING encoding; + TIXML_STRING standalone; +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into TiXmlUnknowns. +*/ +class TiXmlUnknown : public TiXmlNode +{ +public: + TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} + virtual ~TiXmlUnknown() {} + + TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } + void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } + + /// Creates a copy of this Unknown and returns it. + virtual TiXmlNode* Clone() const; + /// Print this Unknown to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + +protected: + void CopyTo( TiXmlUnknown* target ) const; + + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + virtual void StreamOut ( TIXML_OSTREAM * out ) const; + +private: + +}; + + +/** Always the top level node. A document binds together all the + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. +*/ +class TiXmlDocument : public TiXmlNode +{ +public: + /// Create an empty document, that has no name. + TiXmlDocument(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocument( const char * documentName ); + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlDocument( const std::string& documentName ); + #endif + + TiXmlDocument( const TiXmlDocument& copy ); + void operator=( const TiXmlDocument& copy ); + + virtual ~TiXmlDocument() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const char * filename ) const; + /** Load a file using the given FILE*. Returns true if successful. Note that this method + doesn't stream - the entire object pointed at by the FILE* + will be interpreted as an XML file. TinyXML doesn't stream in XML from the current + file location. Streaming may be added in the future. + */ + bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given FILE*. Returns true if successful. + bool SaveFile( FILE* ) const; + + #ifdef TIXML_USE_STL + bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. + { + StringToBuffer f( filename ); + return ( f.buffer && LoadFile( f.buffer, encoding )); + } + bool SaveFile( const std::string& filename ) const ///< STL std::string version. + { + StringToBuffer f( filename ); + return ( f.buffer && SaveFile( f.buffer )); + } + #endif + + /** Parse the given null terminated block of xml data. Passing in an encoding to this + method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml + to use that encoding, regardless of what TinyXml might otherwise try to detect. + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + const TiXmlElement* RootElement() const { return FirstChildElement(); } + TiXmlElement* RootElement() { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const char * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() { return errorLocation.row+1; } + int ErrorCol() { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) + to report the correct values for row and column. It does not change the output + or input in any way. + + By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Dump the document to standard out. */ + void Print() const { Print( stdout, 0 ); } + + /// Print this Document to a FILE stream. + virtual void Print( FILE* cfile, int depth = 0 ) const; + // [internal use] + void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + + virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + +protected : + virtual void StreamOut ( TIXML_OSTREAM * out) const; + // [internal use] + virtual TiXmlNode* Clone() const; + #ifdef TIXML_USE_STL + virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); + #endif + +private: + void CopyTo( TiXmlDocument* target ) const; + + bool error; + int errorId; + TIXML_STRING errorDesc; + int tabsize; + TiXmlCursor errorLocation; + bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. +}; + + +/** + A TiXmlHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + <Document> + <Element attributeA = "valueA"> + <Child attributeB = "value1" /> + <Child attributeB = "value2" /> + </Element> + <Document> + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim +*/ +class TiXmlHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } + /// Copy constructor + TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } + TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } + + /// Return a handle to the first child node. + TiXmlHandle FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandle FirstChild( const char * value ) const; + /// Return a handle to the first child element. + TiXmlHandle FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandle FirstChildElement( const char * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( const char* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( const char* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( int index ) const; + + #ifdef TIXML_USE_STL + TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /// Return the handle as a TiXmlNode. This may return null. + TiXmlNode* Node() const { return node; } + /// Return the handle as a TiXmlElement. This may return null. + TiXmlElement* Element() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /// Return the handle as a TiXmlText. This may return null. + TiXmlText* Text() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + /// Return the handle as a TiXmlUnknown. This may return null; + TiXmlUnknown* Unknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + +private: + TiXmlNode* node; +}; + +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + +#endif + diff --git a/util/tinyxmlerror.cpp b/util/tinyxmlerror.cpp new file mode 100644 index 0000000..5788438 --- /dev/null +++ b/util/tinyxmlerror.cpp @@ -0,0 +1,52 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "tinyxml.h" + +// The goal of the seperate error file is to make the first +// step towards localization. tinyxml (currently) only supports +// english error messages, but the could now be translated. +// +// It also cleans up the code a bit. +// + +const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = +{ + "No error", + "Error", + "Failed to open file", + "Memory allocation failed.", + "Error parsing Element.", + "Failed to read Element name", + "Error reading Element value.", + "Error reading Attributes.", + "Error: empty tag.", + "Error reading end tag.", + "Error parsing Unknown.", + "Error parsing Comment.", + "Error parsing Declaration.", + "Error document empty.", + "Error null (0) or unexpected EOF found in input stream.", + "Error parsing CDATA.", +}; diff --git a/util/tinyxmlparser.cpp b/util/tinyxmlparser.cpp new file mode 100644 index 0000000..9a77ebc --- /dev/null +++ b/util/tinyxmlparser.cpp @@ -0,0 +1,1580 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "tinyxml.h" +#include <ctype.h> +#include <stddef.h> + +//#define DEBUG_PARSER +#if defined( DEBUG_PARSER ) +# if defined( DEBUG ) && defined( _MSC_VER ) +# include <windows.h> +# define TIXML_LOG OutputDebugString +# else +# define TIXML_LOG printf +# endif +#endif + +// Note tha "PutString" hardcodes the same list. This +// is less flexible than it appears. Changing the entries +// or order will break putstring. +TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = +{ + { "&", 5, '&' }, + { "<", 4, '<' }, + { ">", 4, '>' }, + { """, 6, '\"' }, + { "'", 6, '\'' } +}; + +// Bunch of unicode info at: +// http://www.unicode.org/faq/utf_bom.html +// Including the basic of this table, which determines the #bytes in the +// sequence from the lead byte. 1 placed for invalid sequences -- +// although the result will be junk, pass it through as much as possible. +// Beware of the non-characters in UTF-8: +// ef bb bf (Microsoft "lead bytes") +// ef bf be +// ef bf bf + +const unsigned char TIXML_UTF_LEAD_0 = 0xefU; +const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; +const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + +const int TiXmlBase::utf8ByteTable[256] = +{ + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte + 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid +}; + + +void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) +{ + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + if (input < 0x80) + *length = 1; + else if ( input < 0x800 ) + *length = 2; + else if ( input < 0x10000 ) + *length = 3; + else if ( input < 0x200000 ) + *length = 4; + else + { *length = 0; return; } // This code won't covert this correctly anyway. + + output += *length; + + // Scary scary fall throughs. + switch (*length) + { + case 4: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 3: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 2: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 1: + --output; + *output = (char)(input | FIRST_BYTE_MARK[*length]); + } +} + + +/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalpha( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalpha( anyByte ); +// } +} + + +/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) +{ + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalnum( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalnum( anyByte ); +// } +} + + +class TiXmlParsingData +{ + friend class TiXmlDocument; + public: + void Stamp( const char* now, TiXmlEncoding encoding ); + + const TiXmlCursor& Cursor() { return cursor; } + + private: + // Only used by the document! + TiXmlParsingData( const char* start, int _tabsize, int row, int col ) + { + assert( start ); + stamp = start; + tabsize = _tabsize; + cursor.row = row; + cursor.col = col; + } + + TiXmlCursor cursor; + const char* stamp; + int tabsize; +}; + + +void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) +{ + assert( now ); + + // Do nothing if the tabsize is 0. + if ( tabsize < 1 ) + { + return; + } + + // Get the current row, column. + int row = cursor.row; + int col = cursor.col; + const char* p = stamp; + assert( p ); + + while ( p < now ) + { + // Treat p as unsigned, so we have a happy compiler. + const unsigned char* pU = (const unsigned char*)p; + + // Code contributed by Fletcher Dunn: (modified by lee) + switch (*pU) { + case 0: + // We *should* never get here, but in case we do, don't + // advance past the terminating null character, ever + return; + + case '\r': + // bump down to the next line + ++row; + col = 0; + // Eat the character + ++p; + + // Check for \r\n sequence, and treat this as a single character + if (*p == '\n') { + ++p; + } + break; + + case '\n': + // bump down to the next line + ++row; + col = 0; + + // Eat the character + ++p; + + // Check for \n\r sequence, and treat this as a single + // character. (Yes, this bizarre thing does occur still + // on some arcane platforms...) + if (*p == '\r') { + ++p; + } + break; + + case '\t': + // Eat the character + ++p; + + // Skip to next tab stop + col = (col / tabsize + 1) * tabsize; + break; + + case TIXML_UTF_LEAD_0: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( *(p+1) && *(p+2) ) + { + // In these cases, don't advance the column. These are + // 0-width spaces. + if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) + p += 3; + else + { p +=3; ++col; } // A normal character. + } + } + else + { + ++p; + ++col; + } + break; + + default: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // Eat the 1 to 4 byte utf8 character. + int step = TiXmlBase::utf8ByteTable[*((unsigned char*)p)]; + if ( step == 0 ) + step = 1; // Error case from bad encoding, but handle gracefully. + p += step; + + // Just advance one column, of course. + ++col; + } + else + { + ++p; + ++col; + } + break; + } + } + cursor.row = row; + cursor.col = col; + assert( cursor.row >= -1 ); + assert( cursor.col >= -1 ); + stamp = p; + assert( stamp ); +} + + +const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) +{ + if ( !p || !*p ) + { + return 0; + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + while ( *p ) + { + const unsigned char* pU = (const unsigned char*)p; + + // Skip the stupid Microsoft UTF-8 Byte order marks + if ( *(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==TIXML_UTF_LEAD_1 + && *(pU+2)==TIXML_UTF_LEAD_2 ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbeU ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbfU ) + { + p += 3; + continue; + } + + if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. + ++p; + else + break; + } + } + else + { + while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) + ++p; + } + + return p; +} + +#ifdef TIXML_USE_STL +/*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + for( ;; ) + { + if ( !in->good() ) return false; + + int c = in->peek(); + // At this scope, we can't get to a document. So fail silently. + if ( !IsWhiteSpace( c ) || c <= 0 ) + return true; + + *tag += (char) in->get(); + } +} + +/*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ) +{ + //assert( character > 0 && character < 128 ); // else it won't work in utf-8 + while ( in->good() ) + { + int c = in->peek(); + if ( c == character ) + return true; + if ( c <= 0 ) // Silent failure: can't get document at this scope + return false; + + in->get(); + *tag += (char) c; + } + return false; +} +#endif + +const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) +{ + *name = ""; + assert( p ); + + // Names start with letters or underscores. + // Of course, in unicode, tinyxml has no idea what a letter *is*. The + // algorithm is generous. + // + // After that, they can be letters, underscores, numbers, + // hyphens, or colons. (Colons are valid ony for namespaces, + // but tinyxml can't tell namespaces from names.) + if ( p && *p + && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) + { + while( p && *p + && ( IsAlphaNum( (unsigned char ) *p, encoding ) + || *p == '_' + || *p == '-' + || *p == '.' + || *p == ':' ) ) + { + (*name) += *p; + ++p; + } + return p; + } + return 0; +} + +const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) +{ + // Presume an entity, and pull it out. + TIXML_STRING ent; + int i; + *length = 0; + + if ( *(p+1) && *(p+1) == '#' && *(p+2) ) + { + unsigned long ucs = 0; + ptrdiff_t delta = 0; + unsigned mult = 1; + + if ( *(p+2) == 'x' ) + { + // Hexadecimal. + if ( !*(p+3) ) return 0; + + const char* q = p+3; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != 'x' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else if ( *q >= 'a' && *q <= 'f' ) + ucs += mult * (*q - 'a' + 10); + else if ( *q >= 'A' && *q <= 'F' ) + ucs += mult * (*q - 'A' + 10 ); + else + return 0; + mult *= 16; + --q; + } + } + else + { + // Decimal. + if ( !*(p+2) ) return 0; + + const char* q = p+2; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != '#' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else + return 0; + mult *= 10; + --q; + } + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8( ucs, value, length ); + } + else + { + *value = (char)ucs; + *length = 1; + } + return p + delta + 1; + } + + // Now try to match it. + for( i=0; i<NUM_ENTITY; ++i ) + { + if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 ) + { + assert( strlen( entity[i].str ) == entity[i].strLength ); + *value = entity[i].chr; + *length = 1; + return ( p + entity[i].strLength ); + } + } + + // So it wasn't an entity, its unrecognized, or something like that. + *value = *p; // Don't put back the last one, since we return it! + return p+1; +} + + +bool TiXmlBase::StringEqual( const char* p, + const char* tag, + bool ignoreCase, + TiXmlEncoding encoding ) +{ + assert( p ); + assert( tag ); + if ( !p || !*p ) + { + assert( 0 ); + return false; + } + + const char* q = p; + + if ( ignoreCase ) + { + while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) ) + { + ++q; + ++tag; + } + + if ( *tag == 0 ) + return true; + } + else + { + while ( *q && *tag && *q == *tag ) + { + ++q; + ++tag; + } + + if ( *tag == 0 ) // Have we found the end of the tag, and everything equal? + return true; + } + return false; +} + +const char* TiXmlBase::ReadText( const char* p, + TIXML_STRING * text, + bool trimWhiteSpace, + const char* endTag, + bool caseInsensitive, + TiXmlEncoding encoding ) +{ + *text = ""; + if ( !trimWhiteSpace // certain tags always keep whitespace + || !condenseWhiteSpace ) // if true, whitespace is always kept + { + // Keep all the white space. + while ( p && *p + && !StringEqual( p, endTag, caseInsensitive, encoding ) + ) + { + int len; + char cArr[4] = { 0, 0, 0, 0 }; + p = GetChar( p, cArr, &len, encoding ); + text->append( cArr, len ); + } + } + else + { + bool whitespace = false; + + // Remove leading white space: + p = SkipWhiteSpace( p, encoding ); + while ( p && *p + && !StringEqual( p, endTag, caseInsensitive, encoding ) ) + { + if ( *p == '\r' || *p == '\n' ) + { + whitespace = true; + ++p; + } + else if ( IsWhiteSpace( *p ) ) + { + whitespace = true; + ++p; + } + else + { + // If we've found whitespace, add it before the + // new character. Any whitespace just becomes a space. + if ( whitespace ) + { + (*text) += ' '; + whitespace = false; + } + int len; + char cArr[4] = { 0, 0, 0, 0 }; + p = GetChar( p, cArr, &len, encoding ); + if ( len == 1 ) + (*text) += cArr[0]; // more efficient + else + text->append( cArr, len ); + } + } + } + return p + strlen( endTag ); +} + +#ifdef TIXML_USE_STL + +void TiXmlDocument::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + // The basic issue with a document is that we don't know what we're + // streaming. Read something presumed to be a tag (and hope), then + // identify it, and call the appropriate stream method on the tag. + // + // This "pre-streaming" will never read the closing ">" so the + // sub-tag can orient itself. + + if ( !StreamTo( in, '<', tag ) ) + { + SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + while ( in->good() ) + { + int tagIndex = (int) tag->length(); + while ( in->good() && in->peek() != '>' ) + { + int c = in->get(); + if ( c <= 0 ) + { + SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + break; + } + (*tag) += (char) c; + } + + if ( in->good() ) + { + // We now have something we presume to be a node of + // some sort. Identify it, and call the node to + // continue streaming. + TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); + + if ( node ) + { + node->StreamIn( in, tag ); + bool isElement = node->ToElement() != 0; + delete node; + node = 0; + + // If this is the root element, we're done. Parsing will be + // done by the >> operator. + if ( isElement ) + { + return; + } + } + else + { + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + } + } + // We should have returned sooner. + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); +} + +#endif + +const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) +{ + ClearError(); + + // Parse away, at the document level. Since a document + // contains nothing but other tags, most of what happens + // here is skipping white space. + if ( !p || !*p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + // Note that, for a document, this needs to come + // before the while space skip, so that parsing + // starts from the pointer we are given. + location.Clear(); + if ( prevData ) + { + location.row = prevData->cursor.row; + location.col = prevData->cursor.col; + } + else + { + location.row = 0; + location.col = 0; + } + TiXmlParsingData data( p, TabSize(), location.row, location.col ); + location = data.Cursor(); + + if ( encoding == TIXML_ENCODING_UNKNOWN ) + { + // Check for the Microsoft UTF-8 lead bytes. + const unsigned char* pU = (const unsigned char*)p; + if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 + && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 + && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) + { + encoding = TIXML_ENCODING_UTF8; + useMicrosoftBOM = true; + } + } + + p = SkipWhiteSpace( p, encoding ); + if ( !p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + while ( p && *p ) + { + TiXmlNode* node = Identify( p, encoding ); + if ( node ) + { + p = node->Parse( p, &data, encoding ); + LinkEndChild( node ); + } + else + { + break; + } + + // Did we get encoding info? + if ( encoding == TIXML_ENCODING_UNKNOWN + && node->ToDeclaration() ) + { + TiXmlDeclaration* dec = node->ToDeclaration(); + const char* enc = dec->Encoding(); + assert( enc ); + + if ( *enc == 0 ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice + else + encoding = TIXML_ENCODING_LEGACY; + } + + p = SkipWhiteSpace( p, encoding ); + } + + // Was this empty? + if ( !firstChild ) { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); + return 0; + } + + // All is well. + return p; +} + +void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + // The first error in a chain is more accurate - don't set again! + if ( error ) + return; + + assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); + error = true; + errorId = err; + errorDesc = errorString[ errorId ]; + + errorLocation.Clear(); + if ( pError && data ) + { + data->Stamp( pError, encoding ); + errorLocation = data->Cursor(); + } +} + + +TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) +{ + TiXmlNode* returnNode = 0; + + p = SkipWhiteSpace( p, encoding ); + if( !p || !*p || *p != '<' ) + { + return 0; + } + + TiXmlDocument* doc = GetDocument(); + p = SkipWhiteSpace( p, encoding ); + + if ( !p || !*p ) + { + return 0; + } + + // What is this thing? + // - Elements start with a letter or underscore, but xml is reserved. + // - Comments: <!-- + // - Decleration: <?xml + // - Everthing else is unknown to tinyxml. + // + + const char* xmlHeader = { "<?xml" }; + const char* commentHeader = { "<!--" }; + const char* dtdHeader = { "<!" }; + const char* cdataHeader = { "<![CDATA[" }; + + if ( StringEqual( p, xmlHeader, true, encoding ) ) + { + #ifdef DEBUG_PARSER + TIXML_LOG( "XML parsing Declaration\n" ); + #endif + returnNode = new TiXmlDeclaration(); + } + else if ( StringEqual( p, commentHeader, false, encoding ) ) + { + #ifdef DEBUG_PARSER + TIXML_LOG( "XML parsing Comment\n" ); + #endif + returnNode = new TiXmlComment(); + } + else if ( StringEqual( p, cdataHeader, false, encoding ) ) + { + #ifdef DEBUG_PARSER + TIXML_LOG( "XML parsing CDATA\n" ); + #endif + TiXmlText* text = new TiXmlText( "" ); + text->SetCDATA( true ); + returnNode = text; + } + else if ( StringEqual( p, dtdHeader, false, encoding ) ) + { + #ifdef DEBUG_PARSER + TIXML_LOG( "XML parsing Unknown(1)\n" ); + #endif + returnNode = new TiXmlUnknown(); + } + else if ( IsAlpha( *(p+1), encoding ) + || *(p+1) == '_' ) + { + #ifdef DEBUG_PARSER + TIXML_LOG( "XML parsing Element\n" ); + #endif + returnNode = new TiXmlElement( "" ); + } + else + { + #ifdef DEBUG_PARSER + TIXML_LOG( "XML parsing Unknown(2)\n" ); + #endif + returnNode = new TiXmlUnknown(); + } + + if ( returnNode ) + { + // Set the parent, so it can report errors + returnNode->parent = this; + } + else + { + if ( doc ) + doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); + } + return returnNode; +} + +#ifdef TIXML_USE_STL + +void TiXmlElement::StreamIn (TIXML_ISTREAM * in, TIXML_STRING * tag) +{ + // We're called with some amount of pre-parsing. That is, some of "this" + // element is in "tag". Go ahead and stream to the closing ">" + while( in->good() ) + { + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + (*tag) += (char) c ; + + if ( c == '>' ) + break; + } + + if ( tag->length() < 3 ) return; + + // Okay...if we are a "/>" tag, then we're done. We've read a complete tag. + // If not, identify and stream. + + if ( tag->at( tag->length() - 1 ) == '>' + && tag->at( tag->length() - 2 ) == '/' ) + { + // All good! + return; + } + else if ( tag->at( tag->length() - 1 ) == '>' ) + { + // There is more. Could be: + // text + // closing tag + // another node. + for ( ;; ) + { + StreamWhiteSpace( in, tag ); + + // Do we have text? + if ( in->good() && in->peek() != '<' ) + { + // Yep, text. + TiXmlText text( "" ); + text.StreamIn( in, tag ); + + // What follows text is a closing tag or another node. + // Go around again and figure it out. + continue; + } + + // We now have either a closing tag...or another node. + // We should be at a "<", regardless. + if ( !in->good() ) return; + assert( in->peek() == '<' ); + int tagIndex = (int) tag->length(); + + bool closingTag = false; + bool firstCharFound = false; + + for( ;; ) + { + if ( !in->good() ) + return; + + int c = in->peek(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + if ( c == '>' ) + break; + + *tag += (char) c; + in->get(); + + if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) ) + { + firstCharFound = true; + if ( c == '/' ) + closingTag = true; + } + } + // If it was a closing tag, then read in the closing '>' to clean up the input stream. + // If it was not, the streaming will be done by the tag. + if ( closingTag ) + { + if ( !in->good() ) + return; + + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + assert( c == '>' ); + *tag += (char) c; + + // We are done, once we've found our closing tag. + return; + } + else + { + // If not a closing tag, id it, and stream. + const char* tagloc = tag->c_str() + tagIndex; + TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING ); + if ( !node ) + return; + node->StreamIn( in, tag ); + delete node; + node = 0; + + // No return: go around from the beginning: text, closing tag, or node. + } + } + } +} +#endif + +const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + p = SkipWhiteSpace( p, encoding ); + TiXmlDocument* document = GetDocument(); + + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding ); + return 0; + } + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + + if ( *p != '<' ) + { + if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding ); + return 0; + } + + p = SkipWhiteSpace( p+1, encoding ); + + // Read the name. + const char* pErr = p; + + p = ReadName( p, &value, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding ); + return 0; + } + + TIXML_STRING endTag ("</"); + endTag += value; + endTag += ">"; + + // Check for and read attributes. Also look for an empty + // tag or an end tag. + while ( p && *p ) + { + pErr = p; + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); + return 0; + } + if ( *p == '/' ) + { + ++p; + // Empty tag. + if ( *p != '>' ) + { + if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding ); + return 0; + } + return (p+1); + } + else if ( *p == '>' ) + { + // Done with attributes (if there were any.) + // Read the value -- which can include other + // elements -- read the end tag, and return. + ++p; + p = ReadValue( p, data, encoding ); // Note this is an Element method, and will set the error if one happens. + if ( !p || !*p ) + return 0; + + // We should find the end tag now + if ( StringEqual( p, endTag.c_str(), false, encoding ) ) + { + p += endTag.length(); + return p; + } + else + { + if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding ); + return 0; + } + } + else + { + // Try to read an attribute: + TiXmlAttribute* attrib = new TiXmlAttribute(); + if ( !attrib ) + { + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding ); + return 0; + } + + attrib->SetDocument( document ); + const char* pErr = p; + p = attrib->Parse( p, data, encoding ); + + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding ); + delete attrib; + return 0; + } + + // Handle the strange case of double attributes: + TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() ); + if ( node ) + { + node->SetValue( attrib->Value() ); + delete attrib; + return 0; + } + + attributeSet.Add( attrib ); + } + } + return p; +} + + +const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + TiXmlDocument* document = GetDocument(); + + // Read in text and elements in any order. + const char* pWithWhiteSpace = p; + p = SkipWhiteSpace( p, encoding ); + + while ( p && *p ) + { + if ( *p != '<' ) + { + // Take what we have, make a text element. + TiXmlText* textNode = new TiXmlText( "" ); + + if ( !textNode ) + { + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding ); + return 0; + } + + if ( TiXmlBase::IsWhiteSpaceCondensed() ) + { + p = textNode->Parse( p, data, encoding ); + } + else + { + // Special case: we want to keep the white space + // so that leading spaces aren't removed. + p = textNode->Parse( pWithWhiteSpace, data, encoding ); + } + + if ( !textNode->Blank() ) + LinkEndChild( textNode ); + else + delete textNode; + } + else + { + // We hit a '<' + // Have we hit a new element or an end tag? This could also be + // a TiXmlText in the "CDATA" style. + if ( StringEqual( p, "</", false, encoding ) ) + { + return p; + } + else + { + TiXmlNode* node = Identify( p, encoding ); + if ( node ) + { + p = node->Parse( p, data, encoding ); + LinkEndChild( node ); + } + else + { + return 0; + } + } + } + pWithWhiteSpace = p; + p = SkipWhiteSpace( p, encoding ); + } + + if ( !p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding ); + } + return p; +} + + +#ifdef TIXML_USE_STL +void TiXmlUnknown::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + (*tag) += (char) c; + + if ( c == '>' ) + { + // All is well. + return; + } + } +} +#endif + + +const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + TiXmlDocument* document = GetDocument(); + p = SkipWhiteSpace( p, encoding ); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + if ( !p || !*p || *p != '<' ) + { + if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding ); + return 0; + } + ++p; + value = ""; + + while ( p && *p && *p != '>' ) + { + value += *p; + ++p; + } + + if ( !p ) + { + if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding ); + } + if ( *p == '>' ) + return p+1; + return p; +} + +#ifdef TIXML_USE_STL +void TiXmlComment::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + (*tag) += (char) c; + + if ( c == '>' + && tag->at( tag->length() - 2 ) == '-' + && tag->at( tag->length() - 3 ) == '-' ) + { + // All is well. + return; + } + } +} +#endif + + +const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + TiXmlDocument* document = GetDocument(); + value = ""; + + p = SkipWhiteSpace( p, encoding ); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + const char* startTag = "<!--"; + const char* endTag = "-->"; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + p = ReadText( p, &value, false, endTag, false, encoding ); + return p; +} + + +const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) return 0; + + int tabsize = 4; + if ( document ) + tabsize = document->TabSize(); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + // Read the name, the '=' and the value. + const char* pErr = p; + p = ReadName( p, &name, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); + return 0; + } + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p || *p != '=' ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + ++p; // skip '=' + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + const char* end; + + if ( *p == '\'' ) + { + ++p; + end = "\'"; + p = ReadText( p, &value, false, end, false, encoding ); + } + else if ( *p == '"' ) + { + ++p; + end = "\""; + p = ReadText( p, &value, false, end, false, encoding ); + } + else + { + // All attribute values should be in single or double quotes. + // But this is such a common error that the parser will try + // its best, even without them. + value = ""; + while ( p && *p // existence + && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace + && *p != '/' && *p != '>' ) // tag end + { + value += *p; + ++p; + } + } + return p; +} + +#ifdef TIXML_USE_STL +void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + if ( cdata ) + { + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + (*tag) += (char) c; + + if ( c == '>' + && tag->at( tag->length() - 2 ) == ']' + && tag->at( tag->length() - 3 ) == ']' ) + { + // All is well. + return; + } + } + else + { + while ( in->good() ) + { + int c = in->peek(); + if ( c == '<' ) + return; + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + (*tag) += (char) c; + in->get(); + } + } +} +#endif + +const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) +{ + value = ""; + TiXmlDocument* document = GetDocument(); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + + const char* const startTag = "<![CDATA["; + const char* const endTag = "]]>"; + + if ( cdata || StringEqual( p, startTag, false, encoding ) ) + { + cdata = true; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + + // Keep all the white space, ignore the encoding, etc. + while ( p && *p + && !StringEqual( p, endTag, false, encoding ) + ) + { + value += *p; + ++p; + } + + TIXML_STRING dummy; + p = ReadText( p, &dummy, false, endTag, false, encoding ); + return p; + } + else + { + bool ignoreWhite = true; + + const char* end = "<"; + p = ReadText( p, &value, ignoreWhite, end, false, encoding ); + if ( p ) + return p-1; // don't truncate the '<' + return 0; + } +} + +#ifdef TIXML_USE_STL +void TiXmlDeclaration::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) +{ + while ( in->good() ) + { + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + (*tag) += (char) c; + + if ( c == '>' ) + { + // All is well. + return; + } + } +} +#endif + +const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) +{ + p = SkipWhiteSpace( p, _encoding ); + // Find the beginning, find the end, and look for + // the stuff in-between. + TiXmlDocument* document = GetDocument(); + if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) ) + { + if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); + return 0; + } + if ( data ) + { + data->Stamp( p, _encoding ); + location = data->Cursor(); + } + p += 5; + + version = ""; + encoding = ""; + standalone = ""; + + while ( p && *p ) + { + if ( *p == '>' ) + { + ++p; + return p; + } + + p = SkipWhiteSpace( p, _encoding ); + if ( StringEqual( p, "version", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + version = attrib.Value(); + } + else if ( StringEqual( p, "encoding", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + encoding = attrib.Value(); + } + else if ( StringEqual( p, "standalone", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + standalone = attrib.Value(); + } + else + { + // Read over whatever it is. + while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) + ++p; + } + } + return 0; +} + +bool TiXmlText::Blank() const +{ + for ( unsigned i=0; i<value.length(); i++ ) + if ( !IsWhiteSpace( value[i] ) ) + return false; + return true; +} + |