libxml-ruby 0.5.1.0 → 0.5.2.0

Sign up to get free protection for your applications and to get access to all the features.
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);