1077
1580
# Process for each file.
1078
1581
# The value of $bibtex_mode set in an initialization file may get
1079
1582
# overridden, during file processing, so save it:
1080
$save_bibtex_mode = $bibtex_mode;
1583
#?? Unneeded now: $save_bibtex_mode = $bibtex_mode;
1586
$last_failed = 0; # Flag whether failed on making last file
1587
# This is used for showing suitable error diagnostics
1083
1589
foreach $filename ( @file_list )
1591
# Global variables for making of current file:
1085
1593
$failure = 0; # Set nonzero to indicate failure at some point of
1086
1594
# a make. Use value as exit code if I exit.
1087
1595
$failure_msg = ''; # Indicate reason for failure
1088
$bibtex_mode = $save_bibtex_mode;
1598
($filename, $path) = fileparse( $filename );
1599
warn "$My_name: Changing directory to '$path'\n";
1089
1607
## remove extension from filename if was given.
1090
1608
if ( &find_basename($filename, $root_filename, $texfile_name) )
1092
1610
if ( $force_mode ) {
1093
warn "Latexmk: Could not find file [$texfile_name]\n";
1611
warn "$My_name: Could not find file [$texfile_name]\n";
1096
1615
&exit_msg1( "Could not find file [$texfile_name]",
1101
if ($cleanup_mode > 0)
1103
## Do clean if necessary
1105
if ( $cleanup_mode != 2 ) { &cleanup_dvi_ps_pdf; }
1106
if ( $cleanup_mode != 3 ) { &cleanup_aux_dep; }
1109
if ($go_mode == 2) {
1110
warn "Latexmk: Removing all generated files\n" unless $silent;
1111
&cleanup_dvi_ps_pdf;
1114
#Default aux file list:
1115
@aux_files = ("$root_filename.aux");
1118
@includes = (); # Input files
1119
%includes_missing = (); # Possible input files, status problematic:
1120
# filename => [wherefrom, fullname]
1121
# wherefrom 0: exact name known.
1122
# 1: name for non-existent file, from logfile, possibly
1123
# bad parse, possibly it's been deleted.
1124
# 2: not necessarily fullname, from logfile, probably OK
1125
# (graphics file, typically).
1126
# File not found by latexmk.
1127
# 3: possibly incomplete (pathless, possibly extension-less)
1128
# name from error message in .log file
1129
# 4: non-found file from .tex file: either non-existent file
1130
# or I didn't find it.
1131
$read_depend = 0; # True to read depend file, false to generate it.
1132
$dep_file = "$root_filename.dep";
1134
## Figure out if we read the dependency file or generate a new one.
1135
if ( ! $force_generate_and_save_includes )
1137
if ( $generate_and_save_includes )
1141
# Compare timestamp of dependency file and root tex file.
1142
$dep_mtime = &get_mtime("$dep_file");
1143
$tex_mtime = &get_mtime("$texfile_name");
1144
if ( $tex_mtime < $dep_mtime )
1150
elsif ( -e $dep_file ) # If dependency file already exists.
1156
if ( $includes_from_log )
1159
if ( $force_generate_and_save_includes
1160
|| ($generate_and_save_includes && $read_depend == 0 )
1163
&update_depend_file;
1166
elsif ( $read_depend )
1168
# Read the dependency file
1169
open(dep_file) || die "Latexmk: Couldn't open dependency file [$root_filename.dep]\n";
1170
while(<dep_file>) { eval; }
1175
# Generate dependency file.
1176
&scan_for_includes("$texfile_name");
1177
&update_depend_file;
1180
# warn "====@includes===\n";
1619
if ($jobname ne '' ) {
1620
$root_filename = $jobname;
1623
# Initialize basic dependency information:
1625
# For use under error conditions:
1626
@default_includes = ($texfile_name, "$root_filename.aux");
1628
$fdb_file = "$root_filename.$fdb_ext";
1630
if ( $cleanup_mode > 0 ) {
1631
# Use parse_logB to get names of generated files.
1632
# It returns its results in the following variables:
1633
local %dependents = (); # Maps files to status
1634
local @bbl_files = ();
1635
local %idx_files = (); # Maps idx_file to (ind_file, base)
1636
local %generated_log = (); # Lists generated files
1637
local $primary_out = ''; # Actual output file (dvi or pdf)
1638
local %conversions = (); # (pdf)latex-performed conversions.
1639
# Maps output file created and read by (pdf)latex
1640
# to source file of conversion.
1641
print "$My_name: Examining log file for generated files...\n";
1644
my @index_bibtex_generated = ();
1646
my %other_generated = %generated_log;
1648
rdb_read_generatedB( $fdb_file, \@index_bibtex_generated, \@aux_files,
1649
\%other_generated );
1650
if ( ($go_mode == 2) && !$silent ) {
1651
warn "$My_name: Removing all generated files\n" unless $silent;
1653
if ($bibtex_use < 2) {
1654
delete $generated_exts_all{'bbl'};
1656
my %index_bibtex_generated = ();
1658
foreach (@index_bibtex_generated) {
1659
$index_bibtex_generated{$_} = 1
1660
unless ( /\.bbl$/ && ($bibtex_use < 2) );
1661
delete( $other_generated{$_} );
1663
foreach (@aux_files) {
1665
delete( $other_generated{$_} );
1668
show_array( "For deletion:\n"
1669
." Generated (from makeindex and bibtex):",
1670
keys %index_bibtex_generated );
1671
show_array( " Aux files:", keys %aux_files );
1672
show_array( "Other generated files:\n"
1673
." (only deleted if \$cleanup_includes_generated is set): ",
1674
keys %other_generated );
1676
# Add to the generated files, some log file and some backup
1677
# files used in previous versions of latexmk
1678
&cleanup1( $fdb_ext, 'blg', 'ilg', 'log', 'aux.bak', 'idx.bak',
1679
split(' ',$clean_ext),
1680
keys %generated_exts_all
1682
unlink( 'texput.log', "texput.aux",
1683
keys %index_bibtex_generated,
1685
if ($cleanup_includes_generated) {
1686
unlink( keys %other_generated );
1688
if ( $cleanup_mode == 1 ) {
1689
&cleanup1( 'dvi', 'dviF', 'ps', 'psF', 'pdf',
1690
split(' ', $clean_full_ext)
1694
if ($cleanup_fdb) { unlink $fdb_file; }
1695
if ($cleanup_only) { next FILE; }
1697
# Initialize file and rule databases.
1699
&rdb_make_rule_list;
1700
&rdb_set_rules(\%rule_list);
1703
#??? The following are not needed if use makeB.
1704
# ?? They may be set too early?
1705
# Arrays and hashes for picking out accessible rules.
1706
# Distinguish rules for making files and others
1707
@accessible_all = sort ( &rdb_accessible( keys %requested_filerules, keys %one_time ));
1708
%accessible_filerules = ();
1709
foreach (@accessible_all) {
1710
unless ( /view/ || /print/ ) { $accessible_filerules{$_} = 1; }
1712
@accessible_filerules = sort keys %accessible_filerules;
1714
# show_array ( "=======All rules used", @accessible_all );
1715
# show_array ( "=======Requested file rules", sort keys %requested_filerules );
1716
# show_array ( "=======Rules for files", @accessible_filerules );
1718
if ( $diagnostics ) {
1719
print "$My_name: Rules after start up for '$texfile_name'\n";
1724
foreach (@accessible_all) {
1725
if ( ($_ eq 'latex') || ($_ eq 'pdflatex') ) { $primaries{$_} = 1; }
1729
if ( (! -e $fdb_file) && (! -e "$root_filename.aux") ) {
1730
# No aux and no fdb file => set up trivial aux file
1731
# and corresponding fdb_file. Arrange them to provoke one run
1732
# as minimum, but no more if actual aux file is trivial.
1733
# (Useful on big files without cross references.)
1734
&set_trivial_aux_fdb;
1737
if ( -e $fdb_file ) {
1738
$rdb_errors = rdb_read( $fdb_file );
1739
$have_fdb = ($rdb_errors == 0);
1742
# We didn't get a valid set of data on files used in
1743
# previous run. So use filetime criterion for make
1744
# instead of change from previous run, until we have
1745
# done our own make.
1746
rdb_recurseA( [keys %possible_primaries],
1747
sub{ if ( $$Ptest_kind == 1 ) { $$Ptest_kind = 3;} }
1749
if ( -e "$root_filename.log" ) {
1750
rdb_for_some( [keys %possible_primaries], \&rdb_set_from_logB );
1753
foreach $rule ( rdb_accessible( uniq1( keys %requested_filerules ) ) ){
1754
# For all source files of all accessible rules,
1755
# if the file data are not already set (e.g., from fdb_latexmk
1756
# file, set them from disk.
1757
rdb_one_rule ($rule, undef,
1758
sub{ if ( $$Ptime == 0) { &rdb_update1; } }
1763
# Force everything to be remade.
1764
rdb_recurseA( [keys %requested_filerules], sub{$$Pout_of_date=1;} );
1768
if ( $diagnostics ) {
1769
print "$My_name: Rules after initialization\n";
1182
1773
#************************************************************
1184
# Ensure bbl file up-to-date.
1185
# Also remake the bbl file if there is a bad citation, or if we
1186
# use go_mode (which says to remake everything)
1187
# The call to &make_bbl will also remake the bbl file if it is
1188
# out-of-date with respect to the bib files
1189
# But ignore the return code from make_bbl, since the bbl file depends
1190
# on the aux file, which may in fact be out of date if the tex file has
1191
# changed, and we are about to re-latex it.
1193
&make_bbl($bad_citation || $go_mode);
1194
if ( ($failure > 0) && !$force_mode && ! $preview_continuous_mode) {
1199
# Similarly for ind file. This is simpler because it only depends
1202
&make_ind($go_mode);
1203
if ( ($failure > 0) && !$force_mode && ! $preview_continuous_mode) {
1208
$dest_condition_ignore = 0; #According to this setting
1209
# &make_latex_dvi_pdf will or will not examine whether destination
1210
# files exist when deciding to make latex
1211
&make_files($go_mode);
1213
if ( ($failure > 0) && !$force_mode && ! $preview_continuous_mode) {
1214
&exit_msg1( $failure_msg, $failure );
1216
1775
if ( $preview_continuous_mode ) {
1217
&make_preview_continous;
1219
elsif ( $preview_mode ) {
1221
if ( ($failure > 0) && !$force_mode ) {
1222
&exit_msg1( $failure_msg, $failure );
1225
elsif ( $printout_mode) {
1227
if ( ($failure > 0) && !$force_mode ) {
1228
&exit_msg1( $failure_msg, $failure );
1776
&make_preview_continuousB;
1777
# Will probably exit by ctrl/C and never arrive here.
1782
## Handling of failures:
1783
## Variable $failure is set to indicate a failure, with information
1784
## put in $failure_msg.
1785
## These variables should be set to 0 and '' at any point at which it
1786
## should be assumed that no failures have occurred.
1787
## When after a routine is called it is found that $failure is set, then
1788
## processing should normally be aborted, e.g., by return.
1789
## Then there is a cascade of returns back to the outermost level whose
1790
## responsibility is to handle the error.
1791
## Exception: An outer level routine may reset $failure and $failure_msg
1792
## after initial processing, when the error condition may get
1793
## ameliorated later.
1794
#Initialize failure flags now.
1797
$failure = rdb_makeB( keys %requested_filerules );
1798
if ($failure > 0) { next FILE; }
1799
rdb_for_some( [keys %one_time], \&rdb_run1 );
1802
if ($dependents_list) { rdb_list(); }
1804
$error_message_count = rdb_show_rule_errors();
1805
if ( ($error_message_count == 0) || ($failure > 0) ) {
1806
if ( $failure_msg ) {
1807
#Remove trailing space
1808
$failure_msg =~ s/\s*$//;
1809
warn "$My_name: Did not finish processing file:\n $failure_msg\n";
1813
if ( ($failure > 0) || ($error_message_count > 0) ) {
1822
# If we get here without going through the continue section:
1823
if ( $do_cd && ($#dir_stack > -1) ) {
1824
# Just in case we did an abnormal exit from the loop
1825
warn "$My_name: Potential bug: dir_stack not yet unwound, undoing all directory changes now\n";
1829
if ($failure_count > 0) {
1830
if ( $last_failed <= 0 ) {
1831
# Error occured, but not on last file, so
1832
# user may not have seen error messages
1833
warn "\n------------\n";
1834
warn "$My_name: Some operations failed.\n";
1836
if ( !$force_mode ) {
1837
warn "$My_name: Use the -f option to force complete processing.\n";
1845
#############################################################
1848
# If commands do not have placeholders for %S etc, put them in
1849
foreach ($latex, $pdflatex, $lpr, $lpr_dvi, $lpr_pdf,
1850
$pdf_previewer, $ps_previewer, $ps_previewer_landscape,
1851
$dvi_previewer, $dvi_previewer_landscape,
1855
if ( $_ && ! /%/ ) { $_ .= " %O %S"; }
1859
if ( $_ && ! /%/ ) { $_ .= " %O %B"; }
1861
foreach ($dvipdf, $ps2pdf) {
1862
# Source and dest without flag for destination
1863
if ( $_ && ! /%/ ) { $_ .= " %O %S %D"; }
1865
foreach ($dvips, $makeindex) {
1866
# Source and dest with -o dest before source
1867
if ( $_ && ! /%/ ) { $_ .= " %O -o %D %S"; }
1869
foreach ($dvi_filter, $ps_filter) {
1870
# Source and dest, but as filters
1871
if ( $_ && ! /%/ ) { $_ .= " %O <%S >%D"; }
1875
#############################################################
1878
# Call add_option( \$cmd, $opt )
1879
# Add option to command
1880
if ( ${$_[0]} !~ /%/ ) { &fix_cmds; }
1881
${$_[0]} =~ s/%O/$_[1] %O/;
1884
#############################################################
1886
sub rdb_make_rule_list {
1887
# Substitutions: %S = source, %D = dest, %B = this rule's base
1888
# %T = texfile, %R = root = base for latex.
1890
# Defaults for dvi, ps, and pdf files
1891
# Use local, not my, so these variables can be referenced
1892
local $dvi_final = "%R.dvi";
1893
local $ps_final = "%R.ps";
1894
local $pdf_final = "%R.pdf";
1895
if ( length($dvi_filter) > 0) {
1896
$dvi_final = "%R.dviF";
1898
if ( length($ps_filter) > 0) {
1899
$ps_final = "%R.psF";
1902
my $print_file = '';
1904
if ( $print_type eq 'dvi' ) {
1905
$print_file = $dvi_final;
1906
$print_cmd = $lpr_dvi;
1908
elsif ( $print_type eq 'pdf' ) {
1909
$print_file = $pdf_final;
1910
$print_cmd = $lpr_pdf;
1912
elsif ( $print_type eq 'ps' ) {
1913
$print_file = $ps_final;
1919
my $viewer_update_method = 0;
1920
my $viewer_update_signal = undef;
1921
my $viewer_update_command = undef;
1923
if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) {
1924
$view_file = ${$view.'_final'};
1925
$viewer = ${$view.'_previewer'};
1926
$viewer_update_method = ${$view.'_update_method'};
1927
$viewer_update_signal = ${$view.'_update_signal'};
1928
if (defined ${$view.'_update_command'}) {
1929
$viewer_update_command = ${$view.'_update_command'};
1932
# Specification of internal command for viewer update:
1933
my $PA_update = ['do_update_view', $viewer_update_method, $viewer_update_signal, 0, 1];
1935
# For test_kind: Use file contents for latex and friends, but file time for the others.
1936
# This is because, especially for dvi file, the contents of the file may contain
1937
# a pointer to a file to be included, not the contents of the file!
1939
'latex' => [ 'primary', "$latex", '', "%T", "%B.dvi", "%R", 1 ],
1940
'pdflatex' => [ 'primary', "$pdflatex", '', "%T", "%B.pdf", "%R", 1 ],
1941
'dvipdf' => [ 'external', "$dvipdf", 'do_viewfile', $dvi_final, "%B.pdf", "%R", 2 ],
1942
'dvips' => [ 'external', "$dvips", 'do_viewfile', $dvi_final, "%B.ps", "%R", 2 ],
1943
'dvifilter'=> [ 'external', $dvi_filter, 'do_viewfile', "%B.dvi", "%B.dviF", "%R", 2 ],
1944
'ps2pdf' => [ 'external', "$ps2pdf", 'do_viewfile', $ps_final, "%B.pdf", "%R", 2 ],
1945
'psfilter' => [ 'external', $ps_filter, 'do_viewfile', "%B.ps", "%B.psF", "%R", 2 ],
1946
'print' => [ 'external', "$print_cmd", 'if_source', $print_file, "", "", 2 ],
1947
'update_view' => [ 'external', $viewer_update_command, $PA_update,
1948
$view_file, "", "", 2 ],
1949
'view' => [ 'external', "$viewer", 'if_source', $view_file, "", "", 2 ],
1952
foreach my $rule (keys %rule_list) {
1953
$source_list{$rule} = [];
1954
my $PAsources = $source_list{$rule};
1955
my ( $cmd_type, $cmd, $source, $dest, $root ) = @{$rule_list{$rule}};
1957
push @$PAsources, [ $rule, $source, '' ];
1961
# Ensure we only have one way to make pdf file, and that it is appropriate:
1962
if ($pdf_mode == 1) { delete $rule_list{'dvipdf'}; delete $rule_list{'ps2pdf'}; }
1963
elsif ($pdf_mode == 2) { delete $rule_list{'dvipdf'}; delete $rule_list{'pdflatex'}; }
1964
else { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; }
1966
} # END rdb_make_rule_list
1968
#************************************************************
1971
# Call rdb_set_rules( \%rule_list, ...)
1972
# Set up rule database from definitions
1974
# Map of files to rules that MAKE them:
1977
foreach my $Prule_list (@_) {
1978
foreach my $rule ( keys %$Prule_list) {
1979
my ( $cmd_type, $ext_cmd, $int_cmd, $source, $dest, $base, $test_kind ) = @{$$Prule_list{$rule}};
1980
my $needs_making = 0;
1981
# Substitute in the filename variables, since we will use
1982
# those for determining filenames. But delay expanding $cmd
1983
# until run time, in case of changes.
1984
foreach ($base, $source, $dest ) {
1985
s/%R/$root_filename/;
1987
foreach ($source, $dest ) {
1989
s/%T/$texfile_name/;
1991
# print "$rule: $cmd_type, EC='$ext_cmd', IC='$int_cmd', $test_kind,\n",
1992
# " S='$source', D='$dest', B='$base' $needs_making\n";
1993
rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, $test_kind,
1994
$source, $dest, $base,
1995
$needs_making, undef, 1 );
1996
# !! ?? Last line was
1997
# $needs_making, undef, ($test_kind==1) );
1999
} # End arguments of subroutine
2001
} # END rdb_set_rules
2003
#************************************************************
2005
sub rdb_make_links {
2006
# ?? Problem if there are multiple rules for getting a file. Notably pdf.
2007
# Which one to choose?
2008
# Create $from_rule if there's a suitable rule.
2009
# Map files to rules:
2010
local %from_rules = ();
2011
rdb_for_all( sub{ if($$Pdest){$from_rules{$$Pdest} = $rule;} } );
2012
#?? foreach (sort keys %from_rules) {print "D='$_' F='$from_rules{$_}\n";}
2016
if ( exists $from_rules{$file} ) { $$Pfrom_rule = $from_rules{$file}; }
2017
#?? print "$rule: $file, $$Pfrom_rule\n";
2023
if ( exists $from_rules{$file} ) {
2024
$$Pfrom_rule = $from_rules{$file};
2026
if ( $$Pfrom_rule && (! rdb_rule_exists( $$Pfrom_rule ) ) ) {
2029
#?? print "$rule: $file, $$Pfrom_rule\n";
2032
} # END rdb_make_links
2034
#************************************************************
2036
sub set_trivial_aux_fdb {
2037
# 1. Write aux file EXACTLY as would be written if the tex file
2038
# had no cross references, etc. I.e., a minimal .aux file.
2039
# 2. Write a corresponding fdb file
2040
# 3. Provoke a run of (pdf)latex (actually of all primaries).
2042
local $aux_file = "$root_filename.aux";
2043
open( aux_file, '>', $aux_file )
2044
or die "Cannot write file '$aux_file'\n";
2045
print aux_file "\\relax \n";
2048
foreach my $rule (keys %primaries ) {
2049
rdb_ensure_file( $rule, $texfile_name );
2050
rdb_ensure_file( $rule, $aux_file );
2051
rdb_one_rule( $rule,
2052
sub{ $$Pout_of_date = 1; }
2055
&rdb_write( $fdb_file );
2056
} #END set_trivial_aux_fdb
2058
#************************************************************
2059
#### Particular actions
2060
#************************************************************
2061
#************************************************************
2064
# Unconditional application of custom-dependency
2065
# except that rule is not applied if the source file source
2066
# does not exist, and an error is returned if the dest is not made.
2068
# Assumes rule context for the custom-dependency, and that my first
2069
# argument is the name of the subroutine to apply
2070
my $func_name = $_[0];
2072
if ( !-e $$Psource ) {
2073
# Source does not exist. Users of this rule will need to turn
2074
# it off when custom dependencies are reset
2076
## ??? Was commented out. 1 Sep. 2008 restored, for cusdep no-file-exists issue
2077
warn "$My_name: In trying to apply custom-dependency rule\n",
2078
" to make '$$Pdest' from '$$Psource'\n",
2079
" the source file has disappeared since the last run\n";
2081
# Treat as successful
2083
elsif ( !$func_name ) {
2084
warn "$My_name: Possible misconfiguration or bug:\n",
2085
" In trying to apply custom-dependency rule\n",
2086
" to make '$$Pdest' from '$$Psource'\n",
2087
" the function name is blank.\n";
2089
elsif ( ! defined &$func_name ) {
2090
warn "$My_name: Misconfiguration or bug,",
2091
" in trying to apply custom-dependency rule\n",
2092
" to make '$$Pdest' from '$$Psource'\n",
2093
" function name '$func_name' does not exists.\n";
2096
my $cusdep_ret = &$func_name( $$Pbase );
2097
if ( defined $cusdep_ret && ($cusdep_ret != 0) ) {
2098
$return = $cusdep_ret;
2100
warn "Rule '$rule', function '$func_name'\n",
2101
" failed with return code = $return\n";
2104
elsif ( !-e $$Pdest ) {
2105
# Destination non-existent, but routine failed to give an error
2106
warn "$My_name: In running custom-dependency rule\n",
2107
" to make '$$Pdest' from '$$Psource'\n",
2108
" function '$func_name' did not make the destination.\n";
2115
#************************************************************
2118
# Unconditionally make file for viewing, going through temporary file if
2119
# Assumes rule context
2122
my ($base, $path, $ext) = fileparseA( $$Pdest );
2123
if ( &view_file_via_temporary ) {
2124
my $tmpfile = tempfile1( "${root_filename}_tmp", $ext );
2125
$return = &rdb_ext_cmd1( '', '', $tmpfile );
2127
move( $tmpfile, $$Pdest );
2130
$return = &rdb_ext_cmd;
2135
#************************************************************
2137
sub do_update_view {
2139
# Assumes rule context
2140
# Arguments: (method, signal, viewer_process)
2144
# Although the process is passed as an argument, we'll need to update it.
2145
# So (FUDGE??) bypass the standard interface for the process.
2146
# We might as well do this for all the arguments.
2147
my $viewer_update_method = ${$PAint_cmd}[1];
2148
my $viewer_update_signal = ${$PAint_cmd}[2];
2149
my $Pviewer_process = \${$PAint_cmd}[3];
2150
my $Pneed_to_get_viewer_process = \${$PAint_cmd}[4];
2152
if ($viewer_update_method == 2) {
2153
if ($$Pneed_to_get_viewer_process) {
2154
$$Pviewer_process = &find_process_id( $$Psource );
2155
if ($$Pviewer_process != 0) {
2156
$$Pneed_to_get_viewer_process = 0;
2159
if ($$Pviewer_process == 0) {
2160
print "$My_name: need to signal viewer for file '$$Psource', but didn't get \n",
2161
" process ID for some reason, e.g., no viewer, bad configuration, bug\n"
2164
elsif ( defined $viewer_update_signal) {
2165
print "$My_name: signalling viewer, process ID $$Pviewer_process\n"
2167
kill $viewer_update_signal, $$Pviewer_process;
2170
warn "$My_name: viewer is supposed to be sent a signal\n",
2171
" but no signal is defined. Misconfiguration or bug?\n";
2175
elsif ($viewer_update_method == 4) {
2176
if (defined $$Pext_cmd) {
2177
$return = &rdb_ext_cmd;
2180
warn "$My_name: viewer is supposed to be updated by running a command,\n",
2181
" but no command is defined. Misconfiguration or bug?\n";
2185
} #END do_update_view
2187
#************************************************************
2190
# Unconditionally apply rule if source file exists.
2191
# Assumes rule context
2192
if ( -e $$Psource ) {
2193
return &rdb_ext_cmd;
1233
2200
#************************************************************
1234
2201
#### Subroutines
1235
2202
#************************************************************
1237
#************************************************************
1243
my $do_build = $_[0];
1247
= &make_dependents($do_build);
1248
if ($failure > 0) {return;}
1249
if ( ($new_files > 0) || ($new_deps > 0) ) {
1254
&make_latex_dvi_pdf($do_build, 'dvi');
1255
if ($failure > 0) {return;}
1259
if ($failure > 0) {return;}
1261
if ( $need_pdf == 1 ) {
1262
&make_latex_dvi_pdf($do_build, 'pdf');
1263
if ($failure > 0) {return;}
1265
if ( $need_pdf == 2 ) {
1267
if ($failure > 0) {return;}
1269
if ( $need_pdf == 3 ) {
1271
if ($failure > 0) {return;}
1275
#************************************************************
1277
sub make_latex_dvi_pdf
1279
my $do_build = $_[0];
1280
my $dest_type = $_[1];
1283
if ( $dest_type eq 'dvi' ) {
1284
$dest = "$root_filename.dvi";
1285
$processor = $latex;
1286
} elsif ( $dest_type eq 'pdf' ) {
1287
$dest = "$root_filename.pdf";
1288
$processor = $pdflatex;
1290
die("Latexmk: BUG: undefined destination type $dest_type in make_latex_dvi_pdf\n");
1293
## get initial last modified times.
1294
my $tex_mtime = &get_latest_mtime(@includes);
1295
my $dest_mtime= &get_mtime("$dest");
1296
my $aux_mtime = &get_mtime("$root_filename.aux");
1297
my $bib_mtime = &get_latest_mtime(@bib_files);
1298
my $bbl_mtime = &get_mtime("$root_filename.bbl");
1299
my $ilg_mtime = &get_mtime("$root_filename.ilg");
1300
my $ind_mtime = &get_mtime("$root_filename.ind");
1302
## - if no destination file (dvi or pdf),
1303
## or .aux older than tex file or bib file or anything they input,
1308
# !(-e "$root_filename.aux"),
1309
# ($aux_mtime < $tex_mtime),
1311
# ( (-e "$root_filename.bbl") && ($aux_mtime < $bbl_mtime) ),
1312
# ($dest_mtime < $tex_mtime),
1313
# ( (-e "$root_filename.ilg") && ($aux_mtime < $ilg_mtime) ),
1314
# ( (-e "$root_filename.ind") && ($aux_mtime < $ind_mtime) ),
1315
# ( $includes_from_log && ! -e "$root_filename.log" )
1317
my $dest_bad = !(-e "$dest") || ($dest_mtime < $tex_mtime) ;
1318
if ($dest_condition_ignore) {$dest_bad = 0;}
1320
|| !(-e "$root_filename.aux")
1321
|| ($aux_mtime < $tex_mtime)
1323
|| ( (-e "$root_filename.bbl") && ($aux_mtime < $bbl_mtime) )
1324
|| ( (-e "$root_filename.ilg") && ($aux_mtime < $ilg_mtime) )
1325
|| ( (-e "$root_filename.ind") && ($aux_mtime < $ind_mtime) )
1326
|| ( $includes_from_log && ! -e "$root_filename.log" )
1329
&build_latex_dvi_pdf($processor);
1330
if ($failure > 0) {return;}
1331
if ( $dest_type eq 'dvi') {
1333
if ($failure > 0) {return;}
1338
warn "Latexmk: File '$dest' is up to date\n"
1339
if !$quell_uptodate_msgs;
1343
sub list_conditions {
1349
print "On conditions: ";
1350
for ($i = 1; $i <= $#_+1; $i++) {
1351
if ($_[$i-1]) {print "$i ";}
1356
#************************************************************
1358
sub build_latex_dvi_pdf {
1359
# Argument: 0 = processor (e.g., 'latex' or 'pdflatex')
1361
# I don't need to know whether I run latex or pdflatex!
1363
# Repeat running latex as many times as needed to resolve cross
1364
# references, also running bibtex and makeindex as necessary. The
1365
# algorithm for determining whether latex needs to be run again is
1366
# whether certain generated files have changed since the previous
1367
# run. A limit (contained in $max_repeat) is applied on the
1368
# number of runs, to avoid infinite loops in pathological cases or
1369
# in the case of a bug. $max_repeat should be at least 4, to
1370
# allow for the maximum number of repeats under normal
1371
# circumstances, which is 3, plus one for unusual cases of page
1372
# breaks moving around.
1374
# The criterion for needing a rerun is that one or both of the
1375
# .aux file and the .idx file has changed. To prove this: observe
1376
# that reruns are necessary because information that needs to be
1377
# read in from a file does not correspond to the current
1378
# conditions. The relevant files are: the .aux file, and possibly
1379
# one or more of: the index files, the table of contents file
1380
# (.toc), the list of figures file (.lof), the list of tables file
1381
# (.lot). The information read in is: cross reference
1382
# definitions, page references, tables of contents, figures and
1383
# tables. Note that the list of figures (for example) may itself
1384
# contain undefined references or incorrect page references. If
1385
# there is any incorrectness, changed information will be written
1386
# to the corresponding file on the current run, and therefore one
1387
# or more of the auxiliary files will have changed.
1389
# In fact the lines in the .toc, .lof and .lot files correspond to
1390
# entries in the .aux file, so it is not necessary to check the
1391
# .toc, .lof and .lot files (if any). However WHETHER these files
1392
# are input by latex is not determined by the aux file, but does
1393
# affect the output. It is possible for the tex file to change
1394
# the state of one of the .toc, .lof, or .lot files between begin
1395
# required and not required. The same could happen for other
1398
# For example, initially suppose no TOC is required, and that all
1399
# generated files are up-to-date. The .toc file is either not
1400
# present or is out-of-date. Then change the source file so
1401
# that a TOC is requested. Run latex; it uses wrong TOC
1402
# information, but the .aux file might not change.
1404
# Two possibilities: (a) check .toc, .lof, .lot (possibly etc!)
1405
# files for changes; (b) check for a change in the list of input
1406
# files. We'll choose the second: since it requires less file
1407
# checking and is more general. It applies in all situations
1408
# where the extra auxiliary input files (e.g., .toc) correspond in
1409
# contents to the state of the .aux file, but only if these files
1412
# Therefore a correct algorithm is to require a rerun if either of
1413
# the following is true:
1415
# 1. The .aux file has changed from the previous run.
1416
# 2. The .idx file has changed from the previous run.
1417
# 3. The set of input files has changed from the previous run.
1419
# Of course, if a previous version of one of these files did not
1420
# exist (as on a first run), then that implies a rerun is
1421
# necessary. And if a .aux file or a .idx file is not generated,
1422
# there is no point in testing it against a previous version.
1424
# Assume on entry that the .ind and .bbl files are up-to-date with
1425
# respect to the already existing .idx and .aux files. This will
1426
# be the case if latexmk was used to make them.
1429
my $processor = $_[0];
1431
my $count_latex = 0;
1435
# Arrival here means that a new run of latex/pdflatex is requested
1436
# Assume that the .ind file (if any) corresponds to the .idx file
1437
# from the previous run
1438
# and that the .bbl file (if any) corresponds to the .aux file from
1441
$repeat = 0; # Assume no repeat necessary.
1442
$count_latex++; # Count the number of passes through latex
1443
warn "------------\nRun number $count_latex of ",
1444
"$processor [$texfile_name]\n------------\n";
1445
foreach $aux_file (@aux_files)
1447
if ( -e $aux_file ) {
1448
warn "Saving old .aux file \"$aux_file\"\n" unless $silent;
1449
copy_file_and_time ( "$aux_file", "$aux_file.bak");
1452
if ( (! -e "$root_filename.aux") && (! -e "$root_filename.aux.bak") ) {
1453
# Arrive here if neither of the .aux and the .aux.bak files exists
1454
# for the base file.
1455
# I make minimal .aux.bak file, containing a single line "\relax "
1456
# This is the same as the aux file generated for a latex file
1457
# which does not need any cross references, etc. Generating this
1458
# .aux.bak file will save a pass through latex on simple files.
1459
local $aux_bak_file = ">$root_filename.aux.bak";
1460
open(aux_bak_file) || die "Cannot write file $aux_bak_file\n";
1461
print aux_bak_file "\\relax \n";
1462
close(aux_bak_file);
1464
if ( (-e "$root_filename.aux") && $bibtex_mode) {
1465
# We have assumed that the bbl file is up-to-date
1466
# with respect to the previous aux file. However
1467
# it may be out-of-date with respect to the bib file(s).
1468
# So run bibtex in this case
1469
my $bibtex_return_code = &make_bbl(0);
1470
if ( ($bibtex_return_code eq 2) & !$force_mode )
1473
$failure_msg = 'Bibtex reported an error';
1478
if ( -e "$root_filename.idx" ) {
1479
warn "Saving old .idx file\n" unless $silent;
1480
copy_file_and_time ( "$root_filename.idx", "$root_filename.idx.bak");
1483
my @includes_previous = @includes;
1484
my ($pid, $return) = &Run("$processor $texfile_name");
1485
$updated = 1; # Flag that some dependent file has been remade
1489
$failure_msg = 'Latex encountered an error';
1494
# User may not have seen error
1495
warn "====Latex encountered an error: see .log file====\n";
1498
$return = &parse_log;
1499
my $aux_changed = 0;
1500
my $idx_changed = 0;
1505
$failure_msg = 'Latex failed to generate a log file';
1509
if ( $includes_from_log )
1511
my @aux_files_previous = @aux_files;
1512
if ( @aux_files ne @aux_files_previous ){
1514
warn "List of .aux files has changed. ",
1515
"I must run latex again\n"
1520
if ( !$aux_changed )
1522
# Look for changes in the individual aux files.
1523
foreach $aux_file (@aux_files)
1525
if ( -e "$aux_file" ) {
1526
if ( &diff ("$aux_file", "$aux_file.bak") ) {
1527
warn ".aux file \"$aux_file\" changed. ",
1528
"I must run latex again\n"
1534
warn "File \"$aux_file\" has not changed, ",
1535
"so it is valid\n" unless $silent;
1540
if ( (!-e "$root_filename.aux") && (-e "$root_filename.aux.bak") ) {
1541
warn "No aux file was generated, so I don't need .aux.bak file\n"
1543
unlink ("$root_filename.aux.bak");
1546
if ( (-e "$root_filename.aux") && $aux_changed && $bibtex_mode) {
1547
# Note running bibtex only makes sense if the aux file exists.
1548
# If any aux file has changed, then the citations may
1549
# have changed and we must run bibtex.
1550
# The argument to &make_bbl forces this.
1551
# &make_bbl also checks whether the bbl file is
1552
# out-of-date with respect to the bib files.
1553
my $bibtex_return_code = &make_bbl($aux_changed);
1554
if ( ($bibtex_return_code eq 2) && !$force_mode )
1557
$failure_msg = 'Bibtex reported an error';
1562
if ( -e "$root_filename.idx" ) {
1563
if ( &diff ("$root_filename.idx", "$root_filename.idx.bak") ) {
1564
warn "The .idx file changed. I must run latex again\n"
1566
# idx file exists and has changed
1567
# implies idx file written
1568
# implies indexing being used
1572
warn "The .idx file has not changed, so it is valid\n"
1576
my $makeindex_return_code = &make_ind($idx_changed);
1577
if ( ($makeindex_return_code eq 2) && !$force_mode ) {
1579
$failure_msg = 'Makeindex encountered an error';
1585
warn "No .idx file was generated, but index_mode is set; ",
1590
if ( -e "$root_filename.idx.bak") {
1591
warn "No idx file was generated. ",
1592
"So I delete unneeded .idx.bak file\n"
1594
unlink ("$root_filename.idx.bak");
1598
if ( @includes ne @includes_previous ) {
1599
warn "The set of input files changed. I must run latex again\n"
1605
||( @includes ne @includes_previous )
1610
if ( $count_latex ge $max_repeat ) {
1611
# Avoid infinite loop by having a maximum repeat count
1612
# Getting here represents some kind of weird error.
1614
warn "Maximum runs of latex reached ",
1615
"without correctly resolving cross references\n";
1619
} until ($repeat == 0);
1622
my $retcode = &check_for_bibtex_warnings;
1623
if ($retcode == 1) {
1624
print "See $root_filename.blg for details\n";
1626
elsif ($retcode == 2) {
1631
if (!$force_mode && $bad_reference) {
1633
$failure_msg = 'Latex could not resolve all references';
1637
if (!$force_mode && $bad_citation) {
1639
$failure_msg = 'Latex could not resolve all citations or labels';
1644
2203
#************************************************************
1646
2205
# Finds the basename of the root file
1706
2266
$tex_name = "$given_name";
1708
($base_name, $path, $ext) = fileparse ($tex_name, '\.[^\.]*');
2268
($base_name, $path, $ext) = fileparse( $tex_name, '\.[^\.]*' );
1709
2269
$_[1] = $base_name;
1710
2270
$_[2] = $tex_name;
1713
die "Latexmk: Incorrect configuration gives \$extension_treatment=",
1714
"\"$extension_treatment\"\n";
2273
die "$My_name: Incorrect configuration gives \$extension_treatment=",
2274
"'$extension_treatment'\n";
1716
2276
if ($diagnostics) {
1717
print "Given=\"$given_name\", tex=\"$tex_name\", base=\"$base_name\"\n";
2277
print "Given='$given_name', tex='$tex_name', base='$base_name'\n";
1719
2279
return ! -e $tex_name;
1722
#************************************************************
1725
# If necessary, make bbl file. Assume bibtex mode on.
1726
# Force run if first argument is non-zero.
1727
# Return 0 if nothing made,
1728
# 1 if bbl file made,
1729
# 2 if bibtex reported an error
1730
# 3 if .blg file couldn't be opened
1731
# 4 if there was another error
1732
my $bib_mtime = &get_latest_mtime(@bib_files);
1733
my $bbl_mtime = &get_mtime("$root_filename.bbl");
1734
## if no .bbl or .bib changed since last bibtex run, run bibtex.
1735
if ( !-e "$root_filename.aux" )
1737
# bibtex reads aux file, so if there is no aux file, there is
1742
|| !(-e "$root_filename.bbl")
1743
|| ($bbl_mtime < $bib_mtime)
1746
warn "------------\nRunning $bibtex [$root_filename]",
1749
my ($pid, $return) = &Run("$bibtex $root_filename");
1751
$bbl_mtime = &get_mtime("$root_filename.bbl");
1754
$return = &check_for_bibtex_errors;
1757
elsif ( $return == 1 )
1759
elsif ( $return == 2 )
1768
#************************************************************
1771
# If necessary, make ind file. Assume makeindex mode on.
1772
# Force run if first argument is non-zero.
1773
# Return 0 if nothing made,
1774
# 1 if ind file made,
1775
# 2 if makeindex reported an error
1776
if ( !-e "$root_filename.idx" )
1778
# makeindex reads idx file, so if there is no idx file, there is
1782
if ( ($_[0] != 0) || !(-e "$root_filename.ind") )
1784
warn "------------\nRunning $makeindex [$root_filename]",
1787
my ($pid, $return) = &Run("$makeindex $root_filename");
1792
$failure_msg = 'Problem with makeindex';
1802
#************************************************************
1806
my @new_includes = ();
1808
foreach my $missing (sort keys %includes_missing) {
1809
my ($base, $path, $ext) = fileparse ($missing, '\.[^\.]*');
1810
if ( -e "$missing.tex" ) {
1811
push @new_includes, "$missing.tex";
1812
# It's probably best to try all possibilities, since
1813
# we don't know which one applies. So go on to next case.
1814
# next MISSING_FILE;
1816
if ( -e $missing ) {
1817
push @new_includes, $missing;
1818
# next MISSING_FILE;
1821
foreach my $dep (@cus_dep_list){
1822
my ($fromext,$toext) = split(' ',$dep);
1823
if ( ( "$ext" eq ".$toext" )
1824
&& ( -e "$path$base.$fromext" )
1826
# Source file for the missing file exists
1827
# So we have a real include file, and it will be made
1828
# next time by &make_dependents
1829
push @new_includes, $missing ;
1830
# next MISSING_FILE;
1832
# no point testing the $toext if the file doesn't exist.
1836
# $_ doesn't exist, $_.tex doesn't exist,
1837
# and $_ doesn't have an extension
1838
foreach my $dep (@cus_dep_list){
1839
my ($fromext,$toext) = split(' ',$dep);
1840
if ( -e "$path$base.$fromext" ) {
1841
# Source file for the missing file exists
1842
# So we have a real include file, and it will be made
1843
# next time by &make_dependents
1844
push @new_includes, "$path$base.$toext" ;
1845
# next MISSING_FILE;
1847
if ( -e "$path$base.$toext" ) {
1848
# We've found the extensionfor the missing file,
1849
# and the file exists
1850
push @new_includes, "$path$base.$toext" ;
1851
# next MISSING_FILE;
1855
} # end MISSING_FILES
1857
@new_includes = uniq( sort(@new_includes) );
1858
@includes = uniq( sort(@includes, @new_includes) );
1860
my $found = $#new_includes + 1;
1861
if ( $diagnostics && ( $found > 0 ) ) {
1862
warn "Detected previously missing files:\n";
1863
foreach (@new_includes) {
1870
#************************************************************
1874
# Usage: make_dependents(build)
1875
# First argument = 1 => rebuild unconditionally
1876
# 0 => rebuild only if dest is out-of-date
1877
# Return 0 if nothing made, 1 if something made
1879
my $makes = 0; # Count of makes done
1881
foreach my $file (@includes)
1883
my ($base_name, $path, $toext) = fileparse ($file, '\.[^\.]*');
1884
$base_name = $path.$base_name;
1885
if ( $toext eq "" ) {next FILE;}
1888
foreach my $dep ( @cus_dep_list )
1890
my ($fromext,$proptoext,$must,$func_name) = split(' ',$dep);
1891
if ( $toext eq $proptoext )
1893
# Found match of rule
1894
if ( -e "$base_name.$fromext" )
1896
# From file exists, now check if it is newer
1897
if (( ! (-e "$base_name.$toext" ))
1899
|| ( &get_mtime("$base_name.$toext")
1900
< &get_mtime("$base_name.$fromext")
1904
warn "------------\nRunning $func_name [$base_name]\n------------\n"
1906
my $return = &$func_name($base_name);
1908
if ( !$force_mode && $return )
1911
$failure_msg = "$func_name encountered an error";
1920
{ # Source file does not exist
1921
# Perhaps the rule is not to be applied.
1922
if ( !$force_mode && ( $must != 0 ))
1925
$failure_msg = "File '$base_name.$fromext' does not exist ".
1926
"to build '$base_name.$toext'";
1930
} # End of Rule found
1933
return ($makes>0 ? 1 : 0);
1934
} # End sub make_dependents
1936
#************************************************************
1938
sub make_dvi_filtered
1940
my $dvi_file = "$root_filename.dvi";
1941
return if ( length($dvi_filter) == 0 );
1942
if ( ! -e $dvi_file ) {
1943
warn "Dvi file \"$dvi_file\" has not been made, so I cannot filter it\n";
1946
warn "------------\nRunning $dvi_filter [$root_filename]\n------------\n"
1948
&Run("$dvi_filter < $dvi_file > $root_filename.dviF");
1952
#************************************************************
1959
if ( length($ps_filter) == 0 )
1960
{$ps_file = "$root_filename.ps";}
1962
{$ps_file = "$root_filename.psF";}
1963
$pdf_file = "$root_filename.pdf";
1965
my $ps_mtime = &get_mtime("$ps_file");
1966
my $pdf_mtime = &get_mtime("$pdf_file");
1967
if ( ! -e $ps_file ) {
1968
warn "Postscript file \"$ps_file\" has not been made\n";
1971
if ((! -e "$pdf_file")
1972
||( $pdf_mtime < $ps_mtime )
1975
warn "------------\nRunning $ps2pdf [$root_filename]\n------------\n"
1977
&Run("$ps2pdf $ps_file $pdf_file");
1982
warn "Latexmk: File '$pdf_file' is up to date\n" if !$quell_uptodate_msgs;
1986
#************************************************************
1993
if ( length($dvi_filter) == 0 )
1994
{$dvi_file = "$root_filename.dvi";}
1996
{$dvi_file = "$root_filename.dviF";}
1997
$pdf_file = "$root_filename.pdf";
1999
my $dvi_mtime = &get_mtime("$dvi_file");
2000
my $pdf_mtime = &get_mtime("$pdf_file");
2001
if ( ! -e $dvi_file ) {
2002
warn "Dvi file \"$dvi_file\" has not been made, so I cannot convert it to pdf\n";
2005
if ((! -e "$pdf_file")
2006
||( $pdf_mtime < $dvi_mtime )
2009
warn "------------\nRunning $dvipdf [$root_filename]\n------------\n"
2011
&Run("$dvipdf $dvi_file $pdf_file");
2016
warn "Latexmk: File '$pdf_file' is up to date\n" if !$quell_uptodate_msgs;
2020
#************************************************************
2024
my $ext = ''; # extension of file to print
2025
my $command = ''; # command to print it
2026
if ( $print_type eq 'dvi' ) {
2027
if ( length($dvi_filter) == 0 )
2035
$command = $lpr_dvi;
2037
elsif ( $print_type eq 'pdf' ) {
2039
$command = $lpr_pdf;
2041
elsif ( $print_type eq 'ps' ) {
2042
if ( length($ps_filter) == 0 )
2052
elsif ( $print_type eq 'none' ) {
2053
warn "------------\nPrinting is configured off\n------------\n";
2058
die "Latexmk: incorrect value \"$print_type\" for type of file to print\n".
2059
"Allowed values are \"dvi\", \"pdf\", \"ps\", \"none\"\n"
2061
my $file = $root_filename.$ext;
2063
warn "File \"$file\" has not been made, so I cannot print it\n";
2066
warn "------------\nPrinting using $command $file\n------------\n"
2068
&Run("$command $file");
2071
#************************************************************
2079
# Figure out the dvi file name
2080
if ( length($dvi_filter) == 0 )
2082
$dvi_file = "$root_filename.dvi";
2086
$dvi_file = "$root_filename.dviF";
2089
if ( ! -e $dvi_file ) {
2090
warn "Dvi file \"$dvi_file\" has not been made, so I cannot convert it to postscript\n";
2097
## Make temp banner file
2098
# local(*INFILE,*OUTFILE,$count);
2099
local(*OUTFILE,$count);
2101
$tmpfile = "$tmpdir/latexmk.$$";
2103
while ( -e $tmpfile )
2105
$count = $count + 1;
2106
$tmpfile = "$tmpdir/latexmk.$$.$count";
2108
if ( ! open(OUTFILE, ">$tmpfile") ) {
2109
die "Latexmk: Could not open temporary file [$tmpfile]\n"; }
2110
print OUTFILE "userdict begin /bop-hook{gsave 200 30 translate\n";
2111
print OUTFILE "65 rotate /Times-Roman findfont $banner_scale scalefont setfont\n";
2112
print OUTFILE "0 0 moveto $banner_intensity setgray ($banner_message) show grestore}def end\n";
2114
$header = "-h $tmpfile";
2121
my $ps_mtime = &get_mtime("$root_filename.ps");
2122
my $dvi_mtime = &get_mtime("$dvi_file");
2123
if ((! -e "$root_filename.ps")
2124
||( $ps_mtime < $dvi_mtime )
2127
warn "------------\nRunning $dvips [$root_filename]\n------------\n"
2129
&Run("$dvips $header $dvi_file -o $root_filename.ps");
2130
## Do we have postscript filtering?
2131
if ( length($ps_filter) != 0 )
2133
warn "------------\nRunning $ps_filter [$root_filename]\n------------\n"
2135
&Run("$ps_filter < $root_filename.ps > $root_filename.psF");
2141
warn "Latexmk: File '$root_filename.ps' is up to date\n" if !$quell_uptodate_msgs;
2151
#************************************************************
2152
# run appropriate previewer.
2158
if ( $view eq 'dvi' )
2160
$viewer = $dvi_previewer;
2162
if ( length($dvi_filter) != 0 )
2167
elsif ( $view eq 'ps' )
2169
$viewer = $ps_previewer;
2171
if ( length($ps_filter) != 0 )
2176
elsif ( $view eq 'pdf' )
2178
$viewer = $pdf_previewer;
2183
die "Latexmk: BUG: No preview method defined\n";
2186
my $view_file = "$root_filename$ext";
2188
if ( ! -e $view_file ) {
2189
warn "File \"$view_file\" has not been made, so I cannot view it\n";
2192
warn "------------\nStarting previewer: $viewer $view_file\n------------\n"
2194
my ($pid, $return) = &Run ("$viewer $view_file");
2196
warn "Latexmk: Could not start previewer [$viewer $view_file]";
2201
#************************************************************
2203
sub make_preview_continous
2206
# How do we persuade viewer to update. Default is to do nothing.
2207
my $viewer_update_method = 0;
2208
# Extension of file:
2210
$quell_uptodate_msgs = 1;
2211
if ( $view eq 'dvi' )
2213
$viewer = $dvi_previewer;
2214
$viewer_update_method = $dvi_update_method;
2216
if ( length($dvi_filter) != 0 )
2221
elsif ( $view eq 'ps' )
2223
$viewer = $ps_previewer;
2224
$viewer_update_method = $ps_update_method;
2226
if ( length($ps_filter) != 0 )
2231
elsif ( $view eq 'pdf' )
2233
$viewer_update_method = $pdf_update_method;
2234
$viewer = $pdf_previewer;
2239
die "Latexmk: BUG: No preview method defined\n";
2243
# Viewer information:
2244
my $viewer_running = 0; # No viewer running yet
2245
my $view_file = "$root_filename$ext";
2246
my $viewer_process = 0; # default: no viewer process number known
2280
} #END find_basename
2282
#************************************************************
2284
sub make_preview_continuousB {
2285
# Version for use with makeB
2286
local @changed = ();
2287
local @disappeared = ();
2288
local @no_dest = (); # Non-existent destination files
2289
local @rules_never_run = ();
2290
local @rules_to_apply = ();
2294
local %rules_applied = ();
2298
my @targets = keys %requested_filerules;
2300
$quell_uptodate_msgs = 1;
2302
local $view_file = '';
2303
rdb_one_rule( 'view', sub{ $view_file = $$Psource; } );
2248
$dest_condition_ignore = 1; #make_latex_dvi-pdf will ignore destination
2249
#in make rule. If the destination file does not
2250
#exists, it is because of an error.
2251
# Loop forever, rebuilding .dvi and .ps as necessary.
2254
# Wait to run a viewer until we know we have the view file
2255
# If there are errors in the initial run, the
2256
if ( (!$viewer_running) && (-e $view_file) ) {
2257
# note, we only launch a previewer if one isn't already running...
2258
# But I only know how to do this under UNIX
2259
$viewer_process = &find_process_id( $view_file );
2260
if ( $viewer_process ) {
2261
warn "Previewer is already running\n"
2262
if $first_time && !$silent;
2264
warn "I have not found a previewer that is already running. \n",
2265
"So I will start it: $viewer $view_file\n------------\n"
2268
($viewer_process, $retcode)
2269
= &Run ("start $viewer $root_filename$ext");
2270
if ( $retcode != 0 ) {
2272
warn "I could not run previewer\n";
2275
&exit_msg1( "I could not run previewer", $retcode);
2279
$viewer_running = 1;
2280
} # end analyze result of trying to run viewer
2281
} # end if $viewer_process
2282
} # end start viewer
2283
if ( $first_time || $updated ) {
2284
print "\n=== Watching for updated files. Use ctrl/C to stop ...\n";
2291
if ( ($failure <= 0)
2292
&& ($viewer_process != 0)
2294
&& ($viewer_update_method == 2)
2297
if ( $diagnostics ) {
2298
print "I am signalling viewer, process ID $viewer_process\n";
2300
kill 'USR1', $viewer_process;
2302
} #end infinite_loop
2303
} #end sub make_preview_continuous
2305
#************************************************************
2308
# - erases basic set of generated files, exits w/ no other processing.
2309
# (all but aux, dep, dvi, pdf, and ps),
2310
# and also texput.log, and files with extensions in $clean_ext
2315
unlink("$root_filename.aux.bak");
2316
unlink("$root_filename.bbl");
2317
unlink("$root_filename.blg");
2318
unlink("$root_filename.log");
2319
unlink("$root_filename.ind");
2320
unlink("$root_filename.idx");
2321
unlink("$root_filename.idx.bak");
2322
unlink("$root_filename.ilg");
2323
unlink("$root_filename.toc");
2324
unlink("$root_filename.toc.bak");
2325
unlink("$root_filename.lof");
2326
unlink("$root_filename.lot");
2327
unlink("texput.log");
2329
# Do any other file extensions specified
2330
foreach $ext (split(' ',$clean_ext))
2332
unlink("$root_filename.$ext");
2337
#************************************************************
2338
# cleanup_dvi_ps_pdf
2339
# - erases generated dvi, ps, and pdf files (and others specified in
2340
# $cleanup_full_ext),
2341
# and also texput.dvi, and files with extensions in $clean_full_ext
2343
sub cleanup_dvi_ps_pdf
2345
unlink("$root_filename.dvi");
2346
unlink("$root_filename.pdf");
2347
unlink("$root_filename.ps");
2348
unlink("$root_filename.dviF");
2349
unlink("$root_filename.psF");
2350
unlink("texput.dvi");
2351
# Do any other file extensions specified
2352
foreach $ext (split(' ',$clean_full_ext))
2354
unlink("$root_filename.$ext");
2359
#************************************************************
2361
# - erases generated aux and dep files, and also texput.aux
2365
unlink("$root_filename.aux");
2366
unlink("$root_filename.dep");
2367
unlink("texput.aux");
2368
# .aux files are also made for \include'd files
2369
foreach my $include (@includes) {
2370
$include =~ s/\.[^\.]*$/.aux/;
2376
#************************************************************
2379
warn "Latexmk: restoring last $root_filename.aux file\n";
2380
# But don't copy the time from the aux.bak file
2381
# So the aux file will look up-to-date
2382
copy_file_keep_time( "$root_filename.aux.bak", "$root_filename.aux" );
2305
if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) {
2306
warn "Viewing $view\n";
2308
elsif ( $view eq 'none' ) {
2309
warn "Not using a previewer\n";
2313
warn "$My_name: BUG: Invalid preview method '$view'\n";
2317
my $viewer_running = 0; # No viewer known to be running yet
2318
# Get information from update_view rule
2319
local $viewer_update_method = 0;
2320
# Pointers so we can update the following:
2321
local $Pviewer_process = undef;
2322
local $Pneed_to_get_viewer_process = undef;
2323
rdb_one_rule( 'update_view',
2324
sub{ $viewer_update_method = $$PAint_cmd[1];
2325
$Pviewer_process = \$$PAint_cmd[3];
2326
$Pneed_to_get_viewer_process = \$$PAint_cmd[4];
2329
# Note that we don't get the previewer process number from the program
2330
# that starts it; that might only be a script to get things set up and the
2331
# actual previewer could be (and sometimes IS) another process.
2333
if ( ($view_file ne '') && (-e $view_file) && !$new_viewer_always ) {
2334
# Is a viewer already running?
2335
# (We'll save starting up another viewer.)
2336
$$Pviewer_process = &find_process_id( $view_file );
2337
if ( $$Pviewer_process ) {
2338
warn "$My_name: Previewer is already running\n"
2340
$viewer_running = 1;
2341
$$Pneed_to_get_viewer_process = 0;
2345
# Loop forever, rebuilding .dvi and .ps as necessary.
2346
# Set $first_time to flag first run (to save unnecessary diagnostics)
2348
for (my $first_time = 1; 1; $first_time = 0 ) {
2352
if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) {
2353
# Fudge under MSWin32 ONLY, to stop perl/latexmk from
2354
# catching ctrl/C and ctrl/break, and let it only reach
2355
# downstream programs. See comments at first definition of
2356
# $MSWin_fudge_break.
2357
$SIG{BREAK} = $SIG{INT} = 'IGNORE';
2359
$failure = rdb_makeB( @targets );
2361
## warn "=========Viewer PID = $$Pviewer_process; updated=$updated\n";
2363
if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) {
2364
$SIG{BREAK} = $SIG{INT} = 'DEFAULT';
2366
if ( $failure > 0 ) {
2367
if ( !$failure_msg ) {
2368
$failure_msg = 'Failure to make the files correctly';
2370
# There will be files changed during the run that are irrelevant.
2371
# We need to wait for the user to change the files.
2372
# So set the GENERATED files as up-to-date
2373
rdb_for_some( [keys %current_primaries], \&rdb_update_gen_files );
2375
$failure_msg =~ s/\s*$//; #Remove trailing space
2376
warn "$My_name: $failure_msg\n",
2377
" ==> You will need to change a source file before I do another run <==\n";
2379
elsif ( ($view_file ne '') && (-e $view_file) && $updated && $viewer_running ) {
2380
# A viewer is running. Explicitly get it to update screen if we have to do it:
2381
rdb_one_rule( 'update_view', \&rdb_run1 );
2383
elsif ( ($view_file ne '') && (-e $view_file) && !$viewer_running ) {
2386
if ($new_viewer_always) {
2387
warn "$My_name: starting previewer for '$view_file'\n",
2391
warn "$My_name: I have not found a previewer that ",
2392
"is already running. \n",
2393
" So I will start it for '$view_file'\n",
2398
rdb_one_rule( 'view', sub { $retcode = &rdb_run1;} );
2399
# PREVIOUS local $retcode = rdb_makeB ( 'view' );
2400
if ( $retcode != 0 ) {
2402
warn "$My_name: I could not run previewer\n";
2405
&exit_msg1( "I could not run previewer", $retcode);
2409
$viewer_running = 1;
2410
$$Pneed_to_get_viewer_process = 1;
2411
} # end analyze result of trying to run viewer
2412
} # end start viewer
2413
rdb_show_rule_errors();
2414
if ( $first_time || $updated || $failure ) {
2415
print "\n=== Watching for updated files. Use ctrl/C to stop ...\n";
2417
$waiting = 1; if ($diagnostics) { warn "WAITING\n"; }
2422
if ($have_break) { last WAIT; }
2423
if ( rdb_new_changes(@targets) ) {
2425
warn "$My_name: Need to remake files.\n";
2426
&rdb_diagnose_changes( ' ' );
2430
# Does this do this job????
2431
local $new_files = 0;
2432
rdb_for_some( [keys %current_primaries], sub{ $new_files += &rdb_find_new_filesB } );
2433
if ($new_files > 0) {
2434
warn "$My_name: New file(s) found.\n";
2437
if ($have_break) { last WAIT; }
2441
print "$My_name: User typed ctrl/C or ctrl/break. I'll stop.\n";
2444
$waiting = 0; if ($diagnostics) { warn "NOT WAITING\n"; }
2445
} #end infinite_loop CHANGE:
2446
} #END sub make_preview_continuousB
2448
#************************************************************
2450
sub process_rc_file {
2451
# Usage process_rc_file( filename )
2452
# Run rc_file whose name is given in first argument
2453
# Exit with code 11 if file could not be read.
2454
# (In general this is not QUITE the right error)
2455
# Exit with code 13 if there is a syntax error or other problem.
2456
# ???Should I leave the exiting to the caller (perhaps as an option)?
2457
# But I can always catch it with an eval if necessary.
2458
# That confuses ctrl/C and ctrl/break handling.
2459
my $rc_file = $_[0];
2460
warn "$My_name: Executing PERL code in file '$rc_file'...\n"
2463
# The return value from the do is not useful, since it is the value of
2464
# the last expression evaluated, which could be anything.
2465
# The correct test of errors is on the values of $! and $@.
2467
# This is not entirely correct. On gluon2:
2468
# rc_file does open of file, and $! has error, apparently innocuous
2469
# See ~/proposal/06/latexmkrc-effect
2473
# Get both numeric error and its string, by forcing numeric and
2476
my $err_string = "$!";
2477
warn "$My_name: Initialization file '$rc_file' could not be read,\n",
2478
" or it gave some other problem. Error code \$! = $err_no.\n",
2479
" Error string = '$err_string'\n";
2485
# Indent the error message to make it easier to locate
2486
my $indented = prefix( $@, " " );
2488
warn "$My_name: Initialization file '$rc_file' gave an error:\n",
2493
die "$My_name: Stopping because of problem with rc file\n";
2495
} #END process_rc_file
2497
#************************************************************
2499
sub execute_code_string {
2500
# Usage execute_code_string( string_of_code )
2501
# Run the PERL code contained in first argument
2502
# Exit with code 13 if there is a syntax error or other problem.
2503
# ???Should I leave the exiting to the caller (perhaps as an option)?
2504
# But I can always catch it with an eval if necessary.
2505
# That confuses ctrl/C and ctrl/break handling.
2507
warn "$My_name: Executing initialization code specified by -e:\n",
2511
# The return value from the eval is not useful, since it is the value of
2512
# the last expression evaluated, which could be anything.
2513
# The correct test of errors is on the values of $! and $@.
2519
$message =~ s/\s*$//;
2521
"Stopping because executing following code from command line\n",
2526
} #END execute_code_string
2528
#************************************************************
2531
# Usage: cleanup1( exts_without_period, ... )
2532
foreach (@_) { unlink("$root_filename.$_"); }
2535
#************************************************************
2536
#************************************************************
2537
#************************************************************
2539
# Error handling routines, warning routines, help
2541
#************************************************************
2544
# Call: die_trace( message );
2545
&traceback; # argument(s) passed unchanged
2549
#************************************************************
2553
# or traceback( message, )
2555
if ($msg) { warn "$msg\n"; }
2556
warn "Traceback:\n";
2557
my $i=0; # Start with immediate caller
2558
while ( my ($pack, $file, $line, $func) = caller($i++) ) {
2559
if ($func eq 'die_trace') { next; }
2560
warn " $func called from line $line\n";
2385
2564
#************************************************************
2515
2720
" To print a ps file, I use \"$lpr\"\n",
2516
2721
" To print a dvi file, I use \"$lpr_dvi\"\n",
2517
2722
" To print a pdf file, I use \"$lpr_pdf\"\n",
2518
" To find running processes, I use \"$pscmd\", ",
2519
"and the process number is at position $pid_position\n";
2723
" To find running processes, I use \"$pscmd\", \n",
2724
" and the process number is at position $pid_position\n";
2520
2725
warn "Notes:\n",
2521
2726
" Command starting with \"start\" is run detached\n",
2522
2727
" Command that is just \"start\" without any other command, is\n",
2523
2728
" used under MS-Windows to run the command the operating system\n",
2524
2729
" has associated with the relevant file.\n",
2525
2730
" Command starting with \"NONE\" is not used at all\n";
2731
} #END print_commands
2733
#************************************************************
2735
sub view_file_via_temporary {
2736
return $always_view_file_via_temporary
2737
|| ($pvc_view_file_via_temporary && $preview_continuous_mode);
2738
} #END view_file_via_temporary
2528
2740
#************************************************************
2529
2741
#### Tex-related utilities
2532
# check for citation which bibtex didnt find.
2534
sub check_for_bibtex_errors
2535
# return 0: OK, 1: bibtex error, 2: could not open .blg file.
2537
my $log_name = "$root_filename.blg";
2539
my $retcode = open( $log_file, "<$log_name" );
2540
if ( $retcode == 0) {
2541
if ( !$force_mode ) {
2543
$failure_msg = "Could not open bibtex log file for error check";
2545
warn "Could not open bibtex log file for error check\n";
2551
# if (/Warning--/) { return 1; }
2552
if (/error message/)
2562
#************************************************************
2563
# check for bibtex warnings
2565
sub check_for_bibtex_warnings
2566
# return 0: OK, 1: bibtex warnings, 2: could not open .blg file.
2568
my $log_name = "$root_filename.blg";
2570
my $retcode = open( $log_file, "<$log_name" );
2571
if ( $retcode == 0 )
2574
$failure_msg = "Could not open bibtex log file for warning check";
2575
warn "Latexmk: $failure_msg\n";
2578
my $have_warning = 0;
2581
if (/Warning--/) { print "Bibtex warning: $_"; $have_warning = 1}
2582
if (/error message/) { print "Bibtex error: $_"; $have_warning = 1}
2585
return $have_warning;
2588
#************************************************************
2589
# - looks recursively for included & inputted and psfig'd files and puts
2590
# them into @includes.
2591
# - note only primitive comment removal: cannot deal with escaped %s, but then,
2592
# when would they occur in any line important to latexmk??
2594
sub scan_for_includes
2596
my $texfile_name = $_[0];
2597
warn "-----Scanning [$texfile_name] for input files etc ... -----\n";
2598
&scan_for_includes_($texfile_name);
2599
## put root tex file into list of includes.
2600
push @includes, $texfile_name;
2603
sub scan_for_includes_
2605
local(*FILE,$orig_filename);
2607
local($ignoremode,$line);
2610
if (!open(FILE,$_[0]))
2612
warn "Latexmk: could not open input file [$_[0]]\n";
2620
if ( /^\s*(%#.*)\s*$/ )
2623
##warn "======Metacommand \"$_\"\n";
2624
if ( /%#{}end.raw/ || /%#{latexmk}end.ignore/ )
2627
warn " Ignore mode off, at line $line in file $_[0].\n";
2629
elsif ( $ignoremode == 1 )
2631
# In ignore mode only end.raw, etc metacommands are recognized.
2634
elsif ( /%#{}raw/ || /%#{}begin.raw/ ||
2635
/%#{latexmk}ignore/ || /%#{latexmk}begin.ignore/ )
2638
warn " Ignore mode on, at line $line in file $_[0].\n";
2640
elsif ( /%#{latexmk}include.file[\040\011]+([^\040\011\n]*)/
2641
|| /%#{latexmk}input.file[\040\011]+([^\040\011\n]*)/ )
2644
warn " Adding input file \"$1\" at line $line in file $_[0].\n";
2648
# Unrecognized metacommands are, by specification, to be ignored.
2649
warn "Unrec. \"$_\"\n";
2653
if ( $ignoremode == 1 )
2655
##warn "Skipping a line:\n $_";
2659
($_) = split('%',$_); # primitive comment removal
2661
if (/\\def/ || /\\newcommand/ || /\\renewcommand/ || /\\providecommand/)
2663
##JCC Ignore definitions:
2664
warn "Ignoring definition:\n $_";
2666
elsif (/\\include[{\s]+([^\001\040\011}]*)[\s}]/)
2668
$full_filename = $1;
2669
$orig_filename = $full_filename;
2670
$full_filename = &find_file_ext($full_filename, 'tex', \@TEXINPUTS);
2673
push @includes, $full_filename;
2674
if ( -e $full_filename )
2676
warn " Found input file [$full_filename]\n";
2677
&scan_for_includes_($full_filename);
2681
if ( $orig_filename =~ /^\// )
2683
warn "Latexmk: In \\include, ",
2684
"could not find file [$orig_filename]\n";
2688
warn "Latexmk: In \\include, ",
2689
"could not find file [$orig_filename] in path [@TEXINPUTS]\n";
2690
warn " assuming in current directory ($full_filename)\n";
2696
if ( ! $force_include_mode )
2698
if ( $orig_filename =~ /^\// )
2700
die "Latexmk: In \\include, ",
2701
"could not find file [$orig_filename]\n";
2705
die "Latexmk: In \\include, ",
2706
"could not find file [$orig_filename] in path [@TEXINPUTS]\n";
2711
elsif (/\\input[{\s]+([^\001\040\011}]*)[\s}]/)
2713
$full_filename = $1;
2714
$orig_filename = $full_filename;
2715
$full_filename = &find_file_ext($full_filename, 'tex', \@TEXINPUTS);
2718
push @includes, $full_filename;
2719
# warn "added '$full_filename'\n";
2720
if ( -e $full_filename )
2722
warn " Found input for file [$full_filename]\n";
2723
&scan_for_includes_($full_filename);
2727
if ( $orig_filename =~ /^\// )
2729
warn "Latexmk: In \\input, could not find file [$orig_filename]\n";
2733
warn "Latexmk: In \\input, ",
2734
"could not find file [$orig_filename] in path [@TEXINPUTS]\n";
2735
warn " assuming in current directory ($full_filename)\n";
2741
if ( ! $force_include_mode )
2743
if ( $orig_filename =~ /^\// )
2745
die "Latexmk: In \\input, could not find file [$orig_filename]\n";
2749
die "Latexmk: In \\input, ",
2750
"could not find file [$orig_filename] in path [@TEXINPUTS]\n";
2755
elsif (/\\blackandwhite{([^\001\040\011}]*)}/ || /\\colorslides{([^\001}]*)}/)
2757
############ $slide_mode = 1;
2758
$full_filename = &find_file_ext($1, 'tex', \@TEXINPUTS);
2761
push @includes, $full_filename;
2762
if ( -e $full_filename )
2764
warn " Found slide input for file [$full_filename]\n";
2765
&scan_for_includes_($full_filename);
2769
elsif (/\\psfig{file=([^,}]+)/ || /\\psfig{figure=([^,}]+)/)
2771
$orig_filename = $1;
2772
$full_filename = &find_file($1, \@psfigsearchpath);
2775
push @includes, $full_filename;
2776
if ( -e $full_filename )
2778
warn " Found psfig for file [$full_filename]\n";
2782
elsif ( /\\epsfbox{([^}]+)}/ || /\\epsfbox\[[^\]]*\]{([^}]+)}/ ||
2783
/\\epsffile{([^}]+)}/ || /\\epsffile\[[^\]]*\]{([^}]+)}/ ||
2784
/\\epsfig{file=([^,}]+)/ || /\\epsfig{figure=([^,}]+)/ )
2786
$orig_filename = $1;
2787
$full_filename = &find_file($1, \@psfigsearchpath);
2790
push @includes, $full_filename;
2791
if ( -e $full_filename )
2793
warn " Found epsf for file [$full_filename]\n";
2798
/\\includegraphics{([^}]+)}/ || /\\includegraphics\[[^\]]*\]{([^}]+)}/
2801
$orig_filename = $1;
2802
$full_filename = &find_file_ext($1,'eps', \@psfigsearchpath);
2805
push @includes, $full_filename;
2806
if ( -e $full_filename )
2808
warn " Found epsf for file [$full_filename]\n";
2813
warn "Latexmk: For \\includegraphics, ",
2814
"could not find file [$orig_filename]\n",
2815
" in path [@psfigsearchpath]\n";
2816
if ( ! $force_include_mode ) {die "\n";}
2819
elsif (/\\documentstyle[^\000]+landscape/)
2821
warn " Detected landscape mode\n";
2822
$landscape_mode = 1;
2824
elsif (/\\bibliography{([^}]+)}/)
2826
@bib_files = split /,/, $1;
2827
&find_file_list1( \@bib_files, \@bib_files, '.bib', \@BIBINPUTS );
2828
warn " Found bibliography files [@bib_files]\n" unless $silent;
2831
elsif (/\\psfigsearchpath{([^}]+)}/)
2833
@psfigsearchpath = &split_search_path(':', '', $1);
2835
elsif (/\\graphicspath{([^}]+)}/)
2837
@psfigsearchpath = &split_search_path(':', '', $1);
2839
elsif (/\\makeindex/)
2842
warn " Detected index mode\n";
2744
sub check_bibtex_log {
2745
# Check for bibtex warnings:
2746
# Usage: check_bibtex_log( base_of_bibtex_run )
2747
# return 0: OK, 1: bibtex warnings, 2: bibtex errors,
2748
# 3: could not open .blg file.
2751
my $log_name = "$base.blg";
2752
my $log_file = new FileHandle;
2753
open( $log_file, "<$log_name" )
2755
my $have_warning = 0;
2757
while (<$log_file>) {
2759
#print "Bibtex warning: $_";
2762
if (/error message/) {
2763
#print "Bibtex error: $_";
2768
if ($have_error) {return 2;}
2769
if ($have_warning) {return 1;}
2771
} #END check_bibtex_log
2847
2773
#**************************************************
2850
# Scan log file for: include files, bibtex mode,
2775
sub clean_file_name{
2776
# Convert filename found in log file to true filename.
2777
# Used normally only by parse_logB, below
2778
# 1. For names of form
2779
# `"string".ext', which arises e.g., from \jobname.bbl:
2780
# when the base filename contains spaces, \jobname has quotes.
2781
# and from \includegraphics with basename specified.
2782
# 2. Or "string.ext" from \includegraphcs with basename and ext specified.
2783
my $filename = $_[0];
2784
$filename =~ s/^\"([^\"]*)\"(.*)$/$1$2/;
2787
# ------------------------------
2790
# Scan log file for: dependent files
2851
2791
# reference_changed, bad_reference, bad_citation
2852
# In bibtex mode, scan aux file for bib files
2853
2792
# Return value: 1 if success, 0 if no log file.
2854
2793
# Set global variables:
2855
# @includes to list of included files that exist or that appear to be
2856
# genuine files (as opposed to incorrectly parsed names).
2857
# %includes_missing to list of files that latex appeared to search for
2858
# and didn't find, i.e., from error messages
2859
# @aux_files to list of .aux files.
2860
# Leave these unchanged if there is no log file.
2794
# %dependents: maps definite dependents to code:
2795
# 0 = from missing-file line
2796
# May have no extension
2797
# May be missing path
2798
# 1 = from 'File: ... Graphic file (type ...)' line
2799
# no path. Should exist, but may need a search, by kpsewhich.
2800
# 2 = from regular '(...' coding for input file,
2801
# Has NO path, which it would do if LaTeX file
2802
# Highly likely to be mis-parsed line
2803
# 3 = ditto, but has a path character ('/').
2804
# Should be LaTeX file that exists.
2805
# If it doesn't exist, we have probably a mis-parsed line.
2806
# There's no need to do a search.
2807
# 4 = definitive, which in this subroutine is only done:
2808
# for default dependents,
2809
# and for files that exist and are source of conversion
2810
# reported by epstopdf et al.
2811
# 5 = Had a missing file line. Now the file exists.
2812
# 6 = File was written during run. (Overrides 5)
2813
# 7 = File was created during run to be read in. (Overrides 5 and 6)
2814
# (e.g., by epstopdf)
2815
# Treat the following specially, since they have special rules
2816
# @bbl_files to list of .bbl files.
2817
# %idx_files to map from .idx files to .ind files.
2818
# %generated_log: keys give set of files written by (pdf)latex (e.g., aux, idx)
2819
# as determined by \openout = ... lines in log file.
2861
2821
# $reference_changed, $bad_reference, $bad_citation
2864
my $log_name = "$root_filename.log";
2866
if ( ! open( $log_file, "<$log_name" ) )
2822
# Trivial or default values if log file does not exist/cannot be opened
2824
# Give a quick way of looking up custom-dependency extensions
2825
my %cusdep_from = ();
2827
foreach ( @cus_dep_list ) {
2828
my ($fromext, $toext) = split;
2829
$cusdep_from{$fromext} = $cusdep_from{".$fromext"} = $_;
2830
$cusdep_to{$toext} = $cusdep_to{".$toext"} = $_;
2870
my $line_number = 0;
2871
my $graphic_line = 0;
2873
my @ignored_input_files = ();
2875
my @include_list = ($texfile_name);
2876
my @include_graphics_list = ();
2877
my %includes_from_errors = ();
2879
%includes_missing = ();
2832
# print "==== Cusdep from-exts:"; foreach (keys %cusdep_from) {print " '$_'";} print "\n";
2833
# print "==== Cusdep to-exts:"; foreach (keys %cusdep_to) {print " '$_'";} print "\n";
2837
foreach (@default_includes) { $dependents{$_} = 4; }
2839
%idx_files = (); # Maps idx_file to (ind_file, base)
2840
%generated_log = ();
2842
# $primary_out is actual output file (dvi or pdf)
2843
# It is initialized before the call to this routine, to ensure
2844
# a sensible default in case of misparsing
2882
2846
$reference_changed = 0;
2883
2847
$bad_reference = 0;
2884
2848
$bad_citation = 0;
2886
## ?? New. We'll determine these modes from parsing the file
2850
my $log_name = "$root_filename.log";
2851
my $log_file = new FileHandle;
2852
if ( ! open( $log_file, "<$log_name" ) ) {
2855
if ($log_file_binary) { binmode $log_file; }
2856
# Collect lines of log file
2858
while(<$log_file>) {
2859
# Could use chomp here, but that fails if there is a mismatch
2860
# between the end-of-line sequence used by latex and that
2861
# used by perl. (Notably a problem with MSWin latex and
2864
# Handle wrapped lines:
2865
# They are lines brutally broken at exactly $log_wrap chars
2866
# excluding line-end. The TeX program adds an EXTRA
2867
# end-of-line character whenever a line gets to $log_wrap
2868
# characters. So we recover the unwrapped line(s) simply
2869
# by deleting the end-of-line following a line of exactly
2870
# $log_wrap characters.
2871
my $len = length($_);
2872
while ( ($len == $log_wrap) && !eof($log_file) ) {
2873
my $extra = <$log_file>;
2874
$extra =~ s/[\n\r]*$//;
2875
$len = length($extra);
2882
push @lines, ""; # Blank line to terminate. So multiline blocks
2883
# are always terminated by non-block line, rather than eof.
2886
# For parsing multiple line blocks of info
2887
my $current_pkg = ""; # non-empty string for package name, if in
2888
# middle of parsing multi-line block of form:
2892
my $block_type = ""; # Specify information in such a block
2893
my $delegated_source = ""; # If it is a file conversion, specify source
2894
my $delegated_output = ""; # and output file. (Don't put in
2895
# data structure until block is ended.)
2896
my %new_conversions = ();
2891
while(<$log_file>) {
2894
if ( $line_number == 1 ){
2895
if ( /^This is / ) {
2899
die "Error on first line of \"$log_name\". This is not a TeX log file.\n$_";
2902
# Handle wrapped lines:
2903
# They are lines brutally broken at exactly $log_wrap chars
2904
# excluding line-end.
2905
my $len = length($_);
2906
while ($len == $log_wrap)
2908
my $extra = <$log_file>;
2911
$len = length($extra);
2914
# Check for changed references, bad references and bad citations:
2915
if (/Rerun to get/) {
2916
warn "\n=== References changed.\n";
2917
$reference_changed = 1;
2919
if (/LaTeX Warning: (Reference[^\001]*undefined)./) {
2923
if (/LaTeX Warning: (Citation[^\001]*undefined)./) {
2927
if ( /^Document Class: / ) {
2931
if ( /^Output written on / ) {
2935
if ( /^Underfull / ) {
2936
# Latex error/warning
2939
if ( /^Overfull / ) {
2940
# Latex error/warning
2943
if ( /^\(Font\)/ ) {
2947
if ( /^Package: / ) {
2948
# Package sign-on line
2951
if ( /^Document Class: / ) {
2952
# Class sign-on line
2955
if ( /^Writing index file / ) {
2957
warn "Latexmk: Index file written, so turn on index_mode\n"
2961
if ( /^No file .*?\.bbl./ ) {
2962
warn "Non-existent bbl file, so turn on bibtex_mode\n $_"
2963
unless $bibtex_mode == 1;
2967
if ( /^File: ([^\s\[]*) Graphic file \(type / ) {
2968
# First line of message from includegraphics/x
2969
push @include_graphics_list, $1;
2973
# Package sign-on line. Includegraphics/x also produces a line
2974
# with this signature, but I've already handled it.
2977
if (/^\! LaTeX Error: File \`([^\']*)\' not found\./ ) {
2978
$includes_missing{$1} = [3];
2981
if (/^\! LaTeX Error: / ) {
2898
while( $line <= $#lines ) {
2902
if ( /^This is / ) {
2906
warn "$My_name: Error on first line of '$log_name'. ".
2907
"This is apparently not a TeX log file.\n";
2909
$failure_msg = "Log file '$log_name' appears to have wrong format.";
2913
if ( $block_type ) {
2914
# In middle of parsing block
2915
if ( /^\($current_pkg\)/ ) {
2917
if ( ($block_type eq 'conversion')
2918
&& /^\($current_pkg\)\s+Output file: <([^>]+)>/ )
2920
$delegated_output = $1;
2925
if ($block_type eq 'conversion') {
2926
$new_conversions{$delegated_source} = $delegated_output;
2928
$current_pkg = $block_type
2929
= $delegated_source = $delegated_output = "";
2930
# Then process current line
2932
# Check for changed references, bad references and bad citations:
2933
if (/Rerun to get/) {
2934
warn "$My_name: References changed.\n";
2935
$reference_changed = 1;
2937
if (/LaTeX Warning: (Reference[^\001]*undefined)./) {
2938
warn "$My_name: $1 \n";
2941
if (/LaTeX Warning: (Citation[^\001]*undefined)./) {
2942
warn "$My_name: $1 \n";
2945
if ( /^Document Class: / ) {
2946
# Class sign-on line
2949
if ( /^\(Font\)/ ) {
2953
if (/^No pages of output\./) {
2955
warn "$My_name: Log file says no output from latex\n";
2958
if ( /^Output written on\s+(.*)\s+\(\d+\s+page/ ) {
2960
warn "$My_name: Log file says output to '$1'\n"
2966
|| /^or enter new name\. \(Default extension: .*\)/
2967
|| /^\*\*\* \(cannot \\read from terminal in nonstop modes\)/
2969
# Latex error/warning, etc.
2972
if ( /^\\openout\d+\s*=\s*\`([^\']+)\'\.$/ ) {
2973
$generated_log{$1} = 1;
2976
# Test for conversion produced by package:
2977
if ( /^Package (\S+) Info: Source file: <([^>]+)>/ ) {
2978
# Info. produced by epstopdf (and possibly others)
2979
# about file conversion
2981
$delegated_source = $2;
2982
$block_type = 'conversion';
2985
# Test for writing of index file. The precise format of the message
2986
# depends on which package (makeidx.sty , multind.sty or index.sty) and
2987
# which version writes the message.
2988
if ( /Writing index file (.*)$/ ) {
2990
if ( /^Writing index file (.*)$/ ) {
2991
# From makeidx.sty or multind.sty
2994
elsif ( /^index\.sty> Writing index file (.*)$/ ) {
2995
# From old versions of index.sty
2998
elsif ( /^Package \S* Info: Writing index file (.*) on input line/ ) {
2999
# From new versions of index.sty
3003
warn "$My_name: Message indicates index file was written\n",
3004
" ==> but I do not know how to understand it: <==\n",
3008
# Typically, there is trailing space, not part of filename:
3009
$idx_file =~ s/\s*$//;
3010
$idx_file = clean_file_name($idx_file);
3011
my ($idx_base, $idx_path, $idx_ext) = fileparseA( $idx_file );
3012
$idx_base = $idx_path.$idx_base;
3013
$idx_file = $idx_base.$idx_ext;
3014
if ( $idx_ext eq '.idx' ) {
3015
warn "$My_name: Index file '$idx_file' was written\n"
3017
$idx_files{$idx_file} = [ "$idx_base.ind", $idx_base ];
3019
elsif ( exists $cusdep_from{$idx_ext} ) {
3021
warn "$My_name: Index file '$idx_file' was written\n";
3022
warn " Cusdep '$cusdep_from{$idx_ext}' should be used\n";
3024
# No action needed here
3027
warn "$My_name: Index file '$idx_file' written\n",
3028
" ==> but it has an extension I do not know how to handle <==\n";
3033
if ( /^No file (.*?\.bbl)./ ) {
3035
my $bbl_file = clean_file_name($1);
3036
warn "$My_name: Non-existent bbl file '$bbl_file'\n $_\n";
3037
$dependents{$bbl_file} = 0;
3038
push @bbl_files, $bbl_file;
3041
foreach my $pattern (@file_not_found) {
3043
my $file = clean_file_name($1);
3044
warn "$My_name: Missing input file: '$file' from line\n '$_'\n"
3046
$dependents{$file} = 0;
3050
if ( /^File: ([^\s\[]*) Graphic file \(type / ) {
3051
# First line of message from includegraphics/x
3052
$dependents{$1} = 1;
3055
# Now test for generic lines to ignore, only after special cases!
3057
# Package sign-on line. Includegraphics/x also produces a line
3058
# with this signature, but I've already handled it.
3061
if ( /^Package: / ) {
3062
# Package sign-on line
3065
if (/^\! LaTeX Error: / ) {
2984
3068
INCLUDE_CANDIDATE:
2985
while ( /\((.*$)/ ) {
2987
# '(', then filename, then terminator.
2988
# Terminators: obvious candidates: ')': end of reading file
2989
# '(': beginning of next file
2990
# ' ': space is an obvious separator
2991
# ' [': start of page: latex
2992
# and pdflatex put a
2993
# space before the '['
2994
# '[': start of config file
2995
# in pdflatex, after
2997
# '{': some kind of grouping
2999
# All or almost all special characters are allowed in
3000
# filenames under some OS, notably UNIX. Luckily most cases
3001
# are rare, if only because the special characters need
3002
# escaping. BUT 2 important cases are characters that are
3003
# natural punctuation
3004
# Under MSWin, spaces are common (e.g., "C:\Program Files")
3005
# Under VAX/VMS, '[' delimits directory names. This is
3006
# tricky to handle. But I think few users use this OS
3009
# Solution: use ' [', but not '[' as first try at delimiter.
3010
# Then if candidate filename is of form 'name1[name2]', then
3011
# try splitting it. If 'name1' and/or 'name2' exists, put
3012
# it/them in list, else just put 'name1[name2]' in list.
3013
# So form of filename is now:
3015
# then any number of characters that are NOT ')', '(', or '{'
3016
# (these form the filename);
3017
# then ' [', or ' (', or ')', or end-of-string.
3018
# That fails for pdflatex
3020
# '(' => start of reading of file, followed by filename
3021
# ')' => end of reading of file
3022
# '[' => start of page (normally preceeded by space)
3024
# filename (on VAX/VMS) may include '[' and ']' (directory
3026
# filenames (on MS-Win) commonly include space.
3028
# First step: replace $_ by whole of line after the '('
3029
# Thus $_ is putative filename followed by other stuff.
3031
## warn "==='$_'===\n";
3032
if ( /^([^\(^\)^\{]*?)\s\[/ ) {
3033
# Use *? in condition: to pick up first ' [' as terminator
3034
# 'file [' should give good filename.
3036
elsif ( /^([^\(^\)^\{]*)\s(?=\()/ ) {
3037
# Terminator is ' (', but '(' isn't in matched string,
3038
# so we keep the '(' ready for the next match
3040
elsif ( /^([^\(^\)^\{]*)(\))/ ) {
3044
#Terminator is end-of-string
3046
## warn " ---'$1'---'$''---\n";
3047
$_ = $'; # Put $_ equal to the unmatched tail of string '
3048
my $include_candidate = $1;
3049
$include_candidate =~ s/\s*$//; # Remove trailing space.
3050
if ( "$include_candidate" eq "[]" ) {
3051
# Part of overfull hbox message
3052
next INCLUDE_CANDIDATE;
3054
# Put on list of new include files
3055
my @new_includes = ($include_candidate);
3056
if ( $include_candidate =~ /^(.+)\[([^\]]+)\]$/ ) {
3057
# Construct of form 'file1[file2]', as produced by pdflatex
3059
# If the first component exists, we probably have the
3061
@new_includes = ($1, $2);
3064
# We have something else.
3065
# So leave the original candidate in the list
3069
while ( /\((.*$)/ ) {
3071
# '(', then filename, then terminator.
3072
# Terminators: obvious candidates: ')': end of reading file
3073
# '(': beginning of next file
3074
# ' ': space is an obvious separator
3075
# ' [': start of page: latex
3076
# and pdflatex put a
3077
# space before the '['
3078
# '[': start of config file
3079
# in pdflatex, after
3081
# '{': some kind of grouping
3083
# All or almost all special characters are allowed in
3084
# filenames under some OS, notably UNIX. Luckily most cases
3085
# are rare, if only because the special characters need
3086
# escaping. BUT 2 important cases are characters that are
3087
# natural punctuation
3088
# Under MSWin, spaces are common (e.g., "C:\Program Files")
3089
# Under VAX/VMS, '[' delimits directory names. This is
3090
# tricky to handle. But I think few users use this OS
3093
# Solution: use ' [', but not '[' as first try at delimiter.
3094
# Then if candidate filename is of form 'name1[name2]', then
3095
# try splitting it. If 'name1' and/or 'name2' exists, put
3096
# it/them in list, else just put 'name1[name2]' in list.
3097
# So form of filename is now:
3099
# then any number of characters that are NOT ')', '(', or '{'
3100
# (these form the filename);
3101
# then ' [', or ' (', or ')', or end-of-string.
3102
# That fails for pdflatex
3104
# '(' => start of reading of file, followed by filename
3105
# ')' => end of reading of file
3106
# '[' => start of page (normally preceeded by space)
3108
# filename (on VAX/VMS) may include '[' and ']' (directory
3110
# filenames (on MS-Win) commonly include space.
3112
# First step: replace $_ by whole of line after the '('
3113
# Thus $_ is putative filename followed by other stuff.
3115
if ( /^\"([^\(^\)^\"]+)\"/ ) {
3116
# Quoted file name, as from MikTeX
3118
elsif ( /^([^\(^\)]*?)\s\[/ ) {
3119
# Terminator: space then '['
3120
# Use *? in condition: to pick up first ' [' as terminator
3121
# 'file [' should give good filename.
3123
elsif ( /^([^\(^\)]*)\s(?=\()/ ) {
3124
# Terminator is ' (', but '(' isn't in matched string,
3125
# so we keep the '(' ready for the next match
3127
elsif ( /^([^\(^\)]*)(\))/ ) {
3130
elsif ( /^([^\(^\)]*?)\s*\{/ ) {
3131
# Terminator: arbitrary space then '{'
3132
# Use *? in condition: to pick up first ' [' as terminator
3133
# 'file [' should give good filename.
3136
#Terminator is end-of-string
3138
$_ = $'; # Put $_ equal to the unmatched tail of string '
3139
my $include_candidate = $1;
3140
$include_candidate =~ s/\s*$//; # Remove trailing space.
3141
if ( $include_candidate eq "[]" ) {
3142
# Part of overfull hbox message
3143
next INCLUDE_CANDIDATE;
3145
if ( $include_candidate =~ /^\\/ ) {
3146
# Part of font message
3147
next INCLUDE_CANDIDATE;
3149
# Remove quotes around filename, as for MikTeX. I've already
3150
# treated this as a special case. For safety check here:
3151
$include_candidate =~ s/^\"(.*)\"$/$1/;
3153
# Make list of new include files; sometimes more than one.
3154
my @new_includes = ($include_candidate);
3155
if ( $include_candidate =~ /^(.+)\[([^\]]+)\]$/ ) {
3156
# Construct of form 'file1[file2]', as produced by pdflatex
3158
# If the first component exists, we probably have the
3160
@new_includes = ($1, $2);
3163
# We have something else.
3164
# So leave the original candidate in the list
3069
foreach my $include_name (@new_includes) {
3070
my ($base, $path, $ext) = fileparse ($include_name, '\.[^\.]*');
3071
if ( $ext eq '.bbl' ) {
3072
warn "Input bbl file \"$include_name\", so turn on bibtex_mode\n"
3073
unless ($bibtex_mode == 1) || $silent;
3075
push @bbl_files, $include_name;
3076
} elsif ( $ext eq ".aux" ) {
3077
push @aux_files, $include_name;
3078
push @ignored_input_files, $include_name;
3079
} elsif ( $generated_exts{$ext} ) {
3080
#warn "Ignoring '$include_name'\n";
3081
push @ignored_input_files, $include_name;
3083
push @include_list, $include_name;
3086
} # INCLUDE_CANDIDATE
3089
@aux_files = &uniq( sort(@aux_files) );
3090
@ignored_input_files = &uniq( sort(@ignored_input_files) );
3095
push @include_list, @bib_files;
3097
@include_list = &uniq(sort @include_list);
3098
@include_graphics_list = &uniq(sort @include_graphics_list);
3099
foreach (@include_list) {
3103
$includes_missing{$_} = [1];
3106
foreach (@include_graphics_list) {
3110
# I have to work harder finding the file
3111
$includes_missing{$_} = [2];
3118
foreach (sort keys %includes_missing) {
3120
my $code = ${$includes_missing{$_}}[0];
3121
if ($code == 1) {$non_exist ++;}
3122
if ($code == 2) {$not_found ++;}
3126
@includes = @existent;
3130
my $inc = $#include_list + 1;
3131
my $exist = $#existent + 1;
3132
my $non_exist = $#includes_missing + 1;
3133
my $bbl = $#bbl_files + 1;
3134
print "$inc included files detected, of which ";
3135
print "$exist exist, and $non_exist do not exist.\n";
3136
print "Input files that exist:\n";
3137
foreach (@existent) { print " $_\n";}
3139
if ( $#bbl_files >= 0 ) {
3140
print "Input bbl files:\n";
3141
foreach (@bbl_files) { print " $_\n"; }
3143
if ( $#ignored_input_files >= 0 ) {
3144
print "Other input files that are generated via LaTeX run:\n";
3145
foreach (@ignored_input_files) { print " $_\n"; }
3147
if ( $missing > 0 ) {
3148
print "Apparent input files that appear NOT to exist:\n";
3149
print " Some correspond to misunderstood lines in the .log file\n";
3150
print " Some are files that latexmk failed to find\n";
3151
print " Some really don't exist\n";
3152
foreach (sort keys %includes_missing) { print " $_\n"; }
3158
#************************************************************
3161
# Parse aux_file for bib files.
3162
# Return 3 with @bib_files set if aux_file exists, but I couldn't find all the bib_files
3163
# Return 2 with @bib_files empty if aux_file exists, but there are no \bibdata
3164
# lines. In that case turn off bibtex mode, as side effect.
3165
# Return 1 with @bib_files set if aux_file exists
3166
# Return 0 and leave @bib_files unchanged in aux_file does not exist (or
3168
foreach my $include_name (@new_includes) {
3169
my ($base, $path, $ext) = fileparseB( $include_name );
3170
if ( ($path eq './') || ($path eq '.\\') ) {
3171
$include_name = $base.$ext;
3173
if ( $include_name !~ m'[/|\\]' ) {
3174
# Filename does not include a path character
3175
# High potential for misparsed line
3176
$dependents{$include_name} = 2;
3178
$dependents{$include_name} = 3;
3180
if ( $ext eq '.bbl' ) {
3181
warn "$My_name: Found input bbl file '$include_name'\n"
3183
push @bbl_files, $include_name;
3186
} # INCLUDE_CANDIDATE
3189
# Default includes are always definitive:
3190
foreach (@default_includes) { $dependents{$_} = 4; }
3192
###print "New parse: \n";
3193
###foreach (sort keys %dependents) { print " '$_': $dependents{$_}\n"; }
3199
foreach my $candidate (keys %dependents) {
3200
my $code = $dependents{$candidate};
3201
if ( -e $candidate ) {
3202
if ( exists $generated_log{$candidate} ){
3203
$dependents{$candidate} = 6;
3205
elsif ($code == 0) {
3206
$dependents{$candidate} = 5;
3209
$dependents{$candidate} = 4;
3212
elsif ($code == 1) {
3213
# Graphics file that is supposed to have been read.
3214
# Candidate name is as given in source file, not as path
3216
# We have already tested that file doesn't exist, as given.
3218
# If the file still is not found, assume non-existent;
3219
my @kpse_result = kpsewhich( $candidate );
3220
if ($#kpse_result > -1) {
3221
$dependents{$kpse_result[0]} = 4;
3222
delete $dependents{$candidate};
3226
push @not_found, $candidate;
3229
elsif ($code == 2) {
3230
# Candidate is from '(...' construct in log file, for input file
3231
# which should include pathname if valid input file.
3232
# Name does not have pathname-characteristic character (hence
3234
# We get here if candidate file does not exist with given name
3235
# Almost surely result of a misparsed line in log file.
3236
delete $dependents{$candidate};
3237
push @misparse, $candidate;
3239
elsif ($code == 3) {
3240
# Candidate is from '(...' construct in log file, for input file
3241
# which should include pathname if valid input file.
3242
# Name does have pathname-characteristic character (hence
3244
# But we get here only if candidate file does not exist with
3246
# Almost surely result of a misparsed line in log file.
3247
# But with lower probability than $code == 2
3248
delete $dependents{$candidate};
3249
push @misparse, $candidate;
3251
elsif ($code == 0) {
3252
my ($base, $path, $ext) = fileparseA($candidate);
3254
if ( ($ext eq '') && (-e "$path$base.tex") ) {
3255
# I don't think the old version was correct.
3256
# If the missing-file report was of a bare
3257
# extensionless file, and a corresponding .tex file
3258
# exists, then the missing file does not correspond
3259
# to the missing file, unless the .tex file was
3260
# created during the run.
3261
# OLD $dependents{"$path$base.tex"} = 4;
3262
# OLD delete $dependents{$candidate};
3264
$dependents{"$path$base.tex"} = 4;
3266
push @missing, $candidate;
3270
foreach my $delegated_source (keys %new_conversions) {
3271
my $delegated_output = $new_conversions{$delegated_source};
3272
my $rule = "Delegated $delegated_source, $delegated_output";
3273
# N.B. $delegated_source eq '' means the output file
3274
# was created without a named input file.
3275
foreach my $candidate ($delegated_source, $delegated_output) {
3276
if (! -e $candidate ) {
3277
# The file might be somewhere that can be found
3278
# in the search path of kpathsea:
3279
my @kpse_result = kpsewhich( $candidate,);
3280
if ($#kpse_result > -1) {
3281
$candidate = $kpse_result[0];
3285
if ( ( (-e $delegated_source) || ($delegated_source eq '') )
3286
&& (-e $delegated_output) )
3288
$conversions{$delegated_output} = $delegated_source;
3289
$dependents{$delegated_output} = 7;
3290
if ($delegated_source) {
3291
$dependents{$delegated_source} = 4;
3295
print "Logfile claimed conversion from '$delegated_source' ",
3296
"to '$delegated_output'. But:\n";
3297
if (! -e $delegated_output) {
3298
print " Output file does not exist\n";
3300
if ( ($delegated_source ne '') && (! -e $delegated_source) ) {
3301
print " Input file does not exist\n";
3307
if ( $diagnostics ) {
3308
@misparse = uniqs( @misparse );
3309
@missing = uniqs( @missing );
3310
@not_found = uniqs( @not_found );
3311
my @dependents = sort( keys %dependents );
3313
my $dependents = $#dependents + 1;
3314
my $misparse = $#misparse + 1;
3315
my $missing = $#missing + 1;
3316
my $not_found = $#not_found + 1;
3317
my $exist = $dependents - $not_found - $missing;
3318
my $bbl = $#bbl_files + 1;
3320
print "$dependents dependent files detected, of which ",
3321
"$exist exist, $not_found were not found,\n",
3322
" and $missing appear not to exist.\n";
3323
print "Dependents:\n";
3324
foreach (@dependents) {
3326
if ( $dependents{$_} == 6 ) { print " written by (pdf)latex";}
3328
if ( $dependents{$_} == 7 ) { print " converted by (pdf)latex";}
3331
if ($not_found > 0) {
3332
print "Not found:\n";
3333
foreach (@not_found) { print " $_\n"; }
3336
print "Not existent:\n";
3337
foreach (@missing) { print " $_\n"; }
3340
print "Input bbl files:\n";
3341
foreach (@bbl_files) { print " $_\n"; }
3344
if ( $misparse > 0 ) {
3345
print "$misparse\n";
3346
print "Apparent input files apparently from misunderstood lines in .log file:\n";
3347
foreach ( @misparse ) { print " $_\n"; }
3353
#************************************************************
3356
#Usage: parse_aux( $aux_file, \@new_bib_files, \@new_aux_files )
3357
# Parse aux_file (recursively) for bib files.
3358
# If can't open aux file, then
3359
# Return 0 and leave @new_bib_files empty
3360
# Else set @new_bib_files from information in the aux files
3362
# Return 1 if no problems
3363
# Return 2 with @new_bib_files empty if there are no \bibdata
3365
# Return 3 if I couldn't locate all the bib_files
3366
# Set @new_aux_files to aux files parsed
3368
my $aux_file = $_[0];
3369
local $Pbib_files = $_[1];
3370
local $Paux_files = $_[2];
3375
parse_aux1( $aux_file );
3376
if ($#{$Paux_files} < 0) {
3379
@$Pbib_files = uniqs( @$Pbib_files );
3381
if ( $#{$Pbib_files} == -1 ) {
3382
warn "$My_name: No .bib files listed in .aux file '$aux_file' \n",
3385
my $bibret = &find_file_list1( $Pbib_files, $Pbib_files,
3386
'.bib', \@BIBINPUTS );
3387
@$Pbib_files = uniqs( @$Pbib_files );
3389
warn "$My_name: Found bibliography file(s) [@$Pbib_files]\n"
3393
warn "$My_name: Failed to find one or more bibliography files ",
3394
"in [@$Pbib_files]\n";
3396
warn "==== Force_mode is on, so I will continue. ",
3397
"But there may be problems ===\n";
3401
#$failure_msg = 'Failed to find one or more bib files';
3402
#warn "$My_name: Failed to find one or more bib files\n";
3409
#************************************************************
3412
# Parse single aux file for bib files.
3413
# Usage: &parse_aux1( aux_file_name )
3414
# Append newly found bib_filenames in @$Pbib_files, already
3415
# initialized/in use.
3416
# Append aux_file_name to @$Paux_files if aux file opened
3417
# Recursively check \@input aux files
3418
# Return 1 if success in opening $aux_file_name and parsing it
3419
# Return 0 if fail to open it
3169
local($aux_file) = "$root_filename.aux";
3170
if (! open(aux_file) )
3421
my $aux_file = $_[0];
3422
my $aux_fh = new FileHandle;
3423
if (! open($aux_fh, $aux_file) ) {
3424
warn "$My_name: Couldn't find aux file '$aux_file'\n";
3427
push @$Paux_files, $aux_file;
3176
if ( /^\\bibdata\{(.*)\}/ )
3178
# \\bibdata{comma_separated_list_of_bib_file_names}
3179
# (Without the '.bib' extension)
3180
push( @bib_files, split /,/, $1 );
3184
if ( $#bib_files eq -1 ) {
3185
warn "No .bib files listed in .aux file, so turn off bibtex_mode\n";
3189
my $bibret = &find_file_list1( \@bib_files, \@bib_files, '.bib', \@BIBINPUTS );
3191
warn "Found bibliography files [@bib_files]\n" unless $silent;
3194
warn "Failed to find one or more bibliography files in [@bib_files]\n";
3196
warn "==== Force_mode is on, so I will continue. But there may be problems ===\n";
3200
$failure_msg = 'Failed to find one or more bib files';
3430
if ( /^\\bibdata\{(.*)\}/ ) {
3431
# \\bibdata{comma_separated_list_of_bib_file_names}
3432
# (Without the '.bib' extension)
3433
push( @$Pbib_files, split /,/, $1 );
3435
elsif ( /^\\\@input\{(.*)\}/ ) {
3436
# \\@input{next_aux_file_name}
3207
#************************************************************
3209
sub update_depend_file
3211
warn "Writing dependency file [$root_filename.dep]\n";
3212
$rc_file = ">$root_filename.dep";
3213
open(rc_file) || die "Latexmk: Unable to open dependency file [$rc_file] for updating\n";
3214
print rc_file '@includes = (\n';
3216
foreach my $name (@includes) {
3217
if (!$first) {print rc_file ",\n";}
3218
print rc_file "\'$name\'";
3221
print rc_file "\n)\n";
3222
print rc_file '@bib_files = (\n';
3224
foreach $name (@bib_files) {
3225
if (!$first) {print rc_file ",\n";}
3226
print rc_file "\'$name\'";
3229
print rc_file "\n)\n";
3232
print rc_file '$bibtex_mode = 1;' . "\n";
3236
print rc_file '$index_mode = 1;' . "\n";
3238
print rc_file "\$view = \"$view\";\n";
3239
print rc_file "\$need_dvi = $need_dvi;\n";
3240
print rc_file "\$need_ps = $need_ps;\n";
3241
print rc_file "\$need_pdf = $need_pdf;\n";
3242
print rc_file "\$pdf_mode = $pdf_mode;\n";
3444
#************************************************************
3446
#************************************************************
3447
#************************************************************
3448
#************************************************************
3450
# Manipulations of main file database:
3452
#************************************************************
3455
# Call: fdb_get(filename [, runtime])
3456
# Returns an array (time, size, md5) for the current state of the
3458
# The optional argument runtime is the runtime of some command
3459
# associated with the use of the file --- see below.
3460
# For non-existent file, deletes its entry in fdb_current,
3461
# and returns (0,-1,0)
3462
# As an optimization, the md5 value is taken from the cache in
3463
# fdb_current, if the time and size stamp indicate that the
3464
# file has not changed.
3465
# The md5 value is recalculated if
3466
# the current filetime differs from the cached value:
3467
# file has been written
3468
# the current filesize differs from the cached value:
3469
# file has definitely changed
3470
# But the file can also be rewritten without change in filetime when
3471
# file processing happens within the 1-second granularity of the
3472
# timestamp (notably for aux files from latex on a short source file).
3473
# The only case that concerns us is when the file is an input to a program
3474
# at some runtime t, the file is rewritten later by the same or another
3475
# program, with timestamp t, and when the initial file also has
3477
# A test is applied for this situation if the runtime argument is
3478
# supplied and is nonzero.
3480
my ($file, $run_time) = @_;
3481
if ( ! defined $run_time ) { $run_time = 0;}
3482
my ($new_time, $new_size) = get_time_size($file);
3483
my @nofile = (0,-1,0); # What we use for initializing
3484
# a new entry in fdb or flagging
3486
if ( $new_size < 0 ) {
3487
delete $fdb_current{$file};
3490
my $recalculate_md5 = 0;
3491
if ( ! exists $fdb_current{$file} ) {
3492
# Ensure we have a record.
3493
$fdb_current{$file} = [@nofile];
3494
$recalculate_md5 = 1;
3496
my $file_data = $fdb_current{$file};
3497
my ( $time, $size, $md5 ) = @$file_data;
3498
#warn "--------- Getting MD5: $file: (N,O,R) = $new_time, $time, $run_time\n";
3499
#warn "--------- $file: (OT,OS,OM) = @$file_data\n";
3500
if ( ($new_time != $time) || ($new_size != $size)
3501
|| ( $run_time && ($run_time == $time ) )
3503
# Only force recalculation of md5 if time or size changed
3504
# Or if the time equals runtime, so that the file may
3505
# have changed within the 1-second granularity of the time
3506
# Else we assume file is really unchanged.
3507
$recalculate_md5 = 1;
3509
if ($recalculate_md5) {
3510
#warn "--------- RECALC MD5: $rule $file: (N,O,R) = $new_time, $time, $run_time\n";
3511
#warn " ------- $file: (OT,OS,OM) = @$file_data\n";
3513
@$file_data = ( $new_time, $new_size, get_checksum_md5( $file ) );
3514
#warn " ------- $file: (NT,NS,NM) = @$file_data\n";
3516
return @$file_data;;
3519
#************************************************************
3522
# Call: fdb_set(filename, $time, $size, $md5 )
3523
# Set data in file data cache, i.e., %fdb_current
3524
my ($file, $time, $size, $md5 ) = @_;
3525
if ( ! exists $fdb_current{$file} ) {
3526
$fdb_current{$file} = [0, -1, 0];
3528
@{$fdb_current{$file}} = ( $time, $size, $md5 );
3531
#************************************************************
3534
# Displays contents of fdb
3535
foreach my $file ( sort keys %fdb_current ) {
3536
print "'$file': @{$fdb_current{$file}}\n";
3540
#************************************************************
3541
#************************************************************
3542
#************************************************************
3544
# Routines for manipulating rule database
3546
#************************************************************
3549
# Call: rdb_read( $in_name )
3550
# Sets rule database from saved file, in format written by rdb_write.
3551
# Returns -1 if file could not be read else number of errors.
3552
# Thus return value on success is 0
3553
my $in_name = $_[0];
3554
my $in_handle = new FileHandle;
3555
$in_handle->open( $in_name, '<' )
3558
my $state = 0; # Outside a section
3564
local %new_sources = (); # Hash: rule => { file=>[ time, size, md5, fromrule ] }
3565
my $new_source = undef; # Reference to hash of sources for current rule
3567
while ( <$in_handle> ) {
3568
# Remove leading and trailing white space.
3571
# Ignore blank lines and comments
3572
if ( /^$/ || /^#/ || /^%/ ) { next LINE;}
3573
if ( /^\[\"([^\"]+)\"\]/ ) {
3576
#?? print "--- Starting rule '$rule'\n";
3577
my $tail = $'; #' Single quote in comment tricks the parser in
3578
# emacs from misparsing an isolated single quote
3580
$source = $dest = $base = '';
3581
if ( $tail =~ /^\s*(\S+)\s*$/ ) {
3584
elsif ( $tail =~ /^\s*(\S+)\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s*$/ ) {
3590
if ( rdb_rule_exists( $rule ) ) {
3591
rdb_one_rule( $rule,
3592
sub{ $$Ptest_kind = 1;
3593
$$Prun_time = $run_time;
3594
#??if ($source) { $$Psource = $source; }
3595
#??if ($dest) { $$Pdest = $dest; }
3596
#??if ($base) { $$Pbase = $base; }
3600
elsif ($rule =~ /^cusdep\s+(\S+)\s+(\S+)\s+(.+)$/ ) {
3601
# Create custom dependency
3605
$source = "$base.$fromext";
3606
$dest = "$base.$toext";
3607
my $PAnew_cmd = ['do_cusdep', ''];
3608
foreach my $dep ( @cus_dep_list ) {
3609
my ($tryfromext,$trytoext,$must,$func_name) = split(' ',$dep);
3610
if ( ($tryfromext eq $fromext) && ($trytoext eq $toext) ) {
3611
$$PAnew_cmd[1] = $func_name;
3614
# Set source file as non-existent.
3615
# If it existed on last run, it will be in later
3616
# lines of the fdb file
3617
rdb_create_rule( $rule, 'cusdep', '', $PAnew_cmd, 1,
3618
$source, $dest, $base, 0, $run_time, 1 );
3620
elsif ( $rule =~ /^(makeindex|bibtex)\s*(.*)$/ ) {
3621
my $rule_generic = $1;
3623
# If fdb_file was old-style (v. 1)
3627
($base, $path, $ext) = fileparseA( $source );
3628
$base = $path.$base;
3629
if ($rule_generic eq 'makeindex') {
3630
$dest = "$base.ind";
3632
elsif ($rule_generic eq 'bibtex') {
3633
$dest = "$base.bbl";
3634
$source = "$base.aux";
3637
warn "$My_name: File-database '$in_name': setting rule '$rule'\n"
3639
my $cmd_type = 'external';
3640
my $ext_cmd = ${$rule_generic};
3641
warn " Rule kind = '$rule_generic'; ext_cmd = '$ext_cmd';\n",
3642
" source = '$source'; dest = '$dest'; base = '$base';\n"
3644
# Set source file as non-existent.
3645
# If it existed on last run, it will be in later
3646
# lines of the fdb file
3647
rdb_create_rule( $rule, $cmd_type, $ext_cmd, '', 1,
3648
$source, $dest, $base, 0, $run_time, 1);
3651
warn "$My_name: In file-database '$in_name' rule '$rule'\n",
3652
" is not in use in this session\n"
3654
$new_source = undef;
3658
$new_source = $new_sources{$rule} = {};
3659
$state = 1; #Reading a section
3661
elsif ( /^\"([^\"]*)\"\s+(\S+)\s+(\S+)\s+(\S+)\s+\"([^\"]*)\"/ ) {
3664
# The rule is not being currently used.
3672
#?? print " --- File '$file'\n";
3674
warn "$My_name: In file-database '$in_name' ",
3675
"line $. is outside a section:\n '$_'\n";
3679
# Set file in database. But ensure we don't do an unnecessary
3680
# fdb_get, which can trigger a new MD5 calculation, which is
3681
# lengthy for a big file. Ininitially flagging the file
3682
# as non-existent solves the problem:
3683
rdb_ensure_file( $rule, $file, undef, 1 );
3684
rdb_set_file1( $rule, $file, $time, $size, $md5 );
3685
fdb_set( $file, $time, $size, $md5 );
3686
# Save the rest of the data, especially the from_fule until we know all
3687
# the rules, otherwise the from_rule may not exist.
3688
# Also we'll have a better chance of looping through files.
3689
${$new_source}{$file} = [ $time, $size, $md5, $from_rule ];
3691
elsif ($state == 0) {
3692
# Outside a section. Nothing to do.
3695
warn "$My_name: In file-database '$in_name' ",
3696
"line $. is of wrong format:\n '$_'\n";
3702
# Set cus dependencies.
3703
&rdb_set_dependentsA( keys %rule_db );
3705
#?? Check from_rules exist.
3710
#************************************************************
3712
sub rdb_read_generatedB {
3713
# Call: rdb_read_generatedB( $in_name, \@generated1, \@aux_files.
3714
# \%other_generated )
3715
# From rule database in saved file, in format written by rdb_write,
3716
# finds the non-trivial generated files that are to be deleted by a cleanup.
3718
# Keys of %other_generated: any detected generated files, from \openout
3719
# lines log file, usually.
3721
# Array @generated1: files associated with makeindex and bibtex
3722
# Array @aux_files: aux files
3723
# Added to keys of %other_generated: any files that are destinations of rules
3724
# whose source is in %other_generated. (One stage only.)
3725
my ($in_name, $Pgenerated1, $Paux_files, $Pother_generated) = @_;
3729
my $in_handle = new FileHandle;
3730
$in_handle->open( $in_name, '<' )
3739
my $state = 0; # Outside a section
3740
my @other_additions = ();
3742
while ( <$in_handle> ) {
3743
# Remove leading and trailing white space.
3746
# Ignore blank lines and comments
3747
if ( /^$/ || /^#/ || /^%/ ) { next LINE;}
3748
if ( /^\[\"([^\"]+)\"\]/ ) {
3751
my $tail = $'; #' Single quote in comment tricks the parser in
3752
# emacs from misparsing an isolated single quote
3754
$source = $dest = $base = '';
3755
if ( $tail =~ /^\s*(\S+)\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s*$/ ) {
3761
if ( $rule =~ /^makeindex/ ) {
3762
push @$Pgenerated1, $source, $dest, "$base.ilg";
3764
elsif ( $rule =~ /^bibtex/ ) {
3765
push @$Pgenerated1, $dest, "$base.blg";
3766
push @$Paux_files, $source;
3768
elsif ( exists ${$Pother_generated}{$source} ) {
3769
push @other_additions, $dest;
3771
$state = 1; #Reading a section
3773
elsif ( /^\"([^\"]*)\"\s+(\S+)\s+(\S+)\s+(\S+)\s+\"([^\"]*)\"/ ) {
3776
# The rule is not being currently used.
3780
($base, $path, $ext) = fileparseA( $file );
3781
if ( $ext eq '.aux' ) { push @$Paux_files, $file; }
3783
elsif ($state == 0) {
3784
# Outside a section. Nothing to do.
3787
warn "$My_name: In file-database '$in_name' ",
3788
"line $. is of wrong format:\n '$_'\n";
3793
foreach (@other_additions) {
3794
${$Pother_generated}{$_} = 1;
3796
} # END rdb_read_generatedB
3798
#************************************************************
3801
# Call: rdb_write( $out_name )
3802
# Writes to the given file name the database of file and rule data
3803
# for all rules needed to make final output
3804
# !!?? Previously was:
3805
# OLD Writes to the given file name the database of file and rule data
3806
# OLD accessible from the primary rules.
3807
# Returns 1 on success, 0 if file couldn't be opened.
3808
local $out_name = $_[0];
3809
local $out_handle = new FileHandle;
3810
if ( ($out_name eq "") || ($out_name eq "-") ) {
3812
$out_handle->open( '>-' );
3815
$out_handle->open( $out_name, '>' );
3817
if (!$out_handle) { return 0; }
3819
local %current_primaries = (); # Hash whose keys are primary rules
3820
# needed, i.e., known latex-like rules which trigger
3821
# circular dependencies
3822
local @pre_primary = (); # Array of rules
3823
local @post_primary = (); # Array of rules
3824
local @one_time = (); # Array of rules
3825
&rdb_classify_rules( \%possible_primaries, keys %requested_filerules );
3827
print $out_handle "# Fdb version $fdb_ver\n";
3828
# !!?? Rules or rules accessible from primary
3829
# my @rules = rdb_accessible( uniq1( keys %possible_primaries ) ) ;
3830
my @rules = rdb_accessible( uniq1( keys %possible_primaries, keys %requested_filerules ) ) ;
3831
# Separate call to sort. Otherwise rdb_accessible seems to get wrong argument.
3832
@rules = sort( @rules );
3836
# Omit data on a unused and never-run primary rule:
3837
if ( ($$Prun_time == 0)
3838
&& exists( $possible_primaries{$rule} )
3839
&& ! exists( $current_primaries{$rule} )
3844
print $out_handle "[\"$rule\"] $$Prun_time \"$$Psource\" \"$$Pdest\" \"$$Pbase\" \n";
3846
sub { print $out_handle " \"$file\" $$Ptime $$Psize $$Pmd5 \"$$Pfrom_rule\"\n"; }
3854
#************************************************************
3856
sub rdb_set_from_logB {
3857
# Assume rule context.
3858
# This is intended to be applied only for a primary (LaTeX-like) rule
3859
# Starting from the log_file, set current details for the current rule.
3861
# Rules should only be primary
3862
if ( $$Pcmd_type ne 'primary' ) {
3863
warn "\n$My_name: ==========$My_name: Probable BUG======= \n ",
3864
" rdb_set_from_logB called to set files ",
3865
"for non-primary rule '$rule'\n\n";
3870
#?? # We'll prune this by all files determined to be needed for source files.
3871
#?? my %unneeded_source = %$PHsource;
3873
# Parse log file to find relevant filenames
3874
# Result in the following variables:
3875
local %dependents = (); # Maps files to status
3876
local @bbl_files = ();
3877
local %idx_files = (); # Maps idx_file to (ind_file, base)
3878
local %generated_log = (); # Lists generated files found in log file
3879
local $primary_out = $$Pdest; # output file (dvi or pdf)
3880
local %conversions = (); # (pdf)latex-performed conversions.
3881
# Maps output file created and read by (pdf)latex
3882
# to source file of conversion.
3883
# The following are also returned, but are global, to be used by caller
3884
# $reference_changed, $bad_reference $bad_citation
3888
# Handle result on output file:
3889
# 1. Non-existent output file, which is because of no content.
3890
# This could either be because the source file has genuinely
3891
# no content, or because of a missing input file. Since a
3892
# missing input file might be correctable by a run of some
3893
# other program whose running is provoked AFTER a run of
3894
# (pdf)latex, we'll set a diagnostic and leave it to the
3895
# rdb_makeB to handle after all circular dependencies are
3897
# 2. The output file might be of a different kind than expected
3898
# (i.e., dvi instead of pdf, or vv). This could
3899
# legitimately occur when the source file (or an invoked
3900
# package or class) sets \pdfoutput.
3901
$missing_dvi_pdf = '';
3902
if ($primary_out eq '') {
3903
warn "$My_name: For rule '$rule', no output was made\n";
3904
$missing_dvi_pdf = $$Pdest;
3906
elsif ($primary_out ne $$Pdest) {
3907
warn "$My_name: ===For rule '$rule', actual output '$primary_out'\n",
3908
" ======appears not to match expected output '$$Pdest'\n";
3912
foreach my $idx_file ( keys %idx_files ) {
3913
my ($ind_file, $ind_base) = @{$idx_files{$idx_file}};
3914
my $from_rule = "makeindex $idx_file";
3915
if ( ! rdb_rule_exists( $from_rule ) ){
3916
print "!!!===Creating rule '$from_rule': '$ind_file' from '$idx_file'\n"
3918
rdb_create_rule( $from_rule, 'external', $makeindex, '', 1,
3919
$idx_file, $ind_file, $ind_base, 1, 0);
3920
print " ===Source file '$ind_file' for '$rule'\n"
3921
if ($diagnostics > -1);
3922
rdb_ensure_file( $rule, $ind_file, $from_rule );
3924
if ( ! -e $ind_file ) {
3925
# Failure was non-existence of makable file
3926
# Leave failure issue to other rules.
3932
foreach my $bbl_file ( uniqs( @bbl_files ) ) {
3933
my ($bbl_base, $bbl_path, $bbl_ext) = fileparseA( $bbl_file );
3934
$bbl_base = $bbl_path.$bbl_base;
3937
&parse_aux( "$bbl_base.aux", \@new_bib_files, \@new_aux_files );
3938
my $from_rule = "bibtex $bbl_base";
3939
print "!!!===Dealing with rule '$from_rule'\n"
3941
if ( ! rdb_rule_exists( $from_rule ) ){
3942
print " ===Creating rule '$from_rule'\n"
3944
rdb_create_rule( $from_rule, 'external', $bibtex, '', 1,
3945
"$bbl_base.aux", $bbl_file, $bbl_base, 1, 0);
3947
local %old_sources = ();
3948
rdb_one_rule( $from_rule, sub { %old_sources = %$PHsource; } );
3949
foreach my $source ( @new_bib_files, @new_aux_files ) {
3950
print " === Source file '$source' for '$from_rule'\n"
3952
rdb_ensure_file( $from_rule, $source );
3953
delete $old_sources{$source};
3955
if ($diagnostics>-1 ) {
3956
foreach ( keys %old_sources ) {
3957
print "Removing no-longer-needed dependent '$_' from rule '$from_rule'\n";
3960
rdb_remove_files( $from_rule, keys %old_sources );
3961
print " ===Source file '$bbl_file' for '$rule'\n"
3963
rdb_ensure_file( $rule, $bbl_file, $from_rule );
3964
if ( ! -e $bbl_file ) {
3965
# Failure was non-existence of makable file
3966
# Leave failure issue to other rules.
3972
foreach my $new_source (keys %dependents, keys %conversions) {
3973
print " ===Source file for rule '$rule': '$new_source'\n"
3975
if ( ($dependents{$new_source} == 5)
3976
|| ($dependents{$new_source} == 6) ) {
3977
# (a) File was detected in "No file..." line in log file.
3978
# Typically file was searched for early in run of
3979
# latex/pdflatex, was not found, and then was written
3981
# or (b) File was written during run.
3982
# In both cases, if file doesn't already exist in database, we
3983
# don't know its previous status. Therefore we tell
3984
# rdb_ensure_file that if it needs to add the file to its
3985
# database, then the previous version of the file should be
3986
# treated as non-existent, to ensure another run is forced.
3987
rdb_ensure_file( $rule, $new_source, undef, 1 );
3989
elsif ( $dependents{$new_source} == 7 ) {
3990
# File was result of conversion by (pdf)latex.
3991
my $cnv_source = $conversions{$new_source};
3992
rdb_ensure_file( $rule, $new_source );
3994
# Conversion from $cnv_source to $new_source
3995
# implies that effectively $cnv_source is a source
3996
# of the (pdf)latex run.
3997
rdb_ensure_file( $rule, $cnv_source );
3999
# Flag that changes of the generated file during a run
4000
# do not require a rerun:
4001
rdb_one_file( $new_source, sub{ $$Pcorrect_after_primary = 1; } );
4004
# But we don't need special precautions for ordinary user files
4005
# (or for files that are generated outside of latex/pdflatex).
4006
rdb_ensure_file( $rule, $new_source );
4010
my @more_sources = &rdb_set_dependentsA( $rule );
4011
my $num_new = $#more_sources + 1;
4012
foreach (@more_sources) {
4013
$dependents{$_} = 4;
4015
# Failure was non-existence of makable file
4016
# Leave failure issue to other rules.
4018
$$Pchanged = 1; # New files can be made. Ignore error.
4022
if ($num_new > 0 ) {
4023
print "$num_new new source files for rule '$rule':\n";
4024
foreach (@more_sources) { print " '$_'\n"; }
4027
print "No new source files for rule '$rule':\n";
4031
my @files_not_needed = ();
4032
foreach (keys %$PHsource) {
4033
if ( ! exists $dependents{$_} ) {
4034
print "Removing no-longer-needed dependent '$_' from rule '$rule'\n"
4036
push @files_not_needed, $_;
4039
rdb_remove_files( $rule, @files_not_needed );
4041
} # END rdb_set_from_logB
4043
#************************************************************
4045
sub rdb_find_new_filesB {
4046
# Call: rdb_find_new_filesB
4047
# Assumes rule context for primary rule.
4048
# Deal with files which were missing and for which a method
4049
# of finding them has become available:
4050
# (a) A newly available source file for a custom dependency.
4051
# (b) When there was no extension, a file with appropriate
4053
# (c) When there was no extension, and a newly available source
4054
# file for a custom dependency can make it.
4056
my %new_includes = ();
4059
foreach my $missing ( keys %$PHsource ) {
4060
next if ( $$PHsource{$missing} != 0 );
4061
my ($base, $path, $ext) = fileparseA( $missing );
4063
if ( -e "$missing.tex" ) {
4064
$new_includes{"$missing.tex"} = 1;
4066
if ( -e $missing ) {
4067
$new_includes{$missing} = 1;
4070
foreach my $dep (@cus_dep_list){
4071
my ($fromext,$toext) = split(' ',$dep);
4072
if ( ( "$ext" eq "$toext" )
4073
&& ( -e "$path$base.$fromext" )
4075
# Source file for the missing file exists
4076
# So we have a real include file, and it will be made
4077
# next time by rdb_set_dependents
4078
$new_includes{$missing} = 1;
4081
# no point testing the $toext if the file doesn't exist.
4087
# $_ doesn't exist, $_.tex doesn't exist,
4088
# and $_ doesn't have an extension
4089
foreach my $dep (@cus_dep_list){
4090
my ($fromext,$toext) = split(' ',$dep);
4091
if ( -e "$path$base.$fromext" ) {
4092
# Source file for the missing file exists
4093
# So we have a real include file, and it will be made
4094
# next time by &rdb__dependents
4095
$new_includes{"$path$base.$toext"} = 1;
4096
# next MISSING_FILE;
4098
if ( -e "$path$base.$toext" ) {
4099
# We've found the extension for the missing file,
4100
# and the file exists
4101
$new_includes{"$path$base.$toext"} = 1;
4102
# next MISSING_FILE;
4106
} # end MISSING_FILES
4108
# Sometimes bad line-breaks in log file (etc) create the
4109
# impression of a missing file e.g., ./file, but with an incorrect
4110
# extension. The above tests find the file with an extension,
4111
# e.g., ./file.tex, but it is already in the list. So now I will
4112
# remove files in the new_include list that are already in the
4113
# include list. Also handle aliasing of file.tex and ./file.tex.
4114
# For example, I once found:
4115
# (./qcdbook.aux (./to-do.aux) (./ideas.aux) (./intro.aux) (./why.aux) (./basics
4116
#.aux) (./classics.aux)
4119
foreach my $file (keys %new_includes) {
4120
my $stripped = $file;
4121
$stripped =~ s{^\./}{};
4122
if ( exists $PHsource{$file} ) {
4123
delete $new_includes{$file};
4127
rdb_ensure_file( $rule, $file );
4131
if ( $diagnostics && ( $found > 0 ) ) {
4132
warn "$My_name: Detected previously missing files:\n";
4133
foreach ( sort keys %new_includes ) {
4138
} # END rdb_find_new_filesB
4140
#************************************************************
4142
sub rdb_set_dependentsA {
4143
# Call rdb_set_dependentsA( rules ...)
4144
# Returns array (sorted), of new source files.
4145
local @new_sources = ();
4146
local @deletions = ();
4148
# Shouldn't recurse. The definite rules to be examined are given.
4149
rdb_for_some( [@_], 0, \&rdb_one_depA );
4150
# OLD rdb_recurseA( [@_], 0, \&rdb_one_depA );
4151
foreach (@deletions) {
4152
my ($rule, $file) = @$_;
4153
rdb_remove_files( $rule, $file );
4156
return uniqs( @new_sources );
4157
} #END rdb_set_dependentsA
4159
#************************************************************
4162
# Helper for finding dependencies. One case, $rule and $file given
4163
# Assume file (and rule) context for DESTINATION file.
4164
local $new_dest = $file;
4165
my ($base_name, $path, $toext) = fileparseA( $new_dest );
4166
$base_name = $path.$base_name;
4168
my $Pinput_extensions = $input_extensions{$rule};
4170
foreach my $dep ( @cus_dep_list ) {
4171
my ($fromext,$proptoext,$must,$func_name) = split(' ',$dep);
4172
if ( $toext eq $proptoext ) {
4173
my $source = "$base_name.$fromext";
4174
# Found match of rule
4176
print "Found cusdep: $source to make $rule:$new_dest ====\n";
4179
$$Pfrom_rule = "cusdep $fromext $toext $base_name";
4180
#?? print "?? Ensuring rule for '$$Pfrom_rule'\n";
4181
local @PAnew_cmd = ( 'do_cusdep', $func_name );
4182
if ( !-e $new_dest ) {
4183
push @new_sources, $new_dest;
4185
if (! rdb_rule_exists( $$Pfrom_rule ) ) {
4186
print "=== Creating rule for '$$Pfrom_rule'\n";
4187
rdb_create_rule( $$Pfrom_rule, 'cusdep', '', \@PAnew_cmd, 3,
4188
$source, $new_dest, $base_name, 0 );
4193
sub{ @$PAint_cmd = @PAnew_cmd; $$Pdest = $new_dest;}
4199
# Source file does not exist
4200
if ( !$force_mode && ( $must != 0 ) ) {
4201
# But it is required that the source exist ($must !=0)
4203
$failure_msg = "File '$base_name.$fromext' does not exist ".
4204
"to build '$base_name.$toext'";
4207
elsif ( $$Pfrom_rule =~ /^cusdep $fromext $toext / ) {
4208
# Source file does not exist, destination has the rule set.
4209
# So turn the from_rule off
4216
elsif ( ($toext eq '')
4218
&& (! -e "$base_name.$proptoext" )
4219
&& exists $$Pinput_extensions{$proptoext}
4221
# Empty extension and non-existent destination
4222
# This normally results from \includegraphics{A}
4223
# without graphics extension for file, when file does
4224
# not exist. So we will try to find something to make it.
4225
my $source = "$base_name.$fromext";
4227
$new_dest = "$base_name.$proptoext";
4228
my $from_rule = "cusdep $fromext $proptoext $base_name";
4229
push @new_sources, $new_dest;
4230
print "Ensuring rule for '$from_rule', to make '$new_dest'\n"
4231
if $diagnostics > -1;
4232
local @PAnew_cmd = ( 'do_cusdep', $func_name );
4233
if (! rdb_rule_exists( $from_rule ) ) {
4234
rdb_create_rule( $from_rule, 'cusdep', '', \@PAnew_cmd, 3,
4235
$source, $new_dest, $base_name, 0);
4240
sub{ @$PAint_cmd = @PAnew_cmd; $$Pdest = $new_dest;}
4243
rdb_ensure_file( $rule, $new_dest, $from_rule );
4244
# We've now got a spurious file in our rule. But don't mess
4245
# with deleting an item we are in the middle of!
4246
push @deletions, [$rule, $file];
4249
} # End of Rule found
4253
#************************************************************
4257
# List rules and their source files
4258
print "===Rules:\n";
4259
local $count_rules = 0;
4260
my @accessible_all = rdb_accessible( keys %requested_filerules );
4263
sub{ $count_rules++;
4264
print "Rule '$rule' depends on:\n";
4266
sub{ print " '$file'\n"; }
4268
if ($count_rules <= 0) {
4269
print " ---No rules defined\n";
4273
#************************************************************
4277
# Displays contents of rule data base.
4278
# Side effect: Exercises access routines!
4279
print "===Rules:\n";
4280
local $count_rules = 0;
4282
sub{ $count_rules++;
4283
my @int_cmd = @$PAint_cmd;
4284
foreach (@int_cmd) {
4285
if ( !defined($_) ) { $_='undef';}
4287
print " [$rule]: '$$Pcmd_type' '$$Pext_cmd' '@int_cmd' $$Ptest_kind ",
4288
"'$$Psource' '$$Pdest' '$$Pbase' $$Pout_of_date $$Pout_of_date_user\n"; },
4289
sub{ print " '$file': $$Ptime $$Psize $$Pmd5 '$$Pfrom_rule'\n"; }
4291
if ($count_rules <= 0) {
4292
print " ---No rules defined\n";
4296
#************************************************************
4298
sub rdb_accessible {
4299
# Call: rdb_accessible( rule, ...)
4300
# Returns array of rules accessible from the given rules
4301
local @accessible = ();
4302
rdb_recurseA( [@_], sub{ push @accessible, $rule; } );
4304
} #END rdb_accessible
4306
#************************************************************
4307
#************************************************************
4308
#************************************************************
4311
# Call: rdb_makeB( target, ... )
4312
# Makes the targets and prerequisites.
4313
# Leaves one-time rules to last.
4314
# Does appropriate repeated makes to resolve dependency loops
4316
# Returns 0 on success, nonzero on failure.
4318
# General method: Find all accessible rules, then repeatedly make
4319
# them until all accessible rules are up-to-date and the source
4320
# files are unchanged between runs. On termination, all
4321
# accessible rules have stable source files.
4323
# One-time rules are view and print rules that should not be
4324
# repeated in an algorithm that repeats rules until the source
4325
# files are stable. It is the calling routine's responsibility to
4326
# arrange to call them, or to use them here with caution.
4328
# Note that an update-viewer rule need not be considered
4329
# one-time. It can be legitimately applied everytime the viewed
4332
# Note also that the criterion of stability is to be applied to
4333
# source files, not to output files. Repeated application of a
4334
# rule to IDENTICALLY CONSTANT source files may produce different
4335
# output files. This may be for a trivial reason (e.g., the
4336
# output file contains a time stamp, as in the header comments for
4337
# a typical postscript file), or for a non-trivial reason (e.g., a
4338
# stochastic algorithm, as in abcm2ps).
4340
# This caused me some actual trouble. In general, circular
4341
# dependencies produce non-termination, and the the following
4342
# situation is an example of a generic situation where certain
4343
# rules must be obeyed in order to obtain proper results:
4344
# 1. A/the latex source file contains specifications for
4345
# certain postprocessing operations. Standard (pdf)latex
4346
# already has this, for indexing and bibliography.
4347
# 2. In the case in point that caused me trouble, the
4348
# specification was for musical tunes that were contained
4349
# in external source files not directly input to
4350
# (pdf)latex. But in the original version, there was a
4351
# style file (abc.sty) that caused latex itself to call
4352
# abcm2ps to make .eps files for each tune that were to be
4353
# read in on the next run of latex.
4354
# 3. Thus the specification can cause a non-terminating loop
4355
# for latexmk, because the output files of abcm2ps changed
4356
# even with identical input.
4357
# 4. The solution was to
4358
# a. Use a style file abc_get.sty that simply wrote the
4359
# specification on the tunes to the .aux file in a
4360
# completely deterministic fashion.
4361
# b. Instead of latex, use a script abclatex.pl that runs
4362
# latex and then extracts the abc contents for each tune
4363
# from the source abc file. This is also
4365
# c. Use a cusdep rule in latexmk to convert the tune abc
4366
# files to eps. This is non-deterministic, but only
4367
# gets called when the (deterministic) source file
4369
# This solves the problem. Latexmk works. Also, it is no
4370
# longer necessary to enable write18 in latex, and multiple
4371
# unnecessary runs of abcm2ps are no longer used.
4373
# The order of testing and applying rules is chosen by the
4374
# following heuristics:
4375
# 1. Both latex and pdflatex may be used, but the resulting
4376
# aux files etc may not be completely identical. Define
4377
# latex and pdflatex as primary rules. Apply the general
4378
# method of repeated circulating through all rules until
4379
# the source files are stable for each primary rule
4380
# separately. Naturally the rules are all accessible
4381
# rules, but excluding primary rules except for the current
4383
# 2. Assume that the primary rules are relatively
4384
# time-consuming, so that unnecessary passes through them
4385
# to check stability of the source files should be avoided.
4386
# 3. Assume that although circular dependencies exist, the
4387
# rules can nevertheless be thought of as basically
4388
# non-circular, and that many rules are strictly or
4389
# normally non-circular. In particular cusdep rules are
4390
# typically non-circular (e.g., fig2eps), as are normal
4391
# output processing rules like dvi2ps.
4392
# 4. The order for the non-circular approximation is
4393
# determined by applying the assumption that an output file
4394
# from one rule that is read in for an earlier stage is
4396
# HOWEVER, at a first attempt, the ordering is not needed. It
4397
# only gives an optimization
4398
# 5. (Note that these assumptions could be violated, e.g., if
4399
# $dvips is arranged not only to do the basic dvips
4400
# command, but also to extract information from the ps file
4401
# and feed it back to an input file for (pdf)latex.)
4402
# 6. Nevertheless, the overall algorithm should allow
4403
# circularities. Then the general criterion of stability
4404
# of source files covers the general case, and also
4405
# robustly handles the case that the USER changes source
4406
# files during a run. This is particularly important in
4407
# -pvc mode, given that a full make on a large document can
4408
# be quite lengthy in time, and moreover that a user
4409
# naturally wishes to make corrections in response to
4410
# errors, particularly latex errors, and have them apply
4412
# This leads to the following approach:
4413
# 1. Classify accessible rules as: primary, pre-primary
4414
# (typically cusdep, bibtex, makeindex, etc), post-primary
4415
# (typically dvips, etc), and one-time
4416
# 2. Then stratify the rules into an order of application that
4417
# corresponds to the basic feedforward structure, with the
4418
# exclusion of one-time rules.
4419
# 3. Always require that one-time rules are among the
4420
# explicitly requested rules, i.e., the last to be applied,
4421
# were we to apply them. Anything else would not match the
4422
# idea of a one-time rule.
4423
# 4. Then work as follows:
4424
# a. Loop over primaries
4425
# b. For each primary, examine each pre-primary rule and
4426
# apply if needed, then the primary rule and then each
4427
# post-primary rule. The ordering of the pre-primary
4428
# and post-primary rules was found in step 2.
4429
# BUT applying the ordering is not essential
4430
# c. Any time that a pre-primary or primary rule is
4431
# applied, loop back to the beginning of step b. This
4432
# ensures that bibtex etc are applied before rerunning
4433
# (pdf)latex, and also covers changing source files, and
4434
# gives priority to quick pre-primary rules for changing
4435
# source files against slow reruns of latex.
4436
# d. Then apply post-primary rules in order, but not
4437
# looping back after each rule. This non-looping back
4438
# is because the rules are normally feed-forward only.
4439
# BUT applying the ordering is not essential
4440
# e. But after completing post-primary rules do loop back
4441
# to b if any rules were applied. This covers exotic
4442
# circular dependence (and as a byproduct, changing
4444
# f. On each case of looping back to b, re-evaluate the
4445
# dependence setup to allow for the effect of changing
4449
local @requested_targets = @_;
4450
local %current_primaries = (); # Hash whose keys are primary rules
4451
# needed, i.e., known latex-like rules which trigger
4452
# circular dependencies
4453
local @pre_primary = (); # Array of rules
4454
local @post_primary = (); # Array of rules
4455
local @one_time = (); # Array of rules
4458
# For diagnostics on changed files, etc:
4459
local @changed = ();
4460
local @disappeared = ();
4461
local @no_dest = (); # Non-existent destination files
4462
local @rules_never_run = ();
4463
local @rules_to_apply = ();
4465
&rdb_classify_rules( \%possible_primaries, @requested_targets );
4468
local $failure = 0; # General accumulated error flag
4469
local $missing_dvi_pdf = ''; # Did primary run fail to make its output file?
4471
local $too_many_runs = 0;
4472
local %rules_applied = ();
4473
my $retry_msg = 0; # Did I earlier say I was going to attempt
4474
# another pass after a failure?
4476
foreach my $primary (keys %current_primaries ) {
4477
foreach my $rule (keys %rule_db) {
4483
my $previous_failure = $failure;
4485
local $newrule_nofile = 0; # Flags whether rule created for
4486
# making currently non-existent file, which
4487
# could become a needed source file for a run
4488
# and therefore undo an error condition
4490
print "MakeB: doing pre_primary and primary...\n";
4492
rdb_for_some( [@pre_primary, $primary], \&rdb_makeB1 );
4493
if ( ($runs > 0) && ! $too_many_runs ) {
4495
if ( $failure && $newrule_nofile ) {
4497
print "$My_name: Error on run, but found possibility to ",
4498
"make new source files\n";
4501
elsif ( ! $failure ) {
4505
elsif ($runs == 0) {
4506
# $failure not set on this pass, so use value from previous pass:
4507
$failure = $previous_failure;
4509
print "But in fact no new files made\n";
4512
if ( $missing_dvi_pdf ) {
4513
# No output from primary, after completing circular dependence
4514
warn "Failure to make '$missing_dvi_pdf'\n";
4518
if ($failure && !$force_mode ) { last PASS; }
4520
print "MakeB: doing post_primary...\n";
4522
rdb_for_some( [@post_primary], \&rdb_makeB1 );
4523
if ($failure) { last PASS; }
4524
if ($runs > 0) { next PASS; }
4525
# Get here if nothing was run.
4529
# Re-evaluate rule classification and accessibility,
4530
# but do not change primaries.
4531
# Problem is that %current_primaries gets altered
4532
my %old_curr_prim = %current_primaries;
4533
&rdb_classify_rules( \%possible_primaries, @requested_targets );
4534
%current_primaries = %old_curr_prim;
4538
rdb_for_some( [@one_time], \&rdb_makeB1 );
4539
rdb_write( $fdb_file );
4542
# Diagnose of the runs
4543
if ( $#{keys %rules_applied } > -1 ) {
4544
print "$My_name: $runs runs. Rules applied:\n";
4545
foreach (sort keys %rules_applied) {
4549
elsif ($failure && $force_mode) {
4550
print "$My_name: Errors, in force_mode: so I tried finishing targets\n";
4553
print "$My_name: Errors, so I did not complete making targets\n";
4557
rdb_for_some( [@_], sub{ push @dests, $$Pdest if ($$Pdest); } );
4558
print "$My_name: All targets (@dests) are up-to-date\n";
4564
#-------------------
4566
sub rdb_show_rule_errors {
4567
local @messages = ();
4570
if ($$Plast_message ne '') {
4571
push @messages, "$rule: $$Plast_message";
4573
elsif ($$Plast_result == 1) {
4574
push @messages, "$rule: failed to create output file";
4576
elsif ($$Plast_result == 2) {
4577
push @messages, "$rule: gave an error";
4579
elsif ($$Prun_time == 0) {
4580
# This can have innocuous causes. So don't report
4581
# push @messages, "$rule: never run";
4585
if ($#messages > -1) {
4586
warn "Collected error summary (may duplicate other messages):\n";
4587
foreach (@messages){
4591
return $#messages+1;
4594
#-------------------
4598
# Helper routine for rdb_makeB.
4599
# Carries out make at level of given rule (all data available).
4600
# Assumes contexts for recursion, make, and rule, and
4601
# assumes that source files for the rule are to be considered
4603
if ($diagnostics) { print " MakeB1 $rule\n"; }
4604
if ($failure & ! $force_mode) {return;}
4605
if ( ! defined $pass{$rule} ) {$pass{$rule} = 0; }
4606
&rdb_clear_change_record;
4608
# Special fix up for bibtex:
4609
my $bibtex_not_run = -1; # Flags status as to whether this is a
4610
# bibtex rule and if it is, whether out-of-date condition is to
4612
# -1 => not a bibtex rule
4613
# 0 => no special treatment
4614
# 1 => don't run bibtex because of non-existent bibfiles
4615
# (and setting to do this test)
4616
# 2 => don't run bibtex because of setting
4617
my @missing_bib_files = ();
4618
if ( $rule =~ /^bibtex/ ) {
4619
$bibtex_not_run = 0;
4620
if ($bibtex_use == 0) {
4621
$bibtex_not_run = 2;
4623
elsif ($bibtex_use == 1) {
4624
foreach ( keys %$PHsource ) {
4625
if ( ( /\.bib$/ ) && (! -e $_) ) {
4626
push @missing_bib_files, $_;
4627
$bibtex_not_run = 1;
4633
if ( ($$Prun_time == 0) && exists($possible_primaries{$rule}) ) {
4634
push @rules_never_run, $rule;
4636
$$Plast_result = -1;
4639
if ( $$Pdest && (! -e $$Pdest) ) {
4640
# With a non-existent destination, if we haven't made any passes
4641
# through a rule, rerunning the rule is good, because the file
4642
# may fail to exist because of being deleted by the user (for ex.)
4643
# rather than because of a failure on a previous run.
4644
# (We could do better with a flag in fdb file.)
4645
# But after the first pass, the situation is different.
4646
# For a primary rule (pdf)latex, the lack of a destination file
4647
# could result from there being zero content due to a missing
4648
# essential input file. The input file could be generated
4649
# by a program to be run later (e.g., a cusdep or bibtex),
4650
# so we should wait until all passes are completed before
4651
# deciding a non-existent destination file is an error.
4652
# For a custom dependency, the rule may be obsolete, and
4653
# if the source file does not exist also, we should simply
4654
# not run the rule, but not set an error condition.
4655
# Any error will arise at the (pdf)latex level due to a
4656
# missing source file at that level.
4657
if ( ( $$Pcmd_type eq 'cusdep') && $$Psource && (! -e $$Psource) ) {
4660
elsif ( $$Pcmd_type eq 'delegated' ) {
4661
# Delegate to destination rule
4663
elsif ( $pass{$rule}==0) {
4664
push @no_dest, $$Pdest;
4667
if ( $$Pcmd_type eq 'primary' ) {
4668
$missing_dvi_pdf = $$Pdest;
4673
&rdb_flag_changes_here;
4675
if (!$$Pout_of_date) {
4676
#?? if ( ($$Pcmd_type eq 'primary') && (! $silent) ) {
4677
# print "Rule '$rule' up to date\n";
4681
if ($diagnostics) { print " remake\n"; }
4683
print "$My_name: applying rule '$rule'...\n";
4684
&rdb_diagnose_changes( "Rule '$rule': " );
4687
$rules_applied{$rule} = 1;
4690
# We are applying the rule, so its source file state for when it
4691
# was last made is as of now:
4692
# ??IS IT CORRECT TO DO NOTHING IN CURRENT VERSION?
4695
my $return = 0; # Return code from called routine
4696
# Rule may have been created since last run:
4697
if ( ! defined $pass{$rule} ) {$pass{$rule} = 0; }
4698
if ( $pass{$rule} ge $max_repeat ) {
4699
# Avoid infinite loop by having a maximum repeat count
4700
# Getting here represents some kind of weird error.
4701
warn "$My_name: Maximum runs of $rule reached ",
4702
"without getting stable files\n";
4705
$failure_msg = "'$rule' needed too many passes";
4709
if ($bibtex_not_run > 0) {
4710
if ($bibtex_not_run == 1 ) {
4711
show_array ("$My_name: I WON'T RUN '$rule' because I don't find the following files:",
4712
@missing_bib_files);
4714
elsif ($bibtex_not_run == 2 ) {
4715
warn "$My_name: I AM CONFIGURED/INVOKED NOT TO RUN '$rule'\n";
4717
$return = &rdb_dummy_run1;
4720
warn_running( "Run number $pass{$rule} of rule '$rule'" );
4721
if ($$Pcmd_type eq 'primary' ) {
4722
$return = &rdb_primary_run;
4724
else { $return = &rdb_run1; }
4727
$newrule_nofile = 1;
4730
elsif ( $$Pdest && ( !-e $$Pdest ) && (! $failure) ){
4731
# If there is a destination to make, but for some reason
4732
# it did not get made, and no other error was reported,
4733
# then a priori there appears to be an error condition:
4734
# the run failed. But there are two important cases in
4735
# which this is a wrong diagnosis.
4736
if ( ( $$Pcmd_type eq 'cusdep') && $$Psource && (! -e $$Psource) ) {
4737
# However, if the rule is a custom dependency, this is not by
4738
# itself an error, if also the source file does not exist. In
4739
# that case, we may have the situation that (1) the dest file is no
4740
# longer needed by the tex file, and (2) therefore the user
4741
# has deleted the source and dest files. After the next
4742
# latex run and the consequent analysis of the log file, the
4743
# cusdep rule will no longer be needed, and will be removed.
4745
# So in this case, do NOT report an error
4748
elsif ($$Pcmd_type eq 'primary' ) {
4749
# For a primary rule, i.e., (pdf)latex, not to produce the
4750
# expected output file may not be an error condition.
4751
# Diagnostics were handled in parsing the log file.
4752
# Special action in main loop inrdb_makeB1
4753
$missing_dvi_pdf = $$Pdest;
4762
if ( !$$Plast_message ) {
4763
$$Plast_message = "Run of rule '$rule' gave a non-zero error code";
4765
# !!?? $failure_msg = $$Plast_message;
4770
#************************************************************
4773
# Call: rdb_submakeB
4774
# Makes all the source files for a given rule.
4775
# Assumes contexts for recursion, for make, and rule.
4776
%visited = %visited_at_rule_start;
4777
local $failure = 0; # Error flag
4778
my @v = keys %visited;
4779
#?? print "---submakeB $rule. @v \n";
4780
rdb_do_files( sub{ rdb_recurse_rule( $$Pfrom_rule, 0,0,0, \&rdb_makeB1 ) } );
4784
#************************************************************
4787
sub rdb_classify_rules {
4788
# Usage: rdb_classify_rules( \%allowed_primaries, requested targets )
4789
# Assume the following variables are available (global or local):
4791
# @requested_targets # Set to target rules
4794
# %current_primaries # Keys are actual primaries
4795
# @pre_primary # Array of rules
4796
# @post_primary # Array of rules
4797
# @one_time # Array of rules
4798
# @pre_primary and @post_primary are in natural order of application.
4800
local $P_allowed_primaries = shift;
4801
local @requested_targets = @_;
4802
local $state = 0; # Post-primary
4803
local @classify_stack = ();
4805
%current_primaries = ();
4810
rdb_recurseA( \@requested_targets, \&rdb_classify1, 0,0, \&rdb_classify2 );
4812
# Reverse, as tendency is to find last rules first.
4813
@pre_primary = reverse @pre_primary;
4814
@post_primary = reverse @post_primary;
4817
print "Rule classification: \n";
4818
if ($#requested_targets < 0) {
4819
print " No requested rules\n";
4822
print " Requested rules:\n";
4823
foreach ( @requested_targets ) { print " $_\n"; }
4825
if ($#pre_primary < 0) {
4826
print " No pre-primaries\n";
4829
print " Pre-primaries:\n";
4830
foreach (@pre_primary) { print " $_\n"; }
4832
print " Primaries:\n";
4833
foreach (keys %current_primaries) { print " $_\n"; }
4834
if ($#post_primary < 0) {
4835
print " No post-primaries\n";
4838
print " Post-primaries:\n";
4839
foreach (@post_primary) { print " $_\n"; }
4841
if ($#one_time < 0) {
4842
print " No one_time rules\n";
4845
print " One_time rules:\n";
4846
foreach ( @one_time ) { print " $_\n"; }
4850
} #END rdb_classify_rules
4852
#-------------------
4855
# Helper routine for rdb_classify_rules
4856
# Applied as rule_act1 in recursion over rules
4857
# Assumes rule context, and local variables from rdb_classify_rules
4858
#print "??======= '$rule' $depth $state ========== \n";
4859
push @classify_stack, [$state];
4860
if ( exists $possible_one_time{$rule} ) {
4861
# Normally, we will have already extracted the one_time rules,
4862
# and they will never be accessed here. But just in case of
4863
# problems or generalizations, we will cover all possibilities:
4865
warn "ONE TIME rule not at outer level '$rule'\n";
4867
push @one_time, $rule;
4869
elsif ($state == 0) {
4870
if ( exists ${$P_allowed_primaries}{$rule} ) {
4871
$state = 1; # In primary rule
4872
$current_primaries{ $rule } = 1;
4875
push @post_primary, $rule;
4879
$state = 2; # in post-primary rule
4880
push @pre_primary, $rule;
4882
} #END rdb_classify1
4884
#-------------------
4887
# Helper routine for rdb_classify_rules
4888
# Applied as rule_act2 in recursion over rules
4889
# Assumes rule context
4890
($state) = @{ pop @classify_stack };
4891
} #END rdb_classify2
4893
#************************************************************
4897
# Assumes contexts for: rule.
4898
# Unconditionally apply the rule
4899
# Returns return code from applying the rule.
4900
# Otherwise: 0 on other kind of success, -1 on error.
4902
# Source file data, by definition, correspond to the file state just before
4903
# the latest run, and the run_time to the time just before the run:
4906
$$Pchanged = 0; # No special changes in files
4908
$$Plast_message = '';
4910
# Return values for external command:
4913
# Find any internal command
4914
my @int_args = @$PAint_cmd;
4915
my $int_cmd = shift @int_args;
4916
my @int_args_for_printing = @int_args;
4917
foreach (@int_args_for_printing) {
4918
if ( ! defined $_ ) { $_ = 'undef'; }
4921
print "For rule '$rule', running '\&$int_cmd( @int_args_for_printing )' ...\n";
4922
$return = &$int_cmd( @int_args );
4924
elsif ($$Pext_cmd) {
4925
$return = &rdb_ext_cmd;
4928
warn "$My_name: Either a bug OR a configuration error:\n",
4929
" Need to implement the command for '$rule'\n";
4933
$$Plast_message = "Bug or configuration error; incorrect command type";
4935
if ( $rule =~ /^bibtex/ ) {
4936
my $retcode = check_bibtex_log($$Pbase);
4937
if ($retcode == 3) {
4939
$$Plast_message = "Could not open bibtex log file for '$$Pbase'";
4940
push @warnings, $$Plast_message;
4942
elsif ($retcode == 2) {
4943
$$Plast_message = "Bibtex errors: See file '$$Pbase.blg'";
4944
push @warnings, $$Plast_message;
4946
elsif ($retcode == 1) {
4947
push @warnings, "Bibtex warnings for '$$Pbase'";
4952
if ($$Ptest_kind == 3) {
4953
# We are time-criterion first time only. Now switch to
4954
# file-change criterion
4957
$$Pout_of_date = $$Pout_of_date_user = 0;
4959
if ( ($$Plast_result == 0) && ($return != 0) ) {
4961
if ($$Plast_message eq '') {
4962
$$Plast_message = "Command for '$rule' gave return code $return";
4965
elsif ( $$Pdest && (! -e $$Pdest) ) {
4974
sub rdb_dummy_run1 {
4975
# Assumes contexts for: rule.
4976
# Update rule state as if the rule ran successfully,
4977
# but don't run the rule.
4978
# Returns 0 (success code)
4980
# Source file data, by definition, correspond to the file state just before
4981
# the latest run, and the run_time to the time just before the run:
4984
$$Pchanged = 0; # No special changes in files
4986
$$Plast_message = '';
4988
if ($$Ptest_kind == 3) {
4989
# We are time-criterion first time only. Now switch to
4990
# file-change criterion
4993
$$Pout_of_date = $$Pout_of_date_user = 0;
4996
} # END rdb_dummy_run1
5002
# Assumes rule context. Runs external command with substitutions.
5003
# Uses defaults for the substitutions. See rdb_ext_cmd1.
5004
return rdb_ext_cmd1();
5010
# Call: rdb_ext_cmd1( options, source, dest, base ) or rdb_ext_cmd1() or ...
5011
# Assumes rule context. Returns command with substitutions.
5012
# Null arguments or unprovided arguments => use defaults.
5013
# for %S=source, %D=dest, %B=base, %R=root=base for latex, %O='', %T=texfile
5014
my ($options, $source, $dest, $base ) = @_;
5017
$source ||= $$Psource;
5021
my $ext_cmd = $$Pext_cmd;
5023
#Set character to surround filenames:
5024
my $q = $quote_filenames ? '"' : '';
5028
'%R' => $q.$root_filename.$q,
5029
'%B' => $q.$base.$q,
5030
'%T' => $q.$texfile_name.$q,
5031
'%S' => $q.$source.$q,
5032
'%D' => $q.$dest.$q,
5033
'%%' => '%' # To allow literal %B, %R, etc, by %%B.
5036
my @tokens = split /(%.)/, $ext_cmd;
5038
if (exists($subst{$_})) { $_ = $subst{$_}; }
5040
$ext_cmd = join '', @tokens;
5042
# print "quote is '$q'; ext_cmd = '$ext_cmd'\n";
5043
my ($pid, $return) = &Run_msg($ext_cmd);
5049
sub rdb_primary_run {
5050
#?? See multipass_run in previous version Aug 2007 for issues
5051
# Call: rdb_primary_run
5052
# Assumes contexts for: recursion, make, & rule.
5053
# Assumes (a) the rule is a primary,
5054
# (b) a run has to be made,
5055
# (c) source files have been made.
5056
# This routine carries out the run of the rule unconditionally,
5057
# and then parses log file etc.
5060
my $return_latex = &rdb_run1;
5061
if (-e $$Pdest) { $missing_dvi_pdf = '';}
5063
######### Analyze results of run:
5064
if ( ! -e "$root_filename.log" ) {
5067
$$Plast_message = $failure_msg = "(Pdf)LaTeX failed to generate a log file";
5070
####### NOT ANY MORE! Capture any changes in source file status before we
5071
# check for errors in the latex run
5073
# Find current set of source files:
5076
# For each file of the kind made by epstopdf.sty during a run,
5077
# if the file has changed during a run, then the new version of
5078
# the file will have been read during the run. Unlike the usual
5079
# case, we will NOT need to redo the primary run because of the
5080
# change of this file during the run. Therefore set the file as
5082
rdb_do_files( sub { if ($$Pcorrect_after_primary) {&rdb_update1;} } );
5084
# There may be new source files, and the run may have caused
5085
# circular-dependency files to be changed. And the regular
5086
# source files may have been updated during a lengthy run of
5087
# latex. So redo the makes for sources of the current rule:
5088
my $submake_return = &rdb_submakeB;
5089
&rdb_clear_change_record;
5090
&rdb_flag_changes_here;
5091
if ($$Pout_of_date && !$silent) {
5092
&rdb_diagnose_changes( "Rule '$rule': " );
5094
$updated = 1; # Flag that some dependent file has been remade
5095
# Fix the state of the files as of now: this will solve the
5096
# problem of latex and pdflatex interfering with each other,
5097
# at the expense of some non-optimality
5098
#?? Check this is correct:
5100
if ( $diagnostics ) {
5101
print "$My_name: Rules after run: \n";
5105
$return = $return_latex;
5106
if ($return_latex && $$Pout_of_date_user) {
5107
print "Error in (pdf)LaTeX, but change of user file(s), ",
5108
"so ignore error & provoke rerun\n"
5113
# Summarize issues that may have escaped notice:
5115
if ($bad_reference) {
5116
push @warnings, "Latex could not resolve all references";
5118
if ($bad_citation) {
5119
push @warnings, "Latex could not resolve all citations";
5121
if ($#warnings > 0) {
5122
show_array( "$My_name: Summary of warnings:", @warnings );
5125
} #END rdb_primary_run
5127
#************************************************************
5129
sub rdb_clear_change_record {
5130
# Initialize diagnostics for reasons for running rule.
5133
@no_dest = (); # We are not now using this
5134
@rules_never_run = ();
5135
@rules_to_apply = (); # This is used in recursive application
5136
# of rdb_flag_changes_here, to list
5137
# rules that were out-of-date for some reason.
5138
} #END rdb_clear_change_record
5140
#************************************************************
5142
sub rdb_flag_changes_here {
5143
# Flag changes in current rule.
5144
# Assumes rule context.
5145
# Optional argument: if true then fdb_get shouldn't do runtime test
5146
# for recalculation of md5
5147
local $ignore_run_time = $_[0];
5148
if ( ! defined $ignore_run_time ) { $ignore_run_time = 0; }
5149
local $dest_mtime = 0;
5150
$dest_mtime = get_mtime($$Pdest) if ($$Pdest);
5151
rdb_do_files( \&rdb_file_change1);
5152
if ($$Pout_of_date) {
5153
push @rules_to_apply, $rule;
5155
#?? print "======== flag: $rule $$Pout_of_date ==========\n";
5156
} #END rdb_flag_changes_here
5158
#************************************************************
5160
sub rdb_file_change1 {
5161
# Call: &rdb_file_change1
5162
# Assumes rule and file context. Assumes $dest_mtime set.
5163
# Flag whether $file in $rule has changed or disappeared.
5164
# Set rule's make flag if there's a change.
5165
my $run_time_argument = $ignore_run_time ? 0 : $$Prun_time;
5166
my ($new_time, $new_size, $new_md5) = fdb_get($file, $run_time_argument);
5167
#?? print "FC1 '$rule':$file $$Pout_of_date TK=$$Ptest_kind\n";
5168
#?? print " OLD $$Ptime, $$Psize, $$Pmd5\n",
5169
#?? " New $new_time, $new_size, $new_md5\n";
5170
my $ext_no_period = ext_no_period( $file );
5171
if ( ($new_size < 0) && ($$Psize >= 0) ) {
5172
# print "Disappeared '$file' in '$rule'\n";
5173
push @disappeared, $file;
5174
# No reaction is good.
5175
#$$Pout_of_date = 1;
5176
# ??? 1 Sep. 2008: I do NOT think so, for cusdep no-file-exists issue
5177
# ??? 30 Sep 2008: I think I have this fixed. There were other changes
5178
# needed. No-change-flagged is correct. The array @disappeared flags
5179
# files that have disappeared, if I need to know. But having a source
5180
# file disappear is not a reason for a remake unless I know how to
5181
# make the file. If the file is a destination of a rule, that rule
5182
# will be rerun. It may be that the user is changing another source
5183
# in such a way that the disappeared file won't be needed. Before the
5184
# change is applied we get a superfluous infinite loop.
5187
if ( ($new_size < 0) && ($$Psize < 0) ) {
5190
if ( ($new_size != $$Psize) || ($new_md5 ne $$Pmd5) ) {
5191
#?? print "FC1: changed $file: ($new_size != $$Psize) $new_md5 ne $$Pmd5)\n";
5192
push @changed, $file;
5194
if ( ! exists $generated_exts_all{$ext_no_period} ) {
5195
$$Pout_of_date_user = 1;
5198
elsif ( $new_time != $$Ptime ) {
5199
#warn "--==-- Unchanged $file, changed time, update filetime in $rule\n";
5200
$$Ptime = $new_time;
5202
if ( ( ($$Ptest_kind == 2) || ($$Ptest_kind == 3) )
5203
&& (! exists $generated_exts_all{$ext_no_period} )
5204
&& ( $new_time > $dest_mtime )
5206
#?? print "FC1: changed $file: ($new_time > $dest_mtime)\n";
5207
push @changed, $file;
5208
$$Pout_of_date = $$Pout_of_date_user = 1;
5210
} #END rdb_file_change1
5212
#************************************************************
5214
sub rdb_new_changes {
5215
&rdb_clear_change_record;
5216
rdb_recurseA( [@_], sub{ &rdb_flag_changes_here(1); } );
5217
return ($#changed >= 0) || ($#no_dest >= 0) || ($#rules_to_apply >= 0);
5218
} #END rdb_new_changes
5220
#************************************************************
5222
sub rdb_diagnose_changes {
5223
# Call: rdb_diagnose_changes or rdb_diagnose_changes( heading )
5224
# List changes on STDERR
5225
# Precede the message by the optional heading, else by "$My_name: "
5226
my $heading = defined($_[0]) ? $_[0] : "$My_name: ";
5228
if ($#rules_never_run >= 0) {
5229
warn "${heading}Rules & subrules not known to be previously run:\n";
5230
foreach (@rules_never_run) { warn " $_\n"; }
5232
if ( ($#changed >= 0) || ($#disappeared >= 0) || ($#no_dest >= 0) ) {
5233
warn "${heading}File changes, etc:\n";
5234
if ( $#changed >= 0 ) {
5235
warn " Changed files, or newly in use since previous run(s):\n";
5236
foreach (uniqs(@changed)) { warn " '$_'\n"; }
5238
if ( $#disappeared >= 0 ) {
5239
warn " No-longer-existing files:\n";
5240
foreach (uniqs(@disappeared)) { warn " '$_'\n"; }
5242
if ( $#no_dest >= 0 ) {
5243
warn " Non-existent destination files:\n";
5244
foreach (uniqs(@no_dest)) { warn " '$_'\n"; }
5247
elsif ($#rules_to_apply >=0) {
5248
warn "${heading}The following rules & subrules became out-of-date:\n";
5249
foreach (@rules_to_apply) { warn " '$_'\n"; }
5252
warn "${heading}No file changes\n";
5254
} #END rdb_diagnose_changes
5257
#************************************************************
5258
#************************************************************
5259
#************************************************************
5260
#************************************************************
5262
#************************************************************
5263
#************************************************************
5264
#************************************************************
5265
#************************************************************
5267
# Routines for convenient looping and recursion through rule database
5268
# ================= NEW VERSION ================
5270
# There are several places where we need to loop through or recurse
5271
# through rules and files. This tends to involve repeated, tedious
5272
# and error-prone coding of much book-keeping detail. In particular,
5273
# working on files and rules needs access to the variables involved,
5274
# which either involves direct access to the elements of the database,
5275
# and consequent fragility against changes and upgrades in the
5276
# database structure, or involves lots of routines for reading and
5277
# writing data in the database, then with lots of repetitious
5278
# house-keeping code.
5280
# The routines below provide a solution. Looping and recursion
5281
# through the database are provided by a set of basic routines where
5282
# each necessary kind of looping and iteration is coded once. The
5283
# actual actions are provided as references to action subroutines.
5284
# (These can be either actual references, as in \&routine, or
5285
# anonymous subroutines, as in sub{...}, or aas a zero value 0 or an
5286
# omitted argument, to indicate that no action is to be performed.)
5288
# When the action subroutine(s) are actually called, a context for the
5289
# rule and/or file (as appropriate) is given by setting named
5291
# variables to REFERENCES to the relevant data values. These can be
5292
# used to retrieve and set the data values. As a convention,
5293
# references to scalars are given by variables named start with "$P",
5294
# as in "$Pdest", while references to arrays start with "$PA", as in
5295
# "$PAint_cmd", and references to hashes with "$PH", as in "$PHsource".
5296
# After the action subroutine has finished, checks for data
5297
# consistency may be made.
5299
# variables to the relevant data values. After the action subroutine
5300
# has finished, the database is updated with the values of these named
5301
# variables, with any necessary consistency checks. Thus the action
5302
# subroutines can act on sensibly named variables without needed to
5303
# know the database structure.
5305
# The only routines that actually use the database structure and need
5306
# to be changed if that is changed are: (a) the routines rdb_one_rule
5307
# and rdb_one_file that implement the calling of the action subroutines,
5308
# (b) routines for creation of single rules and file items, and (c) to
5309
# a lesser extent, the routine for destroying a file item.
5311
# Note that no routine is provided for destroying a rule. During a
5312
# run, a rule, with its source files, may become inaccessible or
5313
# unused. This happens dynamically, depending on the dependencies
5314
# caused by changes in the source file or by error conditions that
5315
# cause the computation of dependencies, particular of latex files, to
5316
# become wrong. In that situation the files certainly come and go in
5317
# the database, but subsidiary rules, with their content information
5318
# on their source files, need to be retained so that their use can be
5319
# reinstated later depending on dynamic changes in other files.
5321
# However, there is a potential memory leak unless some pruning is
5322
# done in what is written to the fdb file. (Probably only accessible
5323
# rules and those for which source files exist. Other cases have no
5324
# relevant information that needs to be preserved between runs.)
5330
#************************************************************
5332
# First the top level routines for recursion and iteration
5334
#************************************************************
5337
# Call: rdb_recurseA( rule | [ rules],
5338
# \&rule_act1, \&file_act1, \&file_act2,
5340
# The actions are pointers to subroutines, and may be null (0, or
5341
# undefined) to indicate no action to be applied.
5342
# Recursively acts on the given rules and all ancestors:
5343
# foreach rule found:
5345
# loop through its files:
5347
# act on its ancestor rule, if any
5350
# Guards against loops.
5351
# Access to the rule and file data by local variables, only
5352
# for getting and setting.
5354
# This routine sets a context for anything recursive, with @heads,
5355
# %visited and $depth being set as local variables.
5360
# Distinguish between single rule (a string) and a reference to an
5362
if ( ref $rules eq 'ARRAY' ) { @heads = @$rules; }
5363
else { @heads = ( $rules ); }
5365
# Keep a list of visited rules, used to block loops in recursion:
5366
local %visited = ();
5369
foreach $rule ( @heads ) { rdb_recurse_rule( $rule, @_ ); }
5373
#************************************************************
5376
# Call: rdb_for_all( \&rule_act1, \&file_act, \&rule_act2 )
5377
# Loops through all rules and their source files, using the
5378
# specified set of actions, which are pointers to subroutines.
5379
# Sorts rules alphabetically.
5380
# See rdb_for_some for details.
5381
rdb_for_some( [ sort keys %rule_db ], @_);
5384
#************************************************************
5387
# Call: rdb_for_some( rule | [ rules],
5388
# \&rule_act1, \&file_act, \&rule_act2)
5389
# Actions can be zero, and rules at tail of argument list can be
5390
# omitted. E.g. rdb_for_some( rule, 0, \&file_act ).
5391
# Anonymous subroutines can be used, e.g., rdb_for_some( rule, sub{...} ).
5393
# Loops through rules and their source files, using the
5394
# specified set of rules:
5397
# loop through its files:
5401
# Rule data and file data are made available in local variables
5402
# for access by the subroutines.
5406
# Distinguish between single rule (a string) and a reference to an
5408
if ( ref $rules eq 'ARRAY' ) { @heads = @$rules; }
5409
else { @heads = ( $rules ); }
5411
foreach $rule ( @heads ) {
5412
# $rule is implicitly local
5413
&rdb_one_rule( $rule, @_ );
5417
#************************************************************
5419
sub rdb_for_one_file {
5421
# Avoid name collisions with general recursion and iteraction routines:
5422
local $file1 = shift;
5423
local $action1 = shift;
5424
rdb_for_some( $rule, sub{rdb_one_file($file1,$action1)} );
5425
} #END rdb_for_one_file
5428
#************************************************************
5430
# Routines for inner part of recursion and iterations
5432
#************************************************************
5434
sub rdb_recurse_rule {
5435
# Call: rdb_recurse_rule($rule, \&rule_act1, \&file_act1, \&file_act2,
5437
# to do the work for one rule, recurisvely called from_rules for
5438
# the sources of the rules.
5439
# Assumes recursion context, i.e. that %visited, @heads, $depth.
5440
# We are overriding actions:
5441
my ($rule, $rule_act1, $new_file_act1, $new_file_act2, $rule_act2)
5443
# and must propagate the file actions:
5444
local $file_act1 = $new_file_act1;
5445
local $file_act2 = $new_file_act2;
5447
if ( (! $rule) || exists $visited{$rule} ) { return; }
5448
$visited{$rule} = 1;
5451
# We may need to repeat actions on dependent rules, without being
5452
# blocked by the test on visited files. So save %visited:
5453
local %visited_at_rule_start = %visited;
5454
# At end, the last value set for %visited wins.
5455
rdb_one_rule( $rule, $rule_act1, \&rdb_recurse_file, $rule_act2 );
5457
} #END rdb_recurse_rule
5459
#************************************************************
5461
sub rdb_recurse_file {
5462
# Call: rdb_recurse_file to do the work for one file.
5463
# This has no arguments, since it is used as an action subroutine,
5464
# passed as a reference in calls in higher-level subroutine.
5465
# Assumes contexts set for: Recursion, rule, and file
5466
&$file_act1 if $file_act1;
5467
rdb_recurse_rule( $$Pfrom_rule, $rule_act1, $file_act1, $file_act2,
5470
&$file_act2 if $file_act2;
5471
} #END rdb_recurse_file
5473
#************************************************************
5476
# Assumes rule context, including $PHsource.
5477
# Applies an action to all the source files of the rule.
5478
local $file_act = shift;
5479
my @file_list = sort keys %$PHsource;
5480
foreach my $file ( @file_list ){
5481
rdb_one_file( $file, $file_act );
5485
#************************************************************
5487
# Routines for action on one rule and one file. These are the main
5488
# places (in addition to creation and destruction routines for rules
5489
# and files) where the database structure is accessed.
5491
#************************************************************
5494
# Call: rdb_one_rule( $rule, $rule_act1, $file_act, $rule_act2 )
5495
# Sets context for rule and carries out the actions.
5496
#===== Accesses rule part of database structure =======
5498
local ( $rule, $rule_act1, $file_act, $rule_act2 ) = @_;
5500
if ( (! $rule) || ! rdb_rule_exists($rule) ) { return; }
5502
local ( $PArule_data, $PHsource ) = @{$rule_db{$rule}};
5503
local ($Pcmd_type, $Pext_cmd, $PAint_cmd, $Ptest_kind,
5504
$Psource, $Pdest, $Pbase,
5505
$Pout_of_date, $Pout_of_date_user, $Prun_time, $Pchanged,
5506
$Plast_result, $Plast_message )
5507
= Parray( $PArule_data );
5508
# Correct array ref:
5509
$PAint_cmd = $$PArule_data[2];
5511
&$rule_act1 if $rule_act1;
5512
&rdb_do_files( $file_act ) if $file_act;
5513
&$rule_act2 if $rule_act2;
5518
#************************************************************
5521
# Call: rdb_one_file($file, $file_act)
5522
# Sets context for file and carries out the action.
5523
# Assumes $rule context set.
5524
#===== Accesses file part of database structure =======
5525
local ($file, $file_act) = @_;
5527
if ( (!$file) ||(!exists ${$PHsource}{$file}) ) { return; }
5528
local $PAfile_data = ${$PHsource}{$file};
5529
local ($Ptime, $Psize, $Pmd5, $Pfrom_rule, $Pcorrect_after_primary )
5530
= Parray( $PAfile_data );
5531
&$file_act if $file_act;
5532
if ( ! rdb_rule_exists( $$Pfrom_rule ) ) {
5538
#************************************************************
5540
# Routines for creation of rules and file items, and for removing file
5543
#************************************************************
5545
sub rdb_create_rule {
5546
# rdb_create_rule( rule, command_type, ext_cmd, int_cmd, test_kind,
5547
# source, dest, base,
5548
# needs_making, run_time, set_file_not_exists )
5549
# int_cmd is either a string naming a perl subroutine or it is a
5550
# reference to an array containing the subroutine name and its
5552
# Makes rule. Error if it already exists.
5553
# Omitted arguments: replaced by 0 or '' as needed.
5554
# ==== Sets rule data ====
5555
my ( $rule, $cmd_type, $int_cmd, $PAext_cmd, $test_kind,
5556
$source, $dest, $base,
5557
$needs_making, $run_time, $set_file_not_exists ) = @_;
5559
# Set defaults, and normalize parameters:
5560
foreach ( $cmd_type, $int_cmd, $PAext_cmd, $source, $dest, $base,
5561
$set_file_not_exists ) {
5562
if (! defined $_) { $_ = ''; }
5564
foreach ( $needs_making, $run_time, $test_kind ) {
5565
if (! defined $_) { $_ = 0; }
5567
if (!defined $test_kind) {
5568
# Default to test on file change
5571
if ( ref( $PAext_cmd ) eq '' ) {
5572
# It is a single command. Convert to array reference:
5573
$PAext_cmd = [ $PAext_cmd ];
5576
# COPY the referenced array:
5577
$PAext_cmd = [ @$PAext_cmd ];
5581
[ [$cmd_type, $int_cmd, $PAext_cmd, $test_kind,
5582
$source, $dest, $base, $needs_making, 0, $run_time,
5587
rdb_ensure_file( $rule, $source, undef, $set_file_not_exists );
5589
} #END rdb_create_rule
5591
#************************************************************
5593
sub rdb_ensure_file {
5594
# rdb_ensure_file( rule, file[, fromrule[, set_not_exists]] )
5595
# Ensures the source file item exists in the given rule.
5596
# Then if the fromrule is specified, set it for the file item.
5597
# If the item is created, then:
5598
# (a) by default initialize it to current file state.
5599
# (b) but if the fourth argument, set_not_exists, is true,
5600
# initialize the item as if the file does not exist.
5601
# This case is typically used when the log file for a run
5602
# of latex/pdflatex claims that the file was non-existent
5603
# at the beginning of a run.
5604
#============ rule and file data set here ======================================
5606
local ( $new_file, $new_from_rule, $set_not_exists ) = @_;
5607
if ( ! rdb_rule_exists( $rule ) ) {
5608
die_trace( "$My_name: BUG in rdb_ensure_file: non-existent rule '$rule'" );
5610
if ( ! defined $new_file ) {
5611
die_trace( "$My_name: BUG in rdb_ensure_file: undefined file for '$rule'" );
5613
if ( ! defined $set_not_exists ) { $set_not_exists = 0; }
5614
rdb_one_rule( $rule,
5616
if (! exists ${$PHsource}{$new_file} ) {
5617
if ( $set_not_exists ) {
5618
${$PHsource}{$new_file} = [0, -1, 0, '', 0];
5621
${$PHsource}{$new_file}
5622
= [fdb_get($new_file, $$Prun_time), '', 0];
5627
if (defined $new_from_rule ) {
5628
rdb_for_one_file( $rule, $new_file, sub{ $$Pfrom_rule = $new_from_rule; });
5630
} #END rdb_ensure_file
5632
#************************************************************
5634
sub rdb_remove_files {
5635
# rdb_remove_file( rule, file,... )
5636
# Removes file(s) for the rule.
5638
if (!$rule) { return; }
5640
rdb_one_rule( $rule,
5641
sub{ foreach (@files) { delete ${$PHsource}{$_}; } }
5643
} #END rdb_remove_files
5645
#************************************************************
5647
sub rdb_rule_exists {
5648
# Call rdb_rule_exists($rule): Returns whether rule exists.
5650
if (! $rule ) { return 0; }
5651
return exists $rule_db{$rule};
5652
} #END rdb_rule_exists
5654
#************************************************************
5656
sub rdb_file_exists {
5657
# Call rdb_file_exists($rule, $file):
5658
# Returns whether source file item in rule exists.
5659
local ( $rule, $file ) = @_;
5661
rdb_one_rule( $rule,
5662
sub{ $exists = exists( ${$PHsource}{$file} ) ? 1:0; }
5665
} #END rdb_file_exists
5667
#************************************************************
5669
sub rdb_update_gen_files {
5671
# Assumes rule context. Update source files of rule to current state.
5674
if ( exists $generated_exts_all{ ext_no_period($file) } ) {&rdb_update1;}
5677
} #END rdb_update_gen_files
5679
#************************************************************
5681
sub rdb_update_filesA {
5683
# Assumes rule context. Update source files of rule to current state.
5684
rdb_do_files( \&rdb_update1 );
5687
#************************************************************
5690
# Call: rdb_update1.
5691
# Assumes file context. Updates file data to correspond to
5692
# current file state on disk
5693
($$Ptime, $$Psize, $$Pmd5) = fdb_get($file);
5696
#************************************************************
5699
# Call: fdb_file1(rule, file, new_time, new_size, new_md5)
5700
# Sets file time, size and md5.
5703
local @new_file_data = @_;
5704
rdb_for_one_file( $rule, $file, sub{ ($$Ptime,$$Psize,$$Pmd5)=@new_file_data; } );
5707
#************************************************************
5709
sub rdb_dummy_file {
5710
# Returns file data for non-existent file
5711
# ==== Uses rule_db structure ====
5712
return (0, -1, 0, '');
5715
#************************************************************
5716
#************************************************************
5718
# Predefined subroutines for custom dependency
5720
sub cus_dep_delete_dest {
5721
# This subroutine is used for situations like epstopdf.sty, when
5722
# the destination (target) of the custom dependency invoking
5723
# this subroutine will be made by the primary run provided the
5724
# file (destination of the custom dependency, source of the
5725
# primary run) doesn't exist.
5726
# It is assumed that the resulting file will be read by the
5729
# Remove the destination file, to indicate it needs to be remade:
5731
# Arrange that the non-existent destination file is not treated as
5732
# an error. The variable changed here is a bit misnamed.
5734
# Ensure a primary run is done
5735
&cus_dep_require_primary_run;
5740
#************************************************************
5742
sub cus_dep_require_primary_run {
5743
# This subroutine is used for situations like epstopdf.sty, when
5744
# the destination (target) of the custom dependency invoking
5745
# this subroutine will be made by the primary run provided the
5746
# file (destination of the custom dependency, source of the
5747
# primary run) doesn't exist.
5748
# It is assumed that the resulting file will be read by the
5751
local $cus_dep_target = $$Pdest;
5752
# Loop over all rules and source files:
5754
sub { if ($file eq $cus_dep_target) {
5756
$$Pcorrect_after_primary = 1;
3246
5765
#************************************************************
3247
5766
#************************************************************