nokogiri 1.18.0-arm-linux-musl

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 (203) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +39 -0
  3. data/LICENSE-DEPENDENCIES.md +2224 -0
  4. data/LICENSE.md +9 -0
  5. data/README.md +293 -0
  6. data/bin/nokogiri +131 -0
  7. data/dependencies.yml +42 -0
  8. data/ext/nokogiri/depend +38 -0
  9. data/ext/nokogiri/extconf.rb +1173 -0
  10. data/ext/nokogiri/gumbo.c +610 -0
  11. data/ext/nokogiri/html4_document.c +171 -0
  12. data/ext/nokogiri/html4_element_description.c +299 -0
  13. data/ext/nokogiri/html4_entity_lookup.c +37 -0
  14. data/ext/nokogiri/html4_sax_parser.c +40 -0
  15. data/ext/nokogiri/html4_sax_parser_context.c +98 -0
  16. data/ext/nokogiri/html4_sax_push_parser.c +96 -0
  17. data/ext/nokogiri/include/libexslt/exslt.h +108 -0
  18. data/ext/nokogiri/include/libexslt/exsltconfig.h +70 -0
  19. data/ext/nokogiri/include/libexslt/exsltexports.h +63 -0
  20. data/ext/nokogiri/include/libxml2/libxml/HTMLparser.h +336 -0
  21. data/ext/nokogiri/include/libxml2/libxml/HTMLtree.h +147 -0
  22. data/ext/nokogiri/include/libxml2/libxml/SAX.h +202 -0
  23. data/ext/nokogiri/include/libxml2/libxml/SAX2.h +171 -0
  24. data/ext/nokogiri/include/libxml2/libxml/c14n.h +115 -0
  25. data/ext/nokogiri/include/libxml2/libxml/catalog.h +182 -0
  26. data/ext/nokogiri/include/libxml2/libxml/chvalid.h +230 -0
  27. data/ext/nokogiri/include/libxml2/libxml/debugXML.h +217 -0
  28. data/ext/nokogiri/include/libxml2/libxml/dict.h +82 -0
  29. data/ext/nokogiri/include/libxml2/libxml/encoding.h +244 -0
  30. data/ext/nokogiri/include/libxml2/libxml/entities.h +166 -0
  31. data/ext/nokogiri/include/libxml2/libxml/globals.h +41 -0
  32. data/ext/nokogiri/include/libxml2/libxml/hash.h +251 -0
  33. data/ext/nokogiri/include/libxml2/libxml/list.h +137 -0
  34. data/ext/nokogiri/include/libxml2/libxml/nanoftp.h +186 -0
  35. data/ext/nokogiri/include/libxml2/libxml/nanohttp.h +98 -0
  36. data/ext/nokogiri/include/libxml2/libxml/parser.h +1390 -0
  37. data/ext/nokogiri/include/libxml2/libxml/parserInternals.h +671 -0
  38. data/ext/nokogiri/include/libxml2/libxml/pattern.h +106 -0
  39. data/ext/nokogiri/include/libxml2/libxml/relaxng.h +219 -0
  40. data/ext/nokogiri/include/libxml2/libxml/schemasInternals.h +959 -0
  41. data/ext/nokogiri/include/libxml2/libxml/schematron.h +143 -0
  42. data/ext/nokogiri/include/libxml2/libxml/threads.h +87 -0
  43. data/ext/nokogiri/include/libxml2/libxml/tree.h +1382 -0
  44. data/ext/nokogiri/include/libxml2/libxml/uri.h +106 -0
  45. data/ext/nokogiri/include/libxml2/libxml/valid.h +477 -0
  46. data/ext/nokogiri/include/libxml2/libxml/xinclude.h +136 -0
  47. data/ext/nokogiri/include/libxml2/libxml/xlink.h +189 -0
  48. data/ext/nokogiri/include/libxml2/libxml/xmlIO.h +438 -0
  49. data/ext/nokogiri/include/libxml2/libxml/xmlautomata.h +146 -0
  50. data/ext/nokogiri/include/libxml2/libxml/xmlerror.h +962 -0
  51. data/ext/nokogiri/include/libxml2/libxml/xmlexports.h +146 -0
  52. data/ext/nokogiri/include/libxml2/libxml/xmlmemory.h +188 -0
  53. data/ext/nokogiri/include/libxml2/libxml/xmlmodule.h +57 -0
  54. data/ext/nokogiri/include/libxml2/libxml/xmlreader.h +436 -0
  55. data/ext/nokogiri/include/libxml2/libxml/xmlregexp.h +215 -0
  56. data/ext/nokogiri/include/libxml2/libxml/xmlsave.h +102 -0
  57. data/ext/nokogiri/include/libxml2/libxml/xmlschemas.h +249 -0
  58. data/ext/nokogiri/include/libxml2/libxml/xmlschemastypes.h +152 -0
  59. data/ext/nokogiri/include/libxml2/libxml/xmlstring.h +140 -0
  60. data/ext/nokogiri/include/libxml2/libxml/xmlunicode.h +366 -0
  61. data/ext/nokogiri/include/libxml2/libxml/xmlversion.h +347 -0
  62. data/ext/nokogiri/include/libxml2/libxml/xmlwriter.h +489 -0
  63. data/ext/nokogiri/include/libxml2/libxml/xpath.h +579 -0
  64. data/ext/nokogiri/include/libxml2/libxml/xpathInternals.h +633 -0
  65. data/ext/nokogiri/include/libxml2/libxml/xpointer.h +138 -0
  66. data/ext/nokogiri/include/libxslt/attributes.h +39 -0
  67. data/ext/nokogiri/include/libxslt/documents.h +93 -0
  68. data/ext/nokogiri/include/libxslt/extensions.h +262 -0
  69. data/ext/nokogiri/include/libxslt/extra.h +72 -0
  70. data/ext/nokogiri/include/libxslt/functions.h +78 -0
  71. data/ext/nokogiri/include/libxslt/imports.h +75 -0
  72. data/ext/nokogiri/include/libxslt/keys.h +53 -0
  73. data/ext/nokogiri/include/libxslt/namespaces.h +68 -0
  74. data/ext/nokogiri/include/libxslt/numbersInternals.h +73 -0
  75. data/ext/nokogiri/include/libxslt/pattern.h +84 -0
  76. data/ext/nokogiri/include/libxslt/preproc.h +43 -0
  77. data/ext/nokogiri/include/libxslt/security.h +104 -0
  78. data/ext/nokogiri/include/libxslt/templates.h +77 -0
  79. data/ext/nokogiri/include/libxslt/transform.h +207 -0
  80. data/ext/nokogiri/include/libxslt/variables.h +118 -0
  81. data/ext/nokogiri/include/libxslt/xslt.h +110 -0
  82. data/ext/nokogiri/include/libxslt/xsltInternals.h +1995 -0
  83. data/ext/nokogiri/include/libxslt/xsltconfig.h +146 -0
  84. data/ext/nokogiri/include/libxslt/xsltexports.h +64 -0
  85. data/ext/nokogiri/include/libxslt/xsltlocale.h +44 -0
  86. data/ext/nokogiri/include/libxslt/xsltutils.h +343 -0
  87. data/ext/nokogiri/libxml2_polyfill.c +114 -0
  88. data/ext/nokogiri/nokogiri.c +294 -0
  89. data/ext/nokogiri/nokogiri.h +238 -0
  90. data/ext/nokogiri/test_global_handlers.c +40 -0
  91. data/ext/nokogiri/xml_attr.c +103 -0
  92. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  93. data/ext/nokogiri/xml_cdata.c +62 -0
  94. data/ext/nokogiri/xml_comment.c +57 -0
  95. data/ext/nokogiri/xml_document.c +784 -0
  96. data/ext/nokogiri/xml_document_fragment.c +29 -0
  97. data/ext/nokogiri/xml_dtd.c +208 -0
  98. data/ext/nokogiri/xml_element_content.c +131 -0
  99. data/ext/nokogiri/xml_element_decl.c +69 -0
  100. data/ext/nokogiri/xml_encoding_handler.c +112 -0
  101. data/ext/nokogiri/xml_entity_decl.c +112 -0
  102. data/ext/nokogiri/xml_entity_reference.c +50 -0
  103. data/ext/nokogiri/xml_namespace.c +181 -0
  104. data/ext/nokogiri/xml_node.c +2459 -0
  105. data/ext/nokogiri/xml_node_set.c +518 -0
  106. data/ext/nokogiri/xml_processing_instruction.c +54 -0
  107. data/ext/nokogiri/xml_reader.c +777 -0
  108. data/ext/nokogiri/xml_relax_ng.c +149 -0
  109. data/ext/nokogiri/xml_sax_parser.c +403 -0
  110. data/ext/nokogiri/xml_sax_parser_context.c +390 -0
  111. data/ext/nokogiri/xml_sax_push_parser.c +206 -0
  112. data/ext/nokogiri/xml_schema.c +226 -0
  113. data/ext/nokogiri/xml_syntax_error.c +93 -0
  114. data/ext/nokogiri/xml_text.c +59 -0
  115. data/ext/nokogiri/xml_xpath_context.c +486 -0
  116. data/ext/nokogiri/xslt_stylesheet.c +421 -0
  117. data/gumbo-parser/CHANGES.md +63 -0
  118. data/gumbo-parser/Makefile +129 -0
  119. data/gumbo-parser/THANKS +27 -0
  120. data/lib/nokogiri/3.1/nokogiri.so +0 -0
  121. data/lib/nokogiri/3.2/nokogiri.so +0 -0
  122. data/lib/nokogiri/3.3/nokogiri.so +0 -0
  123. data/lib/nokogiri/3.4/nokogiri.so +0 -0
  124. data/lib/nokogiri/class_resolver.rb +67 -0
  125. data/lib/nokogiri/css/node.rb +58 -0
  126. data/lib/nokogiri/css/parser.rb +772 -0
  127. data/lib/nokogiri/css/parser.y +277 -0
  128. data/lib/nokogiri/css/parser_extras.rb +36 -0
  129. data/lib/nokogiri/css/selector_cache.rb +38 -0
  130. data/lib/nokogiri/css/syntax_error.rb +9 -0
  131. data/lib/nokogiri/css/tokenizer.rb +155 -0
  132. data/lib/nokogiri/css/tokenizer.rex +57 -0
  133. data/lib/nokogiri/css/xpath_visitor.rb +375 -0
  134. data/lib/nokogiri/css.rb +132 -0
  135. data/lib/nokogiri/decorators/slop.rb +42 -0
  136. data/lib/nokogiri/encoding_handler.rb +57 -0
  137. data/lib/nokogiri/extension.rb +32 -0
  138. data/lib/nokogiri/gumbo.rb +15 -0
  139. data/lib/nokogiri/html.rb +48 -0
  140. data/lib/nokogiri/html4/builder.rb +37 -0
  141. data/lib/nokogiri/html4/document.rb +235 -0
  142. data/lib/nokogiri/html4/document_fragment.rb +166 -0
  143. data/lib/nokogiri/html4/element_description.rb +25 -0
  144. data/lib/nokogiri/html4/element_description_defaults.rb +2040 -0
  145. data/lib/nokogiri/html4/encoding_reader.rb +121 -0
  146. data/lib/nokogiri/html4/entity_lookup.rb +15 -0
  147. data/lib/nokogiri/html4/sax/parser.rb +48 -0
  148. data/lib/nokogiri/html4/sax/parser_context.rb +15 -0
  149. data/lib/nokogiri/html4/sax/push_parser.rb +37 -0
  150. data/lib/nokogiri/html4.rb +42 -0
  151. data/lib/nokogiri/html5/builder.rb +40 -0
  152. data/lib/nokogiri/html5/document.rb +199 -0
  153. data/lib/nokogiri/html5/document_fragment.rb +200 -0
  154. data/lib/nokogiri/html5/node.rb +103 -0
  155. data/lib/nokogiri/html5.rb +368 -0
  156. data/lib/nokogiri/jruby/dependencies.rb +3 -0
  157. data/lib/nokogiri/jruby/nokogiri_jars.rb +43 -0
  158. data/lib/nokogiri/syntax_error.rb +6 -0
  159. data/lib/nokogiri/version/constant.rb +6 -0
  160. data/lib/nokogiri/version/info.rb +224 -0
  161. data/lib/nokogiri/version.rb +4 -0
  162. data/lib/nokogiri/xml/attr.rb +66 -0
  163. data/lib/nokogiri/xml/attribute_decl.rb +22 -0
  164. data/lib/nokogiri/xml/builder.rb +494 -0
  165. data/lib/nokogiri/xml/cdata.rb +13 -0
  166. data/lib/nokogiri/xml/character_data.rb +9 -0
  167. data/lib/nokogiri/xml/document.rb +514 -0
  168. data/lib/nokogiri/xml/document_fragment.rb +276 -0
  169. data/lib/nokogiri/xml/dtd.rb +34 -0
  170. data/lib/nokogiri/xml/element_content.rb +46 -0
  171. data/lib/nokogiri/xml/element_decl.rb +17 -0
  172. data/lib/nokogiri/xml/entity_decl.rb +23 -0
  173. data/lib/nokogiri/xml/entity_reference.rb +20 -0
  174. data/lib/nokogiri/xml/namespace.rb +57 -0
  175. data/lib/nokogiri/xml/node/save_options.rb +76 -0
  176. data/lib/nokogiri/xml/node.rb +1650 -0
  177. data/lib/nokogiri/xml/node_set.rb +449 -0
  178. data/lib/nokogiri/xml/notation.rb +19 -0
  179. data/lib/nokogiri/xml/parse_options.rb +213 -0
  180. data/lib/nokogiri/xml/pp/character_data.rb +21 -0
  181. data/lib/nokogiri/xml/pp/node.rb +73 -0
  182. data/lib/nokogiri/xml/pp.rb +4 -0
  183. data/lib/nokogiri/xml/processing_instruction.rb +11 -0
  184. data/lib/nokogiri/xml/reader.rb +139 -0
  185. data/lib/nokogiri/xml/relax_ng.rb +75 -0
  186. data/lib/nokogiri/xml/sax/document.rb +258 -0
  187. data/lib/nokogiri/xml/sax/parser.rb +199 -0
  188. data/lib/nokogiri/xml/sax/parser_context.rb +129 -0
  189. data/lib/nokogiri/xml/sax/push_parser.rb +64 -0
  190. data/lib/nokogiri/xml/sax.rb +54 -0
  191. data/lib/nokogiri/xml/schema.rb +140 -0
  192. data/lib/nokogiri/xml/searchable.rb +274 -0
  193. data/lib/nokogiri/xml/syntax_error.rb +94 -0
  194. data/lib/nokogiri/xml/text.rb +11 -0
  195. data/lib/nokogiri/xml/xpath/syntax_error.rb +13 -0
  196. data/lib/nokogiri/xml/xpath.rb +21 -0
  197. data/lib/nokogiri/xml/xpath_context.rb +27 -0
  198. data/lib/nokogiri/xml.rb +65 -0
  199. data/lib/nokogiri/xslt/stylesheet.rb +49 -0
  200. data/lib/nokogiri/xslt.rb +129 -0
  201. data/lib/nokogiri.rb +128 -0
  202. data/lib/xsd/xmlparser/nokogiri.rb +105 -0
  203. metadata +321 -0
