maint: run "make update-copyright"
[platform/upstream/automake.git] / lib / Automake / Item.pm
1 # Copyright (C) 2003-2012 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2, or (at your option)
6 # any later version.
7
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 package Automake::Item;
17 use strict;
18 use Carp;
19
20 use Automake::ChannelDefs;
21 use Automake::DisjConditions;
22
23 =head1 NAME
24
25 Automake::Item - base class for Automake::Variable and Automake::Rule
26
27 =head1 DESCRIPTION
28
29 =head2 Methods
30
31 =over 4
32
33 =item C<new Automake::Item $name>
34
35 Create and return an empty Item called C<$name>.
36
37 =cut
38
39 sub new ($$)
40 {
41   my ($class, $name) = @_;
42   my $self = {
43     name => $name,
44     defs => {},
45     conds => {},
46   };
47   bless $self, $class;
48   return $self;
49 }
50
51 =item C<$item-E<gt>name>
52
53 Return the name of C<$item>.
54
55 =cut
56
57 sub name ($)
58 {
59   my ($self) = @_;
60   return $self->{'name'};
61 }
62
63 =item C<$item-E<gt>def ($cond)>
64
65 Return the definition for this item in condition C<$cond>, if it
66 exists.  Return 0 otherwise.
67
68 =cut
69
70 sub def ($$)
71 {
72   # This method is called very often, so keep it small and fast.  We
73   # don't mind the extra undefined items introduced by lookup failure;
74   # avoiding this with `exists' means doing two hash lookup on
75   # success, and proved worse on benchmark.
76   my $def = $_[0]->{'defs'}{$_[1]};
77   return defined $def && $def;
78 }
79
80 =item C<$item-E<gt>rdef ($cond)>
81
82 Return the definition for this item in condition C<$cond>.  Abort with
83 an internal error if the item was not defined under this condition.
84
85 The I<r> in front of C<def> stands for I<required>.  One
86 should call C<rdef> to assert the conditional definition's existence.
87
88 =cut
89
90 sub rdef ($$)
91 {
92   my ($self, $cond) = @_;
93   my $d = $self->def ($cond);
94   prog_error ("undefined condition `" . $cond->human . "' for `"
95               . $self->name . "'\n" . $self->dump)
96     unless $d;
97   return $d;
98 }
99
100 =item C<$item-E<gt>set ($cond, $def)>
101
102 Add a new definition to an existing item.
103
104 =cut
105
106 sub set ($$$)
107 {
108   my ($self, $cond, $def) = @_;
109   $self->{'defs'}{$cond} = $def;
110   $self->{'conds'}{$cond} = $cond;
111 }
112
113 =item C<$var-E<gt>conditions>
114
115 Return an L<Automake::DisjConditions> describing the conditions that
116 that an item is defined in.
117
118 These are all the conditions for which is would be safe to call
119 C<rdef>.
120
121 =cut
122
123 sub conditions ($)
124 {
125   my ($self) = @_;
126   prog_error ("self is not a reference")
127     unless ref $self;
128   return new Automake::DisjConditions (values %{$self->{'conds'}});
129 }
130
131 =item C<@missing_conds = $var-E<gt>not_always_defined_in_cond ($cond)>
132
133 Check whether C<$var> is always defined for condition C<$cond>.
134 Return a list of conditions where the definition is missing.
135
136 For instance, given
137
138   if COND1
139     if COND2
140       A = foo
141       D = d1
142     else
143       A = bar
144       D = d2
145     endif
146   else
147     D = d3
148   endif
149   if COND3
150     A = baz
151     B = mumble
152   endif
153   C = mumble
154
155 we should have (we display result as conditional strings in this
156 illustration, but we really return DisjConditions objects):
157
158   var ('A')->not_always_defined_in_cond ('COND1_TRUE COND2_TRUE')
159     => ()
160   var ('A')->not_always_defined_in_cond ('COND1_TRUE')
161     => ()
162   var ('A')->not_always_defined_in_cond ('TRUE')
163     => ("COND1_FALSE COND3_FALSE")
164   var ('B')->not_always_defined_in_cond ('COND1_TRUE')
165     => ("COND1_TRUE COND3_FALSE")
166   var ('C')->not_always_defined_in_cond ('COND1_TRUE')
167     => ()
168   var ('D')->not_always_defined_in_cond ('TRUE')
169     => ()
170   var ('Z')->not_always_defined_in_cond ('TRUE')
171     => ("TRUE")
172
173 =cut
174
175 sub not_always_defined_in_cond ($$)
176 {
177   my ($self, $cond) = @_;
178
179   # Compute the subconditions where $var isn't defined.
180   return
181     $self->conditions
182       ->sub_conditions ($cond)
183         ->invert
184           ->multiply ($cond);
185 }
186
187
188 1;
189
190 ### Setup "GNU" style for perl-mode and cperl-mode.
191 ## Local Variables:
192 ## perl-indent-level: 2
193 ## perl-continued-statement-offset: 2
194 ## perl-continued-brace-offset: 0
195 ## perl-brace-offset: 0
196 ## perl-brace-imaginary-offset: 0
197 ## perl-label-offset: -2
198 ## cperl-indent-level: 2
199 ## cperl-brace-offset: 0
200 ## cperl-continued-brace-offset: 0
201 ## cperl-label-offset: -2
202 ## cperl-extra-newline-before-brace: t
203 ## cperl-merge-trailing-else: nil
204 ## cperl-continued-statement-offset: 2
205 ## End: