<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># Copyright (C) 2003-2017 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::Item;

use 5.006;
use strict;
use Carp;
use Automake::ChannelDefs;
use Automake::DisjConditions;

=head1 NAME

Automake::Item - base class for Automake::Variable and Automake::Rule

=head1 DESCRIPTION

=head2 Methods

=over 4

=item C&lt;new Automake::Item $name&gt;

Create and return an empty Item called C&lt;$name&gt;.

=cut

sub new ($$)
{
  my ($class, $name) = @_;
  my $self = {
    name =&gt; $name,
    defs =&gt; {},
    conds =&gt; {},
  };
  bless $self, $class;
  return $self;
}

=item C&lt;$item-E&lt;gt&gt;name&gt;

Return the name of C&lt;$item&gt;.

=cut

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

=item C&lt;$item-E&lt;gt&gt;def ($cond)&gt;

Return the definition for this item in condition C&lt;$cond&gt;, if it
exists.  Return 0 otherwise.

=cut

sub def ($$)
{
  # This method is called very often, so keep it small and fast.  We
  # don't mind the extra undefined items introduced by lookup failure;
  # avoiding this with 'exists' means doing two hash lookup on
  # success, and proved worse on benchmark.
  my $def = $_[0]-&gt;{'defs'}{$_[1]};
  return defined $def &amp;&amp; $def;
}

=item C&lt;$item-E&lt;gt&gt;rdef ($cond)&gt;

Return the definition for this item in condition C&lt;$cond&gt;.  Abort with
an internal error if the item was not defined under this condition.

The I&lt;r&gt; in front of C&lt;def&gt; stands for I&lt;required&gt;.  One
should call C&lt;rdef&gt; to assert the conditional definition's existence.

=cut

sub rdef ($$)
{
  my ($self, $cond) = @_;
  my $d = $self-&gt;def ($cond);
  prog_error ("undefined condition '" . $cond-&gt;human . "' for '"
	      . $self-&gt;name . "'\n" . $self-&gt;dump)
    unless $d;
  return $d;
}

=item C&lt;$item-E&lt;gt&gt;set ($cond, $def)&gt;

Add a new definition to an existing item.

=cut

sub set ($$$)
{
  my ($self, $cond, $def) = @_;
  $self-&gt;{'defs'}{$cond} = $def;
  $self-&gt;{'conds'}{$cond} = $cond;
}

=item C&lt;$var-E&lt;gt&gt;conditions&gt;

Return an L&lt;Automake::DisjConditions&gt; describing the conditions that
that an item is defined in.

These are all the conditions for which is would be safe to call
C&lt;rdef&gt;.

=cut

sub conditions ($)
{
  my ($self) = @_;
  prog_error ("self is not a reference")
    unless ref $self;
  return new Automake::DisjConditions (values %{$self-&gt;{'conds'}});
}

=item C&lt;@missing_conds = $var-E&lt;gt&gt;not_always_defined_in_cond ($cond)&gt;

Check whether C&lt;$var&gt; is always defined for condition C&lt;$cond&gt;.
Return a list of conditions where the definition is missing.

For instance, given

  if COND1
    if COND2
      A = foo
      D = d1
    else
      A = bar
      D = d2
    endif
  else
    D = d3
  endif
  if COND3
    A = baz
    B = mumble
  endif
  C = mumble

we should have (we display result as conditional strings in this
illustration, but we really return DisjConditions objects):

  var ('A')-&gt;not_always_defined_in_cond ('COND1_TRUE COND2_TRUE')
    =&gt; ()
  var ('A')-&gt;not_always_defined_in_cond ('COND1_TRUE')
    =&gt; ()
  var ('A')-&gt;not_always_defined_in_cond ('TRUE')
    =&gt; ("COND1_FALSE COND3_FALSE")
  var ('B')-&gt;not_always_defined_in_cond ('COND1_TRUE')
    =&gt; ("COND1_TRUE COND3_FALSE")
  var ('C')-&gt;not_always_defined_in_cond ('COND1_TRUE')
    =&gt; ()
  var ('D')-&gt;not_always_defined_in_cond ('TRUE')
    =&gt; ()
  var ('Z')-&gt;not_always_defined_in_cond ('TRUE')
    =&gt; ("TRUE")

=cut

sub not_always_defined_in_cond ($$)
{
  my ($self, $cond) = @_;

  # Compute the subconditions where $var isn't defined.
  return
    $self-&gt;conditions
      -&gt;sub_conditions ($cond)
	-&gt;invert
	  -&gt;multiply ($cond);
}


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>