Support `if !COND', `else COND', `end COND'.
authorAkim Demaille <akim@epita.fr>
Tue, 8 May 2001 10:58:49 +0000 (10:58 +0000)
committerAkim Demaille <akim@epita.fr>
Tue, 8 May 2001 10:58:49 +0000 (10:58 +0000)
* automake.texi (Conditionals): Document it.
* automake.in ($WHITE_PATTERN, $MACRO_PATTERN, $BOGUS_MACRO_PATTERN)
($GNITS_VERSION_PATTERN, $INCLUDE_PATTERN): Use `d' and `s'.
($IF_PATTERN, $ELSE_PATTERN, $ENDIF_PATTERN): Likewise, and accept
a leading `!' before the condition.
(&handle_options): Use `d'.
(&cond_stack_if, &cond_stack_else, &&cond_stack_endif): New.
(&read_am_file, &file_contents_internal): Use them.
(&transform): No longer substitute `%!COND%', forcing the use of
`! %?COND%'.
* ansi2knr.am, lex.am, tags.am, texinfos.am, yacc.am: Adjust.

12 files changed:
ChangeLog
NEWS
ansi2knr.am
automake.in
automake.texi
lex.am
lib/am/ansi2knr.am
lib/am/lex.am
lib/am/texinfos.am
lib/am/yacc.am
texinfos.am
yacc.am

index 968697f..814ece7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 2001-05-08  Akim Demaille  <akim@epita.fr>
 
+       Support `if !COND', `else COND', `end COND'.
+
+       * automake.texi (Conditionals): Document it.
+       * automake.in ($WHITE_PATTERN, $MACRO_PATTERN, $BOGUS_MACRO_PATTERN)
+       ($GNITS_VERSION_PATTERN, $INCLUDE_PATTERN): Use `\d' and `\s'.
+       ($IF_PATTERN, $ELSE_PATTERN, $ENDIF_PATTERN): Likewise, and accept
+       a leading `!' before the condition.
+       (&handle_options): Use `\d'.
+       (&cond_stack_if, &cond_stack_else, &&cond_stack_endif): New.
+       (&read_am_file, &file_contents_internal): Use them.
+       (&transform): No longer substitute `%!COND%', forcing the use of
+       `! %?COND%'.
+       * ansi2knr.am, lex.am, tags.am, texinfos.am, yacc.am: Adjust.
+
+2001-05-08  Akim Demaille  <akim@epita.fr>
+
        Uniform handling of per-object compilation rules.
        Note: Automake is repaired.
 
diff --git a/NEWS b/NEWS
index c38f914..67fb0d7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,6 @@
 New in 1.4e:
 * Support for `configure.ac'.
+* Support for `else COND', `endif COND' and negated conditions `!COND'.
 
 New in 1.4b:
 * Faster AM_INIT_AUTOMAKE (requires update of `missing' script)
index 0e4c921..a267cef 100644 (file)
@@ -30,7 +30,7 @@ ANSI2KNR = %ANSI2KNR-DIR%/ansi2knr
 %ANSI2KNR-DIR%/ansi2knr:
        cd %ANSI2KNR-DIR% && $(MAKE) $(AM_MAKEFLAGS) ansi2knr
 
-else %?ANSI2KNR-DIR%
+else !%?ANSI2KNR-DIR%
 
 ## Substitution from AM_C_PROTOTYPES.  This makes it be built only when
 ## necessary.
@@ -39,7 +39,7 @@ ansi2knr: ansi2knr.$(OBJEXT)
        $(LINK) ansi2knr.$(OBJEXT) $(LIBS)
 ansi2knr.$(OBJEXT): $(CONFIG_HEADER)
 
-endif %?ANSI2KNR-DIR%
+endif !%?ANSI2KNR-DIR%
 
 
 ## ------------------- ##
@@ -47,7 +47,7 @@ endif %?ANSI2KNR-DIR%
 ## ------------------- ##
 
 
