nokogiri 1.13.8 → 1.15.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nokogiri might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +40 -0
- data/LICENSE-DEPENDENCIES.md +830 -509
- data/LICENSE.md +1 -1
- data/README.md +18 -11
- data/dependencies.yml +33 -15
- data/ext/nokogiri/extconf.rb +164 -46
- data/ext/nokogiri/gumbo.c +20 -10
- data/ext/nokogiri/html4_document.c +3 -4
- data/ext/nokogiri/html4_element_description.c +20 -15
- data/ext/nokogiri/html4_entity_lookup.c +2 -2
- data/ext/nokogiri/html4_sax_parser_context.c +11 -22
- data/ext/nokogiri/html4_sax_push_parser.c +3 -3
- data/ext/nokogiri/nokogiri.c +84 -75
- data/ext/nokogiri/nokogiri.h +31 -16
- data/ext/nokogiri/test_global_handlers.c +1 -1
- data/ext/nokogiri/xml_attr.c +2 -2
- data/ext/nokogiri/xml_attribute_decl.c +2 -2
- data/ext/nokogiri/xml_cdata.c +32 -18
- data/ext/nokogiri/xml_comment.c +2 -2
- data/ext/nokogiri/xml_document.c +127 -34
- data/ext/nokogiri/xml_document_fragment.c +2 -2
- data/ext/nokogiri/xml_dtd.c +2 -2
- data/ext/nokogiri/xml_element_content.c +34 -31
- data/ext/nokogiri/xml_element_decl.c +7 -7
- data/ext/nokogiri/xml_encoding_handler.c +15 -7
- data/ext/nokogiri/xml_entity_decl.c +1 -1
- data/ext/nokogiri/xml_entity_reference.c +2 -2
- data/ext/nokogiri/xml_namespace.c +79 -14
- data/ext/nokogiri/xml_node.c +300 -34
- data/ext/nokogiri/xml_node_set.c +125 -107
- data/ext/nokogiri/xml_processing_instruction.c +2 -2
- data/ext/nokogiri/xml_reader.c +81 -48
- data/ext/nokogiri/xml_relax_ng.c +66 -81
- data/ext/nokogiri/xml_sax_parser.c +45 -20
- data/ext/nokogiri/xml_sax_parser_context.c +46 -30
- data/ext/nokogiri/xml_sax_push_parser.c +30 -11
- data/ext/nokogiri/xml_schema.c +95 -117
- data/ext/nokogiri/xml_syntax_error.c +1 -1
- data/ext/nokogiri/xml_text.c +28 -14
- data/ext/nokogiri/xml_xpath_context.c +216 -136
- data/ext/nokogiri/xslt_stylesheet.c +118 -64
- data/gumbo-parser/Makefile +10 -0
- data/gumbo-parser/src/attribute.h +1 -1
- data/gumbo-parser/src/error.c +10 -6
- data/gumbo-parser/src/error.h +1 -1
- data/gumbo-parser/src/foreign_attrs.c +15 -16
- data/gumbo-parser/src/foreign_attrs.gperf +1 -1
- data/gumbo-parser/src/{gumbo.h → nokogiri_gumbo.h} +1 -0
- data/gumbo-parser/src/parser.c +21 -5
- data/gumbo-parser/src/replacement.h +1 -1
- data/gumbo-parser/src/string_buffer.h +1 -1
- data/gumbo-parser/src/string_piece.c +1 -1
- data/gumbo-parser/src/svg_attrs.c +2 -2
- data/gumbo-parser/src/svg_tags.c +2 -2
- data/gumbo-parser/src/tag.c +2 -1
- data/gumbo-parser/src/tag_lookup.c +7 -7
- data/gumbo-parser/src/tag_lookup.gperf +1 -0
- data/gumbo-parser/src/tag_lookup.h +1 -1
- data/gumbo-parser/src/token_buffer.h +1 -1
- data/gumbo-parser/src/tokenizer.c +1 -1
- data/gumbo-parser/src/tokenizer.h +1 -1
- data/gumbo-parser/src/utf8.c +1 -1
- data/gumbo-parser/src/utf8.h +1 -1
- data/gumbo-parser/src/util.c +1 -3
- data/gumbo-parser/src/util.h +4 -0
- data/gumbo-parser/src/vector.h +1 -1
- data/lib/nokogiri/css/node.rb +2 -2
- data/lib/nokogiri/css/xpath_visitor.rb +7 -5
- data/lib/nokogiri/css.rb +6 -0
- data/lib/nokogiri/decorators/slop.rb +1 -1
- data/lib/nokogiri/encoding_handler.rb +57 -0
- data/lib/nokogiri/extension.rb +4 -3
- data/lib/nokogiri/html4/document.rb +2 -121
- data/lib/nokogiri/html4/document_fragment.rb +1 -1
- data/lib/nokogiri/html4/element_description_defaults.rb +1827 -365
- data/lib/nokogiri/html4/encoding_reader.rb +121 -0
- data/lib/nokogiri/html4.rb +1 -0
- data/lib/nokogiri/html5/document.rb +113 -36
- data/lib/nokogiri/html5/document_fragment.rb +10 -3
- data/lib/nokogiri/html5/node.rb +8 -5
- data/lib/nokogiri/html5.rb +130 -216
- data/lib/nokogiri/jruby/dependencies.rb +1 -19
- data/lib/nokogiri/jruby/nokogiri_jars.rb +43 -0
- data/lib/nokogiri/version/constant.rb +1 -1
- data/lib/nokogiri/version/info.rb +11 -10
- data/lib/nokogiri/xml/attr.rb +49 -0
- data/lib/nokogiri/xml/attribute_decl.rb +4 -2
- data/lib/nokogiri/xml/builder.rb +1 -1
- data/lib/nokogiri/xml/document.rb +102 -55
- data/lib/nokogiri/xml/document_fragment.rb +50 -7
- data/lib/nokogiri/xml/element_content.rb +10 -2
- data/lib/nokogiri/xml/element_decl.rb +4 -2
- data/lib/nokogiri/xml/entity_decl.rb +4 -2
- data/lib/nokogiri/xml/namespace.rb +42 -0
- data/lib/nokogiri/xml/node/save_options.rb +14 -4
- data/lib/nokogiri/xml/node.rb +212 -48
- data/lib/nokogiri/xml/node_set.rb +88 -9
- data/lib/nokogiri/xml/parse_options.rb +129 -50
- data/lib/nokogiri/xml/pp/node.rb +28 -15
- data/lib/nokogiri/xml/processing_instruction.rb +2 -1
- data/lib/nokogiri/xml/sax/document.rb +1 -1
- data/lib/nokogiri/xml/sax/parser.rb +2 -3
- data/lib/nokogiri/xml/searchable.rb +18 -10
- data/lib/nokogiri/xslt.rb +74 -4
- data/lib/nokogiri.rb +15 -15
- data/lib/xsd/xmlparser/nokogiri.rb +4 -2
- data/patches/libxml2/0010-update-config.guess-and-config.sub-for-libxml2.patch +224 -0
- data/patches/libxml2/0011-rip-out-libxml2-s-libc_single_threaded-support.patch +30 -0
- data/patches/libxslt/0001-update-config.guess-and-config.sub-for-libxslt.patch +224 -0
- data/ports/archives/libxml2-2.11.7.tar.xz +0 -0
- data/ports/archives/libxslt-1.1.39.tar.xz +0 -0
- metadata +19 -242
- data/patches/libxml2/0004-use-glibc-strlen.patch +0 -53
- data/patches/libxml2/0005-avoid-isnan-isinf.patch +0 -81
- data/patches/libxml2/0006-update-automake-files-for-arm64.patch +0 -3040
- data/patches/libxml2/0008-htmlParseComment-handle-abruptly-closed-comments.patch +0 -61
- data/patches/libxslt/0001-update-automake-files-for-arm64.patch +0 -3037
- data/ports/archives/libxml2-2.9.14.tar.xz +0 -0
- data/ports/archives/libxslt-1.1.35.tar.xz +0 -0
@@ -6,17 +6,26 @@ VALUE cNokogiriXmlXpathContext;
|
|
6
6
|
* these constants have matching declarations in
|
7
7
|
* ext/java/nokogiri/internals/NokogiriNamespaceContext.java
|
8
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";
|
9
11
|
static const xmlChar *NOKOGIRI_BUILTIN_PREFIX = (const xmlChar *)"nokogiri-builtin";
|
10
12
|
static const xmlChar *NOKOGIRI_BUILTIN_URI = (const xmlChar *)"https://www.nokogiri.org/default_ns/ruby/builtins";
|
11
13
|
|
12
14
|
static void
|
13
|
-
|
15
|
+
xml_xpath_context_deallocate(void *data)
|
14
16
|
{
|
15
|
-
|
16
|
-
xmlXPathFreeContext(
|
17
|
-
NOKOGIRI_DEBUG_END(ctx);
|
17
|
+
xmlXPathContextPtr c_context = data;
|
18
|
+
xmlXPathFreeContext(c_context);
|
18
19
|
}
|
19
20
|
|
21
|
+
static const rb_data_type_t xml_xpath_context_type = {
|
22
|
+
.wrap_struct_name = "Nokogiri::XML::XPathContext",
|
23
|
+
.function = {
|
24
|
+
.dfree = xml_xpath_context_deallocate,
|
25
|
+
},
|
26
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
27
|
+
};
|
28
|
+
|
20
29
|
/* find a CSS class in an HTML element's `class` attribute */
|
21
30
|
static const xmlChar *
|
22
31
|
builtin_css_class(const xmlChar *str, const xmlChar *val)
|
@@ -87,7 +96,8 @@ xpath_builtin_css_class(xmlXPathParserContextPtr ctxt, int nargs)
|
|
87
96
|
}
|
88
97
|
|
89
98
|
|
90
|
-
/* xmlXPathFunction to select nodes whose local name matches, for HTML5 CSS queries that should
|
99
|
+
/* xmlXPathFunction to select nodes whose local name matches, for HTML5 CSS queries that should
|
100
|
+
* ignore namespaces */
|
91
101
|
static void
|
92
102
|
xpath_builtin_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
|
93
103
|
{
|
@@ -100,7 +110,10 @@ xpath_builtin_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
|
|
100
110
|
CHECK_TYPE(XPATH_STRING);
|
101
111
|
element_name = valuePop(ctxt);
|
102
112
|
|
103
|
-
valuePush(
|
113
|
+
valuePush(
|
114
|
+
ctxt,
|
115
|
+
xmlXPathNewBoolean(xmlStrEqual(ctxt->context->node->name, element_name->stringval))
|
116
|
+
);
|
104
117
|
|
105
118
|
xmlXPathFreeObject(element_name);
|
106
119
|
}
|
@@ -108,44 +121,61 @@ xpath_builtin_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
|
|
108
121
|
|
109
122
|
/*
|
110
123
|
* call-seq:
|
111
|
-
*
|
124
|
+
* register_ns(prefix, uri) → Nokogiri::XML::XPathContext
|
125
|
+
*
|
126
|
+
* Register the namespace with +prefix+ and +uri+ for use in future queries.
|
112
127
|
*
|
113
|
-
*
|
128
|
+
* [Returns] +self+
|
114
129
|
*/
|
115
130
|
static VALUE
|
116
|
-
|
131
|
+
rb_xml_xpath_context_register_ns(VALUE rb_context, VALUE prefix, VALUE uri)
|
117
132
|
{
|
118
|
-
xmlXPathContextPtr
|
119
|
-
Data_Get_Struct(self, xmlXPathContext, ctx);
|
133
|
+
xmlXPathContextPtr c_context;
|
120
134
|
|
121
|
-
|
135
|
+
TypedData_Get_Struct(
|
136
|
+
rb_context,
|
137
|
+
xmlXPathContext,
|
138
|
+
&xml_xpath_context_type,
|
139
|
+
c_context
|
140
|
+
);
|
141
|
+
|
142
|
+
xmlXPathRegisterNs(c_context,
|
122
143
|
(const xmlChar *)StringValueCStr(prefix),
|
123
144
|
(const xmlChar *)StringValueCStr(uri)
|
124
145
|
);
|
125
|
-
return
|
146
|
+
return rb_context;
|
126
147
|
}
|
127
148
|
|
128
149
|
/*
|
129
150
|
* call-seq:
|
130
|
-
*
|
151
|
+
* register_variable(name, value) → Nokogiri::XML::XPathContext
|
152
|
+
*
|
153
|
+
* Register the variable +name+ with +value+ for use in future queries.
|
131
154
|
*
|
132
|
-
*
|
155
|
+
* [Returns] +self+
|
133
156
|
*/
|
134
157
|
static VALUE
|
135
|
-
|
158
|
+
rb_xml_xpath_context_register_variable(VALUE rb_context, VALUE name, VALUE value)
|
136
159
|
{
|
137
|
-
xmlXPathContextPtr
|
160
|
+
xmlXPathContextPtr c_context;
|
138
161
|
xmlXPathObjectPtr xmlValue;
|
139
|
-
|
162
|
+
|
163
|
+
TypedData_Get_Struct(
|
164
|
+
rb_context,
|
165
|
+
xmlXPathContext,
|
166
|
+
&xml_xpath_context_type,
|
167
|
+
c_context
|
168
|
+
);
|
140
169
|
|
141
170
|
xmlValue = xmlXPathNewCString(StringValueCStr(value));
|
142
171
|
|
143
|
-
xmlXPathRegisterVariable(
|
144
|
-
|
145
|
-
|
146
|
-
|
172
|
+
xmlXPathRegisterVariable(
|
173
|
+
c_context,
|
174
|
+
(const xmlChar *)StringValueCStr(name),
|
175
|
+
xmlValue
|
176
|
+
);
|
147
177
|
|
148
|
-
return
|
178
|
+
return rb_context;
|
149
179
|
}
|
150
180
|
|
151
181
|
|
@@ -154,28 +184,30 @@ register_variable(VALUE self, VALUE name, VALUE value)
|
|
154
184
|
* returns Qundef if no conversion was possible.
|
155
185
|
*/
|
156
186
|
static VALUE
|
157
|
-
xpath2ruby(xmlXPathObjectPtr
|
187
|
+
xpath2ruby(xmlXPathObjectPtr c_xpath_object, xmlXPathContextPtr c_context)
|
158
188
|
{
|
159
|
-
VALUE
|
189
|
+
VALUE rb_retval;
|
160
190
|
|
161
|
-
assert(
|
162
|
-
assert(DOC_RUBY_OBJECT_TEST(
|
191
|
+
assert(c_context->doc);
|
192
|
+
assert(DOC_RUBY_OBJECT_TEST(c_context->doc));
|
163
193
|
|
164
|
-
switch (
|
194
|
+
switch (c_xpath_object->type) {
|
165
195
|
case XPATH_STRING:
|
166
|
-
|
167
|
-
xmlFree(
|
168
|
-
return
|
196
|
+
rb_retval = NOKOGIRI_STR_NEW2(c_xpath_object->stringval);
|
197
|
+
xmlFree(c_xpath_object->stringval);
|
198
|
+
return rb_retval;
|
169
199
|
|
170
200
|
case XPATH_NODESET:
|
171
|
-
return noko_xml_node_set_wrap(
|
172
|
-
|
201
|
+
return noko_xml_node_set_wrap(
|
202
|
+
c_xpath_object->nodesetval,
|
203
|
+
DOC_RUBY_OBJECT(c_context->doc)
|
204
|
+
);
|
173
205
|
|
174
206
|
case XPATH_NUMBER:
|
175
|
-
return rb_float_new(
|
207
|
+
return rb_float_new(c_xpath_object->floatval);
|
176
208
|
|
177
209
|
case XPATH_BOOLEAN:
|
178
|
-
return (
|
210
|
+
return (c_xpath_object->boolval == 1) ? Qtrue : Qfalse;
|
179
211
|
|
180
212
|
default:
|
181
213
|
return Qundef;
|
@@ -183,75 +215,77 @@ xpath2ruby(xmlXPathObjectPtr xobj, xmlXPathContextPtr xctx)
|
|
183
215
|
}
|
184
216
|
|
185
217
|
void
|
186
|
-
Nokogiri_marshal_xpath_funcall_and_return_values(
|
187
|
-
|
218
|
+
Nokogiri_marshal_xpath_funcall_and_return_values(
|
219
|
+
xmlXPathParserContextPtr ctxt,
|
220
|
+
int argc,
|
221
|
+
VALUE rb_xpath_handler,
|
222
|
+
const char *method_name
|
223
|
+
)
|
188
224
|
{
|
189
|
-
VALUE
|
225
|
+
VALUE rb_retval;
|
190
226
|
VALUE *argv;
|
191
|
-
VALUE
|
192
|
-
xmlNodeSetPtr
|
193
|
-
xmlXPathObjectPtr
|
227
|
+
VALUE rb_node_set = Qnil;
|
228
|
+
xmlNodeSetPtr c_node_set = NULL;
|
229
|
+
xmlXPathObjectPtr c_xpath_object;
|
194
230
|
|
195
|
-
assert(
|
196
|
-
assert(DOC_RUBY_OBJECT_TEST(
|
231
|
+
assert(ctxt->context->doc);
|
232
|
+
assert(DOC_RUBY_OBJECT_TEST(ctxt->context->doc));
|
197
233
|
|
198
|
-
argv = (VALUE *)
|
199
|
-
for (int j = 0 ; j <
|
234
|
+
argv = (VALUE *)ruby_xcalloc((size_t)argc, sizeof(VALUE));
|
235
|
+
for (int j = 0 ; j < argc ; ++j) {
|
200
236
|
rb_gc_register_address(&argv[j]);
|
201
237
|
}
|
202
238
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
obj = valuePop(ctx);
|
207
|
-
argv[j] = xpath2ruby(obj, ctx->context);
|
239
|
+
for (int j = argc - 1 ; j >= 0 ; --j) {
|
240
|
+
c_xpath_object = valuePop(ctxt);
|
241
|
+
argv[j] = xpath2ruby(c_xpath_object, ctxt->context);
|
208
242
|
if (argv[j] == Qundef) {
|
209
|
-
argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(
|
243
|
+
argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(c_xpath_object));
|
210
244
|
}
|
211
|
-
xmlXPathFreeNodeSetList(
|
245
|
+
xmlXPathFreeNodeSetList(c_xpath_object);
|
212
246
|
}
|
213
247
|
|
214
|
-
|
248
|
+
rb_retval = rb_funcall2(
|
249
|
+
rb_xpath_handler,
|
250
|
+
rb_intern((const char *)method_name),
|
251
|
+
argc,
|
252
|
+
argv
|
253
|
+
);
|
215
254
|
|
216
|
-
for (int j = 0 ; j <
|
255
|
+
for (int j = 0 ; j < argc ; ++j) {
|
217
256
|
rb_gc_unregister_address(&argv[j]);
|
218
257
|
}
|
219
|
-
|
258
|
+
ruby_xfree(argv);
|
220
259
|
|
221
|
-
switch (TYPE(
|
260
|
+
switch (TYPE(rb_retval)) {
|
222
261
|
case T_FLOAT:
|
223
262
|
case T_BIGNUM:
|
224
263
|
case T_FIXNUM:
|
225
|
-
xmlXPathReturnNumber(
|
264
|
+
xmlXPathReturnNumber(ctxt, NUM2DBL(rb_retval));
|
226
265
|
break;
|
227
266
|
case T_STRING:
|
228
|
-
xmlXPathReturnString(
|
229
|
-
ctx,
|
230
|
-
xmlCharStrdup(StringValueCStr(result))
|
231
|
-
);
|
267
|
+
xmlXPathReturnString(ctxt, xmlCharStrdup(StringValueCStr(rb_retval)));
|
232
268
|
break;
|
233
269
|
case T_TRUE:
|
234
|
-
xmlXPathReturnTrue(
|
270
|
+
xmlXPathReturnTrue(ctxt);
|
235
271
|
break;
|
236
272
|
case T_FALSE:
|
237
|
-
xmlXPathReturnFalse(
|
273
|
+
xmlXPathReturnFalse(ctxt);
|
238
274
|
break;
|
239
275
|
case T_NIL:
|
240
276
|
break;
|
241
277
|
case T_ARRAY: {
|
242
|
-
VALUE
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
Data_Get_Struct(node_set, xmlNodeSet, xml_node_set);
|
247
|
-
xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
|
278
|
+
VALUE construct_args[2] = { DOC_RUBY_OBJECT(ctxt->context->doc), rb_retval };
|
279
|
+
rb_node_set = rb_class_new_instance(2, construct_args, cNokogiriXmlNodeSet);
|
280
|
+
c_node_set = noko_xml_node_set_unwrap(rb_node_set);
|
281
|
+
xmlXPathReturnNodeSet(ctxt, xmlXPathNodeSetMerge(NULL, c_node_set));
|
248
282
|
}
|
249
283
|
break;
|
250
284
|
case T_DATA:
|
251
|
-
if (rb_obj_is_kind_of(
|
252
|
-
|
285
|
+
if (rb_obj_is_kind_of(rb_retval, cNokogiriXmlNodeSet)) {
|
286
|
+
c_node_set = noko_xml_node_set_unwrap(rb_retval);
|
253
287
|
/* Copy the node set, otherwise it will get GC'd. */
|
254
|
-
xmlXPathReturnNodeSet(
|
288
|
+
xmlXPathReturnNodeSet(ctxt, xmlXPathNodeSetMerge(NULL, c_node_set));
|
255
289
|
break;
|
256
290
|
}
|
257
291
|
default:
|
@@ -260,65 +294,95 @@ Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr ctx, i
|
|
260
294
|
}
|
261
295
|
|
262
296
|
static void
|
263
|
-
|
297
|
+
method_caller(xmlXPathParserContextPtr ctxt, int argc)
|
264
298
|
{
|
265
|
-
VALUE
|
266
|
-
const char *
|
267
|
-
|
268
|
-
assert(
|
269
|
-
assert(
|
270
|
-
assert(
|
271
|
-
assert(
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
Nokogiri_marshal_xpath_funcall_and_return_values(
|
299
|
+
VALUE rb_xpath_handler = Qnil;
|
300
|
+
const char *method_name = NULL ;
|
301
|
+
|
302
|
+
assert(ctxt);
|
303
|
+
assert(ctxt->context);
|
304
|
+
assert(ctxt->context->userData);
|
305
|
+
assert(ctxt->context->function);
|
306
|
+
|
307
|
+
rb_xpath_handler = (VALUE)(ctxt->context->userData);
|
308
|
+
method_name = (const char *)(ctxt->context->function);
|
309
|
+
|
310
|
+
Nokogiri_marshal_xpath_funcall_and_return_values(
|
311
|
+
ctxt,
|
312
|
+
argc,
|
313
|
+
rb_xpath_handler,
|
314
|
+
method_name
|
315
|
+
);
|
277
316
|
}
|
278
317
|
|
279
318
|
static xmlXPathFunction
|
280
|
-
|
281
|
-
const xmlChar *name,
|
282
|
-
const xmlChar *ns_uri)
|
319
|
+
handler_lookup(void *data, const xmlChar *c_name, const xmlChar *c_ns_uri)
|
283
320
|
{
|
284
|
-
VALUE
|
285
|
-
if (rb_respond_to(
|
286
|
-
|
321
|
+
VALUE rb_handler = (VALUE)data;
|
322
|
+
if (rb_respond_to(rb_handler, rb_intern((const char *)c_name))) {
|
323
|
+
if (c_ns_uri == NULL) {
|
324
|
+
NOKO_WARN_DEPRECATION(
|
325
|
+
"A custom XPath or CSS handler function named '%s' is being invoked without a namespace."
|
326
|
+
" Please update your query to reference this function as 'nokogiri:%s'."
|
327
|
+
" Invoking custom handler functions without a namespace is deprecated and support will be removed in a future release of Nokogiri.",
|
328
|
+
c_name, c_name);
|
329
|
+
}
|
330
|
+
return method_caller;
|
287
331
|
}
|
288
332
|
|
289
333
|
return NULL;
|
290
334
|
}
|
291
335
|
|
292
|
-
|
336
|
+
PRINTFLIKE_DECL(2, 3)
|
293
337
|
static void
|
294
|
-
|
338
|
+
generic_exception_pusher(void *data, const char *msg, ...)
|
295
339
|
{
|
296
|
-
|
340
|
+
VALUE rb_errors = (VALUE)data;
|
341
|
+
VALUE rb_message;
|
342
|
+
VALUE rb_exception;
|
297
343
|
|
344
|
+
Check_Type(rb_errors, T_ARRAY);
|
345
|
+
|
346
|
+
#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES
|
347
|
+
/* It is not currently possible to pass var args from native
|
348
|
+
functions to sulong, so we work around the issue here. */
|
349
|
+
rb_message = rb_sprintf("generic_exception_pusher: %s", msg);
|
350
|
+
#else
|
298
351
|
va_list args;
|
299
352
|
va_start(args, msg);
|
300
|
-
|
353
|
+
rb_message = rb_vsprintf(msg, args);
|
301
354
|
va_end(args);
|
355
|
+
#endif
|
302
356
|
|
303
|
-
|
357
|
+
rb_exception = rb_exc_new_str(cNokogiriXmlXpathSyntaxError, rb_message);
|
358
|
+
rb_ary_push(rb_errors, rb_exception);
|
304
359
|
}
|
305
360
|
|
306
361
|
/*
|
307
362
|
* call-seq:
|
308
|
-
*
|
363
|
+
* evaluate(search_path, handler = nil) → Object
|
364
|
+
*
|
365
|
+
* Evaluate the +search_path+ query.
|
309
366
|
*
|
310
|
-
*
|
367
|
+
* [Returns] an object of the appropriate type for the query, which could be +NodeSet+, a +String+,
|
368
|
+
* a +Float+, or a boolean.
|
311
369
|
*/
|
312
370
|
static VALUE
|
313
|
-
|
371
|
+
rb_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE rb_context)
|
314
372
|
{
|
315
373
|
VALUE search_path, xpath_handler;
|
316
374
|
VALUE retval = Qnil;
|
317
|
-
xmlXPathContextPtr
|
375
|
+
xmlXPathContextPtr c_context;
|
318
376
|
xmlXPathObjectPtr xpath;
|
319
377
|
xmlChar *query;
|
378
|
+
VALUE errors = rb_ary_new();
|
320
379
|
|
321
|
-
|
380
|
+
TypedData_Get_Struct(
|
381
|
+
rb_context,
|
382
|
+
xmlXPathContext,
|
383
|
+
&xml_xpath_context_type,
|
384
|
+
c_context
|
385
|
+
);
|
322
386
|
|
323
387
|
if (rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1) {
|
324
388
|
xpath_handler = Qnil;
|
@@ -328,29 +392,29 @@ evaluate(int argc, VALUE *argv, VALUE self)
|
|
328
392
|
|
329
393
|
if (Qnil != xpath_handler) {
|
330
394
|
/* FIXME: not sure if this is the correct place to shove private data. */
|
331
|
-
|
332
|
-
xmlXPathRegisterFuncLookup(
|
395
|
+
c_context->userData = (void *)xpath_handler;
|
396
|
+
xmlXPathRegisterFuncLookup(
|
397
|
+
c_context,
|
398
|
+
handler_lookup,
|
399
|
+
(void *)xpath_handler
|
400
|
+
);
|
333
401
|
}
|
334
402
|
|
335
|
-
|
336
|
-
|
403
|
+
xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);
|
404
|
+
xmlSetGenericErrorFunc((void *)errors, generic_exception_pusher);
|
337
405
|
|
338
|
-
|
339
|
-
/* when there is a non existent function. */
|
340
|
-
xmlSetGenericErrorFunc(NULL, xpath_generic_exception_handler);
|
406
|
+
xpath = xmlXPathEvalExpression(query, c_context);
|
341
407
|
|
342
|
-
xpath = xmlXPathEvalExpression(query, ctx);
|
343
408
|
xmlSetStructuredErrorFunc(NULL, NULL);
|
344
409
|
xmlSetGenericErrorFunc(NULL, NULL);
|
345
410
|
|
346
411
|
if (xpath == NULL) {
|
347
|
-
|
348
|
-
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
412
|
+
rb_exc_raise(rb_ary_entry(errors, 0));
|
349
413
|
}
|
350
414
|
|
351
|
-
retval = xpath2ruby(xpath,
|
415
|
+
retval = xpath2ruby(xpath, c_context);
|
352
416
|
if (retval == Qundef) {
|
353
|
-
retval = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(
|
417
|
+
retval = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(c_context->doc));
|
354
418
|
}
|
355
419
|
|
356
420
|
xmlXPathFreeNodeSetList(xpath);
|
@@ -360,47 +424,63 @@ evaluate(int argc, VALUE *argv, VALUE self)
|
|
360
424
|
|
361
425
|
/*
|
362
426
|
* call-seq:
|
363
|
-
*
|
427
|
+
* new(node)
|
364
428
|
*
|
365
|
-
* Create a new XPathContext with +node+ as the
|
429
|
+
* Create a new XPathContext with +node+ as the context node.
|
366
430
|
*/
|
367
431
|
static VALUE
|
368
|
-
|
432
|
+
rb_xml_xpath_context_new(VALUE klass, VALUE rb_node)
|
369
433
|
{
|
370
434
|
xmlNodePtr node;
|
371
|
-
xmlXPathContextPtr
|
372
|
-
VALUE
|
435
|
+
xmlXPathContextPtr c_context;
|
436
|
+
VALUE rb_context;
|
373
437
|
|
374
|
-
Noko_Node_Get_Struct(
|
438
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, node);
|
375
439
|
|
440
|
+
#if LIBXML_VERSION < 21000
|
441
|
+
/* deprecated in 40483d0 */
|
376
442
|
xmlXPathInit();
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
xmlXPathRegisterFuncNS(
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
443
|
+
#endif
|
444
|
+
|
445
|
+
c_context = xmlXPathNewContext(node->doc);
|
446
|
+
c_context->node = node;
|
447
|
+
|
448
|
+
xmlXPathRegisterNs(c_context, NOKOGIRI_PREFIX, NOKOGIRI_URI);
|
449
|
+
xmlXPathRegisterNs(c_context, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
|
450
|
+
xmlXPathRegisterFuncNS(
|
451
|
+
c_context,
|
452
|
+
(const xmlChar *)"css-class",
|
453
|
+
NOKOGIRI_BUILTIN_URI,
|
454
|
+
xpath_builtin_css_class
|
455
|
+
);
|
456
|
+
xmlXPathRegisterFuncNS(
|
457
|
+
c_context,
|
458
|
+
(const xmlChar *)"local-name-is",
|
459
|
+
NOKOGIRI_BUILTIN_URI,
|
460
|
+
xpath_builtin_local_name_is
|
461
|
+
);
|
462
|
+
|
463
|
+
rb_context = TypedData_Wrap_Struct(
|
464
|
+
klass,
|
465
|
+
&xml_xpath_context_type,
|
466
|
+
c_context
|
467
|
+
);
|
468
|
+
return rb_context;
|
389
469
|
}
|
390
470
|
|
391
471
|
void
|
392
472
|
noko_init_xml_xpath_context(void)
|
393
473
|
{
|
394
474
|
/*
|
395
|
-
* XPathContext is the entry point for searching a Document by using XPath.
|
475
|
+
* XPathContext is the entry point for searching a +Document+ by using XPath.
|
396
476
|
*/
|
397
477
|
cNokogiriXmlXpathContext = rb_define_class_under(mNokogiriXml, "XPathContext", rb_cObject);
|
398
478
|
|
399
479
|
rb_undef_alloc_func(cNokogiriXmlXpathContext);
|
400
480
|
|
401
|
-
rb_define_singleton_method(cNokogiriXmlXpathContext, "new",
|
481
|
+
rb_define_singleton_method(cNokogiriXmlXpathContext, "new", rb_xml_xpath_context_new, 1);
|
402
482
|
|
403
|
-
rb_define_method(cNokogiriXmlXpathContext, "evaluate",
|
404
|
-
rb_define_method(cNokogiriXmlXpathContext, "register_variable",
|
405
|
-
rb_define_method(cNokogiriXmlXpathContext, "register_ns",
|
483
|
+
rb_define_method(cNokogiriXmlXpathContext, "evaluate", rb_xml_xpath_context_evaluate, -1);
|
484
|
+
rb_define_method(cNokogiriXmlXpathContext, "register_variable", rb_xml_xpath_context_register_variable, 2);
|
485
|
+
rb_define_method(cNokogiriXmlXpathContext, "register_ns", rb_xml_xpath_context_register_ns, 2);
|
406
486
|
}
|