nokogiri 1.10.9 → 1.12.5
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 +3 -0
- data/LICENSE-DEPENDENCIES.md +1173 -884
- data/LICENSE.md +1 -1
- data/README.md +176 -96
- data/dependencies.yml +12 -12
- data/ext/nokogiri/depend +38 -358
- data/ext/nokogiri/extconf.rb +716 -414
- data/ext/nokogiri/gumbo.c +584 -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 +120 -0
- data/ext/nokogiri/html4_sax_push_parser.c +95 -0
- data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
- data/ext/nokogiri/nokogiri.c +228 -91
- data/ext/nokogiri/nokogiri.h +191 -89
- data/ext/nokogiri/test_global_handlers.c +40 -0
- 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 +267 -195
- data/ext/nokogiri/xml_document_fragment.c +13 -15
- data/ext/nokogiri/xml_dtd.c +54 -48
- data/ext/nokogiri/xml_element_content.c +31 -26
- data/ext/nokogiri/xml_element_decl.c +22 -22
- data/ext/nokogiri/xml_encoding_handler.c +28 -17
- data/ext/nokogiri/xml_entity_decl.c +32 -30
- data/ext/nokogiri/xml_entity_reference.c +16 -18
- data/ext/nokogiri/xml_namespace.c +60 -51
- data/ext/nokogiri/xml_node.c +493 -407
- data/ext/nokogiri/xml_node_set.c +174 -162
- data/ext/nokogiri/xml_processing_instruction.c +17 -19
- data/ext/nokogiri/xml_reader.c +197 -172
- data/ext/nokogiri/xml_relax_ng.c +52 -28
- data/ext/nokogiri/xml_sax_parser.c +112 -112
- data/ext/nokogiri/xml_sax_parser_context.c +105 -86
- data/ext/nokogiri/xml_sax_push_parser.c +36 -27
- data/ext/nokogiri/xml_schema.c +96 -46
- data/ext/nokogiri/xml_syntax_error.c +42 -21
- data/ext/nokogiri/xml_text.c +13 -17
- data/ext/nokogiri/xml_xpath_context.c +158 -73
- data/ext/nokogiri/xslt_stylesheet.c +158 -164
- data/gumbo-parser/CHANGES.md +63 -0
- data/gumbo-parser/Makefile +101 -0
- data/gumbo-parser/THANKS +27 -0
- data/gumbo-parser/src/Makefile +34 -0
- data/gumbo-parser/src/README.md +41 -0
- data/gumbo-parser/src/ascii.c +75 -0
- data/gumbo-parser/src/ascii.h +115 -0
- data/gumbo-parser/src/attribute.c +42 -0
- data/gumbo-parser/src/attribute.h +17 -0
- data/gumbo-parser/src/char_ref.c +22225 -0
- data/gumbo-parser/src/char_ref.h +29 -0
- data/gumbo-parser/src/char_ref.rl +2154 -0
- data/gumbo-parser/src/error.c +626 -0
- data/gumbo-parser/src/error.h +148 -0
- data/gumbo-parser/src/foreign_attrs.c +104 -0
- data/gumbo-parser/src/foreign_attrs.gperf +27 -0
- data/gumbo-parser/src/gumbo.h +943 -0
- data/gumbo-parser/src/insertion_mode.h +33 -0
- data/gumbo-parser/src/macros.h +91 -0
- data/gumbo-parser/src/parser.c +4886 -0
- data/gumbo-parser/src/parser.h +41 -0
- data/gumbo-parser/src/replacement.h +33 -0
- data/gumbo-parser/src/string_buffer.c +103 -0
- data/gumbo-parser/src/string_buffer.h +68 -0
- data/gumbo-parser/src/string_piece.c +48 -0
- data/gumbo-parser/src/svg_attrs.c +174 -0
- data/gumbo-parser/src/svg_attrs.gperf +77 -0
- data/gumbo-parser/src/svg_tags.c +137 -0
- data/gumbo-parser/src/svg_tags.gperf +55 -0
- data/gumbo-parser/src/tag.c +222 -0
- data/gumbo-parser/src/tag_lookup.c +382 -0
- data/gumbo-parser/src/tag_lookup.gperf +169 -0
- data/gumbo-parser/src/tag_lookup.h +13 -0
- data/gumbo-parser/src/token_buffer.c +79 -0
- data/gumbo-parser/src/token_buffer.h +71 -0
- data/gumbo-parser/src/token_type.h +17 -0
- data/gumbo-parser/src/tokenizer.c +3463 -0
- data/gumbo-parser/src/tokenizer.h +112 -0
- data/gumbo-parser/src/tokenizer_states.h +339 -0
- data/gumbo-parser/src/utf8.c +245 -0
- data/gumbo-parser/src/utf8.h +164 -0
- data/gumbo-parser/src/util.c +68 -0
- data/gumbo-parser/src/util.h +30 -0
- data/gumbo-parser/src/vector.c +111 -0
- data/gumbo-parser/src/vector.h +45 -0
- data/lib/nokogiri/css/node.rb +1 -0
- data/lib/nokogiri/css/parser.rb +64 -63
- data/lib/nokogiri/css/parser.y +3 -3
- data/lib/nokogiri/css/parser_extras.rb +39 -36
- data/lib/nokogiri/css/syntax_error.rb +2 -1
- data/lib/nokogiri/css/tokenizer.rb +1 -0
- data/lib/nokogiri/css/xpath_visitor.rb +73 -43
- data/lib/nokogiri/css.rb +15 -14
- data/lib/nokogiri/decorators/slop.rb +1 -0
- data/lib/nokogiri/extension.rb +31 -0
- data/lib/nokogiri/gumbo.rb +14 -0
- data/lib/nokogiri/html.rb +32 -27
- data/lib/nokogiri/{html → html4}/builder.rb +3 -2
- data/lib/nokogiri/{html → html4}/document.rb +17 -30
- data/lib/nokogiri/{html → html4}/document_fragment.rb +18 -17
- data/lib/nokogiri/{html → html4}/element_description.rb +2 -1
- data/lib/nokogiri/{html → html4}/element_description_defaults.rb +2 -1
- data/lib/nokogiri/{html → html4}/entity_lookup.rb +2 -1
- data/lib/nokogiri/{html → html4}/sax/parser.rb +12 -14
- data/lib/nokogiri/html4/sax/parser_context.rb +19 -0
- data/lib/nokogiri/{html → html4}/sax/push_parser.rb +6 -5
- data/lib/nokogiri/html4.rb +40 -0
- data/lib/nokogiri/html5/document.rb +74 -0
- data/lib/nokogiri/html5/document_fragment.rb +80 -0
- data/lib/nokogiri/html5/node.rb +93 -0
- data/lib/nokogiri/html5.rb +473 -0
- data/lib/nokogiri/jruby/dependencies.rb +20 -0
- data/lib/nokogiri/syntax_error.rb +1 -0
- data/lib/nokogiri/version/constant.rb +5 -0
- data/lib/nokogiri/version/info.rb +215 -0
- data/lib/nokogiri/version.rb +3 -109
- data/lib/nokogiri/xml/attr.rb +1 -0
- data/lib/nokogiri/xml/attribute_decl.rb +1 -0
- data/lib/nokogiri/xml/builder.rb +41 -2
- data/lib/nokogiri/xml/cdata.rb +1 -0
- data/lib/nokogiri/xml/character_data.rb +1 -0
- data/lib/nokogiri/xml/document.rb +138 -41
- data/lib/nokogiri/xml/document_fragment.rb +5 -6
- data/lib/nokogiri/xml/dtd.rb +1 -0
- data/lib/nokogiri/xml/element_content.rb +1 -0
- data/lib/nokogiri/xml/element_decl.rb +1 -0
- data/lib/nokogiri/xml/entity_decl.rb +1 -0
- data/lib/nokogiri/xml/entity_reference.rb +1 -0
- data/lib/nokogiri/xml/namespace.rb +1 -0
- data/lib/nokogiri/xml/node/save_options.rb +2 -1
- data/lib/nokogiri/xml/node.rb +629 -293
- data/lib/nokogiri/xml/node_set.rb +1 -0
- data/lib/nokogiri/xml/notation.rb +1 -0
- data/lib/nokogiri/xml/parse_options.rb +12 -3
- data/lib/nokogiri/xml/pp/character_data.rb +1 -0
- data/lib/nokogiri/xml/pp/node.rb +1 -0
- data/lib/nokogiri/xml/pp.rb +3 -2
- data/lib/nokogiri/xml/processing_instruction.rb +1 -0
- data/lib/nokogiri/xml/reader.rb +9 -12
- data/lib/nokogiri/xml/relax_ng.rb +7 -2
- data/lib/nokogiri/xml/sax/document.rb +25 -30
- data/lib/nokogiri/xml/sax/parser.rb +1 -0
- data/lib/nokogiri/xml/sax/parser_context.rb +1 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +1 -0
- data/lib/nokogiri/xml/sax.rb +5 -4
- data/lib/nokogiri/xml/schema.rb +13 -4
- data/lib/nokogiri/xml/searchable.rb +25 -16
- data/lib/nokogiri/xml/syntax_error.rb +1 -0
- data/lib/nokogiri/xml/text.rb +1 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +2 -1
- data/lib/nokogiri/xml/xpath.rb +4 -5
- data/lib/nokogiri/xml/xpath_context.rb +1 -0
- data/lib/nokogiri/xml.rb +36 -36
- data/lib/nokogiri/xslt/stylesheet.rb +2 -1
- data/lib/nokogiri/xslt.rb +17 -16
- data/lib/nokogiri.rb +32 -51
- data/lib/xsd/xmlparser/nokogiri.rb +1 -0
- data/patches/libxml2/{0002-Remove-script-macro-support.patch → 0001-Remove-script-macro-support.patch} +0 -0
- data/patches/libxml2/{0003-Update-entities-to-remove-handling-of-ssi.patch → 0002-Update-entities-to-remove-handling-of-ssi.patch} +0 -0
- data/patches/libxml2/{0004-libxml2.la-is-in-top_builddir.patch → 0003-libxml2.la-is-in-top_builddir.patch} +1 -1
- data/patches/libxml2/0004-use-glibc-strlen.patch +53 -0
- data/patches/libxml2/0005-avoid-isnan-isinf.patch +81 -0
- data/patches/libxml2/0006-update-automake-files-for-arm64.patch +2511 -0
- data/patches/libxml2/0007-Fix-XPath-recursion-limit.patch +31 -0
- data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2511 -0
- data/patches/libxslt/0002-Fix-xml2-config-check-in-configure-script.patch +19 -0
- data/ports/archives/libxml2-2.9.12.tar.gz +0 -0
- metadata +139 -161
- data/ext/nokogiri/html_document.c +0 -170
- data/ext/nokogiri/html_document.h +0 -10
- data/ext/nokogiri/html_element_description.c +0 -279
- data/ext/nokogiri/html_element_description.h +0 -10
- data/ext/nokogiri/html_entity_lookup.c +0 -32
- data/ext/nokogiri/html_entity_lookup.h +0 -8
- data/ext/nokogiri/html_sax_parser_context.c +0 -116
- data/ext/nokogiri/html_sax_parser_context.h +0 -11
- data/ext/nokogiri/html_sax_push_parser.c +0 -87
- 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 -61
- 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 -13
- 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
- data/lib/nokogiri/html/sax/parser_context.rb +0 -16
- data/patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch +0 -78
- data/patches/libxml2/0005-Fix-infinite-loop-in-xmlStringLenDecodeEntities.patch +0 -32
- data/ports/archives/libxml2-2.9.10.tar.gz +0 -0
data/ext/nokogiri/xml_node.c
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
2
|
|
3
|
-
|
3
|
+
VALUE cNokogiriXmlNode ;
|
4
|
+
|
5
|
+
static ID id_decorate, id_decorate_bang;
|
4
6
|
|
5
7
|
#ifdef DEBUG
|
6
|
-
static void
|
8
|
+
static void
|
9
|
+
debug_node_dealloc(xmlNodePtr x)
|
7
10
|
{
|
8
11
|
NOKOGIRI_DEBUG_START(x)
|
9
12
|
NOKOGIRI_DEBUG_END(x)
|
@@ -12,25 +15,28 @@ static void debug_node_dealloc(xmlNodePtr x)
|
|
12
15
|
# define debug_node_dealloc 0
|
13
16
|
#endif
|
14
17
|
|
15
|
-
static void
|
18
|
+
static void
|
19
|
+
mark(xmlNodePtr node)
|
16
20
|
{
|
17
21
|
xmlDocPtr doc = node->doc;
|
18
|
-
if(doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE) {
|
19
|
-
if(DOC_RUBY_OBJECT_TEST(doc)) {
|
22
|
+
if (doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE) {
|
23
|
+
if (DOC_RUBY_OBJECT_TEST(doc)) {
|
20
24
|
rb_gc_mark(DOC_RUBY_OBJECT(doc));
|
21
25
|
}
|
22
|
-
} else if(node->doc->_private) {
|
26
|
+
} else if (node->doc->_private) {
|
23
27
|
rb_gc_mark((VALUE)doc->_private);
|
24
28
|
}
|
25
29
|
}
|
26
30
|
|
27
31
|
/* :nodoc: */
|
28
|
-
typedef xmlNodePtr
|
32
|
+
typedef xmlNodePtr(*pivot_reparentee_func)(xmlNodePtr, xmlNodePtr);
|
29
33
|
|
30
34
|
/* :nodoc: */
|
31
|
-
static void
|
35
|
+
static void
|
36
|
+
relink_namespace(xmlNodePtr reparented)
|
32
37
|
{
|
33
38
|
xmlNodePtr child;
|
39
|
+
xmlAttrPtr attr;
|
34
40
|
|
35
41
|
if (reparented->type != XML_ATTRIBUTE_NODE &&
|
36
42
|
reparented->type != XML_ELEMENT_NODE) { return; }
|
@@ -42,7 +48,7 @@ static void relink_namespace(xmlNodePtr reparented)
|
|
42
48
|
name = xmlSplitQName2(reparented->name, &prefix);
|
43
49
|
|
44
50
|
if (reparented->type == XML_ATTRIBUTE_NODE) {
|
45
|
-
if (prefix == NULL || strcmp((char*)prefix, XMLNS_PREFIX) == 0) {
|
51
|
+
if (prefix == NULL || strcmp((char *)prefix, XMLNS_PREFIX) == 0) {
|
46
52
|
xmlFree(name);
|
47
53
|
xmlFree(prefix);
|
48
54
|
return;
|
@@ -64,7 +70,9 @@ static void relink_namespace(xmlNodePtr reparented)
|
|
64
70
|
if (reparented->type != XML_ELEMENT_NODE || !reparented->parent) { return; }
|
65
71
|
|
66
72
|
/* Make sure that our reparented node has the correct namespaces */
|
67
|
-
if (!reparented->ns &&
|
73
|
+
if (!reparented->ns &&
|
74
|
+
(reparented->doc != (xmlDocPtr)reparented->parent) &&
|
75
|
+
(rb_iv_get(DOC_RUBY_OBJECT(reparented->doc), "@namespace_inheritance") == Qtrue)) {
|
68
76
|
xmlSetNs(reparented, reparented->parent->ns);
|
69
77
|
}
|
70
78
|
|
@@ -87,7 +95,7 @@ static void relink_namespace(xmlNodePtr reparented)
|
|
87
95
|
} else {
|
88
96
|
reparented->nsDef = curr->next;
|
89
97
|
}
|
90
|
-
|
98
|
+
noko_xml_document_pin_namespace(curr, reparented->doc);
|
91
99
|
} else {
|
92
100
|
prev = curr;
|
93
101
|
}
|
@@ -127,16 +135,17 @@ static void relink_namespace(xmlNodePtr reparented)
|
|
127
135
|
}
|
128
136
|
|
129
137
|
if (reparented->type == XML_ELEMENT_NODE) {
|
130
|
-
|
131
|
-
while(NULL !=
|
132
|
-
relink_namespace(
|
133
|
-
|
138
|
+
attr = reparented->properties;
|
139
|
+
while (NULL != attr) {
|
140
|
+
relink_namespace((xmlNodePtr)attr);
|
141
|
+
attr = attr->next;
|
134
142
|
}
|
135
143
|
}
|
136
144
|
}
|
137
145
|
|
138
146
|
/* :nodoc: */
|
139
|
-
static xmlNodePtr
|
147
|
+
static xmlNodePtr
|
148
|
+
xmlReplaceNodeWrapper(xmlNodePtr pivot, xmlNodePtr new_node)
|
140
149
|
{
|
141
150
|
xmlNodePtr retval ;
|
142
151
|
|
@@ -160,16 +169,17 @@ static xmlNodePtr xmlReplaceNodeWrapper(xmlNodePtr pivot, xmlNodePtr new_node)
|
|
160
169
|
}
|
161
170
|
|
162
171
|
/* :nodoc: */
|
163
|
-
static VALUE
|
172
|
+
static VALUE
|
173
|
+
reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_reparentee_func prf)
|
164
174
|
{
|
165
175
|
VALUE reparented_obj ;
|
166
|
-
xmlNodePtr reparentee, pivot, reparented, next_text, new_next_text, parent ;
|
176
|
+
xmlNodePtr reparentee, original_reparentee, pivot, reparented, next_text, new_next_text, parent ;
|
167
177
|
int original_ns_prefix_is_default = 0 ;
|
168
178
|
|
169
|
-
if(!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode)) {
|
179
|
+
if (!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode)) {
|
170
180
|
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
171
181
|
}
|
172
|
-
if(rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlDocument)) {
|
182
|
+
if (rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlDocument)) {
|
173
183
|
rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
|
174
184
|
}
|
175
185
|
|
@@ -190,66 +200,66 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep
|
|
190
200
|
|
191
201
|
if (parent) {
|
192
202
|
switch (parent->type) {
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
203
|
+
case XML_DOCUMENT_NODE:
|
204
|
+
case XML_HTML_DOCUMENT_NODE:
|
205
|
+
switch (reparentee->type) {
|
206
|
+
case XML_ELEMENT_NODE:
|
207
|
+
case XML_PI_NODE:
|
208
|
+
case XML_COMMENT_NODE:
|
209
|
+
case XML_DOCUMENT_TYPE_NODE:
|
210
|
+
/*
|
211
|
+
* The DOM specification says no to adding text-like nodes
|
212
|
+
* directly to a document, but we allow it for compatibility.
|
213
|
+
*/
|
214
|
+
case XML_TEXT_NODE:
|
215
|
+
case XML_CDATA_SECTION_NODE:
|
216
|
+
case XML_ENTITY_REF_NODE:
|
217
|
+
goto ok;
|
218
|
+
default:
|
219
|
+
break;
|
220
|
+
}
|
209
221
|
break;
|
210
|
-
|
211
|
-
break;
|
212
|
-
case XML_DOCUMENT_FRAG_NODE:
|
213
|
-
case XML_ENTITY_REF_NODE:
|
214
|
-
case XML_ELEMENT_NODE:
|
215
|
-
switch (reparentee->type) {
|
216
|
-
case XML_ELEMENT_NODE:
|
217
|
-
case XML_PI_NODE:
|
218
|
-
case XML_COMMENT_NODE:
|
219
|
-
case XML_TEXT_NODE:
|
220
|
-
case XML_CDATA_SECTION_NODE:
|
222
|
+
case XML_DOCUMENT_FRAG_NODE:
|
221
223
|
case XML_ENTITY_REF_NODE:
|
222
|
-
|
223
|
-
|
224
|
+
case XML_ELEMENT_NODE:
|
225
|
+
switch (reparentee->type) {
|
226
|
+
case XML_ELEMENT_NODE:
|
227
|
+
case XML_PI_NODE:
|
228
|
+
case XML_COMMENT_NODE:
|
229
|
+
case XML_TEXT_NODE:
|
230
|
+
case XML_CDATA_SECTION_NODE:
|
231
|
+
case XML_ENTITY_REF_NODE:
|
232
|
+
goto ok;
|
233
|
+
default:
|
234
|
+
break;
|
235
|
+
}
|
236
|
+
break;
|
237
|
+
case XML_ATTRIBUTE_NODE:
|
238
|
+
switch (reparentee->type) {
|
239
|
+
case XML_TEXT_NODE:
|
240
|
+
case XML_ENTITY_REF_NODE:
|
241
|
+
goto ok;
|
242
|
+
default:
|
243
|
+
break;
|
244
|
+
}
|
224
245
|
break;
|
225
|
-
}
|
226
|
-
break;
|
227
|
-
case XML_ATTRIBUTE_NODE:
|
228
|
-
switch (reparentee->type) {
|
229
246
|
case XML_TEXT_NODE:
|
230
|
-
|
231
|
-
|
247
|
+
/*
|
248
|
+
* xmlAddChild() breaks the DOM specification in that it allows
|
249
|
+
* adding a text node to another, in which case text nodes are
|
250
|
+
* coalesced, but since our JRuby version does not support such
|
251
|
+
* operation, we should inhibit it.
|
252
|
+
*/
|
253
|
+
break;
|
232
254
|
default:
|
233
255
|
break;
|
234
|
-
}
|
235
|
-
break;
|
236
|
-
case XML_TEXT_NODE:
|
237
|
-
/*
|
238
|
-
* xmlAddChild() breaks the DOM specification in that it allows
|
239
|
-
* adding a text node to another, in which case text nodes are
|
240
|
-
* coalesced, but since our JRuby version does not support such
|
241
|
-
* operation, we should inhibit it.
|
242
|
-
*/
|
243
|
-
break;
|
244
|
-
default:
|
245
|
-
break;
|
246
256
|
}
|
247
257
|
|
248
258
|
rb_raise(rb_eArgError, "cannot reparent %s there", rb_obj_classname(reparentee_obj));
|
249
259
|
}
|
250
260
|
|
251
261
|
ok:
|
252
|
-
|
262
|
+
original_reparentee = reparentee;
|
253
263
|
|
254
264
|
if (reparentee->doc != pivot->doc || reparentee->type == XML_TEXT_NODE) {
|
255
265
|
/*
|
@@ -290,7 +300,7 @@ ok:
|
|
290
300
|
original_ns_prefix_is_default = 1;
|
291
301
|
}
|
292
302
|
|
293
|
-
|
303
|
+
noko_xml_document_pin_node(reparentee);
|
294
304
|
|
295
305
|
if (!(reparentee = xmlDocCopyNode(reparentee, pivot->doc, 1))) {
|
296
306
|
rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
|
@@ -301,11 +311,13 @@ ok:
|
|
301
311
|
* issue #391, where new node's prefix may become the string "default"
|
302
312
|
* see libxml2 tree.c xmlNewReconciliedNs which implements this behavior.
|
303
313
|
*/
|
304
|
-
xmlFree(reparentee->ns->prefix);
|
314
|
+
xmlFree(DISCARD_CONST_QUAL_XMLCHAR(reparentee->ns->prefix));
|
305
315
|
reparentee->ns->prefix = NULL;
|
306
316
|
}
|
307
317
|
}
|
308
318
|
|
319
|
+
xmlUnlinkNode(original_reparentee);
|
320
|
+
|
309
321
|
if (prf != xmlAddPrevSibling && prf != xmlAddNextSibling
|
310
322
|
&& reparentee->type == XML_TEXT_NODE && pivot->next && pivot->next->type == XML_TEXT_NODE) {
|
311
323
|
/*
|
@@ -330,12 +342,12 @@ ok:
|
|
330
342
|
new_next_text = xmlDocCopyNode(next_text, pivot->doc, 1) ;
|
331
343
|
|
332
344
|
xmlUnlinkNode(next_text);
|
333
|
-
|
345
|
+
noko_xml_document_pin_node(next_text);
|
334
346
|
|
335
347
|
xmlAddNextSibling(pivot, new_next_text);
|
336
348
|
}
|
337
349
|
|
338
|
-
if(!(reparented = (*prf)(pivot, reparentee))) {
|
350
|
+
if (!(reparented = (*prf)(pivot, reparentee))) {
|
339
351
|
rb_raise(rb_eRuntimeError, "Could not reparent node");
|
340
352
|
}
|
341
353
|
|
@@ -348,9 +360,9 @@ ok:
|
|
348
360
|
|
349
361
|
relink_namespace(reparented);
|
350
362
|
|
351
|
-
reparented_obj =
|
363
|
+
reparented_obj = noko_xml_node_wrap(Qnil, reparented);
|
352
364
|
|
353
|
-
rb_funcall(reparented_obj,
|
365
|
+
rb_funcall(reparented_obj, id_decorate_bang, 0);
|
354
366
|
|
355
367
|
return reparented_obj ;
|
356
368
|
}
|
@@ -362,7 +374,8 @@ ok:
|
|
362
374
|
*
|
363
375
|
* Get the document for this Node
|
364
376
|
*/
|
365
|
-
static VALUE
|
377
|
+
static VALUE
|
378
|
+
document(VALUE self)
|
366
379
|
{
|
367
380
|
xmlNodePtr node;
|
368
381
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -375,7 +388,8 @@ static VALUE document(VALUE self)
|
|
375
388
|
*
|
376
389
|
* Get the internal pointer number
|
377
390
|
*/
|
378
|
-
static VALUE
|
391
|
+
static VALUE
|
392
|
+
pointer_id(VALUE self)
|
379
393
|
{
|
380
394
|
xmlNodePtr node;
|
381
395
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -389,7 +403,8 @@ static VALUE pointer_id(VALUE self)
|
|
389
403
|
*
|
390
404
|
* Encode any special characters in +string+
|
391
405
|
*/
|
392
|
-
static VALUE
|
406
|
+
static VALUE
|
407
|
+
encode_special_chars(VALUE self, VALUE string)
|
393
408
|
{
|
394
409
|
xmlNodePtr node;
|
395
410
|
xmlChar *encoded;
|
@@ -419,7 +434,8 @@ static VALUE encode_special_chars(VALUE self, VALUE string)
|
|
419
434
|
* doc.create_internal_subset("chapter", nil, "chapter.dtd")
|
420
435
|
* # => <!DOCTYPE chapter SYSTEM "chapter.dtd">
|
421
436
|
*/
|
422
|
-
static VALUE
|
437
|
+
static VALUE
|
438
|
+
create_internal_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_id)
|
423
439
|
{
|
424
440
|
xmlNodePtr node;
|
425
441
|
xmlDocPtr doc;
|
@@ -429,7 +445,7 @@ static VALUE create_internal_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
429
445
|
|
430
446
|
doc = node->doc;
|
431
447
|
|
432
|
-
if(xmlGetIntSubset(doc)) {
|
448
|
+
if (xmlGetIntSubset(doc)) {
|
433
449
|
rb_raise(rb_eRuntimeError, "Document already has an internal subset");
|
434
450
|
}
|
435
451
|
|
@@ -440,9 +456,9 @@ static VALUE create_internal_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
440
456
|
NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id)
|
441
457
|
);
|
442
458
|
|
443
|
-
if(!dtd) { return Qnil; }
|
459
|
+
if (!dtd) { return Qnil; }
|
444
460
|
|
445
|
-
return
|
461
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
446
462
|
}
|
447
463
|
|
448
464
|
/*
|
@@ -451,7 +467,8 @@ static VALUE create_internal_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
451
467
|
*
|
452
468
|
* Create an external subset
|
453
469
|
*/
|
454
|
-
static VALUE
|
470
|
+
static VALUE
|
471
|
+
create_external_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_id)
|
455
472
|
{
|
456
473
|
xmlNodePtr node;
|
457
474
|
xmlDocPtr doc;
|
@@ -461,7 +478,7 @@ static VALUE create_external_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
461
478
|
|
462
479
|
doc = node->doc;
|
463
480
|
|
464
|
-
if(doc->extSubset) {
|
481
|
+
if (doc->extSubset) {
|
465
482
|
rb_raise(rb_eRuntimeError, "Document already has an external subset");
|
466
483
|
}
|
467
484
|
|
@@ -472,9 +489,9 @@ static VALUE create_external_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
472
489
|
NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id)
|
473
490
|
);
|
474
491
|
|
475
|
-
if(!dtd) { return Qnil; }
|
492
|
+
if (!dtd) { return Qnil; }
|
476
493
|
|
477
|
-
return
|
494
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
478
495
|
}
|
479
496
|
|
480
497
|
/*
|
@@ -483,7 +500,8 @@ static VALUE create_external_subset(VALUE self, VALUE name, VALUE external_id, V
|
|
483
500
|
*
|
484
501
|
* Get the external subset
|
485
502
|
*/
|
486
|
-
static VALUE
|
503
|
+
static VALUE
|
504
|
+
external_subset(VALUE self)
|
487
505
|
{
|
488
506
|
xmlNodePtr node;
|
489
507
|
xmlDocPtr doc;
|
@@ -491,14 +509,14 @@ static VALUE external_subset(VALUE self)
|
|
491
509
|
|
492
510
|
Data_Get_Struct(self, xmlNode, node);
|
493
511
|
|
494
|
-
if(!node->doc) { return Qnil; }
|
512
|
+
if (!node->doc) { return Qnil; }
|
495
513
|
|
496
514
|
doc = node->doc;
|
497
515
|
dtd = doc->extSubset;
|
498
516
|
|
499
|
-
if(!dtd) { return Qnil; }
|
517
|
+
if (!dtd) { return Qnil; }
|
500
518
|
|
501
|
-
return
|
519
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
502
520
|
}
|
503
521
|
|
504
522
|
/*
|
@@ -507,7 +525,8 @@ static VALUE external_subset(VALUE self)
|
|
507
525
|
*
|
508
526
|
* Get the internal subset
|
509
527
|
*/
|
510
|
-
static VALUE
|
528
|
+
static VALUE
|
529
|
+
internal_subset(VALUE self)
|
511
530
|
{
|
512
531
|
xmlNodePtr node;
|
513
532
|
xmlDocPtr doc;
|
@@ -515,14 +534,14 @@ static VALUE internal_subset(VALUE self)
|
|
515
534
|
|
516
535
|
Data_Get_Struct(self, xmlNode, node);
|
517
536
|
|
518
|
-
if(!node->doc) { return Qnil; }
|
537
|
+
if (!node->doc) { return Qnil; }
|
519
538
|
|
520
539
|
doc = node->doc;
|
521
540
|
dtd = xmlGetIntSubset(doc);
|
522
541
|
|
523
|
-
if(!dtd) { return Qnil; }
|
542
|
+
if (!dtd) { return Qnil; }
|
524
543
|
|
525
|
-
return
|
544
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd);
|
526
545
|
}
|
527
546
|
|
528
547
|
/*
|
@@ -537,7 +556,8 @@ static VALUE internal_subset(VALUE self)
|
|
537
556
|
* node's parent document. Defaults to the current node's document.
|
538
557
|
* current document.
|
539
558
|
*/
|
540
|
-
static VALUE
|
559
|
+
static VALUE
|
560
|
+
duplicate_node(int argc, VALUE *argv, VALUE self)
|
541
561
|
{
|
542
562
|
VALUE r_level, r_new_parent_doc;
|
543
563
|
int level;
|
@@ -561,11 +581,11 @@ static VALUE duplicate_node(int argc, VALUE *argv, VALUE self)
|
|
561
581
|
}
|
562
582
|
|
563
583
|
dup = xmlDocCopyNode(node, new_parent_doc, level);
|
564
|
-
if(dup == NULL) { return Qnil; }
|
584
|
+
if (dup == NULL) { return Qnil; }
|
565
585
|
|
566
|
-
|
586
|
+
noko_xml_document_pin_node(dup);
|
567
587
|
|
568
|
-
return
|
588
|
+
return noko_xml_node_wrap(rb_obj_class(self), dup);
|
569
589
|
}
|
570
590
|
|
571
591
|
/*
|
@@ -574,12 +594,13 @@ static VALUE duplicate_node(int argc, VALUE *argv, VALUE self)
|
|
574
594
|
*
|
575
595
|
* Unlink this node from its current context.
|
576
596
|
*/
|
577
|
-
static VALUE
|
597
|
+
static VALUE
|
598
|
+
unlink_node(VALUE self)
|
578
599
|
{
|
579
600
|
xmlNodePtr node;
|
580
601
|
Data_Get_Struct(self, xmlNode, node);
|
581
602
|
xmlUnlinkNode(node);
|
582
|
-
|
603
|
+
noko_xml_document_pin_node(node);
|
583
604
|
return self;
|
584
605
|
}
|
585
606
|
|
@@ -589,7 +610,8 @@ static VALUE unlink_node(VALUE self)
|
|
589
610
|
*
|
590
611
|
* Is this node blank?
|
591
612
|
*/
|
592
|
-
static VALUE
|
613
|
+
static VALUE
|
614
|
+
blank_eh(VALUE self)
|
593
615
|
{
|
594
616
|
xmlNodePtr node;
|
595
617
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -602,15 +624,16 @@ static VALUE blank_eh(VALUE self)
|
|
602
624
|
*
|
603
625
|
* Returns the next sibling node
|
604
626
|
*/
|
605
|
-
static VALUE
|
627
|
+
static VALUE
|
628
|
+
next_sibling(VALUE self)
|
606
629
|
{
|
607
630
|
xmlNodePtr node, sibling;
|
608
631
|
Data_Get_Struct(self, xmlNode, node);
|
609
632
|
|
610
633
|
sibling = node->next;
|
611
|
-
if(!sibling) { return Qnil; }
|
634
|
+
if (!sibling) { return Qnil; }
|
612
635
|
|
613
|
-
return
|
636
|
+
return noko_xml_node_wrap(Qnil, sibling) ;
|
614
637
|
}
|
615
638
|
|
616
639
|
/*
|
@@ -619,15 +642,16 @@ static VALUE next_sibling(VALUE self)
|
|
619
642
|
*
|
620
643
|
* Returns the previous sibling node
|
621
644
|
*/
|
622
|
-
static VALUE
|
645
|
+
static VALUE
|
646
|
+
previous_sibling(VALUE self)
|
623
647
|
{
|
624
648
|
xmlNodePtr node, sibling;
|
625
649
|
Data_Get_Struct(self, xmlNode, node);
|
626
650
|
|
627
651
|
sibling = node->prev;
|
628
|
-
if(!sibling) { return Qnil; }
|
652
|
+
if (!sibling) { return Qnil; }
|
629
653
|
|
630
|
-
return
|
654
|
+
return noko_xml_node_wrap(Qnil, sibling);
|
631
655
|
}
|
632
656
|
|
633
657
|
/*
|
@@ -636,15 +660,16 @@ static VALUE previous_sibling(VALUE self)
|
|
636
660
|
*
|
637
661
|
* Returns the next Nokogiri::XML::Element type sibling node.
|
638
662
|
*/
|
639
|
-
static VALUE
|
663
|
+
static VALUE
|
664
|
+
next_element(VALUE self)
|
640
665
|
{
|
641
666
|
xmlNodePtr node, sibling;
|
642
667
|
Data_Get_Struct(self, xmlNode, node);
|
643
668
|
|
644
669
|
sibling = xmlNextElementSibling(node);
|
645
|
-
if(!sibling) { return Qnil; }
|
670
|
+
if (!sibling) { return Qnil; }
|
646
671
|
|
647
|
-
return
|
672
|
+
return noko_xml_node_wrap(Qnil, sibling);
|
648
673
|
}
|
649
674
|
|
650
675
|
/*
|
@@ -653,7 +678,8 @@ static VALUE next_element(VALUE self)
|
|
653
678
|
*
|
654
679
|
* Returns the previous Nokogiri::XML::Element type sibling node.
|
655
680
|
*/
|
656
|
-
static VALUE
|
681
|
+
static VALUE
|
682
|
+
previous_element(VALUE self)
|
657
683
|
{
|
658
684
|
xmlNodePtr node, sibling;
|
659
685
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -662,23 +688,24 @@ static VALUE previous_element(VALUE self)
|
|
662
688
|
* note that we don't use xmlPreviousElementSibling here because it's buggy pre-2.7.7.
|
663
689
|
*/
|
664
690
|
sibling = node->prev;
|
665
|
-
if(!sibling) { return Qnil; }
|
691
|
+
if (!sibling) { return Qnil; }
|
666
692
|
|
667
|
-
while(sibling && sibling->type != XML_ELEMENT_NODE) {
|
693
|
+
while (sibling && sibling->type != XML_ELEMENT_NODE) {
|
668
694
|
sibling = sibling->prev;
|
669
695
|
}
|
670
696
|
|
671
|
-
return sibling ?
|
697
|
+
return sibling ? noko_xml_node_wrap(Qnil, sibling) : Qnil ;
|
672
698
|
}
|
673
699
|
|
674
700
|
/* :nodoc: */
|
675
|
-
static VALUE
|
701
|
+
static VALUE
|
702
|
+
replace(VALUE self, VALUE new_node)
|
676
703
|
{
|
677
704
|
VALUE reparent = reparent_node_with(self, new_node, xmlReplaceNodeWrapper);
|
678
705
|
|
679
706
|
xmlNodePtr pivot;
|
680
707
|
Data_Get_Struct(self, xmlNode, pivot);
|
681
|
-
|
708
|
+
noko_xml_document_pin_node(pivot);
|
682
709
|
|
683
710
|
return reparent;
|
684
711
|
}
|
@@ -689,7 +716,8 @@ static VALUE replace(VALUE self, VALUE new_node)
|
|
689
716
|
*
|
690
717
|
* Get the list of children for this node as a NodeSet
|
691
718
|
*/
|
692
|
-
static VALUE
|
719
|
+
static VALUE
|
720
|
+
children(VALUE self)
|
693
721
|
{
|
694
722
|
xmlNodePtr node;
|
695
723
|
xmlNodePtr child;
|
@@ -704,15 +732,15 @@ static VALUE children(VALUE self)
|
|
704
732
|
|
705
733
|
document = DOC_RUBY_OBJECT(node->doc);
|
706
734
|
|
707
|
-
if(!child) { return
|
735
|
+
if (!child) { return noko_xml_node_set_wrap(set, document); }
|
708
736
|
|
709
737
|
child = child->next;
|
710
|
-
while(NULL != child) {
|
738
|
+
while (NULL != child) {
|
711
739
|
xmlXPathNodeSetAddUnique(set, child);
|
712
740
|
child = child->next;
|
713
741
|
}
|
714
742
|
|
715
|
-
node_set =
|
743
|
+
node_set = noko_xml_node_set_wrap(set, document);
|
716
744
|
|
717
745
|
return node_set;
|
718
746
|
}
|
@@ -728,7 +756,8 @@ static VALUE children(VALUE self)
|
|
728
756
|
*
|
729
757
|
* @doc.root.element_children.all? { |x| x.element? } # => true
|
730
758
|
*/
|
731
|
-
static VALUE
|
759
|
+
static VALUE
|
760
|
+
element_children(VALUE self)
|
732
761
|
{
|
733
762
|
xmlNodePtr node;
|
734
763
|
xmlNodePtr child;
|
@@ -743,15 +772,15 @@ static VALUE element_children(VALUE self)
|
|
743
772
|
|
744
773
|
document = DOC_RUBY_OBJECT(node->doc);
|
745
774
|
|
746
|
-
if(!child) { return
|
775
|
+
if (!child) { return noko_xml_node_set_wrap(set, document); }
|
747
776
|
|
748
777
|
child = xmlNextElementSibling(child);
|
749
|
-
while(NULL != child) {
|
778
|
+
while (NULL != child) {
|
750
779
|
xmlXPathNodeSetAddUnique(set, child);
|
751
780
|
child = xmlNextElementSibling(child);
|
752
781
|
}
|
753
782
|
|
754
|
-
node_set =
|
783
|
+
node_set = noko_xml_node_set_wrap(set, document);
|
755
784
|
|
756
785
|
return node_set;
|
757
786
|
}
|
@@ -762,15 +791,16 @@ static VALUE element_children(VALUE self)
|
|
762
791
|
*
|
763
792
|
* Returns the child node
|
764
793
|
*/
|
765
|
-
static VALUE
|
794
|
+
static VALUE
|
795
|
+
child(VALUE self)
|
766
796
|
{
|
767
797
|
xmlNodePtr node, child;
|
768
798
|
Data_Get_Struct(self, xmlNode, node);
|
769
799
|
|
770
800
|
child = node->children;
|
771
|
-
if(!child) { return Qnil; }
|
801
|
+
if (!child) { return Qnil; }
|
772
802
|
|
773
|
-
return
|
803
|
+
return noko_xml_node_wrap(Qnil, child);
|
774
804
|
}
|
775
805
|
|
776
806
|
/*
|
@@ -783,15 +813,16 @@ static VALUE child(VALUE self)
|
|
783
813
|
*
|
784
814
|
* @doc.root.first_element_child.element? # => true
|
785
815
|
*/
|
786
|
-
static VALUE
|
816
|
+
static VALUE
|
817
|
+
first_element_child(VALUE self)
|
787
818
|
{
|
788
819
|
xmlNodePtr node, child;
|
789
820
|
Data_Get_Struct(self, xmlNode, node);
|
790
821
|
|
791
822
|
child = xmlFirstElementChild(node);
|
792
|
-
if(!child) { return Qnil; }
|
823
|
+
if (!child) { return Qnil; }
|
793
824
|
|
794
|
-
return
|
825
|
+
return noko_xml_node_wrap(Qnil, child);
|
795
826
|
}
|
796
827
|
|
797
828
|
/*
|
@@ -804,15 +835,16 @@ static VALUE first_element_child(VALUE self)
|
|
804
835
|
*
|
805
836
|
* @doc.root.last_element_child.element? # => true
|
806
837
|
*/
|
807
|
-
static VALUE
|
838
|
+
static VALUE
|
839
|
+
last_element_child(VALUE self)
|
808
840
|
{
|
809
841
|
xmlNodePtr node, child;
|
810
842
|
Data_Get_Struct(self, xmlNode, node);
|
811
843
|
|
812
844
|
child = xmlLastElementChild(node);
|
813
|
-
if(!child) { return Qnil; }
|
845
|
+
if (!child) { return Qnil; }
|
814
846
|
|
815
|
-
return
|
847
|
+
return noko_xml_node_wrap(Qnil, child);
|
816
848
|
}
|
817
849
|
|
818
850
|
/*
|
@@ -821,11 +853,12 @@ static VALUE last_element_child(VALUE self)
|
|
821
853
|
*
|
822
854
|
* Returns true if +attribute+ is set
|
823
855
|
*/
|
824
|
-
static VALUE
|
856
|
+
static VALUE
|
857
|
+
key_eh(VALUE self, VALUE attribute)
|
825
858
|
{
|
826
859
|
xmlNodePtr node;
|
827
860
|
Data_Get_Struct(self, xmlNode, node);
|
828
|
-
if(xmlHasProp(node, (xmlChar *)StringValueCStr(attribute))) {
|
861
|
+
if (xmlHasProp(node, (xmlChar *)StringValueCStr(attribute))) {
|
829
862
|
return Qtrue;
|
830
863
|
}
|
831
864
|
return Qfalse;
|
@@ -837,12 +870,13 @@ static VALUE key_eh(VALUE self, VALUE attribute)
|
|
837
870
|
*
|
838
871
|
* Returns true if +attribute+ is set with +namespace+
|
839
872
|
*/
|
840
|
-
static VALUE
|
873
|
+
static VALUE
|
874
|
+
namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace)
|
841
875
|
{
|
842
876
|
xmlNodePtr node;
|
843
877
|
Data_Get_Struct(self, xmlNode, node);
|
844
|
-
if(xmlHasNsProp(node, (xmlChar *)StringValueCStr(attribute),
|
845
|
-
|
878
|
+
if (xmlHasNsProp(node, (xmlChar *)StringValueCStr(attribute),
|
879
|
+
NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace))) {
|
846
880
|
return Qtrue;
|
847
881
|
}
|
848
882
|
return Qfalse;
|
@@ -854,7 +888,8 @@ static VALUE namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace)
|
|
854
888
|
*
|
855
889
|
* Set the +property+ to +value+
|
856
890
|
*/
|
857
|
-
static VALUE
|
891
|
+
static VALUE
|
892
|
+
set(VALUE self, VALUE property, VALUE value)
|
858
893
|
{
|
859
894
|
xmlNodePtr node, cur;
|
860
895
|
xmlAttrPtr prop;
|
@@ -867,13 +902,13 @@ static VALUE set(VALUE self, VALUE property, VALUE value)
|
|
867
902
|
* We can avoid this by unlinking these nodes first.
|
868
903
|
*/
|
869
904
|
if (node->type != XML_ELEMENT_NODE) {
|
870
|
-
return(Qnil);
|
905
|
+
return (Qnil);
|
871
906
|
}
|
872
907
|
prop = xmlHasProp(node, (xmlChar *)StringValueCStr(property));
|
873
908
|
if (prop && prop->children) {
|
874
909
|
for (cur = prop->children; cur; cur = cur->next) {
|
875
910
|
if (cur->_private) {
|
876
|
-
|
911
|
+
noko_xml_document_pin_node(cur);
|
877
912
|
xmlUnlinkNode(cur);
|
878
913
|
}
|
879
914
|
}
|
@@ -891,7 +926,8 @@ static VALUE set(VALUE self, VALUE property, VALUE value)
|
|
891
926
|
*
|
892
927
|
* Get the value for +attribute+
|
893
928
|
*/
|
894
|
-
static VALUE
|
929
|
+
static VALUE
|
930
|
+
get(VALUE self, VALUE rattribute)
|
895
931
|
{
|
896
932
|
xmlNodePtr node;
|
897
933
|
xmlChar *value = 0;
|
@@ -905,7 +941,7 @@ static VALUE get(VALUE self, VALUE rattribute)
|
|
905
941
|
Data_Get_Struct(self, xmlNode, node);
|
906
942
|
attribute = xmlCharStrdup(StringValueCStr(rattribute));
|
907
943
|
|
908
|
-
colon = (
|
944
|
+
colon = DISCARD_CONST_QUAL_XMLCHAR(xmlStrchr(attribute, (const xmlChar)':'));
|
909
945
|
if (colon) {
|
910
946
|
/* split the attribute string into separate prefix and name by
|
911
947
|
* null-terminating the prefix at the colon */
|
@@ -917,7 +953,7 @@ static VALUE get(VALUE self, VALUE rattribute)
|
|
917
953
|
if (ns) {
|
918
954
|
value = xmlGetNsProp(node, attr_name, ns->href);
|
919
955
|
} else {
|
920
|
-
value = xmlGetProp(node, (xmlChar*)StringValueCStr(rattribute));
|
956
|
+
value = xmlGetProp(node, (xmlChar *)StringValueCStr(rattribute));
|
921
957
|
}
|
922
958
|
} else {
|
923
959
|
value = xmlGetNoNsProp(node, attribute);
|
@@ -938,14 +974,15 @@ static VALUE get(VALUE self, VALUE rattribute)
|
|
938
974
|
*
|
939
975
|
* Set the namespace to +namespace+
|
940
976
|
*/
|
941
|
-
static VALUE
|
977
|
+
static VALUE
|
978
|
+
set_namespace(VALUE self, VALUE namespace)
|
942
979
|
{
|
943
980
|
xmlNodePtr node;
|
944
981
|
xmlNsPtr ns = NULL;
|
945
982
|
|
946
983
|
Data_Get_Struct(self, xmlNode, node);
|
947
984
|
|
948
|
-
if(!NIL_P(namespace)) {
|
985
|
+
if (!NIL_P(namespace)) {
|
949
986
|
Data_Get_Struct(namespace, xmlNs, ns);
|
950
987
|
}
|
951
988
|
|
@@ -960,15 +997,16 @@ static VALUE set_namespace(VALUE self, VALUE namespace)
|
|
960
997
|
*
|
961
998
|
* Get the attribute node with +name+
|
962
999
|
*/
|
963
|
-
static VALUE
|
1000
|
+
static VALUE
|
1001
|
+
attr(VALUE self, VALUE name)
|
964
1002
|
{
|
965
1003
|
xmlNodePtr node;
|
966
1004
|
xmlAttrPtr prop;
|
967
1005
|
Data_Get_Struct(self, xmlNode, node);
|
968
1006
|
prop = xmlHasProp(node, (xmlChar *)StringValueCStr(name));
|
969
1007
|
|
970
|
-
if(! prop) { return Qnil; }
|
971
|
-
return
|
1008
|
+
if (! prop) { return Qnil; }
|
1009
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
972
1010
|
}
|
973
1011
|
|
974
1012
|
/*
|
@@ -977,7 +1015,8 @@ static VALUE attr(VALUE self, VALUE name)
|
|
977
1015
|
*
|
978
1016
|
* Get the attribute node with +name+ and +namespace+
|
979
1017
|
*/
|
980
|
-
static VALUE
|
1018
|
+
static VALUE
|
1019
|
+
attribute_with_ns(VALUE self, VALUE name, VALUE namespace)
|
981
1020
|
{
|
982
1021
|
xmlNodePtr node;
|
983
1022
|
xmlAttrPtr prop;
|
@@ -985,28 +1024,23 @@ static VALUE attribute_with_ns(VALUE self, VALUE name, VALUE namespace)
|
|
985
1024
|
prop = xmlHasNsProp(node, (xmlChar *)StringValueCStr(name),
|
986
1025
|
NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace));
|
987
1026
|
|
988
|
-
if(! prop) { return Qnil; }
|
989
|
-
return
|
1027
|
+
if (! prop) { return Qnil; }
|
1028
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
990
1029
|
}
|
991
1030
|
|
992
1031
|
/*
|
993
|
-
*
|
994
|
-
*
|
995
|
-
*
|
996
|
-
* returns a list containing the Node attributes.
|
1032
|
+
* @overload attribute_nodes()
|
1033
|
+
* Get the attributes for a Node
|
1034
|
+
* @return [Array<Nokogiri::XML::Attr>] containing the Node's attributes.
|
997
1035
|
*/
|
998
|
-
static VALUE
|
1036
|
+
static VALUE
|
1037
|
+
attribute_nodes(VALUE rb_node)
|
999
1038
|
{
|
1000
|
-
|
1001
|
-
xmlNodePtr node;
|
1002
|
-
VALUE attr;
|
1003
|
-
|
1004
|
-
Data_Get_Struct(self, xmlNode, node);
|
1039
|
+
xmlNodePtr c_node;
|
1005
1040
|
|
1006
|
-
|
1007
|
-
Nokogiri_xml_node_properties(node, attr);
|
1041
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1008
1042
|
|
1009
|
-
return
|
1043
|
+
return noko_xml_node_attrs(c_node);
|
1010
1044
|
}
|
1011
1045
|
|
1012
1046
|
|
@@ -1017,16 +1051,17 @@ static VALUE attribute_nodes(VALUE self)
|
|
1017
1051
|
* returns the namespace of the element or attribute node as a Namespace
|
1018
1052
|
* object, or nil if there is no namespace for the element or attribute.
|
1019
1053
|
*/
|
1020
|
-
static VALUE
|
1054
|
+
static VALUE
|
1055
|
+
noko_xml_node_namespace(VALUE rb_node)
|
1021
1056
|
{
|
1022
|
-
xmlNodePtr
|
1023
|
-
Data_Get_Struct(
|
1057
|
+
xmlNodePtr c_node ;
|
1058
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1024
1059
|
|
1025
|
-
if (
|
1026
|
-
|
1027
|
-
}
|
1060
|
+
if (c_node->ns) {
|
1061
|
+
return noko_xml_namespace_wrap(c_node->ns, c_node->doc);
|
1062
|
+
}
|
1028
1063
|
|
1029
|
-
return Qnil ;
|
1064
|
+
return Qnil ;
|
1030
1065
|
}
|
1031
1066
|
|
1032
1067
|
/*
|
@@ -1035,27 +1070,27 @@ return Qnil ;
|
|
1035
1070
|
*
|
1036
1071
|
* returns namespaces defined on self element directly, as an array of Namespace objects. Includes both a default namespace (as in"xmlns="), and prefixed namespaces (as in "xmlns:prefix=").
|
1037
1072
|
*/
|
1038
|
-
static VALUE
|
1073
|
+
static VALUE
|
1074
|
+
namespace_definitions(VALUE rb_node)
|
1039
1075
|
{
|
1040
1076
|
/* this code in the mode of xmlHasProp() */
|
1041
|
-
xmlNodePtr
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
Data_Get_Struct(self, xmlNode, node);
|
1077
|
+
xmlNodePtr c_node ;
|
1078
|
+
xmlNsPtr c_namespace;
|
1079
|
+
VALUE definitions = rb_ary_new();
|
1046
1080
|
|
1047
|
-
|
1081
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1048
1082
|
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1083
|
+
c_namespace = c_node->nsDef;
|
1084
|
+
if (!c_namespace) {
|
1085
|
+
return definitions;
|
1086
|
+
}
|
1052
1087
|
|
1053
|
-
while(
|
1054
|
-
rb_ary_push(
|
1055
|
-
|
1088
|
+
while (c_namespace != NULL) {
|
1089
|
+
rb_ary_push(definitions, noko_xml_namespace_wrap(c_namespace, c_node->doc));
|
1090
|
+
c_namespace = c_namespace->next;
|
1056
1091
|
}
|
1057
1092
|
|
1058
|
-
return
|
1093
|
+
return definitions;
|
1059
1094
|
}
|
1060
1095
|
|
1061
1096
|
/*
|
@@ -1067,26 +1102,27 @@ static VALUE namespace_definitions(VALUE self)
|
|
1067
1102
|
* namespaces ("xmlns=" style) for self are included in this array; Default
|
1068
1103
|
* namespaces for ancestors, however, are not. See also #namespaces
|
1069
1104
|
*/
|
1070
|
-
static VALUE
|
1105
|
+
static VALUE
|
1106
|
+
namespace_scopes(VALUE rb_node)
|
1071
1107
|
{
|
1072
|
-
xmlNodePtr
|
1073
|
-
|
1074
|
-
|
1108
|
+
xmlNodePtr c_node ;
|
1109
|
+
xmlNsPtr *namespaces;
|
1110
|
+
VALUE scopes = rb_ary_new();
|
1075
1111
|
int j;
|
1076
1112
|
|
1077
|
-
Data_Get_Struct(
|
1113
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1078
1114
|
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1115
|
+
namespaces = xmlGetNsList(c_node->doc, c_node);
|
1116
|
+
if (!namespaces) {
|
1117
|
+
return scopes;
|
1118
|
+
}
|
1083
1119
|
|
1084
|
-
for (j = 0 ;
|
1085
|
-
rb_ary_push(
|
1120
|
+
for (j = 0 ; namespaces[j] != NULL ; ++j) {
|
1121
|
+
rb_ary_push(scopes, noko_xml_namespace_wrap(namespaces[j], c_node->doc));
|
1086
1122
|
}
|
1087
1123
|
|
1088
|
-
xmlFree(
|
1089
|
-
return
|
1124
|
+
xmlFree(namespaces);
|
1125
|
+
return scopes;
|
1090
1126
|
}
|
1091
1127
|
|
1092
1128
|
/*
|
@@ -1095,7 +1131,8 @@ static VALUE namespace_scopes(VALUE self)
|
|
1095
1131
|
*
|
1096
1132
|
* Get the type for this Node
|
1097
1133
|
*/
|
1098
|
-
static VALUE
|
1134
|
+
static VALUE
|
1135
|
+
node_type(VALUE self)
|
1099
1136
|
{
|
1100
1137
|
xmlNodePtr node;
|
1101
1138
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1108,7 +1145,8 @@ static VALUE node_type(VALUE self)
|
|
1108
1145
|
*
|
1109
1146
|
* Set the content for this Node
|
1110
1147
|
*/
|
1111
|
-
static VALUE
|
1148
|
+
static VALUE
|
1149
|
+
set_native_content(VALUE self, VALUE content)
|
1112
1150
|
{
|
1113
1151
|
xmlNodePtr node, child, next ;
|
1114
1152
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1117,7 +1155,7 @@ static VALUE set_native_content(VALUE self, VALUE content)
|
|
1117
1155
|
while (NULL != child) {
|
1118
1156
|
next = child->next ;
|
1119
1157
|
xmlUnlinkNode(child) ;
|
1120
|
-
|
1158
|
+
noko_xml_document_pin_node(child);
|
1121
1159
|
child = next ;
|
1122
1160
|
}
|
1123
1161
|
|
@@ -1132,15 +1170,16 @@ static VALUE set_native_content(VALUE self, VALUE content)
|
|
1132
1170
|
* Returns the plaintext content for this Node. Note that entities will always
|
1133
1171
|
* be expanded in the returned string.
|
1134
1172
|
*/
|
1135
|
-
static VALUE
|
1173
|
+
static VALUE
|
1174
|
+
get_native_content(VALUE self)
|
1136
1175
|
{
|
1137
1176
|
xmlNodePtr node;
|
1138
|
-
xmlChar *
|
1177
|
+
xmlChar *content;
|
1139
1178
|
|
1140
1179
|
Data_Get_Struct(self, xmlNode, node);
|
1141
1180
|
|
1142
1181
|
content = xmlNodeGetContent(node);
|
1143
|
-
if(content) {
|
1182
|
+
if (content) {
|
1144
1183
|
VALUE rval = NOKOGIRI_STR_NEW2(content);
|
1145
1184
|
xmlFree(content);
|
1146
1185
|
return rval;
|
@@ -1154,13 +1193,14 @@ static VALUE get_native_content(VALUE self)
|
|
1154
1193
|
*
|
1155
1194
|
* Set the language of a node, i.e. the values of the xml:lang attribute.
|
1156
1195
|
*/
|
1157
|
-
static VALUE
|
1196
|
+
static VALUE
|
1197
|
+
set_lang(VALUE self_rb, VALUE lang_rb)
|
1158
1198
|
{
|
1159
1199
|
xmlNodePtr self ;
|
1160
|
-
xmlChar*
|
1200
|
+
xmlChar *lang ;
|
1161
1201
|
|
1162
1202
|
Data_Get_Struct(self_rb, xmlNode, self);
|
1163
|
-
lang = (xmlChar*)StringValueCStr(lang_rb);
|
1203
|
+
lang = (xmlChar *)StringValueCStr(lang_rb);
|
1164
1204
|
|
1165
1205
|
xmlNodeSetLang(self, lang);
|
1166
1206
|
|
@@ -1174,10 +1214,11 @@ static VALUE set_lang(VALUE self_rb, VALUE lang_rb)
|
|
1174
1214
|
* Searches the language of a node, i.e. the values of the xml:lang attribute or
|
1175
1215
|
* the one carried by the nearest ancestor.
|
1176
1216
|
*/
|
1177
|
-
static VALUE
|
1217
|
+
static VALUE
|
1218
|
+
get_lang(VALUE self_rb)
|
1178
1219
|
{
|
1179
1220
|
xmlNodePtr self ;
|
1180
|
-
xmlChar*
|
1221
|
+
xmlChar *lang ;
|
1181
1222
|
VALUE lang_rb ;
|
1182
1223
|
|
1183
1224
|
Data_Get_Struct(self_rb, xmlNode, self);
|
@@ -1193,7 +1234,8 @@ static VALUE get_lang(VALUE self_rb)
|
|
1193
1234
|
}
|
1194
1235
|
|
1195
1236
|
/* :nodoc: */
|
1196
|
-
static VALUE
|
1237
|
+
static VALUE
|
1238
|
+
add_child(VALUE self, VALUE new_child)
|
1197
1239
|
{
|
1198
1240
|
return reparent_node_with(self, new_child, xmlAddChild);
|
1199
1241
|
}
|
@@ -1204,15 +1246,16 @@ static VALUE add_child(VALUE self, VALUE new_child)
|
|
1204
1246
|
*
|
1205
1247
|
* Get the parent Node for this Node
|
1206
1248
|
*/
|
1207
|
-
static VALUE
|
1249
|
+
static VALUE
|
1250
|
+
get_parent(VALUE self)
|
1208
1251
|
{
|
1209
1252
|
xmlNodePtr node, parent;
|
1210
1253
|
Data_Get_Struct(self, xmlNode, node);
|
1211
1254
|
|
1212
1255
|
parent = node->parent;
|
1213
|
-
if(!parent) { return Qnil; }
|
1256
|
+
if (!parent) { return Qnil; }
|
1214
1257
|
|
1215
|
-
return
|
1258
|
+
return noko_xml_node_wrap(Qnil, parent) ;
|
1216
1259
|
}
|
1217
1260
|
|
1218
1261
|
/*
|
@@ -1221,11 +1264,12 @@ static VALUE get_parent(VALUE self)
|
|
1221
1264
|
*
|
1222
1265
|
* Set the name for this Node
|
1223
1266
|
*/
|
1224
|
-
static VALUE
|
1267
|
+
static VALUE
|
1268
|
+
set_name(VALUE self, VALUE new_name)
|
1225
1269
|
{
|
1226
1270
|
xmlNodePtr node;
|
1227
1271
|
Data_Get_Struct(self, xmlNode, node);
|
1228
|
-
xmlNodeSetName(node, (xmlChar*)StringValueCStr(new_name));
|
1272
|
+
xmlNodeSetName(node, (xmlChar *)StringValueCStr(new_name));
|
1229
1273
|
return new_name;
|
1230
1274
|
}
|
1231
1275
|
|
@@ -1235,11 +1279,12 @@ static VALUE set_name(VALUE self, VALUE new_name)
|
|
1235
1279
|
*
|
1236
1280
|
* Returns the name for this Node
|
1237
1281
|
*/
|
1238
|
-
static VALUE
|
1282
|
+
static VALUE
|
1283
|
+
get_name(VALUE self)
|
1239
1284
|
{
|
1240
1285
|
xmlNodePtr node;
|
1241
1286
|
Data_Get_Struct(self, xmlNode, node);
|
1242
|
-
if(node->name) {
|
1287
|
+
if (node->name) {
|
1243
1288
|
return NOKOGIRI_STR_NEW2(node->name);
|
1244
1289
|
}
|
1245
1290
|
return Qnil;
|
@@ -1251,28 +1296,39 @@ static VALUE get_name(VALUE self)
|
|
1251
1296
|
*
|
1252
1297
|
* Returns the path associated with this Node
|
1253
1298
|
*/
|
1254
|
-
static VALUE
|
1299
|
+
static VALUE
|
1300
|
+
noko_xml_node_path(VALUE rb_node)
|
1255
1301
|
{
|
1256
|
-
xmlNodePtr
|
1257
|
-
xmlChar *
|
1302
|
+
xmlNodePtr c_node;
|
1303
|
+
xmlChar *c_path ;
|
1258
1304
|
VALUE rval;
|
1259
1305
|
|
1260
|
-
Data_Get_Struct(
|
1306
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1307
|
+
|
1308
|
+
c_path = xmlGetNodePath(c_node);
|
1309
|
+
if (c_path == NULL) {
|
1310
|
+
// see https://github.com/sparklemotion/nokogiri/issues/2250
|
1311
|
+
// this behavior is clearly undesirable, but is what libxml <= 2.9.10 returned, and so we
|
1312
|
+
// do this for now to preserve the behavior across libxml2 versions.
|
1313
|
+
rval = NOKOGIRI_STR_NEW2("?");
|
1314
|
+
} else {
|
1315
|
+
rval = NOKOGIRI_STR_NEW2(c_path);
|
1316
|
+
xmlFree(c_path);
|
1317
|
+
}
|
1261
1318
|
|
1262
|
-
path = xmlGetNodePath(node);
|
1263
|
-
rval = NOKOGIRI_STR_NEW2(path);
|
1264
|
-
xmlFree(path);
|
1265
1319
|
return rval ;
|
1266
1320
|
}
|
1267
1321
|
|
1268
1322
|
/* :nodoc: */
|
1269
|
-
static VALUE
|
1323
|
+
static VALUE
|
1324
|
+
add_next_sibling(VALUE self, VALUE new_sibling)
|
1270
1325
|
{
|
1271
1326
|
return reparent_node_with(self, new_sibling, xmlAddNextSibling) ;
|
1272
1327
|
}
|
1273
1328
|
|
1274
1329
|
/* :nodoc: */
|
1275
|
-
static VALUE
|
1330
|
+
static VALUE
|
1331
|
+
add_previous_sibling(VALUE self, VALUE new_sibling)
|
1276
1332
|
{
|
1277
1333
|
return reparent_node_with(self, new_sibling, xmlAddPrevSibling) ;
|
1278
1334
|
}
|
@@ -1283,7 +1339,8 @@ static VALUE add_previous_sibling(VALUE self, VALUE new_sibling)
|
|
1283
1339
|
*
|
1284
1340
|
* Write this Node to +io+ with +encoding+ and +options+
|
1285
1341
|
*/
|
1286
|
-
static VALUE
|
1342
|
+
static VALUE
|
1343
|
+
native_write_to(
|
1287
1344
|
VALUE self,
|
1288
1345
|
VALUE io,
|
1289
1346
|
VALUE encoding,
|
@@ -1292,7 +1349,7 @@ static VALUE native_write_to(
|
|
1292
1349
|
)
|
1293
1350
|
{
|
1294
1351
|
xmlNodePtr node;
|
1295
|
-
const char *
|
1352
|
+
const char *before_indent;
|
1296
1353
|
xmlSaveCtxtPtr savectx;
|
1297
1354
|
|
1298
1355
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1304,8 +1361,8 @@ static VALUE native_write_to(
|
|
1304
1361
|
xmlTreeIndentString = StringValueCStr(indent_string);
|
1305
1362
|
|
1306
1363
|
savectx = xmlSaveToIO(
|
1307
|
-
(xmlOutputWriteCallback)
|
1308
|
-
(xmlOutputCloseCallback)
|
1364
|
+
(xmlOutputWriteCallback)noko_io_write,
|
1365
|
+
(xmlOutputCloseCallback)noko_io_close,
|
1309
1366
|
(void *)io,
|
1310
1367
|
RTEST(encoding) ? StringValueCStr(encoding) : NULL,
|
1311
1368
|
(int)NUM2INT(options)
|
@@ -1324,7 +1381,8 @@ static VALUE native_write_to(
|
|
1324
1381
|
*
|
1325
1382
|
* Returns the line for this Node
|
1326
1383
|
*/
|
1327
|
-
static VALUE
|
1384
|
+
static VALUE
|
1385
|
+
line(VALUE self)
|
1328
1386
|
{
|
1329
1387
|
xmlNodePtr node;
|
1330
1388
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1332,6 +1390,26 @@ static VALUE line(VALUE self)
|
|
1332
1390
|
return INT2NUM(xmlGetLineNo(node));
|
1333
1391
|
}
|
1334
1392
|
|
1393
|
+
/*
|
1394
|
+
* call-seq:
|
1395
|
+
* line=(num)
|
1396
|
+
*
|
1397
|
+
* Sets the line for this Node. num must be less than 65535.
|
1398
|
+
*/
|
1399
|
+
static VALUE
|
1400
|
+
set_line(VALUE self, VALUE num)
|
1401
|
+
{
|
1402
|
+
xmlNodePtr node;
|
1403
|
+
int value = NUM2INT(num);
|
1404
|
+
|
1405
|
+
Data_Get_Struct(self, xmlNode, node);
|
1406
|
+
if (value < 65535) {
|
1407
|
+
node->line = value;
|
1408
|
+
}
|
1409
|
+
|
1410
|
+
return num;
|
1411
|
+
}
|
1412
|
+
|
1335
1413
|
/*
|
1336
1414
|
* call-seq:
|
1337
1415
|
* add_namespace_definition(prefix, href)
|
@@ -1343,45 +1421,47 @@ static VALUE line(VALUE self)
|
|
1343
1421
|
* show up in #attributes, but they will be included as an xmlns attribute
|
1344
1422
|
* when the node is serialized to XML.
|
1345
1423
|
*/
|
1346
|
-
static VALUE
|
1424
|
+
static VALUE
|
1425
|
+
add_namespace_definition(VALUE rb_node, VALUE rb_prefix, VALUE rb_href)
|
1347
1426
|
{
|
1348
|
-
xmlNodePtr
|
1349
|
-
xmlNsPtr
|
1427
|
+
xmlNodePtr c_node, element;
|
1428
|
+
xmlNsPtr c_namespace;
|
1429
|
+
const xmlChar *c_prefix = (const xmlChar *)(NIL_P(rb_prefix) ? NULL : StringValueCStr(rb_prefix));
|
1350
1430
|
|
1351
|
-
Data_Get_Struct(
|
1352
|
-
|
1431
|
+
Data_Get_Struct(rb_node, xmlNode, c_node);
|
1432
|
+
element = c_node ;
|
1353
1433
|
|
1354
|
-
|
1355
|
-
node->doc,
|
1356
|
-
node,
|
1357
|
-
(const xmlChar *)(NIL_P(prefix) ? NULL : StringValueCStr(prefix))
|
1358
|
-
);
|
1434
|
+
c_namespace = xmlSearchNs(c_node->doc, c_node, c_prefix);
|
1359
1435
|
|
1360
|
-
if(!
|
1361
|
-
if (
|
1362
|
-
|
1436
|
+
if (!c_namespace) {
|
1437
|
+
if (c_node->type != XML_ELEMENT_NODE) {
|
1438
|
+
element = c_node->parent;
|
1363
1439
|
}
|
1364
|
-
|
1365
|
-
namespace,
|
1366
|
-
(const xmlChar *)StringValueCStr(href),
|
1367
|
-
(const xmlChar *)(NIL_P(prefix) ? NULL : StringValueCStr(prefix))
|
1368
|
-
);
|
1440
|
+
c_namespace = xmlNewNs(element, (const xmlChar *)StringValueCStr(rb_href), c_prefix);
|
1369
1441
|
}
|
1370
1442
|
|
1371
|
-
if (!
|
1443
|
+
if (!c_namespace) {
|
1444
|
+
return Qnil ;
|
1445
|
+
}
|
1372
1446
|
|
1373
|
-
if(NIL_P(
|
1447
|
+
if (NIL_P(rb_prefix) || c_node != element) {
|
1448
|
+
xmlSetNs(c_node, c_namespace);
|
1449
|
+
}
|
1374
1450
|
|
1375
|
-
return
|
1451
|
+
return noko_xml_namespace_wrap(c_namespace, c_node->doc);
|
1376
1452
|
}
|
1377
1453
|
|
1378
1454
|
/*
|
1379
|
-
*
|
1380
|
-
* new
|
1381
|
-
*
|
1382
|
-
*
|
1455
|
+
* @overload new(name, document)
|
1456
|
+
* Create a new node with +name+ sharing GC lifecycle with +document+.
|
1457
|
+
* @param name [String]
|
1458
|
+
* @param document [Nokogiri::XML::Document]
|
1459
|
+
* @yieldparam node [Nokogiri::XML::Node]
|
1460
|
+
* @return [Nokogiri::XML::Node]
|
1461
|
+
* @see Nokogiri::XML::Node#initialize
|
1383
1462
|
*/
|
1384
|
-
static VALUE
|
1463
|
+
static VALUE
|
1464
|
+
rb_xml_node_new(int argc, VALUE *argv, VALUE klass)
|
1385
1465
|
{
|
1386
1466
|
xmlDocPtr doc;
|
1387
1467
|
xmlNodePtr node;
|
@@ -1396,15 +1476,15 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
|
|
1396
1476
|
|
1397
1477
|
node = xmlNewNode(NULL, (xmlChar *)StringValueCStr(name));
|
1398
1478
|
node->doc = doc->doc;
|
1399
|
-
|
1479
|
+
noko_xml_document_pin_node(node);
|
1400
1480
|
|
1401
|
-
rb_node =
|
1481
|
+
rb_node = noko_xml_node_wrap(
|
1402
1482
|
klass == cNokogiriXmlNode ? (VALUE)NULL : klass,
|
1403
1483
|
node
|
1404
1484
|
);
|
1405
1485
|
rb_obj_call_init(rb_node, argc, argv);
|
1406
1486
|
|
1407
|
-
if(rb_block_given_p()) { rb_yield(rb_node); }
|
1487
|
+
if (rb_block_given_p()) { rb_yield(rb_node); }
|
1408
1488
|
|
1409
1489
|
return rb_node;
|
1410
1490
|
}
|
@@ -1415,7 +1495,8 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
|
|
1415
1495
|
*
|
1416
1496
|
* Returns the Node as html.
|
1417
1497
|
*/
|
1418
|
-
static VALUE
|
1498
|
+
static VALUE
|
1499
|
+
dump_html(VALUE self)
|
1419
1500
|
{
|
1420
1501
|
xmlBufferPtr buf ;
|
1421
1502
|
xmlNodePtr node ;
|
@@ -1436,7 +1517,8 @@ static VALUE dump_html(VALUE self)
|
|
1436
1517
|
*
|
1437
1518
|
* Compare this Node to +other+ with respect to their Document
|
1438
1519
|
*/
|
1439
|
-
static VALUE
|
1520
|
+
static VALUE
|
1521
|
+
compare(VALUE self, VALUE _other)
|
1440
1522
|
{
|
1441
1523
|
xmlNodePtr node, other;
|
1442
1524
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -1453,7 +1535,8 @@ static VALUE compare(VALUE self, VALUE _other)
|
|
1453
1535
|
* Loads and substitutes all xinclude elements below the node. The
|
1454
1536
|
* parser context will be initialized with +options+.
|
1455
1537
|
*/
|
1456
|
-
static VALUE
|
1538
|
+
static VALUE
|
1539
|
+
process_xincludes(VALUE self, VALUE options)
|
1457
1540
|
{
|
1458
1541
|
int rcode ;
|
1459
1542
|
xmlNodePtr node;
|
@@ -1469,7 +1552,7 @@ static VALUE process_xincludes(VALUE self, VALUE options)
|
|
1469
1552
|
xmlErrorPtr error;
|
1470
1553
|
|
1471
1554
|
error = xmlGetLastError();
|
1472
|
-
if(error) {
|
1555
|
+
if (error) {
|
1473
1556
|
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
1474
1557
|
} else {
|
1475
1558
|
rb_raise(rb_eRuntimeError, "Could not perform xinclude substitution");
|
@@ -1481,7 +1564,8 @@ static VALUE process_xincludes(VALUE self, VALUE options)
|
|
1481
1564
|
|
1482
1565
|
|
1483
1566
|
/* TODO: DOCUMENT ME */
|
1484
|
-
static VALUE
|
1567
|
+
static VALUE
|
1568
|
+
in_context(VALUE self, VALUE _str, VALUE _options)
|
1485
1569
|
{
|
1486
1570
|
xmlNodePtr node, list = 0, tmp, child_iter, node_children, doc_children;
|
1487
1571
|
xmlNodeSetPtr set;
|
@@ -1562,12 +1646,12 @@ static VALUE in_context(VALUE self, VALUE _str, VALUE _options)
|
|
1562
1646
|
|
1563
1647
|
/* FIXME: This probably needs to handle more constants... */
|
1564
1648
|
switch (error) {
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1649
|
+
case XML_ERR_INTERNAL_ERROR:
|
1650
|
+
case XML_ERR_NO_MEMORY:
|
1651
|
+
rb_raise(rb_eRuntimeError, "error parsing fragment (%d)", error);
|
1652
|
+
break;
|
1653
|
+
default:
|
1654
|
+
break;
|
1571
1655
|
}
|
1572
1656
|
|
1573
1657
|
set = xmlXPathNodeSetCreate(NULL);
|
@@ -1576,178 +1660,180 @@ static VALUE in_context(VALUE self, VALUE _str, VALUE _options)
|
|
1576
1660
|
tmp = list->next;
|
1577
1661
|
list->next = NULL;
|
1578
1662
|
xmlXPathNodeSetAddUnique(set, list);
|
1579
|
-
|
1663
|
+
noko_xml_document_pin_node(list);
|
1580
1664
|
list = tmp;
|
1581
1665
|
}
|
1582
1666
|
|
1583
|
-
return
|
1667
|
+
return noko_xml_node_set_wrap(set, doc);
|
1584
1668
|
}
|
1585
1669
|
|
1586
1670
|
|
1587
|
-
VALUE
|
1671
|
+
VALUE
|
1672
|
+
noko_xml_node_wrap(VALUE rb_class, xmlNodePtr c_node)
|
1588
1673
|
{
|
1589
|
-
VALUE
|
1590
|
-
VALUE node_cache = Qnil ;
|
1591
|
-
VALUE rb_node = Qnil ;
|
1674
|
+
VALUE rb_document, rb_node_cache, rb_node;
|
1592
1675
|
nokogiriTuplePtr node_has_a_document;
|
1593
|
-
xmlDocPtr
|
1676
|
+
xmlDocPtr c_doc;
|
1594
1677
|
void (*mark_method)(xmlNodePtr) = NULL ;
|
1595
1678
|
|
1596
|
-
assert(
|
1679
|
+
assert(c_node);
|
1597
1680
|
|
1598
|
-
if(
|
1599
|
-
return DOC_RUBY_OBJECT(
|
1681
|
+
if (c_node->type == XML_DOCUMENT_NODE || c_node->type == XML_HTML_DOCUMENT_NODE) {
|
1682
|
+
return DOC_RUBY_OBJECT(c_node->doc);
|
1600
1683
|
}
|
1601
1684
|
|
1602
1685
|
/* It's OK if the node doesn't have a fully-realized document (as in XML::Reader). */
|
1603
1686
|
/* see https://github.com/sparklemotion/nokogiri/issues/95 */
|
1604
1687
|
/* and https://github.com/sparklemotion/nokogiri/issues/439 */
|
1605
|
-
|
1606
|
-
if (
|
1607
|
-
node_has_a_document = DOC_RUBY_OBJECT_TEST(
|
1688
|
+
c_doc = c_node->doc;
|
1689
|
+
if (c_doc->type == XML_DOCUMENT_FRAG_NODE) { c_doc = c_doc->doc; }
|
1690
|
+
node_has_a_document = DOC_RUBY_OBJECT_TEST(c_doc);
|
1608
1691
|
|
1609
|
-
if(
|
1610
|
-
return (VALUE)
|
1692
|
+
if (c_node->_private && node_has_a_document) {
|
1693
|
+
return (VALUE)c_node->_private;
|
1611
1694
|
}
|
1612
1695
|
|
1613
|
-
if(!RTEST(
|
1614
|
-
switch(
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1696
|
+
if (!RTEST(rb_class)) {
|
1697
|
+
switch (c_node->type) {
|
1698
|
+
case XML_ELEMENT_NODE:
|
1699
|
+
rb_class = cNokogiriXmlElement;
|
1700
|
+
break;
|
1701
|
+
case XML_TEXT_NODE:
|
1702
|
+
rb_class = cNokogiriXmlText;
|
1703
|
+
break;
|
1704
|
+
case XML_ATTRIBUTE_NODE:
|
1705
|
+
rb_class = cNokogiriXmlAttr;
|
1706
|
+
break;
|
1707
|
+
case XML_ENTITY_REF_NODE:
|
1708
|
+
rb_class = cNokogiriXmlEntityReference;
|
1709
|
+
break;
|
1710
|
+
case XML_COMMENT_NODE:
|
1711
|
+
rb_class = cNokogiriXmlComment;
|
1712
|
+
break;
|
1713
|
+
case XML_DOCUMENT_FRAG_NODE:
|
1714
|
+
rb_class = cNokogiriXmlDocumentFragment;
|
1715
|
+
break;
|
1716
|
+
case XML_PI_NODE:
|
1717
|
+
rb_class = cNokogiriXmlProcessingInstruction;
|
1718
|
+
break;
|
1719
|
+
case XML_ENTITY_DECL:
|
1720
|
+
rb_class = cNokogiriXmlEntityDecl;
|
1721
|
+
break;
|
1722
|
+
case XML_CDATA_SECTION_NODE:
|
1723
|
+
rb_class = cNokogiriXmlCData;
|
1724
|
+
break;
|
1725
|
+
case XML_DTD_NODE:
|
1726
|
+
rb_class = cNokogiriXmlDtd;
|
1727
|
+
break;
|
1728
|
+
case XML_ATTRIBUTE_DECL:
|
1729
|
+
rb_class = cNokogiriXmlAttributeDecl;
|
1730
|
+
break;
|
1731
|
+
case XML_ELEMENT_DECL:
|
1732
|
+
rb_class = cNokogiriXmlElementDecl;
|
1733
|
+
break;
|
1734
|
+
default:
|
1735
|
+
rb_class = cNokogiriXmlNode;
|
1653
1736
|
}
|
1654
1737
|
}
|
1655
1738
|
|
1656
1739
|
mark_method = node_has_a_document ? mark : NULL ;
|
1657
1740
|
|
1658
|
-
rb_node = Data_Wrap_Struct(
|
1659
|
-
|
1741
|
+
rb_node = Data_Wrap_Struct(rb_class, mark_method, debug_node_dealloc, c_node) ;
|
1742
|
+
c_node->_private = (void *)rb_node;
|
1660
1743
|
|
1661
1744
|
if (node_has_a_document) {
|
1662
|
-
|
1663
|
-
|
1664
|
-
rb_ary_push(
|
1665
|
-
rb_funcall(
|
1745
|
+
rb_document = DOC_RUBY_OBJECT(c_doc);
|
1746
|
+
rb_node_cache = DOC_NODE_CACHE(c_doc);
|
1747
|
+
rb_ary_push(rb_node_cache, rb_node);
|
1748
|
+
rb_funcall(rb_document, id_decorate, 1, rb_node);
|
1666
1749
|
}
|
1667
1750
|
|
1668
1751
|
return rb_node ;
|
1669
1752
|
}
|
1670
1753
|
|
1671
1754
|
|
1672
|
-
|
1755
|
+
/*
|
1756
|
+
* return Array<Nokogiri::XML::Attr> containing the node's attributes
|
1757
|
+
*/
|
1758
|
+
VALUE
|
1759
|
+
noko_xml_node_attrs(xmlNodePtr c_node)
|
1673
1760
|
{
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1761
|
+
VALUE rb_properties = rb_ary_new();
|
1762
|
+
xmlAttrPtr c_property;
|
1763
|
+
|
1764
|
+
c_property = c_node->properties ;
|
1765
|
+
while (c_property != NULL) {
|
1766
|
+
rb_ary_push(rb_properties, noko_xml_node_wrap(Qnil, (xmlNodePtr)c_property));
|
1767
|
+
c_property = c_property->next ;
|
1679
1768
|
}
|
1680
|
-
}
|
1681
1769
|
|
1682
|
-
|
1683
|
-
|
1770
|
+
return rb_properties;
|
1771
|
+
}
|
1684
1772
|
|
1685
|
-
void
|
1773
|
+
void
|
1774
|
+
noko_init_xml_node()
|
1686
1775
|
{
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
cNokogiriXmlNode
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
rb_define_method(
|
1698
|
-
rb_define_method(
|
1699
|
-
rb_define_method(
|
1700
|
-
rb_define_method(
|
1701
|
-
rb_define_method(
|
1702
|
-
rb_define_method(
|
1703
|
-
rb_define_method(
|
1704
|
-
rb_define_method(
|
1705
|
-
rb_define_method(
|
1706
|
-
rb_define_method(
|
1707
|
-
rb_define_method(
|
1708
|
-
rb_define_method(
|
1709
|
-
rb_define_method(
|
1710
|
-
rb_define_method(
|
1711
|
-
rb_define_method(
|
1712
|
-
rb_define_method(
|
1713
|
-
rb_define_method(
|
1714
|
-
rb_define_method(
|
1715
|
-
rb_define_method(
|
1716
|
-
rb_define_method(
|
1717
|
-
rb_define_method(
|
1718
|
-
rb_define_method(
|
1719
|
-
rb_define_method(
|
1720
|
-
rb_define_method(
|
1721
|
-
rb_define_method(
|
1722
|
-
rb_define_method(
|
1723
|
-
rb_define_method(
|
1724
|
-
rb_define_method(
|
1725
|
-
rb_define_method(
|
1726
|
-
rb_define_method(
|
1727
|
-
rb_define_method(
|
1728
|
-
rb_define_method(
|
1729
|
-
rb_define_method(
|
1730
|
-
rb_define_method(
|
1731
|
-
rb_define_method(
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1736
|
-
rb_define_private_method(
|
1737
|
-
rb_define_private_method(
|
1738
|
-
rb_define_private_method(
|
1739
|
-
rb_define_private_method(
|
1740
|
-
rb_define_private_method(
|
1741
|
-
rb_define_private_method(
|
1742
|
-
rb_define_private_method(
|
1743
|
-
rb_define_private_method(
|
1744
|
-
rb_define_private_method(
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
decorate = rb_intern("decorate");
|
1750
|
-
decorate_bang = rb_intern("decorate!");
|
1776
|
+
cNokogiriXmlNode = rb_define_class_under(mNokogiriXml, "Node", rb_cObject);
|
1777
|
+
|
1778
|
+
rb_undef_alloc_func(cNokogiriXmlNode);
|
1779
|
+
|
1780
|
+
rb_define_singleton_method(cNokogiriXmlNode, "new", rb_xml_node_new, -1);
|
1781
|
+
|
1782
|
+
rb_define_method(cNokogiriXmlNode, "add_namespace_definition", add_namespace_definition, 2);
|
1783
|
+
rb_define_method(cNokogiriXmlNode, "node_name", get_name, 0);
|
1784
|
+
rb_define_method(cNokogiriXmlNode, "document", document, 0);
|
1785
|
+
rb_define_method(cNokogiriXmlNode, "node_name=", set_name, 1);
|
1786
|
+
rb_define_method(cNokogiriXmlNode, "parent", get_parent, 0);
|
1787
|
+
rb_define_method(cNokogiriXmlNode, "child", child, 0);
|
1788
|
+
rb_define_method(cNokogiriXmlNode, "first_element_child", first_element_child, 0);
|
1789
|
+
rb_define_method(cNokogiriXmlNode, "last_element_child", last_element_child, 0);
|
1790
|
+
rb_define_method(cNokogiriXmlNode, "children", children, 0);
|
1791
|
+
rb_define_method(cNokogiriXmlNode, "element_children", element_children, 0);
|
1792
|
+
rb_define_method(cNokogiriXmlNode, "next_sibling", next_sibling, 0);
|
1793
|
+
rb_define_method(cNokogiriXmlNode, "previous_sibling", previous_sibling, 0);
|
1794
|
+
rb_define_method(cNokogiriXmlNode, "next_element", next_element, 0);
|
1795
|
+
rb_define_method(cNokogiriXmlNode, "previous_element", previous_element, 0);
|
1796
|
+
rb_define_method(cNokogiriXmlNode, "node_type", node_type, 0);
|
1797
|
+
rb_define_method(cNokogiriXmlNode, "path", noko_xml_node_path, 0);
|
1798
|
+
rb_define_method(cNokogiriXmlNode, "key?", key_eh, 1);
|
1799
|
+
rb_define_method(cNokogiriXmlNode, "namespaced_key?", namespaced_key_eh, 2);
|
1800
|
+
rb_define_method(cNokogiriXmlNode, "blank?", blank_eh, 0);
|
1801
|
+
rb_define_method(cNokogiriXmlNode, "attribute_nodes", attribute_nodes, 0);
|
1802
|
+
rb_define_method(cNokogiriXmlNode, "attribute", attr, 1);
|
1803
|
+
rb_define_method(cNokogiriXmlNode, "attribute_with_ns", attribute_with_ns, 2);
|
1804
|
+
rb_define_method(cNokogiriXmlNode, "namespace", noko_xml_node_namespace, 0);
|
1805
|
+
rb_define_method(cNokogiriXmlNode, "namespace_definitions", namespace_definitions, 0);
|
1806
|
+
rb_define_method(cNokogiriXmlNode, "namespace_scopes", namespace_scopes, 0);
|
1807
|
+
rb_define_method(cNokogiriXmlNode, "encode_special_chars", encode_special_chars, 1);
|
1808
|
+
rb_define_method(cNokogiriXmlNode, "dup", duplicate_node, -1);
|
1809
|
+
rb_define_method(cNokogiriXmlNode, "unlink", unlink_node, 0);
|
1810
|
+
rb_define_method(cNokogiriXmlNode, "internal_subset", internal_subset, 0);
|
1811
|
+
rb_define_method(cNokogiriXmlNode, "external_subset", external_subset, 0);
|
1812
|
+
rb_define_method(cNokogiriXmlNode, "create_internal_subset", create_internal_subset, 3);
|
1813
|
+
rb_define_method(cNokogiriXmlNode, "create_external_subset", create_external_subset, 3);
|
1814
|
+
rb_define_method(cNokogiriXmlNode, "pointer_id", pointer_id, 0);
|
1815
|
+
rb_define_method(cNokogiriXmlNode, "line", line, 0);
|
1816
|
+
rb_define_method(cNokogiriXmlNode, "line=", set_line, 1);
|
1817
|
+
rb_define_method(cNokogiriXmlNode, "content", get_native_content, 0);
|
1818
|
+
rb_define_method(cNokogiriXmlNode, "native_content=", set_native_content, 1);
|
1819
|
+
rb_define_method(cNokogiriXmlNode, "lang", get_lang, 0);
|
1820
|
+
rb_define_method(cNokogiriXmlNode, "lang=", set_lang, 1);
|
1821
|
+
|
1822
|
+
rb_define_private_method(cNokogiriXmlNode, "process_xincludes", process_xincludes, 1);
|
1823
|
+
rb_define_private_method(cNokogiriXmlNode, "in_context", in_context, 2);
|
1824
|
+
rb_define_private_method(cNokogiriXmlNode, "add_child_node", add_child, 1);
|
1825
|
+
rb_define_private_method(cNokogiriXmlNode, "add_previous_sibling_node", add_previous_sibling, 1);
|
1826
|
+
rb_define_private_method(cNokogiriXmlNode, "add_next_sibling_node", add_next_sibling, 1);
|
1827
|
+
rb_define_private_method(cNokogiriXmlNode, "replace_node", replace, 1);
|
1828
|
+
rb_define_private_method(cNokogiriXmlNode, "dump_html", dump_html, 0);
|
1829
|
+
rb_define_private_method(cNokogiriXmlNode, "native_write_to", native_write_to, 4);
|
1830
|
+
rb_define_private_method(cNokogiriXmlNode, "get", get, 1);
|
1831
|
+
rb_define_private_method(cNokogiriXmlNode, "set", set, 2);
|
1832
|
+
rb_define_private_method(cNokogiriXmlNode, "set_namespace", set_namespace, 1);
|
1833
|
+
rb_define_private_method(cNokogiriXmlNode, "compare", compare, 1);
|
1834
|
+
|
1835
|
+
id_decorate = rb_intern("decorate");
|
1836
|
+
id_decorate_bang = rb_intern("decorate!");
|
1751
1837
|
}
|
1752
1838
|
|
1753
1839
|
/* vim: set noet sw=4 sws=4 */
|