123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- # 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 <http://www.gnu.org/licenses/>.
- 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<new Automake::Item $name>
- Create and return an empty Item called C<$name>.
- =cut
- sub new ($$)
- {
- my ($class, $name) = @_;
- my $self = {
- name => $name,
- defs => {},
- conds => {},
- };
- bless $self, $class;
- return $self;
- }
- =item C<$item-E<gt>name>
- Return the name of C<$item>.
- =cut
- sub name ($)
- {
- my ($self) = @_;
- return $self->{'name'};
- }
- =item C<$item-E<gt>def ($cond)>
- Return the definition for this item in condition C<$cond>, 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]->{'defs'}{$_[1]};
- return defined $def && $def;
- }
- =item C<$item-E<gt>rdef ($cond)>
- Return the definition for this item in condition C<$cond>. Abort with
- an internal error if the item was not defined under this condition.
- The I<r> in front of C<def> stands for I<required>. One
- should call C<rdef> to assert the conditional definition's existence.
- =cut
- sub rdef ($$)
- {
- my ($self, $cond) = @_;
- my $d = $self->def ($cond);
- prog_error ("undefined condition '" . $cond->human . "' for '"
- . $self->name . "'\n" . $self->dump)
- unless $d;
- return $d;
- }
- =item C<$item-E<gt>set ($cond, $def)>
- Add a new definition to an existing item.
- =cut
- sub set ($$$)
- {
- my ($self, $cond, $def) = @_;
- $self->{'defs'}{$cond} = $def;
- $self->{'conds'}{$cond} = $cond;
- }
- =item C<$var-E<gt>conditions>
- Return an L<Automake::DisjConditions> describing the conditions that
- that an item is defined in.
- These are all the conditions for which is would be safe to call
- C<rdef>.
- =cut
- sub conditions ($)
- {
- my ($self) = @_;
- prog_error ("self is not a reference")
- unless ref $self;
- return new Automake::DisjConditions (values %{$self->{'conds'}});
- }
- =item C<@missing_conds = $var-E<gt>not_always_defined_in_cond ($cond)>
- Check whether C<$var> is always defined for condition C<$cond>.
- 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')->not_always_defined_in_cond ('COND1_TRUE COND2_TRUE')
- => ()
- var ('A')->not_always_defined_in_cond ('COND1_TRUE')
- => ()
- var ('A')->not_always_defined_in_cond ('TRUE')
- => ("COND1_FALSE COND3_FALSE")
- var ('B')->not_always_defined_in_cond ('COND1_TRUE')
- => ("COND1_TRUE COND3_FALSE")
- var ('C')->not_always_defined_in_cond ('COND1_TRUE')
- => ()
- var ('D')->not_always_defined_in_cond ('TRUE')
- => ()
- var ('Z')->not_always_defined_in_cond ('TRUE')
- => ("TRUE")
- =cut
- sub not_always_defined_in_cond ($$)
- {
- my ($self, $cond) = @_;
- # Compute the subconditions where $var isn't defined.
- return
- $self->conditions
- ->sub_conditions ($cond)
- ->invert
- ->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:
|