summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorNorbert Preining <preining@logic.at>2009-12-04 04:58:31 +0000
committerNorbert Preining <preining@logic.at>2009-12-04 04:58:31 +0000
commitb088d18fd87779513119a324910df7be3c8e0be3 (patch)
tree2a20053114a569be7cbc0f05d1e1b63b592127df /Build
parentbe861ba965ad6cda3b589b02f31d38ffd0876e0e (diff)
update latexmk.pl in source
git-svn-id: svn://tug.org/texlive/trunk@16293 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latexmk/latexmk.pl560
1 files changed, 356 insertions, 204 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/latexmk/latexmk.pl b/Build/source/texk/texlive/linked_scripts/latexmk/latexmk.pl
index 13cf3071512..0588b2efe9c 100755
--- a/Build/source/texk/texlive/linked_scripts/latexmk/latexmk.pl
+++ b/Build/source/texk/texlive/linked_scripts/latexmk/latexmk.pl
@@ -16,27 +16,6 @@ use warnings;
# See ?? <===============================
-# Results of 8 Sep 2007:
-
-# Some improvements relative to the issues below.
-
-# ????????:
-# Why is bibtex not always running right? Or running when it shouldn't
-# I've put in rdb_make_links in a few places.
-# and rdb_write
-# Problem is that aux file is always out of date, until after a
-# primary run. Ensure fdb and c. is updated enough etc.
-# I may have it correct now: fdb_write in makeB
-# See also routine rdb_update_files_for_rule, and who calls it
-# It appears to be unused. What is rationale?
-
-# Apparently excess runs of latex after change in .tex file that entails
-# change in bibliography.
-
-## ???!!!!!!!!!!!!! Should I remove bibtex rule? NO
-## ?? Need to set dependence of extra bibtex rules on .bib file
-## ?? Put $pass as variable in rule.
-
## ?? Issues with clean-up
## List of aux files deleted is those read, not those generated.
## Other files are generated by (pdf)latex; should they be deleted?
@@ -46,15 +25,8 @@ use warnings;
#=======================================
-#?? Check all code for rdb stuff.
-#?? Use of $update and $failure, etc
-# Especially in pvc. Should I restore source file set up
-# if there is a latex error??????????????????????
#?? Force mode doesn't appear to do force (if error in latex file)
#??? Get banner back in.
-#?? ==> Clean up of rdb. It accumulates files that aren't in use any more.
-# Restrict to dependents (existent or not) discovered during
-# parse of log file, and its consequences.
#?? CORRECT DIAGNOSTICS ON CHANGED FILES IF THEY DIDN'T EXIST BEFORE
#?? Further corrections to deal with disappeared source files for custom dependencies.
# Message repeatedly appears about remake when source file of cusdep doesn't exist.
@@ -62,11 +34,7 @@ use warnings;
# Reconsider
#?? Do proper run-stuff for bibtex, makeindex, cus-deps. OK I think
# Parse and correctly find bst and ist files
-#?? Remove superfluous code when it's working. Mostly done.
-#?? update_source_times in particular. I think it's done OK
-#?? Add making of other files to rdb. Unify
-#?? Ditto for printing and viewing?
-#?? Update documentation
+
# ATTEMPT TO ALLOW FILENAMES WITH SPACES:
# (as of 1 Apr 2006, and then 14 Sep. 2007)
@@ -132,7 +100,6 @@ use warnings;
# Rationalize again handling of include files.
# Now I use kpsewhich to do searches, if file not found
# (How do I avoid getting slowed down too much?)
-# Better parsing of log file for includes.
# Document the assumptions at each stage of processing algorithm.
# Option to restart previewer automatically, if it dies under -pvc
# Test for already running previewer gets wrong answer if another
@@ -140,8 +107,8 @@ use warnings;
$my_name = 'latexmk';
$My_name = 'Latexmk';
-$version_num = '4.08';
-$version_details = "$My_name, John Collins, 23 June 2009";
+$version_num = '4.11';
+$version_details = "$My_name, John Collins, 27 November 2009";
use Config;
@@ -174,7 +141,7 @@ else {
warn "Something wrong with the perl configuration: No signals?\n";
}
-## Copyright John Collins 1998-2008
+## Copyright John Collins 1998-2009
## (username collins at node phys.psu.edu)
## (and thanks to David Coppit (username david at node coppit.org)
## for suggestions)
@@ -208,107 +175,53 @@ else {
## 5. Parsing of log file instead of source file is used to
## obtain dependencies, by default.
##
-## Modification log for 24 Sep 2008 onwards in detail
+## Modification log from 21 Aug 2009 onwards in detail
##
-## 22 Jun 2009, John Collins Binmode for log file under MSWin
-## to avoid problem with ctrl/Z written
-## by Miktex 2.7 giving spurious end-of-file
-## 10 Jun 2009, John Collins V. 4.08
-## 27 May 2009, John Collins V. 4.07
-## 23 May 2009, John Collins Try to work rationally when run of
-## (pdf)latex does not produce
-## output.
-## Diagonostic when latex makes pdf or
-## pdflatex makes dvi.
-## 28 Apr 2009, John Collins Deal with case that file is written
-## during run, but is not in database
-## before run.
-## 17 Apr 2009, John Collins V. 4.06
-## 14 Apr 2009, John Collins In parse_logB, clean up a bit more
-## aggressively non-existent source files
-## 11 Apr 2009, John Collins Capture ctrl/C and ctrl/break during wait
-## loop in preview_continuous. Then
-## control stays within latexmk on break
-## from loop. It allows user to do
-## postprocessing, like
-## "latexmk -pvc file; cleanup;"
-## 10 Apr 2009, John Collins Safer use of % in placeholders in commands
-## 10 Apr 2009, John Collins V. 4.05
-## 3 Apr 2009, John Collins Change to a nicer #! line
-## 26 Mar 2009, John Collins Case independence for one item in
-## @file_not_found
-## 6 Mar 2009, John Collins Single %input_extensions variable
-## Correct bug in making cusdep for missing
-## extensionless file
-## 5 Mar 2009, John Collins Get rid of warning about variables used
-## only once.
-## 25 Feb 2009, John Collins Ensure viewed file type is made.
-## Configurable extensions for finding
-## cusdep.
-## 24 Feb 2009, John Collins V. 4.04
-## Fix problems when using both latex and pdflatex
-## 1. In fdb, keep primary rules that have been
-## run, even if they are not in use in
-## current invocation of latexmk.
-## 2. But don't write primary rules if they have
-## not been run (i.e., $run_time==0).
-## 3. If $run_time==0 for an in-use primary
-## rule, i.e., if the rule has not
-## been run, then run it
-## unconditionally.
-## 4. But don't let this apply to other
-## rules, since the time-stamp rule
-## will normally have been adequate.
-## Improved diagnostics on reason for rerun.
-## Corrected classify_rules call in pvc.
-## In rdb_set_from_logB: when setting
-## subsidiary rules after parsing log
-## file, this is now done only for the
-## currently-being-applied primary rule,
-## not for all primary rules.
-## 22 Dec 2008, John Collins V. 4.03
-## 22 Dec 2008, John Collins Fix possibility that unwrapping of lines
-## in log_file is done incorrectly
-## 5 Dec 2008, John Collins Correct treatment of -e option
-## 2 Dec 2008, John Collins For home directory (where user's .latexmkrc
-## is located, when $ENV{'HOME'} does
-## not exist, use $ENV{USERPROFILE}
-## (suitable for MS-Win).
-## Clean up code in rdb_set_rules
-## 1 Dec 2008, John Collins -c and -C now also delete fdb_latex file
-## 26 Nov 2008, John Collins Correct problem with invocation of MSWin
-## with cygwin
-## 25 Nov 2008, John Collins Correct problem with invocation of MSWin
-## start command
-## 15 Nov 2008, John Collins Make version # 4.02, for release
-## 12 Nov 2008, John Collins Deal with quoted filenames in log file
-## (as with MikTeX)
-## 10 Nov 2008, John Collins Start fixing bug about -ps -pdfps
-## running ps2pdf before dvips
-## 30 Sep 2008, John Collins V. 4.01a
-## Correct problem that aux files not of
-## same basename are not deleted on clean-up
-## Primary problem: fdb file was deleted before
-## being read
-## ?? Remaining issues on this:
-## List of aux files deleted is those read,
-## not those generated
-## Other files are generated by (pdf)latex
-## should they be deleted?
-## Solution of problem that if a source file
-## for (pdf)latex disappears, that is treated
-## as a change requiring a rerun. This gives
-## an infinite loop of unnecessary runs in
-## -pvc mode
-## Cleanup can also apply to all files
-## generated during (pdf)latex run,
-## as diagnosed by \openout lines,
-## and also to files generated from
-## these. Controlling variable
-## $cleanup_includes_generated.
-## 24 Sep 2008, John Collins Release version 4.01.
+## 27 Nov 2009, John Collins Solve problem that changes in \include
+## files weren't reflected in changes
+## in bibtex source files.
+## Remove excess recalculations of md5 in
+## startup and when initializing rule
+## from fdb_latexmk file.
+## Fdb_latexmk now has data for all rules
+## need for making target files,
+## not just rules accessible from primary
+## rules.
+## 26 Nov 2009, John Collins In testing for changes, when filetime
+## has changed, but file is unchanged,
+## update filetime in rule.
+## This saves excessive md5 calculations.
+## 25 Nov 2009, John Collins Fixed issue with fdb_get and 1-second
+## granularity of file timestamps.
+## The issue was that if runs of
+## latex (etc) occur within the
+## 1-second time granularity, file
+## contents can change even though
+## the file's time and size are
+## unchanged, falsifying an
+## assumption made by fdb_get, but
+## only when the old time is the
+## same as the run time of a command
+## that uses the file.
+## Avoided excess md5 calculations at
+## startup.
+## 24 Nov 2009, John Collins Start 4.11
+## 22 Sep 2009, John Collins Bibtex error => message see blg file.
+## 10 Sep 2009, John Collins When tmp view file is moved to view file,
+## delete original file first. Avoids
+## bug in kpdf
+## 4 Sep 2009, John Collins A missing file message is now suppressed
+## when -silent option used
+## kpsewhich is used to find non-existent
+## converted files (as with epstopdf)
+## 1 Sep 2009, John Collins Change "last FILE" to "next FILE"
+## on failure in main loop.
+## I had earlier changed this from "next FILE" to
+## "last FILE" (for v. 4.08), but I don't see why.
+## 21 Aug 2009, John Collins V. 4.10 for CTAN release.
##
-## 1998-2008, John Collins. Many improvements and fixes.
+## 1998-2009, John Collins. Many improvements and fixes.
+## See CHANGE-log.txt for full list, and CHANGES for summary
##
## Modified by Evan McLean (no longer available for support)
## Original script (RCS version 2.3) called "go" written by David J. Musliner
@@ -404,6 +317,7 @@ else {
#Line length in log file that indicates wrapping.
# This number EXCLUDES line-end characters, and is one-based
+# It is the parameter max_print_line in the TeX program. (tex.web)
$log_wrap = 79;
#########################################################################
@@ -423,6 +337,7 @@ $log_wrap = 79;
'.*?:\\d*: LaTeX Error: File `([^\\\']*)\\\' not found\\.',
'^LaTeX Warning: File `([^\\\']*)\\\' not found',
'^Package .* [fF]ile `([^\\\']*)\\\' not found',
+ 'Error: pdflatex \(file ([^\)]*)\): cannot find image file',
);
## Hash mapping file extension (w/o period, e.g., 'eps') to a single regexp,
@@ -1146,7 +1061,7 @@ if (!$TEXINPUTS) { $TEXINPUTS = '.'; }
# last_result, last_message
# ]
# where
- # cmd_type is 'primary', 'external' or 'cusdep',
+ # cmd_type is 'primary', 'external', or 'cusdep'
# ext_cmd is string for associated external command
# with substitutions (%D for destination, %S
# for source, %B for base of current rule,
@@ -1219,6 +1134,23 @@ if (!$TEXINPUTS) { $TEXINPUTS = '.'; }
# the run, so that even though the file changes during
# a primary run, there is no need to trigger another
# run because of this.
+ # Size and md5 correspond to the values at the last run.
+ # But time may be updated to correspond to the time
+ # for the file, if the file is otherwise unchanged.
+ # This saves excessive md5 calculations, which would
+ # otherwise be done everytime the file is checked,
+ # in the following situation:
+ # When the file has been rewritten after a run
+ # has started (commonly aux, bbl files etc),
+ # but the actual file contents haven't
+ # changed. Then because the filetime has
+ # changed, on every file-change check latexmk
+ # would normally redo the md5 calculation to
+ # test for actual changes. Once one such
+ # check is done, and the contents are
+ # unchanged, later checks are superfluous, and
+ # can be avoided by changing the file's time
+ # in the source-file list.
%fdb_current = (); # Fdb-hash for all files used.
@@ -1688,6 +1620,9 @@ foreach $filename ( @file_list )
local %idx_files = (); # Maps idx_file to (ind_file, base)
local %generated_log = (); # Lists generated files
local $primary_out = ''; # Actual output file (dvi or pdf)
+ local %conversions = (); # (pdf)latex-performed conversions.
+ # Maps output file created and read by (pdf)latex
+ # to source file of conversion.
print "$My_name: Examining log file for generated files...\n";
&parse_logB;
@@ -1788,6 +1723,15 @@ foreach $filename ( @file_list )
rdb_for_some( [keys %possible_primaries], \&rdb_set_from_logB );
}
}
+ foreach $rule ( rdb_accessible( uniq1( keys %requested_filerules ) ) ){
+ # For all source files of all accessible rules,
+ # if the file data are not already set (e.g., from fdb_latexmk
+ # file, set them from disk.
+ rdb_one_rule ($rule, undef,
+ sub{ if ( $$Ptime == 0) { &rdb_update1; } }
+ );
+ }
+
if ($go_mode) {
# Force everything to be remade.
rdb_recurseA( [keys %requested_filerules], sub{$$Pout_of_date=1;} );
@@ -1824,7 +1768,7 @@ foreach $filename ( @file_list )
$failure = 0;
$failure_msg = '';
$failure = rdb_makeB( keys %requested_filerules );
- if ($failure > 0) { last FILE; }
+ if ($failure > 0) { next FILE; }
rdb_for_some( [keys %one_time], \&rdb_run1 );
} # end FILE
continue {
@@ -2021,7 +1965,9 @@ sub rdb_set_rules {
# " S='$source', D='$dest', B='$base' $needs_making\n";
rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, $test_kind,
$source, $dest, $base,
- $needs_making );
+ $needs_making, undef, 1 );
+# !! ?? Last line was
+# $needs_making, undef, ($test_kind==1) );
}
} # End arguments of subroutine
&rdb_make_links;
@@ -2150,6 +2096,7 @@ sub do_viewfile {
if ( &view_file_via_temporary ) {
my $tmpfile = tempfile1( "${root_filename}_tmp", $ext );
$return = &rdb_ext_cmd1( '', '', $tmpfile );
+ unlink $$Pdest;
move( $tmpfile, $$Pdest );
}
else {
@@ -2420,7 +2367,9 @@ CHANGE:
"------------\n";
}
}
- local $retcode = rdb_makeB ( 'view' );
+ local $retcode = 0;
+ rdb_one_rule( 'view', sub { $retcode = &rdb_run1;} );
+# PREVIOUS local $retcode = rdb_makeB ( 'view' );
if ( $retcode != 0 ) {
if ($force_mode) {
warn "$My_name: I could not run previewer\n";
@@ -2444,7 +2393,7 @@ CHANGE:
WAIT: while (1) {
sleep($sleep_time);
if ($have_break) { last WAIT; }
- if ( rdb_have_changes(@targets) ) {
+ if ( rdb_new_changes(@targets) ) {
if (!$silent) {
warn "$My_name: Need to remake files.\n";
&rdb_diagnose_changes( ' ' );
@@ -2824,10 +2773,14 @@ sub parse_logB {
# Should be LaTeX file that exists.
# If it doesn't exist, we have probably a mis-parsed line.
# There's no need to do a search.
-# 4 = definitive, which in this subroutine is only
-# done for default dependents
+# 4 = definitive, which in this subroutine is only done:
+# for default dependents,
+# and for files that exist and are source of conversion
+# reported by epstopdf et al.
# 5 = Had a missing file line. Now the file exists.
# 6 = File was written during run. (Overrides 5)
+# 7 = File was created during run to be read in. (Overrides 5 and 6)
+# (e.g., by epstopdf)
# Treat the following specially, since they have special rules
# @bbl_files to list of .bbl files.
# %idx_files to map from .idx files to .ind files.
@@ -2854,6 +2807,7 @@ sub parse_logB {
@bbl_files = ();
%idx_files = (); # Maps idx_file to (ind_file, base)
%generated_log = ();
+ %conversions = ();
# $primary_out is actual output file (dvi or pdf)
# It is initialized before the call to this routine, to ensure
# a sensible default in case of misparsing
@@ -2876,11 +2830,39 @@ sub parse_logB {
# used by perl. (Notably a problem with MSWin latex and
# cygwin perl!)
s/[\n\r]*$//;
+ # Handle wrapped lines:
+ # They are lines brutally broken at exactly $log_wrap chars
+ # excluding line-end. The TeX program adds an EXTRA
+ # end-of-line character whenever a line gets to $log_wrap
+ # characters. So we recover the unwrapped line(s) simply
+ # by deleting the end-of-line following a line of exactly
+ # $log_wrap characters.
+ my $len = length($_);
+ while ( ($len == $log_wrap) && !eof($log_file) ) {
+ my $extra = <$log_file>;
+ $extra =~ s/[\n\r]*$//;
+ $len = length($extra);
+ $_ .= $extra;
+ }
push @lines, $_;
}
close $log_file;
+
+ push @lines, ""; # Blank line to terminate. So multiline blocks
+ # are always terminated by non-block line, rather than eof.
my $line = 0;
+ # For parsing multiple line blocks of info
+ my $current_pkg = ""; # non-empty string for package name, if in
+ # middle of parsing multi-line block of form:
+ # Package name ....
+ # (name) ...
+ # ...
+ my $block_type = ""; # Specify information in such a block
+ my $delegated_source = ""; # If it is a file conversion, specify source
+ my $delegated_output = ""; # and output file. (Don't put in
+ # data structure until block is ended.)
+ my %new_conversions = ();
LINE:
while( $line <= $#lines ) {
$_ = $lines[$line];
@@ -2897,22 +2879,25 @@ LINE:
return 0;
}
}
- # Handle wrapped lines:
- # They are lines brutally broken at exactly $log_wrap chars
- # excluding line-end.
- # But a line can be of the length where the wrapping occurs, but
- # there can be no wrapping. So for a long line, try parsing it
- # as if it is wrapped, but leave the index variable $line as is,
- # so that on the next loop over LINE, we also try parsing the
- # succeeding line as if there was no wrapping:
- my $len = length($_);
- my $next = $line;
- while ( ($len == $log_wrap) && ($next <= $#lines) ) {
- my $extra = $lines[$next];
- $next++;
- $len = length($extra);
- $_ .= $extra;
- }
+ if ( $block_type ) {
+ # In middle of parsing block
+ if ( /^\($current_pkg\)/ ) {
+ # Block continues
+ if ( ($block_type eq 'conversion')
+ && /^\($current_pkg\)\s+Output file: <([^>]+)>/ )
+ {
+ $delegated_output = $1;
+ }
+ next LINE;
+ }
+ # Block has ended.
+ if ($block_type eq 'conversion') {
+ $new_conversions{$delegated_source} = $delegated_output;
+ }
+ $current_pkg = $block_type
+ = $delegated_source = $delegated_output = "";
+ # Then process current line
+ }
# Check for changed references, bad references and bad citations:
if (/Rerun to get/) {
warn "$My_name: References changed.\n";
@@ -2957,6 +2942,15 @@ LINE:
$generated_log{$1} = 1;
next LINE;
}
+ # Test for conversion produced by package:
+ if ( /^Package (\S+) Info: Source file: <([^>]+)>/ ) {
+ # Info. produced by epstopdf (and possibly others)
+ # about file conversion
+ $current_pkg = $1;
+ $delegated_source = $2;
+ $block_type = 'conversion';
+ next LINE;
+ }
# Test for writing of index file. The precise format of the message
# depends on which package (makeidx.sty , multind.sty or index.sty) and
# which version writes the message.
@@ -3227,12 +3221,56 @@ CANDIDATE:
my ($base, $path, $ext) = fileparseA($candidate);
$ext =~ s/^\.//;
if ( ($ext eq '') && (-e "$path$base.tex") ) {
- $dependents{"$path$base.tex"} = 4;
- delete $dependents{$candidate};
+ # I don't think the old version was correct.
+ # If the missing-file report was of a bare
+ # extensionless file, and a corresponding .tex file
+ # exists, then the missing file does not correspond
+ # to the missing file, unless the .tex file was
+ # created during the run.
+ # OLD $dependents{"$path$base.tex"} = 4;
+ # OLD delete $dependents{$candidate};
+ # NEW:
+ $dependents{"$path$base.tex"} = 4;
}
push @missing, $candidate;
}
}
+CANDIDATE_PAIR:
+ foreach my $delegated_source (keys %new_conversions) {
+ my $delegated_output = $new_conversions{$delegated_source};
+ my $rule = "Delegated $delegated_source, $delegated_output";
+ # N.B. $delegated_source eq '' means the output file
+ # was created without a named input file.
+ foreach my $candidate ($delegated_source, $delegated_output) {
+ if (! -e $candidate ) {
+ # The file might be somewhere that can be found
+ # in the search path of kpathsea:
+ my @kpse_result = kpsewhich( $candidate,);
+ if ($#kpse_result > -1) {
+ $candidate = $kpse_result[0];
+ }
+ }
+ }
+ if ( ( (-e $delegated_source) || ($delegated_source eq '') )
+ && (-e $delegated_output) )
+ {
+ $conversions{$delegated_output} = $delegated_source;
+ $dependents{$delegated_output} = 7;
+ if ($delegated_source) {
+ $dependents{$delegated_source} = 4;
+ }
+ }
+ elsif (!$silent) {
+ print "Logfile claimed conversion from '$delegated_source' ",
+ "to '$delegated_output'. But:\n";
+ if (! -e $delegated_output) {
+ print " Output file does not exist\n";
+ }
+ if ( ($delegated_source ne '') && (! -e $delegated_source) ) {
+ print " Input file does not exist\n";
+ }
+ }
+ }
if ( $diagnostics ) {
@@ -3256,6 +3294,8 @@ CANDIDATE:
print " '$_' ";
if ( $dependents{$_} == 6 ) { print " written by (pdf)latex";}
print "\n";
+ if ( $dependents{$_} == 7 ) { print " converted by (pdf)latex";}
+ print "\n";
}
if ($not_found > 0) {
print "Not found:\n";
@@ -3381,11 +3421,33 @@ AUX_LINE:
#************************************************************
sub fdb_get {
- # Call: fdb_get(filename)
+ # Call: fdb_get(filename [, runtime])
# Returns an array (time, size, md5) for the current state of the
# named file.
- # For non-existent file, deletes entry in fdb_current, and returns (0,-1,0)
- my $file = shift;
+ # The optional argument runtime is the runtime of some command
+ # associated with the use of the file --- see below.
+ # For non-existent file, deletes its entry in fdb_current,
+ # and returns (0,-1,0)
+ # As an optimization, the md5 value is taken from the cache in
+ # fdb_current, if the time and size stamp indicate that the
+ # file has not changed.
+ # The md5 value is recalculated if
+ # the current filetime differs from the cached value:
+ # file has been written
+ # the current filesize differs from the cached value:
+ # file has definitely changed
+ # But the file can also be rewritten without change in filetime when
+ # file processing happens within the 1-second granularity of the
+ # timestamp (notably for aux files from latex on a short source file).
+ # The only case that concerns us is when the file is an input to a program
+ # at some runtime t, the file is rewritten later by the same or another
+ # program, with timestamp t, and when the initial file also has
+ # timestamp t.
+ # A test is applied for this situation if the runtime argument is
+ # supplied and is nonzero.
+
+ my ($file, $run_time) = @_;
+ if ( ! defined $run_time ) { $run_time = 0;}
my ($new_time, $new_size) = get_time_size($file);
my @nofile = (0,-1,0); # What we use for initializing
# a new entry in fdb or flagging
@@ -3402,19 +3464,41 @@ sub fdb_get {
}
my $file_data = $fdb_current{$file};
my ( $time, $size, $md5 ) = @$file_data;
- if ( ($new_time != $time) || ($new_size != $size) ) {
+#warn "--------- Getting MD5: $file: (N,O,R) = $new_time, $time, $run_time\n";
+#warn "--------- $file: (OT,OS,OM) = @$file_data\n";
+ if ( ($new_time != $time) || ($new_size != $size)
+ || ( $run_time && ($run_time == $time ) )
+ ) {
# Only force recalculation of md5 if time or size changed
+ # Or if the time equals runtime, so that the file may
+ # have changed within the 1-second granularity of the time
# Else we assume file is really unchanged.
$recalculate_md5 = 1;
}
if ($recalculate_md5) {
+#warn "--------- RECALC MD5: $rule $file: (N,O,R) = $new_time, $time, $run_time\n";
+#warn " ------- $file: (OT,OS,OM) = @$file_data\n";
+#&traceback;
@$file_data = ( $new_time, $new_size, get_checksum_md5( $file ) );
+#warn " ------- $file: (NT,NS,NM) = @$file_data\n";
}
return @$file_data;;
} #END fdb_get
#************************************************************
+sub fdb_set {
+ # Call: fdb_set(filename, $time, $size, $md5 )
+ # Set data in file data cache, i.e., %fdb_current
+ my ($file, $time, $size, $md5 ) = @_;
+ if ( ! exists $fdb_current{$file} ) {
+ $fdb_current{$file} = [0, -1, 0];
+ }
+ @{$fdb_current{$file}} = ( $time, $size, $md5 );
+} #END fdb_set
+
+#************************************************************
+
sub fdb_show {
# Displays contents of fdb
foreach my $file ( sort keys %fdb_current ) {
@@ -3436,7 +3520,6 @@ sub rdb_read {
# Returns -1 if file could not be read else number of errors.
# Thus return value on success is 0
my $in_name = $_[0];
-
my $in_handle = new FileHandle;
$in_handle->open( $in_name, '<' )
or return ();
@@ -3497,8 +3580,11 @@ LINE:
$$PAnew_cmd[1] = $func_name;
}
}
+ # Set source file as non-existent.
+ # If it existed on last run, it will be in later
+ # lines of the fdb file
rdb_create_rule( $rule, 'cusdep', '', $PAnew_cmd, 1,
- $source, $dest, $base, 0, $run_time );
+ $source, $dest, $base, 0, $run_time, 1 );
}
elsif ( $rule =~ /^(makeindex|bibtex)\s*(.*)$/ ) {
my $rule_generic = $1;
@@ -3524,8 +3610,11 @@ LINE:
warn " Rule kind = '$rule_generic'; ext_cmd = '$ext_cmd';\n",
" source = '$source'; dest = '$dest'; base = '$base';\n"
if $diagnostics;
+ # Set source file as non-existent.
+ # If it existed on last run, it will be in later
+ # lines of the fdb file
rdb_create_rule( $rule, $cmd_type, $ext_cmd, '', 1,
- $source, $dest, $base, 0, $run_time);
+ $source, $dest, $base, 0, $run_time, 1);
}
else {
warn "$My_name: In file-database '$in_name' rule '$rule'\n",
@@ -3556,8 +3645,13 @@ LINE:
$errors++;
next LINE;
}
- rdb_ensure_file( $rule, $file );
+ # Set file in database. But ensure we don't do an unnecessary
+ # fdb_get, which can trigger a new MD5 calculation, which is
+ # lengthy for a big file. Ininitially flagging the file
+ # as non-existent solves the problem:
+ rdb_ensure_file( $rule, $file, undef, 1 );
rdb_set_file1( $rule, $file, $time, $size, $md5 );
+ fdb_set( $file, $time, $size, $md5 );
# Save the rest of the data, especially the from_fule until we know all
# the rules, otherwise the from_rule may not exist.
# Also we'll have a better chance of looping through files.
@@ -3675,7 +3769,10 @@ LINE:
sub rdb_write {
# Call: rdb_write( $out_name )
# Writes to the given file name the database of file and rule data
- # accessible from the primary rules.
+ # for all rules needed to make final output
+ # !!?? Previously was:
+ # OLD Writes to the given file name the database of file and rule data
+ # OLD accessible from the primary rules.
# Returns 1 on success, 0 if file couldn't be opened.
local $out_name = $_[0];
local $out_handle = new FileHandle;
@@ -3697,7 +3794,9 @@ sub rdb_write {
&rdb_classify_rules( \%possible_primaries, keys %requested_filerules );
print $out_handle "# Fdb version $fdb_ver\n";
- my @rules = rdb_accessible( uniq1( keys %possible_primaries ) ) ;
+# !!?? Rules or rules accessible from primary
+# my @rules = rdb_accessible( uniq1( keys %possible_primaries ) ) ;
+ my @rules = rdb_accessible( uniq1( keys %possible_primaries, keys %requested_filerules ) ) ;
# Separate call to sort. Otherwise rdb_accessible seems to get wrong argument.
@rules = sort( @rules );
rdb_for_some(
@@ -3747,7 +3846,9 @@ sub rdb_set_from_logB {
local %idx_files = (); # Maps idx_file to (ind_file, base)
local %generated_log = (); # Lists generated files found in log file
local $primary_out = $$Pdest; # output file (dvi or pdf)
-
+ local %conversions = (); # (pdf)latex-performed conversions.
+ # Maps output file created and read by (pdf)latex
+ # to source file of conversion.
# The following are also returned, but are global, to be used by caller
# $reference_changed, $bad_reference $bad_citation
@@ -3804,29 +3905,40 @@ sub rdb_set_from_logB {
my @new_aux_files;
&parse_aux( "$bbl_base.aux", \@new_bib_files, \@new_aux_files );
my $from_rule = "bibtex $bbl_base";
+ print "!!!===Dealing with rule '$from_rule'\n"
+ if ($diagnostics);
if ( ! rdb_rule_exists( $from_rule ) ){
- print "!!!===Creating rule '$from_rule'\n"
+ print " ===Creating rule '$from_rule'\n"
if ($diagnostics);
rdb_create_rule( $from_rule, 'external', $bibtex, '', 1,
"$bbl_base.aux", $bbl_file, $bbl_base, 1, 0);
- foreach my $source ( @new_bib_files, @new_aux_files ) {
- print " ===Source file '$source'\n"
- if ($diagnostics);
- rdb_ensure_file( $from_rule, $source );
- }
- print " ===Source file '$bbl_file' for '$rule'\n"
- if ($diagnostics);
- rdb_ensure_file( $rule, $bbl_file, $from_rule );
- if ( ! -e $bbl_file ) {
- # Failure was non-existence of makable file
- # Leave failure issue to other rules.
- $failure = 0;
- }
+ }
+ local %old_sources = ();
+ rdb_one_rule( $from_rule, sub { %old_sources = %$PHsource; } );
+ foreach my $source ( @new_bib_files, @new_aux_files ) {
+ print " === Source file '$source' for '$from_rule'\n"
+ if ($diagnostics);
+ rdb_ensure_file( $from_rule, $source );
+ delete $old_sources{$source};
+ }
+ if ($diagnostics>-1 ) {
+ foreach ( keys %old_sources ) {
+ print "Removing no-longer-needed dependent '$_' from rule '$from_rule'\n";
+ }
+ }
+ rdb_remove_files( $from_rule, keys %old_sources );
+ print " ===Source file '$bbl_file' for '$rule'\n"
+ if ($diagnostics);
+ rdb_ensure_file( $rule, $bbl_file, $from_rule );
+ if ( ! -e $bbl_file ) {
+ # Failure was non-existence of makable file
+ # Leave failure issue to other rules.
+ $failure = 0;
}
}
NEW_SOURCE:
- foreach my $new_source (keys %dependents) {
+ foreach my $new_source (keys %dependents, keys %conversions) {
print " ===Source file for rule '$rule': '$new_source'\n"
if ($diagnostics);
if ( ($dependents{$new_source} == 5)
@@ -3843,9 +3955,23 @@ NEW_SOURCE:
# treated as non-existent, to ensure another run is forced.
rdb_ensure_file( $rule, $new_source, undef, 1 );
}
+ elsif ( $dependents{$new_source} == 7 ) {
+ # File was result of conversion by (pdf)latex.
+ my $cnv_source = $conversions{$new_source};
+ rdb_ensure_file( $rule, $new_source );
+ if ($cnv_source) {
+ # Conversion from $cnv_source to $new_source
+ # implies that effectively $cnv_source is a source
+ # of the (pdf)latex run.
+ rdb_ensure_file( $rule, $cnv_source );
+ }
+ # Flag that changes of the generated file during a run
+ # do not require a rerun:
+ rdb_one_file( $new_source, sub{ $$Pcorrect_after_primary = 1; } );
+ }
else {
- # But we don't need this precaution for ordinary user files (or
- # for files that are generated outside of latex/pdflatex).
+ # But we don't need special precautions for ordinary user files
+ # (or for files that are generated outside of latex/pdflatex).
rdb_ensure_file( $rule, $new_source );
}
}
@@ -4036,7 +4162,10 @@ sub rdb_set_dependentsA {
# Returns array (sorted), of new source files.
local @new_sources = ();
local @deletions = ();
- rdb_recurseA( [@_], 0, \&rdb_one_depA );
+
+# Shouldn't recurse. The definite rules to be examined are given.
+ rdb_for_some( [@_], 0, \&rdb_one_depA );
+# OLD rdb_recurseA( [@_], 0, \&rdb_one_depA );
foreach (@deletions) {
my ($rule, $file) = @$_;
rdb_remove_files( $rule, $file );
@@ -4520,6 +4649,9 @@ sub rdb_makeB1 {
if ( ( $$Pcmd_type eq 'cusdep') && $$Psource && (! -e $$Psource) ) {
# No action
}
+ elsif ( $$Pcmd_type eq 'delegated' ) {
+ # Delegate to destination rule
+ }
elsif ( $pass{$rule}==0) {
push @no_dest, $$Pdest;
$$Pout_of_date = 1;
@@ -4606,7 +4738,11 @@ sub rdb_makeB1 {
if ($return != 0) {
$failure = 1;
$$Plast_result = 2;
- $$Plast_message = $failure_msg = "Run of rule '$rule' gave a non-zero error code";
+ if ( !$$Plast_message ) {
+ $$Plast_message = "Run of rule '$rule' gave a non-zero error code";
+ }
+# !!?? $failure_msg = $$Plast_message;
+
}
} #END rdb_makeB1
@@ -4776,13 +4912,15 @@ sub rdb_run1 {
$$Plast_message = "Bug or configuration error; incorrect command type";
}
if ( $rule =~ /^bibtex/ ) {
- my $retcode = &check_bibtex_log($$Pbase);
+ my $retcode = check_bibtex_log($$Pbase);
if ($retcode == 3) {
$$Plast_result = 2;
$$Plast_message = "Could not open bibtex log file for '$$Pbase'";
push @warnings, $$Plast_message;
}
elsif ($retcode == 2) {
+ $$Plast_message = "Bibtex errors: See file '$$Pbase.blg'";
+ push @warnings, $$Plast_message;
}
elsif ($retcode == 1) {
push @warnings, "Bibtex warnings for '$$Pbase'";
@@ -4800,7 +4938,7 @@ sub rdb_run1 {
if ( ($$Plast_result == 0) && ($return != 0) ) {
$$Plast_result = 2;
if ($$Plast_message eq '') {
- $$Plast_message = "Command gave return code $return";
+ $$Plast_message = "Command for '$rule' gave return code $return";
}
}
elsif ( $$Pdest && (! -e $$Pdest) ) {
@@ -4891,7 +5029,7 @@ sub rdb_primary_run {
# For each file of the kind made by epstopdf.sty during a run,
# if the file has changed during a run, then the new version of
# the file will have been read during the run. Unlike the usual
- # case, we will need to redo the primary run because of the
+ # case, we will NOT need to redo the primary run because of the
# change of this file during the run. Therefore set the file as
# up-to-date:
rdb_do_files( sub { if ($$Pcorrect_after_primary) {&rdb_update1;} } );
@@ -4957,6 +5095,10 @@ sub rdb_clear_change_record {
sub rdb_flag_changes_here {
# Flag changes in current rule.
# Assumes rule context.
+ # Optional argument: if true then fdb_get shouldn't do runtime test
+ # for recalculation of md5
+ local $ignore_run_time = $_[0];
+ if ( ! defined $ignore_run_time ) { $ignore_run_time = 0; }
local $dest_mtime = 0;
$dest_mtime = get_mtime($$Pdest) if ($$Pdest);
rdb_do_files( \&rdb_file_change1);
@@ -4973,7 +5115,8 @@ sub rdb_file_change1 {
# Assumes rule and file context. Assumes $dest_mtime set.
# Flag whether $file in $rule has changed or disappeared.
# Set rule's make flag if there's a change.
- my ($new_time, $new_size, $new_md5) = fdb_get($file);
+ my $run_time_argument = $ignore_run_time ? 0 : $$Prun_time;
+ my ($new_time, $new_size, $new_md5) = fdb_get($file, $run_time_argument);
#?? print "FC1 '$rule':$file $$Pout_of_date TK=$$Ptest_kind\n";
#?? print " OLD $$Ptime, $$Psize, $$Pmd5\n",
#?? " New $new_time, $new_size, $new_md5\n";
@@ -5005,6 +5148,10 @@ sub rdb_file_change1 {
$$Pout_of_date_user = 1;
}
}
+ elsif ( $new_time != $$Ptime ) {
+#warn "--==-- Unchanged $file, changed time, update filetime in $rule\n";
+ $$Ptime = $new_time;
+ }
if ( ( ($$Ptest_kind == 2) || ($$Ptest_kind == 3) )
&& (! exists $generated_exts_all{$ext} )
&& ( $new_time > $dest_mtime )
@@ -5017,11 +5164,11 @@ sub rdb_file_change1 {
#************************************************************
-sub rdb_have_changes {
+sub rdb_new_changes {
&rdb_clear_change_record;
- rdb_recurseA( [@_], \&rdb_flag_changes_here );
+ rdb_recurseA( [@_], sub{ &rdb_flag_changes_here(1); } );
return ($#changed >= 0) || ($#no_dest >= 0) || ($#rules_to_apply >= 0);
-} #END rdb_have_changes
+} #END rdb_new_changes
#************************************************************
@@ -5351,7 +5498,7 @@ sub rdb_one_file {
sub rdb_create_rule {
# rdb_create_rule( rule, command_type, ext_cmd, int_cmd, test_kind,
# source, dest, base,
- # needs_making, run_time )
+ # needs_making, run_time, set_file_not_exists )
# int_cmd is either a string naming a perl subroutine or it is a
# reference to an array containing the subroutine name and its
# arguments.
@@ -5360,10 +5507,11 @@ sub rdb_create_rule {
# ==== Sets rule data ====
my ( $rule, $cmd_type, $int_cmd, $PAext_cmd, $test_kind,
$source, $dest, $base,
- $needs_making, $run_time ) = @_;
+ $needs_making, $run_time, $set_file_not_exists ) = @_;
my $changed = 0;
# Set defaults, and normalize parameters:
- foreach ( $cmd_type, $int_cmd, $PAext_cmd, $source, $dest, $base ) {
+ foreach ( $cmd_type, $int_cmd, $PAext_cmd, $source, $dest, $base,
+ $set_file_not_exists ) {
if (! defined $_) { $_ = ''; }
}
foreach ( $needs_making, $run_time, $test_kind ) {
@@ -5388,7 +5536,9 @@ sub rdb_create_rule {
$changed, -1, '' ],
{}
];
- if ($source) { rdb_ensure_file( $rule, $source ); }
+ if ($source) {
+ rdb_ensure_file( $rule, $source, undef, $set_file_not_exists );
+ }
} #END rdb_create_rule
#************************************************************
@@ -5421,7 +5571,8 @@ sub rdb_ensure_file {
${$PHsource}{$new_file} = [0, -1, 0, '', 0];
}
else {
- ${$PHsource}{$new_file} = [fdb_get($new_file), '', 0];
+ ${$PHsource}{$new_file}
+ = [fdb_get($new_file, $$Prun_time), '', 0];
}
}
}
@@ -5489,7 +5640,7 @@ sub rdb_update_filesA {
#************************************************************
sub rdb_update1 {
- # Call: fdb_update1.
+ # Call: rdb_update1.
# Assumes file context. Updates file data to correspond to
# current file state on disk
($$Ptime, $$Psize, $$Pmd5) = fdb_get($file);
@@ -5759,6 +5910,7 @@ sub get_checksum_md5 {
my $md5 = Digest->MD5;
my $ignore_pattern = '';
+#warn "======= GETTING MD5: $source\n";
if ( $source eq "" ) {
# STDIN:
open( $input, '-' );