nokogiri 1.11.4 → 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.

Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE-DEPENDENCIES.md +243 -22
  3. data/LICENSE.md +1 -1
  4. data/README.md +6 -5
  5. data/ext/nokogiri/depend +35 -34
  6. data/ext/nokogiri/extconf.rb +185 -103
  7. data/ext/nokogiri/gumbo.c +584 -0
  8. data/ext/nokogiri/{html_document.c → html4_document.c} +8 -8
  9. data/ext/nokogiri/{html_element_description.c → html4_element_description.c} +21 -19
  10. data/ext/nokogiri/{html_entity_lookup.c → html4_entity_lookup.c} +7 -7
  11. data/ext/nokogiri/{html_sax_parser_context.c → html4_sax_parser_context.c} +6 -5
  12. data/ext/nokogiri/{html_sax_push_parser.c → html4_sax_push_parser.c} +4 -4
  13. data/ext/nokogiri/libxml2_backwards_compat.c +30 -30
  14. data/ext/nokogiri/nokogiri.c +70 -38
  15. data/ext/nokogiri/nokogiri.h +19 -9
  16. data/ext/nokogiri/xml_document.c +14 -14
  17. data/ext/nokogiri/xml_element_content.c +2 -0
  18. data/ext/nokogiri/xml_encoding_handler.c +11 -6
  19. data/ext/nokogiri/xml_namespace.c +4 -2
  20. data/ext/nokogiri/xml_node.c +123 -108
  21. data/ext/nokogiri/xml_node_set.c +20 -20
  22. data/ext/nokogiri/xml_reader.c +2 -0
  23. data/ext/nokogiri/xml_sax_parser.c +6 -6
  24. data/ext/nokogiri/xml_sax_parser_context.c +2 -0
  25. data/ext/nokogiri/xml_schema.c +2 -0
  26. data/ext/nokogiri/xml_xpath_context.c +67 -65
  27. data/ext/nokogiri/xslt_stylesheet.c +2 -1
  28. data/gumbo-parser/CHANGES.md +63 -0
  29. data/gumbo-parser/Makefile +101 -0
  30. data/gumbo-parser/THANKS +27 -0
  31. data/gumbo-parser/src/Makefile +34 -0
  32. data/gumbo-parser/src/README.md +41 -0
  33. data/gumbo-parser/src/ascii.c +75 -0
  34. data/gumbo-parser/src/ascii.h +115 -0
  35. data/gumbo-parser/src/attribute.c +42 -0
  36. data/gumbo-parser/src/attribute.h +17 -0
  37. data/gumbo-parser/src/char_ref.c +22225 -0
  38. data/gumbo-parser/src/char_ref.h +29 -0
  39. data/gumbo-parser/src/char_ref.rl +2154 -0
  40. data/gumbo-parser/src/error.c +626 -0
  41. data/gumbo-parser/src/error.h +148 -0
  42. data/gumbo-parser/src/foreign_attrs.c +104 -0
  43. data/gumbo-parser/src/foreign_attrs.gperf +27 -0
  44. data/gumbo-parser/src/gumbo.h +943 -0
  45. data/gumbo-parser/src/insertion_mode.h +33 -0
  46. data/gumbo-parser/src/macros.h +91 -0
  47. data/gumbo-parser/src/parser.c +4886 -0
  48. data/gumbo-parser/src/parser.h +41 -0
  49. data/gumbo-parser/src/replacement.h +33 -0
  50. data/gumbo-parser/src/string_buffer.c +103 -0
  51. data/gumbo-parser/src/string_buffer.h +68 -0
  52. data/gumbo-parser/src/string_piece.c +48 -0
  53. data/gumbo-parser/src/svg_attrs.c +174 -0
  54. data/gumbo-parser/src/svg_attrs.gperf +77 -0
  55. data/gumbo-parser/src/svg_tags.c +137 -0
  56. data/gumbo-parser/src/svg_tags.gperf +55 -0
  57. data/gumbo-parser/src/tag.c +222 -0
  58. data/gumbo-parser/src/tag_lookup.c +382 -0
  59. data/gumbo-parser/src/tag_lookup.gperf +169 -0
  60. data/gumbo-parser/src/tag_lookup.h +13 -0
  61. data/gumbo-parser/src/token_buffer.c +79 -0
  62. data/gumbo-parser/src/token_buffer.h +71 -0
  63. data/gumbo-parser/src/token_type.h +17 -0
  64. data/gumbo-parser/src/tokenizer.c +3463 -0
  65. data/gumbo-parser/src/tokenizer.h +112 -0
  66. data/gumbo-parser/src/tokenizer_states.h +339 -0
  67. data/gumbo-parser/src/utf8.c +245 -0
  68. data/gumbo-parser/src/utf8.h +164 -0
  69. data/gumbo-parser/src/util.c +68 -0
  70. data/gumbo-parser/src/util.h +30 -0
  71. data/gumbo-parser/src/vector.c +111 -0
  72. data/gumbo-parser/src/vector.h +45 -0
  73. data/lib/nokogiri/css/parser.rb +1 -1
  74. data/lib/nokogiri/css/parser.y +1 -1
  75. data/lib/nokogiri/css/syntax_error.rb +1 -1
  76. data/lib/nokogiri/css.rb +14 -14
  77. data/lib/nokogiri/extension.rb +7 -2
  78. data/lib/nokogiri/gumbo.rb +14 -0
  79. data/lib/nokogiri/html.rb +31 -27
  80. data/lib/nokogiri/{html → html4}/builder.rb +2 -2
  81. data/lib/nokogiri/{html → html4}/document.rb +4 -4
  82. data/lib/nokogiri/{html → html4}/document_fragment.rb +3 -3
  83. data/lib/nokogiri/{html → html4}/element_description.rb +1 -1
  84. data/lib/nokogiri/{html → html4}/element_description_defaults.rb +1 -1
  85. data/lib/nokogiri/{html → html4}/entity_lookup.rb +1 -1
  86. data/lib/nokogiri/{html → html4}/sax/parser.rb +11 -14
  87. data/lib/nokogiri/html4/sax/parser_context.rb +19 -0
  88. data/lib/nokogiri/{html → html4}/sax/push_parser.rb +5 -5
  89. data/lib/nokogiri/html4.rb +40 -0
  90. data/lib/nokogiri/html5/document.rb +74 -0
  91. data/lib/nokogiri/html5/document_fragment.rb +80 -0
  92. data/lib/nokogiri/html5/node.rb +93 -0
  93. data/lib/nokogiri/html5.rb +473 -0
  94. data/lib/nokogiri/version/constant.rb +1 -1
  95. data/lib/nokogiri/version/info.rb +12 -2
  96. data/lib/nokogiri/xml/builder.rb +38 -0
  97. data/lib/nokogiri/xml/document.rb +46 -0
  98. data/lib/nokogiri/xml/node/save_options.rb +1 -1
  99. data/lib/nokogiri/xml/node.rb +6 -5
  100. data/lib/nokogiri/xml/parse_options.rb +2 -0
  101. data/lib/nokogiri/xml/pp.rb +2 -2
  102. data/lib/nokogiri/xml/sax/document.rb +24 -30
  103. data/lib/nokogiri/xml/sax.rb +4 -4
  104. data/lib/nokogiri/xml/xpath.rb +2 -2
  105. data/lib/nokogiri/xml.rb +35 -36
  106. data/lib/nokogiri/xslt/stylesheet.rb +1 -1
  107. data/lib/nokogiri/xslt.rb +16 -16
  108. data/lib/nokogiri.rb +31 -29
  109. data/patches/libxml2/0007-Fix-XPath-recursion-limit.patch +31 -0
  110. metadata +101 -58
  111. data/lib/nokogiri/html/sax/parser_context.rb +0 -17
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
2
+ ENV["RC_ARCHS"] = "" if RUBY_PLATFORM =~ /darwin/
3
3
 
