nokogiri 1.6.0 → 1.13.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 (340) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -19
  3. data/LICENSE-DEPENDENCIES.md +1903 -0
  4. data/LICENSE.md +9 -0
  5. data/README.md +280 -0
  6. data/bin/nokogiri +84 -31
  7. data/dependencies.yml +23 -4
  8. data/ext/nokogiri/depend +38 -358
  9. data/ext/nokogiri/extconf.rb +952 -132
  10. data/ext/nokogiri/gumbo.c +584 -0
  11. data/ext/nokogiri/html4_document.c +166 -0
  12. data/ext/nokogiri/html4_element_description.c +294 -0
  13. data/ext/nokogiri/html4_entity_lookup.c +37 -0
  14. data/ext/nokogiri/html4_sax_parser_context.c +120 -0
  15. data/ext/nokogiri/html4_sax_push_parser.c +95 -0
  16. data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
  17. data/ext/nokogiri/nokogiri.c +231 -96
  18. data/ext/nokogiri/nokogiri.h +188 -129
  19. data/ext/nokogiri/test_global_handlers.c +40 -0
  20. data/ext/nokogiri/xml_attr.c +49 -40
  21. data/ext/nokogiri/xml_attribute_decl.c +18 -18
  22. data/ext/nokogiri/xml_cdata.c +24 -23
  23. data/ext/nokogiri/xml_comment.c +29 -21
  24. data/ext/nokogiri/xml_document.c +327 -223
  25. data/ext/nokogiri/xml_document_fragment.c +12 -16
  26. data/ext/nokogiri/xml_dtd.c +56 -50
  27. data/ext/nokogiri/xml_element_content.c +31 -26
  28. data/ext/nokogiri/xml_element_decl.c +22 -22
  29. data/ext/nokogiri/xml_encoding_handler.c +45 -20
  30. data/ext/nokogiri/xml_entity_decl.c +32 -30
  31. data/ext/nokogiri/xml_entity_reference.c +16 -18
  32. data/ext/nokogiri/xml_namespace.c +74 -32
  33. data/ext/nokogiri/xml_node.c +1290 -680
  34. data/ext/nokogiri/xml_node_set.c +239 -208
  35. data/ext/nokogiri/xml_processing_instruction.c +17 -19
  36. data/ext/nokogiri/xml_reader.c +227 -189
  37. data/ext/nokogiri/xml_relax_ng.c +52 -28
  38. data/ext/nokogiri/xml_sax_parser.c +123 -125
  39. data/ext/nokogiri/xml_sax_parser_context.c +138 -79
  40. data/ext/nokogiri/xml_sax_push_parser.c +88 -35
  41. data/ext/nokogiri/xml_schema.c +112 -33
  42. data/ext/nokogiri/xml_syntax_error.c +50 -23
  43. data/ext/nokogiri/xml_text.c +14 -18
  44. data/ext/nokogiri/xml_xpath_context.c +227 -140
  45. data/ext/nokogiri/xslt_stylesheet.c +269 -177
  46. data/gumbo-parser/CHANGES.md +63 -0
  47. data/gumbo-parser/Makefile +101 -0
  48. data/gumbo-parser/THANKS +27 -0
  49. data/gumbo-parser/src/Makefile +34 -0
  50. data/gumbo-parser/src/README.md +41 -0
  51. data/gumbo-parser/src/ascii.c +75 -0
  52. data/gumbo-parser/src/ascii.h +115 -0
  53. data/gumbo-parser/src/attribute.c +42 -0
  54. data/gumbo-parser/src/attribute.h +17 -0
  55. data/gumbo-parser/src/char_ref.c +22225 -0
  56. data/gumbo-parser/src/char_ref.h +29 -0
  57. data/gumbo-parser/src/char_ref.rl +2154 -0
  58. data/gumbo-parser/src/error.c +626 -0
  59. data/gumbo-parser/src/error.h +148 -0
  60. data/gumbo-parser/src/foreign_attrs.c +104 -0
  61. data/gumbo-parser/src/foreign_attrs.gperf +27 -0
  62. data/gumbo-parser/src/gumbo.h +943 -0
  63. data/gumbo-parser/src/insertion_mode.h +33 -0
  64. data/gumbo-parser/src/macros.h +91 -0
  65. data/gumbo-parser/src/parser.c +4875 -0
  66. data/gumbo-parser/src/parser.h +41 -0
  67. data/gumbo-parser/src/replacement.h +33 -0
  68. data/gumbo-parser/src/string_buffer.c +103 -0
  69. data/gumbo-parser/src/string_buffer.h +68 -0
  70. data/gumbo-parser/src/string_piece.c +48 -0
  71. data/gumbo-parser/src/svg_attrs.c +174 -0
  72. data/gumbo-parser/src/svg_attrs.gperf +77 -0
  73. data/gumbo-parser/src/svg_tags.c +137 -0
  74. data/gumbo-parser/src/svg_tags.gperf +55 -0
  75. data/gumbo-parser/src/tag.c +222 -0
  76. data/gumbo-parser/src/tag_lookup.c +382 -0
  77. data/gumbo-parser/src/tag_lookup.gperf +169 -0
  78. data/gumbo-parser/src/tag_lookup.h +13 -0
  79. data/gumbo-parser/src/token_buffer.c +79 -0
  80. data/gumbo-parser/src/token_buffer.h +71 -0
  81. data/gumbo-parser/src/token_type.h +17 -0
  82. data/gumbo-parser/src/tokenizer.c +3463 -0
  83. data/gumbo-parser/src/tokenizer.h +112 -0
  84. data/gumbo-parser/src/tokenizer_states.h +339 -0
  85. data/gumbo-parser/src/utf8.c +245 -0
  86. data/gumbo-parser/src/utf8.h +164 -0
  87. data/gumbo-parser/src/util.c +68 -0
  88. data/gumbo-parser/src/util.h +30 -0
  89. data/gumbo-parser/src/vector.c +111 -0
  90. data/gumbo-parser/src/vector.h +45 -0
  91. data/lib/nokogiri/class_resolver.rb +67 -0
  92. data/lib/nokogiri/css/node.rb +10 -58
  93. data/lib/nokogiri/css/parser.rb +407 -357
  94. data/lib/nokogiri/css/parser.y +265 -246
  95. data/lib/nokogiri/css/parser_extras.rb +52 -49
  96. data/lib/nokogiri/css/syntax_error.rb +3 -1
  97. data/lib/nokogiri/css/tokenizer.rb +107 -104
  98. data/lib/nokogiri/css/tokenizer.rex +8 -7
  99. data/lib/nokogiri/css/xpath_visitor.rb +266 -80
  100. data/lib/nokogiri/css.rb +50 -17
  101. data/lib/nokogiri/decorators/slop.rb +17 -8
  102. data/lib/nokogiri/extension.rb +31 -0
  103. data/lib/nokogiri/gumbo.rb +15 -0
  104. data/lib/nokogiri/html.rb +38 -27
  105. data/lib/nokogiri/{html → html4}/builder.rb +4 -2
  106. data/lib/nokogiri/html4/document.rb +331 -0
  107. data/lib/nokogiri/html4/document_fragment.rb +54 -0
  108. data/lib/nokogiri/{html → html4}/element_description.rb +3 -1
  109. data/lib/nokogiri/html4/element_description_defaults.rb +578 -0
  110. data/lib/nokogiri/{html → html4}/entity_lookup.rb +4 -2
  111. data/lib/nokogiri/{html → html4}/sax/parser.rb +24 -15
  112. data/lib/nokogiri/html4/sax/parser_context.rb +20 -0
  113. data/lib/nokogiri/html4/sax/push_parser.rb +37 -0
  114. data/lib/nokogiri/html4.rb +46 -0
  115. data/lib/nokogiri/html5/document.rb +88 -0
  116. data/lib/nokogiri/html5/document_fragment.rb +83 -0
  117. data/lib/nokogiri/html5/node.rb +96 -0
  118. data/lib/nokogiri/html5.rb +477 -0
  119. data/lib/nokogiri/jruby/dependencies.rb +21 -0
  120. data/lib/nokogiri/syntax_error.rb +2 -0
  121. data/lib/nokogiri/version/constant.rb +6 -0
  122. data/lib/nokogiri/version/info.rb +221 -0
  123. data/lib/nokogiri/version.rb +3 -105
  124. data/lib/nokogiri/xml/attr.rb +6 -3
  125. data/lib/nokogiri/xml/attribute_decl.rb +3 -1
  126. data/lib/nokogiri/xml/builder.rb +96 -54
  127. data/lib/nokogiri/xml/cdata.rb +3 -1
  128. data/lib/nokogiri/xml/character_data.rb +2 -0
  129. data/lib/nokogiri/xml/document.rb +234 -95
  130. data/lib/nokogiri/xml/document_fragment.rb +86 -36
  131. data/lib/nokogiri/xml/dtd.rb +16 -4
  132. data/lib/nokogiri/xml/element_content.rb +2 -0
  133. data/lib/nokogiri/xml/element_decl.rb +3 -1
  134. data/lib/nokogiri/xml/entity_decl.rb +4 -2
  135. data/lib/nokogiri/xml/entity_reference.rb +20 -0
  136. data/lib/nokogiri/xml/namespace.rb +3 -0
  137. data/lib/nokogiri/xml/node/save_options.rb +8 -4
  138. data/lib/nokogiri/xml/node.rb +947 -502
  139. data/lib/nokogiri/xml/node_set.rb +168 -159
  140. data/lib/nokogiri/xml/notation.rb +13 -0
  141. data/lib/nokogiri/xml/parse_options.rb +40 -5
  142. data/lib/nokogiri/xml/pp/character_data.rb +9 -6
  143. data/lib/nokogiri/xml/pp/node.rb +25 -26
  144. data/lib/nokogiri/xml/pp.rb +4 -2
  145. data/lib/nokogiri/xml/processing_instruction.rb +3 -1
  146. data/lib/nokogiri/xml/reader.rb +23 -28
  147. data/lib/nokogiri/xml/relax_ng.rb +8 -2
  148. data/lib/nokogiri/xml/sax/document.rb +45 -49
  149. data/lib/nokogiri/xml/sax/parser.rb +43 -41
  150. data/lib/nokogiri/xml/sax/parser_context.rb +8 -3
  151. data/lib/nokogiri/xml/sax/push_parser.rb +6 -5
  152. data/lib/nokogiri/xml/sax.rb +6 -4
  153. data/lib/nokogiri/xml/schema.rb +19 -9
  154. data/lib/nokogiri/xml/searchable.rb +270 -0
  155. data/lib/nokogiri/xml/syntax_error.rb +25 -1
  156. data/lib/nokogiri/xml/text.rb +2 -0
  157. data/lib/nokogiri/xml/xpath/syntax_error.rb +4 -2
  158. data/lib/nokogiri/xml/xpath.rb +15 -4
  159. data/lib/nokogiri/xml/xpath_context.rb +3 -3
  160. data/lib/nokogiri/xml.rb +38 -36
  161. data/lib/nokogiri/xslt/stylesheet.rb +3 -1
  162. data/lib/nokogiri/xslt.rb +29 -20
  163. data/lib/nokogiri.rb +69 -69
  164. data/lib/xsd/xmlparser/nokogiri.rb +26 -24
  165. data/patches/libxml2/0001-Remove-script-macro-support.patch +40 -0
  166. data/patches/libxml2/0002-Update-entities-to-remove-handling-of-ssi.patch +44 -0
  167. data/patches/libxml2/0003-libxml2.la-is-in-top_builddir.patch +25 -0
  168. data/patches/libxml2/0004-use-glibc-strlen.patch +53 -0
  169. data/patches/libxml2/0005-avoid-isnan-isinf.patch +81 -0
  170. data/patches/libxml2/0006-update-automake-files-for-arm64.patch +3040 -0
  171. data/patches/libxml2/0008-htmlParseComment-handle-abruptly-closed-comments.patch +61 -0
  172. data/patches/libxml2/0009-allow-wildcard-namespaces.patch +77 -0
  173. data/patches/libxslt/0001-update-automake-files-for-arm64.patch +3037 -0
  174. data/ports/archives/libxml2-2.9.13.tar.xz +0 -0
  175. data/ports/archives/libxslt-1.1.35.tar.xz +0 -0
  176. metadata +278 -362
  177. data/.autotest +0 -26
  178. data/.gemtest +0 -0
  179. data/.travis.yml +0 -27
  180. data/CHANGELOG.ja.rdoc +0 -819
  181. data/CHANGELOG.rdoc +0 -819
  182. data/C_CODING_STYLE.rdoc +0 -33
  183. data/Manifest.txt +0 -315
  184. data/README.ja.rdoc +0 -106
  185. data/README.rdoc +0 -175
  186. data/ROADMAP.md +0 -90
  187. data/Rakefile +0 -246
  188. data/STANDARD_RESPONSES.md +0 -47
  189. data/Y_U_NO_GEMSPEC.md +0 -155
  190. data/build_all +0 -105
  191. data/ext/nokogiri/html_document.c +0 -170
  192. data/ext/nokogiri/html_document.h +0 -10
  193. data/ext/nokogiri/html_element_description.c +0 -279
  194. data/ext/nokogiri/html_element_description.h +0 -10
  195. data/ext/nokogiri/html_entity_lookup.c +0 -32
  196. data/ext/nokogiri/html_entity_lookup.h +0 -8
  197. data/ext/nokogiri/html_sax_parser_context.c +0 -116
  198. data/ext/nokogiri/html_sax_parser_context.h +0 -11
  199. data/ext/nokogiri/html_sax_push_parser.c +0 -87
  200. data/ext/nokogiri/html_sax_push_parser.h +0 -9
  201. data/ext/nokogiri/xml_attr.h +0 -9
  202. data/ext/nokogiri/xml_attribute_decl.h +0 -9
  203. data/ext/nokogiri/xml_cdata.h +0 -9
  204. data/ext/nokogiri/xml_comment.h +0 -9
  205. data/ext/nokogiri/xml_document.h +0 -23
  206. data/ext/nokogiri/xml_document_fragment.h +0 -10
  207. data/ext/nokogiri/xml_dtd.h +0 -10
  208. data/ext/nokogiri/xml_element_content.h +0 -10
  209. data/ext/nokogiri/xml_element_decl.h +0 -9
  210. data/ext/nokogiri/xml_encoding_handler.h +0 -8
  211. data/ext/nokogiri/xml_entity_decl.h +0 -10
  212. data/ext/nokogiri/xml_entity_reference.h +0 -9
  213. data/ext/nokogiri/xml_io.c +0 -56
  214. data/ext/nokogiri/xml_io.h +0 -11
  215. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
  216. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  217. data/ext/nokogiri/xml_namespace.h +0 -13
  218. data/ext/nokogiri/xml_node.h +0 -13
  219. data/ext/nokogiri/xml_node_set.h +0 -14
  220. data/ext/nokogiri/xml_processing_instruction.h +0 -9
  221. data/ext/nokogiri/xml_reader.h +0 -10
  222. data/ext/nokogiri/xml_relax_ng.h +0 -9
  223. data/ext/nokogiri/xml_sax_parser.h +0 -39
  224. data/ext/nokogiri/xml_sax_parser_context.h +0 -10
  225. data/ext/nokogiri/xml_sax_push_parser.h +0 -9
  226. data/ext/nokogiri/xml_schema.h +0 -9
  227. data/ext/nokogiri/xml_syntax_error.h +0 -13
  228. data/ext/nokogiri/xml_text.h +0 -9
  229. data/ext/nokogiri/xml_xpath_context.h +0 -10
  230. data/ext/nokogiri/xslt_stylesheet.h +0 -14
  231. data/lib/nokogiri/html/document.rb +0 -254
  232. data/lib/nokogiri/html/document_fragment.rb +0 -41
  233. data/lib/nokogiri/html/element_description_defaults.rb +0 -671
  234. data/lib/nokogiri/html/sax/parser_context.rb +0 -16
  235. data/lib/nokogiri/html/sax/push_parser.rb +0 -16
  236. data/ports/archives/libxml2-2.8.0.tar.gz +0 -0
  237. data/ports/archives/libxslt-1.1.26.tar.gz +0 -0
  238. data/tasks/cross_compile.rb +0 -132
  239. data/tasks/nokogiri.org.rb +0 -24
  240. data/tasks/test.rb +0 -95
  241. data/test/css/test_nthiness.rb +0 -159
  242. data/test/css/test_parser.rb +0 -341
  243. data/test/css/test_tokenizer.rb +0 -198
  244. data/test/css/test_xpath_visitor.rb +0 -91
  245. data/test/decorators/test_slop.rb +0 -16
  246. data/test/files/2ch.html +0 -108
  247. data/test/files/address_book.rlx +0 -12
  248. data/test/files/address_book.xml +0 -10
  249. data/test/files/bar/bar.xsd +0 -4
  250. data/test/files/bogus.xml +0 -0
  251. data/test/files/dont_hurt_em_why.xml +0 -422
  252. data/test/files/encoding.html +0 -82
  253. data/test/files/encoding.xhtml +0 -84
  254. data/test/files/exslt.xml +0 -8
  255. data/test/files/exslt.xslt +0 -35
  256. data/test/files/foo/foo.xsd +0 -4
  257. data/test/files/metacharset.html +0 -10
  258. data/test/files/noencoding.html +0 -47
  259. data/test/files/po.xml +0 -32
  260. data/test/files/po.xsd +0 -66
  261. data/test/files/saml/saml20assertion_schema.xsd +0 -283
  262. data/test/files/saml/saml20protocol_schema.xsd +0 -302
  263. data/test/files/saml/xenc_schema.xsd +0 -146
  264. data/test/files/saml/xmldsig_schema.xsd +0 -318
  265. data/test/files/shift_jis.html +0 -10
  266. data/test/files/shift_jis.xml +0 -5
  267. data/test/files/snuggles.xml +0 -3
  268. data/test/files/staff.dtd +0 -10
  269. data/test/files/staff.xml +0 -59
  270. data/test/files/staff.xslt +0 -32
  271. data/test/files/test_document_url/bar.xml +0 -2
  272. data/test/files/test_document_url/document.dtd +0 -4
  273. data/test/files/test_document_url/document.xml +0 -6
  274. data/test/files/tlm.html +0 -850
  275. data/test/files/to_be_xincluded.xml +0 -2
  276. data/test/files/valid_bar.xml +0 -2
  277. data/test/files/xinclude.xml +0 -4
  278. data/test/helper.rb +0 -154
  279. data/test/html/sax/test_parser.rb +0 -141
  280. data/test/html/sax/test_parser_context.rb +0 -46
  281. data/test/html/test_builder.rb +0 -164
  282. data/test/html/test_document.rb +0 -552
  283. data/test/html/test_document_encoding.rb +0 -138
  284. data/test/html/test_document_fragment.rb +0 -261
  285. data/test/html/test_element_description.rb +0 -105
  286. data/test/html/test_named_characters.rb +0 -14
  287. data/test/html/test_node.rb +0 -196
  288. data/test/html/test_node_encoding.rb +0 -27
  289. data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +0 -14
  290. data/test/namespaces/test_namespaces_in_builder_doc.rb +0 -75
  291. data/test/namespaces/test_namespaces_in_created_doc.rb +0 -75
  292. data/test/namespaces/test_namespaces_in_parsed_doc.rb +0 -66
  293. data/test/test_convert_xpath.rb +0 -135
  294. data/test/test_css_cache.rb +0 -45
  295. data/test/test_encoding_handler.rb +0 -46
  296. data/test/test_memory_leak.rb +0 -156
  297. data/test/test_nokogiri.rb +0 -132
  298. data/test/test_reader.rb +0 -555
  299. data/test/test_soap4r_sax.rb +0 -52
  300. data/test/test_xslt_transforms.rb +0 -254
  301. data/test/xml/node/test_save_options.rb +0 -28
  302. data/test/xml/node/test_subclass.rb +0 -44
  303. data/test/xml/sax/test_parser.rb +0 -366
  304. data/test/xml/sax/test_parser_context.rb +0 -106
  305. data/test/xml/sax/test_push_parser.rb +0 -157
  306. data/test/xml/test_attr.rb +0 -64
  307. data/test/xml/test_attribute_decl.rb +0 -86
  308. data/test/xml/test_builder.rb +0 -306
  309. data/test/xml/test_c14n.rb +0 -151
  310. data/test/xml/test_cdata.rb +0 -48
  311. data/test/xml/test_comment.rb +0 -29
  312. data/test/xml/test_document.rb +0 -828
  313. data/test/xml/test_document_encoding.rb +0 -28
  314. data/test/xml/test_document_fragment.rb +0 -223
  315. data/test/xml/test_dtd.rb +0 -103
  316. data/test/xml/test_dtd_encoding.rb +0 -33
  317. data/test/xml/test_element_content.rb +0 -56
  318. data/test/xml/test_element_decl.rb +0 -73
  319. data/test/xml/test_entity_decl.rb +0 -122
  320. data/test/xml/test_entity_reference.rb +0 -245
  321. data/test/xml/test_namespace.rb +0 -95
  322. data/test/xml/test_node.rb +0 -1137
  323. data/test/xml/test_node_attributes.rb +0 -96
  324. data/test/xml/test_node_encoding.rb +0 -107
  325. data/test/xml/test_node_inheritance.rb +0 -32
  326. data/test/xml/test_node_reparenting.rb +0 -374
  327. data/test/xml/test_node_set.rb +0 -755
  328. data/test/xml/test_parse_options.rb +0 -64
  329. data/test/xml/test_processing_instruction.rb +0 -30
  330. data/test/xml/test_reader_encoding.rb +0 -142
  331. data/test/xml/test_relax_ng.rb +0 -60
  332. data/test/xml/test_schema.rb +0 -103
  333. data/test/xml/test_syntax_error.rb +0 -12
  334. data/test/xml/test_text.rb +0 -45
  335. data/test/xml/test_unparented_node.rb +0 -422
  336. data/test/xml/test_xinclude.rb +0 -83
  337. data/test/xml/test_xpath.rb +0 -295
  338. data/test/xslt/test_custom_functions.rb +0 -133
  339. data/test/xslt/test_exception_handling.rb +0 -37
  340. data/test_all +0 -81
