nokogiri 1.14.0.rc1-arm-linux

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 (200) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +38 -0
  3. data/LICENSE-DEPENDENCIES.md +2224 -0
  4. data/LICENSE.md +9 -0
  5. data/README.md +287 -0
  6. data/bin/nokogiri +131 -0
  7. data/dependencies.yml +41 -0
  8. data/ext/nokogiri/depend +38 -0
  9. data/ext/nokogiri/extconf.rb +1082 -0
  10. data/ext/nokogiri/gumbo.c +594 -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 +114 -0
  15. data/ext/nokogiri/html4_sax_push_parser.c +95 -0
  16. data/ext/nokogiri/include/libexslt/exslt.h +108 -0
  17. data/ext/nokogiri/include/libexslt/exsltconfig.h +70 -0
  18. data/ext/nokogiri/include/libexslt/exsltexports.h +63 -0
  19. data/ext/nokogiri/include/libxml2/libxml/HTMLparser.h +306 -0
  20. data/ext/nokogiri/include/libxml2/libxml/HTMLtree.h +147 -0
  21. data/ext/nokogiri/include/libxml2/libxml/SAX.h +204 -0
  22. data/ext/nokogiri/include/libxml2/libxml/SAX2.h +172 -0
  23. data/ext/nokogiri/include/libxml2/libxml/c14n.h +128 -0
  24. data/ext/nokogiri/include/libxml2/libxml/catalog.h +182 -0
  25. data/ext/nokogiri/include/libxml2/libxml/chvalid.h +230 -0
  26. data/ext/nokogiri/include/libxml2/libxml/debugXML.h +217 -0
  27. data/ext/nokogiri/include/libxml2/libxml/dict.h +81 -0
  28. data/ext/nokogiri/include/libxml2/libxml/encoding.h +232 -0
  29. data/ext/nokogiri/include/libxml2/libxml/entities.h +153 -0
  30. data/ext/nokogiri/include/libxml2/libxml/globals.h +499 -0
  31. data/ext/nokogiri/include/libxml2/libxml/hash.h +236 -0
  32. data/ext/nokogiri/include/libxml2/libxml/list.h +137 -0
  33. data/ext/nokogiri/include/libxml2/libxml/nanoftp.h +186 -0
  34. data/ext/nokogiri/include/libxml2/libxml/nanohttp.h +81 -0
  35. data/ext/nokogiri/include/libxml2/libxml/parser.h +1244 -0
  36. data/ext/nokogiri/include/libxml2/libxml/parserInternals.h +656 -0
  37. data/ext/nokogiri/include/libxml2/libxml/pattern.h +100 -0
  38. data/ext/nokogiri/include/libxml2/libxml/relaxng.h +218 -0
  39. data/ext/nokogiri/include/libxml2/libxml/schemasInternals.h +958 -0
  40. data/ext/nokogiri/include/libxml2/libxml/schematron.h +142 -0
  41. data/ext/nokogiri/include/libxml2/libxml/threads.h +91 -0
  42. data/ext/nokogiri/include/libxml2/libxml/tree.h +1312 -0
  43. data/ext/nokogiri/include/libxml2/libxml/uri.h +94 -0
  44. data/ext/nokogiri/include/libxml2/libxml/valid.h +463 -0
  45. data/ext/nokogiri/include/libxml2/libxml/xinclude.h +129 -0
  46. data/ext/nokogiri/include/libxml2/libxml/xlink.h +189 -0
  47. data/ext/nokogiri/include/libxml2/libxml/xmlIO.h +368 -0
  48. data/ext/nokogiri/include/libxml2/libxml/xmlautomata.h +146 -0
  49. data/ext/nokogiri/include/libxml2/libxml/xmlerror.h +947 -0
  50. data/ext/nokogiri/include/libxml2/libxml/xmlexports.h +77 -0
  51. data/ext/nokogiri/include/libxml2/libxml/xmlmemory.h +226 -0
  52. data/ext/nokogiri/include/libxml2/libxml/xmlmodule.h +57 -0
  53. data/ext/nokogiri/include/libxml2/libxml/xmlreader.h +428 -0
  54. data/ext/nokogiri/include/libxml2/libxml/xmlregexp.h +222 -0
  55. data/ext/nokogiri/include/libxml2/libxml/xmlsave.h +88 -0
  56. data/ext/nokogiri/include/libxml2/libxml/xmlschemas.h +246 -0
  57. data/ext/nokogiri/include/libxml2/libxml/xmlschemastypes.h +152 -0
  58. data/ext/nokogiri/include/libxml2/libxml/xmlstring.h +140 -0
  59. data/ext/nokogiri/include/libxml2/libxml/xmlunicode.h +202 -0
  60. data/ext/nokogiri/include/libxml2/libxml/xmlversion.h +503 -0
  61. data/ext/nokogiri/include/libxml2/libxml/xmlwriter.h +488 -0
  62. data/ext/nokogiri/include/libxml2/libxml/xpath.h +575 -0
  63. data/ext/nokogiri/include/libxml2/libxml/xpathInternals.h +632 -0
  64. data/ext/nokogiri/include/libxml2/libxml/xpointer.h +137 -0
  65. data/ext/nokogiri/include/libxslt/attributes.h +38 -0
  66. data/ext/nokogiri/include/libxslt/documents.h +93 -0
  67. data/ext/nokogiri/include/libxslt/extensions.h +262 -0
  68. data/ext/nokogiri/include/libxslt/extra.h +72 -0
  69. data/ext/nokogiri/include/libxslt/functions.h +78 -0
  70. data/ext/nokogiri/include/libxslt/imports.h +75 -0
  71. data/ext/nokogiri/include/libxslt/keys.h +53 -0
  72. data/ext/nokogiri/include/libxslt/namespaces.h +68 -0
  73. data/ext/nokogiri/include/libxslt/numbersInternals.h +73 -0
  74. data/ext/nokogiri/include/libxslt/pattern.h +84 -0
  75. data/ext/nokogiri/include/libxslt/preproc.h +43 -0
  76. data/ext/nokogiri/include/libxslt/security.h +104 -0
  77. data/ext/nokogiri/include/libxslt/templates.h +77 -0
  78. data/ext/nokogiri/include/libxslt/transform.h +207 -0
  79. data/ext/nokogiri/include/libxslt/variables.h +118 -0
  80. data/ext/nokogiri/include/libxslt/xslt.h +110 -0
  81. data/ext/nokogiri/include/libxslt/xsltInternals.h +1982 -0
  82. data/ext/nokogiri/include/libxslt/xsltconfig.h +179 -0
  83. data/ext/nokogiri/include/libxslt/xsltexports.h +64 -0
  84. data/ext/nokogiri/include/libxslt/xsltlocale.h +76 -0
  85. data/ext/nokogiri/include/libxslt/xsltutils.h +310 -0
  86. data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
  87. data/ext/nokogiri/nokogiri.c +259 -0
  88. data/ext/nokogiri/nokogiri.h +235 -0
  89. data/ext/nokogiri/test_global_handlers.c +40 -0
  90. data/ext/nokogiri/xml_attr.c +103 -0
  91. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  92. data/ext/nokogiri/xml_cdata.c +57 -0
  93. data/ext/nokogiri/xml_comment.c +62 -0
  94. data/ext/nokogiri/xml_document.c +689 -0
  95. data/ext/nokogiri/xml_document_fragment.c +44 -0
  96. data/ext/nokogiri/xml_dtd.c +208 -0
  97. data/ext/nokogiri/xml_element_content.c +128 -0
  98. data/ext/nokogiri/xml_element_decl.c +69 -0
  99. data/ext/nokogiri/xml_encoding_handler.c +104 -0
  100. data/ext/nokogiri/xml_entity_decl.c +112 -0
  101. data/ext/nokogiri/xml_entity_reference.c +50 -0
  102. data/ext/nokogiri/xml_namespace.c +186 -0
  103. data/ext/nokogiri/xml_node.c +2425 -0
  104. data/ext/nokogiri/xml_node_set.c +496 -0
  105. data/ext/nokogiri/xml_processing_instruction.c +54 -0
  106. data/ext/nokogiri/xml_reader.c +794 -0
  107. data/ext/nokogiri/xml_relax_ng.c +183 -0
  108. data/ext/nokogiri/xml_sax_parser.c +316 -0
  109. data/ext/nokogiri/xml_sax_parser_context.c +283 -0
  110. data/ext/nokogiri/xml_sax_push_parser.c +166 -0
  111. data/ext/nokogiri/xml_schema.c +282 -0
  112. data/ext/nokogiri/xml_syntax_error.c +85 -0
  113. data/ext/nokogiri/xml_text.c +48 -0
  114. data/ext/nokogiri/xml_xpath_context.c +413 -0
  115. data/ext/nokogiri/xslt_stylesheet.c +363 -0
  116. data/gumbo-parser/CHANGES.md +63 -0
  117. data/gumbo-parser/Makefile +111 -0
  118. data/gumbo-parser/THANKS +27 -0
  119. data/lib/nokogiri/2.7/nokogiri.so +0 -0
  120. data/lib/nokogiri/3.0/nokogiri.so +0 -0
  121. data/lib/nokogiri/3.1/nokogiri.so +0 -0
  122. data/lib/nokogiri/3.2/nokogiri.so +0 -0
  123. data/lib/nokogiri/class_resolver.rb +67 -0
  124. data/lib/nokogiri/css/node.rb +54 -0
  125. data/lib/nokogiri/css/parser.rb +770 -0
  126. data/lib/nokogiri/css/parser.y +277 -0
  127. data/lib/nokogiri/css/parser_extras.rb +96 -0
  128. data/lib/nokogiri/css/syntax_error.rb +9 -0
  129. data/lib/nokogiri/css/tokenizer.rb +155 -0
  130. data/lib/nokogiri/css/tokenizer.rex +56 -0
  131. data/lib/nokogiri/css/xpath_visitor.rb +359 -0
  132. data/lib/nokogiri/css.rb +66 -0
  133. data/lib/nokogiri/decorators/slop.rb +44 -0
  134. data/lib/nokogiri/encoding_handler.rb +57 -0
  135. data/lib/nokogiri/extension.rb +32 -0
  136. data/lib/nokogiri/gumbo.rb +15 -0
  137. data/lib/nokogiri/html.rb +48 -0
  138. data/lib/nokogiri/html4/builder.rb +37 -0
  139. data/lib/nokogiri/html4/document.rb +214 -0
  140. data/lib/nokogiri/html4/document_fragment.rb +54 -0
  141. data/lib/nokogiri/html4/element_description.rb +25 -0
  142. data/lib/nokogiri/html4/element_description_defaults.rb +572 -0
  143. data/lib/nokogiri/html4/encoding_reader.rb +121 -0
  144. data/lib/nokogiri/html4/entity_lookup.rb +15 -0
  145. data/lib/nokogiri/html4/sax/parser.rb +63 -0
  146. data/lib/nokogiri/html4/sax/parser_context.rb +20 -0
  147. data/lib/nokogiri/html4/sax/push_parser.rb +37 -0
  148. data/lib/nokogiri/html4.rb +47 -0
  149. data/lib/nokogiri/html5/document.rb +168 -0
  150. data/lib/nokogiri/html5/document_fragment.rb +90 -0
  151. data/lib/nokogiri/html5/node.rb +98 -0
  152. data/lib/nokogiri/html5.rb +389 -0
  153. data/lib/nokogiri/jruby/dependencies.rb +3 -0
  154. data/lib/nokogiri/jruby/nokogiri_jars.rb +43 -0
  155. data/lib/nokogiri/syntax_error.rb +6 -0
  156. data/lib/nokogiri/version/constant.rb +6 -0
  157. data/lib/nokogiri/version/info.rb +223 -0
  158. data/lib/nokogiri/version.rb +4 -0
  159. data/lib/nokogiri/xml/attr.rb +66 -0
  160. data/lib/nokogiri/xml/attribute_decl.rb +20 -0
  161. data/lib/nokogiri/xml/builder.rb +487 -0
  162. data/lib/nokogiri/xml/cdata.rb +13 -0
  163. data/lib/nokogiri/xml/character_data.rb +9 -0
  164. data/lib/nokogiri/xml/document.rb +471 -0
  165. data/lib/nokogiri/xml/document_fragment.rb +205 -0
  166. data/lib/nokogiri/xml/dtd.rb +34 -0
  167. data/lib/nokogiri/xml/element_content.rb +38 -0
  168. data/lib/nokogiri/xml/element_decl.rb +15 -0
  169. data/lib/nokogiri/xml/entity_decl.rb +21 -0
  170. data/lib/nokogiri/xml/entity_reference.rb +20 -0
  171. data/lib/nokogiri/xml/namespace.rb +58 -0
  172. data/lib/nokogiri/xml/node/save_options.rb +68 -0
  173. data/lib/nokogiri/xml/node.rb +1563 -0
  174. data/lib/nokogiri/xml/node_set.rb +446 -0
  175. data/lib/nokogiri/xml/notation.rb +19 -0
  176. data/lib/nokogiri/xml/parse_options.rb +213 -0
  177. data/lib/nokogiri/xml/pp/character_data.rb +21 -0
  178. data/lib/nokogiri/xml/pp/node.rb +57 -0
  179. data/lib/nokogiri/xml/pp.rb +4 -0
  180. data/lib/nokogiri/xml/processing_instruction.rb +11 -0
  181. data/lib/nokogiri/xml/reader.rb +105 -0
  182. data/lib/nokogiri/xml/relax_ng.rb +38 -0
  183. data/lib/nokogiri/xml/sax/document.rb +167 -0
  184. data/lib/nokogiri/xml/sax/parser.rb +125 -0
  185. data/lib/nokogiri/xml/sax/parser_context.rb +21 -0
  186. data/lib/nokogiri/xml/sax/push_parser.rb +61 -0
  187. data/lib/nokogiri/xml/sax.rb +6 -0
  188. data/lib/nokogiri/xml/schema.rb +73 -0
  189. data/lib/nokogiri/xml/searchable.rb +270 -0
  190. data/lib/nokogiri/xml/syntax_error.rb +72 -0
  191. data/lib/nokogiri/xml/text.rb +11 -0
  192. data/lib/nokogiri/xml/xpath/syntax_error.rb +13 -0
  193. data/lib/nokogiri/xml/xpath.rb +21 -0
  194. data/lib/nokogiri/xml/xpath_context.rb +16 -0
  195. data/lib/nokogiri/xml.rb +76 -0
  196. data/lib/nokogiri/xslt/stylesheet.rb +27 -0
  197. data/lib/nokogiri/xslt.rb +65 -0
  198. data/lib/nokogiri.rb +120 -0
  199. data/lib/xsd/xmlparser/nokogiri.rb +104 -0
  200. metadata +317 -0
