nokogiri 1.13.10-x64-mingw-ucrt → 1.14.0.rc1-x64-mingw-ucrt
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.
- checksums.yaml +4 -4
- data/Gemfile +33 -0
- data/LICENSE-DEPENDENCIES.md +830 -509
- data/README.md +18 -11
- data/dependencies.yml +25 -7
- data/ext/nokogiri/extconf.rb +79 -20
- data/ext/nokogiri/gumbo.c +19 -9
- data/ext/nokogiri/html4_document.c +1 -1
- data/ext/nokogiri/html4_entity_lookup.c +1 -1
- data/ext/nokogiri/html4_sax_parser_context.c +0 -5
- data/ext/nokogiri/nokogiri.c +32 -51
- data/ext/nokogiri/nokogiri.h +17 -14
- data/ext/nokogiri/xml_attribute_decl.c +1 -1
- data/ext/nokogiri/xml_cdata.c +1 -1
- data/ext/nokogiri/xml_document.c +16 -11
- data/ext/nokogiri/xml_element_content.c +2 -2
- data/ext/nokogiri/xml_element_decl.c +1 -1
- data/ext/nokogiri/xml_encoding_handler.c +2 -2
- data/ext/nokogiri/xml_namespace.c +38 -8
- data/ext/nokogiri/xml_node.c +286 -26
- data/ext/nokogiri/xml_node_set.c +0 -2
- data/ext/nokogiri/xml_reader.c +40 -20
- data/ext/nokogiri/xml_relax_ng.c +0 -2
- data/ext/nokogiri/xml_sax_parser.c +22 -16
- data/ext/nokogiri/xml_sax_parser_context.c +0 -5
- data/ext/nokogiri/xml_sax_push_parser.c +0 -2
- data/ext/nokogiri/xml_schema.c +0 -2
- data/ext/nokogiri/xml_xpath_context.c +87 -83
- data/ext/nokogiri/xslt_stylesheet.c +14 -13
- data/gumbo-parser/Makefile +10 -0
- data/lib/nokogiri/3.1/nokogiri.so +0 -0
- data/lib/nokogiri/3.2/nokogiri.so +0 -0
- data/lib/nokogiri/css/node.rb +2 -2
- data/lib/nokogiri/css/xpath_visitor.rb +3 -1
- data/lib/nokogiri/css.rb +6 -0
- data/lib/nokogiri/encoding_handler.rb +57 -0
- data/lib/nokogiri/extension.rb +3 -2
- data/lib/nokogiri/html4/document.rb +2 -121
- data/lib/nokogiri/html4/element_description_defaults.rb +6 -12
- 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 +9 -2
- data/lib/nokogiri/html5/node.rb +3 -5
- data/lib/nokogiri/html5.rb +127 -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/builder.rb +1 -1
- data/lib/nokogiri/xml/document.rb +102 -54
- data/lib/nokogiri/xml/document_fragment.rb +49 -6
- data/lib/nokogiri/xml/namespace.rb +42 -0
- data/lib/nokogiri/xml/node/save_options.rb +4 -2
- data/lib/nokogiri/xml/node.rb +190 -35
- data/lib/nokogiri/xml/node_set.rb +87 -9
- data/lib/nokogiri/xml/parse_options.rb +127 -48
- data/lib/nokogiri/xml/pp/node.rb +6 -4
- data/lib/nokogiri/xml/processing_instruction.rb +2 -1
- data/lib/nokogiri/xml/sax/parser.rb +2 -3
- data/lib/nokogiri/xslt.rb +1 -1
- data/lib/nokogiri.rb +3 -11
- metadata +14 -248
data/ext/nokogiri/xml_node_set.c
CHANGED
@@ -88,13 +88,11 @@ deallocate(xmlNodeSetPtr node_set)
|
|
88
88
|
* For reasons outlined in xml_namespace.c, here we reproduce xmlXPathFreeNodeSet() except for the
|
89
89
|
* offending call to xmlXPathNodeSetFreeNs().
|
90
90
|
*/
|
91
|
-
NOKOGIRI_DEBUG_START(node_set) ;
|
92
91
|
if (node_set->nodeTab != NULL) {
|
93
92
|
xmlFree(node_set->nodeTab);
|
94
93
|
}
|
95
94
|
|
96
95
|
xmlFree(node_set);
|
97
|
-
NOKOGIRI_DEBUG_END(node_set) ;
|
98
96
|
}
|
99
97
|
|
100
98
|
|
data/ext/nokogiri/xml_reader.c
CHANGED
@@ -5,9 +5,7 @@ VALUE cNokogiriXmlReader;
|
|
5
5
|
static void
|
6
6
|
dealloc(xmlTextReaderPtr reader)
|
7
7
|
{
|
8
|
-
NOKOGIRI_DEBUG_START(reader);
|
9
8
|
xmlFreeTextReader(reader);
|
10
|
-
NOKOGIRI_DEBUG_END(reader);
|
11
9
|
}
|
12
10
|
|
13
11
|
static int
|
@@ -126,26 +124,37 @@ attributes_eh(VALUE self)
|
|
126
124
|
* Get a hash of namespaces for this Node
|
127
125
|
*/
|
128
126
|
static VALUE
|
129
|
-
|
127
|
+
rb_xml_reader_namespaces(VALUE rb_reader)
|
130
128
|
{
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
Data_Get_Struct(self, xmlTextReader, reader);
|
129
|
+
VALUE rb_namespaces = rb_hash_new() ;
|
130
|
+
xmlTextReaderPtr c_reader;
|
131
|
+
xmlNodePtr c_node;
|
132
|
+
VALUE rb_errors;
|
136
133
|
|
137
|
-
|
134
|
+
Data_Get_Struct(rb_reader, xmlTextReader, c_reader);
|
138
135
|
|
139
|
-
if (! has_attributes(
|
140
|
-
return
|
136
|
+
if (! has_attributes(c_reader)) {
|
137
|
+
return rb_namespaces ;
|
141
138
|
}
|
142
139
|
|
143
|
-
|
144
|
-
if (ptr == NULL) { return Qnil; }
|
140
|
+
rb_errors = rb_funcall(rb_reader, rb_intern("errors"), 0);
|
145
141
|
|
146
|
-
|
142
|
+
xmlSetStructuredErrorFunc((void *)rb_errors, Nokogiri_error_array_pusher);
|
143
|
+
c_node = xmlTextReaderExpand(c_reader);
|
144
|
+
xmlSetStructuredErrorFunc(NULL, NULL);
|
147
145
|
|
148
|
-
|
146
|
+
if (c_node == NULL) {
|
147
|
+
if (RARRAY_LEN(rb_errors) > 0) {
|
148
|
+
VALUE rb_error = rb_ary_entry(rb_errors, 0);
|
149
|
+
VALUE exception_message = rb_funcall(rb_error, rb_intern("to_s"), 0);
|
150
|
+
rb_exc_raise(rb_class_new_instance(1, &exception_message, cNokogiriXmlSyntaxError));
|
151
|
+
}
|
152
|
+
return Qnil;
|
153
|
+
}
|
154
|
+
|
155
|
+
Nokogiri_xml_node_namespaces(c_node, rb_namespaces);
|
156
|
+
|
157
|
+
return rb_namespaces ;
|
149
158
|
}
|
150
159
|
|
151
160
|
/*
|
@@ -204,6 +213,7 @@ rb_xml_reader_attribute_hash(VALUE rb_reader)
|
|
204
213
|
xmlTextReaderPtr c_reader;
|
205
214
|
xmlNodePtr c_node;
|
206
215
|
xmlAttrPtr c_property;
|
216
|
+
VALUE rb_errors;
|
207
217
|
|
208
218
|
Data_Get_Struct(rb_reader, xmlTextReader, c_reader);
|
209
219
|
|
@@ -211,8 +221,18 @@ rb_xml_reader_attribute_hash(VALUE rb_reader)
|
|
211
221
|
return rb_attributes;
|
212
222
|
}
|
213
223
|
|
224
|
+
rb_errors = rb_funcall(rb_reader, rb_intern("errors"), 0);
|
225
|
+
|
226
|
+
xmlSetStructuredErrorFunc((void *)rb_errors, Nokogiri_error_array_pusher);
|
214
227
|
c_node = xmlTextReaderExpand(c_reader);
|
228
|
+
xmlSetStructuredErrorFunc(NULL, NULL);
|
229
|
+
|
215
230
|
if (c_node == NULL) {
|
231
|
+
if (RARRAY_LEN(rb_errors) > 0) {
|
232
|
+
VALUE rb_error = rb_ary_entry(rb_errors, 0);
|
233
|
+
VALUE exception_message = rb_funcall(rb_error, rb_intern("to_s"), 0);
|
234
|
+
rb_exc_raise(rb_class_new_instance(1, &exception_message, cNokogiriXmlSyntaxError));
|
235
|
+
}
|
216
236
|
return Qnil;
|
217
237
|
}
|
218
238
|
|
@@ -306,7 +326,7 @@ attribute_count(VALUE self)
|
|
306
326
|
count = xmlTextReaderAttributeCount(reader);
|
307
327
|
if (count == -1) { return Qnil; }
|
308
328
|
|
309
|
-
return INT2NUM(
|
329
|
+
return INT2NUM(count);
|
310
330
|
}
|
311
331
|
|
312
332
|
/*
|
@@ -325,7 +345,7 @@ depth(VALUE self)
|
|
325
345
|
depth = xmlTextReaderDepth(reader);
|
326
346
|
if (depth == -1) { return Qnil; }
|
327
347
|
|
328
|
-
return INT2NUM(
|
348
|
+
return INT2NUM(depth);
|
329
349
|
}
|
330
350
|
|
331
351
|
/*
|
@@ -498,7 +518,7 @@ state(VALUE self)
|
|
498
518
|
{
|
499
519
|
xmlTextReaderPtr reader;
|
500
520
|
Data_Get_Struct(self, xmlTextReader, reader);
|
501
|
-
return INT2NUM(
|
521
|
+
return INT2NUM(xmlTextReaderReadState(reader));
|
502
522
|
}
|
503
523
|
|
504
524
|
/*
|
@@ -512,7 +532,7 @@ node_type(VALUE self)
|
|
512
532
|
{
|
513
533
|
xmlTextReaderPtr reader;
|
514
534
|
Data_Get_Struct(self, xmlTextReader, reader);
|
515
|
-
return INT2NUM(
|
535
|
+
return INT2NUM(xmlTextReaderNodeType(reader));
|
516
536
|
}
|
517
537
|
|
518
538
|
/*
|
@@ -762,7 +782,7 @@ noko_init_xml_reader()
|
|
762
782
|
rb_define_method(cNokogiriXmlReader, "local_name", local_name, 0);
|
763
783
|
rb_define_method(cNokogiriXmlReader, "name", name, 0);
|
764
784
|
rb_define_method(cNokogiriXmlReader, "namespace_uri", namespace_uri, 0);
|
765
|
-
rb_define_method(cNokogiriXmlReader, "namespaces",
|
785
|
+
rb_define_method(cNokogiriXmlReader, "namespaces", rb_xml_reader_namespaces, 0);
|
766
786
|
rb_define_method(cNokogiriXmlReader, "node_type", node_type, 0);
|
767
787
|
rb_define_method(cNokogiriXmlReader, "outer_xml", outer_xml, 0);
|
768
788
|
rb_define_method(cNokogiriXmlReader, "prefix", prefix, 0);
|
data/ext/nokogiri/xml_relax_ng.c
CHANGED
@@ -195,40 +195,48 @@ comment_func(void *ctx, const xmlChar *value)
|
|
195
195
|
rb_funcall(doc, id_comment, 1, str);
|
196
196
|
}
|
197
197
|
|
198
|
+
PRINTFLIKE_DECL(2, 3)
|
198
199
|
static void
|
199
200
|
warning_func(void *ctx, const char *msg, ...)
|
200
201
|
{
|
201
202
|
VALUE self = NOKOGIRI_SAX_SELF(ctx);
|
202
203
|
VALUE doc = rb_iv_get(self, "@document");
|
203
|
-
|
204
|
-
VALUE ruby_message;
|
204
|
+
VALUE rb_message;
|
205
205
|
|
206
|
+
#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES
|
207
|
+
/* It is not currently possible to pass var args from native
|
208
|
+
functions to sulong, so we work around the issue here. */
|
209
|
+
rb_message = rb_sprintf("warning_func: %s", msg);
|
210
|
+
#else
|
206
211
|
va_list args;
|
207
212
|
va_start(args, msg);
|
208
|
-
|
213
|
+
rb_message = rb_vsprintf(msg, args);
|
209
214
|
va_end(args);
|
215
|
+
#endif
|
210
216
|
|
211
|
-
|
212
|
-
free(message);
|
213
|
-
rb_funcall(doc, id_warning, 1, ruby_message);
|
217
|
+
rb_funcall(doc, id_warning, 1, rb_message);
|
214
218
|
}
|
215
219
|
|
220
|
+
PRINTFLIKE_DECL(2, 3)
|
216
221
|
static void
|
217
222
|
error_func(void *ctx, const char *msg, ...)
|
218
223
|
{
|
219
224
|
VALUE self = NOKOGIRI_SAX_SELF(ctx);
|
220
225
|
VALUE doc = rb_iv_get(self, "@document");
|
221
|
-
|
222
|
-
VALUE ruby_message;
|
226
|
+
VALUE rb_message;
|
223
227
|
|
228
|
+
#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES
|
229
|
+
/* It is not currently possible to pass var args from native
|
230
|
+
functions to sulong, so we work around the issue here. */
|
231
|
+
rb_message = rb_sprintf("error_func: %s", msg);
|
232
|
+
#else
|
224
233
|
va_list args;
|
225
234
|
va_start(args, msg);
|
226
|
-
|
235
|
+
rb_message = rb_vsprintf(msg, args);
|
227
236
|
va_end(args);
|
237
|
+
#endif
|
228
238
|
|
229
|
-
|
230
|
-
free(message);
|
231
|
-
rb_funcall(doc, id_error, 1, ruby_message);
|
239
|
+
rb_funcall(doc, id_error, 1, rb_message);
|
232
240
|
}
|
233
241
|
|
234
242
|
static void
|
@@ -260,15 +268,13 @@ processing_instruction(void *ctx, const xmlChar *name, const xmlChar *content)
|
|
260
268
|
static void
|
261
269
|
deallocate(xmlSAXHandlerPtr handler)
|
262
270
|
{
|
263
|
-
|
264
|
-
free(handler);
|
265
|
-
NOKOGIRI_DEBUG_END(handler);
|
271
|
+
ruby_xfree(handler);
|
266
272
|
}
|
267
273
|
|
268
274
|
static VALUE
|
269
275
|
allocate(VALUE klass)
|
270
276
|
{
|
271
|
-
xmlSAXHandlerPtr handler =
|
277
|
+
xmlSAXHandlerPtr handler = ruby_xcalloc((size_t)1, sizeof(xmlSAXHandler));
|
272
278
|
|
273
279
|
handler->startDocument = start_document;
|
274
280
|
handler->endDocument = end_document;
|
@@ -5,12 +5,10 @@ VALUE cNokogiriXmlSaxPushParser ;
|
|
5
5
|
static void
|
6
6
|
deallocate(xmlParserCtxtPtr ctx)
|
7
7
|
{
|
8
|
-
NOKOGIRI_DEBUG_START(ctx);
|
9
8
|
if (ctx != NULL) {
|
10
9
|
NOKOGIRI_SAX_TUPLE_DESTROY(ctx->userData);
|
11
10
|
xmlFreeParserCtxt(ctx);
|
12
11
|
}
|
13
|
-
NOKOGIRI_DEBUG_END(ctx);
|
14
12
|
}
|
15
13
|
|
16
14
|
static VALUE
|
data/ext/nokogiri/xml_schema.c
CHANGED
@@ -6,15 +6,15 @@ 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(xmlXPathContextPtr ctx)
|
14
16
|
{
|
15
|
-
NOKOGIRI_DEBUG_START(ctx);
|
16
17
|
xmlXPathFreeContext(ctx);
|
17
|
-
NOKOGIRI_DEBUG_END(ctx);
|
18
18
|
}
|
19
19
|
|
20
20
|
/* find a CSS class in an HTML element's `class` attribute */
|
@@ -113,7 +113,7 @@ xpath_builtin_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
|
|
113
113
|
* Register the namespace with +prefix+ and +uri+.
|
114
114
|
*/
|
115
115
|
static VALUE
|
116
|
-
|
116
|
+
rb_xml_xpath_context_register_ns(VALUE self, VALUE prefix, VALUE uri)
|
117
117
|
{
|
118
118
|
xmlXPathContextPtr ctx;
|
119
119
|
Data_Get_Struct(self, xmlXPathContext, ctx);
|
@@ -132,7 +132,7 @@ register_ns(VALUE self, VALUE prefix, VALUE uri)
|
|
132
132
|
* Register the variable +name+ with +value+.
|
133
133
|
*/
|
134
134
|
static VALUE
|
135
|
-
|
135
|
+
rb_xml_xpath_context_register_variable(VALUE self, VALUE name, VALUE value)
|
136
136
|
{
|
137
137
|
xmlXPathContextPtr ctx;
|
138
138
|
xmlXPathObjectPtr xmlValue;
|
@@ -154,28 +154,28 @@ register_variable(VALUE self, VALUE name, VALUE value)
|
|
154
154
|
* returns Qundef if no conversion was possible.
|
155
155
|
*/
|
156
156
|
static VALUE
|
157
|
-
xpath2ruby(xmlXPathObjectPtr
|
157
|
+
xpath2ruby(xmlXPathObjectPtr c_xpath_object, xmlXPathContextPtr ctx)
|
158
158
|
{
|
159
|
-
VALUE
|
159
|
+
VALUE rb_retval;
|
160
160
|
|
161
|
-
assert(
|
162
|
-
assert(DOC_RUBY_OBJECT_TEST(
|
161
|
+
assert(ctx->doc);
|
162
|
+
assert(DOC_RUBY_OBJECT_TEST(ctx->doc));
|
163
163
|
|
164
|
-
switch (
|
164
|
+
switch (c_xpath_object->type) {
|
165
165
|
case XPATH_STRING:
|
166
|
-
|
167
|
-
xmlFree(
|
168
|
-
return
|
166
|
+
rb_retval = NOKOGIRI_STR_NEW2(c_xpath_object->stringval);
|
167
|
+
xmlFree(c_xpath_object->stringval);
|
168
|
+
return rb_retval;
|
169
169
|
|
170
170
|
case XPATH_NODESET:
|
171
|
-
return noko_xml_node_set_wrap(
|
172
|
-
DOC_RUBY_OBJECT(
|
171
|
+
return noko_xml_node_set_wrap(c_xpath_object->nodesetval,
|
172
|
+
DOC_RUBY_OBJECT(ctx->doc));
|
173
173
|
|
174
174
|
case XPATH_NUMBER:
|
175
|
-
return rb_float_new(
|
175
|
+
return rb_float_new(c_xpath_object->floatval);
|
176
176
|
|
177
177
|
case XPATH_BOOLEAN:
|
178
|
-
return (
|
178
|
+
return (c_xpath_object->boolval == 1) ? Qtrue : Qfalse;
|
179
179
|
|
180
180
|
default:
|
181
181
|
return Qundef;
|
@@ -183,52 +183,51 @@ xpath2ruby(xmlXPathObjectPtr xobj, xmlXPathContextPtr xctx)
|
|
183
183
|
}
|
184
184
|
|
185
185
|
void
|
186
|
-
Nokogiri_marshal_xpath_funcall_and_return_values(
|
187
|
-
|
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
|
+
)
|
188
192
|
{
|
189
|
-
VALUE
|
193
|
+
VALUE rb_retval;
|
190
194
|
VALUE *argv;
|
191
|
-
VALUE
|
192
|
-
xmlNodeSetPtr
|
193
|
-
xmlXPathObjectPtr
|
195
|
+
VALUE rb_node_set = Qnil;
|
196
|
+
xmlNodeSetPtr c_node_set = NULL;
|
197
|
+
xmlXPathObjectPtr c_xpath_object;
|
194
198
|
|
195
199
|
assert(ctx->context->doc);
|
196
200
|
assert(DOC_RUBY_OBJECT_TEST(ctx->context->doc));
|
197
201
|
|
198
|
-
argv = (VALUE *)
|
199
|
-
for (int j = 0 ; j <
|
202
|
+
argv = (VALUE *)ruby_xcalloc((size_t)argc, sizeof(VALUE));
|
203
|
+
for (int j = 0 ; j < argc ; ++j) {
|
200
204
|
rb_gc_register_address(&argv[j]);
|
201
205
|
}
|
202
206
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
obj = valuePop(ctx);
|
207
|
-
argv[j] = xpath2ruby(obj, ctx->context);
|
207
|
+
for (int j = argc - 1 ; j >= 0 ; --j) {
|
208
|
+
c_xpath_object = valuePop(ctx);
|
209
|
+
argv[j] = xpath2ruby(c_xpath_object, ctx->context);
|
208
210
|
if (argv[j] == Qundef) {
|
209
|
-
argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(
|
211
|
+
argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(c_xpath_object));
|
210
212
|
}
|
211
|
-
xmlXPathFreeNodeSetList(
|
213
|
+
xmlXPathFreeNodeSetList(c_xpath_object);
|
212
214
|
}
|
213
215
|
|
214
|
-
|
216
|
+
rb_retval = rb_funcall2(rb_xpath_handler, rb_intern((const char *)method_name), argc, argv);
|
215
217
|
|
216
|
-
for (int j = 0 ; j <
|
218
|
+
for (int j = 0 ; j < argc ; ++j) {
|
217
219
|
rb_gc_unregister_address(&argv[j]);
|
218
220
|
}
|
219
|
-
|
221
|
+
ruby_xfree(argv);
|
220
222
|
|
221
|
-
switch (TYPE(
|
223
|
+
switch (TYPE(rb_retval)) {
|
222
224
|
case T_FLOAT:
|
223
225
|
case T_BIGNUM:
|
224
226
|
case T_FIXNUM:
|
225
|
-
xmlXPathReturnNumber(ctx, NUM2DBL(
|
227
|
+
xmlXPathReturnNumber(ctx, NUM2DBL(rb_retval));
|
226
228
|
break;
|
227
229
|
case T_STRING:
|
228
|
-
xmlXPathReturnString(
|
229
|
-
ctx,
|
230
|
-
xmlCharStrdup(StringValueCStr(result))
|
231
|
-
);
|
230
|
+
xmlXPathReturnString(ctx, xmlCharStrdup(StringValueCStr(rb_retval)));
|
232
231
|
break;
|
233
232
|
case T_TRUE:
|
234
233
|
xmlXPathReturnTrue(ctx);
|
@@ -239,19 +238,17 @@ Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr ctx, i
|
|
239
238
|
case T_NIL:
|
240
239
|
break;
|
241
240
|
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));
|
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));
|
248
245
|
}
|
249
246
|
break;
|
250
247
|
case T_DATA:
|
251
|
-
if (rb_obj_is_kind_of(
|
252
|
-
Data_Get_Struct(
|
248
|
+
if (rb_obj_is_kind_of(rb_retval, cNokogiriXmlNodeSet)) {
|
249
|
+
Data_Get_Struct(rb_retval, xmlNodeSet, c_node_set);
|
253
250
|
/* Copy the node set, otherwise it will get GC'd. */
|
254
|
-
xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL,
|
251
|
+
xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, c_node_set));
|
255
252
|
break;
|
256
253
|
}
|
257
254
|
default:
|
@@ -260,47 +257,56 @@ Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr ctx, i
|
|
260
257
|
}
|
261
258
|
|
262
259
|
static void
|
263
|
-
|
260
|
+
method_caller(xmlXPathParserContextPtr ctx, int argc)
|
264
261
|
{
|
265
|
-
VALUE
|
266
|
-
const char *
|
262
|
+
VALUE rb_xpath_handler = Qnil;
|
263
|
+
const char *method_name = NULL ;
|
267
264
|
|
268
265
|
assert(ctx);
|
269
266
|
assert(ctx->context);
|
270
267
|
assert(ctx->context->userData);
|
271
268
|
assert(ctx->context->function);
|
272
269
|
|
273
|
-
|
274
|
-
|
270
|
+
rb_xpath_handler = (VALUE)(ctx->context->userData);
|
271
|
+
method_name = (const char *)(ctx->context->function);
|
275
272
|
|
276
|
-
Nokogiri_marshal_xpath_funcall_and_return_values(ctx,
|
273
|
+
Nokogiri_marshal_xpath_funcall_and_return_values(ctx, argc, rb_xpath_handler, method_name);
|
277
274
|
}
|
278
275
|
|
279
276
|
static xmlXPathFunction
|
280
|
-
|
281
|
-
const xmlChar *name,
|
282
|
-
const xmlChar *ns_uri)
|
277
|
+
handler_lookup(void *ctx, const xmlChar *c_name, const xmlChar *c_ns_uri)
|
283
278
|
{
|
284
|
-
VALUE
|
285
|
-
if (rb_respond_to(
|
286
|
-
return
|
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;
|
287
282
|
}
|
288
283
|
|
289
284
|
return NULL;
|
290
285
|
}
|
291
286
|
|
292
|
-
|
287
|
+
PRINTFLIKE_DECL(2, 3)
|
293
288
|
static void
|
294
|
-
|
289
|
+
generic_exception_pusher(void *ctx, const char *msg, ...)
|
295
290
|
{
|
296
|
-
|
291
|
+
VALUE rb_errors = (VALUE)ctx;
|
292
|
+
VALUE rb_message;
|
293
|
+
VALUE rb_exception;
|
294
|
+
|
295
|
+
Check_Type(rb_errors, T_ARRAY);
|
297
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
|
298
302
|
va_list args;
|
299
303
|
va_start(args, msg);
|
300
|
-
|
304
|
+
rb_message = rb_vsprintf(msg, args);
|
301
305
|
va_end(args);
|
306
|
+
#endif
|
302
307
|
|
303
|
-
|
308
|
+
rb_exception = rb_exc_new_str(cNokogiriXmlXpathSyntaxError, rb_message);
|
309
|
+
rb_ary_push(rb_errors, rb_exception);
|
304
310
|
}
|
305
311
|
|
306
312
|
/*
|
@@ -310,13 +316,14 @@ xpath_generic_exception_handler(void *ctx, const char *msg, ...)
|
|
310
316
|
* Evaluate the +search_path+ returning an XML::XPath object.
|
311
317
|
*/
|
312
318
|
static VALUE
|
313
|
-
|
319
|
+
rb_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE self)
|
314
320
|
{
|
315
321
|
VALUE search_path, xpath_handler;
|
316
322
|
VALUE retval = Qnil;
|
317
323
|
xmlXPathContextPtr ctx;
|
318
324
|
xmlXPathObjectPtr xpath;
|
319
325
|
xmlChar *query;
|
326
|
+
VALUE errors = rb_ary_new();
|
320
327
|
|
321
328
|
Data_Get_Struct(self, xmlXPathContext, ctx);
|
322
329
|
|
@@ -329,23 +336,19 @@ evaluate(int argc, VALUE *argv, VALUE self)
|
|
329
336
|
if (Qnil != xpath_handler) {
|
330
337
|
/* FIXME: not sure if this is the correct place to shove private data. */
|
331
338
|
ctx->userData = (void *)xpath_handler;
|
332
|
-
xmlXPathRegisterFuncLookup(ctx,
|
339
|
+
xmlXPathRegisterFuncLookup(ctx, handler_lookup, (void *)xpath_handler);
|
333
340
|
}
|
334
341
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
/* For some reason, xmlXPathEvalExpression will blow up with a generic error */
|
339
|
-
/* when there is a non existent function. */
|
340
|
-
xmlSetGenericErrorFunc(NULL, xpath_generic_exception_handler);
|
342
|
+
xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);
|
343
|
+
xmlSetGenericErrorFunc((void *)errors, generic_exception_pusher);
|
341
344
|
|
342
345
|
xpath = xmlXPathEvalExpression(query, ctx);
|
346
|
+
|
343
347
|
xmlSetStructuredErrorFunc(NULL, NULL);
|
344
348
|
xmlSetGenericErrorFunc(NULL, NULL);
|
345
349
|
|
346
350
|
if (xpath == NULL) {
|
347
|
-
|
348
|
-
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
351
|
+
rb_exc_raise(rb_ary_entry(errors, 0));
|
349
352
|
}
|
350
353
|
|
351
354
|
retval = xpath2ruby(xpath, ctx);
|
@@ -365,7 +368,7 @@ evaluate(int argc, VALUE *argv, VALUE self)
|
|
365
368
|
* Create a new XPathContext with +node+ as the reference point.
|
366
369
|
*/
|
367
370
|
static VALUE
|
368
|
-
|
371
|
+
rb_xml_xpath_context_new(VALUE klass, VALUE nodeobj)
|
369
372
|
{
|
370
373
|
xmlNodePtr node;
|
371
374
|
xmlXPathContextPtr ctx;
|
@@ -381,13 +384,14 @@ new (VALUE klass, VALUE nodeobj)
|
|
381
384
|
ctx = xmlXPathNewContext(node->doc);
|
382
385
|
ctx->node = node;
|
383
386
|
|
387
|
+
xmlXPathRegisterNs(ctx, NOKOGIRI_PREFIX, NOKOGIRI_URI);
|
384
388
|
xmlXPathRegisterNs(ctx, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
|
385
389
|
xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"css-class", NOKOGIRI_BUILTIN_URI,
|
386
390
|
xpath_builtin_css_class);
|
387
391
|
xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"local-name-is", NOKOGIRI_BUILTIN_URI,
|
388
392
|
xpath_builtin_local_name_is);
|
389
393
|
|
390
|
-
self = Data_Wrap_Struct(klass, 0,
|
394
|
+
self = Data_Wrap_Struct(klass, 0, xml_xpath_context_deallocate, ctx);
|
391
395
|
return self;
|
392
396
|
}
|
393
397
|
|
@@ -401,9 +405,9 @@ noko_init_xml_xpath_context(void)
|
|
401
405
|
|
402
406
|
rb_undef_alloc_func(cNokogiriXmlXpathContext);
|
403
407
|
|
404
|
-
rb_define_singleton_method(cNokogiriXmlXpathContext, "new",
|
408
|
+
rb_define_singleton_method(cNokogiriXmlXpathContext, "new", rb_xml_xpath_context_new, 1);
|
405
409
|
|
406
|
-
rb_define_method(cNokogiriXmlXpathContext, "evaluate",
|
407
|
-
rb_define_method(cNokogiriXmlXpathContext, "register_variable",
|
408
|
-
rb_define_method(cNokogiriXmlXpathContext, "register_ns",
|
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);
|
409
413
|
}
|
@@ -12,27 +12,28 @@ static void
|
|
12
12
|
dealloc(nokogiriXsltStylesheetTuple *wrapper)
|
13
13
|
{
|
14
14
|
xsltStylesheetPtr doc = wrapper->ss;
|
15
|
-
|
16
|
-
|
17
|
-
xsltFreeStylesheet(doc); /* commented out for now. */
|
18
|
-
NOKOGIRI_DEBUG_END(doc);
|
19
|
-
|
20
|
-
free(wrapper);
|
15
|
+
xsltFreeStylesheet(doc);
|
16
|
+
ruby_xfree(wrapper);
|
21
17
|
}
|
22
18
|
|
19
|
+
PRINTFLIKE_DECL(2, 3)
|
23
20
|
static void
|
24
21
|
xslt_generic_error_handler(void *ctx, const char *msg, ...)
|
25
22
|
{
|
26
|
-
|
23
|
+
VALUE message;
|
27
24
|
|
25
|
+
#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES
|
26
|
+
/* It is not currently possible to pass var args from native
|
27
|
+
functions to sulong, so we work around the issue here. */
|
28
|
+
message = rb_sprintf("xslt_generic_error_handler: %s", msg);
|
29
|
+
#else
|
28
30
|
va_list args;
|
29
31
|
va_start(args, msg);
|
30
|
-
|
32
|
+
message = rb_vsprintf(msg, args);
|
31
33
|
va_end(args);
|
34
|
+
#endif
|
32
35
|
|
33
|
-
|
34
|
-
|
35
|
-
free(message);
|
36
|
+
rb_str_concat((VALUE)ctx, message);
|
36
37
|
}
|
37
38
|
|
38
39
|
VALUE
|
@@ -248,7 +249,7 @@ transform(int argc, VALUE *argv, VALUE self)
|
|
248
249
|
Data_Get_Struct(self, nokogiriXsltStylesheetTuple, wrapper);
|
249
250
|
|
250
251
|
param_len = RARRAY_LEN(paramobj);
|
251
|
-
params =
|
252
|
+
params = ruby_xcalloc((size_t)param_len + 1, sizeof(char *));
|
252
253
|
for (j = 0 ; j < param_len ; j++) {
|
253
254
|
VALUE entry = rb_ary_entry(paramobj, j);
|
254
255
|
const char *ptr = StringValueCStr(entry);
|
@@ -261,7 +262,7 @@ transform(int argc, VALUE *argv, VALUE self)
|
|
261
262
|
xmlSetGenericErrorFunc((void *)errstr, xslt_generic_error_handler);
|
262
263
|
|
263
264
|
result = xsltApplyStylesheet(wrapper->ss, xml, params);
|
264
|
-
|
265
|
+
ruby_xfree(params);
|
265
266
|
|
266
267
|
xsltSetGenericErrorFunc(NULL, NULL);
|
267
268
|
xmlSetGenericErrorFunc(NULL, NULL);
|