@@ -1,68 +1,107 @@
1
- #include <xml_node_set.h>
2
- #include <libxml/xpathInternals.h>
1
+ #include <nokogiri.h>
2
+
3
+ VALUE cNokogiriXmlNodeSet ;
3
4
 
4
5
  static ID decorate ;
5
6
 
6
- static int dealloc_namespace(xmlNsPtr ns)
7
+ static void
8
+ Check_Node_Set_Node_Type(VALUE node)
9
+ {
10
+ if (!(rb_obj_is_kind_of(node, cNokogiriXmlNode) ||
11
+ rb_obj_is_kind_of(node, cNokogiriXmlNamespace))) {
12
+ rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace");
13
+ }
14
+ }
15
+
16
+
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)
7
43
  {
8
- if (ns->href)
9
- xmlFree((xmlChar *)ns->href);
10
- if (ns->prefix)
11
- xmlFree((xmlChar *)ns->prefix);
12
- xmlFree(ns);
13
- return ST_CONTINUE;
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
+ }
14
53
  }
15
54
 
16
- static void deallocate(nokogiriNodeSetTuple *tuple)
55
+ static void
56
+ xpath_node_set_del(xmlNodeSetPtr cur, xmlNodePtr val)
17
57
  {
18
58
  /*
19
- * xmlXPathFreeNodeSet() contains an implicit assumption that it is being
20
- * called before any of its pointed-to nodes have been free()d. this
21
- * assumption lies in the operation where it dereferences nodeTab pointers
22
- * while searching for namespace nodes to free.
23
- *
24
- * however, since Ruby's GC mechanism cannot guarantee the strict order in
25
- * which ruby objects will be GC'd, nodes may be garbage collected before a
26
- * nodeset containing pointers to those nodes. (this is true regardless of
27
- * how we declare dependencies between objects with rb_gc_mark().)
28
- *
29
- * as a result, xmlXPathFreeNodeSet() will perform unsafe memory operations,
30
- * and calling it would be evil.
31
- *
32
- * so here, we *manually* free the set of namespace nodes that was
33
- * constructed at initialization time (see Nokogiri_wrap_xml_node_set()), as
34
- * well as the NodeSet, without using the official xmlXPathFreeNodeSet().
35
- *
36
- * there's probably a lesson in here somewhere about intermingling, within a
37
- * single array, structs with different memory-ownership semantics. or more
38
- * generally, a lesson about building an API in C/C++ that does not contain
39
- * assumptions about the strict order in which memory will be released. hey,
40
- * that sounds like a great idea for a blog post! get to it!
41
- *
42
- * "In Valgrind We Trust." seriously.
59
+ * For reasons outlined in xml_namespace.c, here we reproduce xmlXPathNodeSetDel() except for the
60
+ * offending call to xmlXPathNodeSetFreeNs().
43
61
  */
44
- xmlNodeSetPtr node_set;
62
+ int i;
45
63
 
46
- node_set = tuple->node_set;
64
+ if (cur == NULL) { return; }
65
+ if (val == NULL) { return; }
47
66
 
48
- if (!node_set)
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 */
49
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
+ }
50
82
 
