<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># Copyright (C) 2003, 2004, 2006  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 &lt;http://www.gnu.org/licenses/&gt;.

package Automake::VarDef;
use strict;
use Carp;
use Automake::ChannelDefs;
use Automake::ItemDef;

require Exporter;
use vars '@ISA', '@EXPORT';
@ISA = qw/Automake::ItemDef Exporter/;
@EXPORT = qw (&amp;VAR_AUTOMAKE &amp;VAR_CONFIGURE &amp;VAR_MAKEFILE
	      &amp;VAR_ASIS &amp;VAR_PRETTY &amp;VAR_SILENT &amp;VAR_SORTED);

=head1 NAME

Automake::VarDef - a class for variable definitions

=head1 SYNOPSIS

  use Automake::VarDef;
  use Automake::Location;

  # Create a VarDef for a definition such as
  # | # any comment
  # | foo = bar # more comment
  # in Makefile.am
  my $loc = new Automake::Location 'Makefile.am:2';
  my $def = new Automake::VarDef ('foo', 'bar # more comment',
                                  '# any comment',
                                  $loc, '', VAR_MAKEFILE, VAR_ASIS);

  # Appending to a definition.
  $def-&gt;append ('value to append', 'comment to append');

  # Accessors.
  my $value    = $def-&gt;value;  # with trailing `#' comments and
                               # continuation ("\\\n") omitted.
  my $value    = $def-&gt;raw_value; # the real value, as passed to new().
  my $comment  = $def-&gt;comment;
  my $location = $def-&gt;location;
  my $type     = $def-&gt;type;
  my $owner    = $def-&gt;owner;
  my $pretty   = $def-&gt;pretty;

  # Changing owner.
  $def-&gt;set_owner (VAR_CONFIGURE,
                   new Automake::Location 'configure.ac:15');

  # Marking examined definitions.
  $def-&gt;set_seen;
  my $seen_p = $def-&gt;seen;

  # Printing a variable for debugging.
  print STDERR $def-&gt;dump;

=head1 DESCRIPTION

This class gathers data related to one Makefile-variable definition.

=head2 Constants

=over 4

=item C&lt;VAR_AUTOMAKE&gt;, C&lt;VAR_CONFIGURE&gt;, C&lt;VAR_MAKEFILE&gt;

Possible owners for variables.  A variable can be defined
by Automake, in F&lt;configure.ac&gt; (using C&lt;AC_SUBST&gt;), or in
the user's F&lt;Makefile.am&gt;.

=cut

# Defined so that the owner of a variable can only be increased (e.g
# Automake should not override a configure or Makefile variable).
use constant VAR_AUTOMAKE =&gt; 0; # Variable defined by Automake.
use constant VAR_CONFIGURE =&gt; 1;# Variable defined in configure.ac.
use constant VAR_MAKEFILE =&gt; 2; # Variable defined in Makefile.am.

=item C&lt;VAR_ASIS&gt;, C&lt;VAR_PRETTY&gt;, C&lt;VAR_SILENT&gt;, C&lt;VAR_SORTED&gt;

Possible print styles.  C&lt;VAR_ASIS&gt; variables should be output as-is.
C&lt;VAR_PRETTY&gt; variables are wrapped on multiple lines if they cannot
fit on one.  C&lt;VAR_SILENT&gt; variables are not output at all.  Finally,
C&lt;VAR_SORTED&gt; variables should be sorted and then handled as
C&lt;VAR_PRETTY&gt; variables.

C&lt;VAR_SILENT&gt; variables can also be overridden silently (unlike the
other kinds of variables whose overriding may sometimes produce
warnings).

=cut

# Possible values for pretty.
use constant VAR_ASIS =&gt; 0;	# Output as-is.
use constant VAR_PRETTY =&gt; 1;	# Pretty printed on output.
use constant VAR_SILENT =&gt; 2;	# Not output.  (Can also be
				# overridden silently.)
use constant VAR_SORTED =&gt; 3;	# Sorted and pretty-printed.

=back

=head2 Methods

C&lt;VarDef&gt; defines the following methods in addition to those inherited
from L&lt;Automake::ItemDef&gt;.

=over 4

=item C&lt;my $def = new Automake::VarDef ($varname, $value, $comment, $location, $type, $owner, $pretty)&gt;

Create a new Makefile-variable definition.  C&lt;$varname&gt; is the name of
the variable being defined and C&lt;$value&gt; its value.

C&lt;$comment&gt; is any comment preceding the definition.  (Because
Automake reorders variable definitions in the output, it also tries to
carry comments around.)

C&lt;$location&gt; is the place where the definition occurred, it should be
an instance of L&lt;Automake::Location&gt;.

C&lt;$type&gt; should be C&lt;''&gt; for definitions made with C&lt;=&gt;, and C&lt;':'&gt;
for those made with C&lt;:=&gt;.

C&lt;$owner&gt; specifies who owns the variables, it can be one of
C&lt;VAR_AUTOMAKE&gt;, C&lt;VAR_CONFIGURE&gt;, or C&lt;VAR_MAKEFILE&gt; (see these
definitions).

Finally, C&lt;$pretty&gt; tells how the variable should be output, and can
be one of C&lt;VAR_ASIS&gt;, C&lt;VAR_PRETTY&gt;, or C&lt;VAR_SILENT&gt;, or
C&lt;VAR_SORTED&gt; (see these definitions).

