# Copyright (C) 2003-2013 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

package Automake::Variable;

use 5.006;
use strict;
use Carp;

use Automake::Channels;
use Automake::ChannelDefs;
use Automake::Configure_ac;
use Automake::Item;
use Automake::VarDef;
use Automake::Condition qw (TRUE FALSE);
use Automake::DisjConditions;
use Automake::General 'uniq';
use Automake::Wrap 'makefile_wrap';

require Exporter;
use vars '@ISA', '@EXPORT', '@EXPORT_OK';
@ISA = qw/Automake::Item Exporter/;
@EXPORT = qw (err_var msg_var msg_cond_var reject_var
	      var rvar vardef rvardef
	      variables
	      scan_variable_expansions check_variable_expansions
	      variable_delete
	      variables_dump
	      set_seen
	      require_variables
	      variable_value
	      output_variables
	      transform_variable_recursively);

=head1 NAME

Automake::Variable - support for variable definitions

=head1 SYNOPSIS

  use Automake::Variable;
  use Automake::VarDef;

  # Defining a variable.
  Automake::Variable::define($varname, $owner, $type,
                             $cond, $value, $comment,
                             $where, $pretty)

  # Looking up a variable.
  my $var = var $varname;
  if ($var)
    {
      ...
    }

  # Looking up a variable that is assumed to exist.
  my $var = rvar $varname;

  # The list of conditions where $var has been defined.
  # ($var->conditions is an Automake::DisjConditions,
  # $var->conditions->conds is a list of Automake::Condition.)
  my @conds = $var->conditions->conds

  # Access to the definition in Condition $cond.
  # $def is an Automake::VarDef.
  my $def = $var->def ($cond);
  if ($def)
    {
      ...
    }

  # When the conditional definition is assumed to exist, use
  my $def = $var->rdef ($cond);


=head1 DESCRIPTION

This package provides support for Makefile variable definitions.

An C<Automake::Variable> is a variable name associated to possibly
many conditional definitions.  These definitions are instances
of C<Automake::VarDef>.

Therefore obtaining the value of a variable under a given
condition involves two lookups.  One to look up the variable,
and one to look up the conditional definition:

  my $var = var $name;
  if ($var)
    {
      my $def = $var->def ($cond);
      if ($def)
        {
          return $def->value;
        }
      ...
    }
  ...

When it is known that the variable and the definition
being looked up exist, the above can be simplified to

  return var ($name)->def ($cond)->value; # Do not write this.

but is better written

  return rvar ($name)->rdef ($cond)->value;

or even

  return rvardef ($name, $cond)->value;

The I<r> variants of the C<var>, C<def>, and C<vardef> methods add an
extra test to ensure that the lookup succeeded, and will diagnose
failures as internal errors (with a message which is much more
informative than Perl's warning about calling a method on a
non-object).

=cut

my $_VARIABLE_CHARACTERS = '[.A-Za-z0-9_@]+';
my $_VARIABLE_PATTERN = '^' . $_VARIABLE_CHARACTERS . "\$";
my $_VARIABLE_RECURSIVE_PATTERN =
    '^([.A-Za-z0-9_@]|\$[({]' . $_VARIABLE_CHARACTERS . '[})]?)+' . "\$";

# The order in which variables should be output.  (May contain
# duplicates -- only the first occurrence matters.)
my @_var_order;

# This keeps track of all variables defined by &_gen_varname.
# $_gen_varname{$base} is a hash for all variables defined with
# prefix '$base'.  Values stored in this hash are the variable names.
# Keys have the form "(COND1)VAL1(COND2)VAL2..." where VAL1 and VAL2
# are the values of the variable for condition COND1 and COND2.
my %_gen_varname = ();
# $_gen_varname_n{$base} is the number of variables generated by
# _gen_varname() for $base.  This is not the same as keys
# %{$_gen_varname{$base}} because %_gen_varname may also contain
# variables not generated by _gen_varname.
my %_gen_varname_n = ();

# Declare the macros that define known variables, so we can
# hint the user if she try to use one of these variables.

# Macros accessible via aclocal.
my %_am_macro_for_var =
  (
   CCAS => 'AM_PROG_AS',
   CCASFLAGS => 'AM_PROG_AS',
   EMACS => 'AM_PATH_LISPDIR',
   GCJ => 'AM_PROG_GCJ',
   LEX => 'AM_PROG_LEX',
   LIBTOOL => 'LT_INIT',
   lispdir => 'AM_PATH_LISPDIR',
   pkgpyexecdir => 'AM_PATH_PYTHON',
   pkgpythondir => 'AM_PATH_PYTHON',
   pyexecdir => 'AM_PATH_PYTHON',
   PYTHON => 'AM_PATH_PYTHON',
   pythondir => 'AM_PATH_PYTHON',
   );

# Macros shipped with Autoconf.
my %_ac_macro_for_var =
  (
   ALLOCA => 'AC_FUNC_ALLOCA',
   CC => 'AC_PROG_CC',
   CFLAGS => 'AC_PROG_CC',
   CXX => 'AC_PROG_CXX',
   CXXFLAGS => 'AC_PROG_CXX',
   F77 => 'AC_PROG_F77',
   FFLAGS => 'AC_PROG_F77',
   FC => 'AC_PROG_FC',
   FCFLAGS => 'AC_PROG_FC',
   OBJC => 'AC_PROG_OBJC',
   OBJCFLAGS => 'AC_PROG_OBJC',
   OBJCXX => 'AC_PROG_OBJCXX',
   OBJCXXFLAGS => 'AC_PROG_OBJCXX',
   RANLIB => 'AC_PROG_RANLIB',
   UPC => 'AM_PROG_UPC',
   UPCFLAGS => 'AM_PROG_UPC',
   YACC => 'AC_PROG_YACC',
   );

# The name of the configure.ac file.
my $configure_ac;

# Variables that can be overridden without complaint from -Woverride
my %_silent_variable_override =
  (AM_MAKEINFOHTMLFLAGS => 1,
   AR => 1,
   ARFLAGS => 1,
   DEJATOOL => 1,
   JAVAC => 1,
   JAVAROOT => 1);

# Count of helper variables used to implement conditional '+='.
my $_appendvar;

# Each call to C<Automake::Variable::traverse_recursively> gets an
# unique label. This is used to detect recursively defined variables.
my $_traversal = 0;


=head2 Error reporting functions

In these functions, C<$var> can be either a variable name, or
an instance of C<Automake::Variable>.

=over 4

=item C<err_var ($var, $message, [%options])>

Uncategorized errors about variables.

=cut

sub err_var ($$;%)
{
  msg_var ('error', @_);
}

=item C<msg_cond_var ($channel, $cond, $var, $message, [%options])>

Messages about conditional variable.

=cut

sub msg_cond_var ($$$$;%)
{
  my ($channel, $cond, $var, $msg, %opts) = @_;
  my $v = ref ($var) ? $var : rvar ($var);
  msg $channel, $v->rdef ($cond)->location, $msg, %opts;
}

=item C<msg_var ($channel, $var, $message, [%options])>

Messages about variables.

=cut

sub msg_var ($$$;%)
{
  my ($channel, $var, $msg, %opts) = @_;
  my $v = ref ($var) ? $var : rvar ($var);
  # Don't know which condition is concerned.  Pick any.
  my $cond = $v->conditions->one_cond;
  msg_cond_var $channel, $cond, $v, $msg, %opts;
}

=item C<$bool = reject_var ($varname, $error_msg)>

Bail out with C<$error_msg> if a variable with name C<$varname> has
been defined.

Return true iff C<$varname> is defined.

=cut

sub reject_var ($$)
{
  my ($var, $msg) = @_;
  my $v = var ($var);
  if ($v)
    {
      err_var $v, $msg;
      return 1;
    }
  return 0;
}

=back

=head2 Administrative functions

=over 4

=item C<Automake::Variable::hook ($varname, $fun)>

Declare a function to be called whenever a variable
named C<$varname> is defined or redefined.

C<$fun> should take two arguments: C<$type> and C<$value>.
When type is C<''> or <':'>, C<$value> is the value being
assigned to C<$varname>.  When C<$type> is C<'+'>, C<$value>
is the value being appended to  C<$varname>.

=cut

use vars '%_hooks';
sub hook ($$)
{
  my ($var, $fun) = @_;
  $_hooks{$var} = $fun;
}

=item C<variables ([$suffix])>

Returns the list of all L<Automake::Variable> instances.  (I.e., all
variables defined so far.)  If C<$suffix> is supplied, return only
the L<Automake::Variable> instances that ends with C<_$suffix>.

=cut

use vars '%_variable_dict', '%_primary_dict';
sub variables (;$)
{
  my ($suffix) = @_;
  my @vars = ();
  if ($suffix)
    {
      if (exists $_primary_dict{$suffix})
	{
	  @vars = values %{$_primary_dict{$suffix}};
	}
    }
  else
    {
      @vars = values %_variable_dict;
    }
  # The behaviour of the 'sort' built-in is undefined in scalar
  # context, hence we need an ad-hoc handling for such context.
  return wantarray ? sort { $a->name cmp $b->name } @vars : scalar @vars;
}

=item C<Automake::Variable::reset>

The I<forget all> function.  Clears all know variables and reset some
other internal data.

=cut

sub reset ()
{
  %_variable_dict = ();
  %_primary_dict = ();
  $_appendvar = 0;
  @_var_order = ();
  %_gen_varname = ();
  %_gen_varname_n = ();
  $_traversal = 0;
}

=item C<var ($varname)>

Return the C<Automake::Variable> object for the variable
named C<$varname> if defined.  Return 0 otherwise.

=cut

sub var ($)
{
  my ($name) = @_;
  return $_variable_dict{$name} if exists $_variable_dict{$name};
  return 0;
}

=item C<vardef ($varname, $cond)>

Return the C<Automake::VarDef> object for the variable named
C<$varname> if defined in condition C<$cond>.  Return false
if the condition or the variable does not exist.

=cut

sub vardef ($$)
{
  my ($name, $cond) = @_;
  my $var = var $name;
  return $var && $var->def ($cond);
}

# Create the variable if it does not exist.
# This is used only by other functions in this package.
sub _cvar ($)
{
  my ($name) = @_;
  my $v = var $name;
  return $v if $v;
  return _new Automake::Variable $name;
}

=item C<rvar ($varname)>

Return the C<Automake::Variable> object for the variable named
C<$varname>.  Abort with an internal error if the variable was not
defined.

The I<r> in front of C<var> stands for I<required>.  One
should call C<rvar> to assert the variable's existence.

=cut

sub rvar ($)
{
  my ($name) = @_;
  my $v = var $name;
  prog_error ("undefined variable $name\n" . &variables_dump)
    unless $v;
  return $v;
}

=item C<rvardef ($varname, $cond)>

Return the C<Automake::VarDef> object for the variable named
C<$varname> if defined in condition C<$cond>.  Abort with an internal
error if the condition or the variable does not exist.

=cut

sub rvardef ($$)
{
  my ($name, $cond) = @_;
  return rvar ($name)->rdef ($cond);
}

=back

=head2 Methods

C<Automake::Variable> is a subclass of C<Automake::Item>.  See
that package for inherited methods.

Here are the methods specific to the C<Automake::Variable> instances.
Use the C<define> function, described latter, to create such objects.

=over 4

=cut

# Create Automake::Variable objects.  This is used
# only in this file.  Other users should use
# the "define" function.
sub _new ($$)
{
  my ($class, $name) = @_;
  my $self = Automake::Item::new ($class, $name);
  $self->{'scanned'} = 0;
  $self->{'last-append'} = []; # helper variable for last conditional append.
  $_variable_dict{$name} = $self;
  if ($name =~ /_([[:alnum:]]+)$/)
    {
      $_primary_dict{$1}{$name} = $self;
    }
  return $self;
}

# _check_ambiguous_condition ($SELF, $COND, $WHERE)
# -------------------------------------------------
# Check for an ambiguous conditional.  This is called when a variable
# is being defined conditionally.  If we already know about a
# definition that is true under the same conditions, then we have an
# ambiguity.
sub _check_ambiguous_condition ($$$)
{
  my ($self, $cond, $where) = @_;
  my $var = $self->name;
  my ($message, $ambig_cond) = $self->conditions->ambiguous_p ($var, $cond);

  # We allow silent variables to be overridden silently,
  # by either silent or non-silent variables.
  my $def = $self->def ($ambig_cond);
  if ($message && $def->pretty != VAR_SILENT)
    {
      msg 'syntax', $where, "$message ...", partial => 1;
      msg_var ('syntax', $var, "... '$var' previously defined here");
      verb ($self->dump);
    }
}

