nokogiri 1.15.3 → 1.18.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +12 -17
  3. data/LICENSE-DEPENDENCIES.md +6 -6
  4. data/README.md +11 -5
  5. data/dependencies.yml +9 -8
  6. data/ext/nokogiri/extconf.rb +191 -154
  7. data/ext/nokogiri/gumbo.c +69 -53
  8. data/ext/nokogiri/html4_document.c +10 -4
  9. data/ext/nokogiri/html4_element_description.c +18 -18
  10. data/ext/nokogiri/html4_sax_parser.c +40 -0
  11. data/ext/nokogiri/html4_sax_parser_context.c +48 -58
  12. data/ext/nokogiri/html4_sax_push_parser.c +26 -25
  13. data/ext/nokogiri/libxml2_polyfill.c +114 -0
  14. data/ext/nokogiri/nokogiri.c +9 -2
  15. data/ext/nokogiri/nokogiri.h +25 -33
  16. data/ext/nokogiri/test_global_handlers.c +1 -1
  17. data/ext/nokogiri/xml_attr.c +1 -1
  18. data/ext/nokogiri/xml_cdata.c +3 -12
  19. data/ext/nokogiri/xml_comment.c +3 -8
  20. data/ext/nokogiri/xml_document.c +173 -158
  21. data/ext/nokogiri/xml_document_fragment.c +10 -25
  22. data/ext/nokogiri/xml_dtd.c +1 -1
  23. data/ext/nokogiri/xml_element_content.c +9 -9
  24. data/ext/nokogiri/xml_encoding_handler.c +4 -4
  25. data/ext/nokogiri/xml_namespace.c +6 -10
  26. data/ext/nokogiri/xml_node.c +142 -108
  27. data/ext/nokogiri/xml_node_set.c +46 -44
  28. data/ext/nokogiri/xml_reader.c +74 -100
  29. data/ext/nokogiri/xml_relax_ng.c +35 -56
  30. data/ext/nokogiri/xml_sax_parser.c +156 -88
  31. data/ext/nokogiri/xml_sax_parser_context.c +220 -128
  32. data/ext/nokogiri/xml_sax_push_parser.c +69 -50
  33. data/ext/nokogiri/xml_schema.c +51 -87
  34. data/ext/nokogiri/xml_syntax_error.c +19 -11
  35. data/ext/nokogiri/xml_text.c +3 -6
  36. data/ext/nokogiri/xml_xpath_context.c +104 -104
  37. data/ext/nokogiri/xslt_stylesheet.c +16 -11
  38. data/gumbo-parser/Makefile +18 -0
  39. data/gumbo-parser/src/ascii.c +2 -2
  40. data/gumbo-parser/src/error.c +76 -48
  41. data/gumbo-parser/src/error.h +5 -1
  42. data/gumbo-parser/src/nokogiri_gumbo.h +11 -2
  43. data/gumbo-parser/src/parser.c +66 -25
  44. data/gumbo-parser/src/tokenizer.c +7 -6
  45. data/lib/nokogiri/class_resolver.rb +1 -1
  46. data/lib/nokogiri/css/node.rb +6 -2
  47. data/lib/nokogiri/css/parser.rb +6 -4
  48. data/lib/nokogiri/css/parser.y +2 -2
  49. data/lib/nokogiri/css/parser_extras.rb +6 -66
  50. data/lib/nokogiri/css/selector_cache.rb +38 -0
  51. data/lib/nokogiri/css/tokenizer.rb +4 -4
  52. data/lib/nokogiri/css/tokenizer.rex +9 -8
  53. data/lib/nokogiri/css/xpath_visitor.rb +44 -27
  54. data/lib/nokogiri/css.rb +86 -20
  55. data/lib/nokogiri/decorators/slop.rb +3 -5
  56. data/lib/nokogiri/encoding_handler.rb +2 -2
  57. data/lib/nokogiri/html4/document.rb +45 -24
  58. data/lib/nokogiri/html4/document_fragment.rb +124 -12
  59. data/lib/nokogiri/html4/encoding_reader.rb +2 -2
  60. data/lib/nokogiri/html4/sax/parser.rb +23 -38
  61. data/lib/nokogiri/html4/sax/parser_context.rb +4 -9
  62. data/lib/nokogiri/html4.rb +9 -14
  63. data/lib/nokogiri/html5/builder.rb +40 -0
  64. data/lib/nokogiri/html5/document.rb +61 -30
  65. data/lib/nokogiri/html5/document_fragment.rb +130 -20
  66. data/lib/nokogiri/html5/node.rb +4 -4
  67. data/lib/nokogiri/html5.rb +114 -138
  68. data/lib/nokogiri/version/constant.rb +1 -1
  69. data/lib/nokogiri/version/info.rb +6 -5
  70. data/lib/nokogiri/xml/attr.rb +2 -2
  71. data/lib/nokogiri/xml/builder.rb +8 -1
  72. data/lib/nokogiri/xml/document.rb +74 -31
  73. data/lib/nokogiri/xml/document_fragment.rb +86 -15
  74. data/lib/nokogiri/xml/namespace.rb +1 -2
  75. data/lib/nokogiri/xml/node.rb +113 -35
  76. data/lib/nokogiri/xml/node_set.rb +12 -10
  77. data/lib/nokogiri/xml/parse_options.rb +1 -1
  78. data/lib/nokogiri/xml/pp/node.rb +6 -1
  79. data/lib/nokogiri/xml/reader.rb +51 -17
  80. data/lib/nokogiri/xml/relax_ng.rb +57 -20
  81. data/lib/nokogiri/xml/sax/document.rb +174 -83
  82. data/lib/nokogiri/xml/sax/parser.rb +115 -41
  83. data/lib/nokogiri/xml/sax/parser_context.rb +116 -8
  84. data/lib/nokogiri/xml/sax/push_parser.rb +3 -0
  85. data/lib/nokogiri/xml/sax.rb +48 -0
  86. data/lib/nokogiri/xml/schema.rb +112 -45
  87. data/lib/nokogiri/xml/searchable.rb +39 -43
  88. data/lib/nokogiri/xml/syntax_error.rb +23 -1
  89. data/lib/nokogiri/xml/xpath_context.rb +14 -3
  90. data/lib/nokogiri/xml.rb +14 -25
  91. data/lib/nokogiri/xslt/stylesheet.rb +29 -7
  92. data/lib/nokogiri/xslt.rb +4 -10
  93. data/lib/nokogiri.rb +1 -1
  94. data/lib/xsd/xmlparser/nokogiri.rb +3 -4
  95. data/patches/libxml2/0019-xpath-Use-separate-static-hash-table-for-standard-fu.patch +244 -0
  96. data/ports/archives/libxml2-2.13.7.tar.xz +0 -0
  97. data/ports/archives/libxslt-1.1.43.tar.xz +0 -0
  98. metadata +13 -14
  99. data/ext/nokogiri/libxml2_backwards_compat.c +0 -121
  100. data/patches/libxml2/0003-libxml2.la-is-in-top_builddir.patch +0 -25
  101. data/ports/archives/libxml2-2.11.4.tar.xz +0 -0
  102. data/ports/archives/libxslt-1.1.38.tar.xz +0 -0
