[SCM] BOINC packaging branch, master, updated. debian/7.0.33+dfsg-1-98-g3a92b59
Gianfranco Costamagna
costamagnagianfranco at yahoo.it
Sun Nov 11 10:51:18 UTC 2012
The following commit has been merged in the master branch:
commit 2dc6e4b71d170b2e93a92ad0a297df86cf1ec58c
Author: Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
Date: Sun Nov 11 11:42:37 2012 +0100
Imported Upstream version 7.0.39+dfsg
diff --git a/checkin_notes b/checkin_notes
index 99b36c3..f175b48 100644
--- a/checkin_notes
+++ b/checkin_notes
@@ -4736,3 +4736,11 @@ Rom 2 Nov 2012
/
configure.ac
version.h
+
+Rom 8 Nov 2012
+ - Tag for 7.0.39 release, all platforms
+ client_release_7.0.39
+
+ /
+ configure.ac
+ version.h
diff --git a/configure.ac b/configure.ac
index 37ba36d..1798001 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,7 +6,7 @@ dnl not sure exactly what the minimum version is (but 2.13 wont work)
AC_PREREQ(2.58)
dnl Set the BOINC version here. You can also use the set-version script.
-AC_INIT(BOINC, 7.0.38)
+AC_INIT(BOINC, 7.0.39)
AC_CONFIG_MACRO_DIR([m4])
LIBBOINC_VERSION=`echo ${PACKAGE_VERSION} | sed 's/\./:/g'`
AC_SUBST([LIBBOINC_VERSION])
diff --git a/m4/ax_lang_compiler_ms.m4 b/m4/ax_lang_compiler_ms.m4
new file mode 100644
index 0000000..d0c73dc
--- /dev/null
+++ b/m4/ax_lang_compiler_ms.m4
@@ -0,0 +1,14 @@
+dnl Available from the GNU Autoconf Macro Archive at:
+dnl http://www.gnu.org/software/ac-archive/htmldoc/ax_lang_compiler_ms.html
+dnl
+AC_DEFUN([AX_LANG_COMPILER_MS],
+[AC_CACHE_CHECK([whether we are using the Microsoft _AC_LANG compiler],
+ [ax_cv_[]_AC_LANG_ABBREV[]_compiler_ms],
+[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[#ifndef _MSC_VER
+ choke me
+#endif
+]])],
+ [ax_compiler_ms=yes],
+ [ax_compiler_ms=no])
+ax_cv_[]_AC_LANG_ABBREV[]_compiler_ms=$ax_compiler_ms
+])])
diff --git a/samples/mac_build/UpperCase2.xcodeproj/project.pbxproj b/samples/mac_build/UpperCase2.xcodeproj/project.pbxproj
deleted file mode 100644
index f6eb14e..0000000
--- a/samples/mac_build/UpperCase2.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,1248 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 42;
- objects = {
-
-/* Begin PBXAggregateTarget section */
- DD84C71E0C856D9E000EBEC4 /* Build_All */ = {
- isa = PBXAggregateTarget;
- buildConfigurationList = DD84C7280C856DBB000EBEC4 /* Build configuration list for PBXAggregateTarget "Build_All" */;
- buildPhases = (
- );
- dependencies = (
- DDC479C015AC57C40022401F /* PBXTargetDependency */,
- DDC479BE15AC57BC0022401F /* PBXTargetDependency */,
- DD84C7200C856DA6000EBEC4 /* PBXTargetDependency */,
- DD84C7220C856DA6000EBEC4 /* PBXTargetDependency */,
- );
- name = Build_All;
- productName = Build_All;
- };
-/* End PBXAggregateTarget section */
-
-/* Begin PBXBuildFile section */
- DD1194B00F42CB4900C2BC25 /* uc2_graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD1194AF0F42CB4900C2BC25 /* uc2_graphics.cpp */; };
- DD1194B20F42CB5400C2BC25 /* uc2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD1194B10F42CB5400C2BC25 /* uc2.cpp */; };
- DD760E68094E56DB002CACC4 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E65094E56DB002CACC4 /* AppKit.framework */; };
- DD760E69094E56DB002CACC4 /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E66094E56DB002CACC4 /* GLUT.framework */; };
- DD760E6A094E56DB002CACC4 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E67094E56DB002CACC4 /* OpenGL.framework */; };
- DD84C6A90C856B36000EBEC4 /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66A09EBA9710024857D /* jcapimin.c */; };
- DD84C6AA0C856B36000EBEC4 /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66B09EBA9710024857D /* jcapistd.c */; };
- DD84C6AB0C856B36000EBEC4 /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66C09EBA9710024857D /* jccoefct.c */; };
- DD84C6AC0C856B36000EBEC4 /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66D09EBA9710024857D /* jccolor.c */; };
- DD84C6AD0C856B36000EBEC4 /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66E09EBA9710024857D /* jcdctmgr.c */; };
- DD84C6AE0C856B36000EBEC4 /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66F09EBA9710024857D /* jchuff.c */; };
- DD84C6AF0C856B36000EBEC4 /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67109EBA9710024857D /* jcinit.c */; };
- DD84C6B00C856B36000EBEC4 /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67209EBA9710024857D /* jcmainct.c */; };
- DD84C6B10C856B36000EBEC4 /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67309EBA9710024857D /* jcmarker.c */; };
- DD84C6B20C856B36000EBEC4 /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67409EBA9710024857D /* jcmaster.c */; };
- DD84C6B30C856B36000EBEC4 /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67509EBA9710024857D /* jcomapi.c */; };
- DD84C6B40C856B36000EBEC4 /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67709EBA9710024857D /* jcparam.c */; };
- DD84C6B50C856B36000EBEC4 /* jcphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67809EBA9710024857D /* jcphuff.c */; };
- DD84C6B60C856B36000EBEC4 /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67909EBA9710024857D /* jcprepct.c */; };
- DD84C6B70C856B36000EBEC4 /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67A09EBA9710024857D /* jcsample.c */; };
- DD84C6B80C856B36000EBEC4 /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67B09EBA9710024857D /* jctrans.c */; };
- DD84C6B90C856B36000EBEC4 /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67C09EBA9710024857D /* jdapimin.c */; };
- DD84C6BA0C856B36000EBEC4 /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67D09EBA9710024857D /* jdapistd.c */; };
- DD84C6BB0C856B36000EBEC4 /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67E09EBA9710024857D /* jdatadst.c */; };
- DD84C6BC0C856B36000EBEC4 /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67F09EBA9710024857D /* jdatasrc.c */; };
- DD84C6BD0C856B36000EBEC4 /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68009EBA9710024857D /* jdcoefct.c */; };
- DD84C6BE0C856B36000EBEC4 /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68109EBA9710024857D /* jdcolor.c */; };
- DD84C6BF0C856B36000EBEC4 /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68309EBA9710024857D /* jddctmgr.c */; };
- DD84C6C00C856B36000EBEC4 /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68409EBA9710024857D /* jdhuff.c */; };
- DD84C6C10C856B36000EBEC4 /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68609EBA9710024857D /* jdinput.c */; };
- DD84C6C20C856B36000EBEC4 /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68709EBA9710024857D /* jdmainct.c */; };
- DD84C6C30C856B36000EBEC4 /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68809EBA9710024857D /* jdmarker.c */; };
- DD84C6C40C856B36000EBEC4 /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68909EBA9710024857D /* jdmaster.c */; };
- DD84C6C50C856B36000EBEC4 /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68A09EBA9710024857D /* jdmerge.c */; };
- DD84C6C60C856B36000EBEC4 /* jdphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68B09EBA9710024857D /* jdphuff.c */; };
- DD84C6C70C856B36000EBEC4 /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68C09EBA9710024857D /* jdpostct.c */; };
- DD84C6C80C856B36000EBEC4 /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68D09EBA9710024857D /* jdsample.c */; };
- DD84C6C90C856B36000EBEC4 /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68E09EBA9710024857D /* jdtrans.c */; };
- DD84C6CA0C856B36000EBEC4 /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68F09EBA9710024857D /* jerror.c */; };
- DD84C6CB0C856B36000EBEC4 /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69109EBA9710024857D /* jfdctflt.c */; };
- DD84C6CC0C856B36000EBEC4 /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69209EBA9710024857D /* jfdctfst.c */; };
- DD84C6CD0C856B36000EBEC4 /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69309EBA9710024857D /* jfdctint.c */; };
- DD84C6CE0C856B36000EBEC4 /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69409EBA9710024857D /* jidctflt.c */; };
- DD84C6CF0C856B36000EBEC4 /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69509EBA9710024857D /* jidctfst.c */; };
- DD84C6D00C856B36000EBEC4 /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69609EBA9710024857D /* jidctint.c */; };
- DD84C6D10C856B36000EBEC4 /* jidctred.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69709EBA9710024857D /* jidctred.c */; };
- DD84C6D20C856B36000EBEC4 /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69909EBA9710024857D /* jmemmgr.c */; };
- DD84C6D30C856B36000EBEC4 /* jmemnobs.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69A09EBA9710024857D /* jmemnobs.c */; };
- DD84C6D40C856B36000EBEC4 /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69F09EBA9710024857D /* jquant1.c */; };
- DD84C6D50C856B36000EBEC4 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A009EBA9710024857D /* jquant2.c */; };
- DD84C6D60C856B36000EBEC4 /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A109EBA9710024857D /* jutils.c */; };
- DD84C6D70C856B36000EBEC4 /* rdbmp.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A309EBA9710024857D /* rdbmp.c */; };
- DD84C6D80C856B36000EBEC4 /* rdcolmap.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A409EBA9710024857D /* rdcolmap.c */; };
- DD84C6D90C856B36000EBEC4 /* rdgif.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A509EBA9710024857D /* rdgif.c */; };
- DD84C6DA0C856B36000EBEC4 /* rdppm.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A609EBA9710024857D /* rdppm.c */; };
- DD84C6DB0C856B36000EBEC4 /* rdrle.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A709EBA9710024857D /* rdrle.c */; };
- DD84C6DC0C856B36000EBEC4 /* rdswitch.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A809EBA9710024857D /* rdswitch.c */; };
- DD84C6DD0C856B36000EBEC4 /* rdtarga.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A909EBA9710024857D /* rdtarga.c */; };
- DD84C6DF0C856B36000EBEC4 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E65094E56DB002CACC4 /* AppKit.framework */; };
- DD84C6E00C856B36000EBEC4 /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E66094E56DB002CACC4 /* GLUT.framework */; };
- DD84C6E10C856B36000EBEC4 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E67094E56DB002CACC4 /* OpenGL.framework */; };
- DDC4796715AC56CA0022401F /* uc2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD1194B10F42CB5400C2BC25 /* uc2.cpp */; };
- DDC4796915AC56CA0022401F /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E65094E56DB002CACC4 /* AppKit.framework */; };
- DDC4796A15AC56CA0022401F /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E66094E56DB002CACC4 /* GLUT.framework */; };
- DDC4796B15AC56CA0022401F /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E67094E56DB002CACC4 /* OpenGL.framework */; };
- DDC4797915AC56EB0022401F /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66A09EBA9710024857D /* jcapimin.c */; };
- DDC4797A15AC56EB0022401F /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66B09EBA9710024857D /* jcapistd.c */; };
- DDC4797B15AC56EB0022401F /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66C09EBA9710024857D /* jccoefct.c */; };
- DDC4797C15AC56EB0022401F /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66D09EBA9710024857D /* jccolor.c */; };
- DDC4797D15AC56EB0022401F /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66E09EBA9710024857D /* jcdctmgr.c */; };
- DDC4797E15AC56EB0022401F /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F66F09EBA9710024857D /* jchuff.c */; };
- DDC4797F15AC56EB0022401F /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67109EBA9710024857D /* jcinit.c */; };
- DDC4798015AC56EB0022401F /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67209EBA9710024857D /* jcmainct.c */; };
- DDC4798115AC56EB0022401F /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67309EBA9710024857D /* jcmarker.c */; };
- DDC4798215AC56EB0022401F /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67409EBA9710024857D /* jcmaster.c */; };
- DDC4798315AC56EB0022401F /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67509EBA9710024857D /* jcomapi.c */; };
- DDC4798415AC56EB0022401F /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67709EBA9710024857D /* jcparam.c */; };
- DDC4798515AC56EB0022401F /* jcphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67809EBA9710024857D /* jcphuff.c */; };
- DDC4798615AC56EB0022401F /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67909EBA9710024857D /* jcprepct.c */; };
- DDC4798715AC56EB0022401F /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67A09EBA9710024857D /* jcsample.c */; };
- DDC4798815AC56EB0022401F /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67B09EBA9710024857D /* jctrans.c */; };
- DDC4798915AC56EB0022401F /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67C09EBA9710024857D /* jdapimin.c */; };
- DDC4798A15AC56EB0022401F /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67D09EBA9710024857D /* jdapistd.c */; };
- DDC4798B15AC56EB0022401F /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67E09EBA9710024857D /* jdatadst.c */; };
- DDC4798C15AC56EB0022401F /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F67F09EBA9710024857D /* jdatasrc.c */; };
- DDC4798D15AC56EB0022401F /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68009EBA9710024857D /* jdcoefct.c */; };
- DDC4798E15AC56EB0022401F /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68109EBA9710024857D /* jdcolor.c */; };
- DDC4798F15AC56EB0022401F /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68309EBA9710024857D /* jddctmgr.c */; };
- DDC4799015AC56EB0022401F /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68409EBA9710024857D /* jdhuff.c */; };
- DDC4799115AC56EB0022401F /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68609EBA9710024857D /* jdinput.c */; };
- DDC4799215AC56EB0022401F /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68709EBA9710024857D /* jdmainct.c */; };
- DDC4799315AC56EB0022401F /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68809EBA9710024857D /* jdmarker.c */; };
- DDC4799415AC56EB0022401F /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68909EBA9710024857D /* jdmaster.c */; };
- DDC4799515AC56EB0022401F /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68A09EBA9710024857D /* jdmerge.c */; };
- DDC4799615AC56EB0022401F /* jdphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68B09EBA9710024857D /* jdphuff.c */; };
- DDC4799715AC56EB0022401F /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68C09EBA9710024857D /* jdpostct.c */; };
- DDC4799815AC56EB0022401F /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68D09EBA9710024857D /* jdsample.c */; };
- DDC4799915AC56EB0022401F /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68E09EBA9710024857D /* jdtrans.c */; };
- DDC4799A15AC56EB0022401F /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F68F09EBA9710024857D /* jerror.c */; };
- DDC4799B15AC56EB0022401F /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69109EBA9710024857D /* jfdctflt.c */; };
- DDC4799C15AC56EB0022401F /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69209EBA9710024857D /* jfdctfst.c */; };
- DDC4799D15AC56EB0022401F /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69309EBA9710024857D /* jfdctint.c */; };
- DDC4799E15AC56EB0022401F /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69409EBA9710024857D /* jidctflt.c */; };
- DDC4799F15AC56EB0022401F /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69509EBA9710024857D /* jidctfst.c */; };
- DDC479A015AC56EB0022401F /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69609EBA9710024857D /* jidctint.c */; };
- DDC479A115AC56EB0022401F /* jidctred.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69709EBA9710024857D /* jidctred.c */; };
- DDC479A215AC56EB0022401F /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69909EBA9710024857D /* jmemmgr.c */; };
- DDC479A315AC56EB0022401F /* jmemnobs.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69A09EBA9710024857D /* jmemnobs.c */; };
- DDC479A415AC56EB0022401F /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F69F09EBA9710024857D /* jquant1.c */; };
- DDC479A515AC56EB0022401F /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A009EBA9710024857D /* jquant2.c */; };
- DDC479A615AC56EB0022401F /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A109EBA9710024857D /* jutils.c */; };
- DDC479A715AC56EB0022401F /* rdbmp.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A309EBA9710024857D /* rdbmp.c */; };
- DDC479A815AC56EB0022401F /* rdcolmap.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A409EBA9710024857D /* rdcolmap.c */; };
- DDC479A915AC56EB0022401F /* rdgif.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A509EBA9710024857D /* rdgif.c */; };
- DDC479AA15AC56EB0022401F /* rdppm.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A609EBA9710024857D /* rdppm.c */; };
- DDC479AB15AC56EB0022401F /* rdrle.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A709EBA9710024857D /* rdrle.c */; };
- DDC479AC15AC56EB0022401F /* rdswitch.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A809EBA9710024857D /* rdswitch.c */; };
- DDC479AD15AC56EB0022401F /* rdtarga.c in Sources */ = {isa = PBXBuildFile; fileRef = DD00F6A909EBA9710024857D /* rdtarga.c */; };
- DDC479AE15AC56EB0022401F /* uc2_graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD1194AF0F42CB4900C2BC25 /* uc2_graphics.cpp */; };
- DDC479B015AC56EB0022401F /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E65094E56DB002CACC4 /* AppKit.framework */; };
- DDC479B115AC56EB0022401F /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E66094E56DB002CACC4 /* GLUT.framework */; };
- DDC479B215AC56EB0022401F /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD760E67094E56DB002CACC4 /* OpenGL.framework */; };
- DDF8050515CB9C75005473CC /* ttfont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDF8050315CB9C75005473CC /* ttfont.cpp */; };
- DDF8050615CB9C75005473CC /* ttfont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDF8050315CB9C75005473CC /* ttfont.cpp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXBuildRule section */
- DD760E3C094E540C002CACC4 /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.asm;
- isEditable = 1;
- outputFiles = (
- );
- };
- DD760E3D094E540D002CACC4 /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.cpp;
- isEditable = 1;
- outputFiles = (
- );
- };
- DD760E3E094E540D002CACC4 /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.c;
- isEditable = 1;
- outputFiles = (
- );
- };
- DD84C6E30C856B36000EBEC4 /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.c;
- isEditable = 1;
- outputFiles = (
- );
- };
- DD84C6E40C856B36000EBEC4 /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.cpp;
- isEditable = 1;
- outputFiles = (
- );
- };
- DD84C6E50C856B36000EBEC4 /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.asm;
- isEditable = 1;
- outputFiles = (
- );
- };
- DDC4796E15AC56CA0022401F /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.c;
- isEditable = 1;
- outputFiles = (
- );
- };
- DDC4796F15AC56CA0022401F /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.cpp;
- isEditable = 1;
- outputFiles = (
- );
- };
- DDC4797015AC56CA0022401F /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.asm;
- isEditable = 1;
- outputFiles = (
- );
- };
- DDC479B415AC56EB0022401F /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.c;
- isEditable = 1;
- outputFiles = (
- );
- };
- DDC479B515AC56EB0022401F /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.cpp;
- isEditable = 1;
- outputFiles = (
- );
- };
- DDC479B615AC56EB0022401F /* PBXBuildRule */ = {
- isa = PBXBuildRule;
- compilerSpec = com.apple.compilers.gcc.4_0;
- fileType = sourcecode.asm;
- isEditable = 1;
- outputFiles = (
- );
- };
-/* End PBXBuildRule section */
-
-/* Begin PBXContainerItemProxy section */
- DD84C71F0C856DA6000EBEC4 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 8DD76FA90486AB0100D96B5E;
- remoteInfo = UC2;
- };
- DD84C7210C856DA6000EBEC4 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = DD84C6A70C856B36000EBEC4;
- remoteInfo = UC2Gfx;
- };
- DDC479BD15AC57BC0022401F /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = DDC4796515AC56CA0022401F;
- remoteInfo = "UC2-x86_64";
- };
- DDC479BF15AC57C40022401F /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = DDC4797715AC56EB0022401F;
- remoteInfo = "UC2Gfx-x86_64";
- };
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXFileReference section */
- 8DD76FB20486AB0100D96B5E /* uc2_i686-apple-darwin */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "uc2_i686-apple-darwin"; sourceTree = BUILT_PRODUCTS_DIR; };
- DD00F66809EBA9710024857D /* cderror.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cderror.h; path = ../jpeglib/cderror.h; sourceTree = SOURCE_ROOT; };
- DD00F66909EBA9710024857D /* cdjpeg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cdjpeg.h; path = ../jpeglib/cdjpeg.h; sourceTree = SOURCE_ROOT; };
- DD00F66A09EBA9710024857D /* jcapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcapimin.c; path = ../jpeglib/jcapimin.c; sourceTree = SOURCE_ROOT; };
- DD00F66B09EBA9710024857D /* jcapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcapistd.c; path = ../jpeglib/jcapistd.c; sourceTree = SOURCE_ROOT; };
- DD00F66C09EBA9710024857D /* jccoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jccoefct.c; path = ../jpeglib/jccoefct.c; sourceTree = SOURCE_ROOT; };
- DD00F66D09EBA9710024857D /* jccolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jccolor.c; path = ../jpeglib/jccolor.c; sourceTree = SOURCE_ROOT; };
- DD00F66E09EBA9710024857D /* jcdctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcdctmgr.c; path = ../jpeglib/jcdctmgr.c; sourceTree = SOURCE_ROOT; };
- DD00F66F09EBA9710024857D /* jchuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jchuff.c; path = ../jpeglib/jchuff.c; sourceTree = SOURCE_ROOT; };
- DD00F67009EBA9710024857D /* jchuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jchuff.h; path = ../jpeglib/jchuff.h; sourceTree = SOURCE_ROOT; };
- DD00F67109EBA9710024857D /* jcinit.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcinit.c; path = ../jpeglib/jcinit.c; sourceTree = SOURCE_ROOT; };
- DD00F67209EBA9710024857D /* jcmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcmainct.c; path = ../jpeglib/jcmainct.c; sourceTree = SOURCE_ROOT; };
- DD00F67309EBA9710024857D /* jcmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcmarker.c; path = ../jpeglib/jcmarker.c; sourceTree = SOURCE_ROOT; };
- DD00F67409EBA9710024857D /* jcmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcmaster.c; path = ../jpeglib/jcmaster.c; sourceTree = SOURCE_ROOT; };
- DD00F67509EBA9710024857D /* jcomapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcomapi.c; path = ../jpeglib/jcomapi.c; sourceTree = SOURCE_ROOT; };
- DD00F67609EBA9710024857D /* jconfig.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jconfig.h; path = ../jpeglib/jconfig.h; sourceTree = SOURCE_ROOT; };
- DD00F67709EBA9710024857D /* jcparam.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcparam.c; path = ../jpeglib/jcparam.c; sourceTree = SOURCE_ROOT; };
- DD00F67809EBA9710024857D /* jcphuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcphuff.c; path = ../jpeglib/jcphuff.c; sourceTree = SOURCE_ROOT; };
- DD00F67909EBA9710024857D /* jcprepct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcprepct.c; path = ../jpeglib/jcprepct.c; sourceTree = SOURCE_ROOT; };
- DD00F67A09EBA9710024857D /* jcsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jcsample.c; path = ../jpeglib/jcsample.c; sourceTree = SOURCE_ROOT; };
- DD00F67B09EBA9710024857D /* jctrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jctrans.c; path = ../jpeglib/jctrans.c; sourceTree = SOURCE_ROOT; };
- DD00F67C09EBA9710024857D /* jdapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdapimin.c; path = ../jpeglib/jdapimin.c; sourceTree = SOURCE_ROOT; };
- DD00F67D09EBA9710024857D /* jdapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdapistd.c; path = ../jpeglib/jdapistd.c; sourceTree = SOURCE_ROOT; };
- DD00F67E09EBA9710024857D /* jdatadst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdatadst.c; path = ../jpeglib/jdatadst.c; sourceTree = SOURCE_ROOT; };
- DD00F67F09EBA9710024857D /* jdatasrc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdatasrc.c; path = ../jpeglib/jdatasrc.c; sourceTree = SOURCE_ROOT; };
- DD00F68009EBA9710024857D /* jdcoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdcoefct.c; path = ../jpeglib/jdcoefct.c; sourceTree = SOURCE_ROOT; };
- DD00F68109EBA9710024857D /* jdcolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdcolor.c; path = ../jpeglib/jdcolor.c; sourceTree = SOURCE_ROOT; };
- DD00F68209EBA9710024857D /* jdct.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jdct.h; path = ../jpeglib/jdct.h; sourceTree = SOURCE_ROOT; };
- DD00F68309EBA9710024857D /* jddctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jddctmgr.c; path = ../jpeglib/jddctmgr.c; sourceTree = SOURCE_ROOT; };
- DD00F68409EBA9710024857D /* jdhuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdhuff.c; path = ../jpeglib/jdhuff.c; sourceTree = SOURCE_ROOT; };
- DD00F68509EBA9710024857D /* jdhuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jdhuff.h; path = ../jpeglib/jdhuff.h; sourceTree = SOURCE_ROOT; };
- DD00F68609EBA9710024857D /* jdinput.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdinput.c; path = ../jpeglib/jdinput.c; sourceTree = SOURCE_ROOT; };
- DD00F68709EBA9710024857D /* jdmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmainct.c; path = ../jpeglib/jdmainct.c; sourceTree = SOURCE_ROOT; };
- DD00F68809EBA9710024857D /* jdmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmarker.c; path = ../jpeglib/jdmarker.c; sourceTree = SOURCE_ROOT; };
- DD00F68909EBA9710024857D /* jdmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmaster.c; path = ../jpeglib/jdmaster.c; sourceTree = SOURCE_ROOT; };
- DD00F68A09EBA9710024857D /* jdmerge.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdmerge.c; path = ../jpeglib/jdmerge.c; sourceTree = SOURCE_ROOT; };
- DD00F68B09EBA9710024857D /* jdphuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdphuff.c; path = ../jpeglib/jdphuff.c; sourceTree = SOURCE_ROOT; };
- DD00F68C09EBA9710024857D /* jdpostct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdpostct.c; path = ../jpeglib/jdpostct.c; sourceTree = SOURCE_ROOT; };
- DD00F68D09EBA9710024857D /* jdsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdsample.c; path = ../jpeglib/jdsample.c; sourceTree = SOURCE_ROOT; };
- DD00F68E09EBA9710024857D /* jdtrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jdtrans.c; path = ../jpeglib/jdtrans.c; sourceTree = SOURCE_ROOT; };
- DD00F68F09EBA9710024857D /* jerror.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jerror.c; path = ../jpeglib/jerror.c; sourceTree = SOURCE_ROOT; };
- DD00F69009EBA9710024857D /* jerror.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jerror.h; path = ../jpeglib/jerror.h; sourceTree = SOURCE_ROOT; };
- DD00F69109EBA9710024857D /* jfdctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jfdctflt.c; path = ../jpeglib/jfdctflt.c; sourceTree = SOURCE_ROOT; };
- DD00F69209EBA9710024857D /* jfdctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jfdctfst.c; path = ../jpeglib/jfdctfst.c; sourceTree = SOURCE_ROOT; };
- DD00F69309EBA9710024857D /* jfdctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jfdctint.c; path = ../jpeglib/jfdctint.c; sourceTree = SOURCE_ROOT; };
- DD00F69409EBA9710024857D /* jidctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctflt.c; path = ../jpeglib/jidctflt.c; sourceTree = SOURCE_ROOT; };
- DD00F69509EBA9710024857D /* jidctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctfst.c; path = ../jpeglib/jidctfst.c; sourceTree = SOURCE_ROOT; };
- DD00F69609EBA9710024857D /* jidctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctint.c; path = ../jpeglib/jidctint.c; sourceTree = SOURCE_ROOT; };
- DD00F69709EBA9710024857D /* jidctred.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jidctred.c; path = ../jpeglib/jidctred.c; sourceTree = SOURCE_ROOT; };
- DD00F69809EBA9710024857D /* jinclude.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jinclude.h; path = ../jpeglib/jinclude.h; sourceTree = SOURCE_ROOT; };
- DD00F69909EBA9710024857D /* jmemmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jmemmgr.c; path = ../jpeglib/jmemmgr.c; sourceTree = SOURCE_ROOT; };
- DD00F69A09EBA9710024857D /* jmemnobs.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jmemnobs.c; path = ../jpeglib/jmemnobs.c; sourceTree = SOURCE_ROOT; };
- DD00F69B09EBA9710024857D /* jmemsys.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jmemsys.h; path = ../jpeglib/jmemsys.h; sourceTree = SOURCE_ROOT; };
- DD00F69C09EBA9710024857D /* jmorecfg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jmorecfg.h; path = ../jpeglib/jmorecfg.h; sourceTree = SOURCE_ROOT; };
- DD00F69D09EBA9710024857D /* jpegint.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jpegint.h; path = ../jpeglib/jpegint.h; sourceTree = SOURCE_ROOT; };
- DD00F69E09EBA9710024857D /* jpeglib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jpeglib.h; path = ../jpeglib/jpeglib.h; sourceTree = SOURCE_ROOT; };
- DD00F69F09EBA9710024857D /* jquant1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jquant1.c; path = ../jpeglib/jquant1.c; sourceTree = SOURCE_ROOT; };
- DD00F6A009EBA9710024857D /* jquant2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jquant2.c; path = ../jpeglib/jquant2.c; sourceTree = SOURCE_ROOT; };
- DD00F6A109EBA9710024857D /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jutils.c; path = ../jpeglib/jutils.c; sourceTree = SOURCE_ROOT; };
- DD00F6A209EBA9710024857D /* jversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jversion.h; path = ../jpeglib/jversion.h; sourceTree = SOURCE_ROOT; };
- DD00F6A309EBA9710024857D /* rdbmp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rdbmp.c; path = ../jpeglib/rdbmp.c; sourceTree = SOURCE_ROOT; };
- DD00F6A409EBA9710024857D /* rdcolmap.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rdcolmap.c; path = ../jpeglib/rdcolmap.c; sourceTree = SOURCE_ROOT; };
- DD00F6A509EBA9710024857D /* rdgif.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rdgif.c; path = ../jpeglib/rdgif.c; sourceTree = SOURCE_ROOT; };
- DD00F6A609EBA9710024857D /* rdppm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rdppm.c; path = ../jpeglib/rdppm.c; sourceTree = SOURCE_ROOT; };
- DD00F6A709EBA9710024857D /* rdrle.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rdrle.c; path = ../jpeglib/rdrle.c; sourceTree = SOURCE_ROOT; };
- DD00F6A809EBA9710024857D /* rdswitch.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rdswitch.c; path = ../jpeglib/rdswitch.c; sourceTree = SOURCE_ROOT; };
- DD00F6A909EBA9710024857D /* rdtarga.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rdtarga.c; path = ../jpeglib/rdtarga.c; sourceTree = SOURCE_ROOT; };
- DD1194AE0F42CAF400C2BC25 /* checkin_notes_samples */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = checkin_notes_samples; path = ../../checkin_notes_samples; sourceTree = SOURCE_ROOT; };
- DD1194AF0F42CB4900C2BC25 /* uc2_graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = uc2_graphics.cpp; path = ../example_app/uc2_graphics.cpp; sourceTree = SOURCE_ROOT; };
- DD1194B10F42CB5400C2BC25 /* uc2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = uc2.cpp; path = ../example_app/uc2.cpp; sourceTree = SOURCE_ROOT; };
- DD760E65094E56DB002CACC4 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
- DD760E66094E56DB002CACC4 /* GLUT.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLUT.framework; path = /System/Library/Frameworks/GLUT.framework; sourceTree = "<absolute>"; };
- DD760E67094E56DB002CACC4 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
- DD84C6EA0C856B36000EBEC4 /* uc2_graphics_i686-apple-darwin */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "uc2_graphics_i686-apple-darwin"; sourceTree = BUILT_PRODUCTS_DIR; };
- DD84C6F90C856C0E000EBEC4 /* uc2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = uc2.h; path = ../example_app/uc2.h; sourceTree = SOURCE_ROOT; };
- DDC4797515AC56CA0022401F /* UC2_x86_64-apple-darwin */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "UC2_x86_64-apple-darwin"; sourceTree = BUILT_PRODUCTS_DIR; };
- DDC479BB15AC56EB0022401F /* UC2_graphics_x86_64-apple-darwin */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "UC2_graphics_x86_64-apple-darwin"; sourceTree = BUILT_PRODUCTS_DIR; };
- DDF8050315CB9C75005473CC /* ttfont.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ttfont.cpp; path = ../../api/ttfont.cpp; sourceTree = "<group>"; };
- DDF8050415CB9C75005473CC /* ttfont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ttfont.h; path = ../../api/ttfont.h; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DD760E68094E56DB002CACC4 /* AppKit.framework in Frameworks */,
- DD760E69094E56DB002CACC4 /* GLUT.framework in Frameworks */,
- DD760E6A094E56DB002CACC4 /* OpenGL.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DD84C6DE0C856B36000EBEC4 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DD84C6DF0C856B36000EBEC4 /* AppKit.framework in Frameworks */,
- DD84C6E00C856B36000EBEC4 /* GLUT.framework in Frameworks */,
- DD84C6E10C856B36000EBEC4 /* OpenGL.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DDC4796815AC56CA0022401F /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DDC4796915AC56CA0022401F /* AppKit.framework in Frameworks */,
- DDC4796A15AC56CA0022401F /* GLUT.framework in Frameworks */,
- DDC4796B15AC56CA0022401F /* OpenGL.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DDC479AF15AC56EB0022401F /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DDC479B015AC56EB0022401F /* AppKit.framework in Frameworks */,
- DDC479B115AC56EB0022401F /* GLUT.framework in Frameworks */,
- DDC479B215AC56EB0022401F /* OpenGL.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 08FB7794FE84155DC02AAC07 /* UpperCase */ = {
- isa = PBXGroup;
- children = (
- DD00F81309EBAD960024857D /* Documentation */,
- 08FB7795FE84155DC02AAC07 /* Source */,
- DD760E5E094E5663002CACC4 /* External Frameworks and Libraries */,
- 1AB674ADFE9D54B511CA2CBB /* Products */,
- );
- name = UpperCase;
- sourceTree = "<group>";
- };
- 08FB7795FE84155DC02AAC07 /* Source */ = {
- isa = PBXGroup;
- children = (
- DD1194AF0F42CB4900C2BC25 /* uc2_graphics.cpp */,
- DD1194B10F42CB5400C2BC25 /* uc2.cpp */,
- DD84C6F90C856C0E000EBEC4 /* uc2.h */,
- DD00F66509EBA9320024857D /* jpeg */,
- DDF8050715CB9C88005473CC /* api */,
- );
- name = Source;
- sourceTree = "<group>";
- };
- 1AB674ADFE9D54B511CA2CBB /* Products */ = {
- isa = PBXGroup;
- children = (
- 8DD76FB20486AB0100D96B5E /* uc2_i686-apple-darwin */,
- DD84C6EA0C856B36000EBEC4 /* uc2_graphics_i686-apple-darwin */,
- DDC4797515AC56CA0022401F /* UC2_x86_64-apple-darwin */,
- DDC479BB15AC56EB0022401F /* UC2_graphics_x86_64-apple-darwin */,
- );
- name = Products;
- sourceTree = "<group>";
- };
- DD00F66509EBA9320024857D /* jpeg */ = {
- isa = PBXGroup;
- children = (
- DD00F66809EBA9710024857D /* cderror.h */,
- DD00F66909EBA9710024857D /* cdjpeg.h */,
- DD00F66A09EBA9710024857D /* jcapimin.c */,
- DD00F66B09EBA9710024857D /* jcapistd.c */,
- DD00F66C09EBA9710024857D /* jccoefct.c */,
- DD00F66D09EBA9710024857D /* jccolor.c */,
- DD00F66E09EBA9710024857D /* jcdctmgr.c */,
- DD00F66F09EBA9710024857D /* jchuff.c */,
- DD00F67009EBA9710024857D /* jchuff.h */,
- DD00F67109EBA9710024857D /* jcinit.c */,
- DD00F67209EBA9710024857D /* jcmainct.c */,
- DD00F67309EBA9710024857D /* jcmarker.c */,
- DD00F67409EBA9710024857D /* jcmaster.c */,
- DD00F67509EBA9710024857D /* jcomapi.c */,
- DD00F67609EBA9710024857D /* jconfig.h */,
- DD00F67709EBA9710024857D /* jcparam.c */,
- DD00F67809EBA9710024857D /* jcphuff.c */,
- DD00F67909EBA9710024857D /* jcprepct.c */,
- DD00F67A09EBA9710024857D /* jcsample.c */,
- DD00F67B09EBA9710024857D /* jctrans.c */,
- DD00F67C09EBA9710024857D /* jdapimin.c */,
- DD00F67D09EBA9710024857D /* jdapistd.c */,
- DD00F67E09EBA9710024857D /* jdatadst.c */,
- DD00F67F09EBA9710024857D /* jdatasrc.c */,
- DD00F68009EBA9710024857D /* jdcoefct.c */,
- DD00F68109EBA9710024857D /* jdcolor.c */,
- DD00F68209EBA9710024857D /* jdct.h */,
- DD00F68309EBA9710024857D /* jddctmgr.c */,
- DD00F68409EBA9710024857D /* jdhuff.c */,
- DD00F68509EBA9710024857D /* jdhuff.h */,
- DD00F68609EBA9710024857D /* jdinput.c */,
- DD00F68709EBA9710024857D /* jdmainct.c */,
- DD00F68809EBA9710024857D /* jdmarker.c */,
- DD00F68909EBA9710024857D /* jdmaster.c */,
- DD00F68A09EBA9710024857D /* jdmerge.c */,
- DD00F68B09EBA9710024857D /* jdphuff.c */,
- DD00F68C09EBA9710024857D /* jdpostct.c */,
- DD00F68D09EBA9710024857D /* jdsample.c */,
- DD00F68E09EBA9710024857D /* jdtrans.c */,
- DD00F68F09EBA9710024857D /* jerror.c */,
- DD00F69009EBA9710024857D /* jerror.h */,
- DD00F69109EBA9710024857D /* jfdctflt.c */,
- DD00F69209EBA9710024857D /* jfdctfst.c */,
- DD00F69309EBA9710024857D /* jfdctint.c */,
- DD00F69409EBA9710024857D /* jidctflt.c */,
- DD00F69509EBA9710024857D /* jidctfst.c */,
- DD00F69609EBA9710024857D /* jidctint.c */,
- DD00F69709EBA9710024857D /* jidctred.c */,
- DD00F69809EBA9710024857D /* jinclude.h */,
- DD00F69909EBA9710024857D /* jmemmgr.c */,
- DD00F69A09EBA9710024857D /* jmemnobs.c */,
- DD00F69B09EBA9710024857D /* jmemsys.h */,
- DD00F69C09EBA9710024857D /* jmorecfg.h */,
- DD00F69D09EBA9710024857D /* jpegint.h */,
- DD00F69E09EBA9710024857D /* jpeglib.h */,
- DD00F69F09EBA9710024857D /* jquant1.c */,
- DD00F6A009EBA9710024857D /* jquant2.c */,
- DD00F6A109EBA9710024857D /* jutils.c */,
- DD00F6A209EBA9710024857D /* jversion.h */,
- DD00F6A309EBA9710024857D /* rdbmp.c */,
- DD00F6A409EBA9710024857D /* rdcolmap.c */,
- DD00F6A509EBA9710024857D /* rdgif.c */,
- DD00F6A609EBA9710024857D /* rdppm.c */,
- DD00F6A709EBA9710024857D /* rdrle.c */,
- DD00F6A809EBA9710024857D /* rdswitch.c */,
- DD00F6A909EBA9710024857D /* rdtarga.c */,
- );
- name = jpeg;
- sourceTree = "<group>";
- };
- DD00F81309EBAD960024857D /* Documentation */ = {
- isa = PBXGroup;
- children = (
- DD1194AE0F42CAF400C2BC25 /* checkin_notes_samples */,
- );
- name = Documentation;
- sourceTree = "<group>";
- };
- DD760E5E094E5663002CACC4 /* External Frameworks and Libraries */ = {
- isa = PBXGroup;
- children = (
- DD760E65094E56DB002CACC4 /* AppKit.framework */,
- DD760E66094E56DB002CACC4 /* GLUT.framework */,
- DD760E67094E56DB002CACC4 /* OpenGL.framework */,
- );
- name = "External Frameworks and Libraries";
- sourceTree = "<group>";
- };
- DDF8050715CB9C88005473CC /* api */ = {
- isa = PBXGroup;
- children = (
- DDF8050415CB9C75005473CC /* ttfont.h */,
- DDF8050315CB9C75005473CC /* ttfont.cpp */,
- );
- name = api;
- sourceTree = "<group>";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 8DD76FA90486AB0100D96B5E /* UC2-i386 */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = DD6341000973C81800B1057F /* Build configuration list for PBXNativeTarget "UC2-i386" */;
- buildPhases = (
- 8DD76FAB0486AB0100D96B5E /* Sources */,
- 8DD76FAD0486AB0100D96B5E /* Frameworks */,
- DD7A737915AD66AB004F2841 /* ShellScript */,
- );
- buildRules = (
- DD760E3E094E540D002CACC4 /* PBXBuildRule */,
- DD760E3D094E540D002CACC4 /* PBXBuildRule */,
- DD760E3C094E540C002CACC4 /* PBXBuildRule */,
- );
- dependencies = (
- );
- name = "UC2-i386";
- productInstallPath = "$(HOME)/bin";
- productName = UpperCase;
- productReference = 8DD76FB20486AB0100D96B5E /* uc2_i686-apple-darwin */;
- productType = "com.apple.product-type.tool";
- };
- DD84C6A70C856B36000EBEC4 /* UC2Gfx-i386 */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = DD84C6E60C856B36000EBEC4 /* Build configuration list for PBXNativeTarget "UC2Gfx-i386" */;
- buildPhases = (
- DD84C6A80C856B36000EBEC4 /* Sources */,
- DD84C6DE0C856B36000EBEC4 /* Frameworks */,
- DD7A737A15AD66CA004F2841 /* ShellScript */,
- );
- buildRules = (
- DD84C6E30C856B36000EBEC4 /* PBXBuildRule */,
- DD84C6E40C856B36000EBEC4 /* PBXBuildRule */,
- DD84C6E50C856B36000EBEC4 /* PBXBuildRule */,
- );
- dependencies = (
- );
- name = "UC2Gfx-i386";
- productInstallPath = "$(HOME)/bin";
- productName = UpperCase;
- productReference = DD84C6EA0C856B36000EBEC4 /* uc2_graphics_i686-apple-darwin */;
- productType = "com.apple.product-type.tool";
- };
- DDC4796515AC56CA0022401F /* UC2-x86_64 */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = DDC4797115AC56CA0022401F /* Build configuration list for PBXNativeTarget "UC2-x86_64" */;
- buildPhases = (
- DDC4796615AC56CA0022401F /* Sources */,
- DDC4796815AC56CA0022401F /* Frameworks */,
- DD7A737B15AD66D8004F2841 /* ShellScript */,
- );
- buildRules = (
- DDC4796E15AC56CA0022401F /* PBXBuildRule */,
- DDC4796F15AC56CA0022401F /* PBXBuildRule */,
- DDC4797015AC56CA0022401F /* PBXBuildRule */,
- );
- dependencies = (
- );
- name = "UC2-x86_64";
- productInstallPath = "$(HOME)/bin";
- productName = UpperCase;
- productReference = DDC4797515AC56CA0022401F /* UC2_x86_64-apple-darwin */;
- productType = "com.apple.product-type.tool";
- };
- DDC4797715AC56EB0022401F /* UC2Gfx-x86_64 */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = DDC479B715AC56EB0022401F /* Build configuration list for PBXNativeTarget "UC2Gfx-x86_64" */;
- buildPhases = (
- DDC4797815AC56EB0022401F /* Sources */,
- DDC479AF15AC56EB0022401F /* Frameworks */,
- DD7A737C15AD66E2004F2841 /* ShellScript */,
- );
- buildRules = (
- DDC479B415AC56EB0022401F /* PBXBuildRule */,
- DDC479B515AC56EB0022401F /* PBXBuildRule */,
- DDC479B615AC56EB0022401F /* PBXBuildRule */,
- );
- dependencies = (
- );
- name = "UC2Gfx-x86_64";
- productInstallPath = "$(HOME)/bin";
- productName = UpperCase;
- productReference = DDC479BB15AC56EB0022401F /* UC2_graphics_x86_64-apple-darwin */;
- productType = "com.apple.product-type.tool";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 08FB7793FE84155DC02AAC07 /* Project object */ = {
- isa = PBXProject;
- buildConfigurationList = DD6341040973C81800B1057F /* Build configuration list for PBXProject "UpperCase2" */;
- compatibilityVersion = "Xcode 2.4";
- developmentRegion = English;
- hasScannedForEncodings = 1;
- knownRegions = (
- English,
- Japanese,
- French,
- German,
- );
- mainGroup = 08FB7794FE84155DC02AAC07 /* UpperCase */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- DD84C71E0C856D9E000EBEC4 /* Build_All */,
- 8DD76FA90486AB0100D96B5E /* UC2-i386 */,
- DD84C6A70C856B36000EBEC4 /* UC2Gfx-i386 */,
- DDC4796515AC56CA0022401F /* UC2-x86_64 */,
- DDC4797715AC56EB0022401F /* UC2Gfx-x86_64 */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXShellScriptBuildPhase section */
- DD7A737915AD66AB004F2841 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "mkdir -p \"${SRCROOT}/build/${CONFIGURATION}\"\nif [ \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}\" -nt \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}\" ]; then\n cp -fp \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}\" \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}\"\n if [ \"$CONFIGURATION\" = \"Release\" ]; then\n rm -fR \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}.dSYM\"\n cp -fpR \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.dSYM\" \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}.dSYM\"\n fi\nfi\n";
- };
- DD7A737A15AD66CA004F2841 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "mkdir -p \"${SRCROOT}/build/${CONFIGURATION}\"\nif [ \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}\" -nt \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}\" ]; then\n cp -fp \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}\" \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}\"\n if [ \"$CONFIGURATION\" = \"Release\" ]; then\n rm -fR \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}.dSYM\"\n cp -fpR \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.dSYM\" \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}.dSYM\"\n fi\nfi\n";
- };
- DD7A737B15AD66D8004F2841 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "mkdir -p \"${SRCROOT}/build/${CONFIGURATION}\"\nif [ \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}\" -nt \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}\" ]; then\n cp -fp \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}\" \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}\"\n if [ \"$CONFIGURATION\" = \"Release\" ]; then\n rm -fR \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}.dSYM\"\n cp -fpR \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.dSYM\" \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}.dSYM\"\n fi\nfi\n";
- };
- DD7A737C15AD66E2004F2841 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "mkdir -p \"${SRCROOT}/build/${CONFIGURATION}\"\nif [ \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}\" -nt \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}\" ]; then\n cp -fp \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}\" \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}\"\n if [ \"$CONFIGURATION\" = \"Release\" ]; then\n rm -fR \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}.dSYM\"\n cp -fpR \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.dSYM\" \"${SRCROOT}/build/${CONFIGURATION}/${PRODUCT_NAME}.dSYM\"\n fi\nfi\n";
- };
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 8DD76FAB0486AB0100D96B5E /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DD1194B20F42CB5400C2BC25 /* uc2.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DD84C6A80C856B36000EBEC4 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DD84C6A90C856B36000EBEC4 /* jcapimin.c in Sources */,
- DD84C6AA0C856B36000EBEC4 /* jcapistd.c in Sources */,
- DD84C6AB0C856B36000EBEC4 /* jccoefct.c in Sources */,
- DD84C6AC0C856B36000EBEC4 /* jccolor.c in Sources */,
- DD84C6AD0C856B36000EBEC4 /* jcdctmgr.c in Sources */,
- DD84C6AE0C856B36000EBEC4 /* jchuff.c in Sources */,
- DD84C6AF0C856B36000EBEC4 /* jcinit.c in Sources */,
- DD84C6B00C856B36000EBEC4 /* jcmainct.c in Sources */,
- DD84C6B10C856B36000EBEC4 /* jcmarker.c in Sources */,
- DD84C6B20C856B36000EBEC4 /* jcmaster.c in Sources */,
- DD84C6B30C856B36000EBEC4 /* jcomapi.c in Sources */,
- DD84C6B40C856B36000EBEC4 /* jcparam.c in Sources */,
- DD84C6B50C856B36000EBEC4 /* jcphuff.c in Sources */,
- DD84C6B60C856B36000EBEC4 /* jcprepct.c in Sources */,
- DD84C6B70C856B36000EBEC4 /* jcsample.c in Sources */,
- DD84C6B80C856B36000EBEC4 /* jctrans.c in Sources */,
- DD84C6B90C856B36000EBEC4 /* jdapimin.c in Sources */,
- DD84C6BA0C856B36000EBEC4 /* jdapistd.c in Sources */,
- DD84C6BB0C856B36000EBEC4 /* jdatadst.c in Sources */,
- DD84C6BC0C856B36000EBEC4 /* jdatasrc.c in Sources */,
- DD84C6BD0C856B36000EBEC4 /* jdcoefct.c in Sources */,
- DD84C6BE0C856B36000EBEC4 /* jdcolor.c in Sources */,
- DD84C6BF0C856B36000EBEC4 /* jddctmgr.c in Sources */,
- DD84C6C00C856B36000EBEC4 /* jdhuff.c in Sources */,
- DD84C6C10C856B36000EBEC4 /* jdinput.c in Sources */,
- DD84C6C20C856B36000EBEC4 /* jdmainct.c in Sources */,
- DD84C6C30C856B36000EBEC4 /* jdmarker.c in Sources */,
- DD84C6C40C856B36000EBEC4 /* jdmaster.c in Sources */,
- DD84C6C50C856B36000EBEC4 /* jdmerge.c in Sources */,
- DD84C6C60C856B36000EBEC4 /* jdphuff.c in Sources */,
- DD84C6C70C856B36000EBEC4 /* jdpostct.c in Sources */,
- DD84C6C80C856B36000EBEC4 /* jdsample.c in Sources */,
- DD84C6C90C856B36000EBEC4 /* jdtrans.c in Sources */,
- DD84C6CA0C856B36000EBEC4 /* jerror.c in Sources */,
- DD84C6CB0C856B36000EBEC4 /* jfdctflt.c in Sources */,
- DD84C6CC0C856B36000EBEC4 /* jfdctfst.c in Sources */,
- DD84C6CD0C856B36000EBEC4 /* jfdctint.c in Sources */,
- DD84C6CE0C856B36000EBEC4 /* jidctflt.c in Sources */,
- DD84C6CF0C856B36000EBEC4 /* jidctfst.c in Sources */,
- DD84C6D00C856B36000EBEC4 /* jidctint.c in Sources */,
- DD84C6D10C856B36000EBEC4 /* jidctred.c in Sources */,
- DD84C6D20C856B36000EBEC4 /* jmemmgr.c in Sources */,
- DD84C6D30C856B36000EBEC4 /* jmemnobs.c in Sources */,
- DD84C6D40C856B36000EBEC4 /* jquant1.c in Sources */,
- DD84C6D50C856B36000EBEC4 /* jquant2.c in Sources */,
- DD84C6D60C856B36000EBEC4 /* jutils.c in Sources */,
- DD84C6D70C856B36000EBEC4 /* rdbmp.c in Sources */,
- DD84C6D80C856B36000EBEC4 /* rdcolmap.c in Sources */,
- DD84C6D90C856B36000EBEC4 /* rdgif.c in Sources */,
- DD84C6DA0C856B36000EBEC4 /* rdppm.c in Sources */,
- DD84C6DB0C856B36000EBEC4 /* rdrle.c in Sources */,
- DD84C6DC0C856B36000EBEC4 /* rdswitch.c in Sources */,
- DD84C6DD0C856B36000EBEC4 /* rdtarga.c in Sources */,
- DD1194B00F42CB4900C2BC25 /* uc2_graphics.cpp in Sources */,
- DDF8050515CB9C75005473CC /* ttfont.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DDC4796615AC56CA0022401F /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DDC4796715AC56CA0022401F /* uc2.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DDC4797815AC56EB0022401F /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DDC4797915AC56EB0022401F /* jcapimin.c in Sources */,
- DDC4797A15AC56EB0022401F /* jcapistd.c in Sources */,
- DDC4797B15AC56EB0022401F /* jccoefct.c in Sources */,
- DDC4797C15AC56EB0022401F /* jccolor.c in Sources */,
- DDC4797D15AC56EB0022401F /* jcdctmgr.c in Sources */,
- DDC4797E15AC56EB0022401F /* jchuff.c in Sources */,
- DDC4797F15AC56EB0022401F /* jcinit.c in Sources */,
- DDC4798015AC56EB0022401F /* jcmainct.c in Sources */,
- DDC4798115AC56EB0022401F /* jcmarker.c in Sources */,
- DDC4798215AC56EB0022401F /* jcmaster.c in Sources */,
- DDC4798315AC56EB0022401F /* jcomapi.c in Sources */,
- DDC4798415AC56EB0022401F /* jcparam.c in Sources */,
- DDC4798515AC56EB0022401F /* jcphuff.c in Sources */,
- DDC4798615AC56EB0022401F /* jcprepct.c in Sources */,
- DDC4798715AC56EB0022401F /* jcsample.c in Sources */,
- DDC4798815AC56EB0022401F /* jctrans.c in Sources */,
- DDC4798915AC56EB0022401F /* jdapimin.c in Sources */,
- DDC4798A15AC56EB0022401F /* jdapistd.c in Sources */,
- DDC4798B15AC56EB0022401F /* jdatadst.c in Sources */,
- DDC4798C15AC56EB0022401F /* jdatasrc.c in Sources */,
- DDC4798D15AC56EB0022401F /* jdcoefct.c in Sources */,
- DDC4798E15AC56EB0022401F /* jdcolor.c in Sources */,
- DDC4798F15AC56EB0022401F /* jddctmgr.c in Sources */,
- DDC4799015AC56EB0022401F /* jdhuff.c in Sources */,
- DDC4799115AC56EB0022401F /* jdinput.c in Sources */,
- DDC4799215AC56EB0022401F /* jdmainct.c in Sources */,
- DDC4799315AC56EB0022401F /* jdmarker.c in Sources */,
- DDC4799415AC56EB0022401F /* jdmaster.c in Sources */,
- DDC4799515AC56EB0022401F /* jdmerge.c in Sources */,
- DDC4799615AC56EB0022401F /* jdphuff.c in Sources */,
- DDC4799715AC56EB0022401F /* jdpostct.c in Sources */,
- DDC4799815AC56EB0022401F /* jdsample.c in Sources */,
- DDC4799915AC56EB0022401F /* jdtrans.c in Sources */,
- DDC4799A15AC56EB0022401F /* jerror.c in Sources */,
- DDC4799B15AC56EB0022401F /* jfdctflt.c in Sources */,
- DDC4799C15AC56EB0022401F /* jfdctfst.c in Sources */,
- DDC4799D15AC56EB0022401F /* jfdctint.c in Sources */,
- DDC4799E15AC56EB0022401F /* jidctflt.c in Sources */,
- DDC4799F15AC56EB0022401F /* jidctfst.c in Sources */,
- DDC479A015AC56EB0022401F /* jidctint.c in Sources */,
- DDC479A115AC56EB0022401F /* jidctred.c in Sources */,
- DDC479A215AC56EB0022401F /* jmemmgr.c in Sources */,
- DDC479A315AC56EB0022401F /* jmemnobs.c in Sources */,
- DDC479A415AC56EB0022401F /* jquant1.c in Sources */,
- DDC479A515AC56EB0022401F /* jquant2.c in Sources */,
- DDC479A615AC56EB0022401F /* jutils.c in Sources */,
- DDC479A715AC56EB0022401F /* rdbmp.c in Sources */,
- DDC479A815AC56EB0022401F /* rdcolmap.c in Sources */,
- DDC479A915AC56EB0022401F /* rdgif.c in Sources */,
- DDC479AA15AC56EB0022401F /* rdppm.c in Sources */,
- DDC479AB15AC56EB0022401F /* rdrle.c in Sources */,
- DDC479AC15AC56EB0022401F /* rdswitch.c in Sources */,
- DDC479AD15AC56EB0022401F /* rdtarga.c in Sources */,
- DDC479AE15AC56EB0022401F /* uc2_graphics.cpp in Sources */,
- DDF8050615CB9C75005473CC /* ttfont.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
- DD84C7200C856DA6000EBEC4 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 8DD76FA90486AB0100D96B5E /* UC2-i386 */;
- targetProxy = DD84C71F0C856DA6000EBEC4 /* PBXContainerItemProxy */;
- };
- DD84C7220C856DA6000EBEC4 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = DD84C6A70C856B36000EBEC4 /* UC2Gfx-i386 */;
- targetProxy = DD84C7210C856DA6000EBEC4 /* PBXContainerItemProxy */;
- };
- DDC479BE15AC57BC0022401F /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = DDC4796515AC56CA0022401F /* UC2-x86_64 */;
- targetProxy = DDC479BD15AC57BC0022401F /* PBXContainerItemProxy */;
- };
- DDC479C015AC57C40022401F /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = DDC4797715AC56EB0022401F /* UC2Gfx-x86_64 */;
- targetProxy = DDC479BF15AC57C40022401F /* PBXContainerItemProxy */;
- };
-/* End PBXTargetDependency section */
-
-/* Begin XCBuildConfiguration section */
- DD6341010973C81800B1057F /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
- GCC_MODEL_TUNING = G5;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_SYMBOLS_PRIVATE_EXTERN = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = "../../**";
- LIBRARY_SEARCH_PATHS = ../../mac_build/build/Development/;
- PREBINDING = NO;
- PRODUCT_NAME = "uc2_i686-apple-darwin";
- ZERO_LINK = NO;
- };
- name = Debug;
- };
- DD6341050973C81800B1057F /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
- ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- GCC_VERSION = com.apple.compilers.llvmgcc42;
- MACOSX_DEPLOYMENT_TARGET = 10.4;
- OTHER_CFLAGS = (
- "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040",
- "-DMAC_OS_X_VERSION_MIN_REQUIRED=1040",
- );
- OTHER_LDFLAGS = (
- "-lboinc_api",
- "-lboinc",
- );
- SDKROOT = macosx;
- STRIP_INSTALLED_PRODUCT = NO;
- };
- name = Debug;
- };
- DD63410B0973C84A00B1057F /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
- GCC_MODEL_TUNING = G5;
- GCC_SYMBOLS_PRIVATE_EXTERN = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = "../../**";
- LIBRARY_SEARCH_PATHS = ../../mac_build/build/Deployment/;
- PREBINDING = NO;
- PRODUCT_NAME = "uc2_i686-apple-darwin";
- ZERO_LINK = NO;
- };
- name = Release;
- };
- DD63410C0973C84A00B1057F /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
- ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- GCC_VERSION = com.apple.compilers.llvmgcc42;
- MACOSX_DEPLOYMENT_TARGET = 10.4;
- OTHER_CFLAGS = (
- "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040",
- "-DMAC_OS_X_VERSION_MIN_REQUIRED=1040",
- );
- OTHER_LDFLAGS = (
- "-lboinc_api",
- "-lboinc",
- );
- SDKROOT = macosx;
- STRIP_INSTALLED_PRODUCT = YES;
- };
- name = Release;
- };
- DD84C6E70C856B36000EBEC4 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
- GCC_MODEL_TUNING = G5;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_SYMBOLS_PRIVATE_EXTERN = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = (
- "../../../freetype-2.4.10/include",
- "../../../ftgl-2.1.3~rc5/src",
- "../../**",
- );
- INSTALL_PATH = "$(HOME)/bin";
- LIBRARY_SEARCH_PATHS = ../../mac_build/build/Development/;
- OTHER_CFLAGS = (
- "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040",
- "-DMAC_OS_X_VERSION_MIN_REQUIRED=1040",
- "-DHAVE_STDLIB_H",
- );
- OTHER_LDFLAGS = (
- "-lboinc_api",
- "-lboinc_graphics2",
- "-lboinc",
- "../../../freetype-2.4.10/objs/.libs/libfreetype.a",
- "../../../ftgl-2.1.3~rc5/src/.libs/libftgl.a",
- "-lz",
- "-lbz2",
- );
- PREBINDING = NO;
- PRODUCT_NAME = "uc2_graphics_i686-apple-darwin";
- WARNING_LDFLAGS = (
- "-lboinc_api",
- "-lboinc_graphics2",
- "-lboinc",
- "../../../freetype-2.4.10/objs/.libs/libfreetype.a",
- "../../../ftgl-2.1.3~rc5/src/.libs/libftgl.a",
- "-lz",
- "-lbz2",
- );
- ZERO_LINK = NO;
- };
- name = Debug;
- };
- DD84C6E90C856B36000EBEC4 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
- GCC_MODEL_TUNING = G5;
- GCC_SYMBOLS_PRIVATE_EXTERN = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = (
- "../../../freetype-2.4.10/include",
- "../../../ftgl-2.1.3~rc5/src",
- "../../**",
- );
- INSTALL_PATH = "$(HOME)/bin";
- LIBRARY_SEARCH_PATHS = ../../mac_build/build/Deployment/;
- OTHER_CFLAGS = (
- "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040",
- "-DMAC_OS_X_VERSION_MIN_REQUIRED=1040",
- "-DHAVE_STDLIB_H",
- );
- OTHER_LDFLAGS = (
- "-lboinc_api",
- "-lboinc_graphics2",
- "-lboinc",
- "../../../freetype-2.4.10/objs/.libs/libfreetype.a",
- "../../../ftgl-2.1.3~rc5/src/.libs/libftgl.a",
- "-lz",
- "-lbz2",
- );
- PREBINDING = NO;
- PRODUCT_NAME = "uc2_graphics_i686-apple-darwin";
- WARNING_LDFLAGS = (
- "-lboinc_api",
- "-lboinc_graphics2",
- "-lboinc",
- "../../../freetype-2.4.10/objs/.libs/libfreetype.a",
- "../../../ftgl-2.1.3~rc5/src/.libs/libftgl.a",
- "-lz",
- "-lbz2",
- );
- ZERO_LINK = NO;
- };
- name = Release;
- };
- DD84C7290C856DBB000EBEC4 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- PRODUCT_NAME = Build_All;
- };
- name = Debug;
- };
- DD84C72B0C856DBB000EBEC4 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- PRODUCT_NAME = Build_All;
- };
- name = Release;
- };
- DDC4797215AC56CA0022401F /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)";
- ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
- GCC_MODEL_TUNING = G5;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_SYMBOLS_PRIVATE_EXTERN = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = "../../**";
- LIBRARY_SEARCH_PATHS = ../../mac_build/build/Development/;
- PREBINDING = NO;
- PRODUCT_NAME = "UC2_x86_64-apple-darwin";
- ZERO_LINK = NO;
- };
- name = Debug;
- };
- DDC4797315AC56CA0022401F /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)";
- ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
- GCC_MODEL_TUNING = G5;
- GCC_SYMBOLS_PRIVATE_EXTERN = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = "../../**";
- LIBRARY_SEARCH_PATHS = ../../mac_build/build/Deployment/;
- PREBINDING = NO;
- PRODUCT_NAME = "UC2_x86_64-apple-darwin";
- ZERO_LINK = NO;
- };
- name = Release;
- };
- DDC479B815AC56EB0022401F /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)";
- ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
- GCC_MODEL_TUNING = G5;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_SYMBOLS_PRIVATE_EXTERN = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = (
- "../../../freetype-2.4.10/include",
- "../../../ftgl-2.1.3~rc5/src",
- "../../**",
- );
- INSTALL_PATH = "$(HOME)/bin";
- LIBRARY_SEARCH_PATHS = ../../mac_build/build/Development/;
- OTHER_CFLAGS = (
- "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040",
- "-DMAC_OS_X_VERSION_MIN_REQUIRED=1040",
- "-DHAVE_STDLIB_H",
- );
- OTHER_LDFLAGS = (
- "-lboinc_api",
- "-lboinc_graphics2",
- "-lboinc",
- "../../../freetype-2.4.10/objs/.libs/libfreetype.a",
- "../../../ftgl-2.1.3~rc5/src/.libs/libftgl.a",
- "-lz",
- "-lbz2",
- );
- PREBINDING = NO;
- PRODUCT_NAME = "UC2_graphics_x86_64-apple-darwin";
- ZERO_LINK = NO;
- };
- name = Debug;
- };
- DDC479B915AC56EB0022401F /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)";
- ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
- GCC_MODEL_TUNING = G5;
- GCC_SYMBOLS_PRIVATE_EXTERN = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = (
- "../../../freetype-2.4.10/include",
- "../../../ftgl-2.1.3~rc5/src",
- "../../**",
- );
- INSTALL_PATH = "$(HOME)/bin";
- LIBRARY_SEARCH_PATHS = ../../mac_build/build/Deployment/;
- OTHER_CFLAGS = (
- "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040",
- "-DMAC_OS_X_VERSION_MIN_REQUIRED=1040",
- "-DHAVE_STDLIB_H",
- );
- OTHER_LDFLAGS = (
- "-lboinc_api",
- "-lboinc_graphics2",
- "-lboinc",
- "../../../freetype-2.4.10/objs/.libs/libfreetype.a",
- "../../../ftgl-2.1.3~rc5/src/.libs/libftgl.a",
- "-lz",
- "-lbz2",
- );
- PREBINDING = NO;
- PRODUCT_NAME = "UC2_graphics_x86_64-apple-darwin";
- ZERO_LINK = NO;
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- DD6341000973C81800B1057F /* Build configuration list for PBXNativeTarget "UC2-i386" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DD6341010973C81800B1057F /* Debug */,
- DD63410B0973C84A00B1057F /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- DD6341040973C81800B1057F /* Build configuration list for PBXProject "UpperCase2" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DD6341050973C81800B1057F /* Debug */,
- DD63410C0973C84A00B1057F /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- DD84C6E60C856B36000EBEC4 /* Build configuration list for PBXNativeTarget "UC2Gfx-i386" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DD84C6E70C856B36000EBEC4 /* Debug */,
- DD84C6E90C856B36000EBEC4 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- DD84C7280C856DBB000EBEC4 /* Build configuration list for PBXAggregateTarget "Build_All" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DD84C7290C856DBB000EBEC4 /* Debug */,
- DD84C72B0C856DBB000EBEC4 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- DDC4797115AC56CA0022401F /* Build configuration list for PBXNativeTarget "UC2-x86_64" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DDC4797215AC56CA0022401F /* Debug */,
- DDC4797315AC56CA0022401F /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
- DDC479B715AC56EB0022401F /* Build configuration list for PBXNativeTarget "UC2Gfx-x86_64" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- DDC479B815AC56EB0022401F /* Debug */,
- DDC479B915AC56EB0022401F /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Debug;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/stripchart/README b/stripchart/README
new file mode 100644
index 0000000..75f5eb9
--- /dev/null
+++ b/stripchart/README
@@ -0,0 +1,333 @@
+Stripchart version 2.0
+----------------------
+Author: Matt Lebofsky
+ BOINC/SETI at home - University of California, Berkeley
+ mattl at ssl.berkeley.edu
+
+Date of recent version: November 4, 2002
+
+Requirements:
+ * a gnuplot with the ability to generate gifs
+ * perl
+ * apache or other cgi-enabled web browser
+
+Send all thoughts and queries to: mattl at ssl.berkeley.edu
+
+This software is free to edit, distribute and use by anybody, as long as
+I get credit for it in some form or another. Thanks.
+----------------------
+
+Contents:
+
+I. Some questions and answers
+II. So how does it work?
+III. Known bugs, things to do, etc.
+
+----------------------
+I. Some questions and answers
+
+Q: What is stripchart?
+
+A: Well, it's actually two relatively small perl programs:
+
+ 1. stripchart
+
+ stripchart reads in time-based user data and, depending on a flurry of
+ command line options, generates a web-friendly .gif plotting the data.
+ The user can supply the time range, the y axis range, even the color
+ scheme, and more.
+
+ 2. stripchart.cgi
+
+ stripchart.cgi is a web-based GUI interface that allows users to easily
+ select multiple data sources and various parameters to plot, allowing
+ fast comparisons without having to deal with a command line interface.
+
+Q: Why do you bother writing this program?
+
+A: Working as a systems administrator (amongst other things) for SETI at home,
+ we kept finding ourselves in dire problem-solving situations, i.e. Why
+ did the database stop working? Why is load on our web server so high?
+
+ So we started collecting data in flat files, keeping track of server
+ loads, database checkpoint times, even CPU temperatures. When these files
+ grew too large and unwieldy, I found myself writing (and rewriting) simple
+ scripts to generate plots on this data. Sick of constant revision whenever
+ a new problem arose, I wrote stripchart version 1.0.
+
+ Its usefulness became immediately apparent when I added on stripchart.cgi.
+ I couldn't bear to teach everybody the many command line options to
+ stripchart, so I wrote this CGI to do all the dirty work. Suddenly we were
+ able to line up several plots, look for causes and effects, or just enjoy
+ watching the counts in our database tables grow to impossibly high numbers.
+
+ The SETI at home network has proven to be a delicate system, and keeping track
+ of all the data server, user, and web statistics has proven to be quite a
+ life saver. So when BOINC came around we felt that any project aiming to
+ embark on a similar project may need this tool. So I rewrote stripchart to
+ be a bit more friendly and general.
+
+Q: Why don't you make .pngs or .jpgs instead of .gifs? The latest gnuplot
+ doesn't support .gifs.
+
+A: Basically gnuplot support for other graphic file formats isn't as good. For
+ example, you cannot control exact window size, font size, and colors unless
+ you make .gifs. I'm not exactly sure why this is the case, but there you have it.
+ Anywho, you can find older gnuplot distributions out there - you'll need to
+ get the gd libs first, by the way.
+
+----------------------
+II. So how does it work?
+
+You can use stripchart as a stand alone command-line program to produce plots
+whenever you like, but we highly recommend using it in conjunction with the
+stripchart.cgi for ease of use. But here's how to do it both ways.
+
+stripchart (stand alone)
+
+Before anything, look at the section GLOBAL/DEFAULT VARS in the program
+stripchart and see if you need to edit anything (usually pathnames to
+executables and such).
+
+Let's just start with the usage (obtained by typing "stripchart -h"):
+
+stripchart: creates stripchart .gif graphic based on data in flat files
+options:
+ -i: input FILE - name of input data file (mandatory)
+ -o: output FILE - name of output .gif file (default: STDOUT)
+ -O: output FILE - name of output .gif file and dump to STDOUT as well
+ -f: from TIME - stripchart with data starting at TIME
+ (default: 24 hours ago)
+ -t: to TIME - stripchart with data ending at TIME (default: now)
+ -r: range RANGE - stripchart data centered around "from" time the size
+ of RANGE (overrides -t)
+ -l: last LINES - stripchart last number of LINES in data file
+ (overrides -f and -t and -r)
+ -T: title TITLE - title to put on graphic (default: FILE RANGE)
+ -x: column X - time or "x" column (default: 2)
+ -y: column Y - value or "y" column (default: 3)
+ -Y: column Y' - overplot second "y" column (default: none)
+ -b: baseline VALUE - overplot baseline of arbitrary value VALUE
+ -B: baseline-avg - overrides -b, it plots baseline of computed average
+ -d: dump low VALUE - ignore data less than VALUE
+ -D: dump high VALUE - ignore data higher than VALUE
+ -v: verbose - puts verbose runtime output to STDERR
+ -L: log - makes y axis log scale
+ -c: colors "COLORS" - set gnuplot colors for graph/axis/fonts/data (default:
+ "xffffff x000000 xc0c0c0 x00a000 x0000a0 x2020c0"
+ in order: bground, axis/fonts, grids, pointcolor1,2,3)
+ -C: cgi - output CGI header to STDOUT if being called as CGI
+ -s: stats - turn extra plot stats on (current, avg, min, max)
+ -j: julian times - time columns is in local julian date (legacy stuff)
+
+notes:
+ * TIME either unix date, julian date, or civil date in the form:
+ YYYY:MM:DD:HH:MM (year, month, day, hour, minute)
+ If you enter something with colons, it assumes it is civil date
+ If you have a decimal point, it assumes it is julian date
+ If it is an integer, it assumes it is unix date (epoch seconds)
+ If it is a negative number, it is in decimal days from current time
+ (i.e. -2.5 = two and a half days ago)
+ * All times on command line are assumed to be "local" times
+ * All times in the data file must be in unix date (epoch seconds)
+ * RANGE is given in decimal days (i.e. 1.25 = 1 day, 6 hours)
+ * if LINES == 0, (i.e. -l 0) then the whole data file is read in
+ * columns (given with -x, -y, -Y flags) start at 1
+ * titles given with -T can contain the following key words which will
+ be converted:
+ FILE - basename of input file
+ RANGE - pretty civil date range (in local time zone)
+ the default title is: FILE RANGE
+
+...okay that's a lot to ingest, but it's really simple. Let's take a look at an
+example (you'll find in the samples directory two files get_load and crontab).
+
+You have a machine that you want to monitor it's load. Here's a script that
+will output a single line containing two fields for time and the third with the
+actual data. For example:
+
+2002:11:05:12:51 1036529480 0.25
+
+The first field is time in an arbitrary human readable format
+(year:month:day:hour:minute), the second in epoch seconds (standard
+unix time format - the number of seconds since 00:00 1/1/1970 GMT),
+and the third is the load at this time.
+
+And we'll start collecting data every five minutes on this particular machine
+by add such a line to the crontab:
+
+0,5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/local/stripchart/samples/get_load >> /disks/matt/data/machine_load
+
+So the file "machine_load" will quickly fill with lines such as the above.
+Now you may ask yourself - why two columns representing time in two different
+formats? Well sometime you just want to look at the data file itself, in which
+case the human-readable first column is quite handy to have around, but when
+making linear time plots, having time in epoch seconds is much faster to
+manipulate. So generally, we like to have at least the two time fields first,
+and the actual data in the third column. That's what stripchart expects by
+default.
+
+Note: stripchart will understand time in both epoch seconds and julian date.
+If the second time field is in julian date, you should supply the command line
+flag "-j" to warn stripchart so it knows how to handle it.
+
+Okay. So you have this data file now. A very common thing to plot would be the
+data over the past 24 hours. Turns out that's the default! If you type on the
+command line:
+
+stripchart -i machine_load -o machine_load.gif
+
+you will quickly get a new file "machine_load.gif" with all the goods.
+
+Note: you always have to supply an input file via -i. If you don't supply
+an output file via "-o" it .gif gets dumped to stdout. If you supply an
+output file via "-O" the output is stored in both the file and to stdout.
+
+Now let's play with the time ranges. You can supply times in a variety of
+formats on the command line:
+
+ "civil date" i.e. 2002:11:05:12:51 (YYYY:MM:DD:hh:mm)
+ "epoch seconds" i.e. 1036529480
+ "julian date" i.e. 2452583.52345
+
+You can supply a date range using the -f and -t flags (from and to):
+
+stripchart -i machine_load -f 2002:11:01:00:00 -t 2002:11:04:00:00
+
+Usually the "to" time is right now, so you can quickly tell stripchart
+to plot starting at some arbitrary time "ago." This is done also via the
+"-f" flag - if it's negative it will assume you mean that many decimal
+days from now as a starting point. So "-f -3.5" will plot from 3 and a
+half days ago until now.
+
+You can also supply a "range" centered around the from time. For example,
+to plot the 24 hours centered around 2002:11:01:13:40:
+
+stripchart -i machine_load -f 2002:11:01:13:40 -r 1
+
+On some rare occasions you might want to plot the last number of lines
+in a file, regardless of what time they were. If you supply the number
+of lines via the "-l" flag, it overrides any time ranges you may have
+supplied.
+
+Moving on to some other useful flags in no particular order:
+
+To change the default title (which is the basename of the file and
+the time range being plotted), you can do so via the "-T" command.
+Make sure to put the title in quotes. Within the title string the
+all-uppercase string "FILE" will be replaced with the file basename,
+and the string "RANGE" will be replaced by the time range. So in
+essence, the default title string is "FILE RANGE".
+
+If you have data files in different formats, you can specify the data
+columns using the "-x" and "-y" flags. By default -x is 2 and -y is 3.
+Sometimes we have datafiles with many columns so we actively have to tell
+stripchart which is the correct data column.
+
+However, you might want to overplot one column on top of another. If your
+data file has a second data column, you can specify what that is via the
+-Y flag, and this data will be overplotted onto the data from the first
+data column.
+
+Sometime you want to plot a horizontal rule or a "baseline". You can
+turn this feature on by specifying the value with the "-b" flag. If you
+use the "-B" flag (without any values) it automatically computes the
+average over the time range and plots that as the baseline. Simple!
+
+If you want to excise certain y values, you can do so with the dump
+flags, i.e. "-d" and "-D". In particular, any values lower than the one
+supplied with "-d" will be dumped, and any values higher supplied by
+"-D" will be dumped.
+
+To log the y axis, use the "-L" flag. Quite straightforward.
+
+A very useful flag is "-s" which outputs a line of stats underneath
+the plot title. It shows the current value, and the minimum, maximum
+and average values during the plot range.
+
+For verbose output to stderr, use the "-v" flag. It may not make much
+sense, but it's useful for debugging.
+
+Using the "-C" flag causes stripchart to spit out the "Content-type"
+lines necessary for incorporating stripchart plots into CGIs. This
+doesn't work so well now, but there it is.
+
+Okay. That's enough about the flags, and hopefully enough to get you
+playing around with stripchart and plotting some stuff. Now onto:
+
+stripchart.cgi
+
+First and foremost, you need to do the following before running the
+CGI version of stripchart:
+
+1. Put stripchart.cgi in a cgi-enabled web-accessible directory
+2. Make a "lib" directory somewhere that the web server can read/write to
+3. Edit stripchart.cgi GLOBAL/DEFAULT VARS to point to proper paths, including
+ the files "querylist" and "datafiles" in the aforementioned "lib" directory.
+4. Edit the "lib/datafiles" file to contain entries for all your data files.
+ You can find an example datafiles in the samples directory. Follow the
+ instructions in the comment lines, adding your entries below the header.
+
+That should be it, I think. Now go to the URL wherever your stripchart.cgi
+is sitting. If all is well..
+
+You will be immediately presented with a web form. Ignore the "select query"
+pulldown menu for now. Underneath that you will see a line:
+
+Number of stripcharts: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+
+By default stripchart.cgi presents you with the ability to plot 4 simultaneous
+stripcharts, but you can select any number 1-20 by clicking on those numbers.
+The less plots, the faster a web page gets generated.
+
+For each plot, you get a pull down menu which should contain all the entries
+you already put in "datafiles". Here you are selecting your data source.
+
+Then you can select the time of time range: last x hours, last x days, or
+an arbitrary date range. By default the last x hours radio button is selected -
+to pick another type of time range make sure you select the radio button
+before it. Then enter the range via the pull down menus.
+
+Then you get a simple list of checkbox/input options. You can check to log
+the y axis, baseline the average, baseline an arbitrary value (which you
+enter in the window, enter a y minimum, or enter a maximum.
+
+When everything is selected, click on the "click here" button to plot.
+Depending on the speed of your machine, you should soon be presented with
+all the plots your desired, and the form underneath the plots which can
+edit to your heart's content. If you want to reset the form values, click
+on the "reset form" link.
+
+Note the "save images in /tmp" checkbox. If that is checked and you plot
+the stripcharts, numbered .gif files will be placed in /tmp on the web
+server machine so you can copy them elsewhere (files will be named:
+stripchart_plot_1.gif, etc.).
+
+On the topmost "click here" button you will note an "enter name to save
+query" balloon. If you enter a name here (any old string) this exact query
+will be saved into the "querylist" file which will then later appear in the
+pulldown menu at the top. That way if you have a favorite set of diagnostic
+plots which you check every morning, you don't have to enter the entire form
+every time.
+
+If you want to delete a query, enter the name in that same field but click
+the "delete" checkbox next to it. Next time you "click here" the query will
+be deleted.
+
+----------------------
+III. Known bugs, things to do, etc.
+
+* stripchart -C flag is kind of pointless and doesn't work in practice.
+* plots on data collected over small time ranges (points every few seconds, for
+ example) hasn't been tested.
+* plots that don't work via stripchart.cgi either show ugly broken image icons
+ or nothing at all - either way it's ungraceful.
+* pulldown menus and various plots sometimes need to be refreshed via a hard
+ refresh (i.e. shift-refresh).
+* this readme kinda stinks.
+* and many many other issues I'm failing to detail now!
+
+If you have any problems using the product, feel free to e-mail me at:
+
+ mattl at ssl.berkeley.edu
+
diff --git a/stripchart/samples/crontab b/stripchart/samples/crontab
new file mode 100644
index 0000000..d93cafc
--- /dev/null
+++ b/stripchart/samples/crontab
@@ -0,0 +1 @@
+0,5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/local/stripchart/samples/get_load >> /disks/matt/data/machine_load
diff --git a/stripchart/samples/datafiles b/stripchart/samples/datafiles
new file mode 100644
index 0000000..f45dd34
--- /dev/null
+++ b/stripchart/samples/datafiles
@@ -0,0 +1,15 @@
+# This is the list of data sources for stripchart, in the colon-delimited format:
+# path to data file:title for the graph:column number in the data file:flags to stripchart
+#
+# examples:
+# /disks/matt/data_files/connections:connection drops:3
+# /disks/matt/data_files/connections:tcp rate:4:-b 100
+#
+# To put in a horizontal rule for ease of selection, use the line:
+# x:----------------------------------:x
+#
+get_load_out:machine load:3
+count_results_out:Number of results:3
+assimilated_wus_out:Number of assimilated workunits:3
+download_size_out:Bytes in download dir:3
+upload_size_out:Bytes in upload dir:3
diff --git a/stripchart/samples/db_count b/stripchart/samples/db_count
new file mode 100644
index 0000000..1707b2a
--- /dev/null
+++ b/stripchart/samples/db_count
@@ -0,0 +1,9 @@
+#! /bin/csh
+
+set CIVDATE = `date "+%Y:%m:%d:%H:%M"`
+set UNIXDATE = `perl -e 'print time()'`
+set DBNAME = `./parse_config db_name`
+
+set COUNT = `echo "use $DBNAME; select count(*) from $1" | mysql | tail -1`
+
+echo $CIVDATE $UNIXDATE $COUNT
diff --git a/stripchart/samples/db_looper b/stripchart/samples/db_looper
new file mode 100644
index 0000000..66d9769
--- /dev/null
+++ b/stripchart/samples/db_looper
@@ -0,0 +1,4 @@
+#! /bin/csh
+
+set ARG = "db_count $1"
+looper "$ARG" $2
diff --git a/stripchart/samples/db_query b/stripchart/samples/db_query
new file mode 100644
index 0000000..7934b7c
--- /dev/null
+++ b/stripchart/samples/db_query
@@ -0,0 +1,15 @@
+#! /bin/csh
+
+
+
+set CIVDATE = `date "+%Y:%m:%d:%H:%M"`
+
+set UNIXDATE = `perl -e 'print time()'`
+
+set DBNAME = `./parse_config db_name`
+
+set COUNT = `echo "use $DBNAME;$1" | mysql | tail -1`
+
+
+
+echo $CIVDATE $UNIXDATE $COUNT
diff --git a/stripchart/samples/dir_size b/stripchart/samples/dir_size
new file mode 100644
index 0000000..d64a4bf
--- /dev/null
+++ b/stripchart/samples/dir_size
@@ -0,0 +1,8 @@
+#! /bin/csh
+
+set SIZE = `du -sk $1 | awk '{print $1*1024}'`
+
+set CIVDATE = `/bin/date "+%Y:%m:%d:%H:%M"`
+set UNIXDATE = `/usr/local/bin/perl -e 'print time()'`
+
+echo $CIVDATE $UNIXDATE $SIZE
diff --git a/stripchart/samples/get_load b/stripchart/samples/get_load
new file mode 100644
index 0000000..5dbb978
--- /dev/null
+++ b/stripchart/samples/get_load
@@ -0,0 +1,11 @@
+#! /bin/csh
+
+set UPTIME = `/usr/bin/uptime | awk '{print $10}' | sed s/,//`
+if ($UPTIME == "average:") then
+ set UPTIME = `/usr/bin/uptime | awk '{print $11}' | sed s/,//`
+endif
+
+set CIVDATE = `/bin/date "+%Y:%m:%d:%H:%M"`
+set UNIXDATE = `/usr/local/bin/perl -e 'print time()'`
+
+echo $CIVDATE $UNIXDATE $UPTIME
diff --git a/stripchart/samples/looper b/stripchart/samples/looper
new file mode 100644
index 0000000..81c36f2
--- /dev/null
+++ b/stripchart/samples/looper
@@ -0,0 +1,6 @@
+#! /bin/csh
+
+while (1)
+ $1
+ sleep $2;
+end
diff --git a/stripchart/samples/parse_config b/stripchart/samples/parse_config
new file mode 100644
index 0000000..2ad9b63
--- /dev/null
+++ b/stripchart/samples/parse_config
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+# -*- mode: python; python-indent: 4; -*-
+
+
+
+## $Id: parse_config 3581 2004-06-15 19:41:26Z rwalton $
+
+
+
+'''
+
+
+
+A program to pass config file settings to calling programs via stdout
+
+
+
+'''
+
+
+
+import boinc_path_config
+from Boinc import configxml
+
+import sys, os
+
+
+
+program_path = os.path.realpath(os.path.dirname(sys.argv[0]))
+
+config_filename = os.path.realpath(os.path.join(program_path, '../config.xml'))
+
+
+
+config = configxml.ConfigFile(config_filename).read()
+
+
+print config.config.__dict__.get(sys.argv[1])
+
diff --git a/test/1sec_correct_output b/test/1sec_correct_output
new file mode 100644
index 0000000..19f86f4
--- /dev/null
+++ b/test/1sec_correct_output
@@ -0,0 +1 @@
+done
diff --git a/test/1sec_result b/test/1sec_result
new file mode 100644
index 0000000..854f54a
--- /dev/null
+++ b/test/1sec_result
@@ -0,0 +1,13 @@
+<file_info>
+ <name><OUTFILE_0/></name>
+ <generated_locally/>
+ <upload_when_present/>
+ <url><UPLOAD_URL/></url>
+ <max_nbytes>100000</max_nbytes>
+</file_info>
+<result>
+ <file_ref>
+ <file_name><OUTFILE_0/></file_name>
+ <open_name>out</open_name>
+ </file_ref>
+</result>
diff --git a/test/1sec_wu b/test/1sec_wu
new file mode 100644
index 0000000..da05e11
--- /dev/null
+++ b/test/1sec_wu
@@ -0,0 +1,2 @@
+<workunit>
+</workunit>
diff --git a/test/abort_result b/test/abort_result
new file mode 100644
index 0000000..ccbe669
--- /dev/null
+++ b/test/abort_result
@@ -0,0 +1,13 @@
+<file_info>
+ <name><OUTFILE_0/></name>
+ <generated_locally/>
+ <upload_when_present/>
+ <max_nbytes>10000</max_nbytes>
+ <url><UPLOAD_URL/></url>
+</file_info>
+<result>
+ <file_ref>
+ <file_name><OUTFILE_0/></file_name>
+ <open_name>out</open_name>
+ </file_ref>
+</result>
diff --git a/test/cgiserver.py b/test/cgiserver.py
new file mode 100644
index 0000000..5f7f715
--- /dev/null
+++ b/test/cgiserver.py
@@ -0,0 +1,197 @@
+#!/usr/bin/env python
+
+# $Id: cgiserver.py 2680 2003-11-25 07:40:45Z quarl $
+# cgi/php web server
+
+import BaseHTTPServer, CGIHTTPServer
+import sys, os, urllib, select
+import random, time # XXX
+
+php_path = None
+possible_php_paths = [ '/usr/lib/cgi-bin/php4',
+ 'PROGRAM_PATH/fake_php.py' ]
+def setup_php(program_path):
+ global php_path
+ for p in possible_php_paths:
+ p = p.replace('PROGRAM_PATH', program_path)
+ if os.path.exists(p):
+ php_path = p
+ return
+ raise Exception("No php binary found - not even fake_php.py (program_path=%s) !"%program_path)
+
+class PHPHTTPRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
+ def is_cgi(self):
+ if os.path.split(self.path)[1] == '':
+ index_php = os.path.join(self.path, 'index.php')
+ if os.path.exists(self.translate_path(index_php)):
+ self.path = index_php
+ if self.path.find('.php') != -1:
+ self.cgi_info = os.path.split(self.path)
+ return True
+
+ for p in self.cgi_directories:
+ p = os.path.join(p,'')
+ if self.path.startswith(p):
+ self.cgi_info = os.path.split(self.path)
+ return True
+ return False
+
+ def run_cgi(self):
+ """Execute a CGI script."""
+ dir, rest = self.cgi_info
+ i = rest.rfind('?')
+ if i >= 0:
+ rest, query = rest[:i], rest[i+1:]
+ else:
+ query = ''
+ i = rest.find('/')
+ if i >= 0:
+ script, rest = rest[:i], rest[i:]
+ else:
+ script, rest = rest, ''
+ scriptname = dir + '/' + script
+ is_php = script.endswith('.php')
+ # print "#### cgi_info=%s,dir=%s,rest=%s,script=%s,scriptname=%s,is_php=%s"%(self.cgi_info,dir,rest,script,scriptname,is_php)
+ if is_php:
+ if not php_path: raise Exception('php_path not set')
+ scriptfile = php_path
+ sourcefile = self.translate_path(scriptname)
+ else:
+ scriptfile = self.translate_path(scriptname)
+ if not os.path.exists(scriptfile):
+ self.send_error(404, "No such CGI script (%s)" % `scriptname`)
+ return
+ if not os.path.isfile(scriptfile):
+ self.send_error(403, "CGI script is not a plain file (%s)" %
+ `scriptname`)
+ return
+ ispy = self.is_python(scriptname)
+ if not ispy:
+ if not (self.have_fork or self.have_popen2 or self.have_popen3):
+ self.send_error(403, "CGI script is not a Python script (%s)" %
+ `scriptname`)
+ return
+ if not self.is_executable(scriptfile):
+ self.send_error(403, "CGI script is not executable (%s)" %
+ `scriptname`)
+ return
+
+ # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
+ # XXX Much of the following could be prepared ahead of time!
+ env = {}
+ env['DOCUMENT_ROOT'] = os.getcwd()
+ env['SERVER_SOFTWARE'] = self.version_string()
+ env['SERVER_NAME'] = self.server.server_name
+ env['GATEWAY_INTERFACE'] = 'CGI/1.1'
+ env['SERVER_PROTOCOL'] = self.protocol_version
+ env['SERVER_PORT'] = str(self.server.server_port)
+ env['REQUEST_METHOD'] = self.command
+ uqrest = urllib.unquote(self.cgi_info[1])
+ env['REQUEST_URI'] = self.path
+ # env['PATH_INFO'] = uqrest
+ # env['PATH_TRANSLATED'] = self.translate_path(uqrest)
+ env['SCRIPT_NAME'] = scriptname
+ env['SCRIPT_FILENAME'] = self.translate_path(scriptname)
+ if query:
+ env['QUERY_STRING'] = query
+ host = self.address_string()
+ if host != self.client_address[0]:
+ env['REMOTE_HOST'] = host
+ env['REMOTE_ADDR'] = self.client_address[0]
+ env['REDIRECT_STATUS'] = '1' # for php
+ # XXX AUTH_TYPE
+ # XXX REMOTE_USER
+ # XXX REMOTE_IDENT
+ if self.headers.typeheader is None:
+ env['CONTENT_TYPE'] = self.headers.type
+ else:
+ env['CONTENT_TYPE'] = self.headers.typeheader
+ length = self.headers.getheader('content-length')
+ if length:
+ env['CONTENT_LENGTH'] = length
+ accept = []
+ for line in self.headers.getallmatchingheaders('accept'):
+ if line[:1] in "\t\n\r ":
+ accept.append(line.strip())
+ else:
+ accept = accept + line[7:].split(',')
+ env['HTTP_ACCEPT'] = ','.join(accept)
+ ua = self.headers.getheader('user-agent')
+ if ua:
+ env['HTTP_USER_AGENT'] = ua
+ co = filter(None, self.headers.getheaders('cookie'))
+ if co:
+ env['HTTP_COOKIE'] = ', '.join(co)
+ # XXX Other HTTP_* headers
+ if not self.have_fork:
+ # Since we're setting the env in the parent, provide empty
+ # values to override previously set values
+ for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
+ 'HTTP_USER_AGENT', 'HTTP_COOKIE'):
+ env.setdefault(k, "")
+ os.environ.update(env)
+
+ self.send_response(200, "Script output follows")
+
+ decoded_query = query.replace('+', ' ')
+
+ if self.have_fork:
+ # Unix -- fork as we should
+ if is_php:
+ args = [php_path, sourcefile]
+ else:
+ args = [script]
+ if '=' not in decoded_query:
+ args.append(decoded_query)
+ self.wfile.flush() # Always flush before forking
+ pid = os.fork()
+ if pid != 0:
+ # Parent
+ pid, sts = os.waitpid(pid, 0)
+ # throw away additional data [see bug #427345]
+ while select.select([self.rfile], [], [], 0)[0]:
+ try:
+ if not self.rfile.read(1):
+ break
+ except:
+ break
+ if sts:
+ self.log_error("CGI script exit status %#x", sts)
+ return
+ # Child
+ try:
+ if 0:
+ time.sleep(.1)
+ fn = '/tmp/a%d'%random.randint(1000,10000)
+ f = open(fn, 'w')
+ s = ''
+ while select.select([self.rfile], [], [], 0)[0]:
+ try:
+ c = self.rfile.read(1)
+ if not c:
+ break
+ s += c
+ except:
+ break
+ print '### input:', repr(s)
+ print >>f, s
+ f.close()
+ self.rfile = open(fn, 'r')
+ os.dup2(self.rfile.fileno(), 0)
+ os.dup2(self.wfile.fileno(), 1)
+ os.chdir(self.translate_path(dir)) # KC
+ os.execve(scriptfile, args, os.environ)
+ except:
+ self.server.handle_error(self.request, self.client_address)
+ os._exit(127)
+
+ else:
+ raise SystemExit('need fork()')
+
+def serve(bind='localhost', port=8000, handler=PHPHTTPRequestHandler):
+ httpd = BaseHTTPServer.HTTPServer((bind,port), handler)
+ httpd.serve_forever()
+
+if __name__ == '__main__':
+ setup_php(os.path.realpath(os.path.dirname(sys.argv[0])))
+ serve()
diff --git a/test/concat_correct_output b/test/concat_correct_output
new file mode 100644
index 0000000..6e293ae
--- /dev/null
+++ b/test/concat_correct_output
@@ -0,0 +1,2651 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <META http-equiv="Content-Type" CONTENT="text/html" CHARSET="UTF-8">
+ <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
+ <STYLE TYPE="text/css" MEDIA="screen">
+ BODY, H2, H3, H4, P, UL, OL, DL
+ {
+ font-family: "Verdana", "Helvetica", "Arial", "sans-serif"
+ }
+
+ H1 {color: #0058a0; font-size: 20pt}
+ H2 {color: #0058a0; font-size: 16pt}
+ H3 {color: #0058a0; font-size: 14pt}
+ H4 {color: #0058a0; font-size: 12pt}
+
+ A:link, A:active, A:visited
+ {
+ color: #0058a0;
+ text-decoration: none
+ }
+
+ P, UL, OL, DL {margin-left: 10%; margin-right: 10%; font-size: 10pt}
+ DT {margin-bottom: 0.5em}
+ .offset {margin-left: 10%}
+ .afterskip {margin-bottom: 1em}
+ .afterhalf {margin-bottom: 0.5em}
+ .example {margin-left: 10%; margin-right: 10%;
+ border-color: #0058a0; border-style:solid; border-width: 1pt; padding: 1pt}
+ CODE {font-family: "Courier"}
+ .comment {color: #0000ff}
+
+ P.offset {margin-left: 15%}
+ P.inner {margin-left: 2%; width: 96%}
+ P.note {margin-left: 10%; border-color: #0058a0;
+ border-style:solid; border-width: 1pt;
+ padding: 5pt; background-color:#e0e0e0 }
+
+ PRE {font-size: 10pt; padding: 5pt}
+
+ </STYLE>
+ <title>GAdoc - Sablotron 0.60</title>
+ </head>
+ <body bgcolor="#ffffff">
+ <h1 CLASS="afterskip">Sablotron 0.60</h1>
+ <DIV CLASS="afterskip">
+ <p>
+ <b>
+ <i>Tom Kaiser (Ginger Alliance)</i>
+ </b>
+ </p>
+ <p>
+ <i>June 17, 2001</i>
+ </p>
+ </DIV>
+ <h3>Abstract</h3>
+ <DIV CLASS="offset">This is a description of the current version of the
+ XSLT processor called Sablotron, including an overview of its
+ limitations as compared to the XSLT specification.
+ </DIV>
+ <h3>Contents</h3>
+<DIV STYLE="margin-left: 10%; margin-bottom: 2em; font-size: smaller">
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__25"></a> <a href="#i__25">
+ <b>1 This text</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__60"></a> <a href="#i__60">
+ <b>2 Changes from the last release</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__74"></a> <a href="#i__74">
+ <b>3 Introduction</b>
+ </a>
+ <DIV class="offset"> <a href="#i__81">3.1 XSLT</a>
+ <BR> <a href="#i__154">3.2 On Sablotron</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__227"></a> <a href="#i__227">
+ <b>4 The sources</b>
+ </a>
+ <DIV class="offset"> <a href="#i__238">4.1 Getting the sources</a>
+ <BR> <a href="#i__280">4.2 Joining the development</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__305"></a> <a href="#i__305">
+ <b>5 Implementation. Supported instructions and functions</b>
+ </a>
+ <DIV class="offset"> <a href="#i__343">5.1 Templates</a>
+ <BR> <a href="#i__364">5.2 Conditional processing</a>
+ <BR> <a href="#i__381">5.3 Loops</a>
+ <BR> <a href="#i__398">5.4 Variables and parameters</a>
+ <BR> <a href="#i__415">5.5 Element creation</a>
+ <BR> <a href="#i__439">5.6 Global definitions</a>
+ <BR> <a href="#i__476">5.7 Values and copying</a>
+ <BR> <a href="#i__508">5.8 Namespace processing</a>
+ <BR> <a href="#i__529">5.9 Sorting</a>
+ <BR> <a href="#i__577">5.10 Whitespace stripping</a>
+ <BR> <a href="#i__598">5.11 Includes</a>
+ <BR> <a href="#i__623">5.12 Other unimplemented instructions</a>
+ <BR> <a href="#i__654">5.13 Output conformance</a>
+ <BR> <a href="#i__686">5.14 XPath expressions</a>
+ <BR> <a href="#i__714">5.15 Built-in functions</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__804"></a> <a href="#i__804">
+ <b>6 Other implementation-related notes</b>
+ </a>
+ <DIV class="offset"> <a href="#i__811">6.1 Handlers</a>
+ <BR> <a href="#i__859">6.2 Encodings</a>
+ <BR> <a href="#i__887">6.3 Output methods</a>
+ <BR> <a href="#i__915">6.4 URIs</a>
+ <BR> <a href="#i__983">6.5 Named buffers</a>
+ <BR> <a href="#i__1015">6.6 Error and log messages</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__1048"></a> <a href="#i__1048">
+ <b>7 The C interface</b>
+ </a>
+ <DIV class="offset"> <a href="#i__1065">7.1 Shortcuts</a>
+ <BR> <a href="#i__1205">7.2 Basic functions</a>
+ <BR> <a href="#i__1416">7.3 Generalized interface functions</a>
+ <BR> <a href="#i__1578">7.4 The situation object</a>
+ <BR> <a href="#i__1631">7.5 Document Object Model (DOM) functions</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__1870"></a> <a href="#i__1870">
+ <b>8 The command line interface</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__2013"></a> <a href="#i__2013">
+ <b>9 References</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__25"></a>
+ <h2>
+ <a href="#toc_i__25">1 This text</a>
+ </h2>
+ <DIV>
+ <p CLASS="">The HTML form of this description
+ was compiled by Sablotron from the XML source
+ Sablot-0-60.xml.
+ </p>
+ <p CLASS="">
+ The material in the following sections includes:
+ </p>
+ <ul>
+ <li>some background information on XSLT and Sablotron,</li>
+ <li>a detailed comparison of the current version of
+ Sablotron to the XSLT spec,</li>
+ <li>Sablotron usage from the command line or as a
+ library.</li>
+ </ul>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__60"></a>
+ <h2>
+ <a href="#toc_i__60">2 Changes from the last release</a>
+ </h2>
+ <DIV>
+ <p CLASS="">Please see the RELEASE file.</p>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__74"></a>
+ <h2>
+ <a href="#toc_i__74">3 Introduction</a>
+ </h2>
+ <DIV>
+ <DIV class="afterskip">
+ <a name="i__81"></a>
+ <h3>
+ <a href="#toc_i__74">3.1 XSLT</a>
+ </h3>
+ <p CLASS="">XSLT is a language allowing to transform given XML data (the
+ <i>input</i>) according to a <i>stylesheet</i>. XSLT stylesheets
+ are themselves XML documents; that is, all instructions of the
+ language are expressed in the form of XML elements. The
+ <i>output</i>, i.e. the result of the processing, is typically a
+ XML document as well, although the syntactic requirements can be
+ relaxed to allow the creation of a HTML document (one that
+ contains unclosed tags and the like), or even plain text.
+ </p>
+ <p CLASS="">XSLT was designed by the World Wide Web Consortium (W3C) as
+ a part of the XSL stylesheet language, where it is complemented
+ by a powerful set of formatting instructions. The most precise
+ information about XSLT can be found in the W3C Recommendation <a href="#ref-xslt">[XSLT]</a>. In particular, Appendix B of the
+ Recommendation contains a handy syntax table. A good tutorial is
+ <a href="#ref-bible">[XMLBible14]</a>.
+ </p>
+ <p CLASS="">Other W3C Recommendations one often needs to consult are <a href="#ref-xml">[XML]</a> (for the definition of the XML
+ language) and <a href="#ref-xpath">[XPath]</a> (for details on
+ XPath, the language used to form expressions in XSLT and
+ elsewhere).
+ </p>
+ <p CLASS="">An excellent source of information about XSLT (indeed, about
+ anything related to XML and SGML) is <a href="#ref-rcover">[Cover]</a>; see also <a href="#ref-xslinfo">[XSLINFO]</a> and <a href="#ref-xmlorg">[XMLorg]</a>.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__154"></a>
+ <h3>
+ <a href="#toc_i__74">3.2 On Sablotron</a>
+ </h3>
+ <p CLASS="">Sablotron is a XSLT processor (though not quite conforming
+ yet..., see below) written in C++. Since the machines where it
+ is meant to run include various small mobile
+ clients, the main objectives of its design are the following:
+ </p>
+ <ul>
+ <li>portability,</li>
+ <li>compact code,</li>
+ <li>as much independence on other resources (Java etc.) as
+ possible.</li>
+ </ul>
+ <p CLASS="">Sablotron is a single shared library
+ (<code>sablot.dll</code> or <code>libsablot.so.0.60</code>). It can
+ also be used from the command line via the simple interface
+ called <code>sabcmd</code>. See <a href="#invocation">here</a> for
+ more information.
+ </p>
+ <p CLASS="">The only software Sablotron relies on is <b>expat</b>, the
+ XML parser by James Clark. See <a href="#expat">below</a> for
+ information on how to get expat.
+ </p>
+ <p CLASS="">For information on the available interfaces, e.g. for
+ Python, Perl and PHP, see <a href="http://www.gingerall.com">www.gingerall.com</a>.
+ </p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__227"></a>
+ <h2>
+ <a href="#toc_i__227">4 The sources</a>
+ </h2>
+ <DIV>
+ <p CLASS="">
+ Sablotron is written in C++. The source files compile under
+ Win32 (using MS Visual C++ 6.0) and on Solaris and Linux (using
+ g++ 2.95.2) without change.</p>
+ <DIV class="afterskip">
+ <a name="i__238"></a>
+ <h3>
+ <a href="#toc_i__227">4.1 Getting the sources</a>
+ </h3>
+ <p CLASS="">The source or binary distributions of Sablotron can be downloaded
+ from <a href="http://www.gingerall.com">www.gingerall.com</a>. For
+ instructions on how to build the sources (if any), refer to the accompanying INSTALL file.
+ </p>
+ <p CLASS="">If you have access to the Ginger Alliance CVS server, you
+ can get the working version of Sablotron in the CVS module
+ <code>ga</code>. The access rights can be obtained on
+ request from <a href="mailto:cvsadmin at gingerall.com">the CVS admin</a>.
+ </p>
+ <p CLASS="">
+ <a name="expat"></a>
+ Since version 0.50, Sablotron uses expat 1.95.1, available from <a href="http://expat.sourceforge.org">SourceForge</a>.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__280"></a>
+ <h3>
+ <a href="#toc_i__227">4.2 Joining the development</a>
+ </h3>
+ <p CLASS="">
+ Sablotron is an open source project and all volunteers are most
+ welcome! The documentation of the sources is still somewhat
+ sparse but we will try to improve it. If you find the invitation
+ to work on Sablotron with us interesting, please <a href="mailto:sablotron at gingerall.com">contact us</a>. There is also
+ a mailing list available, see <a href="http://www.gingerall.com">www.gingerall.com</a>.
+ </p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__305"></a>
+ <h2>
+ <a href="#toc_i__305">5 Implementation. Supported instructions and functions</a>
+ </h2>
+ <DIV>
+ <p CLASS="">The instruction set supported by this version of Sablotron is
+ already sufficient for many transformation tasks (e.g. the task of
+ formatting this document). On the other
+ hand, a comparison of it to the XSLT specification <a href="#ref-xslt">[XSLT]</a> shows that much is still to be
+ done. The purpose of the
+ following sections is to describe the varying degree of support
+ for the elements of the XSLT language. </p>
+ <p CLASS="">It may be helpful to refer to the syntax table in Appendix B
+ of <a href="#ref-xslt">[XSLT]</a>. The instructions/attributes that
+ are not listed as unsupported should be implemented. The <a href="mailto:sablotron at gingerall.com">authors</a> will appreciate being
+ told about any omissions found in the following
+ description.</p>
+ <p CLASS="">For readability, I sometimes omit the <code>xsl:</code> prefix
+ from the instruction names.</p>
+ <DIV class="afterskip">
+ <a name="i__343"></a>
+ <h3>
+ <a href="#toc_i__305">5.1 Templates</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ template, apply-templates, call-template
+ </code>
+ </p>
+ <p CLASS="">
+ Fully implemented. <code>xsl:sort</code> is supported since release 0.50.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__364"></a>
+ <h3>
+ <a href="#toc_i__305">5.2 Conditional processing</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ if, choose, when, otherwise
+ </code>
+ </p>
+ <p CLASS="">Fully implemented.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__381"></a>
+ <h3>
+ <a href="#toc_i__305">5.3 Loops</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>for-each</code>
+ </p>
+ <p CLASS="">Fully implemented.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__398"></a>
+ <h3>
+ <a href="#toc_i__305">5.4 Variables and parameters</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>variable, param, with-param</code>
+ </p>
+ <p CLASS="">Fully implemented. Top-level variables and parameters are
+ read in the document order, so no forward references are
+ resolved. This is a minor deviation from the spec. </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__415"></a>
+ <h3>
+ <a href="#toc_i__305">5.5 Element creation</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>element, attribute, text,
+ comment, processing-instruction, attribute-set</code>
+ </p>
+ <p CLASS="">
+ <code>xsl:attribute-set</code> is not implemented. For the
+ rest, <code>name</code> is the only recognized attribute (where
+ applicable). Literal result elements work.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__439"></a>
+ <h3>
+ <a href="#toc_i__305">5.6 Global definitions</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>stylesheet, transform, output</code>
+ </p>
+ <p CLASS="">For <code>stylesheet</code> and <code>transform</code>,
+ the only recognized attribute is
+ <code>version</code>. <code>xsl:output</code> should work
+ (see below for notes on the <code>encoding</code>
+ attribute). HTML indentation has been added in 0.60.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__476"></a>
+ <h3>
+ <a href="#toc_i__305">5.7 Values and copying</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>value-of, copy, copy-of</code>
+ </p>
+ <p CLASS="">
+ <code>copy-of</code> and <code>value-of</code> are fully
+ implemented. <code>copy</code> is implemented except for the
+ <code>use-attribute-sets</code> attribute.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__508"></a>
+ <h3>
+ <a href="#toc_i__305">5.8 Namespace processing</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>namespace-alias</code>
+ </p>
+ <p CLASS="">Namespaces should be processed correctly. The
+ <code>namespace-alias</code> instruction is now supported
+ (patch by Major).</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__529"></a>
+ <h3>
+ <a href="#toc_i__305">5.9 Sorting</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>sort</code>
+ </p>
+ <p CLASS="">
+ <code>xsl:sort</code> is implemented since 0.50. There are
+ minor limitations:
+ </p>
+ <ul>
+ <li>currently, the <code>lang</code> attribute may only
+ contain the values <code>"en"</code> or <code>"cz"</code>.</li>
+ <li>
+ <code>case-order</code> cannot be specified.</li>
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__577"></a>
+ <h3>
+ <a href="#toc_i__305">5.10 Whitespace stripping</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>strip-space, preserve-space</code>
+ </p>
+ <p CLASS="">Only the default whitespace stripping is done. That is,
+ all whitespace-only text nodes in any stylesheet, not appearing
+ inside a <code>xsl:text</code>, are removed. The two
+ instructions for whitespace stripping and preservation are
+ unsupported.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__598"></a>
+ <h3>
+ <a href="#toc_i__305">5.11 Includes</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>include, import, apply-imports</code>
+ </p>
+ <p CLASS="">Only <code>xsl:include</code> is implemented. Processing
+ involving multiple documents works, but has to get more testing,
+ eg. with respect to <code>generate-id()</code>.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__623"></a>
+ <h3>
+ <a href="#toc_i__305">5.12 Other unimplemented instructions</a>
+ </h3>
+ <ul>
+ <li>
+ <code>xsl:key,</code>
+ </li>
+ <li>
+ <code>xsl:number,</code>
+ </li>
+ <li>
+ <code>xsl:fallback.</code>
+ </li>
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__654"></a>
+ <h3>
+ <a href="#toc_i__305">5.13 Output conformance</a>
+ </h3>
+ <p CLASS="">The output mechanism is much closer to the spec than in
+ the versions prior to 0.4. The following issues remain for the
+ html method:</p>
+ <ul>
+ <li>Output the boolean attributes correctly.</li>
+ <li>Disable the escaping inside
+ <code><SCRIPT></code> and
+ <code><STYLE></code>
+ </li>.
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__686"></a>
+ <h3>
+ <a href="#toc_i__305">5.14 XPath expressions</a>
+ </h3>
+ <p CLASS="">Almost all features of XPath are fully implemented. This means
+ there should be no problems with expressions of any kind.</p>
+ <p CLASS="">One exception relates to axes. The <code>following</code> and
+ <code>preceding</code> axes haven't been implemented yet.</p>
+ <p CLASS="">Another possible exception may be numbers; we did not yet do a
+ thorough test of rounding, NaNs, infinity, etc.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__714"></a>
+ <h3>
+ <a href="#toc_i__305">5.15 Built-in functions</a>
+ </h3>
+ <p CLASS="">
+ <a name="corelib"></a>Only a few functions from the standard
+ function library remain
+ unimplemented:
+ </p>
+ <ul>
+ <li>
+ <code>id()</code>,</li>
+ <li>
+ <code>lang()</code> (accepted but always returns true),</li>
+ <li>
+ <code>key()</code>,</li>
+ <li>
+ <code>format-number()</code>,</li>
+ <li>
+ <code>unparsed-entity-uri()</code>.</li>
+ </ul>
+ <p CLASS="">As for the fuctions that <i>are</i> implemented, the
+ following is a list of differences from the spec:
+ </p>
+ <ul>
+ <li>
+ <code>document()</code> only accepts one argument, always
+ getting the base URI from the stylesheet URI.
+ </li>
+ <li>
+ <code>string-length()</code> returns the byte length of
+ the UTF-8 representation of the string. This will typically
+ differ from the actual length.
+ </li>
+ <li>
+ <code>generate-id()</code> might fail to generate unique identifiers
+ when several input documents are present (giving the same id to
+ nodes from different documents).
+ </li>
+ </ul>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__804"></a>
+ <h2>
+ <a href="#toc_i__804">6 Other implementation-related notes</a>
+ </h2>
+ <DIV>
+ <DIV class="afterskip">
+ <a name="i__811"></a>
+ <h3>
+ <a href="#toc_i__804">6.1 Handlers</a>
+ </h3>
+ <p CLASS="">It is possible for the user to supply the following
+ handlers to Sablotron:
+ <ul>
+ <li>message handler (to bypass the default way of displaying
+ error and warning messages and logging),</li>
+ <li>scheme handler (to retrieve documents whose URI use an
+ unsupported scheme),</li>
+ <li>streaming handler (an expat-like interface to the XML
+ document which is the result of the processing),</li>
+ <li>'miscellaneous' handler (which will probably server as a
+ collections of odd callbacks).</li>
+ </ul>
+ </p>
+ <p CLASS="">
+ The handlers are set using <code>SablotRegHandler()</code>
+ For details concerning the interface of these handlers,
+ consult the header files <code>sablot.h</code> and
+ <code>shandler.h</code>.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__859"></a>
+ <h3>
+ <a href="#toc_i__804">6.2 Encodings</a>
+ </h3>
+ <p CLASS="">
+ In version 0.52, the encoding conversion capabilities of
+ Sablotron have been much extended. The most important fact is the
+ following: if you have the iconv library installed on your system, you
+ can use any encoding it supports (that is, almost any encoding
+ whatsoever) for both the input and the output documents. Iconv
+ is available on most systems (it is a standard part of glibc2,
+ for instance). There are implementations for Win32 as well.
+ </p>
+ <p CLASS="">If iconv is not available, the encoding may still be supported internally by
+ Sablotron. At present, the list is of such encodings is rather
+ short: besides UTF-8, these are UTF-16, ASCII, iso-8859-1,
+ iso-8859-2 and windows-1250 on input, none on output. However,
+ we plan to implement a half independent light-weight
+ conversion library for use on systems without iconv,
+ extending the set of internally supported encodings
+ considerably.
+ </p>
+ <p CLASS="">Lastly, the user has the option to implement a custom
+ encoding conversion handler, which will be asked to perform any unsupported
+ conversion. See the <code>shandler.h</code> header file for
+ details.
+ </p>
+ <p CLASS="">The default input and output encoding is in all cases UTF-8.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__887"></a>
+ <h3>
+ <a href="#toc_i__804">6.3 Output methods</a>
+ </h3>
+ <p CLASS="">In addition to the standard output methods (xml, html and
+ text), it is possible to output xhtml. Documents output using
+ this method obey the XHTML 1.0 rules (in particular, all empty
+ elements are closed). To choose the method, use
+ <code><xsl:output method='xhtml'></code>. <b>Please note</b>
+ that the name of this method will possibly be changed since the XSLT
+ spec requires any processor-specific methods to have qualified
+ names, say <code>sab:xhtml</code>. On the other hand, the name
+ <code>xhtml</code> is considered in the XSLT 2.0 working draft.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__915"></a>
+ <h3>
+ <a href="#toc_i__804">6.4 URIs</a>
+ </h3>
+ <p CLASS="">Sablotron can handle
+ two URI schemes natively: 'file' and 'arg' (see
+ below). Moreover, it is possible to use the function
+ <code>SablotRegSchemeHandler</code> to register an external scheme
+ handler which will receive requests in all other schemes. See
+ the documentation in <code>sablot.h</code> and
+ <code>shandler.h</code>.
+ </p>
+ <p CLASS="">Relative URI references are resolved in conformance to RFC
+ 2396. The base URI is well defined when the relative reference appears
+ inside a XML document; when invoking sabcmd, the base URI is
+ taken to correspond to the current working directory.
+ </p>
+ <p CLASS="">
+ <a name="fname-rules"></a>When specifying filenames, the
+ following rules are in effect:
+ </p>
+ <ul>
+ <li>specify the "file:" scheme for any standard files,
+ i.e. refer to <code>stdin</code> as <code>file://stdin</code>
+ etc.</li>
+ <li>slashes and backslashes work equally fine, in Windows as
+ well as Linux.</li>
+ <li>to include a drive letter under Windows
+ (e.g. <code>C:\doc.xml</code>), it is necessary to say
+ <code>file://c:/doc.xml</code>.
+ </li>
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__983"></a>
+ <h3>
+ <a href="#toc_i__804">6.5 Named buffers</a>
+ </h3>
+ <p CLASS="">
+ <a name="argscheme"></a>Sablotron introduces an URI scheme
+ 'arg:' which enables one to use strings in named memory
+ buffers. The buffer names can have a tree-like structure so that
+ a relative reference from a document in a buffer can be resolved
+ as pointing to another buffer.
+ </p>
+ <p CLASS="">For instance, if we invoke Sablotron specifying that a
+ buffer named <code>/mybuf/1</code> contains the string
+ "<a>contents</a>", then the expression
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ document('arg:/mybuf/1')/a
+ </code>
+ </p>
+ <p CLASS="">has string-value "contents". If the document in arg:/mybuf/1
+ contained a relative URI reference "../theirbuf/2" then this
+ would be resolved as pointing to "arg:/theirbuf/2".</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1015"></a>
+ <h3>
+ <a href="#toc_i__804">6.6 Error and log messages</a>
+ </h3>
+ <p CLASS="">By default, Sablotron writes error and warning messages to
+ stderr, and does no logging. By a call to
+ <code>SablotSetLog()</code>, you can specify the name of the log
+ file to be used.</p>
+ <p CLASS="">Besides, you can use <code>SablotRegHandler()</code>
+ to override the default message handling. The handler you
+ register will receive all messages in a structured form that's
+ easy to process and filter. For details, see
+ the documentation in <code>sablot.h</code> and
+ <code>shandler.h</code>.</p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1048"></a>
+ <h2>
+ <a href="#toc_i__1048">7 The C interface</a>
+ </h2>
+ <DIV>
+ <p CLASS="">
+ <a name="invocation"></a>
+ </p>
+ <p CLASS="">
+ This section describes the functions exported from the
+ Sablotron library. All of them have a return type of 'int'
+ and return an error flag (nonzero signals an error). Errors
+ are reported to the user by Sablotron itself.
+ </p>
+ <DIV class="afterskip">
+ <a name="i__1065"></a>
+ <h3>
+ <a href="#toc_i__1048">7.1 Shortcuts</a>
+ </h3>
+ <p CLASS="">
+ We'll first describe the 'shortcuts' that do the whole
+ processing in one call.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotProcess(char *sheetURI, char *inputURI, char *resultURI,
+ char **params, char **arguments, char **resultArg);
+ </code>
+ </p>
+ <p CLASS="">
+ This is the basic function. The first three of its arguments
+ are the URIs of the XSLT stylesheet, the XML source and the
+ resulting document, respectively. For some notes on specifying
+ file names, see <a href="#fname-rules">above</a>.
+ </p>
+ <p CLASS="">
+ <code>params</code> is an array of pointers to the names
+ and contents of the top-level stylesheet parameters. Thus,
+ <code>params[0]</code> is a pointer to the null-terminated name
+ of the first parameter, <code>params[1]</code> points to the
+ (null-terminated) contents of the first parameter. The following
+ two array items do the same for the second parameter, etc. The
+ whole array is terminated by a NULL pointer in place of the
+ name. If no parameters are to be passed, you can specify NULL
+ for <code>params</code> itself.
+ </p>
+ <p CLASS="">
+ <code>arguments</code> is a similar array of named buffers
+ to be passed to the stylesheet. (They can be referred to via the
+ 'arg:' scheme, see <a href="#argscheme">above</a>.) Again, the
+ array is a sequence of (name, value) pairs terminated by NULL in
+ place of a name. If no named buffers are to be passed, you can
+ specify NULL for <code>arguments</code> itself.
+ </p>
+ <p CLASS="">
+ <code>resultArg</code> enables one to access the
+ resulting document in case the output went to a named buffer. In
+ that situation, <code>*resultArg</code> points to the resulting
+ null-terminated string, allocated by Sablotron. You can pass NULL
+ for <code>resultArg</code> if the output is sure to go to a
+ file.
+ </p>
+ <p CLASS="">
+ <b>Note:</b>When you are done processing the string
+ pointed to by <code>*resultArg</code>, free it using <a href="#sablotfree">
+ <code>SablotFree()</code>
+ </a> - never use
+ <code>free()</code>. The latter is guaranteed to produce a
+ segmentation fault under Linux.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotProcessFiles(char *styleSheetName,
+ char *inputName,
+ char *resultName);
+ </code>
+ </p>
+ <p CLASS="">A wrapper for <code>SablotProcess()</code> working on
+ files. The parameters are the null-terminated file names of the
+ XSLT stylesheet, the XML input and the result,
+ respectively. Sablotron opens these files itself and closes them
+ after the processing is complete. Values like "file://stdin" are
+ allowed.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotProcessStrings(char *styleSheetStr, char *inputStr, char
+ **resultStr);
+ </code>
+ </p>
+ <p CLASS="">Another wrapper for <code>SablotProcess()</code>, this
+ time for accessing named buffers (i.e. user-allocated memory
+ blocks)only. Thus, the first parameter is a null-terminated
+ string containing the whole stylesheet; the second parameter
+ is a null-terminated string containing the XML
+ input. Sablotron allocates the buffer for the resulting string
+ and returns a pointer to it in resultStr. Hence, invoking
+ <code>puts(*resultStr)</code> after having called
+ <code>SablotProcessStrings</code> sends the result to
+ stdout. The buffer allocated <b>must</b> be freed by calling the
+ function <code>SablotFree</code> described next.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1205"></a>
+ <h3>
+ <a href="#toc_i__1048">7.2 Basic functions</a>
+ </h3>
+ <p CLASS="">The above shortcuts just call the basic, lower-level
+ functions described below. Note that if you need to set options
+ for logging etc., you may need to use the low-level
+ functions. </p>
+ <p CLASS="">A typical processing session may look like this:</p>
+ <p CLASS="">
+ <pre>
+ SablotHandle p;
+ char *my_buf;
+ SablotCreateProcessor(&p);
+ SablotSetLog(p, ...);
+ /* ...set other instance-specific options here... */
+ SablotRunProcessor(p, ...);
+ SablotGetResultArg(p, "arg:/somename", &my_buf)
+ /* ...do something with my_buf... */
+ /* can run the processor again if necessary */
+ SablotRunProcessor(p, ...);
+ SablotDestroyProcessor(p);
+ </pre>
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotCreateProcessor(SablotHandle *processorPtr);
+ </code>
+ </p>
+ <p CLASS="">Creates an instance of Sablotron and returns a pointer to
+ it in *processorPtr. This pointer is passed on all subsequent
+ calls to this instance. </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotDestroyProcessor(SablotHandle processor_);
+ </code>
+ </p>
+ <p CLASS="">Destroys an instance of the processor, deallocating all
+ the memory used up by it.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotRunProcessor(SablotHandle processor_,
+ char *sheetURI,
+ char *inputURI,
+ char *resultURI,
+ char **params,
+ char **arguments);
+ </code>
+ </p>
+ <p CLASS="">Processes documents using the given processor instance and
+ given params and args definitions. See
+ <code>SablotProcess()</code>.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotGetResultArg(SablotHandle processor_,
+ char *argURI,
+ char **argValue);
+ </code>
+ </p>
+ <p CLASS="">Copies the result 'arg' buffer with the given URI,
+ returning a pointer to the newly-allocated block in
+ *argValue. If no such buffer exists, returns NULL in *argValue.
+ </p>
+ <p CLASS="">This function is necessary, because if the result document
+ is output to memory, it would be lost when
+ <code>SablotDestroyProcessor()</code> is called. When
+ deallocating the copy obtained from
+ <code>SablotGetResultArg()</code>, use <code>SablotFree</code>
+ (never <code>free()</code>). </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotFreeResultArgs(SablotHandle processor_);
+ </code>
+ </p>
+ <p CLASS="">Removes the Sablotron-internal copies of the 'arg' buffers
+ from the last Sablotron run. Normally, there should be no reason
+ to call this function as it is called automatically on both
+ <code>SablotRunProcessor()</code> and
+ <code>SablotDestroyProcessor()</code>. </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ <a name="sablotfree"></a>
+ int SablotFree(char *resultBuf);
+ </code>
+ </p>
+ <p CLASS="">This function frees the buffer allocated on previous call
+ to <code>SablotProcessStrings</code>. Calling it with an
+ invalid pointer will cause a crash.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotRegHandler(
+ SablotHandle processor_,
+ HandlerType type,
+ void *handler,
+ void *userData);
+ </code>
+ </p>
+ <p CLASS="">Registers an external handler. <code>type</code> can be
+ <code>HLR_MESSAGE</code>, <code>HLR_SCHEME</code>,
+ <code>HLR_SAX</code>, <code>HLR_MISC</code> or
+ <code>HLR_ENC</code>.
+ <code>handler</code> points to the
+ callback vector of the appropriate type. <code>userData</code>
+ is a data item to passed to all callbacks of this particular
+ handler. For details, check the <code>sablot.h</code> and
+ <code>shandler.h</code> header files.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotUnregHandler(
+ SablotHandle processor_,
+ HandlerType type,
+ void *handler,
+ void *userData);
+ </code>
+ </p>
+ <p CLASS="">Unregisters the given external handler. For details, check the
+ <code>sablot.h</code> and <code>shandler.h</code> header
+ files.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotSetLog(
+ SablotHandle processor_,
+ const char *logFilename,
+ int logLevel);
+ </code>
+ </p>
+ <p CLASS="">Sets the log filename. The <code>logLevel</code> parameter
+ is currently not used. Pass NULL for <code>logFilename</code> to
+ turn logging off (default). </p>
+ <p CLASS="">The other functions published by sablot.h have been
+ included for experimental reasons or for compatibility, and it
+ is better not to use them.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotClearError(SablotHandle processor_);
+ </code>
+ </p>
+ <p CLASS="">Clears the 'pending error' flag for this instance of
+ Sablotron.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1416"></a>
+ <h3>
+ <a href="#toc_i__1048">7.3 Generalized interface functions</a>
+ </h3>
+ <p CLASS="">The implementation of the <a href="#dom">DOM interface</a>
+ brought the need to extend some of the functions described in
+ the previous section. This extension enables the user to:
+ </p>
+ <ul>
+ <li>process documents created by the DOM functions, and</li>
+ <li>process frequently used documents in pre-parsed form.</li>
+ </ul>
+ <p CLASS="">An object called <i>situation</i> is used to provide a
+persistent context for all calls to the DOM-related
+functions. Functions used to manipulate the situation are described in
+<a href="#situation">the following section</a>.</p>
+ <p CLASS="">
+ <b>Note:</b> If not specified otherwise, all these
+ functions return an error code. A positive value indicates an error.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotCreateDocument(SablotSituation S,
+ SDOM_Document *D);
+ </code>
+ </p>
+ <p CLASS="">Creates an empty document. Typically followed by calls to
+ DOM functions to populate the document.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotDestroyDocument(SablotSituation S,
+ SDOM_Document D);
+ </code>
+ </p>
+ <p CLASS="">Destroys a document, freeing all the nodes it has created.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotParse(SablotSituation S,
+ const char *uri, SDOM_Document *D);
+ </code>
+ </p>
+ <p CLASS="">Reads in a document from the given URI.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotParseBuffer(SablotSituation S,
+ const char *buffer, SDOM_Document *D);
+ </code>
+ </p>
+ <p CLASS="">Reads in a document from the given in-memory buffer.</p>
+ <p CLASS="">These functions have variants to be used if the document
+ is to be interpreted as an XSLT stylesheet, namely
+ <code>SablotParseStylesheet</code> and
+ <code>SablotParseStylesheetBuffer</code>.</p>
+ <p CLASS="">The following functions generalize
+ <code>SablotRunProcessor</code> in that they make it possible to
+ utilize an extra kind of a source document: a DOM tree.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotRunProcessorGen(SablotSituation S,
+ void *processor_,
+ char *sheetURI,
+ char *inputURI,
+ char *resultURI);
+ </code>
+ </p>
+ <p CLASS="">A key ingredient of the extended interface. Only the URIs
+ of the sources and of the result document are given to it. The
+ rest of the information passed to
+ <code>SablotRunProcessor</code> is conveyed through
+ <code>SablotAddArgBuffer,</code> <code>SablotAddArgTree</code>
+ and <code>SablotAddParam.</code> The scheme part of the
+ stylesheet URI or the input URI may be "arg:", in which
+ case they refer to a buffer or tree passed by these
+ functions. </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotAddArgBuffer(SablotSituation S,
+ void *processor_,
+ const char *argName,
+ const char *bufferValue);
+</code>
+ </p>
+ <p CLASS="">Creates a named buffer for the next processor run. The
+ buffer's name and contents are passed as arguments. The name
+ is interpreted relative to the 'arg:/' scheme.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotAddArgTree(SablotSituation S,
+ void *processor_,
+ const char *argName,
+ SDOM_Document tree);
+</code>
+ </p>
+ <p CLASS="">Associates the given document with a name for the next
+ processor run. The document is <i>not</i> destroyed after the
+ run is finished. The name is interpreted relative to the 'arg:/'
+ scheme.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotAddParam(SablotSituation S,
+ void *processor_,
+ const char *paramName,
+ const char *paramValue);
+ </code>
+ </p>
+ <p CLASS="">Adds a global stylesheet parameter for the next processor
+ run.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1578"></a>
+ <h3>
+ <a href="#toc_i__1048">7.4 The situation object</a>
+ </h3>
+ <p CLASS="">
+ <a name="situation"></a>At present, the situation object primarily holds information on any pending errors. A
+situation is created using</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotCreateSituation(SablotSituation
+ *SP);</code>
+ </p>
+ <p CLASS="">and destroyed by</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotDestroySituation(SablotSituation
+ S);</code>
+ </p>
+ <p CLASS="">To clear the pending error flag in a situation, use</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotClearSituation(SablotSituation
+ S);</code>
+ </p>
+ <p CLASS="">The following self-explanatory functions extract parts of the error information
+ from the situation:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ const char *SablotGetErrorURI(SablotSituation S);<br>
+ int SablotGetErrorLine(SablotSituation S);<br>
+ const char *SablotGetErrorMsg(SablotSituation S);
+ </code>
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1631"></a>
+ <h3>
+ <a href="#toc_i__1048">7.5 Document Object Model (DOM) functions</a>
+ </h3>
+ <p CLASS="">
+ <a name="dom"></a>Starting with version 0.60, Sablotron implements
+ a major subset of the DOM Level 1 Core Specification <a href="#ref-dom">[DOM]</a>. A brief
+ description of the implemented interface follows; for more
+ details, please refer to the header file named
+ <code>sdom.h.</code>
+ </p>
+ <p CLASS="">All of the names related to the DOM interface start with
+ SDOM_ (for Sablot DOM).</p>
+ <p CLASS="">Major new types are <code>SDOM_Document</code> (a DOM tree) and
+ <code>SDOM_Node</code> (a node of the tree). A document can also be used in
+ place of a node. This reflects the fact in the DOM spec,
+ Document is a subclass of Node. When used in this way, the
+ document represents its own root node (which is not the same as
+ the `root element').</p>
+ <p CLASS="">Other types include:</p>
+ <ul>
+ <li>
+ <code>SDOM_char:</code> a DOM character type. Currently, this is just
+ char. Note that the DOM spec requires that the DOM
+ implementations work with UTF-16. Sablotron deviates from this
+ by using UTF-8 instead. A separate set of functions taking
+ UTF-16 strings will be provided.</li>
+ <li>
+ <code>SDOM_NodeType:</code> a node type enum. Some of the values are
+ <code>SDOM_ELEMENT_NODE,</code> <code>SDOM_ATTRIBUTE_NODE</code> and <code>SDOM_TEXT_NODE.</code> See
+ <code>sdom.h</code> for the rest.</li>
+ <li>
+ <code>SDOM_NodeList:</code> a node list returned by some of the
+ functions.</li>
+ <li>
+ <code>SDOM_Exception:</code> DOM exception codes enum, with values such
+ as <code>SDOM_NOT_FOUND_ERR</code> or <code>SDOM_INVALID_NODE_TYPE</code>. See <code>sdom.h</code>
+ for details.</li>
+</ul>
+ <p CLASS="">The functions listed below are implemented more or less as defined in
+ the DOM Level 1 Specification, with two exceptions:
+ their names are prefixed with <code>SDOM_</code> and the first argument is
+ always a <code>SablotSituation.</code> All the functions return
+ a <code>SDOM_Exception.</code> </p>
+ <ul>
+<li>
+ <code>createElement, createAttribute, createTextNode,
+createCDATASection, createComment, createProcessingInstruction</code>
+ </li>
+<li>
+ <code>getNodeType, getNodeName, setNodeName, getNodeValue, setNodeValue</code>
+ </li>
+<li>
+ <code>getParentNode, getFirstChild, getLastChild, getPreviousSibling,
+getNextSibling, getOwnerDocument</code>
+ </li>
+<li>
+ <code>insertBefore, appendChild, removeChild, replaceChild</code>
+ </li>
+<li>
+ <code>cloneNode</code>
+ </li>
+<li>
+ <code>getAttribute, setAttribute, removeAttribute, getAttributeList</code>
+ </li>
+</ul>
+ <p CLASS="">Several functions have been added:</p>
+ <ul>
+<li>
+ <code>disposeNode</code> frees all memory used by the given node</li>
+<li>
+ <code>cloneForeignNode</code> clones a node from a different
+document</li>
+<li>
+ <code>docToString</code> serializes the document, returning the
+resulting string</li>
+<li>
+ <code>xql</code> performs an XPath query on the DOM tree,
+returning a list of the nodes satisfying it.</li>
+</ul>
+ <p CLASS="">In addition, there are some functions used to manipulate
+ the node lists returned by <code>xql</code> and
+ <code>getAttributeList</code>. These include
+ <code>getNodeListLength</code>, <code>getNodeListItem</code> and
+ <code>disposeNodeList</code>.</p>
+ <p CLASS="">Finally, there are functions to extract DOM
+ exception-related information from the situation object, namely
+ <code>getExceptionCode</code>, <code>getExceptionMessage</code>
+ and <code>getExceptionDetails</code>.</p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1870"></a>
+ <h2>
+ <a href="#toc_i__1870">8 The command line interface</a>
+ </h2>
+ <DIV>
+ <p CLASS="">Sablotron comes with a command-line interface to the
+ shared library, which is a program named
+ <code>sabcmd</code>. At present, <code>sabcmd</code> is invoked
+ as follows:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ sabcmd [<i>options</i>] <i>stylesheet</i> [<i>input</i> [<i>result</i>]] [<i>assignments</i>]
+ </code>
+ </p>
+ <p CLASS="">The arguments are the URIs of the XSLT stylesheet, the
+ XML input document, and the resulting document, respectively. The
+ default for <code>
+ <i>input</i>
+ </code> is
+ <code>file://stdin</code> (meaning plain old stdin);
+ <code>
+ <i>result</i>
+ </code> defaults to
+ <code>file://stdout</code>. Filenames have to include the extension (if
+ any).</p>
+ <p CLASS="">You can display the list of available options by typing
+ <code>sabcmd --help</code>. Among the more useful ones are
+ <code>--log-file</code> (for setting the log file) and
+ <code>--measure</code> (measures and outputs the total
+ processing time).
+ </p>
+ <p CLASS="">
+ <a href="#fname-rules">The rules for filenames</a> are the same as
+ with <code>SablotProcess()</code>.
+ </p>
+ <p CLASS="">
+ <code>assignments</code> is a series of definitions of the
+ form:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ name1=value1 name2=value2 ...
+ </code>
+ </p>
+ <p CLASS="">
+ assigning values to top-level stylesheet parameters and to named
+ buffers. These two cases are distinguished by a leading '$' in
+ the name of a stylesheet parameter. The names of the buffers do
+ <i>not</i> start with "arg:". They may start with a slash; if
+ they don't, the slash is prepended.
+ </p>
+ <p CLASS="">
+ <b>Note:</b> In most cases, it will be necessary to quote
+ the individual assignments. Whether to use single or double
+ quotes may depend on the shell used (or may it?) Single quotes
+ work for bash, double quotes work in Windows.
+ </p>
+ <p CLASS="">If the result URI refers to a named buffer, the output
+ would normally remain buried in memory. Sabcmd dumps the buffer to standard
+ output instead.
+ </p>
+ <p CLASS="">To sum up and give an example, the following would be a
+ valid invocation of sabcmd:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ sabcmd sheet.xsl arg:/the_input "the_input=<a/>"
+ "$use_defaults=1"
+ </code>
+ </p>
+ <p CLASS="">This processes the document passed in the buffer named
+ the_input, using a stylesheet found in file "sheet.xsl" in the
+ working directory. We assign 1 to the top-level parameter called
+ "use_defaults". The output goes to stdout by default.
+ </p>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__2013"></a>
+ <h2>
+ <a href="#toc_i__2013">9 References</a>
+ </h2>
+ <DIV>
+ <dl>
+ <dt>
+ <a name="ref-xslt"></a>[XSLT]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/1999/REC-xslt-19991116">
+ XSL Transformations (XSLT) Version 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-xpath"></a>[XPath]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/1999/REC-xpath-19991116">
+ XML Path Language (XPath) Version 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-xml"></a>[XML]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/1998/REC-xml-19980210">
+ Extensible Markup Language (XML) 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-dom"></a>[DOM]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1">
+ Document Object Model Level 1 Specification, Version 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-rcover"></a>[Cover]</dt>
+ <dd>
+ <a href="http://www.oasis-open.org/cover/sgml-xml.html">
+ The XML Cover Pages</a>
+ </dd>
+
+ <dt>
+ <a name="ref-xmlorg"></a>[XMLorg]</dt>
+ <dd>
+ <a href="http://xml.org">XML.org</a>
+ </dd>
+
+ <dt>
+ <a name="ref-xslinfo"></a>[XSLINFO]</dt>
+ <dd>
+ <a href="http://www.xslinfo.com">XSLINFO.com</a>
+ </dd>
+
+ <dt>
+ <a name="ref-bible"></a>[XMLBible14]</dt>
+ <dd>
+ <a href="http://metalab.unc.edu/xml/books/bible/updates/14.html">
+ Harold, E. R.: XML Bible, Chapter 14 (online presentation)
+ </a>
+ </dd>
+ </dl>
+ </DIV>
+ </DIV>
+ <hr>
+ <p STYLE="font-style: italic; margin-left: 0">(c) 2000 Ginger Alliance s.r.o.</p>
+ </body>
+</html><html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <META http-equiv="Content-Type" CONTENT="text/html" CHARSET="UTF-8">
+ <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
+ <STYLE TYPE="text/css" MEDIA="screen">
+ BODY, H2, H3, H4, P, UL, OL, DL
+ {
+ font-family: "Verdana", "Helvetica", "Arial", "sans-serif"
+ }
+
+ H1 {color: #0058a0; font-size: 20pt}
+ H2 {color: #0058a0; font-size: 16pt}
+ H3 {color: #0058a0; font-size: 14pt}
+ H4 {color: #0058a0; font-size: 12pt}
+
+ A:link, A:active, A:visited
+ {
+ color: #0058a0;
+ text-decoration: none
+ }
+
+ P, UL, OL, DL {margin-left: 10%; margin-right: 10%; font-size: 10pt}
+ DT {margin-bottom: 0.5em}
+ .offset {margin-left: 10%}
+ .afterskip {margin-bottom: 1em}
+ .afterhalf {margin-bottom: 0.5em}
+ .example {margin-left: 10%; margin-right: 10%;
+ border-color: #0058a0; border-style:solid; border-width: 1pt; padding: 1pt}
+ CODE {font-family: "Courier"}
+ .comment {color: #0000ff}
+
+ P.offset {margin-left: 15%}
+ P.inner {margin-left: 2%; width: 96%}
+ P.note {margin-left: 10%; border-color: #0058a0;
+ border-style:solid; border-width: 1pt;
+ padding: 5pt; background-color:#e0e0e0 }
+
+ PRE {font-size: 10pt; padding: 5pt}
+
+ </STYLE>
+ <title>GAdoc - Sablotron 0.60</title>
+ </head>
+ <body bgcolor="#ffffff">
+ <h1 CLASS="afterskip">Sablotron 0.60</h1>
+ <DIV CLASS="afterskip">
+ <p>
+ <b>
+ <i>Tom Kaiser (Ginger Alliance)</i>
+ </b>
+ </p>
+ <p>
+ <i>June 17, 2001</i>
+ </p>
+ </DIV>
+ <h3>Abstract</h3>
+ <DIV CLASS="offset">This is a description of the current version of the
+ XSLT processor called Sablotron, including an overview of its
+ limitations as compared to the XSLT specification.
+ </DIV>
+ <h3>Contents</h3>
+<DIV STYLE="margin-left: 10%; margin-bottom: 2em; font-size: smaller">
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__25"></a> <a href="#i__25">
+ <b>1 This text</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__60"></a> <a href="#i__60">
+ <b>2 Changes from the last release</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__74"></a> <a href="#i__74">
+ <b>3 Introduction</b>
+ </a>
+ <DIV class="offset"> <a href="#i__81">3.1 XSLT</a>
+ <BR> <a href="#i__154">3.2 On Sablotron</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__227"></a> <a href="#i__227">
+ <b>4 The sources</b>
+ </a>
+ <DIV class="offset"> <a href="#i__238">4.1 Getting the sources</a>
+ <BR> <a href="#i__280">4.2 Joining the development</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__305"></a> <a href="#i__305">
+ <b>5 Implementation. Supported instructions and functions</b>
+ </a>
+ <DIV class="offset"> <a href="#i__343">5.1 Templates</a>
+ <BR> <a href="#i__364">5.2 Conditional processing</a>
+ <BR> <a href="#i__381">5.3 Loops</a>
+ <BR> <a href="#i__398">5.4 Variables and parameters</a>
+ <BR> <a href="#i__415">5.5 Element creation</a>
+ <BR> <a href="#i__439">5.6 Global definitions</a>
+ <BR> <a href="#i__476">5.7 Values and copying</a>
+ <BR> <a href="#i__508">5.8 Namespace processing</a>
+ <BR> <a href="#i__529">5.9 Sorting</a>
+ <BR> <a href="#i__577">5.10 Whitespace stripping</a>
+ <BR> <a href="#i__598">5.11 Includes</a>
+ <BR> <a href="#i__623">5.12 Other unimplemented instructions</a>
+ <BR> <a href="#i__654">5.13 Output conformance</a>
+ <BR> <a href="#i__686">5.14 XPath expressions</a>
+ <BR> <a href="#i__714">5.15 Built-in functions</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__804"></a> <a href="#i__804">
+ <b>6 Other implementation-related notes</b>
+ </a>
+ <DIV class="offset"> <a href="#i__811">6.1 Handlers</a>
+ <BR> <a href="#i__859">6.2 Encodings</a>
+ <BR> <a href="#i__887">6.3 Output methods</a>
+ <BR> <a href="#i__915">6.4 URIs</a>
+ <BR> <a href="#i__983">6.5 Named buffers</a>
+ <BR> <a href="#i__1015">6.6 Error and log messages</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__1048"></a> <a href="#i__1048">
+ <b>7 The C interface</b>
+ </a>
+ <DIV class="offset"> <a href="#i__1065">7.1 Shortcuts</a>
+ <BR> <a href="#i__1205">7.2 Basic functions</a>
+ <BR> <a href="#i__1416">7.3 Generalized interface functions</a>
+ <BR> <a href="#i__1578">7.4 The situation object</a>
+ <BR> <a href="#i__1631">7.5 Document Object Model (DOM) functions</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__1870"></a> <a href="#i__1870">
+ <b>8 The command line interface</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__2013"></a> <a href="#i__2013">
+ <b>9 References</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__25"></a>
+ <h2>
+ <a href="#toc_i__25">1 This text</a>
+ </h2>
+ <DIV>
+ <p CLASS="">The HTML form of this description
+ was compiled by Sablotron from the XML source
+ Sablot-0-60.xml.
+ </p>
+ <p CLASS="">
+ The material in the following sections includes:
+ </p>
+ <ul>
+ <li>some background information on XSLT and Sablotron,</li>
+ <li>a detailed comparison of the current version of
+ Sablotron to the XSLT spec,</li>
+ <li>Sablotron usage from the command line or as a
+ library.</li>
+ </ul>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__60"></a>
+ <h2>
+ <a href="#toc_i__60">2 Changes from the last release</a>
+ </h2>
+ <DIV>
+ <p CLASS="">Please see the RELEASE file.</p>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__74"></a>
+ <h2>
+ <a href="#toc_i__74">3 Introduction</a>
+ </h2>
+ <DIV>
+ <DIV class="afterskip">
+ <a name="i__81"></a>
+ <h3>
+ <a href="#toc_i__74">3.1 XSLT</a>
+ </h3>
+ <p CLASS="">XSLT is a language allowing to transform given XML data (the
+ <i>input</i>) according to a <i>stylesheet</i>. XSLT stylesheets
+ are themselves XML documents; that is, all instructions of the
+ language are expressed in the form of XML elements. The
+ <i>output</i>, i.e. the result of the processing, is typically a
+ XML document as well, although the syntactic requirements can be
+ relaxed to allow the creation of a HTML document (one that
+ contains unclosed tags and the like), or even plain text.
+ </p>
+ <p CLASS="">XSLT was designed by the World Wide Web Consortium (W3C) as
+ a part of the XSL stylesheet language, where it is complemented
+ by a powerful set of formatting instructions. The most precise
+ information about XSLT can be found in the W3C Recommendation <a href="#ref-xslt">[XSLT]</a>. In particular, Appendix B of the
+ Recommendation contains a handy syntax table. A good tutorial is
+ <a href="#ref-bible">[XMLBible14]</a>.
+ </p>
+ <p CLASS="">Other W3C Recommendations one often needs to consult are <a href="#ref-xml">[XML]</a> (for the definition of the XML
+ language) and <a href="#ref-xpath">[XPath]</a> (for details on
+ XPath, the language used to form expressions in XSLT and
+ elsewhere).
+ </p>
+ <p CLASS="">An excellent source of information about XSLT (indeed, about
+ anything related to XML and SGML) is <a href="#ref-rcover">[Cover]</a>; see also <a href="#ref-xslinfo">[XSLINFO]</a> and <a href="#ref-xmlorg">[XMLorg]</a>.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__154"></a>
+ <h3>
+ <a href="#toc_i__74">3.2 On Sablotron</a>
+ </h3>
+ <p CLASS="">Sablotron is a XSLT processor (though not quite conforming
+ yet..., see below) written in C++. Since the machines where it
+ is meant to run include various small mobile
+ clients, the main objectives of its design are the following:
+ </p>
+ <ul>
+ <li>portability,</li>
+ <li>compact code,</li>
+ <li>as much independence on other resources (Java etc.) as
+ possible.</li>
+ </ul>
+ <p CLASS="">Sablotron is a single shared library
+ (<code>sablot.dll</code> or <code>libsablot.so.0.60</code>). It can
+ also be used from the command line via the simple interface
+ called <code>sabcmd</code>. See <a href="#invocation">here</a> for
+ more information.
+ </p>
+ <p CLASS="">The only software Sablotron relies on is <b>expat</b>, the
+ XML parser by James Clark. See <a href="#expat">below</a> for
+ information on how to get expat.
+ </p>
+ <p CLASS="">For information on the available interfaces, e.g. for
+ Python, Perl and PHP, see <a href="http://www.gingerall.com">www.gingerall.com</a>.
+ </p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__227"></a>
+ <h2>
+ <a href="#toc_i__227">4 The sources</a>
+ </h2>
+ <DIV>
+ <p CLASS="">
+ Sablotron is written in C++. The source files compile under
+ Win32 (using MS Visual C++ 6.0) and on Solaris and Linux (using
+ g++ 2.95.2) without change.</p>
+ <DIV class="afterskip">
+ <a name="i__238"></a>
+ <h3>
+ <a href="#toc_i__227">4.1 Getting the sources</a>
+ </h3>
+ <p CLASS="">The source or binary distributions of Sablotron can be downloaded
+ from <a href="http://www.gingerall.com">www.gingerall.com</a>. For
+ instructions on how to build the sources (if any), refer to the accompanying INSTALL file.
+ </p>
+ <p CLASS="">If you have access to the Ginger Alliance CVS server, you
+ can get the working version of Sablotron in the CVS module
+ <code>ga</code>. The access rights can be obtained on
+ request from <a href="mailto:cvsadmin at gingerall.com">the CVS admin</a>.
+ </p>
+ <p CLASS="">
+ <a name="expat"></a>
+ Since version 0.50, Sablotron uses expat 1.95.1, available from <a href="http://expat.sourceforge.org">SourceForge</a>.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__280"></a>
+ <h3>
+ <a href="#toc_i__227">4.2 Joining the development</a>
+ </h3>
+ <p CLASS="">
+ Sablotron is an open source project and all volunteers are most
+ welcome! The documentation of the sources is still somewhat
+ sparse but we will try to improve it. If you find the invitation
+ to work on Sablotron with us interesting, please <a href="mailto:sablotron at gingerall.com">contact us</a>. There is also
+ a mailing list available, see <a href="http://www.gingerall.com">www.gingerall.com</a>.
+ </p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__305"></a>
+ <h2>
+ <a href="#toc_i__305">5 Implementation. Supported instructions and functions</a>
+ </h2>
+ <DIV>
+ <p CLASS="">The instruction set supported by this version of Sablotron is
+ already sufficient for many transformation tasks (e.g. the task of
+ formatting this document). On the other
+ hand, a comparison of it to the XSLT specification <a href="#ref-xslt">[XSLT]</a> shows that much is still to be
+ done. The purpose of the
+ following sections is to describe the varying degree of support
+ for the elements of the XSLT language. </p>
+ <p CLASS="">It may be helpful to refer to the syntax table in Appendix B
+ of <a href="#ref-xslt">[XSLT]</a>. The instructions/attributes that
+ are not listed as unsupported should be implemented. The <a href="mailto:sablotron at gingerall.com">authors</a> will appreciate being
+ told about any omissions found in the following
+ description.</p>
+ <p CLASS="">For readability, I sometimes omit the <code>xsl:</code> prefix
+ from the instruction names.</p>
+ <DIV class="afterskip">
+ <a name="i__343"></a>
+ <h3>
+ <a href="#toc_i__305">5.1 Templates</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ template, apply-templates, call-template
+ </code>
+ </p>
+ <p CLASS="">
+ Fully implemented. <code>xsl:sort</code> is supported since release 0.50.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__364"></a>
+ <h3>
+ <a href="#toc_i__305">5.2 Conditional processing</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ if, choose, when, otherwise
+ </code>
+ </p>
+ <p CLASS="">Fully implemented.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__381"></a>
+ <h3>
+ <a href="#toc_i__305">5.3 Loops</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>for-each</code>
+ </p>
+ <p CLASS="">Fully implemented.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__398"></a>
+ <h3>
+ <a href="#toc_i__305">5.4 Variables and parameters</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>variable, param, with-param</code>
+ </p>
+ <p CLASS="">Fully implemented. Top-level variables and parameters are
+ read in the document order, so no forward references are
+ resolved. This is a minor deviation from the spec. </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__415"></a>
+ <h3>
+ <a href="#toc_i__305">5.5 Element creation</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>element, attribute, text,
+ comment, processing-instruction, attribute-set</code>
+ </p>
+ <p CLASS="">
+ <code>xsl:attribute-set</code> is not implemented. For the
+ rest, <code>name</code> is the only recognized attribute (where
+ applicable). Literal result elements work.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__439"></a>
+ <h3>
+ <a href="#toc_i__305">5.6 Global definitions</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>stylesheet, transform, output</code>
+ </p>
+ <p CLASS="">For <code>stylesheet</code> and <code>transform</code>,
+ the only recognized attribute is
+ <code>version</code>. <code>xsl:output</code> should work
+ (see below for notes on the <code>encoding</code>
+ attribute). HTML indentation has been added in 0.60.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__476"></a>
+ <h3>
+ <a href="#toc_i__305">5.7 Values and copying</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>value-of, copy, copy-of</code>
+ </p>
+ <p CLASS="">
+ <code>copy-of</code> and <code>value-of</code> are fully
+ implemented. <code>copy</code> is implemented except for the
+ <code>use-attribute-sets</code> attribute.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__508"></a>
+ <h3>
+ <a href="#toc_i__305">5.8 Namespace processing</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>namespace-alias</code>
+ </p>
+ <p CLASS="">Namespaces should be processed correctly. The
+ <code>namespace-alias</code> instruction is now supported
+ (patch by Major).</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__529"></a>
+ <h3>
+ <a href="#toc_i__305">5.9 Sorting</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>sort</code>
+ </p>
+ <p CLASS="">
+ <code>xsl:sort</code> is implemented since 0.50. There are
+ minor limitations:
+ </p>
+ <ul>
+ <li>currently, the <code>lang</code> attribute may only
+ contain the values <code>"en"</code> or <code>"cz"</code>.</li>
+ <li>
+ <code>case-order</code> cannot be specified.</li>
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__577"></a>
+ <h3>
+ <a href="#toc_i__305">5.10 Whitespace stripping</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>strip-space, preserve-space</code>
+ </p>
+ <p CLASS="">Only the default whitespace stripping is done. That is,
+ all whitespace-only text nodes in any stylesheet, not appearing
+ inside a <code>xsl:text</code>, are removed. The two
+ instructions for whitespace stripping and preservation are
+ unsupported.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__598"></a>
+ <h3>
+ <a href="#toc_i__305">5.11 Includes</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>include, import, apply-imports</code>
+ </p>
+ <p CLASS="">Only <code>xsl:include</code> is implemented. Processing
+ involving multiple documents works, but has to get more testing,
+ eg. with respect to <code>generate-id()</code>.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__623"></a>
+ <h3>
+ <a href="#toc_i__305">5.12 Other unimplemented instructions</a>
+ </h3>
+ <ul>
+ <li>
+ <code>xsl:key,</code>
+ </li>
+ <li>
+ <code>xsl:number,</code>
+ </li>
+ <li>
+ <code>xsl:fallback.</code>
+ </li>
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__654"></a>
+ <h3>
+ <a href="#toc_i__305">5.13 Output conformance</a>
+ </h3>
+ <p CLASS="">The output mechanism is much closer to the spec than in
+ the versions prior to 0.4. The following issues remain for the
+ html method:</p>
+ <ul>
+ <li>Output the boolean attributes correctly.</li>
+ <li>Disable the escaping inside
+ <code><SCRIPT></code> and
+ <code><STYLE></code>
+ </li>.
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__686"></a>
+ <h3>
+ <a href="#toc_i__305">5.14 XPath expressions</a>
+ </h3>
+ <p CLASS="">Almost all features of XPath are fully implemented. This means
+ there should be no problems with expressions of any kind.</p>
+ <p CLASS="">One exception relates to axes. The <code>following</code> and
+ <code>preceding</code> axes haven't been implemented yet.</p>
+ <p CLASS="">Another possible exception may be numbers; we did not yet do a
+ thorough test of rounding, NaNs, infinity, etc.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__714"></a>
+ <h3>
+ <a href="#toc_i__305">5.15 Built-in functions</a>
+ </h3>
+ <p CLASS="">
+ <a name="corelib"></a>Only a few functions from the standard
+ function library remain
+ unimplemented:
+ </p>
+ <ul>
+ <li>
+ <code>id()</code>,</li>
+ <li>
+ <code>lang()</code> (accepted but always returns true),</li>
+ <li>
+ <code>key()</code>,</li>
+ <li>
+ <code>format-number()</code>,</li>
+ <li>
+ <code>unparsed-entity-uri()</code>.</li>
+ </ul>
+ <p CLASS="">As for the fuctions that <i>are</i> implemented, the
+ following is a list of differences from the spec:
+ </p>
+ <ul>
+ <li>
+ <code>document()</code> only accepts one argument, always
+ getting the base URI from the stylesheet URI.
+ </li>
+ <li>
+ <code>string-length()</code> returns the byte length of
+ the UTF-8 representation of the string. This will typically
+ differ from the actual length.
+ </li>
+ <li>
+ <code>generate-id()</code> might fail to generate unique identifiers
+ when several input documents are present (giving the same id to
+ nodes from different documents).
+ </li>
+ </ul>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__804"></a>
+ <h2>
+ <a href="#toc_i__804">6 Other implementation-related notes</a>
+ </h2>
+ <DIV>
+ <DIV class="afterskip">
+ <a name="i__811"></a>
+ <h3>
+ <a href="#toc_i__804">6.1 Handlers</a>
+ </h3>
+ <p CLASS="">It is possible for the user to supply the following
+ handlers to Sablotron:
+ <ul>
+ <li>message handler (to bypass the default way of displaying
+ error and warning messages and logging),</li>
+ <li>scheme handler (to retrieve documents whose URI use an
+ unsupported scheme),</li>
+ <li>streaming handler (an expat-like interface to the XML
+ document which is the result of the processing),</li>
+ <li>'miscellaneous' handler (which will probably server as a
+ collections of odd callbacks).</li>
+ </ul>
+ </p>
+ <p CLASS="">
+ The handlers are set using <code>SablotRegHandler()</code>
+ For details concerning the interface of these handlers,
+ consult the header files <code>sablot.h</code> and
+ <code>shandler.h</code>.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__859"></a>
+ <h3>
+ <a href="#toc_i__804">6.2 Encodings</a>
+ </h3>
+ <p CLASS="">
+ In version 0.52, the encoding conversion capabilities of
+ Sablotron have been much extended. The most important fact is the
+ following: if you have the iconv library installed on your system, you
+ can use any encoding it supports (that is, almost any encoding
+ whatsoever) for both the input and the output documents. Iconv
+ is available on most systems (it is a standard part of glibc2,
+ for instance). There are implementations for Win32 as well.
+ </p>
+ <p CLASS="">If iconv is not available, the encoding may still be supported internally by
+ Sablotron. At present, the list is of such encodings is rather
+ short: besides UTF-8, these are UTF-16, ASCII, iso-8859-1,
+ iso-8859-2 and windows-1250 on input, none on output. However,
+ we plan to implement a half independent light-weight
+ conversion library for use on systems without iconv,
+ extending the set of internally supported encodings
+ considerably.
+ </p>
+ <p CLASS="">Lastly, the user has the option to implement a custom
+ encoding conversion handler, which will be asked to perform any unsupported
+ conversion. See the <code>shandler.h</code> header file for
+ details.
+ </p>
+ <p CLASS="">The default input and output encoding is in all cases UTF-8.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__887"></a>
+ <h3>
+ <a href="#toc_i__804">6.3 Output methods</a>
+ </h3>
+ <p CLASS="">In addition to the standard output methods (xml, html and
+ text), it is possible to output xhtml. Documents output using
+ this method obey the XHTML 1.0 rules (in particular, all empty
+ elements are closed). To choose the method, use
+ <code><xsl:output method='xhtml'></code>. <b>Please note</b>
+ that the name of this method will possibly be changed since the XSLT
+ spec requires any processor-specific methods to have qualified
+ names, say <code>sab:xhtml</code>. On the other hand, the name
+ <code>xhtml</code> is considered in the XSLT 2.0 working draft.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__915"></a>
+ <h3>
+ <a href="#toc_i__804">6.4 URIs</a>
+ </h3>
+ <p CLASS="">Sablotron can handle
+ two URI schemes natively: 'file' and 'arg' (see
+ below). Moreover, it is possible to use the function
+ <code>SablotRegSchemeHandler</code> to register an external scheme
+ handler which will receive requests in all other schemes. See
+ the documentation in <code>sablot.h</code> and
+ <code>shandler.h</code>.
+ </p>
+ <p CLASS="">Relative URI references are resolved in conformance to RFC
+ 2396. The base URI is well defined when the relative reference appears
+ inside a XML document; when invoking sabcmd, the base URI is
+ taken to correspond to the current working directory.
+ </p>
+ <p CLASS="">
+ <a name="fname-rules"></a>When specifying filenames, the
+ following rules are in effect:
+ </p>
+ <ul>
+ <li>specify the "file:" scheme for any standard files,
+ i.e. refer to <code>stdin</code> as <code>file://stdin</code>
+ etc.</li>
+ <li>slashes and backslashes work equally fine, in Windows as
+ well as Linux.</li>
+ <li>to include a drive letter under Windows
+ (e.g. <code>C:\doc.xml</code>), it is necessary to say
+ <code>file://c:/doc.xml</code>.
+ </li>
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__983"></a>
+ <h3>
+ <a href="#toc_i__804">6.5 Named buffers</a>
+ </h3>
+ <p CLASS="">
+ <a name="argscheme"></a>Sablotron introduces an URI scheme
+ 'arg:' which enables one to use strings in named memory
+ buffers. The buffer names can have a tree-like structure so that
+ a relative reference from a document in a buffer can be resolved
+ as pointing to another buffer.
+ </p>
+ <p CLASS="">For instance, if we invoke Sablotron specifying that a
+ buffer named <code>/mybuf/1</code> contains the string
+ "<a>contents</a>", then the expression
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ document('arg:/mybuf/1')/a
+ </code>
+ </p>
+ <p CLASS="">has string-value "contents". If the document in arg:/mybuf/1
+ contained a relative URI reference "../theirbuf/2" then this
+ would be resolved as pointing to "arg:/theirbuf/2".</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1015"></a>
+ <h3>
+ <a href="#toc_i__804">6.6 Error and log messages</a>
+ </h3>
+ <p CLASS="">By default, Sablotron writes error and warning messages to
+ stderr, and does no logging. By a call to
+ <code>SablotSetLog()</code>, you can specify the name of the log
+ file to be used.</p>
+ <p CLASS="">Besides, you can use <code>SablotRegHandler()</code>
+ to override the default message handling. The handler you
+ register will receive all messages in a structured form that's
+ easy to process and filter. For details, see
+ the documentation in <code>sablot.h</code> and
+ <code>shandler.h</code>.</p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1048"></a>
+ <h2>
+ <a href="#toc_i__1048">7 The C interface</a>
+ </h2>
+ <DIV>
+ <p CLASS="">
+ <a name="invocation"></a>
+ </p>
+ <p CLASS="">
+ This section describes the functions exported from the
+ Sablotron library. All of them have a return type of 'int'
+ and return an error flag (nonzero signals an error). Errors
+ are reported to the user by Sablotron itself.
+ </p>
+ <DIV class="afterskip">
+ <a name="i__1065"></a>
+ <h3>
+ <a href="#toc_i__1048">7.1 Shortcuts</a>
+ </h3>
+ <p CLASS="">
+ We'll first describe the 'shortcuts' that do the whole
+ processing in one call.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotProcess(char *sheetURI, char *inputURI, char *resultURI,
+ char **params, char **arguments, char **resultArg);
+ </code>
+ </p>
+ <p CLASS="">
+ This is the basic function. The first three of its arguments
+ are the URIs of the XSLT stylesheet, the XML source and the
+ resulting document, respectively. For some notes on specifying
+ file names, see <a href="#fname-rules">above</a>.
+ </p>
+ <p CLASS="">
+ <code>params</code> is an array of pointers to the names
+ and contents of the top-level stylesheet parameters. Thus,
+ <code>params[0]</code> is a pointer to the null-terminated name
+ of the first parameter, <code>params[1]</code> points to the
+ (null-terminated) contents of the first parameter. The following
+ two array items do the same for the second parameter, etc. The
+ whole array is terminated by a NULL pointer in place of the
+ name. If no parameters are to be passed, you can specify NULL
+ for <code>params</code> itself.
+ </p>
+ <p CLASS="">
+ <code>arguments</code> is a similar array of named buffers
+ to be passed to the stylesheet. (They can be referred to via the
+ 'arg:' scheme, see <a href="#argscheme">above</a>.) Again, the
+ array is a sequence of (name, value) pairs terminated by NULL in
+ place of a name. If no named buffers are to be passed, you can
+ specify NULL for <code>arguments</code> itself.
+ </p>
+ <p CLASS="">
+ <code>resultArg</code> enables one to access the
+ resulting document in case the output went to a named buffer. In
+ that situation, <code>*resultArg</code> points to the resulting
+ null-terminated string, allocated by Sablotron. You can pass NULL
+ for <code>resultArg</code> if the output is sure to go to a
+ file.
+ </p>
+ <p CLASS="">
+ <b>Note:</b>When you are done processing the string
+ pointed to by <code>*resultArg</code>, free it using <a href="#sablotfree">
+ <code>SablotFree()</code>
+ </a> - never use
+ <code>free()</code>. The latter is guaranteed to produce a
+ segmentation fault under Linux.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotProcessFiles(char *styleSheetName,
+ char *inputName,
+ char *resultName);
+ </code>
+ </p>
+ <p CLASS="">A wrapper for <code>SablotProcess()</code> working on
+ files. The parameters are the null-terminated file names of the
+ XSLT stylesheet, the XML input and the result,
+ respectively. Sablotron opens these files itself and closes them
+ after the processing is complete. Values like "file://stdin" are
+ allowed.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotProcessStrings(char *styleSheetStr, char *inputStr, char
+ **resultStr);
+ </code>
+ </p>
+ <p CLASS="">Another wrapper for <code>SablotProcess()</code>, this
+ time for accessing named buffers (i.e. user-allocated memory
+ blocks)only. Thus, the first parameter is a null-terminated
+ string containing the whole stylesheet; the second parameter
+ is a null-terminated string containing the XML
+ input. Sablotron allocates the buffer for the resulting string
+ and returns a pointer to it in resultStr. Hence, invoking
+ <code>puts(*resultStr)</code> after having called
+ <code>SablotProcessStrings</code> sends the result to
+ stdout. The buffer allocated <b>must</b> be freed by calling the
+ function <code>SablotFree</code> described next.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1205"></a>
+ <h3>
+ <a href="#toc_i__1048">7.2 Basic functions</a>
+ </h3>
+ <p CLASS="">The above shortcuts just call the basic, lower-level
+ functions described below. Note that if you need to set options
+ for logging etc., you may need to use the low-level
+ functions. </p>
+ <p CLASS="">A typical processing session may look like this:</p>
+ <p CLASS="">
+ <pre>
+ SablotHandle p;
+ char *my_buf;
+ SablotCreateProcessor(&p);
+ SablotSetLog(p, ...);
+ /* ...set other instance-specific options here... */
+ SablotRunProcessor(p, ...);
+ SablotGetResultArg(p, "arg:/somename", &my_buf)
+ /* ...do something with my_buf... */
+ /* can run the processor again if necessary */
+ SablotRunProcessor(p, ...);
+ SablotDestroyProcessor(p);
+ </pre>
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotCreateProcessor(SablotHandle *processorPtr);
+ </code>
+ </p>
+ <p CLASS="">Creates an instance of Sablotron and returns a pointer to
+ it in *processorPtr. This pointer is passed on all subsequent
+ calls to this instance. </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotDestroyProcessor(SablotHandle processor_);
+ </code>
+ </p>
+ <p CLASS="">Destroys an instance of the processor, deallocating all
+ the memory used up by it.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotRunProcessor(SablotHandle processor_,
+ char *sheetURI,
+ char *inputURI,
+ char *resultURI,
+ char **params,
+ char **arguments);
+ </code>
+ </p>
+ <p CLASS="">Processes documents using the given processor instance and
+ given params and args definitions. See
+ <code>SablotProcess()</code>.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotGetResultArg(SablotHandle processor_,
+ char *argURI,
+ char **argValue);
+ </code>
+ </p>
+ <p CLASS="">Copies the result 'arg' buffer with the given URI,
+ returning a pointer to the newly-allocated block in
+ *argValue. If no such buffer exists, returns NULL in *argValue.
+ </p>
+ <p CLASS="">This function is necessary, because if the result document
+ is output to memory, it would be lost when
+ <code>SablotDestroyProcessor()</code> is called. When
+ deallocating the copy obtained from
+ <code>SablotGetResultArg()</code>, use <code>SablotFree</code>
+ (never <code>free()</code>). </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotFreeResultArgs(SablotHandle processor_);
+ </code>
+ </p>
+ <p CLASS="">Removes the Sablotron-internal copies of the 'arg' buffers
+ from the last Sablotron run. Normally, there should be no reason
+ to call this function as it is called automatically on both
+ <code>SablotRunProcessor()</code> and
+ <code>SablotDestroyProcessor()</code>. </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ <a name="sablotfree"></a>
+ int SablotFree(char *resultBuf);
+ </code>
+ </p>
+ <p CLASS="">This function frees the buffer allocated on previous call
+ to <code>SablotProcessStrings</code>. Calling it with an
+ invalid pointer will cause a crash.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotRegHandler(
+ SablotHandle processor_,
+ HandlerType type,
+ void *handler,
+ void *userData);
+ </code>
+ </p>
+ <p CLASS="">Registers an external handler. <code>type</code> can be
+ <code>HLR_MESSAGE</code>, <code>HLR_SCHEME</code>,
+ <code>HLR_SAX</code>, <code>HLR_MISC</code> or
+ <code>HLR_ENC</code>.
+ <code>handler</code> points to the
+ callback vector of the appropriate type. <code>userData</code>
+ is a data item to passed to all callbacks of this particular
+ handler. For details, check the <code>sablot.h</code> and
+ <code>shandler.h</code> header files.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotUnregHandler(
+ SablotHandle processor_,
+ HandlerType type,
+ void *handler,
+ void *userData);
+ </code>
+ </p>
+ <p CLASS="">Unregisters the given external handler. For details, check the
+ <code>sablot.h</code> and <code>shandler.h</code> header
+ files.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotSetLog(
+ SablotHandle processor_,
+ const char *logFilename,
+ int logLevel);
+ </code>
+ </p>
+ <p CLASS="">Sets the log filename. The <code>logLevel</code> parameter
+ is currently not used. Pass NULL for <code>logFilename</code> to
+ turn logging off (default). </p>
+ <p CLASS="">The other functions published by sablot.h have been
+ included for experimental reasons or for compatibility, and it
+ is better not to use them.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotClearError(SablotHandle processor_);
+ </code>
+ </p>
+ <p CLASS="">Clears the 'pending error' flag for this instance of
+ Sablotron.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1416"></a>
+ <h3>
+ <a href="#toc_i__1048">7.3 Generalized interface functions</a>
+ </h3>
+ <p CLASS="">The implementation of the <a href="#dom">DOM interface</a>
+ brought the need to extend some of the functions described in
+ the previous section. This extension enables the user to:
+ </p>
+ <ul>
+ <li>process documents created by the DOM functions, and</li>
+ <li>process frequently used documents in pre-parsed form.</li>
+ </ul>
+ <p CLASS="">An object called <i>situation</i> is used to provide a
+persistent context for all calls to the DOM-related
+functions. Functions used to manipulate the situation are described in
+<a href="#situation">the following section</a>.</p>
+ <p CLASS="">
+ <b>Note:</b> If not specified otherwise, all these
+ functions return an error code. A positive value indicates an error.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotCreateDocument(SablotSituation S,
+ SDOM_Document *D);
+ </code>
+ </p>
+ <p CLASS="">Creates an empty document. Typically followed by calls to
+ DOM functions to populate the document.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotDestroyDocument(SablotSituation S,
+ SDOM_Document D);
+ </code>
+ </p>
+ <p CLASS="">Destroys a document, freeing all the nodes it has created.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotParse(SablotSituation S,
+ const char *uri, SDOM_Document *D);
+ </code>
+ </p>
+ <p CLASS="">Reads in a document from the given URI.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotParseBuffer(SablotSituation S,
+ const char *buffer, SDOM_Document *D);
+ </code>
+ </p>
+ <p CLASS="">Reads in a document from the given in-memory buffer.</p>
+ <p CLASS="">These functions have variants to be used if the document
+ is to be interpreted as an XSLT stylesheet, namely
+ <code>SablotParseStylesheet</code> and
+ <code>SablotParseStylesheetBuffer</code>.</p>
+ <p CLASS="">The following functions generalize
+ <code>SablotRunProcessor</code> in that they make it possible to
+ utilize an extra kind of a source document: a DOM tree.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotRunProcessorGen(SablotSituation S,
+ void *processor_,
+ char *sheetURI,
+ char *inputURI,
+ char *resultURI);
+ </code>
+ </p>
+ <p CLASS="">A key ingredient of the extended interface. Only the URIs
+ of the sources and of the result document are given to it. The
+ rest of the information passed to
+ <code>SablotRunProcessor</code> is conveyed through
+ <code>SablotAddArgBuffer,</code> <code>SablotAddArgTree</code>
+ and <code>SablotAddParam.</code> The scheme part of the
+ stylesheet URI or the input URI may be "arg:", in which
+ case they refer to a buffer or tree passed by these
+ functions. </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotAddArgBuffer(SablotSituation S,
+ void *processor_,
+ const char *argName,
+ const char *bufferValue);
+</code>
+ </p>
+ <p CLASS="">Creates a named buffer for the next processor run. The
+ buffer's name and contents are passed as arguments. The name
+ is interpreted relative to the 'arg:/' scheme.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotAddArgTree(SablotSituation S,
+ void *processor_,
+ const char *argName,
+ SDOM_Document tree);
+</code>
+ </p>
+ <p CLASS="">Associates the given document with a name for the next
+ processor run. The document is <i>not</i> destroyed after the
+ run is finished. The name is interpreted relative to the 'arg:/'
+ scheme.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotAddParam(SablotSituation S,
+ void *processor_,
+ const char *paramName,
+ const char *paramValue);
+ </code>
+ </p>
+ <p CLASS="">Adds a global stylesheet parameter for the next processor
+ run.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1578"></a>
+ <h3>
+ <a href="#toc_i__1048">7.4 The situation object</a>
+ </h3>
+ <p CLASS="">
+ <a name="situation"></a>At present, the situation object primarily holds information on any pending errors. A
+situation is created using</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotCreateSituation(SablotSituation
+ *SP);</code>
+ </p>
+ <p CLASS="">and destroyed by</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotDestroySituation(SablotSituation
+ S);</code>
+ </p>
+ <p CLASS="">To clear the pending error flag in a situation, use</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotClearSituation(SablotSituation
+ S);</code>
+ </p>
+ <p CLASS="">The following self-explanatory functions extract parts of the error information
+ from the situation:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ const char *SablotGetErrorURI(SablotSituation S);<br>
+ int SablotGetErrorLine(SablotSituation S);<br>
+ const char *SablotGetErrorMsg(SablotSituation S);
+ </code>
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1631"></a>
+ <h3>
+ <a href="#toc_i__1048">7.5 Document Object Model (DOM) functions</a>
+ </h3>
+ <p CLASS="">
+ <a name="dom"></a>Starting with version 0.60, Sablotron implements
+ a major subset of the DOM Level 1 Core Specification <a href="#ref-dom">[DOM]</a>. A brief
+ description of the implemented interface follows; for more
+ details, please refer to the header file named
+ <code>sdom.h.</code>
+ </p>
+ <p CLASS="">All of the names related to the DOM interface start with
+ SDOM_ (for Sablot DOM).</p>
+ <p CLASS="">Major new types are <code>SDOM_Document</code> (a DOM tree) and
+ <code>SDOM_Node</code> (a node of the tree). A document can also be used in
+ place of a node. This reflects the fact in the DOM spec,
+ Document is a subclass of Node. When used in this way, the
+ document represents its own root node (which is not the same as
+ the `root element').</p>
+ <p CLASS="">Other types include:</p>
+ <ul>
+ <li>
+ <code>SDOM_char:</code> a DOM character type. Currently, this is just
+ char. Note that the DOM spec requires that the DOM
+ implementations work with UTF-16. Sablotron deviates from this
+ by using UTF-8 instead. A separate set of functions taking
+ UTF-16 strings will be provided.</li>
+ <li>
+ <code>SDOM_NodeType:</code> a node type enum. Some of the values are
+ <code>SDOM_ELEMENT_NODE,</code> <code>SDOM_ATTRIBUTE_NODE</code> and <code>SDOM_TEXT_NODE.</code> See
+ <code>sdom.h</code> for the rest.</li>
+ <li>
+ <code>SDOM_NodeList:</code> a node list returned by some of the
+ functions.</li>
+ <li>
+ <code>SDOM_Exception:</code> DOM exception codes enum, with values such
+ as <code>SDOM_NOT_FOUND_ERR</code> or <code>SDOM_INVALID_NODE_TYPE</code>. See <code>sdom.h</code>
+ for details.</li>
+</ul>
+ <p CLASS="">The functions listed below are implemented more or less as defined in
+ the DOM Level 1 Specification, with two exceptions:
+ their names are prefixed with <code>SDOM_</code> and the first argument is
+ always a <code>SablotSituation.</code> All the functions return
+ a <code>SDOM_Exception.</code> </p>
+ <ul>
+<li>
+ <code>createElement, createAttribute, createTextNode,
+createCDATASection, createComment, createProcessingInstruction</code>
+ </li>
+<li>
+ <code>getNodeType, getNodeName, setNodeName, getNodeValue, setNodeValue</code>
+ </li>
+<li>
+ <code>getParentNode, getFirstChild, getLastChild, getPreviousSibling,
+getNextSibling, getOwnerDocument</code>
+ </li>
+<li>
+ <code>insertBefore, appendChild, removeChild, replaceChild</code>
+ </li>
+<li>
+ <code>cloneNode</code>
+ </li>
+<li>
+ <code>getAttribute, setAttribute, removeAttribute, getAttributeList</code>
+ </li>
+</ul>
+ <p CLASS="">Several functions have been added:</p>
+ <ul>
+<li>
+ <code>disposeNode</code> frees all memory used by the given node</li>
+<li>
+ <code>cloneForeignNode</code> clones a node from a different
+document</li>
+<li>
+ <code>docToString</code> serializes the document, returning the
+resulting string</li>
+<li>
+ <code>xql</code> performs an XPath query on the DOM tree,
+returning a list of the nodes satisfying it.</li>
+</ul>
+ <p CLASS="">In addition, there are some functions used to manipulate
+ the node lists returned by <code>xql</code> and
+ <code>getAttributeList</code>. These include
+ <code>getNodeListLength</code>, <code>getNodeListItem</code> and
+ <code>disposeNodeList</code>.</p>
+ <p CLASS="">Finally, there are functions to extract DOM
+ exception-related information from the situation object, namely
+ <code>getExceptionCode</code>, <code>getExceptionMessage</code>
+ and <code>getExceptionDetails</code>.</p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1870"></a>
+ <h2>
+ <a href="#toc_i__1870">8 The command line interface</a>
+ </h2>
+ <DIV>
+ <p CLASS="">Sablotron comes with a command-line interface to the
+ shared library, which is a program named
+ <code>sabcmd</code>. At present, <code>sabcmd</code> is invoked
+ as follows:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ sabcmd [<i>options</i>] <i>stylesheet</i> [<i>input</i> [<i>result</i>]] [<i>assignments</i>]
+ </code>
+ </p>
+ <p CLASS="">The arguments are the URIs of the XSLT stylesheet, the
+ XML input document, and the resulting document, respectively. The
+ default for <code>
+ <i>input</i>
+ </code> is
+ <code>file://stdin</code> (meaning plain old stdin);
+ <code>
+ <i>result</i>
+ </code> defaults to
+ <code>file://stdout</code>. Filenames have to include the extension (if
+ any).</p>
+ <p CLASS="">You can display the list of available options by typing
+ <code>sabcmd --help</code>. Among the more useful ones are
+ <code>--log-file</code> (for setting the log file) and
+ <code>--measure</code> (measures and outputs the total
+ processing time).
+ </p>
+ <p CLASS="">
+ <a href="#fname-rules">The rules for filenames</a> are the same as
+ with <code>SablotProcess()</code>.
+ </p>
+ <p CLASS="">
+ <code>assignments</code> is a series of definitions of the
+ form:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ name1=value1 name2=value2 ...
+ </code>
+ </p>
+ <p CLASS="">
+ assigning values to top-level stylesheet parameters and to named
+ buffers. These two cases are distinguished by a leading '$' in
+ the name of a stylesheet parameter. The names of the buffers do
+ <i>not</i> start with "arg:". They may start with a slash; if
+ they don't, the slash is prepended.
+ </p>
+ <p CLASS="">
+ <b>Note:</b> In most cases, it will be necessary to quote
+ the individual assignments. Whether to use single or double
+ quotes may depend on the shell used (or may it?) Single quotes
+ work for bash, double quotes work in Windows.
+ </p>
+ <p CLASS="">If the result URI refers to a named buffer, the output
+ would normally remain buried in memory. Sabcmd dumps the buffer to standard
+ output instead.
+ </p>
+ <p CLASS="">To sum up and give an example, the following would be a
+ valid invocation of sabcmd:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ sabcmd sheet.xsl arg:/the_input "the_input=<a/>"
+ "$use_defaults=1"
+ </code>
+ </p>
+ <p CLASS="">This processes the document passed in the buffer named
+ the_input, using a stylesheet found in file "sheet.xsl" in the
+ working directory. We assign 1 to the top-level parameter called
+ "use_defaults". The output goes to stdout by default.
+ </p>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__2013"></a>
+ <h2>
+ <a href="#toc_i__2013">9 References</a>
+ </h2>
+ <DIV>
+ <dl>
+ <dt>
+ <a name="ref-xslt"></a>[XSLT]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/1999/REC-xslt-19991116">
+ XSL Transformations (XSLT) Version 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-xpath"></a>[XPath]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/1999/REC-xpath-19991116">
+ XML Path Language (XPath) Version 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-xml"></a>[XML]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/1998/REC-xml-19980210">
+ Extensible Markup Language (XML) 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-dom"></a>[DOM]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1">
+ Document Object Model Level 1 Specification, Version 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-rcover"></a>[Cover]</dt>
+ <dd>
+ <a href="http://www.oasis-open.org/cover/sgml-xml.html">
+ The XML Cover Pages</a>
+ </dd>
+
+ <dt>
+ <a name="ref-xmlorg"></a>[XMLorg]</dt>
+ <dd>
+ <a href="http://xml.org">XML.org</a>
+ </dd>
+
+ <dt>
+ <a name="ref-xslinfo"></a>[XSLINFO]</dt>
+ <dd>
+ <a href="http://www.xslinfo.com">XSLINFO.com</a>
+ </dd>
+
+ <dt>
+ <a name="ref-bible"></a>[XMLBible14]</dt>
+ <dd>
+ <a href="http://metalab.unc.edu/xml/books/bible/updates/14.html">
+ Harold, E. R.: XML Bible, Chapter 14 (online presentation)
+ </a>
+ </dd>
+ </dl>
+ </DIV>
+ </DIV>
+ <hr>
+ <p STYLE="font-style: italic; margin-left: 0">(c) 2000 Ginger Alliance s.r.o.</p>
+ </body>
+</html>
\ No newline at end of file
diff --git a/test/concat_result b/test/concat_result
new file mode 100644
index 0000000..f4a2b7f
--- /dev/null
+++ b/test/concat_result
@@ -0,0 +1,13 @@
+<file_info>
+ <name><OUTFILE_0/></name>
+ <generated_locally/>
+ <upload_when_present/>
+ <url><UPLOAD_URL/></url>
+ <max_nbytes>120000</max_nbytes>
+</file_info>
+<result>
+ <file_ref>
+ <file_name><OUTFILE_0/></file_name>
+ <open_name>out</open_name>
+ </file_ref>
+</result>
diff --git a/test/concat_wu b/test/concat_wu
new file mode 100644
index 0000000..c053e26
--- /dev/null
+++ b/test/concat_wu
@@ -0,0 +1,17 @@
+<file_info>
+ <number>0</number>
+</file_info>
+<file_info>
+ <number>1</number>
+</file_info>
+<workunit>
+ <file_ref>
+ <file_number>0</file_number>
+ <open_name>in1</open_name>
+ </file_ref>
+ <file_ref>
+ <file_number>1</file_number>
+ <open_name>in2</open_name>
+ </file_ref>
+ <command_line>in1 in2 out</command_line>
+</workunit>
diff --git a/test/db_def_to_php b/test/db_def_to_php
new file mode 100644
index 0000000..5a7c198
--- /dev/null
+++ b/test/db_def_to_php
@@ -0,0 +1,20 @@
+#!/usr/bin/env perl
+
+## $Id: db_def_to_php 2587 2003-10-28 00:41:04Z quarl $
+
+## parse the db #defines to php.
+
+## syntax: ./db_def_to_php < ../db/boinc_db.h > boinc_db.inc
+
+print "<?php\n";
+print " // Generated by db_def_to_php\n";
+# print " // Generated by db_def_to_php on ";
+# system('date');
+
+while (<>) {
+ if (/^\s*#define\s+([^\s]+)\s+([0-9]+)\s*$/) {
+ print qq/ define("$1", $2);\n/;
+ }
+}
+
+print "?>\n";
diff --git a/test/db_def_to_py b/test/db_def_to_py
new file mode 100644
index 0000000..8789966
--- /dev/null
+++ b/test/db_def_to_py
@@ -0,0 +1,16 @@
+#!/usr/bin/env perl
+
+## $Id: db_def_to_py 1528 2003-06-18 03:04:06Z quarl $
+
+## parse the db #defines to php.
+
+## syntax: ./db_def_to_php < ../db/boinc_db.h > boinc_db.inc
+
+print "# Generated by db_def_to_py on ";
+system('date');
+
+while (<>) {
+ if (/^\s*#define\s+([^\s]+)\s+([0-9]+)\s*$/) {
+ print qq/$1 = $2\n/;
+ }
+}
diff --git a/test/fake_php.py b/test/fake_php.py
new file mode 100644
index 0000000..3044625
--- /dev/null
+++ b/test/fake_php.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+# $Id: fake_php.py 2180 2003-08-22 22:52:52Z chrisz $
+
+# fake php - all we really need is 'include schedulers.txt'
+
+import os, sys
+
+REQUEST_URI = os.environ['REQUEST_URI']
+
+print 'Content-Type: text/plain'
+print
+
+print """--- FAKE PHP ---
+
+[ REQUEST_URI=%s ]
+
+Since I can't find php4 on your system, this stub program fake_php.py just
+prints schedulers.txt as necessary.
+
+"""%REQUEST_URI
+
+if REQUEST_URI.endswith('/index.php'):
+ sys.stdout.write(open('schedulers.txt').read())
diff --git a/test/gen_keys.php b/test/gen_keys.php
new file mode 100644
index 0000000..f242eb7
--- /dev/null
+++ b/test/gen_keys.php
@@ -0,0 +1,9 @@
+#! /usr/local/bin/php
+<?php
+ // Generate encryption keys
+
+ include_once("test.inc");
+
+ create_keys();
+
+?>
diff --git a/test/init.inc b/test/init.inc
new file mode 100644
index 0000000..8f92f9f
--- /dev/null
+++ b/test/init.inc
@@ -0,0 +1,310 @@
+<?php
+
+define("VERSION", "1");
+define("CORE_CLIENT", "boinc_".VERSION."_$BOINC_PLATFORM");
+define("PROJECTS", "localhost.localdomain zoot");
+
+
+function clear_db() {
+ PassThru("cd ../db; init_db");
+}
+
+$BOINC_DOWNLOAD_DIR = null;
+$BOINC_UPLOAD_DIR = null;
+$BOINC_PLATFORM = null;
+$BOINC_EMAIL = null;
+$BOINC_DOWNLOAD_URL = null;
+$BOINC_KEY_DIR = null;
+$BOINC_MASTER_URL = null;
+$BOINC_DB_NAME = null;
+
+function open_db() {
+ global $BOINC_DB_NAME;
+
+ $retval = mysql_connect();
+ if (!$retval) {
+ echo "mysql_connect() failed\n";
+ exit();
+ }
+ $retval = mysql_select_db($BOINC_DB_NAME);
+ if (!$retval) {
+ echo "mysql_select_db() failed\n";
+ exit();
+ }
+}
+
+function check_env_vars() {
+ global $BOINC_DOWNLOAD_DIR;
+ global $BOINC_UPLOAD_DIR;
+ global $BOINC_PLATFORM;
+ global $BOINC_EMAIL;
+ global $BOINC_DOWNLOAD_URL;
+ global $BOINC_KEY_DIR;
+ global $BOINC_MASTER_URL;
+ global $BOINC_DB_NAME;
+
+ $bad = false;
+ $BOINC_DOWNLOAD_DIR = getenv("BOINC_DOWNLOAD_DIR");
+ if ($BOINC_DOWNLOAD_DIR == null) {
+ echo "Must define BOINC_DOWNLOAD_DIR\n";
+ $bad = true;
+ }
+ $BOINC_UPLOAD_DIR = getenv("BOINC_UPLOAD_DIR");
+ if ($BOINC_UPLOAD_DIR == null) {
+ echo "Must define BOINC_UPLOAD_DIR\n";
+ $bad = true;
+ }
+ $BOINC_PLATFORM = getenv("BOINC_PLATFORM");
+ if ($BOINC_PLATFORM == null) {
+ echo "Must define BOINC_PLATFORM\n";
+ $bad = true;
+ }
+ $BOINC_EMAIL = getenv("BOINC_EMAIL");
+ if ($BOINC_EMAIL == null) {
+ echo "Must define BOINC_EMAIL\n";
+ $bad = true;
+ }
+ $BOINC_DOWNLOAD_URL = getenv("BOINC_DOWNLOAD_URL");
+ if ($BOINC_DOWNLOAD_URL == null) {
+ echo "Must define BOINC_DOWNLOAD_URL\n";
+ $bad = true;
+ }
+ $BOINC_KEY_DIR = getenv("BOINC_KEY_DIR");
+ if ($BOINC_KEY_DIR == null) {
+ echo "Must define BOINC_KEY_DIR\n";
+ $bad = true;
+ }
+ $BOINC_MASTER_URL = getenv("BOINC_MASTER_URL");
+ if ($BOINC_MASTER_URL == null) {
+ echo "Must define BOINC_MASTER_URL\n";
+ $bad = true;
+ }
+ $BOINC_DB_NAME = getenv("BOINC_DB_NAME");
+ if ($BOINC_DB_NAME == null) {
+ echo "Must define BOINC_DB_NAME\n";
+ $bad = true;
+ }
+ if ($bad) exit();
+}
+
+function clear_server_dirs($clear_key_dir) {
+ global $BOINC_DOWNLOAD_DIR;
+ global $BOINC_UPLOAD_DIR;
+ global $BOINC_KEY_DIR;
+
+ $bad = false;
+ if ($BOINC_DOWNLOAD_DIR == null) {
+ echo "Must define BOINC_DOWNLOAD_DIR\n";
+ $bad = true;
+ }
+ if ($BOINC_UPLOAD_DIR == null) {
+ echo "Must define BOINC_UPLOAD_DIR\n";
+ $bad = true;
+ }
+ if ($BOINC_KEY_DIR == null) {
+ echo "Must define BOINC_KEY_DIR\n";
+ $bad = true;
+ }
+ if ($bad) exit();
+
+ PassThru("rm -f $BOINC_DOWNLOAD_DIR/*");
+ PassThru("rm -f $BOINC_UPLOAD_DIR/*");
+ if ($clear_key_dir) {
+ PassThru("rm -f $BOINC_KEY_DIR/*");
+ }
+}
+
+function clear_client_dirs() {
+ PassThru("rm -rf projects/*" );
+}
+
+function init_client_dirs($prefs_file, $account_file) {
+ global $BOINC_MASTER_URL;
+
+ PassThru("rm -f client_state.xml");
+ PassThru("rm -rf ".PROJECTS);
+ PassThru("rm -rf slots");
+ PassThru("cp $prefs_file prefs.xml");
+ PassThru("sed -e s/BOINC_MASTER_URL/$BOINC_MASTER_URL/ $account_file > account_foo.xml");
+}
+
+function copy_to_download_dir($f) {
+ global $BOINC_DOWNLOAD_DIR;
+
+ PassThru("cp $f $BOINC_DOWNLOAD_DIR");
+}
+
+function add_user($global_prefs_file) {
+ global $BOINC_EMAIL;
+ global $BOINC_MASTER_URL;
+
+ $cmd = "../tools/add user -email_addr $BOINC_EMAIL -user_name David -web_password foobar -authenticator 3f7b90793a0175ad0bda68684e8bd136 ";
+ if ($global_prefs_file) {
+ PassThru("sed -e s/BOINC_MASTER_URL/$BOINC_MASTER_URL/ $global_prefs_file > prefs_temp.xml");
+ $cmd = $cmd." -global_prefs_file prefs_temp.xml";
+ }
+ PassThru($cmd);
+}
+
+function add_project($short_name,$long_name) {
+ PassThru("../tools/add project -project_short_name '$short_name' -project_long_name '$long_name'");
+}
+
+function add_platform($platform) {
+ global $BOINC_PLATFORM;
+
+ if( $platform ) {
+ PassThru("../tools/add platform -platform_name $platform");
+ } else {
+ PassThru("../tools/add platform -platform_name $BOINC_PLATFORM");
+ }
+}
+
+function add_core_client_message($message, $priority, $platform) {
+ global $BOINC_DOWNLOAD_DIR;
+ global $BOINC_UPLOAD_DIR;
+ global $BOINC_PLATFORM;
+ global $BOINC_KEY_DIR;
+
+ if( $platform == null ) {
+ $plat = $BOINC_PLATFORM;
+ } else {
+ $plat = $platform;
+ }
+ PassThru("../tools/add app -app_name core_client -version ".VERSION);
+ $cmd = "../tools/add app_version -app_name core_client -platform_name $plat -version ".VERSION." -download_dir $BOINC_DOWNLOAD_DIR -download_url $BOINC_DOWNLOAD_URL -message '$message' -message_priority '$priority' -code_sign_keyfile $BOINC_KEY_DIR/code_sign_private -exec_dir ../client -exec_files ".CORE_CLIENT;
+ //echo "$cmd\n";
+ PassThru($cmd);
+ PassThru("cp ../client/".CORE_CLIENT." $BOINC_DOWNLOAD_DIR");
+}
+
+function add_core_client($platform) {
+ add_core_client_message("", "", $platform);
+}
+
+function add_app($name, $platform, $exec_name) {
+ PassThru("../tools/add app -app_name $name -version ".VERSION);
+ add_app_version( $name, $platform, $exec_name );
+}
+
+function add_app_version($name, $platform, $exec_name) {
+ global $BOINC_DOWNLOAD_DIR;
+ global $BOINC_PLATFORM;
+ global $BOINC_DOWNLOAD_URL;
+ global $BOINC_KEY_DIR;
+
+ if( $exec_name == null ) {
+ $exec_name = $name;
+ }
+ if( $platform == null ) {
+ $plat = $BOINC_PLATFORM;
+ } else {
+ $plat = $platform;
+ }
+
+ $cmd = "../tools/add app_version -app_name $name -platform_name $plat -version ".VERSION." -download_dir $BOINC_DOWNLOAD_DIR -download_url $BOINC_DOWNLOAD_URL -code_sign_keyfile $BOINC_KEY_DIR/code_sign_private -exec_dir ../apps -exec_files $exec_name";
+ //echo "$cmd\n";
+ PassThru($cmd);
+ PassThru("cp ../apps/$exec_name $BOINC_DOWNLOAD_DIR");
+}
+
+function create_work($x) {
+ global $BOINC_KEY_DIR;
+ PassThru("../tools/create_work -keyfile $BOINC_KEY_DIR/upload_private $x");
+}
+
+function create_keys() {
+ global $BOINC_KEY_DIR;
+ PassThru("../lib/crypt_prog -genkey 1024 $BOINC_KEY_DIR/upload_private $BOINC_KEY_DIR/upload_public");
+ PassThru("../lib/crypt_prog -genkey 1024 $BOINC_KEY_DIR/code_sign_private $BOINC_KEY_DIR/code_sign_public");
+}
+
+function run_client($args) {
+ PassThru("../client/".CORE_CLIENT." $args");
+}
+
+function start_feeder() {
+ PassThru("cd ../sched; feeder -asynch > feeder_out");
+}
+
+function stop_feeder() {
+ $f = fopen("../sched/feeder_trigger", "w");
+ fputs($f, "<quit/>\n");
+ fclose($f);
+}
+
+function compare_file($out, $correct) {
+ global $BOINC_UPLOAD_DIR;
+
+ PassThru("diff $BOINC_UPLOAD_DIR/$out $correct", $retval);
+ if ($retval) {
+ echo "File mismatch: $out $correct\n";
+ } else {
+ echo "Files match: $out $correct\n";
+ }
+}
+
+function check_results_done() {
+ open_db();
+ $result = mysql_query("select * from result where state<>4");
+ while ($x = mysql_fetch_object($result)) {
+ echo "result $x->id is not done\n";
+ }
+}
+
+function num_wus_left() {
+ open_db();
+ $numwus = mysql_query("select count(*) as nres from result where state<>4");
+ $result = mysql_fetch_object($numwus);
+ return $result->nres;
+}
+
+function compare_files($out, $correct) {
+ PassThru("diff $out $correct", $retval);
+ if ($retval) {
+ echo "File mismatch: $out $correct\n";
+ } else {
+ echo "Files match: $out $correct\n";
+ }
+}
+
+function run_api_test() {
+ PassThru("../api/api_test");
+}
+
+function clean_api() {
+ PassThru("rm -f counter app_to_core.xml core_to_app.xml foobar");
+}
+
+function get_time($file_name) {
+ $time_file = fopen($file_name, "r");
+ if($time_file == NULL) return 0;
+ fscanf($time_file, "%f", $app_time);
+ PassThru("rm -f ".$file_name);
+ return $app_time;
+}
+
+function compare_time($app_time) {
+ $epsilon = 0.0001;
+ open_db();
+ $data = mysql_query("select cpu_time from result where name = 'uccpu_wu_0'");
+ $result = mysql_fetch_object($data);
+ $db_time = $result->cpu_time;
+ $client_time = get_time("client_time");
+ if(abs($app_time - $client_time) > $epsilon) {
+ printf("Time mismatch: app %f client %f\n", $app_time, $client_time);
+ }
+ else {
+ printf("Client time %f matches app time %f\n", $client_time, $app_time)
+;
+ }
+ if(abs($db_time - $app_time) > $epsilon) {
+ printf("Time mismatch: client %f server %f\n", $client_time, $db_time);
+ }
+ else {
+ printf("Reported time %f matches client time %f\n", $db_time, $client_time);
+ }
+ PassThru("rm -f client_time app_time");
+}
+
+?>
diff --git a/test/input b/test/input
new file mode 100644
index 0000000..f448d51
--- /dev/null
+++ b/test/input
@@ -0,0 +1,1326 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <META http-equiv="Content-Type" CONTENT="text/html" CHARSET="UTF-8">
+ <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
+ <STYLE TYPE="text/css" MEDIA="screen">
+ BODY, H2, H3, H4, P, UL, OL, DL
+ {
+ font-family: "Verdana", "Helvetica", "Arial", "sans-serif"
+ }
+
+ H1 {color: #0058a0; font-size: 20pt}
+ H2 {color: #0058a0; font-size: 16pt}
+ H3 {color: #0058a0; font-size: 14pt}
+ H4 {color: #0058a0; font-size: 12pt}
+
+ A:link, A:active, A:visited
+ {
+ color: #0058a0;
+ text-decoration: none
+ }
+
+ P, UL, OL, DL {margin-left: 10%; margin-right: 10%; font-size: 10pt}
+ DT {margin-bottom: 0.5em}
+ .offset {margin-left: 10%}
+ .afterskip {margin-bottom: 1em}
+ .afterhalf {margin-bottom: 0.5em}
+ .example {margin-left: 10%; margin-right: 10%;
+ border-color: #0058a0; border-style:solid; border-width: 1pt; padding: 1pt}
+ CODE {font-family: "Courier"}
+ .comment {color: #0000ff}
+
+ P.offset {margin-left: 15%}
+ P.inner {margin-left: 2%; width: 96%}
+ P.note {margin-left: 10%; border-color: #0058a0;
+ border-style:solid; border-width: 1pt;
+ padding: 5pt; background-color:#e0e0e0 }
+
+ PRE {font-size: 10pt; padding: 5pt}
+
+ </STYLE>
+ <title>GAdoc - Sablotron 0.60</title>
+ </head>
+ <body bgcolor="#ffffff">
+ <h1 CLASS="afterskip">Sablotron 0.60</h1>
+ <DIV CLASS="afterskip">
+ <p>
+ <b>
+ <i>Tom Kaiser (Ginger Alliance)</i>
+ </b>
+ </p>
+ <p>
+ <i>June 17, 2001</i>
+ </p>
+ </DIV>
+ <h3>Abstract</h3>
+ <DIV CLASS="offset">This is a description of the current version of the
+ XSLT processor called Sablotron, including an overview of its
+ limitations as compared to the XSLT specification.
+ </DIV>
+ <h3>Contents</h3>
+<DIV STYLE="margin-left: 10%; margin-bottom: 2em; font-size: smaller">
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__25"></a> <a href="#i__25">
+ <b>1 This text</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__60"></a> <a href="#i__60">
+ <b>2 Changes from the last release</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__74"></a> <a href="#i__74">
+ <b>3 Introduction</b>
+ </a>
+ <DIV class="offset"> <a href="#i__81">3.1 XSLT</a>
+ <BR> <a href="#i__154">3.2 On Sablotron</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__227"></a> <a href="#i__227">
+ <b>4 The sources</b>
+ </a>
+ <DIV class="offset"> <a href="#i__238">4.1 Getting the sources</a>
+ <BR> <a href="#i__280">4.2 Joining the development</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__305"></a> <a href="#i__305">
+ <b>5 Implementation. Supported instructions and functions</b>
+ </a>
+ <DIV class="offset"> <a href="#i__343">5.1 Templates</a>
+ <BR> <a href="#i__364">5.2 Conditional processing</a>
+ <BR> <a href="#i__381">5.3 Loops</a>
+ <BR> <a href="#i__398">5.4 Variables and parameters</a>
+ <BR> <a href="#i__415">5.5 Element creation</a>
+ <BR> <a href="#i__439">5.6 Global definitions</a>
+ <BR> <a href="#i__476">5.7 Values and copying</a>
+ <BR> <a href="#i__508">5.8 Namespace processing</a>
+ <BR> <a href="#i__529">5.9 Sorting</a>
+ <BR> <a href="#i__577">5.10 Whitespace stripping</a>
+ <BR> <a href="#i__598">5.11 Includes</a>
+ <BR> <a href="#i__623">5.12 Other unimplemented instructions</a>
+ <BR> <a href="#i__654">5.13 Output conformance</a>
+ <BR> <a href="#i__686">5.14 XPath expressions</a>
+ <BR> <a href="#i__714">5.15 Built-in functions</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__804"></a> <a href="#i__804">
+ <b>6 Other implementation-related notes</b>
+ </a>
+ <DIV class="offset"> <a href="#i__811">6.1 Handlers</a>
+ <BR> <a href="#i__859">6.2 Encodings</a>
+ <BR> <a href="#i__887">6.3 Output methods</a>
+ <BR> <a href="#i__915">6.4 URIs</a>
+ <BR> <a href="#i__983">6.5 Named buffers</a>
+ <BR> <a href="#i__1015">6.6 Error and log messages</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__1048"></a> <a href="#i__1048">
+ <b>7 The C interface</b>
+ </a>
+ <DIV class="offset"> <a href="#i__1065">7.1 Shortcuts</a>
+ <BR> <a href="#i__1205">7.2 Basic functions</a>
+ <BR> <a href="#i__1416">7.3 Generalized interface functions</a>
+ <BR> <a href="#i__1578">7.4 The situation object</a>
+ <BR> <a href="#i__1631">7.5 Document Object Model (DOM) functions</a>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__1870"></a> <a href="#i__1870">
+ <b>8 The command line interface</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ <SPAN CLASS="afterhalf">
+ <a name="toc_i__2013"></a> <a href="#i__2013">
+ <b>9 References</b>
+ </a>
+ <DIV class="offset"></DIV>
+ </SPAN>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__25"></a>
+ <h2>
+ <a href="#toc_i__25">1 This text</a>
+ </h2>
+ <DIV>
+ <p CLASS="">The HTML form of this description
+ was compiled by Sablotron from the XML source
+ Sablot-0-60.xml.
+ </p>
+ <p CLASS="">
+ The material in the following sections includes:
+ </p>
+ <ul>
+ <li>some background information on XSLT and Sablotron,</li>
+ <li>a detailed comparison of the current version of
+ Sablotron to the XSLT spec,</li>
+ <li>Sablotron usage from the command line or as a
+ library.</li>
+ </ul>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__60"></a>
+ <h2>
+ <a href="#toc_i__60">2 Changes from the last release</a>
+ </h2>
+ <DIV>
+ <p CLASS="">Please see the RELEASE file.</p>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__74"></a>
+ <h2>
+ <a href="#toc_i__74">3 Introduction</a>
+ </h2>
+ <DIV>
+ <DIV class="afterskip">
+ <a name="i__81"></a>
+ <h3>
+ <a href="#toc_i__74">3.1 XSLT</a>
+ </h3>
+ <p CLASS="">XSLT is a language allowing to transform given XML data (the
+ <i>input</i>) according to a <i>stylesheet</i>. XSLT stylesheets
+ are themselves XML documents; that is, all instructions of the
+ language are expressed in the form of XML elements. The
+ <i>output</i>, i.e. the result of the processing, is typically a
+ XML document as well, although the syntactic requirements can be
+ relaxed to allow the creation of a HTML document (one that
+ contains unclosed tags and the like), or even plain text.
+ </p>
+ <p CLASS="">XSLT was designed by the World Wide Web Consortium (W3C) as
+ a part of the XSL stylesheet language, where it is complemented
+ by a powerful set of formatting instructions. The most precise
+ information about XSLT can be found in the W3C Recommendation <a href="#ref-xslt">[XSLT]</a>. In particular, Appendix B of the
+ Recommendation contains a handy syntax table. A good tutorial is
+ <a href="#ref-bible">[XMLBible14]</a>.
+ </p>
+ <p CLASS="">Other W3C Recommendations one often needs to consult are <a href="#ref-xml">[XML]</a> (for the definition of the XML
+ language) and <a href="#ref-xpath">[XPath]</a> (for details on
+ XPath, the language used to form expressions in XSLT and
+ elsewhere).
+ </p>
+ <p CLASS="">An excellent source of information about XSLT (indeed, about
+ anything related to XML and SGML) is <a href="#ref-rcover">[Cover]</a>; see also <a href="#ref-xslinfo">[XSLINFO]</a> and <a href="#ref-xmlorg">[XMLorg]</a>.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__154"></a>
+ <h3>
+ <a href="#toc_i__74">3.2 On Sablotron</a>
+ </h3>
+ <p CLASS="">Sablotron is a XSLT processor (though not quite conforming
+ yet..., see below) written in C++. Since the machines where it
+ is meant to run include various small mobile
+ clients, the main objectives of its design are the following:
+ </p>
+ <ul>
+ <li>portability,</li>
+ <li>compact code,</li>
+ <li>as much independence on other resources (Java etc.) as
+ possible.</li>
+ </ul>
+ <p CLASS="">Sablotron is a single shared library
+ (<code>sablot.dll</code> or <code>libsablot.so.0.60</code>). It can
+ also be used from the command line via the simple interface
+ called <code>sabcmd</code>. See <a href="#invocation">here</a> for
+ more information.
+ </p>
+ <p CLASS="">The only software Sablotron relies on is <b>expat</b>, the
+ XML parser by James Clark. See <a href="#expat">below</a> for
+ information on how to get expat.
+ </p>
+ <p CLASS="">For information on the available interfaces, e.g. for
+ Python, Perl and PHP, see <a href="http://www.gingerall.com">www.gingerall.com</a>.
+ </p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__227"></a>
+ <h2>
+ <a href="#toc_i__227">4 The sources</a>
+ </h2>
+ <DIV>
+ <p CLASS="">
+ Sablotron is written in C++. The source files compile under
+ Win32 (using MS Visual C++ 6.0) and on Solaris and Linux (using
+ g++ 2.95.2) without change.</p>
+ <DIV class="afterskip">
+ <a name="i__238"></a>
+ <h3>
+ <a href="#toc_i__227">4.1 Getting the sources</a>
+ </h3>
+ <p CLASS="">The source or binary distributions of Sablotron can be downloaded
+ from <a href="http://www.gingerall.com">www.gingerall.com</a>. For
+ instructions on how to build the sources (if any), refer to the accompanying INSTALL file.
+ </p>
+ <p CLASS="">If you have access to the Ginger Alliance CVS server, you
+ can get the working version of Sablotron in the CVS module
+ <code>ga</code>. The access rights can be obtained on
+ request from <a href="mailto:cvsadmin at gingerall.com">the CVS admin</a>.
+ </p>
+ <p CLASS="">
+ <a name="expat"></a>
+ Since version 0.50, Sablotron uses expat 1.95.1, available from <a href="http://expat.sourceforge.org">SourceForge</a>.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__280"></a>
+ <h3>
+ <a href="#toc_i__227">4.2 Joining the development</a>
+ </h3>
+ <p CLASS="">
+ Sablotron is an open source project and all volunteers are most
+ welcome! The documentation of the sources is still somewhat
+ sparse but we will try to improve it. If you find the invitation
+ to work on Sablotron with us interesting, please <a href="mailto:sablotron at gingerall.com">contact us</a>. There is also
+ a mailing list available, see <a href="http://www.gingerall.com">www.gingerall.com</a>.
+ </p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__305"></a>
+ <h2>
+ <a href="#toc_i__305">5 Implementation. Supported instructions and functions</a>
+ </h2>
+ <DIV>
+ <p CLASS="">The instruction set supported by this version of Sablotron is
+ already sufficient for many transformation tasks (e.g. the task of
+ formatting this document). On the other
+ hand, a comparison of it to the XSLT specification <a href="#ref-xslt">[XSLT]</a> shows that much is still to be
+ done. The purpose of the
+ following sections is to describe the varying degree of support
+ for the elements of the XSLT language. </p>
+ <p CLASS="">It may be helpful to refer to the syntax table in Appendix B
+ of <a href="#ref-xslt">[XSLT]</a>. The instructions/attributes that
+ are not listed as unsupported should be implemented. The <a href="mailto:sablotron at gingerall.com">authors</a> will appreciate being
+ told about any omissions found in the following
+ description.</p>
+ <p CLASS="">For readability, I sometimes omit the <code>xsl:</code> prefix
+ from the instruction names.</p>
+ <DIV class="afterskip">
+ <a name="i__343"></a>
+ <h3>
+ <a href="#toc_i__305">5.1 Templates</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ template, apply-templates, call-template
+ </code>
+ </p>
+ <p CLASS="">
+ Fully implemented. <code>xsl:sort</code> is supported since release 0.50.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__364"></a>
+ <h3>
+ <a href="#toc_i__305">5.2 Conditional processing</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ if, choose, when, otherwise
+ </code>
+ </p>
+ <p CLASS="">Fully implemented.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__381"></a>
+ <h3>
+ <a href="#toc_i__305">5.3 Loops</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>for-each</code>
+ </p>
+ <p CLASS="">Fully implemented.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__398"></a>
+ <h3>
+ <a href="#toc_i__305">5.4 Variables and parameters</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>variable, param, with-param</code>
+ </p>
+ <p CLASS="">Fully implemented. Top-level variables and parameters are
+ read in the document order, so no forward references are
+ resolved. This is a minor deviation from the spec. </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__415"></a>
+ <h3>
+ <a href="#toc_i__305">5.5 Element creation</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>element, attribute, text,
+ comment, processing-instruction, attribute-set</code>
+ </p>
+ <p CLASS="">
+ <code>xsl:attribute-set</code> is not implemented. For the
+ rest, <code>name</code> is the only recognized attribute (where
+ applicable). Literal result elements work.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__439"></a>
+ <h3>
+ <a href="#toc_i__305">5.6 Global definitions</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>stylesheet, transform, output</code>
+ </p>
+ <p CLASS="">For <code>stylesheet</code> and <code>transform</code>,
+ the only recognized attribute is
+ <code>version</code>. <code>xsl:output</code> should work
+ (see below for notes on the <code>encoding</code>
+ attribute). HTML indentation has been added in 0.60.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__476"></a>
+ <h3>
+ <a href="#toc_i__305">5.7 Values and copying</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>value-of, copy, copy-of</code>
+ </p>
+ <p CLASS="">
+ <code>copy-of</code> and <code>value-of</code> are fully
+ implemented. <code>copy</code> is implemented except for the
+ <code>use-attribute-sets</code> attribute.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__508"></a>
+ <h3>
+ <a href="#toc_i__305">5.8 Namespace processing</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>namespace-alias</code>
+ </p>
+ <p CLASS="">Namespaces should be processed correctly. The
+ <code>namespace-alias</code> instruction is now supported
+ (patch by Major).</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__529"></a>
+ <h3>
+ <a href="#toc_i__305">5.9 Sorting</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>sort</code>
+ </p>
+ <p CLASS="">
+ <code>xsl:sort</code> is implemented since 0.50. There are
+ minor limitations:
+ </p>
+ <ul>
+ <li>currently, the <code>lang</code> attribute may only
+ contain the values <code>"en"</code> or <code>"cz"</code>.</li>
+ <li>
+ <code>case-order</code> cannot be specified.</li>
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__577"></a>
+ <h3>
+ <a href="#toc_i__305">5.10 Whitespace stripping</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>strip-space, preserve-space</code>
+ </p>
+ <p CLASS="">Only the default whitespace stripping is done. That is,
+ all whitespace-only text nodes in any stylesheet, not appearing
+ inside a <code>xsl:text</code>, are removed. The two
+ instructions for whitespace stripping and preservation are
+ unsupported.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__598"></a>
+ <h3>
+ <a href="#toc_i__305">5.11 Includes</a>
+ </h3>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>include, import, apply-imports</code>
+ </p>
+ <p CLASS="">Only <code>xsl:include</code> is implemented. Processing
+ involving multiple documents works, but has to get more testing,
+ eg. with respect to <code>generate-id()</code>.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__623"></a>
+ <h3>
+ <a href="#toc_i__305">5.12 Other unimplemented instructions</a>
+ </h3>
+ <ul>
+ <li>
+ <code>xsl:key,</code>
+ </li>
+ <li>
+ <code>xsl:number,</code>
+ </li>
+ <li>
+ <code>xsl:fallback.</code>
+ </li>
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__654"></a>
+ <h3>
+ <a href="#toc_i__305">5.13 Output conformance</a>
+ </h3>
+ <p CLASS="">The output mechanism is much closer to the spec than in
+ the versions prior to 0.4. The following issues remain for the
+ html method:</p>
+ <ul>
+ <li>Output the boolean attributes correctly.</li>
+ <li>Disable the escaping inside
+ <code><SCRIPT></code> and
+ <code><STYLE></code>
+ </li>.
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__686"></a>
+ <h3>
+ <a href="#toc_i__305">5.14 XPath expressions</a>
+ </h3>
+ <p CLASS="">Almost all features of XPath are fully implemented. This means
+ there should be no problems with expressions of any kind.</p>
+ <p CLASS="">One exception relates to axes. The <code>following</code> and
+ <code>preceding</code> axes haven't been implemented yet.</p>
+ <p CLASS="">Another possible exception may be numbers; we did not yet do a
+ thorough test of rounding, NaNs, infinity, etc.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__714"></a>
+ <h3>
+ <a href="#toc_i__305">5.15 Built-in functions</a>
+ </h3>
+ <p CLASS="">
+ <a name="corelib"></a>Only a few functions from the standard
+ function library remain
+ unimplemented:
+ </p>
+ <ul>
+ <li>
+ <code>id()</code>,</li>
+ <li>
+ <code>lang()</code> (accepted but always returns true),</li>
+ <li>
+ <code>key()</code>,</li>
+ <li>
+ <code>format-number()</code>,</li>
+ <li>
+ <code>unparsed-entity-uri()</code>.</li>
+ </ul>
+ <p CLASS="">As for the fuctions that <i>are</i> implemented, the
+ following is a list of differences from the spec:
+ </p>
+ <ul>
+ <li>
+ <code>document()</code> only accepts one argument, always
+ getting the base URI from the stylesheet URI.
+ </li>
+ <li>
+ <code>string-length()</code> returns the byte length of
+ the UTF-8 representation of the string. This will typically
+ differ from the actual length.
+ </li>
+ <li>
+ <code>generate-id()</code> might fail to generate unique identifiers
+ when several input documents are present (giving the same id to
+ nodes from different documents).
+ </li>
+ </ul>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__804"></a>
+ <h2>
+ <a href="#toc_i__804">6 Other implementation-related notes</a>
+ </h2>
+ <DIV>
+ <DIV class="afterskip">
+ <a name="i__811"></a>
+ <h3>
+ <a href="#toc_i__804">6.1 Handlers</a>
+ </h3>
+ <p CLASS="">It is possible for the user to supply the following
+ handlers to Sablotron:
+ <ul>
+ <li>message handler (to bypass the default way of displaying
+ error and warning messages and logging),</li>
+ <li>scheme handler (to retrieve documents whose URI use an
+ unsupported scheme),</li>
+ <li>streaming handler (an expat-like interface to the XML
+ document which is the result of the processing),</li>
+ <li>'miscellaneous' handler (which will probably server as a
+ collections of odd callbacks).</li>
+ </ul>
+ </p>
+ <p CLASS="">
+ The handlers are set using <code>SablotRegHandler()</code>
+ For details concerning the interface of these handlers,
+ consult the header files <code>sablot.h</code> and
+ <code>shandler.h</code>.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__859"></a>
+ <h3>
+ <a href="#toc_i__804">6.2 Encodings</a>
+ </h3>
+ <p CLASS="">
+ In version 0.52, the encoding conversion capabilities of
+ Sablotron have been much extended. The most important fact is the
+ following: if you have the iconv library installed on your system, you
+ can use any encoding it supports (that is, almost any encoding
+ whatsoever) for both the input and the output documents. Iconv
+ is available on most systems (it is a standard part of glibc2,
+ for instance). There are implementations for Win32 as well.
+ </p>
+ <p CLASS="">If iconv is not available, the encoding may still be supported internally by
+ Sablotron. At present, the list is of such encodings is rather
+ short: besides UTF-8, these are UTF-16, ASCII, iso-8859-1,
+ iso-8859-2 and windows-1250 on input, none on output. However,
+ we plan to implement a half independent light-weight
+ conversion library for use on systems without iconv,
+ extending the set of internally supported encodings
+ considerably.
+ </p>
+ <p CLASS="">Lastly, the user has the option to implement a custom
+ encoding conversion handler, which will be asked to perform any unsupported
+ conversion. See the <code>shandler.h</code> header file for
+ details.
+ </p>
+ <p CLASS="">The default input and output encoding is in all cases UTF-8.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__887"></a>
+ <h3>
+ <a href="#toc_i__804">6.3 Output methods</a>
+ </h3>
+ <p CLASS="">In addition to the standard output methods (xml, html and
+ text), it is possible to output xhtml. Documents output using
+ this method obey the XHTML 1.0 rules (in particular, all empty
+ elements are closed). To choose the method, use
+ <code><xsl:output method='xhtml'></code>. <b>Please note</b>
+ that the name of this method will possibly be changed since the XSLT
+ spec requires any processor-specific methods to have qualified
+ names, say <code>sab:xhtml</code>. On the other hand, the name
+ <code>xhtml</code> is considered in the XSLT 2.0 working draft.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__915"></a>
+ <h3>
+ <a href="#toc_i__804">6.4 URIs</a>
+ </h3>
+ <p CLASS="">Sablotron can handle
+ two URI schemes natively: 'file' and 'arg' (see
+ below). Moreover, it is possible to use the function
+ <code>SablotRegSchemeHandler</code> to register an external scheme
+ handler which will receive requests in all other schemes. See
+ the documentation in <code>sablot.h</code> and
+ <code>shandler.h</code>.
+ </p>
+ <p CLASS="">Relative URI references are resolved in conformance to RFC
+ 2396. The base URI is well defined when the relative reference appears
+ inside a XML document; when invoking sabcmd, the base URI is
+ taken to correspond to the current working directory.
+ </p>
+ <p CLASS="">
+ <a name="fname-rules"></a>When specifying filenames, the
+ following rules are in effect:
+ </p>
+ <ul>
+ <li>specify the "file:" scheme for any standard files,
+ i.e. refer to <code>stdin</code> as <code>file://stdin</code>
+ etc.</li>
+ <li>slashes and backslashes work equally fine, in Windows as
+ well as Linux.</li>
+ <li>to include a drive letter under Windows
+ (e.g. <code>C:\doc.xml</code>), it is necessary to say
+ <code>file://c:/doc.xml</code>.
+ </li>
+ </ul>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__983"></a>
+ <h3>
+ <a href="#toc_i__804">6.5 Named buffers</a>
+ </h3>
+ <p CLASS="">
+ <a name="argscheme"></a>Sablotron introduces an URI scheme
+ 'arg:' which enables one to use strings in named memory
+ buffers. The buffer names can have a tree-like structure so that
+ a relative reference from a document in a buffer can be resolved
+ as pointing to another buffer.
+ </p>
+ <p CLASS="">For instance, if we invoke Sablotron specifying that a
+ buffer named <code>/mybuf/1</code> contains the string
+ "<a>contents</a>", then the expression
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ document('arg:/mybuf/1')/a
+ </code>
+ </p>
+ <p CLASS="">has string-value "contents". If the document in arg:/mybuf/1
+ contained a relative URI reference "../theirbuf/2" then this
+ would be resolved as pointing to "arg:/theirbuf/2".</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1015"></a>
+ <h3>
+ <a href="#toc_i__804">6.6 Error and log messages</a>
+ </h3>
+ <p CLASS="">By default, Sablotron writes error and warning messages to
+ stderr, and does no logging. By a call to
+ <code>SablotSetLog()</code>, you can specify the name of the log
+ file to be used.</p>
+ <p CLASS="">Besides, you can use <code>SablotRegHandler()</code>
+ to override the default message handling. The handler you
+ register will receive all messages in a structured form that's
+ easy to process and filter. For details, see
+ the documentation in <code>sablot.h</code> and
+ <code>shandler.h</code>.</p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1048"></a>
+ <h2>
+ <a href="#toc_i__1048">7 The C interface</a>
+ </h2>
+ <DIV>
+ <p CLASS="">
+ <a name="invocation"></a>
+ </p>
+ <p CLASS="">
+ This section describes the functions exported from the
+ Sablotron library. All of them have a return type of 'int'
+ and return an error flag (nonzero signals an error). Errors
+ are reported to the user by Sablotron itself.
+ </p>
+ <DIV class="afterskip">
+ <a name="i__1065"></a>
+ <h3>
+ <a href="#toc_i__1048">7.1 Shortcuts</a>
+ </h3>
+ <p CLASS="">
+ We'll first describe the 'shortcuts' that do the whole
+ processing in one call.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotProcess(char *sheetURI, char *inputURI, char *resultURI,
+ char **params, char **arguments, char **resultArg);
+ </code>
+ </p>
+ <p CLASS="">
+ This is the basic function. The first three of its arguments
+ are the URIs of the XSLT stylesheet, the XML source and the
+ resulting document, respectively. For some notes on specifying
+ file names, see <a href="#fname-rules">above</a>.
+ </p>
+ <p CLASS="">
+ <code>params</code> is an array of pointers to the names
+ and contents of the top-level stylesheet parameters. Thus,
+ <code>params[0]</code> is a pointer to the null-terminated name
+ of the first parameter, <code>params[1]</code> points to the
+ (null-terminated) contents of the first parameter. The following
+ two array items do the same for the second parameter, etc. The
+ whole array is terminated by a NULL pointer in place of the
+ name. If no parameters are to be passed, you can specify NULL
+ for <code>params</code> itself.
+ </p>
+ <p CLASS="">
+ <code>arguments</code> is a similar array of named buffers
+ to be passed to the stylesheet. (They can be referred to via the
+ 'arg:' scheme, see <a href="#argscheme">above</a>.) Again, the
+ array is a sequence of (name, value) pairs terminated by NULL in
+ place of a name. If no named buffers are to be passed, you can
+ specify NULL for <code>arguments</code> itself.
+ </p>
+ <p CLASS="">
+ <code>resultArg</code> enables one to access the
+ resulting document in case the output went to a named buffer. In
+ that situation, <code>*resultArg</code> points to the resulting
+ null-terminated string, allocated by Sablotron. You can pass NULL
+ for <code>resultArg</code> if the output is sure to go to a
+ file.
+ </p>
+ <p CLASS="">
+ <b>Note:</b>When you are done processing the string
+ pointed to by <code>*resultArg</code>, free it using <a href="#sablotfree">
+ <code>SablotFree()</code>
+ </a> - never use
+ <code>free()</code>. The latter is guaranteed to produce a
+ segmentation fault under Linux.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotProcessFiles(char *styleSheetName,
+ char *inputName,
+ char *resultName);
+ </code>
+ </p>
+ <p CLASS="">A wrapper for <code>SablotProcess()</code> working on
+ files. The parameters are the null-terminated file names of the
+ XSLT stylesheet, the XML input and the result,
+ respectively. Sablotron opens these files itself and closes them
+ after the processing is complete. Values like "file://stdin" are
+ allowed.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotProcessStrings(char *styleSheetStr, char *inputStr, char
+ **resultStr);
+ </code>
+ </p>
+ <p CLASS="">Another wrapper for <code>SablotProcess()</code>, this
+ time for accessing named buffers (i.e. user-allocated memory
+ blocks)only. Thus, the first parameter is a null-terminated
+ string containing the whole stylesheet; the second parameter
+ is a null-terminated string containing the XML
+ input. Sablotron allocates the buffer for the resulting string
+ and returns a pointer to it in resultStr. Hence, invoking
+ <code>puts(*resultStr)</code> after having called
+ <code>SablotProcessStrings</code> sends the result to
+ stdout. The buffer allocated <b>must</b> be freed by calling the
+ function <code>SablotFree</code> described next.
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1205"></a>
+ <h3>
+ <a href="#toc_i__1048">7.2 Basic functions</a>
+ </h3>
+ <p CLASS="">The above shortcuts just call the basic, lower-level
+ functions described below. Note that if you need to set options
+ for logging etc., you may need to use the low-level
+ functions. </p>
+ <p CLASS="">A typical processing session may look like this:</p>
+ <p CLASS="">
+ <pre>
+ SablotHandle p;
+ char *my_buf;
+ SablotCreateProcessor(&p);
+ SablotSetLog(p, ...);
+ /* ...set other instance-specific options here... */
+ SablotRunProcessor(p, ...);
+ SablotGetResultArg(p, "arg:/somename", &my_buf)
+ /* ...do something with my_buf... */
+ /* can run the processor again if necessary */
+ SablotRunProcessor(p, ...);
+ SablotDestroyProcessor(p);
+ </pre>
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotCreateProcessor(SablotHandle *processorPtr);
+ </code>
+ </p>
+ <p CLASS="">Creates an instance of Sablotron and returns a pointer to
+ it in *processorPtr. This pointer is passed on all subsequent
+ calls to this instance. </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotDestroyProcessor(SablotHandle processor_);
+ </code>
+ </p>
+ <p CLASS="">Destroys an instance of the processor, deallocating all
+ the memory used up by it.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotRunProcessor(SablotHandle processor_,
+ char *sheetURI,
+ char *inputURI,
+ char *resultURI,
+ char **params,
+ char **arguments);
+ </code>
+ </p>
+ <p CLASS="">Processes documents using the given processor instance and
+ given params and args definitions. See
+ <code>SablotProcess()</code>.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotGetResultArg(SablotHandle processor_,
+ char *argURI,
+ char **argValue);
+ </code>
+ </p>
+ <p CLASS="">Copies the result 'arg' buffer with the given URI,
+ returning a pointer to the newly-allocated block in
+ *argValue. If no such buffer exists, returns NULL in *argValue.
+ </p>
+ <p CLASS="">This function is necessary, because if the result document
+ is output to memory, it would be lost when
+ <code>SablotDestroyProcessor()</code> is called. When
+ deallocating the copy obtained from
+ <code>SablotGetResultArg()</code>, use <code>SablotFree</code>
+ (never <code>free()</code>). </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotFreeResultArgs(SablotHandle processor_);
+ </code>
+ </p>
+ <p CLASS="">Removes the Sablotron-internal copies of the 'arg' buffers
+ from the last Sablotron run. Normally, there should be no reason
+ to call this function as it is called automatically on both
+ <code>SablotRunProcessor()</code> and
+ <code>SablotDestroyProcessor()</code>. </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ <a name="sablotfree"></a>
+ int SablotFree(char *resultBuf);
+ </code>
+ </p>
+ <p CLASS="">This function frees the buffer allocated on previous call
+ to <code>SablotProcessStrings</code>. Calling it with an
+ invalid pointer will cause a crash.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotRegHandler(
+ SablotHandle processor_,
+ HandlerType type,
+ void *handler,
+ void *userData);
+ </code>
+ </p>
+ <p CLASS="">Registers an external handler. <code>type</code> can be
+ <code>HLR_MESSAGE</code>, <code>HLR_SCHEME</code>,
+ <code>HLR_SAX</code>, <code>HLR_MISC</code> or
+ <code>HLR_ENC</code>.
+ <code>handler</code> points to the
+ callback vector of the appropriate type. <code>userData</code>
+ is a data item to passed to all callbacks of this particular
+ handler. For details, check the <code>sablot.h</code> and
+ <code>shandler.h</code> header files.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotUnregHandler(
+ SablotHandle processor_,
+ HandlerType type,
+ void *handler,
+ void *userData);
+ </code>
+ </p>
+ <p CLASS="">Unregisters the given external handler. For details, check the
+ <code>sablot.h</code> and <code>shandler.h</code> header
+ files.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotSetLog(
+ SablotHandle processor_,
+ const char *logFilename,
+ int logLevel);
+ </code>
+ </p>
+ <p CLASS="">Sets the log filename. The <code>logLevel</code> parameter
+ is currently not used. Pass NULL for <code>logFilename</code> to
+ turn logging off (default). </p>
+ <p CLASS="">The other functions published by sablot.h have been
+ included for experimental reasons or for compatibility, and it
+ is better not to use them.
+ </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ int SablotClearError(SablotHandle processor_);
+ </code>
+ </p>
+ <p CLASS="">Clears the 'pending error' flag for this instance of
+ Sablotron.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1416"></a>
+ <h3>
+ <a href="#toc_i__1048">7.3 Generalized interface functions</a>
+ </h3>
+ <p CLASS="">The implementation of the <a href="#dom">DOM interface</a>
+ brought the need to extend some of the functions described in
+ the previous section. This extension enables the user to:
+ </p>
+ <ul>
+ <li>process documents created by the DOM functions, and</li>
+ <li>process frequently used documents in pre-parsed form.</li>
+ </ul>
+ <p CLASS="">An object called <i>situation</i> is used to provide a
+persistent context for all calls to the DOM-related
+functions. Functions used to manipulate the situation are described in
+<a href="#situation">the following section</a>.</p>
+ <p CLASS="">
+ <b>Note:</b> If not specified otherwise, all these
+ functions return an error code. A positive value indicates an error.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotCreateDocument(SablotSituation S,
+ SDOM_Document *D);
+ </code>
+ </p>
+ <p CLASS="">Creates an empty document. Typically followed by calls to
+ DOM functions to populate the document.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotDestroyDocument(SablotSituation S,
+ SDOM_Document D);
+ </code>
+ </p>
+ <p CLASS="">Destroys a document, freeing all the nodes it has created.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotParse(SablotSituation S,
+ const char *uri, SDOM_Document *D);
+ </code>
+ </p>
+ <p CLASS="">Reads in a document from the given URI.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotParseBuffer(SablotSituation S,
+ const char *buffer, SDOM_Document *D);
+ </code>
+ </p>
+ <p CLASS="">Reads in a document from the given in-memory buffer.</p>
+ <p CLASS="">These functions have variants to be used if the document
+ is to be interpreted as an XSLT stylesheet, namely
+ <code>SablotParseStylesheet</code> and
+ <code>SablotParseStylesheetBuffer</code>.</p>
+ <p CLASS="">The following functions generalize
+ <code>SablotRunProcessor</code> in that they make it possible to
+ utilize an extra kind of a source document: a DOM tree.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotRunProcessorGen(SablotSituation S,
+ void *processor_,
+ char *sheetURI,
+ char *inputURI,
+ char *resultURI);
+ </code>
+ </p>
+ <p CLASS="">A key ingredient of the extended interface. Only the URIs
+ of the sources and of the result document are given to it. The
+ rest of the information passed to
+ <code>SablotRunProcessor</code> is conveyed through
+ <code>SablotAddArgBuffer,</code> <code>SablotAddArgTree</code>
+ and <code>SablotAddParam.</code> The scheme part of the
+ stylesheet URI or the input URI may be "arg:", in which
+ case they refer to a buffer or tree passed by these
+ functions. </p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotAddArgBuffer(SablotSituation S,
+ void *processor_,
+ const char *argName,
+ const char *bufferValue);
+</code>
+ </p>
+ <p CLASS="">Creates a named buffer for the next processor run. The
+ buffer's name and contents are passed as arguments. The name
+ is interpreted relative to the 'arg:/' scheme.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotAddArgTree(SablotSituation S,
+ void *processor_,
+ const char *argName,
+ SDOM_Document tree);
+</code>
+ </p>
+ <p CLASS="">Associates the given document with a name for the next
+ processor run. The document is <i>not</i> destroyed after the
+ run is finished. The name is interpreted relative to the 'arg:/'
+ scheme.</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotAddParam(SablotSituation S,
+ void *processor_,
+ const char *paramName,
+ const char *paramValue);
+ </code>
+ </p>
+ <p CLASS="">Adds a global stylesheet parameter for the next processor
+ run.</p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1578"></a>
+ <h3>
+ <a href="#toc_i__1048">7.4 The situation object</a>
+ </h3>
+ <p CLASS="">
+ <a name="situation"></a>At present, the situation object primarily holds information on any pending errors. A
+situation is created using</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotCreateSituation(SablotSituation
+ *SP);</code>
+ </p>
+ <p CLASS="">and destroyed by</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotDestroySituation(SablotSituation
+ S);</code>
+ </p>
+ <p CLASS="">To clear the pending error flag in a situation, use</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>int SablotClearSituation(SablotSituation
+ S);</code>
+ </p>
+ <p CLASS="">The following self-explanatory functions extract parts of the error information
+ from the situation:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ const char *SablotGetErrorURI(SablotSituation S);<br>
+ int SablotGetErrorLine(SablotSituation S);<br>
+ const char *SablotGetErrorMsg(SablotSituation S);
+ </code>
+ </p>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1631"></a>
+ <h3>
+ <a href="#toc_i__1048">7.5 Document Object Model (DOM) functions</a>
+ </h3>
+ <p CLASS="">
+ <a name="dom"></a>Starting with version 0.60, Sablotron implements
+ a major subset of the DOM Level 1 Core Specification <a href="#ref-dom">[DOM]</a>. A brief
+ description of the implemented interface follows; for more
+ details, please refer to the header file named
+ <code>sdom.h.</code>
+ </p>
+ <p CLASS="">All of the names related to the DOM interface start with
+ SDOM_ (for Sablot DOM).</p>
+ <p CLASS="">Major new types are <code>SDOM_Document</code> (a DOM tree) and
+ <code>SDOM_Node</code> (a node of the tree). A document can also be used in
+ place of a node. This reflects the fact in the DOM spec,
+ Document is a subclass of Node. When used in this way, the
+ document represents its own root node (which is not the same as
+ the `root element').</p>
+ <p CLASS="">Other types include:</p>
+ <ul>
+ <li>
+ <code>SDOM_char:</code> a DOM character type. Currently, this is just
+ char. Note that the DOM spec requires that the DOM
+ implementations work with UTF-16. Sablotron deviates from this
+ by using UTF-8 instead. A separate set of functions taking
+ UTF-16 strings will be provided.</li>
+ <li>
+ <code>SDOM_NodeType:</code> a node type enum. Some of the values are
+ <code>SDOM_ELEMENT_NODE,</code> <code>SDOM_ATTRIBUTE_NODE</code> and <code>SDOM_TEXT_NODE.</code> See
+ <code>sdom.h</code> for the rest.</li>
+ <li>
+ <code>SDOM_NodeList:</code> a node list returned by some of the
+ functions.</li>
+ <li>
+ <code>SDOM_Exception:</code> DOM exception codes enum, with values such
+ as <code>SDOM_NOT_FOUND_ERR</code> or <code>SDOM_INVALID_NODE_TYPE</code>. See <code>sdom.h</code>
+ for details.</li>
+</ul>
+ <p CLASS="">The functions listed below are implemented more or less as defined in
+ the DOM Level 1 Specification, with two exceptions:
+ their names are prefixed with <code>SDOM_</code> and the first argument is
+ always a <code>SablotSituation.</code> All the functions return
+ a <code>SDOM_Exception.</code> </p>
+ <ul>
+<li>
+ <code>createElement, createAttribute, createTextNode,
+createCDATASection, createComment, createProcessingInstruction</code>
+ </li>
+<li>
+ <code>getNodeType, getNodeName, setNodeName, getNodeValue, setNodeValue</code>
+ </li>
+<li>
+ <code>getParentNode, getFirstChild, getLastChild, getPreviousSibling,
+getNextSibling, getOwnerDocument</code>
+ </li>
+<li>
+ <code>insertBefore, appendChild, removeChild, replaceChild</code>
+ </li>
+<li>
+ <code>cloneNode</code>
+ </li>
+<li>
+ <code>getAttribute, setAttribute, removeAttribute, getAttributeList</code>
+ </li>
+</ul>
+ <p CLASS="">Several functions have been added:</p>
+ <ul>
+<li>
+ <code>disposeNode</code> frees all memory used by the given node</li>
+<li>
+ <code>cloneForeignNode</code> clones a node from a different
+document</li>
+<li>
+ <code>docToString</code> serializes the document, returning the
+resulting string</li>
+<li>
+ <code>xql</code> performs an XPath query on the DOM tree,
+returning a list of the nodes satisfying it.</li>
+</ul>
+ <p CLASS="">In addition, there are some functions used to manipulate
+ the node lists returned by <code>xql</code> and
+ <code>getAttributeList</code>. These include
+ <code>getNodeListLength</code>, <code>getNodeListItem</code> and
+ <code>disposeNodeList</code>.</p>
+ <p CLASS="">Finally, there are functions to extract DOM
+ exception-related information from the situation object, namely
+ <code>getExceptionCode</code>, <code>getExceptionMessage</code>
+ and <code>getExceptionDetails</code>.</p>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__1870"></a>
+ <h2>
+ <a href="#toc_i__1870">8 The command line interface</a>
+ </h2>
+ <DIV>
+ <p CLASS="">Sablotron comes with a command-line interface to the
+ shared library, which is a program named
+ <code>sabcmd</code>. At present, <code>sabcmd</code> is invoked
+ as follows:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ sabcmd [<i>options</i>] <i>stylesheet</i> [<i>input</i> [<i>result</i>]] [<i>assignments</i>]
+ </code>
+ </p>
+ <p CLASS="">The arguments are the URIs of the XSLT stylesheet, the
+ XML input document, and the resulting document, respectively. The
+ default for <code>
+ <i>input</i>
+ </code> is
+ <code>file://stdin</code> (meaning plain old stdin);
+ <code>
+ <i>result</i>
+ </code> defaults to
+ <code>file://stdout</code>. Filenames have to include the extension (if
+ any).</p>
+ <p CLASS="">You can display the list of available options by typing
+ <code>sabcmd --help</code>. Among the more useful ones are
+ <code>--log-file</code> (for setting the log file) and
+ <code>--measure</code> (measures and outputs the total
+ processing time).
+ </p>
+ <p CLASS="">
+ <a href="#fname-rules">The rules for filenames</a> are the same as
+ with <code>SablotProcess()</code>.
+ </p>
+ <p CLASS="">
+ <code>assignments</code> is a series of definitions of the
+ form:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ name1=value1 name2=value2 ...
+ </code>
+ </p>
+ <p CLASS="">
+ assigning values to top-level stylesheet parameters and to named
+ buffers. These two cases are distinguished by a leading '$' in
+ the name of a stylesheet parameter. The names of the buffers do
+ <i>not</i> start with "arg:". They may start with a slash; if
+ they don't, the slash is prepended.
+ </p>
+ <p CLASS="">
+ <b>Note:</b> In most cases, it will be necessary to quote
+ the individual assignments. Whether to use single or double
+ quotes may depend on the shell used (or may it?) Single quotes
+ work for bash, double quotes work in Windows.
+ </p>
+ <p CLASS="">If the result URI refers to a named buffer, the output
+ would normally remain buried in memory. Sabcmd dumps the buffer to standard
+ output instead.
+ </p>
+ <p CLASS="">To sum up and give an example, the following would be a
+ valid invocation of sabcmd:</p>
+ <p CLASS="" STYLE="background-color: #ffffee">
+ <code>
+ sabcmd sheet.xsl arg:/the_input "the_input=<a/>"
+ "$use_defaults=1"
+ </code>
+ </p>
+ <p CLASS="">This processes the document passed in the buffer named
+ the_input, using a stylesheet found in file "sheet.xsl" in the
+ working directory. We assign 1 to the top-level parameter called
+ "use_defaults". The output goes to stdout by default.
+ </p>
+ </DIV>
+ </DIV>
+ <DIV class="afterskip">
+ <a name="i__2013"></a>
+ <h2>
+ <a href="#toc_i__2013">9 References</a>
+ </h2>
+ <DIV>
+ <dl>
+ <dt>
+ <a name="ref-xslt"></a>[XSLT]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/1999/REC-xslt-19991116">
+ XSL Transformations (XSLT) Version 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-xpath"></a>[XPath]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/1999/REC-xpath-19991116">
+ XML Path Language (XPath) Version 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-xml"></a>[XML]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/1998/REC-xml-19980210">
+ Extensible Markup Language (XML) 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-dom"></a>[DOM]</dt>
+ <dd>
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1">
+ Document Object Model Level 1 Specification, Version 1.0
+ </a>
+ </dd>
+
+ <dt>
+ <a name="ref-rcover"></a>[Cover]</dt>
+ <dd>
+ <a href="http://www.oasis-open.org/cover/sgml-xml.html">
+ The XML Cover Pages</a>
+ </dd>
+
+ <dt>
+ <a name="ref-xmlorg"></a>[XMLorg]</dt>
+ <dd>
+ <a href="http://xml.org">XML.org</a>
+ </dd>
+
+ <dt>
+ <a name="ref-xslinfo"></a>[XSLINFO]</dt>
+ <dd>
+ <a href="http://www.xslinfo.com">XSLINFO.com</a>
+ </dd>
+
+ <dt>
+ <a name="ref-bible"></a>[XMLBible14]</dt>
+ <dd>
+ <a href="http://metalab.unc.edu/xml/books/bible/updates/14.html">
+ Harold, E. R.: XML Bible, Chapter 14 (online presentation)
+ </a>
+ </dd>
+ </dl>
+ </DIV>
+ </DIV>
+ <hr>
+ <p STYLE="font-style: italic; margin-left: 0">(c) 2000 Ginger Alliance s.r.o.</p>
+ </body>
+</html>
\ No newline at end of file
diff --git a/test/make_project.php b/test/make_project.php
new file mode 100644
index 0000000..63ea626
--- /dev/null
+++ b/test/make_project.php
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+echo "this file is obsolete! cvs remove when ready"
+exit 1
+
+
+#! /usr/local/bin/php
+<?php
+ // This script creates a BOINC project.
+ // You just need to plug in an application,
+ // and back-end systems for creating work and validating results
+
+ include_once("test.inc");
+
+ $project = new Project;
+ $project->short_name = "project_name";
+ $project->long_name = "Your Project";
+
+ $platform = new Platform("windows_intelx86", "Windows");
+
+ $app = new App("Astropulse");
+ $app_version = new App_Version($app);
+ $app_version->platform = $platform;
+ $app_version->exec_dir = "../apps";
+ $app_version->exec_name = "ap_win_0.02.exe";
+
+ $core_app = new App("core client");
+ $core_app_version = new App_Version($core_app);
+ $core_app_version->platform = $platform;
+ $core_app_version->exec_dir = "../apps";
+ $core_app_version->exec_name = "BOINC_0.10.exe";
+
+ $project->add_app($app);
+ $project->add_app_version($app_version);
+ $project->add_app($core_app);
+ $project->add_app_version($core_app_version);
+ $project->start_assimilator = true;
+ $project->start_feeder = true;
+ $project->start_file_deleter = true;
+ $project->start_make_work = true;
+ $project->start_timeout_check = true;
+ $project->start_validate = true;
+ $project->shmem_key = 0x31415926;
+
+ $project->install();
+ $project->start_feeder();
+?>
diff --git a/test/make_project_sah.php b/test/make_project_sah.php
new file mode 100644
index 0000000..d5affd9
--- /dev/null
+++ b/test/make_project_sah.php
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+echo "this file is obsolete! cvs remove when ready"
+exit 1
+
+
+#! /usr/local/bin/php
+<?php
+ // This script creates a BOINC project.
+ // You just need to plug in an application,
+ // and back-end systems for creating work and validating results
+
+ include_once("test.inc");
+
+ $project = new Project;
+ $project->short_name = "sah";
+ $project->long_name = "SETI at home II";
+
+ $platform = new Platform("windows_intelx86", "Windows");
+
+ $app = new App("Astropulse");
+ $app_version = new App_Version($app);
+ $app_version->platform = $platform;
+ $app_version->exec_dir = "../apps";
+ $app_version->version = 5;
+ $app_version->exec_name = "ap_win_0.05.exe";
+
+ $core_app = new App("core client");
+ $core_app_version = new App_Version($core_app);
+ $core_app_version->platform = $platform;
+ $core_app_version->exec_dir = "../apps";
+ $core_app_version->version = 13;
+ $core_app_version->exec_name = "BOINC_0.13a.exe";
+
+ $project->add_app($app);
+ $project->add_app_version($app_version);
+ $project->add_app($core_app);
+ $project->add_app_version($core_app_version);
+ $project->start_assimilator = false;
+ $project->start_feeder = true;
+ $project->start_file_deleter = false;
+ $project->start_make_work = true;
+ $project->make_work_wu_template = "pulse_wu";
+ $project->make_work_result_template = "pulse_result";
+ $project->start_timeout_check = false;
+ $project->start_validate = false;
+ $project->shmem_key = 0x31415928;
+ $project->project_php_file = "project_sah.inc";
+
+ $project->install();
+
+ $work = new Work($app);
+ $work->wu_template = "pulse_wu";
+ $work->result_template = "pulse_result";
+ $work->redundancy = 5;
+ array_push($work->input_files, "03au00ab_20575_00000.wu");
+ $work->install($project);
+ $project->http_password("admin","mypass");
+
+ $project->start_servers();
+?>
diff --git a/test/small_input b/test/small_input
new file mode 100644
index 0000000..323831e
--- /dev/null
+++ b/test/small_input
@@ -0,0 +1 @@
+fjfiwfwnfwieowefnkj
diff --git a/test/ta_correct_atc b/test/ta_correct_atc
new file mode 100644
index 0000000..d2d2b12
--- /dev/null
+++ b/test/ta_correct_atc
@@ -0,0 +1,2 @@
+<percent_done>0.000000</percent_done>
+<cpu_time_at_checkpoint>5.000000</cpu_time_at_checkpoint>
diff --git a/test/ta_correct_f b/test/ta_correct_f
new file mode 100644
index 0000000..678cd69
--- /dev/null
+++ b/test/ta_correct_f
@@ -0,0 +1,2 @@
+blah 17 34.500000
+foo
diff --git a/test/test_1sec.php b/test/test_1sec.php
new file mode 100644
index 0000000..4a34525
--- /dev/null
+++ b/test/test_1sec.php
@@ -0,0 +1,75 @@
+#!/usr/local/bin/php -q
+<?php {
+ // $Id: test_1sec.php 1383 2003-06-11 23:09:11Z quarl $
+
+ // This tests whether the client handles multiple projects,
+ // and whether CPU time is divided correctly between projects
+ // The client should do work for project 2 5 times faster
+ // than for project 1
+
+ include_once("test.inc");
+
+ test_msg("multiple projects with resource share");
+
+ $project1 = new Project;
+ $project2 = new Project;
+ $user = new User();
+ $host = new Host($user);
+
+ $project1->add_core_and_version();
+ $project1->add_app_and_version("upper_case");
+ $project2->add_core_and_version();
+ $project2->add_app_and_version("upper_case");
+
+ $work = new Work();
+ $work->wu_template = "uc_wu";
+ $work->result_template = "uc_result";
+ $work->redundancy = 5;
+ $work->delay_bound = 60;
+ array_push($work->input_files, "input");
+
+ $project1->resource_share = 1;
+ $project1->shmem_key = "0x12344321";
+ $project1->short_name = "Project1";
+ $project1->long_name = "Project1";
+ $project1->add_user($user);
+ $project1->install(); // must install projects before adding to hosts
+ $project1->install_feeder();
+
+ $project2->resource_share = 5;
+ $project2->shmem_key = "0x12345678";
+ $project2->short_name = "Project2";
+ $project2->long_name = "Project2";
+ $project2->add_user($user);
+ $project2->install(); // must install projects before adding to hosts
+ $project2->install_feeder();
+
+ $host->add_user($user,$project1);
+ $host->add_user($user,$project2);
+ $host->install();
+
+ $work->install($project1);
+ $work->install($project2);
+
+ $project1->start_servers();
+ $project2->start_servers();
+ $host->run("-exit_when_idle -skip_cpu_benchmarks");
+ $project1->stop(1);
+ $project2->stop();
+
+ $result->server_state = RESULT_SERVER_STATE_OVER;
+ $project1->check_results(5, $result);
+ $project1->compare_file("uc_wu_0_0", "uc_correct_output");
+ $project1->compare_file("uc_wu_1_0", "uc_correct_output");
+ $project1->compare_file("uc_wu_2_0", "uc_correct_output");
+ $project1->compare_file("uc_wu_3_0", "uc_correct_output");
+ $project1->compare_file("uc_wu_4_0", "uc_correct_output");
+ $project2->check_results(5, $result);
+ $project2->compare_file("uc_wu_0_0", "uc_correct_output");
+ $project2->compare_file("uc_wu_1_0", "uc_correct_output");
+ $project2->compare_file("uc_wu_2_0", "uc_correct_output");
+ $project2->compare_file("uc_wu_3_0", "uc_correct_output");
+ $project2->compare_file("uc_wu_4_0", "uc_correct_output");
+
+ test_done();
+} ?>
diff --git a/test/test_1sec.py b/test/test_1sec.py
new file mode 100644
index 0000000..57b4928
--- /dev/null
+++ b/test/test_1sec.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+
+## $Id: test_1sec.py 1734 2003-07-18 21:43:12Z quarl $
+
+# This tests whether the client handles multiple projects, and whether CPU
+# time is divided correctly between projects The client should do work for
+# project 2 5 times faster than for project 1
+
+from test_uc import *
+
+if __name__ == '__main__':
+ test_msg("multiple projects with resource share");
+ # create two projects with the same host/user
+ host = Host()
+ user = UserUC()
+ for i in range(2):
+ ProjectUC(users=[user], hosts=[host], redundancy=5,
+ short_name="test_1sec_%d"%i, resource_share=[1, 5][i])
+ run_check_all()
diff --git a/test/test_abort.php b/test/test_abort.php
new file mode 100644
index 0000000..7b12d8e
--- /dev/null
+++ b/test/test_abort.php
@@ -0,0 +1,42 @@
+#!/usr/local/bin/php -q
+<?php {
+ // This tests whether the result abort mechanism is working
+
+ include_once("test.inc");
+
+ test_msg("result abort mechanism (disk space limit)");
+
+ $project = new Project;
+ $project->add_app_and_version("upper_case");
+
+ $user = new User();
+
+ $project->add_user($user);
+ $project->install(); // must install projects before adding to hosts
+ $project->install_feeder();
+
+ $host = new Host();
+ $host->add_user($user, $project);
+ $host->install();
+
+ $work = new Work();
+ $work->wu_template = "uc_wu";
+ $work->result_template = "abort_result";
+ $work->redundancy = 2;
+ array_push($work->input_files, "input");
+ $work->install($project);
+
+ $project->start_servers();
+ $host->run("-exit_when_idle -skip_cpu_benchmarks -sched_retry_delay_min 1 >& /dev/null");
+
+ $project->validate(2);
+ $result->server_state = RESULT_SERVER_STATE_OVER;
+ $project->check_results(2, $result);
+
+ $project->assimilate();
+ $project->file_delete();
+
+ $project->stop();
+
+ test_done();
+} ?>
diff --git a/test/test_abort.py b/test/test_abort.py
new file mode 100644
index 0000000..7a192f0
--- /dev/null
+++ b/test/test_abort.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+## $Id: test_abort.py 2114 2003-08-15 20:27:21Z quarl $
+
+# Makes sure that the client aborts when the output file size limit is
+# exceeded, and that the server knows it.
+
+from test_uc import *
+
+class WorkAbort(WorkUC):
+ def __init__(self):
+ WorkUC.__init__(self)
+ self.result_template = "abort_result"
+
+class ResultAbort(ResultUCError):
+ def __init__(self):
+ ResultUCError.__init__(self)
+ self.stderr_out.append('<message>Output file exceeded size limit')
+
+class ProjectAbort(ProjectUC):
+ def __init__(self):
+ ProjectUC.__init__(self, short_name='test_abort', works=[WorkAbort()])
+ def check(self):
+ self.check_client_error(ResultAbort())
+
+if __name__ == '__main__':
+ test_msg("result abort mechanism (disk space limit)")
+ ProjectAbort()
+ run_check_all()
diff --git a/test/test_api.php b/test/test_api.php
new file mode 100644
index 0000000..a897237
--- /dev/null
+++ b/test/test_api.php
@@ -0,0 +1,10 @@
+#! /usr/local/bin/php
+<?php
+ include_once("init.inc");
+
+ clean_api();
+ run_api_test();
+ compare_files("foobar", "ta_correct_f");
+ clean_api();
+?>
+
diff --git a/test/test_backend.php b/test/test_backend.php
new file mode 100644
index 0000000..9d9f37d
--- /dev/null
+++ b/test/test_backend.php
@@ -0,0 +1,80 @@
+#!/usr/local/bin/php -q
+<?php {
+ // $Id: test_backend.php 1412 2003-06-11 23:47:36Z quarl $
+
+ // End to end test. Tests make_work, feeder, scheduling server, client,
+ // file_upload_handler, validator, assimilator, timeout_check, and
+ // file_deleter on a large batch of workunits. Confirms that credit
+ // is correctly granted and that unneeded files are deleted
+
+ include_once("test.inc");
+
+ test_msg("backend");
+
+ $project = new Project;
+ $user = new User();
+ $host = new Host($user);
+ $app = new App("upper_case");
+ $app_version = new App_Version($app);
+
+ $work = new Work($app);
+ $work->wu_template = "uc_wu";
+ $work->result_template = "uc_result";
+ $work->redundancy = 5;
+ $work->delay_bound = 70;
+ array_push($work->input_files, "input");
+
+ $project->add_user($user);
+ $project->add_app($app);
+ $project->add_app_version($app_version);
+ $project->install(); // must install projects before adding to hosts
+ $project->install_make_work($work, 499, 5);
+
+ $host->log_flags = "log_flags.xml";
+ $host->add_user($user,$project);
+ $host->install();
+
+ $work->install($project);
+
+ $project->start_servers();
+
+ // Start by generating a batch of 500 results
+ $n = 0;
+ while($n < 500 ) {
+ $n = $project->num_wus_left();
+ verbose_echo(1, "Generating results [$n/500]");
+ sleep(1);
+ }
+ verbose_echo(1, "Generating results... 500 done");
+
+ // Stop the project, deinstall make_work, and install the normal backend components
+ $project->stop();
+ $project->deinstall_make_work();
+ $project->install_assimilator($app);
+ $project->install_file_delete();
+ $project->install_validate($app, 5);
+ $project->install_feeder();
+ $project->install_timeout_check($app, 5, 5, 0);
+
+ while (($pid=exec("pgrep -n make_work")) != null) sleep(1);
+
+ // Restart the server
+ $project->restart();
+ $project->start_servers();
+
+ // Run the client until there's no more work
+ $host->run("-exit_when_idle -skip_cpu_benchmarks");
+
+ // Give the server 30 seconds to finish assimilating/deleting
+ sleep(30);
+
+ // *** DO CHECKS HERE
+ $result->server_state = RESULT_SERVER_STATE_OVER;
+ $result->exit_status = 0;
+ $project->check_results(500, $result);
+
+ // Stop the server
+ $project->stop();
+
+ test_done();
+} ?>
diff --git a/test/test_concat.php b/test/test_concat.php
new file mode 100644
index 0000000..dd7a53e
--- /dev/null
+++ b/test/test_concat.php
@@ -0,0 +1,42 @@
+#!/usr/local/bin/php -q
+<?php {
+ // $Id: test_concat.php 1383 2003-06-11 23:09:11Z quarl $
+ // tests whether command-line arg passing works
+
+ include_once("test.inc");
+
+ test_msg("standard concat application");
+
+ $project = new Project;
+ $project->add_core_and_version();
+ $project->add_app_and_version("concat");
+
+ $user = new User();
+ $host = new Host($user);
+
+ $project->add_user($user);
+ $project->install(); // must install projects before adding to hosts
+ $project->install_feeder();
+
+ $host->add_user($user,$project);
+ $host->install();
+
+ $work = new Work($app);
+ $work->wu_template = "concat_wu";
+ $work->result_template = "concat_result";
+ $work->redundancy = 2;
+ array_push($work->input_files, "input");
+ array_push($work->input_files, "input");
+ $work->install($project);
+
+ $project->start_servers();
+ $host->run("-exit_when_idle -skip_cpu_benchmarks");
+ $project->stop();
+
+ $result->server_state = RESULT_SERVER_STATE_OVER;
+ $project->check_results(2, $result);
+ $project->compare_file("concat_wu_0_0", "concat_correct_output");
+ $project->compare_file("concat_wu_1_0", "concat_correct_output");
+
+ test_done();
+} ?>
diff --git a/test/test_concat.py b/test/test_concat.py
new file mode 100644
index 0000000..18d674e
--- /dev/null
+++ b/test/test_concat.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+
+## $Id: test_concat.py 2144 2003-08-18 23:51:46Z quarl $
+
+# tests whether command-line arg passing works
+
+from testbase import *
+
+class WorkConcat(Work):
+ def __init__(self, redundancy, **kwargs):
+ Work.__init__(self, redundancy=redundancy)
+ self.wu_template = "concat_wu"
+ self.result_template = "concat_result"
+ self.input_files = ['input']*2
+ self.__dict__.update(kwargs)
+
+class ProjectConcat(TestProject):
+ def __init__(self, works=None, users=None, hosts=None):
+ (num_wu, redundancy) = get_redundancy_args()
+ TestProject.__init__(self,
+ appname = 'concat',
+ num_wu=num_wu, redundancy=redundancy,
+ expected_result = Result(),
+ works = works or [WorkConcat(redundancy=redundancy)],
+ users = users,
+ hosts = hosts)
+
+ # def check(self):
+ # self.sched_run('validate_test')
+ # result = {}
+ # result['server_state'] = RESULT_SERVER_STATE_OVER
+ # self.check_results(result)
+ # self.check_files_match("upload/concat_wu_%d_0", "concat_correct_output", count=self.redundancy)
+ # self.sched_run('assimilator')
+ # self.sched_run('file_deleter')
+ # self.check_deleted("download/input")
+ # self.check_deleted("upload/concat_wu_%d_0", count=self.redundancy)
+
+ # def run(self):
+ # self.install()
+ # self.sched_install('feeder')
+ # self.start_servers()
+
+if __name__ == '__main__':
+ test_msg("standard concat application");
+ ProjectConcat()
+ run_check_all()
diff --git a/test/test_download_backoff.php b/test/test_download_backoff.php
new file mode 100644
index 0000000..e9d205e
--- /dev/null
+++ b/test/test_download_backoff.php
@@ -0,0 +1,53 @@
+#! /usr/local/bin/php
+<?php
+// Tests the exponential backoff mechanism on the client for failed downloads
+// This test is not automated. It has to be run, and then client.out (in the host directory) must be looked at to examine wether everything is working correctly.
+ include_once("test.inc");
+
+ $project = new Project;
+ $user = new User();
+ $host = new Host($user);
+
+ $app = new App("upper_case");
+ $app_version = new App_Version($app);
+
+ $project->add_user($user);
+ $project->add_app($app);
+ $project->add_app_version($app_version);
+
+ $project->install(); // must install projects before adding to hosts
+ $project->install_feeder();
+
+ $host->log_flags = "log_flags.xml";
+ $host->add_user($user, $project);
+ $host->install();
+
+ echo "adding work\n";
+
+ $work = new Work($app);
+ $work->wu_template = "uc_wu";
+ $work->result_template = "uc_result";
+ $work->redundancy = 2;
+ array_push($work->input_files, "input");
+ $work->install($project);
+
+ //delete the download_dir immediately
+ $project->delete_downloaddir();
+
+ $project->start_servers();
+ $pid = $host->run_asynch("-exit_when_idle");
+ echo "sleeping 100 secs\n";
+ sleep(100);
+ $project->reinstall_downloaddir(null);
+ $status = 0;
+ //wait until the host has stopped running
+ pcntl_waitpid($pid, $status, 0);
+ $project->stop();
+
+ $result->server_state = RESULT_SERVER_STATE_OVER;
+ $result->stderr_out = "APP: upper_case: starting, argc 1";
+ $result->exit_status = 0;
+ $project->check_results(2, $result);
+ $project->compare_file("uc_wu_0_0", "uc_correct_output");
+ $project->compare_file("uc_wu_1_0", "uc_correct_output");
+?>
diff --git a/test/test_exit.py b/test/test_exit.py
new file mode 100644
index 0000000..e117a69
--- /dev/null
+++ b/test/test_exit.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+## $Id: test_exit.py 2114 2003-08-15 20:27:21Z quarl $
+
+# Make sure server hears that client exited with nonzero status.
+
+from test_uc import *
+
+class WorkExit(WorkUC):
+ def __init__(self):
+ WorkUC.__init__(self)
+ self.wu_template = "uc_exit_wu"
+
+class ResultExit(ResultUCError):
+ def __init__(self):
+ ResultUCError.__init__(self)
+ self.stderr_out.append('<message>process exited with a non-zero exit code')
+
+class ProjectExit(ProjectUC):
+ def __init__(self):
+ ProjectUC.__init__(self, short_name='test_exit', works=[WorkExit()])
+ def check(self):
+ self.check_client_error(ResultExit())
+
+if __name__ == '__main__':
+ test_msg("application exit report mechanism")
+ ProjectExit()
+ run_check_all()
diff --git a/test/test_limit.php b/test/test_limit.php
new file mode 100644
index 0000000..9160ee3
--- /dev/null
+++ b/test/test_limit.php
@@ -0,0 +1,70 @@
+#! /usr/local/bin/php
+<?php
+ // This tests whether the most basic mechanisms are working
+ // Also whether stderr output is reported correctly
+ // Also tests if water levels are working correctly
+
+ include_once("test.inc");
+
+ $retval = 0;
+
+ $project = new Project;
+
+ $app = new App("upper_case");
+ $app_version = new App_Version($app);
+
+ // the following is optional (makes client web download possible)
+ $core_app = new App("core client");
+ $core_app_version = new App_Version($core_app);
+ $project->add_app($core_app);
+ $project->add_app_version($core_app_version);
+
+ $project->add_app($app);
+ $project->add_app_version($app_version);
+
+ $user = new User();
+ $user->project_prefs = "<project_specific>\nfoobar\n</project_specific>\n";
+ $user->global_prefs = "<venue name=\"home\">\n".
+ "<work_buf_min_days>0</work_buf_min_days>\n".
+ "<work_buf_max_days>2</work_buf_max_days>\n".
+ "<run_on_batteries/>\n".
+ "<max_bytes_sec_down>400000</max_bytes_sec_down>\n".
+ "</venue>\n";
+
+ $project->add_user($user);
+ $project->install(); // must install projects before adding to hosts
+ $project->install_feeder();
+
+ $host = new Host();
+ $host->log_flags = "log_flags.xml";
+ $host->add_user($user, $project);
+ $host->install();
+
+ echo "adding work\n";
+
+ $work = new Work($app);
+ $work->wu_template = "ucs_wu";
+ $work->result_template = "uc_result";
+ $work->redundancy = 1;
+ $work->delay_bound = 2;
+ // Say that 1 WU takes 1 day on a ref comp
+ $work->rsc_fpops = 86400*1e9/2;
+ $work->rsc_iops = 86400*1e9/2;
+ $work->rsc_memory = 1024*1024;
+ $work->rsc_disk = 1;
+ array_push($work->input_files, "input");
+ $work->install($project);
+
+ $project->start_servers();
+ sleep(1); // make sure feeder has a chance to run
+ $host->run("-exit_when_idle -skip_cpu_benchmarks");
+
+ $result->server_state = RESULT_SERVER_STATE_OVER;
+ $result->stderr_out = "APP: upper_case: starting, argc 1";
+ $result->exit_status = 0;
+ $project->check_results(1, $result);
+
+ $project->stop();
+
+ exit($retval);
+?>
diff --git a/test/test_loop.php b/test/test_loop.php
new file mode 100644
index 0000000..02e9c34
--- /dev/null
+++ b/test/test_loop.php
@@ -0,0 +1,47 @@
+#! /usr/local/bin/php
+<?php
+ // This tests whether the most basic mechanisms are working
+ // Also whether stderr output is reported correctly
+
+ include_once("test.inc");
+
+ $project = new Project;
+ $user = new User();
+ $host = new Host($user);
+ $app = new App("upper_case");
+ $app_version = new App_Version($app);
+
+ $project->add_user($user);
+ $project->add_app($app);
+ $project->add_app_version($app_version);
+ $project->start_feeder = true;
+ $project->start_make_work = true;
+ $project->start_validate = true;
+ $project->start_file_delete = true;
+ $project->start_assimilator = true;
+ $project->install(); // must install projects before adding to hosts
+
+ $host->log_flags = "log_flags.xml";
+ $host->add_user($user,$project);
+ $host->install();
+
+ echo "adding work\n";
+
+ $work = new Work($app);
+ $work->wu_template = "uc_wu";
+ $work->result_template = "uc_result";
+ $work->redundancy = 3;
+
+ array_push($work->input_files, "input");
+ $work->install($project);
+
+ $project->start_feeder();
+ $project->start_make_work($work);
+ $project->start_validate($app, 3);
+ $project->start_file_delete();
+ $project->start_assimilator($app);
+ $project->start_stripchart();
+ //$project->start_servers();
+ $host->run();
+ $project->stop();
+?>
diff --git a/test/test_masterurl_failure.php b/test/test_masterurl_failure.php
new file mode 100644
index 0000000..e504bbd
--- /dev/null
+++ b/test/test_masterurl_failure.php
@@ -0,0 +1,22 @@
+#!/usr/local/bin/php -q
+<?php {
+ // $Id: test_masterurl_failure.php 1510 2003-06-17 01:36:47Z quarl $
+
+ $use_proxy_html = 1;
+
+ include_once("test_uc.inc");
+ test_msg("master url failure");
+
+ $project = new ProjectUC;
+
+ start_proxy('exit 1 if $nconnections < 4; if_done_kill(); if_done_ping();');
+
+ // TODO: verify it took ??? seconds
+
+ // TODO: time out after ??? seconds and fail this test
+
+ $project->start_servers_and_host();
+ $project->validate_all_and_stop();
+
+ test_done();
+} ?>
diff --git a/test/test_masterurl_failure.py b/test/test_masterurl_failure.py
new file mode 100644
index 0000000..8eac987
--- /dev/null
+++ b/test/test_masterurl_failure.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+
+## $Id: test_masterurl_failure.py 1655 2003-07-10 00:35:51Z quarl $
+
+from test_uc import *
+
+if __name__ == '__main__':
+ test_msg("scheduler exponential backoff (master url failure)")
+ Proxy('close_connection if $nconnections < 2; ', html=1)
+ # Proxy(('print "hi nc=$nconnections start=$start nchars=$nchars url=$url\n"; ' +
+ # 'close_connection if $nconnections < 2; '),
+ # html=1)
+ # Proxy(( 'print "hi nc=$nconnections start=$start nchars=$nchars url=$url\n"; ' +
+ # ''),
+ # html=1)
+ ProjectUC(short_name='test_masterurl_failure')
+ run_check_all()
+
+ ## TODO: verify it took ??? seconds
diff --git a/test/test_mdownload_backoff.php b/test/test_mdownload_backoff.php
new file mode 100644
index 0000000..33ca7f0
--- /dev/null
+++ b/test/test_mdownload_backoff.php
@@ -0,0 +1,58 @@
+#! /usr/local/bin/php
+<?php
+//This tests the exponential backoff mechanism on the client in case of downloadURLs going down. in this case multiple URLS stay up while one goes down.
+//This test is not automated. It has to be run, and then client.out (in the host directory) must be looked at to examine wether everything is working correctly.
+ include_once("test.inc");
+
+ $project = new Project;
+ $user = new User();
+ $host = new Host($user);
+
+ $app = new App("upper_case");
+ $app_version = new App_Version($app);
+
+ // the following is optional (makes client web download possible)
+ $core_app = new App("core client");
+ $core_app_version = new App_Version($core_app);
+ $project->add_app($core_app);
+ $project->add_app_version($core_app_version);
+
+ $project->add_user($user);
+ $project->add_app($app);
+ $project->add_app_version($app_version);
+
+ $project->install(); // must install projects before adding to hosts
+
+ $host->log_flags = "log_flags.xml";
+ $host->add_project($project);
+ $host->install();
+
+ echo "adding work\n";
+
+ $work = new Work($app);
+ $work->wu_template = "uc_multiple_download_wu";
+ $work->result_template = "uc_result";
+ $work->redundancy = 2;
+ $work->delay_bound = 10;
+ array_push($work->input_files, "input");
+ $work->install($project);
+
+ $project->start_feeder();
+ //delete the download_dir0 immediately
+ $project->delete_downloaddir(null, 0);
+ $project->delete_downloaddir(null, 1);
+ $project->delete_downloaddir(null, 2);
+
+ $pid = $host->run_asynch("-exit_when_idle");
+ $status = 0;
+ //wait until the host has stopped running
+ pcntl_waitpid($pid,$status,0);
+ $project->stop();
+
+ $result->server_state = RESULT_SERVER_STATE_OVER;
+ $result->stderr_out = "APP: upper_case: starting, argc 1";
+ $result->exit_status = 0;
+ $project->check_results(2, $result);
+ $project->compare_file("uc_multiple_download_wu_0_0", "uc_correct_output");
+ $project->compare_file("uc_multiple_download_wu_1_0", "uc_correct_output");
+?>
diff --git a/test/test_pers.php b/test/test_pers.php
new file mode 100644
index 0000000..992ba91
--- /dev/null
+++ b/test/test_pers.php
@@ -0,0 +1,149 @@
+#! /usr/local/bin/php
+<?php
+
+//This tests the persistent file transfers for download and upload. It interrupts them in the middle and makes sure that the filesize never decreases along interrupted transfers.
+
+include_once("test.inc");
+set_time_limit(10000000000);
+
+$project = new Project;
+$user = new User();
+$host = new Host($user);
+$app = new App("upper_case");
+$app_version = new App_Version($app);
+
+$project->add_user($user);
+$project->add_app($app);
+$project->add_app_version($app_version);
+$project->install(); // must install projects before adding to hosts
+
+$host->log_flags = "log_flags.xml";
+$host->add_project($project);
+$host->install();
+
+echo "adding work\n";
+
+$work = new Work($app);
+$work->wu_template = "uc_wu";
+$work->result_template = "uc_result";
+$work->redundancy = 2;
+array_push($work->input_files, "input");
+$work->install($project);
+$project->start_feeder();
+
+//get the path for checking download
+$source_dir = SRC_DIR;
+$enc_url = strtr($project->master_url, "/", "_");
+$enc_url = substr($enc_url,7,strlen($enc_url));
+$path= "$host->host_dir/projects/$enc_url/upper_case";
+print "\n the path for checking download is :".$path;
+
+$pid = $host->run_asynch("-exit_when_idle -limit_transfer_rate 2048");
+$client_pid = $host->get_new_client_pid(null);
+assert($pid != -1);
+$first = 0;
+$file_size = 0;
+//Check download
+
+while(1)
+{
+
+ if(file_exists($path))
+ {
+ $temp = filesize($path);
+ if($temp < $file_size)
+ {
+ echo "\nfilesize dropped, problem downloading\n";
+ echo "temp is $temp, file_size is $file_size\n";
+ break;
+ }
+
+ else if($temp > $file_size)
+ {
+ print "\n filesize increased, it is : ".$temp;
+ if(($temp > 40000) && ($first ==0))
+ {
+ print "\n stopping and rerunning the client";
+ echo "\n now killing client_pid : $client_pid";
+ $host->kill($client_pid, null);
+ $host->run_asynch("-exit_when_idle -limit_transfer_rate 2048");
+ $client_pid = $host->get_new_client_pid($client_pid);
+ echo "\nNow executing : $client_pid";
+ $first++;
+ }
+
+ }
+
+ $file_size = $temp;
+
+ if($file_size == filesize("$source_dir/apps/upper_case"))
+ {
+ echo "\n download test succeeded";
+ break;
+ }
+
+ }
+}
+
+
+$file_size = 0;
+$path= "$project->project_dir/upload/uc_wu_0_0";
+$first =0;
+print "\nupload path is: ".$path;
+echo "\n Now checking upload";
+
+
+while(1)
+{
+ // echo "\n checking upload";
+
+
+ if(file_exists($path))
+ {
+
+ // echo "\nfile exists is download";
+ $temp = filesize($path);
+ if($temp < $file_size)
+ {
+ echo "\nfilesize dropped, problem uploading\n";
+ echo "temp is $temp, file_size if $file_size\n";
+ break;
+ }
+ if($temp > $file_size)
+ {
+ print "\n filesize increased, it is : ".$temp;
+ if(($temp > 20000) && ($first ==0))
+ {
+ print "\n stopping and rerunning the client";
+ print "\nkilling $client_pid";
+ $host->kill($client_pid,null);
+ $host->run_asynch("-exit_when_idle -limit_transfer_rate 2048");
+ $client_pid = $host->get_new_client_pid($client_pid);
+ echo "\nnew client_pid is $client_pid";
+ $first++;
+ }
+
+ }
+ $file_size = $temp;
+ if($file_size == filesize("$source_dir/test/uc_correct_output"))
+ {
+ print "\n all of the files has been uploaded";
+ print "\n stopping and rerunning the client";
+ $host->kill($client_pid, null);
+ $host->run("-exit_when_idle");
+ break;
+ }
+ }
+}
+
+
+$project->stop();
+
+$result->server_state = RESULT_SERVER_STATE_OVER;
+$result->stderr_out = "APP: upper_case: starting, argc 1";
+$result->exit_status = 0;
+$project->check_results(2, $result);
+$project->compare_file("uc_wu_0_0", "uc_correct_output");
+$project->compare_file("uc_wu_1_0", "uc_correct_output");
+
+?>
diff --git a/test/test_prefs.php b/test/test_prefs.php
new file mode 100644
index 0000000..5583318
--- /dev/null
+++ b/test/test_prefs.php
@@ -0,0 +1,37 @@
+#! /usr/local/bin/php
+<?php
+ // test global preferences
+
+ include_once("test.inc");
+
+ $project = new Project;
+ $user = new User();
+ $host = new Host($user);
+ $app = new App("uc_slow");
+ $app_version = new App_Version($app);
+
+ $project->add_user($user);
+ $project->add_app($app);
+ $project->add_app_version($app_version);
+ $project->install(); // must install projects before adding to hosts
+
+ $host->log_flags = "log_flags.xml";
+ $host->add_project($project);
+ $host->global_prefs = "laptop_prefs";
+ $host->install();
+
+ echo "adding work\n";
+
+ $work = new Work($app);
+ $work->wu_template = "ucs_wu";
+ $work->result_template = "uc_result";
+ array_push($work->input_files, "small_input");
+ $work->install($project);
+
+ $project->start_feeder();
+
+ echo "Now run the client manually; start and stop it a few times.\n";
+
+ //$project->check_results(1, $result);
+ //$project->compare_file("ucs_wu_0_0", "uc_small_correct_output");
+?>
diff --git a/test/test_rsc.php b/test/test_rsc.php
new file mode 100644
index 0000000..8f743a7
--- /dev/null
+++ b/test/test_rsc.php
@@ -0,0 +1,41 @@
+#!/usr/local/bin/php -q
+<?php {
+ // $Id: test_rsc.php 1383 2003-06-11 23:09:11Z quarl $
+
+ // test whether the scheduling server filters out work units too big for
+ // client
+
+ include_once("test.inc");
+
+ test_msg("resource filtering for large work units");
+
+ $project = new Project;
+ $user = new User();
+ $host = new Host($user);
+ $project->add_app_and_version("upper_case");
+
+ $project->add_user($user);
+ $project->install(); // must install projects before adding to hosts
+ $project->install_feeder();
+
+ $host->add_user($user,$project);
+ $host->install();
+
+ $work = new Work($app);
+ $work->wu_template = "uc_wu";
+ $work->result_template = "uc_result";
+ $work->redundancy = 1;
+ $work->rsc_disk = 1000000000000; // 1 TB
+ $work->rsc_fpops = 0;
+ array_push($work->input_files, "input");
+ $work->install($project);
+
+ $project->start_servers();
+ $host->run("-exit_when_idle -skip_cpu_benchmarks");
+ $project->stop();
+
+ $result->server_state = RESULT_SERVER_STATE_UNSENT;
+ $project->check_results(1, $result);
+
+ test_done();
+} ?>
diff --git a/test/test_rsc.py b/test/test_rsc.py
new file mode 100644
index 0000000..bbf1c65
--- /dev/null
+++ b/test/test_rsc.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+
+## $Id: test_rsc.py 2243 2003-09-04 00:41:51Z davea $
+
+# Test whether the scheduling server filters out work units too big for client
+
+from test_uc import *
+
+class WorkTooBig(WorkUC):
+ def __init__(self):
+ WorkUC.__init__(self)
+ self.rsc_disk_bound = 1000000000000 # 1 TB
+
+class ResultUnsent:
+ def __init__(self):
+ self.server_state = RESULT_SERVER_STATE_UNSENT
+
+class ProjectRsc(ProjectUC):
+ def __init__(self):
+ ProjectUC.__init__(self, short_name='test_rsc', works=[WorkTooBig()])
+ def check(self):
+ self.check_results(ResultUnsent())
+
+if __name__ == '__main__':
+ test_msg("resource filtering for large work units")
+ ProjectRsc()
+ run_check_all()
diff --git a/test/test_sanity.php b/test/test_sanity.php
new file mode 100644
index 0000000..8f6a927
--- /dev/null
+++ b/test/test_sanity.php
@@ -0,0 +1,36 @@
+#!/usr/local/bin/php -q
+<?php {
+ // $Id: test_sanity.php 1357 2003-06-11 22:11:32Z quarl $
+
+ // tests makes sure that testing framework is sane
+
+ include_once("test.inc");
+
+ // make sure applications executable
+
+ check_core_client_executable();
+ check_app_executable("upper_case");
+ check_app_executable("concat");
+ check_app_executable("1sec");
+
+ if (!is_dir(KEY_DIR)) {
+ error("Keydir doesn't exist: ".KEY_DIR);
+ }
+ if (!is_dir(PROJECTS_DIR)) {
+ error("Projects dir doesn't exist: ".PROJECTS_DIR);
+ }
+ if (!is_dir(HOSTS_DIR)) {
+ error("Hosts dir doesn't exist: ".HOSTS_DIR);
+ }
+ if (!is_dir(CGI_DIR)) {
+ error("CGI dir doesn't exist: ".CGI_DIR);
+ }
+ if (!is_dir(HTML_DIR)) {
+ error("HTML dir doesn't exist: ".HTML_DIR);
+ }
+ if (!fopen(HTML_URL, 'r')) {
+ error("Couldn't open html url: ".HTML_URL);
+ }
+
+ test_done();
+} ?>
diff --git a/test/test_sanity.py b/test/test_sanity.py
new file mode 100644
index 0000000..01a6704
--- /dev/null
+++ b/test/test_sanity.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+
+## $Id: test_sanity.py 2246 2003-09-04 05:07:17Z quarl $
+
+from testbase import *
+import urllib, random
+
+# Test makes sure that testing framework is sane:
+#
+# - executables compiled
+# - cgi server works
+# - test proxy works
+# - mysql permissions and command-line client works
+
+def read_url(url, quiet=False):
+ '''return 1 line from url'''
+ verbose_echo(2, " reading url: "+url)
+ err = ''
+ try:
+ return urllib.URLopener().open(url).readline().strip()
+ except IOError, e:
+ err = e
+ except AttributeError:
+ # Python urllib is buggy if connection is closed (by our proxy
+ # intentionally) right after opened
+ pass
+ if not quiet:
+ error("couldn't access url: %s %s" % (url, err))
+ else:
+ verbose_echo(2, "couldn't access url: %s %s" % (url, err))
+ return ''
+
+if __name__ == '__main__':
+ test_msg("framework sanity")
+
+ # verbose_echo(1, "Checking executables")
+ # check_core_client_executable()
+ # check_app_executable("upper_case")
+ # check_app_executable("concat")
+ # check_app_executable("1sec")
+
+ verbose_echo(1, "Checking directories")
+ for d in ['projects_dir',
+ 'cgi_dir', 'html_dir', 'hosts_dir']:
+ dir = options.__dict__[d]
+ if not os.path.isdir(dir):
+ error("%s doesn't exist: %s" % (d, dir))
+
+ magic = "Foo %x Bar" % random.randint(0,2**16)
+
+ html_path = os.path.join(options.html_dir, 'test_sanity.txt')
+ html_url = os.path.join(options.html_url, 'test_sanity.txt')
+ html_proxy_url = proxerize(html_url)
+ cgi_path = os.path.join(options.cgi_dir, 'test_sanity_cgi')
+ cgi_url = os.path.join(options.cgi_url, 'test_sanity_cgi')
+
+ verbose_echo(1, "Checking webserver setup: non-cgi")
+ print >>open(html_path,'w'), magic
+ if read_url(html_url) != magic:
+ error("couldn't access a file I just wrote: "+html_path+"\n using url: "+html_url)
+
+ verbose_echo(1, "Checking proxy setup")
+ if read_url(html_proxy_url, quiet=True):
+ error("Another proxy already running")
+ else:
+ proxy = Proxy('')
+ if read_url(html_proxy_url) != magic:
+ error("couldn't access file using proxy url: "+html_proxy_url)
+ else:
+ proxy.stop()
+
+ proxy = Proxy('close_connection if $nconnections < 2')
+ if read_url(html_proxy_url, quiet=True):
+ error("Proxy should have closed connection #1")
+ if read_url(html_proxy_url) != magic:
+ error("Proxy should have allowed connection #2")
+ proxy.stop()
+
+ os.unlink(html_path)
+
+ verbose_echo(1, "Checking webserver setup: cgi")
+ print >>open(cgi_path,'w'), '''#!/bin/sh
+echo "Content-Type: text/plain"
+echo ""
+echo "%s"
+''' % magic
+ os.chmod(cgi_path, 0755)
+
+ if read_url(cgi_url) != magic:
+ error("couldn't access a cgi file I just wrote: "+cgi_path+"\n using url: "+cgi_url)
+
+ os.unlink(cgi_path)
+
+
+ database_name = 'boinc_test_sanity_mysql_%s_%d'%(
+ os.environ['USER'], random.randint(0,2**16))
+
+ # create and drop a database
+ verbose_echo(1, "Checking mysql commandline and permissions")
+ shell_call('echo "create database %s" | mysql' % database_name)
+ shell_call('echo "drop database %s" | mysql' % database_name)
diff --git a/test/test_sched_failure.php b/test/test_sched_failure.php
new file mode 100644
index 0000000..bec5b6e
--- /dev/null
+++ b/test/test_sched_failure.php
@@ -0,0 +1,57 @@
+#! /usr/local/bin/php
+<?php
+//This tests the exponential backoff mechanism on the client in case of scheduling server failures.
+//This test is not automated. It has to be run, and then client.out (in the host directory) must be looked at to examine wether everything is working correctly.
+ include_once("test.inc");
+
+ $project = new Project;
+ $user = new User();
+ $host = new Host($user);
+
+ $app = new App("upper_case");
+ $app_version = new App_Version($app);
+
+ // the following is optional (makes client web download possible)
+ $core_app = new App("core client");
+ $core_app_version = new App_Version($core_app);
+ $project->add_app($core_app);
+ $project->add_app_version($core_app_version);
+
+ $project->add_user($user);
+ $project->add_app($app);
+ $project->add_app_version($app_version);
+
+ $project->install(); // must install projects before adding to hosts
+
+ $host->log_flags = "log_flags.xml";
+ $host->add_project($project);
+ $host->install();
+
+ echo "adding work\n";
+
+ $work = new Work($app);
+ $work->wu_template = "uc_wu";
+ $work->result_template = "uc_result";
+ $work->redundancy = 2;
+ $work->delay_bound = 10;
+ array_push($work->input_files, "input");
+ $work->install($project);
+
+ $project->start_feeder();
+ $project->delete_scheduler();
+ $pid = $host->run_asynch("-exit_when_idle");
+ echo "sleeping for 100 seconds\n";
+ sleep(100);
+ $project->reinstall_scheduler();
+ $status = 0;
+ //wait until the host has stopped running
+ pcntl_waitpid($pid,$status,0);
+ $project->stop();
+
+ $result->server_state = RESULT_SERVER_STATE_OVER;
+ $result->stderr_out = "APP: upper_case: starting, argc 1";
+ $result->exit_status = 0;
+ $project->check_results(2, $result);
+ $project->compare_file("uc_wu_0_0", "uc_correct_output");
+ $project->compare_file("uc_wu_1_0", "uc_correct_output");
+?>
diff --git a/test/test_sched_moved.py b/test/test_sched_moved.py
new file mode 100644
index 0000000..1ee5530
--- /dev/null
+++ b/test/test_sched_moved.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+
+## $Id: test_sched_moved.py 1656 2003-07-10 00:59:56Z quarl $
+
+# DOESN"T WORK YET
+
+from test_uc import *
+
+class ProjectSchedMove(ProjectUC):
+ def run(self):
+ self.sched_install('feeder')
+ self.start_servers()
+
+
+if __name__ == '__main__':
+ test_msg("backing off and finding new scheduler URL from master URL")
+ verbose_echo(0, "BEFORE SCHEDULER MOVE")
+ proj = ProjectSchedMove(short_name='test_sched_moved')
+ proj.install()
+ run_check_all()
+
+ verbose_echo(0, "AFTER SCHEDULER MOVE")
+ # TODO: change scheduler url
+ proj.install_project()
+ proj.install_works()
+ run_check_all()
+
diff --git a/test/test_signal.py b/test/test_signal.py
new file mode 100644
index 0000000..78d7303
--- /dev/null
+++ b/test/test_signal.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+## $Id: test_signal.py 2114 2003-08-15 20:27:21Z quarl $
+
+# Make sure server hears that client died by a signal.
+
+from test_uc import *
+
+class WorkSignal(WorkUC):
+ def __init__(self):
+ WorkUC.__init__(self)
+ self.wu_template = "uc_sig_wu"
+
+class ResultSignal(ResultUCError):
+ def __init__(self):
+ ResultUCError.__init__(self)
+ self.stderr_out.append('SIGHUP: terminal line hangup')
+ self.stderr_out.append('<message>process exited with a non-zero exit code')
+
+class ProjectSignal(ProjectUC):
+ def __init__(self):
+ ProjectUC.__init__(self, short_name='test_signal', works=[WorkSignal()])
+ def check(self):
+ self.check_client_error(ResultSignal())
+
+if __name__ == '__main__':
+ test_msg("application signal report mechanism")
+ ProjectSignal()
+ run_check_all()
diff --git a/test/test_sticky.php b/test/test_sticky.php
new file mode 100644
index 0000000..d945efa
--- /dev/null
+++ b/test/test_sticky.php
@@ -0,0 +1,42 @@
+#!/usr/local/bin/php -q
+<?php {
+ // $Id: test_sticky.php 1412 2003-06-11 23:47:36Z quarl $
+
+ include_once("test.inc");
+
+ test_msg("sticky file mechanism");
+
+ $project = new Project;
+ $user = new User();
+ $host = new Host($user);
+
+ $project->add_user($user);
+ $project->add_app_and_version("upper_case");
+ $project->install(); // must install projects before adding to hosts
+ $project->install_feeder();
+
+ $host->add_user($user,$project);
+ $host->install();
+
+ $work = new Work($app);
+ $work->wu_template = "uc_wu_sticky";
+ $work->result_template = "uc_result_sticky";
+ $work->redundancy = 2;
+ array_push($work->input_files, "input");
+ $work->install($project);
+
+ $project->start_servers();
+ $host->run("-exit_when_idle -skip_cpu_benchmarks");
+ $project->stop();
+
+ $result->server_state = RESULT_SERVER_STATE_OVER;
+ $project->check_results(2, $result);
+ $project->compare_file("uc_wu_sticky_0_0", "uc_correct_output");
+ $project->compare_file("uc_wu_sticky_1_0", "uc_correct_output");
+
+ // make sure result files are still there
+ $host->check_file_present($project, "uc_wu_sticky_0_0");
+ $host->check_file_present($project, "uc_wu_sticky_1_0");
+
+ test_done();
+} ?>
diff --git a/test/test_suite.php b/test/test_suite.php
new file mode 100644
index 0000000..41f026c
--- /dev/null
+++ b/test/test_suite.php
@@ -0,0 +1,28 @@
+#! /usr/local/bin/php
+<?php
+ //Run the comprehensive suite of tests
+ //
+
+ passthru("./test_1sec.php", $retval);
+ if($retval) printf("./test_1sec.php did not run correctly\n");
+ sleep(3);
+
+ PassThru("./test_backend.php", $retval);
+ if($retval) printf("./test_backend.php did not run correctly\n");
+ sleep(3);
+
+ PassThru("./test_concat.php", $retval);
+ if($retval) printf("./test_concat.php did not run correctly\n");
+ sleep(3);
+
+ PassThru("./test_rsc.php", $retval);
+ if($retval) printf("./test_rsc.php did not run correctly\n");
+ sleep(3);
+
+ PassThru("./test_sticky.php", $retval);
+ if($retval) printf("./test_sticky.php did not run correctly\n");
+ sleep(3);
+
+ passthru("./test_uc.php", $retval);
+ if($retval) printf("./test_uc.php did not run correctly\n");
+?>
diff --git a/test/test_time.php b/test/test_time.php
new file mode 100644
index 0000000..83146e3
--- /dev/null
+++ b/test/test_time.php
@@ -0,0 +1,49 @@
+#! /usr/local/bin/php
+<?php
+ // test whether CPU time is computed correctly across restarts
+
+ include_once("test.inc");
+
+ $project = new Project;
+ $user = new User();
+ $host = new Host($user);
+ $app = new App("uc_cpu");
+ $app_version = new App_Version($app);
+
+ $project->add_user($user);
+ $project->add_app($app);
+ $project->add_app_version($app_version);
+ $project->install(); // must install projects before adding to hosts
+
+ $host->log_flags = "log_flags.xml";
+ $host->add_project($project);
+ $host->install();
+
+ echo "adding work\n";
+
+ $work = new Work($app);
+ $work->wu_template = "uccpu_wu";
+ $work->result_template = "uccpu_result";
+ $work->redundancy = 1;
+ array_push($work->input_files, "small_input");
+ $work->install($project);
+
+ $project->start_feeder();
+ $app_time = 0;
+ $host->run("-exit_after_app_start 400");
+ $app_time += $host->read_cpu_time_file("app.time");
+ $host->run("-exit_when_idle");
+ $project->stop();
+
+ $result->server_state = RESULT_SERVER_STATE_OVER;
+ $project->check_results(1, $result);
+ $project->compare_file("uccpu_wu_0_0", "uc_small_correct_output");
+ $client_time = $host->read_cpu_time_file("client_time");
+ $x = mysql_query("select cpu_time from result where name='uccpu_wu_0'");
+ $result = mysql_fetch_object($x);
+ $db_time = $result->cpu_time;
+
+ if (abs($app_time-$client_time) > .01) echo "time mismatch\n";
+ if (abs($app_time-$db_time) > .01) echo "time mismatch\n";
+
+?>
diff --git a/test/test_uc.inc b/test/test_uc.inc
new file mode 100644
index 0000000..2b354a6
--- /dev/null
+++ b/test/test_uc.inc
@@ -0,0 +1,75 @@
+<?php {
+ // $Id: test_uc.inc 1510 2003-06-17 01:36:47Z quarl $
+
+ include_once("test.inc");
+
+ class ProjectUC extends Project
+ {
+ var $work;
+ var $host;
+ var $user;
+
+ function ProjectUC() {
+ $this->Project();
+ $this->add_core_and_version();
+ $this->add_app_and_version("upper_case");
+
+ $this->user = new User();
+ $this->user->project_prefs = "<project_specific>\nfoobar\n</project_specific>\n";
+ $this->user->global_prefs = "<venue name=\"home\">\n".
+ "<work_buf_min_days>0</work_buf_min_days>\n".
+ "<work_buf_max_days>2</work_buf_max_days>\n".
+ "<disk_interval>1</disk_interval>\n".
+ "<run_on_batteries/>\n".
+ "<max_bytes_sec_down>400000</max_bytes_sec_down>\n".
+ "</venue>\n";
+
+ $this->add_user($this->user);
+ $this->install(); // must install projects before adding to hosts
+ $this->install_feeder();
+
+ $this->host = new Host();
+ $this->host->add_user($this->user, $this);
+ $this->host->install();
+
+ $this->work = new Work();
+ $this->work->wu_template = "uc_wu";
+ $this->work->result_template = "uc_result";
+ $this->work->redundancy = 2;
+ $this->work->delay_bound = 10;
+ // Say that 1 WU takes 1 day on a ref comp
+ $this->work->rsc_fpops = 86400*1e9/2;
+ $this->work->rsc_iops = 86400*1e9/2;
+ $this->work->rsc_disk = 10e8;
+ array_push($this->work->input_files, "input");
+ $this->work->install($this);
+ }
+
+ function start_servers_and_host()
+ {
+ $this->start_servers();
+ $this->host->run("-exit_when_idle -skip_cpu_benchmarks");
+ }
+
+ function validate_all_and_stop()
+ {
+ $this->validate($this->work->redundancy);
+ $result->server_state = RESULT_SERVER_STATE_OVER;
+ $result->stderr_out = "APP: upper_case: starting, argc 1
+APP: upper_case: argv[0] is upper_case
+APP: upper_case ending, wrote ";
+ $result->exit_status = 0;
+ $this->check_results(2, $result);
+ $this->compare_file("uc_wu_0_0", "uc_correct_output");
+ $this->compare_file("uc_wu_1_0", "uc_correct_output");
+
+ $this->assimilate();
+ $this->file_delete();
+
+ $this->check_server_deleted("download/input");
+ $this->check_server_deleted("upload/uc_wu_0_0");
+ $this->check_server_deleted("upload/uc_wu_1_0");
+ $this->stop();
+ }
+ }
+} ?>
diff --git a/test/test_uc.php b/test/test_uc.php
new file mode 100644
index 0000000..f7fc74d
--- /dev/null
+++ b/test/test_uc.php
@@ -0,0 +1,17 @@
+#!/usr/local/bin/php -q
+<?php {
+ // $Id: test_uc.php 1510 2003-06-17 01:36:47Z quarl $
+
+ // This tests whether the most basic mechanisms are working
+ // Also whether stderr output is reported correctly
+ // Also tests if water levels are working correctly
+
+ include_once("test_uc.inc");
+ test_msg("standard upper_case application");
+
+ $project = new ProjectUC;
+ $project->start_servers_and_host();
+ $project->validate_all_and_stop();
+
+ test_done();
+} ?>
diff --git a/test/test_uc.py b/test/test_uc.py
new file mode 100644
index 0000000..27e2dcb
--- /dev/null
+++ b/test/test_uc.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+## $Id: test_uc.py 5506 2005-02-23 19:44:59Z boincadm $
+
+# This tests whether the most basic mechanisms are working
+# Also whether stderr output is reported correctly
+# Also tests if work buffer limits are working correctly
+
+from testbase import *
+
+class UserUC(User):
+ def init(self):
+ self.User.__init__()
+ self.project_prefs = """<project_preferences>
+<project_specific>
+foobar
+</project_specific>
+</project_preferences>
+"""
+ self.global_prefs = """<global_preferences>
+<venue name=\"home\">
+<work_buf_min_days>0</work_buf_min_days>
+<work_buf_max_days>2</work_buf_max_days>
+<disk_interval>1</disk_interval>
+<run_on_batteries/>
+<max_bytes_sec_down>400000</max_bytes_sec_down>
+</venue>
+</global_preferences>
+"""
+
+class WorkUC(Work):
+ def __init__(self, redundancy, **kwargs):
+ Work.__init__(self, redundancy=redundancy)
+ self.wu_template = "uc_wu_nodelete"
+ self.result_template = "uc_result"
+ self.input_files = ['input']
+ self.__dict__.update(kwargs)
+
+class ResultUC(ExpectedResult):
+ def __init__(self):
+ ExpectedResult.__init__(self)
+ self.stderr_out = MATCH_REGEXPS([
+ "<stderr_txt>",
+ "APP: upper_case: starting, argc \\d+",
+ "APP: upper_case: argv[[]0[]] is upper_case",
+ "APP: upper_case ending, wrote \\d+ chars"])
+
+class ResultComputeErrorUC(ExpectedResultComputeError):
+ def __init__(self):
+ ExpectedResultComputeError.__init__(self)
+ self.stderr_out = MATCH_REGEXPS([ """<stderr_txt>
+APP: upper_case: starting, argc \\d+"""])
+
+## TODO: check that uc_wu_%d_0 matches uc_correct_output BEFORE deleted by
+## file deleter!
+
+class ProjectUC(TestProject):
+ def __init__(self,
+ num_wu=None, redundancy=None,
+ expect_success=True,
+ works=None, users=None, hosts=None,
+ short_name=None, long_name=None,
+ resource_share=1):
+ (num_wu, redundancy) = get_redundancy_args(num_wu, redundancy)
+ TestProject.__init__(self,
+ appname = 'upper_case',
+ num_wu=num_wu, redundancy=redundancy,
+ expected_result = (expect_success and ResultUC() or ResultComputeErrorUC()),
+ works = works or [WorkUC(redundancy=redundancy)],
+ users = users or [UserUC()],
+ hosts = hosts,
+ short_name=short_name, long_name=long_name,
+ resource_share=resource_share
+ )
+
+if __name__ == '__main__':
+ test_msg("standard upper_case application");
+ ProjectUC()
+ run_check_all()
diff --git a/test/test_uc_slow.php b/test/test_uc_slow.php
new file mode 100644
index 0000000..3527593
--- /dev/null
+++ b/test/test_uc_slow.php
@@ -0,0 +1,31 @@
+#!/usr/local/bin/php -q
+<?php {
+ // $Id: test_uc_slow.php 1496 2003-06-16 17:59:38Z eheien $
+
+ include_once("test.inc");
+
+ test_msg("client checkpoint/restart mechanism");
+
+ $project = new Project;
+ $user = new User();
+ $host = new Host();
+
+ $project->add_user($user);
+ $project->add_app_and_version("upper_case");
+ $project->install(); // must install projects before adding to hosts
+
+ $host->add_user($user, $project);
+ $host->install();
+
+ $work = new Work();
+ $work->wu_template = "ucs_wu";
+ $work->result_template = "uc_result";
+ array_push($work->input_files, "small_input");
+ $work->install($project);
+
+ $project->install_feeder();
+ $project->start_servers();
+
+ verbose_echo(0, "Now run the client manually; start and stop it a few times");
+ //compare_file("ucs_wu_0_0", "uc_small_correct_output");
+} ?>
diff --git a/test/test_uc_win.php b/test/test_uc_win.php
new file mode 100644
index 0000000..d05e37d
--- /dev/null
+++ b/test/test_uc_win.php
@@ -0,0 +1,46 @@
+#! /usr/local/bin/php
+<?php
+ // set up a test for the windows client
+ // set BOINC_PLATFORM to "windows_intelx86"
+
+ include_once("test.inc");
+
+ $project = new Project;
+ $user = new User();
+ $host = new Host($user);
+ $app = new App("upper_case");
+ $app_version = new App_Version($app);
+ $platform->name = "windows_intelx86";
+ $platform->user_friendly_name = "Windows";
+ $app_version->platform = $platform;
+ array_push($app_version->exec_names, "upper_case.exe");
+
+ $work = new Work($app);
+ $work->wu_template = "uc_wu";
+ $work->result_template = "uc_result";
+ $work->redundancy = 2;
+ array_push($work->input_files, "input");
+
+ $project->add_user($user);
+ $project->add_app($app);
+ $project->add_app_version($app_version);
+ $project->add_platform($platform);
+ $project->install();
+ $project->install_feeder();
+ $project->install_make_work($work,20,5);
+
+ echo "adding work\n";
+ $work->install($project);
+
+ $project->start_servers();
+
+ echo "Go run the client\n";
+ /*echo "Hit any key to stop the server\n";
+
+ $project->stop();
+
+ $project->check_results(2, $result);
+ $project->compare_file("uc_wu_0_0", "uc_correct_output");
+ $project->compare_file("uc_wu_1_0", "uc_correct_output");
+ */
+?>
diff --git a/test/test_upload_backoff.php b/test/test_upload_backoff.php
new file mode 100644
index 0000000..ed62335
--- /dev/null
+++ b/test/test_upload_backoff.php
@@ -0,0 +1,20 @@
+#!/usr/local/bin/php -q
+<?php {
+ // $Id: test_upload_backoff.php 1526 2003-06-18 02:59:57Z quarl $
+
+ $use_proxy_cgi = 1;
+
+ include_once("test_uc.inc");
+ test_msg("upload backoff");
+
+ start_proxy('print "#$nconnections url=$url time=$time\n"; exit 1 if ($nconnections < 4); if_done_kill(); if_done_ping();');
+
+ $project = new ProjectUC;
+
+ // $pid = $host->run_asynch("-exit_when_idle");
+
+ $project->start_servers_and_host();
+ $project->validate_all_and_stop();
+
+ test_done();
+} ?>
diff --git a/test/test_upload_resume.php b/test/test_upload_resume.php
new file mode 100644
index 0000000..3292b8f
--- /dev/null
+++ b/test/test_upload_resume.php
@@ -0,0 +1,21 @@
+#!/usr/local/bin/php -q
+<?php {
+ // $Id: test_upload_resume.php 1510 2003-06-17 01:36:47Z quarl $
+
+ // This tests whether upload resuming works correctly.
+
+ $use_proxy_cgi = 1;
+
+ include_once("test_uc.inc");
+ test_msg("upload resumes");
+
+ $project = new ProjectUC;
+
+ // TODO
+ // start_proxy('exit 1 if ($nconnections ==1 && $bytes_transferred==ZZZ); if_done_kill(); if_done_ping();');
+
+ $project->start_servers_and_host();
+ $project->validate_all_and_stop();
+
+ test_done();
+} ?>
diff --git a/test/test_water.php b/test/test_water.php
new file mode 100644
index 0000000..122aa2c
--- /dev/null
+++ b/test/test_water.php
@@ -0,0 +1,19 @@
+#! /usr/local/bin/php
+<?php
+ //make sure that the scheduler sends the correct number of wu's in test_uc
+
+ PassThru("test_uc.php | grep -c '<scheduler_request>' > tw_results",
+ $retval
+ );
+ if($retval) {
+ echo "test_uc.php did not run correctly\n";
+ }
+ $f = fopen("tw_results", "r");
+ fscanf($f, "%d", $val);
+ if($val > 2) {
+ echo "Water marks are working\n";
+ } else {
+ echo "Water marks are not working\n";
+ }
+ PassThru("rm -f tw_results");
+?>
diff --git a/test/testproxy b/test/testproxy
new file mode 100644
index 0000000..d3f3adf
--- /dev/null
+++ b/test/testproxy
@@ -0,0 +1,245 @@
+#!/usr/bin/env perl
+
+# -T
+
+# $Id: testproxy 1676 2003-07-15 18:19:29Z davea $
+
+# testproxy - proxy a TCP/IP connection with configurable mid-way
+# disconnections, for simulating internet transfer failures
+
+use strict;
+use warnings;
+use Carp;
+use IO::Socket::INET;
+
+my $listen_port = shift;
+my $target_server = shift;
+my $testcode = join(' ', @ARGV);
+
+if (!$listen_port || !$target_server) {
+ print STDERR <<HELP;
+syntax: $0 <listen_port> <target_server:port> CODE...
+
+CODE is evaluated every 128 bytes transferred from server to client.
+ Some variables you can access/modify:
+ \$target, \$client : perl IO::Handle::INET objects
+ \$nconnections : number of connections so far
+ \$url : url of request (if applicable)
+ \$time : seconds since server started
+ \$chars, \$nchars : characters & length about to send to client.
+ \$bytes_transferred : characters already sent to client
+ \$start : beginning of connection
+ \$done, \$success : finished transfer; successful transfer
+ \$n, \$m : unused variables initialized to 0
+
+ For more, view the code.
+
+ Functions:
+ close_connection, kill_server, if_done_kill, if_done_ping, logmsg
+
+ You can also call standard perl functions such as print, sleep, exit.
+
+Examples:
+ # fail connections for first 3 connections
+ $0 8080 localhost:80 'close_connection if \$nconnections < 4'
+
+ # sleep 5 seconds in the middle of transfer, and print "success" if
+ # transfer succeeds; kill the server after the first connection
+ $0 8080 localhost:80 'sleep 5 if \$bytes_transferred == 256;
+ if (\$done) { print "success\\n" if \$success; kill_server; \$success }'
+
+ # equivalent to above:
+ $0 8080 localhost:80 'sleep 5 if \$bytes_transferred == 256;
+ if_done_kill(); if_done_ping();'
+
+HELP
+ ;
+ exit(1);
+}
+
+if ($target_server !~ /:/) {
+ $target_server .= ':http';
+}
+
+my $N = "\015\012";
+
+sub proxy;
+sub spawn;
+use POSIX qw/strftime/;
+sub logmsg { print STDERR "$0 $$ ", strftime("%Y/%m/%d %H:%M:%S", localtime), ": @_\n" }
+
+my $server = IO::Socket::INET->new(Listen => 5,
+ LocalAddr => inet_ntoa(INADDR_ANY),
+ LocalPort => $listen_port,
+ Proto => 'tcp',
+ ReuseAddr => 1)
+ or die "$0: creating socket on port $listen_port: $!";
+
+logmsg "server started on port $listen_port proxy to $target_server";
+
+my $waitedpid = 0;
+my $paddr;
+my $server_pid = $$;
+
+use POSIX ":sys_wait_h";
+sub REAPER {
+ while (($waitedpid = waitpid(-1,WNOHANG)) > 0) {
+ logmsg "reaped $waitedpid" . ($? ? " with exit $?" : '');
+ }
+ # $SIG{CHLD} = \&REAPER; # loathe sysV
+}
+
+# $SIG{CHLD} = \&REAPER;
+
+my $time_started = time();
+my $nconnections = 0;
+my $cclient;
+
+# for ( $waitedpid = 0;
+# ($cclient = $server->accept()) || $waitedpid;
+# $waitedpid = 0)
+while (($cclient = $server->accept()))
+{
+ # next if $waitedpid and not $cclient;
+ die unless $cclient;
+ REAPER();
+ my $paddr = $cclient->peername();
+ my($port,$iaddr) = sockaddr_in($paddr);
+ my $name = gethostbyaddr($iaddr,AF_INET);
+
+ logmsg "connection from $name:$port"; # [", inet_ntoa($iaddr), "]"
+
+ ++$nconnections;
+
+ spawn \&proxy, $cclient;
+}
+
+sub spawn {
+ my $coderef = shift;
+
+ unless ($coderef && ref($coderef) eq 'CODE') {
+ confess "usage: spawn CODEREF";
+ }
+
+ my $pid;
+ if (!defined($pid = fork)) {
+ logmsg "cannot fork: $!";
+ return;
+ } elsif ($pid) {
+ logmsg "begat $pid";
+ return; # I'm the parent
+ }
+ # else I'm the child -- go spawn
+
+ exit &$coderef(@_);
+}
+
+sub kill_server()
+{
+ kill "INT", $server_pid;
+}
+
+my $start = 0;
+my $done = 0;
+my $success = 0;
+my $url;
+my $n = 0;
+my $m = 0;
+my $bytes_transferred = 0;
+my $chars;
+my $nchars;
+
+sub if_done_ping()
+{
+ if ($done) {
+ if ($success) {
+ print "success\n";
+ } else {
+ print "failed\n";
+ return 0;
+ }
+ }
+}
+
+sub if_done_kill()
+{
+ if ($done) {
+ kill_server();
+ }
+}
+
+sub eval_test_code()
+{
+ return unless $testcode;
+ my $time = time() - $time_started;
+ warn "test code failed: $!" unless defined eval $testcode;
+}
+
+my ($client, $target);
+
+sub close_connection {
+ my $ok = (shift) ? 1 : 0;
+ logmsg "closing connection ok=$ok";
+ # $client->close(), $target->close() doesn't always work for some reason
+ # (maybe to do with forked processes)
+ $client->shutdown(2);
+ $target->shutdown(2);
+ logmsg "exiting";
+ exit !$ok;
+}
+
+sub proxy {
+ $client = shift or die;
+
+ $target = IO::Socket::INET->new(PeerAddr => $target_server)
+ or die "$0: couldn't connect to $target_server: $!";
+
+ $client->autoflush(1);
+ $target->autoflush(1);
+
+ {
+ $bytes_transferred = 0;
+ $chars = undef; $nchars = 0;
+ $done = 0;
+ $success = 0;
+ $start = 1;
+ $url = '';
+ eval_test_code();
+ $start = 0;
+ }
+
+ # transfer lines from client -> server until we get an empty line
+
+ while (my $line = $client->getline()) {
+ if ($. == 1 && $line =~ /^(GET|PUT|POST) ([^\s]+)/) {
+ $url = $2;
+ logmsg "url = $url";
+ }
+ $target->print($line);
+ $line =~ s/[\015\012]+$//;
+ last unless $line;
+ }
+
+ # indicate we have stopped reading data from client and stopped writing
+ # data to server (not sure if this helps)
+ $client->shutdown(0);
+ $target->shutdown(1);
+
+ # transfer from server->client
+
+ while ($nchars = $target->read($chars, 128)) {
+ eval_test_code();
+ $bytes_transferred += $nchars;
+ $client->write($chars, $nchars);
+ }
+
+ {
+ $chars = undef; $nchars = 0;
+ $done = 1;
+ $success = $client->connected() && 1;
+ eval_test_code();
+ }
+
+ close_connection(1);
+ return 0;
+}
diff --git a/test/uc_correct_output b/test/uc_correct_output
new file mode 100644
index 0000000..7df6319
--- /dev/null
+++ b/test/uc_correct_output
@@ -0,0 +1,1326 @@
+<HTML>
+ <HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="TEXT/HTML; CHARSET=UTF-8">
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="TEXT/HTML" CHARSET="UTF-8">
+ <META HTTP-EQUIV="CONTENT-STYLE-TYPE" CONTENT="TEXT/CSS">
+ <STYLE TYPE="TEXT/CSS" MEDIA="SCREEN">
+ BODY, H2, H3, H4, P, UL, OL, DL
+ {
+ FONT-FAMILY: "VERDANA", "HELVETICA", "ARIAL", "SANS-SERIF"
+ }
+
+ H1 {COLOR: #0058A0; FONT-SIZE: 20PT}
+ H2 {COLOR: #0058A0; FONT-SIZE: 16PT}
+ H3 {COLOR: #0058A0; FONT-SIZE: 14PT}
+ H4 {COLOR: #0058A0; FONT-SIZE: 12PT}
+
+ A:LINK, A:ACTIVE, A:VISITED
+ {
+ COLOR: #0058A0;
+ TEXT-DECORATION: NONE
+ }
+
+ P, UL, OL, DL {MARGIN-LEFT: 10%; MARGIN-RIGHT: 10%; FONT-SIZE: 10PT}
+ DT {MARGIN-BOTTOM: 0.5EM}
+ .OFFSET {MARGIN-LEFT: 10%}
+ .AFTERSKIP {MARGIN-BOTTOM: 1EM}
+ .AFTERHALF {MARGIN-BOTTOM: 0.5EM}
+ .EXAMPLE {MARGIN-LEFT: 10%; MARGIN-RIGHT: 10%;
+ BORDER-COLOR: #0058A0; BORDER-STYLE:SOLID; BORDER-WIDTH: 1PT; PADDING: 1PT}
+ CODE {FONT-FAMILY: "COURIER"}
+ .COMMENT {COLOR: #0000FF}
+
+ P.OFFSET {MARGIN-LEFT: 15%}
+ P.INNER {MARGIN-LEFT: 2%; WIDTH: 96%}
+ P.NOTE {MARGIN-LEFT: 10%; BORDER-COLOR: #0058A0;
+ BORDER-STYLE:SOLID; BORDER-WIDTH: 1PT;
+ PADDING: 5PT; BACKGROUND-COLOR:#E0E0E0 }
+
+ PRE {FONT-SIZE: 10PT; PADDING: 5PT}
+
+ </STYLE>
+ <TITLE>GADOC - SABLOTRON 0.60</TITLE>
+ </HEAD>
+ <BODY BGCOLOR="#FFFFFF">
+ <H1 CLASS="AFTERSKIP">SABLOTRON 0.60</H1>
+ <DIV CLASS="AFTERSKIP">
+ <P>
+ <B>
+ <I>TOM KAISER (GINGER ALLIANCE)</I>
+ </B>
+ </P>
+ <P>
+ <I>JUNE 17, 2001</I>
+ </P>
+ </DIV>
+ <H3>ABSTRACT</H3>
+ <DIV CLASS="OFFSET">THIS IS A DESCRIPTION OF THE CURRENT VERSION OF THE
+ XSLT PROCESSOR CALLED SABLOTRON, INCLUDING AN OVERVIEW OF ITS
+ LIMITATIONS AS COMPARED TO THE XSLT SPECIFICATION.
+ </DIV>
+ <H3>CONTENTS</H3>
+<DIV STYLE="MARGIN-LEFT: 10%; MARGIN-BOTTOM: 2EM; FONT-SIZE: SMALLER">
+ <SPAN CLASS="AFTERHALF">
+ <A NAME="TOC_I__25"></A>&NBSP;<A HREF="#I__25">
+ <B>1&NBSP;&NBSP;THIS TEXT</B>
+ </A>
+ <DIV CLASS="OFFSET"></DIV>
+ </SPAN>
+ <SPAN CLASS="AFTERHALF">
+ <A NAME="TOC_I__60"></A>&NBSP;<A HREF="#I__60">
+ <B>2&NBSP;&NBSP;CHANGES FROM THE LAST RELEASE</B>
+ </A>
+ <DIV CLASS="OFFSET"></DIV>
+ </SPAN>
+ <SPAN CLASS="AFTERHALF">
+ <A NAME="TOC_I__74"></A>&NBSP;<A HREF="#I__74">
+ <B>3&NBSP;&NBSP;INTRODUCTION</B>
+ </A>
+ <DIV CLASS="OFFSET">&NBSP;&NBSP;<A HREF="#I__81">3.1&NBSP;&NBSP;XSLT</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__154">3.2&NBSP;&NBSP;ON SABLOTRON</A>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="AFTERHALF">
+ <A NAME="TOC_I__227"></A>&NBSP;<A HREF="#I__227">
+ <B>4&NBSP;&NBSP;THE SOURCES</B>
+ </A>
+ <DIV CLASS="OFFSET">&NBSP;&NBSP;<A HREF="#I__238">4.1&NBSP;&NBSP;GETTING THE SOURCES</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__280">4.2&NBSP;&NBSP;JOINING THE DEVELOPMENT</A>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="AFTERHALF">
+ <A NAME="TOC_I__305"></A>&NBSP;<A HREF="#I__305">
+ <B>5&NBSP;&NBSP;IMPLEMENTATION. SUPPORTED INSTRUCTIONS AND FUNCTIONS</B>
+ </A>
+ <DIV CLASS="OFFSET">&NBSP;&NBSP;<A HREF="#I__343">5.1&NBSP;&NBSP;TEMPLATES</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__364">5.2&NBSP;&NBSP;CONDITIONAL PROCESSING</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__381">5.3&NBSP;&NBSP;LOOPS</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__398">5.4&NBSP;&NBSP;VARIABLES AND PARAMETERS</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__415">5.5&NBSP;&NBSP;ELEMENT CREATION</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__439">5.6&NBSP;&NBSP;GLOBAL DEFINITIONS</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__476">5.7&NBSP;&NBSP;VALUES AND COPYING</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__508">5.8&NBSP;&NBSP;NAMESPACE PROCESSING</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__529">5.9&NBSP;&NBSP;SORTING</A>
+ <BR>&NBSP;<A HREF="#I__577">5.10&NBSP;&NBSP;WHITESPACE STRIPPING</A>
+ <BR>&NBSP;<A HREF="#I__598">5.11&NBSP;&NBSP;INCLUDES</A>
+ <BR>&NBSP;<A HREF="#I__623">5.12&NBSP;&NBSP;OTHER UNIMPLEMENTED INSTRUCTIONS</A>
+ <BR>&NBSP;<A HREF="#I__654">5.13&NBSP;&NBSP;OUTPUT CONFORMANCE</A>
+ <BR>&NBSP;<A HREF="#I__686">5.14&NBSP;&NBSP;XPATH EXPRESSIONS</A>
+ <BR>&NBSP;<A HREF="#I__714">5.15&NBSP;&NBSP;BUILT-IN FUNCTIONS</A>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="AFTERHALF">
+ <A NAME="TOC_I__804"></A>&NBSP;<A HREF="#I__804">
+ <B>6&NBSP;&NBSP;OTHER IMPLEMENTATION-RELATED NOTES</B>
+ </A>
+ <DIV CLASS="OFFSET">&NBSP;&NBSP;<A HREF="#I__811">6.1&NBSP;&NBSP;HANDLERS</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__859">6.2&NBSP;&NBSP;ENCODINGS</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__887">6.3&NBSP;&NBSP;OUTPUT METHODS</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__915">6.4&NBSP;&NBSP;URIS</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__983">6.5&NBSP;&NBSP;NAMED BUFFERS</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__1015">6.6&NBSP;&NBSP;ERROR AND LOG MESSAGES</A>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="AFTERHALF">
+ <A NAME="TOC_I__1048"></A>&NBSP;<A HREF="#I__1048">
+ <B>7&NBSP;&NBSP;THE C INTERFACE</B>
+ </A>
+ <DIV CLASS="OFFSET">&NBSP;&NBSP;<A HREF="#I__1065">7.1&NBSP;&NBSP;SHORTCUTS</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__1205">7.2&NBSP;&NBSP;BASIC FUNCTIONS</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__1416">7.3&NBSP;&NBSP;GENERALIZED INTERFACE FUNCTIONS</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__1578">7.4&NBSP;&NBSP;THE SITUATION OBJECT</A>
+ <BR>&NBSP;&NBSP;<A HREF="#I__1631">7.5&NBSP;&NBSP;DOCUMENT OBJECT MODEL (DOM) FUNCTIONS</A>
+ <BR>
+ </DIV>
+ </SPAN>
+ <SPAN CLASS="AFTERHALF">
+ <A NAME="TOC_I__1870"></A>&NBSP;<A HREF="#I__1870">
+ <B>8&NBSP;&NBSP;THE COMMAND LINE INTERFACE</B>
+ </A>
+ <DIV CLASS="OFFSET"></DIV>
+ </SPAN>
+ <SPAN CLASS="AFTERHALF">
+ <A NAME="TOC_I__2013"></A>&NBSP;<A HREF="#I__2013">
+ <B>9&NBSP;&NBSP;REFERENCES</B>
+ </A>
+ <DIV CLASS="OFFSET"></DIV>
+ </SPAN>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__25"></A>
+ <H2>
+ <A HREF="#TOC_I__25">1&NBSP;&NBSP;THIS TEXT</A>
+ </H2>
+ <DIV>
+ <P CLASS="">THE HTML FORM OF THIS DESCRIPTION
+ WAS COMPILED BY SABLOTRON FROM THE XML SOURCE
+ SABLOT-0-60.XML.
+ </P>
+ <P CLASS="">
+ THE MATERIAL IN THE FOLLOWING SECTIONS INCLUDES:
+ </P>
+ <UL>
+ <LI>SOME BACKGROUND INFORMATION ON XSLT AND SABLOTRON,</LI>
+ <LI>A DETAILED COMPARISON OF THE CURRENT VERSION OF
+ SABLOTRON TO THE XSLT SPEC,</LI>
+ <LI>SABLOTRON USAGE FROM THE COMMAND LINE OR AS A
+ LIBRARY.</LI>
+ </UL>
+ </DIV>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__60"></A>
+ <H2>
+ <A HREF="#TOC_I__60">2&NBSP;&NBSP;CHANGES FROM THE LAST RELEASE</A>
+ </H2>
+ <DIV>
+ <P CLASS="">PLEASE SEE THE RELEASE FILE.</P>
+ </DIV>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__74"></A>
+ <H2>
+ <A HREF="#TOC_I__74">3&NBSP;&NBSP;INTRODUCTION</A>
+ </H2>
+ <DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__81"></A>
+ <H3>
+ <A HREF="#TOC_I__74">3.1&NBSP;&NBSP;XSLT</A>
+ </H3>
+ <P CLASS="">XSLT IS A LANGUAGE ALLOWING TO TRANSFORM GIVEN XML DATA (THE
+ <I>INPUT</I>) ACCORDING TO A <I>STYLESHEET</I>. XSLT STYLESHEETS
+ ARE THEMSELVES XML DOCUMENTS; THAT IS, ALL INSTRUCTIONS OF THE
+ LANGUAGE ARE EXPRESSED IN THE FORM OF XML ELEMENTS. THE
+ <I>OUTPUT</I>, I.E. THE RESULT OF THE PROCESSING, IS TYPICALLY A
+ XML DOCUMENT AS WELL, ALTHOUGH THE SYNTACTIC REQUIREMENTS CAN BE
+ RELAXED TO ALLOW THE CREATION OF A HTML DOCUMENT (ONE THAT
+ CONTAINS UNCLOSED TAGS AND THE LIKE), OR EVEN PLAIN TEXT.
+ </P>
+ <P CLASS="">XSLT WAS DESIGNED BY THE WORLD WIDE WEB CONSORTIUM (W3C) AS
+ A PART OF THE XSL STYLESHEET LANGUAGE, WHERE IT IS COMPLEMENTED
+ BY A POWERFUL SET OF FORMATTING INSTRUCTIONS. THE MOST PRECISE
+ INFORMATION ABOUT XSLT CAN BE FOUND IN THE W3C RECOMMENDATION <A HREF="#REF-XSLT">[XSLT]</A>. IN PARTICULAR, APPENDIX B OF THE
+ RECOMMENDATION CONTAINS A HANDY SYNTAX TABLE. A GOOD TUTORIAL IS
+ <A HREF="#REF-BIBLE">[XMLBIBLE14]</A>.
+ </P>
+ <P CLASS="">OTHER W3C RECOMMENDATIONS ONE OFTEN NEEDS TO CONSULT ARE <A HREF="#REF-XML">[XML]</A> (FOR THE DEFINITION OF THE XML
+ LANGUAGE) AND <A HREF="#REF-XPATH">[XPATH]</A> (FOR DETAILS ON
+ XPATH, THE LANGUAGE USED TO FORM EXPRESSIONS IN XSLT AND
+ ELSEWHERE).
+ </P>
+ <P CLASS="">AN EXCELLENT SOURCE OF INFORMATION ABOUT XSLT (INDEED, ABOUT
+ ANYTHING RELATED TO XML AND SGML) IS <A HREF="#REF-RCOVER">[COVER]</A>; SEE ALSO <A HREF="#REF-XSLINFO">[XSLINFO]</A> AND <A HREF="#REF-XMLORG">[XMLORG]</A>.
+ </P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__154"></A>
+ <H3>
+ <A HREF="#TOC_I__74">3.2&NBSP;&NBSP;ON SABLOTRON</A>
+ </H3>
+ <P CLASS="">SABLOTRON IS A XSLT PROCESSOR (THOUGH NOT QUITE CONFORMING
+ YET..., SEE BELOW) WRITTEN IN C++. SINCE THE MACHINES WHERE IT
+ IS MEANT TO RUN INCLUDE VARIOUS SMALL MOBILE
+ CLIENTS, THE MAIN OBJECTIVES OF ITS DESIGN ARE THE FOLLOWING:
+ </P>
+ <UL>
+ <LI>PORTABILITY,</LI>
+ <LI>COMPACT CODE,</LI>
+ <LI>AS MUCH INDEPENDENCE ON OTHER RESOURCES (JAVA ETC.) AS
+ POSSIBLE.</LI>
+ </UL>
+ <P CLASS="">SABLOTRON IS A SINGLE SHARED LIBRARY
+ (<CODE>SABLOT.DLL</CODE> OR <CODE>LIBSABLOT.SO.0.60</CODE>). IT CAN
+ ALSO BE USED FROM THE COMMAND LINE VIA THE SIMPLE INTERFACE
+ CALLED <CODE>SABCMD</CODE>. SEE <A HREF="#INVOCATION">HERE</A> FOR
+ MORE INFORMATION.
+ </P>
+ <P CLASS="">THE ONLY SOFTWARE SABLOTRON RELIES ON IS <B>EXPAT</B>, THE
+ XML PARSER BY JAMES CLARK. SEE <A HREF="#EXPAT">BELOW</A> FOR
+ INFORMATION ON HOW TO GET EXPAT.
+ </P>
+ <P CLASS="">FOR INFORMATION ON THE AVAILABLE INTERFACES, E.G. FOR
+ PYTHON, PERL AND PHP, SEE <A HREF="HTTP://WWW.GINGERALL.COM">WWW.GINGERALL.COM</A>.
+ </P>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__227"></A>
+ <H2>
+ <A HREF="#TOC_I__227">4&NBSP;&NBSP;THE SOURCES</A>
+ </H2>
+ <DIV>
+ <P CLASS="">
+ SABLOTRON IS WRITTEN IN C++. THE SOURCE FILES COMPILE UNDER
+ WIN32 (USING MS VISUAL C++ 6.0) AND ON SOLARIS AND LINUX (USING
+ G++ 2.95.2) WITHOUT CHANGE.</P>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__238"></A>
+ <H3>
+ <A HREF="#TOC_I__227">4.1&NBSP;&NBSP;GETTING THE SOURCES</A>
+ </H3>
+ <P CLASS="">THE SOURCE OR BINARY DISTRIBUTIONS OF SABLOTRON CAN BE DOWNLOADED
+ FROM <A HREF="HTTP://WWW.GINGERALL.COM">WWW.GINGERALL.COM</A>. FOR
+ INSTRUCTIONS ON HOW TO BUILD THE SOURCES (IF ANY), REFER TO THE ACCOMPANYING INSTALL FILE.
+ </P>
+ <P CLASS="">IF YOU HAVE ACCESS TO THE GINGER ALLIANCE CVS SERVER, YOU
+ CAN GET THE WORKING VERSION OF SABLOTRON IN THE CVS MODULE
+ <CODE>GA</CODE>. THE ACCESS RIGHTS CAN BE OBTAINED ON
+ REQUEST FROM <A HREF="MAILTO:CVSADMIN at GINGERALL.COM">THE CVS ADMIN</A>.
+ </P>
+ <P CLASS="">
+ <A NAME="EXPAT"></A>
+ SINCE VERSION 0.50, SABLOTRON USES EXPAT 1.95.1, AVAILABLE FROM <A HREF="HTTP://EXPAT.SOURCEFORGE.ORG">SOURCEFORGE</A>.
+ </P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__280"></A>
+ <H3>
+ <A HREF="#TOC_I__227">4.2&NBSP;&NBSP;JOINING THE DEVELOPMENT</A>
+ </H3>
+ <P CLASS="">
+ SABLOTRON IS AN OPEN SOURCE PROJECT AND ALL VOLUNTEERS ARE MOST
+ WELCOME! THE DOCUMENTATION OF THE SOURCES IS STILL SOMEWHAT
+ SPARSE BUT WE WILL TRY TO IMPROVE IT. IF YOU FIND THE INVITATION
+ TO WORK ON SABLOTRON WITH US INTERESTING, PLEASE <A HREF="MAILTO:SABLOTRON at GINGERALL.COM">CONTACT US</A>. THERE IS ALSO
+ A MAILING LIST AVAILABLE, SEE <A HREF="HTTP://WWW.GINGERALL.COM">WWW.GINGERALL.COM</A>.
+ </P>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__305"></A>
+ <H2>
+ <A HREF="#TOC_I__305">5&NBSP;&NBSP;IMPLEMENTATION. SUPPORTED INSTRUCTIONS AND FUNCTIONS</A>
+ </H2>
+ <DIV>
+ <P CLASS="">THE INSTRUCTION SET SUPPORTED BY THIS VERSION OF SABLOTRON IS
+ ALREADY SUFFICIENT FOR MANY TRANSFORMATION TASKS (E.G. THE TASK OF
+ FORMATTING THIS DOCUMENT). ON THE OTHER
+ HAND, A COMPARISON OF IT TO THE XSLT SPECIFICATION <A HREF="#REF-XSLT">[XSLT]</A> SHOWS THAT MUCH IS STILL TO BE
+ DONE. THE PURPOSE OF THE
+ FOLLOWING SECTIONS IS TO DESCRIBE THE VARYING DEGREE OF SUPPORT
+ FOR THE ELEMENTS OF THE XSLT LANGUAGE. </P>
+ <P CLASS="">IT MAY BE HELPFUL TO REFER TO THE SYNTAX TABLE IN APPENDIX B
+ OF <A HREF="#REF-XSLT">[XSLT]</A>. THE INSTRUCTIONS/ATTRIBUTES THAT
+ ARE NOT LISTED AS UNSUPPORTED SHOULD BE IMPLEMENTED. THE <A HREF="MAILTO:SABLOTRON at GINGERALL.COM">AUTHORS</A> WILL APPRECIATE BEING
+ TOLD ABOUT ANY OMISSIONS FOUND IN THE FOLLOWING
+ DESCRIPTION.</P>
+ <P CLASS="">FOR READABILITY, I SOMETIMES OMIT THE <CODE>XSL:</CODE> PREFIX
+ FROM THE INSTRUCTION NAMES.</P>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__343"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.1&NBSP;&NBSP;TEMPLATES</A>
+ </H3>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ TEMPLATE, APPLY-TEMPLATES, CALL-TEMPLATE
+ </CODE>
+ </P>
+ <P CLASS="">
+ FULLY IMPLEMENTED. <CODE>XSL:SORT</CODE> IS SUPPORTED SINCE RELEASE 0.50.
+ </P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__364"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.2&NBSP;&NBSP;CONDITIONAL PROCESSING</A>
+ </H3>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ IF, CHOOSE, WHEN, OTHERWISE
+ </CODE>
+ </P>
+ <P CLASS="">FULLY IMPLEMENTED.
+ </P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__381"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.3&NBSP;&NBSP;LOOPS</A>
+ </H3>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>FOR-EACH</CODE>
+ </P>
+ <P CLASS="">FULLY IMPLEMENTED.
+ </P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__398"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.4&NBSP;&NBSP;VARIABLES AND PARAMETERS</A>
+ </H3>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>VARIABLE, PARAM, WITH-PARAM</CODE>
+ </P>
+ <P CLASS="">FULLY IMPLEMENTED. TOP-LEVEL VARIABLES AND PARAMETERS ARE
+ READ IN THE DOCUMENT ORDER, SO NO FORWARD REFERENCES ARE
+ RESOLVED. THIS IS A MINOR DEVIATION FROM THE SPEC. </P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__415"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.5&NBSP;&NBSP;ELEMENT CREATION</A>
+ </H3>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>ELEMENT, ATTRIBUTE, TEXT,
+ COMMENT, PROCESSING-INSTRUCTION, ATTRIBUTE-SET</CODE>
+ </P>
+ <P CLASS="">
+ <CODE>XSL:ATTRIBUTE-SET</CODE> IS NOT IMPLEMENTED. FOR THE
+ REST, <CODE>NAME</CODE> IS THE ONLY RECOGNIZED ATTRIBUTE (WHERE
+ APPLICABLE). LITERAL RESULT ELEMENTS WORK.</P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__439"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.6&NBSP;&NBSP;GLOBAL DEFINITIONS</A>
+ </H3>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>STYLESHEET, TRANSFORM, OUTPUT</CODE>
+ </P>
+ <P CLASS="">FOR <CODE>STYLESHEET</CODE> AND <CODE>TRANSFORM</CODE>,
+ THE ONLY RECOGNIZED ATTRIBUTE IS
+ <CODE>VERSION</CODE>. <CODE>XSL:OUTPUT</CODE> SHOULD WORK
+ (SEE BELOW FOR NOTES ON THE <CODE>ENCODING</CODE>
+ ATTRIBUTE). HTML INDENTATION HAS BEEN ADDED IN 0.60.
+ </P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__476"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.7&NBSP;&NBSP;VALUES AND COPYING</A>
+ </H3>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>VALUE-OF, COPY, COPY-OF</CODE>
+ </P>
+ <P CLASS="">
+ <CODE>COPY-OF</CODE> AND <CODE>VALUE-OF</CODE> ARE FULLY
+ IMPLEMENTED. <CODE>COPY</CODE> IS IMPLEMENTED EXCEPT FOR THE
+ <CODE>USE-ATTRIBUTE-SETS</CODE> ATTRIBUTE.</P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__508"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.8&NBSP;&NBSP;NAMESPACE PROCESSING</A>
+ </H3>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>NAMESPACE-ALIAS</CODE>
+ </P>
+ <P CLASS="">NAMESPACES SHOULD BE PROCESSED CORRECTLY. THE
+ <CODE>NAMESPACE-ALIAS</CODE> INSTRUCTION IS NOW SUPPORTED
+ (PATCH BY MAJOR).</P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__529"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.9&NBSP;&NBSP;SORTING</A>
+ </H3>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>SORT</CODE>
+ </P>
+ <P CLASS="">
+ <CODE>XSL:SORT</CODE> IS IMPLEMENTED SINCE 0.50. THERE ARE
+ MINOR LIMITATIONS:
+ </P>
+ <UL>
+ <LI>CURRENTLY, THE <CODE>LANG</CODE> ATTRIBUTE MAY ONLY
+ CONTAIN THE VALUES <CODE>"EN"</CODE> OR <CODE>"CZ"</CODE>.</LI>
+ <LI>
+ <CODE>CASE-ORDER</CODE> CANNOT BE SPECIFIED.</LI>
+ </UL>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__577"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.10&NBSP;&NBSP;WHITESPACE STRIPPING</A>
+ </H3>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>STRIP-SPACE, PRESERVE-SPACE</CODE>
+ </P>
+ <P CLASS="">ONLY THE DEFAULT WHITESPACE STRIPPING IS DONE. THAT IS,
+ ALL WHITESPACE-ONLY TEXT NODES IN ANY STYLESHEET, NOT APPEARING
+ INSIDE A <CODE>XSL:TEXT</CODE>, ARE REMOVED. THE TWO
+ INSTRUCTIONS FOR WHITESPACE STRIPPING AND PRESERVATION ARE
+ UNSUPPORTED.</P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__598"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.11&NBSP;&NBSP;INCLUDES</A>
+ </H3>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INCLUDE, IMPORT, APPLY-IMPORTS</CODE>
+ </P>
+ <P CLASS="">ONLY <CODE>XSL:INCLUDE</CODE> IS IMPLEMENTED. PROCESSING
+ INVOLVING MULTIPLE DOCUMENTS WORKS, BUT HAS TO GET MORE TESTING,
+ EG. WITH RESPECT TO <CODE>GENERATE-ID()</CODE>.</P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__623"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.12&NBSP;&NBSP;OTHER UNIMPLEMENTED INSTRUCTIONS</A>
+ </H3>
+ <UL>
+ <LI>
+ <CODE>XSL:KEY,</CODE>
+ </LI>
+ <LI>
+ <CODE>XSL:NUMBER,</CODE>
+ </LI>
+ <LI>
+ <CODE>XSL:FALLBACK.</CODE>
+ </LI>
+ </UL>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__654"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.13&NBSP;&NBSP;OUTPUT CONFORMANCE</A>
+ </H3>
+ <P CLASS="">THE OUTPUT MECHANISM IS MUCH CLOSER TO THE SPEC THAN IN
+ THE VERSIONS PRIOR TO 0.4. THE FOLLOWING ISSUES REMAIN FOR THE
+ HTML METHOD:</P>
+ <UL>
+ <LI>OUTPUT THE BOOLEAN ATTRIBUTES CORRECTLY.</LI>
+ <LI>DISABLE THE ESCAPING INSIDE
+ <CODE><SCRIPT></CODE> AND
+ <CODE><STYLE></CODE>
+ </LI>.
+ </UL>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__686"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.14&NBSP;&NBSP;XPATH EXPRESSIONS</A>
+ </H3>
+ <P CLASS="">ALMOST ALL FEATURES OF XPATH ARE FULLY IMPLEMENTED. THIS MEANS
+ THERE SHOULD BE NO PROBLEMS WITH EXPRESSIONS OF ANY KIND.</P>
+ <P CLASS="">ONE EXCEPTION RELATES TO AXES. THE <CODE>FOLLOWING</CODE> AND
+ <CODE>PRECEDING</CODE> AXES HAVEN'T BEEN IMPLEMENTED YET.</P>
+ <P CLASS="">ANOTHER POSSIBLE EXCEPTION MAY BE NUMBERS; WE DID NOT YET DO A
+ THOROUGH TEST OF ROUNDING, NANS, INFINITY, ETC.</P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__714"></A>
+ <H3>
+ <A HREF="#TOC_I__305">5.15&NBSP;&NBSP;BUILT-IN FUNCTIONS</A>
+ </H3>
+ <P CLASS="">
+ <A NAME="CORELIB"></A>ONLY A FEW FUNCTIONS FROM THE STANDARD
+ FUNCTION LIBRARY REMAIN
+ UNIMPLEMENTED:
+ </P>
+ <UL>
+ <LI>
+ <CODE>ID()</CODE>,</LI>
+ <LI>
+ <CODE>LANG()</CODE> (ACCEPTED BUT ALWAYS RETURNS TRUE),</LI>
+ <LI>
+ <CODE>KEY()</CODE>,</LI>
+ <LI>
+ <CODE>FORMAT-NUMBER()</CODE>,</LI>
+ <LI>
+ <CODE>UNPARSED-ENTITY-URI()</CODE>.</LI>
+ </UL>
+ <P CLASS="">AS FOR THE FUCTIONS THAT <I>ARE</I> IMPLEMENTED, THE
+ FOLLOWING IS A LIST OF DIFFERENCES FROM THE SPEC:
+ </P>
+ <UL>
+ <LI>
+ <CODE>DOCUMENT()</CODE> ONLY ACCEPTS ONE ARGUMENT, ALWAYS
+ GETTING THE BASE URI FROM THE STYLESHEET URI.
+ </LI>
+ <LI>
+ <CODE>STRING-LENGTH()</CODE> RETURNS THE BYTE LENGTH OF
+ THE UTF-8 REPRESENTATION OF THE STRING. THIS WILL TYPICALLY
+ DIFFER FROM THE ACTUAL LENGTH.
+ </LI>
+ <LI>
+ <CODE>GENERATE-ID()</CODE> MIGHT FAIL TO GENERATE UNIQUE IDENTIFIERS
+ WHEN SEVERAL INPUT DOCUMENTS ARE PRESENT (GIVING THE SAME ID TO
+ NODES FROM DIFFERENT DOCUMENTS).
+ </LI>
+ </UL>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__804"></A>
+ <H2>
+ <A HREF="#TOC_I__804">6&NBSP;&NBSP;OTHER IMPLEMENTATION-RELATED NOTES</A>
+ </H2>
+ <DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__811"></A>
+ <H3>
+ <A HREF="#TOC_I__804">6.1&NBSP;&NBSP;HANDLERS</A>
+ </H3>
+ <P CLASS="">IT IS POSSIBLE FOR THE USER TO SUPPLY THE FOLLOWING
+ HANDLERS TO SABLOTRON:
+ <UL>
+ <LI>MESSAGE HANDLER (TO BYPASS THE DEFAULT WAY OF DISPLAYING
+ ERROR AND WARNING MESSAGES AND LOGGING),</LI>
+ <LI>SCHEME HANDLER (TO RETRIEVE DOCUMENTS WHOSE URI USE AN
+ UNSUPPORTED SCHEME),</LI>
+ <LI>STREAMING HANDLER (AN EXPAT-LIKE INTERFACE TO THE XML
+ DOCUMENT WHICH IS THE RESULT OF THE PROCESSING),</LI>
+ <LI>'MISCELLANEOUS' HANDLER (WHICH WILL PROBABLY SERVER AS A
+ COLLECTIONS OF ODD CALLBACKS).</LI>
+ </UL>
+ </P>
+ <P CLASS="">
+ THE HANDLERS ARE SET USING <CODE>SABLOTREGHANDLER()</CODE>
+ FOR DETAILS CONCERNING THE INTERFACE OF THESE HANDLERS,
+ CONSULT THE HEADER FILES <CODE>SABLOT.H</CODE> AND
+ <CODE>SHANDLER.H</CODE>.
+ </P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__859"></A>
+ <H3>
+ <A HREF="#TOC_I__804">6.2&NBSP;&NBSP;ENCODINGS</A>
+ </H3>
+ <P CLASS="">
+ IN VERSION 0.52, THE ENCODING CONVERSION CAPABILITIES OF
+ SABLOTRON HAVE BEEN MUCH EXTENDED. THE MOST IMPORTANT FACT IS THE
+ FOLLOWING: IF YOU HAVE THE ICONV LIBRARY INSTALLED ON YOUR SYSTEM, YOU
+ CAN USE ANY ENCODING IT SUPPORTS (THAT IS, ALMOST ANY ENCODING
+ WHATSOEVER) FOR BOTH THE INPUT AND THE OUTPUT DOCUMENTS. ICONV
+ IS AVAILABLE ON MOST SYSTEMS (IT IS A STANDARD PART OF GLIBC2,
+ FOR INSTANCE). THERE ARE IMPLEMENTATIONS FOR WIN32 AS WELL.
+ </P>
+ <P CLASS="">IF ICONV IS NOT AVAILABLE, THE ENCODING MAY STILL BE SUPPORTED INTERNALLY BY
+ SABLOTRON. AT PRESENT, THE LIST IS OF SUCH ENCODINGS IS RATHER
+ SHORT: BESIDES UTF-8, THESE ARE UTF-16, ASCII, ISO-8859-1,
+ ISO-8859-2 AND WINDOWS-1250 ON INPUT, NONE ON OUTPUT. HOWEVER,
+ WE PLAN TO IMPLEMENT A HALF INDEPENDENT LIGHT-WEIGHT
+ CONVERSION LIBRARY FOR USE ON SYSTEMS WITHOUT ICONV,
+ EXTENDING THE SET OF INTERNALLY SUPPORTED ENCODINGS
+ CONSIDERABLY.
+ </P>
+ <P CLASS="">LASTLY, THE USER HAS THE OPTION TO IMPLEMENT A CUSTOM
+ ENCODING CONVERSION HANDLER, WHICH WILL BE ASKED TO PERFORM ANY UNSUPPORTED
+ CONVERSION. SEE THE <CODE>SHANDLER.H</CODE> HEADER FILE FOR
+ DETAILS.
+ </P>
+ <P CLASS="">THE DEFAULT INPUT AND OUTPUT ENCODING IS IN ALL CASES UTF-8.</P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__887"></A>
+ <H3>
+ <A HREF="#TOC_I__804">6.3&NBSP;&NBSP;OUTPUT METHODS</A>
+ </H3>
+ <P CLASS="">IN ADDITION TO THE STANDARD OUTPUT METHODS (XML, HTML AND
+ TEXT), IT IS POSSIBLE TO OUTPUT XHTML. DOCUMENTS OUTPUT USING
+ THIS METHOD OBEY THE XHTML 1.0 RULES (IN PARTICULAR, ALL EMPTY
+ ELEMENTS ARE CLOSED). TO CHOOSE THE METHOD, USE
+ <CODE><XSL:OUTPUT METHOD='XHTML'></CODE>. <B>PLEASE NOTE</B>
+ THAT THE NAME OF THIS METHOD WILL POSSIBLY BE CHANGED SINCE THE XSLT
+ SPEC REQUIRES ANY PROCESSOR-SPECIFIC METHODS TO HAVE QUALIFIED
+ NAMES, SAY <CODE>SAB:XHTML</CODE>. ON THE OTHER HAND, THE NAME
+ <CODE>XHTML</CODE> IS CONSIDERED IN THE XSLT 2.0 WORKING DRAFT.</P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__915"></A>
+ <H3>
+ <A HREF="#TOC_I__804">6.4&NBSP;&NBSP;URIS</A>
+ </H3>
+ <P CLASS="">SABLOTRON CAN HANDLE
+ TWO URI SCHEMES NATIVELY: 'FILE' AND 'ARG' (SEE
+ BELOW). MOREOVER, IT IS POSSIBLE TO USE THE FUNCTION
+ <CODE>SABLOTREGSCHEMEHANDLER</CODE> TO REGISTER AN EXTERNAL SCHEME
+ HANDLER WHICH WILL RECEIVE REQUESTS IN ALL OTHER SCHEMES. SEE
+ THE DOCUMENTATION IN <CODE>SABLOT.H</CODE> AND
+ <CODE>SHANDLER.H</CODE>.
+ </P>
+ <P CLASS="">RELATIVE URI REFERENCES ARE RESOLVED IN CONFORMANCE TO RFC
+ 2396. THE BASE URI IS WELL DEFINED WHEN THE RELATIVE REFERENCE APPEARS
+ INSIDE A XML DOCUMENT; WHEN INVOKING SABCMD, THE BASE URI IS
+ TAKEN TO CORRESPOND TO THE CURRENT WORKING DIRECTORY.
+ </P>
+ <P CLASS="">
+ <A NAME="FNAME-RULES"></A>WHEN SPECIFYING FILENAMES, THE
+ FOLLOWING RULES ARE IN EFFECT:
+ </P>
+ <UL>
+ <LI>SPECIFY THE "FILE:" SCHEME FOR ANY STANDARD FILES,
+ I.E. REFER TO <CODE>STDIN</CODE> AS <CODE>FILE://STDIN</CODE>
+ ETC.</LI>
+ <LI>SLASHES AND BACKSLASHES WORK EQUALLY FINE, IN WINDOWS AS
+ WELL AS LINUX.</LI>
+ <LI>TO INCLUDE A DRIVE LETTER UNDER WINDOWS
+ (E.G. <CODE>C:\DOC.XML</CODE>), IT IS NECESSARY TO SAY
+ <CODE>FILE://C:/DOC.XML</CODE>.
+ </LI>
+ </UL>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__983"></A>
+ <H3>
+ <A HREF="#TOC_I__804">6.5&NBSP;&NBSP;NAMED BUFFERS</A>
+ </H3>
+ <P CLASS="">
+ <A NAME="ARGSCHEME"></A>SABLOTRON INTRODUCES AN URI SCHEME
+ 'ARG:' WHICH ENABLES ONE TO USE STRINGS IN NAMED MEMORY
+ BUFFERS. THE BUFFER NAMES CAN HAVE A TREE-LIKE STRUCTURE SO THAT
+ A RELATIVE REFERENCE FROM A DOCUMENT IN A BUFFER CAN BE RESOLVED
+ AS POINTING TO ANOTHER BUFFER.
+ </P>
+ <P CLASS="">FOR INSTANCE, IF WE INVOKE SABLOTRON SPECIFYING THAT A
+ BUFFER NAMED <CODE>/MYBUF/1</CODE> CONTAINS THE STRING
+ "&LT;A>CONTENTS&LT;/A>", THEN THE EXPRESSION
+ </P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ DOCUMENT('ARG:/MYBUF/1')/A
+ </CODE>
+ </P>
+ <P CLASS="">HAS STRING-VALUE "CONTENTS". IF THE DOCUMENT IN ARG:/MYBUF/1
+ CONTAINED A RELATIVE URI REFERENCE "../THEIRBUF/2" THEN THIS
+ WOULD BE RESOLVED AS POINTING TO "ARG:/THEIRBUF/2".</P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__1015"></A>
+ <H3>
+ <A HREF="#TOC_I__804">6.6&NBSP;&NBSP;ERROR AND LOG MESSAGES</A>
+ </H3>
+ <P CLASS="">BY DEFAULT, SABLOTRON WRITES ERROR AND WARNING MESSAGES TO
+ STDERR, AND DOES NO LOGGING. BY A CALL TO
+ <CODE>SABLOTSETLOG()</CODE>, YOU CAN SPECIFY THE NAME OF THE LOG
+ FILE TO BE USED.</P>
+ <P CLASS="">BESIDES, YOU CAN USE <CODE>SABLOTREGHANDLER()</CODE>
+ TO OVERRIDE THE DEFAULT MESSAGE HANDLING. THE HANDLER YOU
+ REGISTER WILL RECEIVE ALL MESSAGES IN A STRUCTURED FORM THAT'S
+ EASY TO PROCESS AND FILTER. FOR DETAILS, SEE
+ THE DOCUMENTATION IN <CODE>SABLOT.H</CODE> AND
+ <CODE>SHANDLER.H</CODE>.</P>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__1048"></A>
+ <H2>
+ <A HREF="#TOC_I__1048">7&NBSP;&NBSP;THE C INTERFACE</A>
+ </H2>
+ <DIV>
+ <P CLASS="">
+ <A NAME="INVOCATION"></A>
+ </P>
+ <P CLASS="">
+ THIS SECTION DESCRIBES THE FUNCTIONS EXPORTED FROM THE
+ SABLOTRON LIBRARY. ALL OF THEM HAVE A RETURN TYPE OF 'INT'
+ AND RETURN AN ERROR FLAG (NONZERO SIGNALS AN ERROR). ERRORS
+ ARE REPORTED TO THE USER BY SABLOTRON ITSELF.
+ </P>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__1065"></A>
+ <H3>
+ <A HREF="#TOC_I__1048">7.1&NBSP;&NBSP;SHORTCUTS</A>
+ </H3>
+ <P CLASS="">
+ WE'LL FIRST DESCRIBE THE 'SHORTCUTS' THAT DO THE WHOLE
+ PROCESSING IN ONE CALL.
+ </P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTPROCESS(CHAR *SHEETURI, CHAR *INPUTURI, CHAR *RESULTURI,
+ CHAR **PARAMS, CHAR **ARGUMENTS, CHAR **RESULTARG);
+ </CODE>
+ </P>
+ <P CLASS="">
+ THIS IS THE BASIC FUNCTION. THE FIRST THREE OF ITS ARGUMENTS
+ ARE THE URIS OF THE XSLT STYLESHEET, THE XML SOURCE AND THE
+ RESULTING DOCUMENT, RESPECTIVELY. FOR SOME NOTES ON SPECIFYING
+ FILE NAMES, SEE <A HREF="#FNAME-RULES">ABOVE</A>.
+ </P>
+ <P CLASS="">
+ <CODE>PARAMS</CODE> IS AN ARRAY OF POINTERS TO THE NAMES
+ AND CONTENTS OF THE TOP-LEVEL STYLESHEET PARAMETERS. THUS,
+ <CODE>PARAMS[0]</CODE> IS A POINTER TO THE NULL-TERMINATED NAME
+ OF THE FIRST PARAMETER, <CODE>PARAMS[1]</CODE> POINTS TO THE
+ (NULL-TERMINATED) CONTENTS OF THE FIRST PARAMETER. THE FOLLOWING
+ TWO ARRAY ITEMS DO THE SAME FOR THE SECOND PARAMETER, ETC. THE
+ WHOLE ARRAY IS TERMINATED BY A NULL POINTER IN PLACE OF THE
+ NAME. IF NO PARAMETERS ARE TO BE PASSED, YOU CAN SPECIFY NULL
+ FOR <CODE>PARAMS</CODE> ITSELF.
+ </P>
+ <P CLASS="">
+ <CODE>ARGUMENTS</CODE> IS A SIMILAR ARRAY OF NAMED BUFFERS
+ TO BE PASSED TO THE STYLESHEET. (THEY CAN BE REFERRED TO VIA THE
+ 'ARG:' SCHEME, SEE <A HREF="#ARGSCHEME">ABOVE</A>.) AGAIN, THE
+ ARRAY IS A SEQUENCE OF (NAME, VALUE) PAIRS TERMINATED BY NULL IN
+ PLACE OF A NAME. IF NO NAMED BUFFERS ARE TO BE PASSED, YOU CAN
+ SPECIFY NULL FOR <CODE>ARGUMENTS</CODE> ITSELF.
+ </P>
+ <P CLASS="">
+ <CODE>RESULTARG</CODE> ENABLES ONE TO ACCESS THE
+ RESULTING DOCUMENT IN CASE THE OUTPUT WENT TO A NAMED BUFFER. IN
+ THAT SITUATION, <CODE>*RESULTARG</CODE> POINTS TO THE RESULTING
+ NULL-TERMINATED STRING, ALLOCATED BY SABLOTRON. YOU CAN PASS NULL
+ FOR <CODE>RESULTARG</CODE> IF THE OUTPUT IS SURE TO GO TO A
+ FILE.
+ </P>
+ <P CLASS="">
+ <B>NOTE:</B>WHEN YOU ARE DONE PROCESSING THE STRING
+ POINTED TO BY <CODE>*RESULTARG</CODE>, FREE IT USING <A HREF="#SABLOTFREE">
+ <CODE>SABLOTFREE()</CODE>
+ </A> - NEVER USE
+ <CODE>FREE()</CODE>. THE LATTER IS GUARANTEED TO PRODUCE A
+ SEGMENTATION FAULT UNDER LINUX.
+ </P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTPROCESSFILES(CHAR *STYLESHEETNAME,
+ CHAR *INPUTNAME,
+ CHAR *RESULTNAME);
+ </CODE>
+ </P>
+ <P CLASS="">A WRAPPER FOR <CODE>SABLOTPROCESS()</CODE> WORKING ON
+ FILES. THE PARAMETERS ARE THE NULL-TERMINATED FILE NAMES OF THE
+ XSLT STYLESHEET, THE XML INPUT AND THE RESULT,
+ RESPECTIVELY. SABLOTRON OPENS THESE FILES ITSELF AND CLOSES THEM
+ AFTER THE PROCESSING IS COMPLETE. VALUES LIKE "FILE://STDIN" ARE
+ ALLOWED.</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTPROCESSSTRINGS(CHAR *STYLESHEETSTR, CHAR *INPUTSTR, CHAR
+ **RESULTSTR);
+ </CODE>
+ </P>
+ <P CLASS="">ANOTHER WRAPPER FOR <CODE>SABLOTPROCESS()</CODE>, THIS
+ TIME FOR ACCESSING NAMED BUFFERS (I.E. USER-ALLOCATED MEMORY
+ BLOCKS)ONLY. THUS, THE FIRST PARAMETER IS A NULL-TERMINATED
+ STRING CONTAINING THE WHOLE STYLESHEET; THE SECOND PARAMETER
+ IS A NULL-TERMINATED STRING CONTAINING THE XML
+ INPUT. SABLOTRON ALLOCATES THE BUFFER FOR THE RESULTING STRING
+ AND RETURNS A POINTER TO IT IN RESULTSTR. HENCE, INVOKING
+ <CODE>PUTS(*RESULTSTR)</CODE> AFTER HAVING CALLED
+ <CODE>SABLOTPROCESSSTRINGS</CODE> SENDS THE RESULT TO
+ STDOUT. THE BUFFER ALLOCATED <B>MUST</B> BE FREED BY CALLING THE
+ FUNCTION <CODE>SABLOTFREE</CODE> DESCRIBED NEXT.
+ </P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__1205"></A>
+ <H3>
+ <A HREF="#TOC_I__1048">7.2&NBSP;&NBSP;BASIC FUNCTIONS</A>
+ </H3>
+ <P CLASS="">THE ABOVE SHORTCUTS JUST CALL THE BASIC, LOWER-LEVEL
+ FUNCTIONS DESCRIBED BELOW. NOTE THAT IF YOU NEED TO SET OPTIONS
+ FOR LOGGING ETC., YOU MAY NEED TO USE THE LOW-LEVEL
+ FUNCTIONS. </P>
+ <P CLASS="">A TYPICAL PROCESSING SESSION MAY LOOK LIKE THIS:</P>
+ <P CLASS="">
+ <PRE>
+ SABLOTHANDLE P;
+ CHAR *MY_BUF;
+ SABLOTCREATEPROCESSOR(&P);
+ SABLOTSETLOG(P, ...);
+ /* ...SET OTHER INSTANCE-SPECIFIC OPTIONS HERE... */
+ SABLOTRUNPROCESSOR(P, ...);
+ SABLOTGETRESULTARG(P, "ARG:/SOMENAME", &MY_BUF)
+ /* ...DO SOMETHING WITH MY_BUF... */
+ /* CAN RUN THE PROCESSOR AGAIN IF NECESSARY */
+ SABLOTRUNPROCESSOR(P, ...);
+ SABLOTDESTROYPROCESSOR(P);
+ </PRE>
+ </P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTCREATEPROCESSOR(SABLOTHANDLE *PROCESSORPTR);
+ </CODE>
+ </P>
+ <P CLASS="">CREATES AN INSTANCE OF SABLOTRON AND RETURNS A POINTER TO
+ IT IN *PROCESSORPTR. THIS POINTER IS PASSED ON ALL SUBSEQUENT
+ CALLS TO THIS INSTANCE. </P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTDESTROYPROCESSOR(SABLOTHANDLE PROCESSOR_);
+ </CODE>
+ </P>
+ <P CLASS="">DESTROYS AN INSTANCE OF THE PROCESSOR, DEALLOCATING ALL
+ THE MEMORY USED UP BY IT.</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTRUNPROCESSOR(SABLOTHANDLE PROCESSOR_,
+ CHAR *SHEETURI,
+ CHAR *INPUTURI,
+ CHAR *RESULTURI,
+ CHAR **PARAMS,
+ CHAR **ARGUMENTS);
+ </CODE>
+ </P>
+ <P CLASS="">PROCESSES DOCUMENTS USING THE GIVEN PROCESSOR INSTANCE AND
+ GIVEN PARAMS AND ARGS DEFINITIONS. SEE
+ <CODE>SABLOTPROCESS()</CODE>.</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTGETRESULTARG(SABLOTHANDLE PROCESSOR_,
+ CHAR *ARGURI,
+ CHAR **ARGVALUE);
+ </CODE>
+ </P>
+ <P CLASS="">COPIES THE RESULT 'ARG' BUFFER WITH THE GIVEN URI,
+ RETURNING A POINTER TO THE NEWLY-ALLOCATED BLOCK IN
+ *ARGVALUE. IF NO SUCH BUFFER EXISTS, RETURNS NULL IN *ARGVALUE.
+ </P>
+ <P CLASS="">THIS FUNCTION IS NECESSARY, BECAUSE IF THE RESULT DOCUMENT
+ IS OUTPUT TO MEMORY, IT WOULD BE LOST WHEN
+ <CODE>SABLOTDESTROYPROCESSOR()</CODE> IS CALLED. WHEN
+ DEALLOCATING THE COPY OBTAINED FROM
+ <CODE>SABLOTGETRESULTARG()</CODE>, USE <CODE>SABLOTFREE</CODE>
+ (NEVER <CODE>FREE()</CODE>). </P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTFREERESULTARGS(SABLOTHANDLE PROCESSOR_);
+ </CODE>
+ </P>
+ <P CLASS="">REMOVES THE SABLOTRON-INTERNAL COPIES OF THE 'ARG' BUFFERS
+ FROM THE LAST SABLOTRON RUN. NORMALLY, THERE SHOULD BE NO REASON
+ TO CALL THIS FUNCTION AS IT IS CALLED AUTOMATICALLY ON BOTH
+ <CODE>SABLOTRUNPROCESSOR()</CODE> AND
+ <CODE>SABLOTDESTROYPROCESSOR()</CODE>. </P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ <A NAME="SABLOTFREE"></A>
+ INT SABLOTFREE(CHAR *RESULTBUF);
+ </CODE>
+ </P>
+ <P CLASS="">THIS FUNCTION FREES THE BUFFER ALLOCATED ON PREVIOUS CALL
+ TO <CODE>SABLOTPROCESSSTRINGS</CODE>. CALLING IT WITH AN
+ INVALID POINTER WILL CAUSE A CRASH.
+ </P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTREGHANDLER(
+ SABLOTHANDLE PROCESSOR_,
+ HANDLERTYPE TYPE,
+ VOID *HANDLER,
+ VOID *USERDATA);
+ </CODE>
+ </P>
+ <P CLASS="">REGISTERS AN EXTERNAL HANDLER. <CODE>TYPE</CODE> CAN BE
+ <CODE>HLR_MESSAGE</CODE>, <CODE>HLR_SCHEME</CODE>,
+ <CODE>HLR_SAX</CODE>, <CODE>HLR_MISC</CODE> OR
+ <CODE>HLR_ENC</CODE>.
+ <CODE>HANDLER</CODE> POINTS TO THE
+ CALLBACK VECTOR OF THE APPROPRIATE TYPE. <CODE>USERDATA</CODE>
+ IS A DATA ITEM TO PASSED TO ALL CALLBACKS OF THIS PARTICULAR
+ HANDLER. FOR DETAILS, CHECK THE <CODE>SABLOT.H</CODE> AND
+ <CODE>SHANDLER.H</CODE> HEADER FILES.
+ </P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTUNREGHANDLER(
+ SABLOTHANDLE PROCESSOR_,
+ HANDLERTYPE TYPE,
+ VOID *HANDLER,
+ VOID *USERDATA);
+ </CODE>
+ </P>
+ <P CLASS="">UNREGISTERS THE GIVEN EXTERNAL HANDLER. FOR DETAILS, CHECK THE
+ <CODE>SABLOT.H</CODE> AND <CODE>SHANDLER.H</CODE> HEADER
+ FILES.</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTSETLOG(
+ SABLOTHANDLE PROCESSOR_,
+ CONST CHAR *LOGFILENAME,
+ INT LOGLEVEL);
+ </CODE>
+ </P>
+ <P CLASS="">SETS THE LOG FILENAME. THE <CODE>LOGLEVEL</CODE> PARAMETER
+ IS CURRENTLY NOT USED. PASS NULL FOR <CODE>LOGFILENAME</CODE> TO
+ TURN LOGGING OFF (DEFAULT). </P>
+ <P CLASS="">THE OTHER FUNCTIONS PUBLISHED BY SABLOT.H HAVE BEEN
+ INCLUDED FOR EXPERIMENTAL REASONS OR FOR COMPATIBILITY, AND IT
+ IS BETTER NOT TO USE THEM.
+ </P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ INT SABLOTCLEARERROR(SABLOTHANDLE PROCESSOR_);
+ </CODE>
+ </P>
+ <P CLASS="">CLEARS THE 'PENDING ERROR' FLAG FOR THIS INSTANCE OF
+ SABLOTRON.</P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__1416"></A>
+ <H3>
+ <A HREF="#TOC_I__1048">7.3&NBSP;&NBSP;GENERALIZED INTERFACE FUNCTIONS</A>
+ </H3>
+ <P CLASS="">THE IMPLEMENTATION OF THE <A HREF="#DOM">DOM INTERFACE</A>
+ BROUGHT THE NEED TO EXTEND SOME OF THE FUNCTIONS DESCRIBED IN
+ THE PREVIOUS SECTION. THIS EXTENSION ENABLES THE USER TO:
+ </P>
+ <UL>
+ <LI>PROCESS DOCUMENTS CREATED BY THE DOM FUNCTIONS, AND</LI>
+ <LI>PROCESS FREQUENTLY USED DOCUMENTS IN PRE-PARSED FORM.</LI>
+ </UL>
+ <P CLASS="">AN OBJECT CALLED <I>SITUATION</I> IS USED TO PROVIDE A
+PERSISTENT CONTEXT FOR ALL CALLS TO THE DOM-RELATED
+FUNCTIONS. FUNCTIONS USED TO MANIPULATE THE SITUATION ARE DESCRIBED IN
+<A HREF="#SITUATION">THE FOLLOWING SECTION</A>.</P>
+ <P CLASS="">
+ <B>NOTE:</B> IF NOT SPECIFIED OTHERWISE, ALL THESE
+ FUNCTIONS RETURN AN ERROR CODE. A POSITIVE VALUE INDICATES AN ERROR.</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INT SABLOTCREATEDOCUMENT(SABLOTSITUATION S,
+ SDOM_DOCUMENT *D);
+ </CODE>
+ </P>
+ <P CLASS="">CREATES AN EMPTY DOCUMENT. TYPICALLY FOLLOWED BY CALLS TO
+ DOM FUNCTIONS TO POPULATE THE DOCUMENT.</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INT SABLOTDESTROYDOCUMENT(SABLOTSITUATION S,
+ SDOM_DOCUMENT D);
+ </CODE>
+ </P>
+ <P CLASS="">DESTROYS A DOCUMENT, FREEING ALL THE NODES IT HAS CREATED.</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INT SABLOTPARSE(SABLOTSITUATION S,
+ CONST CHAR *URI, SDOM_DOCUMENT *D);
+ </CODE>
+ </P>
+ <P CLASS="">READS IN A DOCUMENT FROM THE GIVEN URI.</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INT SABLOTPARSEBUFFER(SABLOTSITUATION S,
+ CONST CHAR *BUFFER, SDOM_DOCUMENT *D);
+ </CODE>
+ </P>
+ <P CLASS="">READS IN A DOCUMENT FROM THE GIVEN IN-MEMORY BUFFER.</P>
+ <P CLASS="">THESE FUNCTIONS HAVE VARIANTS TO BE USED IF THE DOCUMENT
+ IS TO BE INTERPRETED AS AN XSLT STYLESHEET, NAMELY
+ <CODE>SABLOTPARSESTYLESHEET</CODE> AND
+ <CODE>SABLOTPARSESTYLESHEETBUFFER</CODE>.</P>
+ <P CLASS="">THE FOLLOWING FUNCTIONS GENERALIZE
+ <CODE>SABLOTRUNPROCESSOR</CODE> IN THAT THEY MAKE IT POSSIBLE TO
+ UTILIZE AN EXTRA KIND OF A SOURCE DOCUMENT: A DOM TREE.</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INT SABLOTRUNPROCESSORGEN(SABLOTSITUATION S,
+ VOID *PROCESSOR_,
+ CHAR *SHEETURI,
+ CHAR *INPUTURI,
+ CHAR *RESULTURI);
+ </CODE>
+ </P>
+ <P CLASS="">A KEY INGREDIENT OF THE EXTENDED INTERFACE. ONLY THE URIS
+ OF THE SOURCES AND OF THE RESULT DOCUMENT ARE GIVEN TO IT. THE
+ REST OF THE INFORMATION PASSED TO
+ <CODE>SABLOTRUNPROCESSOR</CODE> IS CONVEYED THROUGH
+ <CODE>SABLOTADDARGBUFFER,</CODE> <CODE>SABLOTADDARGTREE</CODE>
+ AND <CODE>SABLOTADDPARAM.</CODE> THE SCHEME PART OF THE
+ STYLESHEET URI OR THE INPUT URI MAY BE "ARG:", IN WHICH
+ CASE THEY REFER TO A BUFFER OR TREE PASSED BY THESE
+ FUNCTIONS. </P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INT SABLOTADDARGBUFFER(SABLOTSITUATION S,
+ VOID *PROCESSOR_,
+ CONST CHAR *ARGNAME,
+ CONST CHAR *BUFFERVALUE);
+</CODE>
+ </P>
+ <P CLASS="">CREATES A NAMED BUFFER FOR THE NEXT PROCESSOR RUN. THE
+ BUFFER'S NAME AND CONTENTS ARE PASSED AS ARGUMENTS. THE NAME
+ IS INTERPRETED RELATIVE TO THE 'ARG:/' SCHEME.</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INT SABLOTADDARGTREE(SABLOTSITUATION S,
+ VOID *PROCESSOR_,
+ CONST CHAR *ARGNAME,
+ SDOM_DOCUMENT TREE);
+</CODE>
+ </P>
+ <P CLASS="">ASSOCIATES THE GIVEN DOCUMENT WITH A NAME FOR THE NEXT
+ PROCESSOR RUN. THE DOCUMENT IS <I>NOT</I> DESTROYED AFTER THE
+ RUN IS FINISHED. THE NAME IS INTERPRETED RELATIVE TO THE 'ARG:/'
+ SCHEME.</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INT SABLOTADDPARAM(SABLOTSITUATION S,
+ VOID *PROCESSOR_,
+ CONST CHAR *PARAMNAME,
+ CONST CHAR *PARAMVALUE);
+ </CODE>
+ </P>
+ <P CLASS="">ADDS A GLOBAL STYLESHEET PARAMETER FOR THE NEXT PROCESSOR
+ RUN.</P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__1578"></A>
+ <H3>
+ <A HREF="#TOC_I__1048">7.4&NBSP;&NBSP;THE SITUATION OBJECT</A>
+ </H3>
+ <P CLASS="">
+ <A NAME="SITUATION"></A>AT PRESENT, THE SITUATION OBJECT PRIMARILY HOLDS INFORMATION ON ANY PENDING ERRORS. A
+SITUATION IS CREATED USING</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INT SABLOTCREATESITUATION(SABLOTSITUATION
+ *SP);</CODE>
+ </P>
+ <P CLASS="">AND DESTROYED BY</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INT SABLOTDESTROYSITUATION(SABLOTSITUATION
+ S);</CODE>
+ </P>
+ <P CLASS="">TO CLEAR THE PENDING ERROR FLAG IN A SITUATION, USE</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>INT SABLOTCLEARSITUATION(SABLOTSITUATION
+ S);</CODE>
+ </P>
+ <P CLASS="">THE FOLLOWING SELF-EXPLANATORY FUNCTIONS EXTRACT PARTS OF THE ERROR INFORMATION
+ FROM THE SITUATION:</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ CONST CHAR *SABLOTGETERRORURI(SABLOTSITUATION S);<BR>
+ INT SABLOTGETERRORLINE(SABLOTSITUATION S);<BR>
+ CONST CHAR *SABLOTGETERRORMSG(SABLOTSITUATION S);
+ </CODE>
+ </P>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__1631"></A>
+ <H3>
+ <A HREF="#TOC_I__1048">7.5&NBSP;&NBSP;DOCUMENT OBJECT MODEL (DOM) FUNCTIONS</A>
+ </H3>
+ <P CLASS="">
+ <A NAME="DOM"></A>STARTING WITH VERSION 0.60, SABLOTRON IMPLEMENTS
+ A MAJOR SUBSET OF THE DOM LEVEL 1 CORE SPECIFICATION <A HREF="#REF-DOM">[DOM]</A>. A BRIEF
+ DESCRIPTION OF THE IMPLEMENTED INTERFACE FOLLOWS; FOR MORE
+ DETAILS, PLEASE REFER TO THE HEADER FILE NAMED
+ <CODE>SDOM.H.</CODE>
+ </P>
+ <P CLASS="">ALL OF THE NAMES RELATED TO THE DOM INTERFACE START WITH
+ SDOM_ (FOR SABLOT DOM).</P>
+ <P CLASS="">MAJOR NEW TYPES ARE <CODE>SDOM_DOCUMENT</CODE> (A DOM TREE) AND
+ <CODE>SDOM_NODE</CODE> (A NODE OF THE TREE). A DOCUMENT CAN ALSO BE USED IN
+ PLACE OF A NODE. THIS REFLECTS THE FACT IN THE DOM SPEC,
+ DOCUMENT IS A SUBCLASS OF NODE. WHEN USED IN THIS WAY, THE
+ DOCUMENT REPRESENTS ITS OWN ROOT NODE (WHICH IS NOT THE SAME AS
+ THE `ROOT ELEMENT').</P>
+ <P CLASS="">OTHER TYPES INCLUDE:</P>
+ <UL>
+ <LI>
+ <CODE>SDOM_CHAR:</CODE> A DOM CHARACTER TYPE. CURRENTLY, THIS IS JUST
+ CHAR. NOTE THAT THE DOM SPEC REQUIRES THAT THE DOM
+ IMPLEMENTATIONS WORK WITH UTF-16. SABLOTRON DEVIATES FROM THIS
+ BY USING UTF-8 INSTEAD. A SEPARATE SET OF FUNCTIONS TAKING
+ UTF-16 STRINGS WILL BE PROVIDED.</LI>
+ <LI>
+ <CODE>SDOM_NODETYPE:</CODE> A NODE TYPE ENUM. SOME OF THE VALUES ARE
+ <CODE>SDOM_ELEMENT_NODE,</CODE> <CODE>SDOM_ATTRIBUTE_NODE</CODE> AND <CODE>SDOM_TEXT_NODE.</CODE> SEE
+ <CODE>SDOM.H</CODE> FOR THE REST.</LI>
+ <LI>
+ <CODE>SDOM_NODELIST:</CODE> A NODE LIST RETURNED BY SOME OF THE
+ FUNCTIONS.</LI>
+ <LI>
+ <CODE>SDOM_EXCEPTION:</CODE> DOM EXCEPTION CODES ENUM, WITH VALUES SUCH
+ AS <CODE>SDOM_NOT_FOUND_ERR</CODE> OR <CODE>SDOM_INVALID_NODE_TYPE</CODE>. SEE <CODE>SDOM.H</CODE>
+ FOR DETAILS.</LI>
+</UL>
+ <P CLASS="">THE FUNCTIONS LISTED BELOW ARE IMPLEMENTED MORE OR LESS AS DEFINED IN
+ THE DOM LEVEL 1 SPECIFICATION, WITH TWO EXCEPTIONS:
+ THEIR NAMES ARE PREFIXED WITH <CODE>SDOM_</CODE> AND THE FIRST ARGUMENT IS
+ ALWAYS A <CODE>SABLOTSITUATION.</CODE> ALL THE FUNCTIONS RETURN
+ A <CODE>SDOM_EXCEPTION.</CODE> </P>
+ <UL>
+<LI>
+ <CODE>CREATEELEMENT, CREATEATTRIBUTE, CREATETEXTNODE,
+CREATECDATASECTION, CREATECOMMENT, CREATEPROCESSINGINSTRUCTION</CODE>
+ </LI>
+<LI>
+ <CODE>GETNODETYPE, GETNODENAME, SETNODENAME, GETNODEVALUE, SETNODEVALUE</CODE>
+ </LI>
+<LI>
+ <CODE>GETPARENTNODE, GETFIRSTCHILD, GETLASTCHILD, GETPREVIOUSSIBLING,
+GETNEXTSIBLING, GETOWNERDOCUMENT</CODE>
+ </LI>
+<LI>
+ <CODE>INSERTBEFORE, APPENDCHILD, REMOVECHILD, REPLACECHILD</CODE>
+ </LI>
+<LI>
+ <CODE>CLONENODE</CODE>
+ </LI>
+<LI>
+ <CODE>GETATTRIBUTE, SETATTRIBUTE, REMOVEATTRIBUTE, GETATTRIBUTELIST</CODE>
+ </LI>
+</UL>
+ <P CLASS="">SEVERAL FUNCTIONS HAVE BEEN ADDED:</P>
+ <UL>
+<LI>
+ <CODE>DISPOSENODE</CODE> FREES ALL MEMORY USED BY THE GIVEN NODE</LI>
+<LI>
+ <CODE>CLONEFOREIGNNODE</CODE> CLONES A NODE FROM A DIFFERENT
+DOCUMENT</LI>
+<LI>
+ <CODE>DOCTOSTRING</CODE> SERIALIZES THE DOCUMENT, RETURNING THE
+RESULTING STRING</LI>
+<LI>
+ <CODE>XQL</CODE> PERFORMS AN XPATH QUERY ON THE DOM TREE,
+RETURNING A LIST OF THE NODES SATISFYING IT.</LI>
+</UL>
+ <P CLASS="">IN ADDITION, THERE ARE SOME FUNCTIONS USED TO MANIPULATE
+ THE NODE LISTS RETURNED BY <CODE>XQL</CODE> AND
+ <CODE>GETATTRIBUTELIST</CODE>. THESE INCLUDE
+ <CODE>GETNODELISTLENGTH</CODE>, <CODE>GETNODELISTITEM</CODE> AND
+ <CODE>DISPOSENODELIST</CODE>.</P>
+ <P CLASS="">FINALLY, THERE ARE FUNCTIONS TO EXTRACT DOM
+ EXCEPTION-RELATED INFORMATION FROM THE SITUATION OBJECT, NAMELY
+ <CODE>GETEXCEPTIONCODE</CODE>, <CODE>GETEXCEPTIONMESSAGE</CODE>
+ AND <CODE>GETEXCEPTIONDETAILS</CODE>.</P>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__1870"></A>
+ <H2>
+ <A HREF="#TOC_I__1870">8&NBSP;&NBSP;THE COMMAND LINE INTERFACE</A>
+ </H2>
+ <DIV>
+ <P CLASS="">SABLOTRON COMES WITH A COMMAND-LINE INTERFACE TO THE
+ SHARED LIBRARY, WHICH IS A PROGRAM NAMED
+ <CODE>SABCMD</CODE>. AT PRESENT, <CODE>SABCMD</CODE> IS INVOKED
+ AS FOLLOWS:</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ SABCMD [<I>OPTIONS</I>] <I>STYLESHEET</I> [<I>INPUT</I> [<I>RESULT</I>]] [<I>ASSIGNMENTS</I>]
+ </CODE>
+ </P>
+ <P CLASS="">THE ARGUMENTS ARE THE URIS OF THE XSLT STYLESHEET, THE
+ XML INPUT DOCUMENT, AND THE RESULTING DOCUMENT, RESPECTIVELY. THE
+ DEFAULT FOR <CODE>
+ <I>INPUT</I>
+ </CODE> IS
+ <CODE>FILE://STDIN</CODE> (MEANING PLAIN OLD STDIN);
+ <CODE>
+ <I>RESULT</I>
+ </CODE> DEFAULTS TO
+ <CODE>FILE://STDOUT</CODE>. FILENAMES HAVE TO INCLUDE THE EXTENSION (IF
+ ANY).</P>
+ <P CLASS="">YOU CAN DISPLAY THE LIST OF AVAILABLE OPTIONS BY TYPING
+ <CODE>SABCMD --HELP</CODE>. AMONG THE MORE USEFUL ONES ARE
+ <CODE>--LOG-FILE</CODE> (FOR SETTING THE LOG FILE) AND
+ <CODE>--MEASURE</CODE> (MEASURES AND OUTPUTS THE TOTAL
+ PROCESSING TIME).
+ </P>
+ <P CLASS="">
+ <A HREF="#FNAME-RULES">THE RULES FOR FILENAMES</A> ARE THE SAME AS
+ WITH <CODE>SABLOTPROCESS()</CODE>.
+ </P>
+ <P CLASS="">
+ <CODE>ASSIGNMENTS</CODE> IS A SERIES OF DEFINITIONS OF THE
+ FORM:</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ NAME1=VALUE1 NAME2=VALUE2 ...
+ </CODE>
+ </P>
+ <P CLASS="">
+ ASSIGNING VALUES TO TOP-LEVEL STYLESHEET PARAMETERS AND TO NAMED
+ BUFFERS. THESE TWO CASES ARE DISTINGUISHED BY A LEADING '$' IN
+ THE NAME OF A STYLESHEET PARAMETER. THE NAMES OF THE BUFFERS DO
+ <I>NOT</I> START WITH "ARG:". THEY MAY START WITH A SLASH; IF
+ THEY DON'T, THE SLASH IS PREPENDED.
+ </P>
+ <P CLASS="">
+ <B>NOTE:</B> IN MOST CASES, IT WILL BE NECESSARY TO QUOTE
+ THE INDIVIDUAL ASSIGNMENTS. WHETHER TO USE SINGLE OR DOUBLE
+ QUOTES MAY DEPEND ON THE SHELL USED (OR MAY IT?) SINGLE QUOTES
+ WORK FOR BASH, DOUBLE QUOTES WORK IN WINDOWS.
+ </P>
+ <P CLASS="">IF THE RESULT URI REFERS TO A NAMED BUFFER, THE OUTPUT
+ WOULD NORMALLY REMAIN BURIED IN MEMORY. SABCMD DUMPS THE BUFFER TO STANDARD
+ OUTPUT INSTEAD.
+ </P>
+ <P CLASS="">TO SUM UP AND GIVE AN EXAMPLE, THE FOLLOWING WOULD BE A
+ VALID INVOCATION OF SABCMD:</P>
+ <P CLASS="" STYLE="BACKGROUND-COLOR: #FFFFEE">
+ <CODE>
+ SABCMD SHEET.XSL ARG:/THE_INPUT "THE_INPUT=&LT;A/>"
+ "$USE_DEFAULTS=1"
+ </CODE>
+ </P>
+ <P CLASS="">THIS PROCESSES THE DOCUMENT PASSED IN THE BUFFER NAMED
+ THE_INPUT, USING A STYLESHEET FOUND IN FILE "SHEET.XSL" IN THE
+ WORKING DIRECTORY. WE ASSIGN 1 TO THE TOP-LEVEL PARAMETER CALLED
+ "USE_DEFAULTS". THE OUTPUT GOES TO STDOUT BY DEFAULT.
+ </P>
+ </DIV>
+ </DIV>
+ <DIV CLASS="AFTERSKIP">
+ <A NAME="I__2013"></A>
+ <H2>
+ <A HREF="#TOC_I__2013">9&NBSP;&NBSP;REFERENCES</A>
+ </H2>
+ <DIV>
+ <DL>
+ <DT>
+ <A NAME="REF-XSLT"></A>[XSLT]</DT>
+ <DD>
+ <A HREF="HTTP://WWW.W3.ORG/TR/1999/REC-XSLT-19991116">
+ XSL TRANSFORMATIONS (XSLT) VERSION 1.0
+ </A>
+ </DD>
+
+ <DT>
+ <A NAME="REF-XPATH"></A>[XPATH]</DT>
+ <DD>
+ <A HREF="HTTP://WWW.W3.ORG/TR/1999/REC-XPATH-19991116">
+ XML PATH LANGUAGE (XPATH) VERSION 1.0
+ </A>
+ </DD>
+
+ <DT>
+ <A NAME="REF-XML"></A>[XML]</DT>
+ <DD>
+ <A HREF="HTTP://WWW.W3.ORG/TR/1998/REC-XML-19980210">
+ EXTENSIBLE MARKUP LANGUAGE (XML) 1.0
+ </A>
+ </DD>
+
+ <DT>
+ <A NAME="REF-DOM"></A>[DOM]</DT>
+ <DD>
+ <A HREF="HTTP://WWW.W3.ORG/TR/REC-DOM-LEVEL-1">
+ DOCUMENT OBJECT MODEL LEVEL 1 SPECIFICATION, VERSION 1.0
+ </A>
+ </DD>
+
+ <DT>
+ <A NAME="REF-RCOVER"></A>[COVER]</DT>
+ <DD>
+ <A HREF="HTTP://WWW.OASIS-OPEN.ORG/COVER/SGML-XML.HTML">
+ THE XML COVER PAGES</A>
+ </DD>
+
+ <DT>
+ <A NAME="REF-XMLORG"></A>[XMLORG]</DT>
+ <DD>
+ <A HREF="HTTP://XML.ORG">XML.ORG</A>
+ </DD>
+
+ <DT>
+ <A NAME="REF-XSLINFO"></A>[XSLINFO]</DT>
+ <DD>
+ <A HREF="HTTP://WWW.XSLINFO.COM">XSLINFO.COM</A>
+ </DD>
+
+ <DT>
+ <A NAME="REF-BIBLE"></A>[XMLBIBLE14]</DT>
+ <DD>
+ <A HREF="HTTP://METALAB.UNC.EDU/XML/BOOKS/BIBLE/UPDATES/14.HTML">
+ HAROLD, E. R.: XML BIBLE, CHAPTER 14 (ONLINE PRESENTATION)
+ </A>
+ </DD>
+ </DL>
+ </DIV>
+ </DIV>
+ <HR>
+ <P STYLE="FONT-STYLE: ITALIC; MARGIN-LEFT: 0">(C) 2000 GINGER ALLIANCE S.R.O.</P>
+ </BODY>
+</HTML>
\ No newline at end of file
diff --git a/test/uc_exit_wu b/test/uc_exit_wu
new file mode 100644
index 0000000..242e4ff
--- /dev/null
+++ b/test/uc_exit_wu
@@ -0,0 +1,10 @@
+<file_info>
+ <number>0</number>
+</file_info>
+<workunit>
+ <file_ref>
+ <file_number>0</file_number>
+ <open_name>in</open_name>
+ </file_ref>
+ <command_line>-exit</command_line>
+</workunit>
diff --git a/test/uc_multiple_download_wu b/test/uc_multiple_download_wu
new file mode 100644
index 0000000..dd67573
--- /dev/null
+++ b/test/uc_multiple_download_wu
@@ -0,0 +1,14 @@
+<file_info>
+ <name><INFILE_0/></name>
+ <url><DOWNLOAD_URL/>/<INFILE_0/></url>
+ <url><DOWNLOAD_URL/>0/<INFILE_0/></url>
+ <url><DOWNLOAD_URL/>1/<INFILE_0/></url>
+ <url><DOWNLOAD_URL/>2/<INFILE_0/></url>
+ <md5_cksum><MD5_0/></md5_cksum>
+</file_info>
+<workunit>
+ <file_ref>
+ <file_name><INFILE_0/></file_name>
+ <open_name>in</open_name>
+ </file_ref>
+</workunit>
diff --git a/test/uc_multiple_uploads_result b/test/uc_multiple_uploads_result
new file mode 100644
index 0000000..6078c6f
--- /dev/null
+++ b/test/uc_multiple_uploads_result
@@ -0,0 +1,16 @@
+<file_info>
+ <name><OUTFILE_0/></name>
+ <generated_locally/>
+ <upload_when_present/>
+ <max_nbytes>100000</max_nbytes>
+ <url><UPLOAD_URL/></url>
+ <url><UPLOAD_URL/>0</url>
+ <url><UPLOAD_URL/>1</url>
+ <url><UPLOAD_URL/>2</url>
+</file_info>
+<result>
+ <file_ref>
+ <file_name><OUTFILE_0/></file_name>
+ <open_name>out</open_name>
+ </file_ref>
+</result>
diff --git a/test/uc_result_sticky b/test/uc_result_sticky
new file mode 100644
index 0000000..7c03092
--- /dev/null
+++ b/test/uc_result_sticky
@@ -0,0 +1,14 @@
+<file_info>
+ <name><OUTFILE_0/></name>
+ <generated_locally/>
+ <upload_when_present/>
+ <max_nbytes>100000</max_nbytes>
+ <url><UPLOAD_URL/></url>
+ <sticky/>
+</file_info>
+<result>
+ <file_ref>
+ <file_name><OUTFILE_0/></file_name>
+ <open_name>out</open_name>
+ </file_ref>
+</result>
diff --git a/test/uc_sig_wu b/test/uc_sig_wu
new file mode 100644
index 0000000..96a1c3d
--- /dev/null
+++ b/test/uc_sig_wu
@@ -0,0 +1,10 @@
+<file_info>
+ <number>0</number>
+</file_info>
+<workunit>
+ <file_ref>
+ <file_number>0</file_number>
+ <open_name>in</open_name>
+ </file_ref>
+ <command_line>-signal</command_line>
+</workunit>
diff --git a/test/uc_small_correct_output b/test/uc_small_correct_output
new file mode 100644
index 0000000..26f7a5f
--- /dev/null
+++ b/test/uc_small_correct_output
@@ -0,0 +1 @@
+FJFIWFWNFWIEOWEFNKJ
diff --git a/test/uc_wu_nodelete b/test/uc_wu_nodelete
new file mode 100644
index 0000000..f92f1d5
--- /dev/null
+++ b/test/uc_wu_nodelete
@@ -0,0 +1,9 @@
+<file_info>
+ <number>0</number>
+</file_info>
+<workunit>
+ <file_ref>
+ <file_number>0</file_number>
+ <open_name>in</open_name>
+ </file_ref>
+</workunit>
diff --git a/test/uc_wu_sticky b/test/uc_wu_sticky
new file mode 100644
index 0000000..4b0b2ba
--- /dev/null
+++ b/test/uc_wu_sticky
@@ -0,0 +1,10 @@
+<file_info>
+ <number>0</number>
+ <sticky/>
+</file_info>
+<workunit>
+ <file_ref>
+ <file_number>0</file_number>
+ <open_name>in</open_name>
+ </file_ref>
+</workunit>
diff --git a/test/ucs_wu b/test/ucs_wu
new file mode 100644
index 0000000..165e9f5
--- /dev/null
+++ b/test/ucs_wu
@@ -0,0 +1,10 @@
+<file_info>
+ <number>0</number>
+</file_info>
+<workunit>
+ <file_ref>
+ <file_number>0</file_number>
+ <open_name>in</open_name>
+ </file_ref>
+ <command_line>-run_slow</command_line>
+</workunit>
diff --git a/test/version.inc.in b/test/version.inc.in
new file mode 100644
index 0000000..c2ab89f
--- /dev/null
+++ b/test/version.inc.in
@@ -0,0 +1,12 @@
+<?php
+
+// version.inc.in
+
+// defines version numbers using autoconf
+define("MAJOR_VERSION", @MAJOR_VERSION@);
+define("MINOR_VERSION", @MINOR_VERSION@);
+define("CLIENT_BIN_FILENAME", "@CLIENT_BIN_FILENAME@");
+define("PLATFORM", "@host@");
+define("SRC_DIR", "@SOURCE_TOP_DIR@");
+
+?>
diff --git a/test/version.py.in b/test/version.py.in
new file mode 100644
index 0000000..114eb90
--- /dev/null
+++ b/test/version.py.in
@@ -0,0 +1,11 @@
+## $Id: version.py.in 3856 2004-07-13 10:36:18Z quarl $
+
+# define version numbers using autoconf
+BOINC_MAJOR_VERSION = @BOINC_MAJOR_VERSION@
+BOINC_MINOR_VERSION = @BOINC_MINOR_VERSION@
+CLIENT_BIN_FILENAME = "@CLIENT_BIN_FILENAME@"
+PLATFORM = "@host@"
+SRC_DIR = "@SOURCE_TOP_DIR@"
+
+# todo: use TOP_SRC_DIR, SRC_DIR, BUILD_DIR from autoconf; can remove AC_SUBST
+# for SOURCE_TOP_DIR
--
BOINC packaging
More information about the pkg-boinc-commits
mailing list