nokogiri 1.14.0.rc1-arm-linux
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 +7 -0
- data/Gemfile +38 -0
- data/LICENSE-DEPENDENCIES.md +2224 -0
- data/LICENSE.md +9 -0
- data/README.md +287 -0
- data/bin/nokogiri +131 -0
- data/dependencies.yml +41 -0
- data/ext/nokogiri/depend +38 -0
- data/ext/nokogiri/extconf.rb +1082 -0
- data/ext/nokogiri/gumbo.c +594 -0
- data/ext/nokogiri/html4_document.c +166 -0
- data/ext/nokogiri/html4_element_description.c +294 -0
- data/ext/nokogiri/html4_entity_lookup.c +37 -0
- data/ext/nokogiri/html4_sax_parser_context.c +114 -0
- data/ext/nokogiri/html4_sax_push_parser.c +95 -0
- data/ext/nokogiri/include/libexslt/exslt.h +108 -0
- data/ext/nokogiri/include/libexslt/exsltconfig.h +70 -0
- data/ext/nokogiri/include/libexslt/exsltexports.h +63 -0
- data/ext/nokogiri/include/libxml2/libxml/HTMLparser.h +306 -0
- data/ext/nokogiri/include/libxml2/libxml/HTMLtree.h +147 -0
- data/ext/nokogiri/include/libxml2/libxml/SAX.h +204 -0
- data/ext/nokogiri/include/libxml2/libxml/SAX2.h +172 -0
- data/ext/nokogiri/include/libxml2/libxml/c14n.h +128 -0
- data/ext/nokogiri/include/libxml2/libxml/catalog.h +182 -0
- data/ext/nokogiri/include/libxml2/libxml/chvalid.h +230 -0
- data/ext/nokogiri/include/libxml2/libxml/debugXML.h +217 -0
- data/ext/nokogiri/include/libxml2/libxml/dict.h +81 -0
- data/ext/nokogiri/include/libxml2/libxml/encoding.h +232 -0
- data/ext/nokogiri/include/libxml2/libxml/entities.h +153 -0
- data/ext/nokogiri/include/libxml2/libxml/globals.h +499 -0
- data/ext/nokogiri/include/libxml2/libxml/hash.h +236 -0
- data/ext/nokogiri/include/libxml2/libxml/list.h +137 -0
- data/ext/nokogiri/include/libxml2/libxml/nanoftp.h +186 -0
- data/ext/nokogiri/include/libxml2/libxml/nanohttp.h +81 -0
- data/ext/nokogiri/include/libxml2/libxml/parser.h +1244 -0
- data/ext/nokogiri/include/libxml2/libxml/parserInternals.h +656 -0
- data/ext/nokogiri/include/libxml2/libxml/pattern.h +100 -0
- data/ext/nokogiri/include/libxml2/libxml/relaxng.h +218 -0
- data/ext/nokogiri/include/libxml2/libxml/schemasInternals.h +958 -0
- data/ext/nokogiri/include/libxml2/libxml/schematron.h +142 -0
- data/ext/nokogiri/include/libxml2/libxml/threads.h +91 -0
- data/ext/nokogiri/include/libxml2/libxml/tree.h +1312 -0
- data/ext/nokogiri/include/libxml2/libxml/uri.h +94 -0
- data/ext/nokogiri/include/libxml2/libxml/valid.h +463 -0
- data/ext/nokogiri/include/libxml2/libxml/xinclude.h +129 -0
- data/ext/nokogiri/include/libxml2/libxml/xlink.h +189 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlIO.h +368 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlautomata.h +146 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlerror.h +947 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlexports.h +77 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlmemory.h +226 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlmodule.h +57 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlreader.h +428 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlregexp.h +222 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlsave.h +88 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlschemas.h +246 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlschemastypes.h +152 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlstring.h +140 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlunicode.h +202 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlversion.h +503 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlwriter.h +488 -0
- data/ext/nokogiri/include/libxml2/libxml/xpath.h +575 -0
- data/ext/nokogiri/include/libxml2/libxml/xpathInternals.h +632 -0
- data/ext/nokogiri/include/libxml2/libxml/xpointer.h +137 -0
- data/ext/nokogiri/include/libxslt/attributes.h +38 -0
- data/ext/nokogiri/include/libxslt/documents.h +93 -0
- data/ext/nokogiri/include/libxslt/extensions.h +262 -0
- data/ext/nokogiri/include/libxslt/extra.h +72 -0
- data/ext/nokogiri/include/libxslt/functions.h +78 -0
- data/ext/nokogiri/include/libxslt/imports.h +75 -0
- data/ext/nokogiri/include/libxslt/keys.h +53 -0
- data/ext/nokogiri/include/libxslt/namespaces.h +68 -0
- data/ext/nokogiri/include/libxslt/numbersInternals.h +73 -0
- data/ext/nokogiri/include/libxslt/pattern.h +84 -0
- data/ext/nokogiri/include/libxslt/preproc.h +43 -0
- data/ext/nokogiri/include/libxslt/security.h +104 -0
- data/ext/nokogiri/include/libxslt/templates.h +77 -0
- data/ext/nokogiri/include/libxslt/transform.h +207 -0
- data/ext/nokogiri/include/libxslt/variables.h +118 -0
- data/ext/nokogiri/include/libxslt/xslt.h +110 -0
- data/ext/nokogiri/include/libxslt/xsltInternals.h +1982 -0
- data/ext/nokogiri/include/libxslt/xsltconfig.h +179 -0
- data/ext/nokogiri/include/libxslt/xsltexports.h +64 -0
- data/ext/nokogiri/include/libxslt/xsltlocale.h +76 -0
- data/ext/nokogiri/include/libxslt/xsltutils.h +310 -0
- data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
- data/ext/nokogiri/nokogiri.c +259 -0
- data/ext/nokogiri/nokogiri.h +235 -0
- data/ext/nokogiri/test_global_handlers.c +40 -0
- data/ext/nokogiri/xml_attr.c +103 -0
- data/ext/nokogiri/xml_attribute_decl.c +70 -0
- data/ext/nokogiri/xml_cdata.c +57 -0
- data/ext/nokogiri/xml_comment.c +62 -0
- data/ext/nokogiri/xml_document.c +689 -0
- data/ext/nokogiri/xml_document_fragment.c +44 -0
- data/ext/nokogiri/xml_dtd.c +208 -0
- data/ext/nokogiri/xml_element_content.c +128 -0
- data/ext/nokogiri/xml_element_decl.c +69 -0
- data/ext/nokogiri/xml_encoding_handler.c +104 -0
- data/ext/nokogiri/xml_entity_decl.c +112 -0
- data/ext/nokogiri/xml_entity_reference.c +50 -0
- data/ext/nokogiri/xml_namespace.c +186 -0
- data/ext/nokogiri/xml_node.c +2425 -0
- data/ext/nokogiri/xml_node_set.c +496 -0
- data/ext/nokogiri/xml_processing_instruction.c +54 -0
- data/ext/nokogiri/xml_reader.c +794 -0
- data/ext/nokogiri/xml_relax_ng.c +183 -0
- data/ext/nokogiri/xml_sax_parser.c +316 -0
- data/ext/nokogiri/xml_sax_parser_context.c +283 -0
- data/ext/nokogiri/xml_sax_push_parser.c +166 -0
- data/ext/nokogiri/xml_schema.c +282 -0
- data/ext/nokogiri/xml_syntax_error.c +85 -0
- data/ext/nokogiri/xml_text.c +48 -0
- data/ext/nokogiri/xml_xpath_context.c +413 -0
- data/ext/nokogiri/xslt_stylesheet.c +363 -0
- data/gumbo-parser/CHANGES.md +63 -0
- data/gumbo-parser/Makefile +111 -0
- data/gumbo-parser/THANKS +27 -0
- data/lib/nokogiri/2.7/nokogiri.so +0 -0
- data/lib/nokogiri/3.0/nokogiri.so +0 -0
- data/lib/nokogiri/3.1/nokogiri.so +0 -0
- data/lib/nokogiri/3.2/nokogiri.so +0 -0
- data/lib/nokogiri/class_resolver.rb +67 -0
- data/lib/nokogiri/css/node.rb +54 -0
- data/lib/nokogiri/css/parser.rb +770 -0
- data/lib/nokogiri/css/parser.y +277 -0
- data/lib/nokogiri/css/parser_extras.rb +96 -0
- data/lib/nokogiri/css/syntax_error.rb +9 -0
- data/lib/nokogiri/css/tokenizer.rb +155 -0
- data/lib/nokogiri/css/tokenizer.rex +56 -0
- data/lib/nokogiri/css/xpath_visitor.rb +359 -0
- data/lib/nokogiri/css.rb +66 -0
- data/lib/nokogiri/decorators/slop.rb +44 -0
- data/lib/nokogiri/encoding_handler.rb +57 -0
- data/lib/nokogiri/extension.rb +32 -0
- data/lib/nokogiri/gumbo.rb +15 -0
- data/lib/nokogiri/html.rb +48 -0
- data/lib/nokogiri/html4/builder.rb +37 -0
- data/lib/nokogiri/html4/document.rb +214 -0
- data/lib/nokogiri/html4/document_fragment.rb +54 -0
- data/lib/nokogiri/html4/element_description.rb +25 -0
- data/lib/nokogiri/html4/element_description_defaults.rb +572 -0
- data/lib/nokogiri/html4/encoding_reader.rb +121 -0
- data/lib/nokogiri/html4/entity_lookup.rb +15 -0
- data/lib/nokogiri/html4/sax/parser.rb +63 -0
- data/lib/nokogiri/html4/sax/parser_context.rb +20 -0
- data/lib/nokogiri/html4/sax/push_parser.rb +37 -0
- data/lib/nokogiri/html4.rb +47 -0
- data/lib/nokogiri/html5/document.rb +168 -0
- data/lib/nokogiri/html5/document_fragment.rb +90 -0
- data/lib/nokogiri/html5/node.rb +98 -0
- data/lib/nokogiri/html5.rb +389 -0
- data/lib/nokogiri/jruby/dependencies.rb +3 -0
- data/lib/nokogiri/jruby/nokogiri_jars.rb +43 -0
- data/lib/nokogiri/syntax_error.rb +6 -0
- data/lib/nokogiri/version/constant.rb +6 -0
- data/lib/nokogiri/version/info.rb +223 -0
- data/lib/nokogiri/version.rb +4 -0
- data/lib/nokogiri/xml/attr.rb +66 -0
- data/lib/nokogiri/xml/attribute_decl.rb +20 -0
- data/lib/nokogiri/xml/builder.rb +487 -0
- data/lib/nokogiri/xml/cdata.rb +13 -0
- data/lib/nokogiri/xml/character_data.rb +9 -0
- data/lib/nokogiri/xml/document.rb +471 -0
- data/lib/nokogiri/xml/document_fragment.rb +205 -0
- data/lib/nokogiri/xml/dtd.rb +34 -0
- data/lib/nokogiri/xml/element_content.rb +38 -0
- data/lib/nokogiri/xml/element_decl.rb +15 -0
- data/lib/nokogiri/xml/entity_decl.rb +21 -0
- data/lib/nokogiri/xml/entity_reference.rb +20 -0
- data/lib/nokogiri/xml/namespace.rb +58 -0
- data/lib/nokogiri/xml/node/save_options.rb +68 -0
- data/lib/nokogiri/xml/node.rb +1563 -0
- data/lib/nokogiri/xml/node_set.rb +446 -0
- data/lib/nokogiri/xml/notation.rb +19 -0
- data/lib/nokogiri/xml/parse_options.rb +213 -0
- data/lib/nokogiri/xml/pp/character_data.rb +21 -0
- data/lib/nokogiri/xml/pp/node.rb +57 -0
- data/lib/nokogiri/xml/pp.rb +4 -0
- data/lib/nokogiri/xml/processing_instruction.rb +11 -0
- data/lib/nokogiri/xml/reader.rb +105 -0
- data/lib/nokogiri/xml/relax_ng.rb +38 -0
- data/lib/nokogiri/xml/sax/document.rb +167 -0
- data/lib/nokogiri/xml/sax/parser.rb +125 -0
- data/lib/nokogiri/xml/sax/parser_context.rb +21 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +61 -0
- data/lib/nokogiri/xml/sax.rb +6 -0
- data/lib/nokogiri/xml/schema.rb +73 -0
- data/lib/nokogiri/xml/searchable.rb +270 -0
- data/lib/nokogiri/xml/syntax_error.rb +72 -0
- data/lib/nokogiri/xml/text.rb +11 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +13 -0
- data/lib/nokogiri/xml/xpath.rb +21 -0
- data/lib/nokogiri/xml/xpath_context.rb +16 -0
- data/lib/nokogiri/xml.rb +76 -0
- data/lib/nokogiri/xslt/stylesheet.rb +27 -0
- data/lib/nokogiri/xslt.rb +65 -0
- data/lib/nokogiri.rb +120 -0
- data/lib/xsd/xmlparser/nokogiri.rb +104 -0
- metadata +317 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
#include <nokogiri.h>
|
2
|
+
|
3
|
+
VALUE cNokogiriXmlSyntaxError;
|
4
|
+
|
5
|
+
void
|
6
|
+
Nokogiri_structured_error_func_save(libxmlStructuredErrorHandlerState *handler_state)
|
7
|
+
{
|
8
|
+
/* this method is tightly coupled to the implementation of xmlSetStructuredErrorFunc */
|
9
|
+
handler_state->user_data = xmlStructuredErrorContext;
|
10
|
+
handler_state->handler = xmlStructuredError;
|
11
|
+
}
|
12
|
+
|
13
|
+
void
|
14
|
+
Nokogiri_structured_error_func_save_and_set(libxmlStructuredErrorHandlerState *handler_state,
|
15
|
+
void *user_data,
|
16
|
+
xmlStructuredErrorFunc handler)
|
17
|
+
{
|
18
|
+
Nokogiri_structured_error_func_save(handler_state);
|
19
|
+
xmlSetStructuredErrorFunc(user_data, handler);
|
20
|
+
}
|
21
|
+
|
22
|
+
void
|
23
|
+
Nokogiri_structured_error_func_restore(libxmlStructuredErrorHandlerState *handler_state)
|
24
|
+
{
|
25
|
+
xmlSetStructuredErrorFunc(handler_state->user_data, handler_state->handler);
|
26
|
+
}
|
27
|
+
|
28
|
+
void
|
29
|
+
Nokogiri_error_array_pusher(void *ctx, xmlErrorPtr error)
|
30
|
+
{
|
31
|
+
VALUE list = (VALUE)ctx;
|
32
|
+
Check_Type(list, T_ARRAY);
|
33
|
+
rb_ary_push(list, Nokogiri_wrap_xml_syntax_error(error));
|
34
|
+
}
|
35
|
+
|
36
|
+
void
|
37
|
+
Nokogiri_error_raise(void *ctx, xmlErrorPtr error)
|
38
|
+
{
|
39
|
+
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
40
|
+
}
|
41
|
+
|
42
|
+
VALUE
|
43
|
+
Nokogiri_wrap_xml_syntax_error(xmlErrorPtr error)
|
44
|
+
{
|
45
|
+
VALUE msg, e, klass;
|
46
|
+
|
47
|
+
klass = cNokogiriXmlSyntaxError;
|
48
|
+
|
49
|
+
if (error && error->domain == XML_FROM_XPATH) {
|
50
|
+
klass = cNokogiriXmlXpathSyntaxError;
|
51
|
+
}
|
52
|
+
|
53
|
+
msg = (error && error->message) ? NOKOGIRI_STR_NEW2(error->message) : Qnil;
|
54
|
+
|
55
|
+
e = rb_class_new_instance(
|
56
|
+
1,
|
57
|
+
&msg,
|
58
|
+
klass
|
59
|
+
);
|
60
|
+
|
61
|
+
if (error) {
|
62
|
+
rb_iv_set(e, "@domain", INT2NUM(error->domain));
|
63
|
+
rb_iv_set(e, "@code", INT2NUM(error->code));
|
64
|
+
rb_iv_set(e, "@level", INT2NUM((short)error->level));
|
65
|
+
rb_iv_set(e, "@file", RBSTR_OR_QNIL(error->file));
|
66
|
+
rb_iv_set(e, "@line", INT2NUM(error->line));
|
67
|
+
rb_iv_set(e, "@str1", RBSTR_OR_QNIL(error->str1));
|
68
|
+
rb_iv_set(e, "@str2", RBSTR_OR_QNIL(error->str2));
|
69
|
+
rb_iv_set(e, "@str3", RBSTR_OR_QNIL(error->str3));
|
70
|
+
rb_iv_set(e, "@int1", INT2NUM(error->int1));
|
71
|
+
rb_iv_set(e, "@column", INT2NUM(error->int2));
|
72
|
+
}
|
73
|
+
|
74
|
+
return e;
|
75
|
+
}
|
76
|
+
|
77
|
+
void
|
78
|
+
noko_init_xml_syntax_error()
|
79
|
+
{
|
80
|
+
assert(cNokogiriSyntaxError);
|
81
|
+
/*
|
82
|
+
* The XML::SyntaxError is raised on parse errors
|
83
|
+
*/
|
84
|
+
cNokogiriXmlSyntaxError = rb_define_class_under(mNokogiriXml, "SyntaxError", cNokogiriSyntaxError);
|
85
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#include <nokogiri.h>
|
2
|
+
|
3
|
+
VALUE cNokogiriXmlText ;
|
4
|
+
|
5
|
+
/*
|
6
|
+
* call-seq:
|
7
|
+
* new(content, document)
|
8
|
+
*
|
9
|
+
* Create a new Text element on the +document+ with +content+
|
10
|
+
*/
|
11
|
+
static VALUE
|
12
|
+
new (int argc, VALUE *argv, VALUE klass)
|
13
|
+
{
|
14
|
+
xmlDocPtr doc;
|
15
|
+
xmlNodePtr node;
|
16
|
+
VALUE string;
|
17
|
+
VALUE document;
|
18
|
+
VALUE rest;
|
19
|
+
VALUE rb_node;
|
20
|
+
|
21
|
+
rb_scan_args(argc, argv, "2*", &string, &document, &rest);
|
22
|
+
|
23
|
+
Noko_Node_Get_Struct(document, xmlDoc, doc);
|
24
|
+
|
25
|
+
node = xmlNewText((xmlChar *)StringValueCStr(string));
|
26
|
+
node->doc = doc->doc;
|
27
|
+
|
28
|
+
noko_xml_document_pin_node(node);
|
29
|
+
|
30
|
+
rb_node = noko_xml_node_wrap(klass, node) ;
|
31
|
+
rb_obj_call_init(rb_node, argc, argv);
|
32
|
+
|
33
|
+
if (rb_block_given_p()) { rb_yield(rb_node); }
|
34
|
+
|
35
|
+
return rb_node;
|
36
|
+
}
|
37
|
+
|
38
|
+
void
|
39
|
+
noko_init_xml_text()
|
40
|
+
{
|
41
|
+
assert(cNokogiriXmlCharacterData);
|
42
|
+
/*
|
43
|
+
* Wraps Text nodes.
|
44
|
+
*/
|
45
|
+
cNokogiriXmlText = rb_define_class_under(mNokogiriXml, "Text", cNokogiriXmlCharacterData);
|
46
|
+
|
47
|
+
rb_define_singleton_method(cNokogiriXmlText, "new", new, -1);
|
48
|
+
}
|
@@ -0,0 +1,413 @@
|
|
1
|
+
#include <nokogiri.h>
|
2
|
+
|
3
|
+
VALUE cNokogiriXmlXpathContext;
|
4
|
+
|
5
|
+
/*
|
6
|
+
* these constants have matching declarations in
|
7
|
+
* ext/java/nokogiri/internals/NokogiriNamespaceContext.java
|
8
|
+
*/
|
9
|
+
static const xmlChar *NOKOGIRI_PREFIX = (const xmlChar *)"nokogiri";
|
10
|
+
static const xmlChar *NOKOGIRI_URI = (const xmlChar *)"http://www.nokogiri.org/default_ns/ruby/extensions_functions";
|
11
|
+
static const xmlChar *NOKOGIRI_BUILTIN_PREFIX = (const xmlChar *)"nokogiri-builtin";
|
12
|
+
static const xmlChar *NOKOGIRI_BUILTIN_URI = (const xmlChar *)"https://www.nokogiri.org/default_ns/ruby/builtins";
|
13
|
+
|
14
|
+
static void
|
15
|
+
xml_xpath_context_deallocate(xmlXPathContextPtr ctx)
|
16
|
+
{
|
17
|
+
xmlXPathFreeContext(ctx);
|
18
|
+
}
|
19
|
+
|
20
|
+
/* find a CSS class in an HTML element's `class` attribute */
|
21
|
+
static const xmlChar *
|
22
|
+
builtin_css_class(const xmlChar *str, const xmlChar *val)
|
23
|
+
{
|
24
|
+
int val_len;
|
25
|
+
|
26
|
+
if (str == NULL) { return (NULL); }
|
27
|
+
if (val == NULL) { return (NULL); }
|
28
|
+
|
29
|
+
val_len = xmlStrlen(val);
|
30
|
+
if (val_len == 0) { return (str); }
|
31
|
+
|
32
|
+
while (*str != 0) {
|
33
|
+
if ((*str == *val) && !xmlStrncmp(str, val, val_len)) {
|
34
|
+
const xmlChar *next_byte = str + val_len;
|
35
|
+
|
36
|
+
/* only match if the next byte is whitespace or end of string */
|
37
|
+
if ((*next_byte == 0) || (IS_BLANK_CH(*next_byte))) {
|
38
|
+
return ((const xmlChar *)str);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
/* advance str to whitespace */
|
43
|
+
while ((*str != 0) && !IS_BLANK_CH(*str)) {
|
44
|
+
str++;
|
45
|
+
}
|
46
|
+
|
47
|
+
/* advance str to start of next word or end of string */
|
48
|
+
while ((*str != 0) && IS_BLANK_CH(*str)) {
|
49
|
+
str++;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
return (NULL);
|
54
|
+
}
|
55
|
+
|
56
|
+
/* xmlXPathFunction to wrap builtin_css_class() */
|
57
|
+
static void
|
58
|
+
xpath_builtin_css_class(xmlXPathParserContextPtr ctxt, int nargs)
|
59
|
+
{
|
60
|
+
xmlXPathObjectPtr hay, needle;
|
61
|
+
|
62
|
+
CHECK_ARITY(2);
|
63
|
+
|
64
|
+
CAST_TO_STRING;
|
65
|
+
needle = valuePop(ctxt);
|
66
|
+
if ((needle == NULL) || (needle->type != XPATH_STRING)) {
|
67
|
+
xmlXPathFreeObject(needle);
|
68
|
+
XP_ERROR(XPATH_INVALID_TYPE);
|
69
|
+
}
|
70
|
+
|
71
|
+
CAST_TO_STRING;
|
72
|
+
hay = valuePop(ctxt);
|
73
|
+
if ((hay == NULL) || (hay->type != XPATH_STRING)) {
|
74
|
+
xmlXPathFreeObject(hay);
|
75
|
+
xmlXPathFreeObject(needle);
|
76
|
+
XP_ERROR(XPATH_INVALID_TYPE);
|
77
|
+
}
|
78
|
+
|
79
|
+
if (builtin_css_class(hay->stringval, needle->stringval)) {
|
80
|
+
valuePush(ctxt, xmlXPathNewBoolean(1));
|
81
|
+
} else {
|
82
|
+
valuePush(ctxt, xmlXPathNewBoolean(0));
|
83
|
+
}
|
84
|
+
|
85
|
+
xmlXPathFreeObject(hay);
|
86
|
+
xmlXPathFreeObject(needle);
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
/* xmlXPathFunction to select nodes whose local name matches, for HTML5 CSS queries that should ignore namespaces */
|
91
|
+
static void
|
92
|
+
xpath_builtin_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
|
93
|
+
{
|
94
|
+
xmlXPathObjectPtr element_name;
|
95
|
+
|
96
|
+
assert(ctxt->context->node);
|
97
|
+
|
98
|
+
CHECK_ARITY(1);
|
99
|
+
CAST_TO_STRING;
|
100
|
+
CHECK_TYPE(XPATH_STRING);
|
101
|
+
element_name = valuePop(ctxt);
|
102
|
+
|
103
|
+
valuePush(ctxt, xmlXPathNewBoolean(xmlStrEqual(ctxt->context->node->name, element_name->stringval)));
|
104
|
+
|
105
|
+
xmlXPathFreeObject(element_name);
|
106
|
+
}
|
107
|
+
|
108
|
+
|
109
|
+
/*
|
110
|
+
* call-seq:
|
111
|
+
* register_ns(prefix, uri)
|
112
|
+
*
|
113
|
+
* Register the namespace with +prefix+ and +uri+.
|
114
|
+
*/
|
115
|
+
static VALUE
|
116
|
+
rb_xml_xpath_context_register_ns(VALUE self, VALUE prefix, VALUE uri)
|
117
|
+
{
|
118
|
+
xmlXPathContextPtr ctx;
|
119
|
+
Data_Get_Struct(self, xmlXPathContext, ctx);
|
120
|
+
|
121
|
+
xmlXPathRegisterNs(ctx,
|
122
|
+
(const xmlChar *)StringValueCStr(prefix),
|
123
|
+
(const xmlChar *)StringValueCStr(uri)
|
124
|
+
);
|
125
|
+
return self;
|
126
|
+
}
|
127
|
+
|
128
|
+
/*
|
129
|
+
* call-seq:
|
130
|
+
* register_variable(name, value)
|
131
|
+
*
|
132
|
+
* Register the variable +name+ with +value+.
|
133
|
+
*/
|
134
|
+
static VALUE
|
135
|
+
rb_xml_xpath_context_register_variable(VALUE self, VALUE name, VALUE value)
|
136
|
+
{
|
137
|
+
xmlXPathContextPtr ctx;
|
138
|
+
xmlXPathObjectPtr xmlValue;
|
139
|
+
Data_Get_Struct(self, xmlXPathContext, ctx);
|
140
|
+
|
141
|
+
xmlValue = xmlXPathNewCString(StringValueCStr(value));
|
142
|
+
|
143
|
+
xmlXPathRegisterVariable(ctx,
|
144
|
+
(const xmlChar *)StringValueCStr(name),
|
145
|
+
xmlValue
|
146
|
+
);
|
147
|
+
|
148
|
+
return self;
|
149
|
+
}
|
150
|
+
|
151
|
+
|
152
|
+
/*
|
153
|
+
* convert an XPath object into a Ruby object of the appropriate type.
|
154
|
+
* returns Qundef if no conversion was possible.
|
155
|
+
*/
|
156
|
+
static VALUE
|
157
|
+
xpath2ruby(xmlXPathObjectPtr c_xpath_object, xmlXPathContextPtr ctx)
|
158
|
+
{
|
159
|
+
VALUE rb_retval;
|
160
|
+
|
161
|
+
assert(ctx->doc);
|
162
|
+
assert(DOC_RUBY_OBJECT_TEST(ctx->doc));
|
163
|
+
|
164
|
+
switch (c_xpath_object->type) {
|
165
|
+
case XPATH_STRING:
|
166
|
+
rb_retval = NOKOGIRI_STR_NEW2(c_xpath_object->stringval);
|
167
|
+
xmlFree(c_xpath_object->stringval);
|
168
|
+
return rb_retval;
|
169
|
+
|
170
|
+
case XPATH_NODESET:
|
171
|
+
return noko_xml_node_set_wrap(c_xpath_object->nodesetval,
|
172
|
+
DOC_RUBY_OBJECT(ctx->doc));
|
173
|
+
|
174
|
+
case XPATH_NUMBER:
|
175
|
+
return rb_float_new(c_xpath_object->floatval);
|
176
|
+
|
177
|
+
case XPATH_BOOLEAN:
|
178
|
+
return (c_xpath_object->boolval == 1) ? Qtrue : Qfalse;
|
179
|
+
|
180
|
+
default:
|
181
|
+
return Qundef;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
void
|
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
|
+
)
|
192
|
+
{
|
193
|
+
VALUE rb_retval;
|
194
|
+
VALUE *argv;
|
195
|
+
VALUE rb_node_set = Qnil;
|
196
|
+
xmlNodeSetPtr c_node_set = NULL;
|
197
|
+
xmlXPathObjectPtr c_xpath_object;
|
198
|
+
|
199
|
+
assert(ctx->context->doc);
|
200
|
+
assert(DOC_RUBY_OBJECT_TEST(ctx->context->doc));
|
201
|
+
|
202
|
+
argv = (VALUE *)ruby_xcalloc((size_t)argc, sizeof(VALUE));
|
203
|
+
for (int j = 0 ; j < argc ; ++j) {
|
204
|
+
rb_gc_register_address(&argv[j]);
|
205
|
+
}
|
206
|
+
|
207
|
+
for (int j = argc - 1 ; j >= 0 ; --j) {
|
208
|
+
c_xpath_object = valuePop(ctx);
|
209
|
+
argv[j] = xpath2ruby(c_xpath_object, ctx->context);
|
210
|
+
if (argv[j] == Qundef) {
|
211
|
+
argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(c_xpath_object));
|
212
|
+
}
|
213
|
+
xmlXPathFreeNodeSetList(c_xpath_object);
|
214
|
+
}
|
215
|
+
|
216
|
+
rb_retval = rb_funcall2(rb_xpath_handler, rb_intern((const char *)method_name), argc, argv);
|
217
|
+
|
218
|
+
for (int j = 0 ; j < argc ; ++j) {
|
219
|
+
rb_gc_unregister_address(&argv[j]);
|
220
|
+
}
|
221
|
+
ruby_xfree(argv);
|
222
|
+
|
223
|
+
switch (TYPE(rb_retval)) {
|
224
|
+
case T_FLOAT:
|
225
|
+
case T_BIGNUM:
|
226
|
+
case T_FIXNUM:
|
227
|
+
xmlXPathReturnNumber(ctx, NUM2DBL(rb_retval));
|
228
|
+
break;
|
229
|
+
case T_STRING:
|
230
|
+
xmlXPathReturnString(ctx, xmlCharStrdup(StringValueCStr(rb_retval)));
|
231
|
+
break;
|
232
|
+
case T_TRUE:
|
233
|
+
xmlXPathReturnTrue(ctx);
|
234
|
+
break;
|
235
|
+
case T_FALSE:
|
236
|
+
xmlXPathReturnFalse(ctx);
|
237
|
+
break;
|
238
|
+
case T_NIL:
|
239
|
+
break;
|
240
|
+
case T_ARRAY: {
|
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));
|
245
|
+
}
|
246
|
+
break;
|
247
|
+
case T_DATA:
|
248
|
+
if (rb_obj_is_kind_of(rb_retval, cNokogiriXmlNodeSet)) {
|
249
|
+
Data_Get_Struct(rb_retval, xmlNodeSet, c_node_set);
|
250
|
+
/* Copy the node set, otherwise it will get GC'd. */
|
251
|
+
xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, c_node_set));
|
252
|
+
break;
|
253
|
+
}
|
254
|
+
default:
|
255
|
+
rb_raise(rb_eRuntimeError, "Invalid return type");
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
static void
|
260
|
+
method_caller(xmlXPathParserContextPtr ctx, int argc)
|
261
|
+
{
|
262
|
+
VALUE rb_xpath_handler = Qnil;
|
263
|
+
const char *method_name = NULL ;
|
264
|
+
|
265
|
+
assert(ctx);
|
266
|
+
assert(ctx->context);
|
267
|
+
assert(ctx->context->userData);
|
268
|
+
assert(ctx->context->function);
|
269
|
+
|
270
|
+
rb_xpath_handler = (VALUE)(ctx->context->userData);
|
271
|
+
method_name = (const char *)(ctx->context->function);
|
272
|
+
|
273
|
+
Nokogiri_marshal_xpath_funcall_and_return_values(ctx, argc, rb_xpath_handler, method_name);
|
274
|
+
}
|
275
|
+
|
276
|
+
static xmlXPathFunction
|
277
|
+
handler_lookup(void *ctx, const xmlChar *c_name, const xmlChar *c_ns_uri)
|
278
|
+
{
|
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;
|
282
|
+
}
|
283
|
+
|
284
|
+
return NULL;
|
285
|
+
}
|
286
|
+
|
287
|
+
PRINTFLIKE_DECL(2, 3)
|
288
|
+
static void
|
289
|
+
generic_exception_pusher(void *ctx, const char *msg, ...)
|
290
|
+
{
|
291
|
+
VALUE rb_errors = (VALUE)ctx;
|
292
|
+
VALUE rb_message;
|
293
|
+
VALUE rb_exception;
|
294
|
+
|
295
|
+
Check_Type(rb_errors, T_ARRAY);
|
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
|
302
|
+
va_list args;
|
303
|
+
va_start(args, msg);
|
304
|
+
rb_message = rb_vsprintf(msg, args);
|
305
|
+
va_end(args);
|
306
|
+
#endif
|
307
|
+
|
308
|
+
rb_exception = rb_exc_new_str(cNokogiriXmlXpathSyntaxError, rb_message);
|
309
|
+
rb_ary_push(rb_errors, rb_exception);
|
310
|
+
}
|
311
|
+
|
312
|
+
/*
|
313
|
+
* call-seq:
|
314
|
+
* evaluate(search_path, handler = nil)
|
315
|
+
*
|
316
|
+
* Evaluate the +search_path+ returning an XML::XPath object.
|
317
|
+
*/
|
318
|
+
static VALUE
|
319
|
+
rb_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE self)
|
320
|
+
{
|
321
|
+
VALUE search_path, xpath_handler;
|
322
|
+
VALUE retval = Qnil;
|
323
|
+
xmlXPathContextPtr ctx;
|
324
|
+
xmlXPathObjectPtr xpath;
|
325
|
+
xmlChar *query;
|
326
|
+
VALUE errors = rb_ary_new();
|
327
|
+
|
328
|
+
Data_Get_Struct(self, xmlXPathContext, ctx);
|
329
|
+
|
330
|
+
if (rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1) {
|
331
|
+
xpath_handler = Qnil;
|
332
|
+
}
|
333
|
+
|
334
|
+
query = (xmlChar *)StringValueCStr(search_path);
|
335
|
+
|
336
|
+
if (Qnil != xpath_handler) {
|
337
|
+
/* FIXME: not sure if this is the correct place to shove private data. */
|
338
|
+
ctx->userData = (void *)xpath_handler;
|
339
|
+
xmlXPathRegisterFuncLookup(ctx, handler_lookup, (void *)xpath_handler);
|
340
|
+
}
|
341
|
+
|
342
|
+
xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);
|
343
|
+
xmlSetGenericErrorFunc((void *)errors, generic_exception_pusher);
|
344
|
+
|
345
|
+
xpath = xmlXPathEvalExpression(query, ctx);
|
346
|
+
|
347
|
+
xmlSetStructuredErrorFunc(NULL, NULL);
|
348
|
+
xmlSetGenericErrorFunc(NULL, NULL);
|
349
|
+
|
350
|
+
if (xpath == NULL) {
|
351
|
+
rb_exc_raise(rb_ary_entry(errors, 0));
|
352
|
+
}
|
353
|
+
|
354
|
+
retval = xpath2ruby(xpath, ctx);
|
355
|
+
if (retval == Qundef) {
|
356
|
+
retval = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(ctx->doc));
|
357
|
+
}
|
358
|
+
|
359
|
+
xmlXPathFreeNodeSetList(xpath);
|
360
|
+
|
361
|
+
return retval;
|
362
|
+
}
|
363
|
+
|
364
|
+
/*
|
365
|
+
* call-seq:
|
366
|
+
* new(node)
|
367
|
+
*
|
368
|
+
* Create a new XPathContext with +node+ as the reference point.
|
369
|
+
*/
|
370
|
+
static VALUE
|
371
|
+
rb_xml_xpath_context_new(VALUE klass, VALUE nodeobj)
|
372
|
+
{
|
373
|
+
xmlNodePtr node;
|
374
|
+
xmlXPathContextPtr ctx;
|
375
|
+
VALUE self;
|
376
|
+
|
377
|
+
Noko_Node_Get_Struct(nodeobj, xmlNode, node);
|
378
|
+
|
379
|
+
#if LIBXML_VERSION < 21000
|
380
|
+
/* deprecated in 40483d0 */
|
381
|
+
xmlXPathInit();
|
382
|
+
#endif
|
383
|
+
|
384
|
+
ctx = xmlXPathNewContext(node->doc);
|
385
|
+
ctx->node = node;
|
386
|
+
|
387
|
+
xmlXPathRegisterNs(ctx, NOKOGIRI_PREFIX, NOKOGIRI_URI);
|
388
|
+
xmlXPathRegisterNs(ctx, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
|
389
|
+
xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"css-class", NOKOGIRI_BUILTIN_URI,
|
390
|
+
xpath_builtin_css_class);
|
391
|
+
xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"local-name-is", NOKOGIRI_BUILTIN_URI,
|
392
|
+
xpath_builtin_local_name_is);
|
393
|
+
|
394
|
+
self = Data_Wrap_Struct(klass, 0, xml_xpath_context_deallocate, ctx);
|
395
|
+
return self;
|
396
|
+
}
|
397
|
+
|
398
|
+
void
|
399
|
+
noko_init_xml_xpath_context(void)
|
400
|
+
{
|
401
|
+
/*
|
402
|
+
* XPathContext is the entry point for searching a Document by using XPath.
|
403
|
+
*/
|
404
|
+
cNokogiriXmlXpathContext = rb_define_class_under(mNokogiriXml, "XPathContext", rb_cObject);
|
405
|
+
|
406
|
+
rb_undef_alloc_func(cNokogiriXmlXpathContext);
|
407
|
+
|
408
|
+
rb_define_singleton_method(cNokogiriXmlXpathContext, "new", rb_xml_xpath_context_new, 1);
|
409
|
+
|
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);
|
413
|
+
}
|