-if %!ANSI2KNR-DIR%
+if !%?ANSI2KNR-DIR%
 .PHONY: clean-krextra
 
 clean-am: clean-krextra
@@ -59,7 +59,7 @@ clean-krextra:
 ## should remove it (and if the maintainer built it, then
 ## maintainer-clean should remove it).
        -rm -f ansi2knr
-endif %!ANSI2KNR-DIR%
+endif !%?ANSI2KNR-DIR%
 
 
 
index 96b269e..d7c0f3d 100755 (executable)
@@ -88,7 +88,7 @@ my $pkgdata_dir = "@datadir@/@PACKAGE@";
 
 # String constants.
 my $IGNORE_PATTERN = '^##([^#].*)?$';
-my $WHITE_PATTERN = '^[ \t]*$';
+my $WHITE_PATTERN = '^\s*$';
 my $COMMENT_PATTERN = '^#';
 my $TARGET_PATTERN='[$a-zA-Z_.][-.a-zA-Z0-9_(){}/$]*';
 my $RULE_PATTERN = "^($TARGET_PATTERN) *:([^=].*|)\$";
@@ -96,21 +96,21 @@ my $SUFFIX_RULE_PATTERN = '^\.([a-zA-Z0-9]+)\.([a-zA-Z0-9]+)$';
 # Only recognize leading spaces, not leading tabs.  If we recognize
 # leading tabs here then we need to make the reader smarter, because
 # otherwise it will think rules like `foo=bar; \' are errors.
-my $MACRO_PATTERN = '^ *([A-Za-z0-9_@]+)[ \t]*([:+]?)=[ \t]*(.*)$';
-my $BOGUS_MACRO_PATTERN = '^ *([^ \t]*)[ \t]*([:+]?)=[ \t]*(.*)$';
+my $MACRO_PATTERN = '^ *([A-Za-z0-9_@]+)\s*([:+]?)=\s*(.*)$';
+my $BOGUS_MACRO_PATTERN = '^ *([^ \t]*)\s*([:+]?)=\s*(.*)$';
 # This pattern recognizes a Gnits version id and sets $1 if the
 # release is an alpha release.  We also allow a suffix which can be
 # used to extend the version number with a "fork" identifier.
-my $GNITS_VERSION_PATTERN = '[0-9]+\.[0-9]+([a-z]|\.[0-9]+)?(-[A-Za-z0-9]+)?';
-my $IF_PATTERN = '^if[ \t]+([A-Za-z][A-Za-z0-9_]*)[ \t]*(#.*)?$';
-my $ELSE_PATTERN =   '^else(?:[ \t]+([A-Za-z][A-Za-z0-9_]*))?[ \t]*(#.*)?$';
-my $ENDIF_PATTERN = '^endif(?:[ \t]+([A-Za-z][A-Za-z0-9_]*))?[ \t]*(#.*)?$';
+my $GNITS_VERSION_PATTERN = '\d+\.\d+([a-z]|\.\d+)?(-[A-Za-z0-9]+)?';
+my $IF_PATTERN =          '^if\s+(!?)\s*([A-Za-z][A-Za-z0-9_]*)\s*(?:#.*)?$';
+my $ELSE_PATTERN =   '^else(?:\s+(!?)\s*([A-Za-z][A-Za-z0-9_]*))?\s*(?:#.*)?$';
+my $ENDIF_PATTERN = '^endif(?:\s+(!?)\s*([A-Za-z][A-Za-z0-9_]*))?\s*(?:#.*)?$';
 my $PATH_PATTERN='(\w|[/.-])+';
 # This will pass through anything not of the prescribed form.
-my $INCLUDE_PATTERN = ('^include[ \t]+'
+my $INCLUDE_PATTERN = ('^include\s+'
                       . '((\$\(top_srcdir\)/' . $PATH_PATTERN . ')'
                       . '|(\$\(srcdir\)/' . $PATH_PATTERN . ')'
-                      . '|([^/\$]' . $PATH_PATTERN. '))[ \t]*(#.*)?$');
+                      . '|([^/\$]' . $PATH_PATTERN. '))\s*(#.*)?$');
 
 # Some regular expressions.  One reason to put them here is that it
 # makes indentation work better in Emacs.
@@ -1251,14 +1251,14 @@ sub handle_options
            {
                $use_dependencies = 0;
            }
-           elsif (/([0-9]+)\.([0-9]+)([a-z]?)(-[A-Za-z0-9]+)?/)
+           elsif (/(\d+)\.(\d+)([a-z]?)(-[A-Za-z0-9]+)?/)
            {
                # Got a version number.
 
                my ($rmajor, $rminor, $ralpha, $rfork) = ($1, $2, $3, $4);
 
                &prog_error ("version is incorrect: $VERSION")
-                 if $VERSION !~ /([0-9]+)\.([0-9]+)([a-z]?)(-[A-Za-z0-9]+)?/;
+                 if $VERSION !~ /(\d+)\.(\d+)([a-z]?)(-[A-Za-z0-9]+)?/;
 
                my ($tmajor, $tminor, $talpha, $tfork) = ($1, $2, $3, $4);
 
@@ -5640,6 +5640,103 @@ sub check_ambiguous_conditional ($$)
 
 
 
+## ------------------------------ ##
+## Handling the condition stack.  ##
+## ------------------------------ ##
+
+
+# $COND_STRING
+# cond_stack_if ($NEGATE, $COND, $WHERE)
+# --------------------------------------
+sub cond_stack_if ($$$)
+{
+  my ($negate, $cond, $where) = @_;
+
+  &am_file_error ($where, "$cond does not appear in AM_CONDITIONAL")
+    if ! $configure_cond{$cond} && $cond !~ /^TRUE|FALSE$/;
+
+  $cond = "${cond}_TRUE"
+    unless $cond =~ /^TRUE|FALSE$/;
+  $cond = condition_negate ($cond)
+    if $negate;
+
+  push (@cond_stack, $cond);
+
+  return conditional_string (@cond_stack);
+}
+
+
+# $COND_STRING
+# cond_stack_else ($NEGATE, $COND, $WHERE)
+# ----------------------------------------
+sub cond_stack_else ($$$)
+{
+  my ($negate, $cond, $where) = @_;
+
+  if (! @cond_stack)
+    {
+      &am_file_error ($where, "else without if");
+      return;
+    }
+
+  $cond_stack[$#cond_stack] = condition_negate ($cond_stack[$#cond_stack]);
+
+  # If $COND is given, check against it.
+  if (defined $cond)
+    {
+      $cond = "${cond}_TRUE"
+       unless $cond =~ /^TRUE|FALSE$/;
+      $cond = condition_negate ($cond)
+       if $negate;
+
+      &am_file_error ($where,
+                     "else reminder ($negate$cond) incompatible with "
+                     . "current conditional: $cond_stack[$#cond_stack]")
+       if $cond_stack[$#cond_stack] ne $cond;
+    }
+
+  return conditional_string (@cond_stack);
+}
+
+
+# $COND_STRING
+# cond_stack_endif ($NEGATE, $COND, $WHERE)
+# -----------------------------------------
+sub cond_stack_endif ($$$)
+{
+  my ($negate, $cond, $where) = @_;
+  my $old_cond;
+
+  if (! @cond_stack)
+    {
+      &am_file_error ($where, "endif without if");
+      return;
+    }
+
+
+  # If $COND is given, check against it.
+  if (defined $cond)
+    {
+      $cond = "${cond}_TRUE"
+       unless $cond =~ /^TRUE|FALSE$/;
+      $cond = condition_negate ($cond)
+       if $negate;
+
+      &am_file_error ($where,
+                     "endif reminder ($negate$cond) incompatible with "
+                     . "current conditional: $cond_stack[$#cond_stack]")
+       if $cond_stack[$#cond_stack] ne $cond;
+    }
+
+  pop @cond_stack;
+
+  return conditional_string (@cond_stack);
+}
+
+
+
+
+
 ## ------------------------ ##
 ## Handling the variables.  ##
 ## ------------------------ ##
@@ -6516,45 +6613,20 @@ sub read_am_file
                }
            }
        }
+
        elsif (/$IF_PATTERN/o)
-       {
-           my $new_cond = $1;
-           &am_line_error ($., "$new_cond does not appear in AM_CONDITIONAL")
-               if ! $configure_cond{$new_cond} && $new_cond !~ /^TRUE|FALSE$/;
-           push (@cond_stack,
-                 (($new_cond =~ /^TRUE|FALSE$/)
-                  ? "$new_cond" : "${new_cond}_TRUE"));
-           $cond = conditional_string (@cond_stack);
-       }
+         {
+           $cond = cond_stack_if ($1, $2, "$amfile:$.");
+         }
        elsif (/$ELSE_PATTERN/o)
-       {
-           if (! @cond_stack)
-           {
-               &am_line_error ($., "else without if");
-           }
-           elsif ($cond_stack[$#cond_stack] =~ /_FALSE$/)
-           {
-               &am_line_error ($., "else after else");
-           }
-           else
-           {
-               $cond_stack[$#cond_stack]
-                 = condition_negate ($cond_stack[$#cond_stack]);
-               $cond = conditional_string (@cond_stack);
-           }
-       }
+         {
+           $cond = cond_stack_else ($1, $2, "$amfile:$.");
+         }
        elsif (/$ENDIF_PATTERN/o)
-       {
-           if (! @cond_stack)
-           {
-               &am_line_error ($., "endif without if");
-           }
-           else
-           {
-               pop @cond_stack;
-               $cond = conditional_string (@cond_stack);
-           }
-       }
+         {
+           $cond = cond_stack_endif ($1, $2, "$amfile:$.");
+         }
+
        elsif (/$RULE_PATTERN/o)
        {
            # Found a rule.
@@ -6911,43 +6983,17 @@ sub file_contents_internal ($%)
 
         # Handling the conditionals.
         elsif (/$IF_PATTERN/o)
-       {
-           my $new_cond = $1;
-           &am_line_error ($., "$new_cond does not appear in AM_CONDITIONAL")
-               if ! $configure_cond{$new_cond} && $new_cond !~ /^TRUE|FALSE$/;
-           push (@cond_stack,
-                 ($new_cond =~ /^TRUE|FALSE$/) ? "$new_cond" : "${new_cond}_TRUE");
-           $cond = conditional_string (@cond_stack);
-       }
+         {
+           $cond = cond_stack_if ($1, $2, $basename);
+         }
        elsif (/$ELSE_PATTERN/o)
-       {
-           if (! @cond_stack)
-           {
-               &am_error ("else without if");
-           }
-           elsif ($cond_stack[$#cond_stack] =~ /_FALSE$/)
-           {
-               &am_error ("else after else");
-           }
-           else
-           {
-             $cond_stack[$#cond_stack] =
-               condition_negate ($cond_stack[$#cond_stack]);
-             $cond = conditional_string (@cond_stack);
-           }
-       }
+         {
+           $cond = cond_stack_else ($1, $2, $basename);
+         }
        elsif (/$ENDIF_PATTERN/o)
-       {
-           if (! @cond_stack)
-           {
-               &am_error ("endif without if");
-           }
-           else
-           {
-               pop @cond_stack;
-               $cond = conditional_string (@cond_stack);
-           }
-       }
+         {
+           $cond = cond_stack_endif ($1, $2, $basename);
+         }
 
         # Handling rules.
        elsif (/$RULE_PATTERN/mso)
@@ -7083,12 +7129,12 @@ sub transform (%)
        if ($val)
        {
            $result .= "s/\Q?$token?\E//gm;s/^.*\Q?!$token?\E.*\\n//gm;";
-           $result .= "s/\Q%?$token%\E/TRUE/gm;s/\Q%!$token%\E/FALSE/gm;";
+           $result .= "s/\Q%?$token%\E/TRUE/gm;";
        }
        else
        {
            $result .= "s/\Q?!$token?\E//gm;s/^.*\Q?$token?\E.*\\n//gm;";
-           $result .= "s/\Q%?$token%\E/FALSE/gm;s/\Q%!$token%\E/TRUE/gm;";
+           $result .= "s/\Q%?$token%\E/FALSE/gm;";
        }
     }
 
index 0693c92..9e7007d 100644 (file)
@@ -3408,9 +3408,23 @@ noinst_PROGRAMS = $(DBG)
 This trivial example could also be handled using EXTRA_PROGRAMS
 (@pxref{A Program}).
 
-You may only test a single variable in an @code{if} statement.  The
-@code{else} statement may be omitted.  Conditionals may be nested to any
-depth.
+You may only test a single variable in an @code{if} statement, possibly
+negated using @samp{!}.  The @code{else} statement may be omitted.
+Conditionals may be nested to any depth.  You may specify an argument to
+@code{else} in which case it must be the negation of the condition used
+for the current @code{if}.  Similarly you may specify the condition
+which is closed by an @code{end}:
+
+@example
+if DEBUG
+DBG = debug
+else !DEBUG
+DBG =
+endif !DEBUG
+@end example
+
+@noindent
+Unbalanced conditions are errors.
 
 Note that conditionals in Automake are not the same as conditionals in
 GNU Make.  Automake conditionals are checked at configure time by the
diff --git a/lex.am b/lex.am
index 006e0be..82cb589 100644 (file)
--- a/lex.am
+++ b/lex.am
@@ -23,6 +23,6 @@ LEXLIB = @LEXLIB@
 %LEX_SUFFIX%%C_SUFFIX%:
 if %?YLWRAP%
        $(SHELL) $(YLWRAP) $(LEX) $< $(LEX_OUTPUT_ROOT).c $@ -- $(AM_LFLAGS) $(LFLAGS)
-else
+else !%?YLWRAP%
        $(LEX) $(AM_LFLAGS) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@
-endif %?YLWRAP%
+endif !%?YLWRAP%
index 0e4c921..a267cef 100644 (file)
@@ -30,7 +30,7 @@ ANSI2KNR = %ANSI2KNR-DIR%/ansi2knr
 %ANSI2KNR-DIR%/ansi2knr:
        cd %ANSI2KNR-DIR% && $(MAKE) $(AM_MAKEFLAGS) ansi2knr
 
-else %?ANSI2KNR-DIR%
+else !%?ANSI2KNR-DIR%
 
 ## Substitution from AM_C_PROTOTYPES.  This makes it be built only when
 ## necessary.
@@ -39,7 +39,7 @@ ansi2knr: ansi2knr.$(OBJEXT)
        $(LINK) ansi2knr.$(OBJEXT) $(LIBS)
 ansi2knr.$(OBJEXT): $(CONFIG_HEADER)
 
-endif %?ANSI2KNR-DIR%
+endif !%?ANSI2KNR-DIR%
 
 
 ## ------------------- ##
@@ -47,7 +47,7 @@ endif %?ANSI2KNR-DIR%
 ## ------------------- ##
 
 
-if %!ANSI2KNR-DIR%
+if !%?ANSI2KNR-DIR%
 .PHONY: clean-krextra
 
 clean-am: clean-krextra
@@ -59,7 +59,7 @@ clean-krextra:
 ## should remove it (and if the maintainer built it, then
 ## maintainer-clean should remove it).
        -rm -f ansi2knr
-endif %!ANSI2KNR-DIR%
+endif !%?ANSI2KNR-DIR%
 
 
 
index 006e0be..82cb589 100644 (file)
@@ -23,6 +23,6 @@ LEXLIB = @LEXLIB@
 %LEX_SUFFIX%%C_SUFFIX%:
 if %?YLWRAP%
        $(SHELL) $(YLWRAP) $(LEX) $< $(LEX_OUTPUT_ROOT).c $@ -- $(AM_LFLAGS) $(LFLAGS)
-else
+else !%?YLWRAP%
        $(LEX) $(AM_LFLAGS) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@
-endif %?YLWRAP%
+endif !%?YLWRAP%
index 2a831b3..4864ce0 100644 (file)
@@ -27,10 +27,10 @@ if %?SUBDIRS%
 RECURSIVE_TARGETS += info-recursive dvi-recursive
 .PHONY info: info-recursive
 .PHONY dvi: dvi-recursive
-else %?SUBDIRS%
+else !%?SUBDIRS%
 info: info-am
 dvi: dvi-am
-endif %?SUBDIRS%
+endif !%?SUBDIRS%
 
 info-am: $(INFO_DEPS)
 dvi-am: $(DVIS)
@@ -55,9 +55,9 @@ install-data-am: install-info-am
 if %?SUBDIRS%
 RECURSIVE_TARGETS += install-info-recursive
 .PHONY install-info: install-info-recursive
-else %?SUBDIRS%
+else !%?SUBDIRS%
 .PHONY install-info: install-info-am
-endif %?SUBDIRS%
+endif !%?SUBDIRS%
 endif %?INSTALL-INFO%
 install-info-am: $(INFO_DEPS)
        @$(NORMAL_INSTALL)
index 5800ca2..0d7e105 100644 (file)
@@ -20,7 +20,7 @@
 %YACC_SUFFIX%%C_SUFFIX%:
 if %?YLWRAP%
        $(SHELL) $(YLWRAP) $(YACC) $< y.tab.c $*%C_SUFFIX% y.tab.h $*.h -- $(AM_YFLAGS) $(YFLAGS)
-else
+else !%?YLWRAP%
        $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*%C_SUFFIX%
        if test -f y.tab.h; then \
          if cmp -s y.tab.h $*.h; then \
@@ -29,4 +29,4 @@ else
            mv y.tab.h $*.h; \
          fi; \
        fi
-endif %?YLWRAP%
+endif !%?YLWRAP%
index 2a831b3..4864ce0 100644 (file)
@@ -27,10 +27,10 @@ if %?SUBDIRS%
 RECURSIVE_TARGETS += info-recursive dvi-recursive
 .PHONY info: info-recursive
 .PHONY dvi: dvi-recursive
-else %?SUBDIRS%
+else !%?SUBDIRS%
 info: info-am
 dvi: dvi-am
-endif %?SUBDIRS%
+endif !%?SUBDIRS%
 
 info-am: $(INFO_DEPS)
 dvi-am: $(DVIS)
@@ -55,9 +55,9 @@ install-data-am: install-info-am
 if %?SUBDIRS%
 RECURSIVE_TARGETS += install-info-recursive
 .PHONY install-info: install-info-recursive
-else %?SUBDIRS%
+else !%?SUBDIRS%
 .PHONY install-info: install-info-am
-endif %?SUBDIRS%
+endif !%?SUBDIRS%
 endif %?INSTALL-INFO%
 install-info-am: $(INFO_DEPS)
        @$(NORMAL_INSTALL)
diff --git a/yacc.am b/yacc.am
index 5800ca2..0d7e105 100644 (file)
--- a/yacc.am
+++ b/yacc.am
@@ -20,7 +20,7 @@
 %YACC_SUFFIX%%C_SUFFIX%:
 if %?YLWRAP%
        $(SHELL) $(YLWRAP) $(YACC) $< y.tab.c $*%C_SUFFIX% y.tab.h $*.h -- $(AM_YFLAGS) $(YFLAGS)
-else
+else !%?YLWRAP%
        $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*%C_SUFFIX%
        if test -f y.tab.h; then \
          if cmp -s y.tab.h $*.h; then \
@@ -29,4 +29,4 @@ else
            mv y.tab.h $*.h; \
          fi; \
        fi
-endif %?YLWRAP%
+endif !%?YLWRAP%