nokogiri 1.11.1 → 1.11.2
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/LICENSE-DEPENDENCIES.md +12 -12
- data/LICENSE.md +1 -1
- data/README.md +20 -15
- data/ext/nokogiri/depend +34 -474
- data/ext/nokogiri/extconf.rb +253 -183
- data/ext/nokogiri/html_document.c +10 -15
- data/ext/nokogiri/html_element_description.c +84 -71
- data/ext/nokogiri/html_entity_lookup.c +21 -16
- data/ext/nokogiri/html_sax_parser_context.c +66 -65
- data/ext/nokogiri/html_sax_push_parser.c +29 -27
- data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
- data/ext/nokogiri/nokogiri.c +171 -63
- data/ext/nokogiri/nokogiri.h +158 -75
- data/ext/nokogiri/test_global_handlers.c +3 -4
- data/ext/nokogiri/xml_attr.c +15 -15
- data/ext/nokogiri/xml_attribute_decl.c +18 -18
- data/ext/nokogiri/xml_cdata.c +13 -18
- data/ext/nokogiri/xml_comment.c +19 -26
- data/ext/nokogiri/xml_document.c +221 -164
- data/ext/nokogiri/xml_document_fragment.c +13 -15
- data/ext/nokogiri/xml_dtd.c +54 -48
- data/ext/nokogiri/xml_element_content.c +30 -27
- data/ext/nokogiri/xml_element_decl.c +22 -22
- data/ext/nokogiri/xml_encoding_handler.c +17 -11
- data/ext/nokogiri/xml_entity_decl.c +32 -30
- data/ext/nokogiri/xml_entity_reference.c +16 -18
- data/ext/nokogiri/xml_namespace.c +56 -49
- data/ext/nokogiri/xml_node.c +338 -286
- data/ext/nokogiri/xml_node_set.c +168 -156
- data/ext/nokogiri/xml_processing_instruction.c +17 -19
- data/ext/nokogiri/xml_reader.c +191 -157
- data/ext/nokogiri/xml_relax_ng.c +29 -23
- data/ext/nokogiri/xml_sax_parser.c +117 -112
- data/ext/nokogiri/xml_sax_parser_context.c +100 -85
- data/ext/nokogiri/xml_sax_push_parser.c +34 -27
- data/ext/nokogiri/xml_schema.c +48 -42
- data/ext/nokogiri/xml_syntax_error.c +21 -23
- data/ext/nokogiri/xml_text.c +13 -17
- data/ext/nokogiri/xml_xpath_context.c +134 -127
- data/ext/nokogiri/xslt_stylesheet.c +157 -157
- data/lib/nokogiri.rb +1 -22
- data/lib/nokogiri/css/parser.rb +1 -1
- data/lib/nokogiri/extension.rb +26 -0
- data/lib/nokogiri/html/document_fragment.rb +15 -15
- data/lib/nokogiri/version/constant.rb +1 -1
- data/lib/nokogiri/version/info.rb +31 -8
- data/lib/nokogiri/xml/document.rb +31 -11
- data/lib/nokogiri/xml/node.rb +38 -42
- data/lib/nokogiri/xml/reader.rb +2 -9
- data/lib/nokogiri/xml/xpath.rb +1 -3
- data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -1
- data/patches/libxml2/0010-parser.c-shrink-the-input-buffer-when-appropriate.patch +70 -0
- metadata +8 -41
- data/ext/nokogiri/html_document.h +0 -10
- data/ext/nokogiri/html_element_description.h +0 -10
- data/ext/nokogiri/html_entity_lookup.h +0 -8
- data/ext/nokogiri/html_sax_parser_context.h +0 -11
- data/ext/nokogiri/html_sax_push_parser.h +0 -9
- data/ext/nokogiri/xml_attr.h +0 -9
- data/ext/nokogiri/xml_attribute_decl.h +0 -9
- data/ext/nokogiri/xml_cdata.h +0 -9
- data/ext/nokogiri/xml_comment.h +0 -9
- data/ext/nokogiri/xml_document.h +0 -23
- data/ext/nokogiri/xml_document_fragment.h +0 -10
- data/ext/nokogiri/xml_dtd.h +0 -10
- data/ext/nokogiri/xml_element_content.h +0 -10
- data/ext/nokogiri/xml_element_decl.h +0 -9
- data/ext/nokogiri/xml_encoding_handler.h +0 -8
- data/ext/nokogiri/xml_entity_decl.h +0 -10
- data/ext/nokogiri/xml_entity_reference.h +0 -9
- data/ext/nokogiri/xml_io.c +0 -63
- data/ext/nokogiri/xml_io.h +0 -11
- data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
- data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
- data/ext/nokogiri/xml_namespace.h +0 -14
- data/ext/nokogiri/xml_node.h +0 -13
- data/ext/nokogiri/xml_node_set.h +0 -12
- data/ext/nokogiri/xml_processing_instruction.h +0 -9
- data/ext/nokogiri/xml_reader.h +0 -10
- data/ext/nokogiri/xml_relax_ng.h +0 -9
- data/ext/nokogiri/xml_sax_parser.h +0 -39
- data/ext/nokogiri/xml_sax_parser_context.h +0 -10
- data/ext/nokogiri/xml_sax_push_parser.h +0 -9
- data/ext/nokogiri/xml_schema.h +0 -9
- data/ext/nokogiri/xml_syntax_error.h +0 -25
- data/ext/nokogiri/xml_text.h +0 -9
- data/ext/nokogiri/xml_xpath_context.h +0 -10
- data/ext/nokogiri/xslt_stylesheet.h +0 -14
@@ -1,4 +1,6 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
|
+
|
3
|
+
VALUE cNokogiriXmlSyntaxError;
|
2
4
|
|
3
5
|
void
|
4
6
|
Nokogiri_structured_error_func_save(libxmlStructuredErrorHandlerState *handler_state)
|
@@ -10,8 +12,8 @@ Nokogiri_structured_error_func_save(libxmlStructuredErrorHandlerState *handler_s
|
|
10
12
|
|
11
13
|
void
|
12
14
|
Nokogiri_structured_error_func_save_and_set(libxmlStructuredErrorHandlerState *handler_state,
|
13
|
-
|
14
|
-
|
15
|
+
void *user_data,
|
16
|
+
xmlStructuredErrorFunc handler)
|
15
17
|
{
|
16
18
|
Nokogiri_structured_error_func_save(handler_state);
|
17
19
|
xmlSetStructuredErrorFunc(user_data, handler);
|
@@ -23,39 +25,40 @@ Nokogiri_structured_error_func_restore(libxmlStructuredErrorHandlerState *handle
|
|
23
25
|
xmlSetStructuredErrorFunc(handler_state->user_data, handler_state->handler);
|
24
26
|
}
|
25
27
|
|
26
|
-
void
|
28
|
+
void
|
29
|
+
Nokogiri_error_array_pusher(void *ctx, xmlErrorPtr error)
|
27
30
|
{
|
28
31
|
VALUE list = (VALUE)ctx;
|
29
32
|
Check_Type(list, T_ARRAY);
|
30
33
|
rb_ary_push(list, Nokogiri_wrap_xml_syntax_error(error));
|
31
34
|
}
|
32
35
|
|
33
|
-
void
|
36
|
+
void
|
37
|
+
Nokogiri_error_raise(void *ctx, xmlErrorPtr error)
|
34
38
|
{
|
35
39
|
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
36
40
|
}
|
37
41
|
|
38
|
-
VALUE
|
42
|
+
VALUE
|
43
|
+
Nokogiri_wrap_xml_syntax_error(xmlErrorPtr error)
|
39
44
|
{
|
40
45
|
VALUE msg, e, klass;
|
41
46
|
|
42
47
|
klass = cNokogiriXmlSyntaxError;
|
43
48
|
|
44
49
|
if (error && error->domain == XML_FROM_XPATH) {
|
45
|
-
|
46
|
-
klass = rb_const_get(xpath, rb_intern("SyntaxError"));
|
50
|
+
klass = cNokogiriXmlXpathSyntaxError;
|
47
51
|
}
|
48
52
|
|
49
53
|
msg = (error && error->message) ? NOKOGIRI_STR_NEW2(error->message) : Qnil;
|
50
54
|
|
51
55
|
e = rb_class_new_instance(
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
+
1,
|
57
|
+
&msg,
|
58
|
+
klass
|
59
|
+
);
|
56
60
|
|
57
|
-
if (error)
|
58
|
-
{
|
61
|
+
if (error) {
|
59
62
|
rb_iv_set(e, "@domain", INT2NUM(error->domain));
|
60
63
|
rb_iv_set(e, "@code", INT2NUM(error->code));
|
61
64
|
rb_iv_set(e, "@level", INT2NUM((short)error->level));
|
@@ -71,17 +74,12 @@ VALUE Nokogiri_wrap_xml_syntax_error(xmlErrorPtr error)
|
|
71
74
|
return e;
|
72
75
|
}
|
73
76
|
|
74
|
-
|
75
|
-
|
77
|
+
void
|
78
|
+
noko_init_xml_syntax_error()
|
76
79
|
{
|
77
|
-
|
78
|
-
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
79
|
-
|
80
|
+
assert(cNokogiriSyntaxError);
|
80
81
|
/*
|
81
82
|
* The XML::SyntaxError is raised on parse errors
|
82
83
|
*/
|
83
|
-
|
84
|
-
VALUE klass = rb_define_class_under(xml, "SyntaxError", syntax_error_mommy);
|
85
|
-
cNokogiriXmlSyntaxError = klass;
|
86
|
-
|
84
|
+
cNokogiriXmlSyntaxError = rb_define_class_under(mNokogiriXml, "SyntaxError", cNokogiriSyntaxError);
|
87
85
|
}
|
data/ext/nokogiri/xml_text.c
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
|
+
|
3
|
+
VALUE cNokogiriXmlText ;
|
2
4
|
|
3
5
|
/*
|
4
6
|
* call-seq:
|
@@ -6,7 +8,8 @@
|
|
6
8
|
*
|
7
9
|
* Create a new Text element on the +document+ with +content+
|
8
10
|
*/
|
9
|
-
static VALUE
|
11
|
+
static VALUE
|
12
|
+
new (int argc, VALUE *argv, VALUE klass)
|
10
13
|
{
|
11
14
|
xmlDocPtr doc;
|
12
15
|
xmlNodePtr node;
|
@@ -22,31 +25,24 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
|
|
22
25
|
node = xmlNewText((xmlChar *)StringValueCStr(string));
|
23
26
|
node->doc = doc->doc;
|
24
27
|
|
25
|
-
|
28
|
+
noko_xml_document_pin_node(node);
|
26
29
|
|
27
|
-
rb_node =
|
30
|
+
rb_node = noko_xml_node_wrap(klass, node) ;
|
28
31
|
rb_obj_call_init(rb_node, argc, argv);
|
29
32
|
|
30
|
-
if(rb_block_given_p()) rb_yield(rb_node);
|
33
|
+
if (rb_block_given_p()) { rb_yield(rb_node); }
|
31
34
|
|
32
35
|
return rb_node;
|
33
36
|
}
|
34
37
|
|
35
|
-
|
36
|
-
|
38
|
+
void
|
39
|
+
noko_init_xml_text()
|
37
40
|
{
|
38
|
-
|
39
|
-
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
40
|
-
/* */
|
41
|
-
VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
|
42
|
-
VALUE char_data = rb_define_class_under(xml, "CharacterData", node);
|
43
|
-
|
41
|
+
assert(cNokogiriXmlCharacterData);
|
44
42
|
/*
|
45
43
|
* Wraps Text nodes.
|
46
44
|
*/
|
47
|
-
|
48
|
-
|
49
|
-
cNokogiriXmlText = klass;
|
45
|
+
cNokogiriXmlText = rb_define_class_under(mNokogiriXml, "Text", cNokogiriXmlCharacterData);
|
50
46
|
|
51
|
-
rb_define_singleton_method(
|
47
|
+
rb_define_singleton_method(cNokogiriXmlText, "new", new, -1);
|
52
48
|
}
|
@@ -1,4 +1,6 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
|
+
|
3
|
+
VALUE cNokogiriXmlXpathContext;
|
2
4
|
|
3
5
|
/*
|
4
6
|
* these constants have matching declarations in
|
@@ -7,7 +9,8 @@
|
|
7
9
|
static const xmlChar *NOKOGIRI_BUILTIN_PREFIX = (const xmlChar *)"nokogiri-builtin";
|
8
10
|
static const xmlChar *NOKOGIRI_BUILTIN_URI = (const xmlChar *)"https://www.nokogiri.org/default_ns/ruby/builtins";
|
9
11
|
|
10
|
-
static void
|
12
|
+
static void
|
13
|
+
deallocate(xmlXPathContextPtr ctx)
|
11
14
|
{
|
12
15
|
NOKOGIRI_DEBUG_START(ctx);
|
13
16
|
xmlXPathFreeContext(ctx);
|
@@ -15,23 +18,24 @@ static void deallocate(xmlXPathContextPtr ctx)
|
|
15
18
|
}
|
16
19
|
|
17
20
|
/* find a CSS class in an HTML element's `class` attribute */
|
18
|
-
|
21
|
+
static const xmlChar *
|
22
|
+
builtin_css_class(const xmlChar *str, const xmlChar *val)
|
19
23
|
{
|
20
24
|
int val_len;
|
21
25
|
|
22
|
-
if (str == NULL) { return(NULL); }
|
23
|
-
if (val == NULL) { return(NULL); }
|
26
|
+
if (str == NULL) { return (NULL); }
|
27
|
+
if (val == NULL) { return (NULL); }
|
24
28
|
|
25
29
|
val_len = xmlStrlen(val);
|
26
|
-
if (val_len == 0) { return(str); }
|
30
|
+
if (val_len == 0) { return (str); }
|
27
31
|
|
28
32
|
while (*str != 0) {
|
29
33
|
if ((*str == *val) && !xmlStrncmp(str, val, val_len)) {
|
30
|
-
const xmlChar*
|
34
|
+
const xmlChar *next_byte = str + val_len;
|
31
35
|
|
32
36
|
/* only match if the next byte is whitespace or end of string */
|
33
37
|
if ((*next_byte == 0) || (IS_BLANK_CH(*next_byte))) {
|
34
|
-
return((const xmlChar*)str);
|
38
|
+
return ((const xmlChar *)str);
|
35
39
|
}
|
36
40
|
}
|
37
41
|
|
@@ -46,11 +50,12 @@ const xmlChar* builtin_css_class(const xmlChar* str, const xmlChar *val)
|
|
46
50
|
}
|
47
51
|
}
|
48
52
|
|
49
|
-
return(NULL);
|
53
|
+
return (NULL);
|
50
54
|
}
|
51
55
|
|
52
56
|
/* xmlXPathFunction to wrap builtin_css_class() */
|
53
|
-
static void
|
57
|
+
static void
|
58
|
+
xpath_builtin_css_class(xmlXPathParserContextPtr ctxt, int nargs)
|
54
59
|
{
|
55
60
|
xmlXPathObjectPtr hay, needle;
|
56
61
|
|
@@ -87,15 +92,16 @@ static void xpath_builtin_css_class(xmlXPathParserContextPtr ctxt, int nargs)
|
|
87
92
|
*
|
88
93
|
* Register the namespace with +prefix+ and +uri+.
|
89
94
|
*/
|
90
|
-
static VALUE
|
95
|
+
static VALUE
|
96
|
+
register_ns(VALUE self, VALUE prefix, VALUE uri)
|
91
97
|
{
|
92
98
|
xmlXPathContextPtr ctx;
|
93
99
|
Data_Get_Struct(self, xmlXPathContext, ctx);
|
94
100
|
|
95
|
-
xmlXPathRegisterNs(
|
96
|
-
|
97
|
-
|
98
|
-
|
101
|
+
xmlXPathRegisterNs(ctx,
|
102
|
+
(const xmlChar *)StringValueCStr(prefix),
|
103
|
+
(const xmlChar *)StringValueCStr(uri)
|
104
|
+
);
|
99
105
|
return self;
|
100
106
|
}
|
101
107
|
|
@@ -105,23 +111,26 @@ static VALUE register_ns(VALUE self, VALUE prefix, VALUE uri)
|
|
105
111
|
*
|
106
112
|
* Register the variable +name+ with +value+.
|
107
113
|
*/
|
108
|
-
static VALUE
|
114
|
+
static VALUE
|
115
|
+
register_variable(VALUE self, VALUE name, VALUE value)
|
109
116
|
{
|
110
|
-
|
111
|
-
|
112
|
-
|
117
|
+
xmlXPathContextPtr ctx;
|
118
|
+
xmlXPathObjectPtr xmlValue;
|
119
|
+
Data_Get_Struct(self, xmlXPathContext, ctx);
|
113
120
|
|
114
|
-
|
121
|
+
xmlValue = xmlXPathNewCString(StringValueCStr(value));
|
115
122
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
123
|
+
xmlXPathRegisterVariable(ctx,
|
124
|
+
(const xmlChar *)StringValueCStr(name),
|
125
|
+
xmlValue
|
126
|
+
);
|
120
127
|
|
121
|
-
|
128
|
+
return self;
|
122
129
|
}
|
123
130
|
|
124
|
-
void
|
131
|
+
void
|
132
|
+
Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr ctx, int nargs, VALUE handler,
|
133
|
+
const char *function_name)
|
125
134
|
{
|
126
135
|
int i;
|
127
136
|
VALUE result, doc;
|
@@ -144,76 +153,76 @@ void Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr c
|
|
144
153
|
i = nargs - 1;
|
145
154
|
do {
|
146
155
|
obj = valuePop(ctx);
|
147
|
-
switch(obj->type) {
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
156
|
+
switch (obj->type) {
|
157
|
+
case XPATH_STRING:
|
158
|
+
argv[i] = NOKOGIRI_STR_NEW2(obj->stringval);
|
159
|
+
break;
|
160
|
+
case XPATH_BOOLEAN:
|
161
|
+
argv[i] = obj->boolval == 1 ? Qtrue : Qfalse;
|
162
|
+
break;
|
163
|
+
case XPATH_NUMBER:
|
164
|
+
argv[i] = rb_float_new(obj->floatval);
|
165
|
+
break;
|
166
|
+
case XPATH_NODESET:
|
167
|
+
argv[i] = noko_xml_node_set_wrap(obj->nodesetval, doc);
|
168
|
+
break;
|
169
|
+
default:
|
170
|
+
argv[i] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(obj));
|
162
171
|
}
|
163
172
|
xmlXPathFreeNodeSetList(obj);
|
164
|
-
} while(i-- > 0);
|
173
|
+
} while (i-- > 0);
|
165
174
|
}
|
166
175
|
|
167
|
-
result = rb_funcall2(handler, rb_intern((const char*)function_name), nargs, argv);
|
176
|
+
result = rb_funcall2(handler, rb_intern((const char *)function_name), nargs, argv);
|
168
177
|
|
169
178
|
for (i = 0 ; i < nargs ; ++i) {
|
170
179
|
rb_gc_unregister_address(&argv[i]);
|
171
180
|
}
|
172
181
|
free(argv);
|
173
182
|
|
174
|
-
switch(TYPE(result)) {
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
break;
|
180
|
-
case T_STRING:
|
181
|
-
xmlXPathReturnString(
|
182
|
-
ctx,
|
183
|
-
xmlCharStrdup(StringValueCStr(result))
|
184
|
-
);
|
185
|
-
break;
|
186
|
-
case T_TRUE:
|
187
|
-
xmlXPathReturnTrue(ctx);
|
188
|
-
break;
|
189
|
-
case T_FALSE:
|
190
|
-
xmlXPathReturnFalse(ctx);
|
191
|
-
break;
|
192
|
-
case T_NIL:
|
193
|
-
break;
|
194
|
-
case T_ARRAY:
|
195
|
-
{
|
196
|
-
VALUE args[2];
|
197
|
-
args[0] = doc;
|
198
|
-
args[1] = result;
|
199
|
-
node_set = rb_class_new_instance(2, args, cNokogiriXmlNodeSet);
|
200
|
-
Data_Get_Struct(node_set, xmlNodeSet, xml_node_set);
|
201
|
-
xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
|
202
|
-
}
|
183
|
+
switch (TYPE(result)) {
|
184
|
+
case T_FLOAT:
|
185
|
+
case T_BIGNUM:
|
186
|
+
case T_FIXNUM:
|
187
|
+
xmlXPathReturnNumber(ctx, NUM2DBL(result));
|
203
188
|
break;
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
189
|
+
case T_STRING:
|
190
|
+
xmlXPathReturnString(
|
191
|
+
ctx,
|
192
|
+
xmlCharStrdup(StringValueCStr(result))
|
193
|
+
);
|
194
|
+
break;
|
195
|
+
case T_TRUE:
|
196
|
+
xmlXPathReturnTrue(ctx);
|
197
|
+
break;
|
198
|
+
case T_FALSE:
|
199
|
+
xmlXPathReturnFalse(ctx);
|
200
|
+
break;
|
201
|
+
case T_NIL:
|
202
|
+
break;
|
203
|
+
case T_ARRAY: {
|
204
|
+
VALUE args[2];
|
205
|
+
args[0] = doc;
|
206
|
+
args[1] = result;
|
207
|
+
node_set = rb_class_new_instance(2, args, cNokogiriXmlNodeSet);
|
208
|
+
Data_Get_Struct(node_set, xmlNodeSet, xml_node_set);
|
209
|
+
xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
|
210
|
+
}
|
211
|
+
break;
|
212
|
+
case T_DATA:
|
213
|
+
if (rb_obj_is_kind_of(result, cNokogiriXmlNodeSet)) {
|
214
|
+
Data_Get_Struct(result, xmlNodeSet, xml_node_set);
|
215
|
+
/* Copy the node set, otherwise it will get GC'd. */
|
216
|
+
xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
|
217
|
+
break;
|
213
218
|
}
|
219
|
+
default:
|
220
|
+
rb_raise(rb_eRuntimeError, "Invalid return type");
|
221
|
+
}
|
214
222
|
}
|
215
223
|
|
216
|
-
static void
|
224
|
+
static void
|
225
|
+
ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
|
217
226
|
{
|
218
227
|
VALUE handler = Qnil;
|
219
228
|
const char *function = NULL ;
|
@@ -224,26 +233,29 @@ static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
|
|
224
233
|
assert(ctx->context->function);
|
225
234
|
|
226
235
|
handler = (VALUE)(ctx->context->userData);
|
227
|
-
function = (const char*)(ctx->context->function);
|
236
|
+
function = (const char *)(ctx->context->function);
|
228
237
|
|
229
238
|
Nokogiri_marshal_xpath_funcall_and_return_values(ctx, nargs, handler, function);
|
230
239
|
}
|
231
240
|
|
232
|
-
static xmlXPathFunction
|
233
|
-
|
234
|
-
|
241
|
+
static xmlXPathFunction
|
242
|
+
lookup(void *ctx,
|
243
|
+
const xmlChar *name,
|
244
|
+
const xmlChar *ns_uri)
|
235
245
|
{
|
236
246
|
VALUE xpath_handler = (VALUE)ctx;
|
237
|
-
if(rb_respond_to(xpath_handler, rb_intern((const char *)name)))
|
247
|
+
if (rb_respond_to(xpath_handler, rb_intern((const char *)name))) {
|
238
248
|
return ruby_funcall;
|
249
|
+
}
|
239
250
|
|
240
251
|
return NULL;
|
241
252
|
}
|
242
253
|
|
243
|
-
NORETURN(static void xpath_generic_exception_handler(void *
|
244
|
-
static void
|
254
|
+
NORETURN(static void xpath_generic_exception_handler(void *ctx, const char *msg, ...));
|
255
|
+
static void
|
256
|
+
xpath_generic_exception_handler(void *ctx, const char *msg, ...)
|
245
257
|
{
|
246
|
-
char *
|
258
|
+
char *message;
|
247
259
|
|
248
260
|
va_list args;
|
249
261
|
va_start(args, msg);
|
@@ -259,7 +271,8 @@ static void xpath_generic_exception_handler(void * ctx, const char *msg, ...)
|
|
259
271
|
*
|
260
272
|
* Evaluate the +search_path+ returning an XML::XPath object.
|
261
273
|
*/
|
262
|
-
static VALUE
|
274
|
+
static VALUE
|
275
|
+
evaluate(int argc, VALUE *argv, VALUE self)
|
263
276
|
{
|
264
277
|
VALUE search_path, xpath_handler;
|
265
278
|
VALUE thing = Qnil;
|
@@ -269,12 +282,13 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
|
|
269
282
|
|
270
283
|
Data_Get_Struct(self, xmlXPathContext, ctx);
|
271
284
|
|
272
|
-
if(rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1)
|
285
|
+
if (rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1) {
|
273
286
|
xpath_handler = Qnil;
|
287
|
+
}
|
274
288
|
|
275
289
|
query = (xmlChar *)StringValueCStr(search_path);
|
276
290
|
|
277
|
-
if(Qnil != xpath_handler) {
|
291
|
+
if (Qnil != xpath_handler) {
|
278
292
|
/* FIXME: not sure if this is the correct place to shove private data. */
|
279
293
|
ctx->userData = (void *)xpath_handler;
|
280
294
|
xmlXPathRegisterFuncLookup(ctx, lookup, (void *)xpath_handler);
|
@@ -291,7 +305,7 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
|
|
291
305
|
xmlSetStructuredErrorFunc(NULL, NULL);
|
292
306
|
xmlSetGenericErrorFunc(NULL, NULL);
|
293
307
|
|
294
|
-
if(xpath == NULL) {
|
308
|
+
if (xpath == NULL) {
|
295
309
|
xmlErrorPtr error = xmlGetLastError();
|
296
310
|
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
297
311
|
}
|
@@ -299,23 +313,23 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
|
|
299
313
|
assert(ctx->doc);
|
300
314
|
assert(DOC_RUBY_OBJECT_TEST(ctx->doc));
|
301
315
|
|
302
|
-
switch(xpath->type) {
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
316
|
+
switch (xpath->type) {
|
317
|
+
case XPATH_STRING:
|
318
|
+
thing = NOKOGIRI_STR_NEW2(xpath->stringval);
|
319
|
+
xmlFree(xpath->stringval);
|
320
|
+
break;
|
321
|
+
case XPATH_NODESET:
|
322
|
+
thing = noko_xml_node_set_wrap(xpath->nodesetval,
|
323
|
+
DOC_RUBY_OBJECT(ctx->doc));
|
324
|
+
break;
|
325
|
+
case XPATH_NUMBER:
|
326
|
+
thing = rb_float_new(xpath->floatval);
|
327
|
+
break;
|
328
|
+
case XPATH_BOOLEAN:
|
329
|
+
thing = xpath->boolval == 1 ? Qtrue : Qfalse;
|
330
|
+
break;
|
331
|
+
default:
|
332
|
+
thing = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(ctx->doc));
|
319
333
|
}
|
320
334
|
|
321
335
|
xmlXPathFreeNodeSetList(xpath);
|
@@ -329,7 +343,8 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
|
|
329
343
|
*
|
330
344
|
* Create a new XPathContext with +node+ as the reference point.
|
331
345
|
*/
|
332
|
-
static VALUE
|
346
|
+
static VALUE
|
347
|
+
new (VALUE klass, VALUE nodeobj)
|
333
348
|
{
|
334
349
|
xmlNodePtr node;
|
335
350
|
xmlXPathContextPtr ctx;
|
@@ -350,25 +365,17 @@ static VALUE new(VALUE klass, VALUE nodeobj)
|
|
350
365
|
return self;
|
351
366
|
}
|
352
367
|
|
353
|
-
|
354
|
-
|
368
|
+
void
|
369
|
+
noko_init_xml_xpath_context(void)
|
355
370
|
{
|
356
|
-
VALUE module = rb_define_module("Nokogiri");
|
357
|
-
|
358
|
-
/*
|
359
|
-
* Nokogiri::XML
|
360
|
-
*/
|
361
|
-
VALUE xml = rb_define_module_under(module, "XML");
|
362
|
-
|
363
371
|
/*
|
364
372
|
* XPathContext is the entry point for searching a Document by using XPath.
|
365
373
|
*/
|
366
|
-
|
374
|
+
cNokogiriXmlXpathContext = rb_define_class_under(mNokogiriXml, "XPathContext", rb_cObject);
|
367
375
|
|
368
|
-
cNokogiriXmlXpathContext
|
376
|
+
rb_define_singleton_method(cNokogiriXmlXpathContext, "new", new, 1);
|
369
377
|
|
370
|
-
|
371
|
-
rb_define_method(
|
372
|
-
rb_define_method(
|
373
|
-
rb_define_method(klass, "register_ns", register_ns, 2);
|
378
|
+
rb_define_method(cNokogiriXmlXpathContext, "evaluate", evaluate, -1);
|
379
|
+
rb_define_method(cNokogiriXmlXpathContext, "register_variable", register_variable, 2);
|
380
|
+
rb_define_method(cNokogiriXmlXpathContext, "register_ns", register_ns, 2);
|
374
381
|
}
|