nokogiri 1.11.1 → 1.11.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE-DEPENDENCIES.md +12 -12
  3. data/LICENSE.md +1 -1
  4. data/README.md +20 -15
  5. data/ext/nokogiri/depend +34 -474
  6. data/ext/nokogiri/extconf.rb +253 -183
  7. data/ext/nokogiri/html_document.c +10 -15
  8. data/ext/nokogiri/html_element_description.c +84 -71
  9. data/ext/nokogiri/html_entity_lookup.c +21 -16
  10. data/ext/nokogiri/html_sax_parser_context.c +66 -65
  11. data/ext/nokogiri/html_sax_push_parser.c +29 -27
  12. data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
  13. data/ext/nokogiri/nokogiri.c +171 -63
  14. data/ext/nokogiri/nokogiri.h +158 -75
  15. data/ext/nokogiri/test_global_handlers.c +3 -4
  16. data/ext/nokogiri/xml_attr.c +15 -15
  17. data/ext/nokogiri/xml_attribute_decl.c +18 -18
  18. data/ext/nokogiri/xml_cdata.c +13 -18
  19. data/ext/nokogiri/xml_comment.c +19 -26
  20. data/ext/nokogiri/xml_document.c +221 -164
  21. data/ext/nokogiri/xml_document_fragment.c +13 -15
  22. data/ext/nokogiri/xml_dtd.c +54 -48
  23. data/ext/nokogiri/xml_element_content.c +30 -27
  24. data/ext/nokogiri/xml_element_decl.c +22 -22
  25. data/ext/nokogiri/xml_encoding_handler.c +17 -11
  26. data/ext/nokogiri/xml_entity_decl.c +32 -30
  27. data/ext/nokogiri/xml_entity_reference.c +16 -18
  28. data/ext/nokogiri/xml_namespace.c +56 -49
  29. data/ext/nokogiri/xml_node.c +338 -286
  30. data/ext/nokogiri/xml_node_set.c +168 -156
  31. data/ext/nokogiri/xml_processing_instruction.c +17 -19
  32. data/ext/nokogiri/xml_reader.c +191 -157
  33. data/ext/nokogiri/xml_relax_ng.c +29 -23
  34. data/ext/nokogiri/xml_sax_parser.c +117 -112
  35. data/ext/nokogiri/xml_sax_parser_context.c +100 -85
  36. data/ext/nokogiri/xml_sax_push_parser.c +34 -27
  37. data/ext/nokogiri/xml_schema.c +48 -42
  38. data/ext/nokogiri/xml_syntax_error.c +21 -23
  39. data/ext/nokogiri/xml_text.c +13 -17
  40. data/ext/nokogiri/xml_xpath_context.c +134 -127
  41. data/ext/nokogiri/xslt_stylesheet.c +157 -157
  42. data/lib/nokogiri.rb +1 -22
  43. data/lib/nokogiri/css/parser.rb +1 -1
  44. data/lib/nokogiri/extension.rb +26 -0
  45. data/lib/nokogiri/html/document_fragment.rb +15 -15
  46. data/lib/nokogiri/version/constant.rb +1 -1
  47. data/lib/nokogiri/version/info.rb +31 -8
  48. data/lib/nokogiri/xml/document.rb +31 -11
  49. data/lib/nokogiri/xml/node.rb +38 -42
  50. data/lib/nokogiri/xml/reader.rb +2 -9
  51. data/lib/nokogiri/xml/xpath.rb +1 -3
  52. data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -1
  53. data/patches/libxml2/0010-parser.c-shrink-the-input-buffer-when-appropriate.patch +70 -0
  54. metadata +8 -41
  55. data/ext/nokogiri/html_document.h +0 -10
  56. data/ext/nokogiri/html_element_description.h +0 -10
  57. data/ext/nokogiri/html_entity_lookup.h +0 -8
  58. data/ext/nokogiri/html_sax_parser_context.h +0 -11
  59. data/ext/nokogiri/html_sax_push_parser.h +0 -9
  60. data/ext/nokogiri/xml_attr.h +0 -9
  61. data/ext/nokogiri/xml_attribute_decl.h +0 -9
  62. data/ext/nokogiri/xml_cdata.h +0 -9
  63. data/ext/nokogiri/xml_comment.h +0 -9
  64. data/ext/nokogiri/xml_document.h +0 -23
  65. data/ext/nokogiri/xml_document_fragment.h +0 -10
  66. data/ext/nokogiri/xml_dtd.h +0 -10
  67. data/ext/nokogiri/xml_element_content.h +0 -10
  68. data/ext/nokogiri/xml_element_decl.h +0 -9
  69. data/ext/nokogiri/xml_encoding_handler.h +0 -8
  70. data/ext/nokogiri/xml_entity_decl.h +0 -10
  71. data/ext/nokogiri/xml_entity_reference.h +0 -9
  72. data/ext/nokogiri/xml_io.c +0 -63
  73. data/ext/nokogiri/xml_io.h +0 -11
  74. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
  75. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  76. data/ext/nokogiri/xml_namespace.h +0 -14
  77. data/ext/nokogiri/xml_node.h +0 -13
  78. data/ext/nokogiri/xml_node_set.h +0 -12
  79. data/ext/nokogiri/xml_processing_instruction.h +0 -9
  80. data/ext/nokogiri/xml_reader.h +0 -10
  81. data/ext/nokogiri/xml_relax_ng.h +0 -9
  82. data/ext/nokogiri/xml_sax_parser.h +0 -39
  83. data/ext/nokogiri/xml_sax_parser_context.h +0 -10
  84. data/ext/nokogiri/xml_sax_push_parser.h +0 -9
  85. data/ext/nokogiri/xml_schema.h +0 -9
  86. data/ext/nokogiri/xml_syntax_error.h +0 -25
  87. data/ext/nokogiri/xml_text.h +0 -9
  88. data/ext/nokogiri/xml_xpath_context.h +0 -10
  89. data/ext/nokogiri/xslt_stylesheet.h +0 -14