51
- NOKOGIRI_DEBUG_START(node_set) ;
52
- st_foreach(tuple->namespaces, dealloc_namespace, 0);
53
83
 
54
- if (node_set->nodeTab != NULL)
84
+ static void
85
+ deallocate(xmlNodeSetPtr node_set)
86
+ {
87
+ /*
88
+ * For reasons outlined in xml_namespace.c, here we reproduce xmlXPathFreeNodeSet() except for the
89
+ * offending call to xmlXPathNodeSetFreeNs().
90
+ */
91
+ NOKOGIRI_DEBUG_START(node_set) ;
92
+ if (node_set->nodeTab != NULL) {
55
93
  xmlFree(node_set->nodeTab);
94
+ }
56
95
 
57
96
  xmlFree(node_set);
58
- st_free_table(tuple->namespaces);
59
- free(tuple);
60
97
  NOKOGIRI_DEBUG_END(node_set) ;
61
98
  }
62
99
 
63
- static VALUE allocate(VALUE klass)
100
+
101
+ static VALUE
102
+ allocate(VALUE klass)
64
103
  {
65
- return Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL), Qnil);
104
+ return noko_xml_node_set_wrap(xmlXPathNodeSetCreate(NULL), Qnil);
66
105
  }
67
106
 
68
107
 
@@ -70,18 +109,20 @@ static VALUE allocate(VALUE klass)
70
109
  * call-seq:
71
110
  * dup
72
111
  *
73
- * Duplicate this node set
112
+ * Duplicate this NodeSet. Note that the Nodes contained in the NodeSet are not
113
+ * duplicated (similar to how Array and other Enumerable classes work).
74
114
  */
75
- static VALUE duplicate(VALUE self)
115
+ static VALUE
116
+ duplicate(VALUE self)
76
117
  {
77
- nokogiriNodeSetTuple *tuple;
118
+ xmlNodeSetPtr node_set;
78
119
  xmlNodeSetPtr dupl;
79
120
 
80
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
121
+ Data_Get_Struct(self, xmlNodeSet, node_set);
81
122
 
82
- dupl = xmlXPathNodeSetMerge(NULL, tuple->node_set);
123
+ dupl = xmlXPathNodeSetMerge(NULL, node_set);
83
124
 
84
- 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"));
85
126
  }
86
127
 
87
128
  /*
@@ -90,12 +131,14 @@ static VALUE duplicate(VALUE self)
90
131
  *
91
132
  * Get the length of the node set
92
133
  */
93
- static VALUE length(VALUE self)
134
+ static VALUE
135
+ length(VALUE self)
94
136
  {
95
- nokogiriNodeSetTuple *tuple;
96
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
137
+ xmlNodeSetPtr node_set;
97
138
 
98
- return tuple->node_set ? INT2NUM(tuple->node_set->nodeNr) : INT2NUM(0);
139
+ Data_Get_Struct(self, xmlNodeSet, node_set);
140
+
141
+ return node_set ? INT2NUM(node_set->nodeNr) : INT2NUM(0);
99
142
  }
100
143
 
101
144
  /*
@@ -104,17 +147,19 @@ static VALUE length(VALUE self)
104
147
  *
105
148
  * Append +node+ to the NodeSet.
106
149
  */
107
- static VALUE push(VALUE self, VALUE rb_node)
150
+ static VALUE
151
+ push(VALUE self, VALUE rb_node)
108
152
  {
109
- nokogiriNodeSetTuple *tuple;
153
+ xmlNodeSetPtr node_set;
110
154
  xmlNodePtr node;
111
155
 
112
- if(!(rb_obj_is_kind_of(rb_node, cNokogiriXmlNode) || rb_obj_is_kind_of(rb_node, cNokogiriXmlNamespace)))
113
- rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace");
156
+ Check_Node_Set_Node_Type(rb_node);
114
157
 
115
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
158
+ Data_Get_Struct(self, xmlNodeSet, node_set);
116
159
  Data_Get_Struct(rb_node, xmlNode, node);
117
- xmlXPathNodeSetAdd(tuple->node_set, node);
160
+
161
+ xmlXPathNodeSetAdd(node_set, node);
162
+
118
163
  return self;
119
164
  }
120
165
 
@@ -126,31 +171,21 @@ static VALUE push(VALUE self, VALUE rb_node)
126
171
  * if found, otherwise returns nil.
127
172
  */
128
173
  static VALUE
129
- delete(VALUE self, VALUE rb_node)
174
+ delete (VALUE self, VALUE rb_node)
130
175
  {
131
- nokogiriNodeSetTuple *tuple;
132
- xmlNodePtr node;
133
- xmlNodeSetPtr cur;
134
- int i;
135
-
136
- if (!(rb_obj_is_kind_of(rb_node, cNokogiriXmlNode) || rb_obj_is_kind_of(rb_node, cNokogiriXmlNamespace)))
137
- rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace");
138
-
139
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
140
- Data_Get_Struct(rb_node, xmlNode, node);
141
- cur = tuple->node_set;
142
-
143
- if (xmlXPathNodeSetContains(cur, node)) {
144
- for (i = 0; i < cur->nodeNr; i++)
145
- if (cur->nodeTab[i] == node) break;
146
-
147
- cur->nodeNr--;
148
- for (;i < cur->nodeNr;i++)
149
- cur->nodeTab[i] = cur->nodeTab[i + 1];
150
- cur->nodeTab[cur->nodeNr] = NULL;
151
- return rb_node;
152
- }
153
- return Qnil ;
176
+ xmlNodeSetPtr node_set;
177
+ xmlNodePtr node;
178
+
179
+ Check_Node_Set_Node_Type(rb_node);
180
+
181
+ Data_Get_Struct(self, xmlNodeSet, node_set);
182
+ Data_Get_Struct(rb_node, xmlNode, node);
183
+
184
+ if (xmlXPathNodeSetContains(node_set, node)) {
185
+ xpath_node_set_del(node_set, node);
186
+ return rb_node;
187
+ }
188
+ return Qnil ;
154
189
  }
155
190
 
156
191
 
@@ -160,19 +195,21 @@ delete(VALUE self, VALUE rb_node)
160
195
  *
161
196
  * Set Intersection — Returns a new NodeSet containing nodes common to the two NodeSets.
162
197
  */
163
- static VALUE intersection(VALUE self, VALUE rb_other)
198
+ static VALUE
199
+ intersection(VALUE self, VALUE rb_other)
164
200
  {
165
- nokogiriNodeSetTuple *tuple, *other;
201
+ xmlNodeSetPtr node_set, other ;
166
202
  xmlNodeSetPtr intersection;
167
203
 
168
- if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
204
+ if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) {
169
205
  rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
206
+ }
170
207
 
171
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
172
- Data_Get_Struct(rb_other, nokogiriNodeSetTuple, other);
208
+ Data_Get_Struct(self, xmlNodeSet, node_set);
209
+ Data_Get_Struct(rb_other, xmlNodeSet, other);
173
210
 
174
- intersection = xmlXPathIntersection(tuple->node_set, other->node_set);
175
- return Nokogiri_wrap_xml_node_set(intersection, rb_iv_get(self, "@document"));
211
+ intersection = xmlXPathIntersection(node_set, other);
212
+ return noko_xml_node_set_wrap(intersection, rb_iv_get(self, "@document"));
176
213
  }
177
214
 
178
215
 
@@ -182,18 +219,18 @@ static VALUE intersection(VALUE self, VALUE rb_other)
182
219
  *
183
220
  * Returns true if any member of node set equals +node+.
184
221
  */
185
- static VALUE include_eh(VALUE self, VALUE rb_node)
222
+ static VALUE
223
+ include_eh(VALUE self, VALUE rb_node)
186
224
  {
187
- nokogiriNodeSetTuple *tuple;
225
+ xmlNodeSetPtr node_set;
188
226
  xmlNodePtr node;
189
227
 
190
- if(!(rb_obj_is_kind_of(rb_node, cNokogiriXmlNode) || rb_obj_is_kind_of(rb_node, cNokogiriXmlNamespace)))
191
- rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace");
228
+ Check_Node_Set_Node_Type(rb_node);
192
229
 
193
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
230
+ Data_Get_Struct(self, xmlNodeSet, node_set);
194
231
  Data_Get_Struct(rb_node, xmlNode, node);
195
232
 
196
- return (xmlXPathNodeSetContains(tuple->node_set, node) ? Qtrue : Qfalse);
233
+ return (xmlXPathNodeSetContains(node_set, node) ? Qtrue : Qfalse);
197
234
  }
198
235
 
199
236
 
@@ -204,21 +241,23 @@ static VALUE include_eh(VALUE self, VALUE rb_node)
204
241
  * Returns a new set built by merging the set and the elements of the given
205
242
  * set.
206
243
  */
207
- 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)
208
246
  {
209
- nokogiriNodeSetTuple *tuple, *other;
210
- xmlNodeSetPtr new;
247
+ xmlNodeSetPtr c_node_set, c_other;
248
+ xmlNodeSetPtr c_new_node_set;
211
249
 
212
- if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
250
+ if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) {
213
251
  rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
252
+ }
214
253
 
215
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
216
- Data_Get_Struct(rb_other, nokogiriNodeSetTuple, other);
254
+ Data_Get_Struct(rb_node_set, xmlNodeSet, c_node_set);
255
+ Data_Get_Struct(rb_other, xmlNodeSet, c_other);
217
256
 
218
- new = xmlXPathNodeSetMerge(NULL, tuple->node_set);
219
- new = xmlXPathNodeSetMerge(new, other->node_set);
257
+ c_new_node_set = xmlXPathNodeSetMerge(NULL, c_node_set);
258
+ c_new_node_set = xmlXPathNodeSetMerge(c_new_node_set, c_other);
220
259
 
221
- 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"));
222
261
  }
223
262
 
224
263
  /*
@@ -228,68 +267,66 @@ static VALUE set_union(VALUE self, VALUE rb_other)
228
267
  * Difference - returns a new NodeSet that is a copy of this NodeSet, removing
229
268
  * each item that also appears in +node_set+
230
269
  */
231
- static VALUE minus(VALUE self, VALUE rb_other)
270
+ static VALUE
271
+ minus(VALUE self, VALUE rb_other)
232
272
  {
233
- nokogiriNodeSetTuple *tuple, *other;
273
+ xmlNodeSetPtr node_set, other;
234
274
  xmlNodeSetPtr new;
235
275
  int j ;
236
276
 
237
- if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
277
+ if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) {
238
278
  rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
279
+ }
239
280
 
240
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
241
- Data_Get_Struct(rb_other, nokogiriNodeSetTuple, other);
281
+ Data_Get_Struct(self, xmlNodeSet, node_set);
282
+ Data_Get_Struct(rb_other, xmlNodeSet, other);
242
283
 
243
- new = xmlXPathNodeSetMerge(NULL, tuple->node_set);
244
- for (j = 0 ; j < other->node_set->nodeNr ; ++j) {
245
- xmlXPathNodeSetDel(new, other->node_set->nodeTab[j]);
284
+ new = xmlXPathNodeSetMerge(NULL, node_set);
285
+ for (j = 0 ; j < other->nodeNr ; ++j) {
286
+ xpath_node_set_del(new, other->nodeTab[j]);
246
287
  }
247
288
 
248
- 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"));
249
290
  }
250
291
 
251
292
 
252
- static VALUE index_at(VALUE self, long offset)
293
+ static VALUE
294
+ index_at(VALUE self, long offset)
253
295
  {
254
296
  xmlNodeSetPtr node_set;
255
- nokogiriNodeSetTuple *tuple;
256
297
 
257
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
258
- node_set = tuple->node_set;
298
+ Data_Get_Struct(self, xmlNodeSet, node_set);
259
299
 
260
- if (offset >= node_set->nodeNr || abs((int)offset) > node_set->nodeNr)
300
+ if (offset >= node_set->nodeNr || abs((int)offset) > node_set->nodeNr) {
261
301
  return Qnil;
302
+ }
262
303
 
263
- if (offset < 0)
264
- offset += node_set->nodeNr;
304
+ if (offset < 0) { offset += node_set->nodeNr ; }
265
305
 
266
- if (XML_NAMESPACE_DECL == node_set->nodeTab[offset]->type)
267
- return Nokogiri_wrap_xml_namespace2(rb_iv_get(self, "@document"), (xmlNsPtr)(node_set->nodeTab[offset]));
268
- return Nokogiri_wrap_xml_node(Qnil, node_set->nodeTab[offset]);
306
+ return noko_xml_node_wrap_node_set_result(node_set->nodeTab[offset], self);
269
307
  }
270
308
 
271
- static VALUE subseq(VALUE self, long beg, long len)
309
+ static VALUE
310
+ subseq(VALUE self, long beg, long len)
272
311
  {
273
312
  long j;
274
- nokogiriNodeSetTuple *tuple;
275
313
  xmlNodeSetPtr node_set;
276
314
  xmlNodeSetPtr new_set ;
277
315
 
278
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
279
- node_set = tuple->node_set;
316
+ Data_Get_Struct(self, xmlNodeSet, node_set);
280
317
 
281
- if (beg > node_set->nodeNr) return Qnil ;
282
- if (beg < 0 || len < 0) return Qnil ;
318
+ if (beg > node_set->nodeNr) { return Qnil ; }
319
+ if (beg < 0 || len < 0) { return Qnil ; }
283
320
 
284
321
  if ((beg + len) > node_set->nodeNr) {
285
322
  len = node_set->nodeNr - beg ;
286
323
  }
287
324
 
288
325
  new_set = xmlXPathNodeSetCreate(NULL);
289
- for (j = beg ; j < beg+len ; ++j) {
326
+ for (j = beg ; j < beg + len ; ++j) {
290
327
  xmlXPathNodeSetAddUnique(new_set, node_set->nodeTab[j]);
291
328
  }
292
- 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"));
293
330
  }
294
331
 
295
332
  /*
@@ -307,14 +344,14 @@ static VALUE subseq(VALUE self, long beg, long len)
307
344
  * count backward from the end of the +node_set+ (-1 is the last node). Returns
308
345
  * nil if the +index+ (or +start+) are out of range.
309
346
  */
310
- static VALUE slice(int argc, VALUE *argv, VALUE self)
347
+ static VALUE
348
+ slice(int argc, VALUE *argv, VALUE self)
311
349
  {
312
350
  VALUE arg ;
313
351
  long beg, len ;
314
352
  xmlNodeSetPtr node_set;
315
- nokogiriNodeSetTuple *tuple;
316
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
317
- node_set = tuple->node_set;
353
+
354
+ Data_Get_Struct(self, xmlNodeSet, node_set);
318
355
 
319
356
  if (argc == 2) {
320
357
  beg = NUM2LONG(argv[0]);
@@ -333,15 +370,15 @@ static VALUE slice(int argc, VALUE *argv, VALUE self)
333
370
  if (FIXNUM_P(arg)) {
334
371
  return index_at(self, FIX2LONG(arg));
335
372
  }
336
-
373
+
337
374
  /* if arg is Range */
338
375
  switch (rb_range_beg_len(arg, &beg, &len, (long)node_set->nodeNr, 0)) {
339
- case Qfalse:
340
- break;
341
- case Qnil:
342
- return Qnil;
343
- default:
344
- return subseq(self, beg, len);
376
+ case Qfalse:
377
+ break;
378
+ case Qnil:
379
+ return Qnil;
380
+ default:
381
+ return subseq(self, beg, len);
345
382
  }
346
383
 
347
384
  return index_at(self, NUM2LONG(arg));
@@ -354,29 +391,21 @@ static VALUE slice(int argc, VALUE *argv, VALUE self)
354
391
  *
355
392
  * Return this list as an Array
356
393
  */
357
- static VALUE to_array(VALUE self, VALUE rb_node)
394
+ static VALUE
395
+ to_array(VALUE self)
358
396
  {
359
- xmlNodeSetPtr set;
360
- VALUE *elts;
397
+ xmlNodeSetPtr node_set ;
361
398
  VALUE list;
362
399
  int i;
363
- nokogiriNodeSetTuple *tuple;
364
400
 
365
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
366
- set = tuple->node_set;
401
+ Data_Get_Struct(self, xmlNodeSet, node_set);
367
402
 
368
- elts = calloc((size_t)set->nodeNr, sizeof(VALUE *));
369
- for(i = 0; i < set->nodeNr; i++) {
370
- if (XML_NAMESPACE_DECL == set->nodeTab[i]->type)
371
- elts[i] = Nokogiri_wrap_xml_namespace2(rb_iv_get(self, "@document"), (xmlNsPtr)(set->nodeTab[i]));
372
- else
373
- elts[i] = Nokogiri_wrap_xml_node(Qnil, set->nodeTab[i]);
403
+ list = rb_ary_new2(node_set->nodeNr);
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);
374
407
  }
375
408
 
376
- list = rb_ary_new4((long)set->nodeNr, elts);
377
-
378
- /*free(elts); */
379
-
380
409
  return list;
381
410
  }
382
411
 
@@ -386,20 +415,20 @@ static VALUE to_array(VALUE self, VALUE rb_node)
386
415
  *
387
416
  * Unlink this NodeSet and all Node objects it contains from their current context.
388
417
  */
389
- static VALUE unlink_nodeset(VALUE self)
418
+ static VALUE
419
+ unlink_nodeset(VALUE self)
390
420
  {
391
421
  xmlNodeSetPtr node_set;
392
422
  int j, nodeNr ;
393
- nokogiriNodeSetTuple *tuple;
394
423
 
395
- Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
396
- node_set = tuple->node_set;
424
+ Data_Get_Struct(self, xmlNodeSet, node_set);
425
+
397
426
  nodeNr = node_set->nodeNr ;
398
427
  for (j = 0 ; j < nodeNr ; j++) {
399
- if (XML_NAMESPACE_DECL != node_set->nodeTab[j]->type) {
428
+ if (! NOKOGIRI_NAMESPACE_EH(node_set->nodeTab[j])) {
400
429
  VALUE node ;
401
430
  xmlNodePtr node_ptr;
402
- node = Nokogiri_wrap_xml_node(Qnil, node_set->nodeTab[j]);
431
+ node = noko_xml_node_wrap(Qnil, node_set->nodeTab[j]);
403
432
  rb_funcall(node, rb_intern("unlink"), 0); /* modifies the C struct out from under the object */
404
433
  Data_Get_Struct(node, xmlNode, node_ptr);
405
434
  node_set->nodeTab[j] = node_ptr ;
@@ -408,60 +437,62 @@ static VALUE unlink_nodeset(VALUE self)
408
437
  return self ;
409
438
  }
410
439
 
411
- VALUE Nokogiri_wrap_xml_node_set(xmlNodeSetPtr node_set, VALUE document)
440
+
441
+ VALUE
442
+ noko_xml_node_set_wrap(xmlNodeSetPtr c_node_set, VALUE document)
412
443
  {
413
- VALUE new_set ;
414
- int i;
415
- xmlNodePtr cur;
416
- xmlNsPtr ns;
417
- nokogiriNodeSetTuple *tuple;
444
+ int j;
445
+ VALUE rb_node_set ;
418
446
 
419
- new_set = Data_Make_Struct(cNokogiriXmlNodeSet, nokogiriNodeSetTuple, 0,
420
- deallocate, tuple);
447
+ if (c_node_set == NULL) {
448
+ c_node_set = xmlXPathNodeSetCreate(NULL);
449
+ }
421
450
 
422
- tuple->node_set = node_set;
423
- tuple->namespaces = st_init_numtable();
451
+ rb_node_set = Data_Wrap_Struct(cNokogiriXmlNodeSet, mark, deallocate, c_node_set);
424
452
 
425
453
  if (!NIL_P(document)) {
426
- rb_iv_set(new_set, "@document", document);
427
- 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);
428
456
  }
429
457
 
430
- if (node_set && node_set->nodeTab) {
431
- for (i = 0; i < node_set->nodeNr; i++) {
432
- cur = node_set->nodeTab[i];
433
- if (cur && cur->type == XML_NAMESPACE_DECL) {
434
- ns = (xmlNsPtr)cur;
435
- if (ns->next && ns->next->type != XML_NAMESPACE_DECL)
436
- st_insert(tuple->namespaces, (st_data_t)cur, (st_data_t)0);
437
- }
438
- }
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);
439
461
  }
440
462
 
441
- return new_set ;
463
+ return rb_node_set ;
442
464
  }
443
465
 
444
- VALUE cNokogiriXmlNodeSet ;
445
- void init_xml_node_set(void)
466
+ VALUE
467
+ noko_xml_node_wrap_node_set_result(xmlNodePtr node, VALUE node_set)
468
+ {
469
+ if (NOKOGIRI_NAMESPACE_EH(node)) {
470
+ return noko_xml_namespace_wrap_xpath_copy((xmlNsPtr)node);
471
+ } else {
472
+ return noko_xml_node_wrap(Qnil, node);
473
+ }
474
+ }
475
+
476
+
477
+ void
478
+ noko_init_xml_node_set(void)
446
479
  {
447
- VALUE nokogiri = rb_define_module("Nokogiri");
448
- VALUE xml = rb_define_module_under(nokogiri, "XML");
449
- VALUE klass = rb_define_class_under(xml, "NodeSet", rb_cObject);
450
- cNokogiriXmlNodeSet = klass;
451
-
452
- rb_define_alloc_func(klass, allocate);
453
- rb_define_method(klass, "length", length, 0);
454
- rb_define_method(klass, "[]", slice, -1);
455
- rb_define_method(klass, "slice", slice, -1);
456
- rb_define_method(klass, "push", push, 1);
457
- rb_define_method(klass, "|", set_union, 1);
458
- rb_define_method(klass, "-", minus, 1);
459
- rb_define_method(klass, "unlink", unlink_nodeset, 0);
460
- rb_define_method(klass, "to_a", to_array, 0);
461
- rb_define_method(klass, "dup", duplicate, 0);
462
- rb_define_method(klass, "delete", delete, 1);
463
- rb_define_method(klass, "&", intersection, 1);
464
- 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);
465
496
 
466
497
  decorate = rb_intern("decorate");
467
498
  }