nokogiri 1.5.10 → 1.13.0

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 (334) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +5 -0
  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 +73 -0
  8. data/ext/nokogiri/depend +38 -358
  9. data/ext/nokogiri/extconf.rb +956 -100
  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 +232 -87
  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 +162 -168
  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 +327 -288
  94. data/lib/nokogiri/css/parser.y +67 -45
  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 +7 -6
  99. data/lib/nokogiri/css/xpath_visitor.rb +263 -75
  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 -90
  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 +259 -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 +18 -16
  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 +2511 -0
  171. data/patches/libxml2/0007-Fix-XPath-recursion-limit.patch +31 -0
  172. data/patches/libxml2/0008-htmlParseComment-handle-abruptly-closed-comments.patch +61 -0
  173. data/patches/libxml2/0009-allow-wildcard-namespaces.patch +77 -0
  174. data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2511 -0
  175. data/patches/libxslt/0002-Fix-xml2-config-check-in-configure-script.patch +19 -0
  176. data/ports/archives/libxml2-2.9.12.tar.gz +0 -0
  177. data/ports/archives/libxslt-1.1.34.tar.gz +0 -0
  178. metadata +382 -460
  179. data/.autotest +0 -26
  180. data/.gemtest +0 -0
  181. data/CHANGELOG.ja.rdoc +0 -785
  182. data/CHANGELOG.rdoc +0 -783
  183. data/C_CODING_STYLE.rdoc +0 -33
  184. data/Manifest.txt +0 -303
  185. data/README.ja.rdoc +0 -106
  186. data/README.rdoc +0 -175
  187. data/ROADMAP.md +0 -90
  188. data/Rakefile +0 -228
  189. data/STANDARD_RESPONSES.md +0 -47
  190. data/Y_U_NO_GEMSPEC.md +0 -155
  191. data/build_all +0 -105
  192. data/ext/nokogiri/html_document.c +0 -170
  193. data/ext/nokogiri/html_document.h +0 -10
  194. data/ext/nokogiri/html_element_description.c +0 -279
  195. data/ext/nokogiri/html_element_description.h +0 -10
  196. data/ext/nokogiri/html_entity_lookup.c +0 -32
  197. data/ext/nokogiri/html_entity_lookup.h +0 -8
  198. data/ext/nokogiri/html_sax_parser_context.c +0 -116
  199. data/ext/nokogiri/html_sax_parser_context.h +0 -11
  200. data/ext/nokogiri/html_sax_push_parser.c +0 -87
  201. data/ext/nokogiri/html_sax_push_parser.h +0 -9
  202. data/ext/nokogiri/xml_attr.h +0 -9
  203. data/ext/nokogiri/xml_attribute_decl.h +0 -9
  204. data/ext/nokogiri/xml_cdata.h +0 -9
  205. data/ext/nokogiri/xml_comment.h +0 -9
  206. data/ext/nokogiri/xml_document.h +0 -23
  207. data/ext/nokogiri/xml_document_fragment.h +0 -10
  208. data/ext/nokogiri/xml_dtd.h +0 -10
  209. data/ext/nokogiri/xml_element_content.h +0 -10
  210. data/ext/nokogiri/xml_element_decl.h +0 -9
  211. data/ext/nokogiri/xml_encoding_handler.h +0 -8
  212. data/ext/nokogiri/xml_entity_decl.h +0 -10
  213. data/ext/nokogiri/xml_entity_reference.h +0 -9
  214. data/ext/nokogiri/xml_io.c +0 -56
  215. data/ext/nokogiri/xml_io.h +0 -11
  216. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
  217. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  218. data/ext/nokogiri/xml_namespace.h +0 -13
  219. data/ext/nokogiri/xml_node.h +0 -13
  220. data/ext/nokogiri/xml_node_set.h +0 -14
  221. data/ext/nokogiri/xml_processing_instruction.h +0 -9
  222. data/ext/nokogiri/xml_reader.h +0 -10
  223. data/ext/nokogiri/xml_relax_ng.h +0 -9
  224. data/ext/nokogiri/xml_sax_parser.h +0 -39
  225. data/ext/nokogiri/xml_sax_parser_context.h +0 -10
  226. data/ext/nokogiri/xml_sax_push_parser.h +0 -9
  227. data/ext/nokogiri/xml_schema.h +0 -9
  228. data/ext/nokogiri/xml_syntax_error.h +0 -13
  229. data/ext/nokogiri/xml_text.h +0 -9
  230. data/ext/nokogiri/xml_xpath_context.h +0 -10
  231. data/ext/nokogiri/xslt_stylesheet.h +0 -14
  232. data/lib/nokogiri/html/document.rb +0 -254
  233. data/lib/nokogiri/html/document_fragment.rb +0 -41
  234. data/lib/nokogiri/html/element_description_defaults.rb +0 -671
  235. data/lib/nokogiri/html/sax/parser_context.rb +0 -16
  236. data/lib/nokogiri/html/sax/push_parser.rb +0 -16
  237. data/tasks/cross_compile.rb +0 -150
  238. data/tasks/nokogiri.org.rb +0 -24
  239. data/tasks/test.rb +0 -95
  240. data/test/css/test_nthiness.rb +0 -159
  241. data/test/css/test_parser.rb +0 -341
  242. data/test/css/test_tokenizer.rb +0 -198
  243. data/test/css/test_xpath_visitor.rb +0 -91
  244. data/test/decorators/test_slop.rb +0 -16
  245. data/test/files/2ch.html +0 -108
  246. data/test/files/address_book.rlx +0 -12
  247. data/test/files/address_book.xml +0 -10
  248. data/test/files/bar/bar.xsd +0 -4
  249. data/test/files/dont_hurt_em_why.xml +0 -422
  250. data/test/files/encoding.html +0 -82
  251. data/test/files/encoding.xhtml +0 -84
  252. data/test/files/exslt.xml +0 -8
  253. data/test/files/exslt.xslt +0 -35
  254. data/test/files/foo/foo.xsd +0 -4
  255. data/test/files/metacharset.html +0 -10
  256. data/test/files/noencoding.html +0 -47
  257. data/test/files/po.xml +0 -32
  258. data/test/files/po.xsd +0 -66
  259. data/test/files/shift_jis.html +0 -10
  260. data/test/files/shift_jis.xml +0 -5
  261. data/test/files/snuggles.xml +0 -3
  262. data/test/files/staff.dtd +0 -10
  263. data/test/files/staff.xml +0 -59
  264. data/test/files/staff.xslt +0 -32
  265. data/test/files/test_document_url/bar.xml +0 -2
  266. data/test/files/test_document_url/document.dtd +0 -4
  267. data/test/files/test_document_url/document.xml +0 -6
  268. data/test/files/tlm.html +0 -850
  269. data/test/files/to_be_xincluded.xml +0 -2
  270. data/test/files/valid_bar.xml +0 -2
  271. data/test/files/xinclude.xml +0 -4
  272. data/test/helper.rb +0 -154
  273. data/test/html/sax/test_parser.rb +0 -141
  274. data/test/html/sax/test_parser_context.rb +0 -46
  275. data/test/html/test_builder.rb +0 -164
  276. data/test/html/test_document.rb +0 -552
  277. data/test/html/test_document_encoding.rb +0 -138
  278. data/test/html/test_document_fragment.rb +0 -261
  279. data/test/html/test_element_description.rb +0 -105
  280. data/test/html/test_named_characters.rb +0 -14
  281. data/test/html/test_node.rb +0 -196
  282. data/test/html/test_node_encoding.rb +0 -27
  283. data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +0 -14
  284. data/test/namespaces/test_namespaces_in_builder_doc.rb +0 -75
  285. data/test/namespaces/test_namespaces_in_created_doc.rb +0 -75
  286. data/test/namespaces/test_namespaces_in_parsed_doc.rb +0 -66
  287. data/test/test_convert_xpath.rb +0 -135
  288. data/test/test_css_cache.rb +0 -45
  289. data/test/test_encoding_handler.rb +0 -46
  290. data/test/test_memory_leak.rb +0 -156
  291. data/test/test_nokogiri.rb +0 -132
  292. data/test/test_reader.rb +0 -555
  293. data/test/test_soap4r_sax.rb +0 -52
  294. data/test/test_xslt_transforms.rb +0 -254
  295. data/test/xml/node/test_save_options.rb +0 -28
  296. data/test/xml/node/test_subclass.rb +0 -44
  297. data/test/xml/sax/test_parser.rb +0 -366
  298. data/test/xml/sax/test_parser_context.rb +0 -106
  299. data/test/xml/sax/test_push_parser.rb +0 -157
  300. data/test/xml/test_attr.rb +0 -64
  301. data/test/xml/test_attribute_decl.rb +0 -86
  302. data/test/xml/test_builder.rb +0 -306
  303. data/test/xml/test_c14n.rb +0 -151
  304. data/test/xml/test_cdata.rb +0 -48
  305. data/test/xml/test_comment.rb +0 -29
  306. data/test/xml/test_document.rb +0 -828
  307. data/test/xml/test_document_encoding.rb +0 -28
  308. data/test/xml/test_document_fragment.rb +0 -223
  309. data/test/xml/test_dtd.rb +0 -103
  310. data/test/xml/test_dtd_encoding.rb +0 -33
  311. data/test/xml/test_element_content.rb +0 -56
  312. data/test/xml/test_element_decl.rb +0 -73
  313. data/test/xml/test_entity_decl.rb +0 -122
  314. data/test/xml/test_entity_reference.rb +0 -245
  315. data/test/xml/test_namespace.rb +0 -95
  316. data/test/xml/test_node.rb +0 -1137
  317. data/test/xml/test_node_attributes.rb +0 -96
  318. data/test/xml/test_node_encoding.rb +0 -107
  319. data/test/xml/test_node_inheritance.rb +0 -32
  320. data/test/xml/test_node_reparenting.rb +0 -374
  321. data/test/xml/test_node_set.rb +0 -755
  322. data/test/xml/test_parse_options.rb +0 -64
  323. data/test/xml/test_processing_instruction.rb +0 -30
  324. data/test/xml/test_reader_encoding.rb +0 -142
  325. data/test/xml/test_relax_ng.rb +0 -60
  326. data/test/xml/test_schema.rb +0 -103
  327. data/test/xml/test_syntax_error.rb +0 -12
  328. data/test/xml/test_text.rb +0 -45
  329. data/test/xml/test_unparented_node.rb +0 -422
  330. data/test/xml/test_xinclude.rb +0 -83
  331. data/test/xml/test_xpath.rb +0 -295
  332. data/test/xslt/test_custom_functions.rb +0 -133
  333. data/test/xslt/test_exception_handling.rb +0 -37
  334. data/test_all +0 -81