@@ -1,12 +1,11 @@
1
- #include <xml_node_set.h>
2
- #include <xml_namespace.h>
3
- #include <libxml/xpathInternals.h>
1
+ #include <nokogiri.h>
4
2
 
5
- static ID decorate ;
6
- static void xpath_node_set_del(xmlNodeSetPtr cur, xmlNodePtr val);
3
+ VALUE cNokogiriXmlNodeSet ;
7
4
 
5
+ static ID decorate ;
8
6
 
9
- static void Check_Node_Set_Node_Type(VALUE node)
7
+ static void
8
+ Check_Node_Set_Node_Type(VALUE node)
10
9
  {
11
10
  if (!(rb_obj_is_kind_of(node, cNokogiriXmlNode) ||
12
11
  rb_obj_is_kind_of(node, cNokogiriXmlNamespace))) {
@@ -15,34 +14,94 @@ static void Check_Node_Set_Node_Type(VALUE node)
15
14
  }
16
15
 
17
16
 
18
- static void deallocate(xmlNodeSetPtr node_set)
17
+ static
18
+ VALUE
19
+ ruby_object_get(xmlNodePtr c_node)
20
+ {
21
+ /* see xmlElementType in libxml2 tree.h */
22
+ switch (c_node->type) {
23
+ case XML_NAMESPACE_DECL:
24
+ /* _private is later in the namespace struct */
25
+ return (VALUE)(((xmlNsPtr)c_node)->_private);
26
+
27
+ case XML_DOCUMENT_NODE:
28
+ case XML_HTML_DOCUMENT_NODE:
29
+ /* in documents we use _private to store a tuple */
30
+ if (DOC_RUBY_OBJECT_TEST(((xmlDocPtr)c_node))) {
31
+ return DOC_RUBY_OBJECT((xmlDocPtr)c_node);
32
+ }
33
+ return (VALUE)NULL;
34
+
35
+ default:
36
+ return (VALUE)(c_node->_private);
37
+ }
38
+ }
39
+
40
+
41
+ static void
42
+ mark(xmlNodeSetPtr node_set)
43
+ {
44
+ VALUE rb_node;
45
+ int jnode;
46
+
47
+ for (jnode = 0; jnode < node_set->nodeNr; jnode++) {
48
+ rb_node = ruby_object_get(node_set->nodeTab[jnode]);
49
+ if (rb_node) {
50
+ rb_gc_mark(rb_node);
51
+ }
52
+ }
53
+ }
54
+
55
+ static void
56
+ xpath_node_set_del(xmlNodeSetPtr cur, xmlNodePtr val)
57
+ {
58
+ /*
59
+ * For reasons outlined in xml_namespace.c, here we reproduce xmlXPathNodeSetDel() except for the
60
+ * offending call to xmlXPathNodeSetFreeNs().
61
+ */
62
+ int i;
63
+
64
+ if (cur == NULL) { return; }
65
+ if (val == NULL) { return; }
66
+
67
+ /*
68
+ * find node in nodeTab
69
+ */
70
+ for (i = 0; i < cur->nodeNr; i++)
71
+ if (cur->nodeTab[i] == val) { break; }
72
+
73
+ if (i >= cur->nodeNr) { /* not found */
74
+ return;
75
+ }
76
+ cur->nodeNr--;
77
+ for (; i < cur->nodeNr; i++) {
78
+ cur->nodeTab[i] = cur->nodeTab[i + 1];
79
+ }
80
+ cur->nodeTab[cur->nodeNr] = NULL;
81
+ }
82
+
83
+
84
+ static void
85
+ deallocate(xmlNodeSetPtr node_set)
19
86
  {
20
87
  /*
21
- *
22
- * since xpath queries return copies of the xmlNs structs,
23
- * xmlXPathFreeNodeSet() frees those xmlNs structs that are in the
24
- * NodeSet.
25
- *
26
- * this is bad if someone is still trying to use the Namespace object wrapped
27
- * around the xmlNs, so we need to avoid that.
28
- *
29
- * here we reproduce xmlXPathFreeNodeSet() without the xmlNs logic.
30
- *
31
- * this doesn't cause a leak because Namespace objects that are in an XPath
32
- * query NodeSet are given their own lifecycle in
33
- * Nokogiri_wrap_xml_namespace().
88
+ * For reasons outlined in xml_namespace.c, here we reproduce xmlXPathFreeNodeSet() except for the
89
+ * offending call to xmlXPathNodeSetFreeNs().
34
90
  */
35
91
  NOKOGIRI_DEBUG_START(node_set) ;
36
- if (node_set->nodeTab != NULL)
92
+ if (node_set->nodeTab != NULL) {
37
93
  xmlFree(node_set->nodeTab);
94
+ }
38
95
 
39
96
  xmlFree(node_set);
40
97
  NOKOGIRI_DEBUG_END(node_set) ;
41
98
  }
42
99
 
43
- static VALUE allocate(VALUE klass)
100
+
101
+ static VALUE
102
+ allocate(VALUE klass)
44
103
  {
45
- return Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL), Qnil);
104
+ return noko_xml_node_set_wrap(xmlXPathNodeSetCreate(NULL), Qnil);
46
105
  }