@@ -17,6 +17,8 @@ dealloc_node_i2(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
17
17
  break;
18
18
  default:
19
19
  if (node->parent == NULL) {
20
+ node->next = NULL;
21
+ node->prev = NULL;
20
22
  xmlAddChild((xmlNodePtr)doc, node);
21
23
  }
22
24
  }
@@ -74,8 +76,10 @@ dealloc(void *data)
74
76
 
75
77
  ruby_xfree(doc->_private);
76
78
 
79
+ #if defined(__GNUC__) && __GNUC__ >= 5
77
80
  #pragma GCC diagnostic push
78
81
  #pragma GCC diagnostic ignored "-Wdeprecated-declarations" // xmlDeregisterNodeDefault is deprecated as of libxml2 2.11.0
82
+ #endif
79
83
  /*
80
84
  * libxml-ruby < 3.0.0 uses xmlDeregisterNodeDefault. If the user is using one of those older
81
85
  * versions, the registered callback from libxml-ruby will access the _private pointers set by
@@ -90,7 +94,9 @@ dealloc(void *data)
90
94
  if (xmlDeregisterNodeDefaultValue) {
91
95
  remove_private((xmlNodePtr)doc);
92
96
  }
97
+ #if defined(__GNUC__) && __GNUC__ >= 5
93
98
  #pragma GCC diagnostic pop
99
+ #endif
94
100
 
95
101
  xmlFreeDoc(doc);
96
102
  }
@@ -100,14 +106,18 @@ memsize_node(const xmlNodePtr node)
100
106
  {
101
107
  /* note we don't count namespace definitions, just going for a good-enough number here */
102
108
  xmlNodePtr child;
109
+ xmlAttrPtr property;
103
110
  size_t memsize = 0;
104
111
 