=item C<$bool = $var-E<gt>check_defined_unconditionally ([$parent, $parent_cond])>

Warn if the variable is conditionally defined.  C<$parent> is the name
of the parent variable, and C<$parent_cond> the condition of the parent
definition.  These two variables are used to display diagnostics.

=cut

sub check_defined_unconditionally ($;$$)
{
  my ($self, $parent, $parent_cond) = @_;

  if (!$self->conditions->true)
    {
      if ($parent)
	{
	  msg_cond_var ('unsupported', $parent_cond, $parent,
			"automake does not support conditional definition of "
			. $self->name . " in $parent");
	}
      else
	{
	  msg_var ('unsupported', $self,
		   "automake does not support " . $self->name
		   . " being defined conditionally");
	}
    }
}

=item C<$str = $var-E<gt>output ([@conds])>

Format all the definitions of C<$var> if C<@cond> is not specified,
else only that corresponding to C<@cond>.

=cut

sub output ($@)
{
  my ($self, @conds) = @_;

  @conds = $self->conditions->conds
    unless @conds;

  my $res = '';
  my $name = $self->name;

  foreach my $cond (@conds)
    {
      my $def = $self->def ($cond);
      prog_error ("unknown condition '" . $cond->human . "' for '"
		  . $self->name . "'")
	unless $def;

      next
	if $def->pretty == VAR_SILENT;

      $res .= $def->comment;

      my $val = $def->raw_value;
      my $equals = $def->type eq ':' ? ':=' : '=';
      my $str = $cond->subst_string;


      if ($def->pretty == VAR_ASIS)
	{
	  my $output_var = "$name $equals $val";
	  $output_var =~ s/^/$str/meg;
	  $res .= "$output_var\n";
	}
      elsif ($def->pretty == VAR_PRETTY)
	{
	  # Suppress escaped new lines.  &makefile_wrap will
	  # add them back, maybe at other places.
	  $val =~ s/\\$//mg;
	  my $wrap = makefile_wrap ("$str$name $equals", "$str\t",
				    split (' ', $val));

	  # If the last line of the definition is made only of
	  # @substitutions@, append an empty variable to make sure it
	  # cannot be substituted as a blank line (that would confuse
	  # HP-UX Make).
	  $wrap = makefile_wrap ("$str$name $equals", "$str\t",
				 split (' ', $val), '$(am__empty)')
	    if $wrap =~ /\n(\s*@\w+@)+\s*$/;

	  $res .= $wrap;
	}
      else # ($def->pretty == VAR_SORTED)
	{
	  # Suppress escaped new lines.  &makefile_wrap will
	  # add them back, maybe at other places.
	  $val =~ s/\\$//mg;
	  $res .= makefile_wrap ("$str$name $equals", "$str\t",
				 sort (split (' ' , $val)));
	}
    }
  return $res;
}

=item C<@values = $var-E<gt>value_as_list ($cond, [$parent, $parent_cond])>

Get the value of C<$var> as a list, given a specified condition,
without recursing through any subvariables.

C<$cond> is the condition of interest.  C<$var> does not need
to be defined for condition C<$cond> exactly, but it needs
to be defined for at most one condition implied by C<$cond>.

C<$parent> and C<$parent_cond> designate the name and the condition
of the parent variable, i.e., the variable in which C<$var> is
being expanded.  These are used in diagnostics.

For example, if C<A> is defined as "C<foo $(B) bar>" in condition
C<TRUE>, calling C<rvar ('A')->value_as_list (TRUE)> will return
C<("foo", "$(B)", "bar")>.

=cut

sub value_as_list ($$;$$)
{
  my ($self, $cond, $parent, $parent_cond) = @_;
  my @result;

  # Get value for given condition
  my $onceflag;
  foreach my $vcond ($self->conditions->conds)
    {
      if ($vcond->true_when ($cond))
	{
	  # If there is more than one definitions of $var matching
	  # $cond then we are in trouble: tell the user we need a
	  # paddle.  Continue by merging results from all conditions,
	  # although it doesn't make much sense.
	  $self->check_defined_unconditionally ($parent, $parent_cond)
	    if $onceflag;
	  $onceflag = 1;

	  my $val = $self->rdef ($vcond)->value;
	  push @result, split (' ', $val);
	}
    }
  return @result;
}

=item C<@values = $var-E<gt>value_as_list_recursive ([%options])>

Return the contents of C<$var> as a list, split on whitespace.  This
will recursively follow C<$(...)> and C<${...}> inclusions.  It
preserves C<@...@> substitutions.

C<%options> is a list of option for C<Variable::traverse_recursively>
(see this method).  The most useful is C<cond_filter>:

  $var->value_as_list_recursive (cond_filter => $cond)

will return the contents of C<$var> and any subvariable in all
conditions implied by C<$cond>.

C<%options> can also carry options specific to C<value_as_list_recursive>.
Presently, the only such option is C<location =E<gt> 1> which instructs
C<value_as_list_recursive> to return a list of C<[$location, @values]> pairs.

=cut

sub value_as_list_recursive ($;%)
{
  my ($var, %options) = @_;

  return $var->traverse_recursively
    (# Construct [$location, $value] pairs if requested.
     sub {
       my ($var, $val, $cond, $full_cond) = @_;
       return [$var->rdef ($cond)->location, $val] if $options{'location'};
       return $val;
     },
     # Collect results.
     sub {
       my ($var, $parent_cond, @allresults) = @_;
       return map { my ($cond, @vals) = @$_; @vals } @allresults;
     },
     %options);
}


=item C<$bool = $var-E<gt>has_conditional_contents>

Return 1 if C<$var> or one of its subvariable was conditionally
defined.  Return 0 otherwise.

=cut

sub has_conditional_contents ($)
{
  my ($self) = @_;

  # Traverse the variable recursively until we
  # find a variable defined conditionally.
  # Use 'die' to abort the traversal, and pass it '$full_cond'
  # to we can find easily whether the 'eval' block aborted
  # because we found a condition, or for some other error.
  eval
    {
      $self->traverse_recursively
	(sub
	 {
	   my ($subvar, $val, $cond, $full_cond) = @_;
	   die $full_cond if ! $full_cond->true;
	   return ();
	 },
	 sub { return (); });
    };
  if ($@)
    {
      return 1 if ref ($@) && $@->isa ("Automake::Condition");
      # Propagate other errors.
      die;
    }
  return 0;
}


=item C<$string = $var-E<gt>dump>

Return a string describing all we know about C<$var>.
For debugging.

=cut

sub dump ($)
{
  my ($self) = @_;

  my $text = $self->name . ": \n  {\n";
  foreach my $vcond ($self->conditions->conds)
    {
      $text .= "    " . $vcond->human . " => " . $self->rdef ($vcond)->dump;
    }
  $text .= "  }\n";
  return $text;
}


=back

=head2 Utility functions

=over 4

=item C<@list = scan_variable_expansions ($text)>

Return the list of variable names expanded in C<$text>.  Note that
unlike some other functions, C<$text> is not split on spaces before we
check for subvariables.

=cut

sub scan_variable_expansions ($)
{
  my ($text) = @_;
  my @result = ();

  # Strip comments.
  $text =~ s/#.*$//;

  # Record each use of ${stuff} or $(stuff) that does not follow a $.
  while ($text =~ /(?<!\$)\$(?:\{([^\}]*)\}|\(([^\)]*)\))/g)
    {
      my $var = $1 || $2;
      # The occurrence may look like $(string1[:subst1=[subst2]]) but
      # we want only 'string1'.
      $var =~ s/:[^:=]*=[^=]*$//;
      push @result, $var;
    }

  return @result;
}

=item C<check_variable_expansions ($text, $where)>

Check variable expansions in C<$text> and warn about any name that
does not conform to POSIX.  C<$where> is the location of C<$text>
for the error message.

=cut

sub check_variable_expansions ($$)
{
  my ($text, $where) = @_;
  # Catch expansion of variables whose name does not conform to POSIX.
  foreach my $var (scan_variable_expansions ($text))
    {
      if ($var !~ /$_VARIABLE_PATTERN/o)
	{
	  # If the variable name contains a space, it's likely
	  # to be a GNU make extension (such as $(addsuffix ...)).
	  # Mention this in the diagnostic.
	  my $gnuext = "";
	  $gnuext = "\n(probably a GNU make extension)" if $var =~ / /;
	  # Accept recursive variable expansions if so desired
	  # (we hope they are rather portable in practice).
	  if ($var =~ /$_VARIABLE_RECURSIVE_PATTERN/o)
	    {
	      msg ('portability-recursive', $where,
		   "$var: non-POSIX recursive variable expansion$gnuext");
	    }
	  else
	    {
	      msg ('portability', $where, "$var: non-POSIX variable name$gnuext");
	    }
	}
    }
}



=item C<Automake::Variable::define($varname, $owner, $type, $cond, $value, $comment, $where, $pretty)>

Define or append to a new variable.

C<$varname>: the name of the variable being defined.

C<$owner>: owner of the variable (one of C<VAR_MAKEFILE>,
C<VAR_CONFIGURE>, or C<VAR_AUTOMAKE>, defined by L<Automake::VarDef>).
Variables can be overridden, provided the new owner is not weaker
(C<VAR_AUTOMAKE> < C<VAR_CONFIGURE> < C<VAR_MAKEFILE>).

C<$type>: the type of the assignment (C<''> for C<FOO = bar>,
C<':'> for C<FOO := bar>, and C<'+'> for C<'FOO += bar'>).

C<$cond>: the C<Condition> in which C<$var> is being defined.

C<$value>: the value assigned to C<$var> in condition C<$cond>.

C<$comment>: any comment (C<'# bla.'>) associated with the assignment.
Comments from C<+=> assignments stack with comments from the last C<=>
assignment.

C<$where>: the C<Location> of the assignment.

C<$pretty>: whether C<$value> should be pretty printed (one of
C<VAR_ASIS>, C<VAR_PRETTY>, C<VAR_SILENT>, or C<VAR_SORTED>, defined
by by L<Automake::VarDef>).  C<$pretty> applies only to real
assignments.  I.e., it does not apply to a C<+=> assignment (except
when part of it is being done as a conditional C<=> assignment).

This function will all run any hook registered with the C<hook>
function.

=cut