47
106
 
48
107
 
@@ -53,7 +112,8 @@ static VALUE allocate(VALUE klass)
53
112
  * Duplicate this NodeSet. Note that the Nodes contained in the NodeSet are not
54
113
  * duplicated (similar to how Array and other Enumerable classes work).
55
114
  */
56
- static VALUE duplicate(VALUE self)
115
+ static VALUE
116
+ duplicate(VALUE self)
57
117
  {
58
118
  xmlNodeSetPtr node_set;
59
119
  xmlNodeSetPtr dupl;
@@ -62,7 +122,7 @@ static VALUE duplicate(VALUE self)
62
122
 
63
123
  dupl = xmlXPathNodeSetMerge(NULL, node_set);
64
124
 
65
- return Nokogiri_wrap_xml_node_set(dupl, rb_iv_get(self, "@document"));
125
+ return noko_xml_node_set_wrap(dupl, rb_iv_get(self, "@document"));
66
126
  }
67
127
 
68
128
  /*
@@ -71,7 +131,8 @@ static VALUE duplicate(VALUE self)
71
131
  *
72
132
  * Get the length of the node set
73
133
  */
74
- static VALUE length(VALUE self)
134
+ static VALUE
135
+ length(VALUE self)
75
136
  {
76
137
  xmlNodeSetPtr node_set;
77
138
 
@@ -86,7 +147,8 @@ static VALUE length(VALUE self)
86
147
  *
87
148
  * Append +node+ to the NodeSet.
88
149
  */
89
- static VALUE push(VALUE self, VALUE rb_node)
150
+ static VALUE
151
+ push(VALUE self, VALUE rb_node)
90
152
  {
91
153
  xmlNodeSetPtr node_set;
92
154
  xmlNodePtr node;
@@ -109,7 +171,7 @@ static VALUE push(VALUE self, VALUE rb_node)
109
171
  * if found, otherwise returns nil.
110
172
  */
111
173
  static VALUE
112
- delete(VALUE self, VALUE rb_node)
174
+ delete (VALUE self, VALUE rb_node)
113
175
  {
114
176
  xmlNodeSetPtr node_set;
115
177
  xmlNodePtr node;
@@ -133,19 +195,21 @@ delete(VALUE self, VALUE rb_node)
133
195
  *
134
196
  * Set Intersection — Returns a new NodeSet containing nodes common to the two NodeSets.
135
197
  */
136
- static VALUE intersection(VALUE self, VALUE rb_other)
198
+ static VALUE
199
+ intersection(VALUE self, VALUE rb_other)
137
200
  {
138
201
  xmlNodeSetPtr node_set, other ;
139
202
  xmlNodeSetPtr intersection;
140
203
 
141
- if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
204
+ if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) {
142
205
  rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
206
+ }
143
207
 
144
208
  Data_Get_Struct(self, xmlNodeSet, node_set);
145
209
  Data_Get_Struct(rb_other, xmlNodeSet, other);
146
210
 
147
211
  intersection = xmlXPathIntersection(node_set, other);
148
- return Nokogiri_wrap_xml_node_set(intersection, rb_iv_get(self, "@document"));
212
+ return noko_xml_node_set_wrap(intersection, rb_iv_get(self, "@document"));
149
213
  }
150
214
 
151
215
 
@@ -155,7 +219,8 @@ static VALUE intersection(VALUE self, VALUE rb_other)
155
219
  *
156
220
  * Returns true if any member of node set equals +node+.
157
221
  */
158
- static VALUE include_eh(VALUE self, VALUE rb_node)
222
+ static VALUE
223
+ include_eh(VALUE self, VALUE rb_node)
159
224
  {
160
225
  xmlNodeSetPtr node_set;
161
226
  xmlNodePtr node;
@@ -176,21 +241,23 @@ static VALUE include_eh(VALUE self, VALUE rb_node)
176
241
  * Returns a new set built by merging the set and the elements of the given
177
242
  * set.
178
243
  */
179
- static VALUE set_union(VALUE self, VALUE rb_other)
244
+ static VALUE
245
+ rb_xml_node_set_union(VALUE rb_node_set, VALUE rb_other)
180
246
  {
181
- xmlNodeSetPtr node_set, other;
182
- xmlNodeSetPtr new;
247
+ xmlNodeSetPtr c_node_set, c_other;
248
+ xmlNodeSetPtr c_new_node_set;
183
249
 
184
- if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
250
+ if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) {
185
251
  rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
252
+ }
186
253
 
187
- Data_Get_Struct(self, xmlNodeSet, node_set);
188
- Data_Get_Struct(rb_other, xmlNodeSet, other);
254
+ Data_Get_Struct(rb_node_set, xmlNodeSet, c_node_set);
255
+ Data_Get_Struct(rb_other, xmlNodeSet, c_other);
189
256
 
190
- new = xmlXPathNodeSetMerge(NULL, node_set);
191
- new = xmlXPathNodeSetMerge(new, other);
257
+ c_new_node_set = xmlXPathNodeSetMerge(NULL, c_node_set);
258
+ c_new_node_set = xmlXPathNodeSetMerge(c_new_node_set, c_other);
192
259
 
193
- return Nokogiri_wrap_xml_node_set(new, rb_iv_get(self, "@document"));
260
+ return noko_xml_node_set_wrap(c_new_node_set, rb_iv_get(rb_node_set, "@document"));
194
261
  }
195
262
 
196
263
  /*
@@ -200,14 +267,16 @@ static VALUE set_union(VALUE self, VALUE rb_other)
200
267
  * Difference - returns a new NodeSet that is a copy of this NodeSet, removing
201
268
  * each item that also appears in +node_set+
202
269
  */
203
- static VALUE minus(VALUE self, VALUE rb_other)
270
+ static VALUE
271
+ minus(VALUE self, VALUE rb_other)
204
272
  {
205
273
  xmlNodeSetPtr node_set, other;
206
274
  xmlNodeSetPtr new;
207
275
  int j ;
208
276
 
209
- if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
277
+ if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) {
210
278
  rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
279
+ }
211
280
 
212
281
  Data_Get_Struct(self, xmlNodeSet, node_set);
213
282
  Data_Get_Struct(rb_other, xmlNodeSet, other);
@@ -217,11 +286,12 @@ static VALUE minus(VALUE self, VALUE rb_other)
217
286
  xpath_node_set_del(new, other->nodeTab[j]);
218
287
  }
219
288
 
220
- return Nokogiri_wrap_xml_node_set(new, rb_iv_get(self, "@document"));
289
+ return noko_xml_node_set_wrap(new, rb_iv_get(self, "@document"));
221
290
  }