4
4
  require "mkmf"
5
5
  require "rbconfig"
@@ -8,13 +8,13 @@ require "shellwords"
8
8
  require "pathname"
9
9
 
10
10
  # helpful constants
11
- PACKAGE_ROOT_DIR = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
11
+ PACKAGE_ROOT_DIR = File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
12
12
  REQUIRED_LIBXML_VERSION = "2.6.21"
13
13
  RECOMMENDED_LIBXML_VERSION = "2.9.3"
14
14
 
15
15
  # The gem version constraint in the Rakefile is not respected at install time.
16
16
  # Keep this version in sync with the one in the Rakefile !
17
- REQUIRED_MINI_PORTILE_VERSION = "~> 2.5.0"
17
+ REQUIRED_MINI_PORTILE_VERSION = "~> 2.6.1"
18
18
  REQUIRED_PKG_CONFIG_VERSION = "~> 1.1"
19
19
 
20
20
  # Keep track of what versions of what libraries we build against
@@ -91,6 +91,9 @@ NOKOGIRI_HELP_MESSAGE = <<~HELP
91
91
  --with-xml2-include=DIRECTORY
92
92
  Look for xml2 headers in DIRECTORY.
93
93
 
94
+ --with-xml2-source-dir=DIRECTORY
95
+ (dev only) Build libxml2 from the source code in DIRECTORY
96
+
94
97
 
95
98
  Related to libxslt:
96
99
 
@@ -103,6 +106,9 @@ NOKOGIRI_HELP_MESSAGE = <<~HELP
103
106
  --with-xslt-include=DIRECTORY
104
107
  Look for xslt headers in DIRECTORY.
105
108
 
109
+ --with-xslt-source-dir=DIRECTORY
110
+ (dev only) Build libxslt from the source code in DIRECTORY
111
+
106
112
 
107
113
  Related to libexslt:
108
114
 
@@ -150,7 +156,7 @@ HELP
150
156
  # utility functions
151
157
  #
152
158
  def config_clean?
153
- enable_config('clean', true)
159
+ enable_config("clean", true)
154
160
  end
155
161
 
156
162
  def config_static?
@@ -164,24 +170,24 @@ end
164
170
 
165
171
  def config_system_libraries?
166
172
  enable_config("system-libraries", ENV.key?("NOKOGIRI_USE_SYSTEM_LIBRARIES")) do |_, default|
167
- arg_config('--use-system-libraries', default)
173
+ arg_config("--use-system-libraries", default)
168
174
  end
169
175
  end
170
176
 
171
177
  def windows?
172
- RbConfig::CONFIG['target_os'] =~ /mingw32|mswin/
178
+ RbConfig::CONFIG["target_os"] =~ /mingw32|mswin/
173
179
  end
174
180
 
175
181
  def solaris?
176
- RbConfig::CONFIG['target_os'] =~ /solaris/
182
+ RbConfig::CONFIG["target_os"] =~ /solaris/
177
183
  end
178
184
 
179
185
  def darwin?
180
- RbConfig::CONFIG['target_os'] =~ /darwin/
186
+ RbConfig::CONFIG["target_os"] =~ /darwin/
181
187
  end
182
188
 
183
189
  def openbsd?
184
- RbConfig::CONFIG['target_os'] =~ /openbsd/
190
+ RbConfig::CONFIG["target_os"] =~ /openbsd/
185
191
  end
186
192
 
187
193
  def aix?
@@ -193,7 +199,7 @@ def nix?
193
199
  end
194
200
 
195
201
  def truffle?
196
- ::RUBY_ENGINE == 'truffleruby'
202
+ ::RUBY_ENGINE == "truffleruby"
197
203
  end
198
204
 
199
205
  def concat_flags(*args)
@@ -222,9 +228,9 @@ def try_package_configuration(pc)
222
228
  # let's fall back to the pkg-config gem, which knows how to parse .pc files, and wrap it with the
223
229
  # same logic as MakeMakefile#pkg_config
224
230
  begin
225
- require 'rubygems'
226
- gem('pkg-config', REQUIRED_PKG_CONFIG_VERSION)
227
- require 'pkg-config'
231
+ require "rubygems"
232
+ gem("pkg-config", REQUIRED_PKG_CONFIG_VERSION)
233
+ require "pkg-config"
228
234
 
229
235
  checking_for("#{pc} using pkg-config gem version #{PKGConfig::VERSION}", LOCAL_PACKAGE_RESPONSE) do
230
236
  if PKGConfig.have_package(pc)
@@ -285,7 +291,7 @@ def chdir_for_build
285
291
  # When using rake-compiler-dock on Windows, the underlying Virtualbox shared
286
292
  # folders don't support symlinks, but libiconv expects it for a build on
287
293
  # Linux. We work around this limitation by using the temp dir for cooking.
288
- build_dir = ENV['RCD_HOST_RUBY_PLATFORM'].to_s =~ /mingw|mswin|cygwin/ ? '/tmp' : '.'
294
+ build_dir = ENV["RCD_HOST_RUBY_PLATFORM"].to_s =~ /mingw|mswin|cygwin/ ? "/tmp" : "."
289
295
  Dir.chdir(build_dir) do
290
296
  yield
291
297
  end
@@ -339,8 +345,8 @@ def have_libxml_headers?(version = nil)
339
345
  end
340
346
 
341
347
  def try_link_iconv(using = nil)
342
- checking_for(using ? "iconv using #{using}" : 'iconv') do
343
- ['', '-liconv'].any? do |opt|
348
+ checking_for(using ? "iconv using #{using}" : "iconv") do
349
+ ["", "-liconv"].any? do |opt|
344
350
  preserving_globals do
345
351
  yield if block_given?
346
352
 
@@ -371,22 +377,22 @@ def iconv_configure_flags
371
377
  end
372
378
 
373
379
  return [
374
- '--with-iconv=yes',
375
- *("CPPFLAGS=#{idirs.map { |dir| '-I' + dir }.join(' ')}" if idirs),
376
- *("LDFLAGS=#{ldirs.map { |dir| '-L' + dir }.join(' ')}" if ldirs),
380
+ "--with-iconv=yes",
381
+ *("CPPFLAGS=#{idirs.map { |dir| "-I" + dir }.join(" ")}" if idirs),
382
+ *("LDFLAGS=#{ldirs.map { |dir| "-L" + dir }.join(" ")}" if ldirs),
377
383
  ]
378
384
  end
379
385
 
380
386
  if try_link_iconv
381
- return ['--with-iconv=yes']
387
+ return ["--with-iconv=yes"]
382
388
  end
383
389
 
384
- config = preserving_globals { have_package_configuration('libiconv') }
385
- if config && try_link_iconv('pkg-config libiconv') { have_package_configuration('libiconv') }
390
+ config = preserving_globals { have_package_configuration("libiconv") }
391
+ if config && try_link_iconv("pkg-config libiconv") { have_package_configuration("libiconv") }
386
392
  cflags, ldflags, libs = config
387
393
 