@@ -0,0 +1,85 @@
1
+ #include <nokogiri.h>
2
+
3
+ VALUE cNokogiriXmlSyntaxError;
4
+
5
+ void
6
+ Nokogiri_structured_error_func_save(libxmlStructuredErrorHandlerState *handler_state)
7
+ {
8
+ /* this method is tightly coupled to the implementation of xmlSetStructuredErrorFunc */
9
+ handler_state->user_data = xmlStructuredErrorContext;
10
+ handler_state->handler = xmlStructuredError;
11
+ }
12
+
13
+ void
14
+ Nokogiri_structured_error_func_save_and_set(libxmlStructuredErrorHandlerState *handler_state,
15
+ void *user_data,
16
+ xmlStructuredErrorFunc handler)
17
+ {
18
+ Nokogiri_structured_error_func_save(handler_state);
19
+ xmlSetStructuredErrorFunc(user_data, handler);
20
+ }
21
+
22
+ void
23
+ Nokogiri_structured_error_func_restore(libxmlStructuredErrorHandlerState *handler_state)
24
+ {
25
+ xmlSetStructuredErrorFunc(handler_state->user_data, handler_state->handler);
26
+ }
27
+
28
+ void
29
+ Nokogiri_error_array_pusher(void *ctx, xmlErrorPtr error)
30
+ {
31
+ VALUE list = (VALUE)ctx;
32
+ Check_Type(list, T_ARRAY);
33
+ rb_ary_push(list, Nokogiri_wrap_xml_syntax_error(error));
34
+ }
35
+
36
+ void
37
+ Nokogiri_error_raise(void *ctx, xmlErrorPtr error)
38
+ {
39
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
40
+ }
41
+
42
+ VALUE
43
+ Nokogiri_wrap_xml_syntax_error(xmlErrorPtr error)
44
+ {
45
+ VALUE msg, e, klass;
46
+
47
+ klass = cNokogiriXmlSyntaxError;
48
+
49
+ if (error && error->domain == XML_FROM_XPATH) {
50
+ klass = cNokogiriXmlXpathSyntaxError;
51
+ }
52
+
53
+ msg = (error && error->message) ? NOKOGIRI_STR_NEW2(error->message) : Qnil;
54
+
55
+ e = rb_class_new_instance(
56
+ 1,
57
+ &msg,
58
+ klass
59
+ );
60
+
61
+ if (error) {
62
+ rb_iv_set(e, "@domain", INT2NUM(error->domain));
63
+ rb_iv_set(e, "@code", INT2NUM(error->code));
64
+ rb_iv_set(e, "@level", INT2NUM((short)error->level));
65
+ rb_iv_set(e, "@file", RBSTR_OR_QNIL(error->file));
66
+ rb_iv_set(e, "@line", INT2NUM(error->line));
67
+ rb_iv_set(e, "@str1", RBSTR_OR_QNIL(error->str1));
68
+ rb_iv_set(e, "@str2", RBSTR_OR_QNIL(error->str2));
69
+ rb_iv_set(e, "@str3", RBSTR_OR_QNIL(error->str3));
70
+ rb_iv_set(e, "@int1", INT2NUM(error->int1));
71
+ rb_iv_set(e, "@column", INT2NUM(error->int2));
72
+ }
73
+
74
+ return e;
75
+ }
76
+
77
+ void
78
+ noko_init_xml_syntax_error()
79
+ {
80
+ assert(cNokogiriSyntaxError);
81
+ /*
82
+ * The XML::SyntaxError is raised on parse errors
83
+ */
84
+ cNokogiriXmlSyntaxError = rb_define_class_under(mNokogiriXml, "SyntaxError", cNokogiriSyntaxError);
85
+ }
@@ -0,0 +1,48 @@
1
+ #include <nokogiri.h>
2
+
3
+ VALUE cNokogiriXmlText ;
4
+
5
+ /*
6
+ * call-seq:
7
+ * new(content, document)
8
+ *
9
+ * Create a new Text element on the +document+ with +content+
10
+ */
11
+ static VALUE
12
+ new (int argc, VALUE *argv, VALUE klass)
13
+ {
14
+ xmlDocPtr doc;
15
+ xmlNodePtr node;
16
+ VALUE string;
17
+ VALUE document;
18
+ VALUE rest;
19
+ VALUE rb_node;
20
+
21
+ rb_scan_args(argc, argv, "2*", &string, &document, &rest);
22
+
23
+ Noko_Node_Get_Struct(document, xmlDoc, doc);
24
+
25
+ node = xmlNewText((xmlChar *)StringValueCStr(string));
26
+ node->doc = doc->doc;
27
+
28
+ noko_xml_document_pin_node(node);
29
+
30
+ rb_node = noko_xml_node_wrap(klass, node) ;
31
+ rb_obj_call_init(rb_node, argc, argv);
32
+
33
+ if (rb_block_given_p()) { rb_yield(rb_node); }
34
+
35
+ return rb_node;
36
+ }
37
+
38
+ void
39
+ noko_init_xml_text()
40
+ {
41
+ assert(cNokogiriXmlCharacterData);
42
+ /*
43
+ * Wraps Text nodes.
44
+ */
45
+ cNokogiriXmlText = rb_define_class_under(mNokogiriXml, "Text", cNokogiriXmlCharacterData);
46
+
47
+ rb_define_singleton_method(cNokogiriXmlText, "new", new, -1);
48
+ }
@@ -0,0 +1,413 @@
1
+ #include <nokogiri.h>
2
+
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_PREFIX = (const xmlChar *)"nokogiri";
10
+ static const xmlChar *NOKOGIRI_URI = (const xmlChar *)"http://www.nokogiri.org/default_ns/ruby/extensions_functions";
11
+ static const xmlChar *NOKOGIRI_BUILTIN_PREFIX = (const xmlChar *)"nokogiri-builtin";
12
+ static const xmlChar *NOKOGIRI_BUILTIN_URI = (const xmlChar *)"https://www.nokogiri.org/default_ns/ruby/builtins";
13
+
14
+ static void
15
+ xml_xpath_context_deallocate(xmlXPathContextPtr ctx)
16
+ {
17
+ xmlXPathFreeContext(ctx);
18
+ }
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
+
109
+ /*
110
+ * call-seq:
111
+ * register_ns(prefix, uri)
112
+ *
113
+ * Register the namespace with +prefix+ and +uri+.
114
+ */
115
+ static VALUE
116
+ rb_xml_xpath_context_register_ns(VALUE self, VALUE prefix, VALUE uri)
117
+ {
118
+ xmlXPathContextPtr ctx;
119
+ Data_Get_Struct(self, xmlXPathContext, ctx);
120
+
121
+ xmlXPathRegisterNs(ctx,
122
+ (const xmlChar *)StringValueCStr(prefix),
123
+ (const xmlChar *)StringValueCStr(uri)
124
+ );
125
+ return self;
126
+ }
127
+
128
+ /*
129
+ * call-seq:
130
+ * register_variable(name, value)
131
+ *
132
+ * Register the variable +name+ with +value+.
133
+ */
134
+ static VALUE
135
+ rb_xml_xpath_context_register_variable(VALUE self, VALUE name, VALUE value)
136
+ {
137
+ xmlXPathContextPtr ctx;
138
+ xmlXPathObjectPtr xmlValue;
139
+ Data_Get_Struct(self, xmlXPathContext, ctx);
140
+
141
+ xmlValue = xmlXPathNewCString(StringValueCStr(value));
142
+
143
+ xmlXPathRegisterVariable(ctx,
144
+ (const xmlChar *)StringValueCStr(name),
145
+ xmlValue
146
+ );
147
+
148
+ return self;
149
+ }
150
+
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 c_xpath_object, xmlXPathContextPtr ctx)
158
+ {
159
+ VALUE rb_retval;
160
+
161
+ assert(ctx->doc);
162
+ assert(DOC_RUBY_OBJECT_TEST(ctx->doc));
163
+
164
+ switch (c_xpath_object->type) {
165
+ case XPATH_STRING:
166
+ rb_retval = NOKOGIRI_STR_NEW2(c_xpath_object->stringval);
167
+ xmlFree(c_xpath_object->stringval);
168
+ return rb_retval;
169
+
170
+ case XPATH_NODESET:
171
+ return noko_xml_node_set_wrap(c_xpath_object->nodesetval,
172
+ DOC_RUBY_OBJECT(ctx->doc));
173
+
174
+ case XPATH_NUMBER:
175
+ return rb_float_new(c_xpath_object->floatval);
176
+
177
+ case XPATH_BOOLEAN:
178
+ return (c_xpath_object->boolval == 1) ? Qtrue : Qfalse;
179
+
180
+ default:
181
+ return Qundef;
182
+ }
183
+ }
184
+
185
+ void
186
+ Nokogiri_marshal_xpath_funcall_and_return_values(
187
+ xmlXPathParserContextPtr ctx,
188
+ int argc,
189
+ VALUE rb_xpath_handler,
190
+ const char *method_name
191
+ )
192
+ {
193
+ VALUE rb_retval;
194
+ VALUE *argv;
195
+ VALUE rb_node_set = Qnil;
196
+ xmlNodeSetPtr c_node_set = NULL;
197
+ xmlXPathObjectPtr c_xpath_object;
198
+
199
+ assert(ctx->context->doc);
200
+ assert(DOC_RUBY_OBJECT_TEST(ctx->context->doc));
201
+
202
+ argv = (VALUE *)ruby_xcalloc((size_t)argc, sizeof(VALUE));
203
+ for (int j = 0 ; j < argc ; ++j) {
204
+ rb_gc_register_address(&argv[j]);
205
+ }
206
+
207
+ for (int j = argc - 1 ; j >= 0 ; --j) {
208
+ c_xpath_object = valuePop(ctx);
209
+ argv[j] = xpath2ruby(c_xpath_object, ctx->context);
210
+ if (argv[j] == Qundef) {
211
+ argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(c_xpath_object));
212
+ }
213
+ xmlXPathFreeNodeSetList(c_xpath_object);
214
+ }
215
+
216
+ rb_retval = rb_funcall2(rb_xpath_handler, rb_intern((const char *)method_name), argc, argv);
217
+
218
+ for (int j = 0 ; j < argc ; ++j) {
219
+ rb_gc_unregister_address(&argv[j]);
220
+ }
221
+ ruby_xfree(argv);
222
+
223
+ switch (TYPE(rb_retval)) {
224
+ case T_FLOAT:
225
+ case T_BIGNUM:
226
+ case T_FIXNUM:
227
+ xmlXPathReturnNumber(ctx, NUM2DBL(rb_retval));
228
+ break;
229
+ case T_STRING:
230
+ xmlXPathReturnString(ctx, xmlCharStrdup(StringValueCStr(rb_retval)));
231
+ break;
232
+ case T_TRUE:
233
+ xmlXPathReturnTrue(ctx);
234
+ break;
235
+ case T_FALSE:
236
+ xmlXPathReturnFalse(ctx);
237
+ break;
238
+ case T_NIL:
239
+ break;
240
+ case T_ARRAY: {
241
+ VALUE construct_args[2] = { DOC_RUBY_OBJECT(ctx->context->doc), rb_retval };
242
+ rb_node_set = rb_class_new_instance(2, construct_args, cNokogiriXmlNodeSet);
243
+ Data_Get_Struct(rb_node_set, xmlNodeSet, c_node_set);
244
+ xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, c_node_set));
245
+ }
246
+ break;
247
+ case T_DATA:
248
+ if (rb_obj_is_kind_of(rb_retval, cNokogiriXmlNodeSet)) {
249
+ Data_Get_Struct(rb_retval, xmlNodeSet, c_node_set);
250
+ /* Copy the node set, otherwise it will get GC'd. */
251
+ xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, c_node_set));
252
+ break;
253
+ }
254
+ default:
255
+ rb_raise(rb_eRuntimeError, "Invalid return type");
256
+ }
257
+ }
258
+
259
+ static void
260
+ method_caller(xmlXPathParserContextPtr ctx, int argc)
261
+ {
262
+ VALUE rb_xpath_handler = Qnil;
263
+ const char *method_name = NULL ;
264
+
265
+ assert(ctx);
266
+ assert(ctx->context);
267
+ assert(ctx->context->userData);
268
+ assert(ctx->context->function);
269
+
270
+ rb_xpath_handler = (VALUE)(ctx->context->userData);
271
+ method_name = (const char *)(ctx->context->function);
272
+
273
+ Nokogiri_marshal_xpath_funcall_and_return_values(ctx, argc, rb_xpath_handler, method_name);
274
+ }
275
+
276
+ static xmlXPathFunction
277
+ handler_lookup(void *ctx, const xmlChar *c_name, const xmlChar *c_ns_uri)
278
+ {
279
+ VALUE rb_xpath_handler = (VALUE)ctx;
280
+ if (rb_respond_to(rb_xpath_handler, rb_intern((const char *)c_name))) {
281
+ return method_caller;
282
+ }
283
+
284
+ return NULL;
285
+ }
286
+
287
+ PRINTFLIKE_DECL(2, 3)
288
+ static void
289
+ generic_exception_pusher(void *ctx, const char *msg, ...)
290
+ {
291
+ VALUE rb_errors = (VALUE)ctx;
292
+ VALUE rb_message;
293
+ VALUE rb_exception;
294
+
295
+ Check_Type(rb_errors, T_ARRAY);
296
+
297
+ #ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES
298
+ /* It is not currently possible to pass var args from native
299
+ functions to sulong, so we work around the issue here. */
300
+ rb_message = rb_sprintf("generic_exception_pusher: %s", msg);
301
+ #else
302
+ va_list args;
303
+ va_start(args, msg);
304
+ rb_message = rb_vsprintf(msg, args);
305
+ va_end(args);
306
+ #endif
307
+
308
+ rb_exception = rb_exc_new_str(cNokogiriXmlXpathSyntaxError, rb_message);
309
+ rb_ary_push(rb_errors, rb_exception);
310
+ }
311
+
312
+ /*
313
+ * call-seq:
314
+ * evaluate(search_path, handler = nil)
315
+ *
316
+ * Evaluate the +search_path+ returning an XML::XPath object.
317
+ */
318
+ static VALUE
319
+ rb_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE self)
320
+ {
321
+ VALUE search_path, xpath_handler;
322
+ VALUE retval = Qnil;
323
+ xmlXPathContextPtr ctx;
324
+ xmlXPathObjectPtr xpath;
325
+ xmlChar *query;
326
+ VALUE errors = rb_ary_new();
327
+
328
+ Data_Get_Struct(self, xmlXPathContext, ctx);
329
+
330
+ if (rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1) {
331
+ xpath_handler = Qnil;
332
+ }
333
+
334
+ query = (xmlChar *)StringValueCStr(search_path);
335
+
336
+ if (Qnil != xpath_handler) {
337
+ /* FIXME: not sure if this is the correct place to shove private data. */
338
+ ctx->userData = (void *)xpath_handler;
339
+ xmlXPathRegisterFuncLookup(ctx, handler_lookup, (void *)xpath_handler);
340
+ }
341
+
342
+ xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);
343
+ xmlSetGenericErrorFunc((void *)errors, generic_exception_pusher);
344
+
345
+ xpath = xmlXPathEvalExpression(query, ctx);
346
+
347
+ xmlSetStructuredErrorFunc(NULL, NULL);
348
+ xmlSetGenericErrorFunc(NULL, NULL);
349
+
350
+ if (xpath == NULL) {
351
+ rb_exc_raise(rb_ary_entry(errors, 0));
352
+ }
353
+
354
+ retval = xpath2ruby(xpath, ctx);
355
+ if (retval == Qundef) {
356
+ retval = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(ctx->doc));
357
+ }
358
+
359
+ xmlXPathFreeNodeSetList(xpath);
360
+
361
+ return retval;
362
+ }
363
+
364
+ /*
365
+ * call-seq:
366
+ * new(node)
367
+ *
368
+ * Create a new XPathContext with +node+ as the reference point.
369
+ */
370
+ static VALUE
371
+ rb_xml_xpath_context_new(VALUE klass, VALUE nodeobj)
372
+ {
373
+ xmlNodePtr node;
374
+ xmlXPathContextPtr ctx;
375
+ VALUE self;
376
+
377
+ Noko_Node_Get_Struct(nodeobj, xmlNode, node);
378
+
379
+ #if LIBXML_VERSION < 21000
380
+ /* deprecated in 40483d0 */
381
+ xmlXPathInit();
382
+ #endif
383
+
384
+ ctx = xmlXPathNewContext(node->doc);
385
+ ctx->node = node;
386
+
387
+ xmlXPathRegisterNs(ctx, NOKOGIRI_PREFIX, NOKOGIRI_URI);
388
+ xmlXPathRegisterNs(ctx, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
389
+ xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"css-class", NOKOGIRI_BUILTIN_URI,
390
+ xpath_builtin_css_class);
391
+ xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"local-name-is", NOKOGIRI_BUILTIN_URI,
392
+ xpath_builtin_local_name_is);
393
+
394
+ self = Data_Wrap_Struct(klass, 0, xml_xpath_context_deallocate, ctx);
395
+ return self;
396
+ }
397
+
398
+ void
399
+ noko_init_xml_xpath_context(void)
400
+ {
401
+ /*
402
+ * XPathContext is the entry point for searching a Document by using XPath.
403
+ */
404
+ cNokogiriXmlXpathContext = rb_define_class_under(mNokogiriXml, "XPathContext", rb_cObject);
405
+
406
+ rb_undef_alloc_func(cNokogiriXmlXpathContext);
407
+
408
+ rb_define_singleton_method(cNokogiriXmlXpathContext, "new", rb_xml_xpath_context_new, 1);
409
+
410
+ rb_define_method(cNokogiriXmlXpathContext, "evaluate", rb_xml_xpath_context_evaluate, -1);
411
+ rb_define_method(cNokogiriXmlXpathContext, "register_variable", rb_xml_xpath_context_register_variable, 2);
412
+ rb_define_method(cNokogiriXmlXpathContext, "register_ns", rb_xml_xpath_context_register_ns, 2);
413
+ }