sub define ($$$$$$$$)
{
  my ($var, $owner, $type, $cond, $value, $comment, $where, $pretty) = @_;

  prog_error "$cond is not a reference"
    unless ref $cond;

  prog_error "$where is not a reference"
    unless ref $where;

  prog_error "pretty argument missing"
    unless defined $pretty && ($pretty == VAR_ASIS
			       || $pretty == VAR_PRETTY
			       || $pretty == VAR_SILENT
			       || $pretty == VAR_SORTED);

  error $where, "bad characters in variable name '$var'"
    if $var !~ /$_VARIABLE_PATTERN/o;

  # ':='-style assignments are not acknowledged by POSIX.  Moreover it
  # has multiple meanings.  In GNU make or BSD make it means "assign
  # with immediate expansion", while in OSF make it is used for
  # conditional assignments.
  msg ('portability', $where, "':='-style assignments are not portable")
    if $type eq ':';

  check_variable_expansions ($value, $where);

  # If there's a comment, make sure it is \n-terminated.
  if ($comment)
    {
      chomp $comment;
      $comment .= "\n";
    }
  else
    {
      $comment = '';
    }

  my $self = _cvar $var;

  my $def = $self->def ($cond);
  my $new_var = $def ? 0 : 1;

  # Additional checks for Automake definitions.
  if ($owner == VAR_AUTOMAKE && ! $new_var)
    {
      # An Automake variable must be consistently defined with the same
      # sign by Automake.
      if ($def->type ne $type && $def->owner == VAR_AUTOMAKE)
	{
	  error ($def->location,
		 "Automake variable '$var' was set with '"
		 . $def->type . "=' here ...", partial => 1);
	  error ($where, "... and is now set with '$type=' here.");
	  prog_error ("Automake variable assignments should be consistently\n"
		      . "defined with the same sign");
	}

      # If Automake tries to override a value specified by the user,
      # just don't let it do.
      if ($def->owner != VAR_AUTOMAKE)
	{
	  if (! exists $_silent_variable_override{$var})
	    {
	      my $condmsg = ($cond == TRUE
			     ? '' : (" in condition '" . $cond->human . "'"));
	      msg_cond_var ('override', $cond, $var,
			    "user variable '$var' defined here$condmsg ...",
			    partial => 1);
	      msg ('override', $where,
		   "... overrides Automake variable '$var' defined here");
	    }
	  verb ("refusing to override the user definition of:\n"
		. $self->dump ."with '" . $cond->human . "' => '$value'");
	  return;
	}
    }

  # Differentiate assignment types.

  # 1. append (+=) to a variable defined for current condition
  if ($type eq '+' && ! $new_var)
    {
      $def->append ($value, $comment);
      $self->{'last-append'} = [];

      # Only increase owners.  A VAR_CONFIGURE variable augmented in a
      # Makefile.am becomes a VAR_MAKEFILE variable.
      $def->set_owner ($owner, $where->clone)
	if $owner > $def->owner;
    }
  # 2. append (+=) to a variable defined for *another* condition
  elsif ($type eq '+' && ! $self->conditions->false)
    {
      # * Generally, $cond is not TRUE.  For instance:
      #     FOO = foo
      #     if COND
      #       FOO += bar
      #     endif
      #   In this case, we declare an helper variable conditionally,
      #   and append it to FOO:
      #     FOO = foo $(am__append_1)
      #     @COND_TRUE@am__append_1 = bar
      #   Of course if FOO is defined under several conditions, we add
      #   $(am__append_1) to each definitions.
      #
      # * If $cond is TRUE, we don't need the helper variable.  E.g., in
      #     if COND1
      #       FOO = foo1
      #     else
      #       FOO = foo2
      #     endif
      #     FOO += bar
      #   we can add bar directly to all definition of FOO, and output
      #     @COND_TRUE@FOO = foo1 bar
      #     @COND_FALSE@FOO = foo2 bar

      my $lastappend = [];
      # Do we need an helper variable?
      if ($cond != TRUE)
        {
	  # Can we reuse the helper variable created for the previous
	  # append?  (We cannot reuse older helper variables because
	  # we must preserve the order of items appended to the
	  # variable.)
	  my $condstr = $cond->string;
	  my $key = "$var:$condstr";
	  my ($appendvar, $appendvarcond) = @{$self->{'last-append'}};
	  if ($appendvar && $condstr eq $appendvarcond)
	    {
	      # Yes, let's simply append to it.
	      $var = $appendvar;
	      $owner = VAR_AUTOMAKE;
	      $self = var ($var);
	      $def = $self->rdef ($cond);
	      $new_var = 0;
	    }
	  else
	    {
	      # No, create it.
	      my $num = ++$_appendvar;
	      my $hvar = "am__append_$num";
	      $lastappend = [$hvar, $condstr];
	      &define ($hvar, VAR_AUTOMAKE, '+',
		       $cond, $value, $comment, $where, $pretty);

	      # Now HVAR is to be added to VAR.
	      $comment = '';
	      $value = "\$($hvar)";
	    }
	}

      # Add VALUE to all definitions of SELF.
      foreach my $vcond ($self->conditions->conds)
        {
	  # We have a bit of error detection to do here.
	  # This:
	  #   if COND1
	  #     X = Y
	  #   endif
	  #   X += Z
	  # should be rejected because X is not defined for all conditions
	  # where '+=' applies.
	  my $undef_cond = $self->not_always_defined_in_cond ($cond);
	  if (! $undef_cond->false)
	    {
	      error ($where,
		     "cannot apply '+=' because '$var' is not defined "
		     . "in\nthe following conditions:\n  "
		     . join ("\n  ", map { $_->human } $undef_cond->conds)
		     . "\neither define '$var' in these conditions,"
		     . " or use\n'+=' in the same conditions as"
		     . " the definitions.");
	    }
	  else
	    {
	      &define ($var, $owner, '+', $vcond, $value, $comment,
		       $where, $pretty);
	    }
	}
      $self->{'last-append'} = $lastappend;
    }
  # 3. first assignment (=, :=, or +=)
  else
    {
      # There must be no previous value unless the user is redefining
      # an Automake variable or an AC_SUBST variable for an existing
      # condition.
      _check_ambiguous_condition ($self, $cond, $where)
	unless (!$new_var
		&& (($def->owner == VAR_AUTOMAKE && $owner != VAR_AUTOMAKE)
		    || $def->owner == VAR_CONFIGURE));

      # Never decrease an owner.
      $owner = $def->owner
	if ! $new_var && $owner < $def->owner;

      # Assignments to a macro set its location.  We don't adjust
      # locations for '+='.  Ideally I suppose we would associate
      # line numbers with random bits of text.
      $def = new Automake::VarDef ($var, $value, $comment, $where->clone,
				   $type, $owner, $pretty);
      $self->set ($cond, $def);
      push @_var_order, $var;
    }

  # Call any defined hook.  This helps to update some internal state
  # *while* parsing the file.  For instance the handling of SUFFIXES
  # requires this (see var_SUFFIXES_trigger).
  &{$_hooks{$var}}($type, $value) if exists $_hooks{$var};
}

=item C<variable_delete ($varname, [@conds])>

Forget about C<$varname> under the conditions C<@conds>, or completely
if C<@conds> is empty.

=cut

sub variable_delete ($@)
{
  my ($var, @conds) = @_;

  if (!@conds)
    {
      delete $_variable_dict{$var};
    }
  else
    {
      for my $cond (@conds)
	{
	  delete $_variable_dict{$var}{'defs'}{$cond};
	}
    }
  if ($var =~ /_([[:alnum:]]+)$/)
    {
      delete $_primary_dict{$1}{$var};
    }
}

=item C<$str = variables_dump>

Return a string describing all we know about all variables.
For debugging.

=cut

sub variables_dump ()
{
  my $text = "all variables:\n{\n";
  foreach my $var (variables())
    {
      $text .= $var->dump;
    }
  $text .= "}\n";
  return $text;
}


=item C<$var = set_seen ($varname)>

=item C<$var = $var-E<gt>set_seen>