388
394
  return [
389
- '--with-iconv=yes',
395
+ "--with-iconv=yes",
390
396
  "CPPFLAGS=#{cflags}",
391
397
  "LDFLAGS=#{ldflags}",
392
398
  "LIBS=#{libs}",
@@ -396,23 +402,22 @@ def iconv_configure_flags
396
402
  abort_could_not_find_library("libiconv")
397
403
  end
398
404
 
399
- def process_recipe(name, version, static_p, cross_p)
400
- require 'rubygems'
401
- gem('mini_portile2', REQUIRED_MINI_PORTILE_VERSION)
402
- require 'mini_portile2'
405
+ def process_recipe(name, version, static_p, cross_p, cacheable_p=true)
406
+ require "rubygems"
407
+ gem("mini_portile2", REQUIRED_MINI_PORTILE_VERSION)
408
+ require "mini_portile2"
403
409
  message("Using mini_portile version #{MiniPortile::VERSION}\n")
404
410
 
405
- if name != "libxml2" && name != "libxslt"
411
+ unless ["libxml2", "libxslt"].include?(name)
406
412
  OTHER_LIBRARY_VERSIONS[name] = version
407
413
  end
408
414
 
409
415
  MiniPortile.new(name, version).tap do |recipe|
410
- recipe.target = File.join(PACKAGE_ROOT_DIR, "ports")
416
+ recipe.target = File.join(PACKAGE_ROOT_DIR, "ports") if cacheable_p
411
417
  # Prefer host_alias over host in order to use i586-mingw32msvc as
412
418
  # correct compiler prefix for cross build, but use host if not set.
413
419
  recipe.host = RbConfig::CONFIG["host_alias"].empty? ? RbConfig::CONFIG["host"] : RbConfig::CONFIG["host_alias"]
414
- recipe.patch_files = Dir[File.join(PACKAGE_ROOT_DIR, "patches", name, "*.patch")].sort
415
- recipe.configure_options << "--libdir=#{File.join(recipe.path, 'lib')}"
420
+ recipe.configure_options << "--libdir=#{File.join(recipe.path, "lib")}"
416
421
 
417
422
  yield recipe
418
423
 
@@ -456,10 +461,10 @@ def process_recipe(name, version, static_p, cross_p)
456
461
  ]
457
462
  end
458
463
 
459
- if RbConfig::CONFIG['target_cpu'] == 'universal'
464
+ if RbConfig::CONFIG["target_cpu"] == "universal"
460
465
  %w[CFLAGS LDFLAGS].each do |key|
461
- unless env[key].include?('-arch')
462
- env[key] = concat_flags(env[key], RbConfig::CONFIG['ARCH_FLAG'])
466
+ unless env[key].include?("-arch")
467
+ env[key] = concat_flags(env[key], RbConfig::CONFIG["ARCH_FLAG"])
463
468
  end
464
469
  end
465
470
  end
@@ -469,7 +474,7 @@ def process_recipe(name, version, static_p, cross_p)
469
474
  end
470
475
 
471
476
  checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
472
- if File.exist?(checkpoint)
477
+ if File.exist?(checkpoint) && !recipe.source_directory
473
478
  message("Building Nokogiri with a packaged version of #{name}-#{version}.\n")
474
479
  else
475
480
  message(<<~EOM)
@@ -486,7 +491,7 @@ def process_recipe(name, version, static_p, cross_p)
486
491
  end
487
492
  end
488
493
 
489
- message(<<~EOM)
494
+ message(<<~EOM) if name != "libgumbo"
490
495
 
491
496
  The Nokogiri maintainers intend to provide timely security updates, but if
492
497
  this is a concern for you and want to use your OS/distro system library
@@ -497,15 +502,13 @@ def process_recipe(name, version, static_p, cross_p)
497
502
 
498
503
  EOM
499
504
 
500
- message(<<~EOM) if name == 'libxml2'
501
- Note, however, that nokogiri cannot guarantee compatiblity with every
505
+ message(<<~EOM) if name == "libxml2"
506
+ Note, however, that nokogiri cannot guarantee compatibility with every
502
507
  version of libxml2 that may be provided by OS/package vendors.
503
508
 
504
509
  EOM
505
510
 
506
- chdir_for_build do
507
- recipe.cook
508
- end
511
+ chdir_for_build { recipe.cook }
509
512
  FileUtils.touch(checkpoint)
510
513
  end
511
514
  recipe.activate
@@ -516,7 +519,7 @@ def copy_packaged_libraries_headers(to_path:, from_recipes:)
516
519
  FileUtils.rm_rf(to_path, secure: true)
517
520
  FileUtils.mkdir(to_path)
518
521
  from_recipes.each do |recipe|
519
- FileUtils.cp_r(Dir[File.join(recipe.path, 'include/*')], to_path)
522
+ FileUtils.cp_r(Dir[File.join(recipe.path, "include/*")], to_path)
520
523
  end
521
524
  end
522
525
 
@@ -530,22 +533,22 @@ def do_clean
530
533
  pwd = Pathname(Dir.pwd)
531
534
 
532
535
  # Skip if this is a development work tree
533
- unless (root + '.git').exist?
536
+ unless (root + ".git").exist?
534
537
  message("Cleaning files only used during build.\n")
535
538
 
536
539
  # (root + 'tmp') cannot be removed at this stage because
537
540
  # nokogiri.so is yet to be copied to lib.
538
541
 
539
542
  # clean the ports build directory
540
- Pathname.glob(pwd.join('tmp', '*', 'ports')) do |dir|
543
+ Pathname.glob(pwd.join("tmp", "*", "ports")) do |dir|
541
544
  FileUtils.rm_rf(dir, verbose: true)
542
545
  end
543
546
 
544
547
  if config_static?
545
548
  # ports installation can be safely removed if statically linked.
546
- FileUtils.rm_rf(root + 'ports', verbose: true)
549
+ FileUtils.rm_rf(root + "ports", verbose: true)
547
550
  else
548
- FileUtils.rm_rf(root + 'ports' + 'archives', verbose: true)
551
+ FileUtils.rm_rf(root + "ports" + "archives", verbose: true)
549
552
  end
550
553
  end
551
554
 
@@ -555,25 +558,25 @@ end
555
558
  #
556
559
  # main
557
560
  #
558
- do_help if arg_config('--help')
559
- do_clean if arg_config('--clean')
561
+ do_help if arg_config("--help")
562
+ do_clean if arg_config("--clean")
560
563
 
561
564
  if openbsd? && !config_system_libraries?
562
- if %x(#{ENV['CC'] || '/usr/bin/cc'} -v 2>&1) !~ /clang/
563
- (ENV['CC'] ||= find_executable('egcc')) ||
565
+ if %x(#{ENV["CC"] || "/usr/bin/cc"} -v 2>&1) !~ /clang/
566
+ (ENV["CC"] ||= find_executable("egcc")) ||
564
567
  abort("Please install gcc 4.9+ from ports using `pkg_add -v gcc`")
565
568
  end
566
569
  append_cppflags "-I/usr/local/include"
567
570
  end
568
571
 
569
- if ENV['CC']
570
- RbConfig::CONFIG['CC'] = RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC']
572
+ if ENV["CC"]
573
+ RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"]
571
574
  end
572
575
 
573
576
  # use same c compiler for libxml and libxslt
574
- ENV['CC'] = RbConfig::CONFIG['CC']
577
+ ENV["CC"] = RbConfig::CONFIG["CC"]
575
578
 
576
- if arg_config('--prevent-strip')
579
+ if arg_config("--prevent-strip")
577
580
  old_cflags = $CFLAGS.split.join(" ")
578
581
  old_ldflags = $LDFLAGS.split.join(" ")
579
582
  old_dldflags = $DLDFLAGS.split.join(" ")
@@ -591,6 +594,10 @@ append_cppflags(ENV["CPPFLAGS"].split) unless ENV["CPPFLAGS"].nil?
591
594
  append_ldflags(ENV["LDFLAGS"].split) unless ENV["LDFLAGS"].nil?
592
595
  $LIBS = concat_flags($LIBS, ENV["LIBS"])
593
596
 
597
+ # nokogumbo code uses C90/C99 features, let's make sure older compilers won't give
598
+ # errors/warnings. see #2302
599
+ append_cflags(["-std=c99", "-Wno-declaration-after-statement"])
600
+
594
601
  # always include debugging information
595
602
  append_cflags("-g")
596
603
 
@@ -619,13 +626,13 @@ append_cppflags(' "-Idummypath"') if windows?
619
626
  if config_system_libraries?
620
627
  message "Building nokogiri using system libraries.\n"
621
628
  ensure_package_configuration(opt: "zlib", pc: "zlib", lib: "z",
622
- headers: "zlib.h", func: "gzdopen")
629
+ headers: "zlib.h", func: "gzdopen")
623
630
  ensure_package_configuration(opt: "xml2", pc: "libxml-2.0", lib: "xml2",
624
- headers: "libxml/parser.h", func: "xmlParseDoc")
631
+ headers: "libxml/parser.h", func: "xmlParseDoc")
625
632
  ensure_package_configuration(opt: "xslt", pc: "libxslt", lib: "xslt",
626
- headers: "libxslt/xslt.h", func: "xsltParseStylesheetDoc")
633
+ headers: "libxslt/xslt.h", func: "xsltParseStylesheetDoc")
627
634
  ensure_package_configuration(opt: "exslt", pc: "libexslt", lib: "exslt",
628
- headers: "libexslt/exslt.h", func: "exsltFuncRegister")
635
+ headers: "libexslt/exslt.h", func: "exsltFuncRegister")
629
636
 
630
637
  have_libxml_headers?(REQUIRED_LIBXML_VERSION) ||
631
638
  abort("ERROR: libxml2 version #{REQUIRED_LIBXML_VERSION} or later is required!")
@@ -636,15 +643,15 @@ else
636
643
  message "Building nokogiri using packaged libraries.\n"
637
644
 
638
645
  static_p = config_static?
639
- message "Static linking is #{static_p ? 'enabled' : 'disabled'}.\n"
646
+ message "Static linking is #{static_p ? "enabled" : "disabled"}.\n"
640
647
 
641
648
  cross_build_p = config_cross_build?
642
- message "Cross build is #{cross_build_p ? 'enabled' : 'disabled'}.\n"
649
+ message "Cross build is #{cross_build_p ? "enabled" : "disabled"}.\n"
643
650
 
644
- require 'yaml'
651
+ require "yaml"
645
652
  dependencies = YAML.load_file(File.join(PACKAGE_ROOT_DIR, "dependencies.yml"))
646
653
 
647
- dir_config('zlib')
654
+ dir_config("zlib")
648
655
 
649
656
  if cross_build_p || windows?
650
657
  zlib_recipe = process_recipe("zlib", dependencies["zlib"]["version"], static_p, cross_build_p) do |recipe|
@@ -658,8 +665,8 @@ else
658
665
 
659
666
  def configure
660
667
  Dir.chdir(work_path) do
661
- mk = File.read('win32/Makefile.gcc')
662
- File.open('win32/Makefile.gcc', 'wb') do |f|
668
+ mk = File.read("win32/Makefile.gcc")
669
+ File.open("win32/Makefile.gcc", "wb") do |f|
663
670
  f.puts "BINARY_PATH = #{path}/bin"
664
671
  f.puts "LIBRARY_PATH = #{path}/lib"
665
672
  f.puts "INCLUDE_PATH = #{path}/include"
@@ -671,7 +678,7 @@ else
671
678
 
672
679
  def configured?
673
680
  Dir.chdir(work_path) do
674
- !!(File.read('win32/Makefile.gcc') =~ /^BINARY_PATH/)
681
+ !!(File.read("win32/Makefile.gcc") =~ /^BINARY_PATH/)
675
682
  end
676
683
  end
677
684
 
@@ -689,7 +696,7 @@ else
689
696
  def configure
690
697
  cflags = concat_flags(ENV["CFLAGS"], "-fPIC", "-g")
691
698
  execute("configure",
692
- ["env", "CHOST=#{host}", "CFLAGS=#{cflags}", "./configure", "--static", configure_prefix])
699
+ ["env", "CHOST=#{host}", "CFLAGS=#{cflags}", "./configure", "--static", configure_prefix])
693
700
  end
694
701
 
695
702
  def compile
@@ -705,7 +712,7 @@ else
705
712
 
706
713
  unless nix?
707
714
  libiconv_recipe = process_recipe("libiconv", dependencies["libiconv"]["version"], static_p,
708
- cross_build_p) do |recipe|
715
+ cross_build_p) do |recipe|
709
716
  recipe.files = [{
710
717
  url: "http://ftp.gnu.org/pub/gnu/libiconv/#{recipe.name}-#{recipe.version}.tar.gz",
711
718
  sha256: dependencies["libiconv"]["sha256"],
@@ -714,6 +721,7 @@ cross_build_p) do |recipe|
714
721
  cflags = concat_flags(ENV["CFLAGS"], "-O2", "-U_FORTIFY_SOURCE", "-g")
715
722
 
716
723
  recipe.configure_options += [
724
+ "--disable-dependency-tracking",
717
725
  "CPPFLAGS=-Wall",
718
726
  "CFLAGS=#{cflags}",
719
727
  "CXXFLAGS=#{cflags}",
@@ -721,7 +729,7 @@ cross_build_p) do |recipe|
721
729
  ]
722
730
  end
723
731
  end
724
- elsif darwin? && !have_header('iconv.h')
732
+ elsif darwin? && !have_header("iconv.h")
725
733
  abort(<<~EOM.chomp)
726
734
  -----
727
735
  The file "iconv.h" is missing in your build environment,
@@ -737,15 +745,21 @@ cross_build_p) do |recipe|
737
745
  end
738
746
 
739
747
  unless windows?
740
- preserving_globals { local_have_library('z', 'gzdopen', 'zlib.h') } ||
741
- abort('zlib is missing; necessary for building libxml2')
748
+ preserving_globals { local_have_library("z", "gzdopen", "zlib.h") } ||
749
+ abort("zlib is missing; necessary for building libxml2")
742
750
  end
743
751
 
744
752
  libxml2_recipe = process_recipe("libxml2", dependencies["libxml2"]["version"], static_p, cross_build_p) do |recipe|
745
- recipe.files = [{
746
- url: "http://xmlsoft.org/sources/#{recipe.name}-#{recipe.version}.tar.gz",
747
- sha256: dependencies["libxml2"]["sha256"],
748
- }]
753
+ source_dir = arg_config("--with-xml2-source-dir")
754
+ if source_dir
755
+ recipe.source_directory = source_dir
756
+ else
757
+ recipe.files = [{
758
+ url: "http://xmlsoft.org/sources/#{recipe.name}-#{recipe.version}.tar.gz",
759
+ sha256: dependencies["libxml2"]["sha256"],
760
+ }]
761
+ recipe.patch_files = Dir[File.join(PACKAGE_ROOT_DIR, "patches", "libxml2", "*.patch")].sort
762
+ end
749
763
 
750
764
  cflags = concat_flags(ENV["CFLAGS"], "-O2", "-U_FORTIFY_SOURCE", "-g")
751
765
 
@@ -768,6 +782,12 @@ cross_build_p) do |recipe|
768
782
  cflags = concat_flags(cflags, "-ULIBXML_STATIC", "-DIN_LIBXML")
769
783
  end
770
784
 
785
+ recipe.configure_options << if source_dir
786
+ "--config-cache"
787
+ else
788
+ "--disable-dependency-tracking"
789
+ end
790
+
771
791
  recipe.configure_options += [
772
792
  "--without-python",
773
793
  "--without-readline",
@@ -779,10 +799,16 @@ cross_build_p) do |recipe|
779
799
  end
780
800
 
781
801
  libxslt_recipe = process_recipe("libxslt", dependencies["libxslt"]["version"], static_p, cross_build_p) do |recipe|
782
- recipe.files = [{
783
- url: "http://xmlsoft.org/sources/#{recipe.name}-#{recipe.version}.tar.gz",
784
- sha256: dependencies["libxslt"]["sha256"],
785
- }]
802
+ source_dir = arg_config("--with-xslt-source-dir")
803
+ if source_dir
804
+ recipe.source_directory = source_dir
805
+ else
806
+ recipe.files = [{
807
+ url: "http://xmlsoft.org/sources/#{recipe.name}-#{recipe.version}.tar.gz",
808
+ sha256: dependencies["libxslt"]["sha256"],
809
+ }]
810
+ recipe.patch_files = Dir[File.join(PACKAGE_ROOT_DIR, "patches", "libxslt", "*.patch")].sort
811
+ end
786
812
 
787
813
  cflags = concat_flags(ENV["CFLAGS"], "-O2", "-U_FORTIFY_SOURCE", "-g")
788
814
 
@@ -790,6 +816,12 @@ cross_build_p) do |recipe|
790
816
  recipe.configure_options += ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"]
791
817
  end
792
818
 
819
+ recipe.configure_options << if source_dir
820
+ "--config-cache"
821
+ else
822
+ "--disable-dependency-tracking"
823
+ end
824
+
793
825
  recipe.configure_options += [
794
826
  "--without-python",
795
827
  "--without-crypto",
@@ -810,12 +842,12 @@ cross_build_p) do |recipe|
810
842
  libname = recipe.name[/\Alib(.+)\z/, 1]
811
843
  File.join(recipe.path, "bin", "#{libname}-config").tap do |config|
812
844
  # call config scripts explicit with 'sh' for compat with Windows
