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