Mark all definitions of this variable as examined, if the variable
exists.  See L<Automake::VarDef::set_seen>.

Return the C<Variable> object if the variable exists, or 0
otherwise (i.e., as the C<var> function).

=cut

sub set_seen ($)
{
  my ($self) = @_;
  $self = ref $self ? $self : var $self;

  return 0 unless $self;

  for my $c ($self->conditions->conds)
    {
      $self->rdef ($c)->set_seen;
    }

  return $self;
}


=item C<$count = require_variables ($where, $reason, $cond, @variables)>

Make sure that each supplied variable is defined in C<$cond>.
Otherwise, issue a warning showing C<$reason> (C<$reason> should be
the reason why these variables are required, for instance C<'option foo
used'>).  If we know which macro can define this variable, hint the
user.  Return the number of undefined variables.

=cut

sub require_variables ($$$@)
{
  my ($where, $reason, $cond, @vars) = @_;
  my $res = 0;
  $reason .= ' but ' unless $reason eq '';

  $configure_ac = find_configure_ac
    unless defined $configure_ac;

 VARIABLE:
  foreach my $var (@vars)
    {
      # Nothing to do if the variable exists.
      next VARIABLE
	if vardef ($var, $cond);

      my $text = "$reason'$var' is undefined\n";
      my $v = var $var;
      if ($v)
	{
	  my $undef_cond = $v->not_always_defined_in_cond ($cond);
	  next VARIABLE
	    if $undef_cond->false;
	  $text .= ("in the following conditions:\n  "
		    . join ("\n  ", map { $_->human } $undef_cond->conds)
		    . "\n");
	}

      ++$res;

      if (exists $_am_macro_for_var{$var})
	{
	  my $mac = $_am_macro_for_var{$var};
	  $text .= "  The usual way to define '$var' is to add "
	    . "'$mac'\n  to '$configure_ac' and run 'aclocal' and "
	    . "'autoconf' again.";
	  # aclocal will not warn about undefined macros unless it
	  # starts with AM_.
	  $text .= "\n  If '$mac' is in '$configure_ac', make sure\n"
	    . "  its definition is in aclocal's search path."
	    unless $mac =~ /^AM_/;
	}
      elsif (exists $_ac_macro_for_var{$var})
	{
	  $text .= "  The usual way to define '$var' is to add "
	    . "'$_ac_macro_for_var{$var}'\n  to '$configure_ac' and "
	    . "run 'autoconf' again.";
	}

      error $where, $text, uniq_scope => US_GLOBAL;
    }
  return $res;
}

=item C<$count = $var->requires_variables ($reason, @variables)>

Same as C<require_variables>, but a method of Automake::Variable.
C<@variables> should be defined in the same conditions as C<$var> is
defined.

=cut

sub requires_variables ($$@)
{
  my ($var, $reason, @args) = @_;
  my $res = 0;
  for my $cond ($var->conditions->conds)
    {
      $res += require_variables ($var->rdef ($cond)->location, $reason,
				 $cond, @args);
    }
  return $res;
}


=item C<variable_value ($var)>

Get the C<TRUE> value of a variable, warn if the variable is
conditionally defined.  C<$var> can be either a variable name
or a C<Automake::Variable> instance (this allows calls such
as C<$var-E<gt>variable_value>).

=cut

sub variable_value ($)
{
    my ($var) = @_;
    my $v = ref ($var) ? $var : var ($var);
    return () unless $v;
    $v->check_defined_unconditionally;
    my $d = $v->def (TRUE);
    return $d ? $d->value : "";
}

=item C<$str = output_variables>

Format definitions for all variables.

=cut

sub output_variables ()
{
  my $res = '';
  # We output variables it in the same order in which they were
  # defined (skipping duplicates).
  my @vars = uniq @_var_order;

  # Output all the Automake variables.  If the user changed one,
  # then it is now marked as VAR_CONFIGURE or VAR_MAKEFILE.
  foreach my $var (@vars)
    {
      my $v = rvar $var;
      foreach my $cond ($v->conditions->conds)
	{
	  $res .= $v->output ($cond)
	    if $v->rdef ($cond)->owner == VAR_AUTOMAKE;
	}
    }

  # Now dump the user variables that were defined.
  foreach my $var (@vars)
    {
      my $v = rvar $var;
      foreach my $cond ($v->conditions->conds)
	{
	  $res .= $v->output ($cond)
	    if $v->rdef ($cond)->owner != VAR_AUTOMAKE;
	}
    }
  return $res;
}

=item C<$var-E<gt>traverse_recursively (&fun_item, &fun_collect, [cond_filter =E<gt> $cond_filter], [inner_expand =E<gt> 1], [skip_ac_subst =E<gt> 1])>

Split the value of the Automake::Variable C<$var> on space, and
traverse its components recursively.

If C<$cond_filter> is an C<Automake::Condition>, process any
conditions which are true when C<$cond_filter> is true.  Otherwise,
process all conditions.

We distinguish two kinds of items in the content of C<$var>.
Terms that look like C<$(foo)> or C<${foo}> are subvariables
and cause recursion.  Other terms are assumed to be filenames.

Each time a filename is encountered, C<&fun_item> is called with the
following arguments:

  ($var,        -- the Automake::Variable we are currently
                   traversing
   $val,        -- the item (i.e., filename) to process
   $cond,       -- the Condition for the $var definition we are
                   examining (ignoring the recursion context)
   $full_cond)  -- the full Condition, taking into account
                   conditions inherited from parent variables
                   during recursion

If C<inner_expand> is set, variable references occurring in filename
(as in C<$(BASE).ext>) are expanded before the filename is passed to
C<&fun_item>.

If C<skip_ac_subst> is set, Autoconf @substitutions@ will be skipped,
i.e., C<&fun_item> will never be called for them.

C<&fun_item> may return a list of items, they will be passed to
C<&fun_store> later on.  Define C<&fun_item> or @<&fun_store> as
C<undef> when they serve no purpose.

Once all items of a variable have been processed, the result (of the
calls to C<&fun_items>, or of recursive traversals of subvariables)
are passed to C<&fun_collect>.  C<&fun_collect> receives three
arguments:

  ($var,         -- the variable being traversed
   $parent_cond, -- the Condition inherited from parent
                    variables during recursion
   @condlist)    -- a list of [$cond, @results] pairs
                    where each $cond appear only once, and @result
                    are all the results for this condition.

Typically you should do C<$cond->merge ($parent_cond)> to recompute
the C<$full_cond> associated to C<@result>.  C<&fun_collect> may
return a list of items, that will be used as the result of
C<Automake::Variable::traverse_recursively> (the top-level, or its
recursive calls).

=cut

# Contains a stack of 'from' and 'to' parts of variable
# substitutions currently in force.
my @_substfroms;
my @_substtos;
sub traverse_recursively ($&&;%)
{
  ++$_traversal;
  @_substfroms = ();
  @_substtos = ();
  my ($var, $fun_item, $fun_collect, %options) = @_;
  my $cond_filter = $options{'cond_filter'};
  my $inner_expand = $options{'inner_expand'};
  my $skip_ac_subst = $options{'skip_ac_subst'};
  return $var->_do_recursive_traversal ($var,
					$fun_item, $fun_collect,
					$cond_filter, TRUE, $inner_expand,
					$skip_ac_subst)
}

# The guts of Automake::Variable::traverse_recursively.
sub _do_recursive_traversal ($$&&$$$$)
{
  my ($var, $parent, $fun_item, $fun_collect, $cond_filter, $parent_cond,
      $inner_expand, $skip_ac_subst) = @_;

  $var->set_seen;

  if ($var->{'scanned'} == $_traversal)
    {
      err_var $var, "variable '" . $var->name() . "' recursively defined";
      return ();
    }
  $var->{'scanned'} = $_traversal;

  my @allresults = ();
  my $cond_once = 0;
  foreach my $cond ($var->conditions->conds)
    {
      if (ref $cond_filter)
	{
	  # Ignore conditions that don't match $cond_filter.
	  next if ! $cond->true_when ($cond_filter);
	  # If we found out several definitions of $var
	  # match $cond_filter then we are in trouble.
	  # Tell the user we don't support this.
	  $var->check_defined_unconditionally ($parent, $parent_cond)
	    if $cond_once;
	  $cond_once = 1;
	}
      my @result = ();
      my $full_cond = $cond->merge ($parent_cond);

      my @to_process = $var->value_as_list ($cond, $parent, $parent_cond);
      while (@to_process)
	{
	  my $val = shift @to_process;
	  # If $val is a variable (i.e. ${foo} or $(bar), not a filename),
	  # handle the sub variable recursively.
	  # (Backslashes before '}' and ')' within brackets are here to
	  # please Emacs's indentation.)
	  if ($val =~ /^\$\{([^\}]*)\}$/ || $val =~ /^\$\(([^\)]*)\)$/)
	    {
	      my $subvarname = $1;

	      # If the user uses a losing variable name, just ignore it.
	      # This isn't ideal, but people have requested it.
	      next if ($subvarname =~ /\@.*\@/);

	      # See if the variable is actually a substitution reference
	      my ($from, $to);
              # This handles substitution references like ${foo:.a=.b}.
	      if ($subvarname =~ /^([^:]*):([^=]*)=(.*)$/o)
		{
		  $subvarname = $1;
		  $to = $3;
		  $from = quotemeta $2;
		}

	      my $subvar = var ($subvarname);
	      # Don't recurse into undefined variables.
	      next unless $subvar;

	      push @_substfroms, $from;
	      push @_substtos, $to;

	      my @res = $subvar->_do_recursive_traversal ($parent,
							  $fun_item,
							  $fun_collect,
							  $cond_filter,
							  $full_cond,
							  $inner_expand,
							  $skip_ac_subst);
	      push (@result, @res);

	      pop @_substfroms;
	      pop @_substtos;

	      next;
	    }
	  # Try to expand variable references inside filenames such as
	  # '$(NAME).txt'.  We do not handle ':.foo=.bar'
	  # substitutions, but it would make little sense to use this
	  # here anyway.
	  elsif ($inner_expand
		 && ($val =~ /\$\{([^\}]*)\}/ || $val =~ /\$\(([^\)]*)\)/))
	    {
	      my $subvarname = $1;
	      my $subvar = var $subvarname;
	      if ($subvar)
		{
		  # Replace the reference by its value, and reschedule
		  # for expansion.
		  foreach my $c ($subvar->conditions->conds)
		    {
		      if (ref $cond_filter)
			{
			  # Ignore conditions that don't match $cond_filter.
			  next if ! $c->true_when ($cond_filter);
			  # If we found out several definitions of $var
			  # match $cond_filter then we are in trouble.
			  # Tell the user we don't support this.
			  $subvar->check_defined_unconditionally ($var,
								  $full_cond)
			    if $cond_once;
			  $cond_once = 1;
			}
		      my $subval = $subvar->rdef ($c)->value;
		      $val =~ s/\$\{$subvarname\}/$subval/g;
		      $val =~ s/\$\($subvarname\)/$subval/g;
		      unshift @to_process, split (' ', $val);
		    }
		  next;
		}
	      # We do not know any variable with this name.  Fall through
	      # to filename processing.
	    }
	  elsif ($skip_ac_subst && $val =~ /^\@.+\@$/)
	    {
	      next;
	    }

	  if ($fun_item) # $var is a filename we must process
	    {
	      my $substnum=$#_substfroms;
	      while ($substnum >= 0)
		{
		  $val =~ s/$_substfroms[$substnum]$/$_substtos[$substnum]/
		    if defined $_substfroms[$substnum];
		  $substnum -= 1;
		}

	      # Make sure you update the doc of
	      # Automake::Variable::traverse_recursively
	      # if you change the prototype of &fun_item.
	      my @transformed = &$fun_item ($var, $val, $cond, $full_cond);
	      push (@result, @transformed);
	    }
	}
      push (@allresults, [$cond, @result]) if @result;
    }

  # We only care about _recursive_ variable definitions.  The user
  # is free to use the same variable several times in the same definition.
  $var->{'scanned'} = -1;

  return ()
    unless $fun_collect;
  # Make sure you update the doc of Automake::Variable::traverse_recursively
  # if you change the prototype of &fun_collect.
  return &$fun_collect ($var, $parent_cond, @allresults);
}