@@ -1,29 +1,127 @@
1
- #include <xml_xpath_context.h>
1
+ #include <nokogiri.h>
2
2
 
3
- int vasprintf (char **strp, const char *fmt, va_list ap);
3
+ VALUE cNokogiriXmlXpathContext;
4
+
5
+ /*
6
+ * these constants have matching declarations in
7
+ * ext/java/nokogiri/internals/NokogiriNamespaceContext.java
8
+ */
9
+ static const xmlChar *NOKOGIRI_BUILTIN_PREFIX = (const xmlChar *)"nokogiri-builtin";
10
+ static const xmlChar *NOKOGIRI_BUILTIN_URI = (const xmlChar *)"https://www.nokogiri.org/default_ns/ruby/builtins";
4
11
 
5
- static void deallocate(xmlXPathContextPtr ctx)
12
+ static void
13
+ deallocate(xmlXPathContextPtr ctx)
6
14
  {
7
15
  NOKOGIRI_DEBUG_START(ctx);
8
16
  xmlXPathFreeContext(ctx);
9
17
  NOKOGIRI_DEBUG_END(ctx);
10
18
  }
11
19
 
20
+ /* find a CSS class in an HTML element's `class` attribute */
21
+ static const xmlChar *
22
+ builtin_css_class(const xmlChar *str, const xmlChar *val)
23
+ {
24
+ int val_len;
25
+
26
+ if (str == NULL) { return (NULL); }
27
+ if (val == NULL) { return (NULL); }
28
+
29
+ val_len = xmlStrlen(val);
30
+ if (val_len == 0) { return (str); }
31
+
32
+ while (*str != 0) {
33
+ if ((*str == *val) && !xmlStrncmp(str, val, val_len)) {
34
+ const xmlChar *next_byte = str + val_len;
35
+
36
+ /* only match if the next byte is whitespace or end of string */
37
+ if ((*next_byte == 0) || (IS_BLANK_CH(*next_byte))) {
38
+ return ((const xmlChar *)str);
39
+ }
40
+ }
41
+
42
+ /* advance str to whitespace */
43
+ while ((*str != 0) && !IS_BLANK_CH(*str)) {
44
+ str++;
45
+ }
46
+
47
+ /* advance str to start of next word or end of string */
48
+ while ((*str != 0) && IS_BLANK_CH(*str)) {
49
+ str++;
50
+ }
51
+ }
52
+
53
+ return (NULL);
54
+ }
55
+
56
+ /* xmlXPathFunction to wrap builtin_css_class() */
57
+ static void
58
+ xpath_builtin_css_class(xmlXPathParserContextPtr ctxt, int nargs)
59
+ {
60
+ xmlXPathObjectPtr hay, needle;
61
+
62
+ CHECK_ARITY(2);
63
+
64
+ CAST_TO_STRING;
65
+ needle = valuePop(ctxt);
66
+ if ((needle == NULL) || (needle->type != XPATH_STRING)) {
67
+ xmlXPathFreeObject(needle);
68
+ XP_ERROR(XPATH_INVALID_TYPE);
69
+ }
70
+
71
+ CAST_TO_STRING;
72
+ hay = valuePop(ctxt);
73
+ if ((hay == NULL) || (hay->type != XPATH_STRING)) {
74
+ xmlXPathFreeObject(hay);
75
+ xmlXPathFreeObject(needle);
76
+ XP_ERROR(XPATH_INVALID_TYPE);
77
+ }
78
+
79
+ if (builtin_css_class(hay->stringval, needle->stringval)) {
80
+ valuePush(ctxt, xmlXPathNewBoolean(1));
81
+ } else {
82
+ valuePush(ctxt, xmlXPathNewBoolean(0));
83
+ }
84
+
85
+ xmlXPathFreeObject(hay);
86
+ xmlXPathFreeObject(needle);
87
+ }
88
+
89
+
90
+ /* xmlXPathFunction to select nodes whose local name matches, for HTML5 CSS queries that should ignore namespaces */
91
+ static void
92
+ xpath_builtin_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
93
+ {
94
+ xmlXPathObjectPtr element_name;
95
+
96
+ assert(ctxt->context->node);
97
+
98
+ CHECK_ARITY(1);
99
+ CAST_TO_STRING;
100
+ CHECK_TYPE(XPATH_STRING);
101
+ element_name = valuePop(ctxt);
102
+
103
+ valuePush(ctxt, xmlXPathNewBoolean(xmlStrEqual(ctxt->context->node->name, element_name->stringval)));
104
+
105
+ xmlXPathFreeObject(element_name);
106
+ }
107
+
108
+
12
109
  /*
13
110
  * call-seq:
14
111
  * register_ns(prefix, uri)
15
112
  *
16
113
  * Register the namespace with +prefix+ and +uri+.
17
114
  */
