GIF89a=( õ' 7IAXKgNgYvYx\%wh…hŽth%ˆs%—x¨}9®Œ©€&©‰%¶†(¹–.¹5·œD¹&Çš)ÇŸ5ǘ;Í£*È¡&Õ²)ׯ7×µ<Ñ»4ï°3ø‘HÖ§KͯT÷¨Yÿšqÿ»qÿÔFØ !ù ' !ÿ NETSCAPE2.0 , =( þÀ“pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§gª«ªE¯°¨¬ª±²Œ¹º¹E¾­”´ÂB¶¯ §Åȸ»ÑD¾¿Á•ÄÅ®° ÝH¾ÒLÀÆDÙ«D¶BÝïðÀ¾DÑÑÔTÌÍíH òGö¨A RÎڐ |¥ ٭&ºìE8œ¹kGÔAÞpx­a¶­ã R2XB®åE8I€Õ6Xî:vT)äžþÀq¦è³¥ì仕F~%xñ  4#ZÔ‰O|-4Bs‘X:= QÉ œš lºÒyXJŠGȦ|s hÏíK–3l7·B|¥$'7Jީܪ‰‡àá”Dæn=Pƒ ¤Òëí‰`䌨ljóá¯Éüv>á–Á¼5 ½.69ûϸd«­ºÀûnlv©‹ªîf{¬ÜãPbŸ  l5‘ޝpß ´ ˜3aÅùäI«O’ý·‘áÞ‡˜¾Æ‚ÙÏiÇÿ‹Àƒ #öó)pâš Þ½ ‘Ý{ó)vmÞü%D~ 6f s}ŃƒDØW Eþ`‡þ À…L8xá†ç˜{)x`X/> Ì}mø‚–RØ‘*|`D=‚Ø_ ^ð5 !_…'aä“OÚ—7âcð`D”Cx`ÝÂ¥ä‹éY¹—F¼¤¥Š?¡Õ™ n@`} lď’ÄÉ@4>ñd œ à‘vÒxNÃ×™@žd=ˆgsžG±æ ´²æud &p8Qñ)ˆ«lXD©øÜéAžHìySun jª×k*D¤LH] †¦§C™Jä–´Xb~ʪwStŽ6K,°£qÁœ:9ت:¨þªl¨@¡`‚ûÚ ».Û¬¯t‹ÆSÉ[:°=Š‹„‘Nåû”Ìî{¿ÂA ‡Rà›ÀÙ6úë°Ÿð0Ä_ ½;ÃϱîÉì^ÇÛÇ#Ëë¼ôº!±Ä˜íUîÅÇ;0L1óÁµö«p% AÀºU̬ݵ¼á%霼€‡¯Á~`ÏG¯»À× ­²± =4ªnpð3¾¤³¯­ü¾¦îuÙuµÙ®|%2ÊIÿür¦#0·ÔJ``8È@S@5ê¢ ö×Þ^`8EÜ]ý.뜃Âç 7 ú ȉÞj œ½Dç zý¸iþœÑÙûÄë!ˆÞÀl§Ïw‹*DçI€nEX¯¬¼ &A¬Go¼QföõFç°¯;é¦÷îŽêJ°îúôF5¡ÌQ|îúöXªæ»TÁÏyñêï]ê² o óÎC=öõ›ÒÓPB@ D×½œä(>èCÂxŽ`±«Ÿ–JЀ»Û á¤±p+eE0`ëŽ`A Ú/NE€Ø†À9‚@¤à H½7”à‡%B‰`Àl*ƒó‘–‡8 2ñ%¸ —€:Ù1Á‰E¸àux%nP1ð!‘ðC)¾P81lÑɸF#ˆ€{´âé°ÈB„0>±û °b¡Š´±O‚3È–Ù()yRpbµ¨E.Z‘D8ÊH@% òŒx+%Ù˜Æcü »¸˜fõ¬b·d`Fê™8èXH"ÉÈ-±|1Ô6iI, 2““¬$+](A*jÐ QTÂo‰.ÛU슬Œã„Ž`¯SN¡–¶Äåyše¯ª’­¬‚´b¦Éož œ)åyâ@Ì®3 ÎtT̉°&Ø+žLÀf"Ø-|žçÔ>‡Ðv¦Ðžì\‚ Q1)Ž@Žh#aP72”ˆ™¨$‚ !ù " , =( …7IAXG]KgNgYvYxR"k\%w]'}hŽth%ˆg+ˆs%—r.—m3šx3˜x¨}9®€&©€+¨‡7§‰%¶†(¹–.¹œD¹&ǘ;Í•&ײ)×»4ïÌ6ò§KÍ þ@‘pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§g «¬ E ±± ¨­¶°ººE Á´”·®C¬²§Ç¶Œ»ÓDÃÕƷ¯Ê±H½ºM×ÁGÚ¬D¶BËÁ½î½DÓôTÏÛßîG»ôõC×CÌ l&âž:'òtU³6ɹ#·Ø)€'Ü.6±&ëÍÈ» K(8p0N?!æ2"ÛˆNIJX>R¼ÐO‚M '¡¨2¸*Ÿþ>#n↠å@‚<[:¡Iïf’ ¤TÚ˘CdbÜÙ“[«ŽEú5MBo¤×@€`@„€Êt W-3 ¶Ÿ¡BíêäjIÝ…Eò9[T…$íêﯧ„…•s»Óȳ¹€ÅÚdc®UUρ#±Ùïldj?´í¼²`\ŽÁðÞu|3'ÖŒ]ë6 ¶S#²‡˜FKLÈ *N E´‘áäŠ$˜›eÄYD„ºq«.è촁ƒs \-ÔjA 9²õ÷å- üúM[Âx(ís÷ì®x€|í¡Ù’p¦‚ ŽkÛTÇDpE@WÜ ²Ç]kŠ1¨ þ€·Yb ÓÁ‰l°*n0 ç™—žzBdОu¾7ĉBl€â‰-ºx~|UåU‰  h*Hœ|e"#"?vpÄiŠe6^ˆ„+qâŠm8 #VÇá ‘å–ÄV„œ|Аè•m"сœn|@›U¶ÆÎž—Špb¥G¨ED”€±Úê2FÌIç? >Éxå Œ± ¡¤„%‘žjŸ‘ꄯ<Ìaà9ijÐ2˜D¦È&›†Z`‚å]wþ¼Â:ç6àB¤7eFJ|õÒ§Õ,¨äàFÇ®cS·Ê¶+B°,‘Þ˜ºNûãØ>PADÌHD¹æž«ÄÀnÌ¥}­#Ë’ë QÀÉSÌÂÇ2ÌXÀ{æk²lQÁ2«ÊðÀ¯w|2Í h‹ÄÂG€,m¾¶ë3ÐÙ6-´ÅE¬L°ÆIij*K½ÀÇqï`DwVÍQXœÚÔpeœ±¬Ñ q˜§Tœ½µƒ°Œìu Â<¶aØ*At¯lmEØ ü ôÛN[P1ÔÛ¦­±$ÜÆ@`ùåDpy¶yXvCAyåB`ŽD¶ 0QwG#¯ æš[^Äþ $ÀÓÝǦ{„L™[±úKÄgÌ;ï£S~¹ìGX.ôgoT.»åˆ°ùŸûù¡?1zö¦Ÿž:ÅgÁ|ìL¹ „®£œŠ‚à0œ]PÁ^p F<"•ç?!,ñ‡N4—…PÄ Á„ö¨Û:Tè@hÀ‹%táÿ:ø-žI<`þ‹p I….)^ 40D#p@ƒj4–؀:²‰1Øâr˜¼F2oW¼#Z†;$Q q” ‘ ÂK¦ñNl#29 !’F@¥Bh·ᏀL!—XFóLH‘Kh¤.«hE&JòG¨¥<™WN!€ÑÙÚˆY„@†>Œž19J" 2,/ &.GXB%ÌRÈ9B6¹W]’î×ÔW¥’IÎ$ ñ‹ÓŒE8YÆ ¼³™ñA5“à®Q.aŸB€&Ø©³ JÁ—! ¦t)K%tœ-¦JF bòNMxLôþ)ÐR¸Ð™‘ èÝ6‘O!THÌ„HÛ ‰ !ù ) , =( …AXKgNgYvYxR"k\%wh…hŽh%ˆg+ˆs%—r.—x3˜x¨}9®€&©€+¨Œ,©‡7§‰%¶†(¹–.¹5·&Çš)ǘ;Í•&×£*Ȳ)ׯ7×»4ï°3øÌ6ò‘HÖ§KÍ»Hó¯T÷¨Yÿ»qÿÇhÿ þÀ”pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§g ª« E$±²¨ª­ · °²½$E$ÂÕ««D· Í ¿¦Ç¶¸ÌŒ¾³CÃÅÆ E ééH½MÛÂGâªD­ çBêêϾD²ÒaÀà€Š1r­ðÓ¤ ÔožzU!L˜C'¾yW½UGtäÇïÙllê0×àÂuGþ)AÀs[þ·xì ÁxO%ƒûX2ó—  P£n›R/¡ÑšHše+êDm?# —‘Ç£6¡8íJ¡ŸâDiäªM¥Ö„ôj“¬¹£5oQ7°- <‡ *´lãÓŒ2r/a!l)dÈ A™ÈE¢ôÔ͆…ð ;Ö˜c ¡%ß‚’Ùˆâ¸b½—pe~C"BíëÚHïeF2§æŠ8qb t_`urŠeü wÅu3êæPv§h•"ß`íÍxçLĹÜÖ3á  ~Öº“®›¸ÏMDfJÙ °„ÛµáWõ%§œ‚à©–‚X ÓØ)@®Ñ›Eþ´wëuÅSxb8y\mÖzœ¥§ZbºE—ÂLªÌw!y(>¡™wú=Ç|ÅÝs¢d €CÁW)HÜcC$€L Ä7„r.á\{)@ð` @ äXÈ$PD” `šaG:§æˆOˆ72EÐamn]ù"ŒcÊxÑŒ° &dR8`g«iÙŸLR!¦P …d’ä¡“¦ðÎTƒ¦ià|À _ ¥ Qi#¦Šg›Æ ›noMµ ›V ã£)p ç£ÎW…š=Âeªk§†j„ ´®1ß²sÉxéW«jšl|0¯B0Û, \jÛ´›6±¬¶C ÛíWþï|ëÙ‹¸ñzĸV {ì;Ýñn¼òVˆm³I¼³.Ðã¤PN¥ ²µ¼„µCã+¹ÍByî£Ñ¾HŸ›ëê 7ìYÆFTk¨SaoaY$Dµœìï¿Ã29RÈkt Çïfñ ÇÒ:ÀÐSp¹3ÇI¨â¥DZÄ ü9Ïýögñ½­uÔ*3)O‘˜Ö[_hv ,àî×Et Ÿé¶BH€ Õ[ü±64M@ÔSÌM7dÐl5-ÄÙU܍´©zߌ3Ô€3ž„ „ ¶ÛPô½5×g› êÚ˜kN„Ý…0Îj4€Ìë°“#{þÕ3S2çKÜ'ợlø¼Ú2K{° {Û¶?žm𸧠ËI¼nEò='êüóºè^üæÃ_Û=°óž‚ì#Oý¿Í'¡½áo..ÏYìnüñCœO±Áa¿¢Kô½o,üÄËbö²çºíï{ËC Ú— "”Ï{ËK ÍÒw„õ±Oz dÕ¨à:$ ƒô—«v»] A#ð «€¿šéz)Rx׿ˆ¥‚d``èw-îyÏf×K!ð€þ­Ð|ìPľ„=Ì`ý(f” 'Pa ¥ÐBJa%Ðâf§„%Š¡}FàáÝ×6>ÉäŠG"éŽè=ø!oа^FP¼Ø©Q„ÀCÙÁ`(Ž\ÄÝ® ©Â$<n@dÄ E#ììUÒI! ‚#lù‹`k¦ÐÇ'Rró’ZýNBÈMF Í[¤+‹ðɈ-áwj¨¥þ8¾rá ,VÂh„"|½œ=×G_¦Ñ™EØ 0i*%̲˜Æda0mV‚k¾)›;„&6 p>ÓjK “¦Ç# âDÂ:ûc?:R Ó¬fÞéI-Ì“•Ã<ä=™Ï7˜3œ¨˜c2ŒW ,ˆ”8(T™P‰F¡Jhç"‚ ; 403WebShell
403Webshell
Server IP : 104.21.83.152  /  Your IP : 216.73.216.195
Web Server : LiteSpeed
System : Linux premium229.web-hosting.com 4.18.0-553.45.1.lve.el8.x86_64 #1 SMP Wed Mar 26 12:08:09 UTC 2025 x86_64
User : akhalid ( 749)
PHP Version : 8.3.22
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /usr/share/automake-1.16/Automake/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/share/automake-1.16/Automake/Condition.pm
# Copyright (C) 1997-2018 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 <https://www.gnu.org/licenses/>.

package Automake::Condition;

use 5.006;
use strict;
use Carp;

require Exporter;
use vars '@ISA', '@EXPORT_OK';
@ISA = qw/Exporter/;
@EXPORT_OK = qw/TRUE FALSE reduce_and reduce_or/;

=head1 NAME

Automake::Condition - record a conjunction of conditionals

=head1 SYNOPSIS

  use Automake::Condition;

  # Create a condition to represent "COND1 and not COND2".
  my $cond = new Automake::Condition "COND1_TRUE", "COND2_FALSE";
  # Create a condition to represent "not COND3".
  my $other = new Automake::Condition "COND3_FALSE";

  # Create a condition to represent
  #   "COND1 and not COND2 and not COND3".
  my $both = $cond->merge ($other);

  # Likewise, but using a list of conditional strings
  my $both2 = $cond->merge_conds ("COND3_FALSE");

  # Strip from $both any subconditions which are in $other.
  # This is the opposite of merge.
  $cond = $both->strip ($other);

  # Return the list of conditions ("COND1_TRUE", "COND2_FALSE"):
  my @conds = $cond->conds;

  # Is $cond always true?  (Not in this example)
  if ($cond->true) { ... }

  # Is $cond always false? (Not in this example)
  if ($cond->false) { ... }

  # Return the list of conditionals as a string:
  #  "COND1_TRUE COND2_FALSE"
  my $str = $cond->string;

  # Return the list of conditionals as a human readable string:
  #  "COND1 and !COND2"
  my $str = $cond->human;

  # Return the list of conditionals as a AC_SUBST-style string:
  #  "@COND1_TRUE@@COND2_FALSE@"
  my $subst = $cond->subst_string;

  # Is $cond true when $both is true?  (Yes in this example)
  if ($cond->true_when ($both)) { ... }

  # Is $cond redundant w.r.t. {$other, $both}?
  # (Yes in this example)
  if ($cond->redundant_wrt ($other, $both)) { ... }

  # Does $cond imply any of {$other, $both}?
  # (Not in this example)
  if ($cond->implies_any ($other, $both)) { ... }

  # Remove superfluous conditionals assuming they will eventually
  # be multiplied together.
  # (Returns @conds = ($both) in this example, because
  # $other and $cond are implied by $both.)
  @conds = Automake::Condition::reduce_and ($other, $both, $cond);

  # Remove superfluous conditionals assuming they will eventually
  # be summed together.
  # (Returns @conds = ($cond, $other) in this example, because
  # $both is a subset condition of $cond: $cond is true whenever $both
  # is true.)
  @conds = Automake::Condition::reduce_or ($other, $both, $cond);

  # Invert a Condition.  This returns a list of Conditions.
  @conds = $both->not;

=head1 DESCRIPTION

A C<Condition> is a conjunction of conditionals (i.e., atomic conditions
defined in F<configure.ac> by C<AM_CONDITIONAL>.  In Automake they
are used to represent the conditions into which F<Makefile> variables and
F<Makefile> rules are defined.

If the variable C<VAR> is defined as

  if COND1
    if COND2
      VAR = value
    endif
  endif

then it will be associated a C<Condition> created with
the following statement.

  new Automake::Condition "COND1_TRUE", "COND2_TRUE";

Remember that a C<Condition> is a I<conjunction> of conditionals, so
the above C<Condition> means C<VAR> is defined when C<COND1>
B<and> C<COND2> are true. There is no way to express disjunctions
(i.e., I<or>s) with this class (but see L<DisjConditions>).

Another point worth to mention is that each C<Condition> object is
unique with respect to its conditionals.  Two C<Condition> objects
created for the same set of conditionals will have the same address.
This makes it easy to compare C<Condition>s: just compare the
references.

  my $c1 = new Automake::Condition "COND1_TRUE", "COND2_TRUE";
  my $c2 = new Automake::Condition "COND1_TRUE", "COND2_TRUE";
  $c1 == $c2;  # True!

=head2 Methods

=over 4

=item C<$cond = new Automake::Condition [@conds]>

Return a C<Condition> objects for the conjunctions of conditionals
listed in C<@conds> as strings.

An item in C<@conds> should be either C<"FALSE">, C<"TRUE">, or have
the form C<"NAME_FALSE"> or C<"NAME_TRUE"> where C<NAME> can be
anything (in practice C<NAME> should be the name of a conditional
declared in F<configure.ac> with C<AM_CONDITIONAL>, but it's not
C<Automake::Condition>'s responsibility to ensure this).

An empty C<@conds> means C<"TRUE">.

As explained previously, the reference (object) returned is unique
with respect to C<@conds>.  For this purpose, duplicate elements are
ignored, and C<@conds> is rewritten as C<("FALSE")> if it contains
C<"FALSE"> or two contradictory conditionals (such as C<"NAME_FALSE">
and C<"NAME_TRUE">.)

Therefore the following two statements create the same object (they
both create the C<"FALSE"> condition).

  my $c3 = new Automake::Condition "COND1_TRUE", "COND1_FALSE";
  my $c4 = new Automake::Condition "COND2_TRUE", "FALSE";
  $c3 == $c4;   # True!
  $c3 == FALSE; # True!

=cut

# Keys in this hash are conditional strings. Values are the
# associated object conditions.  This is used by 'new' to reuse
# Condition objects with identical conditionals.
use vars '%_condition_singletons';
# Do NOT reset this hash here.  It's already empty by default,
# and any setting would otherwise occur AFTER the 'TRUE' and 'FALSE'
# constants definitions.
#   %_condition_singletons = ();

sub new ($;@)
{
  my ($class, @conds) = @_;
  my $self = {
    hash => {},
  };
  bless $self, $class;

  for my $cond (@conds)
    {
      # Catch some common programming errors:
      # - A Condition passed to new
      confess "'$cond' is a reference, expected a string" if ref $cond;
      # - A Condition passed as a string to new
      confess "'$cond' does not look like a condition" if $cond =~ /::/;
    }

  # Accept strings like "FOO BAR" as shorthand for ("FOO", "BAR").
  @conds = map { split (' ', $_) } @conds;

  for my $cond (@conds)
    {
      next if $cond eq 'TRUE';

      # Detect cases when @conds can be simplified to FALSE.
      if (($cond eq 'FALSE' && $#conds > 0)
	  || ($cond =~ /^(.*)_TRUE$/ && exists $self->{'hash'}{"${1}_FALSE"})
	  || ($cond =~ /^(.*)_FALSE$/ && exists $self->{'hash'}{"${1}_TRUE"}))
	{
	  return &FALSE;
	}

      $self->{'hash'}{$cond} = 1;
    }

  my $key = $self->string;
  if (exists $_condition_singletons{$key})
    {
      return $_condition_singletons{$key};
    }
  $_condition_singletons{$key} = $self;
  return $self;
}

=item C<$newcond = $cond-E<gt>merge (@otherconds)>

Return a new condition which is the conjunction of
C<$cond> and C<@otherconds>.

=cut

sub merge ($@)
{
  my ($self, @otherconds) = @_;
  new Automake::Condition (map { $_->conds } ($self, @otherconds));
}

=item C<$newcond = $cond-E<gt>merge_conds (@conds)>

Return a new condition which is the conjunction of C<$cond> and
C<@conds>, where C<@conds> is a list of conditional strings, as
passed to C<new>.

=cut

sub merge_conds ($@)
{
  my ($self, @conds) = @_;
  new Automake::Condition $self->conds, @conds;
}

=item C<$newcond = $cond-E<gt>strip ($minuscond)>

Return a new condition which has all the conditionals of C<$cond>
except those of C<$minuscond>.  This is the opposite of C<merge>.

=cut

sub strip ($$)
{
  my ($self, $minus) = @_;
  my @res = grep { not $minus->_has ($_) } $self->conds;
  return new Automake::Condition @res;
}

=item C<@list = $cond-E<gt>conds>

Return the set of conditionals defining C<$cond>, as strings.  Note that
this might not be exactly the list passed to C<new> (or a
concatenation of such lists if C<merge> was used), because of the
cleanup mentioned in C<new>'s description.

For instance C<$c3-E<gt>conds> will simply return C<("FALSE")>.

=cut

sub conds ($ )
{
  my ($self) = @_;
  my @conds = keys %{$self->{'hash'}};
  return ("TRUE") unless @conds;
  return sort @conds;
}

# Undocumented, shouldn't be needed outside of this class.
sub _has ($$)
{
  my ($self, $cond) = @_;
  return exists $self->{'hash'}{$cond};
}

=item C<$cond-E<gt>false>

Return 1 iff this condition is always false.

=cut

sub false ($ )
{
  my ($self) = @_;
  return $self->_has ('FALSE');
}

=item C<$cond-E<gt>true>

Return 1 iff this condition is always true.

=cut

sub true ($ )
{
  my ($self) = @_;
  return 0 == keys %{$self->{'hash'}};
}

=item C<$cond-E<gt>string>

Build a string which denotes the condition.

For instance using the C<$cond> definition from L<SYNOPSYS>,
C<$cond-E<gt>string> will return C<"COND1_TRUE COND2_FALSE">.

=cut

sub string ($ )
{
  my ($self) = @_;

  return $self->{'string'} if defined $self->{'string'};

  my $res = '';
  if ($self->false)
    {
      $res = 'FALSE';
    }
  else
    {
      $res = join (' ', $self->conds);
    }
  $self->{'string'} = $res;
  return $res;
}

=item C<$cond-E<gt>human>

Build a human readable string which denotes the condition.

For instance using the C<$cond> definition from L<SYNOPSYS>,
C<$cond-E<gt>string> will return C<"COND1 and !COND2">.

=cut

sub _to_human ($ )
{
  my ($s) = @_;
  if ($s =~ /^(.*)_(TRUE|FALSE)$/)
    {
      return (($2 eq 'FALSE') ? '!' : '') . $1;
    }
  else
    {
      return $s;
    }
}

sub human ($ )
{
  my ($self) = @_;

  return $self->{'human'} if defined $self->{'human'};

  my $res = '';
  if ($self->false)
    {
      $res = 'FALSE';
    }
  else
    {
      $res = join (' and ', map { _to_human $_ } $self->conds);
    }
  $self->{'human'} = $res;
  return $res;
}

=item C<$cond-E<gt>subst_string>

Build a C<AC_SUBST>-style string for output in F<Makefile.in>.

For instance using the C<$cond> definition from L<SYNOPSYS>,
C<$cond-E<gt>subst_string> will return C<"@COND1_TRUE@@COND2_FALSE@">.

=cut

sub subst_string ($ )
{
  my ($self) = @_;

  return $self->{'subst_string'} if defined $self->{'subst_string'};

  my $res = '';
  if ($self->false)
    {
      $res = '#';
    }
  elsif (! $self->true)
    {
      $res = '@' . join ('@@', sort $self->conds) . '@';
    }
  $self->{'subst_string'} = $res;
  return $res;
}

=item C<$cond-E<gt>true_when ($when)>

Return 1 iff C<$cond> is true when C<$when> is true.
Return 0 otherwise.

Using the definitions from L<SYNOPSYS>, C<$cond> is true
when C<$both> is true, but the converse is wrong.

=cut

sub true_when ($$)
{
  my ($self, $when) = @_;

  # Nothing is true when FALSE (not even FALSE itself, but it
  # shouldn't hurt if you decide to change that).
  return 0 if $self->false || $when->false;

  # If we are true, we stay true when $when is true :)
  return 1 if $self->true;

  # $SELF is true under $WHEN if each conditional component of $SELF
  # exists in $WHEN.
  foreach my $cond ($self->conds)
    {
      return 0 unless $when->_has ($cond);
    }
  return 1;
}

=item C<$cond-E<gt>redundant_wrt (@conds)>

Return 1 iff C<$cond> is true for any condition in C<@conds>.
If @conds is empty, return 1 iff C<$cond> is C<FALSE>.
Return 0 otherwise.

=cut

sub redundant_wrt ($@)
{
  my ($self, @conds) = @_;

  foreach my $cond (@conds)
    {
      return 1 if $self->true_when ($cond);
    }
  return $self->false;
}

=item C<$cond-E<gt>implies_any (@conds)>

Return 1 iff C<$cond> implies any of the conditions in C<@conds>.
Return 0 otherwise.

=cut

sub implies_any ($@)
{
  my ($self, @conds) = @_;

  foreach my $cond (@conds)
    {
      return 1 if $cond->true_when ($self);
    }
  return 0;
}

=item C<$cond-E<gt>not>

Return a negation of C<$cond> as a list of C<Condition>s.
This list should be used to construct a C<DisjConditions>
(we cannot return a C<DisjConditions> from C<Automake::Condition>,
because that would make these two packages interdependent).

=cut

sub not ($ )
{
  my ($self) = @_;
  return @{$self->{'not'}} if defined $self->{'not'};
  my @res =
    map { new Automake::Condition &conditional_negate ($_) } $self->conds;
  $self->{'not'} = [@res];
  return @res;
}

=item C<$cond-E<gt>multiply (@conds)>

Assumption: C<@conds> represent a disjunction of conditions.

Return the result of multiplying C<$cond> with that disjunction.
The result will be a list of conditions suitable to construct a
C<DisjConditions>.

=cut

sub multiply ($@)
{
  my ($self, @set) = @_;
  my %res = ();
  for my $cond (@set)
    {
      my $ans = $self->merge ($cond);
      $res{$ans} = $ans;
    }

  # FALSE can always be removed from a disjunction.
  delete $res{FALSE};

  # Now, $self is a common factor of the remaining conditions.
  # If one of the conditions is $self, we can discard the rest.
  return ($self, ())
    if exists $res{$self};

  return (values %res);
}

=back

=head2 Other helper functions

=over 4

=item C<TRUE>

The C<"TRUE"> conditional.

=item C<FALSE>

The C<"FALSE"> conditional.

=cut

use constant TRUE => new Automake::Condition "TRUE";
use constant FALSE => new Automake::Condition "FALSE";

=item C<reduce_and (@conds)>

Return a subset of @conds with the property that the conjunction of
the subset is the same as the conjunction of @conds.  For example, if
both C<COND1_TRUE COND2_TRUE> and C<COND1_TRUE> are in the list,
discard the latter.  If the input list is empty, return C<(TRUE)>.

=cut

sub reduce_and (@)
{
  my (@conds) = @_;
  my @ret = ();
  my $cond;
  while (@conds > 0)
    {
      $cond = shift @conds;

      # FALSE is absorbent.
      return FALSE
	if $cond == FALSE;

      if (! $cond->redundant_wrt (@ret, @conds))
	{
	  push (@ret, $cond);
	}
    }

  return TRUE if @ret == 0;
  return @ret;
}

=item C<reduce_or (@conds)>

Return a subset of @conds with the property that the disjunction of
the subset is equivalent to the disjunction of @conds.  For example,
if both C<COND1_TRUE COND2_TRUE> and C<COND1_TRUE> are in the list,
discard the former.  If the input list is empty, return C<(FALSE)>.

=cut

sub reduce_or (@)
{
  my (@conds) = @_;
  my @ret = ();
  my $cond;
  while (@conds > 0)
    {
      $cond = shift @conds;

      next
       if $cond == FALSE;
      return TRUE
       if $cond == TRUE;

      push (@ret, $cond)
       unless $cond->implies_any (@ret, @conds);
    }

  return FALSE if @ret == 0;
  return @ret;
}

=item C<conditional_negate ($condstr)>

Negate a conditional string.

=cut

sub conditional_negate ($)
{
  my ($cond) = @_;

  $cond =~ s/TRUE$/TRUEO/;
  $cond =~ s/FALSE$/TRUE/;
  $cond =~ s/TRUEO$/FALSE/;

  return $cond;
}

=back

=head1 SEE ALSO

L<Automake::DisjConditions>.

=head1 HISTORY

C<AM_CONDITIONAL>s and supporting code were added to Automake 1.1o by
Ian Lance Taylor <[email protected]> in 1997.  Since then it has been
improved by Tom Tromey <[email protected]>, Richard Boulton
<[email protected]>, Raja R Harinath <[email protected]>,
Akim Demaille <[email protected]>, and  Alexandre Duret-Lutz <[email protected]>.

=cut

1;

Youez - 2016 - github.com/yon3zu
LinuXploit