# 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::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',
   );

my $configure_ac = '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) = @_;
  if ($suffix)
    {
      if (exists $_primary_dict{$suffix})
	{
	  return values %{$_primary_dict{$suffix}};
	}
      else
	{
	  return ();
	}
    }
  else
    {
      return values %_variable_dict;
    }
}

=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 (sort { $a->name cmp $b->name } 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 '';

 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:
