intf_libs = # Interface dependencies.
impl_libs = # Implementation dependencies.

import libbuild2 = build2%lib{build2}

import impl_libs += $libbuild2 # Implied interface dependency.
import impl_libs += build2%lib{build2-in}

lib{build2-autoconf}: {hxx ixx txx cxx}{* -checks} {hxx cxx}{checks} \
                      $impl_libs $intf_libs

# - File name must be the exact variable name plus .h (used for sorting).
# - First line in the file should be `// <NAME> [<MODIFIER>] [:<BASE>...]`.
# - Lines starting with `//` (including the first) are removed (can be used
#   to comment implementation details not to be copied to the output).
# - No double-quotes or backslash escaping except for line continuations.
#
# NOTE: remember to update README.md if changing anything here.
#
# NOTE: see equivalent parsing code in load_project_checks().
#
<{hxx cxx}{checks}>: checks/file{*.h}
{
  install = false
  backlink = true
}
{{
  diag gen $>

  # We have to sort input files without the extension and as strings (to sort
  # case-sensitively on Windows).
  #
  is = $regex.apply($sort([strings] $base($path($<))), '(.+)', '\1.h')

  h = $path($>[0])
  s = $path($>[1])

  # We regularize the output with a dummy start entry plus add five end
  # dummies that are used in tests.
  #
  n = $size($is)
  n += 6

  cat <<"EOI" >$h
  namespace build2
  {
    namespace autoconf
    {
      struct check
      {
        const char* name;
        const char* modifier; // ! or empty
        const char* base;     // base names or empty
        const char* value;
      };

      using builtin_check = check;

      extern const builtin_check builtin_checks[$n];
    }
  }
  EOI

  cat <<"EOI" >$s
  #include <libbuild2/autoconf/checks.hxx>

  const build2::autoconf::builtin_check build2::autoconf::builtin_checks[$n] = {
  {
  \"\", \"\", \"\",

  \"\"
  },
  EOI

  for i: $is
  {
    # Split the contents of the file into lines.
    #
    cat $i | set --newline ls [strings]

    # Extract the name (\1), modifier (\2) and base (\4) from the first line.
    #
    # Note: remember to update the C++ parsing code if changing anything here.
    #
    nmb = [strings] $regex.match($ls[0],                                     \
                                 '// ([^ !:]+) *(!)? *(: *(( *[^ ]+)+))? *', \
                                 return_subs)

    ifn $nmb
      exit "incorrect first line format in $i"

    # Note that if there is no modifier or base, we get empty strings.
    #
    cat <<"EOI" >>$s

    {
    "($nmb[0])", "($nmb[1])", "($nmb[3])",

    EOI

    # Filter out lines starting with // (including the first line).
    #
    # @@ Maybe we should get rid of the blank lines or at least collapse
    #    multiple blank lines (which are bound to occur because we are now
    #    removing some lines) into a single one? Note: in the C++ version
    #    we zap continuous comment/blank line blocks.
    #
    ls = $regex.filter_out_match($ls, '\s*//.*')

    # Merge and post-process the lines (handle line continuations and wrap in
    # "...\n").
    #
    sed -n \
      -e 's|^(.*)\\$|\1\\\\|' \
      -e 's|^(.*)$|"\1\\n"|p' \
      <<<"$regex.merge($ls, '(.*)', '\1', $\n, format_copy_empty)" >>$s

    echo '},' >>$s
  }

  cat <<EOI >>$s

  {
  "zzz_TEST_DUMMY1_H", "", "",

  "#define zzz_TEST_DUMMY1_H 1\n"
  },

  {
  "zzz_TEST_DUMMY2_H", "", "",

  "#define zzz_TEST_DUMMY2_H 1\n"
  },

  {
  "zzz_TEST_DUMMY3_H", "!", "",

  "#define zzz_TEST_DUMMY3_H 1\n"
  },

  {
  "zzz_TEST_DUMMY4_H", "", "zzz_TEST_DUMMY1_H zzz_TEST_DUMMY3_H",

  "#ifdef zzz_TEST_DUMMY1_H\n"
  "#  define zzz_TEST_DUMMY4_H zzz_TEST_DUMMY3_H\n"
  "#endif /*zzz_TEST_DUMMY1_H*/\n"
  },

  {
  "zzz_TEST_DUMMY5_H", "", "zzz_TEST_DUMMY3_H zzz_TEST_DUMMY4_H",

  "#ifdef zzz_TEST_DUMMY3_H\n"
  "#  define zzz_TEST_DUMMY5_H zzz_TEST_DUMMY4_H\n"
  "#endif /*zzz_TEST_DUMMY3_H*/\n"
  }
  };
  EOI
}}

# Build options.
#
cxx.poptions =+ "-I$out_root" "-I$src_root"

obja{*}: cxx.poptions += -DLIBBUILD2_AUTOCONF_STATIC_BUILD
objs{*}: cxx.poptions += -DLIBBUILD2_AUTOCONF_SHARED_BUILD

# Export options.
#
lib{build2-autoconf}:
{
  cxx.export.poptions = "-I$out_root" "-I$src_root"
  cxx.export.libs = $intf_libs
}

liba{build2-autoconf}: cxx.export.poptions += -DLIBBUILD2_AUTOCONF_STATIC
libs{build2-autoconf}: cxx.export.poptions += -DLIBBUILD2_AUTOCONF_SHARED

# For pre-releases use the complete version to make sure they cannot be used
# in place of another pre-release or the final version. See the version module
# for details on the version.* variable values.
#
if $version.pre_release
  lib{build2-autoconf}: bin.lib.version = "-$version.project_id"
else
  lib{build2-autoconf}: bin.lib.version = "-$version.major.$version.minor"

# Embed the build system core version as our load suffix.
#
# Get the version as exported by the lib{build2} target falling back to the
# running build system version if unable to (installed lib{build2}).
#
iv = ($project($libbuild2) == [null]     \
      ? $($libbuild2: interface_version) \
      : [null])

ifn $iv
  iv = $build.version.interface

libs{build2-autoconf}: bin.lib.load_suffix = "-$iv"

# Install into the libbuild2/autoconf/ subdirectory of, say, /usr/include/
# recreating subdirectories.
#
{hxx ixx txx}{*}:
{
  install         = include/libbuild2/autoconf/
  install.subdirs = true
}
