summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-04-15 18:21:17 +0000
committerKarl Berry <karl@freefriends.org>2009-04-15 18:21:17 +0000
commit88f7d1ac35385d57d17eb60fb2d77f6704eadde5 (patch)
tree9a1168ab8bd498e87bd743e4fe2e9b4fe289653b /Build
parentf331ca2bd8e23f91132a8c372c999c2d8a8731aa (diff)
latexmk 4.05 (13apr09)
git-svn-id: svn://tug.org/texlive/trunk@12722 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/latexmk/latexmk.pl673
1 files changed, 474 insertions, 199 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/latexmk/latexmk.pl b/Build/source/texk/texlive/linked_scripts/latexmk/latexmk.pl
index 4d124a67893..1b122c7e975 100755
--- a/Build/source/texk/texlive/linked_scripts/latexmk/latexmk.pl
+++ b/Build/source/texk/texlive/linked_scripts/latexmk/latexmk.pl
@@ -1,22 +1,16 @@
-eval '(exit $?0)' && eval 'exec perl -x -S "$0" ${1+"$@"}' &&
-eval 'exec perl -x -S "$0" $argv:q'
-if 0;
+#!/usr/bin/env perl
+# On a UNIX-like system, the above enables latexmk to run independently
+# of the location of the perl executable. This line relies on the
+# existence of the program /usr/bin/env
+# If there is a problem for any reason, you can replace the first line of
+# this file by:
+
#!/usr/bin/perl -w
-#!/opt/local/bin/perl -w
-#!/usr/local/bin/perl -w
-# The above code allows this script to be run under UNIX/LINUX without
-# the need to adjust the path to the perl program in a "shebang" line.
-# (The location of perl changes between different installations, and
-# may even be different when several computers running different
-# flavors of UNIX/LINUX share a copy of latex or other scripts.) The
-# script is started under the default command interpreter sh, and the
-# evals in the first two lines restart the script under perl, and work
-# under various flavors of sh. The -x switch tells perl to start the
-# script at the first #! line containing "perl". The "if 0;" on the
-# 3rd line converts the first two lines into a valid perl statement
-# that does nothing.
-#
-# Source of the above: manpage for perlrun
+
+# with the path of the perl executable adjusted for your system.
+
+
+use warnings;
# Delete #??!! when working
@@ -34,17 +28,21 @@ if 0;
# 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.
-# Now I am missing diagnostics
-
-
## ???!!!!!!!!!!!!! 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?
+## (I have hooks for this).
+
+
#=======================================
@@ -142,8 +140,8 @@ if 0;
$my_name = 'latexmk';
$My_name = 'Latexmk';
-$version_num = '4.01';
-$version_details = "$My_name, John Collins, 24 September 2008";
+$version_num = '4.05b';
+$version_details = "$My_name, John Collins, 11 April 2009";
use Config;
@@ -210,8 +208,88 @@ else {
## 5. Parsing of log file instead of source file is used to
## obtain dependencies, by default.
##
-## Modification log for 28 Mar 2007 onwards in detail
+## Modification log for 24 Sep 2008 onwards in detail
##
+## 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.
##
## 1998-2008, John Collins. Many improvements and fixes.
@@ -328,7 +406,7 @@ $log_wrap = 79;
'^\\! LaTeX Error: File `([^\\\']*)\\\' not found\\.',
'.*?:\\d*: LaTeX Error: File `([^\\\']*)\\\' not found\\.',
'^LaTeX Warning: File `([^\\\']*)\\\' not found',
- '^Package .* file `([^\\\']*)\\\' not found',
+ '^Package .* [fF]ile `([^\\\']*)\\\' not found',
);
## Hash mapping file extension (w/o period, e.g., 'eps') to a single regexp,
@@ -360,6 +438,17 @@ $pdflatex = 'pdflatex %O %S';
$latex_silent_switch = '-interaction=batchmode';
$pdflatex_silent_switch = '-interaction=batchmode';
+# %input_extensions maps primary_rule_name to pointer to hash of file extensions
+# used for extensionless files specified in the source file by constructs
+# like \input{file} \includegraphics{file}
+# Could write
+#%input_extensions = ( 'latex' => { 'tex' => 1, 'eps' => 1 };,
+# 'pdflatex' => { 'tex' => 1, 'pdf' => 1, 'jpg' => 1, 'png' => 1 }; );
+# Instead we'll exercise the user-friendly access routines:
+add_input_ext( 'latex', 'tex', 'eps' );
+add_input_ext( 'pdflatex', 'tex', 'jpg', 'pdf' );
+#show_input_ext( 'latex' ); show_input_ext( 'pdflatex' );
+
## Command to invoke bibtex
$bibtex = 'bibtex %O %B';
# Switch(es) to make bibtex silent:
@@ -584,7 +673,7 @@ elsif ( $^O eq "cygwin" ) {
# NT-native start command of a cmd.exe is used.
# For a pdf-file, "start x.pdf" starts the pdf viewer associated with
# pdf files, so no program name is needed:
- $start_NT = "cmd /c start";
+ $start_NT = "cmd /c start \"\"";
$pdf_previewer = "$start_NT %O %S";
$ps_previewer = "$start_NT %O %S";
$ps_previewer_landscape = $ps_previewer;
@@ -840,6 +929,9 @@ $cleanup_mode = 0; # No cleanup of nonessential LaTex-related files.
# dviF, pdf, ps, & psF
$cleanup_fdb = 0; # No removal of file for latexmk's file-database
$cleanup_only = 0; # When doing cleanup, do not go-on to making files
+$cleanup_includes_generated = 0;
+ # Determines whether cleanup deletes files generated by
+ # (pdf)latex (found from \openout lines in log file).
$diagnostics = 0;
$dvi_filter = ''; # DVI filter command
$ps_filter = ''; # Postscript filter command
@@ -1003,8 +1095,7 @@ if (!$TEXINPUTS) { $TEXINPUTS = '.'; }
# List of known rules. Rule types: primary,
# external (calls program), internal (calls routine), cusdep.
-%known_rules = ( 'latex' => 'primary', 'pdflatex' => 'primary',
- );
+%possible_primaries = ( 'latex' => 'primary', 'pdflatex' => 'primary' );
%primaries = (); # Hash of rules for primary part of make. Keys are
# currently 'latex', 'pdflatex' or both. Value is
# currently irrelevant. Use hash for ease of lookup
@@ -1023,7 +1114,7 @@ if (!$TEXINPUTS) { $TEXINPUTS = '.'; }
%rule_db = (); # Database of all rules:
# Hash: rulename -> [array of rule data]
# Rule data:
- # 0: [ cmd_type, ext_cmd, int_cmd, out_of_date-crit,
+ # 0: [ cmd_type, ext_cmd, int_cmd, test_kind,
# source, dest, base, out_of_date,
# out_of_date_user, time_of_last_run ]
# where
@@ -1043,7 +1134,7 @@ if (!$TEXINPUTS) { $TEXINPUTS = '.'; }
# This variable intcmd is a reference to an array,
# $$intcmd[0] = internal routine
# $$intcmd[1...] = its arguments (if any)
- # out_of_date_crit specifies method of determining
+ # test_kind specifies method of determining
# whether a file is out-of-date:
# 0 for never
# 1 for usual: whether there is a source
@@ -1100,6 +1191,17 @@ if (!$TEXINPUTS) { $TEXINPUTS = '.'; }
#==================================================
## Read rc files:
+# User's home directory
+$HOME = '';
+if (exists $ENV{'HOME'} ) {
+ $HOME = $ENV{'HOME'};
+}
+elsif (exists $ENV{'USERPROFILE'} ) {
+ $HOME = $ENV{'USERPROFILE'};
+}
+
+
+
sub read_first_rc_file_in_list {
foreach my $rc_file ( @_ ) {
#print "===Testing for rc file \"$rc_file\" ...\n";
@@ -1114,7 +1216,7 @@ sub read_first_rc_file_in_list {
# Read system rc file:
read_first_rc_file_in_list( @rc_system_files );
# Read user rc file.
-read_first_rc_file_in_list( "$ENV{'HOME'}/.latexmkrc" );
+read_first_rc_file_in_list( "$HOME/.latexmkrc" );
# Read rc file in current directory.
read_first_rc_file_in_list( "latexmkrc", ".latexmkrc" );
@@ -1133,9 +1235,8 @@ while ($_ = $ARGV[0])
# Make -- and - equivalent at beginning of option:
s/^--/-/;
shift;
- if (/^-c$/) { $cleanup_mode = 2; $cleanup_only = 1; }
- elsif (/^-C$/) { $cleanup_mode = 1; $cleanup_only = 1; }
- elsif (/^-CA$/) { $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 1;}
+ if (/^-c$/) { $cleanup_mode = 2; $cleanup_fdb = 1; $cleanup_only = 1; }
+ elsif (/^-C$/ || /^-CA$/ ) { $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 1; }
elsif (/^-CF$/) { $cleanup_fdb = 1; }
elsif (/^-cd$/) { $do_cd = 1; }
elsif (/^-cd-$/) { $do_cd = 0; }
@@ -1211,12 +1312,10 @@ while ($_ = $ARGV[0])
elsif (/^-view=ps$/) { $view = "ps";}
elsif (/^-view=pdf$/) { $view = "pdf"; }
elsif (/^-e$/) {
- if ( $ARGV[0] eq '' ) {
+ if ( $#ARGV < 0 ) {
&exit_help( "No code to execute specified after -e switch");
}
- else {
- execute_code_string( $ARGV[0] );
- }
+ execute_code_string( $ARGV[0] );
shift;
}
elsif (/^-r$/) {
@@ -1438,6 +1537,14 @@ if ( $view eq "default" ) {
if ( $pdf_mode ) { $view = "pdf"; }
}
+# Make sure we make the kind of file we want to view:
+if ($view eq 'dvi') { $dvi_mode = 1; }
+if ($view eq 'ps') { $postscript_mode = 1; }
+if ( ($view eq 'pdf') && ($pdf_mode == 0) ) {
+ $pdf_mode = 1;
+}
+
+# Make sure that we make something if all requests are turned off
if ( ! ( $dvi_mode || $pdf_mode || $postscript_mode || $printout_mode) ) {
print "No specific requests made, so default to dvi by latex\n";
$dvi_mode = 1;
@@ -1446,9 +1553,19 @@ if ( ! ( $dvi_mode || $pdf_mode || $postscript_mode || $printout_mode) ) {
# Set new-style requested rules:
if ( $dvi_mode ) { $requested_filerules{'latex'} = 1; }
if ( $pdf_mode == 1 ) { $requested_filerules{'pdflatex'} = 1; }
-elsif ( $pdf_mode == 2 ) { $requested_filerules{'ps2pdf'} = 1; }
-elsif ( $pdf_mode == 3 ) { $requested_filerules{'dvipdf'} = 1; }
-if ( $postscript_mode ) { $requested_filerules{'dvips'} = 1; }
+elsif ( $pdf_mode == 2 ) {
+ $requested_filerules{'latex'} = 1;
+ $requested_filerules{'dvips'} = 1;
+ $requested_filerules{'ps2pdf'} = 1;
+}
+elsif ( $pdf_mode == 3 ) {
+ $requested_filerules{'latex'} = 1;
+ $requested_filerules{'dvipdf'} = 1;
+}
+if ( $postscript_mode ) {
+ $requested_filerules{'latex'} = 1;
+ $requested_filerules{'dvips'} = 1;
+}
if ( $printout_mode ) { $one_time{'print'} = 1; }
if ( $preview_continuous_mode || $preview_mode ) { $one_time{'view'} = 1; }
if ( length($dvi_filter) != 0 ) { $requested_filerules{'dvi_filter'} = 1; }
@@ -1456,16 +1573,6 @@ if ( length($ps_filter) != 0 ) { $requested_filerules{'ps_filter'} = 1; }
if ( $banner ) { $requested_filerules{'dvips'} = 1; }
-%possible_primaries = ();
-foreach (&rdb_possible_primaries) {
- $possible_primaries{$_} = 1;
-}
-
-#print "POSSIBLE PRIMARIES: ";
-#foreach (keys %possible_primaries ) {print "$_, ";}
-#print "\n";
-
-
if ( $pdf_mode == 2 ) {
# We generate pdf from ps. Make sure we have the correct kind of ps.
add_option( \$dvips, " $dvips_pdf_switch" );
@@ -1504,7 +1611,6 @@ foreach $filename ( @file_list )
$failure = 0; # Set nonzero to indicate failure at some point of
# a make. Use value as exit code if I exit.
$failure_msg = ''; # Indicate reason for failure
-#?? Unneeded now: $bibtex_mode = $save_bibtex_mode;
if ( $do_cd ) {
($filename, $path) = fileparse( $filename );
@@ -1539,31 +1645,55 @@ foreach $filename ( @file_list )
$fdb_file = "$root_filename.$fdb_ext";
- if ($cleanup_fdb) { unlink $fdb_file; }
if ( $cleanup_mode > 0 ) {
- my @extra_generated = ();
+ # Use parse_logB to get names of generated files.
+ # It returns its results in the following variables:
+ local %dependents = (); # Maps files to status
+ local @bbl_files = ();
+ local %idx_files = (); # Maps idx_file to (ind_file, base)
+ local %generated_log = (); # Lists generated files
+ print "$My_name: Examining log file for generated files...\n";
+ &parse_logB;
+
+ my @index_bibtex_generated = ();
my @aux_files = ();
- rdb_read_generatedB( $fdb_file, \@extra_generated, \@aux_files );
+ my %other_generated = %generated_log;
+
+ rdb_read_generatedB( $fdb_file, \@index_bibtex_generated, \@aux_files,
+ \%other_generated );
if ( ($go_mode == 2) && !$silent ) {
warn "$My_name: Removing all generated files\n" unless $silent;
}
+ foreach (@index_bibtex_generated, @aux_files) {
+ delete( $other_generated{$_} );
+ }
if ($diagnostics) {
- show_array( "For deletion:\n Extra_generated:", @extra_generated );
+ show_array( "For deletion:\n"
+ ." Generated (from makeindex and bibtex):",
+ @index_bibtex_generated );
show_array( " Aux files:", @aux_files );
+ show_array( "Other generated files:\n"
+ ." (only deleted if \$cleanup_includes_generated is set): ",
+ keys %other_generated );
}
+
# Add to the generated files, some log file and some backup
# files used in previous versions of latexmk
- &cleanup1( 'blg', 'ilg', 'log', 'aux.bak', 'idx.bak',
+ &cleanup1( $fdb_ext, 'blg', 'ilg', 'log', 'aux.bak', 'idx.bak',
split(' ',$clean_ext),
@generated_exts
);
- unlink( 'texput.log', @extra_generated, "texput.aux", @aux_files );
+ unlink( 'texput.log', @index_bibtex_generated, "texput.aux", @aux_files );
+ if ($cleanup_includes_generated) {
+ unlink( keys %other_generated );
+ }
if ( $cleanup_mode == 1 ) {
&cleanup1( 'dvi', 'dviF', 'ps', 'psF', 'pdf',
split(' ', $clean_full_ext)
);
}
}
+ if ($cleanup_fdb) { unlink $fdb_file; }
if ($cleanup_only) { next FILE; }
# Initialize file and rule databases.
@@ -1832,11 +1962,10 @@ sub rdb_set_rules {
# Set up rule database from definitions
# Map of files to rules that MAKE them:
- local %from_rules = ();
%rule_db = ();
foreach my $Prule_list (@_) {
- foreach my $rule ( sort keys %$Prule_list) {
+ foreach my $rule ( keys %$Prule_list) {
my ( $cmd_type, $ext_cmd, $int_cmd, $source, $dest, $base, $test_kind ) = @{$$Prule_list{$rule}};
my $needs_making = 0;
# Substitute in the filename variables, since we will use
@@ -1854,21 +1983,7 @@ sub rdb_set_rules {
rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, $test_kind,
$source, $dest, $base,
$needs_making );
- if ($dest) { $from_rules{$dest} = $rule ; }
}
- rdb_for_all(
- 0,
- sub{
- # my ($base, $path, $ext) = fileparse( $file, '\.[^\.]*' );
- # if ( exists $from_rules{$file} && ! exists $generated_exts_all{$ext} ) {
- # # Show how to make this file. But don't worry about generated
- # # files.
- if ( exists $from_rules{$file} ) {
- $$Pfrom_rule = $from_rules{$file};
- }
- #?? print "$rule: $file, $$Pfrom_rule\n";
- }
- );
} # End arguments of subroutine
&rdb_make_links;
} # END rdb_set_rules
@@ -2158,7 +2273,9 @@ sub make_preview_continuousB {
local @changed = ();
local @disappeared = ();
local @no_dest = (); # Non-existent destination files
+ local @rules_never_run = ();
local @rules_to_apply = ();
+
local $failure = 0;
local $runs = 0;
local %rules_applied = ();
@@ -2282,15 +2399,18 @@ CHANGE:
print "\n=== Watching for updated files. Use ctrl/C to stop ...\n";
}
$waiting = 1; if ($diagnostics) { warn "WAITING\n"; }
+ &catch_break;
+ $have_break = 0;
WAIT: while (1) {
sleep($sleep_time);
+ if ($have_break) { last WAIT; }
&rdb_clear_change_record;
rdb_recurseA( [@targets], \&rdb_flag_changes_here );
- if ( &rdb_count_changes > 0) {
- &rdb_diagnose_changes
- unless $silent;
-#???
- warn "$My_name: File(s) changed or not used in previous run(s). Remake files.\n";
+ if ( &rdb_need_run ) {
+ if (!$silent) {
+ warn "$My_name: Need to remake files.\n";
+ &rdb_diagnose_changes( ' ' );
+ }
last WAIT;
}
# Does this do this job????
@@ -2300,8 +2420,14 @@ CHANGE:
warn "$My_name: New file(s) found.\n";
last WAIT;
}
+ if ($have_break) { last WAIT; }
} # end WAIT:
- $waiting = 0; if ($diagnostics) { warn "NOT WAITING\n"; }
+ &default_break;
+ if ($have_break) {
+ print "$Latexmk: User typed ctrl/C or ctrl/break. I'll stop.\n";
+ exit;
+ }
+ $waiting = 0; if ($diagnostics) { warn "NOT WAITING\n"; }
} #end infinite_loop CHANGE:
} #END sub make_preview_continuousB
@@ -2483,10 +2609,9 @@ sub print_help
" This and the other clean-ups are instead of a regular make.\n",
" -C - clean up (remove) all nonessential files\n",
" including aux, dep, dvi, postscript and pdf files\n",
- " But exclude file of database of file information\n",
- " -CA - clean up (remove) absolutely ALL nonessential files\n",
- " including aux, dep, dvi, postscript and pdf files,\n",
" and file of database of file information\n",
+ " -CA - clean up (remove) absolutely ALL nonessential files.\n",
+ " Now equivalent to -C option.\n",
" -CF - Remove file of database of file information before doing \n",
" other actions\n",
" -cd - Change to directory of source file when processing it\n",
@@ -2666,6 +2791,8 @@ sub parse_logB {
# 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.
+# %generated_log: keys give set of files written by (pdf)latex (e.g., aux, idx)
+# as determined by \openout = ... lines in log file.
# Also set
# $reference_changed, $bad_reference, $bad_citation
# Trivial or default values if log file does not exist/cannot be opened
@@ -2686,6 +2813,7 @@ sub parse_logB {
foreach (@default_includes) { $dependents{$_} = 4; }
@bbl_files = ();
%idx_files = (); # Maps idx_file to (ind_file, base)
+ %generated_log = ();
$reference_changed = 0;
$bad_reference = 0;
@@ -2697,21 +2825,30 @@ sub parse_logB {
return 0;
}
-LINE:
+# Collect lines of log file
+ my @lines = ();
while(<$log_file>) {
# Could use chomp here, but that fails if there is a mismatch
# between the end-of-line sequence used by latex and that
# used by perl. (Notably a problem with MSWin latex and
# cygwin perl!)
s/[\n\r]*$//;
- if ( $. == 1 ){
+ push @lines, $_;
+ }
+ close $log_file;
+
+ my $line = 0;
+LINE:
+ while( $line <= $#lines ) {
+ $_ = $lines[$line];
+ $line ++;
+ if ( $line == 1 ){
if ( /^This is / ) {
# First line OK
next LINE;
} else {
warn "$My_name: Error on first line of '$log_name'. ".
"This is apparently not a TeX log file.\n";
- close $log_file;
$failure = 1;
$failure_msg = "Log file '$log_name' appears to have wrong format.";
return 0;
@@ -2720,10 +2857,16 @@ LINE:
# 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($_);
- while ($len == $log_wrap) {
- my $extra = <$log_file>;
- $extra =~ s/[\n\r]*$//;
+ my $next = $line;
+ while ( ($len == $log_wrap) && ($next <= $#lines) ) {
+ my $extra = $lines[$next];
+ $next++;
$len = length($extra);
$_ .= $extra;
}
@@ -2760,6 +2903,10 @@ LINE:
# Latex error/warning, etc.
next LINE;
}
+ if ( /^\\openout\d+\s*=\s*\`([^\']+)\'\.$/ ) {
+ $generated_log{$1} = 1;
+ 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.
@@ -2895,19 +3042,22 @@ LINE:
# First step: replace $_ by whole of line after the '('
# Thus $_ is putative filename followed by other stuff.
$_ = $1;
- if ( /^([^\(^\)^\{]*?)\s\[/ ) {
+ if ( /^\"([^\(^\)^\"]+)\"/ ) {
+ # Quoted file name, as from MikTeX
+ }
+ elsif ( /^([^\(^\)]*?)\s\[/ ) {
# Terminator: space then '['
# Use *? in condition: to pick up first ' [' as terminator
# 'file [' should give good filename.
}
- elsif ( /^([^\(^\)^\{]*)\s(?=\()/ ) {
+ elsif ( /^([^\(^\)]*)\s(?=\()/ ) {
# Terminator is ' (', but '(' isn't in matched string,
# so we keep the '(' ready for the next match
}
- elsif ( /^([^\(^\)^\{]*)(\))/ ) {
+ elsif ( /^([^\(^\)]*)(\))/ ) {
# Terminator is ')'
}
- elsif ( /^([^\(^\)^\{]*?)\s*\{/ ) {
+ elsif ( /^([^\(^\)]*?)\s*\{/ ) {
# Terminator: arbitrary space then '{'
# Use *? in condition: to pick up first ' [' as terminator
# 'file [' should give good filename.
@@ -2926,6 +3076,10 @@ LINE:
# Part of font message
next INCLUDE_CANDIDATE;
}
+ # Remove quotes around filename, as for MikTeX. I've already
+ # treated this as a special case. For safety check here:
+ $include_candidate =~ s/^\"(.*)\"$/$1/;
+
# Make list of new include files; sometimes more than one.
my @new_includes = ($include_candidate);
if ( $include_candidate =~ /^(.+)\[([^\]]+)\]$/ ) {
@@ -2961,7 +3115,6 @@ LINE:
} # INCLUDE_NAME
} # INCLUDE_CANDIDATE
} # LINE
- close($log_file);
# Default includes are always definitive:
foreach (@default_includes) { $dependents{$_} = 4; }
@@ -3050,9 +3203,14 @@ CANDIDATE:
if ( $misparse > 0 ) {
print "$misparse\n";
- print "Apparent input files appearently from misunderstood lines in .log file:\n";
+ print "Apparent input files apparently from misunderstood lines in .log file:\n";
foreach ( @misparse ) { print " $_\n"; }
}
+ print "Log file shows the following generated files: ";
+ foreach (keys %generated_log) {
+ print "'$_' ";
+ }
+ print "\n";
}
return 1;
@@ -3364,13 +3522,20 @@ LINE:
#************************************************************
sub rdb_read_generatedB {
- # Call: rdb_read_generatedB( $in_name, \@extra_generated, \@aux_files )
+ # Call: rdb_read_generatedB( $in_name, \@generated1, \@aux_files.
+ # \%other_generated )
# From rule database in saved file, in format written by rdb_write,
- # finds the non-basic generated files that are to be deleted by a cleanup.
- # Returns an array of these files, or an empty array if the file
- # does not exist or cannot be opened.
- my ($in_name, $Pgenerated, $Paux_files) = @_;
- @$Pgenerated = ();
+ # finds the non-trivial generated files that are to be deleted by a cleanup.
+ # On entry:
+ # Keys of %other_generated: any detected generated files, from \openout
+ # lines log file, usually.
+ # At exit:
+ # Array @generated1: files associated with makeindex and bibtex
+ # Array @aux_files: aux files
+ # Added to keys of %other_generated: any files that are destinations of rules
+ # whose source is in %other_generated. (One stage only.)
+ my ($in_name, $Pgenerated1, $Paux_files, $Pother_generated) = @_;
+ @$Pgenerated1 = ();
@$Paux_files = ();
my $in_handle = new FileHandle;
@@ -3384,6 +3549,7 @@ sub rdb_read_generatedB {
my $ext = '';
my $path = '';
my $state = 0; # Outside a section
+ my @other_additions = ();
LINE:
while ( <$in_handle> ) {
# Remove leading and trailing white space.
@@ -3405,12 +3571,15 @@ LINE:
}
else { next LINE; }
if ( $rule =~ /^makeindex/ ) {
- push @$Pgenerated, $source, $dest, "$base.ilg";
+ push @$Pgenerated1, $source, $dest, "$base.ilg";
}
elsif ( $rule =~ /^bibtex/ ) {
- push @$Pgenerated, $dest, "$base.blg";
+ push @$Pgenerated1, $dest, "$base.blg";
push @$Paux_files, $source;
}
+ elsif ( exists ${$Pother_generated}{$source} ) {
+ push @other_additions, $dest;
+ }
$state = 1; #Reading a section
}
elsif ( /^\"([^\"]*)\"\s+(\S+)\s+(\S+)\s+(\S+)\s+\"([^\"]*)\"/ ) {
@@ -3433,7 +3602,9 @@ LINE:
}
} # LINE
undef $in_handle;
-
+ foreach (@other_additions) {
+ ${$Pother_generated}{$_} = 1;
+ }
} # END rdb_read_generatedB
#************************************************************
@@ -3463,13 +3634,25 @@ sub rdb_write {
&rdb_classify_rules( \%possible_primaries, keys %requested_filerules );
print $out_handle "# Fdb version $fdb_ver\n";
- my @rules = sort(
- rdb_accessible(
- uniq1( keys %known_rules, keys %current_primaries )));
+ my @rules = rdb_accessible( uniq1( keys %possible_primaries ) ) ;
+ # Separate call to sort. Otherwise rdb_accessible seems to get wrong argument.
+ @rules = sort( @rules );
rdb_for_some(
\@rules,
- sub { print $out_handle "[\"$rule\"] $$Prun_time \"$$Psource\" \"$$Pdest\" \"$$Pbase\" \n"; },
- sub { print $out_handle " \"$file\" $$Ptime $$Psize $$Pmd5 \"$$Pfrom_rule\"\n"; },
+ sub {
+ # Omit data on a unused and never-run primary rule:
+ if ( ($$Prun_time == 0)
+ && exists( $possible_primaries{$rule} )
+ && ! exists( $current_primaries{$rule} )
+ )
+ {
+ return;
+ }
+ print $out_handle "[\"$rule\"] $$Prun_time \"$$Psource\" \"$$Pdest\" \"$$Pbase\" \n";
+ rdb_do_files(
+ sub { print $out_handle " \"$file\" $$Ptime $$Psize $$Pmd5 \"$$Pfrom_rule\"\n"; }
+ );
+ }
);
undef $out_handle;
return 1;
@@ -3496,9 +3679,10 @@ sub rdb_set_from_logB {
# Parse log file to find relevant filenames
# Result in the following variables:
- local %dependents = (); # Maps files to status
+ local %dependents = (); # Maps files to status
local @bbl_files = ();
- local %idx_files = (); # Maps idx_file to (ind_file, base)
+ local %idx_files = (); # Maps idx_file to (ind_file, base)
+ local %generated_log = (); # Lists generated files found in log file
# The following are also returned, but are global, to be used by caller
# $reference_changed, $bad_reference $bad_citation
@@ -3514,11 +3698,9 @@ sub rdb_set_from_logB {
if ($diagnostics);
rdb_create_rule( $from_rule, 'external', $makeindex, '', 1,
$idx_file, $ind_file, $ind_base, 1, 0);
- foreach my $primary ( keys %primaries ) {
- print " ===Source file '$ind_file' for '$primary'\n"
+ print " ===Source file '$ind_file' for '$rule'\n"
if ($diagnostics > -1);
- rdb_ensure_file( $primary, $ind_file, $from_rule );
- }
+ rdb_ensure_file( $rule, $ind_file, $from_rule );
}
if ( ! -e $ind_file ) {
# Failure was non-existence of makable file
@@ -3545,24 +3727,22 @@ sub rdb_set_from_logB {
if ($diagnostics);
rdb_ensure_file( $from_rule, $source );
}
- foreach my $primary ( keys %primaries ) {
- print " ===Source file '$bbl_file' for '$primary'\n"
+ print " ===Source file '$bbl_file' for '$rule'\n"
if ($diagnostics);
- rdb_ensure_file( $primary, $bbl_file, $from_rule );
- if ( ! -e $bbl_file ) {
- # Failure was non-existence of makable file
- # Leave failure issue to other rules.
- $failure = 0;
- }
+ 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 $primary ( keys %primaries ) {
- rdb_ensure_file( $primary, $new_source );
- }
+ print " ===Source file for rule '$rule': '$new_source'\n"
+ if ($diagnostics);
+ rdb_ensure_file( $rule, $new_source );
}
my @more_sources = &rdb_set_dependentsA( $rule );
@@ -3750,7 +3930,12 @@ sub rdb_set_dependentsA {
# Call rdb_set_dependentsA( rules ...)
# Returns array (sorted), of new source files.
local @new_sources = ();
+ local @deletions = ();
rdb_recurseA( [@_], 0, \&rdb_one_depA );
+ foreach (@deletions) {
+ my ($rule, $file) = @$_;
+ rdb_remove_files( $rule, $file );
+ }
&rdb_make_links;
return uniqs( @new_sources );
} #END rdb_set_dependentsA
@@ -3764,6 +3949,7 @@ sub rdb_one_depA {
my ($base_name, $path, $toext) = fileparseA( $new_dest );
$base_name = $path.$base_name;
$toext =~ s/^\.//;
+ my $Pinput_extensions = $input_extensions{$rule};
DEP:
foreach my $dep ( @cus_dep_list ) {
my ($fromext,$proptoext,$must,$func_name) = split(' ',$dep);
@@ -3781,6 +3967,7 @@ DEP:
push @new_sources, $new_dest;
}
if (! rdb_rule_exists( $$Pfrom_rule ) ) {
+ print "=== Creating rule for '$$Pfrom_rule'\n";
rdb_create_rule( $$Pfrom_rule, 'cusdep', '', \@PAnew_cmd, 3,
$source, $new_dest, $base_name, 0 );
}
@@ -3810,7 +3997,11 @@ DEP:
}
}
}
- elsif ( ($toext eq '') && (! -e $file ) ) {
+ elsif ( ($toext eq '')
+ && (! -e $file )
+ && (! -e "$base_name.$proptoext" )
+ && exists $$Pinput_extensions{$proptoext}
+ ) {
# Empty extension and non-existent destination
# This normally results from \includegraphics{A}
# without graphics extension for file, when file does
@@ -3818,7 +4009,7 @@ DEP:
my $source = "$base_name.$fromext";
if ( -e $source ) {
$new_dest = "$base_name.$proptoext";
- my $from_rule = "cusdep $fromext $toext $base_name";
+ my $from_rule = "cusdep $fromext $proptoext $base_name";
push @new_sources, $new_dest;
print "Ensuring rule for '$from_rule', to make '$new_dest'\n"
if $diagnostics > -1;
@@ -3834,6 +4025,9 @@ DEP:
);
}
rdb_ensure_file( $rule, $new_dest, $from_rule );
+ # We've now got a spurious file in our rule. But don't mess
+ # with deleting an item we are in the middle of!
+ push @deletions, [$rule, $file];
return;
}
} # End of Rule found
@@ -3894,29 +4088,7 @@ sub rdb_accessible {
} #END rdb_accessible
#************************************************************
-
-sub rdb_possible_primaries {
- # Returns array of possible primaries
- my @rules = ();
- foreach my $rule ( keys %known_rules ) {
- if ( $known_rules{$rule} eq 'primary') {
- push @rules, $rule;
- }
- }
- return @rules;
-} #END rdb_possible_primaries
-
-#************************************************************
-#************************************************************
#************************************************************
-
-# Routines for makes. NEW VERSIONS ??
-
-#????????Debugging routines:
-sub R1 {print "===START $rule\n"}
-sub R2 {print "===END $rule\n"}
-sub F1 {print " ---START $file\n"}
-sub F2 {print " ---END $file\n"}
#************************************************************
sub rdb_makeB {
@@ -4071,6 +4243,7 @@ sub rdb_makeB {
local @changed = ();
local @disappeared = ();
local @no_dest = (); # Non-existent destination files
+ local @rules_never_run = ();
local @rules_to_apply = ();
&rdb_classify_rules( \%possible_primaries, @requested_targets );
@@ -4100,6 +4273,7 @@ sub rdb_makeB {
print "MakeB: doing pre_primary and primary...\n";
}
rdb_for_some( [@pre_primary, $primary], \&rdb_makeB1 );
+
if ( ($runs > 0) && ! $too_many_runs ) {
$retry_msg = 0;
if ( $failure && $newrule_nofile ) {
@@ -4132,7 +4306,10 @@ sub rdb_makeB {
continue {
# Re-evaluate rule classification and accessibility,
# but do not change primaries.
- &rdb_classify_rules( \%current_primaries, @requested_targets );
+ # Problem is that %current_primaries gets altered
+ my %old_curr_prim = %current_primaries;
+ &rdb_classify_rules( \%possible_primaries, @requested_targets );
+ %current_primaries = %old_curr_prim;
&rdb_make_links;
}
}
@@ -4174,11 +4351,14 @@ sub rdb_makeB1 {
if ($diagnostics) { print " MakeB1 $rule\n"; }
if ($failure & ! $force_mode) {return;}
&rdb_clear_change_record;
- &rdb_flag_changes_here;
-# if ($diagnostics>-1) { print " MakeB1.1 $rule $$Pout_of_date\n"; }
+ if ( ($$Prun_time == 0) && exists($possible_primaries{$rule}) ) {
+ push @rules_never_run, $rule;
+ $$Pout_of_date = 1;
+ }
+ else {
+ &rdb_flag_changes_here;
+ }
- my $return = 0; # Return code from called routine
-#?? print "makeB1: Trying '$rule' for '$$Pdest': ";
if (!$$Pout_of_date) {
#?? if ( ($$Pcmd_type eq 'primary') && (! $silent) ) {
# print "Rule '$rule' up to date\n";
@@ -4188,19 +4368,17 @@ sub rdb_makeB1 {
if ($diagnostics) { print " remake\n"; }
if (!$silent) {
print "$My_name: applying rule '$rule'...\n";
- &rdb_diagnose_changes( "Rule $rule: ");
+ &rdb_diagnose_changes( "Rule '$rule': ");
}
-##????????????????????????????????????: variable rules_applied not used
$rules_applied{$rule} = 1;
$runs++;
-#?? print "$rule: $$Pcmd_type\n";
# We are applying the rule, so its source file state for when it
# was last made is as of now:
# ??IS IT CORRECT TO DO NOTHING IN CURRENT VERSION?
# The actual run
- $return = 0;
+ my $return = 0; # Return code from called routine
# Rule may have been created since last run:
if ( ! defined $pass{$rule} ) {$pass{$rule} = 0; }
if ( $pass{$rule} ge $max_repeat ) {
@@ -4330,6 +4508,7 @@ sub rdb_classify_rules {
foreach ( @one_time ) { print " $_\n"; }
}
} #end diagnostics
+
} #END rdb_classify_rules
#-------------------
@@ -4338,7 +4517,7 @@ sub rdb_classify1 {
# Helper routine for rdb_classify_rules
# Applied as rule_act1 in recursion over rules
# Assumes rule context, and local variables from rdb_classify_rules
-# print "=========== '$rule' $depth ========== \n";
+ #print "??======= '$rule' $depth $state ========== \n";
push @classify_stack, [$state];
if ( exists $possible_one_time{$rule} ) {
# Normally, we will have already extracted the one_time rules,
@@ -4462,14 +4641,23 @@ sub rdb_ext_cmd1 {
#Set character to surround filenames:
my $q = $quote_filenames ? '"' : '';
- foreach ($ext_cmd) {
- s/%O/$options/g;
- s/%R/$q$root_filename$q/g;
- s/%B/$q$base$q/g;
- s/%T/$q$texfile_name$q/g;
- s/%S/$q$source$q/g;
- s/%D/$q$dest$q/g;
+
+ %subst = (
+ '%O' => $options,
+ '%R' => $q.$root_filename.$q,
+ '%B' => $q.$base.$q,
+ '%T' => $q.$texfile_name.$q,
+ '%S' => $q.$source.$q,
+ '%D' => $q.$dest.$q,
+ '%%' => '%' # To allow literal %B, %R, etc, by %%B.
+ );
+
+ my @tokens = split /(%.)/, $ext_cmd;
+ foreach (@tokens) {
+ if (exists($subst{$_})) { $_ = $subst{$_}; }
}
+ $ext_cmd = join '', @tokens;
+
# print "quote is '$q'; ext_cmd = '$ext_cmd'\n";
my ($pid, $return) = &Run_msg($ext_cmd);
return $return;
@@ -4553,13 +4741,14 @@ sub rdb_primary_run {
#************************************************************
sub rdb_clear_change_record {
+ # Initialize diagnostics for reasons for running rule.
@changed = ();
@disappeared = ();
@no_dest = ();
- @rules_to_apply = ();
-#??????????????? $failure = 0;
-##????????????????????????????????????: variable rules_applied not used
- $rules_applied = 0;
+ @rules_never_run = ();
+ @rules_to_apply = (); # This is used in recursive application
+ # of rdb_flag_changes_here, to list
+ # rules that were out-of-date for some reason.
} #END rdb_clear_change_record
#************************************************************
@@ -4607,12 +4796,19 @@ sub rdb_file_change1 {
#?? " New $new_time, $new_size, $new_md5\n";
my $ext = ext( $file );
if ( ($new_size < 0) && ($$Psize >= 0) ) {
- print "Disappeared '$file' in '$rule'\n";
+ # print "Disappeared '$file' in '$rule'\n";
push @disappeared, $file;
# No reaction is good.
#$$Pout_of_date = 1;
# ??? 1 Sep. 2008: I do NOT think so, for cusdep no-file-exists issue
- $$Pout_of_date = 1;
+ # ??? 30 Sep 2008: I think I have this fixed. There were other changes
+ # needed. No-change-flagged is correct. The array @disappeared flags
+ # files that have disappeared, if I need to know. But having a source
+ # file disappear is not a reason for a remake unless I know how to
+ # make the file. If the file is a destination of a rule, that rule
+ # will be rerun. It may be that the user is changing another source
+ # in such a way that the disappeared file won't be needed. Before the
+ # change is applied we get a superfluous infinite loop.
return;
}
if ( ($new_size < 0) && ($$Psize < 0) ) {
@@ -4638,9 +4834,9 @@ sub rdb_file_change1 {
#************************************************************
-sub rdb_count_changes {
- return $#changed + $#disappeared + $#no_dest + $#rules_to_apply + 4;
-} #END rdb_count_changes
+sub rdb_need_run {
+ return ($#changed >= 0) || ($#no_dest >= 0) || ($#rules_to_apply >= 0);
+} #END rdb_need_run
#************************************************************
@@ -4650,26 +4846,31 @@ sub rdb_diagnose_changes {
# Precede the message by the optional heading, else by "$My_name: "
my $heading = defined($_[0]) ? $_[0] : "$My_name: ";
- if ( &rdb_count_changes == 0 ) {
- warn "${heading}No changes\n";
- return;
- }
- warn "${heading}Changes:\n";
- if ( $#changed >= 0 ) {
- warn " Changed files, or newly in use since previous run(s):\n";
- foreach (uniqs(@changed)) { warn " '$_'\n"; }
+ if ($#rules_never_run >= 0) {
+ warn "${heading}Rules & subrules not known to be previously run:\n";
+ foreach (@rules_never_run) { warn " $_\n"; }
}
- if ( $#disappeared >= 0 ) {
- warn " No-longer-existing files:\n";
- foreach (uniqs(@disappeared)) { warn " '$_'\n"; }
+ if ( ($#changed >= 0) || ($#disappeared >= 0) || ($#no_dest >= 0) ) {
+ warn "${heading}File changes, etc:\n";
+ if ( $#changed >= 0 ) {
+ warn " Changed files, or newly in use since previous run(s):\n";
+ foreach (uniqs(@changed)) { warn " '$_'\n"; }
+ }
+ if ( $#disappeared >= 0 ) {
+ warn " No-longer-existing files:\n";
+ foreach (uniqs(@disappeared)) { warn " '$_'\n"; }
+ }
+ if ( $#no_dest >= 0 ) {
+ warn " Non-existent destination files:\n";
+ foreach (uniqs(@no_dest)) { warn " '$_'\n"; }
+ }
}
- if ( $#no_dest >= 0 ) {
- warn " Non-existent destination files:\n";
- foreach (uniqs(@no_dest)) { warn " '$_'\n"; }
+ elsif ($#rules_to_apply >=0) {
+ warn "${heading}The following rules & subrules became out-of-date:\n";
+ foreach (@rules_to_apply) { warn " '$_'\n"; }
}
- if ( $#rules_to_apply >= 0 ) {
- warn " Rules to apply:\n";
- foreach (uniqs(@rules_to_apply)) { warn " '$_'\n"; }
+ else {
+ warn "${heading}No file changes\n";
}
} #END rdb_diagnose_changes
@@ -4773,6 +4974,7 @@ sub rdb_recurseA {
# This routine sets a context for anything recursive, with @heads,
# %visited and $depth being set as local variables.
+
local @heads = ();
my $rules = shift;
@@ -5180,7 +5382,8 @@ sub show_array {
# Then print rest of @_, one item per line preceeded by some space
warn "$_[0]\n";
shift;
- foreach (@_){ warn " $_\n";}
+ if ($#_ >= 0) { foreach (@_){ warn " '$_'\n";} }
+ else { warn " NONE\n"; }
}
#************************************************************
@@ -5630,6 +5833,47 @@ sub show_cus_dep {
####################################################
+sub add_input_ext {
+ # Usage: add_input_ext( rule, ext, ... )
+ # Add extension(s) (specified without a leading period) to the
+ # list of input extensions for the given rule. The rule should be
+ # 'latex' or 'pdflatex'. These extensions are used when an input
+ # file without an extension is found by (pdf)latex, as in
+ # \input{file} or \includegraphics{figure}. When latexmk searches
+ # custom dependencies to make the missing file, it will assume that
+ # the file has one of the specified extensions.
+ my $rule = shift;
+ if ( ! exists $input_extensions{$rule} ) {
+ $input_extensions{$rule} = {};
+ }
+ my $Prule = $input_extensions{$rule};
+ foreach (@_) { $$Prule{$_} = 1; }
+}
+
+####################################################
+
+sub remove_input_ext {
+ # Usage: remove_input_ext( rule, ext, ... )
+ # Remove extension(s) (specified without a leading period) to the
+ # list of input extensions for the given rule. The rule should be
+ # 'latex' or 'pdflatex'. See sub add_input_ext for the use.
+ my $rule = shift;
+ if ( ! exists $input_extensions{$rule} ) { return; }
+ my $Prule = $input_extensions{$rule};
+ foreach (@_) { delete $$Prule{$_}; }
+}
+
+####################################################
+
+sub show_input_ext {
+ # Usage: show_input_ext( rule )
+ my $rule = shift;
+ show_array ("Input extensions for rule '$rule': ",
+ keys %{$input_extensions{$rule}} );
+}
+
+####################################################
+
sub find_dirs1 {
# Same as find_dirs, but argument is single string with directories
# separated by $search_path_separator
@@ -5909,7 +6153,9 @@ sub Run_Detached {
if ( "$^O" eq "MSWin32" ){
# Win95, WinNT, etc: Use MS's start command:
- return( 0, system( "start $cmd_line" ) );
+ # Need extra double quotes to deal with quoted filenames:
+ # MSWin start takes first quoted argument to be a Window title.
+ return( 0, system( "start \"\" $cmd_line" ) );
} else {
# Assume anything else is UNIX or clone
# For this purpose cygwin behaves like UNIX.
@@ -6023,9 +6269,38 @@ sub finish_dir_stack {
#************************************************************
#************************************************************
-#************************************************************
-#************************************************************
-#************************************************************
-#************************************************************
+# Break handling routines (for wait-loop in preview continuous)
+
+sub end_wait {
+ # Handler for break: Set global variable $have_break to 1.
+ $signal = shift;
+ # Some systems (e.g., MSWin reset) appear to reset the handler.
+ # So I'll re-enable it
+ &catch_break;
+ $have_break = 1;
+}
+
+#========================
+
+sub catch_break {
+# Capture ctrl/C and ctrl/break.
+# $SIG{INT} corresponds to ctrl/C on LINUX/?UNIX and MSWin
+# $SIG{BREAK} corresponds to ctrl/break on MSWin, doesn't exist on LINUX
+ $SIG{INT} = \&end_wait;
+ if ( exists $SIG{BREAK} ) {
+ $SIG{BREAK} = \&end_wait;
+ }
+}
+
+#========================
+
+sub default_break {
+# Arrange for ctrl/C and ctrl/break to give default behavior
+ $SIG{INT} = 'DEFAULT';
+ if ( exists $SIG{BREAK} ) {
+ $SIG{BREAK} = 'DEFAULT';
+ }
+}
+
#************************************************************
#************************************************************