lib scripts: Make time-stamp after-save-hooks buffer-local.
[automake.git] / lib / Automake / Item.pm
blob5e98e04b2ab2dac5e7fb6124931e4309dd72df86
1 # Copyright (C) 2003-2024 Free Software Foundation, Inc.
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.
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.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <https://www.gnu.org/licenses/>.
16 package Automake::Item;
18 use 5.006;
19 use strict;
20 use warnings FATAL => 'all';
22 use Carp;
24 use Automake::ChannelDefs;
25 use Automake::DisjConditions;
27 =head1 NAME
29 Automake::Item - base class for Automake::Variable and Automake::Rule
31 =head1 DESCRIPTION
33 =head2 Methods
35 =over 4
37 =item C<new Automake::Item $name>
39 Create and return an empty Item called C<$name>.
41 =cut
43 sub new ($$)
45 my ($class, $name) = @_;
46 my $self = {
47 name => $name,
48 defs => {},
49 conds => {},
51 bless $self, $class;
52 return $self;
55 =item C<$item-E<gt>name>
57 Return the name of C<$item>.
59 =cut
61 sub name ($)
63 my ($self) = @_;
64 return $self->{'name'};
67 =item C<$item-E<gt>def ($cond)>
69 Return the definition for this item in condition C<$cond>, if it
70 exists. Return 0 otherwise.
72 =cut
74 sub def ($$)
76 # This method is called very often, so keep it small and fast. We
77 # don't mind the extra undefined items introduced by lookup failure;
78 # avoiding this with 'exists' means doing two hash lookup on
79 # success, and proved worse on benchmark.
80 my $def = $_[0]->{'defs'}{$_[1]};
81 return defined $def && $def;
84 =item C<$item-E<gt>rdef ($cond)>
86 Return the definition for this item in condition C<$cond>. Abort with
87 an internal error if the item was not defined under this condition.
89 The I<r> in front of C<def> stands for I<required>. One
90 should call C<rdef> to assert the conditional definition's existence.
92 =cut
94 sub rdef ($$)
96 my ($self, $cond) = @_;
97 my $d = $self->def ($cond);
98 prog_error ("undefined condition '" . $cond->human . "' for '"
99 . $self->name . "'\n" . $self->dump)
100 unless $d;
101 return $d;
104 =item C<$item-E<gt>set ($cond, $def)>
106 Add a new definition to an existing item.
108 =cut
110 sub set ($$$)
112 my ($self, $cond, $def) = @_;
113 $self->{'defs'}{$cond} = $def;
114 $self->{'conds'}{$cond} = $cond;
117 =item C<$var-E<gt>conditions>
119 Return an L<Automake::DisjConditions> describing the conditions
120 that an item is defined in.
122 These are all the conditions for which it would be safe to call
123 C<rdef>.
125 =cut
127 sub conditions ($)
129 my ($self) = @_;
130 prog_error ("self is not a reference")
131 unless ref $self;
132 return new Automake::DisjConditions (values %{$self->{'conds'}});
135 =item C<@missing_conds = $var-E<gt>not_always_defined_in_cond ($cond)>
137 Check whether C<$var> is always defined for condition C<$cond>.
138 Return a list of conditions where the definition is missing.
140 For instance, given
142 if COND1
143 if COND2
144 A = foo
145 D = d1
146 else
147 A = bar
148 D = d2
149 endif
150 else
151 D = d3
152 endif
153 if COND3
154 A = baz
155 B = mumble
156 endif
157 C = mumble
159 we should have (we display result as conditional strings in this
160 illustration, but we really return DisjConditions objects):
162 var ('A')->not_always_defined_in_cond ('COND1_TRUE COND2_TRUE')
163 => ()
164 var ('A')->not_always_defined_in_cond ('COND1_TRUE')
165 => ()
166 var ('A')->not_always_defined_in_cond ('TRUE')
167 => ("COND1_FALSE COND3_FALSE")
168 var ('B')->not_always_defined_in_cond ('COND1_TRUE')
169 => ("COND1_TRUE COND3_FALSE")
170 var ('C')->not_always_defined_in_cond ('COND1_TRUE')
171 => ()
172 var ('D')->not_always_defined_in_cond ('TRUE')
173 => ()
174 var ('Z')->not_always_defined_in_cond ('TRUE')
175 => ("TRUE")
177 =cut
179 sub not_always_defined_in_cond ($$)
181 my ($self, $cond) = @_;
183 # Compute the subconditions where $var isn't defined.
184 return
185 $self->conditions
186 ->sub_conditions ($cond)
187 ->invert
188 ->multiply ($cond);