libxml-ruby 0.5.1.0 → 0.5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. data/ext/xml/libxml.c +2 -1
  2. data/ext/xml/libxml.h +5 -3
  3. data/ext/xml/libxml.rb +1 -1
  4. data/ext/xml/ruby_xml_attr.c +13 -33
  5. data/ext/xml/ruby_xml_document.c +11 -22
  6. data/ext/xml/ruby_xml_document.h +2 -1
  7. data/ext/xml/ruby_xml_html_parser.c +3 -6
  8. data/ext/xml/ruby_xml_html_parser.h +1 -1
  9. data/ext/xml/ruby_xml_node.c +87 -70
  10. data/ext/xml/ruby_xml_node.h +2 -1
  11. data/ext/xml/ruby_xml_node_set.c +32 -111
  12. data/ext/xml/ruby_xml_node_set.h +5 -11
  13. data/ext/xml/ruby_xml_ns.c +1 -1
  14. data/ext/xml/ruby_xml_ns.h +1 -1
  15. data/ext/xml/ruby_xml_parser.c +11 -11
  16. data/ext/xml/ruby_xml_parser.h +1 -1
  17. data/ext/xml/ruby_xml_parser_context.c +11 -9
  18. data/ext/xml/ruby_xml_parser_context.h +1 -1
  19. data/ext/xml/ruby_xml_sax_parser.c +1 -1
  20. data/ext/xml/ruby_xml_sax_parser.h +1 -1
  21. data/ext/xml/ruby_xml_state.c +114 -0
  22. data/ext/xml/ruby_xml_state.h +11 -0
  23. data/ext/xml/ruby_xml_tree.c +1 -1
  24. data/ext/xml/ruby_xml_tree.h +1 -1
  25. data/ext/xml/ruby_xml_xinclude.c +1 -1
  26. data/ext/xml/ruby_xml_xinclude.h +1 -1
  27. data/ext/xml/ruby_xml_xpath.c +117 -231
  28. data/ext/xml/ruby_xml_xpath.h +4 -5
  29. data/ext/xml/ruby_xml_xpath_context.c +43 -50
  30. data/ext/xml/ruby_xml_xpath_context.h +3 -7
  31. data/ext/xml/ruby_xml_xpath_object.c +246 -0
  32. data/ext/xml/ruby_xml_xpath_object.h +29 -0
  33. data/ext/xml/ruby_xml_xpointer.c +8 -14
  34. data/ext/xml/ruby_xml_xpointer.h +1 -1
  35. data/ext/xml/ruby_xml_xpointer_context.c +1 -1
  36. data/ext/xml/ruby_xml_xpointer_context.h +1 -1
  37. data/ext/xml/sax_parser_callbacks.inc +1 -1
  38. data/tests/tc_xml_document.rb +5 -4
  39. data/tests/tc_xml_html_parser.rb +7 -4
  40. data/tests/tc_xml_node.rb +6 -5
  41. data/tests/tc_xml_node_set.rb +2 -2
  42. data/tests/tc_xml_node_set2.rb +3 -3
  43. data/tests/tc_xml_xpath.rb +3 -3
  44. data/tests/tc_xml_xpointer.rb +2 -2
  45. metadata +16 -10
data/ext/xml/libxml.c CHANGED
@@ -1,4 +1,4 @@
1
- /* $Id: libxml.c 138 2007-08-29 18:00:35Z danj $ */
1
+ /* $Id: libxml.c 189 2007-09-26 15:04:47Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -66,6 +66,7 @@ Init_libxml_so(void) {
66
66
 
67
67
  rb_define_const(mXML, "XML_NAMESPACE", rb_str_new2((const char*)XML_XML_NAMESPACE));
68
68
 
69
+ ruby_init_state();
69
70
  ruby_init_parser();
70
71
  ruby_init_xml_parser_context();
71
72
  ruby_init_xml_attr();
data/ext/xml/libxml.h CHANGED
@@ -6,11 +6,11 @@
6
6
  /* Don't nuke this block! It is used for automatically updating the
7
7
  * versions below. VERSION = string formatting, VERNUM = numbered
8
8
  * version for inline testing: increment both or none at all. */
9
- #define RUBY_LIBXML_VERSION "0.5.1.0"
10
- #define RUBY_LIBXML_VERNUM 510
9
+ #define RUBY_LIBXML_VERSION "0.5.2.0"
10
+ #define RUBY_LIBXML_VERNUM 520
11
11
  #define RUBY_LIBXML_VER_MAJ 0
12
12
  #define RUBY_LIBXML_VER_MIN 5
13
- #define RUBY_LIBXML_VER_MIC 1
13
+ #define RUBY_LIBXML_VER_MIC 2
14
14
  #define RUBY_LIBXML_VER_PATCH 0
15
15
 
16
16
  #include <ruby.h>
@@ -64,6 +64,7 @@ typedef struct rx_xpath_data {
64
64
  VALUE ctxt;
65
65
  } rx_xpath_data;
66
66
 
67
+ #include "ruby_xml_state.h"
67
68
  #include "ruby_xml_attr.h"
68
69
  #include "ruby_xml_document.h"
69
70
  #include "ruby_xml_node.h"
@@ -76,6 +77,7 @@ typedef struct rx_xpath_data {
76
77
  #include "ruby_xml_xinclude.h"
77
78
  #include "ruby_xml_xpath.h"
78
79
  #include "ruby_xml_xpath_context.h"
80
+ #include "ruby_xml_xpath_object.h"
79
81
  #include "ruby_xml_xpointer.h"
80
82
  #include "ruby_xml_xpointer_context.h"
81
83
  #include "ruby_xml_input_cbg.h"
data/ext/xml/libxml.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id: libxml.rb 120 2006-11-26 12:57:56Z roscopeco $
1
+ # $Id: libxml.rb 134 2007-08-29 17:30:19Z danj $
2
2
  # Please see the LICENSE file for copyright and distribution information
3
3
  require 'xml/libxml_so'
4
4
 
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_attr.c 138 2007-08-29 18:00:35Z danj $ */
1
+ /* $Id: ruby_xml_attr.c 189 2007-09-26 15:04:47Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -8,25 +8,28 @@
8
8
  VALUE cXMLAttr;
9
9
 
10
10
  void ruby_xml_attr_free(ruby_xml_attr_t *rx) {
11
- if (rx->attr == NULL ) return;
11
+ if (rx == NULL ) return;
12
12
 
13
- if (rx->attr->parent == NULL && rx->attr->doc == NULL ) {
13
+ if (rx->attr != NULL ) {
14
+ rx->attr->_private=NULL;
15
+ if (rx->attr->parent == NULL && rx->attr->doc == NULL ) {
14
16
  #ifdef NODE_DEBUG
15
- fprintf(stderr,"free rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)rxn->node,(long)rxn->node->_private);
17
+ fprintf(stderr,"free rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)rxn->node,(long)rxn->node->_private);
16
18
  #endif
17
- rx->attr->_private=NULL;
18
- xmlFreeProp(rx->attr);
19
+ xmlFreeProp(rx->attr);
20
+ }
21
+
22
+ rx->attr=NULL;
19
23
  }
20
24
 
21
- rx->attr=NULL;
22
- // fprintf(stderr,"%0x ",(long)rxn);
23
25
  free(rx);
24
26
  }
25
27
 
26
28
  void
27
29
  ruby_xml_attr_mark(ruby_xml_attr_t *rx) {
28
30
  xmlNodePtr node;
29
- if (rx->attr == NULL ) return;
31
+ if ( rx == NULL ) return;
32
+ if ( rx->attr == NULL ) return;
30
33
 
31
34
  if (rx->attr->_private == NULL ) {
32
35
  rb_warning("XmlAttr is not bound! (%s:%d)",
@@ -34,30 +37,7 @@ ruby_xml_attr_mark(ruby_xml_attr_t *rx) {
34
37
  return;
35
38
  }
36
39
 
37
- if (rx->attr->doc != NULL ) {
38
- if (rx->attr->doc->_private == NULL )
39
- rb_warning("XmlAttr Doc is not bound! (%s:%d)",
40
- __FILE__,__LINE__);
41
- else {
42
- rb_gc_mark((VALUE)rx->attr->doc->_private);
43
- #ifdef NODE_DEBUG
44
- fprintf(stderr,"mark rx=0x%x xn=0x%x o=0x%x\n",(long)rx,(long)rx->attr,(long)rx->attr->_private);
45
- #endif
46
- }
47
- } else if (rx->attr->parent != NULL ) {
48
- if (rx->attr->parent->_private == NULL )
49
- rb_warning("XmlAttr Parent is not bound! (%s:%d)",
50
- __FILE__,__LINE__);
51
- node=rx->attr->parent;
52
- while (node->parent != NULL )
53
- node=node->parent;
54
- if (node->_private != NULL) {
55
- rb_gc_mark((VALUE)node->_private);
56
- #ifdef NODE_DEBUG
57
- fprintf(stderr,"mark rx=0x%x xn=0x%x o=0x%x\n",(long)0,(long)node,(long)node->_private);
58
- #endif
59
- }
60
- }
40
+ ruby_xml_node_mark_common(rx->attr);
61
41
  }
62
42
 
63
43
  VALUE
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_document.c 140 2007-08-29 18:28:40Z danj $ */
1
+ /* $Id: ruby_xml_document.c 190 2007-09-28 17:13:52Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -393,19 +393,10 @@ ruby_xml_document_filename_get(VALUE self) {
393
393
  */
394
394
  VALUE
395
395
  ruby_xml_document_find(int argc, VALUE *argv, VALUE self) {
396
- int i, vargc;
397
- VALUE *vargv;
398
-
399
396
  if (argc > 2 || argc < 1)
400
397
  rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
401
398
 
402
- vargc = argc + 1;
403
- vargv = ALLOC_N(VALUE, vargc + 1);
404
- vargv[0] = ruby_xml_document_root_get(self);
405
- for (i = 0; i<argc; i++)
406
- vargv[i + 1] = argv[i];
407
-
408
- return(ruby_xml_xpath_find2(vargc, vargv));
399
+ return(ruby_xml_xpath_find2(self,argv[0],(argc==2)?argv[1]:Qnil));
409
400
  }
410
401
 
411
402
 
@@ -415,14 +406,12 @@ ruby_xml_document_free(ruby_xml_document_t *rxd) {
415
406
 
416
407
  if (rxd->doc == NULL) return;
417
408
  rxd->doc->_private=NULL;
409
+ #ifdef NODE_DEBUG
410
+ fprintf(stderr,"ruby_xml_document_free 0x%x/0x%x\n",rxd,rxd->doc);
411
+ #endif
418
412
  xmlFreeDoc(rxd->doc);
419
- ruby_xml_parser_count--;
420
413
  rxd->doc = NULL;
421
414
 
422
- // All this should be replaced by VALUE objects that GC can work
423
- if (ruby_xml_parser_count == 0)
424
- xmlCleanupParser();
425
-
426
415
  switch(rxd->data_type) {
427
416
  case RUBY_LIBXML_SRC_TYPE_NULL:
428
417
  break;
@@ -449,6 +438,7 @@ void
449
438
  ruby_xml_document_mark(ruby_xml_document_t *rxd) {
450
439
  // will mark parsers and source types
451
440
  // I do not thing doc->parent has anything useful in it.
441
+ ruby_xml_state_marker();
452
442
  }
453
443
 
454
444
  /*
@@ -523,12 +513,6 @@ ruby_xml_document_wrap(VALUE class, xmlDocPtr xnode) {
523
513
  if (xnode->_private != NULL)
524
514
  return (VALUE)xnode->_private;
525
515
 
526
- /*
527
- * XXX This is bad and needs to be replaced with
528
- * something that interacts with the GC. I did not do all this
529
- * to have reference counting still around. -danj
530
- */
531
- ruby_xml_parser_count++;
532
516
  obj=Data_Make_Struct(class,ruby_xml_document_t,
533
517
  ruby_xml_document_mark,
534
518
  ruby_xml_document_free,rx);
@@ -543,6 +527,11 @@ ruby_xml_document_wrap(VALUE class, xmlDocPtr xnode) {
543
527
  return obj;
544
528
  }
545
529
 
530
+ VALUE
531
+ ruby_xml_document_wrap2(xmlDocPtr xnode) {
532
+ return ruby_xml_document_wrap(cXMLDocument,xnode);
533
+ }
534
+
546
535
  VALUE
547
536
  ruby_xml_document_new_native(VALUE class, VALUE xmlver) {
548
537
  xmlDocPtr rx;
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_document.h 138 2007-08-29 18:00:35Z danj $ */
1
+ /* $Id: ruby_xml_document.h 188 2007-09-24 01:43:21Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -16,6 +16,7 @@ typedef struct rxp_document {
16
16
  VALUE ruby_xml_document_filename_get(VALUE self);
17
17
  VALUE ruby_xml_document_new_native(VALUE class, VALUE xmlver);
18
18
  VALUE ruby_xml_document_wrap(VALUE class, xmlDocPtr xnode);
19
+ VALUE ruby_xml_document_wrap2(xmlDocPtr xnode);
19
20
  void ruby_xml_document_free(ruby_xml_document_t *rxd);
20
21
  VALUE ruby_xml_document_root_get(VALUE self);
21
22
  void ruby_init_xml_document(void);
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_html_parser.c 138 2007-08-29 18:00:35Z danj $ */
1
+ /* $Id: ruby_xml_html_parser.c 189 2007-09-26 15:04:47Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -80,10 +80,6 @@ void
80
80
  ruby_xml_html_parser_free(ruby_xml_html_parser *rxp) {
81
81
  void *data;
82
82
 
83
- ruby_xml_parser_count--;
84
- if (ruby_xml_parser_count == 0)
85
- xmlCleanupParser();
86
-
87
83
  switch(rxp->data_type) {
88
84
  case RUBY_LIBXML_SRC_TYPE_NULL:
89
85
  break;
@@ -187,6 +183,8 @@ ruby_xml_html_parser_mark(ruby_xml_html_parser *rxp) {
187
183
  if (rxp == NULL) return;
188
184
  if (!NIL_P(rxp->ctxt)) rb_gc_mark(rxp->ctxt);
189
185
 
186
+ ruby_xml_state_marker();
187
+
190
188
  switch(rxp->data_type) {
191
189
  case RUBY_LIBXML_SRC_TYPE_NULL:
192
190
  break;
@@ -218,7 +216,6 @@ VALUE
218
216
  ruby_xml_html_parser_new(VALUE class) {
219
217
  ruby_xml_html_parser *rxp;
220
218
 
221
- ruby_xml_parser_count++;
222
219
  rxp = ALLOC(ruby_xml_html_parser);
223
220
  rxp->ctxt = Qnil;
224
221
  rxp->data_type = RUBY_LIBXML_SRC_TYPE_NULL;
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_html_parser.h 111 2006-11-20 01:39:14Z roscopeco $ */
1
+ /* $Id: ruby_xml_html_parser.h 134 2007-08-29 17:30:19Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_node.c 167 2007-09-05 12:47:54Z danj $ */
1
+ /* $Id: ruby_xml_node.c 192 2007-10-05 15:13:17Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -309,16 +309,12 @@ ruby_xml_node_child_q(VALUE self) {
309
309
  return(Qtrue);
310
310
  }
311
311
 
312
-
313
- // TODO Fixes below should be applied to sibling, prev, etc ?
314
312
  /*
315
- * call-seq:
316
- * node.child = node
317
- *
318
- * Set a child node for this node.
313
+ * underlying for child_set and child_add, difference being
314
+ * former raises on implicit copy, latter does not.
319
315
  */
320
316
  VALUE
321
- ruby_xml_node_child_set(VALUE self, VALUE rnode) {
317
+ ruby_xml_node_child_set_aux(VALUE self, VALUE rnode, int do_raise) {
322
318
  ruby_xml_node *cnode, *pnode;
323
319
  xmlNodePtr chld, ret;
324
320
  int copied=0;
@@ -334,7 +330,8 @@ ruby_xml_node_child_set(VALUE self, VALUE rnode) {
334
330
  if ( chld->parent != NULL || chld->doc != NULL ) {
335
331
  chld=xmlCopyNode(chld,1);
336
332
  copied=1;
337
- rb_warning("implicit copy of %s",chld->name);
333
+ if ( do_raise == 1 )
334
+ rb_raise(rb_eRuntimeError, "implicit copy not legal for child= or <<");
338
335
  }
339
336
 
340
337
  ret = xmlAddChild(pnode->node, chld);
@@ -348,6 +345,28 @@ ruby_xml_node_child_set(VALUE self, VALUE rnode) {
348
345
  return ruby_xml_node2_wrap(cXMLNode,chld);
349
346
  }
350
347
 
348
+ /*
349
+ * call-seq:
350
+ * node.child = node
351
+ *
352
+ * Set a child node for this node. Also called for <<
353
+ */
354
+ VALUE
355
+ ruby_xml_node_child_set(VALUE self, VALUE rnode) {
356
+ return ruby_xml_node_child_set_aux(self,rnode,1);
357
+ }
358
+
359
+ /*
360
+ * call-seq:
361
+ * node.child_add(node)
362
+ *
363
+ * Set a child node for this node.
364
+ */
365
+ VALUE
366
+ ruby_xml_node_child_add(VALUE self, VALUE rnode) {
367
+ return ruby_xml_node_child_set_aux(self,rnode,0);
368
+ }
369
+
351
370
  /*
352
371
  * call-seq:
353
372
  * node.doc => document
@@ -628,19 +647,10 @@ ruby_xml_node_eql_q(VALUE self, VALUE other) {
628
647
  */
629
648
  VALUE
630
649
  ruby_xml_node_find(int argc, VALUE *argv, VALUE self) {
631
- int i, vargc;
632
- VALUE *vargv;
633
-
634
650
  if (argc > 2 || argc < 1)
635
651
  rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
636
652
 
637
- vargc = argc + 1;
638
- vargv = ALLOC_N(VALUE, vargc + 1);
639
- vargv[0] = self;
640
- for (i = 0; i<argc; i++)
641
- vargv[i + 1] = argv[i];
642
-
643
- return(ruby_xml_xpath_find2(vargc, vargv));
653
+ return(ruby_xml_xpath_find2(self,argv[0],(argc==2)?argv[1]:Qnil));
644
654
  }
645
655
 
646
656
  /*
@@ -652,23 +662,7 @@ ruby_xml_node_find(int argc, VALUE *argv, VALUE self) {
652
662
  */
653
663
  VALUE
654
664
  ruby_xml_node_find_first(int argc, VALUE *argv, VALUE self) {
655
- VALUE ns = ruby_xml_node_find(argc, argv, self);
656
- ruby_xml_node_set *rxnset;
657
- VALUE nodeobj;
658
-
659
- Data_Get_Struct(ns, ruby_xml_node_set, rxnset);
660
- if (rxnset->node_set == NULL || rxnset->node_set->nodeNr < 1)
661
- return(Qnil);
662
-
663
- switch(rxnset->node_set->nodeTab[0]->type) {
664
- case XML_ATTRIBUTE_NODE:
665
- nodeobj = ruby_xml_attr_wrap(cXMLAttr, (xmlAttrPtr)rxnset->node_set->nodeTab[0]);
666
- break;
667
- default:
668
- nodeobj = ruby_xml_node2_wrap(cXMLNode, rxnset->node_set->nodeTab[0]);
669
- }
670
-
671
- return(nodeobj);
665
+ return ruby_xml_xpath_object_first(ruby_xml_node_find(argc, argv, self));
672
666
  }
673
667
 
674
668
 
@@ -1246,21 +1240,51 @@ ruby_xml_node_namespace_q(VALUE self) {
1246
1240
  void
1247
1241
  ruby_xml_node2_free(ruby_xml_node *rxn) {
1248
1242
 
1249
- if (rxn->node == NULL ) return;
1243
+ if (rxn == NULL ) return;
1244
+
1245
+ if (rxn->node != NULL ) {
1246
+ rxn->node->_private=NULL;
1250
1247
 
1251
- if (rxn->node->parent == NULL && rxn->node->doc == NULL ) {
1248
+ if ( rxn->node->doc==NULL && rxn->node->parent==NULL ) {
1252
1249
  #ifdef NODE_DEBUG
1253
- fprintf(stderr,"free rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)rxn->node,(long)rxn->node->_private);
1250
+ fprintf(stderr,"ruby_xml_node2_free free rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)rxn->node,(long)rxn->node->_private);
1254
1251
  #endif
1255
- rxn->node->_private=NULL;
1256
- xmlFreeNode(rxn->node);
1252
+ xmlFreeNode(rxn->node);
1253
+ }
1254
+
1255
+ rxn->node=NULL;
1257
1256
  }
1258
1257
 
1259
- rxn->node=NULL;
1260
- // fprintf(stderr,"%0x ",(long)rxn);
1261
1258
  free(rxn);
1262
1259
  }
1263
1260
 
1261
+ void
1262
+ ruby_xml_node_mark_common(xmlNodePtr node) {
1263
+ if (node->parent == NULL ) {
1264
+ #ifdef NODE_DEBUG
1265
+ fprintf(stderr,"mark no parent r=0x%x *n=0x%x\n",rxn,node);
1266
+ #endif
1267
+ } else if ( node->doc != NULL ) {
1268
+ if (node->doc->_private == NULL) {
1269
+ rb_bug("XmlNode Doc is not bound! (%s:%d)",
1270
+ __FILE__,__LINE__);
1271
+ }
1272
+ rb_gc_mark((VALUE)node->doc->_private);
1273
+ } else {
1274
+ while (node->parent != NULL )
1275
+ node=node->parent;
1276
+ if (node->_private == NULL )
1277
+ rb_warning("XmlNode Root Parent is not bound! (%s:%d)",
1278
+ __FILE__,__LINE__);
1279
+ else {
1280
+ #ifdef NODE_DEBUG
1281
+ fprintf(stderr,"mark rxn=0x%x xn=0x%x o=0x%x doc=0x%x\n",(long)rxn,(long)node,(long)node->_private,node->doc);
1282
+ #endif
1283
+ rb_gc_mark((VALUE)node->_private);
1284
+ }
1285
+ }
1286
+ }
1287
+
1264
1288
  void
1265
1289
  ruby_xml_node2_mark(ruby_xml_node *rxn) {
1266
1290
  xmlNodePtr node;
@@ -1272,30 +1296,7 @@ ruby_xml_node2_mark(ruby_xml_node *rxn) {
1272
1296
  return;
1273
1297
  }
1274
1298
 
1275
- if (rxn->node->doc != NULL ) {
1276
- if (rxn->node->doc->_private == NULL )
1277
- rb_warning("XmlNode Doc is not bound! (%s:%d)",
1278
- __FILE__,__LINE__);
1279
- else {
1280
- rb_gc_mark((VALUE)rxn->node->doc->_private);
1281
- #ifdef NODE_DEBUG
1282
- fprintf(stderr,"mark rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)rxn->node,(long)rxn->node->_private);
1283
- #endif
1284
- }
1285
- } else if (rxn->node->parent != NULL ) {
1286
- if (rxn->node->parent->_private == NULL )
1287
- rb_warning("XmlNode Parent is not bound! (%s:%d)",
1288
- __FILE__,__LINE__);
1289
- node=rxn->node;
1290
- while (node->parent != NULL )
1291
- node=node->parent;
1292
- if (node->_private != NULL) {
1293
- rb_gc_mark((VALUE)node->_private);
1294
- #ifdef NODE_DEBUG
1295
- fprintf(stderr,"mark rxn=0x%x xn=0x%x o=0x%x\n",(long)0,(long)node,(long)node->_private);
1296
- #endif
1297
- }
1298
- }
1299
+ ruby_xml_node_mark_common(rxn->node);
1299
1300
  }
1300
1301
 
1301
1302
  VALUE
@@ -1305,8 +1306,13 @@ ruby_xml_node2_wrap(VALUE class, xmlNodePtr xnode)
1305
1306
  ruby_xml_node *rxn;
1306
1307
 
1307
1308
  // This node is already wrapped
1308
- if (xnode->_private != NULL)
1309
+ if (xnode->_private != NULL) {
1310
+ #ifdef NODE_DEBUG
1311
+ Data_Get_Struct((VALUE)xnode->_private,ruby_xml_node,rxn);
1312
+ fprintf(stderr,"re-wrap rn=0x%x n*=0x%x\n",(long)rxn,(long)xnode);
1313
+ #endif
1309
1314
  return (VALUE)xnode->_private;
1315
+ }
1310
1316
 
1311
1317
  obj=Data_Make_Struct(class,ruby_xml_node,ruby_xml_node2_mark,
1312
1318
  ruby_xml_node2_free,rxn);
@@ -1314,7 +1320,8 @@ ruby_xml_node2_wrap(VALUE class, xmlNodePtr xnode)
1314
1320
  rxn->node=xnode;
1315
1321
  xnode->_private=(void*)obj;
1316
1322
  #ifdef NODE_DEBUG
1317
- fprintf(stderr,"wrap rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)xnode,(long)obj);
1323
+ fprintf(stderr,"wrap rn=0x%x n*=0x%x d*=0x%x\n",
1324
+ (long)rxn,(long)xnode,xnode->doc);
1318
1325
  #endif
1319
1326
  return obj;
1320
1327
  }
@@ -2209,6 +2216,15 @@ ruby_xml_node_registerNode(xmlNodePtr node)
2209
2216
  node->_private=NULL;
2210
2217
  }
2211
2218
 
2219
+ void
2220
+ ruby_xml_node_deregisterNode(xmlNodePtr node)
2221
+ {
2222
+ ruby_xml_node *rxn;
2223
+ if ( node->_private==NULL ) return;
2224
+ Data_Get_Struct(node->_private, ruby_xml_node, rxn);
2225
+ rxn->node=NULL;
2226
+ }
2227
+
2212
2228
  // Rdoc needs to know
2213
2229
  #ifdef RDOC_NEVER_DEFINED
2214
2230
  mXML = rb_define_module("XML");
@@ -2219,6 +2235,7 @@ ruby_init_xml_node(void) {
2219
2235
  VALUE singleton;
2220
2236
 
2221
2237
  xmlRegisterNodeDefault(ruby_xml_node_registerNode);
2238
+ xmlDeregisterNodeDefault(ruby_xml_node_deregisterNode);
2222
2239
 
2223
2240
  cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject);
2224
2241
  eXMLNodeSetNamespace = rb_define_class_under(cXMLNode, "SetNamespace", eXMLError);
@@ -2263,7 +2280,7 @@ ruby_init_xml_node(void) {
2263
2280
  rb_define_method(cXMLNode, "child", ruby_xml_node_child_get, 0);
2264
2281
  rb_define_method(cXMLNode, "child?", ruby_xml_node_child_q, 0);
2265
2282
  rb_define_method(cXMLNode, "child=", ruby_xml_node_child_set, 1);
2266
- rb_define_method(cXMLNode, "child_add", ruby_xml_node_child_set, 1);
2283
+ rb_define_method(cXMLNode, "child_add", ruby_xml_node_child_add, 1);
2267
2284
  rb_define_method(cXMLNode, "children", ruby_xml_node_child_get, 0);
2268
2285
  rb_define_method(cXMLNode, "children?", ruby_xml_node_child_q, 0);
2269
2286
  rb_define_method(cXMLNode, "content", ruby_xml_node_content_get, 0);