18
- static VALUE register_ns(VALUE self, VALUE prefix, VALUE uri)
115
+ static VALUE
116
+ register_ns(VALUE self, VALUE prefix, VALUE uri)
19
117
  {
20
118
  xmlXPathContextPtr ctx;
21
119
  Data_Get_Struct(self, xmlXPathContext, ctx);
22
120
 
23
- xmlXPathRegisterNs( ctx,
24
- (const xmlChar *)StringValuePtr(prefix),
25
- (const xmlChar *)StringValuePtr(uri)
26
- );
121
+ xmlXPathRegisterNs(ctx,
122
+ (const xmlChar *)StringValueCStr(prefix),
123
+ (const xmlChar *)StringValueCStr(uri)
124
+ );
27
125
  return self;
28
126
  }
29
127
 
@@ -33,74 +131,94 @@ static VALUE register_ns(VALUE self, VALUE prefix, VALUE uri)
33
131
  *
34
132
  * Register the variable +name+ with +value+.
35
133
  */
36
- static VALUE register_variable(VALUE self, VALUE name, VALUE value)
134
+ static VALUE
135
+ register_variable(VALUE self, VALUE name, VALUE value)
37
136
  {
38
- xmlXPathContextPtr ctx;
39
- xmlXPathObjectPtr xmlValue;
40
- Data_Get_Struct(self, xmlXPathContext, ctx);
137
+ xmlXPathContextPtr ctx;
138
+ xmlXPathObjectPtr xmlValue;
139
+ Data_Get_Struct(self, xmlXPathContext, ctx);
41
140
 
42
- xmlValue = xmlXPathNewCString(StringValuePtr(value));
141
+ xmlValue = xmlXPathNewCString(StringValueCStr(value));
43
142
 
44
- xmlXPathRegisterVariable( ctx,
45
- (const xmlChar *)StringValuePtr(name),
46
- xmlValue
47
- );
143
+ xmlXPathRegisterVariable(ctx,
144
+ (const xmlChar *)StringValueCStr(name),
145
+ xmlValue
146
+ );
48
147
 
49
- return self;
148
+ return self;
50
149
  }