813
- $CPPFLAGS = %x(sh #{config} --cflags).strip << ' ' << $CPPFLAGS
845
+ $CPPFLAGS = %x(sh #{config} --cflags).strip << " " << $CPPFLAGS
814
846
  %x(sh #{config} --libs).strip.shellsplit.each do |arg|
815
847
  case arg
816
848
  when /\A-L(.+)\z/
817
849
  # Prioritize ports' directories
818
- $LIBPATH = if Regexp.last_match(1).start_with?(PACKAGE_ROOT_DIR + '/')
850
+ $LIBPATH = if Regexp.last_match(1).start_with?(PACKAGE_ROOT_DIR + "/")
819
851
  [Regexp.last_match(1)] | $LIBPATH
820
852
  else
821
853
  $LIBPATH | [Regexp.last_match(1)]
@@ -823,26 +855,26 @@ cross_build_p) do |recipe|
823
855
  when /\A-l./
824
856
  libs.unshift(arg)
825
857
  else
826
- $LDFLAGS << ' ' << arg.shellescape
858
+ $LDFLAGS << " " << arg.shellescape
827
859
  end
828
860
  end
829
861
  end
830
862
 
831
- patches_string = recipe.patch_files.map { |path| File.basename(path) }.join(' ')
863
+ patches_string = recipe.patch_files.map { |path| File.basename(path) }.join(" ")
832
864
  append_cppflags(%[-DNOKOGIRI_#{recipe.name.upcase}_PATCHES="\\\"#{patches_string}\\\""])
833
865
 
834
866
  case libname
835
- when 'xml2'
867
+ when "xml2"
836
868
  # xslt-config --libs or pkg-config libxslt --libs does not include
837
869
  # -llzma, so we need to add it manually when linking statically.
838
- if static_p && preserving_globals { local_have_library('lzma') }
870
+ if static_p && preserving_globals { local_have_library("lzma") }
839
871
  # Add it at the end; GH #988
840
- libs << '-llzma'
872
+ libs << "-llzma"
841
873
  end
842
- when 'xslt'
874
+ when "xslt"
843
875
  # xslt-config does not have a flag to emit options including
844
876
  # -lexslt, so add it manually.
845
- libs.unshift('-lexslt')
877
+ libs.unshift("-lexslt")
846
878
  end
847
879
  end
848
880
  end.shelljoin
@@ -850,10 +882,10 @@ cross_build_p) do |recipe|
850
882
  if static_p
851
883
  $libs = $libs.shellsplit.map do |arg|
852
884
  case arg
853
- when '-lxml2'
854
- File.join(libxml2_recipe.path, 'lib', libflag_to_filename(arg))
855
- when '-lxslt', '-lexslt'
856
- File.join(libxslt_recipe.path, 'lib', libflag_to_filename(arg))
885
+ when "-lxml2"
886
+ File.join(libxml2_recipe.path, "lib", libflag_to_filename(arg))
887
+ when "-lxslt", "-lexslt"
888
+ File.join(libxslt_recipe.path, "lib", libflag_to_filename(arg))
857
889
  else
858
890
  arg
859
891
  end
@@ -865,14 +897,64 @@ cross_build_p) do |recipe|
865
897
  ensure_func("exsltFuncRegister", "libexslt/exslt.h")
866
898
  end
867
899
 
868
- have_func('xmlHasFeature') || abort("xmlHasFeature() is missing.") # introduced in libxml 2.6.21
869
- have_func('xmlFirstElementChild') # introduced in libxml 2.7.3
870
- have_func('xmlRelaxNGSetParserStructuredErrors') # introduced in libxml 2.6.24
871
- have_func('xmlRelaxNGSetValidStructuredErrors') # introduced in libxml 2.6.21
872
- have_func('xmlSchemaSetValidStructuredErrors') # introduced in libxml 2.6.23
873
- have_func('xmlSchemaSetParserStructuredErrors') # introduced in libxml 2.6.23
900
+ libgumbo_recipe = process_recipe("libgumbo", "1.0.0-nokogiri", static_p, cross_build_p, false) do |recipe|
901
+ recipe.configure_options = []
902
+
903
+ class << recipe
904
+ def downloaded?
905
+ true
906
+ end
907
+
908
+ def extract
909
+ target = File.join(tmp_path, "gumbo-parser")
910
+ output("Copying gumbo-parser files into #{target}...")
911
+ FileUtils.mkdir_p(target)
912
+ FileUtils.cp(Dir.glob(File.join(PACKAGE_ROOT_DIR, "gumbo-parser/src/*")), target)
913
+ end
914
+
915
+ def configured?
916
+ true
917
+ end
918
+
919
+ def install
920
+ lib_dir = File.join(port_path, "lib")
921
+ inc_dir = File.join(port_path, "include")
922
+ FileUtils.mkdir_p([lib_dir, inc_dir])
923
+ FileUtils.cp(File.join(work_path, "libgumbo.a"), lib_dir)
924
+ FileUtils.cp(Dir.glob(File.join(work_path, "*.h")), inc_dir)
925
+ end
926
+
927
+ def compile
928
+ cflags = concat_flags(ENV["CFLAGS"], "-fPIC", "-g")
929
+
930
+ env = { "CC" => gcc_cmd, "CFLAGS" => cflags }
931
+ if config_cross_build?
932
+ if host =~ /darwin/
933
+ env["AR"] = "#{host}-libtool"
934
+ env["ARFLAGS"] = "-o"
935
+ else
936
+ env["AR"] = "#{host}-ar"
937
+ end
938
+ env["RANLIB"] = "#{host}-ranlib"
939
+ end
940
+
941
+ execute("compile", make_cmd, { env: env })
942
+ end
943
+ end
944
+ end
945
+ append_cppflags("-I#{File.join(libgumbo_recipe.path, "include")}")
946
+ $libs = $libs + " " + File.join(libgumbo_recipe.path, "lib", "libgumbo.a")
947
+ $LIBPATH = $LIBPATH | [File.join(libgumbo_recipe.path, "lib")]
948
+ ensure_func("gumbo_parse_with_options", "gumbo.h")
949
+
950
+ have_func("xmlHasFeature") || abort("xmlHasFeature() is missing.") # introduced in libxml 2.6.21
951
+ have_func("xmlFirstElementChild") # introduced in libxml 2.7.3
952
+ have_func("xmlRelaxNGSetParserStructuredErrors") # introduced in libxml 2.6.24
953
+ have_func("xmlRelaxNGSetValidStructuredErrors") # introduced in libxml 2.6.21
954
+ have_func("xmlSchemaSetValidStructuredErrors") # introduced in libxml 2.6.23
955
+ have_func("xmlSchemaSetParserStructuredErrors") # introduced in libxml 2.6.23
874
956
 
875
- have_func('vasprintf')
957
+ have_func("vasprintf")
876
958
 
877
959
  other_library_versions_string = OTHER_LIBRARY_VERSIONS.map { |k, v| [k, v].join(":") }.join(",")
878
960
  append_cppflags(%[-DNOKOGIRI_OTHER_LIBRARY_VERSIONS="\\\"#{other_library_versions_string}\\\""])
@@ -882,25 +964,25 @@ unless config_system_libraries?
882
964
  # When precompiling native gems, copy packaged libraries' headers to ext/nokogiri/include
883
965
  # These are packaged up by the cross-compiling callback in the ExtensionTask
884
966
  copy_packaged_libraries_headers(to_path: File.join(PACKAGE_ROOT_DIR, "ext/nokogiri/include"),
885
- from_recipes: [libxml2_recipe, libxslt_recipe])
967
+ from_recipes: [libxml2_recipe, libxslt_recipe])
886
968
  else
887
969
  # When compiling during installation, install packaged libraries' header files into ext/nokogiri/include
888
970
  copy_packaged_libraries_headers(to_path: "include",
889
- from_recipes: [libxml2_recipe, libxslt_recipe])
971
+ from_recipes: [libxml2_recipe, libxslt_recipe])
890
972
  $INSTALLFILES << ["include/**/*.h", "$(rubylibdir)"]
891
973
  end
892
974
  end
893
975
 
894
- create_makefile('nokogiri/nokogiri')
976
+ create_makefile("nokogiri/nokogiri")
895
977
 
896
978
  if config_clean?
897
979
  # Do not clean if run in a development work tree.
898
- File.open('Makefile', 'at') do |mk|
980
+ File.open("Makefile", "at") do |mk|
899
981
  mk.print(<<~EOF)
900
982
 
901
983
  all: clean-ports
902
984
  clean-ports: $(DLLIB)
903
- \t-$(Q)$(RUBY) $(srcdir)/extconf.rb --clean --#{static_p ? 'enable' : 'disable'}-static
985
+ \t-$(Q)$(RUBY) $(srcdir)/extconf.rb --clean --#{static_p ? "enable" : "disable"}-static
904
986
  EOF
905
987
  end
906
988
  end