]> git.ipfire.org Git - thirdparty/automake.git/commitdiff
* aclocal.in (list_compare): New functions.
authorAlexandre Duret-Lutz <adl@gnu.org>
Mon, 31 Jan 2005 23:41:10 +0000 (23:41 +0000)
committerAlexandre Duret-Lutz <adl@gnu.org>
Mon, 31 Jan 2005 23:41:10 +0000 (23:41 +0000)
(scan_file): Honor #serial lines.
* tests/acloca18.test: New test.
* tests/Makefile.am (TESTS): Add it.
* doc/automake.texi (aclocal options, Local Macros): Document
#serial.

ChangeLog
NEWS
aclocal.in
doc/automake.texi
doc/stamp-vti
doc/version.texi
tests/Makefile.am
tests/Makefile.in
tests/acloca18.test [new file with mode: 0755]

index ec2f1ec7b1ebbe2bee144a0f715ffc0c8ddc31ab..78706921640a9f75aca8900d4ea389503811e02d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2005-02-01  Alexandre Duret-Lutz  <adl@gnu.org>
+
+       * aclocal.in (list_compare): New functions.
+       (scan_file): Honor #serial lines.
+       * tests/acloca18.test: New test.
+       * tests/Makefile.am (TESTS): Add it.
+       * doc/automake.texi (aclocal options, Local Macros): Document
+       #serial.
+
 2005-01-30  Alexandre Duret-Lutz  <adl@gnu.org>
 
        Preliminary support for `aclocal --install'.
diff --git a/NEWS b/NEWS
index f369e3225d7beab672fd8aaa1c17a5d0edfeefa9..f821127741eaee31912955b64e43e302e46d86fe 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -21,7 +21,8 @@ New in 1.9a:
 
   - aclocal supports an --install option, that will cause system-wide
     third-party macros to be installed in the local directory
-    specified with the first -I flag.
+    specified with the first -I flag.  This option also uses #serial
+    lines in M4 files to upgrade local macros.
 
   - Per-target flags are now correctly handled in link rules.
 
index 44b687eb843a77cbee509d5a1059e8422bc8d32f..a071cfdcd993862c51cdc827d1fd75ee81d9fc36 100644 (file)
@@ -89,6 +89,9 @@ my %map = ();
 # Ditto, but records the last definition of each macro as returned by --trace.
 my %map_traced_defs = ();
 
+# Map basenames to macro names.
+my %invmap = ();
+
 # Map file names to file contents.
 my %file_contents = ();
 
@@ -107,6 +110,11 @@ my %file_added = ();
 # Files that have already been scanned.
 my %scanned_configure_dep = ();
 
+# Serial numbers, for files that have one.
+# The key is the basename of the file,
+# the value is the serial number represented as a list.
+my %serial = ();
+
 # Matches a macro definition.
 #   AC_DEFUN([macroname], ...)
 # or
@@ -123,6 +131,9 @@ my $ac_require_rx = "AC_REQUIRE\\((?:\\[([^]]+)\\]|([^],)\n]+))\\)";
 # Matches an m4_include line
 my $m4_include_rx = "(?:m4_)?s?include\\((?:\\[([^]]+)\\]|([^],)\n]+))\\)";
 
+# Match a serial number
+my $serial_line_rx = '^#\s*serial\s*(.*?)\s*$';
+my $serial_number_rx = '^\d+(?:\.\d+)*$';
 \f
 ################################################################
 
@@ -150,6 +161,8 @@ sub reset_maps ()
   %file_includes = ();
   %file_added = ();
   %scanned_configure_dep = ();
+  %invmap = ();
+  %serial = ();
   undef &search;
 }
 
@@ -173,6 +186,34 @@ sub install_file ($$)
     }
 }
 
+# Compare two lists of numbers.
+sub list_compare (\@\@)
+{
+  my @l = @{$_[0]};
+  my @r = @{$_[1]};
+  while (1)
+    {
+      if (0 == @l)
+       {
+         return (0 == @r) ? 0 : -1;
+       }
+      elsif (0 == @r)
+       {
+         return 1;
+       }
+      elsif ($l[0] < $r[0])
+       {
+         return -1;
+       }
+      elsif ($l[0] > $r[0])
+       {
+         return 1;
+       }
+      shift @l;
+      shift @r;
+    }
+}
+
 ################################################################
 
 # scan_m4_dirs($TYPE, @DIRS)
@@ -343,7 +384,8 @@ my $underquoted_manual_once = 0;
 sub scan_file ($$$)
 {
   my ($type, $file, $where) = @_;
-  my $base = dirname $file;
+  my $dirname = dirname $file;
+  my $basename = basename $file;
 
   # Do not scan the same file twice.
   return @{$file_includes{$file}} if exists $file_includes{$file};
@@ -360,6 +402,11 @@ sub scan_file ($$$)
   my $contents = '';
   my @inc_files = ();
   my %inc_lines = ();
+
+  my $defun_seen = 0;
+  my $serial_seen = 0;
+  my $serial_older = 0;
+
   while ($_ = $fh->getline)
     {
       # Ignore `##' lines.
