#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_xslt.h"
#if HAVE_XSLT
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#define XSLT_DEBUG 0
extern void xslt_debug(char *function_name, char *format, ...)
{
#if DEBUG
va_list argv;
char buffer[1024];
va_start(argv, format);
vsnprintf(buffer, sizeof(buffer) - 1, format, argv);
va_end(argv);
buffer[sizeof(buffer) - 1] = '\0';
php_printf("<b>XSLT Debug</b>: %s: %s<br />\n",
function_name, buffer);
#endif
}
static char *_find_xslt_argument(const char **argv, const char *key)
{
char **ptr;
char *return_value = NULL;
if (! argv)
return NULL;
ptr = (char **) argv;
while (*ptr) {
if (! strcmp(*ptr, key)) {
return_value = estrdup(*ptr);
break;
}
++ptr;
}
return return_value;
}
extern void xslt_make_array(zval **zarr, char ***carr)
{
zval **current;
HashTable *arr;
int idx = 0;
TSRMLS_FETCH();
if ( Z_TYPE_PP(zarr) == IS_NULL)
return;
arr = HASH_OF(*zarr);
if (! arr) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid argument or parameter array");
return;
}
*carr = emalloc(((zend_hash_num_elements(arr) * 2) + 1) * sizeof(char *));
for (zend_hash_internal_pointer_reset(arr);
zend_hash_get_current_data(arr, (void **) ¤t) == SUCCESS;
zend_hash_move_forward(arr)) {
char *string_key = NULL;
ulong num_key;
int type;
SEPARATE_ZVAL(current);
convert_to_string_ex(current);
type = zend_hash_get_current_key(arr, &string_key, &num_key, 0);
if (type == HASH_KEY_IS_LONG) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid key value for argument or parameter array");
(*carr)[idx] = NULL;
return;
}
(*carr)[idx++] = estrdup(string_key);
(*carr)[idx++] = estrndup(Z_STRVAL_PP(current), Z_STRLEN_PP(current));
}
(*carr)[idx] = NULL;
}
extern void xslt_free_array(char **arr)
{
char **ptr = arr;
while (*ptr != NULL) {
efree(*ptr);
ptr++;
}
efree(arr);
}
extern xslt_args *xslt_parse_arguments(char *xml,
char *xsl,
char *result,
char **argv)
{
xslt_args *return_value;
return_value = emalloc(sizeof(xslt_args));
if (! strncasecmp(xml, "arg:", 4)) {
char *key = xml + 5;
return_value->xml.type = XSLT_IS_DATA;
return_value->xml.ptr = _find_xslt_argument((const char **) argv,
(const char *) key);
}
else {
return_value->xml.type = XSLT_IS_FILE;
return_value->xml.ptr = estrdup(xml);
}
if (! strncasecmp(xsl, "arg:", 4)) {
char *key = xsl + 5;
return_value->xsl.type = XSLT_IS_DATA;
return_value->xsl.ptr = _find_xslt_argument((const char **) argv,
(const char *) key);
}
else {
return_value->xsl.type = XSLT_IS_FILE;
return_value->xsl.ptr = estrdup(xsl);
}
if (! strncasecmp(result, "arg:", 4)) {
char *key = result + 5;
return_value->result.type = XSLT_IS_DATA;
return_value->result.ptr = _find_xslt_argument((const char **) argv,
(const char *) key);
}
else {
return_value->result.type = XSLT_IS_FILE;
return_value->result.ptr = estrdup(result);
}
return return_value;
}
extern void xslt_free_arguments(xslt_args *to_free)
{
if (to_free->xml.ptr) {
efree(to_free->xml.ptr);
}
if (to_free->xsl.ptr) {
efree(to_free->xsl.ptr);
}
if (to_free->result.ptr) {
efree(to_free->result.ptr);
}
efree(to_free);
}
extern void xslt_call_function(char *name,
zval *function,
zval *object,
int argc,
zval **user_args,
zval **retval)
{
zval ***argv;
int error;
int idx;
TSRMLS_FETCH();
argv = emalloc(argc * sizeof(zval **));
for (idx = 0; idx < argc; idx++) {
argv[idx] = &user_args[idx];
}
if (object == NULL)
{
error = call_user_function_ex(EG(function_table),
NULL, function,
retval, argc, argv, 0, NULL TSRMLS_CC);
}
else
{
error = call_user_function_ex(EG(function_table),
&object, function,
retval, argc, argv, 0, NULL TSRMLS_CC);
}
if (error == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the %s handler: %s",
name, Z_STRVAL_P(function));
}
for (idx = 0; idx < argc; idx++) {
zval_ptr_dtor(argv[idx]);
}
efree(argv);
}
#endif