nokogiri 1.13.6 → 1.16.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +43 -0
- data/LICENSE-DEPENDENCIES.md +830 -509
- data/LICENSE.md +1 -1
- data/README.md +21 -11
- data/dependencies.yml +34 -15
- data/ext/nokogiri/extconf.rb +167 -48
- data/ext/nokogiri/gumbo.c +21 -11
- 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 +4 -4
- data/ext/nokogiri/nokogiri.c +84 -75
- data/ext/nokogiri/nokogiri.h +46 -16
- data/ext/nokogiri/test_global_handlers.c +2 -2
- data/ext/nokogiri/xml_attr.c +3 -3
- data/ext/nokogiri/xml_attribute_decl.c +5 -5
- data/ext/nokogiri/xml_cdata.c +31 -18
- data/ext/nokogiri/xml_comment.c +2 -2
- data/ext/nokogiri/xml_document.c +135 -38
- data/ext/nokogiri/xml_document_fragment.c +2 -2
- data/ext/nokogiri/xml_dtd.c +9 -9
- data/ext/nokogiri/xml_element_content.c +34 -31
- data/ext/nokogiri/xml_element_decl.c +10 -10
- data/ext/nokogiri/xml_encoding_handler.c +15 -7
- data/ext/nokogiri/xml_entity_decl.c +6 -6
- data/ext/nokogiri/xml_entity_reference.c +2 -2
- data/ext/nokogiri/xml_namespace.c +75 -14
- data/ext/nokogiri/xml_node.c +365 -87
- data/ext/nokogiri/xml_node_set.c +129 -111
- data/ext/nokogiri/xml_processing_instruction.c +2 -2
- data/ext/nokogiri/xml_reader.c +126 -64
- data/ext/nokogiri/xml_relax_ng.c +67 -82
- data/ext/nokogiri/xml_sax_parser.c +45 -20
- data/ext/nokogiri/xml_sax_parser_context.c +50 -30
- data/ext/nokogiri/xml_sax_push_parser.c +31 -12
- data/ext/nokogiri/xml_schema.c +95 -118
- data/ext/nokogiri/xml_syntax_error.c +4 -4
- data/ext/nokogiri/xml_text.c +27 -14
- data/ext/nokogiri/xml_xpath_context.c +213 -136
- data/ext/nokogiri/xslt_stylesheet.c +126 -67
- data/gumbo-parser/Makefile +28 -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 +29 -10
- 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 +2 -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/parser_extras.rb +1 -1
- data/lib/nokogiri/css/xpath_visitor.rb +8 -26
- 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 +3 -122
- 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 +74 -226
- 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 +16 -14
- 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 +103 -56
- 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 +41 -0
- data/lib/nokogiri/xml/node/save_options.rb +14 -4
- data/lib/nokogiri/xml/node.rb +241 -70
- data/lib/nokogiri/xml/node_set.rb +90 -11
- 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/reader.rb +16 -17
- data/lib/nokogiri/xml/sax/document.rb +1 -1
- data/lib/nokogiri/xml/sax/parser.rb +2 -3
- data/lib/nokogiri/xml/searchable.rb +21 -13
- data/lib/nokogiri/xml/syntax_error.rb +1 -1
- data/lib/nokogiri/xml.rb +1 -1
- data/lib/nokogiri/xslt/stylesheet.rb +29 -7
- data/lib/nokogiri/xslt.rb +75 -5
- 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.12.9.tar.xz +0 -0
- data/ports/archives/libxslt-1.1.39.tar.xz +0 -0
- metadata +21 -248
- 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,92 @@ 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("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.",
|
325
|
+
c_name, c_name); // deprecated in v1.15.0, remove in v1.17.0
|
326
|
+
}
|
327
|
+
return method_caller;
|
287
328
|
}
|
288
329
|
|
289
330
|
return NULL;
|
290
331
|
}
|
291
332
|
|
292
|
-
|
333
|
+
PRINTFLIKE_DECL(2, 3)
|
293
334
|
static void
|
294
|
-
|
335
|
+
generic_exception_pusher(void *data, const char *msg, ...)
|
295
336
|
{
|
296
|
-
|
337
|
+
VALUE rb_errors = (VALUE)data;
|
338
|
+
VALUE rb_message;
|
339
|
+
VALUE rb_exception;
|
297
340
|
|
341
|
+
Check_Type(rb_errors, T_ARRAY);
|
342
|
+
|
343
|
+
#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES
|
344
|
+
/* It is not currently possible to pass var args from native
|
345
|
+
functions to sulong, so we work around the issue here. */
|
346
|
+
rb_message = rb_sprintf("generic_exception_pusher: %s", msg);
|
347
|
+
#else
|
298
348
|
va_list args;
|
299
349
|
va_start(args, msg);
|
300
|
-
|
350
|
+
rb_message = rb_vsprintf(msg, args);
|
301
351
|
va_end(args);
|
352
|
+
#endif
|
302
353
|
|
303
|
-
|
354
|
+
rb_exception = rb_exc_new_str(cNokogiriXmlXpathSyntaxError, rb_message);
|
355
|
+
rb_ary_push(rb_errors, rb_exception);
|
304
356
|
}
|
305
357
|
|
306
358
|
/*
|
307
359
|
* call-seq:
|
308
|
-
*
|
360
|
+
* evaluate(search_path, handler = nil) → Object
|
361
|
+
*
|
362
|
+
* Evaluate the +search_path+ query.
|
309
363
|
*
|
310
|
-
*
|
364
|
+
* [Returns] an object of the appropriate type for the query, which could be +NodeSet+, a +String+,
|
365
|
+
* a +Float+, or a boolean.
|
311
366
|
*/
|
312
367
|
static VALUE
|
313
|
-
|
368
|
+
rb_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE rb_context)
|
314
369
|
{
|
315
370
|
VALUE search_path, xpath_handler;
|
316
371
|
VALUE retval = Qnil;
|
317
|
-
xmlXPathContextPtr
|
372
|
+
xmlXPathContextPtr c_context;
|
318
373
|
xmlXPathObjectPtr xpath;
|
319
374
|
xmlChar *query;
|
375
|
+
VALUE errors = rb_ary_new();
|
320
376
|
|
321
|
-
|
377
|
+
TypedData_Get_Struct(
|
378
|
+
rb_context,
|
379
|
+
xmlXPathContext,
|
380
|
+
&xml_xpath_context_type,
|
381
|
+
c_context
|
382
|
+
);
|
322
383
|
|
323
384
|
if (rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1) {
|
324
385
|
xpath_handler = Qnil;
|
@@ -328,29 +389,29 @@ evaluate(int argc, VALUE *argv, VALUE self)
|
|
328
389
|
|
329
390
|
if (Qnil != xpath_handler) {
|
330
391
|
/* FIXME: not sure if this is the correct place to shove private data. */
|
331
|
-
|
332
|
-
xmlXPathRegisterFuncLookup(
|
392
|
+
c_context->userData = (void *)xpath_handler;
|
393
|
+
xmlXPathRegisterFuncLookup(
|
394
|
+
c_context,
|
395
|
+
handler_lookup,
|
396
|
+
(void *)xpath_handler
|
397
|
+
);
|
333
398
|
}
|
334
399
|
|
335
|
-
|
336
|
-
|
400
|
+
xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);
|
401
|
+
xmlSetGenericErrorFunc((void *)errors, generic_exception_pusher);
|
337
402
|
|
338
|
-
|
339
|
-
/* when there is a non existent function. */
|
340
|
-
xmlSetGenericErrorFunc(NULL, xpath_generic_exception_handler);
|
403
|
+
xpath = xmlXPathEvalExpression(query, c_context);
|
341
404
|
|
342
|
-
xpath = xmlXPathEvalExpression(query, ctx);
|
343
405
|
xmlSetStructuredErrorFunc(NULL, NULL);
|
344
406
|
xmlSetGenericErrorFunc(NULL, NULL);
|
345
407
|
|
346
408
|
if (xpath == NULL) {
|
347
|
-
|
348
|
-
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
409
|
+
rb_exc_raise(rb_ary_entry(errors, 0));
|
349
410
|
}
|
350
411
|
|
351
|
-
retval = xpath2ruby(xpath,
|
412
|
+
retval = xpath2ruby(xpath, c_context);
|
352
413
|
if (retval == Qundef) {
|
353
|
-
retval = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(
|
414
|
+
retval = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(c_context->doc));
|
354
415
|
}
|
355
416
|
|
356
417
|
xmlXPathFreeNodeSetList(xpath);
|
@@ -360,47 +421,63 @@ evaluate(int argc, VALUE *argv, VALUE self)
|
|
360
421
|
|
361
422
|
/*
|
362
423
|
* call-seq:
|
363
|
-
*
|
424
|
+
* new(node)
|
364
425
|
*
|
365
|
-
* Create a new XPathContext with +node+ as the
|
426
|
+
* Create a new XPathContext with +node+ as the context node.
|
366
427
|
*/
|
367
428
|
static VALUE
|
368
|
-
|
429
|
+
rb_xml_xpath_context_new(VALUE klass, VALUE rb_node)
|
369
430
|
{
|
370
431
|
xmlNodePtr node;
|
371
|
-
xmlXPathContextPtr
|
372
|
-
VALUE
|
432
|
+
xmlXPathContextPtr c_context;
|
433
|
+
VALUE rb_context;
|
373
434
|
|
374
|
-
|
435
|
+
Noko_Node_Get_Struct(rb_node, xmlNode, node);
|
375
436
|
|
437
|
+
#if LIBXML_VERSION < 21000
|
438
|
+
/* deprecated in 40483d0 */
|
376
439
|
xmlXPathInit();
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
xmlXPathRegisterFuncNS(
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
440
|
+
#endif
|
441
|
+
|
442
|
+
c_context = xmlXPathNewContext(node->doc);
|
443
|
+
c_context->node = node;
|
444
|
+
|
445
|
+
xmlXPathRegisterNs(c_context, NOKOGIRI_PREFIX, NOKOGIRI_URI);
|
446
|
+
xmlXPathRegisterNs(c_context, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
|
447
|
+
xmlXPathRegisterFuncNS(
|
448
|
+
c_context,
|
449
|
+
(const xmlChar *)"css-class",
|
450
|
+
NOKOGIRI_BUILTIN_URI,
|
451
|
+
xpath_builtin_css_class
|
452
|
+
);
|
453
|
+
xmlXPathRegisterFuncNS(
|
454
|
+
c_context,
|
455
|
+
(const xmlChar *)"local-name-is",
|
456
|
+
NOKOGIRI_BUILTIN_URI,
|
457
|
+
xpath_builtin_local_name_is
|
458
|
+
);
|
459
|
+
|
460
|
+
rb_context = TypedData_Wrap_Struct(
|
461
|
+
klass,
|
462
|
+
&xml_xpath_context_type,
|
463
|
+
c_context
|
464
|
+
);
|
465
|
+
return rb_context;
|
389
466
|
}
|
390
467
|
|
391
468
|
void
|
392
469
|
noko_init_xml_xpath_context(void)
|
393
470
|
{
|
394
471
|
/*
|
395
|
-
* XPathContext is the entry point for searching a Document by using XPath.
|
472
|
+
* XPathContext is the entry point for searching a +Document+ by using XPath.
|
396
473
|
*/
|
397
474
|
cNokogiriXmlXpathContext = rb_define_class_under(mNokogiriXml, "XPathContext", rb_cObject);
|
398
475
|
|
399
476
|
rb_undef_alloc_func(cNokogiriXmlXpathContext);
|
400
477
|
|
401
|
-
rb_define_singleton_method(cNokogiriXmlXpathContext, "new",
|
478
|
+
rb_define_singleton_method(cNokogiriXmlXpathContext, "new", rb_xml_xpath_context_new, 1);
|
402
479
|
|
403
|
-
rb_define_method(cNokogiriXmlXpathContext, "evaluate",
|
404
|
-
rb_define_method(cNokogiriXmlXpathContext, "register_variable",
|
405
|
-
rb_define_method(cNokogiriXmlXpathContext, "register_ns",
|
480
|
+
rb_define_method(cNokogiriXmlXpathContext, "evaluate", rb_xml_xpath_context_evaluate, -1);
|
481
|
+
rb_define_method(cNokogiriXmlXpathContext, "register_variable", rb_xml_xpath_context_register_variable, 2);
|
482
|
+
rb_define_method(cNokogiriXmlXpathContext, "register_ns", rb_xml_xpath_context_register_ns, 2);
|
406
483
|
}
|