=cut

sub new ($$$$$$$$)
{
  my ($class, $var, $value, $comment, $location, $type, $owner, $pretty) = @_;

  # A user variable must be set by either `=' or `:=', and later
  # promoted to `+='.
  if ($owner != VAR_AUTOMAKE &amp;&amp; $type eq '+')
    {
      error $location, "$var must be set with `=' before using `+='";
    }

  my $self = Automake::ItemDef::new ($class, $comment, $location, $owner);
  $self-&gt;{'value'} = $value;
  $self-&gt;{'type'} = $type;
  $self-&gt;{'pretty'} = $pretty;
  $self-&gt;{'seen'} = 0;
  return $self;
}

=item C&lt;$def-E&lt;gt&gt;append ($value, $comment)&gt;

Append C&lt;$value&gt; and &lt;$comment&gt; to the existing value and comment of
C&lt;$def&gt;.  This is normally called on C&lt;+=&gt; definitions.

=cut

sub append ($$$)
{
  my ($self, $value, $comment) = @_;
  $self-&gt;{'comment'} .= $comment;

  my $val = $self-&gt;{'value'};

  # Strip comments from augmented variables.  This is so that
  #   VAR = foo # com
  #   VAR += bar
  # does not become
  #   VAR = foo # com bar
  # Furthermore keeping `#' would not be portable if the variable is
  # output on multiple lines.
  $val =~ s/ ?#.*//;
  # Insert a separator, if required.
  $val .= ' ' if $val;
  $self-&gt;{'value'} = $val . $value;
  # Turn ASIS appended variables into PRETTY variables.  This is to
  # cope with `make' implementation that cannot read very long lines.
  $self-&gt;{'pretty'} = VAR_PRETTY if $self-&gt;{'pretty'} == VAR_ASIS;
}

=item C&lt;$def-E&lt;gt&gt;value&gt;

=item C&lt;$def-E&lt;gt&gt;type&gt;

=item C&lt;$def-E&lt;gt&gt;pretty&gt;

Accessors to the various constituents of a C&lt;VarDef&gt;.  See the
documentation of C&lt;new&gt;'s arguments for a description of these.

=cut

sub value ($)
{
  my ($self) = @_;
  my $val = $self-&gt;raw_value;
  # Strip anything past `#'.  `#' characters cannot be escaped
  # in Makefiles, so we don't have to be smart.
  $val =~ s/#.*$//s;
  # Strip backslashes.
  $val =~ s/\\$/ /mg;
  return $val;
}

sub raw_value ($)
{
  my ($self) = @_;
  return $self-&gt;{'value'};
}

sub type ($)
{
  my ($self) = @_;
  return $self-&gt;{'type'};
}

sub pretty ($)
{
  my ($self) = @_;
  return $self-&gt;{'pretty'};
}

=item C&lt;$def-E&lt;gt&gt;set_owner ($owner, $location)&gt;

Change the owner of a definition.  This usually happens because
the user used C&lt;+=&gt; on an Automake variable, so (s)he now owns
the content.  C&lt;$location&gt; should be an instance of L&lt;Automake::Location&gt;
indicating where the change took place.

=cut

sub set_owner ($$$)
{
  my ($self, $owner, $location) = @_;
  # We always adjust the location when the owner changes (even for
  # `+=' statements).  The risk otherwise is to warn about
  # a VAR_MAKEFILE variable and locate it in configure.ac...
  $self-&gt;{'owner'} = $owner;
  $self-&gt;{'location'} = $location;
}

=item C&lt;$def-E&lt;gt&gt;set_seen&gt;

=item C&lt;$bool = $def-E&lt;gt&gt;seen&gt;

These function allows Automake to mark (C&lt;set_seen&gt;) variable that
it has examined in some way, and latter check (using C&lt;seen&gt;) for
unused variables.  Unused variables usually indicate typos.

=cut

sub set_seen ($)
{
  my ($self) = @_;
  $self-&gt;{'seen'} = 1;
}

sub seen ($)
{
  my ($self) = @_;
  return $self-&gt;{'seen'};
}

=item C&lt;$str = $def-E&lt;gt&gt;dump&gt;

Format the contents of C&lt;$def&gt; as a human-readable string,
for debugging.

=cut

sub dump ($)
{
  my ($self) = @_;
  my $owner = $self-&gt;owner;

  if ($owner == VAR_AUTOMAKE)
    {
      $owner = 'Automake';
    }
  elsif ($owner == VAR_CONFIGURE)
    {
      $owner = 'Configure';
    }
  elsif ($owner == VAR_MAKEFILE)
    {
      $owner = 'Makefile';
    }
  else
    {
      prog_error ("unexpected owner");
    }

  my $where = $self-&gt;location-&gt;dump;
  my $comment = $self-&gt;comment;
  my $value = $self-&gt;raw_value;
  my $type = $self-&gt;type;

  return "{
      type: $type=
      where: $where      comment: $comment
      value: $value
      owner: $owner
    }\n";
}

=back

=head1 SEE ALSO

L&lt;Automake::Variable&gt;, L&lt;Automake::ItemDef&gt;.

=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:
</pre></body></html>