rrichards               Thu Feb 10 10:52:39 2005 EDT

  Modified files:              
    /php-src/ext/libxml php_libxml.h libxml.c 
  Log:
  initial cut of new error handling
  
http://cvs.php.net/diff.php/php-src/ext/libxml/php_libxml.h?r1=1.11&r2=1.12&ty=u
Index: php-src/ext/libxml/php_libxml.h
diff -u php-src/ext/libxml/php_libxml.h:1.11 
php-src/ext/libxml/php_libxml.h:1.12
--- php-src/ext/libxml/php_libxml.h:1.11        Tue Nov  9 03:13:35 2004
+++ php-src/ext/libxml/php_libxml.h     Thu Feb 10 10:52:38 2005
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: php_libxml.h,v 1.11 2004/11/09 08:13:35 dmitry Exp $ */
+/* $Id: php_libxml.h,v 1.12 2005/02/10 15:52:38 rrichards Exp $ */
 
 #ifndef PHP_LIBXML_H
 #define PHP_LIBXML_H
@@ -43,6 +43,7 @@
 typedef struct {
        zval *stream_context;
        smart_str error_buffer;
+       zend_llist *error_list;
 } php_libxml_globals;
 
 typedef struct _php_libxml_ref_obj {
@@ -67,11 +68,15 @@
 typedef void * (*php_libxml_export_node) (zval *object TSRMLS_DC);
 
 PHP_FUNCTION(libxml_set_streams_context);
+PHP_FUNCTION(libxml_use_internal_errors);
+PHP_FUNCTION(libxml_get_last_error);
+PHP_FUNCTION(libxml_clear_errors);
+PHP_FUNCTION(libxml_get_errors);
 
 int php_libxml_increment_node_ptr(php_libxml_node_object *object, xmlNodePtr 
node, void *private_data TSRMLS_DC);
 int php_libxml_decrement_node_ptr(php_libxml_node_object *object TSRMLS_DC);
-int php_libxml_increment_doc_ref(php_libxml_node_object *object, xmlDocPtr 
docp TSRMLS_DC);
-int php_libxml_decrement_doc_ref(php_libxml_node_object *object TSRMLS_DC);
+PHP_LIBXML_API int php_libxml_increment_doc_ref(php_libxml_node_object 
*object, xmlDocPtr docp TSRMLS_DC);
+PHP_LIBXML_API int php_libxml_decrement_doc_ref(php_libxml_node_object *object 
TSRMLS_DC);
 PHP_LIBXML_API xmlNodePtr php_libxml_import_node(zval *object TSRMLS_DC);
 PHP_LIBXML_API int php_libxml_register_export(zend_class_entry *ce, 
php_libxml_export_node export_function);
 /* When an explicit freeing of node and children is required */
http://cvs.php.net/diff.php/php-src/ext/libxml/libxml.c?r1=1.27&r2=1.28&ty=u
Index: php-src/ext/libxml/libxml.c
diff -u php-src/ext/libxml/libxml.c:1.27 php-src/ext/libxml/libxml.c:1.28
--- php-src/ext/libxml/libxml.c:1.27    Sun Jan  2 07:21:14 2005
+++ php-src/ext/libxml/libxml.c Thu Feb 10 10:52:38 2005
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: libxml.c,v 1.27 2005/01/02 12:21:14 rrichards Exp $ */
+/* $Id: libxml.c,v 1.28 2005/02/10 15:52:38 rrichards Exp $ */
 
 #define IS_EXT_MODULE
 
@@ -65,6 +65,10 @@
 PHP_LIBXML_API php_libxml_globals libxml_globals;
 #endif
 
+#if LIBXML_VERSION >= 20600
+zend_class_entry *libxmlerror_class_entry;
+#endif
+
 /* {{{ dynamically loadable module stuff */
 #ifdef COMPILE_DL_LIBXML
 ZEND_GET_MODULE(libxml)
@@ -86,6 +90,10 @@
 /* {{{ extension definition structures */
 function_entry libxml_functions[] = {
        PHP_FE(libxml_set_streams_context, NULL)
+       PHP_FE(libxml_use_internal_errors, NULL)
+       PHP_FE(libxml_get_last_error, NULL)
+       PHP_FE(libxml_clear_errors, NULL)
+       PHP_FE(libxml_get_errors, NULL)
        {NULL, NULL, NULL}
 };
 
@@ -235,6 +243,7 @@
 {
        LIBXML(stream_context) = NULL;
        LIBXML(error_buffer).c = NULL;
+       LIBXML(error_list) = NULL;
 }
 #endif
 
@@ -325,6 +334,45 @@
        return php_stream_close((php_stream*)context);
 }
 
