def create_iso639_language_list_file
  cpp_file_name = "src/common/iso639_language_list.cpp"
  iso639_2      = JSON.parse(IO.readlines("/usr/share/iso-codes/json/iso_639-2.json").join('')) \
    ["639-2"].
    reject { |entry| %r{^qaa}.match(entry["alpha_3"]) }.
    map do |entry|
      entry["has_639_2"]      = true
      entry["alpha_3_to_use"] = entry["bibliographic"] || entry["alpha_3"]
      entry
    end

  used_codes = Hash[ *iso639_2.map { |entry| [ entry["alpha_3"], true, entry["bibliographic"], true ] }.flatten ]

  JSON.parse(IO.readlines("/usr/share/iso-codes/json/iso_639-3.json").join('')) \
    ["639-3"].
    reject { |entry| entry["type"] != "L" }.
    reject { |entry| used_codes.include?(entry["alpha_3"]) }.
    each do |entry|
      iso639_2 << {
        "name"           => entry["name"],
        "alpha_3"        => entry["alpha_3"],
        "alpha_3_to_use" => entry["alpha_3"],
        "has_639_2"      => false,
      }
    end

  rows = iso639_2.
    map do |entry|
    [ entry["name"].to_u8_cpp_string,
      entry["alpha_3_to_use"].to_cpp_string,
      (entry["alpha_2"] || '').to_cpp_string,
      entry["bibliographic"] ? entry["alpha_3"].to_cpp_string : '""s',
      entry["has_639_2"].to_s,
    ]
  end

  rows += ("a".."d").map do |letter|
    [ %Q{u8"Reserved for local use: qa#{letter}"s},
      %Q{u8"qa#{letter}"s},
      '""s',
      '""s',
      'true ',
    ]
  end

  header = <<EOT
/*
   mkvmerge -- utility for splicing together matroska files
   from component media subtypes

   Distributed under the GPL v2
   see the file COPYING for details
   or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html

   ISO 639 language definitions, lookup functions

   Written by Moritz Bunkus <moritz@bunkus.org>.
*/

// -----------------------------------------------------------------------
// NOTE: this file is auto-generated by the "dev:iso639_list" rake target.
// -----------------------------------------------------------------------

#include "common/iso639_types.h"

using namespace std::string_literals;

namespace mtx::iso639 {

std::vector<language_t> g_languages;

void
init() {
  g_languages.reserve(#{rows.size});

EOT

  footer = <<EOT
}

} // namespace mtx::iso639
EOT

  content = header + format_table(rows.sort, :column_suffix => ',', :row_prefix => "  g_languages.emplace_back(", :row_suffix => ");").join("\n") + "\n" + footer

  runq("write", cpp_file_name) { IO.write("#{$source_dir}/#{cpp_file_name}", content); 0 }
end
