]> granicus.if.org Git - php/commitdiff
Inital cut of new xsl extension
authorRob Richards <rrichards@php.net>
Thu, 5 Jun 2003 17:10:13 +0000 (17:10 +0000)
committerRob Richards <rrichards@php.net>
Thu, 5 Jun 2003 17:10:13 +0000 (17:10 +0000)
interoperates with new dom extension
PHP5 only

ext/xsl/config.m4 [new file with mode: 0644]
ext/xsl/php_xsl.c [new file with mode: 0644]
ext/xsl/php_xsl.h [new file with mode: 0644]
ext/xsl/xsl.dsp [new file with mode: 0644]
ext/xsl/xsl_fe.h [new file with mode: 0644]
ext/xsl/xsltprocessor.c [new file with mode: 0644]

diff --git a/ext/xsl/config.m4 b/ext/xsl/config.m4
new file mode 100644 (file)
index 0000000..2b5e0eb
--- /dev/null
@@ -0,0 +1,67 @@
+dnl
+dnl $Id$
+dnl
+AC_DEFUN(PHP_XSL_CHECK_VERSION,[
+  old_CPPFLAGS=$CPPFLAGS
+  CPPFLAGS=-I$XSL_DIR/include
+  AC_MSG_CHECKING(for libxslt version)
+  AC_EGREP_CPP(yes,[
+#include <libxslt/xsltconfig.h>
+#if LIBXSLT_VERSION >= 10018
+  yes
+#endif
+  ],[
+    AC_MSG_RESULT(>= 1.0.18)
+  ],[
+    AC_MSG_ERROR(libxslt version 1.0.18 or greater required.)
+  ])
+  CPPFLAGS=$old_CPPFLAGS
+])
+
+PHP_ARG_WITH(xsl, for XSL support,
+[  --with-xsl[=DIR]        Include new DOM support (requires libxml >= 2.4.14).
+                          DIR is the libxml install directory.])
+
+
+
+if test "$PHP_XSL" != "no"; then
+
+  if test -r $PHP_XSL/include/libxslt/transform.h; then
+    XSL_DIR=$PHP_XSL
+  else
+    for i in /usr/local /usr; do
+      test -r $i/include/libxslt/transform.h && XSL_DIR=$i
+    done
+  fi
+
+  if test -z "$XSL_DIR"; then
+    AC_MSG_RESULT(not found)
+    AC_MSG_ERROR(Please reinstall the libxslt >= 1.0.3 distribution)
+  fi
+
+  PHP_XSL_CHECK_VERSION
+
+  XSLT_CONFIG=$XSL_DIR/bin/xslt-config
+  if test -x $XSLT_CONFIG; then
+    DOM_LIBS=`$XSLT_CONFIG --libs`
+    DOM_INCLUDES=`$XSLT_CONFIG --cflags`
+    AC_MSG_RESULT(found xslt-config in $XSLT_CONFIG)
+    PHP_EVAL_LIBLINE($DOM_LIBS, XSL_SHARED_LIBADD)
+    CFLAGS="$CFLAGS $DOM_INCLUDES"
+  else 
+    PHP_ADD_LIBRARY_WITH_PATH($DOM_LIBNAME, $XSL_DIR/lib, XSL_SHARED_LIBADD)
+    PHP_ADD_INCLUDE($XSL_DIR/include)
+  fi
+
+  
+  AC_DEFINE(HAVE_XSL,1,[ ])
+  PHP_NEW_EXTENSION(xsl, php_xsl.c xsltprocessor.c, $ext_shared)
+  PHP_SUBST(XSL_SHARED_LIBADD)
+fi
+
+
+
+
+
+
diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c
new file mode 100644 (file)
index 0000000..9b9562b
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+  +----------------------------------------------------------------------+
+  | PHP Version 4                                                        |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 1997-2003 The PHP Group                                |
+  +----------------------------------------------------------------------+
+  | This source file is subject to version 2.02 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available at through the world-wide-web at                           |
+  | http://www.php.net/license/2_02.txt.                                 |
+  | If you did not receive a copy of the PHP license and are unable to   |
+  | obtain it through the world-wide-web, please send a note to          |
+  | license@php.net so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Author: Christian Stocker <chregu@php.net>                           |
+  +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "zend_execute_locks.h"
+#include "ext/standard/info.h"
+#include "php_xsl.h"
+
+/* If you declare any globals in php_xsl.h uncomment this:
+ZEND_DECLARE_MODULE_GLOBALS(xsl)
+*/
+
+/* True global resources - no need for thread safety here */
+
+static HashTable classes;
+/* not used right now  
+static zend_object_handlers xsl_object_handlers;
+static HashTable xsl_xsltprocessor_prop_handlers;
+*/
+
+/* {{{ xsl_functions[]
+ *
+ * Every user visible function must have an entry in xsl_functions[].
+ */
+function_entry xsl_functions[] = {
+       {NULL, NULL, NULL}  /* Must be the last line in xsl_functions[] */
+};
+/* }}} */
+
+/* {{{ xsl_module_entry
+ */
+zend_module_entry xsl_module_entry = {
+#if ZEND_MODULE_API_NO >= 20010901
+       STANDARD_MODULE_HEADER,
+#endif
+       "xsl",
+       xsl_functions,
+       PHP_MINIT(xsl),
+       PHP_MSHUTDOWN(xsl),
+       PHP_RINIT(xsl),         /* Replace with NULL if there's nothing to do at request start */
+       PHP_RSHUTDOWN(xsl),     /* Replace with NULL if there's nothing to do at request end */
+       PHP_MINFO(xsl),
+#if ZEND_MODULE_API_NO >= 20010901
+       "0.1", /* Replace with version number for your extension */
+#endif
+       STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
+#ifdef COMPILE_DL_XSL
+ZEND_GET_MODULE(xsl)
+#endif
+
+
+/************
+* copied from php_dom .... should be in a common file...
+**********/
+
+
+typedef int (*dom_read_t)(xsl_object *obj, zval **retval TSRMLS_DC);
+typedef int (*dom_write_t)(xsl_object *obj, zval *newval TSRMLS_DC);
+
+typedef struct _dom_prop_handler {
+       dom_read_t read_func;
+       dom_write_t write_func;
+} dom_prop_handler;
+
+/* end copied from php_dom.c */
+       
+/* {{{ xsl_objects_dtor */
+void xsl_objects_dtor(void *object, zend_object_handle handle TSRMLS_DC)
+{
+       /* TODO */
+       xsl_object *intern = (xsl_object *)object;
+
+       zend_hash_destroy(intern->std.properties);
+       FREE_HASHTABLE(intern->std.properties);
+
+       zend_hash_destroy(intern->parameter);
+       FREE_HASHTABLE(intern->parameter);
+       
+       if (intern->ptr) {
+               /* free wrapper */
+               if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
+                       ((xsltStylesheetPtr) intern->ptr)->_private = NULL;   
+               }
+               /* libxslt uses _private for itself, so turning of the deregistering is maybe a solution 
+                  we copied the doc at import, so it shouldn't be possible to be used from php land */
+               xsltFreeStylesheet((xsltStylesheetPtr) intern->ptr);
+               intern->ptr = NULL;
+       }
+       efree(object);
+}
+/* }}} */
+/* {{{ xsl_objects_new */
+zend_object_value xsl_objects_new(zend_class_entry *class_type TSRMLS_DC)
+{
+       zend_object_value retval;
+       xsl_object *intern;
+       zend_class_entry *base_class;
+       zval *tmp;
+
+       intern = emalloc(sizeof(xsl_object));
+       intern->std.ce = class_type;
+       intern->std.in_get = 0;
+       intern->std.in_set = 0;
+       intern->ptr = NULL;
+       intern->node_list = NULL;
+       intern->prop_handler = NULL;
+       intern->parameter = NULL;
+       
+       base_class = class_type;
+       while(base_class->type != ZEND_INTERNAL_CLASS && base_class->parent != NULL) {
+               base_class = base_class->parent;
+       }
+
+       zend_hash_find(&classes, base_class->name , base_class->name_length + 1, &intern->prop_handler);
+
+       ALLOC_HASHTABLE(intern->std.properties);
+       zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
+       zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+       ALLOC_HASHTABLE(intern->parameter);
+       zend_hash_init(intern->parameter, 0, NULL, ZVAL_PTR_DTOR, 0);
+       retval.handle = zend_objects_store_put(intern, xsl_objects_dtor, dom_objects_clone TSRMLS_CC);
+       retval.handlers = &dom_object_handlers;
+       return retval;
+}
+/* }}} */
+
+/* {{{ PHP_MINIT_FUNCTION
+ */
+PHP_MINIT_FUNCTION(xsl)
+{
+       
+       zend_class_entry ce;
+       zend_hash_init(&classes, 0, NULL, NULL, 1);
+       
+       memcpy(&dom_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+       dom_object_handlers.read_property = dom_read_property;
+       dom_object_handlers.write_property = dom_write_property;
+       
+       REGISTER_XSL_CLASS(ce, "xsltprocessor", NULL, php_xsl_xsltprocessor_class_functions, xsl_xsltprocessor_class_entry);
+       return SUCCESS;
+}
+/* }}} */
+
+/* {{{ xsl_object_get_data */
+zval *xsl_object_get_data(void *obj)
+{
+       zval *dom_wrapper;
+       dom_wrapper = ((xsltStylesheetPtr) obj)->_private;
+       return dom_wrapper;
+}
+/* }}} */
+
+/* {{{ xsl_object_set_data */
+static void xsl_object_set_data(void *obj, zval *wrapper TSRMLS_DC)
+{
+       ((xsltStylesheetPtr) obj)->_private = wrapper;
+}
+/* }}} */
+
+/* {{{ php_xsl_set_object */
+void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC)
+{
+       xsl_object *object;
+
+       object = (xsl_object *)zend_objects_get_address(wrapper TSRMLS_CC);
+       object->ptr = obj;
+       xsl_object_set_data(obj, wrapper TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ php_xsl_create_object */
+zval *php_xsl_create_object(xsltStylesheetPtr obj, int *found, zval *wrapper_in, zval *return_value  TSRMLS_DC)
+{
+       zval *wrapper;
+       zend_class_entry *ce;
+
+       *found = 0;
+
+       if (!obj) {
+               if(!wrapper_in) {
+                       ALLOC_ZVAL(wrapper);
+               } else {
+                       wrapper = wrapper_in;
+               }
+               ZVAL_NULL(wrapper);
+               return wrapper;
+       }
+
+       if ((wrapper = (zval *) xsl_object_get_data((void *) obj))) {
+               zval_add_ref(&wrapper);
+               *found = 1;
+               return wrapper;
+       }
+
+       if(!wrapper_in) {
+               wrapper = return_value;
+       } else {
+               wrapper = wrapper_in;
+       }
+
+       
+       ce = xsl_xsltprocessor_class_entry;
+
+       if(!wrapper_in) {
+               object_init_ex(wrapper, ce);
+       }
+       php_xsl_set_object(wrapper, (void *) obj TSRMLS_CC);
+       return (wrapper);
+}
+/* }}} */
+
+
+
+
+/* {{{ PHP_MSHUTDOWN_FUNCTION
+ */
+PHP_MSHUTDOWN_FUNCTION(xsl)
+{
+       /* uncomment this line if you have INI entries
+       UNREGISTER_INI_ENTRIES();
+       */
+       xsltCleanupGlobals();
+
+       return SUCCESS;
+}
+/* }}} */
+
+/* Remove if there's nothing to do at request start */
+/* {{{ PHP_RINIT_FUNCTION
+ */
+PHP_RINIT_FUNCTION(xsl)
+{
+       return SUCCESS;
+}
+/* }}} */
+
+/* Remove if there's nothing to do at request end */
+/* {{{ PHP_RSHUTDOWN_FUNCTION
+ */
+PHP_RSHUTDOWN_FUNCTION(xsl)
+{
+       return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MINFO_FUNCTION
+ */
+PHP_MINFO_FUNCTION(xsl)
+{
+       php_info_print_table_start();
+       php_info_print_table_row(2, "XML/XSLT", "enabled");
+   {
+               char buffer[128];
+               int major, minor, subminor;
+
+               php_info_print_table_row(2, "DOM/XSLT", "enabled");
+               major = xsltLibxsltVersion/10000;
+               minor = (xsltLibxsltVersion - major * 10000) / 100;
+               subminor = (xsltLibxsltVersion - major * 10000 - minor * 100);
+               snprintf(buffer, 128, "%d.%d.%d", major, minor, subminor);
+               php_info_print_table_row(2, "libxslt Version", buffer);
+               major = xsltLibxmlVersion/10000;
+               minor = (xsltLibxmlVersion - major * 10000) / 100;
+               subminor = (xsltLibxmlVersion - major * 10000 - minor * 100);
+               snprintf(buffer, 128, "%d.%d.%d", major, minor, subminor);
+               php_info_print_table_row(2, "libxslt compiled against libxml Version", buffer);
+         }
+       php_info_print_table_end();
+
+       /* Remove comments if you have entries in php.ini
+       DISPLAY_INI_ENTRIES();
+       */
+}
+/* }}} */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/xsl/php_xsl.h b/ext/xsl/php_xsl.h
new file mode 100644 (file)
index 0000000..2362fb3
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+  +----------------------------------------------------------------------+
+  | PHP Version 4                                                        |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 1997-2003 The PHP Group                                |
+  +----------------------------------------------------------------------+
+  | This source file is subject to version 2.02 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available at through the world-wide-web at                           |
+  | http://www.php.net/license/2_02.txt.                                 |
+  | If you did not receive a copy of the PHP license and are unable to   |
+  | obtain it through the world-wide-web, please send a note to          |
+  | license@php.net so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Author:                                                              |
+  +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_XSL_H
+#define PHP_XSL_H
+
+extern zend_module_entry xsl_module_entry;
+#define phpext_xsl_ptr &xsl_module_entry
+
+#ifdef PHP_WIN32
+#define PHP_XSL_API __declspec(dllexport)
+#else
+#define PHP_XSL_API
+#endif
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#include <libxslt/xsltconfig.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/xsltutils.h>
+#include <libxslt/transform.h>
+
+#include "../dom/xml_common.h"
+#include "xsl_fe.h"
+
+typedef struct _xsl_object {
+       zend_object  std;
+       void *ptr;
+       HashTable *prop_handler;
+       node_list_pointer *node_list;
+    HashTable *parameter;
+} xsl_object;
+
+void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC);
+void xsl_objects_dtor(void *object, zend_object_handle handle TSRMLS_DC);
+zval *php_xsl_create_object(xsltStylesheetPtr obj, int *found, zval *wrapper_in, zval *return_value  TSRMLS_DC);
+
+#define REGISTER_XSL_CLASS(ce, name, parent_ce, funcs, entry) \
+INIT_CLASS_ENTRY(ce, name, funcs); \
+ce.create_object = xsl_objects_new; \
+entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC);
+
+#define XSL_DOMOBJ_NEW(zval, obj, ret) \
+       if (NULL == (zval = php_xsl_create_object(obj, ret, zval, return_value TSRMLS_CC))) { \
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); \
+               RETURN_FALSE; \
+       }
+
+    
+    
+PHP_MINIT_FUNCTION(xsl);
+PHP_MSHUTDOWN_FUNCTION(xsl);
+PHP_RINIT_FUNCTION(xsl);
+PHP_RSHUTDOWN_FUNCTION(xsl);
+PHP_MINFO_FUNCTION(xsl);
+
+
+/* 
+       Declare any global variables you may need between the BEGIN
+       and END macros here:     
+
+ZEND_BEGIN_MODULE_GLOBALS(xsl)
+       long  global_value;
+       char *global_string;
+ZEND_END_MODULE_GLOBALS(xsl)
+*/
+
+/* In every utility function you add that needs to use variables 
+   in php_xsl_globals, call TSRM_FETCH(); after declaring other 
+   variables used by that function, or better yet, pass in TSRMLS_CC
+   after the last function argument and declare your utility function
+   with TSRMLS_DC after the last declared argument.  Always refer to
+   the globals in your function as XSL_G(variable).  You are 
+   encouraged to rename these macros something shorter, see
+   examples in any other php module directory.
+*/
+
+#ifdef ZTS
+#define XSL_G(v) TSRMG(xsl_globals_id, zend_xsl_globals *, v)
+#else
+#define XSL_G(v) (xsl_globals.v)
+#endif
+
+#endif /* PHP_XSL_H */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/xsl/xsl.dsp b/ext/xsl/xsl.dsp
new file mode 100644 (file)
index 0000000..f93a73d
--- /dev/null
@@ -0,0 +1,118 @@
+# Microsoft Developer Studio Project File - Name="xsl" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r
+\r
+CFG=xsl - Win32 Debug_TS\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "xsl.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "xsl.mak" CFG="xsl - Win32 Debug_TS"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "xsl - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "xsl - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "xsl - Win32 Release_TS"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release_TS"\r
+# PROP BASE Intermediate_Dir "Release_TS"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release_TS"\r
+# PROP Intermediate_Dir "Release_TS"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XSL_EXPORTS" /YX /FD /c\r
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XSL_EXPORTS" /YX /FD /c\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "xsl - Win32 Debug_TS"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug_TS"\r
+# PROP BASE Intermediate_Dir "Debug_TS"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug_TS"\r
+# PROP Intermediate_Dir "Debug_TS"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XSL_EXPORTS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XSL_EXPORTS" /D "COMPILE_DL_XSL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D LIBXML_STATIC=1 /D LIBXSLT_STATIC=1 /FR /YX /FD /c\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x406 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 php4ts_debug.lib php_dom.lib libxml2_a.lib libxslt_a.lib iconv.lib resolv.lib kernel32.lib user32.lib gdi32.lib winspool.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"msvcrt" /out:"..\..\Debug_TS/php_xsl.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\bindlib_w32\Release" /libpath:"..\..\..\php_build\lib\libxslt" /libpath:"..\domxml5\debug_ts"\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "xsl - Win32 Release_TS"\r
+# Name "xsl - Win32 Debug_TS"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=.\php_xsl.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\xsltprocessor.c\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=.\php_xsl.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\xsl_fe.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/ext/xsl/xsl_fe.h b/ext/xsl/xsl_fe.h
new file mode 100644 (file)
index 0000000..39a8491
--- /dev/null
@@ -0,0 +1,12 @@
+
+
+extern zend_function_entry php_xsl_xsltprocessor_class_functions[];
+zend_class_entry *xsl_xsltprocessor_class_entry;
+
+PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet);
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc);
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri);
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml);
+PHP_FUNCTION(xsl_xsltprocessor_set_parameter);
+PHP_FUNCTION(xsl_xsltprocessor_get_parameter);
+PHP_FUNCTION(xsl_xsltprocessor_remove_parameter);
diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c
new file mode 100644 (file)
index 0000000..7b3f4a5
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 4                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2003 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Christian Stocker <chregu@php.net>                          |
+   |          Rob Richards <rrichards@php.net>                            |
+   +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_xsl.h"
+
+
+/*
+* class xsl_xsltprocessor 
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
+* Since: 
+*/
+
+zend_function_entry php_xsl_xsltprocessor_class_functions[] = {
+       PHP_FALIAS(import_stylesheet, xsl_xsltprocessor_import_stylesheet, NULL)
+       PHP_FALIAS(transform_to_doc, xsl_xsltprocessor_transform_to_doc, NULL)
+       PHP_FALIAS(transform_to_uri, xsl_xsltprocessor_transform_to_uri, NULL)
+       PHP_FALIAS(transform_to_xml, xsl_xsltprocessor_transform_to_xml, NULL)
+       PHP_FALIAS(set_parameter, xsl_xsltprocessor_set_parameter, NULL)
+       PHP_FALIAS(get_parameter, xsl_xsltprocessor_get_parameter, NULL)
+       PHP_FALIAS(remove_parameter, xsl_xsltprocessor_remove_parameter, NULL)
+       {NULL, NULL, NULL}
+};
+
+/* {{{ attribute protos, not implemented yet */
+/* {{{ php_xsl_xslt_string_to_xpathexpr()
+   Translates a string to a XPath Expression */
+static char *php_xsl_xslt_string_to_xpathexpr(const char *str TSRMLS_DC)
+{
+       const xmlChar *string = (const xmlChar *)str;
+
+       xmlChar *value;
+       int str_len;
+       
+       str_len = xmlStrlen(string) + 3;
+       
+       if (xmlStrchr(string, '"')) {
+               if (xmlStrchr(string, '\'')) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create XPath expression (string contains both quote and double-quotes)");
+                       return NULL;
+               }
+               value = (xmlChar*) emalloc (str_len * sizeof(xmlChar) );
+               snprintf(value, str_len, "'%s'", string);
+       } else {
+               value = (xmlChar*) emalloc (str_len * sizeof(xmlChar) );
+               snprintf(value, str_len, "\"%s\"", string);
+       }
+       return (char *) value;
+}
+
+/* {{{ php_xsl_xslt_make_params()
+   Translates a PHP array to a libxslt parameters array */
+static char **php_xsl_xslt_make_params(HashTable *parht, int xpath_params TSRMLS_DC)
+{
+       
+       int parsize;
+       zval **value;
+       char *xpath_expr, *string_key = NULL;
+       ulong num_key;
+       char **params = NULL;
+       int i = 0;
+
+       parsize = (2 * zend_hash_num_elements(parht) + 1) * sizeof(char *);
+       params = (char **)emalloc(parsize);
+       memset((char *)params, 0, parsize);
+
+       for (zend_hash_internal_pointer_reset(parht);
+               zend_hash_get_current_data(parht, (void **)&value) == SUCCESS;
+               zend_hash_move_forward(parht)) {
+
+               if (zend_hash_get_current_key(parht, &string_key, &num_key, 1) != HASH_KEY_IS_STRING) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid argument or parameter array");
+                       return NULL;
+               } else {
+                       SEPARATE_ZVAL(value);
+                       convert_to_string_ex(value);
+
+                       if (!xpath_params) {
+                               xpath_expr = php_xsl_xslt_string_to_xpathexpr(Z_STRVAL_PP(value) TSRMLS_CC);
+                       } else {
+                               xpath_expr = Z_STRVAL_PP(value);
+                       }
+                       if (xpath_expr) {
+                               params[i++] = string_key;
+                               params[i++] = xpath_expr;
+                       }
+               }
+       }
+
+       params[i++] = NULL;
+
+       return params;
+}
+/* }}} */
+/* {{{ proto xsl_xsltdocucument xsl_xsltprocessor_import_stylesheet(node index);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
+Since: 
+*/
+PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
+{
+       zval *id, *docp = NULL;
+       xmlDoc *doc;
+       xsltStylesheetPtr sheetp, oldsheetp;
+       xmlDocPtr newdocp;
+       xsl_object *intern;
+       
+       DOM_GET_THIS(id);
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
+               RETURN_FALSE;
+       }
+       DOM_GET_OBJ(doc, docp, xmlDocPtr);
+       /* copy the doc, so that it's not accessable from outside
+       FIXME: and doubling memory consumption...
+       */
+       newdocp = xmlCopyDoc(doc, 1);
+       sheetp = xsltParseStylesheetDoc(newdocp);
+
+       if (!sheetp) {
+               xmlFreeDoc(newdocp);
+               RETURN_FALSE;
+       }
+
+       intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); 
+       if ((oldsheetp = (xsltStylesheetPtr)intern->ptr)) { 
+               /* free wrapper */
+               if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
+                       efree(((xsltStylesheetPtr) intern->ptr)->_private);
+                       ((xsltStylesheetPtr) intern->ptr)->_private = NULL;   
+               }
+               //FIXME: more non-thread safe stuff
+               xsltFreeStylesheet((xsltStylesheetPtr) intern->ptr);
+               intern->ptr = NULL;
+       } 
+       php_xsl_set_object(id, sheetp TSRMLS_CC);
+}
+/* }}} end xsl_xsltprocessor_import_stylesheet */
+
+
+/* {{{ proto xsl_document xsl_xsltprocessor_transform_to_doc(node doc);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
+Since: 
+*/
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
+{
+       zval *id, *rv = NULL, *docp = NULL;
+       xmlDoc *doc;
+       xmlDoc *newdocp;
+       xsltStylesheetPtr sheetp;
+       int ret;
+       char **params = NULL;
+       xsl_object *intern;
+       
+       DOM_GET_THIS_OBJ(sheetp, id, xsltStylesheetPtr);
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
+               RETURN_FALSE;
+       }
+       DOM_GET_OBJ(doc, docp, xmlDocPtr);
+       intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+       if (intern->parameter) {
+               params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
+       }
+       newdocp = xsltApplyStylesheet(sheetp, doc, (const char**) params);
+
+       if (params) {
+               efree(params);
+       }
+
+       if (newdocp) {
+               DOM_RET_OBJ(rv, (xmlNodePtr) newdocp, &ret);
+       } else {
+               RETURN_FALSE;
+       }
+       
+}
+/* }}} end xsl_xsltprocessor_transform_to_doc */
+
+
+/* {{{ proto xsl_ xsl_xsltprocessor_transform_to_uri(node doc, string uri);
+*/
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end xsl_xsltprocessor_transform_to_uri */
+
+
+/* {{{ proto xsl_string xsl_xsltprocessor_transform_to_xml(node doc);
+*/
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
+{
+       zval *id, *docp = NULL;
+       xmlDoc *doc;
+       xmlDoc *newdocp;
+       xsltStylesheetPtr sheetp;
+       int ret;
+       xmlChar *doc_txt_ptr;
+       int doc_txt_len;
+       char **params = NULL;
+       xsl_object *intern;
+       
+       DOM_GET_THIS_OBJ(sheetp, id, xsltStylesheetPtr);
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
+               RETURN_FALSE;
+       }
+       DOM_GET_OBJ(doc, docp, xmlDocPtr);
+       intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+       if (intern->parameter) {
+               params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
+       }
+       newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params);
+       
+       if (params) {
+               efree(params);
+       }
+       ret = xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len, newdocp, sheetp);
+
+       if (ret < 0) {
+               RETURN_FALSE;
+       }
+
+       RETVAL_STRINGL(doc_txt_ptr, doc_txt_len, 1);
+       xmlFree(doc_txt_ptr);
+       xmlFreeDoc(newdocp);
+}
+/* }}} end xsl_xsltprocessor_transform_to_xml */
+
+
+/* {{{ proto xsl_ xsl_xsltprocessor_set_parameter(string namespace, string name, string value);
+*/
+PHP_FUNCTION(xsl_xsltprocessor_set_parameter)
+{
+       zval *id;
+       int name_len = 0, namespace_len = 0, value_len = 0;
+       char *name, *namespace, *value;
+       xsl_object *intern;
+       zval *new_string;
+
+       DOM_GET_THIS(id);
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &namespace, &namespace_len, &name, &name_len, &value, &value_len) == FAILURE) {
+               RETURN_FALSE;
+       }
+       intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+   
+
+       MAKE_STD_ZVAL(new_string);
+       ZVAL_STRING(new_string, value, 1);
+       zend_hash_update(intern->parameter, name, name_len + 1, &new_string, sizeof(zval*), NULL);
+}
+/* }}} end xsl_xsltprocessor_set_parameter */
+
+/* {{{ proto xsl_ xsl_xsltprocessor_get_parameter(string namespace, string name);
+*/
+PHP_FUNCTION(xsl_xsltprocessor_get_parameter)
+{
+       zval *id;
+       int name_len = 0, namespace_len = 0;
+       char *name, *namespace;
+       zval **value;
+       xsl_object *intern;
+
+       DOM_GET_THIS(id);
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &namespace, &namespace_len, &name, &name_len) == FAILURE) {
+               RETURN_FALSE;
+       }
+       intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+       if ( zend_hash_find(intern->parameter, name, name_len + 1,  (void**) &value) == SUCCESS) {
+               convert_to_string_ex(value);
+               RETVAL_STRING(Z_STRVAL_PP(value),1);
+       } else {
+               RETURN_FALSE;
+       }
+}
+/* }}} end xsl_xsltprocessor_get_parameter */
+
+/* {{{ proto xsl_ xsl_xsltprocessor_remove_parameter(string namespace, string name);
+*/
+PHP_FUNCTION(xsl_xsltprocessor_remove_parameter)
+{
+       zval *id;
+       int name_len = 0, namespace_len = 0;
+       char *name, *namespace;
+       xsl_object *intern;
+
+       DOM_GET_THIS(id);
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &namespace, &namespace_len, &name, &name_len) == FAILURE) {
+               RETURN_FALSE;
+       }
+       intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+       if ( zend_hash_del(intern->parameter, name, name_len + 1) == SUCCESS) {
+               RETURN_TRUE;
+       } else {
+               RETURN_FALSE;
+       }
+}
+/* }}} end xsl_xsltprocessor_remove_parameter */