@@ -0,0 +1,486 @@
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
+ _noko_xml_xpath_context_dfree(void *data)
16
+ {
17
+ xmlXPathContextPtr c_context = data;
18
+ xmlXPathFreeContext(c_context);
19
+ }
20
+
21
+ static const rb_data_type_t _noko_xml_xpath_context_type = {
22
+ .wrap_struct_name = "xmlXPathContext",
23
+ .function = {
24
+ .dfree = _noko_xml_xpath_context_dfree,
25
+ },
26
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
27
+ };
28
+
29
+ /* find a CSS class in an HTML element's `class` attribute */
30
+ static const xmlChar *
31
+ _noko_xml_xpath_context__css_class(const xmlChar *str, const xmlChar *val)
32
+ {
33
+ int val_len;
34
+
35
+ if (str == NULL) { return (NULL); }
36
+ if (val == NULL) { return (NULL); }
37
+
38
+ val_len = xmlStrlen(val);
39
+ if (val_len == 0) { return (str); }
40
+
41
+ while (*str != 0) {
42
+ if ((*str == *val) && !xmlStrncmp(str, val, val_len)) {
43
+ const xmlChar *next_byte = str + val_len;
44
+
45
+ /* only match if the next byte is whitespace or end of string */
46
+ if ((*next_byte == 0) || (IS_BLANK_CH(*next_byte))) {
47
+ return ((const xmlChar *)str);
48
+ }
49
+ }
50
+
51
+ /* advance str to whitespace */
52
+ while ((*str != 0) && !IS_BLANK_CH(*str)) {
53
+ str++;
54
+ }
55
+
56
+ /* advance str to start of next word or end of string */
57
+ while ((*str != 0) && IS_BLANK_CH(*str)) {
58
+ str++;
59
+ }
60
+ }
61
+
62
+ return (NULL);
63
+ }
64
+
65
+ /* xmlXPathFunction to wrap _noko_xml_xpath_context__css_class() */
66
+ static void
67
+ noko_xml_xpath_context_xpath_func_css_class(xmlXPathParserContextPtr ctxt, int nargs)
68
+ {
69
+ xmlXPathObjectPtr hay, needle;
70
+
71
+ CHECK_ARITY(2);
72
+
73
+ CAST_TO_STRING;
74
+ needle = valuePop(ctxt);
75
+ if ((needle == NULL) || (needle->type != XPATH_STRING)) {
76
+ xmlXPathFreeObject(needle);
77
+ XP_ERROR(XPATH_INVALID_TYPE);
78
+ }
79
+
80
+ CAST_TO_STRING;
81
+ hay = valuePop(ctxt);
82
+ if ((hay == NULL) || (hay->type != XPATH_STRING)) {
83
+ xmlXPathFreeObject(hay);
84
+ xmlXPathFreeObject(needle);
85
+ XP_ERROR(XPATH_INVALID_TYPE);
86
+ }
87
+
88
+ if (_noko_xml_xpath_context__css_class(hay->stringval, needle->stringval)) {
89
+ valuePush(ctxt, xmlXPathNewBoolean(1));
90
+ } else {
91
+ valuePush(ctxt, xmlXPathNewBoolean(0));
92
+ }
93
+
94
+ xmlXPathFreeObject(hay);
95
+ xmlXPathFreeObject(needle);
96
+ }
97
+
98
+
99
+ /* xmlXPathFunction to select nodes whose local name matches, for HTML5 CSS queries that should
100
+ * ignore namespaces */
101
+ static void
102
+ noko_xml_xpath_context_xpath_func_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
103
+ {
104
+ xmlXPathObjectPtr element_name;
105
+
106
+ assert(ctxt->context->node);
107
+
108
+ CHECK_ARITY(1);
109
+ CAST_TO_STRING;
110
+ CHECK_TYPE(XPATH_STRING);
111
+ element_name = valuePop(ctxt);
112
+
113
+ valuePush(
114
+ ctxt,
115
+ xmlXPathNewBoolean(xmlStrEqual(ctxt->context->node->name, element_name->stringval))
116
+ );
117
+
118
+ xmlXPathFreeObject(element_name);
119
+ }
120
+
121
+
122
+ /*
123
+ * call-seq:
124
+ * register_ns(prefix, uri) → Nokogiri::XML::XPathContext
125
+ *
126
+ * Register the namespace with +prefix+ and +uri+ for use in future queries.
127
+ * Passing a uri of +nil+ will unregister the namespace.
128
+ *
129
+ * [Returns] +self+
130
+ */
131
+ static VALUE
132
+ noko_xml_xpath_context_register_ns(VALUE rb_context, VALUE prefix, VALUE uri)
133
+ {
134
+ xmlXPathContextPtr c_context;
135
+ const xmlChar *ns_uri;
136
+
137
+ TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context);
138
+
139
+ if (NIL_P(uri)) {
140
+ ns_uri = NULL;
141
+ } else {
142
+ ns_uri = (const xmlChar *)StringValueCStr(uri);
143
+ }
144
+
145
+ xmlXPathRegisterNs(c_context, (const xmlChar *)StringValueCStr(prefix), ns_uri);
146
+
147
+ return rb_context;
148
+ }
149
+
150
+ /*
151
+ * call-seq:
152
+ * register_variable(name, value) → Nokogiri::XML::XPathContext
153
+ *
154
+ * Register the variable +name+ with +value+ for use in future queries.
155
+ * Passing a value of +nil+ will unregister the variable.
156
+ *
157
+ * [Returns] +self+
158
+ */
159
+ static VALUE
160
+ noko_xml_xpath_context_register_variable(VALUE rb_context, VALUE name, VALUE value)
161
+ {
162
+ xmlXPathContextPtr c_context;
163
+ xmlXPathObjectPtr xmlValue;
164
+
165
+ TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context);
166
+
167
+ if (NIL_P(value)) {
168
+ xmlValue = NULL;
169
+ } else {
170
+ xmlValue = xmlXPathNewCString(StringValueCStr(value));
171
+ }
172
+
173
+ xmlXPathRegisterVariable(c_context, (const xmlChar *)StringValueCStr(name), xmlValue);
174
+
175
+ return rb_context;
176
+ }
177
+
178
+
179
+ /*
180
+ * convert an XPath object into a Ruby object of the appropriate type.
181
+ * returns Qundef if no conversion was possible.
182
+ */
183
+ static VALUE
184
+ _noko_xml_xpath_context__xpath2ruby(xmlXPathObjectPtr c_xpath_object, xmlXPathContextPtr c_context)
185
+ {
186
+ VALUE rb_retval;
187
+
188
+ assert(c_context->doc);
189
+ assert(DOC_RUBY_OBJECT_TEST(c_context->doc));
190
+
191
+ switch (c_xpath_object->type) {
192
+ case XPATH_STRING:
193
+ rb_retval = NOKOGIRI_STR_NEW2(c_xpath_object->stringval);
194
+ xmlFree(c_xpath_object->stringval);
195
+ return rb_retval;
196
+
197
+ case XPATH_NODESET:
198
+ return noko_xml_node_set_wrap(
199
+ c_xpath_object->nodesetval,
200
+ DOC_RUBY_OBJECT(c_context->doc)
201
+ );
202
+
203
+ case XPATH_NUMBER:
204
+ return rb_float_new(c_xpath_object->floatval);
205
+
206
+ case XPATH_BOOLEAN:
207
+ return (c_xpath_object->boolval == 1) ? Qtrue : Qfalse;
208
+
209
+ default:
210
+ return Qundef;
211
+ }
212
+ }
213
+
214
+ void
215
+ Nokogiri_marshal_xpath_funcall_and_return_values(
216
+ xmlXPathParserContextPtr ctxt,
217
+ int argc,
218
+ VALUE rb_xpath_handler,
219
+ const char *method_name
220
+ )
221
+ {
222
+ VALUE rb_retval;
223
+ VALUE *argv;
224
+ VALUE rb_node_set = Qnil;
225
+ xmlNodeSetPtr c_node_set = NULL;
226
+ xmlXPathObjectPtr c_xpath_object;
227
+
228
+ assert(ctxt->context->doc);
229
+ assert(DOC_RUBY_OBJECT_TEST(ctxt->context->doc));
230
+
231
+ argv = (VALUE *)ruby_xcalloc((size_t)argc, sizeof(VALUE));
232
+ for (int j = 0 ; j < argc ; ++j) {
233
+ rb_gc_register_address(&argv[j]);
234
+ }
235
+
236
+ for (int j = argc - 1 ; j >= 0 ; --j) {
237
+ c_xpath_object = valuePop(ctxt);
238
+ argv[j] = _noko_xml_xpath_context__xpath2ruby(c_xpath_object, ctxt->context);
239
+ if (argv[j] == Qundef) {
240
+ argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(c_xpath_object));
241
+ }
242
+ xmlXPathFreeNodeSetList(c_xpath_object);
243
+ }
244
+
245
+ rb_retval = rb_funcall2(
246
+ rb_xpath_handler,
247
+ rb_intern((const char *)method_name),
248
+ argc,
249
+ argv
250
+ );
251
+
252
+ for (int j = 0 ; j < argc ; ++j) {
253
+ rb_gc_unregister_address(&argv[j]);
254
+ }
255
+ ruby_xfree(argv);
256
+
257
+ switch (TYPE(rb_retval)) {
258
+ case T_FLOAT:
259
+ case T_BIGNUM:
260
+ case T_FIXNUM:
261
+ xmlXPathReturnNumber(ctxt, NUM2DBL(rb_retval));
262
+ break;
263
+ case T_STRING:
264
+ xmlXPathReturnString(ctxt, xmlCharStrdup(StringValueCStr(rb_retval)));
265
+ break;
266
+ case T_TRUE:
267
+ xmlXPathReturnTrue(ctxt);
268
+ break;
269
+ case T_FALSE:
270
+ xmlXPathReturnFalse(ctxt);
271
+ break;
272
+ case T_NIL:
273
+ break;
274
+ case T_ARRAY: {
275
+ VALUE construct_args[2] = { DOC_RUBY_OBJECT(ctxt->context->doc), rb_retval };
276
+ rb_node_set = rb_class_new_instance(2, construct_args, cNokogiriXmlNodeSet);
277
+ c_node_set = noko_xml_node_set_unwrap(rb_node_set);
278
+ xmlXPathReturnNodeSet(ctxt, xmlXPathNodeSetMerge(NULL, c_node_set));
279
+ }
280
+ break;
281
+ case T_DATA:
282
+ if (rb_obj_is_kind_of(rb_retval, cNokogiriXmlNodeSet)) {
283
+ c_node_set = noko_xml_node_set_unwrap(rb_retval);
284
+ /* Copy the node set, otherwise it will get GC'd. */
285
+ xmlXPathReturnNodeSet(ctxt, xmlXPathNodeSetMerge(NULL, c_node_set));
286
+ break;
287
+ }
288
+ default:
289
+ rb_raise(rb_eRuntimeError, "Invalid return type");
290
+ }
291
+ }
292
+
293
+ static void
294
+ _noko_xml_xpath_context__handler_invoker(xmlXPathParserContextPtr ctxt, int argc)
295
+ {
296
+ VALUE rb_xpath_handler = Qnil;
297
+ const char *method_name = NULL ;
298
+
299
+ assert(ctxt);
300
+ assert(ctxt->context);
301
+ assert(ctxt->context->userData);
302
+ assert(ctxt->context->function);
303
+
304
+ rb_xpath_handler = (VALUE)(ctxt->context->userData);
305
+ method_name = (const char *)(ctxt->context->function);
306
+
307
+ Nokogiri_marshal_xpath_funcall_and_return_values(
308
+ ctxt,
309
+ argc,
310
+ rb_xpath_handler,
311
+ method_name
312
+ );
313
+ }
314
+
315
+ static xmlXPathFunction
316
+ _noko_xml_xpath_context_handler_lookup(void *data, const xmlChar *c_name, const xmlChar *c_ns_uri)
317
+ {
318
+ VALUE rb_handler = (VALUE)data;
319
+ if (rb_respond_to(rb_handler, rb_intern((const char *)c_name))) {
320
+ if (c_ns_uri == NULL) {
321
+ NOKO_WARN_DEPRECATION("A custom XPath or CSS handler function named '%s' is being invoked without a namespace. Please update your query to reference this function as 'nokogiri:%s'. Invoking custom handler functions without a namespace is deprecated and will become an error in Nokogiri v1.17.0.",
322
+ c_name, c_name); // TODO deprecated in v1.15.0, remove in v1.19.0
323
+ }
324
+ return _noko_xml_xpath_context__handler_invoker;
325
+ }
326
+
327
+ return NULL;
328
+ }
329
+
330
+ PRINTFLIKE_DECL(2, 3)
331
+ static void
332
+ _noko_xml_xpath_context__generic_exception_pusher(void *data, const char *msg, ...)
333
+ {
334
+ VALUE rb_errors = (VALUE)data;
335
+ VALUE rb_message;
336
+ VALUE rb_exception;
337
+
338
+ Check_Type(rb_errors, T_ARRAY);
339
+
340
+ #ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES
341
+ /* It is not currently possible to pass var args from native
342
+ functions to sulong, so we work around the issue here. */
343
+ rb_message = rb_sprintf("_noko_xml_xpath_context__generic_exception_pusher: %s", msg);
344
+ #else
345
+ va_list args;
346
+ va_start(args, msg);
347
+ rb_message = rb_vsprintf(msg, args);
348
+ va_end(args);
349
+ #endif
350
+
351
+ rb_exception = rb_exc_new_str(cNokogiriXmlXpathSyntaxError, rb_message);
352
+ rb_ary_push(rb_errors, rb_exception);
353
+ }
354
+
355
+ /*
356
+ * call-seq:
357
+ * evaluate(search_path, handler = nil) → Object
358
+ *
359
+ * Evaluate the +search_path+ query.
360
+ *
361
+ * [Returns] an object of the appropriate type for the query, which could be +NodeSet+, a +String+,
362
+ * a +Float+, or a boolean.
363
+ */
364
+ static VALUE
365
+ noko_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE rb_context)
366
+ {
367
+ xmlXPathContextPtr c_context;
368
+ VALUE rb_expression = Qnil;
369
+ VALUE rb_function_lookup_handler = Qnil;
370
+ xmlChar *c_expression_str = NULL;
371
+ VALUE rb_errors = rb_ary_new();
372
+ xmlXPathObjectPtr c_xpath_object;
373
+ VALUE rb_xpath_object = Qnil;
374
+
375
+ TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context);
376
+
377
+ rb_scan_args(argc, argv, "11", &rb_expression, &rb_function_lookup_handler);
378
+
379
+ c_expression_str = (xmlChar *)StringValueCStr(rb_expression);
380
+
381
+ if (Qnil != rb_function_lookup_handler) {
382
+ /* FIXME: not sure if this is the correct place to shove private data. */
383
+ c_context->userData = (void *)rb_function_lookup_handler;
384
+ xmlXPathRegisterFuncLookup(
385
+ c_context,
386
+ _noko_xml_xpath_context_handler_lookup,
387
+ (void *)rb_function_lookup_handler
388
+ );
389
+ }
390
+
391
+ /* TODO: use xmlXPathSetErrorHandler (as of 2.13.0) */
392
+ xmlSetStructuredErrorFunc((void *)rb_errors, noko__error_array_pusher);
393
+ xmlSetGenericErrorFunc((void *)rb_errors, _noko_xml_xpath_context__generic_exception_pusher);
394
+
395
+ c_xpath_object = xmlXPathEvalExpression(c_expression_str, c_context);
396
+
397
+ xmlSetStructuredErrorFunc(NULL, NULL);
398
+ xmlSetGenericErrorFunc(NULL, NULL);
399
+
400
+ xmlXPathRegisterFuncLookup(c_context, NULL, NULL);
401
+
402
+ if (c_xpath_object == NULL) {
403
+ rb_exc_raise(rb_ary_entry(rb_errors, 0));
404
+ }
405
+
406
+ rb_xpath_object = _noko_xml_xpath_context__xpath2ruby(c_xpath_object, c_context);
407
+ if (rb_xpath_object == Qundef) {
408
+ rb_xpath_object = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(c_context->doc));
409
+ }
410
+
411
+ xmlXPathFreeNodeSetList(c_xpath_object);
412
+
413
+ return rb_xpath_object;
414
+ }
415
+
416
+ /*
417
+ * call-seq:
418
+ * new(node)
419
+ *
420
+ * Create a new XPathContext with +node+ as the context node.
421
+ */
422
+ static VALUE
423
+ noko_xml_xpath_context_new(VALUE klass, VALUE rb_node)
424
+ {
425
+ xmlNodePtr c_node;
426
+ xmlXPathContextPtr c_context;
427
+ VALUE rb_context;
428
+
429
+ Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
430
+
431
+ #if LIBXML_VERSION < 21000
432
+ xmlXPathInit(); /* deprecated in 40483d0 */
433
+ #endif
434
+
435
+ c_context = xmlXPathNewContext(c_node->doc);
436
+ c_context->node = c_node;
437
+
438
+ xmlXPathRegisterNs(c_context, NOKOGIRI_PREFIX, NOKOGIRI_URI);
439
+ xmlXPathRegisterNs(c_context, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
440
+
441
+ xmlXPathRegisterFuncNS(c_context,
442
+ (const xmlChar *)"css-class", NOKOGIRI_BUILTIN_URI,
443
+ noko_xml_xpath_context_xpath_func_css_class);
444
+ xmlXPathRegisterFuncNS(c_context,
445
+ (const xmlChar *)"local-name-is", NOKOGIRI_BUILTIN_URI,
446
+ noko_xml_xpath_context_xpath_func_local_name_is);
447
+
448
+ rb_context = TypedData_Wrap_Struct(klass, &_noko_xml_xpath_context_type, c_context);
449
+
450
+ return rb_context;
451
+ }
452
+
453
+
454
+ /* :nodoc: */
455
+ static VALUE
456
+ noko_xml_xpath_context_set_node(VALUE rb_context, VALUE rb_node)
457
+ {
458
+ xmlNodePtr c_node;
459
+ xmlXPathContextPtr c_context;
460
+
461
+ TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context);
462
+ Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
463
+
464
+ c_context->doc = c_node->doc;
465
+ c_context->node = c_node;
466
+
467
+ return rb_node;
468
+ }
469
+
470
+ void
471
+ noko_init_xml_xpath_context(void)
472
+ {
473
+ /*
474
+ * XPathContext is the entry point for searching a +Document+ by using XPath.
475
+ */
476
+ cNokogiriXmlXpathContext = rb_define_class_under(mNokogiriXml, "XPathContext", rb_cObject);
477
+
478
+ rb_undef_alloc_func(cNokogiriXmlXpathContext);
479
+
480
+ rb_define_singleton_method(cNokogiriXmlXpathContext, "new", noko_xml_xpath_context_new, 1);
481
+
482
+ rb_define_method(cNokogiriXmlXpathContext, "evaluate", noko_xml_xpath_context_evaluate, -1);
483
+ rb_define_method(cNokogiriXmlXpathContext, "register_variable", noko_xml_xpath_context_register_variable, 2);
484
+ rb_define_method(cNokogiriXmlXpathContext, "register_ns", noko_xml_xpath_context_register_ns, 2);
485
+ rb_define_method(cNokogiriXmlXpathContext, "node=", noko_xml_xpath_context_set_node, 1);
486
+ }