nokogiri-backport 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (239) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE-DEPENDENCIES.md +1682 -0
  4. data/LICENSE.md +9 -0
  5. data/README.md +272 -0
  6. data/bin/nokogiri +118 -0
  7. data/dependencies.yml +74 -0
  8. data/ext/java/nokogiri/EncodingHandler.java +124 -0
  9. data/ext/java/nokogiri/HtmlDocument.java +178 -0
  10. data/ext/java/nokogiri/HtmlElementDescription.java +148 -0
  11. data/ext/java/nokogiri/HtmlEntityLookup.java +79 -0
  12. data/ext/java/nokogiri/HtmlSaxParserContext.java +282 -0
  13. data/ext/java/nokogiri/HtmlSaxPushParser.java +222 -0
  14. data/ext/java/nokogiri/NokogiriService.java +597 -0
  15. data/ext/java/nokogiri/XmlAttr.java +162 -0
  16. data/ext/java/nokogiri/XmlAttributeDecl.java +129 -0
  17. data/ext/java/nokogiri/XmlCdata.java +82 -0
  18. data/ext/java/nokogiri/XmlComment.java +97 -0
  19. data/ext/java/nokogiri/XmlDocument.java +633 -0
  20. data/ext/java/nokogiri/XmlDocumentFragment.java +185 -0
  21. data/ext/java/nokogiri/XmlDtd.java +481 -0
  22. data/ext/java/nokogiri/XmlElement.java +68 -0
  23. data/ext/java/nokogiri/XmlElementContent.java +382 -0
  24. data/ext/java/nokogiri/XmlElementDecl.java +147 -0
  25. data/ext/java/nokogiri/XmlEntityDecl.java +157 -0
  26. data/ext/java/nokogiri/XmlEntityReference.java +101 -0
  27. data/ext/java/nokogiri/XmlNamespace.java +199 -0
  28. data/ext/java/nokogiri/XmlNode.java +1684 -0
  29. data/ext/java/nokogiri/XmlNodeSet.java +434 -0
  30. data/ext/java/nokogiri/XmlProcessingInstruction.java +100 -0
  31. data/ext/java/nokogiri/XmlReader.java +531 -0
  32. data/ext/java/nokogiri/XmlRelaxng.java +151 -0
  33. data/ext/java/nokogiri/XmlSaxParserContext.java +374 -0
  34. data/ext/java/nokogiri/XmlSaxPushParser.java +286 -0
  35. data/ext/java/nokogiri/XmlSchema.java +388 -0
  36. data/ext/java/nokogiri/XmlSyntaxError.java +138 -0
  37. data/ext/java/nokogiri/XmlText.java +110 -0
  38. data/ext/java/nokogiri/XmlXpathContext.java +301 -0
  39. data/ext/java/nokogiri/XsltStylesheet.java +347 -0
  40. data/ext/java/nokogiri/internals/ClosedStreamException.java +10 -0
  41. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +252 -0
  42. data/ext/java/nokogiri/internals/IgnoreSchemaErrorsErrorHandler.java +20 -0
  43. data/ext/java/nokogiri/internals/NokogiriBlockingQueueInputStream.java +151 -0
  44. data/ext/java/nokogiri/internals/NokogiriDomParser.java +116 -0
  45. data/ext/java/nokogiri/internals/NokogiriEntityResolver.java +121 -0
  46. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +69 -0
  47. data/ext/java/nokogiri/internals/NokogiriHandler.java +327 -0
  48. data/ext/java/nokogiri/internals/NokogiriHelpers.java +734 -0
  49. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +217 -0
  50. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +127 -0
  51. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +100 -0
  52. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +121 -0
  53. data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +78 -0
  54. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +180 -0
  55. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +72 -0
  56. data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +60 -0
  57. data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +87 -0
  58. data/ext/java/nokogiri/internals/ParserContext.java +259 -0
  59. data/ext/java/nokogiri/internals/ReaderNode.java +488 -0
  60. data/ext/java/nokogiri/internals/SaveContextVisitor.java +778 -0
  61. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +73 -0
  62. data/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +168 -0
  63. data/ext/java/nokogiri/internals/XmlDeclHandler.java +42 -0
  64. data/ext/java/nokogiri/internals/XmlDomParserContext.java +274 -0
  65. data/ext/java/nokogiri/internals/XmlSaxParser.java +65 -0
  66. data/ext/java/nokogiri/internals/c14n/AttrCompare.java +119 -0
  67. data/ext/java/nokogiri/internals/c14n/C14nHelper.java +159 -0
  68. data/ext/java/nokogiri/internals/c14n/CanonicalFilter.java +37 -0
  69. data/ext/java/nokogiri/internals/c14n/CanonicalizationException.java +93 -0
  70. data/ext/java/nokogiri/internals/c14n/Canonicalizer.java +252 -0
  71. data/ext/java/nokogiri/internals/c14n/Canonicalizer11.java +639 -0
  72. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_OmitComments.java +38 -0
  73. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_WithComments.java +38 -0
  74. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java +367 -0
  75. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java +295 -0
  76. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclOmitComments.java +40 -0
  77. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclWithComments.java +44 -0
  78. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315OmitComments.java +44 -0
  79. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315WithComments.java +43 -0
  80. data/ext/java/nokogiri/internals/c14n/CanonicalizerBase.java +630 -0
  81. data/ext/java/nokogiri/internals/c14n/CanonicalizerPhysical.java +173 -0
  82. data/ext/java/nokogiri/internals/c14n/CanonicalizerSpi.java +76 -0
  83. data/ext/java/nokogiri/internals/c14n/Constants.java +42 -0
  84. data/ext/java/nokogiri/internals/c14n/ElementProxy.java +293 -0
  85. data/ext/java/nokogiri/internals/c14n/HelperNodeList.java +93 -0
  86. data/ext/java/nokogiri/internals/c14n/IgnoreAllErrorHandler.java +79 -0
  87. data/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +166 -0
  88. data/ext/java/nokogiri/internals/c14n/InvalidCanonicalizerException.java +76 -0
  89. data/ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java +402 -0
  90. data/ext/java/nokogiri/internals/c14n/NodeFilter.java +51 -0
  91. data/ext/java/nokogiri/internals/c14n/UtfHelpper.java +179 -0
  92. data/ext/java/nokogiri/internals/c14n/XMLUtils.java +507 -0
  93. data/ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java +1745 -0
  94. data/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java +685 -0
  95. data/ext/nokogiri/depend +477 -0
  96. data/ext/nokogiri/extconf.rb +836 -0
  97. data/ext/nokogiri/html_document.c +171 -0
  98. data/ext/nokogiri/html_document.h +10 -0
  99. data/ext/nokogiri/html_element_description.c +279 -0
  100. data/ext/nokogiri/html_element_description.h +10 -0
  101. data/ext/nokogiri/html_entity_lookup.c +32 -0
  102. data/ext/nokogiri/html_entity_lookup.h +8 -0
  103. data/ext/nokogiri/html_sax_parser_context.c +116 -0
  104. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  105. data/ext/nokogiri/html_sax_push_parser.c +87 -0
  106. data/ext/nokogiri/html_sax_push_parser.h +9 -0
  107. data/ext/nokogiri/nokogiri.c +135 -0
  108. data/ext/nokogiri/nokogiri.h +130 -0
  109. data/ext/nokogiri/xml_attr.c +103 -0
  110. data/ext/nokogiri/xml_attr.h +9 -0
  111. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  112. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  113. data/ext/nokogiri/xml_cdata.c +62 -0
  114. data/ext/nokogiri/xml_cdata.h +9 -0
  115. data/ext/nokogiri/xml_comment.c +69 -0
  116. data/ext/nokogiri/xml_comment.h +9 -0
  117. data/ext/nokogiri/xml_document.c +622 -0
  118. data/ext/nokogiri/xml_document.h +23 -0
  119. data/ext/nokogiri/xml_document_fragment.c +48 -0
  120. data/ext/nokogiri/xml_document_fragment.h +10 -0
  121. data/ext/nokogiri/xml_dtd.c +202 -0
  122. data/ext/nokogiri/xml_dtd.h +10 -0
  123. data/ext/nokogiri/xml_element_content.c +123 -0
  124. data/ext/nokogiri/xml_element_content.h +10 -0
  125. data/ext/nokogiri/xml_element_decl.c +69 -0
  126. data/ext/nokogiri/xml_element_decl.h +9 -0
  127. data/ext/nokogiri/xml_encoding_handler.c +79 -0
  128. data/ext/nokogiri/xml_encoding_handler.h +8 -0
  129. data/ext/nokogiri/xml_entity_decl.c +110 -0
  130. data/ext/nokogiri/xml_entity_decl.h +10 -0
  131. data/ext/nokogiri/xml_entity_reference.c +52 -0
  132. data/ext/nokogiri/xml_entity_reference.h +9 -0
  133. data/ext/nokogiri/xml_io.c +63 -0
  134. data/ext/nokogiri/xml_io.h +11 -0
  135. data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
  136. data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
  137. data/ext/nokogiri/xml_namespace.c +111 -0
  138. data/ext/nokogiri/xml_namespace.h +14 -0
  139. data/ext/nokogiri/xml_node.c +1773 -0
  140. data/ext/nokogiri/xml_node.h +13 -0
  141. data/ext/nokogiri/xml_node_set.c +486 -0
  142. data/ext/nokogiri/xml_node_set.h +12 -0
  143. data/ext/nokogiri/xml_processing_instruction.c +56 -0
  144. data/ext/nokogiri/xml_processing_instruction.h +9 -0
  145. data/ext/nokogiri/xml_reader.c +657 -0
  146. data/ext/nokogiri/xml_reader.h +10 -0
  147. data/ext/nokogiri/xml_relax_ng.c +179 -0
  148. data/ext/nokogiri/xml_relax_ng.h +9 -0
  149. data/ext/nokogiri/xml_sax_parser.c +305 -0
  150. data/ext/nokogiri/xml_sax_parser.h +39 -0
  151. data/ext/nokogiri/xml_sax_parser_context.c +262 -0
  152. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  153. data/ext/nokogiri/xml_sax_push_parser.c +159 -0
  154. data/ext/nokogiri/xml_sax_push_parser.h +9 -0
  155. data/ext/nokogiri/xml_schema.c +276 -0
  156. data/ext/nokogiri/xml_schema.h +9 -0
  157. data/ext/nokogiri/xml_syntax_error.c +64 -0
  158. data/ext/nokogiri/xml_syntax_error.h +13 -0
  159. data/ext/nokogiri/xml_text.c +52 -0
  160. data/ext/nokogiri/xml_text.h +9 -0
  161. data/ext/nokogiri/xml_xpath_context.c +374 -0
  162. data/ext/nokogiri/xml_xpath_context.h +10 -0
  163. data/ext/nokogiri/xslt_stylesheet.c +263 -0
  164. data/ext/nokogiri/xslt_stylesheet.h +14 -0
  165. data/lib/isorelax.jar +0 -0
  166. data/lib/jing.jar +0 -0
  167. data/lib/nekodtd.jar +0 -0
  168. data/lib/nekohtml.jar +0 -0
  169. data/lib/nokogiri/css/node.rb +53 -0
  170. data/lib/nokogiri/css/parser.rb +751 -0
  171. data/lib/nokogiri/css/parser.y +272 -0
  172. data/lib/nokogiri/css/parser_extras.rb +94 -0
  173. data/lib/nokogiri/css/syntax_error.rb +8 -0
  174. data/lib/nokogiri/css/tokenizer.rb +154 -0
  175. data/lib/nokogiri/css/tokenizer.rex +55 -0
  176. data/lib/nokogiri/css/xpath_visitor.rb +260 -0
  177. data/lib/nokogiri/css.rb +28 -0
  178. data/lib/nokogiri/decorators/slop.rb +43 -0
  179. data/lib/nokogiri/html/builder.rb +36 -0
  180. data/lib/nokogiri/html/document.rb +322 -0
  181. data/lib/nokogiri/html/document_fragment.rb +50 -0
  182. data/lib/nokogiri/html/element_description.rb +24 -0
  183. data/lib/nokogiri/html/element_description_defaults.rb +672 -0
  184. data/lib/nokogiri/html/entity_lookup.rb +14 -0
  185. data/lib/nokogiri/html/sax/parser.rb +63 -0
  186. data/lib/nokogiri/html/sax/parser_context.rb +17 -0
  187. data/lib/nokogiri/html/sax/push_parser.rb +37 -0
  188. data/lib/nokogiri/html.rb +38 -0
  189. data/lib/nokogiri/jruby/dependencies.rb +20 -0
  190. data/lib/nokogiri/syntax_error.rb +5 -0
  191. data/lib/nokogiri/version/constant.rb +5 -0
  192. data/lib/nokogiri/version/info.rb +182 -0
  193. data/lib/nokogiri/version.rb +3 -0
  194. data/lib/nokogiri/xml/attr.rb +15 -0
  195. data/lib/nokogiri/xml/attribute_decl.rb +19 -0
  196. data/lib/nokogiri/xml/builder.rb +447 -0
  197. data/lib/nokogiri/xml/cdata.rb +12 -0
  198. data/lib/nokogiri/xml/character_data.rb +8 -0
  199. data/lib/nokogiri/xml/document.rb +290 -0
  200. data/lib/nokogiri/xml/document_fragment.rb +159 -0
  201. data/lib/nokogiri/xml/dtd.rb +33 -0
  202. data/lib/nokogiri/xml/element_content.rb +37 -0
  203. data/lib/nokogiri/xml/element_decl.rb +14 -0
  204. data/lib/nokogiri/xml/entity_decl.rb +20 -0
  205. data/lib/nokogiri/xml/entity_reference.rb +19 -0
  206. data/lib/nokogiri/xml/namespace.rb +14 -0
  207. data/lib/nokogiri/xml/node/save_options.rb +62 -0
  208. data/lib/nokogiri/xml/node.rb +1240 -0
  209. data/lib/nokogiri/xml/node_set.rb +372 -0
  210. data/lib/nokogiri/xml/notation.rb +7 -0
  211. data/lib/nokogiri/xml/parse_options.rb +127 -0
  212. data/lib/nokogiri/xml/pp/character_data.rb +19 -0
  213. data/lib/nokogiri/xml/pp/node.rb +57 -0
  214. data/lib/nokogiri/xml/pp.rb +3 -0
  215. data/lib/nokogiri/xml/processing_instruction.rb +9 -0
  216. data/lib/nokogiri/xml/reader.rb +116 -0
  217. data/lib/nokogiri/xml/relax_ng.rb +37 -0
  218. data/lib/nokogiri/xml/sax/document.rb +172 -0
  219. data/lib/nokogiri/xml/sax/parser.rb +123 -0
  220. data/lib/nokogiri/xml/sax/parser_context.rb +17 -0
  221. data/lib/nokogiri/xml/sax/push_parser.rb +61 -0
  222. data/lib/nokogiri/xml/sax.rb +5 -0
  223. data/lib/nokogiri/xml/schema.rb +72 -0
  224. data/lib/nokogiri/xml/searchable.rb +239 -0
  225. data/lib/nokogiri/xml/syntax_error.rb +71 -0
  226. data/lib/nokogiri/xml/text.rb +10 -0
  227. data/lib/nokogiri/xml/xpath/syntax_error.rb +12 -0
  228. data/lib/nokogiri/xml/xpath.rb +11 -0
  229. data/lib/nokogiri/xml/xpath_context.rb +17 -0
  230. data/lib/nokogiri/xml.rb +76 -0
  231. data/lib/nokogiri/xslt/stylesheet.rb +26 -0
  232. data/lib/nokogiri/xslt.rb +57 -0
  233. data/lib/nokogiri.rb +144 -0
  234. data/lib/serializer.jar +0 -0
  235. data/lib/xalan.jar +0 -0
  236. data/lib/xercesImpl.jar +0 -0
  237. data/lib/xml-apis.jar +0 -0
  238. data/lib/xsd/xmlparser/nokogiri.rb +103 -0
  239. metadata +531 -0
