1
0
mirror of https://github.com/php/php-src.git synced 2026-04-10 17:43:13 +02:00

Major rework of the basic api which provides:

- All Sablotron errors are now caught meaning nothing is
          ever outputted directly to the screen allowing you to
          catch all errors.
        - A mechanism is provided for you to have an error function
          which recieves all sablotron errors.
        - All of the basic functions re-use a single processor increasing
          performance (especially with high loads).
        - Added a bunch of comments, more to come (this way other people
          can easily modify my source).

@ Added the xslt_set_error_handler() function to the Sablotron extension.
@ (Sterling)

@ Improved Sablotron's error handling system allowing you to catch all
@ errors before they are outputted to the screen. (Sterling)
This commit is contained in:
Sterling Hughes
2000-11-21 12:12:19 +00:00
parent 358731195f
commit 0a1f0ea22e
2 changed files with 433 additions and 153 deletions

View File

@@ -32,34 +32,53 @@ extern zend_module_entry sablot_module_entry;
#define PHP_SABLOT_API
#endif
/* Module functions */
PHP_MINIT_FUNCTION(sablot);
PHP_MSHUTDOWN_FUNCTION(sablot);
PHP_MINFO_FUNCTION(sablot);
/* Output transformation functions */
PHP_FUNCTION(xslt_output_begintransform);
PHP_FUNCTION(xslt_output_endtransform);
/* Basic transformation functions */
PHP_FUNCTION(xslt_transform);
PHP_FUNCTION(xslt_process);
/* Advanced API transformation functions */
PHP_FUNCTION(xslt_create);
PHP_FUNCTION(xslt_run);
PHP_FUNCTION(xslt_fetch_result);
PHP_FUNCTION(xslt_openlog);
PHP_FUNCTION(xslt_closelog);
PHP_FUNCTION(xslt_set_sax_handler);
PHP_FUNCTION(xslt_set_error_handler);
PHP_FUNCTION(xslt_fetch_result);
PHP_FUNCTION(xslt_free);
/* Error Handling functions */
PHP_FUNCTION(xslt_error);
PHP_FUNCTION(xslt_errno);
PHP_FUNCTION(xslt_openlog);
PHP_FUNCTION(xslt_closelog);
/* Sablotron error structure */
struct _php_sablot_error {
char *key;
char *value;
struct _php_sablot_error *next;
};
typedef struct _php_sablot_error php_sablot_error;
/* Sablotron Handle */
typedef struct {
long index;
/* Error Handling */
zval *errorHandler;
php_sablot_error *errors;
php_sablot_error errors_start;
int last_errno;
php_sablot_error *errors, errors_start;
/* SAX Handling */
long index;
zval *startDocHandler;
zval *startElementHandler;
zval *endElementHandler;
@@ -69,37 +88,43 @@ typedef struct {
zval *PIHandler;
zval *charactersHandler;
zval *endDocHandler;
/* Sablotron Related */
SablotHandle p;
} php_sablot;
/* Sablotron Globals */
typedef struct {
char *output_transform_file;
int le_sablot;
int last_errno;
int processor;
zval *errorHandler;
SablotHandle processor;
php_sablot_error *errors;
php_sablot_error errors_start;
char *output_transform_file; /* For output transformations */
int last_errno; /* Global last_errno, if no handle is found */
} php_sablot_globals;
#ifdef ZTS
#define SABLOTG(v) (sablot_globals->v)
#define SABLOTLS_FETCH() php_sablot_globals *sablot_globals = ts_resource(sablot_globals_id)
#define SABLOTG_HANDLE (*sablot_globals)
#else
#define SABLOTG(v) (sablot_globals.v)
#define SABLOTG_HANDLE sablot_globals
#define SABLOTLS_FETCH()
#endif
#else
#define phpext_sablot_ptr NULL
#endif
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
*/

View File

@@ -31,6 +31,8 @@
#include "ext/standard/php_output.h"
#include "php_sablot.h"
static int le_sablot;
/* Functions related to PHP's list handling */
static void _php_sablot_free_processor(zend_rsrc_list_entry *rsrc);
@@ -50,27 +52,59 @@ static SAX_RETURN _php_sablot_sax_endDoc(void *);
/* Error Handling Functions */
static MH_ERROR _php_sablot_make_code(void *, SablotHandle, int, unsigned short, unsigned short);
static MH_ERROR _php_sablot_error(void *, SablotHandle, MH_ERROR, MH_LEVEL, char **);
static void _php_sablot_standard_error(php_sablot_error *, php_sablot_error, int, int);
/* PHP Utility Functions */
static void _php_sablot_ht_char(HashTable *, char **);
static zval *_php_sablot_string_zval(const char *);
static zval *_php_sablot_resource_zval(long);
/* Macro's */
/* Free macros */
#define S_FREE(__var) if (__var) efree(__var);
#define FUNCH_FREE(__var) if (__var) zval_del_ref(&(__var));
/* ERROR Macro */
#define SEND_ERROR_INFO(__error, __errlevel) \
php_printf("A %s has occurred, sending all relevant information\n", __error); \
handle->errors = handle->errors_start.next; \
while (handle->errors) { \
php_printf("%s: %s\n", handle->errors->key, handle->errors->value); \
handle->errors = handle->errors->next; \
} \
php_error(__errlevel, "");
/* ERROR Macros */
#define SABLOT_FREE_ERROR_HANDLE(__handle) \
if ((__handle).errors) { \
(__handle).errors = (__handle).errors_start.next; \
while ((__handle).errors) { \
S_FREE((__handle).errors->key); \
S_FREE((__handle).errors->value); \
(__handle).errors = (__handle).errors->next; \
} \
S_FREE((__handle).errors); \
}
/* Sablotron Basic Api macro's */
#define SABLOT_BASIC_CREATE_PROCESSOR() \
if (SABLOTG(processor) == NULL) { \
int ret = 0; \
\
ret = SablotCreateProcessor(&SABLOTG(processor)); \
if (ret) { \
SABLOTG(last_errno) = ret; \
return; \
} \
\
ret = SablotRegHandler(SABLOTG(processor), HLR_MESSAGE, (void *)&mh, (void *)NULL); \
if (ret) { \
SABLOTG(last_errno) = ret; \
return; \
} \
}
#define SABLOT_BASIC_HANDLE SABLOTG(processor)
/**
* SAX Handler structure, this defines the different functions to be
* called when Sablotron's internal expat parser reaches the
* different callbacks. These are the same as the functions which are
* defined for expat.
*/
static SAXHandler sax = {
_php_sablot_sax_startDoc,
_php_sablot_sax_startElement,
@@ -83,14 +117,17 @@ static SAXHandler sax = {
_php_sablot_sax_endDoc
};
/**
* Message Handler structure for use when Sablotron
* reports that something has gone wrong.
*/
static MessageHandler mh = {
_php_sablot_make_code,
_php_sablot_error,
_php_sablot_error
};
/* {{{ Begin PHP Extension code */
#ifdef ZTS
int sablot_globals_id;
#else
@@ -112,6 +149,7 @@ function_entry sablot_functions[] = {
PHP_FE(xslt_openlog, NULL)
PHP_FE(xslt_closelog, NULL)
PHP_FE(xslt_set_sax_handler, NULL)
PHP_FE(xslt_set_error_handler, NULL)
PHP_FE(xslt_free, NULL)
PHP_FE(xslt_error, NULL)
PHP_FE(xslt_errno, NULL)
@@ -122,7 +160,7 @@ zend_module_entry sablot_module_entry = {
"sablot",
sablot_functions,
PHP_MINIT(sablot),
NULL,
PHP_MSHUTDOWN(sablot),
NULL,
NULL,
PHP_MINFO(sablot),
@@ -133,37 +171,43 @@ zend_module_entry sablot_module_entry = {
ZEND_GET_MODULE(sablot)
#endif
/* }}} */
/* {{{ MINIT and MINFO Functions */
/* MINIT and MINFO Functions */
PHP_MINIT_FUNCTION(sablot)
{
SABLOTLS_FETCH();
SABLOTG(le_sablot) = zend_register_list_destructors_ex(_php_sablot_free_processor, NULL, "sablotron", module_number);
le_sablot = zend_register_list_destructors_ex(_php_sablot_free_processor, NULL, "Sablotron XSLT", module_number);
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(sablot)
{
SABLOTLS_FETCH();
if (SABLOTG(processor)) {
SablotUnregHandler(SABLOTG(processor), HLR_MESSAGE, NULL, NULL);
SablotDestroyProcessor(SABLOTG(processor));
}
return SUCCESS;
}
PHP_MINFO_FUNCTION(sablot)
{
php_info_print_table_start();
php_info_print_table_row(2, "Sablotron support", "enabled");
php_info_print_table_row(2, "Sablotron XSLT support", "enabled");
php_info_print_table_end();
}
/* }}} */
/* }}} */
/* {{{ Begin Extension function */
/* {{{ Begin Output Transformation functions */
/* {{{ proto void xslt_output_begintransform(string file)
Begin filtering of all data that is being printed out through the XSL file given by the file parameter. */
PHP_FUNCTION(xslt_output_begintransform)
{
/* The name of the file to pass the output through */
zval **file;
/* needed for the output transformation file name */
SABLOTLS_FETCH();
if (ZEND_NUM_ARGS() != 1 ||
@@ -172,9 +216,15 @@ PHP_FUNCTION(xslt_output_begintransform)
}
convert_to_string_ex(file);
/* If the buffer exists, free it */
S_FREE(SABLOTG(output_transform_file));
SABLOTG(output_transform_file) = estrndup(Z_STRVAL_PP(file), Z_STRLEN_PP(file));
/**
* Start output buffering, NULL signifies that no "user-space" output function
* will be used.
*/
php_start_ob_buffer(NULL);
}
/* }}} */
@@ -186,45 +236,81 @@ PHP_FUNCTION(xslt_output_endtransform)
char *tRes = NULL,
*buffer = NULL;
int ret = 0;
/* Fetch both the output globals and the sablotron globals */
OLS_FETCH();
SABLOTLS_FETCH();
/**
* Make sure that we don't have more than one output buffer going on
* at the same time.
*/
if (OG(nesting_level) == 0) {
RETURN_NULL();
}
buffer = estrndup(OG(active_ob_buffer).buffer, OG(active_ob_buffer).text_length);
/* Nake sure there is data to send */
if (strlen(buffer)) {
char *args[] = {"/_xmlinput", buffer,
"/_output", NULL};
ret = SablotProcess(SABLOTG(output_transform_file), "arg:/_xmlinput", "arg:/_output", NULL, args, &tRes);
}
SABLOT_BASIC_CREATE_PROCESSOR();
ret = SablotRunProcessor(SABLOT_BASIC_HANDLE, SABLOTG(output_transform_file),
"arg:/_xmlinput", "arg:/_output", NULL, args);
if (ret) {
SABLOTG(last_errno) = ret;
S_FREE(SABLOTG(output_transform_file));
RETURN_NULL();
}
ret = SablotGetResultArg(SABLOT_BASIC_HANDLE, "arg:/_output", &tRes);
if (ret) {
SABLOTG(last_errno) = ret;
S_FREE(SABLOTG(output_transform_file));
RETURN_NULL();
}
}
/**
* A non-zero return means error, save this error in the global
* errno (for xslt_errno() and xslt_error()) free the output
* transformation file and null.
*/
if (ret) {
SABLOTG(last_errno) = ret;
S_FREE(SABLOTG(output_transform_file));
return;
RETURN_NULL();
}
php_end_ob_buffer(0);
/**
* If there is a buffer, end output buffering and clear the
* current output buffer (so we don't send data twice)
*/
if (tRes)
php_end_ob_buffer(0);
PUTS(tRes);
S_FREE(SABLOTG(output_transform_file));
S_FREE(buffer);
if (tRes) {
SablotFree(tRes);
} else {
php_end_ob_buffer(0);
}
/**
* If there exists a result, free that result
* otherwise just end output buffering and send the
* data.
*/
if (tRes)
SablotFree(tRes);
else
php_end_ob_buffer(1);
}
/* }}} */
/* }}} */
/* {{{ Begin Simple API */
/* {{{ proto bool xslt_transform(string xslt_uri, string transform_uri, string result_uri[, array xslt_params[, array xslt_args[, string &result]]])
Transform an XML document, transform_uri, with an XSL stylesheet, xslt_uri with parameters, xslt_params, into the Result buffer, result_uri, xslt_args defines the variables in xslt_uri, transform_uri and result_uri. */
PHP_FUNCTION(xslt_transform)
@@ -235,11 +321,14 @@ PHP_FUNCTION(xslt_transform)
**xslt_params,
**xslt_args,
**result;
char **args = NULL,
**params = NULL,
*tResult = NULL;
int argc = ZEND_NUM_ARGS(),
ret = 0;
SABLOTLS_FETCH();
if (argc < 3 || argc > 6 ||
@@ -248,24 +337,45 @@ PHP_FUNCTION(xslt_transform)
}
multi_convert_to_string_ex(3, xslt_uri, transform_uri, result_uri);
/**
* if there are more than 3 function arguments, inspect the value of
* the third argument and decide whether or not there are Sablotron
* parameters.
*/
if (argc > 3) {
if (Z_TYPE_PP(xslt_params) != IS_LONG || Z_LVAL_PP(xslt_params) != 0) {
if (Z_TYPE_PP(xslt_params) != IS_LONG || Z_LVAL_PP(xslt_params) != 0 ||
Z_TYPE_PP(xslt_params) != IS_NULL) {
int numelems,
size;
HashTable *ar = HASH_OF(*xslt_params);
/**
* Allocate 2 times the number of elements in
* the array, since with associative arrays in PHP
* keys are not counted.
*/
numelems = zend_hash_num_elements(ar);
size = (numelems * 2 + 1) * sizeof(char *);
params = (char **)emalloc(size+1);
memset((char *)params, 0, size);
/**
* Translate a PHP array (HashTable *) into a
* Sablotron array (char **).
*/
_php_sablot_ht_char(ar, params);
}
}
/**
* If there are more than 4 function arguments, inspect the value
* of the 4 argument and decide whether or not there are Sablotron
* arguments.
*/
if (argc > 4) {
if (Z_TYPE_PP(xslt_args) != IS_LONG || Z_LVAL_PP(xslt_args) != 0) {
if (Z_TYPE_PP(xslt_args) != IS_LONG || Z_LVAL_PP(xslt_args) != 0 ||
Z_TYPE_PP(xslt_args) != IS_NULL) {
int numelems,
size;
HashTable *ar = HASH_OF(*xslt_args);
@@ -280,21 +390,33 @@ PHP_FUNCTION(xslt_transform)
}
}
ret = SablotProcess(Z_STRVAL_PP(xslt_uri), Z_STRVAL_PP(transform_uri),
Z_STRVAL_PP(result_uri), params, args, &tResult);
SABLOT_BASIC_CREATE_PROCESSOR();
ret = SablotRunProcessor(SABLOT_BASIC_HANDLE, Z_STRVAL_PP(xslt_uri),
Z_STRVAL_PP(transform_uri), Z_STRVAL_PP(result_uri),
params, args);
if (ret) {
SABLOTG(last_errno) = ret;
S_FREE(params);
S_FREE(args);
if (tResult) {
SablotFree(tResult);
}
RETURN_FALSE;
} else { RETVAL_TRUE; }
}
ret = SablotGetResultArg(SABLOT_BASIC_HANDLE, Z_STRVAL_PP(result_uri), &tResult);
if (ret) {
SABLOTG(last_errno) = ret;
S_FREE(params);
S_FREE(args);
if (tResult)
SablotFree(tResult);
RETURN_FALSE;
} else { RETVAL_TRUE; }
if (tResult &&
argc == 6) {
@@ -327,22 +449,48 @@ PHP_FUNCTION(xslt_process)
WRONG_PARAM_COUNT;
}
multi_convert_to_string_ex(2, xslt, input);
SABLOT_BASIC_CREATE_PROCESSOR();
/**
* If we have more than three arguments that means we have
* a base!
*/
if (argc > 3) {
convert_to_string_ex(base);
ret = SablotProcessStringsWithBase(Z_STRVAL_PP(xslt), Z_STRVAL_PP(input), &tRes, Z_STRVAL_PP(base));
} else {
ret = SablotProcessStrings(Z_STRVAL_PP(xslt), Z_STRVAL_PP(input), &tRes);
convert_to_string_ex(base);
SablotSetBase(SABLOT_BASIC_HANDLE, Z_STRVAL_PP(base));
}
/**
* Need to declare args here (to lazy to actually allocate
* it with emalloc() ;)
*/
{
char *args[] = {"/_stylesheet", Z_STRVAL_PP(xslt),
"/_xmlinput", Z_STRVAL_PP(input),
"/_output", NULL,
NULL};
ret = SablotRunProcessor(SABLOT_BASIC_HANDLE, "arg:/_stylesheet",
"arg:/_xmlinput", "arg:/_output",
NULL, args);
}
if (ret) {
SABLOTG(last_errno) = ret;
if (tRes) {
SablotFree(tRes);
}
RETURN_FALSE;
SABLOTG(last_errno) = ret;
RETURN_FALSE;
}
SablotGetResultArg(SABLOT_BASIC_HANDLE, "arg:/_output", &tRes);
if (ret) {
SABLOTG(last_errno) = ret;
RETURN_FALSE;
if (tRes)
SablotFree(tRes);
}
if (tRes) {
ZVAL_STRING(*result, tRes, 1);
SablotFree(tRes);
@@ -351,9 +499,6 @@ PHP_FUNCTION(xslt_process)
}
/* }}} */
/* }}} */
/* {{{ Begin Advanced Resource API */
/* {{{ proto resource xslt_create(void)
Create a new XSL processor and return a resource identifier. */
@@ -393,7 +538,7 @@ PHP_FUNCTION(xslt_create)
RETURN_FALSE;
}
ZEND_REGISTER_RESOURCE(return_value, handle, SABLOTG(le_sablot));
ZEND_REGISTER_RESOURCE(return_value, handle, le_sablot);
handle->index = Z_LVAL_P(return_value);
}
/* }}} */
@@ -420,7 +565,7 @@ PHP_FUNCTION(xslt_run)
zend_get_parameters_ex(argc, &xh, &xslt_file, &data_file, &xslt_result, &xslt_params, &xslt_args) == FAILURE) {
WRONG_PARAM_COUNT;
}
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron handle", SABLOTG(le_sablot));
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron handle", le_sablot);
multi_convert_to_string_ex(2, xslt_file, data_file);
if (argc == 3) {
@@ -500,7 +645,7 @@ PHP_FUNCTION(xslt_openlog)
zend_get_parameters_ex(argc, &xh, &logfile, &opt_loglevel) == FAILURE) {
WRONG_PARAM_COUNT;
}
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron", SABLOTG(le_sablot));
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron", le_sablot);
convert_to_string_ex(logfile);
if (argc > 2) {
@@ -533,7 +678,7 @@ PHP_FUNCTION(xslt_closelog)
zend_get_parameters_ex(1, &xh) == FAILURE) {
WRONG_PARAM_COUNT;
}
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron", SABLOTG(le_sablot));
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron", le_sablot);
ret = SablotSetLog(handle->p, (const char *)NULL, 1);
@@ -561,7 +706,7 @@ PHP_FUNCTION(xslt_fetch_result)
zend_get_parameters_ex(argc, &xh, &result_name) == FAILURE) {
WRONG_PARAM_COUNT;
}
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron Handle", SABLOTG(le_sablot));
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron Handle", le_sablot);
if (argc > 1) {
convert_to_string_ex(result_name);
@@ -603,7 +748,7 @@ PHP_FUNCTION(xslt_free)
WRONG_PARAM_COUNT;
}
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron Handle", SABLOTG(le_sablot));
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron Handle", le_sablot);
zend_list_delete(Z_LVAL_PP(xh));
}
/* }}} */
@@ -626,7 +771,7 @@ PHP_FUNCTION(xslt_set_sax_handler)
zend_get_parameters_ex(2, &xh, &handlers) == FAILURE) {
WRONG_PARAM_COUNT;
}
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron Handle", SABLOTG(le_sablot));
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron Handle", le_sablot);
handlers_list = HASH_OF(*handlers);
@@ -692,7 +837,7 @@ PHP_FUNCTION(xslt_error)
}
if (argc) {
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron Handle", SABLOTG(le_sablot));
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron Handle", le_sablot);
if (handle->errors) {
if (array_init(return_value) == FAILURE) {
@@ -735,7 +880,7 @@ PHP_FUNCTION(xslt_errno)
}
if (argc) {
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron Handle", SABLOTG(le_sablot));
ZEND_FETCH_RESOURCE(handle, php_sablot *, xh, -1, "PHP-Sablotron Handle", le_sablot);
RETURN_LONG(handle->last_errno);
} else {
RETURN_LONG(SABLOTG(last_errno));
@@ -743,13 +888,40 @@ PHP_FUNCTION(xslt_errno)
}
/* }}} */
/* {{{ proto void xslt_set_error_handler([int xh, ] string error_handler_name)
Set a error handler (either per handle or global) */
PHP_FUNCTION(xslt_set_error_handler)
{
zval **arg1, **arg2;
php_sablot *handle;
int argc = ZEND_NUM_ARGS();
if (argc > 2 || argc < 1 ||
zend_get_parameters_ex(argc, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
if (argc > 1) {
convert_to_string_ex(arg2);
ZEND_FETCH_RESOURCE(handle, php_sablot *, arg1, -1, "PHP-Sablotron Handle", le_sablot);
if (!handle->errorHandler)
MAKE_STD_ZVAL(handle->errorHandler);
*handle->errorHandler = **arg2;
zval_copy_ctor(handle->errorHandler);
} else {
convert_to_string_ex(arg1);
if (!SABLOTG(errorHandler))
MAKE_STD_ZVAL(SABLOTG(errorHandler));
*SABLOTG(errorHandler) = **arg1;
zval_copy_ctor(SABLOTG(errorHandler));
}
}
/* }}} */
/* }}} */
/* {{{ BEGIN HANDLER FUNCTIONS */
/* {{{ Begin SAX Handler functions */
/* {{{ _php_sablot_handler_pair()
Set the handler functions from a two item array */
@@ -990,68 +1162,160 @@ static MH_ERROR _php_sablot_make_code(void *userData, SablotHandle p, int severi
Handle Sablotron errors */
static MH_ERROR _php_sablot_error(void *userData, SablotHandle p, MH_ERROR code, MH_LEVEL level, char **fields)
{
php_sablot *handle = (php_sablot *)userData;
zval **argv = NULL,
*errorHandler;
php_sablot_error *errors,
errors_start;
php_sablot *handle = NULL;
char *sep = NULL;
int isAdvanced = 0,
argc = 0,
idx,
len;
if (userData == NULL) {
SABLOT_FREE_ERROR_HANDLE(SABLOTG_HANDLE);
SABLOTG(errors_start).next = NULL;
SABLOTG(errors) = &SABLOTG(errors_start);
errors = SABLOTG(errors);
errorHandler = SABLOTG(errorHandler);
} else {
handle = (php_sablot *)userData;
SABLOT_FREE_ERROR_HANDLE(*handle);
handle->errors_start.next = NULL;
handle->errors = &errors_start;
errors = handle->errors;
errorHandler = handle->errorHandler;
isAdvanced = 1;
}
char *sep;
int idx,
len;
while (fields && *fields) {
errors->next = (php_sablot_error *)emalloc(sizeof(php_sablot_error));
errors = errors->next;
sep = strchr(fields[0], ':');
idx = sep - fields[0];
len = strlen(fields[0]);
errors->key = emalloc(idx+1);
errors->value = emalloc((len - idx) + 1);
memcpy(errors->key, fields[0], idx);
memcpy(errors->value, fields[0] + idx + 1, len - idx - 1);
errors->value[len - idx - 1] = '\0';
errors->next = NULL;
fields++;
}
if (isAdvanced)
handle->last_errno = (int)code;
else
SABLOTG(last_errno) = (int)code;
if (errorHandler) {
zval *retval;
int i;
ELS_FETCH();
MAKE_STD_ZVAL(retval);
argc = isAdvanced ? 4 : 3;
argv = emalloc(argc * sizeof(zval *));
MAKE_STD_ZVAL(argv[0]);
MAKE_STD_ZVAL(argv[1]);
MAKE_STD_ZVAL(argv[2]);
if (isAdvanced) {
MAKE_STD_ZVAL(argv[3]);
if (!fields) {
if (code) {
handle->last_errno = (int)code;
}
return(0);
}
if (handle->errors) {
handle->errors = handle->errors_start.next;
while (handle->errors) {
S_FREE(handle->errors->key);
S_FREE(handle->errors->value);
handle->errors = handle->errors->next;
}
S_FREE(handle->errors);
}
ZVAL_RESOURCE(argv[0], handle->index);
ZVAL_LONG(argv[1], code);
ZVAL_LONG(argv[2], level);
array_init(argv[3]);
errors = handle->errors_start.next;
while (errors->next) {
add_assoc_string(argv[3], errors->key, errors->value, 1);
errors = errors->next;
}
} else {
ZVAL_LONG(argv[0], code);
ZVAL_LONG(argv[1], level);
array_init(argv[2]);
errors = SABLOTG(errors_start).next;
while (errors) {
add_assoc_string(argv[2], errors->key, errors->value, 1);
errors = errors->next;
}
}
handle->errors_start.next = NULL;
handle->errors = &(handle->errors_start);
if (call_user_function(EG(function_table), NULL, errorHandler, retval, argc, argv) == FAILURE) {
php_error(E_WARNING, "Sorry, couldn't call %s error handler", Z_STRVAL_P(errorHandler));
}
while (fields && *fields) {
handle->errors->next = (php_sablot_error *)emalloc(sizeof(php_sablot_error));
handle->errors = handle->errors->next;
sep = strchr(fields[0], ':');
idx = sep - fields[0];
len = strlen(fields[0]);
handle->errors->key = emalloc(idx+1);
handle->errors->value = emalloc((len - idx) + 1);
memcpy(handle->errors->key, fields[0], idx);
memcpy(handle->errors->value, fields[0] + idx + 1, len - idx - 1);
handle->errors->next = NULL;
fields++;
}
handle->last_errno = (int)code;
switch (code) {
case MH_LEVEL_CRITICAL:
SEND_ERROR_INFO("Fatal Error", E_CORE);
return (0);
case MH_LEVEL_ERROR:
SEND_ERROR_INFO("Serious Error", E_ERROR);
return (0);
case MH_LEVEL_WARN:
SEND_ERROR_INFO("Warning", E_WARNING);
break;
}
zval_dtor(retval);
efree(retval);
} else {
_php_sablot_standard_error(errors, isAdvanced ? handle->errors_start : SABLOTG(errors_start), code, level);
}
return(0);
}
/* }}} */
static void _php_sablot_standard_error(php_sablot_error *errors, php_sablot_error errors_start, int code, int level)
{
int len = 0,
pos = 0;
char *errstr = NULL;
SABLOTLS_FETCH();
errors = errors_start.next;
while (errors) {
len = pos + strlen(errors->key) + sizeof(": ") + strlen(errors->value) + sizeof("\n");
/**
* Could be a problem, I just hate looping through strings
* more than I have to ;-)
*/
if (pos)
errstr = erealloc(errstr, len);
else
errstr = emalloc(len+1);
sprintf(errstr + pos, "%s: %s\n", errors->key, errors->value);
pos = len;
errors = errors->next;
}
switch (level) {
case MH_LEVEL_CRITICAL:
case MH_LEVEL_ERROR:
php_error(E_ERROR, errstr);
break;
case MH_LEVEL_WARN:
php_error(E_WARNING, errstr);
break;
}
}
/* }}} */
/* {{{ List Handling functions */
@@ -1077,16 +1341,7 @@ static void _php_sablot_free_processor(zend_rsrc_list_entry *rsrc)
FUNCH_FREE(handle->charactersHandler);
FUNCH_FREE(handle->endDocHandler);
if (handle->errors) {
handle->errors = handle->errors_start.next;
while (handle->errors) {
S_FREE(handle->errors->key);
S_FREE(handle->errors->value);
handle->errors = handle->errors->next;
}
S_FREE(handle->errors);
}
S_FREE(handle);
SABLOT_FREE_ERROR_HANDLE(*handle);
}
/* }}} */