nokogiri 1.11.0.rc4 → 1.11.3

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.

Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/LICENSE-DEPENDENCIES.md +12 -12
  4. data/LICENSE.md +1 -1
  5. data/README.md +168 -91
  6. data/ext/nokogiri/depend +34 -474
  7. data/ext/nokogiri/extconf.rb +270 -183
  8. data/ext/nokogiri/html_document.c +10 -15
  9. data/ext/nokogiri/html_element_description.c +84 -71
  10. data/ext/nokogiri/html_entity_lookup.c +21 -16
  11. data/ext/nokogiri/html_sax_parser_context.c +67 -64
  12. data/ext/nokogiri/html_sax_push_parser.c +42 -34
  13. data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
  14. data/ext/nokogiri/nokogiri.c +171 -60
  15. data/ext/nokogiri/nokogiri.h +158 -75
  16. data/ext/nokogiri/test_global_handlers.c +40 -0
  17. data/ext/nokogiri/xml_attr.c +15 -15
  18. data/ext/nokogiri/xml_attribute_decl.c +18 -18
  19. data/ext/nokogiri/xml_cdata.c +13 -18
  20. data/ext/nokogiri/xml_comment.c +19 -26
  21. data/ext/nokogiri/xml_document.c +246 -188
  22. data/ext/nokogiri/xml_document_fragment.c +13 -15
  23. data/ext/nokogiri/xml_dtd.c +54 -48
  24. data/ext/nokogiri/xml_element_content.c +30 -27
  25. data/ext/nokogiri/xml_element_decl.c +22 -22
  26. data/ext/nokogiri/xml_encoding_handler.c +17 -11
  27. data/ext/nokogiri/xml_entity_decl.c +32 -30
  28. data/ext/nokogiri/xml_entity_reference.c +16 -18
  29. data/ext/nokogiri/xml_namespace.c +56 -49
  30. data/ext/nokogiri/xml_node.c +371 -320
  31. data/ext/nokogiri/xml_node_set.c +168 -156
  32. data/ext/nokogiri/xml_processing_instruction.c +17 -19
  33. data/ext/nokogiri/xml_reader.c +191 -157
  34. data/ext/nokogiri/xml_relax_ng.c +29 -23
  35. data/ext/nokogiri/xml_sax_parser.c +117 -112
  36. data/ext/nokogiri/xml_sax_parser_context.c +101 -84
  37. data/ext/nokogiri/xml_sax_push_parser.c +36 -27
  38. data/ext/nokogiri/xml_schema.c +48 -42
  39. data/ext/nokogiri/xml_syntax_error.c +42 -21
  40. data/ext/nokogiri/xml_text.c +13 -17
  41. data/ext/nokogiri/xml_xpath_context.c +134 -127
  42. data/ext/nokogiri/xslt_stylesheet.c +157 -157
  43. data/lib/nokogiri/css/parser.rb +1 -1
  44. data/lib/nokogiri/extension.rb +26 -0
  45. data/lib/nokogiri/html/document_fragment.rb +15 -15
  46. data/lib/nokogiri/version/constant.rb +1 -1
  47. data/lib/nokogiri/version/info.rb +31 -8
  48. data/lib/nokogiri/xml/document.rb +74 -28
  49. data/lib/nokogiri/xml/node.rb +39 -42
  50. data/lib/nokogiri/xml/reader.rb +2 -9
  51. data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -1
  52. data/lib/nokogiri/xml/xpath.rb +1 -3
  53. data/lib/nokogiri.rb +2 -6
  54. data/patches/libxml2/0009-avoid-isnan-isinf.patch +81 -0
  55. data/patches/libxml2/0010-parser.c-shrink-the-input-buffer-when-appropriate.patch +70 -0
  56. data/patches/libxml2/0011-update-automake-files-for-arm64.patch +2511 -0
  57. data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2511 -0
  58. metadata +66 -160
  59. data/ext/nokogiri/html_document.h +0 -10
  60. data/ext/nokogiri/html_element_description.h +0 -10
  61. data/ext/nokogiri/html_entity_lookup.h +0 -8
  62. data/ext/nokogiri/html_sax_parser_context.h +0 -11
  63. data/ext/nokogiri/html_sax_push_parser.h +0 -9
  64. data/ext/nokogiri/xml_attr.h +0 -9
  65. data/ext/nokogiri/xml_attribute_decl.h +0 -9
  66. data/ext/nokogiri/xml_cdata.h +0 -9
  67. data/ext/nokogiri/xml_comment.h +0 -9
  68. data/ext/nokogiri/xml_document.h +0 -23
  69. data/ext/nokogiri/xml_document_fragment.h +0 -10
  70. data/ext/nokogiri/xml_dtd.h +0 -10
  71. data/ext/nokogiri/xml_element_content.h +0 -10
  72. data/ext/nokogiri/xml_element_decl.h +0 -9
  73. data/ext/nokogiri/xml_encoding_handler.h +0 -8
  74. data/ext/nokogiri/xml_entity_decl.h +0 -10
  75. data/ext/nokogiri/xml_entity_reference.h +0 -9
  76. data/ext/nokogiri/xml_io.c +0 -63
  77. data/ext/nokogiri/xml_io.h +0 -11
  78. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
  79. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  80. data/ext/nokogiri/xml_namespace.h +0 -14
  81. data/ext/nokogiri/xml_node.h +0 -13
  82. data/ext/nokogiri/xml_node_set.h +0 -12
  83. data/ext/nokogiri/xml_processing_instruction.h +0 -9
  84. data/ext/nokogiri/xml_reader.h +0 -10
  85. data/ext/nokogiri/xml_relax_ng.h +0 -9
  86. data/ext/nokogiri/xml_sax_parser.h +0 -39
  87. data/ext/nokogiri/xml_sax_parser_context.h +0 -10
  88. data/ext/nokogiri/xml_sax_push_parser.h +0 -9
  89. data/ext/nokogiri/xml_schema.h +0 -9
  90. data/ext/nokogiri/xml_syntax_error.h +0 -13
  91. data/ext/nokogiri/xml_text.h +0 -9
  92. data/ext/nokogiri/xml_xpath_context.h +0 -10
  93. data/ext/nokogiri/xslt_stylesheet.h +0 -14
@@ -1,8 +1,11 @@
1
- #include <xml_document.h>
1
+ #include <nokogiri.h>
2
2
 
3
- static int dealloc_node_i2(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
3
+ VALUE cNokogiriXmlDocument ;
4
+
5
+ static int
6
+ dealloc_node_i2(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
4
7
  {
5
- switch(node->type) {
8
+ switch (node->type) {
6
9
  case XML_ATTRIBUTE_NODE:
7
10
  xmlFreePropList((xmlAttrPtr)node);
8
11
  break;
@@ -13,46 +16,52 @@ static int dealloc_node_i2(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
13
16
  xmlFreeDtd((xmlDtdPtr)node);
14
17
  break;
15
18
  default:
16
- if(node->parent == NULL) {
19
+ if (node->parent == NULL) {
17
20
  xmlAddChild((xmlNodePtr)doc, node);
18
21
  }
19
22
  }
20
23
  return ST_CONTINUE;
21
24
  }
22
25
 
23
- static int dealloc_node_i(st_data_t key, st_data_t node, st_data_t doc)
26
+ static int
27
+ dealloc_node_i(st_data_t key, st_data_t node, st_data_t doc)
24
28
  {
25
29
  return dealloc_node_i2((xmlNodePtr)key, (xmlNodePtr)node, (xmlDocPtr)doc);
26
30
  }
27
31
 
28
- static void remove_private(xmlNodePtr node)
32
+ static void
33
+ remove_private(xmlNodePtr node)
29
34
  {
30
35
  xmlNodePtr child;
31
36
 
32
- for (child = node->children; child; child = child->next)
37
+ for (child = node->children; child; child = child->next) {
33
38
  remove_private(child);
39
+ }
34
40
 
35
41
  if ((node->type == XML_ELEMENT_NODE ||
36
42
  node->type == XML_XINCLUDE_START ||
37
43
  node->type == XML_XINCLUDE_END) &&
38
44
  node->properties) {
39
- for (child = (xmlNodePtr)node->properties; child; child = child->next)
45
+ for (child = (xmlNodePtr)node->properties; child; child = child->next) {
40
46
  remove_private(child);
47
+ }
41
48
  }
42
49
 
43
50
  node->_private = NULL;
44
51
  }
45
52
 
46
- static void mark(xmlDocPtr doc)
53
+ static void
54
+ mark(xmlDocPtr doc)
47
55
  {
48
56
  nokogiriTuplePtr tuple = (nokogiriTuplePtr)doc->_private;
49
- if(tuple) {
50
- rb_gc_mark(tuple->doc);
51
- rb_gc_mark(tuple->node_cache);
57
+ if (tuple) {
58
+ rb_gc_mark(tuple->doc);
59
+ rb_gc_mark(tuple->node_cache);
52
60
  }
53
61
  }
54
62
 
55
- static void dealloc(xmlDocPtr doc)
63
+ static void
64
+ dealloc(xmlDocPtr doc)
56
65
  {
57
66
  st_table *node_hash;
58
67
 
@@ -70,23 +79,26 @@ static void dealloc(xmlDocPtr doc)
70
79
  * xmlDeregisterNode callback from accessing VALUE pointers from ruby's GC
71
80
  * free context, which can result in segfaults.
72
81
  */
73
- if (xmlDeregisterNodeDefaultValue)
82
+ if (xmlDeregisterNodeDefaultValue) {
74
83
  remove_private((xmlNodePtr)doc);
84
+ }
75
85
 
76
86
  xmlFreeDoc(doc);
77
87
 
78
88
  NOKOGIRI_DEBUG_END(doc);
79
89
  }
80
90
 
81
- static void recursively_remove_namespaces_from_node(xmlNodePtr node)
91
+ static void
92
+ recursively_remove_namespaces_from_node(xmlNodePtr node)
82
93
  {
83
94
  xmlNodePtr child ;
84
95
  xmlAttrPtr property ;
85
96
 
86
97
  xmlSetNs(node, NULL);
87
98
 
88
- for (child = node->children ; child ; child = child->next)
99
+ for (child = node->children ; child ; child = child->next) {
89
100
  recursively_remove_namespaces_from_node(child);
101
+ }
90
102
 
91
103
  if (((node->type == XML_ELEMENT_NODE) ||
92
104
  (node->type == XML_XINCLUDE_START) ||
@@ -99,7 +111,7 @@ static void recursively_remove_namespaces_from_node(xmlNodePtr node)
99
111
  if (node->type == XML_ELEMENT_NODE && node->properties != NULL) {
100
112
  property = node->properties ;
101
113
  while (property != NULL) {
102
- if (property->ns) property->ns = NULL ;
114
+ if (property->ns) { property->ns = NULL ; }
103
115
  property = property->next ;
104
116
  }
105
117
  }
@@ -111,12 +123,13 @@ static void recursively_remove_namespaces_from_node(xmlNodePtr node)
111
123
  *
112
124
  * Get the url name for this document.
113
125
  */
114
- static VALUE url(VALUE self)
126
+ static VALUE
127
+ url(VALUE self)
115
128
  {
116
129
  xmlDocPtr doc;
117
130
  Data_Get_Struct(self, xmlDoc, doc);
118
131
 
119
- if(doc->URL) return NOKOGIRI_STR_NEW2(doc->URL);
132
+ if (doc->URL) { return NOKOGIRI_STR_NEW2(doc->URL); }
120
133
 
121
134
  return Qnil;
122
135
  }
@@ -127,42 +140,42 @@ static VALUE url(VALUE self)
127
140
  *
128
141
  * Set the root element on this document
129
142
  */
130
- static VALUE set_root(VALUE self, VALUE root)
143
+ static VALUE
144
+ rb_xml_document_root_set(VALUE self, VALUE rb_new_root)
131
145
  {
132
- xmlDocPtr doc;
133
- xmlNodePtr new_root;
134
- xmlNodePtr old_root;
146
+ xmlDocPtr c_document;
147
+ xmlNodePtr c_new_root = NULL, c_current_root;
135
148
 
136
- Data_Get_Struct(self, xmlDoc, doc);
137
-
138
- old_root = NULL;
149
+ Data_Get_Struct(self, xmlDoc, c_document);
139
150
 
140
- if(NIL_P(root)) {
141
- old_root = xmlDocGetRootElement(doc);
142
-
143
- if(old_root) {
144
- xmlUnlinkNode(old_root);
145
- nokogiri_root_node(old_root);
146
- }
147
-
148
- return root;
151
+ c_current_root = xmlDocGetRootElement(c_document);
152
+ if (c_current_root) {
153
+ xmlUnlinkNode(c_current_root);
154
+ noko_xml_document_pin_node(c_current_root);
149
155
  }
150
156
 
151
- Data_Get_Struct(root, xmlNode, new_root);
157
+ if (!NIL_P(rb_new_root)) {
158
+ if (!rb_obj_is_kind_of(rb_new_root, cNokogiriXmlNode)) {
159
+ rb_raise(rb_eArgError,
160
+ "expected Nokogiri::XML::Node but received %"PRIsVALUE,
161
+ rb_obj_class(rb_new_root));
162
+ }
152
163
 
164
+ Data_Get_Struct(rb_new_root, xmlNode, c_new_root);
153
165
 
154
- /* If the new root's document is not the same as the current document,
155
- * then we need to dup the node in to this document. */
156
- if(new_root->doc != doc) {
157
- old_root = xmlDocGetRootElement(doc);
158
- if (!(new_root = xmlDocCopyNode(new_root, doc, 1))) {
159
- rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
166
+ /* If the new root's document is not the same as the current document,
167
+ * then we need to dup the node in to this document. */
168
+ if (c_new_root->doc != c_document) {
169
+ c_new_root = xmlDocCopyNode(c_new_root, c_document, 1);
170
+ if (!c_new_root) {
171
+ rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
172
+ }
160
173
  }
161
174
  }
162
175
 
163
- xmlDocSetRootElement(doc, new_root);
164
- if(old_root) nokogiri_root_node(old_root);
165
- return root;
176
+ xmlDocSetRootElement(c_document, c_new_root);
177
+
178
+ return rb_new_root;
166
179
  }
167
180
 
168
181
  /*
@@ -171,17 +184,20 @@ static VALUE set_root(VALUE self, VALUE root)
171
184
  *
172
185
  * Get the root node for this document.
173
186
  */
174
- static VALUE root(VALUE self)
187
+ static VALUE
188
+ rb_xml_document_root(VALUE self)
175
189
  {
176
- xmlDocPtr doc;
177
- xmlNodePtr root;
190
+ xmlDocPtr c_document;
191
+ xmlNodePtr c_root;
178
192
 
179
- Data_Get_Struct(self, xmlDoc, doc);
193
+ Data_Get_Struct(self, xmlDoc, c_document);
180
194
 
181
- root = xmlDocGetRootElement(doc);
195
+ c_root = xmlDocGetRootElement(c_document);
196
+ if (!c_root) {
197
+ return Qnil;
198
+ }
182
199
 
183
- if(!root) return Qnil;
184
- return Nokogiri_wrap_xml_node(Qnil, root) ;
200
+ return noko_xml_node_wrap(Qnil, c_root) ;
185
201
  }
186
202
 
187
203
  /*
@@ -190,13 +206,15 @@ static VALUE root(VALUE self)
190
206
  *
191
207
  * Set the encoding string for this Document
192
208
  */
193
- static VALUE set_encoding(VALUE self, VALUE encoding)
209
+ static VALUE
210
+ set_encoding(VALUE self, VALUE encoding)
194
211
  {
195
212
  xmlDocPtr doc;
196
213
  Data_Get_Struct(self, xmlDoc, doc);
197
214
 
198
- if (doc->encoding)
199
- free((char *)(uintptr_t) doc->encoding); /* avoid gcc cast warning */
215
+ if (doc->encoding) {
216
+ free((char *)(uintptr_t) doc->encoding); /* avoid gcc cast warning */
217
+ }
200
218
 
201
219
  doc->encoding = xmlStrdup((xmlChar *)StringValueCStr(encoding));
202
220
 
@@ -209,12 +227,13 @@ static VALUE set_encoding(VALUE self, VALUE encoding)
209
227
  *
210
228
  * Get the encoding for this Document
211
229
  */
212
- static VALUE encoding(VALUE self)
230
+ static VALUE
231
+ encoding(VALUE self)
213
232
  {
214
233
  xmlDocPtr doc;
215
234
  Data_Get_Struct(self, xmlDoc, doc);
216
235
 
217
- if(!doc->encoding) return Qnil;
236
+ if (!doc->encoding) { return Qnil; }
218
237
  return NOKOGIRI_STR_NEW2(doc->encoding);
219
238
  }
220
239
 
@@ -224,12 +243,13 @@ static VALUE encoding(VALUE self)
224
243
  *
225
244
  * Get the XML version for this Document
226
245
  */
227
- static VALUE version(VALUE self)
246
+ static VALUE
247
+ version(VALUE self)
228
248
  {
229
249
  xmlDocPtr doc;
230
250
  Data_Get_Struct(self, xmlDoc, doc);
231
251
 
232
- if(!doc->version) return Qnil;
252
+ if (!doc->version) { return Qnil; }
233
253
  return NOKOGIRI_STR_NEW2(doc->version);
234
254
  }
235
255
 
@@ -239,14 +259,15 @@ static VALUE version(VALUE self)
239
259
  *
240
260
  * Create a new document from an IO object
241
261
  */
242
- static VALUE read_io( VALUE klass,
243
- VALUE io,
244
- VALUE url,
245
- VALUE encoding,
246
- VALUE options )
262
+ static VALUE
263
+ read_io(VALUE klass,
264
+ VALUE io,
265
+ VALUE url,
266
+ VALUE encoding,
267
+ VALUE options)
247
268
  {
248
- const char * c_url = NIL_P(url) ? NULL : StringValueCStr(url);
249
- const char * c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
269
+ const char *c_url = NIL_P(url) ? NULL : StringValueCStr(url);
270
+ const char *c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
250
271
  VALUE error_list = rb_ary_new();
251
272
  VALUE document;
252
273
  xmlDocPtr doc;
@@ -255,30 +276,31 @@ static VALUE read_io( VALUE klass,
255
276
  xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
256
277
 
257
278
  doc = xmlReadIO(
258
- (xmlInputReadCallback)io_read_callback,
259
- (xmlInputCloseCallback)io_close_callback,
260
- (void *)io,
261
- c_url,
262
- c_enc,
263
- (int)NUM2INT(options)
264
- );
279
+ (xmlInputReadCallback)noko_io_read,
280
+ (xmlInputCloseCallback)noko_io_close,
281
+ (void *)io,
282
+ c_url,
283
+ c_enc,
284
+ (int)NUM2INT(options)
285
+ );
265
286
  xmlSetStructuredErrorFunc(NULL, NULL);
266
287
 
267
- if(doc == NULL) {
288
+ if (doc == NULL) {
268
289
  xmlErrorPtr error;
269
290
 
270
291
  xmlFreeDoc(doc);
271
292
 
272
293
  error = xmlGetLastError();
273
- if(error)
294
+ if (error) {
274
295
  rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
275
- else
296
+ } else {
276
297
  rb_raise(rb_eRuntimeError, "Could not parse document");
298
+ }
277
299
 
278
300
  return Qnil;
279
301
  }
280
302
 
281
- document = Nokogiri_wrap_xml_document(klass, doc);
303
+ document = noko_xml_document_wrap(klass, doc);
282
304
  rb_iv_set(document, "@errors", error_list);
283
305
  return document;
284
306
  }
@@ -289,15 +311,16 @@ static VALUE read_io( VALUE klass,
289
311
  *
290
312
  * Create a new document from a String
291
313
  */
292
- static VALUE read_memory( VALUE klass,
293
- VALUE string,
294
- VALUE url,
295
- VALUE encoding,
296
- VALUE options )
314
+ static VALUE
315
+ read_memory(VALUE klass,
316
+ VALUE string,
317
+ VALUE url,
318
+ VALUE encoding,
319
+ VALUE options)
297
320
  {
298
- const char * c_buffer = StringValuePtr(string);
299
- const char * c_url = NIL_P(url) ? NULL : StringValueCStr(url);
300
- const char * c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
321
+ const char *c_buffer = StringValuePtr(string);
322
+ const char *c_url = NIL_P(url) ? NULL : StringValueCStr(url);
323
+ const char *c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
301
324
  int len = (int)RSTRING_LEN(string);
302
325
  VALUE error_list = rb_ary_new();
303
326
  VALUE document;
@@ -308,21 +331,22 @@ static VALUE read_memory( VALUE klass,
308
331
  doc = xmlReadMemory(c_buffer, len, c_url, c_enc, (int)NUM2INT(options));
309
332
  xmlSetStructuredErrorFunc(NULL, NULL);
310
333
 
311
- if(doc == NULL) {
334
+ if (doc == NULL) {
312
335
  xmlErrorPtr error;
313
336
 
314
337
  xmlFreeDoc(doc);
315
338
 
316
339
  error = xmlGetLastError();
317
- if(error)
340
+ if (error) {
318
341
  rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
319
- else
342
+ } else {
320
343
  rb_raise(rb_eRuntimeError, "Could not parse document");
344
+ }
321
345
 
322
346
  return Qnil;
323
347
  }
324
348
 
325
- document = Nokogiri_wrap_xml_document(klass, doc);
349
+ document = noko_xml_document_wrap(klass, doc);
326
350
  rb_iv_set(document, "@errors", error_list);
327
351
  return document;
328
352
  }
@@ -334,26 +358,26 @@ static VALUE read_memory( VALUE klass,
334
358
  * Copy this Document. An optional depth may be passed in, but it defaults
335
359
  * to a deep copy. 0 is a shallow copy, 1 is a deep copy.
336
360
  */
337
- static VALUE duplicate_document(int argc, VALUE *argv, VALUE self)
361
+ static VALUE
362
+ duplicate_document(int argc, VALUE *argv, VALUE self)
338
363
  {
339
364
  xmlDocPtr doc, dup;
340
365
  VALUE copy;
341
366
  VALUE level;
342
- VALUE error_list;
343
367
 
344
- if(rb_scan_args(argc, argv, "01", &level) == 0)
368
+ if (rb_scan_args(argc, argv, "01", &level) == 0) {
345
369
  level = INT2NUM((long)1);
370
+ }
346
371
 
347
372
  Data_Get_Struct(self, xmlDoc, doc);
348
373
 
349
374
  dup = xmlCopyDoc(doc, (int)NUM2INT(level));
350
375
 
351
- if(dup == NULL) return Qnil;
376
+ if (dup == NULL) { return Qnil; }
352
377
 
353
378
  dup->type = doc->type;
354
- copy = Nokogiri_wrap_xml_document(rb_obj_class(self), dup);
355
- error_list = rb_iv_get(self, "@errors");
356
- rb_iv_set(copy, "@errors", error_list);
379
+ copy = noko_xml_document_wrap(rb_obj_class(self), dup);
380
+ rb_iv_set(copy, "@errors", rb_iv_get(self, "@errors"));
357
381
  return copy ;
358
382
  }
359
383
 
@@ -363,18 +387,18 @@ static VALUE duplicate_document(int argc, VALUE *argv, VALUE self)
363
387
  *
364
388
  * Create a new document with +version+ (defaults to "1.0")
365
389
  */
366
- static VALUE new(int argc, VALUE *argv, VALUE klass)
390
+ static VALUE
391
+ new (int argc, VALUE *argv, VALUE klass)
367
392
  {
368
393
  xmlDocPtr doc;
369
394
  VALUE version, rest, rb_doc ;
370
395
 
371
396
  rb_scan_args(argc, argv, "0*", &rest);
372
397
  version = rb_ary_entry(rest, (long)0);
373
- if (NIL_P(version)) version = rb_str_new2("1.0");
398
+ if (NIL_P(version)) { version = rb_str_new2("1.0"); }
374
399
 
375
400
  doc = xmlNewDoc((xmlChar *)StringValueCStr(version));
376
- rb_doc = Nokogiri_wrap_xml_document(klass, doc);
377
- rb_obj_call_init(rb_doc, argc, argv);
401
+ rb_doc = noko_xml_document_wrap_with_init_args(klass, doc, argc, argv);
378
402
  return rb_doc ;
379
403
  }
380
404
 
@@ -415,7 +439,8 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
415
439
  * please direct your browser to
416
440
  * http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html
417
441
  */
418
- VALUE remove_namespaces_bang(VALUE self)
442
+ static VALUE
443
+ remove_namespaces_bang(VALUE self)
419
444
  {
420
445
  xmlDocPtr doc ;
421
446
  Data_Get_Struct(self, xmlDoc, doc);
@@ -435,7 +460,8 @@ VALUE remove_namespaces_bang(VALUE self)
435
460
  * +external_id+, +system_id+, and +content+ set the External ID, System ID,
436
461
  * and content respectively. All of these parameters are optional.
437
462
  */
438
- static VALUE create_entity(int argc, VALUE *argv, VALUE self)
463
+ static VALUE
464
+ create_entity(int argc, VALUE *argv, VALUE self)
439
465
  {
440
466
  VALUE name;
441
467
  VALUE type;
@@ -448,52 +474,50 @@ static VALUE create_entity(int argc, VALUE *argv, VALUE self)
448
474
  Data_Get_Struct(self, xmlDoc, doc);
449
475
 
450
476
  rb_scan_args(argc, argv, "14", &name, &type, &external_id, &system_id,
451
- &content);
477
+ &content);
452
478
 
453
479
  xmlResetLastError();
454
480
  ptr = xmlAddDocEntity(
455
- doc,
456
- (xmlChar *)(NIL_P(name) ? NULL : StringValueCStr(name)),
457
- (int) (NIL_P(type) ? XML_INTERNAL_GENERAL_ENTITY : NUM2INT(type)),
458
- (xmlChar *)(NIL_P(external_id) ? NULL : StringValueCStr(external_id)),
459
- (xmlChar *)(NIL_P(system_id) ? NULL : StringValueCStr(system_id)),
460
- (xmlChar *)(NIL_P(content) ? NULL : StringValueCStr(content))
461
- );
462
-
463
- if(NULL == ptr) {
481
+ doc,
482
+ (xmlChar *)(NIL_P(name) ? NULL : StringValueCStr(name)),
483
+ (int)(NIL_P(type) ? XML_INTERNAL_GENERAL_ENTITY : NUM2INT(type)),
484
+ (xmlChar *)(NIL_P(external_id) ? NULL : StringValueCStr(external_id)),
485
+ (xmlChar *)(NIL_P(system_id) ? NULL : StringValueCStr(system_id)),
486
+ (xmlChar *)(NIL_P(content) ? NULL : StringValueCStr(content))
487
+ );
488
+
489
+ if (NULL == ptr) {
464
490
  xmlErrorPtr error = xmlGetLastError();
465
- if(error)
491
+ if (error) {
466
492
  rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
467
- else
493
+ } else {
468
494
  rb_raise(rb_eRuntimeError, "Could not create entity");
495
+ }
469
496
 
470
497
  return Qnil;
471
498
  }
472
499
 
473
- return Nokogiri_wrap_xml_node(cNokogiriXmlEntityDecl, (xmlNodePtr)ptr);
500
+ return noko_xml_node_wrap(cNokogiriXmlEntityDecl, (xmlNodePtr)ptr);
474
501
  }
475
502
 
476
- static int block_caller(void * ctx, xmlNodePtr _node, xmlNodePtr _parent)
503
+ static int
504
+ block_caller(void *ctx, xmlNodePtr c_node, xmlNodePtr c_parent_node)
477
505
  {
478
- VALUE block;
479
- VALUE node;
480
- VALUE parent;
506
+ VALUE block = (VALUE)ctx;
507
+ VALUE rb_node;
508
+ VALUE rb_parent_node;
481
509
  VALUE ret;
482
510
 
483
- if(_node->type == XML_NAMESPACE_DECL){
484
- node = Nokogiri_wrap_xml_namespace(_parent->doc, (xmlNsPtr) _node);
511
+ if (c_node->type == XML_NAMESPACE_DECL) {
512
+ rb_node = noko_xml_namespace_wrap((xmlNsPtr)c_node, c_parent_node->doc);
513
+ } else {
514
+ rb_node = noko_xml_node_wrap(Qnil, c_node);
485
515
  }
486
- else{
487
- node = Nokogiri_wrap_xml_node(Qnil, _node);
488
- }
489
- parent = _parent ? Nokogiri_wrap_xml_node(Qnil, _parent) : Qnil;
490
- block = (VALUE)ctx;
491
-
492
- ret = rb_funcall(block, rb_intern("call"), 2, node, parent);
516
+ rb_parent_node = c_parent_node ? noko_xml_node_wrap(Qnil, c_parent_node) : Qnil;
493
517
 
494
- if(Qfalse == ret || Qnil == ret) return 0;
518
+ ret = rb_funcall(block, rb_intern("call"), 2, rb_node, rb_parent_node);
495
519
 
496
- return 1;
520
+ return (Qfalse == ret || Qnil == ret) ? 0 : 1;
497
521
  }
498
522
 
499
523
  /* call-seq:
@@ -506,7 +530,8 @@ static int block_caller(void * ctx, xmlNodePtr _node, xmlNodePtr _parent)
506
530
  * The block must return a non-nil, non-false value if the +obj+ passed in
507
531
  * should be included in the canonicalized document.
508
532
  */
509
- static VALUE nokogiri_xml_document_canonicalize(int argc, VALUE* argv, VALUE self)
533
+ static VALUE
534
+ rb_xml_document_canonicalize(int argc, VALUE *argv, VALUE self)
510
535
  {
511
536
  VALUE mode;
512
537
  VALUE incl_ns;
@@ -517,7 +542,7 @@ static VALUE nokogiri_xml_document_canonicalize(int argc, VALUE* argv, VALUE sel
517
542
  xmlDocPtr doc;
518
543
  xmlOutputBufferPtr buf;
519
544
  xmlC14NIsVisibleCallback cb = NULL;
520
- void * ctx = NULL;
545
+ void *ctx = NULL;
521
546
 
522
547
  VALUE rb_cStringIO;
523
548
  VALUE io;
@@ -530,93 +555,126 @@ static VALUE nokogiri_xml_document_canonicalize(int argc, VALUE* argv, VALUE sel
530
555
  io = rb_class_new_instance(0, 0, rb_cStringIO);
531
556
  buf = xmlAllocOutputBuffer(NULL);
532
557
 
533
- buf->writecallback = (xmlOutputWriteCallback)io_write_callback;
534
- buf->closecallback = (xmlOutputCloseCallback)io_close_callback;
558
+ buf->writecallback = (xmlOutputWriteCallback)noko_io_write;
559
+ buf->closecallback = (xmlOutputCloseCallback)noko_io_close;
535
560
  buf->context = (void *)io;
536
561
 
537
- if(rb_block_given_p()) {
562
+ if (rb_block_given_p()) {
538
563
  cb = block_caller;
539
564
  ctx = (void *)rb_block_proc();
540
565
  }
541
566
 
542
- if(NIL_P(incl_ns)){
567
+ if (NIL_P(incl_ns)) {
543
568
  ns = NULL;
544
- }
545
- else{
569
+ } else {
546
570
  Check_Type(incl_ns, T_ARRAY);
547
571
  ns_len = RARRAY_LEN(incl_ns);
548
- ns = calloc((size_t)ns_len+1, sizeof(xmlChar *));
572
+ ns = calloc((size_t)ns_len + 1, sizeof(xmlChar *));
549
573
  for (i = 0 ; i < ns_len ; i++) {
550
574
  VALUE entry = rb_ary_entry(incl_ns, i);
551
- ns[i] = (xmlChar*)StringValueCStr(entry);
575
+ ns[i] = (xmlChar *)StringValueCStr(entry);
552
576
  }
553
577
  }
554
578
 
555
579
 
556
580
  xmlC14NExecute(doc, cb, ctx,
557
- (int) (NIL_P(mode) ? 0 : NUM2INT(mode)),
558
- ns,
559
- (int) RTEST(with_comments),
560
- buf);
581
+ (int)(NIL_P(mode) ? 0 : NUM2INT(mode)),
582
+ ns,
583
+ (int) RTEST(with_comments),
584
+ buf);
561
585
 
562
586
  xmlOutputBufferClose(buf);
563
587
 
564
588
  return rb_funcall(io, rb_intern("string"), 0);
565
589
  }
566
590
 
567
- VALUE cNokogiriXmlDocument ;
568
- void init_xml_document()
591
+ VALUE
592
+ noko_xml_document_wrap_with_init_args(VALUE klass, xmlDocPtr c_document, int argc, VALUE *argv)
569
593
  {
570
- VALUE nokogiri = rb_define_module("Nokogiri");
571
- VALUE xml = rb_define_module_under(nokogiri, "XML");
572
- VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
594
+ VALUE rb_document;
595
+ nokogiriTuplePtr tuple;
573
596
 
574
- /*
575
- * Nokogiri::XML::Document wraps an xml document.
576
- */
577
- VALUE klass = rb_define_class_under(xml, "Document", node);
578
-
579
- cNokogiriXmlDocument = klass;
580
-
581
- rb_define_singleton_method(klass, "read_memory", read_memory, 4);
582
- rb_define_singleton_method(klass, "read_io", read_io, 4);
583
- rb_define_singleton_method(klass, "new", new, -1);
584
-
585
- rb_define_method(klass, "root", root, 0);
586
- rb_define_method(klass, "root=", set_root, 1);
587
- rb_define_method(klass, "encoding", encoding, 0);
588
- rb_define_method(klass, "encoding=", set_encoding, 1);
589
- rb_define_method(klass, "version", version, 0);
590
- rb_define_method(klass, "canonicalize", nokogiri_xml_document_canonicalize, -1);
591
- rb_define_method(klass, "dup", duplicate_document, -1);
592
- rb_define_method(klass, "url", url, 0);
593
- rb_define_method(klass, "create_entity", create_entity, -1);
594
- rb_define_method(klass, "remove_namespaces!", remove_namespaces_bang, 0);
597
+ if (!klass) {
598
+ klass = cNokogiriXmlDocument;
599
+ }
600
+
601
+ rb_document = Data_Wrap_Struct(klass, mark, dealloc, c_document);
602
+
603
+ tuple = (nokogiriTuplePtr)malloc(sizeof(nokogiriTuple));
604
+ tuple->doc = rb_document;
605
+ tuple->unlinkedNodes = st_init_numtable_with_size(128);
606
+ tuple->node_cache = rb_ary_new();
607
+
608
+ c_document->_private = tuple ;
609
+
610
+ rb_iv_set(rb_document, "@decorators", Qnil);
611
+ rb_iv_set(rb_document, "@errors", Qnil);
612
+ rb_iv_set(rb_document, "@node_cache", tuple->node_cache);
613
+
614
+ rb_obj_call_init(rb_document, argc, argv);
615
+
616
+ return rb_document ;
595
617
  }
596
618
 
597
619
 
598
- /* this takes klass as a param because it's used for HtmlDocument, too. */
599
- VALUE Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc)
620
+ /* deprecated. use noko_xml_document_wrap() instead. */
621
+ VALUE
622
+ Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc)
600
623
  {
601
- nokogiriTuplePtr tuple = (nokogiriTuplePtr)malloc(sizeof(nokogiriTuple));
624
+ /* TODO: deprecate this method in v2.0 */
625
+ return noko_xml_document_wrap_with_init_args(klass, doc, 0, NULL);
626
+ }
602
627
 
603
- VALUE rb_doc = Data_Wrap_Struct(
604
- klass ? klass : cNokogiriXmlDocument,
605
- mark,
606
- dealloc,
607
- doc
608
- );
628
+ VALUE
629
+ noko_xml_document_wrap(VALUE klass, xmlDocPtr doc)
630
+ {
631
+ return noko_xml_document_wrap_with_init_args(klass, doc, 0, NULL);
632
+ }
609
633
 
610
- VALUE cache = rb_ary_new();
611
- rb_iv_set(rb_doc, "@decorators", Qnil);
612
- rb_iv_set(rb_doc, "@node_cache", cache);
613
634
 
614
- tuple->doc = rb_doc;
615
- tuple->unlinkedNodes = st_init_numtable_with_size(128);
616
- tuple->node_cache = cache;
617
- doc->_private = tuple ;
635
+ void
636
+ noko_xml_document_pin_node(xmlNodePtr node)
637
+ {
638
+ xmlDocPtr doc;
639
+ nokogiriTuplePtr tuple;
618
640
 
619
- rb_obj_call_init(rb_doc, 0, NULL);
641
+ doc = node->doc;
642
+ tuple = (nokogiriTuplePtr)doc->_private;
643
+ st_insert(tuple->unlinkedNodes, (st_data_t)node, (st_data_t)node);
644
+ }
620
645
 
621
- return rb_doc ;
646
+
647
+ void
648
+ noko_xml_document_pin_namespace(xmlNsPtr ns, xmlDocPtr doc)
649
+ {
650
+ nokogiriTuplePtr tuple;
651
+
652
+ tuple = (nokogiriTuplePtr)doc->_private;
653
+ st_insert(tuple->unlinkedNodes, (st_data_t)ns, (st_data_t)ns);
654
+ }
655
+
656
+
657
+ void
658
+ noko_init_xml_document()
659
+ {
660
+ assert(cNokogiriXmlNode);
661
+ /*
662
+ * Nokogiri::XML::Document wraps an xml document.
663
+ */
664
+ cNokogiriXmlDocument = rb_define_class_under(mNokogiriXml, "Document", cNokogiriXmlNode);
665
+
666
+ rb_define_singleton_method(cNokogiriXmlDocument, "read_memory", read_memory, 4);
667
+ rb_define_singleton_method(cNokogiriXmlDocument, "read_io", read_io, 4);
668
+ rb_define_singleton_method(cNokogiriXmlDocument, "new", new, -1);
669
+
670
+ rb_define_method(cNokogiriXmlDocument, "root", rb_xml_document_root, 0);
671
+ rb_define_method(cNokogiriXmlDocument, "root=", rb_xml_document_root_set, 1);
672
+ rb_define_method(cNokogiriXmlDocument, "encoding", encoding, 0);
673
+ rb_define_method(cNokogiriXmlDocument, "encoding=", set_encoding, 1);
674
+ rb_define_method(cNokogiriXmlDocument, "version", version, 0);
675
+ rb_define_method(cNokogiriXmlDocument, "canonicalize", rb_xml_document_canonicalize, -1);
676
+ rb_define_method(cNokogiriXmlDocument, "dup", duplicate_document, -1);
677
+ rb_define_method(cNokogiriXmlDocument, "url", url, 0);
678
+ rb_define_method(cNokogiriXmlDocument, "create_entity", create_entity, -1);
679
+ rb_define_method(cNokogiriXmlDocument, "remove_namespaces!", remove_namespaces_bang, 0);
622
680
  }