222
291
 
223
292
 
224
- static VALUE index_at(VALUE self, long offset)
293
+ static VALUE
294
+ index_at(VALUE self, long offset)
225
295
  {
226
296
  xmlNodeSetPtr node_set;
227
297
 
@@ -233,10 +303,11 @@ static VALUE index_at(VALUE self, long offset)
233
303
 
234
304
  if (offset < 0) { offset += node_set->nodeNr ; }
235
305
 
236
- return Nokogiri_wrap_xml_node_set_node(node_set->nodeTab[offset], self);
306
+ return noko_xml_node_wrap_node_set_result(node_set->nodeTab[offset], self);
237
307
  }
238
308
 
239
- static VALUE subseq(VALUE self, long beg, long len)
309
+ static VALUE
310
+ subseq(VALUE self, long beg, long len)
240
311
  {
241
312
  long j;
242
313
  xmlNodeSetPtr node_set;
@@ -244,18 +315,18 @@ static VALUE subseq(VALUE self, long beg, long len)
244
315
 
245
316
  Data_Get_Struct(self, xmlNodeSet, node_set);
246
317
 
247
- if (beg > node_set->nodeNr) return Qnil ;
248
- if (beg < 0 || len < 0) return Qnil ;
318
+ if (beg > node_set->nodeNr) { return Qnil ; }
319
+ if (beg < 0 || len < 0) { return Qnil ; }
249
320
 
250
321
  if ((beg + len) > node_set->nodeNr) {
251
322
  len = node_set->nodeNr - beg ;
252
323
  }
253
324
 
254
325
  new_set = xmlXPathNodeSetCreate(NULL);
255
- for (j = beg ; j < beg+len ; ++j) {
326
+ for (j = beg ; j < beg + len ; ++j) {
256
327
  xmlXPathNodeSetAddUnique(new_set, node_set->nodeTab[j]);
257
328
  }
258
- return Nokogiri_wrap_xml_node_set(new_set, rb_iv_get(self, "@document"));
329
+ return noko_xml_node_set_wrap(new_set, rb_iv_get(self, "@document"));
259
330
  }
260
331
 
261
332
  /*
@@ -273,7 +344,8 @@ static VALUE subseq(VALUE self, long beg, long len)
273
344
  * count backward from the end of the +node_set+ (-1 is the last node). Returns
274
345
  * nil if the +index+ (or +start+) are out of range.
275
346
  */
276
- static VALUE slice(int argc, VALUE *argv, VALUE self)
347
+ static VALUE
348
+ slice(int argc, VALUE *argv, VALUE self)
277
349
  {
278
350
  VALUE arg ;
279
351
  long beg, len ;
@@ -319,7 +391,8 @@ static VALUE slice(int argc, VALUE *argv, VALUE self)
319
391
  *
320
392
  * Return this list as an Array
321
393
  */
322
- static VALUE to_array(VALUE self)
394
+ static VALUE
395
+ to_array(VALUE self)
323
396
  {
324
397
  xmlNodeSetPtr node_set ;
325
398
  VALUE list;
@@ -328,9 +401,9 @@ static VALUE to_array(VALUE self)
328
401
  Data_Get_Struct(self, xmlNodeSet, node_set);
329
402
 
330
403
  list = rb_ary_new2(node_set->nodeNr);
331
- for(i = 0; i < node_set->nodeNr; i++) {
332
- VALUE elt = Nokogiri_wrap_xml_node_set_node(node_set->nodeTab[i], self);
333
- rb_ary_push( list, elt );
404
+ for (i = 0; i < node_set->nodeNr; i++) {
405
+ VALUE elt = noko_xml_node_wrap_node_set_result(node_set->nodeTab[i], self);
406
+ rb_ary_push(list, elt);
334
407
  }
335
408
 
336
409
  return list;
@@ -342,7 +415,8 @@ static VALUE to_array(VALUE self)
342
415
  *
343
416
  * Unlink this NodeSet and all Node objects it contains from their current context.
344
417
  */
345
- static VALUE unlink_nodeset(VALUE self)
418
+ static VALUE
419
+ unlink_nodeset(VALUE self)
346
420
  {
347
421
  xmlNodeSetPtr node_set;
348
422
  int j, nodeNr ;
@@ -354,7 +428,7 @@ static VALUE unlink_nodeset(VALUE self)
354
428
  if (! NOKOGIRI_NAMESPACE_EH(node_set->nodeTab[j])) {
355
429
  VALUE node ;
356
430
  xmlNodePtr node_ptr;
357
- node = Nokogiri_wrap_xml_node(Qnil, node_set->nodeTab[j]);
431
+ node = noko_xml_node_wrap(Qnil, node_set->nodeTab[j]);
358
432
  rb_funcall(node, rb_intern("unlink"), 0); /* modifies the C struct out from under the object */
359
433
  Data_Get_Struct(node, xmlNode, node_ptr);
360
434
  node_set->nodeTab[j] = node_ptr ;
@@ -364,123 +438,61 @@ static VALUE unlink_nodeset(VALUE self)
364
438
  }
365
439
 
366
440
 
367
- static void reify_node_set_namespaces(VALUE self)
368
- {
369
- /*
370
- * as mentioned in deallocate() above, xmlNs structs returned in an XPath
371
- * NodeSet are duplicates, and we don't clean them up at deallocate() time.
372
- *
373
- * as a result, we need to make sure the Ruby manages this memory. we do this
374
- * by forcing the creation of a Ruby object wrapped around the xmlNs.
375
- *
376
- * we also have to make sure that the NodeSet has a reference to the
377
- * Namespace object, otherwise GC will kick in and the Namespace won't be
378
- * marked.
379
- *
380
- * we *could* do this safely with *all* the nodes in the NodeSet, but we only
381
- * *need* to do it for xmlNs structs, and so you get the code we have here.
382
- */
383
- int j ;
384
- xmlNodeSetPtr node_set ;
385
- VALUE namespace_cache ;
386
-
387
- Data_Get_Struct(self, xmlNodeSet, node_set);
388
-
389
- namespace_cache = rb_iv_get(self, "@namespace_cache");
390
-
391
- for (j = 0 ; j < node_set->nodeNr ; j++) {
392
- if (NOKOGIRI_NAMESPACE_EH(node_set->nodeTab[j])) {
393
- rb_ary_push(namespace_cache, Nokogiri_wrap_xml_node_set_node(node_set->nodeTab[j], self));
394
- }
395
- }
396
- }
397
-
398
-
399
- VALUE Nokogiri_wrap_xml_node_set(xmlNodeSetPtr node_set, VALUE document)
441
+ VALUE
442
+ noko_xml_node_set_wrap(xmlNodeSetPtr c_node_set, VALUE document)
400
443
  {
401
- VALUE new_set ;
444
+ int j;
445
+ VALUE rb_node_set ;
402
446
 
403
- if (node_set == NULL) {
404
- node_set = xmlXPathNodeSetCreate(NULL);
447
+ if (c_node_set == NULL) {
448
+ c_node_set = xmlXPathNodeSetCreate(NULL);
405
449
  }
406
450
 
407
- new_set = Data_Wrap_Struct(cNokogiriXmlNodeSet, 0, deallocate, node_set);
451
+ rb_node_set = Data_Wrap_Struct(cNokogiriXmlNodeSet, mark, deallocate, c_node_set);
408
452
 
409
453
  if (!NIL_P(document)) {
410
- rb_iv_set(new_set, "@document", document);
411
- rb_funcall(document, decorate, 1, new_set);
454
+ rb_iv_set(rb_node_set, "@document", document);
455
+ rb_funcall(document, decorate, 1, rb_node_set);
412
456
  }
413
457
 
414
- rb_iv_set(new_set, "@namespace_cache", rb_ary_new());
415
- reify_node_set_namespaces(new_set);
458
+ /* make sure we create ruby objects for all the results, so they'll be marked during the GC mark phase */
459
+ for (j = 0 ; j < c_node_set->nodeNr ; j++) {
460
+ noko_xml_node_wrap_node_set_result(c_node_set->nodeTab[j], rb_node_set);
461
+ }
416
462
 
417
- return new_set ;
463
+ return rb_node_set ;
418
464
  }
419
465
 
420
- VALUE Nokogiri_wrap_xml_node_set_node(xmlNodePtr node, VALUE node_set)
466
+ VALUE
467
+ noko_xml_node_wrap_node_set_result(xmlNodePtr node, VALUE node_set)
421
468
  {
422
- xmlDocPtr document ;
423
-
424
469
  if (NOKOGIRI_NAMESPACE_EH(node)) {
425
- Data_Get_Struct(rb_iv_get(node_set, "@document"), xmlDoc, document);
426
- return Nokogiri_wrap_xml_namespace(document, (xmlNsPtr)node);
470
+ return noko_xml_namespace_wrap_xpath_copy((xmlNsPtr)node);
427
471
  } else {
428
- return Nokogiri_wrap_xml_node(Qnil, node);
429
- }
430
- }
431
-
432
-
433
- static void xpath_node_set_del(xmlNodeSetPtr cur, xmlNodePtr val)
434
- {
435
- /*
436
- * as mentioned a few times above, we do not want to free xmlNs structs
437
- * outside of the Namespace lifecycle.
438
- *
439
- * xmlXPathNodeSetDel() frees xmlNs structs, and so here we reproduce that
440
- * function with the xmlNs logic.
441
- */
442
- int i;
443
-
444
- if (cur == NULL) return;
445
- if (val == NULL) return;
446
-
447
- /*
448
- * find node in nodeTab
449
- */
450
- for (i = 0;i < cur->nodeNr;i++)
451
- if (cur->nodeTab[i] == val) break;
452
-
453
- if (i >= cur->nodeNr) { /* not found */
454
- return;
472
+ return noko_xml_node_wrap(Qnil, node);
455
473
  }
456
- cur->nodeNr--;
457
- for (;i < cur->nodeNr;i++)
458
- cur->nodeTab[i] = cur->nodeTab[i + 1];
459
- cur->nodeTab[cur->nodeNr] = NULL;
460
474
  }
461
475
 
462
476
 
463
- VALUE cNokogiriXmlNodeSet ;
464
- void init_xml_node_set(void)
477
+ void
478
+ noko_init_xml_node_set(void)
465
479
  {
466
- VALUE nokogiri = rb_define_module("Nokogiri");
467
- VALUE xml = rb_define_module_under(nokogiri, "XML");
468
- VALUE klass = rb_define_class_under(xml, "NodeSet", rb_cObject);
469
- cNokogiriXmlNodeSet = klass;
470
-
471
- rb_define_alloc_func(klass, allocate);
472
- rb_define_method(klass, "length", length, 0);
473
- rb_define_method(klass, "[]", slice, -1);
474
- rb_define_method(klass, "slice", slice, -1);
475
- rb_define_method(klass, "push", push, 1);
476
- rb_define_method(klass, "|", set_union, 1);
477
- rb_define_method(klass, "-", minus, 1);
478
- rb_define_method(klass, "unlink", unlink_nodeset, 0);
479
- rb_define_method(klass, "to_a", to_array, 0);
480
- rb_define_method(klass, "dup", duplicate, 0);
481
- rb_define_method(klass, "delete", delete, 1);
482
- rb_define_method(klass, "&", intersection, 1);
483
- rb_define_method(klass, "include?", include_eh, 1);
480
+ cNokogiriXmlNodeSet = rb_define_class_under(mNokogiriXml, "NodeSet", rb_cObject);
481
+
482
+ rb_define_alloc_func(cNokogiriXmlNodeSet, allocate);
483
+
484
+ rb_define_method(cNokogiriXmlNodeSet, "length", length, 0);
485
+ rb_define_method(cNokogiriXmlNodeSet, "[]", slice, -1);
486
+ rb_define_method(cNokogiriXmlNodeSet, "slice", slice, -1);
487
+ rb_define_method(cNokogiriXmlNodeSet, "push", push, 1);
488
+ rb_define_method(cNokogiriXmlNodeSet, "|", rb_xml_node_set_union, 1);
489
+ rb_define_method(cNokogiriXmlNodeSet, "-", minus, 1);
490
+ rb_define_method(cNokogiriXmlNodeSet, "unlink", unlink_nodeset, 0);
491
+ rb_define_method(cNokogiriXmlNodeSet, "to_a", to_array, 0);
492
+ rb_define_method(cNokogiriXmlNodeSet, "dup", duplicate, 0);
493
+ rb_define_method(cNokogiriXmlNodeSet, "delete", delete, 1);
494
+ rb_define_method(cNokogiriXmlNodeSet, "&", intersection, 1);
495
+ rb_define_method(cNokogiriXmlNodeSet, "include?", include_eh, 1);
484
496
 
485
497
  decorate = rb_intern("decorate");
486
498
  }