51
150
 
52
- void Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr ctx, int nargs, VALUE handler, const char* function_name)
151
+
152
+ /*
153
+ * convert an XPath object into a Ruby object of the appropriate type.
154
+ * returns Qundef if no conversion was possible.
155
+ */
156
+ static VALUE
157
+ xpath2ruby(xmlXPathObjectPtr xobj, xmlXPathContextPtr xctx)
158
+ {
159
+ VALUE retval;
160
+
161
+ assert(xctx->doc);
162
+ assert(DOC_RUBY_OBJECT_TEST(xctx->doc));
163
+
164
+ switch (xobj->type) {
165
+ case XPATH_STRING:
166
+ retval = NOKOGIRI_STR_NEW2(xobj->stringval);
167
+ xmlFree(xobj->stringval);
168
+ return retval;
169
+
170
+ case XPATH_NODESET:
171
+ return noko_xml_node_set_wrap(xobj->nodesetval,
172
+ DOC_RUBY_OBJECT(xctx->doc));
173
+
174
+ case XPATH_NUMBER:
175
+ return rb_float_new(xobj->floatval);
176
+
177
+ case XPATH_BOOLEAN:
178
+ return (xobj->boolval == 1) ? Qtrue : Qfalse;
179
+
180
+ default:
181
+ return Qundef;
182
+ }
183
+ }
184
+
185
+ void
186
+ Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr ctx, int nargs, VALUE handler,
187
+ const char *function_name)
53
188
  {
54
- int i;
55
189
  VALUE result, doc;
56
190
  VALUE *argv;
57
191
  VALUE node_set = Qnil;
58
192
  xmlNodeSetPtr xml_node_set = NULL;
59
193
  xmlXPathObjectPtr obj;
60
- nokogiriNodeSetTuple *node_set_tuple;
61
194
 
62
195
  assert(ctx->context->doc);
63
196
  assert(DOC_RUBY_OBJECT_TEST(ctx->context->doc));
64
197
 
65
198
  argv = (VALUE *)calloc((size_t)nargs, sizeof(VALUE));
66
- for (i = 0 ; i < nargs ; ++i) {
67
- rb_gc_register_address(&argv[i]);
199
+ for (int j = 0 ; j < nargs ; ++j) {
200
+ rb_gc_register_address(&argv[j]);
68
201
  }
69
202
 
70
203
  doc = DOC_RUBY_OBJECT(ctx->context->doc);
71
204
 
72
- if (nargs > 0) {
73
- i = nargs - 1;
74
- do {
75
- obj = valuePop(ctx);
76
- switch(obj->type) {
77
- case XPATH_STRING:
78
- argv[i] = NOKOGIRI_STR_NEW2(obj->stringval);
79
- break;
80
- case XPATH_BOOLEAN:
81
- argv[i] = obj->boolval == 1 ? Qtrue : Qfalse;
82
- break;
83
- case XPATH_NUMBER:
84
- argv[i] = rb_float_new(obj->floatval);
85
- break;
86
- case XPATH_NODESET:
87
- argv[i] = Nokogiri_wrap_xml_node_set(obj->nodesetval, doc);
88
- break;
89
- default:
90
- argv[i] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(obj));
91
- }
92
- xmlXPathFreeNodeSetList(obj);
93
- } while(i-- > 0);
205
+ for (int j = nargs - 1 ; j >= 0 ; --j) {
206
+ obj = valuePop(ctx);
207
+ argv[j] = xpath2ruby(obj, ctx->context);
208
+ if (argv[j] == Qundef) {
209
+ argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(obj));
210
+ }
211
+ xmlXPathFreeNodeSetList(obj);
94
212
  }
95
213
 
96
- result = rb_funcall2(handler, rb_intern((const char*)function_name), nargs, argv);
214
+ result = rb_funcall2(handler, rb_intern((const char *)function_name), nargs, argv);
97
215
 
98
- for (i = 0 ; i < nargs ; ++i) {
99
- rb_gc_unregister_address(&argv[i]);
216
+ for (int j = 0 ; j < nargs ; ++j) {
217
+ rb_gc_unregister_address(&argv[j]);
100
218
  }
101
219
  free(argv);
102
220
 
103
- switch(TYPE(result)) {
221
+ switch (TYPE(result)) {
104
222
  case T_FLOAT:
105
223
  case T_BIGNUM:
106
224
  case T_FIXNUM:
@@ -108,8 +226,8 @@ void Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr c
108
226
  break;
109
227
  case T_STRING:
110
228
  xmlXPathReturnString(
111
- ctx,
112
- xmlCharStrdup(StringValuePtr(result))
229
+ ctx,
230
+ xmlCharStrdup(StringValueCStr(result))
113
231
  );
114
232
  break;
115
233
  case T_TRUE:
@@ -120,21 +238,18 @@ void Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr c
120
238
  break;
121
239
  case T_NIL:
122
240
  break;
123
- case T_ARRAY:
124
- {
125
- VALUE args[2];
126
- args[0] = doc;
127
- args[1] = result;
128
- node_set = rb_class_new_instance(2, args, cNokogiriXmlNodeSet);
129
- Data_Get_Struct(node_set, nokogiriNodeSetTuple, node_set_tuple);
130
- xml_node_set = node_set_tuple->node_set;
131
- xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
132
- }
133
- break;
241
+ case T_ARRAY: {
242
+ VALUE args[2];
243
+ args[0] = doc;
244
+ args[1] = result;
245
+ node_set = rb_class_new_instance(2, args, cNokogiriXmlNodeSet);
246
+ Data_Get_Struct(node_set, xmlNodeSet, xml_node_set);
247
+ xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
248
+ }
249
+ break;
134
250
  case T_DATA:
135
- if(rb_obj_is_kind_of(result, cNokogiriXmlNodeSet)) {
136
- Data_Get_Struct(result, nokogiriNodeSetTuple, node_set_tuple);
137
- xml_node_set = node_set_tuple->node_set;
251
+ if (rb_obj_is_kind_of(result, cNokogiriXmlNodeSet)) {
252
+ Data_Get_Struct(result, xmlNodeSet, xml_node_set);
138
253
  /* Copy the node set, otherwise it will get GC'd. */
139
254
  xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
140
255
  break;
@@ -144,7 +259,8 @@ void Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr c
144
259
  }
145
260
  }
146
261
 
147
- static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
262
+ static void
263
+ ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
148
264
  {
149
265
  VALUE handler = Qnil;
150
266
  const char *function = NULL ;
@@ -155,35 +271,29 @@ static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
155
271
  assert(ctx->context->function);
156
272
 
157
273
  handler = (VALUE)(ctx->context->userData);
158
- function = (const char*)(ctx->context->function);
274
+ function = (const char *)(ctx->context->function);
159
275
 
160
276
  Nokogiri_marshal_xpath_funcall_and_return_values(ctx, nargs, handler, function);
161
277
  }
162
278
 
163
- static xmlXPathFunction lookup( void *ctx,
164
- const xmlChar * name,
165
- const xmlChar* ns_uri )
279
+ static xmlXPathFunction
280
+ lookup(void *ctx,
281
+ const xmlChar *name,
282
+ const xmlChar *ns_uri)
166
283
  {
167
284
  VALUE xpath_handler = (VALUE)ctx;
168
- if(rb_respond_to(xpath_handler, rb_intern((const char *)name)))
285
+ if (rb_respond_to(xpath_handler, rb_intern((const char *)name))) {
169
286
  return ruby_funcall;
287
+ }
170
288
 
171
289
  return NULL;
172
290
  }
173
291
 
174
- NORETURN(static void xpath_exception_handler(void * ctx, xmlErrorPtr error));
175
- static void xpath_exception_handler(void * ctx, xmlErrorPtr error)
292
+ NORETURN(static void xpath_generic_exception_handler(void *ctx, const char *msg, ...));
293
+ static void
294
+ xpath_generic_exception_handler(void *ctx, const char *msg, ...)
176
295
  {
177
- VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
178
- VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));
179
-
180
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error(klass, error));
181
- }
182
-
183
- NORETURN(static void xpath_generic_exception_handler(void * ctx, const char *msg, ...));
184
- static void xpath_generic_exception_handler(void * ctx, const char *msg, ...)
185
- {
186
- char * message;
296
+ char *message;
187
297
 
188
298
  va_list args;
189
299
  va_start(args, msg);
@@ -199,29 +309,31 @@ static void xpath_generic_exception_handler(void * ctx, const char *msg, ...)
199
309
  *
200
310
  * Evaluate the +search_path+ returning an XML::XPath object.
201
311
  */
202
- static VALUE evaluate(int argc, VALUE *argv, VALUE self)
312
+ static VALUE
313
+ evaluate(int argc, VALUE *argv, VALUE self)
203
314
  {
204
315
  VALUE search_path, xpath_handler;
205
- VALUE thing = Qnil;
316
+ VALUE retval = Qnil;
206
317
  xmlXPathContextPtr ctx;
207
318
  xmlXPathObjectPtr xpath;
208
319
  xmlChar *query;
209
320
 
210
321
  Data_Get_Struct(self, xmlXPathContext, ctx);
211
322
 
212
- if(rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1)
323
+ if (rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1) {
213
324
  xpath_handler = Qnil;
325
+ }
214
326
 
215
- query = (xmlChar *)StringValuePtr(search_path);
327
+ query = (xmlChar *)StringValueCStr(search_path);
216
328
 
217
- if(Qnil != xpath_handler) {
329
+ if (Qnil != xpath_handler) {
218
330
  /* FIXME: not sure if this is the correct place to shove private data. */
219
331
  ctx->userData = (void *)xpath_handler;
220
332
  xmlXPathRegisterFuncLookup(ctx, lookup, (void *)xpath_handler);
221
333
  }
222
334
 
223
335
  xmlResetLastError();
224
- xmlSetStructuredErrorFunc(NULL, xpath_exception_handler);
336
+ xmlSetStructuredErrorFunc(NULL, Nokogiri_error_raise);
225
337
 
226
338
  /* For some reason, xmlXPathEvalExpression will blow up with a generic error */
227
339
  /* when there is a non existent function. */
@@ -231,45 +343,19 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
231
343
  xmlSetStructuredErrorFunc(NULL, NULL);
232
344
  xmlSetGenericErrorFunc(NULL, NULL);
233
345
 
234
- if(xpath == NULL) {
235
- VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
236
- VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));
237
-
346
+ if (xpath == NULL) {
238
347
  xmlErrorPtr error = xmlGetLastError();
239
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error(klass, error));
348
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
240
349
  }
241
350
 
242
- assert(ctx->doc);
243
- assert(DOC_RUBY_OBJECT_TEST(ctx->doc));
244
-
245
- switch(xpath->type) {
246
- case XPATH_STRING:
247
- thing = NOKOGIRI_STR_NEW2(xpath->stringval);
248
- xmlFree(xpath->stringval);
249
- break;
250
- case XPATH_NODESET:
251
- if(NULL == xpath->nodesetval) {
252
- thing = Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL),
253
- DOC_RUBY_OBJECT(ctx->doc));
254
- } else {
255
- thing = Nokogiri_wrap_xml_node_set(xpath->nodesetval,
256
- DOC_RUBY_OBJECT(ctx->doc));
257
- }
258
- break;
259
- case XPATH_NUMBER:
260
- thing = rb_float_new(xpath->floatval);
261
- break;
262
- case XPATH_BOOLEAN:
263
- thing = xpath->boolval == 1 ? Qtrue : Qfalse;
264
- break;
265
- default:
266
- thing = Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL),
267
- DOC_RUBY_OBJECT(ctx->doc));
351
+ retval = xpath2ruby(xpath, ctx);
352
+ if (retval == Qundef) {
353
+ retval = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(ctx->doc));
268
354
  }
