From: Akim Demaille Date: Sat, 4 Aug 2001 13:14:39 +0000 (+0000) Subject: Don't let autom4te compute the `include' traces several times: X-Git-Tag: AUTOCONF-2.52d~122 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4ffd4212d667914b32d4909221d23f5c7ea65a56;p=thirdparty%2Fautoconf.git Don't let autom4te compute the `include' traces several times: first check that the trace cache file is up to date, and then compare its timestamp with that of the output. * bin/autom4te.in, bin/autoupdate.in, bin/autoscan.in: Normalize the preamble. Don't require 5.005 as Autom4te::General does it, and better yet (use `use', not `require'!). * lib/Autom4te/Struct.pm: Rename the last occurrences of Class::Struct as Autom4te::Struct. * lib/Autom4te/General.pm (File::stat): Use it. (&mtime): New, export it. * bin/autom4te.in: Use it. Declare `$req' is invalid if it is outdated. Don't declare it valid before saving it if something went wrong. --- diff --git a/ChangeLog b/ChangeLog index 84f09ba49..f5928af1c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2001-08-04 Akim Demaille + + Don't let autom4te compute the `include' traces several times: + first check that the trace cache file is up to date, and then + compare its timestamp with that of the output. + + * bin/autom4te.in, bin/autoupdate.in, bin/autoscan.in: Normalize + the preamble. Don't require 5.005 as Autom4te::General does it, + and better yet (use `use', not `require'!). + * lib/Autom4te/Struct.pm: Rename the last occurrences of + Class::Struct as Autom4te::Struct. + * lib/Autom4te/General.pm (File::stat): Use it. + (&mtime): New, export it. + * bin/autom4te.in: Use it. + Declare `$req' is invalid if it is outdated. + Don't declare it valid before saving it if something went wrong. + 2001-08-04 Akim Demaille Autom4te shall not encode Autoconf data, and preselecting traces diff --git a/bin/autom4te.in b/bin/autom4te.in index b5a7a875e..35996f3dd 100644 --- a/bin/autom4te.in +++ b/bin/autom4te.in @@ -23,25 +23,20 @@ eval 'exec @PERL@ -S $0 ${1+"$@"}' # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. -require 5.005; -use File::Basename; - -my $me = basename ($0); - -## --------- ## -## Request. ## -## --------- ## - -package Request; BEGIN { my $prefix = "@prefix@"; - # FIXME: Import Struct into Autoconf. my $perllibdir = $ENV{'autom4te_perllibdir'} || "@datadir@"; unshift @INC, "$perllibdir"; } +## --------- ## +## Request. ## +## --------- ## + +package Request; + use Data::Dumper; use Autom4te::General; use Autom4te::Struct; @@ -62,7 +57,7 @@ struct ( # The key of the cache file. 'cache' => "\$", - # True if the cache file is up to date. + # True iff %MACRO contains all the macros we want to trace. 'valid' => "\$", # The include path. 'path' => '@', @@ -75,7 +70,11 @@ struct ); +# $REQUEST-OBJ +# retrieve ($SELF, %ATTR) +# ----------------------- # Find a request with the same path and source. +# Private. sub retrieve { my ($self, %attr) = @_; @@ -97,8 +96,13 @@ sub retrieve return undef; } + +# $REQUEST-OBJ +# register ($SELF, %ATTR) +# ----------------------- # NEW should not be called directly. -sub register +# Private. +sub register ($%) { my ($self, %attr) = @_; @@ -114,27 +118,33 @@ sub register } -# request(%REQUEST) -# ----------------- +# $REQUEST-OBJ +# request($SELF, %REQUEST) +# ------------------------ # Return a request corresponding to $REQUEST{path} and $REQUEST{source}, # using a cache value if it exists. -sub request +sub request ($%) { my ($self, %request) = @_; - my $obj = Request->retrieve (%request) || Request->register (%request); + my $req = Request->retrieve (%request) || Request->register (%request); # If there are new traces to produce, then we are not valid. foreach (@{$request{'macro'}}) { - if (! exists ${$obj->macro}{$_}) + if (! exists ${$req->macro}{$_}) { - ${$obj->macro}{$_} = 1; - $obj->valid (0); - } + ${$req->macro}{$_} = 1; + $req->valid (0); + } } - return $obj; + # It would be great to have $REQ check that it up to date wrt its + # dependencies, but that requires gettting traces (to fetch the + # included files), which is out of the scope of Request + # (currently?). + + return $req; } # Serialize a request or all the current requests. @@ -848,23 +858,24 @@ EOF # $BOOL -# up_to_date_p ($REQ, $FILE) -# -------------------------- -# If $FILE up to date? -# We need $REQ since we check $FILE against all its dependencies, -# and we use the traces on `include' to find them. -sub up_to_date_p ($$) +# up_to_date_p ($REQ) +# ------------------- +# Is the cache file of $REQ up to date? +# $REQ is `valid' if it corresponds to the request and exists, which +# does not mean it is up to date. It is up to date if, in addition, +# it's younger than its dependencies. +sub up_to_date_p ($) { - my ($req, $file) = @_; + my ($req) = @_; - # If STDOUT or doesn't exist, it sure is outdated! return 0 - if $file eq '-' || ! -f $file; + if ! $req->valid; # We can't answer properly if the traces are not computed since we # need to know what other files were included. + my $file = "$me.cache/" . $req->cache; return 0 - if ! -f "$me.cache/" . $req->cache; + if ! -f $file; # We depend at least upon the arguments. my @dep = @ARGV; @@ -875,13 +886,13 @@ sub up_to_date_p ($$) handle_traces ($req, "$tmp/dependencies", ('include' => '$1', 'm4_include' => '$1')); - my $mtime = (stat ($file))[9]; + my $mtime = mtime ($file); my $deps = new IO::File ("$tmp/dependencies"); push @dep, map { chomp; find_file ($_) } $deps->getlines; foreach (@dep) { verbose "$file depends on $_"; - if ($mtime < (stat ($_))[9]) + if ($mtime < mtime ($_)) { verbose "$file depends on $_ which is more recent"; return 0; @@ -912,45 +923,51 @@ Request->load ("$me.cache/requests") # Add the new trace requests. my $req = Request->request ('source' => \@ARGV, - 'path' => \@include, - 'macro' => [keys %trace, @preselect]); + 'path' => \@include, + 'macro' => [keys %trace, @preselect]); +# If $REQ is not up to date, declare it invalid. +$req->valid (0) + if ! up_to_date_p ($req); + +# We now know whether we can trust the Request object. Say it. if ($verbose) { print STDERR "$me: the trace request object is:\n"; print STDERR $req->marshall; } -# We need to run M4 if -# - for traces -# + there is no cache, or -# + it does not include the traces we need, or -# + it exists but is outdated -# - for output if it is not /dev/null and -# + it doesn't exist, or -# + it is outdated +# We need to run M4 if (i) $REQ is invalid, or (ii) we are expanding +# (i.e., not tracing) and the output is older than the cache file +# (since the later is valid if it's older than the dependencies). +# STDOUT is pretty old. +my $output_mtime = mtime ($output); + handle_m4 ($req, keys %{$req->macro}) if (! $req->valid - || ! up_to_date_p ($req, "$me.cache/" . $req->cache) - || (! %trace && ! up_to_date_p ($req, "$output"))); + || (! %trace && $output_mtime < mtime ("$me.cache/" . $req->cache))); + +# Now output... if (%trace) { - # Producing traces. - # Trying to produce the output only when needed is very - # error prone here, as you'd have to check that the trace - # requests have not changed etc. + # Always produce traces, since even if the output is young enough, + # there is no guarantee that the traces use the same *format* + # (e.g., `-t FOO:foo' and `-t FOO:bar' are both using the same M4 + # traces, hence the M4 traces cache is usable, but its formating + # will yield different results). handle_traces ($req, $output, %trace); } else { - # Actual M4 expansion. + # Actual M4 expansion, only if $output is too old. handle_output ($output) - if ! up_to_date_p ($req, $output); + if $output_mtime < mtime ("$me.cache/" . $req->cache); } -# All went fine, the cache is valid. -$req->valid (1); +# If all went fine, the cache is valid. +$req->valid (1) + if $exit_status == 0; Request->save ("$me.cache/requests"); diff --git a/bin/autoscan.in b/bin/autoscan.in index be508aff5..3aba42101 100644 --- a/bin/autoscan.in +++ b/bin/autoscan.in @@ -20,12 +20,9 @@ # Written by David MacKenzie . -use 5.005; - BEGIN { my $prefix = "@prefix@"; - # FIXME: Import Struct into Autoconf. my $perllibdir = $ENV{'autom4te_perllibdir'} || "@datadir@"; unshift @INC, "$perllibdir"; } diff --git a/bin/autoupdate.in b/bin/autoupdate.in index 9fd790386..491477722 100644 --- a/bin/autoupdate.in +++ b/bin/autoupdate.in @@ -21,12 +21,9 @@ # Originally written by David MacKenzie . # Rewritten by Akim Demaille . -use 5.005; - BEGIN { my $prefix = "@prefix@"; - # FIXME: Import Struct into Autoconf. my $perllibdir = $ENV{'autom4te_perllibdir'} || "@datadir@"; unshift @INC, "$perllibdir"; } diff --git a/lib/Autom4te/General.pm b/lib/Autom4te/General.pm index bcfcdf8c3..a084c369a 100644 --- a/lib/Autom4te/General.pm +++ b/lib/Autom4te/General.pm @@ -21,12 +21,15 @@ package Autom4te::General; use 5.005; use Exporter; use File::Basename; +use File::stat; use Carp; use strict; -use vars qw (@ISA @EXPORT $me); + +use vars qw (@ISA @EXPORT); @ISA = qw (Exporter); -@EXPORT = qw (&find_configure_ac &find_peer &mktmpdir &uniq &verbose &xsystem +@EXPORT = qw (&find_configure_ac &find_peer &mktmpdir &mtime + &uniq &verbose &xsystem $me $verbose $debug $tmp); # Variable we share with the main package. Be sure to have a single @@ -164,6 +167,25 @@ sub mktmpdir ($) } +# $MTIME +# MTIME ($FILE) +# ------------- +# Return the mtime of $FILE. Missing files, or `-' standing for STDIN +# or STDOUT are ``obsolete'', i.e., as old as possible. +sub mtime ($) +{ + my ($file) = @_; + + return 0 + if $file eq '-' || ! -f $file; + + my $stat = stat ($file) + or croak "$me: cannot stat $file: $!\n"; + + return $stat->mtime; +} + + # @RES # uniq (@LIST) # ------------ diff --git a/lib/Autom4te/Struct.pm b/lib/Autom4te/Struct.pm index 9ca728103..6a3e90d06 100644 --- a/lib/Autom4te/Struct.pm +++ b/lib/Autom4te/Struct.pm @@ -16,6 +16,12 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. +# This file is basically Perl 5.6's Class::Struct, but made compatible +# with Perl 5.5. If someday this has to be updated, be sure to rename +# all the occurrences of Class::Struct into Autom4te::Struct, otherwise +# if we `use' a Perl module (e.g., File::stat) that uses Class::Struct, +# we would have two packages defining the same symbols. Boom. + package Autom4te::Struct; ## See POD after __END__ @@ -43,7 +49,7 @@ sub printem { } { - package Class::Struct::Tie_ISA; + package Autom4te::Struct::Tie_ISA; sub TIEARRAY { my $class = shift; @@ -52,7 +58,7 @@ sub printem { sub STORE { my ($self, $index, $value) = @_; - Class::Struct::_subclass_error(); + Autom4te::Struct::_subclass_error(); } sub FETCH { @@ -102,7 +108,7 @@ sub struct { \@{$class . '::ISA'}; }; _subclass_error() if @$isa; - tie @$isa, 'Class::Struct::Tie_ISA'; + tie @$isa, 'Autom4te::Struct::Tie_ISA'; # Create constructor. @@ -244,24 +250,24 @@ __END__ =head1 NAME -Class::Struct - declare struct-like datatypes as Perl classes +Autom4te::Struct - declare struct-like datatypes as Perl classes =head1 SYNOPSIS - use Class::Struct; + use Autom4te::Struct; # declare struct, based on array: struct( CLASS_NAME => [ ELEMENT_NAME => ELEMENT_TYPE, ... ]); # declare struct, based on hash: struct( CLASS_NAME => { ELEMENT_NAME => ELEMENT_TYPE, ... }); package CLASS_NAME; - use Class::Struct; + use Autom4te::Struct; # declare struct, based on array, implicit class name: struct( ELEMENT_NAME => ELEMENT_TYPE, ... ); package Myobj; - use Class::Struct; + use Autom4te::Struct; # declare struct with four types of elements: struct( s => '$', a => '@', h => '%', c => 'My_Other_Class' ); @@ -289,7 +295,7 @@ Class::Struct - declare struct-like datatypes as Perl classes =head1 DESCRIPTION -C exports a single function, C. +C exports a single function, C. Given a list of element names and types, and optionally a class name, C creates a Perl 5 class that implements a "struct-like" data structure. @@ -439,7 +445,7 @@ structs are nested. Here, C represents a time (seconds and microseconds), and C has two elements, each of which is of type C. - use Class::Struct; + use Autom4te::Struct; struct( rusage => { ru_utime => timeval, # seconds @@ -470,7 +476,7 @@ element always to be nonnegative, so we redefine the C accessor accordingly. package MyObj; - use Class::Struct; + use Autom4te::Struct; # declare the struct struct ( 'MyObj', { count => '$', stuff => '%' } ); @@ -510,7 +516,7 @@ as an anonymous hash of initializers, which is passed on to the nested struct's constructor. - use Class::Struct; + use Autom4te::Struct; struct Breed => { @@ -541,6 +547,12 @@ struct's constructor. =head1 Author and Modification History +Modified by Akim Demaille, 2001-08-03 + + Rename as Autom4te::Struct to avoid name clashes with + Class::Struct. + + Make it compatible with Perl 5.5. Modified by Damian Conway, 1999-03-05, v0.58. diff --git a/man/autoscan.1 b/man/autoscan.1 index b485e0e3f..6b71ae848 100644 --- a/man/autoscan.1 +++ b/man/autoscan.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.24. -.TH AUTOSCAN "1" "August 2001" "GNU Autoconf 2.52b" FSF +.TH AUTOSCAN "1" "August 2001" "GNU Autoconf 2.52c" FSF .SH NAME autoscan \- Generate a preliminary configure.in .SH SYNOPSIS diff --git a/man/autoupdate.1 b/man/autoupdate.1 index fe1e53e94..889eaf482 100644 --- a/man/autoupdate.1 +++ b/man/autoupdate.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.24. -.TH AUTOUPDATE "1" "August 2001" "GNU Autoconf 2.52b" FSF +.TH AUTOUPDATE "1" "August 2001" "GNU Autoconf 2.52c" FSF .SH NAME autoupdate \- Update a configure.in to a newer Autoconf .SH SYNOPSIS @@ -35,7 +35,7 @@ M4 GNU M4 1.4 or above .TP AUTOCONF -autoconf 2.52b +autoconf 2.52c .SH AUTHOR Written by David J. MacKenzie and Akim Demaille. .PP