105
- memsize += xmlStrlen(node->name);
106
- for (child = (xmlNodePtr)node->properties; child; child = child->next) {
107
- memsize += sizeof(xmlAttr) + memsize_node(child);
112
+ memsize += (size_t)xmlStrlen(node->name);
113
+
114
+ if (node->type == XML_ELEMENT_NODE) {
115
+ for (property = node->properties; property; property = property->next) {
116
+ memsize += sizeof(xmlAttr) + memsize_node((xmlNodePtr)property);
117
+ }
108
118
  }
109
119
  if (node->type == XML_TEXT_NODE) {
110
- memsize += xmlStrlen(node->content);
120
+ memsize += (size_t)xmlStrlen(node->content);
111
121
  }
112
122
  for (child = node->children; child; child = child->next) {
113
123
  memsize += sizeof(xmlNode) + memsize_node(child);
@@ -125,8 +135,8 @@ memsize(const void *data)
125
135
  return memsize;
126
136
  }
127
137
 
128
- static const rb_data_type_t noko_xml_document_data_type = {
129
- .wrap_struct_name = "Nokogiri::XML::Document",
138
+ static const rb_data_type_t xml_doc_type = {
139
+ .wrap_struct_name = "xmlDoc",
130
140
  .function = {
131
141
  .dmark = mark,
132
142
  .dfree = dealloc,
@@ -135,6 +145,53 @@ static const rb_data_type_t noko_xml_document_data_type = {
135
145
  // .flags = RUBY_TYPED_FREE_IMMEDIATELY, // TODO see https://github.com/sparklemotion/nokogiri/issues/2822
136
146
  };
137
147
 
148
+ static VALUE
149
+ _xml_document_alloc(VALUE klass)
150
+ {
151
+ return TypedData_Wrap_Struct(klass, &xml_doc_type, NULL);
152
+ }
153
+
154
+ static void
155
+ _xml_document_data_ptr_set(VALUE rb_document, xmlDocPtr c_document)
156
+ {
157
+ nokogiriTuplePtr tuple;
158
+
159
+ assert(DATA_PTR(rb_document) == NULL);
160
+ assert(c_document->_private == NULL);
161
+
162
+ DATA_PTR(rb_document) = c_document;
163
+
164
+ tuple = (nokogiriTuplePtr)ruby_xmalloc(sizeof(nokogiriTuple));
165
+ tuple->doc = rb_document;
166
+ tuple->unlinkedNodes = st_init_numtable_with_size(128);
167
+ tuple->node_cache = rb_ary_new();
168
+
169
+ c_document->_private = tuple ;
170
+
171
+ rb_iv_set(rb_document, "@node_cache", tuple->node_cache);
172
+
173
+ return;
174
+ }
175
+
176
+ /* :nodoc: */
177
+ static VALUE
178
+ rb_xml_document_initialize_copy_with_args(VALUE rb_self, VALUE rb_other, VALUE rb_level)
179
+ {
180
+ xmlDocPtr c_other, c_self;
181
+ int c_level;
182
+
183
+ c_other = noko_xml_document_unwrap(rb_other);
184
+ c_level = (int)NUM2INT(rb_level);
185
+
186
+ c_self = xmlCopyDoc(c_other, c_level);
187
+ if (c_self == NULL) { return Qnil; }
188
+
189
+ c_self->type = c_other->type;
190
+ _xml_document_data_ptr_set(rb_self, c_self);
191
+
192
+ return rb_self ;
193
+ }
194
+
138
195
  static void
139
196
  recursively_remove_namespaces_from_node(xmlNodePtr node)
140
197
  {
@@ -307,49 +364,46 @@ version(VALUE self)
307
364
  * Create a new document from an IO object
308
365
  */
309
366
  static VALUE
310
- read_io(VALUE klass,
311
- VALUE io,
312
- VALUE url,
313
- VALUE encoding,
314
- VALUE options)
315
- {
316
- const char *c_url = NIL_P(url) ? NULL : StringValueCStr(url);
317
- const char *c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
318
- VALUE error_list = rb_ary_new();
319
- VALUE document;
320
- xmlDocPtr doc;
321
-
322
- xmlResetLastError();
323
- xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
324
-
325
- doc = xmlReadIO(
326
- (xmlInputReadCallback)noko_io_read,
327
- (xmlInputCloseCallback)noko_io_close,
328
- (void *)io,
329
- c_url,
330
- c_enc,
331
- (int)NUM2INT(options)
332
- );
333
- xmlSetStructuredErrorFunc(NULL, NULL);
334
-
335
- if (doc == NULL) {
336
- xmlErrorPtr error;
337
-
338
- xmlFreeDoc(doc);
339
-
340
- error = xmlGetLastError();
341
- if (error) {
342
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
367
+ noko_xml_document_s_read_io(VALUE rb_class,
368
+ VALUE rb_io,
369
+ VALUE rb_url,
370
+ VALUE rb_encoding,
371
+ VALUE rb_options)
372
+ {
373
+ /* TODO: deprecate this method, parse should be the preferred entry point. then we can make this
374
+ private. */
375
+ libxmlStructuredErrorHandlerState handler_state;
376
+ VALUE rb_errors = rb_ary_new();
377
+
378
+ noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher);
379
+
380
+ const char *c_url = NIL_P(rb_url) ? NULL : StringValueCStr(rb_url);
381
+ const char *c_enc = NIL_P(rb_encoding) ? NULL : StringValueCStr(rb_encoding);
382
+ xmlDocPtr c_document = xmlReadIO(
383
+ (xmlInputReadCallback)noko_io_read,
384
+ (xmlInputCloseCallback)noko_io_close,
385
+ (void *)rb_io,
386
+ c_url,
387
+ c_enc,
388
+ (int)NUM2INT(rb_options)
389
+ );
390
+
391
+ noko__structured_error_func_restore(&handler_state);
392
+
393
+ if (c_document == NULL) {
394
+ xmlFreeDoc(c_document);
395
+
396
+ VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors);
397
+ if (RB_TEST(exception)) {
398
+ rb_exc_raise(exception);
343
399
  } else {
344
400
  rb_raise(rb_eRuntimeError, "Could not parse document");
345
401
  }
346
-
347
- return Qnil;
348
402
  }
349
403
 
350
- document = noko_xml_document_wrap(klass, doc);
351
- rb_iv_set(document, "@errors", error_list);
352
- return document;
404
+ VALUE rb_document = noko_xml_document_wrap(rb_class, c_document);
405
+ rb_iv_set(rb_document, "@errors", rb_errors);
406
+ return rb_document;
353
407
  }
354
408
 
355
409
  /*
@@ -359,80 +413,44 @@ read_io(VALUE klass,
359
413
  * Create a new document from a String
360
414
  */
361
415
  static VALUE
362
- read_memory(VALUE klass,
363
- VALUE string,
364
- VALUE url,
365
- VALUE encoding,
366
- VALUE options)
367
- {
368
- const char *c_buffer = StringValuePtr(string);
369
- const char *c_url = NIL_P(url) ? NULL : StringValueCStr(url);
370
- const char *c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
371
- int len = (int)RSTRING_LEN(string);
372
- VALUE error_list = rb_ary_new();
373
- VALUE document;
374
- xmlDocPtr doc;
375
-
376
- xmlResetLastError();
377
- xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
378
- doc = xmlReadMemory(c_buffer, len, c_url, c_enc, (int)NUM2INT(options));
379
- xmlSetStructuredErrorFunc(NULL, NULL);
416
+ noko_xml_document_s_read_memory(VALUE rb_class,
417
+ VALUE rb_input,
418
+ VALUE rb_url,
419
+ VALUE rb_encoding,
420
+ VALUE rb_options)
421
+ {
422
+ /* TODO: deprecate this method, parse should be the preferred entry point. then we can make this
423
+ private. */
424
+ VALUE rb_errors = rb_ary_new();
425
+ xmlSetStructuredErrorFunc((void *)rb_errors, noko__error_array_pusher);
380
426
 
381
- if (doc == NULL) {
382
- xmlErrorPtr error;
427
+ const char *c_buffer = StringValuePtr(rb_input);
428
+ const char *c_url = NIL_P(rb_url) ? NULL : StringValueCStr(rb_url);
429
+ const char *c_enc = NIL_P(rb_encoding) ? NULL : StringValueCStr(rb_encoding);
430
+ int c_buffer_len = (int)RSTRING_LEN(rb_input);
431
+ xmlDocPtr c_document = xmlReadMemory(c_buffer, c_buffer_len, c_url, c_enc, (int)NUM2INT(rb_options));
383
432
 
384
- xmlFreeDoc(doc);
433
+ xmlSetStructuredErrorFunc(NULL, NULL);
385
434
 
386
- error = xmlGetLastError();
387
- if (error) {
388
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
435
+ if (c_document == NULL) {
436
+ VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors);
437
+ if (RB_TEST(exception)) {
438
+ rb_exc_raise(exception);
389
439
  } else {
390
440
  rb_raise(rb_eRuntimeError, "Could not parse document");
391
441
  }
392
-
393
- return Qnil;
394
442
  }
395
443
 
396
- document = noko_xml_document_wrap(klass, doc);
397
- rb_iv_set(document, "@errors", error_list);
444
+ VALUE document = noko_xml_document_wrap(rb_class, c_document);
445
+ rb_iv_set(document, "@errors", rb_errors);
398
446
  return document;
399
447
  }
400
448
 
401
449
  /*
402
450
  * call-seq:
403
- * dup
404
- *
405
- * Copy this Document. An optional depth may be passed in, but it defaults
406
- * to a deep copy. 0 is a shallow copy, 1 is a deep copy.
407
- */
408
- static VALUE
409
- duplicate_document(int argc, VALUE *argv, VALUE self)
410
- {
411
- xmlDocPtr doc, dup;
412
- VALUE copy;
413
- VALUE level;
414
-
415
- if (rb_scan_args(argc, argv, "01", &level) == 0) {
416
- level = INT2NUM((long)1);
417
- }
418
-
419
- doc = noko_xml_document_unwrap(self);
420
-
421
- dup = xmlCopyDoc(doc, (int)NUM2INT(level));
422
-
423
- if (dup == NULL) { return Qnil; }
424
-
425
- dup->type = doc->type;
426
- copy = noko_xml_document_wrap(rb_obj_class(self), dup);
427
- rb_iv_set(copy, "@errors", rb_iv_get(self, "@errors"));
428
- return copy ;
429
- }
430
-
431
- /*
432
- * call-seq:
433
- * new(version = default)
451
+ * new(version = "1.0")
434
452
  *
435
- * Create a new document with +version+ (defaults to "1.0")
453
+ * Create a new empty document declaring XML version +version+.
436
454
  */
437
455
  static VALUE
438
456
  new (int argc, VALUE *argv, VALUE klass)
@@ -495,55 +513,58 @@ remove_namespaces_bang(VALUE self)
495
513
  return self;
496
514
  }
497
515
 
498
- /* call-seq: doc.create_entity(name, type, external_id, system_id, content)
516
+ /* call-seq:
517
+ * doc.create_entity(name, type, external_id, system_id, content)
499
518
  *
500
519
  * Create a new entity named +name+.
501
520
  *
502
- * +type+ is an integer representing the type of entity to be created, and it
503
- * defaults to Nokogiri::XML::EntityDecl::INTERNAL_GENERAL. See
504
- * the constants on Nokogiri::XML::EntityDecl for more information.
521
+ * +type+ is an integer representing the type of entity to be created, and it defaults to
522
+ * +Nokogiri::XML::EntityDecl::INTERNAL_GENERAL+. See the constants on Nokogiri::XML::EntityDecl for
523
+ * more information.
505
524
  *
506
525
  * +external_id+, +system_id+, and +content+ set the External ID, System ID,
507
526
  * and content respectively. All of these parameters are optional.
508
527
  */
509
528
  static VALUE
510
- create_entity(int argc, VALUE *argv, VALUE self)
511
- {
512
- VALUE name;
513
- VALUE type;
514
- VALUE external_id;
515
- VALUE system_id;
516
- VALUE content;
517
- xmlEntityPtr ptr;
518
- xmlDocPtr doc ;
519
-
520
- doc = noko_xml_document_unwrap(self);
521
-
522
- rb_scan_args(argc, argv, "14", &name, &type, &external_id, &system_id,
523
- &content);
524
-
525
- xmlResetLastError();
526
- ptr = xmlAddDocEntity(
527
- doc,
528
- (xmlChar *)(NIL_P(name) ? NULL : StringValueCStr(name)),
529
- (int)(NIL_P(type) ? XML_INTERNAL_GENERAL_ENTITY : NUM2INT(type)),
530
- (xmlChar *)(NIL_P(external_id) ? NULL : StringValueCStr(external_id)),
531
- (xmlChar *)(NIL_P(system_id) ? NULL : StringValueCStr(system_id)),
532
- (xmlChar *)(NIL_P(content) ? NULL : StringValueCStr(content))
533
- );
534
-
535
- if (NULL == ptr) {
536
- xmlErrorPtr error = xmlGetLastError();
537
- if (error) {
538
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
529
+ noko_xml_document__create_entity(int argc, VALUE *argv, VALUE rb_document)
530
+ {
531
+ VALUE rb_name;
532
+ VALUE rb_type;
533
+ VALUE rb_ext_id;
534
+ VALUE rb_sys_id;
535
+ VALUE rb_content;
536
+
537
+ rb_scan_args(argc, argv, "14",
538
+ &rb_name,
539
+ &rb_type, &rb_ext_id, &rb_sys_id, &rb_content);
540
+
541
+ xmlDocPtr c_document = noko_xml_document_unwrap(rb_document);
542
+
543
+ libxmlStructuredErrorHandlerState handler_state;
544
+ VALUE rb_errors = rb_ary_new();
545
+ noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher);
546
+
547
+ xmlEntityPtr c_entity = xmlAddDocEntity(
548
+ c_document,
549
+ (xmlChar *)(NIL_P(rb_name) ? NULL : StringValueCStr(rb_name)),
550
+ (int)(NIL_P(rb_type) ? XML_INTERNAL_GENERAL_ENTITY : NUM2INT(rb_type)),
551
+ (xmlChar *)(NIL_P(rb_ext_id) ? NULL : StringValueCStr(rb_ext_id)),
552
+ (xmlChar *)(NIL_P(rb_sys_id) ? NULL : StringValueCStr(rb_sys_id)),
553
+ (xmlChar *)(NIL_P(rb_content) ? NULL : StringValueCStr(rb_content))
554
+ );
555
+
556
+ noko__structured_error_func_restore(&handler_state);
557
+
558
+ if (NULL == c_entity) {
559
+ VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors);
560
+ if (RB_TEST(exception)) {
561
+ rb_exc_raise(exception);
539
562
  } else {
540
563
  rb_raise(rb_eRuntimeError, "Could not create entity");
541
564
  }
542
-
543
- return Qnil;
544
565
  }
545
566
 
546
- return noko_xml_node_wrap(cNokogiriXmlEntityDecl, (xmlNodePtr)ptr);
567
+ return noko_xml_node_wrap(cNokogiriXmlEntityDecl, (xmlNodePtr)c_entity);
547
568
  }
548
569
 
549
570
  static int
@@ -647,24 +668,16 @@ VALUE
647
668
  noko_xml_document_wrap_with_init_args(VALUE klass, xmlDocPtr c_document, int argc, VALUE *argv)
648
669
  {
649
670
  VALUE rb_document;
650
- nokogiriTuplePtr tuple;
651
671
 
652
672
  if (!klass) {
653
673
  klass = cNokogiriXmlDocument;
654
674
  }
655
675
 
656
- rb_document = TypedData_Wrap_Struct(klass, &noko_xml_document_data_type, c_document);
657
-
658
- tuple = (nokogiriTuplePtr)ruby_xmalloc(sizeof(nokogiriTuple));
659
- tuple->doc = rb_document;
660
- tuple->unlinkedNodes = st_init_numtable_with_size(128);
661
- tuple->node_cache = rb_ary_new();
662
-
663
- c_document->_private = tuple ;
676
+ rb_document = _xml_document_alloc(klass);
677
+ _xml_document_data_ptr_set(rb_document, c_document);
664
678
 
665
679
  rb_iv_set(rb_document, "@decorators", Qnil);
666
680
  rb_iv_set(rb_document, "@errors", Qnil);
667
- rb_iv_set(rb_document, "@node_cache", tuple->node_cache);
668
681
 
669
682
  rb_obj_call_init(rb_document, argc, argv);
670
683
 
@@ -690,7 +703,7 @@ xmlDocPtr
690
703
  noko_xml_document_unwrap(VALUE rb_document)
691
704
  {
692
705
  xmlDocPtr c_document;
693
- TypedData_Get_Struct(rb_document, xmlDoc, &noko_xml_document_data_type, c_document);
706
+ TypedData_Get_Struct(rb_document, xmlDoc, &xml_doc_type, c_document);
694
707
  return c_document;
695
708
  }
696
709
 
@@ -747,13 +760,13 @@ void
747
760
  noko_init_xml_document(void)
748
761
  {
749
762
  assert(cNokogiriXmlNode);
750
- /*
751
- * Nokogiri::XML::Document wraps an xml document.
752
- */
763
+
753
764
  cNokogiriXmlDocument = rb_define_class_under(mNokogiriXml, "Document", cNokogiriXmlNode);
754
765
 
755
- rb_define_singleton_method(cNokogiriXmlDocument, "read_memory", read_memory, 4);
756
- rb_define_singleton_method(cNokogiriXmlDocument, "read_io", read_io, 4);
766
+ rb_define_alloc_func(cNokogiriXmlDocument, _xml_document_alloc);
767
+
768
+ rb_define_singleton_method(cNokogiriXmlDocument, "read_memory", noko_xml_document_s_read_memory, 4);
769
+ rb_define_singleton_method(cNokogiriXmlDocument, "read_io", noko_xml_document_s_read_io, 4);
757
770
  rb_define_singleton_method(cNokogiriXmlDocument, "new", new, -1);
758
771
 
759
772
  rb_define_method(cNokogiriXmlDocument, "root", rb_xml_document_root, 0);
@@ -762,8 +775,10 @@ noko_init_xml_document(void)
762
775
  rb_define_method(cNokogiriXmlDocument, "encoding=", set_encoding, 1);
763
776
  rb_define_method(cNokogiriXmlDocument, "version", version, 0);
764
777
  rb_define_method(cNokogiriXmlDocument, "canonicalize", rb_xml_document_canonicalize, -1);
765
- rb_define_method(cNokogiriXmlDocument, "dup", duplicate_document, -1);
766
778
  rb_define_method(cNokogiriXmlDocument, "url", url, 0);
767
- rb_define_method(cNokogiriXmlDocument, "create_entity", create_entity, -1);
779
+ rb_define_method(cNokogiriXmlDocument, "create_entity", noko_xml_document__create_entity, -1);
768
780
  rb_define_method(cNokogiriXmlDocument, "remove_namespaces!", remove_namespaces_bang, 0);
781
+
782
+ rb_define_protected_method(cNokogiriXmlDocument, "initialize_copy_with_args", rb_xml_document_initialize_copy_with_args,
783
+ 2);
769
784
  }
@@ -2,31 +2,18 @@
2
2
 
3
3
  VALUE cNokogiriXmlDocumentFragment;
4
4
 
5
- /*
6
- * call-seq:
7
- * new(document)
8
- *
9
- * Create a new DocumentFragment element on the +document+
10
- */
5
+ /* :nodoc: */
11
6
  static VALUE
12
- new (int argc, VALUE *argv, VALUE klass)
7
+ noko_xml_document_fragment_s_native_new(VALUE klass, VALUE rb_doc)
13
8
  {
14
- xmlDocPtr xml_doc;
15
- xmlNodePtr node;
16
- VALUE document;
17
- VALUE rest;
9
+ xmlDocPtr c_doc;
10
+ xmlNodePtr c_node;
18
11
  VALUE rb_node;
19
12
 
20
- rb_scan_args(argc, argv, "1*", &document, &rest);
21
-
22
- xml_doc = noko_xml_document_unwrap(document);
23
-
24
- node = xmlNewDocFragment(xml_doc->doc);
25
-
26
- noko_xml_document_pin_node(node);
27
-
28
- rb_node = noko_xml_node_wrap(klass, node);
29
- rb_obj_call_init(rb_node, argc, argv);
13
+ c_doc = noko_xml_document_unwrap(rb_doc);
14
+ c_node = xmlNewDocFragment(c_doc->doc);
15
+ noko_xml_document_pin_node(c_node);
16
+ rb_node = noko_xml_node_wrap(klass, c_node);
30
17
 
31
18
  return rb_node;
32
19
  }
@@ -35,10 +22,8 @@ void
35
22
  noko_init_xml_document_fragment(void)
36
23
  {
37
24
  assert(cNokogiriXmlNode);
38
- /*
39
- * DocumentFragment represents a DocumentFragment node in an xml document.
40
- */
25
+
41
26
  cNokogiriXmlDocumentFragment = rb_define_class_under(mNokogiriXml, "DocumentFragment", cNokogiriXmlNode);
42
27
 
43
- rb_define_singleton_method(cNokogiriXmlDocumentFragment, "new", new, -1);
28
+ rb_define_singleton_method(cNokogiriXmlDocumentFragment, "native_new", noko_xml_document_fragment_s_native_new, 1);
44
29
  }
@@ -144,7 +144,7 @@ validate(VALUE self, VALUE document)
144
144
 
145
145
  ctxt = xmlNewValidCtxt();
146
146
 
147
- xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
147
+ xmlSetStructuredErrorFunc((void *)error_list, noko__error_array_pusher);
148
148
 
149
149
  xmlValidateDtd(ctxt, doc, dtd);
150
150
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  VALUE cNokogiriXmlElementContent;
4
4
 
5
- static const rb_data_type_t element_content_data_type = {
6
- .wrap_struct_name = "Nokogiri::XML::ElementContent",
5
+ static const rb_data_type_t xml_element_content_type = {
6
+ .wrap_struct_name = "xmlElementContent",
7
7
  .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
8
8
  };
9
9
 
@@ -17,7 +17,7 @@ static VALUE
17
17
  get_name(VALUE self)
18
18
  {
19
19
  xmlElementContentPtr elem;
20
- TypedData_Get_Struct(self, xmlElementContent, &element_content_data_type, elem);
20
+ TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem);
21
21
 
22
22
  if (!elem->name) { return Qnil; }
23
23
  return NOKOGIRI_STR_NEW2(elem->name);
@@ -33,7 +33,7 @@ static VALUE
33
33
  get_type(VALUE self)
34
34
  {
35
35
  xmlElementContentPtr elem;
36
- TypedData_Get_Struct(self, xmlElementContent, &element_content_data_type, elem);
36
+ TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem);
37
37
 
38
38
  return INT2NUM(elem->type);
39
39
  }
@@ -45,7 +45,7 @@ static VALUE
45
45
  get_c1(VALUE self)
46
46
  {
47
47
  xmlElementContentPtr elem;
48
- TypedData_Get_Struct(self, xmlElementContent, &element_content_data_type, elem);
48
+ TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem);
49
49
 
50
50
  if (!elem->c1) { return Qnil; }
51
51
  return noko_xml_element_content_wrap(rb_iv_get(self, "@document"), elem->c1);
@@ -58,7 +58,7 @@ static VALUE
58
58
  get_c2(VALUE self)
59
59
  {
60
60
  xmlElementContentPtr elem;
61
- TypedData_Get_Struct(self, xmlElementContent, &element_content_data_type, elem);
61
+ TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem);
62
62
 
63
63
  if (!elem->c2) { return Qnil; }
64
64
  return noko_xml_element_content_wrap(rb_iv_get(self, "@document"), elem->c2);
@@ -74,7 +74,7 @@ static VALUE
74
74
  get_occur(VALUE self)
75
75
  {
76
76
  xmlElementContentPtr elem;
77
- TypedData_Get_Struct(self, xmlElementContent, &element_content_data_type, elem);
77
+ TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem);
78
78
 
79
79
  return INT2NUM(elem->ocur);
80
80
  }
@@ -89,7 +89,7 @@ static VALUE
89
89
  get_prefix(VALUE self)
90
90
  {
91
91
  xmlElementContentPtr elem;
92
- TypedData_Get_Struct(self, xmlElementContent, &element_content_data_type, elem);
92
+ TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem);
93
93
 
94
94
  if (!elem->prefix) { return Qnil; }
95
95
 
@@ -104,7 +104,7 @@ noko_xml_element_content_wrap(VALUE rb_document, xmlElementContentPtr c_element_
104
104
  {
105
105
  VALUE elem = TypedData_Wrap_Struct(
106
106
  cNokogiriXmlElementContent,
107
- &element_content_data_type,
107
+ &xml_element_content_type,
108
108
  c_element_content
109
109
  );
110
110
 
@@ -10,8 +10,8 @@ xml_encoding_handler_dealloc(void *data)
10
10
  xmlCharEncCloseFunc(c_handler);
11
11
  }
12
12
 
13
- static const rb_data_type_t xml_encoding_handler_type = {
14
- .wrap_struct_name = "Nokogiri::EncodingHandler",
13
+ static const rb_data_type_t xml_char_encoding_handler_type = {
14
+ .wrap_struct_name = "xmlCharEncodingHandler",
15
15
  .function = {
16
16
  .dfree = xml_encoding_handler_dealloc,
17
17
  },
@@ -31,7 +31,7 @@ rb_xml_encoding_handler_s_get(VALUE klass, VALUE key)
31
31
 
32
32
  handler = xmlFindCharEncodingHandler(StringValueCStr(key));
33
33
  if (handler) {
34
- return TypedData_Wrap_Struct(klass, &xml_encoding_handler_type, handler);
34
+ return TypedData_Wrap_Struct(klass, &xml_char_encoding_handler_type, handler);
35
35
  }
36
36
 
37
37
  return Qnil;
@@ -90,7 +90,7 @@ rb_xml_encoding_handler_name(VALUE self)
90
90
  {
91
91
  xmlCharEncodingHandlerPtr handler;
92
92
 
93
- TypedData_Get_Struct(self, xmlCharEncodingHandler, &xml_encoding_handler_type, handler);
93
+ TypedData_Get_Struct(self, xmlCharEncodingHandler, &xml_char_encoding_handler_type, handler);
94
94
 
95
95
  return NOKOGIRI_STR_NEW2(handler->name);
96
96
  }
@@ -42,7 +42,6 @@ _xml_namespace_dealloc(void *ptr)
42
42
  xmlFree(ns);
43
43
  }
44
44
 
45
- #ifdef HAVE_RB_GC_LOCATION
46
45
  static void
47
46
  _xml_namespace_update_references(void *ptr)
48
47
  {
@@ -51,12 +50,9 @@ _xml_namespace_update_references(void *ptr)
51
50
  ns->_private = (void *)rb_gc_location((VALUE)ns->_private);
52
51
  }
53
52
  }
54
- #else
55
- # define _xml_namespace_update_references 0
56
- #endif
57
53
 
58
- static const rb_data_type_t nokogiri_xml_namespace_type_with_dealloc = {
59
- .wrap_struct_name = "Nokogiri::XML::Namespace#with_dealloc",
54
+ static const rb_data_type_t xml_ns_type_with_free = {
55
+ .wrap_struct_name = "xmlNs (with free)",
60
56
  .function = {
61
57
  .dfree = _xml_namespace_dealloc,
62
58
  .dcompact = _xml_namespace_update_references,
@@ -64,8 +60,8 @@ static const rb_data_type_t nokogiri_xml_namespace_type_with_dealloc = {
64
60
  .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
65
61
  };
66
62
 
67
- static const rb_data_type_t nokogiri_xml_namespace_type_without_dealloc = {
68
- .wrap_struct_name = "Nokogiri::XML::Namespace#without_dealloc",
63
+ static const rb_data_type_t xml_ns_type_without_free = {
64
+ .wrap_struct_name = "xmlNs (without free)",
69
65
  .function = {
70
66
  .dcompact = _xml_namespace_update_references,
71
67
  },
@@ -149,7 +145,7 @@ noko_xml_namespace_wrap(xmlNsPtr c_namespace, xmlDocPtr c_document)
149
145
 
150
146
  if (c_document) {
151
147
  rb_namespace = TypedData_Wrap_Struct(cNokogiriXmlNamespace,
152
- &nokogiri_xml_namespace_type_without_dealloc,
148
+ &xml_ns_type_without_free,
153
149
  c_namespace);
154
150
 
155
151
  if (DOC_RUBY_OBJECT_TEST(c_document)) {
@@ -158,7 +154,7 @@ noko_xml_namespace_wrap(xmlNsPtr c_namespace, xmlDocPtr c_document)
158
154
  }
159
155
  } else {
160
156
  rb_namespace = TypedData_Wrap_Struct(cNokogiriXmlNamespace,
161
- &nokogiri_xml_namespace_type_with_dealloc,
157
+ &xml_ns_type_with_free,
162
158
  c_namespace);
163
159
  }
164
160