# _hash_varname ($VAR)
# --------------------
# Compute the key associated $VAR in %_gen_varname.
# See _gen_varname() below.
sub _hash_varname ($)
{
  my ($var) = @_;
  my $key = '';
  foreach my $cond ($var->conditions->conds)
    {
      my @values = $var->value_as_list ($cond);
      $key .= "($cond)@values";
    }
  return $key;
}

# _hash_values (@VALUES)
# ----------------------
# Hash @VALUES for %_gen_varname.  @VALUES should be a list
# of pairs: ([$cond, @values], [$cond, @values], ...).
# See _gen_varname() below.
sub _hash_values (@)
{
  my $key = '';
  foreach my $pair (@_)
    {
      my ($cond, @values) = @$pair;
      $key .= "($cond)@values";
    }
  return $key;
}
# ($VARNAME, $GENERATED)
# _gen_varname ($BASE, @DEFINITIONS)
# ----------------------------------
# Return a variable name starting with $BASE, that will be
# used to store definitions @DEFINITIONS.
# @DEFINITIONS is a list of pair [$COND, @OBJECTS].
#
# If we already have a $BASE-variable containing @DEFINITIONS, reuse
# it and set $GENERATED to 0.  Otherwise construct a new name and set
# $GENERATED to 1.
#
# This way, we avoid combinatorial explosion of the generated
# variables.  Especially, in a Makefile such as:
#
# | if FOO1
# | A1=1
# | endif
# |
# | if FOO2
# | A2=2
# | endif
# |
# | ...
# |
# | if FOON
# | AN=N
# | endif
# |
# | B=$(A1) $(A2) ... $(AN)
# |
# | c_SOURCES=$(B)
# | d_SOURCES=$(B)
#
# The generated c_OBJECTS and d_OBJECTS will share the same variable
# definitions.
#
# This setup can be the case of a testsuite containing lots (>100) of
# small C programs, all testing the same set of source files.
sub _gen_varname ($@)
{
  my $base = shift;
  my $key = _hash_values @_;

  return ($_gen_varname{$base}{$key}, 0)
    if exists $_gen_varname{$base}{$key};

  my $num = 1 + ($_gen_varname_n{$base} || 0);
  $_gen_varname_n{$base} = $num;
  my $name = "${base}_${num}";
  $_gen_varname{$base}{$key} = $name;

  return ($name, 1);
}

=item C<$resvar = transform_variable_recursively ($var, $resvar, $base, $nodefine, $where, &fun_item, [%options])>

=item C<$resvar = $var-E<gt>transform_variable_recursively ($resvar, $base, $nodefine, $where, &fun_item, [%options])>

Traverse C<$var> recursively, and create a C<$resvar> variable in
which each filename in C<$var> have been transformed using
C<&fun_item>.  (C<$var> may be a variable name in the first syntax.
It must be an C<Automake::Variable> otherwise.)

Helper variables (corresponding to sub-variables of C<$var>) are
created as needed, using C<$base> as prefix.

Arguments are:
  $var       source variable to traverse
  $resvar    resulting variable to define
  $base      prefix to use when naming subvariables of $resvar
  $nodefine  if true, traverse $var but do not define any variable
             (this assumes &fun_item has some useful side-effect)
  $where     context into which variable definitions are done
  &fun_item  a transformation function -- see the documentation
             of &fun_item in Automake::Variable::traverse_recursively.

This returns the string C<"\$($RESVAR)">.

C<%options> is a list of options to pass to
C<Variable::traverse_recursively> (see this method).

=cut

sub transform_variable_recursively ($$$$$&;%)
{
  my ($var, $resvar, $base, $nodefine, $where, $fun_item, %options) = @_;

  $var = ref $var ? $var : rvar $var;

  my $res = $var->traverse_recursively
    ($fun_item,
     # The code that defines the variable holding the result
     # of the recursive transformation of a subvariable.
     sub {
       my ($subvar, $parent_cond, @allresults) = @_;
       # If no definition is required, return anything: the result is
       # not expected to be used, only the side effect of $fun_item
       # should matter.
       return 'report-me' if $nodefine;
       # Cache $subvar, so that we reuse it if @allresults is the same.
       my $key = _hash_varname $subvar;
       $_gen_varname{$base}{$key} = $subvar->name;

       # Find a name for the variable, unless this is the top-variable
       # for which we want to use $resvar.
       my ($varname, $generated) =
	 ($var != $subvar) ? _gen_varname ($base, @allresults) : ($resvar, 1);

       # Define the variable if we are not reusing a previously
       # defined variable.  At the top-level, we can also avoid redefining
       # the variable if it already contains the same values.
       if ($generated
	   && !($varname eq $var->name && $key eq _hash_values @allresults))
	 {
	   # If the new variable is the source variable, we assume
	   # we are trying to override a user variable.  Delete
	   # the old variable first.
	   variable_delete ($varname) if $varname eq $var->name;
	   # Define an empty variable in condition TRUE if there is no
	   # result.
	   @allresults = ([TRUE, '']) unless @allresults;
	   # Define the rewritten variable in all conditions not
	   # already covered by user definitions.
	   foreach my $pair (@allresults)
	     {
	       my ($cond, @result) = @$pair;
	       my $var = var $varname;
	       my @conds = ($var
			    ? $var->not_always_defined_in_cond ($cond)->conds
			    : $cond);

	       foreach (@conds)
		 {
		   define ($varname, VAR_AUTOMAKE, '', $_, "@result",
			   '', $where, VAR_PRETTY);
		 }
	     }
	 }
       set_seen $varname;
       return "\$($varname)";
     },
     %options);
  return $res;
}


=back

=head1 SEE ALSO

L<Automake::VarDef>, L<Automake::Condition>,
L<Automake::DisjConditions>, L<Automake::Location>.

=cut

1;

### Setup "GNU" style for perl-mode and cperl-mode.
## Local Variables:
## perl-indent-level: 2
## perl-continued-statement-offset: 2
## perl-continued-brace-offset: 0
## perl-brace-offset: 0
## perl-brace-imaginary-offset: 0
## perl-label-offset: -2
## cperl-indent-level: 2
## cperl-brace-offset: 0
## cperl-continued-brace-offset: 0
## cperl-label-offset: -2
## cperl-extra-newline-before-brace: t
## cperl-merge-trailing-else: nil
## cperl-continued-statement-offset: 2
## End:
