Annotation of embedaddon/php/ext/tidy/tidy.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
                      5:   | Copyright (c) 1997-2012 The PHP Group                                |
                      6:   +----------------------------------------------------------------------+
                      7:   | This source file is subject to version 3.01 of the PHP license,      |
                      8:   | that is bundled with this package in the file LICENSE, and is        |
                      9:   | available through the world-wide-web at the following url:           |
                     10:   | http://www.php.net/license/3_01.txt                                  |
                     11:   | If you did not receive a copy of the PHP license and are unable to   |
                     12:   | obtain it through the world-wide-web, please send a note to          |
                     13:   | license@php.net so we can mail you a copy immediately.               |
                     14:   +----------------------------------------------------------------------+
                     15:   | Author: John Coggeshall <john@php.net>                               |
                     16:   +----------------------------------------------------------------------+
                     17: */
                     18: 
                     19: /* $Id: tidy.c 321634 2012-01-01 13:15:04Z felipe $ */
                     20: 
                     21: #ifdef HAVE_CONFIG_H
                     22: #include "config.h"
                     23: #endif
                     24: 
                     25: #include "php.h"
                     26: #include "php_tidy.h"
                     27: 
                     28: #if HAVE_TIDY
                     29: 
                     30: #include "php_ini.h"
                     31: #include "ext/standard/info.h"
                     32: #include "safe_mode.h"
                     33: 
                     34: #include "tidy.h"
                     35: #include "buffio.h"
                     36: 
                     37: /* compatibility with older versions of libtidy */
                     38: #ifndef TIDY_CALL
                     39: #define TIDY_CALL
                     40: #endif
                     41: 
                     42: #define PHP_TIDY_MODULE_VERSION        "2.0"
                     43: 
                     44: /* {{{ ext/tidy macros
                     45: */
                     46: #define TIDY_SET_CONTEXT \
                     47:     zval *object = getThis();
                     48: 
                     49: #define TIDY_FETCH_OBJECT      \
                     50:        PHPTidyObj *obj;        \
                     51:        TIDY_SET_CONTEXT; \
                     52:        if (object) {   \
                     53:                if (zend_parse_parameters_none() == FAILURE) {  \
                     54:                        return; \
                     55:                }       \
                     56:        } else {        \
                     57:                if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) {      \
                     58:                        RETURN_FALSE;   \
                     59:                }       \
                     60:        }       \
                     61:        obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC);    \
                     62: 
                     63: #define TIDY_FETCH_ONLY_OBJECT \
                     64:        PHPTidyObj *obj;        \
                     65:        TIDY_SET_CONTEXT; \
                     66:        if (zend_parse_parameters_none() == FAILURE) {  \
                     67:                return; \
                     68:        }       \
                     69:        obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC);    \
                     70: 
                     71: #define TIDY_APPLY_CONFIG_ZVAL(_doc, _val) \
                     72:     if(_val) { \
                     73:         if(Z_TYPE_PP(_val) == IS_ARRAY) { \
                     74:             _php_tidy_apply_config_array(_doc, HASH_OF(*_val) TSRMLS_CC); \
                     75:         } else { \
                     76:             convert_to_string_ex(_val); \
                     77:             TIDY_SAFE_MODE_CHECK(Z_STRVAL_PP(_val)); \
                     78:             switch (tidyLoadConfig(_doc, Z_STRVAL_PP(_val))) { \
                     79:               case -1: \
                     80:                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s'", Z_STRVAL_PP(_val)); \
                     81:                 break; \
                     82:               case 1: \
                     83:                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "There were errors while parsing the configuration file '%s'", Z_STRVAL_PP(_val)); \
                     84:                 break; \
                     85:             } \
                     86:         } \
                     87:     }
                     88: 
                     89: #define REGISTER_TIDY_CLASS(classname, name, parent, __flags) \
                     90:        { \
                     91:                zend_class_entry ce; \
                     92:                INIT_CLASS_ENTRY(ce, # classname, tidy_funcs_ ## name); \
                     93:                ce.create_object = tidy_object_new_ ## name; \
                     94:                tidy_ce_ ## name = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \
                     95:                tidy_ce_ ## name->ce_flags |= __flags;  \
                     96:                memcpy(&tidy_object_handlers_ ## name, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); \
                     97:                tidy_object_handlers_ ## name.clone_obj = NULL; \
                     98:        }
                     99: 
                    100: #define TIDY_TAG_CONST(tag) REGISTER_LONG_CONSTANT("TIDY_TAG_" #tag, TidyTag_##tag, CONST_CS | CONST_PERSISTENT)
                    101: #define TIDY_NODE_CONST(name, type) REGISTER_LONG_CONSTANT("TIDY_NODETYPE_" #name, TidyNode_##type, CONST_CS | CONST_PERSISTENT)
                    102: 
                    103: #ifndef TRUE
                    104: #define TRUE 1
                    105: #endif
                    106: 
                    107: #ifndef FALSE
                    108: #define FALSE 0
                    109: #endif
                    110: 
                    111: #define ADD_PROPERTY_STRING(_table, _key, _string) \
                    112:        { \
                    113:                zval *tmp; \
                    114:                MAKE_STD_ZVAL(tmp); \
                    115:                if (_string) { \
                    116:                        ZVAL_STRING(tmp, (char *)_string, 1); \
                    117:                } else { \
                    118:                        ZVAL_EMPTY_STRING(tmp); \
                    119:                } \
                    120:                zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
                    121:        }
                    122: 
                    123: #define ADD_PROPERTY_STRINGL(_table, _key, _string, _len) \
                    124:    { \
                    125:        zval *tmp; \
                    126:        MAKE_STD_ZVAL(tmp); \
                    127:        if (_string) { \
                    128:            ZVAL_STRINGL(tmp, (char *)_string, _len, 1); \
                    129:        } else { \
                    130:            ZVAL_EMPTY_STRING(tmp); \
                    131:        } \
                    132:        zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
                    133:    }
                    134: 
                    135: #define ADD_PROPERTY_LONG(_table, _key, _long) \
                    136:        { \
                    137:                zval *tmp; \
                    138:                MAKE_STD_ZVAL(tmp); \
                    139:                ZVAL_LONG(tmp, _long); \
                    140:                zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
                    141:        }
                    142: 
                    143: #define ADD_PROPERTY_NULL(_table, _key) \
                    144:        { \
                    145:                zval *tmp; \
                    146:                MAKE_STD_ZVAL(tmp); \
                    147:                ZVAL_NULL(tmp); \
                    148:                zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
                    149:        }
                    150: 
                    151: #define ADD_PROPERTY_BOOL(_table, _key, _bool) \
                    152:     { \
                    153:        zval *tmp; \
                    154:        MAKE_STD_ZVAL(tmp); \
                    155:        ZVAL_BOOL(tmp, _bool); \
                    156:        zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
                    157:    }
                    158: 
                    159: #define TIDY_SAFE_MODE_CHECK(filename) \
                    160: if ((PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename TSRMLS_CC)) { \
                    161:        RETURN_FALSE; \
                    162: } \
                    163: 
                    164: #define TIDY_SET_DEFAULT_CONFIG(_doc) \
                    165:        if (TG(default_config) && TG(default_config)[0]) { \
                    166:                if (tidyLoadConfig(_doc, TG(default_config)) < 0) { \
                    167:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load Tidy configuration file at '%s'.", TG(default_config)); \
                    168:                } \
                    169:        }
                    170: /* }}} */
                    171: 
                    172: /* {{{ ext/tidy structs 
                    173: */
                    174: typedef struct _PHPTidyDoc PHPTidyDoc;
                    175: typedef struct _PHPTidyObj PHPTidyObj;
                    176: 
                    177: typedef enum {
                    178:        is_node,
                    179:        is_doc
                    180: } tidy_obj_type;
                    181: 
                    182: typedef enum {
                    183:        is_root_node,
                    184:        is_html_node,
                    185:        is_head_node,
                    186:        is_body_node
                    187: } tidy_base_nodetypes;
                    188: 
                    189: struct _PHPTidyDoc {
                    190:        TidyDoc     doc;
                    191:        TidyBuffer  *errbuf;
                    192:        unsigned int ref_count;
                    193: };
                    194: 
                    195: struct _PHPTidyObj {
                    196:        zend_object         std;
                    197:        TidyNode            node;
                    198:        tidy_obj_type       type;
                    199:        PHPTidyDoc          *ptdoc;
                    200: };
                    201: /* }}} */
                    202: 
                    203: /* {{{ ext/tidy prototypes
                    204: */
                    205: static char *php_tidy_file_to_mem(char *, zend_bool, int * TSRMLS_DC);
                    206: static void tidy_object_free_storage(void * TSRMLS_DC);
                    207: static zend_object_value tidy_object_new_node(zend_class_entry * TSRMLS_DC);
                    208: static zend_object_value tidy_object_new_doc(zend_class_entry * TSRMLS_DC);
                    209: static zval * tidy_instanciate(zend_class_entry *, zval * TSRMLS_DC);
                    210: static int tidy_doc_cast_handler(zval *, zval *, int TSRMLS_DC);
                    211: static int tidy_node_cast_handler(zval *, zval *, int TSRMLS_DC);
                    212: static void tidy_doc_update_properties(PHPTidyObj * TSRMLS_DC);
                    213: static void tidy_add_default_properties(PHPTidyObj *, tidy_obj_type TSRMLS_DC);
                    214: static void *php_tidy_get_opt_val(PHPTidyDoc *, TidyOption, TidyOptionType * TSRMLS_DC);
                    215: static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetypes);
                    216: static int _php_tidy_set_tidy_opt(TidyDoc, char *, zval * TSRMLS_DC);
                    217: static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC);
                    218: static void _php_tidy_register_nodetypes(INIT_FUNC_ARGS);
                    219: static void _php_tidy_register_tags(INIT_FUNC_ARGS);
                    220: 
                    221: static PHP_MINIT_FUNCTION(tidy);
                    222: static PHP_MSHUTDOWN_FUNCTION(tidy);
                    223: static PHP_RINIT_FUNCTION(tidy);
                    224: static PHP_MINFO_FUNCTION(tidy);
                    225: 
                    226: static PHP_FUNCTION(tidy_getopt);
                    227: static PHP_FUNCTION(tidy_parse_string);
                    228: static PHP_FUNCTION(tidy_parse_file);
                    229: static PHP_FUNCTION(tidy_clean_repair);
                    230: static PHP_FUNCTION(tidy_repair_string);
                    231: static PHP_FUNCTION(tidy_repair_file);
                    232: static PHP_FUNCTION(tidy_diagnose);
                    233: static PHP_FUNCTION(tidy_get_output);
                    234: static PHP_FUNCTION(tidy_get_error_buffer);
                    235: static PHP_FUNCTION(tidy_get_release);
                    236: static PHP_FUNCTION(tidy_get_config);
                    237: static PHP_FUNCTION(tidy_get_status);
                    238: static PHP_FUNCTION(tidy_get_html_ver);
                    239: #if HAVE_TIDYOPTGETDOC
                    240: static PHP_FUNCTION(tidy_get_opt_doc);
                    241: #endif
                    242: static PHP_FUNCTION(tidy_is_xhtml);
                    243: static PHP_FUNCTION(tidy_is_xml);
                    244: static PHP_FUNCTION(tidy_error_count);
                    245: static PHP_FUNCTION(tidy_warning_count);
                    246: static PHP_FUNCTION(tidy_access_count);
                    247: static PHP_FUNCTION(tidy_config_count);
                    248: 
                    249: static PHP_FUNCTION(ob_tidyhandler);
                    250: 
                    251: static PHP_FUNCTION(tidy_get_root);
                    252: static PHP_FUNCTION(tidy_get_html);
                    253: static PHP_FUNCTION(tidy_get_head);
                    254: static PHP_FUNCTION(tidy_get_body);
                    255: 
                    256: static TIDY_DOC_METHOD(__construct);
                    257: static TIDY_DOC_METHOD(parseFile);
                    258: static TIDY_DOC_METHOD(parseString);
                    259: 
                    260: static TIDY_NODE_METHOD(hasChildren);
                    261: static TIDY_NODE_METHOD(hasSiblings);
                    262: static TIDY_NODE_METHOD(isComment);
                    263: static TIDY_NODE_METHOD(isHtml);
                    264: static TIDY_NODE_METHOD(isText);
                    265: static TIDY_NODE_METHOD(isJste);
                    266: static TIDY_NODE_METHOD(isAsp);
                    267: static TIDY_NODE_METHOD(isPhp);
                    268: static TIDY_NODE_METHOD(getParent);
                    269: static TIDY_NODE_METHOD(__construct);
                    270: /* }}} */
                    271: 
                    272: ZEND_DECLARE_MODULE_GLOBALS(tidy)
                    273: 
                    274: PHP_INI_BEGIN()
                    275: STD_PHP_INI_ENTRY("tidy.default_config",       "",     PHP_INI_SYSTEM,         OnUpdateString,         default_config,         zend_tidy_globals,      tidy_globals)
                    276: PHP_INI_ENTRY("tidy.clean_output",     "0",    PHP_INI_PERDIR,         NULL)
                    277: PHP_INI_END()
                    278: 
                    279: /* {{{ arginfo */
                    280: ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_parse_string, 0, 0, 1)
                    281:        ZEND_ARG_INFO(0, input)
                    282:        ZEND_ARG_INFO(0, config_options)
                    283:        ZEND_ARG_INFO(0, encoding)
                    284: ZEND_END_ARG_INFO()
                    285: 
                    286: ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_get_error_buffer, 0, 0, 0)
                    287:        ZEND_ARG_INFO(0, detailed)
                    288: ZEND_END_ARG_INFO()
                    289: 
                    290: ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_output, 0)
                    291: ZEND_END_ARG_INFO()
                    292: 
                    293: ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_parse_file, 0, 0, 1)
                    294:        ZEND_ARG_INFO(0, file)
                    295:        ZEND_ARG_INFO(0, config_options)
                    296:        ZEND_ARG_INFO(0, encoding)
                    297:        ZEND_ARG_INFO(0, use_include_path)
                    298: ZEND_END_ARG_INFO()
                    299: 
                    300: ZEND_BEGIN_ARG_INFO(arginfo_tidy_clean_repair, 0)
                    301: ZEND_END_ARG_INFO()
                    302: 
                    303: ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_repair_string, 0, 0, 1)
                    304:        ZEND_ARG_INFO(0, data)
                    305:        ZEND_ARG_INFO(0, config_file)
                    306:        ZEND_ARG_INFO(0, encoding)
                    307: ZEND_END_ARG_INFO()
                    308: 
                    309: ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_repair_file, 0, 0, 1)
                    310:        ZEND_ARG_INFO(0, filename)
                    311:        ZEND_ARG_INFO(0, config_file)
                    312:        ZEND_ARG_INFO(0, encoding)
                    313:        ZEND_ARG_INFO(0, use_include_path)
                    314: ZEND_END_ARG_INFO()
                    315: 
                    316: ZEND_BEGIN_ARG_INFO(arginfo_tidy_diagnose, 0)
                    317: ZEND_END_ARG_INFO()
                    318: 
                    319: ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_release, 0)
                    320: ZEND_END_ARG_INFO()
                    321: 
                    322: #if HAVE_TIDYOPTGETDOC
                    323: ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_get_opt_doc, 0, 0, 2)
                    324:        ZEND_ARG_INFO(0, resource)
                    325:        ZEND_ARG_INFO(0, optname)
                    326: ZEND_END_ARG_INFO()
                    327: #endif
                    328: 
                    329: ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_config, 0)
                    330: ZEND_END_ARG_INFO()
                    331: 
                    332: ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_status, 0)
                    333: ZEND_END_ARG_INFO()
                    334: 
                    335: ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_html_ver, 0)
                    336: ZEND_END_ARG_INFO()
                    337: 
                    338: ZEND_BEGIN_ARG_INFO(arginfo_tidy_is_xhtml, 0)
                    339: ZEND_END_ARG_INFO()
                    340: 
                    341: ZEND_BEGIN_ARG_INFO(arginfo_tidy_is_xml, 0)
                    342: ZEND_END_ARG_INFO()
                    343: 
                    344: ZEND_BEGIN_ARG_INFO(arginfo_tidy_error_count, 0)
                    345: ZEND_END_ARG_INFO()
                    346: 
                    347: ZEND_BEGIN_ARG_INFO(arginfo_tidy_warning_count, 0)
                    348: ZEND_END_ARG_INFO()
                    349: 
                    350: ZEND_BEGIN_ARG_INFO(arginfo_tidy_access_count, 0)
                    351: ZEND_END_ARG_INFO()
                    352: 
                    353: ZEND_BEGIN_ARG_INFO(arginfo_tidy_config_count, 0)
                    354: ZEND_END_ARG_INFO()
                    355: 
                    356: ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_getopt, 0, 0, 1)
                    357:        ZEND_ARG_INFO(0, option)
                    358: ZEND_END_ARG_INFO()
                    359: 
                    360: ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_root, 0)
                    361: ZEND_END_ARG_INFO()
                    362: 
                    363: ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_html, 0)
                    364: ZEND_END_ARG_INFO()
                    365: 
                    366: ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_head, 0)
                    367: ZEND_END_ARG_INFO()
                    368: 
                    369: ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_get_body, 0, 0, 1)
                    370:        ZEND_ARG_INFO(0, tidy)
                    371: ZEND_END_ARG_INFO()
                    372: 
                    373: ZEND_BEGIN_ARG_INFO_EX(arginfo_ob_tidyhandler, 0, 0, 1)
                    374:        ZEND_ARG_INFO(0, input)
                    375:        ZEND_ARG_INFO(0, mode)
                    376: ZEND_END_ARG_INFO()
                    377: /* }}} */
                    378: 
                    379: static const zend_function_entry tidy_functions[] = {
                    380:        PHP_FE(tidy_getopt,             arginfo_tidy_getopt)
                    381:        PHP_FE(tidy_parse_string,       arginfo_tidy_parse_string)
                    382:        PHP_FE(tidy_parse_file,         arginfo_tidy_parse_file)
                    383:        PHP_FE(tidy_get_output,         arginfo_tidy_get_output)
                    384:        PHP_FE(tidy_get_error_buffer,   arginfo_tidy_get_error_buffer) 
                    385:        PHP_FE(tidy_clean_repair,       arginfo_tidy_clean_repair)
                    386:        PHP_FE(tidy_repair_string,      arginfo_tidy_repair_string)
                    387:        PHP_FE(tidy_repair_file,        arginfo_tidy_repair_file)
                    388:        PHP_FE(tidy_diagnose,           arginfo_tidy_diagnose)
                    389:        PHP_FE(tidy_get_release,        arginfo_tidy_get_release)
                    390:        PHP_FE(tidy_get_config,         arginfo_tidy_get_config)
                    391:        PHP_FE(tidy_get_status,         arginfo_tidy_get_status)
                    392:        PHP_FE(tidy_get_html_ver,       arginfo_tidy_get_html_ver)
                    393:        PHP_FE(tidy_is_xhtml,           arginfo_tidy_is_xhtml)
                    394:        PHP_FE(tidy_is_xml,             arginfo_tidy_is_xml)
                    395:        PHP_FE(tidy_error_count,        arginfo_tidy_error_count)
                    396:        PHP_FE(tidy_warning_count,      arginfo_tidy_warning_count)
                    397:        PHP_FE(tidy_access_count,       arginfo_tidy_access_count)
                    398:        PHP_FE(tidy_config_count,       arginfo_tidy_config_count) 
                    399: #if HAVE_TIDYOPTGETDOC
                    400:        PHP_FE(tidy_get_opt_doc,        arginfo_tidy_get_opt_doc)
                    401: #endif
                    402:        PHP_FE(tidy_get_root,           arginfo_tidy_get_root)
                    403:        PHP_FE(tidy_get_head,           arginfo_tidy_get_head)
                    404:        PHP_FE(tidy_get_html,           arginfo_tidy_get_html)
                    405:        PHP_FE(tidy_get_body,           arginfo_tidy_get_body)
                    406:        PHP_FE(ob_tidyhandler,          arginfo_ob_tidyhandler)
                    407:        PHP_FE_END
                    408: };
                    409: 
                    410: static const zend_function_entry tidy_funcs_doc[] = {
                    411:        TIDY_METHOD_MAP(getOpt, tidy_getopt, NULL)
                    412:        TIDY_METHOD_MAP(cleanRepair, tidy_clean_repair, NULL)
                    413:        TIDY_DOC_ME(parseFile, NULL)
                    414:        TIDY_DOC_ME(parseString, NULL)
                    415:        TIDY_METHOD_MAP(repairString, tidy_repair_string, NULL)
                    416:        TIDY_METHOD_MAP(repairFile, tidy_repair_file, NULL)
                    417:        TIDY_METHOD_MAP(diagnose, tidy_diagnose, NULL)
                    418:        TIDY_METHOD_MAP(getRelease, tidy_get_release, NULL)
                    419:        TIDY_METHOD_MAP(getConfig, tidy_get_config, NULL)
                    420:        TIDY_METHOD_MAP(getStatus, tidy_get_status, NULL)
                    421:        TIDY_METHOD_MAP(getHtmlVer, tidy_get_html_ver, NULL)
                    422: #if HAVE_TIDYOPTGETDOC
                    423:        TIDY_METHOD_MAP(getOptDoc, tidy_get_opt_doc, NULL)
                    424: #endif
                    425:        TIDY_METHOD_MAP(isXhtml, tidy_is_xhtml, NULL)
                    426:        TIDY_METHOD_MAP(isXml, tidy_is_xml, NULL)
                    427:        TIDY_METHOD_MAP(root, tidy_get_root, NULL)
                    428:        TIDY_METHOD_MAP(head, tidy_get_head, NULL)
                    429:        TIDY_METHOD_MAP(html, tidy_get_html, NULL)
                    430:        TIDY_METHOD_MAP(body, tidy_get_body, NULL)
                    431:        TIDY_DOC_ME(__construct, NULL)
                    432:        PHP_FE_END
                    433: };
                    434: 
                    435: static const zend_function_entry tidy_funcs_node[] = {
                    436:        TIDY_NODE_ME(hasChildren, NULL)
                    437:        TIDY_NODE_ME(hasSiblings, NULL)
                    438:        TIDY_NODE_ME(isComment, NULL)
                    439:        TIDY_NODE_ME(isHtml, NULL)
                    440:        TIDY_NODE_ME(isText, NULL)
                    441:        TIDY_NODE_ME(isJste, NULL)
                    442:        TIDY_NODE_ME(isAsp, NULL)
                    443:        TIDY_NODE_ME(isPhp, NULL)
                    444:        TIDY_NODE_ME(getParent, NULL)
                    445:        TIDY_NODE_PRIVATE_ME(__construct, NULL)
                    446:        PHP_FE_END
                    447: };
                    448: 
                    449: static zend_class_entry *tidy_ce_doc, *tidy_ce_node;
                    450: 
                    451: static zend_object_handlers tidy_object_handlers_doc;
                    452: static zend_object_handlers tidy_object_handlers_node;
                    453: 
                    454: zend_module_entry tidy_module_entry = {
                    455:        STANDARD_MODULE_HEADER,
                    456:        "tidy",
                    457:        tidy_functions,
                    458:        PHP_MINIT(tidy),
                    459:        PHP_MSHUTDOWN(tidy),
                    460:        PHP_RINIT(tidy),
                    461:        NULL,
                    462:        PHP_MINFO(tidy),
                    463:        PHP_TIDY_MODULE_VERSION,
                    464:        PHP_MODULE_GLOBALS(tidy),
                    465:        NULL,
                    466:        NULL,
                    467:        NULL,
                    468:        STANDARD_MODULE_PROPERTIES_EX
                    469: };
                    470: 
                    471: #ifdef COMPILE_DL_TIDY
                    472: ZEND_GET_MODULE(tidy)
                    473: #endif
                    474: 
                    475: static void* TIDY_CALL php_tidy_malloc(size_t len)
                    476: {
                    477:        return emalloc(len);
                    478: }
                    479: 
                    480: static void* TIDY_CALL php_tidy_realloc(void *buf, size_t len)
                    481: {
                    482:        return erealloc(buf, len);
                    483: }
                    484: 
                    485: static void TIDY_CALL php_tidy_free(void *buf)
                    486: {
                    487:        efree(buf);
                    488: }
                    489: 
                    490: static void TIDY_CALL php_tidy_panic(ctmbstr msg)
                    491: {
                    492:        TSRMLS_FETCH();
                    493:        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not allocate memory for tidy! (Reason: %s)", (char *)msg);
                    494: }
                    495: 
                    496: static int _php_tidy_set_tidy_opt(TidyDoc doc, char *optname, zval *value TSRMLS_DC)
                    497: {
                    498:        TidyOption opt = tidyGetOptionByName(doc, optname);
                    499:        zval conv = *value;
                    500: 
                    501:        if (!opt) {
                    502:                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown Tidy Configuration Option '%s'", optname);
                    503:                return FAILURE;
                    504:        }
                    505:        
                    506:        if (tidyOptIsReadOnly(opt)) {
                    507:                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Attempting to set read-only option '%s'", optname);
                    508:                return FAILURE;
                    509:        }
                    510: 
                    511:        switch(tidyOptGetType(opt)) {
                    512:                case TidyString:
                    513:                        if (Z_TYPE(conv) != IS_STRING) {
                    514:                                zval_copy_ctor(&conv);
                    515:                                convert_to_string(&conv);
                    516:                        }
                    517:                        if (tidyOptSetValue(doc, tidyOptGetId(opt), Z_STRVAL(conv))) {
                    518:                                if (Z_TYPE(conv) != Z_TYPE_P(value)) {
                    519:                                        zval_dtor(&conv);
                    520:                                }
                    521:                                return SUCCESS;
                    522:                        }
                    523:                        if (Z_TYPE(conv) != Z_TYPE_P(value)) {
                    524:                                zval_dtor(&conv);
                    525:                        }
                    526:                        break;
                    527: 
                    528:                case TidyInteger:
                    529:                        if (Z_TYPE(conv) != IS_LONG) {
                    530:                                zval_copy_ctor(&conv);
                    531:                                convert_to_long(&conv);
                    532:                        }
                    533:                        if (tidyOptSetInt(doc, tidyOptGetId(opt), Z_LVAL(conv))) {
                    534:                                return SUCCESS;
                    535:                        }
                    536:                        break;
                    537: 
                    538:                case TidyBoolean:
                    539:                        if (Z_TYPE(conv) != IS_LONG) {
                    540:                                zval_copy_ctor(&conv);
                    541:                                convert_to_long(&conv);
                    542:                        }
                    543:                        if (tidyOptSetBool(doc, tidyOptGetId(opt), Z_LVAL(conv))) {
                    544:                                return SUCCESS;
                    545:                        }
                    546:                        break;
                    547: 
                    548:                default:
                    549:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to determine type of configuration option");
                    550:                        break;
                    551:        }       
                    552: 
                    553:        return FAILURE;
                    554: }
                    555: 
                    556: static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_file)
                    557: {
                    558:        char *data=NULL, *arg1, *enc = NULL;
                    559:        int arg1_len, enc_len = 0, data_len = 0;
                    560:        zend_bool use_include_path = 0;
                    561:        TidyDoc doc;
                    562:        TidyBuffer *errbuf;
                    563:        zval **config = NULL;
                    564: 
                    565:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zsb", &arg1, &arg1_len, &config, &enc, &enc_len, &use_include_path) == FAILURE) {
                    566:                RETURN_FALSE;
                    567:        }
                    568:        
                    569:        if (is_file) {
                    570:                if (strlen(arg1) != arg1_len) {
                    571:                        RETURN_FALSE;
                    572:                }
                    573:                if (!(data = php_tidy_file_to_mem(arg1, use_include_path, &data_len TSRMLS_CC))) {
                    574:                        RETURN_FALSE;
                    575:                }
                    576:        } else {
                    577:                data = arg1;
                    578:                data_len = arg1_len;
                    579:        }
                    580: 
                    581:        doc = tidyCreate();
                    582:        errbuf = emalloc(sizeof(TidyBuffer));
                    583:        tidyBufInit(errbuf);
                    584:        
                    585:        if (tidySetErrorBuffer(doc, errbuf) != 0) {
                    586:                tidyBufFree(errbuf);
                    587:                efree(errbuf);
                    588:                tidyRelease(doc);
                    589:                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not set Tidy error buffer");
                    590:        }
                    591:        
                    592:        tidyOptSetBool(doc, TidyForceOutput, yes);
                    593:        tidyOptSetBool(doc, TidyMark, no);
                    594:        
                    595:        TIDY_SET_DEFAULT_CONFIG(doc);
                    596:        
                    597:        if (config) {
                    598:                TIDY_APPLY_CONFIG_ZVAL(doc, config);
                    599:        }
                    600: 
                    601:        if(enc_len) {
                    602:                if (tidySetCharEncoding(doc, enc) < 0) {
                    603:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not set encoding '%s'", enc);
                    604:                        RETVAL_FALSE;
                    605:                }
                    606:        }
                    607:        
                    608:        if (data) {
                    609:                TidyBuffer buf;
                    610: 
                    611:                tidyBufInit(&buf);
                    612:                tidyBufAppend(&buf, data, data_len);
                    613: 
                    614:                if (tidyParseBuffer(doc, &buf) < 0) {
                    615:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf->bp);
                    616:                        RETVAL_FALSE;
                    617:                } else {
                    618:                        if (tidyCleanAndRepair(doc) >= 0) {
                    619:                                TidyBuffer output;
                    620:                                tidyBufInit(&output);
                    621: 
                    622:                                tidySaveBuffer (doc, &output);
                    623:                                RETVAL_STRINGL((char*)output.bp, output.size ? output.size-1 : 0, 1);
                    624:                                tidyBufFree(&output);
                    625:                        } else {
                    626:                                RETVAL_FALSE;
                    627:                        }
                    628:                }
                    629:                
                    630:                tidyBufFree(&buf);
                    631:        }
                    632: 
                    633:        if (is_file) {
                    634:                efree(data);
                    635:        }
                    636:        
                    637:        tidyBufFree(errbuf);
                    638:        efree(errbuf);
                    639:        tidyRelease(doc);
                    640: }
                    641: 
                    642: static char *php_tidy_file_to_mem(char *filename, zend_bool use_include_path, int *len TSRMLS_DC)
                    643: {
                    644:        php_stream *stream;
                    645:        char *data = NULL;
                    646: 
                    647:        if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE, NULL))) {
                    648:                return NULL;
                    649:        }
                    650:        if ((*len = (int) php_stream_copy_to_mem(stream, &data, PHP_STREAM_COPY_ALL, 0)) == 0) {
                    651:                data = estrdup("");
                    652:                *len = 0;
                    653:        }
                    654:        php_stream_close(stream);
                    655: 
                    656:        return data;
                    657: }
                    658: 
                    659: static void tidy_object_free_storage(void *object TSRMLS_DC)
                    660: {
                    661:        PHPTidyObj *intern = (PHPTidyObj *)object;
                    662: 
                    663:        zend_object_std_dtor(&intern->std TSRMLS_CC);
                    664: 
                    665:        if (intern->ptdoc) {
                    666:                intern->ptdoc->ref_count--;
                    667: 
                    668:                if (intern->ptdoc->ref_count <= 0) {
                    669:                        tidyBufFree(intern->ptdoc->errbuf);
                    670:                        efree(intern->ptdoc->errbuf);
                    671:                        tidyRelease(intern->ptdoc->doc);
                    672:                        efree(intern->ptdoc);
                    673:                }
                    674:        }
                    675: 
                    676:        efree(object);
                    677: }
                    678: 
                    679: static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *handlers,
                    680:                                                        zend_object_value *retval, tidy_obj_type objtype TSRMLS_DC)
                    681: {
                    682:        PHPTidyObj *intern;
                    683:        zval *tmp;
                    684: 
                    685:        intern = emalloc(sizeof(PHPTidyObj));
                    686:        memset(intern, 0, sizeof(PHPTidyObj));
                    687:        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
                    688:        
                    689:        zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
                    690: 
                    691:        switch(objtype) {
                    692:                case is_node:
                    693:                        break;
                    694: 
                    695:                case is_doc:
                    696:                        tidySetMallocCall(php_tidy_malloc);
                    697:                        tidySetReallocCall(php_tidy_realloc);
                    698:                        tidySetFreeCall(php_tidy_free);
                    699:                        tidySetPanicCall(php_tidy_panic);
                    700: 
                    701:                        intern->ptdoc = emalloc(sizeof(PHPTidyDoc));
                    702:                        intern->ptdoc->doc = tidyCreate();
                    703:                        intern->ptdoc->ref_count = 1;
                    704:                        intern->ptdoc->errbuf = emalloc(sizeof(TidyBuffer));
                    705:                        tidyBufInit(intern->ptdoc->errbuf);
                    706: 
                    707:                        if (tidySetErrorBuffer(intern->ptdoc->doc, intern->ptdoc->errbuf) != 0) {
                    708:                                tidyBufFree(intern->ptdoc->errbuf);
                    709:                                efree(intern->ptdoc->errbuf);
                    710:                                tidyRelease(intern->ptdoc->doc);
                    711:                                efree(intern->ptdoc);
                    712:                                efree(intern);
                    713:                                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not set Tidy error buffer");
                    714:                        }
                    715: 
                    716:                        tidyOptSetBool(intern->ptdoc->doc, TidyForceOutput, yes);
                    717:                        tidyOptSetBool(intern->ptdoc->doc, TidyMark, no);
                    718: 
                    719:                        TIDY_SET_DEFAULT_CONFIG(intern->ptdoc->doc);
                    720: 
                    721:                        tidy_add_default_properties(intern, is_doc TSRMLS_CC);
                    722:                        break;
                    723: 
                    724:                default:
                    725:                        break;
                    726:        }
                    727: 
                    728:        retval->handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) tidy_object_free_storage, NULL TSRMLS_CC);
                    729:        retval->handlers = handlers;
                    730: }
                    731: 
                    732: static zend_object_value tidy_object_new_node(zend_class_entry *class_type TSRMLS_DC)
                    733: {
                    734:        zend_object_value retval;
                    735:        tidy_object_new(class_type, &tidy_object_handlers_node, &retval, is_node TSRMLS_CC);
                    736:        return retval;
                    737: }
                    738: 
                    739: static zend_object_value tidy_object_new_doc(zend_class_entry *class_type TSRMLS_DC)
                    740: {
                    741:        zend_object_value retval;
                    742:        tidy_object_new(class_type, &tidy_object_handlers_doc, &retval, is_doc TSRMLS_CC);
                    743:        return retval;
                    744: }
                    745: 
                    746: static zval * tidy_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC)
                    747: {
                    748:        if (!object) {
                    749:                ALLOC_ZVAL(object);
                    750:        }
                    751: 
                    752:        Z_TYPE_P(object) = IS_OBJECT;
                    753:        object_init_ex(object, pce);
                    754:        Z_SET_REFCOUNT_P(object, 1);
                    755:        Z_SET_ISREF_P(object);
                    756:        return object;
                    757: }
                    758: 
                    759: static int tidy_doc_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
                    760: {
                    761:        TidyBuffer output;
                    762:        PHPTidyObj *obj;
                    763: 
                    764:        switch(type) {
                    765:                case IS_LONG:
                    766:                        ZVAL_LONG(out, 0);
                    767:                        break;
                    768: 
                    769:                case IS_DOUBLE:
                    770:                        ZVAL_DOUBLE(out, 0);
                    771:                        break;
                    772: 
                    773:                case IS_BOOL:
                    774:                        ZVAL_BOOL(out, TRUE);
                    775:                        break;
                    776: 
                    777:                case IS_STRING:
                    778:                        obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC);
                    779:                        tidyBufInit(&output);
                    780:                        tidySaveBuffer (obj->ptdoc->doc, &output);
                    781:                        ZVAL_STRINGL(out, (char*)output.bp, output.size ? output.size-1 : 0, TRUE);
                    782:                        tidyBufFree(&output);
                    783:                        break;
                    784: 
                    785:                default:
                    786:                        return FAILURE;
                    787:        }
                    788: 
                    789:        return SUCCESS;
                    790: }
                    791: 
                    792: static int tidy_node_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
                    793: {
                    794:        TidyBuffer buf;
                    795:        PHPTidyObj *obj;
                    796: 
                    797:        switch(type) {
                    798:                case IS_LONG:
                    799:                        ZVAL_LONG(out, 0);
                    800:                        break;
                    801: 
                    802:                case IS_DOUBLE:
                    803:                        ZVAL_DOUBLE(out, 0);
                    804:                        break;
                    805: 
                    806:                case IS_BOOL:
                    807:                        ZVAL_BOOL(out, TRUE);
                    808:                        break;
                    809: 
                    810:                case IS_STRING:
                    811:                        obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC);
                    812:                        tidyBufInit(&buf);
                    813:                        if (obj->ptdoc) {
                    814:                                tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf);
                    815:                        }
                    816:                        ZVAL_STRINGL(out, (char*)buf.bp, buf.size ? buf.size-1 : 0, TRUE);
                    817:                        tidyBufFree(&buf);
                    818:                        break;
                    819: 
                    820:                default:
                    821:                        return FAILURE;
                    822:        }
                    823: 
                    824:        return SUCCESS;
                    825: }
                    826: 
                    827: static void tidy_doc_update_properties(PHPTidyObj *obj TSRMLS_DC)
                    828: {
                    829: 
                    830:        TidyBuffer output;
                    831:        zval *temp;
                    832: 
                    833:        tidyBufInit(&output);
                    834:        tidySaveBuffer (obj->ptdoc->doc, &output);
                    835:        
                    836:        if (output.size) {
                    837:                MAKE_STD_ZVAL(temp);
                    838:                ZVAL_STRINGL(temp, (char*)output.bp, output.size-1, TRUE);
                    839:                zend_hash_update(obj->std.properties, "value", sizeof("value"), (void *)&temp, sizeof(zval *), NULL);
                    840:        }
                    841:        
                    842:        tidyBufFree(&output);
                    843: 
                    844:        if (obj->ptdoc->errbuf->size) {
                    845:                MAKE_STD_ZVAL(temp);
                    846:                ZVAL_STRINGL(temp, (char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1, TRUE);
                    847:                zend_hash_update(obj->std.properties, "errorBuffer", sizeof("errorBuffer"), (void *)&temp, sizeof(zval *), NULL);
                    848:        }
                    849: }
                    850: 
                    851: static void tidy_add_default_properties(PHPTidyObj *obj, tidy_obj_type type TSRMLS_DC)
                    852: {
                    853: 
                    854:        TidyBuffer buf;
                    855:        TidyAttr        tempattr;
                    856:        TidyNode        tempnode;
                    857:        zval *attribute, *children, *temp;
                    858:        PHPTidyObj *newobj;
                    859: 
                    860:        switch(type) {
                    861: 
                    862:                case is_node:
                    863:                        tidyBufInit(&buf);
                    864:                        tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf);
                    865:                        ADD_PROPERTY_STRINGL(obj->std.properties, value, buf.bp, buf.size-1);
                    866:                        tidyBufFree(&buf);
                    867: 
                    868:                        ADD_PROPERTY_STRING(obj->std.properties, name, tidyNodeGetName(obj->node));
                    869:                        ADD_PROPERTY_LONG(obj->std.properties, type, tidyNodeGetType(obj->node));
                    870:                        ADD_PROPERTY_LONG(obj->std.properties, line, tidyNodeLine(obj->node));
                    871:                        ADD_PROPERTY_LONG(obj->std.properties, column, tidyNodeColumn(obj->node));
                    872:                        ADD_PROPERTY_BOOL(obj->std.properties, proprietary, tidyNodeIsProp(obj->ptdoc->doc, obj->node));
                    873: 
                    874:                        switch(tidyNodeGetType(obj->node)) {
                    875:                                case TidyNode_Root:
                    876:                                case TidyNode_DocType:
                    877:                                case TidyNode_Text:
                    878:                                case TidyNode_Comment:
                    879:                                        break;
                    880:        
                    881:                                default:
                    882:                                        ADD_PROPERTY_LONG(obj->std.properties, id, tidyNodeGetId(obj->node));
                    883:                        }
                    884: 
                    885:                        tempattr = tidyAttrFirst(obj->node);
                    886:                        MAKE_STD_ZVAL(attribute);
                    887: 
                    888:                        if (tempattr) {
                    889:                                char *name, *val;
                    890:                                array_init(attribute);
                    891: 
                    892:                                do {
                    893:                                        name = (char *)tidyAttrName(tempattr);
                    894:                                        val = (char *)tidyAttrValue(tempattr);
                    895:                                        if (name && val) {
                    896:                                                add_assoc_string(attribute, name, val, TRUE);
                    897:                                        }
                    898:                                } while((tempattr = tidyAttrNext(tempattr)));
                    899:                        } else {
                    900:                                ZVAL_NULL(attribute);
                    901:                        }
                    902:                        zend_hash_update(obj->std.properties, "attribute", sizeof("attribute"), (void *)&attribute, sizeof(zval *), NULL);
                    903: 
                    904:                        tempnode = tidyGetChild(obj->node);
                    905: 
                    906:                        MAKE_STD_ZVAL(children);
                    907:                        if (tempnode) {
                    908:                                array_init(children);
                    909:                                do {
                    910:                                        MAKE_STD_ZVAL(temp);
                    911:                                        tidy_instanciate(tidy_ce_node, temp TSRMLS_CC);
                    912:                                        newobj = (PHPTidyObj *) zend_object_store_get_object(temp TSRMLS_CC);
                    913:                                        newobj->node = tempnode;
                    914:                                        newobj->type = is_node;
                    915:                                        newobj->ptdoc = obj->ptdoc;
                    916:                                        newobj->ptdoc->ref_count++;
                    917: 
                    918:                                        tidy_add_default_properties(newobj, is_node TSRMLS_CC);
                    919:                                        add_next_index_zval(children, temp);
                    920: 
                    921:                                } while((tempnode = tidyGetNext(tempnode)));
                    922: 
                    923:                        } else {
                    924:                                ZVAL_NULL(children);
                    925:                        }
                    926: 
                    927:                        zend_hash_update(obj->std.properties, "child", sizeof("child"), (void *)&children, sizeof(zval *), NULL);
                    928: 
                    929:                        break;
                    930: 
                    931:                case is_doc:
                    932:                        ADD_PROPERTY_NULL(obj->std.properties, errorBuffer);
                    933:                        ADD_PROPERTY_NULL(obj->std.properties, value);
                    934:                        break;
                    935:        }
                    936: }
                    937: 
                    938: static void *php_tidy_get_opt_val(PHPTidyDoc *ptdoc, TidyOption opt, TidyOptionType *type TSRMLS_DC)
                    939: {
                    940:        *type = tidyOptGetType(opt);
                    941: 
                    942:        switch (*type) {
                    943:                case TidyString: {
                    944:                        char *val = (char *) tidyOptGetValue(ptdoc->doc, tidyOptGetId(opt));
                    945:                        if (val) {
                    946:                                return (void *) estrdup(val);
                    947:                        } else {
                    948:                                return (void *) estrdup("");
                    949:                        }
                    950:                }
                    951:                        break;
                    952: 
                    953:                case TidyInteger:
                    954:                        return (void *) tidyOptGetInt(ptdoc->doc, tidyOptGetId(opt));
                    955:                        break;
                    956: 
                    957:                case TidyBoolean:
                    958:                        return (void *) tidyOptGetBool(ptdoc->doc, tidyOptGetId(opt));
                    959:                        break;
                    960:        }
                    961: 
                    962:        /* should not happen */
                    963:        return NULL;
                    964: }
                    965: 
                    966: static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetypes node_type)
                    967: {
                    968:        PHPTidyObj *newobj;
                    969:        TidyNode node;
                    970:        TIDY_FETCH_OBJECT;
                    971: 
                    972:        switch (node_type) {
                    973:                case is_root_node:
                    974:                        node = tidyGetRoot(obj->ptdoc->doc);
                    975:                        break;
                    976: 
                    977:                case is_html_node:
                    978:                        node = tidyGetHtml(obj->ptdoc->doc);
                    979:                        break;
                    980: 
                    981:                case is_head_node:
                    982:                        node = tidyGetHead(obj->ptdoc->doc);
                    983:                        break;
                    984: 
                    985:                case is_body_node:
                    986:                        node = tidyGetBody(obj->ptdoc->doc);
                    987:                        break;
                    988: 
                    989:                default:
                    990:                        RETURN_NULL();
                    991:                        break;
                    992:        }
                    993: 
                    994:        if (!node) {
                    995:                RETURN_NULL();
                    996:        }
                    997: 
                    998:        tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC);
                    999:        newobj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
                   1000:        newobj->type  = is_node;
                   1001:        newobj->ptdoc = obj->ptdoc;
                   1002:        newobj->node  = node;
                   1003:        newobj->ptdoc->ref_count++;
                   1004: 
                   1005:        tidy_add_default_properties(newobj, is_node TSRMLS_CC);
                   1006: }
                   1007: 
                   1008: static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC)
                   1009: {
                   1010:        char *opt_name = NULL;
                   1011:        zval **opt_val;
                   1012:        ulong opt_indx;
                   1013:        
                   1014:        for (zend_hash_internal_pointer_reset(ht_options);
                   1015:                 zend_hash_get_current_data(ht_options, (void **)&opt_val) == SUCCESS;
                   1016:                 zend_hash_move_forward(ht_options)) {
                   1017:                
                   1018:                if(zend_hash_get_current_key(ht_options, &opt_name, &opt_indx, FALSE) == FAILURE) {
                   1019:                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not retrieve key from option array");
                   1020:                        return FAILURE;
                   1021:                }
                   1022: 
                   1023:                if(opt_name) {
                   1024:                        _php_tidy_set_tidy_opt(doc, opt_name, *opt_val TSRMLS_CC);
                   1025:                        opt_name = NULL;
                   1026:                }
                   1027:                                        
                   1028:        }
                   1029:        
                   1030:        return SUCCESS;
                   1031: }
                   1032: 
                   1033: static int php_tidy_parse_string(PHPTidyObj *obj, char *string, int len, char *enc TSRMLS_DC)
                   1034: {
                   1035:        TidyBuffer buf;
                   1036:        
                   1037:        if(enc) {
                   1038:                if (tidySetCharEncoding(obj->ptdoc->doc, enc) < 0) {
                   1039:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not set encoding '%s'", enc);
                   1040:                        return FAILURE;
                   1041:                }
                   1042:        }
                   1043:        
                   1044:        tidyBufInit(&buf);
                   1045:        tidyBufAppend(&buf, string, len);
                   1046:        if (tidyParseBuffer(obj->ptdoc->doc, &buf) < 0) {
                   1047:                tidyBufFree(&buf);
                   1048:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", obj->ptdoc->errbuf->bp);
                   1049:                return FAILURE;
                   1050:        
                   1051:        }
                   1052:        tidyBufFree(&buf);
                   1053:        tidy_doc_update_properties(obj TSRMLS_CC);
                   1054: 
                   1055:        return SUCCESS;
                   1056: }
                   1057: 
                   1058: static PHP_MINIT_FUNCTION(tidy)
                   1059: {
                   1060:        REGISTER_INI_ENTRIES();
                   1061:        REGISTER_TIDY_CLASS(tidy, doc,  NULL, 0);
                   1062:        REGISTER_TIDY_CLASS(tidyNode, node,     NULL, ZEND_ACC_FINAL_CLASS);
                   1063: 
                   1064:        tidy_object_handlers_doc.cast_object = tidy_doc_cast_handler;
                   1065:        tidy_object_handlers_node.cast_object = tidy_node_cast_handler;
                   1066: 
                   1067:        _php_tidy_register_tags(INIT_FUNC_ARGS_PASSTHRU);
                   1068:        _php_tidy_register_nodetypes(INIT_FUNC_ARGS_PASSTHRU);
                   1069: 
                   1070:        return SUCCESS;
                   1071: }
                   1072: 
                   1073: static PHP_RINIT_FUNCTION(tidy)
                   1074: {
                   1075:        if (INI_BOOL("tidy.clean_output") == TRUE) {
                   1076:                if (php_start_ob_buffer_named("ob_tidyhandler", 0, 1 TSRMLS_CC) == FAILURE) {
                   1077:                        zend_error(E_NOTICE, "Failure installing Tidy output buffering.");
                   1078:                }
                   1079:        }
                   1080: 
                   1081:        return SUCCESS;
                   1082: }
                   1083: 
                   1084: static PHP_MSHUTDOWN_FUNCTION(tidy)
                   1085: {
                   1086:        UNREGISTER_INI_ENTRIES();
                   1087:        return SUCCESS;
                   1088: }
                   1089: 
                   1090: static PHP_MINFO_FUNCTION(tidy)
                   1091: {
                   1092:        php_info_print_table_start();
                   1093:        php_info_print_table_header(2, "Tidy support", "enabled");
                   1094:        php_info_print_table_row(2, "libTidy Release", (char *)tidyReleaseDate());
                   1095:        php_info_print_table_row(2, "Extension Version", PHP_TIDY_MODULE_VERSION " ($Id: tidy.c 321634 2012-01-01 13:15:04Z felipe $)");
                   1096:        php_info_print_table_end();
                   1097: 
                   1098:        DISPLAY_INI_ENTRIES();
                   1099: }
                   1100: 
                   1101: static PHP_FUNCTION(ob_tidyhandler)
                   1102: {
                   1103:        char *input;
                   1104:        int input_len;
                   1105:        long mode;
                   1106:        TidyBuffer errbuf;
                   1107:        TidyDoc doc;
                   1108: 
                   1109:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &input, &input_len, &mode) == FAILURE) {
                   1110:                return;
                   1111:        }
                   1112: 
                   1113:        doc = tidyCreate();
                   1114:        tidyBufInit(&errbuf);
                   1115: 
                   1116:        tidyOptSetBool(doc, TidyForceOutput, yes);
                   1117:        tidyOptSetBool(doc, TidyMark, no);
                   1118: 
                   1119:        if (tidySetErrorBuffer(doc, &errbuf) != 0) {
                   1120:                tidyRelease(doc);
                   1121:                tidyBufFree(&errbuf);
                   1122: 
                   1123:                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not set Tidy error buffer");
                   1124:        }
                   1125: 
                   1126:        TIDY_SET_DEFAULT_CONFIG(doc);
                   1127: 
                   1128:        if (input_len > 1) {
                   1129:                TidyBuffer buf;
                   1130:                
                   1131:                tidyBufInit(&buf);
                   1132:                tidyBufAppend(&buf, input, input_len);
                   1133:                
                   1134:                if (tidyParseBuffer(doc, &buf) < 0 || tidyCleanAndRepair(doc) < 0) {
                   1135:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf.bp);
                   1136:                        RETVAL_NULL();
                   1137:                } else {
                   1138:                        TidyBuffer output;
                   1139:                        tidyBufInit(&output);
                   1140: 
                   1141:                        tidySaveBuffer(doc, &output);
                   1142:                        RETVAL_STRINGL((char*)output.bp, output.size ? output.size-1 : 0, 1);
                   1143: 
                   1144:                        tidyBufFree(&output);
                   1145:                }
                   1146:                
                   1147:                tidyBufFree(&buf);
                   1148:        } else {
                   1149:                RETVAL_NULL();
                   1150:        }
                   1151: 
                   1152:        tidyRelease(doc);
                   1153:        tidyBufFree(&errbuf);
                   1154: }
                   1155: 
                   1156: /* {{{ proto bool tidy_parse_string(string input [, mixed config_options [, string encoding]])
                   1157:    Parse a document stored in a string */
                   1158: static PHP_FUNCTION(tidy_parse_string)
                   1159: {
                   1160:        char *input, *enc = NULL;
                   1161:        int input_len, enc_len = 0;
                   1162:        zval **options = NULL;
                   1163:        
                   1164:        PHPTidyObj *obj;
                   1165: 
                   1166:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zs", &input, &input_len, &options, &enc, &enc_len) == FAILURE) {
                   1167:                RETURN_FALSE;
                   1168:        }
                   1169: 
                   1170:        tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC);
                   1171:        obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
                   1172:                
                   1173:        TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
                   1174:        
                   1175:        if(php_tidy_parse_string(obj, input, input_len, enc TSRMLS_CC) == FAILURE) {
                   1176:                zval_dtor(return_value);
                   1177:                INIT_ZVAL(*return_value);
                   1178:                RETURN_FALSE;
                   1179:        }
                   1180:        
                   1181: }
                   1182: /* }}} */
                   1183: 
                   1184: /* {{{ proto string tidy_get_error_buffer([boolean detailed])
                   1185:    Return warnings and errors which occured parsing the specified document*/
                   1186: static PHP_FUNCTION(tidy_get_error_buffer)
                   1187: {
                   1188:        TIDY_FETCH_OBJECT;
                   1189: 
                   1190:        if (obj->ptdoc->errbuf && obj->ptdoc->errbuf->bp) {
                   1191:                RETURN_STRINGL((char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1, 1);
                   1192:        } else {
                   1193:                RETURN_FALSE;
                   1194:        }
                   1195: }
                   1196: /* }}} */
                   1197: 
                   1198: /* {{{ proto string tidy_get_output()
                   1199:    Return a string representing the parsed tidy markup */
                   1200: static PHP_FUNCTION(tidy_get_output)
                   1201: {
                   1202:        TidyBuffer output;
                   1203:        TIDY_FETCH_OBJECT;
                   1204: 
                   1205:        tidyBufInit(&output);
                   1206:        tidySaveBuffer(obj->ptdoc->doc, &output);
                   1207: 
                   1208:        RETVAL_STRINGL((char*)output.bp, output.size ? output.size-1 : 0, 1);
                   1209: 
                   1210:        tidyBufFree(&output);
                   1211: }
                   1212: /* }}} */
                   1213: 
                   1214: /* {{{ proto boolean tidy_parse_file(string file [, mixed config_options [, string encoding [, bool use_include_path]]])
                   1215:    Parse markup in file or URI */
                   1216: static PHP_FUNCTION(tidy_parse_file)
                   1217: {
                   1218:        char *inputfile, *enc = NULL;
                   1219:        int input_len, contents_len, enc_len = 0;
                   1220:        zend_bool use_include_path = 0;
                   1221:        char *contents;
                   1222:        zval **options = NULL;
                   1223:        
                   1224:        PHPTidyObj *obj;
                   1225: 
                   1226:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zsb", &inputfile, &input_len,
                   1227:                                                          &options, &enc, &enc_len, &use_include_path) == FAILURE) {
                   1228:                RETURN_FALSE;
                   1229:        }
                   1230: 
                   1231:        if (strlen(inputfile) != input_len) {
                   1232:                RETURN_FALSE;
                   1233:        }
                   1234:        tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC);
                   1235:        obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
                   1236: 
                   1237:        if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
                   1238:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : "");
                   1239:                RETURN_FALSE;
                   1240:        }
                   1241: 
                   1242:        TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
                   1243: 
                   1244:        if(php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC) == FAILURE) {
                   1245:                zval_dtor(return_value);
                   1246:                INIT_ZVAL(*return_value);
                   1247:                RETVAL_FALSE;
                   1248:        }
                   1249: 
                   1250:        efree(contents);
                   1251: }
                   1252: /* }}} */
                   1253: 
                   1254: /* {{{ proto boolean tidy_clean_repair()
                   1255:    Execute configured cleanup and repair operations on parsed markup */
                   1256: static PHP_FUNCTION(tidy_clean_repair)
                   1257: {
                   1258:        TIDY_FETCH_OBJECT;
                   1259: 
                   1260:        if (tidyCleanAndRepair(obj->ptdoc->doc) >= 0) {
                   1261:                tidy_doc_update_properties(obj TSRMLS_CC);
                   1262:                RETURN_TRUE;
                   1263:        }
                   1264: 
                   1265:        RETURN_FALSE;
                   1266: }
                   1267: /* }}} */
                   1268: 
                   1269: /* {{{ proto boolean tidy_repair_string(string data [, mixed config_file [, string encoding]])
                   1270:    Repair a string using an optionally provided configuration file */
                   1271: static PHP_FUNCTION(tidy_repair_string)
                   1272: {
                   1273:        php_tidy_quick_repair(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE);
                   1274: }
                   1275: /* }}} */
                   1276: 
                   1277: /* {{{ proto boolean tidy_repair_file(string filename [, mixed config_file [, string encoding [, bool use_include_path]]])
                   1278:    Repair a file using an optionally provided configuration file */
                   1279: static PHP_FUNCTION(tidy_repair_file)
                   1280: {
                   1281:        php_tidy_quick_repair(INTERNAL_FUNCTION_PARAM_PASSTHRU, TRUE);
                   1282: }
                   1283: /* }}} */
                   1284: 
                   1285: /* {{{ proto boolean tidy_diagnose()
                   1286:    Run configured diagnostics on parsed and repaired markup. */
                   1287: static PHP_FUNCTION(tidy_diagnose)
                   1288: {
                   1289:        TIDY_FETCH_OBJECT;
                   1290: 
                   1291:        if (tidyStatus(obj->ptdoc->doc) != 0 && tidyRunDiagnostics(obj->ptdoc->doc) >= 0) {
                   1292:                tidy_doc_update_properties(obj TSRMLS_CC);
                   1293:                RETURN_TRUE;
                   1294:        }
                   1295: 
                   1296:        RETURN_FALSE;
                   1297: }
                   1298: /* }}} */
                   1299: 
                   1300: /* {{{ proto string tidy_get_release()
                   1301:    Get release date (version) for Tidy library */
                   1302: static PHP_FUNCTION(tidy_get_release)
                   1303: {
                   1304:        if (zend_parse_parameters_none() == FAILURE) {
                   1305:                return;
                   1306:        }
                   1307: 
                   1308:        RETURN_STRING((char *)tidyReleaseDate(), 1);
                   1309: }
                   1310: /* }}} */
                   1311: 
                   1312: 
                   1313: #if HAVE_TIDYOPTGETDOC
                   1314: /* {{{ proto string tidy_get_opt_doc(tidy resource, string optname)
                   1315:    Returns the documentation for the given option name */
                   1316: static PHP_FUNCTION(tidy_get_opt_doc)
                   1317: {
                   1318:        PHPTidyObj *obj;
                   1319:        char *optname, *optval;
                   1320:        int optname_len;
                   1321:        TidyOption opt;
                   1322: 
                   1323:        TIDY_SET_CONTEXT;
                   1324: 
                   1325:        if (object) {
                   1326:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &optname, &optname_len) == FAILURE) {
                   1327:                        RETURN_FALSE;
                   1328:                }
                   1329:        } else {
                   1330:                if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, NULL, "Os", &object, tidy_ce_doc, &optname, &optname_len) == FAILURE) {
                   1331:                        RETURN_FALSE;
                   1332:                }
                   1333:        }
                   1334: 
                   1335:        obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC);
                   1336: 
                   1337:        opt = tidyGetOptionByName(obj->ptdoc->doc, optname);
                   1338: 
                   1339:        if (!opt) {
                   1340:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown Tidy Configuration Option '%s'", optname);
                   1341:                RETURN_FALSE;
                   1342:        }
                   1343: 
                   1344:        if ( (optval = (char *) tidyOptGetDoc(obj->ptdoc->doc, opt)) ) {
                   1345:                RETURN_STRING(optval, 1);
                   1346:        }
                   1347: 
                   1348:        RETURN_FALSE;
                   1349: }
                   1350: /* }}} */
                   1351: #endif
                   1352: 
                   1353: 
                   1354: /* {{{ proto array tidy_get_config()
                   1355:    Get current Tidy configuarion */
                   1356: static PHP_FUNCTION(tidy_get_config)
                   1357: {
                   1358:        TidyIterator itOpt;
                   1359:        char *opt_name;
                   1360:        void *opt_value;
                   1361:        TidyOptionType optt;
                   1362: 
                   1363:        TIDY_FETCH_OBJECT;
                   1364: 
                   1365:        itOpt = tidyGetOptionList(obj->ptdoc->doc);
                   1366: 
                   1367:        array_init(return_value);
                   1368: 
                   1369:        while (itOpt) {
                   1370:                TidyOption opt = tidyGetNextOption(obj->ptdoc->doc, &itOpt);
                   1371: 
                   1372:                opt_name = (char *)tidyOptGetName(opt);
                   1373:                opt_value = php_tidy_get_opt_val(obj->ptdoc, opt, &optt TSRMLS_CC);
                   1374:                switch (optt) {
                   1375:                        case TidyString:
                   1376:                                add_assoc_string(return_value, opt_name, (char*)opt_value, 0);
                   1377:                                break;
                   1378: 
                   1379:                        case TidyInteger:
                   1380:                                add_assoc_long(return_value, opt_name, (long)opt_value);
                   1381:                                break;
                   1382: 
                   1383:                        case TidyBoolean:
                   1384:                                add_assoc_bool(return_value, opt_name, (long)opt_value);
                   1385:                                break;
                   1386:                }
                   1387:        }
                   1388: 
                   1389:        return;
                   1390: }
                   1391: /* }}} */
                   1392: 
                   1393: /* {{{ proto int tidy_get_status()
                   1394:    Get status of specfied document. */
                   1395: static PHP_FUNCTION(tidy_get_status)
                   1396: {
                   1397:        TIDY_FETCH_OBJECT;
                   1398: 
                   1399:        RETURN_LONG(tidyStatus(obj->ptdoc->doc));
                   1400: }
                   1401: /* }}} */
                   1402: 
                   1403: /* {{{ proto int tidy_get_html_ver()
                   1404:    Get the Detected HTML version for the specified document. */
                   1405: static PHP_FUNCTION(tidy_get_html_ver)
                   1406: {
                   1407:        TIDY_FETCH_OBJECT;
                   1408: 
                   1409:        RETURN_LONG(tidyDetectedHtmlVersion(obj->ptdoc->doc));
                   1410: }
                   1411: /* }}} */
                   1412: 
                   1413: /* {{{ proto boolean tidy_is_xhtml()
                   1414:    Indicates if the document is a XHTML document. */
                   1415: static PHP_FUNCTION(tidy_is_xhtml)
                   1416: {
                   1417:        TIDY_FETCH_OBJECT;
                   1418: 
                   1419:        RETURN_BOOL(tidyDetectedXhtml(obj->ptdoc->doc));
                   1420: }
                   1421: /* }}} */
                   1422: 
                   1423: /* {{{ proto boolean tidy_is_xml()
                   1424:    Indicates if the document is a generic (non HTML/XHTML) XML document. */
                   1425: static PHP_FUNCTION(tidy_is_xml)
                   1426: {
                   1427:        TIDY_FETCH_OBJECT;
                   1428: 
                   1429:        RETURN_BOOL(tidyDetectedGenericXml(obj->ptdoc->doc));
                   1430: }
                   1431: /* }}} */
                   1432: 
                   1433: /* {{{ proto int tidy_error_count()
                   1434:    Returns the Number of Tidy errors encountered for specified document. */
                   1435: static PHP_FUNCTION(tidy_error_count)
                   1436: {
                   1437:        TIDY_FETCH_OBJECT;
                   1438: 
                   1439:        RETURN_LONG(tidyErrorCount(obj->ptdoc->doc));
                   1440: }
                   1441: /* }}} */
                   1442: 
                   1443: /* {{{ proto int tidy_warning_count()
                   1444:    Returns the Number of Tidy warnings encountered for specified document. */
                   1445: static PHP_FUNCTION(tidy_warning_count)
                   1446: {
                   1447:        TIDY_FETCH_OBJECT;
                   1448: 
                   1449:        RETURN_LONG(tidyWarningCount(obj->ptdoc->doc));
                   1450: }
                   1451: /* }}} */
                   1452: 
                   1453: /* {{{ proto int tidy_access_count()
                   1454:    Returns the Number of Tidy accessibility warnings encountered for specified document. */
                   1455: static PHP_FUNCTION(tidy_access_count)
                   1456: {
                   1457:        TIDY_FETCH_OBJECT;
                   1458: 
                   1459:        RETURN_LONG(tidyAccessWarningCount(obj->ptdoc->doc));
                   1460: }
                   1461: /* }}} */
                   1462: 
                   1463: /* {{{ proto int tidy_config_count()
                   1464:    Returns the Number of Tidy configuration errors encountered for specified document. */
                   1465: static PHP_FUNCTION(tidy_config_count)
                   1466: {
                   1467:        TIDY_FETCH_OBJECT;
                   1468: 
                   1469:        RETURN_LONG(tidyConfigErrorCount(obj->ptdoc->doc));
                   1470: }
                   1471: /* }}} */
                   1472: 
                   1473: /* {{{ proto mixed tidy_getopt(string option)
                   1474:    Returns the value of the specified configuration option for the tidy document. */
                   1475: static PHP_FUNCTION(tidy_getopt)
                   1476: {  
                   1477:        PHPTidyObj *obj;
                   1478:        char *optname;
                   1479:        void *optval;
                   1480:        int optname_len;
                   1481:        TidyOption opt;
                   1482:        TidyOptionType optt;
                   1483:        
                   1484:        TIDY_SET_CONTEXT;
                   1485: 
                   1486:        if (object) {
                   1487:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &optname, &optname_len) == FAILURE) {
                   1488:                        RETURN_FALSE;
                   1489:                }
                   1490:        } else {
                   1491:                if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, NULL, "Os", &object, tidy_ce_doc, &optname, &optname_len) == FAILURE) {
                   1492:                        RETURN_FALSE;
                   1493:                }
                   1494:        }
                   1495: 
                   1496:        obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC);
                   1497: 
                   1498:        opt = tidyGetOptionByName(obj->ptdoc->doc, optname);
                   1499: 
                   1500:        if (!opt) {
                   1501:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown Tidy Configuration Option '%s'", optname);
                   1502:                RETURN_FALSE;
                   1503:        }
                   1504: 
                   1505:        optval = php_tidy_get_opt_val(obj->ptdoc, opt, &optt TSRMLS_CC);
                   1506:        switch (optt) {
                   1507:                case TidyString:
                   1508:                        RETURN_STRING((char *)optval, 0);
                   1509:                        break;
                   1510: 
                   1511:                case TidyInteger:
                   1512:                        RETURN_LONG((long)optval);
                   1513:                        break;
                   1514: 
                   1515:                case TidyBoolean:
                   1516:                        if (optval) {
                   1517:                                RETURN_TRUE;
                   1518:                        } else {
                   1519:                                RETURN_FALSE;
                   1520:                        }
                   1521:                        break;
                   1522: 
                   1523:                default:
                   1524:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to determine type of configuration option");
                   1525:                        break;
                   1526:        }
                   1527: 
                   1528:        RETURN_FALSE;
                   1529: }
                   1530: /* }}} */
                   1531: 
                   1532: static TIDY_DOC_METHOD(__construct)
                   1533: {
                   1534:        char *inputfile = NULL, *enc = NULL;
                   1535:        int input_len = 0, enc_len = 0, contents_len = 0;
                   1536:        zend_bool use_include_path = 0;
                   1537:        char *contents;
                   1538:        zval **options = NULL;
                   1539:        
                   1540:        PHPTidyObj *obj;
                   1541:        TIDY_SET_CONTEXT;       
                   1542:        
                   1543:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sZsb", &inputfile, &input_len,
                   1544:                                                          &options, &enc, &enc_len, &use_include_path) == FAILURE) {
                   1545:                RETURN_FALSE;
                   1546:        }
                   1547: 
                   1548:        obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC);
                   1549:        
                   1550:        if (inputfile) {
                   1551:                if (strlen(inputfile) != input_len) {
                   1552:                        RETURN_FALSE;
                   1553:                }
                   1554:                if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
                   1555:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : "");
                   1556:                        return;
                   1557:                }
                   1558: 
                   1559:                TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
                   1560: 
                   1561:                php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC);
                   1562: 
                   1563:                efree(contents);
                   1564:        }
                   1565: }
                   1566: 
                   1567: static TIDY_DOC_METHOD(parseFile)
                   1568: {
                   1569:        char *inputfile, *enc = NULL;
                   1570:        int input_len, enc_len = 0, contents_len = 0;
                   1571:        zend_bool use_include_path = 0;
                   1572:        char *contents;
                   1573:        zval **options = NULL;
                   1574:        PHPTidyObj *obj;
                   1575: 
                   1576:        TIDY_SET_CONTEXT;
                   1577: 
                   1578:        obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC);
                   1579: 
                   1580:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zsb", &inputfile, &input_len,
                   1581:                                                          &options, &enc, &enc_len, &use_include_path) == FAILURE) {
                   1582:                RETURN_FALSE;
                   1583:        }
                   1584: 
                   1585:        if (strlen(inputfile) != input_len) {
                   1586:                RETURN_FALSE;
                   1587:        }
                   1588:        if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
                   1589:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : "");
                   1590:                RETURN_FALSE;
                   1591:        }
                   1592: 
                   1593:        TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
                   1594: 
                   1595:        if(php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC) == FAILURE) {
                   1596:                RETVAL_FALSE;
                   1597:        } else {
                   1598:                RETVAL_TRUE;
                   1599:        }
                   1600: 
                   1601:        efree(contents);
                   1602: }
                   1603: 
                   1604: static TIDY_DOC_METHOD(parseString)
                   1605: {
                   1606:        char *input, *enc = NULL;
                   1607:        int input_len, enc_len = 0;
                   1608:        zval **options = NULL;
                   1609:        PHPTidyObj *obj;
                   1610: 
                   1611:        TIDY_SET_CONTEXT;
                   1612: 
                   1613:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zs", &input, &input_len, &options, &enc, &enc_len) == FAILURE) {
                   1614:                RETURN_FALSE;
                   1615:        }
                   1616: 
                   1617:        obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC);
                   1618: 
                   1619:        TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
                   1620: 
                   1621:        if(php_tidy_parse_string(obj, input, input_len, enc TSRMLS_CC) == SUCCESS) {
                   1622:                RETURN_TRUE;
                   1623:        }
                   1624:        
                   1625:        RETURN_FALSE;
                   1626: }
                   1627: 
                   1628: 
                   1629: /* {{{ proto TidyNode tidy_get_root()
                   1630:    Returns a TidyNode Object representing the root of the tidy parse tree */
                   1631: static PHP_FUNCTION(tidy_get_root)
                   1632: {
                   1633:        php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_root_node);
                   1634: }
                   1635: /* }}} */
                   1636: 
                   1637: /* {{{ proto TidyNode tidy_get_html()
                   1638:    Returns a TidyNode Object starting from the <HTML> tag of the tidy parse tree */
                   1639: static PHP_FUNCTION(tidy_get_html)
                   1640: {
                   1641:        php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_html_node);
                   1642: }
                   1643: /* }}} */
                   1644: 
                   1645: /* {{{ proto TidyNode tidy_get_head()
                   1646:    Returns a TidyNode Object starting from the <HEAD> tag of the tidy parse tree */
                   1647: static PHP_FUNCTION(tidy_get_head)
                   1648: {
                   1649:        php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_head_node);
                   1650: }
                   1651: /* }}} */
                   1652: 
                   1653: /* {{{ proto TidyNode tidy_get_body(resource tidy)
                   1654:    Returns a TidyNode Object starting from the <BODY> tag of the tidy parse tree */
                   1655: static PHP_FUNCTION(tidy_get_body)
                   1656: {
                   1657:        php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_body_node);
                   1658: }
                   1659: /* }}} */
                   1660: 
                   1661: /* {{{ proto boolean tidyNode::hasChildren()
                   1662:    Returns true if this node has children */
                   1663: static TIDY_NODE_METHOD(hasChildren)
                   1664: {
                   1665:        TIDY_FETCH_ONLY_OBJECT;
                   1666: 
                   1667:        if (tidyGetChild(obj->node)) {
                   1668:                RETURN_TRUE;
                   1669:        } else {
                   1670:                RETURN_FALSE;
                   1671:        }
                   1672: }
                   1673: /* }}} */
                   1674: 
                   1675: /* {{{ proto boolean tidyNode::hasSiblings()
                   1676:    Returns true if this node has siblings */
                   1677: static TIDY_NODE_METHOD(hasSiblings)
                   1678: {
                   1679:        TIDY_FETCH_ONLY_OBJECT;
                   1680: 
                   1681:        if (obj->node && tidyGetNext(obj->node)) {
                   1682:                RETURN_TRUE;
                   1683:        } else {
                   1684:                RETURN_FALSE;
                   1685:        }
                   1686: }
                   1687: /* }}} */
                   1688: 
                   1689: /* {{{ proto boolean tidyNode::isComment()
                   1690:    Returns true if this node represents a comment */
                   1691: static TIDY_NODE_METHOD(isComment)
                   1692: {
                   1693:        TIDY_FETCH_ONLY_OBJECT;
                   1694: 
                   1695:        if (tidyNodeGetType(obj->node) == TidyNode_Comment) {
                   1696:                RETURN_TRUE;
                   1697:        } else {
                   1698:                RETURN_FALSE;
                   1699:        }
                   1700: }
                   1701: /* }}} */
                   1702: 
                   1703: /* {{{ proto boolean tidyNode::isHtml()
                   1704:    Returns true if this node is part of a HTML document */
                   1705: static TIDY_NODE_METHOD(isHtml)
                   1706: {
                   1707:        TIDY_FETCH_ONLY_OBJECT;
                   1708: 
                   1709:        if (tidyNodeGetType(obj->node) & (TidyNode_Start | TidyNode_End | TidyNode_StartEnd)) {
                   1710:                RETURN_TRUE;
                   1711:        }
                   1712: 
                   1713:        RETURN_FALSE;
                   1714: }
                   1715: /* }}} */
                   1716: 
                   1717: /* {{{ proto boolean tidyNode::isText()
                   1718:    Returns true if this node represents text (no markup) */
                   1719: static TIDY_NODE_METHOD(isText)
                   1720: {
                   1721:        TIDY_FETCH_ONLY_OBJECT;
                   1722: 
                   1723:        if (tidyNodeGetType(obj->node) == TidyNode_Text) {
                   1724:                RETURN_TRUE;
                   1725:        } else {
                   1726:                RETURN_FALSE;
                   1727:        }
                   1728: }
                   1729: /* }}} */
                   1730: 
                   1731: /* {{{ proto boolean tidyNode::isJste()
                   1732:    Returns true if this node is JSTE */
                   1733: static TIDY_NODE_METHOD(isJste)
                   1734: {
                   1735:        TIDY_FETCH_ONLY_OBJECT;
                   1736: 
                   1737:        if (tidyNodeGetType(obj->node) == TidyNode_Jste) {
                   1738:                RETURN_TRUE;
                   1739:        } else {
                   1740:                RETURN_FALSE;
                   1741:        }
                   1742: }
                   1743: /* }}} */
                   1744: 
                   1745: /* {{{ proto boolean tidyNode::isAsp()
                   1746:    Returns true if this node is ASP */
                   1747: static TIDY_NODE_METHOD(isAsp)
                   1748: {
                   1749:        TIDY_FETCH_ONLY_OBJECT;
                   1750: 
                   1751:        if (tidyNodeGetType(obj->node) == TidyNode_Asp) {
                   1752:                RETURN_TRUE;
                   1753:        } else {
                   1754:                RETURN_FALSE;
                   1755:        }
                   1756: }
                   1757: /* }}} */
                   1758: 
                   1759: /* {{{ proto boolean tidyNode::isPhp()
                   1760:    Returns true if this node is PHP */
                   1761: static TIDY_NODE_METHOD(isPhp)
                   1762: {
                   1763:        TIDY_FETCH_ONLY_OBJECT;
                   1764: 
                   1765:        if (tidyNodeGetType(obj->node) == TidyNode_Php) {
                   1766:                RETURN_TRUE;
                   1767:        } else {
                   1768:                RETURN_FALSE;
                   1769:        }
                   1770: }
                   1771: /* }}} */
                   1772: 
                   1773: /* {{{ proto tidyNode tidyNode::getParent()
                   1774:    Returns the parent node if available or NULL */
                   1775: static TIDY_NODE_METHOD(getParent)
                   1776: {
                   1777:        TidyNode        parent_node;
                   1778:        PHPTidyObj *newobj;
                   1779:        TIDY_FETCH_ONLY_OBJECT;
                   1780: 
                   1781:        parent_node = tidyGetParent(obj->node);
                   1782:        if(parent_node) {
                   1783:                tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC);
                   1784:                newobj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
                   1785:                newobj->node = parent_node;
                   1786:                newobj->type = is_node;
                   1787:                newobj->ptdoc = obj->ptdoc;
                   1788:                newobj->ptdoc->ref_count++;
                   1789:                tidy_add_default_properties(newobj, is_node TSRMLS_CC);
                   1790:        } else {
                   1791:                ZVAL_NULL(return_value);
                   1792:        }
                   1793: }
                   1794: /* }}} */
                   1795: 
                   1796: /* {{{ proto void tidyNode::__construct()
                   1797:          __constructor for tidyNode. */
                   1798: static TIDY_NODE_METHOD(__construct)
                   1799: {
                   1800:        php_error_docref(NULL TSRMLS_CC, E_ERROR, "You should not create a tidyNode manually");
                   1801: }   
                   1802: /* }}} */
                   1803: 
                   1804: static void _php_tidy_register_nodetypes(INIT_FUNC_ARGS)
                   1805: {
                   1806:        TIDY_NODE_CONST(ROOT, Root);
                   1807:        TIDY_NODE_CONST(DOCTYPE, DocType);
                   1808:        TIDY_NODE_CONST(COMMENT, Comment);
                   1809:        TIDY_NODE_CONST(PROCINS, ProcIns);
                   1810:        TIDY_NODE_CONST(TEXT, Text);
                   1811:        TIDY_NODE_CONST(START, Start);
                   1812:        TIDY_NODE_CONST(END, End);
                   1813:        TIDY_NODE_CONST(STARTEND, StartEnd);
                   1814:        TIDY_NODE_CONST(CDATA, CDATA);
                   1815:        TIDY_NODE_CONST(SECTION, Section);
                   1816:        TIDY_NODE_CONST(ASP, Asp);
                   1817:        TIDY_NODE_CONST(JSTE, Jste);
                   1818:        TIDY_NODE_CONST(PHP, Php);
                   1819:        TIDY_NODE_CONST(XMLDECL, XmlDecl);
                   1820: }
                   1821: 
                   1822: static void _php_tidy_register_tags(INIT_FUNC_ARGS)
                   1823: {
                   1824:        TIDY_TAG_CONST(UNKNOWN);
                   1825:        TIDY_TAG_CONST(A);
                   1826:        TIDY_TAG_CONST(ABBR);
                   1827:        TIDY_TAG_CONST(ACRONYM);
                   1828:        TIDY_TAG_CONST(ADDRESS);
                   1829:        TIDY_TAG_CONST(ALIGN);
                   1830:        TIDY_TAG_CONST(APPLET);
                   1831:        TIDY_TAG_CONST(AREA);
                   1832:        TIDY_TAG_CONST(B);
                   1833:        TIDY_TAG_CONST(BASE);
                   1834:        TIDY_TAG_CONST(BASEFONT);
                   1835:        TIDY_TAG_CONST(BDO);
                   1836:        TIDY_TAG_CONST(BGSOUND);
                   1837:        TIDY_TAG_CONST(BIG);
                   1838:        TIDY_TAG_CONST(BLINK);
                   1839:        TIDY_TAG_CONST(BLOCKQUOTE);
                   1840:        TIDY_TAG_CONST(BODY);
                   1841:        TIDY_TAG_CONST(BR);
                   1842:        TIDY_TAG_CONST(BUTTON);
                   1843:        TIDY_TAG_CONST(CAPTION);
                   1844:        TIDY_TAG_CONST(CENTER);
                   1845:        TIDY_TAG_CONST(CITE);
                   1846:        TIDY_TAG_CONST(CODE);
                   1847:        TIDY_TAG_CONST(COL);
                   1848:        TIDY_TAG_CONST(COLGROUP);
                   1849:        TIDY_TAG_CONST(COMMENT);
                   1850:        TIDY_TAG_CONST(DD);
                   1851:        TIDY_TAG_CONST(DEL);
                   1852:        TIDY_TAG_CONST(DFN);
                   1853:        TIDY_TAG_CONST(DIR);
                   1854:        TIDY_TAG_CONST(DIV);
                   1855:        TIDY_TAG_CONST(DL);
                   1856:        TIDY_TAG_CONST(DT);
                   1857:        TIDY_TAG_CONST(EM);
                   1858:        TIDY_TAG_CONST(EMBED);
                   1859:        TIDY_TAG_CONST(FIELDSET);
                   1860:        TIDY_TAG_CONST(FONT);
                   1861:        TIDY_TAG_CONST(FORM);
                   1862:        TIDY_TAG_CONST(FRAME);
                   1863:        TIDY_TAG_CONST(FRAMESET);
                   1864:        TIDY_TAG_CONST(H1);
                   1865:        TIDY_TAG_CONST(H2);
                   1866:        TIDY_TAG_CONST(H3);
                   1867:        TIDY_TAG_CONST(H4);
                   1868:        TIDY_TAG_CONST(H5);
                   1869:        TIDY_TAG_CONST(H6);
                   1870:        TIDY_TAG_CONST(HEAD);
                   1871:        TIDY_TAG_CONST(HR);
                   1872:        TIDY_TAG_CONST(HTML);
                   1873:        TIDY_TAG_CONST(I);
                   1874:        TIDY_TAG_CONST(IFRAME);
                   1875:        TIDY_TAG_CONST(ILAYER);
                   1876:        TIDY_TAG_CONST(IMG);
                   1877:        TIDY_TAG_CONST(INPUT);
                   1878:        TIDY_TAG_CONST(INS);
                   1879:        TIDY_TAG_CONST(ISINDEX);
                   1880:        TIDY_TAG_CONST(KBD);
                   1881:        TIDY_TAG_CONST(KEYGEN);
                   1882:        TIDY_TAG_CONST(LABEL);
                   1883:        TIDY_TAG_CONST(LAYER);
                   1884:        TIDY_TAG_CONST(LEGEND);
                   1885:        TIDY_TAG_CONST(LI);
                   1886:        TIDY_TAG_CONST(LINK);
                   1887:        TIDY_TAG_CONST(LISTING);
                   1888:        TIDY_TAG_CONST(MAP);
                   1889:        TIDY_TAG_CONST(MARQUEE);
                   1890:        TIDY_TAG_CONST(MENU);
                   1891:        TIDY_TAG_CONST(META);
                   1892:        TIDY_TAG_CONST(MULTICOL);
                   1893:        TIDY_TAG_CONST(NOBR);
                   1894:        TIDY_TAG_CONST(NOEMBED);
                   1895:        TIDY_TAG_CONST(NOFRAMES);
                   1896:        TIDY_TAG_CONST(NOLAYER);
                   1897:        TIDY_TAG_CONST(NOSAVE);
                   1898:        TIDY_TAG_CONST(NOSCRIPT);
                   1899:        TIDY_TAG_CONST(OBJECT);
                   1900:        TIDY_TAG_CONST(OL);
                   1901:        TIDY_TAG_CONST(OPTGROUP);
                   1902:        TIDY_TAG_CONST(OPTION);
                   1903:        TIDY_TAG_CONST(P);
                   1904:        TIDY_TAG_CONST(PARAM);
                   1905:        TIDY_TAG_CONST(PLAINTEXT);
                   1906:        TIDY_TAG_CONST(PRE);
                   1907:        TIDY_TAG_CONST(Q);
                   1908:        TIDY_TAG_CONST(RB);
                   1909:        TIDY_TAG_CONST(RBC);
                   1910:        TIDY_TAG_CONST(RP);
                   1911:        TIDY_TAG_CONST(RT);
                   1912:        TIDY_TAG_CONST(RTC);
                   1913:        TIDY_TAG_CONST(RUBY);
                   1914:        TIDY_TAG_CONST(S);
                   1915:        TIDY_TAG_CONST(SAMP);
                   1916:        TIDY_TAG_CONST(SCRIPT);
                   1917:        TIDY_TAG_CONST(SELECT);
                   1918:        TIDY_TAG_CONST(SERVER);
                   1919:        TIDY_TAG_CONST(SERVLET);
                   1920:        TIDY_TAG_CONST(SMALL);
                   1921:        TIDY_TAG_CONST(SPACER);
                   1922:        TIDY_TAG_CONST(SPAN);
                   1923:        TIDY_TAG_CONST(STRIKE);
                   1924:        TIDY_TAG_CONST(STRONG);
                   1925:        TIDY_TAG_CONST(STYLE);
                   1926:        TIDY_TAG_CONST(SUB);
                   1927:        TIDY_TAG_CONST(SUP);
                   1928:        TIDY_TAG_CONST(TABLE);
                   1929:        TIDY_TAG_CONST(TBODY);
                   1930:        TIDY_TAG_CONST(TD);
                   1931:        TIDY_TAG_CONST(TEXTAREA);
                   1932:        TIDY_TAG_CONST(TFOOT);
                   1933:        TIDY_TAG_CONST(TH);
                   1934:        TIDY_TAG_CONST(THEAD);
                   1935:        TIDY_TAG_CONST(TITLE);
                   1936:        TIDY_TAG_CONST(TR);
                   1937:        TIDY_TAG_CONST(TT);
                   1938:        TIDY_TAG_CONST(U);
                   1939:        TIDY_TAG_CONST(UL);
                   1940:        TIDY_TAG_CONST(VAR);
                   1941:        TIDY_TAG_CONST(WBR);
                   1942:        TIDY_TAG_CONST(XMP);
                   1943: }
                   1944: 
                   1945: #endif
                   1946: 
                   1947: /*
                   1948:  * Local variables:
                   1949:  * tab-width: 4
                   1950:  * c-basic-offset: 4
                   1951:  * End:
                   1952:  * vim600: noet sw=4 ts=4 fdm=marker
                   1953:  * vim<600: noet sw=4 ts=4
                   1954:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>