From b088d18fd87779513119a324910df7be3c8e0be3 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Fri, 4 Dec 2009 04:58:31 +0000 Subject: update latexmk.pl in source git-svn-id: svn://tug.org/texlive/trunk@16293 c570f23f-e606-0410-a88d-b1316a301751 --- .../texk/texlive/linked_scripts/latexmk/latexmk.pl | 560 +++++++++++++-------- 1 file changed, 356 insertions(+), 204 deletions(-) (limited to 'Build') 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, '-' ); -- cgit v1.2.3