@@ -0,0 +1,64 @@
1
+ #include <xml_syntax_error.h>
2
+
3
+ void Nokogiri_error_array_pusher(void * ctx, xmlErrorPtr error)
4
+ {
5
+ VALUE list = (VALUE)ctx;
6
+ Check_Type(list, T_ARRAY);
7
+ rb_ary_push(list, Nokogiri_wrap_xml_syntax_error(error));
8
+ }
9
+
10
+ void Nokogiri_error_raise(void * ctx, xmlErrorPtr error)
11
+ {
12
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
13
+ }
14
+
15
+ VALUE Nokogiri_wrap_xml_syntax_error(xmlErrorPtr error)
16
+ {
17
+ VALUE msg, e, klass;
18
+
19
+ klass = cNokogiriXmlSyntaxError;
20
+
21
+ if (error && error->domain == XML_FROM_XPATH) {
22
+ VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
23
+ klass = rb_const_get(xpath, rb_intern("SyntaxError"));
24
+ }
25
+
26
+ msg = (error && error->message) ? NOKOGIRI_STR_NEW2(error->message) : Qnil;
27
+
28
+ e = rb_class_new_instance(
29
+ 1,
30
+ &msg,
31
+ klass
32
+ );
33
+
34
+ if (error)
35
+ {
36
+ rb_iv_set(e, "@domain", INT2NUM(error->domain));
37
+ rb_iv_set(e, "@code", INT2NUM(error->code));
38
+ rb_iv_set(e, "@level", INT2NUM((short)error->level));
39
+ rb_iv_set(e, "@file", RBSTR_OR_QNIL(error->file));
40
+ rb_iv_set(e, "@line", INT2NUM(error->line));
41
+ rb_iv_set(e, "@str1", RBSTR_OR_QNIL(error->str1));
42
+ rb_iv_set(e, "@str2", RBSTR_OR_QNIL(error->str2));
43
+ rb_iv_set(e, "@str3", RBSTR_OR_QNIL(error->str3));
44
+ rb_iv_set(e, "@int1", INT2NUM(error->int1));
45
+ rb_iv_set(e, "@column", INT2NUM(error->int2));
46
+ }
47
+
48
+ return e;
49
+ }
50
+
51
+ VALUE cNokogiriXmlSyntaxError;
52
+ void init_xml_syntax_error()
53
+ {
54
+ VALUE nokogiri = rb_define_module("Nokogiri");
55
+ VALUE xml = rb_define_module_under(nokogiri, "XML");
56
+
57
+ /*
58
+ * The XML::SyntaxError is raised on parse errors
59
+ */
60
+ VALUE syntax_error_mommy = rb_define_class_under(nokogiri, "SyntaxError", rb_eStandardError);
61
+ VALUE klass = rb_define_class_under(xml, "SyntaxError", syntax_error_mommy);
62
+ cNokogiriXmlSyntaxError = klass;
63
+
64
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef NOKOGIRI_XML_SYNTAX_ERROR
2
+ #define NOKOGIRI_XML_SYNTAX_ERROR
3
+
4
+ #include <nokogiri.h>
5
+
6
+ void init_xml_syntax_error();
7
+ VALUE Nokogiri_wrap_xml_syntax_error(xmlErrorPtr error);
8
+ void Nokogiri_error_array_pusher(void * ctx, xmlErrorPtr error);
9
+ NORETURN(void Nokogiri_error_raise(void * ctx, xmlErrorPtr error));
10
+
11
+ extern VALUE cNokogiriXmlSyntaxError;
12
+ #endif
13
+
@@ -0,0 +1,52 @@
1
+ #include <xml_text.h>
2
+
3
+ /*
4
+ * call-seq:
5
+ * new(content, document)
6
+ *
7
+ * Create a new Text element on the +document+ with +content+
8
+ */
9
+ static VALUE new(int argc, VALUE *argv, VALUE klass)
10
+ {
11
+ xmlDocPtr doc;
12
+ xmlNodePtr node;
13
+ VALUE string;
14
+ VALUE document;
15
+ VALUE rest;
16
+ VALUE rb_node;
17
+
18
+ rb_scan_args(argc, argv, "2*", &string, &document, &rest);
19
+
20
+ Data_Get_Struct(document, xmlDoc, doc);
21
+
22
+ node = xmlNewText((xmlChar *)StringValueCStr(string));
23
+ node->doc = doc->doc;
24
+
25
+ nokogiri_root_node(node);
26
+
27
+ rb_node = Nokogiri_wrap_xml_node(klass, node) ;
28
+ rb_obj_call_init(rb_node, argc, argv);
29
+
30
+ if(rb_block_given_p()) rb_yield(rb_node);
31
+
32
+ return rb_node;
33
+ }
34
+
35
+ VALUE cNokogiriXmlText ;
36
+ void init_xml_text()
37
+ {
38
+ VALUE nokogiri = rb_define_module("Nokogiri");
39
+ VALUE xml = rb_define_module_under(nokogiri, "XML");
40
+ /* */
41
+ VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
42
+ VALUE char_data = rb_define_class_under(xml, "CharacterData", node);
43
+
44
+ /*
45
+ * Wraps Text nodes.
46
+ */
47
+ VALUE klass = rb_define_class_under(xml, "Text", char_data);
48
+
49
+ cNokogiriXmlText = klass;
50
+
51
+ rb_define_singleton_method(klass, "new", new, -1);
52
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef NOKOGIRI_XML_TEXT
2
+ #define NOKOGIRI_XML_TEXT
3
+
4
+ #include <nokogiri.h>
5
+
6
+ void init_xml_text();
7
+
8
+ extern VALUE cNokogiriXmlText ;
9
+ #endif
@@ -0,0 +1,374 @@
1
+ #include <xml_xpath_context.h>
2
+
3
+ /*
4
+ * these constants have matching declarations in
5
+ * ext/java/nokogiri/internals/NokogiriNamespaceContext.java
6
+ */
7
+ static const xmlChar *NOKOGIRI_BUILTIN_PREFIX = (const xmlChar *)"nokogiri-builtin";
8
+ static const xmlChar *NOKOGIRI_BUILTIN_URI = (const xmlChar *)"https://www.nokogiri.org/default_ns/ruby/builtins";
9
+
10
+ static void deallocate(xmlXPathContextPtr ctx)
11
+ {
12
+ NOKOGIRI_DEBUG_START(ctx);
13
+ xmlXPathFreeContext(ctx);
14
+ NOKOGIRI_DEBUG_END(ctx);
15
+ }
16
+
17
+ /* find a CSS class in an HTML element's `class` attribute */
18
+ const xmlChar* builtin_css_class(const xmlChar* str, const xmlChar *val)
19
+ {
20
+ int val_len;
21
+
22
+ if (str == NULL) { return(NULL); }
23
+ if (val == NULL) { return(NULL); }
24
+
25
+ val_len = xmlStrlen(val);
26
+ if (val_len == 0) { return(str); }
27
+
28
+ while (*str != 0) {
29
+ if ((*str == *val) && !xmlStrncmp(str, val, val_len)) {
30
+ const xmlChar* next_byte = str + val_len;
31
+
32
+ /* only match if the next byte is whitespace or end of string */
33
+ if ((*next_byte == 0) || (IS_BLANK_CH(*next_byte))) {
34
+ return((const xmlChar*)str);
35
+ }
36
+ }
37
+
38
+ /* advance str to whitespace */
39
+ while ((*str != 0) && !IS_BLANK_CH(*str)) {
40
+ str++;
41
+ }
42
+
43
+ /* advance str to start of next word or end of string */
44
+ while ((*str != 0) && IS_BLANK_CH(*str)) {
45
+ str++;
46
+ }
47
+ }
48
+
49
+ return(NULL);
50
+ }
51
+
52
+ /* xmlXPathFunction to wrap builtin_css_class() */
53
+ static void xpath_builtin_css_class(xmlXPathParserContextPtr ctxt, int nargs)
54
+ {
55
+ xmlXPathObjectPtr hay, needle;
56
+
57
+ CHECK_ARITY(2);
58
+
59
+ CAST_TO_STRING;
60
+ needle = valuePop(ctxt);
61
+ if ((needle == NULL) || (needle->type != XPATH_STRING)) {
62
+ xmlXPathFreeObject(needle);
63
+ XP_ERROR(XPATH_INVALID_TYPE);
64
+ }
65
+
66
+ CAST_TO_STRING;
67
+ hay = valuePop(ctxt);
68
+ if ((hay == NULL) || (hay->type != XPATH_STRING)) {
69
+ xmlXPathFreeObject(hay);
70
+ xmlXPathFreeObject(needle);
71
+ XP_ERROR(XPATH_INVALID_TYPE);
72
+ }
73
+
74
+ if (builtin_css_class(hay->stringval, needle->stringval)) {
75
+ valuePush(ctxt, xmlXPathNewBoolean(1));
76
+ } else {
77
+ valuePush(ctxt, xmlXPathNewBoolean(0));
78
+ }
79
+
80
+ xmlXPathFreeObject(hay);
81
+ xmlXPathFreeObject(needle);
82
+ }
83
+
84
+ /*
85
+ * call-seq:
86
+ * register_ns(prefix, uri)
87
+ *
88
+ * Register the namespace with +prefix+ and +uri+.
89
+ */
90
+ static VALUE register_ns(VALUE self, VALUE prefix, VALUE uri)
91
+ {
92
+ xmlXPathContextPtr ctx;
93
+ Data_Get_Struct(self, xmlXPathContext, ctx);
94
+
95
+ xmlXPathRegisterNs( ctx,
96
+ (const xmlChar *)StringValueCStr(prefix),
97
+ (const xmlChar *)StringValueCStr(uri)
98
+ );
99
+ return self;
100
+ }
101
+
102
+ /*
103
+ * call-seq:
104
+ * register_variable(name, value)
105
+ *
106
+ * Register the variable +name+ with +value+.
107
+ */
108
+ static VALUE register_variable(VALUE self, VALUE name, VALUE value)
109
+ {
110
+ xmlXPathContextPtr ctx;
111
+ xmlXPathObjectPtr xmlValue;
112
+ Data_Get_Struct(self, xmlXPathContext, ctx);
113
+
114
+ xmlValue = xmlXPathNewCString(StringValueCStr(value));
115
+
116
+ xmlXPathRegisterVariable( ctx,
117
+ (const xmlChar *)StringValueCStr(name),
118
+ xmlValue
119
+ );
120
+
121
+ return self;
122
+ }
123
+
124
+ void Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr ctx, int nargs, VALUE handler, const char* function_name)
125
+ {
126
+ int i;
127
+ VALUE result, doc;
128
+ VALUE *argv;
129
+ VALUE node_set = Qnil;
130
+ xmlNodeSetPtr xml_node_set = NULL;
131
+ xmlXPathObjectPtr obj;
132
+
133
+ assert(ctx->context->doc);
134
+ assert(DOC_RUBY_OBJECT_TEST(ctx->context->doc));
135
+
136
+ argv = (VALUE *)calloc((size_t)nargs, sizeof(VALUE));
137
+ for (i = 0 ; i < nargs ; ++i) {
138
+ rb_gc_register_address(&argv[i]);
139
+ }
140
+
141
+ doc = DOC_RUBY_OBJECT(ctx->context->doc);
142
+
143
+ if (nargs > 0) {
144
+ i = nargs - 1;
145
+ do {
146
+ obj = valuePop(ctx);
147
+ switch(obj->type) {
148
+ case XPATH_STRING:
149
+ argv[i] = NOKOGIRI_STR_NEW2(obj->stringval);
150
+ break;
151
+ case XPATH_BOOLEAN:
152
+ argv[i] = obj->boolval == 1 ? Qtrue : Qfalse;
153
+ break;
154
+ case XPATH_NUMBER:
155
+ argv[i] = rb_float_new(obj->floatval);
156
+ break;
157
+ case XPATH_NODESET:
158
+ argv[i] = Nokogiri_wrap_xml_node_set(obj->nodesetval, doc);
159
+ break;
160
+ default:
161
+ argv[i] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(obj));
162
+ }
163
+ xmlXPathFreeNodeSetList(obj);
164
+ } while(i-- > 0);
165
+ }
166
+
167
+ result = rb_funcall2(handler, rb_intern((const char*)function_name), nargs, argv);
168
+
169
+ for (i = 0 ; i < nargs ; ++i) {
170
+ rb_gc_unregister_address(&argv[i]);
171
+ }
172
+ free(argv);
173
+
174
+ switch(TYPE(result)) {
175
+ case T_FLOAT:
176
+ case T_BIGNUM:
177
+ case T_FIXNUM:
178
+ xmlXPathReturnNumber(ctx, NUM2DBL(result));
179
+ break;
180
+ case T_STRING:
181
+ xmlXPathReturnString(
182
+ ctx,
183
+ xmlCharStrdup(StringValueCStr(result))
184
+ );
185
+ break;
186
+ case T_TRUE:
187
+ xmlXPathReturnTrue(ctx);
188
+ break;
189
+ case T_FALSE:
190
+ xmlXPathReturnFalse(ctx);
191
+ break;
192
+ case T_NIL:
193
+ break;
194
+ case T_ARRAY:
195
+ {
196
+ VALUE args[2];
197
+ args[0] = doc;
198
+ args[1] = result;
199
+ node_set = rb_class_new_instance(2, args, cNokogiriXmlNodeSet);
200
+ Data_Get_Struct(node_set, xmlNodeSet, xml_node_set);
201
+ xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
202
+ }
203
+ break;
204
+ case T_DATA:
205
+ if(rb_obj_is_kind_of(result, cNokogiriXmlNodeSet)) {
206
+ Data_Get_Struct(result, xmlNodeSet, xml_node_set);
207
+ /* Copy the node set, otherwise it will get GC'd. */
208
+ xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
209
+ break;
210
+ }
211
+ default:
212
+ rb_raise(rb_eRuntimeError, "Invalid return type");
213
+ }
214
+ }
215
+
216
+ static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
217
+ {
218
+ VALUE handler = Qnil;
219
+ const char *function = NULL ;
220
+
221
+ assert(ctx);
222
+ assert(ctx->context);
223
+ assert(ctx->context->userData);
224
+ assert(ctx->context->function);
225
+
226
+ handler = (VALUE)(ctx->context->userData);
227
+ function = (const char*)(ctx->context->function);
228
+
229
+ Nokogiri_marshal_xpath_funcall_and_return_values(ctx, nargs, handler, function);
230
+ }
231
+
232
+ static xmlXPathFunction lookup( void *ctx,
233
+ const xmlChar * name,
234
+ const xmlChar* ns_uri )
235
+ {
236
+ VALUE xpath_handler = (VALUE)ctx;
237
+ if(rb_respond_to(xpath_handler, rb_intern((const char *)name)))
238
+ return ruby_funcall;
239
+
240
+ return NULL;
241
+ }
242
+
243
+ NORETURN(static void xpath_generic_exception_handler(void * ctx, const char *msg, ...));
244
+ static void xpath_generic_exception_handler(void * ctx, const char *msg, ...)
245
+ {
246
+ char * message;
247
+
248
+ va_list args;
249
+ va_start(args, msg);
250
+ vasprintf(&message, msg, args);
251
+ va_end(args);
252
+
253
+ rb_raise(rb_eRuntimeError, "%s", message);
254
+ }
255
+
256
+ /*
257
+ * call-seq:
258
+ * evaluate(search_path, handler = nil)
259
+ *
260
+ * Evaluate the +search_path+ returning an XML::XPath object.
261
+ */
262
+ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
263
+ {
264
+ VALUE search_path, xpath_handler;
265
+ VALUE thing = Qnil;
266
+ xmlXPathContextPtr ctx;
267
+ xmlXPathObjectPtr xpath;
268
+ xmlChar *query;
269
+
270
+ Data_Get_Struct(self, xmlXPathContext, ctx);
271
+
272
+ if(rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1)
273
+ xpath_handler = Qnil;
274
+
275
+ query = (xmlChar *)StringValueCStr(search_path);
276
+
277
+ if(Qnil != xpath_handler) {
278
+ /* FIXME: not sure if this is the correct place to shove private data. */
279
+ ctx->userData = (void *)xpath_handler;
280
+ xmlXPathRegisterFuncLookup(ctx, lookup, (void *)xpath_handler);
281
+ }
282
+
283
+ xmlResetLastError();
284
+ xmlSetStructuredErrorFunc(NULL, Nokogiri_error_raise);
285
+
286
+ /* For some reason, xmlXPathEvalExpression will blow up with a generic error */
287
+ /* when there is a non existent function. */
288
+ xmlSetGenericErrorFunc(NULL, xpath_generic_exception_handler);
289
+
290
+ xpath = xmlXPathEvalExpression(query, ctx);
291
+ xmlSetStructuredErrorFunc(NULL, NULL);
292
+ xmlSetGenericErrorFunc(NULL, NULL);
293
+
294
+ if(xpath == NULL) {
295
+ xmlErrorPtr error = xmlGetLastError();
296
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
297
+ }
298
+
299
+ assert(ctx->doc);
300
+ assert(DOC_RUBY_OBJECT_TEST(ctx->doc));
301
+
302
+ switch(xpath->type) {
303
+ case XPATH_STRING:
304
+ thing = NOKOGIRI_STR_NEW2(xpath->stringval);
305
+ xmlFree(xpath->stringval);
306
+ break;
307
+ case XPATH_NODESET:
308
+ thing = Nokogiri_wrap_xml_node_set(xpath->nodesetval,
309
+ DOC_RUBY_OBJECT(ctx->doc));
310
+ break;
311
+ case XPATH_NUMBER:
312
+ thing = rb_float_new(xpath->floatval);
313
+ break;
314
+ case XPATH_BOOLEAN:
315
+ thing = xpath->boolval == 1 ? Qtrue : Qfalse;
316
+ break;
317
+ default:
318
+ thing = Nokogiri_wrap_xml_node_set(NULL, DOC_RUBY_OBJECT(ctx->doc));
319
+ }
320
+
321
+ xmlXPathFreeNodeSetList(xpath);
322
+
323
+ return thing;
324
+ }
325
+
326
+ /*
327
+ * call-seq:
328
+ * new(node)
329
+ *
330
+ * Create a new XPathContext with +node+ as the reference point.
331
+ */
332
+ static VALUE new(VALUE klass, VALUE nodeobj)
333
+ {
334
+ xmlNodePtr node;
335
+ xmlXPathContextPtr ctx;
336
+ VALUE self;
337
+
338
+ Data_Get_Struct(nodeobj, xmlNode, node);
339
+
340
+ xmlXPathInit();
341
+
342
+ ctx = xmlXPathNewContext(node->doc);
343
+ ctx->node = node;
344
+
345
+ xmlXPathRegisterNs(ctx, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
346
+ xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"css-class", NOKOGIRI_BUILTIN_URI,
347
+ xpath_builtin_css_class);
348
+
349
+ self = Data_Wrap_Struct(klass, 0, deallocate, ctx);
350
+ return self;
351
+ }
352
+
353
+ VALUE cNokogiriXmlXpathContext;
354
+ void init_xml_xpath_context(void)
355
+ {
356
+ VALUE module = rb_define_module("Nokogiri");
357
+
358
+ /*
359
+ * Nokogiri::XML
360
+ */
361
+ VALUE xml = rb_define_module_under(module, "XML");
362
+
363
+ /*
364
+ * XPathContext is the entry point for searching a Document by using XPath.
365
+ */
366
+ VALUE klass = rb_define_class_under(xml, "XPathContext", rb_cObject);
367
+
368
+ cNokogiriXmlXpathContext = klass;
369
+
370
+ rb_define_singleton_method(klass, "new", new, 1);
371
+ rb_define_method(klass, "evaluate", evaluate, -1);
372
+ rb_define_method(klass, "register_variable", register_variable, 2);
373
+ rb_define_method(klass, "register_ns", register_ns, 2);
374
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef NOKOGIRI_XML_XPATH_CONTEXT
2
+ #define NOKOGIRI_XML_XPATH_CONTEXT
3
+
4
+ #include <nokogiri.h>
5
+
6
+ void init_xml_xpath_context();
7
+ void Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr ctx, int nargs, VALUE handler, const char* function_name) ;
8
+
9
+ extern VALUE cNokogiriXmlXpathContext;
10
+ #endif