269
355
 
270
356
  xmlXPathFreeNodeSetList(xpath);
271
357
 
272
- return thing;
358
+ return retval;
273
359
  }
274
360
 
275
361
  /*
@@ -278,42 +364,43 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
278
364
  *
279
365
  * Create a new XPathContext with +node+ as the reference point.
280
366
  */
281
- static VALUE new(VALUE klass, VALUE nodeobj)
367
+ static VALUE
368
+ new (VALUE klass, VALUE nodeobj)
282
369
  {
283
370
  xmlNodePtr node;
284
371
  xmlXPathContextPtr ctx;
285
372
  VALUE self;
286
373
 
287
- xmlXPathInit();
288
-
289
374
  Data_Get_Struct(nodeobj, xmlNode, node);
290
375
 
376
+ xmlXPathInit();
377
+
291
378
  ctx = xmlXPathNewContext(node->doc);
292
379
  ctx->node = node;
380
+
381
+ xmlXPathRegisterNs(ctx, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
382
+ xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"css-class", NOKOGIRI_BUILTIN_URI,
383
+ xpath_builtin_css_class);
384
+ xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"local-name-is", NOKOGIRI_BUILTIN_URI,
385
+ xpath_builtin_local_name_is);
386
+
293
387
  self = Data_Wrap_Struct(klass, 0, deallocate, ctx);
294
- /*rb_iv_set(self, "@xpath_handler", Qnil); */
295
388
  return self;
296
389
  }
297
390
 
298
- VALUE cNokogiriXmlXpathContext;
299
- void init_xml_xpath_context(void)
391
+ void
392
+ noko_init_xml_xpath_context(void)
300
393
  {
301
- VALUE module = rb_define_module("Nokogiri");
302
-
303
- /*
304
- * Nokogiri::XML
305
- */
306
- VALUE xml = rb_define_module_under(module, "XML");
307
-
308
394
  /*
309
395
  * XPathContext is the entry point for searching a Document by using XPath.
310
396
  */
311
- VALUE klass = rb_define_class_under(xml, "XPathContext", rb_cObject);
397
+ cNokogiriXmlXpathContext = rb_define_class_under(mNokogiriXml, "XPathContext", rb_cObject);
398
+
399
+ rb_undef_alloc_func(cNokogiriXmlXpathContext);
312
400
 
313
- cNokogiriXmlXpathContext = klass;
401
+ rb_define_singleton_method(cNokogiriXmlXpathContext, "new", new, 1);
314
402
 
315
- rb_define_singleton_method(klass, "new", new, 1);
316
- rb_define_method(klass, "evaluate", evaluate, -1);
317
- rb_define_method(klass, "register_variable", register_variable, 2);
318
- rb_define_method(klass, "register_ns", register_ns, 2);
403
+ rb_define_method(cNokogiriXmlXpathContext, "evaluate", evaluate, -1);
404
+ rb_define_method(cNokogiriXmlXpathContext, "register_variable", register_variable, 2);
405
+ rb_define_method(cNokogiriXmlXpathContext, "register_ns", register_ns, 2);
319
406
  }