@@ -368,8 +415,57 @@ sub scan_file ($$$)
       $contents .= $_;
       my $line = $_;
 
+      if ($line =~ /$serial_line_rx/go)
+       {
+         my $number = $1;
+         if ($number !~ /$serial_number_rx/go)
+           {
+             msg ('syntax', "$file:$.",
+                  "malformed serial number `$number', "
+                  . "expecting only digits and dots");
+           }
+         elsif ($defun_seen)
+           {
+             # aclocal removes all definitions from M4 file with the
+             # same basename if a greater serial number is found.
+             # Encountering a serial after some macros will undefine
+             # these macros...
+             msg ('syntax', "$file:$.",
+                  'the serial number must appear before any macro definition');
+           }
+         # We really care about serials only for non-automake macros
+         # and when --install is used.  But the above diagnostics are
+         # made regardless of this, because not using --install is
+         # not a reason not the fix macro files.
+         elsif ($install && $type != FT_AUTOMAKE)
+           {
+             $serial_seen = 1;
+             my @new = split (/\./, $number);
+
+             verb "$file:$.: serial $number";
+
+             if (!exists $serial{$basename}
+                 || list_compare (@new, @{$serial{$basename}}) > 0)
+               {
+                 # Delete any definition we knew from the old macro.
+                 foreach my $def (@{$invmap{$basename}})
+                   {
+                     verb "$file:$.: ignoring previous definition of $def";
+                     delete $map{$def};
+                   }
+                 $invmap{$basename} = [];
+                 $serial{$basename} = \@new;
+               }
+             else
+               {
+                 $serial_older = 1;
+               }
+           }
+       }
+
       while ($line =~ /$ac_defun_rx/go)
        {
+         $defun_seen = 1;
          if (! defined $1)
            {
              msg ('syntax', "$file:$.", "warning: underquoted definition of $2"
@@ -379,11 +475,20 @@ sub scan_file ($$$)
                unless $underquoted_manual_once;
              $underquoted_manual_once = 1;
            }
+
+         # If this macro does not have a serial and we have already
+         # seen a macro with the same basename earlier, we should
+         # ignore the macro (don't exit immediately so we can still
+         # diagnose later #serial numbers and underquoted macros).
+         $serial_older ||= ($type != FT_AUTOMAKE
+                            && !$serial_seen && exists $serial{$basename});
+
          my $macro = $1 || $2;
-         if (! defined $map{$macro})
+         if (!$serial_older && !defined $map{$macro})
            {
              verb "found macro $macro in $file: $.";
              $map{$macro} = $file;
+             push @{$invmap{$basename}}, $macro;
            }
          else
            {
@@ -406,12 +511,19 @@ sub scan_file ($$$)
          # paths (they might be used later of aclocal outputs an
          # m4_include for this file, or if the user itself includes
          # this file).
-         $ifile = "$base/$ifile"
-           unless $base eq '.' || File::Spec->file_name_is_absolute ($ifile);
+         $ifile = "$dirname/$ifile"
+           unless $dirname eq '.' || File::Spec->file_name_is_absolute ($ifile);
          push (@inc_files, $ifile);
          $inc_lines{$ifile} = $.;
        }
     }
+
+  # Ignore any file that has an old serial (or no serial if we know
+  # another one with a serial).
+  return ()
+    if ($serial_older ||
+       ($type != FT_AUTOMAKE && !$serial_seen && exists $serial{$basename}));
+
   $file_contents{$file} = $contents;
 
   # For some reason I don't understand, it does not work
index 71a428f81bbafb1f31f7174068e61b1167f78d94..ed99f1076e1444d5ac9b6675a14066f2e8bb60dc 100644 (file)
@@ -1663,6 +1663,11 @@ Install system-wide third-party macros into the first directory
 specified with @code{-I @var{dir}} instead of copying them in the
 output files.
 
+When this option is used, @command{aclocal} will also honor
+@code{#serial @var{NUMBER}} lines that appear in macros: an M4 file is
+ignored if there exists another M4 file with the same basename and a
+greater serial number in the search path.
+
 @item --force
 @opindex --force
 Always overwrite the output file.  The default is to overwrite the output
@@ -2247,18 +2252,34 @@ Since Automake 1.10, @command{aclocal} offers an option to copy these
 system-wide third-party macros in your local macro directory, solving
 the above problem.  Simply use:
 
-@example
+@smallexample
  ACLOCAL_AMFLAGS = -I m4 --install
-@end example
+@end smallexample
 
 @noindent
 With this setup, system-wide macros will be copied to @file{m4/}
 the first time you run @command{autoreconf}.  Then the locally
 installed macros will have precedence over the system-wide installed
-macros each time @command{aclocal} is run again.  (So the only reason
-to keep @code{--install} in the flags after the first run is that when
-you later edit @file{configure.ac} and depend on a new macro, this
-macro will be installed in your @file{m4/} automatically.)
+macros each time @command{aclocal} is run again.
+
+One reason why you should keep @code{--install} in the flags even
+after the first run is that when you later edit @file{configure.ac}
+and depend on a new macro, this macro will be installed in your
+@file{m4/} automatically.  Another one is that serial numbers can be
+used to update the macros in your source tree automatically when new
+system-wide versions are installed.  A serial number should be a
+single line of the form
+
+@smallexample
+#serial @var{NNN}
+@end smallexample
+
+@noindent
+where @var{NNN} contains only digits and dots.  It should appear in
+the M4 file before any macro definition.  It is a good practice to
+maintain a serial number for each macro you distribute, even if you do
+not use the @code{--install} option of @command{aclocal}: this allows
+other people to use it.
 
 
 @node Future of aclocal
index 21e3ad8c75fd8b1a01cc3a0b7c438d2cb1ca9cdb..f8d917edfa302c05bd3b896802c9b58733a42612 100644 (file)
@@ -1,4 +1,4 @@
-@set UPDATED 30 January 2005
-@set UPDATED-MONTH January 2005
+@set UPDATED 1 February 2005
+@set UPDATED-MONTH February 2005
 @set EDITION 1.9a
 @set VERSION 1.9a
index 21e3ad8c75fd8b1a01cc3a0b7c438d2cb1ca9cdb..f8d917edfa302c05bd3b896802c9b58733a42612 100644 (file)
@@ -1,4 +1,4 @@
-@set UPDATED 30 January 2005
-@set UPDATED-MONTH January 2005
+@set UPDATED 1 February 2005
+@set UPDATED-MONTH February 2005
 @set EDITION 1.9a
 @set VERSION 1.9a
index 8e5e60f456401ea99a5e95bbc4d693cd38681a80..80779b6f0afe4cadb64a4c44a6a7684493441166 100644 (file)
@@ -20,6 +20,7 @@ acloca14.test \
 acloca15.test \
 acloca16.test \
 acloca17.test \
+acloca18.test \
 acoutnoq.test \
 acoutpt.test \
 acoutpt2.test \
index 5d0fcfca5772662f3ffa44e40934121a03b6d5aa..837565d63ba0fdce3db0d324a9432464fa3c9934 100644 (file)
@@ -140,6 +140,7 @@ acloca14.test \
 acloca15.test \
 acloca16.test \
 acloca17.test \
+acloca18.test \
 acoutnoq.test \
 acoutpt.test \
 acoutpt2.test \
diff --git a/tests/acloca18.test b/tests/acloca18.test
new file mode 100755 (executable)
index 0000000..362d8ba
--- /dev/null
@@ -0,0 +1,95 @@
+#! /bin/sh
+# Copyright (C) 2005  Free Software Foundation, Inc.
+#
+# This file is part of GNU Automake.
+#
+# GNU Automake 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.
+#
+# GNU Automake 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 Automake; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# Test for --install with #serial numbers.
+
+. ./defs || exit 1
+
+set -e
+
+cat >> configure.in << 'END'
+AM_MACRO1
+AM_MACRO2
+END
+
+mkdir 1 2 3 4
+
+cat >1/m1.m4 <<EOF
+#serial 1.8.1230.9
+AC_DEFUN([AM_MACRO1], [echo macro11 >> foo])
+AC_DEFUN([AM_MACRO2], [echo macro21 >> foo])
+EOF
+
+cat >2/m1.m4 <<EOF
+#serial 1.8.1231.9
+AC_DEFUN([AM_MACRO1], [echo macro12 >> foo])
+EOF
+
+cat >3/m2.m4 <<EOF
+#serial 13
+AC_DEFUN([AM_MACRO2], [echo macro23 >> foo])
+EOF
+
+cat >3/m1.m4 <<EOF
+#serial 1.8.1230.1
+AC_DEFUN([AM_MACRO1], [echo macro13 >> foo])
+EOF
+
+cat >4/mumble.m4 <<EOF
+#serial 0
+AC_DEFUN([AM_MACRO1], [echo macro14 >> foo])
+EOF
+
+
+ACLOCAL_TESTSUITE_FLAGS='-I 1 -I 2 -I 3 -I 4'
+
+$ACLOCAL
+$AUTOCONF
+./configure
+grep macro11 foo
+grep macro21 foo
+
+rm -f foo
+$ACLOCAL --install
+$AUTOCONF
+./configure
+grep macro12 foo
+grep macro23 foo
+
+ACLOCAL_TESTSUITE_FLAGS='-I 4 -I 1 -I 2 -I 3'
+rm -f foo
+$ACLOCAL --install
+$AUTOCONF
+./configure
+grep macro14 foo
+grep macro23 foo
+
+ACLOCAL_TESTSUITE_FLAGS='-I 4 -I 1 -I 2'
+rm -f foo
+$ACLOCAL --install 2>stderr && exit 1
+grep AM_MACRO2 stderr
+
+ACLOCAL_TESTSUITE_FLAGS='-I 4 -I 1'
+rm -f foo
+$ACLOCAL --install
+$AUTOCONF
+./configure
+grep macro14 foo
+grep macro21 foo