+static int _php_libxml_free_error(xmlErrorPtr error) {
+       /* This will free the libxml alloc'd memory */
+       xmlResetError(error);
+       return 1;
+}
+
+static void _php_list_set_error_structure(xmlErrorPtr error, const char *msg)
+{
+       xmlError error_copy;
+       int ret;
+
+       TSRMLS_FETCH();
+
+       memset(&error_copy, 0, sizeof(xmlError));
+
+       if (error) {
+               ret = xmlCopyError(error, &error_copy);
+       } else {
+               error_copy.domain = 0;
+               error_copy.code = XML_ERR_INTERNAL_ERROR;
+               error_copy.level = XML_ERR_ERROR;
+               error_copy.line = 0;
+               error_copy.node = NULL;
+               error_copy.int1 = 0;
+               error_copy.int2 = 0;
+               error_copy.ctxt = NULL;
+               error_copy.message = xmlStrdup(msg);
+               error_copy.file = NULL;
+               error_copy.str1 = NULL;
+               error_copy.str2 = NULL;
+               error_copy.str3 = NULL;
+               ret = 0;
+       }
+
+       if (ret == 0) {
+               zend_llist_add_element(LIBXML(error_list), &error_copy);
+       }
+}
+
 static void php_libxml_ctx_error_level(int level, void *ctx, const char *msg 
TSRMLS_DC)
 {
        xmlParserCtxtPtr parser;
@@ -361,15 +409,19 @@
        efree(buf);
 
        if (output == 1) {
-               switch (error_type) {
-                       case PHP_LIBXML_CTX_ERROR:
-                               php_libxml_ctx_error_level(E_WARNING, ctx, 
LIBXML(error_buffer).c TSRMLS_CC);
-                               break;
-                       case PHP_LIBXML_CTX_WARNING:
-                               php_libxml_ctx_error_level(E_NOTICE, ctx, 
LIBXML(error_buffer).c TSRMLS_CC);
-                               break;
-                       default:
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"%s", LIBXML(error_buffer).c);
+               if (LIBXML(error_list)) {
+                       _php_list_set_error_structure(NULL, 
LIBXML(error_buffer).c);
+               } else {
+                       switch (error_type) {
+                               case PHP_LIBXML_CTX_ERROR:
+                                       php_libxml_ctx_error_level(E_WARNING, 
ctx, LIBXML(error_buffer).c TSRMLS_CC);
+                                       break;
+                               case PHP_LIBXML_CTX_WARNING:
+                                       php_libxml_ctx_error_level(E_NOTICE, 
ctx, LIBXML(error_buffer).c TSRMLS_CC);
+                                       break;
+                               default:
+                                       php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "%s", LIBXML(error_buffer).c);
+                       }
                }
                smart_str_free(&LIBXML(error_buffer));
        }
@@ -391,6 +443,13 @@
        va_end(args);
 }
 
