rrichards Thu Jun 5 13:10:13 2003 EDT
Added files:
/php4/ext/xsl config.m4 php_xsl.c php_xsl.h xsl.dsp xsl_fe.h
xsltprocessor.c
Log:
Inital cut of new xsl extension
interoperates with new dom extension
PHP5 only
Index: php4/ext/xsl/config.m4
+++ php4/ext/xsl/config.m4
dnl
dnl $Id: config.m4,v 1.1 2003/06/05 17:10:13 rrichards Exp $
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
Index: php4/ext/xsl/php_xsl.c
+++ php4/ext/xsl/php_xsl.c
/*
+----------------------------------------------------------------------+
| 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 |
| [EMAIL PROTECTED] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Christian Stocker <[EMAIL PROTECTED]> |
+----------------------------------------------------------------------+
*/
/* $Id: php_xsl.c,v 1.1 2003/06/05 17:10:13 rrichards Exp $ */
#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
*/
Index: php4/ext/xsl/php_xsl.h
+++ php4/ext/xsl/php_xsl.h
/*
+----------------------------------------------------------------------+
| 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 |
| [EMAIL PROTECTED] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: |
+----------------------------------------------------------------------+
*/
/* $Id: php_xsl.h,v 1.1 2003/06/05 17:10:13 rrichards Exp $ */
#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
*/
Index: php4/ext/xsl/xsl.dsp
+++ php4/ext/xsl/xsl.dsp
# Microsoft Developer Studio Project File - Name="xsl" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=xsl - Win32 Debug_TS
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "xsl.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "xsl.mak" CFG="xsl - Win32 Debug_TS"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "xsl - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "xsl - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "xsl - Win32 Release_TS"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release_TS"
# PROP BASE Intermediate_Dir "Release_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_TS"
# PROP Intermediate_Dir "Release_TS"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS"
/D "_USRDLL" /D "XSL_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D
"_USRDLL" /D "XSL_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# 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
!ELSEIF "$(CFG)" == "xsl - Win32 Debug_TS"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug_TS"
# PROP BASE Intermediate_Dir "Debug_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug_TS"
# PROP Intermediate_Dir "Debug_TS"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# 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
# 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
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x406 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# 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"
!ENDIF
# Begin Target
# Name "xsl - Win32 Release_TS"
# Name "xsl - Win32 Debug_TS"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\php_xsl.c
# End Source File
# Begin Source File
SOURCE=.\xsltprocessor.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\php_xsl.h
# End Source File
# Begin Source File
SOURCE=.\xsl_fe.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
Index: php4/ext/xsl/xsl_fe.h
+++ php4/ext/xsl/xsl_fe.h
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);
Index: php4/ext/xsl/xsltprocessor.c
+++ php4/ext/xsl/xsltprocessor.c
/*
+----------------------------------------------------------------------+
| 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 |
| [EMAIL PROTECTED] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Christian Stocker <[EMAIL PROTECTED]> |
| Rob Richards <[EMAIL PROTECTED]> |
+----------------------------------------------------------------------+
*/
/* $Id: xsltprocessor.c,v 1.1 2003/06/05 17:10:13 rrichards Exp $ */
#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 */
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php