Refactored tidy (all tests passes)

This commit is contained in:
Xinchen Hui 2014-05-14 16:44:07 +08:00
parent c25f09e6ab
commit 0f6c93d620
3 changed files with 186 additions and 206 deletions

View file

@ -36,7 +36,7 @@ object(tidyNode)#2 (8) {
["child"]=> ["child"]=>
array(1) { array(1) {
[0]=> [0]=>
&object(tidyNode)#3 (9) { object(tidyNode)#3 (9) {
["value"]=> ["value"]=>
string(94) "<html> string(94) "<html>
<head> <head>
@ -62,7 +62,7 @@ object(tidyNode)#2 (8) {
["child"]=> ["child"]=>
array(2) { array(2) {
[0]=> [0]=>
&object(tidyNode)#4 (9) { object(tidyNode)#4 (9) {
["value"]=> ["value"]=>
string(31) "<head> string(31) "<head>
<title></title> <title></title>
@ -85,7 +85,7 @@ object(tidyNode)#2 (8) {
["child"]=> ["child"]=>
array(1) { array(1) {
[0]=> [0]=>
&object(tidyNode)#5 (9) { object(tidyNode)#5 (9) {
["value"]=> ["value"]=>
string(16) "<title></title> string(16) "<title></title>
" "
@ -109,7 +109,7 @@ object(tidyNode)#2 (8) {
} }
} }
[1]=> [1]=>
&object(tidyNode)#6 (9) { object(tidyNode)#6 (9) {
["value"]=> ["value"]=>
string(49) "<body bgcolor="#FFFFFF" alink="#000000"> string(49) "<body bgcolor="#FFFFFF" alink="#000000">
</body> </body>
@ -193,7 +193,7 @@ object(tidyNode)#2 (9) {
["child"]=> ["child"]=>
array(2) { array(2) {
[0]=> [0]=>
&object(tidyNode)#3 (9) { object(tidyNode)#3 (9) {
["value"]=> ["value"]=>
string(31) "<head> string(31) "<head>
<title></title> <title></title>
@ -216,7 +216,7 @@ object(tidyNode)#2 (9) {
["child"]=> ["child"]=>
array(1) { array(1) {
[0]=> [0]=>
&object(tidyNode)#6 (9) { object(tidyNode)#6 (9) {
["value"]=> ["value"]=>
string(16) "<title></title> string(16) "<title></title>
" "
@ -240,7 +240,7 @@ object(tidyNode)#2 (9) {
} }
} }
[1]=> [1]=>
&object(tidyNode)#4 (9) { object(tidyNode)#4 (9) {
["value"]=> ["value"]=>
string(49) "<body bgcolor="#FFFFFF" alink="#000000"> string(49) "<body bgcolor="#FFFFFF" alink="#000000">
</body> </body>
@ -292,7 +292,7 @@ object(tidyNode)#2 (9) {
["child"]=> ["child"]=>
array(1) { array(1) {
[0]=> [0]=>
&object(tidyNode)#4 (9) { object(tidyNode)#4 (9) {
["value"]=> ["value"]=>
string(16) "<title></title> string(16) "<title></title>
" "

View file

@ -55,7 +55,7 @@ object(tidyNode)#3 (9) {
["child"]=> ["child"]=>
array(1) { array(1) {
[0]=> [0]=>
&object(tidyNode)#4 (9) { object(tidyNode)#4 (9) {
["value"]=> ["value"]=>
string(16) "<title></title> string(16) "<title></title>
" "
@ -128,7 +128,7 @@ object(tidyNode)#5 (9) {
["child"]=> ["child"]=>
array(2) { array(2) {
[0]=> [0]=>
&object(tidyNode)#6 (9) { object(tidyNode)#6 (9) {
["value"]=> ["value"]=>
string(9) "<b>Hi</b>" string(9) "<b>Hi</b>"
["name"]=> ["name"]=>
@ -148,7 +148,7 @@ object(tidyNode)#5 (9) {
["child"]=> ["child"]=>
array(1) { array(1) {
[0]=> [0]=>
&object(tidyNode)#7 (8) { object(tidyNode)#7 (8) {
["value"]=> ["value"]=>
string(2) "Hi" string(2) "Hi"
["name"]=> ["name"]=>
@ -169,7 +169,7 @@ object(tidyNode)#5 (9) {
} }
} }
[1]=> [1]=>
&object(tidyNode)#8 (9) { object(tidyNode)#8 (9) {
["value"]=> ["value"]=>
string(21) "<i>Bye<u>Test</u></i>" string(21) "<i>Bye<u>Test</u></i>"
["name"]=> ["name"]=>
@ -189,7 +189,7 @@ object(tidyNode)#5 (9) {
["child"]=> ["child"]=>
array(2) { array(2) {
[0]=> [0]=>
&object(tidyNode)#9 (8) { object(tidyNode)#9 (8) {
["value"]=> ["value"]=>
string(3) "Bye" string(3) "Bye"
["name"]=> ["name"]=>
@ -208,7 +208,7 @@ object(tidyNode)#5 (9) {
NULL NULL
} }
[1]=> [1]=>
&object(tidyNode)#10 (9) { object(tidyNode)#10 (9) {
["value"]=> ["value"]=>
string(11) "<u>Test</u>" string(11) "<u>Test</u>"
["name"]=> ["name"]=>
@ -228,7 +228,7 @@ object(tidyNode)#5 (9) {
["child"]=> ["child"]=>
array(1) { array(1) {
[0]=> [0]=>
&object(tidyNode)#11 (8) { object(tidyNode)#11 (8) {
["value"]=> ["value"]=>
string(4) "Test" string(4) "Test"
["name"]=> ["name"]=>
@ -273,7 +273,7 @@ object(tidyNode)#6 (9) {
["child"]=> ["child"]=>
array(1) { array(1) {
[0]=> [0]=>
&object(tidyNode)#7 (8) { object(tidyNode)#7 (8) {
["value"]=> ["value"]=>
string(2) "Hi" string(2) "Hi"
["name"]=> ["name"]=>
@ -332,7 +332,7 @@ object(tidyNode)#8 (9) {
["child"]=> ["child"]=>
array(2) { array(2) {
[0]=> [0]=>
&object(tidyNode)#9 (8) { object(tidyNode)#9 (8) {
["value"]=> ["value"]=>
string(3) "Bye" string(3) "Bye"
["name"]=> ["name"]=>
@ -351,7 +351,7 @@ object(tidyNode)#8 (9) {
NULL NULL
} }
[1]=> [1]=>
&object(tidyNode)#10 (9) { object(tidyNode)#10 (9) {
["value"]=> ["value"]=>
string(11) "<u>Test</u>" string(11) "<u>Test</u>"
["name"]=> ["name"]=>
@ -371,7 +371,7 @@ object(tidyNode)#8 (9) {
["child"]=> ["child"]=>
array(1) { array(1) {
[0]=> [0]=>
&object(tidyNode)#11 (8) { object(tidyNode)#11 (8) {
["value"]=> ["value"]=>
string(4) "Test" string(4) "Test"
["name"]=> ["name"]=>
@ -432,7 +432,7 @@ object(tidyNode)#10 (9) {
["child"]=> ["child"]=>
array(1) { array(1) {
[0]=> [0]=>
&object(tidyNode)#11 (8) { object(tidyNode)#11 (8) {
["value"]=> ["value"]=>
string(4) "Test" string(4) "Test"
["name"]=> ["name"]=>

View file

@ -59,7 +59,7 @@
RETURN_FALSE; \ RETURN_FALSE; \
} \ } \
} \ } \
obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); \ obj = Z_TIDY_P(object); \
#define TIDY_FETCH_ONLY_OBJECT \ #define TIDY_FETCH_ONLY_OBJECT \
PHPTidyObj *obj; \ PHPTidyObj *obj; \
@ -67,21 +67,21 @@
if (zend_parse_parameters_none() == FAILURE) { \ if (zend_parse_parameters_none() == FAILURE) { \
return; \ return; \
} \ } \
obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); \ obj = Z_TIDY_P(object); \
#define TIDY_APPLY_CONFIG_ZVAL(_doc, _val) \ #define TIDY_APPLY_CONFIG_ZVAL(_doc, _val) \
if(_val) { \ if(_val) { \
if(Z_TYPE_PP(_val) == IS_ARRAY) { \ if(Z_TYPE_P(_val) == IS_ARRAY) { \
_php_tidy_apply_config_array(_doc, HASH_OF(*_val) TSRMLS_CC); \ _php_tidy_apply_config_array(_doc, HASH_OF(_val) TSRMLS_CC); \
} else { \ } else { \
convert_to_string_ex(_val); \ convert_to_string_ex(_val); \
TIDY_OPEN_BASE_DIR_CHECK(Z_STRVAL_PP(_val)); \ TIDY_OPEN_BASE_DIR_CHECK(Z_STRVAL_P(_val)); \
switch (tidyLoadConfig(_doc, Z_STRVAL_PP(_val))) { \ switch (tidyLoadConfig(_doc, Z_STRVAL_P(_val))) { \
case -1: \ case -1: \
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s'", Z_STRVAL_PP(_val)); \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s'", Z_STRVAL_P(_val)); \
break; \ break; \
case 1: \ case 1: \
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "There were errors while parsing the configuration file '%s'", Z_STRVAL_PP(_val)); \ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "There were errors while parsing the configuration file '%s'", Z_STRVAL_P(_val)); \
break; \ break; \
} \ } \
} \ } \
@ -111,51 +111,46 @@
#define ADD_PROPERTY_STRING(_table, _key, _string) \ #define ADD_PROPERTY_STRING(_table, _key, _string) \
{ \ { \
zval *tmp; \ zval tmp; \
MAKE_STD_ZVAL(tmp); \
if (_string) { \ if (_string) { \
ZVAL_STRING(tmp, (char *)_string, 1); \ ZVAL_STRING(&tmp, (char *)_string); \
} else { \ } else { \
ZVAL_EMPTY_STRING(tmp); \ ZVAL_EMPTY_STRING(&tmp); \
} \ } \
zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \ zend_hash_str_update(_table, #_key, sizeof(#_key) - 1, &tmp); \
} }
#define ADD_PROPERTY_STRINGL(_table, _key, _string, _len) \ #define ADD_PROPERTY_STRINGL(_table, _key, _string, _len) \
{ \ { \
zval *tmp; \ zval tmp; \
MAKE_STD_ZVAL(tmp); \
if (_string) { \ if (_string) { \
ZVAL_STRINGL(tmp, (char *)_string, _len, 1); \ ZVAL_STRINGL(&tmp, (char *)_string, _len); \
} else { \ } else { \
ZVAL_EMPTY_STRING(tmp); \ ZVAL_EMPTY_STRING(&tmp); \
} \ } \
zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \ zend_hash_str_update(_table, #_key, sizeof(#_key) - 1, &tmp); \
} }
#define ADD_PROPERTY_LONG(_table, _key, _long) \ #define ADD_PROPERTY_LONG(_table, _key, _long) \
{ \ { \
zval *tmp; \ zval tmp; \
MAKE_STD_ZVAL(tmp); \ ZVAL_LONG(&tmp, _long); \
ZVAL_LONG(tmp, _long); \ zend_hash_str_update(_table, #_key, sizeof(#_key) - 1, &tmp); \
zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
} }
#define ADD_PROPERTY_NULL(_table, _key) \ #define ADD_PROPERTY_NULL(_table, _key) \
{ \ { \
zval *tmp; \ zval tmp; \
MAKE_STD_ZVAL(tmp); \ ZVAL_NULL(&tmp); \
ZVAL_NULL(tmp); \ zend_hash_str_update(_table, #_key, sizeof(#_key) - 1, &tmp); \
zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \
} }
#define ADD_PROPERTY_BOOL(_table, _key, _bool) \ #define ADD_PROPERTY_BOOL(_table, _key, _bool) \
{ \ { \
zval *tmp; \ zval tmp; \
MAKE_STD_ZVAL(tmp); \ ZVAL_BOOL(&tmp, _bool); \
ZVAL_BOOL(tmp, _bool); \ zend_hash_str_update(_table, #_key, sizeof(#_key) - 1, &tmp); \
zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \ }
}
#define TIDY_OPEN_BASE_DIR_CHECK(filename) \ #define TIDY_OPEN_BASE_DIR_CHECK(filename) \
if (php_check_open_basedir(filename TSRMLS_CC)) { \ if (php_check_open_basedir(filename TSRMLS_CC)) { \
@ -195,19 +190,25 @@ struct _PHPTidyDoc {
}; };
struct _PHPTidyObj { struct _PHPTidyObj {
zend_object std;
TidyNode node; TidyNode node;
tidy_obj_type type; tidy_obj_type type;
PHPTidyDoc *ptdoc; PHPTidyDoc *ptdoc;
zend_object std;
}; };
static inline PHPTidyObj *php_tidy_fetch_object(zend_object *obj) {
return (PHPTidyObj *)((char*)(obj) - XtOffsetOf(PHPTidyObj, std));
}
#define Z_TIDY_P(zv) php_tidy_fetch_object(Z_OBJ_P((zv)))
/* }}} */ /* }}} */
/* {{{ ext/tidy prototypes /* {{{ ext/tidy prototypes
*/ */
static char *php_tidy_file_to_mem(char *, zend_bool, int * TSRMLS_DC); static zend_string *php_tidy_file_to_mem(char *, zend_bool TSRMLS_DC);
static void tidy_object_free_storage(void * TSRMLS_DC); static void tidy_object_free_storage(zend_object * TSRMLS_DC);
static zend_object_value tidy_object_new_node(zend_class_entry * TSRMLS_DC); static zend_object *tidy_object_new_node(zend_class_entry * TSRMLS_DC);
static zend_object_value tidy_object_new_doc(zend_class_entry * TSRMLS_DC); static zend_object *tidy_object_new_doc(zend_class_entry * TSRMLS_DC);
static zval * tidy_instanciate(zend_class_entry *, zval * TSRMLS_DC); static zval * tidy_instanciate(zend_class_entry *, zval * TSRMLS_DC);
static int tidy_doc_cast_handler(zval *, zval *, int TSRMLS_DC); static int tidy_doc_cast_handler(zval *, zval *, int TSRMLS_DC);
static int tidy_node_cast_handler(zval *, zval *, int TSRMLS_DC); static int tidy_node_cast_handler(zval *, zval *, int TSRMLS_DC);
@ -552,26 +553,26 @@ static int _php_tidy_set_tidy_opt(TidyDoc doc, char *optname, zval *value TSRMLS
static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_file) static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_file)
{ {
char *data=NULL, *arg1, *enc = NULL; char *enc = NULL;
int arg1_len, enc_len = 0, data_len = 0; int enc_len = 0;
zend_bool use_include_path = 0; zend_bool use_include_path = 0;
TidyDoc doc; TidyDoc doc;
TidyBuffer *errbuf; TidyBuffer *errbuf;
zval **config = NULL; zend_string *data, *arg1;
zval *config = NULL;
if (is_file) { if (is_file) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|Zsb", &arg1, &arg1_len, &config, &enc, &enc_len, &use_include_path) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "P|zsb", &arg1, &config, &enc, &enc_len, &use_include_path) == FAILURE) {
RETURN_FALSE; RETURN_FALSE;
} }
if (!(data = php_tidy_file_to_mem(arg1, use_include_path, &data_len TSRMLS_CC))) { if (!(data = php_tidy_file_to_mem(arg1->val, use_include_path TSRMLS_CC))) {
RETURN_FALSE; RETURN_FALSE;
} }
} else { } else {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zsb", &arg1, &arg1_len, &config, &enc, &enc_len, &use_include_path) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S|zsb", &arg1, &config, &enc, &enc_len, &use_include_path) == FAILURE) {
RETURN_FALSE; RETURN_FALSE;
} }
data = arg1; data = arg1;
data_len = arg1_len;
} }
doc = tidyCreate(); doc = tidyCreate();
@ -591,7 +592,20 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
TIDY_SET_DEFAULT_CONFIG(doc); TIDY_SET_DEFAULT_CONFIG(doc);
if (config) { if (config) {
TIDY_APPLY_CONFIG_ZVAL(doc, config); if(Z_TYPE_P(config) == IS_ARRAY) {
_php_tidy_apply_config_array(doc, HASH_OF(config) TSRMLS_CC);
} else {
convert_to_string_ex(config);
TIDY_OPEN_BASE_DIR_CHECK(Z_STRVAL_P(config));
switch (tidyLoadConfig(doc, Z_STRVAL_P(config))) {
case -1:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s'", Z_STRVAL_P(config));
break;
case 1:
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "There were errors while parsing the configuration file '%s'", Z_STRVAL_P(config));
break;
}
}
} }
if(enc_len) { if(enc_len) {
@ -605,7 +619,7 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
TidyBuffer buf; TidyBuffer buf;
tidyBufInit(&buf); tidyBufInit(&buf);
tidyBufAttach(&buf, (byte *) data, data_len); tidyBufAttach(&buf, (byte *) data->val, data->len);
if (tidyParseBuffer(doc, &buf) < 0) { if (tidyParseBuffer(doc, &buf) < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf->bp); php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf->bp);
@ -617,7 +631,7 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
tidySaveBuffer (doc, &output); tidySaveBuffer (doc, &output);
FIX_BUFFER(&output); FIX_BUFFER(&output);
RETVAL_STRINGL((char *) output.bp, output.size ? output.size-1 : 0, 1); RETVAL_STRINGL((char *) output.bp, output.size ? output.size-1 : 0);
tidyBufFree(&output); tidyBufFree(&output);
} else { } else {
RETVAL_FALSE; RETVAL_FALSE;
@ -626,7 +640,7 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
} }
if (is_file) { if (is_file) {
efree(data); STR_RELEASE(data);
} }
tidyBufFree(errbuf); tidyBufFree(errbuf);
@ -634,26 +648,25 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
tidyRelease(doc); tidyRelease(doc);
} }
static char *php_tidy_file_to_mem(char *filename, zend_bool use_include_path, int *len TSRMLS_DC) static zend_string *php_tidy_file_to_mem(char *filename, zend_bool use_include_path TSRMLS_DC)
{ {
php_stream *stream; php_stream *stream;
char *data = NULL; zend_string *data = NULL;
if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0), NULL))) { if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0), NULL))) {
return NULL; return NULL;
} }
if ((*len = (int) php_stream_copy_to_mem(stream, (void*) &data, PHP_STREAM_COPY_ALL, 0)) == 0) { if ((data = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) == NULL) {
data = estrdup(""); data = STR_EMPTY_ALLOC();
*len = 0;
} }
php_stream_close(stream); php_stream_close(stream);
return data; return data;
} }
static void tidy_object_free_storage(void *object TSRMLS_DC) static void tidy_object_free_storage(zend_object *object TSRMLS_DC)
{ {
PHPTidyObj *intern = (PHPTidyObj *)object; PHPTidyObj *intern = php_tidy_fetch_object(object);
zend_object_std_dtor(&intern->std TSRMLS_CC); zend_object_std_dtor(&intern->std TSRMLS_CC);
@ -667,17 +680,13 @@ static void tidy_object_free_storage(void *object TSRMLS_DC)
efree(intern->ptdoc); efree(intern->ptdoc);
} }
} }
efree(object);
} }
static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, static zend_object *tidy_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, tidy_obj_type objtype TSRMLS_DC)
zend_object_value *retval, tidy_obj_type objtype TSRMLS_DC)
{ {
PHPTidyObj *intern; PHPTidyObj *intern;
intern = emalloc(sizeof(PHPTidyObj)); intern = ecalloc(1, sizeof(PHPTidyObj) + sizeof(zval) * (class_type->default_properties_count - 1));
memset(intern, 0, sizeof(PHPTidyObj));
zend_object_std_init(&intern->std, class_type TSRMLS_CC); zend_object_std_init(&intern->std, class_type TSRMLS_CC);
object_properties_init(&intern->std, class_type); object_properties_init(&intern->std, class_type);
@ -711,34 +720,24 @@ static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *
break; break;
} }
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); intern->std.handlers = handlers;
retval->handlers = handlers;
return &intern->std;
} }
static zend_object_value tidy_object_new_node(zend_class_entry *class_type TSRMLS_DC) static zend_object *tidy_object_new_node(zend_class_entry *class_type TSRMLS_DC)
{ {
zend_object_value retval; return tidy_object_new(class_type, &tidy_object_handlers_node, is_node TSRMLS_CC);
tidy_object_new(class_type, &tidy_object_handlers_node, &retval, is_node TSRMLS_CC);
return retval;
} }
static zend_object_value tidy_object_new_doc(zend_class_entry *class_type TSRMLS_DC) static zend_object *tidy_object_new_doc(zend_class_entry *class_type TSRMLS_DC)
{ {
zend_object_value retval; return tidy_object_new(class_type, &tidy_object_handlers_doc, is_doc TSRMLS_CC);
tidy_object_new(class_type, &tidy_object_handlers_doc, &retval, is_doc TSRMLS_CC);
return retval;
} }
static zval * tidy_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC) static zval * tidy_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC)
{ {
if (!object) {
ALLOC_ZVAL(object);
}
Z_TYPE_P(object) = IS_OBJECT;
object_init_ex(object, pce); object_init_ex(object, pce);
Z_SET_REFCOUNT_P(object, 1);
Z_SET_ISREF_P(object);
return object; return object;
} }
@ -747,7 +746,7 @@ static int tidy_doc_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
TidyBuffer output; TidyBuffer output;
PHPTidyObj *obj; PHPTidyObj *obj;
switch(type) { switch (type) {
case IS_LONG: case IS_LONG:
ZVAL_LONG(out, 0); ZVAL_LONG(out, 0);
break; break;
@ -756,15 +755,15 @@ static int tidy_doc_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
ZVAL_DOUBLE(out, 0); ZVAL_DOUBLE(out, 0);
break; break;
case IS_BOOL: case _IS_BOOL:
ZVAL_BOOL(out, TRUE); ZVAL_BOOL(out, TRUE);
break; break;
case IS_STRING: case IS_STRING:
obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC); obj = Z_TIDY_P(in);
tidyBufInit(&output); tidyBufInit(&output);
tidySaveBuffer (obj->ptdoc->doc, &output); tidySaveBuffer (obj->ptdoc->doc, &output);
ZVAL_STRINGL(out, (char *) output.bp, output.size ? output.size-1 : 0, 1); ZVAL_STRINGL(out, (char *) output.bp, output.size ? output.size-1 : 0);
tidyBufFree(&output); tidyBufFree(&output);
break; break;
@ -789,16 +788,16 @@ static int tidy_node_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
ZVAL_DOUBLE(out, 0); ZVAL_DOUBLE(out, 0);
break; break;
case IS_BOOL: case _IS_BOOL:
ZVAL_BOOL(out, TRUE); ZVAL_BOOL(out, TRUE);
break; break;
case IS_STRING: case IS_STRING:
obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC); obj = Z_TIDY_P(in);
tidyBufInit(&buf); tidyBufInit(&buf);
if (obj->ptdoc) { if (obj->ptdoc) {
tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf); tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf);
ZVAL_STRINGL(out, (char *) buf.bp, buf.size-1, 1); ZVAL_STRINGL(out, (char *) buf.bp, buf.size-1);
} else { } else {
ZVAL_EMPTY_STRING(out); ZVAL_EMPTY_STRING(out);
} }
@ -816,7 +815,7 @@ static void tidy_doc_update_properties(PHPTidyObj *obj TSRMLS_DC)
{ {
TidyBuffer output; TidyBuffer output;
zval *temp; zval temp;
tidyBufInit(&output); tidyBufInit(&output);
tidySaveBuffer (obj->ptdoc->doc, &output); tidySaveBuffer (obj->ptdoc->doc, &output);
@ -825,9 +824,8 @@ static void tidy_doc_update_properties(PHPTidyObj *obj TSRMLS_DC)
if (!obj->std.properties) { if (!obj->std.properties) {
rebuild_object_properties(&obj->std); rebuild_object_properties(&obj->std);
} }
MAKE_STD_ZVAL(temp); ZVAL_STRINGL(&temp, (char*)output.bp, output.size-1);
ZVAL_STRINGL(temp, (char*)output.bp, output.size-1, TRUE); zend_hash_str_update(obj->std.properties, "value", sizeof("value") - 1, &temp);
zend_hash_update(obj->std.properties, "value", sizeof("value"), (void *)&temp, sizeof(zval *), NULL);
} }
tidyBufFree(&output); tidyBufFree(&output);
@ -836,9 +834,8 @@ static void tidy_doc_update_properties(PHPTidyObj *obj TSRMLS_DC)
if (!obj->std.properties) { if (!obj->std.properties) {
rebuild_object_properties(&obj->std); rebuild_object_properties(&obj->std);
} }
MAKE_STD_ZVAL(temp); ZVAL_STRINGL(&temp, (char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1);
ZVAL_STRINGL(temp, (char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1, TRUE); zend_hash_str_update(obj->std.properties, "errorBuffer", sizeof("errorBuffer") - 1, &temp);
zend_hash_update(obj->std.properties, "errorBuffer", sizeof("errorBuffer"), (void *)&temp, sizeof(zval *), NULL);
} }
} }
@ -848,7 +845,7 @@ static void tidy_add_default_properties(PHPTidyObj *obj, tidy_obj_type type TSRM
TidyBuffer buf; TidyBuffer buf;
TidyAttr tempattr; TidyAttr tempattr;
TidyNode tempnode; TidyNode tempnode;
zval *attribute, *children, *temp; zval attribute, children, temp;
PHPTidyObj *newobj; PHPTidyObj *newobj;
switch(type) { switch(type) {
@ -880,48 +877,45 @@ static void tidy_add_default_properties(PHPTidyObj *obj, tidy_obj_type type TSRM
} }
tempattr = tidyAttrFirst(obj->node); tempattr = tidyAttrFirst(obj->node);
MAKE_STD_ZVAL(attribute);
if (tempattr) { if (tempattr) {
char *name, *val; char *name, *val;
array_init(attribute); array_init(&attribute);
do { do {
name = (char *)tidyAttrName(tempattr); name = (char *)tidyAttrName(tempattr);
val = (char *)tidyAttrValue(tempattr); val = (char *)tidyAttrValue(tempattr);
if (name && val) { if (name && val) {
add_assoc_string(attribute, name, val); add_assoc_string(&attribute, name, val);
} }
} while((tempattr = tidyAttrNext(tempattr))); } while((tempattr = tidyAttrNext(tempattr)));
} else { } else {
ZVAL_NULL(attribute); ZVAL_NULL(&attribute);
} }
zend_hash_update(obj->std.properties, "attribute", sizeof("attribute"), (void *)&attribute, sizeof(zval *), NULL); zend_hash_str_update(obj->std.properties, "attribute", sizeof("attribute") - 1, &attribute);
tempnode = tidyGetChild(obj->node); tempnode = tidyGetChild(obj->node);
MAKE_STD_ZVAL(children);
if (tempnode) { if (tempnode) {
array_init(children); array_init(&children);
do { do {
MAKE_STD_ZVAL(temp); tidy_instanciate(tidy_ce_node, &temp TSRMLS_CC);
tidy_instanciate(tidy_ce_node, temp TSRMLS_CC); newobj = Z_TIDY_P(&temp);
newobj = (PHPTidyObj *) zend_object_store_get_object(temp TSRMLS_CC);
newobj->node = tempnode; newobj->node = tempnode;
newobj->type = is_node; newobj->type = is_node;
newobj->ptdoc = obj->ptdoc; newobj->ptdoc = obj->ptdoc;
newobj->ptdoc->ref_count++; newobj->ptdoc->ref_count++;
tidy_add_default_properties(newobj, is_node TSRMLS_CC); tidy_add_default_properties(newobj, is_node TSRMLS_CC);
add_next_index_zval(children, temp); add_next_index_zval(&children, &temp);
} while((tempnode = tidyGetNext(tempnode))); } while((tempnode = tidyGetNext(tempnode)));
} else { } else {
ZVAL_NULL(children); ZVAL_NULL(&children);
} }
zend_hash_update(obj->std.properties, "child", sizeof("child"), (void *)&children, sizeof(zval *), NULL); zend_hash_str_update(obj->std.properties, "child", sizeof("child") - 1, &children);
break; break;
@ -996,7 +990,7 @@ static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetyp
} }
tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC); tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC);
newobj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); newobj = Z_TIDY_P(return_value);
newobj->type = is_node; newobj->type = is_node;
newobj->ptdoc = obj->ptdoc; newobj->ptdoc = obj->ptdoc;
newobj->node = node; newobj->node = node;
@ -1007,34 +1001,16 @@ static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetyp
static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC) static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC)
{ {
char *opt_name; zval *opt_val;
zval **opt_val;
ulong opt_indx; ulong opt_indx;
uint opt_name_len; zend_string *opt_name;
zend_bool clear_str;
for (zend_hash_internal_pointer_reset(ht_options); ZEND_HASH_FOREACH_KEY_VAL(ht_options, opt_indx, opt_name, opt_val) {
zend_hash_get_current_data(ht_options, (void *) &opt_val) == SUCCESS; if (opt_name == NULL) {
zend_hash_move_forward(ht_options)) { continue;
switch (zend_hash_get_current_key_ex(ht_options, &opt_name, &opt_name_len, &opt_indx, FALSE, NULL)) {
case HASH_KEY_IS_STRING:
clear_str = 0;
break;
case HASH_KEY_IS_LONG:
continue; /* ignore numeric keys */
default:
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not retrieve key from option array");
return FAILURE;
} }
_php_tidy_set_tidy_opt(doc, opt_name->val, opt_val TSRMLS_CC);
_php_tidy_set_tidy_opt(doc, opt_name, *opt_val TSRMLS_CC); } ZEND_HASH_FOREACH_END();
if (clear_str) {
efree(opt_name);
}
}
return SUCCESS; return SUCCESS;
} }
@ -1077,6 +1053,9 @@ static PHP_MINIT_FUNCTION(tidy)
tidy_object_handlers_doc.cast_object = tidy_doc_cast_handler; tidy_object_handlers_doc.cast_object = tidy_doc_cast_handler;
tidy_object_handlers_node.cast_object = tidy_node_cast_handler; tidy_object_handlers_node.cast_object = tidy_node_cast_handler;
tidy_object_handlers_node.offset = tidy_object_handlers_doc.offset = XtOffsetOf(PHPTidyObj, std);
tidy_object_handlers_node.free_obj = tidy_object_handlers_doc.free_obj = tidy_object_free_storage;
_php_tidy_register_tags(INIT_FUNC_ARGS_PASSTHRU); _php_tidy_register_tags(INIT_FUNC_ARGS_PASSTHRU);
_php_tidy_register_nodetypes(INIT_FUNC_ARGS_PASSTHRU); _php_tidy_register_nodetypes(INIT_FUNC_ARGS_PASSTHRU);
@ -1215,23 +1194,23 @@ static int php_tidy_output_handler(void **nothing, php_output_context *output_co
Parse a document stored in a string */ Parse a document stored in a string */
static PHP_FUNCTION(tidy_parse_string) static PHP_FUNCTION(tidy_parse_string)
{ {
char *input, *enc = NULL; char *enc = NULL;
int input_len, enc_len = 0; int enc_len = 0;
zval **options = NULL; zend_string *input;
zval *options = NULL;
PHPTidyObj *obj; PHPTidyObj *obj;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zs", &input, &input_len, &options, &enc, &enc_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S|zs", &input, &options, &enc, &enc_len) == FAILURE) {
RETURN_FALSE; RETURN_FALSE;
} }
tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC); tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC);
obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); obj = Z_TIDY_P(return_value);
TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options); TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
if(php_tidy_parse_string(obj, input, input_len, enc TSRMLS_CC) == FAILURE) { if (php_tidy_parse_string(obj, input->val, input->len, enc TSRMLS_CC) == FAILURE) {
zval_dtor(return_value); zval_ptr_dtor(return_value);
INIT_ZVAL(*return_value);
RETURN_FALSE; RETURN_FALSE;
} }
} }
@ -1244,7 +1223,7 @@ static PHP_FUNCTION(tidy_get_error_buffer)
TIDY_FETCH_OBJECT; TIDY_FETCH_OBJECT;
if (obj->ptdoc->errbuf && obj->ptdoc->errbuf->bp) { if (obj->ptdoc->errbuf && obj->ptdoc->errbuf->bp) {
RETURN_STRINGL((char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1, 1); RETURN_STRINGL((char*)obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size-1);
} else { } else {
RETURN_FALSE; RETURN_FALSE;
} }
@ -1261,7 +1240,7 @@ static PHP_FUNCTION(tidy_get_output)
tidyBufInit(&output); tidyBufInit(&output);
tidySaveBuffer(obj->ptdoc->doc, &output); tidySaveBuffer(obj->ptdoc->doc, &output);
FIX_BUFFER(&output); FIX_BUFFER(&output);
RETVAL_STRINGL((char *) output.bp, output.size ? output.size-1 : 0, 1); RETVAL_STRINGL((char *) output.bp, output.size ? output.size-1 : 0);
tidyBufFree(&output); tidyBufFree(&output);
} }
/* }}} */ /* }}} */
@ -1270,36 +1249,35 @@ static PHP_FUNCTION(tidy_get_output)
Parse markup in file or URI */ Parse markup in file or URI */
static PHP_FUNCTION(tidy_parse_file) static PHP_FUNCTION(tidy_parse_file)
{ {
char *inputfile, *enc = NULL; char *enc = NULL;
int input_len, contents_len, enc_len = 0; int enc_len = 0;
zend_bool use_include_path = 0; zend_bool use_include_path = 0;
char *contents; zend_string *inputfile, *contents;
zval **options = NULL; zval *options = NULL;
PHPTidyObj *obj; PHPTidyObj *obj;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|Zsb", &inputfile, &input_len, if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "P|zsb", &inputfile,
&options, &enc, &enc_len, &use_include_path) == FAILURE) { &options, &enc, &enc_len, &use_include_path) == FAILURE) {
RETURN_FALSE; RETURN_FALSE;
} }
tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC); tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC);
obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); obj = Z_TIDY_P(return_value);
if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) { if (!(contents = php_tidy_file_to_mem(inputfile->val, use_include_path TSRMLS_CC))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile, (use_include_path) ? " (Using include path)" : ""); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile->val, (use_include_path) ? " (Using include path)" : "");
RETURN_FALSE; RETURN_FALSE;
} }
TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options); TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
if(php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC) == FAILURE) { if (php_tidy_parse_string(obj, contents->val, contents->len, enc TSRMLS_CC) == FAILURE) {
zval_dtor(return_value); zval_ptr_dtor(return_value);
INIT_ZVAL(*return_value);
RETVAL_FALSE; RETVAL_FALSE;
} }
efree(contents); STR_RELEASE(contents);
} }
/* }}} */ /* }}} */
@ -1357,7 +1335,7 @@ static PHP_FUNCTION(tidy_get_release)
return; return;
} }
RETURN_STRING((char *)tidyReleaseDate(), 1); RETURN_STRING((char *)tidyReleaseDate());
} }
/* }}} */ /* }}} */
@ -1384,7 +1362,7 @@ static PHP_FUNCTION(tidy_get_opt_doc)
} }
} }
obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); obj = Z_TIDY_P(object);
opt = tidyGetOptionByName(obj->ptdoc->doc, optname); opt = tidyGetOptionByName(obj->ptdoc->doc, optname);
@ -1394,7 +1372,7 @@ static PHP_FUNCTION(tidy_get_opt_doc)
} }
if ( (optval = (char *) tidyOptGetDoc(obj->ptdoc->doc, opt)) ) { if ( (optval = (char *) tidyOptGetDoc(obj->ptdoc->doc, opt)) ) {
RETURN_STRING(optval, 1); RETURN_STRING(optval);
} }
RETURN_FALSE; RETURN_FALSE;
@ -1547,7 +1525,7 @@ static PHP_FUNCTION(tidy_getopt)
} }
} }
obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); obj = Z_TIDY_P(object);
opt = tidyGetOptionByName(obj->ptdoc->doc, optname); opt = tidyGetOptionByName(obj->ptdoc->doc, optname);
@ -1559,8 +1537,9 @@ static PHP_FUNCTION(tidy_getopt)
optval = php_tidy_get_opt_val(obj->ptdoc, opt, &optt TSRMLS_CC); optval = php_tidy_get_opt_val(obj->ptdoc, opt, &optt TSRMLS_CC);
switch (optt) { switch (optt) {
case TidyString: case TidyString:
RETURN_STRING((char *)optval, 0); RETVAL_STRING((char *)optval);
break; efree(optval);
return;
case TidyInteger: case TidyInteger:
RETURN_LONG((long)optval); RETURN_LONG((long)optval);
@ -1585,88 +1564,89 @@ static PHP_FUNCTION(tidy_getopt)
static TIDY_DOC_METHOD(__construct) static TIDY_DOC_METHOD(__construct)
{ {
char *inputfile = NULL, *enc = NULL; char *enc = NULL;
int input_len = 0, enc_len = 0, contents_len = 0; int enc_len = 0;
zend_bool use_include_path = 0; zend_bool use_include_path = 0;
char *contents; zval *options = NULL;
zval **options = NULL; zend_string *contents, *inputfile = NULL;
PHPTidyObj *obj; PHPTidyObj *obj;
TIDY_SET_CONTEXT; TIDY_SET_CONTEXT;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|pZsb", &inputfile, &input_len, if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Pzsb", &inputfile,
&options, &enc, &enc_len, &use_include_path) == FAILURE) { &options, &enc, &enc_len, &use_include_path) == FAILURE) {
RETURN_FALSE; RETURN_FALSE;
} }
obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC); obj = Z_TIDY_P(object);
if (inputfile) { if (inputfile) {
if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) { if (!(contents = php_tidy_file_to_mem(inputfile->val, use_include_path TSRMLS_CC))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile, (use_include_path) ? " (Using include path)" : ""); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile->val, (use_include_path) ? " (Using include path)" : "");
return; return;
} }
TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options); TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC); php_tidy_parse_string(obj, contents->val, contents->len, enc TSRMLS_CC);
efree(contents); STR_RELEASE(contents);
} }
} }
static TIDY_DOC_METHOD(parseFile) static TIDY_DOC_METHOD(parseFile)
{ {
char *inputfile, *enc = NULL; char *enc = NULL;
int input_len, enc_len = 0, contents_len = 0; int enc_len = 0;
zend_bool use_include_path = 0; zend_bool use_include_path = 0;
char *contents; zval *options = NULL;
zval **options = NULL; zend_string *inputfile, *contents;
PHPTidyObj *obj; PHPTidyObj *obj;
TIDY_SET_CONTEXT; TIDY_SET_CONTEXT;
obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC); obj = Z_TIDY_P(object);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|Zsb", &inputfile, &input_len, if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "P|zsb", &inputfile,
&options, &enc, &enc_len, &use_include_path) == FAILURE) { &options, &enc, &enc_len, &use_include_path) == FAILURE) {
RETURN_FALSE; RETURN_FALSE;
} }
if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) { if (!(contents = php_tidy_file_to_mem(inputfile->val, use_include_path TSRMLS_CC))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile, (use_include_path) ? " (Using include path)" : ""); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile->val, (use_include_path) ? " (Using include path)" : "");
RETURN_FALSE; RETURN_FALSE;
} }
TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options); TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
if(php_tidy_parse_string(obj, contents, contents_len, enc TSRMLS_CC) == FAILURE) { if (php_tidy_parse_string(obj, contents->val, contents->len, enc TSRMLS_CC) == FAILURE) {
RETVAL_FALSE; RETVAL_FALSE;
} else { } else {
RETVAL_TRUE; RETVAL_TRUE;
} }
efree(contents); STR_RELEASE(contents);
} }
static TIDY_DOC_METHOD(parseString) static TIDY_DOC_METHOD(parseString)
{ {
char *input, *enc = NULL; char *enc = NULL;
int input_len, enc_len = 0; int enc_len = 0;
zval **options = NULL; zval *options = NULL;
PHPTidyObj *obj; PHPTidyObj *obj;
zend_string *input;
TIDY_SET_CONTEXT; TIDY_SET_CONTEXT;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zs", &input, &input_len, &options, &enc, &enc_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S|zs", &input, &options, &enc, &enc_len) == FAILURE) {
RETURN_FALSE; RETURN_FALSE;
} }
obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC); obj = Z_TIDY_P(object);
TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options); TIDY_APPLY_CONFIG_ZVAL(obj->ptdoc->doc, options);
if(php_tidy_parse_string(obj, input, input_len, enc TSRMLS_CC) == SUCCESS) { if(php_tidy_parse_string(obj, input->val, input->len, enc TSRMLS_CC) == SUCCESS) {
RETURN_TRUE; RETURN_TRUE;
} }
@ -1829,7 +1809,7 @@ static TIDY_NODE_METHOD(getParent)
parent_node = tidyGetParent(obj->node); parent_node = tidyGetParent(obj->node);
if(parent_node) { if(parent_node) {
tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC); tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC);
newobj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); newobj = Z_TIDY_P(return_value);
newobj->node = parent_node; newobj->node = parent_node;
newobj->type = is_node; newobj->type = is_node;
newobj->ptdoc = obj->ptdoc; newobj->ptdoc = obj->ptdoc;