class PackageConfig

def cflags

def cflags
  path_flags, other_flags = collect_cflags
  (path_flags + other_flags).join(" ")
end

def cflags_only_I

def cflags_only_I
  collect_cflags[0].join(" ")
end

def clear_configure_args_cache

def clear_configure_args_cache
  @native_pkg_config = nil
  @custom_override_variables = nil
end

def collect_cflags

def collect_cflags
  all_cflags = required_packages.collect do |package|
    self.class.new(package, @options).cflags
  end
  all_cflags = [declaration("Cflags")] + all_cflags
  all_cflags = all_cflags.join(" ").gsub(/-I /, '-I').split.uniq
  path_flags, other_flags = all_cflags.partition {|flag| /\A-I/ =~ flag}
  path_flags = path_flags.reject do |flag|
    flag == "-I/usr/include"
  end
  if @msvc_syntax
    path_flags = path_flags.collect do |flag|
      flag.gsub(/\A-I/, "/I")
    end
  end
  [path_flags, other_flags]
end

def collect_libs

def collect_libs
  all_libs = required_packages.collect do |package|
    self.class.new(package, @options).libs
  end
  all_libs = [declaration("Libs")] + all_libs
  all_libs = all_libs.join(" ").gsub(/-([Ll]) /, '\1').split.uniq
  path_flags, other_flags = all_libs.partition {|flag| /\A-L/ =~ flag}
  path_flags = path_flags.reject do |flag|
    /\A-L\/usr\/lib(?:64)?\z/ =~ flag
  end
  if @msvc_syntax
    path_flags = path_flags.collect do |flag|
      flag.gsub(/\A-L/, "/libpath:")
    end
    other_flags = other_flags.collect do |flag|
      if /\A-l/ =~ flag
        "#{$POSTMATCH}.lib"
      else
        flag
      end
    end
  end
  [path_flags, other_flags]
end

def custom_override_variables

def custom_override_variables
  @custom_override_variables ||= with_config("override-variables", "")
end

def declaration(name)

def declaration(name)
  parse_pc if @declarations.nil?
  expand_value(@declarations[name])
end

def description

def description
  declaration("Description")
end

def exist?

def exist?
  not pc.nil?
end

def expand_value(value)

def expand_value(value)
  return nil if value.nil?
  value.gsub(/\$\{(#{IDENTIFIER_RE})\}/) do
    variable($1)
  end
end

def guess_default_path

def guess_default_path
  default_path = ["/usr/local/lib64/pkgconfig",
                  "/usr/local/lib/pkgconfig",
                  "/usr/local/libdata/pkgconfig",
                  "/opt/local/lib/pkgconfig",
                  "/usr/lib64/pkgconfig",
                  "/usr/lib/pkgconfig",
                  "/usr/X11/lib/pkgconfig/",
                  "/usr/share/pkgconfig"].join(SEPARATOR)
  libdir = ENV["PKG_CONFIG_LIBDIR"]
  default_path = [libdir, default_path].join(SEPARATOR) if libdir
  pkg_config = self.class.native_pkg_config
  return default_path unless pkg_config.absolute?
  [(pkg_config.parent.parent + "lib" + "pkgconfig").to_s,
   (pkg_config.parent.parent + "libdata" + "pkgconfig").to_s,
   default_path].join(SEPARATOR)
end

def guess_native_pkg_config

def guess_native_pkg_config
  pkg_config = with_config("pkg-config", ENV["PKG_CONFIG"] || "pkg-config")
  pkg_config = Pathname.new(pkg_config)
  unless pkg_config.absolute?
    found_pkg_config = search_pkg_config_from_path(pkg_config)
    pkg_config = found_pkg_config if found_pkg_config
  end
  unless pkg_config.absolute?
    found_pkg_config = search_pkg_config_by_dln_find_exe(pkg_config)
    pkg_config = found_pkg_config if found_pkg_config
  end
  pkg_config
end

def initialize(name, options={})

def initialize(name, options={})
  @name = name
  @options = options
  path = @options[:path] || ENV["PKG_CONFIG_PATH"]
  @paths = [path, guess_default_path].compact.join(SEPARATOR).split(SEPARATOR)
  @paths.unshift(*(@options[:paths] || []))
  @msvc_syntax = @options[:msvc_syntax]
  @variables = @declarations = nil
  override_variables = self.class.custom_override_variables
  @override_variables = parse_override_variables(override_variables)
  default_override_variables = @options[:override_variables] || {}
  @override_variables = default_override_variables.merge(@override_variables)
end

def libs

def libs
  path_flags, other_flags = collect_libs
  (path_flags + other_flags).join(" ")
end

def libs_only_L

def libs_only_L
  collect_libs[0].find_all do |arg|
    if @msvc_syntax
      /\A\/libpath:/ =~ arg
    else
      /\A-L/ =~ arg
    end
  end.join(" ")
end

def libs_only_l

def libs_only_l
  collect_libs[1].find_all do |arg|
    if @msvc_syntax
      /\.lib\z/ =~ arg
    else
      /\A-l/ =~ arg
    end
  end.join(" ")
end

def native_pkg_config

def native_pkg_config
  @native_pkg_config ||= guess_native_pkg_config
end

def parse_override_variables(override_variables)

def parse_override_variables(override_variables)
  variables = {}
  override_variables.split(",").each do |variable|
    name, value = variable.split("=", 2)
    variables[name] = value
  end
  variables
end

def parse_pc

def parse_pc
  raise ".pc for #{@name} doesn't exist." unless exist?
  @variables = {}
  @declarations = {}
  File.open(pc) do |input|
    input.each_line do |line|
      line = line.gsub(/#.*/, '').strip
      next if line.empty?
      case line
      when /^(#{IDENTIFIER_RE})=/
        @variables[$1] = $POSTMATCH.strip
      when /^(#{IDENTIFIER_RE}):/
        @declarations[$1] = $POSTMATCH.strip
      end
    end
  end
end

def parse_requires(requires)

def parse_requires(requires)
  return [] if requires.nil?
  requires_without_version = requires.gsub(/[<>]?=\s*[\d.]+\s*/, '')
  requires_without_version.split(/[,\s]+/)
end

def pc

def pc
  @paths.each do |path|
    pc_name = File.join(path, "#{@name}.pc")
    return pc_name if File.exist?(pc_name)
  end
  return nil
end

def required_packages

def required_packages
  (requires_private + requires.reverse).reject do |package|
    @name == package
  end.uniq
end

def requires

def requires
  parse_requires(declaration("Requires"))
end

def requires_private

def requires_private
  parse_requires(declaration("Requires.private"))
end

def search_pkg_config_by_dln_find_exe(pkg_config)

def search_pkg_config_by_dln_find_exe(pkg_config)
  begin
    require "dl/import"
  rescue LoadError
    return nil
  end
  dln = Module.new
  dln.module_eval do
    if DL.const_defined?(:Importer)
      extend DL::Importer
    else
      extend DL::Importable
    end
    begin
      dlload RbConfig::CONFIG["LIBRUBY"]
    rescue RuntimeError
      return nil if $!.message == "unknown error"
      return nil if /: image not found\z/ =~ $!.message
      raise
    rescue DL::DLError
      return nil
    end
    extern "const char *dln_find_exe(const char *, const char *)"
  end
  path = dln.dln_find_exe(pkg_config.to_s, nil)
  if path.size.zero?
    nil
  else
    Pathname(path.to_s)
  end
end

def search_pkg_config_from_path(pkg_config)

def search_pkg_config_from_path(pkg_config)
  (ENV["PATH"] || "").split(SEPARATOR).each do |path|
    try_pkg_config = Pathname(path) + pkg_config
    return try_pkg_config if try_pkg_config.exist?
  end
  nil
end

def variable(name)

def variable(name)
  parse_pc if @variables.nil?
  expand_value(@override_variables[name] || @variables[name])
end

def version

def version
  declaration("Version")
end