+PHP_LIBXML_API void php_libxml_structured_error_handler(void *userData, 
xmlErrorPtr error)
+{
+       _php_list_set_error_structure(error, NULL);
+
+       return;
+}
+
 PHP_LIBXML_API void php_libxml_error_handler(void *ctx, const char *msg, ...)
 {
        va_list args;
@@ -449,6 +508,10 @@
 
 PHP_MINIT_FUNCTION(libxml)
 {
+#if LIBXML_VERSION >= 20600
+       zend_class_entry ce;
+#endif
+
        php_libxml_initialize();
 
 #ifdef ZTS
@@ -456,6 +519,7 @@
 #else
        LIBXML(stream_context) = NULL;
        LIBXML(error_buffer).c = NULL;
+       LIBXML(error_list) = NULL;
 #endif
 
 #if LIBXML_VERSION >= 20600
@@ -471,6 +535,15 @@
        REGISTER_LONG_CONSTANT("LIBXML_NSCLEAN",        XML_PARSE_NSCLEAN,      
        CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("LIBXML_NOCDATA",        XML_PARSE_NOCDATA,      
        CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("LIBXML_NONET",          XML_PARSE_NONET,        
        CONST_CS | CONST_PERSISTENT);
+
+       /* Error levels */
+       REGISTER_LONG_CONSTANT("LIBXML_ERR_NONE",               XML_ERR_NONE,   
        CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("LIBXML_ERR_WARNING",    XML_ERR_WARNING,        
CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("LIBXML_ERR_ERROR",              XML_ERR_ERROR,  
        CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("LIBXML_ERR_FATAL",              XML_ERR_FATAL,  
        CONST_CS | CONST_PERSISTENT);
+
+       INIT_CLASS_ENTRY(ce, "LibXMLError", NULL);
+       libxmlerror_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
 #endif
 
        return SUCCESS;
@@ -481,7 +554,6 @@
 {
        /* report errors via handler rather than stderr */
        xmlSetGenericErrorFunc(NULL, php_libxml_error_handler);
-
     return SUCCESS;
 }
 
@@ -498,8 +570,15 @@
 {
        /* reset libxml generic error handling */
        xmlSetGenericErrorFunc(NULL, NULL);
+       xmlSetStructuredErrorFunc(NULL, NULL);
 
        smart_str_free(&LIBXML(error_buffer));
+       if (LIBXML(error_list)) {
+               zend_llist_destroy(LIBXML(error_list));
+               efree(LIBXML(error_list));
+               LIBXML(error_list) = NULL;
+       }
+
        return SUCCESS;
 }
 
@@ -533,6 +612,144 @@
 }
 /* }}} */
 
+/* {{{ proto void libxml_use_internal_errors(boolean use_errors) 
+   Disable libxml errors and allow user to fetch error information as needed */
+PHP_FUNCTION(libxml_use_internal_errors)
+{
+#if LIBXML_VERSION >= 20600
+       xmlStructuredErrorFunc current_handler;
+       int use_errors=0, retval;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &use_errors) 
== FAILURE) {
+               return;
+       }
+
+       current_handler = xmlStructuredError;
+       if (current_handler && current_handler == 
php_libxml_structured_error_handler) {
+               retval = 1;
+       } else {
+               retval = 0;
+       }
+
+       if (ZEND_NUM_ARGS() == 0) {
+               RETURN_BOOL(retval);
+       }
+
+       if (use_errors == 0) {
+               xmlSetStructuredErrorFunc(NULL, NULL);
+               if (LIBXML(error_list)) {
+                       zend_llist_destroy(LIBXML(error_list));
+                       efree(LIBXML(error_list));
+                       LIBXML(error_list) = NULL;
+               }
+       } else {
+               xmlSetStructuredErrorFunc(NULL, 
php_libxml_structured_error_handler);
+               if (LIBXML(error_list) == NULL) {
+                       LIBXML(error_list) = (zend_llist *) 
emalloc(sizeof(zend_llist));
+                       zend_llist_init(LIBXML(error_list), sizeof(xmlError), 
(llist_dtor_func_t) _php_libxml_free_error, 0);
+               }
+       }
+       RETURN_BOOL(retval);
+#else
+       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Libxml 2.6 or higher is 
required");
+#endif
+}
+
+/* {{{ proto object libxml_get_last_error() 
+   Retrieve last error from libxml */
+PHP_FUNCTION(libxml_get_last_error)
+{
+#if LIBXML_VERSION >= 20600
+       xmlErrorPtr error;
+
+       error = xmlGetLastError();
+       
+       if (error) {
+               object_init_ex(return_value, libxmlerror_class_entry);
+               add_property_long(return_value, "level", error->level);
+               add_property_long(return_value, "code", error->code);
+               add_property_long(return_value, "column", error->int2);
+               if (error->message) {
+                       add_property_string(return_value, "message", 
error->message, 1);
+               } else {
+                       add_property_stringl(return_value, "message", "", 0, 1);
+               }
+               if (error->file) {
+                       add_property_string(return_value, "file", error->file, 
1);
+               } else {
+                       add_property_stringl(return_value, "file", "", 0, 1);
+               }
+               add_property_long(return_value, "line", error->line);
+       } else {
+               RETURN_FALSE;
+       }
+#else
+       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Libxml 2.6 or higher is 
required");
+#endif
+}
+/* }}} */
+
+/* {{{ proto object libxml_get_errors()
+   Retrieve array of errors */
+PHP_FUNCTION(libxml_get_errors)
+{
+#if LIBXML_VERSION >= 20600
+       
+       xmlErrorPtr error;
+
+       if (array_init(return_value) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       if (LIBXML(error_list)) {
+
+               error = zend_llist_get_first(LIBXML(error_list));
+
+               while (error != NULL) {
+                       zval *z_error;
+                       MAKE_STD_ZVAL(z_error);
+
+                       object_init_ex(z_error, libxmlerror_class_entry);
+                       add_property_long(z_error, "level", error->level);
+                       add_property_long(z_error, "code", error->code);
+                       add_property_long(z_error, "column", error->int2);
+                       if (error->message) {
+                               add_property_string(z_error, "message", 
error->message, 1);
+                       } else {
+                               add_property_stringl(z_error, "message", "", 0, 
1);
+                       }
+                       if (error->file) {
+                               add_property_string(z_error, "file", 
error->file, 1);
+                       } else {
+                               add_property_stringl(z_error, "file", "", 0, 1);
+                       }
+                       add_property_long(z_error, "line", error->line);
+                       add_next_index_zval(return_value, z_error);
+
+                       error = zend_llist_get_next(LIBXML(error_list));
+               }
+       }
+#else
+       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Libxml 2.6 or higher is 
required");
+#endif
+}
+/* }}} */
+
+/* {{{ proto void libxml_clear_errors() 
+    Clear last error from libxml */
+PHP_FUNCTION(libxml_clear_errors)
+{
+#if LIBXML_VERSION >= 20600
+       xmlResetLastError();
+       if (LIBXML(error_list)) {
+               zend_llist_clean(LIBXML(error_list));
+       }
+#else
+       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Libxml 2.6 or higher is 
required");
+#endif
+}
+/* }}} */
+
 /* {{{ Common functions shared by extensions */
 int php_libxml_xmlCheckUTF8(const unsigned char *s)
 {

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to