· 7 years ago · Dec 19, 2018, 01:26 AM
1#!/usr/bin/env perl
2
3# ?? Still need to fix bcf error issue.
4# Don't keep looping after error
5# pvc: Only re-run on USER FILE CHANGE.
6# See # ??????? BCF
7
8
9#!!!!!!!!??? Check @pwd_log
10
11
12# !!!!!!!!!! Don't forget to document $silence_logfile_warnings.!!!
13
14# N.B. !!!!!!!!!!! See 17 July 2012 comments !!!!!!!!!!!!!!!!!!
15
16# On a UNIX-like system, the above enables latexmk to run independently
17# of the location of the perl executable. This line relies on the
18# existence of the program /usr/bin/env
19# If there is a problem for any reason, you can replace the first line of
20# this file by:
21
22#!/usr/bin/perl -w
23
24# with the path of the perl executable adjusted for your system.
25
26use warnings;
27
28# Delete #??!! when working
29
30# See ?? <===============================
31
32## ?? Issues with clean-up
33## List of aux files deleted is those read, not those generated.
34## Other files are generated by (pdf)latex; should they be deleted?
35## (I have hooks for this).
36
37
38
39#=======================================
40
41#?? Force mode doesn't appear to do force (if error in latex file)
42#??? Get banner back in.
43#?? CORRECT DIAGNOSTICS ON CHANGED FILES IF THEY DIDN'T EXIST BEFORE
44#?? Further corrections to deal with disappeared source files for custom dependencies.
45# Message repeatedly appears about remake when source file of cusdep doesn't exist.
46#?? logfile w/o fdb file: don't set changed file, perhaps for generated exts.
47# Reconsider
48#?? Do proper run-stuff for bibtex, makeindex, cus-deps. OK I think
49# Parse and correctly find ist files
50
51
52# ATTEMPT TO ALLOW FILENAMES WITH SPACES:
53# (as of 1 Apr 2006, and then 14 Sep. 2007)
54
55# Problems:
56# A. Quoting filenames will not always work.
57# a. Under UNIX, quotes are legal in filenames, so when PERL
58# directly runs a binary, a quoted filename will be treated as
59# as a filename containing a quote character. But when it calls
60# a shell, the quotes are handled by the shell as quotes.
61# b. Under MSWin32, quotes are illegal filename characters, and tend
62# to be handled correctly.
63# c. But under cygwin, results are not so clear (there are many
64# combinations: native v. cygwin perl, native v cygwin programs
65# NT v. unix scripts, which shell is called.
66# B. TeX doesn't always handle filenames with spaces gracefully.
67# a. UNIX/LINUX: The version on gluon2 Mar 31, 2006 to Sep. 2007)
68# doesn't handle them at all. (TeX treats space as separator.)
69# b. At least some later versions actually do (Brad Miller e-mail,
70# Sep. 2007).
71# c. fptex [[e-TeXk, Version 3.141592-2.1 (Web2c 7.5.2)] does, on
72# my MSWin at home. In \input the filename must be in quotes.
73# d. Bibtex [BibTeX (Web2c 7.5.2) 0.99c on my MSWin system at home,
74# Sep. 2007] does not allow names of bibfiles to have spaces.
75# C. =====> Using the shell for command lines is not safe, since special
76# characters can cause lots of mayhem.
77# It will therefore be a good idea to sanitize filenames.
78#
79# I've sanitized all calls out:
80# a. system and exec use a single argument, which forces
81# use of shell, under all circumstances
82# Thus I can safely use quotes on filenames: They will be handled by
83# the shell under UNIX, and simply passed on to the program under MSWin32.
84# b. I reorganized Run, Run_Detached to use single command line
85# c. All calls to Run and Run_Detached have quoted filenames.
86# d. So if a space-free filename with wildcards is given on latexmk's
87# command line, and it globs to space-containing filename(s), that
88# works (fptex on home computer, native NT tex)
89# e. ====> But globbing fails: the glob function takes space as filename
90# separator. ====================
91
92#================= TO DO ================
93#
94# 1. See ?? ESPECIALLY $MSWin_fudge_break
95# 2. Check fudged conditions in looping and make_files
96# 3. Should not completely abort after a run that ends in failure from latex
97# Missing input files (including via custom dependency) should be checked for
98# a change in status
99# If sources for missing files from custom dependency
100# are available, then do a rerun
101# If sources of any kind become available rerun (esp. for pvc)
102# rerun
103# Must parse log_file after unsuccessful run of latex: it may give
104# information about missing files.
105# 4. Check file of bug reports and requests
106# 5. Rationalize bibtex warnings and errors. Two almost identical routines.
107# Should 1. Use single routine
108# 2. Convert errors to failure only in calling routine
109# 3. Save first warning/error.
110
111# ?? Use of generated_exts arrays and hashes needs rationalization
112
113# To do:
114# Rationalize again handling of include files.
115# Now I use kpsewhich to do searches, if file not found
116# (How do I avoid getting slowed down too much?)
117# Document the assumptions at each stage of processing algorithm.
118# Option to restart previewer automatically, if it dies under -pvc
119# Test for already running previewer gets wrong answer if another
120# process has the viewed file in its command line
121
122$my_name = 'latexmk';
123$My_name = 'Latexmk';
124$version_num = '4.55';
125$version_details = "$My_name, John Collins, 17 Jan. 2018";
126
127use Config;
128use File::Basename;
129use File::Copy;
130
131# If possible, use better glob, which does not use space as item separator.
132# It's either File::Glob::bsd_glob or File::Glob::glob
133# The first does not exist in old versions of Perl, while the second
134# is deprecated in more recent versions and will be removed
135$have_bsd_glob = 0;
136sub my_glob {
137 if ($have_bsd_glob) { return bsd_glob( $_[0] ); }
138 else { return glob( $_[0] ); }
139}
140use File::Glob;
141if ( eval{ File::Glob->import('bsd_glob'); 1; } ) {
142 # Success in importing bsd_glob
143 $have_bsd_glob = 1;
144}
145elsif ( eval{ File::Glob->import('glob'); 1; } ) {
146 warn "$My_name: I could not import File::Glob:bsd_glob, probably because your\n",
147 " Perl is too old. I have arranged to use the deprecated File::Glob:glob\n",
148 " instead.\n",
149 " WARNING: It may malfunction on clean up operation on filenames containing\n",
150 " spaces.\n";
151 $have_bsd_glob = 0;
152}
153else {
154 die "Could not import 'File::Glob:bsd_glob' or 'File::Glob:glob'\n";
155}
156
157use File::Path 2.08 qw( make_path );
158use FileHandle;
159use File::Find;
160use List::Util qw( max );
161use Cwd; # To be able to change cwd
162use Cwd "chdir"; # Ensure $ENV{PWD} tracks cwd
163use Digest::MD5;
164
165#use strict;
166
167# The following variables are assigned once and then used in symbolic
168# references, so we need to avoid warnings 'name used only once':
169use vars qw( $dvi_update_command $ps_update_command $pdf_update_command );
170
171# Translation of signal names to numbers and vv:
172%signo = ();
173@signame = ();
174if ( defined $Config{sig_name} ) {
175 $i = 0;
176 foreach $name (split('\s+', $Config{sig_name})) {
177 $signo{$name} = $i;
178 $signame[$i] = $name;
179 $i++;
180 }
181}
182else {
183 warn "Something wrong with the perl configuration: No signals?\n";
184}
185
186## Copyright John Collins 1998-2018
187## (username jcc8 at node psu.edu)
188## (and thanks to David Coppit (username david at node coppit.org)
189## for suggestions)
190## Copyright Evan McLean
191## (modifications up to version 2)
192## Copyright 1992 by David J. Musliner and The University of Michigan.
193## (original version)
194##
195## This program is free software; you can redistribute it and/or modify
196## it under the terms of the GNU General Public License as published by
197## the Free Software Foundation; either version 2 of the License, or
198## (at your option) any later version.
199##
200## This program is distributed in the hope that it will be useful,
201## but WITHOUT ANY WARRANTY; without even the implied warranty of
202## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
203## GNU General Public License for more details.
204##
205## You should have received a copy of the GNU General Public License
206## along with this program; if not, write to the Free Software
207## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
208##
209##
210##
211## NEW FEATURES, since v. 2.0:
212## 1. Correct algorithm for deciding how many times to run latex:
213## based on whether source file(s) change between runs
214## 2. Continuous preview works, and can be of ps file or dvi file
215## 3. pdf creation by pdflatex possible
216## 4. Defaults for commands are OS dependent.
217## 5. Parsing of log file instead of source file is used to
218## obtain dependencies, by default.
219##
220## Modification log from 9 Dec 2011 onwards in detail
221##
222## 12 Jan 2012 STILL NEED TO DOCUMENT some items below
223##
224## 17 Jan 2018 John Collins Version number to 4.55. Ready for release.
225## 15, 16 Jan 2018 John Collins Correct bug in measuring filetime offset.
226## 14 Jan 2018 John Collins Correct issue with possible filetime offset
227## on remote file system.
228## Define defaults for configuration variables
229## that didn't have defaults.
230## 12 Jan 2018 John Collins Implement pvc timeout
231## 10 Jan 2018 John Collins Ensure $search_path_separator is defined.
232## Set it to MS-Win value for msys.
233## 12 Dec 2017 John Collins Further correct bsd_glob fudge (to be in subroutine my_glob)
234## 8 Dec 2017 John Collins Correct bsd_glob fudge
235## 2 Dec 2017 John Collins Fudge on bsd_glob if it doesn't exist
236## 20 Nov 2017 John Collins Ver. 4.54
237##
238## 1998-2017, John Collins. Many improvements and fixes.
239## See CHANGE-log.txt for full list, and CHANGES for summary
240##
241## Modified by Evan McLean (no longer available for support)
242## Original script (RCS version 2.3) called "go" written by David J. Musliner
243##
244##-----------------------------------------------------------------------
245
246
247## Explicit exit codes:
248## 10 = bad command line arguments
249## 11 = file specified on command line not found
250## or other file not found
251## 12 = failure in some part of making files
252## 13 = error in initialization file
253## 20 = probable bug
254## or retcode from called program.
255
256
257# Line length in log file that indicates wrapping.
258# This number EXCLUDES line-end characters, and is one-based.
259# It is the parameter max_print_line in the TeX program. (tex.web)
260$log_wrap = 79;
261
262#########################################################################
263## Default parsing and file-handling settings
264
265## Array of reg-exps for patterns in log-file for file-not-found
266## Each item is the string in a regexp, without the enclosing slashes.
267## First parenthesized part is the filename.
268## Note the need to quote slashes and single right quotes to make them
269## appear in the regexp.
270## Add items by push, e.g.,
271## push @file_not_found, '^No data file found `([^\\\']*)\\\'';
272## will give match to line starting "No data file found `filename'"
273@file_not_found = (
274 '^No file\\s*(.*)\\.$',
275 '^\\! LaTeX Error: File `([^\\\']*)\\\' not found\\.',
276 '.*?:\\d*: LaTeX Error: File `([^\\\']*)\\\' not found\\.',
277 '^LaTeX Warning: File `([^\\\']*)\\\' not found',
278 '^Package .* [fF]ile `([^\\\']*)\\\' not found',
279 '^Package .* No file `([^\\\']*)\\\'',
280 'Error: pdflatex \(file ([^\)]*)\): cannot find image file',
281 ': File (.*) not found:\s*$',
282 '! Unable to load picture or PDF file \\\'([^\\\']+)\\\'.',
283);
284
285## Hash mapping file extension (w/o period, e.g., 'eps') to a single regexp,
286# whose matching by a line in a file with that extension indicates that the
287# line is to be ignored in the calculation of the hash number (md5 checksum)
288# for the file. Typically used for ignoring datestamps in testing whether
289# a file has changed.
290# Add items e.g., by
291# $hash_calc_ignore_pattern{'eps'} = '^%%CreationDate: ';
292# This makes the hash calculation for an eps file ignore lines starting with
293# '%%CreationDate: '
294# ?? Note that a file will be considered changed if
295# (a) its size changes
296# or (b) its hash changes
297# So it is useful to ignore lines in the hash calculation only if they
298# are of a fixed size (as with a date/time stamp).
299%hash_calc_ignore_pattern =();
300
301
302# Specification of templates for extra rules.
303# See subroutine rdb_make_rule_list for examples of rule templates.
304# See subroutine rdb_set_rules for how they get used to construct rules.
305# (Documentation obviously needs to be improved!)
306%extra_rule_spec = ();
307
308
309# Hooks for customized extra processing on aux files. The following
310# variable is an array of references to function. Each function is
311# invoked in turn when a line of an aux file is processed (if none
312# of the built-in actions have been done). On entry to the function,
313# the following variables are set:
314# $_ = current line of aux file
315# $rule = name of rule during the invocation of which, the aux file
316# was supposed to have been generated.
317@aux_hooks = ();
318
319#########################################################################
320## Default document processing programs, and related settings,
321## These are mostly the same on all systems.
322## Most of these variables represents the external command needed to
323## perform a certain action. Some represent switches.
324
325## Commands to invoke latex, pdflatex, etc
326$latex = 'latex %O %S';
327$pdflatex = 'pdflatex %O %S';
328$lualatex = 'lualatex %O %S';
329# xelatex is used to give xdv file, not pdf file
330$xelatex = 'xelatex -no-pdf %O %S';
331
332## Default switches:
333$latex_default_switches = '';
334$pdflatex_default_switches = '';
335$lualatex_default_switches = '';
336$xelatex_default_switches = '';
337
338## Switch(es) to make them silent:
339$latex_silent_switch = '-interaction=batchmode';
340$pdflatex_silent_switch = '-interaction=batchmode';
341$lualatex_silent_switch = '-interaction=batchmode';
342$xelatex_silent_switch = '-interaction=batchmode';
343
344# %input_extensions maps primary_rule_name to pointer to hash of file extensions
345# used for extensionless files specified in the source file by constructs
346# like \input{file} \includegraphics{file}
347# Could write
348#%input_extensions = ( 'latex' => { 'tex' => 1, 'eps' => 1 };,
349# 'pdflatex' => { 'tex' => 1, 'pdf' => 1, 'jpg' => 1, 'png' => 1 }; );
350# Instead we'll exercise the user-friendly access routines:
351add_input_ext( 'latex', 'tex', 'eps' );
352add_input_ext( 'pdflatex', 'tex', 'jpg', 'pdf', 'png' );
353add_input_ext( 'lualatex', 'tex', 'jpg', 'pdf', 'png' );
354add_input_ext( 'xelatex', 'tex', 'jpg', 'pdf', 'png' );
355#show_input_ext( 'latex' ); show_input_ext( 'pdflatex' );
356
357# Information about options to latex and pdflatex that latexmk will simply
358# pass through to (pdf)latex
359# Option without arg. maps to itself.
360# Option with arg. maps the option part to the full specification
361# e.g., -kpathsea-debug => -kpathsea-debug=NUMBER
362%allowed_latex_options = ();
363%allowed_latex_options_with_arg = ();
364foreach (
365 #####
366 # TeXLive options
367 "-draftmode switch on draft mode (generates no output PDF)",
368 "-enc enable encTeX extensions such as \\mubyte",
369 "-etex enable e-TeX extensions",
370 "-file-line-error enable file:line:error style messages",
371 "-no-file-line-error disable file:line:error style messages",
372 "-fmt=FMTNAME use FMTNAME instead of program name or a %& line",
373 "-halt-on-error stop processing at the first error",
374 "-interaction=STRING set interaction mode (STRING=batchmode/nonstopmode/\n".
375 " scrollmode/errorstopmode)",
376 "-ipc send DVI output to a socket as well as the usual\n".
377 " output file",
378 "-ipc-start as -ipc, and also start the server at the other end",
379 "-kpathsea-debug=NUMBER set path searching debugging flags according to\n".
380 " the bits of NUMBER",
381 "-mktex=FMT enable mktexFMT generation (FMT=tex/tfm/pk)",
382 "-no-mktex=FMT disable mktexFMT generation (FMT=tex/tfm/pk)",
383 "-mltex enable MLTeX extensions such as \charsubdef",
384 "-output-comment=STRING use STRING for DVI file comment instead of date\n".
385 " (no effect for PDF)",
386 "-output-format=FORMAT use FORMAT for job output; FORMAT is `dvi\" or `pdf\"",
387 "-parse-first-line enable parsing of first line of input file",
388 "-no-parse-first-line disable parsing of first line of input file",
389 "-progname=STRING set program (and fmt) name to STRING",
390 "-shell-escape enable \\write18{SHELL COMMAND}",
391 "-no-shell-escape disable \\write18{SHELL COMMAND}",
392 "-shell-restricted enable restricted \\write18",
393 "-src-specials insert source specials into the DVI file",
394 "-src-specials=WHERE insert source specials in certain places of\n".
395 " the DVI file. WHERE is a comma-separated value\n".
396 " list: cr display hbox math par parend vbox",
397 "-synctex=NUMBER generate SyncTeX data for previewers if nonzero",
398 "-translate-file=TCXNAME use the TCX file TCXNAME",
399 "-8bit make all characters printable by default",
400
401 #####
402 # MikTeX options not in TeXLive
403 "-alias=app pretend to be app",
404 "-buf-size=n maximum number of characters simultaneously present\n".
405 " in current lines",
406 "-c-style-errors C-style error messages",
407 "-disable-installer disable automatic installation of missing packages",
408 "-disable-pipes disable input (output) from (to) child processes",
409 "-disable-write18 disable the \\write18{command} construct",
410 "-dont-parse-first-line disable checking whether the first line of the main\n".
411 " input file starts with %&",
412 "-enable-enctex enable encTeX extensions such as \\mubyte",
413 "-enable-installer enable automatic installation of missing packages",
414 "-enable-mltex enable MLTeX extensions such as \charsubdef",
415 "-enable-pipes enable input (output) from (to) child processes",
416 "-enable-write18 fully enable the \\write18{command} construct",
417 "-error-line=n set the width of context lines on terminal error\n".
418 " messages",
419 "-extra-mem-bot=n set the extra size (in memory words) for large data\n".
420 " structures",
421 "-extra-mem-top=n set the extra size (in memory words) for chars,\n".
422 " tokens, et al",
423 "-font-max=n set the maximum internal font number",
424 "-font-mem-size=n set the size, in TeX memory words, of the font memory",
425 "-half-error-line=n set the width of first lines of contexts in terminal\n".
426 " error messages",
427 "-hash-extra=n set the extra space for the hash table of control\n".
428 " sequences",
429 "-job-time=file set the time-stamp of all output files equal to\n".
430 " file's time-stamp",
431 "-main-memory=n change the total size (in memory words) of the main\n".
432 " memory array",
433 "-max-in-open=n set the maximum number of input files and error\n".
434 " insertions that can be going on simultaneously",
435 "-max-print-line=n set the width of longest text lines output",
436 "-max-strings=n set the maximum number of strings",
437 "-nest-size=n set the maximum number of semantic levels\n".
438 " simultaneously active",
439 "-no-c-style-errors standard error messages",
440 "-param-size=n set the the maximum number of simultaneous macro\n".
441 " parameters",
442 "-pool-size=n set the maximum number of characters in strings",
443 "-record-package-usages=file record all package usages and write them into\n".
444 " file",
445 "-restrict-write18 partially enable the \\write18{command} construct",
446 "-save-size=n set the the amount of space for saving values\n".
447 " outside of current group",
448 "-stack-size=n set the maximum number of simultaneous input sources",
449 "-string-vacancies=n set the minimum number of characters that should be\n".
450 " available for the user's control sequences and font\n".
451 " names",
452 "-tcx=name process the TCX table name",
453 "-time-statistics show processing time statistics",
454 "-trace enable trace messages",
455 "-trace=tracestreams enable trace messages. The tracestreams argument is\n".
456 " a comma-separated list of trace stream names",
457 "-trie-size=n set the amount of space for hyphenation patterns",
458 "-undump=name use name as the name of the format to be used,\n".
459 " instead of the name by which the program was\n".
460 " called or a %& line.",
461
462 #####
463 # Options passed to (pdf)latex that have special processing by latexmk,
464 # so they are commented out here.
465 #-jobname=STRING set the job name to STRING
466 #-aux-directory=dir Set the directory dir to which auxiliary files are written
467 #-output-directory=DIR use existing DIR as the directory to write files in
468 #-quiet
469 #-recorder enable filename recorder
470 #
471 # Options with different processing by latexmk than (pdf)latex
472 #-help
473 #-version
474 #
475 # Options NOT used by latexmk
476 #-includedirectory=dir prefix dir to the search path
477 #-initialize become the INI variant of the compiler
478 #-ini be pdfinitex, for dumping formats; this is implicitly
479 # true if the program name is `pdfinitex'
480) {
481 if ( /^([^\s=]+)=/ ) {
482 $allowed_latex_options_with_arg{$1} = $_;
483 }
484 elsif ( /^([^\s=]+)\s/ ) {
485 $allowed_latex_options{$1} = $_;
486 }
487 else {
488 $allowed_latex_options{$_} = $_;
489 }
490}
491
492# Arrays of options that will be added to latex and pdflatex.
493# These need to be stored until after the command line parsing is finished,
494# in case the values of $latex and/or $pdflatex change after an option
495# is added.
496@extra_latex_options = ();
497@extra_pdflatex_options = ();
498@extra_lualatex_options = ();
499@extra_xelatex_options = ();
500
501
502## Command to invoke biber & bibtex
503$biber = 'biber %O %B';
504$bibtex = 'bibtex %O %B';
505# Switch(es) to make biber & bibtex silent:
506$biber_silent_switch = '--onlylog';
507$bibtex_silent_switch = '-terse';
508$bibtex_use = 1; # Whether to actually run bibtex to update bbl files.
509 # This variable is also used in deciding whether to
510 # delete bbl files in clean up operations.
511 # 0: Never run bibtex.
512 # Do NOT delete bbl files on clean up.
513 # 1: Run bibtex only if the bibfiles exists
514 # according to kpsewhich, and the bbl files
515 # appear to be out-of-date.
516 # Do NOT delete bbl files on clean up.
517 # 1.5: Run bibtex only if the bibfiles exists
518 # according to kpsewhich, and the bbl files
519 # appear to be out-of-date.
520 # Only delete bbl files on clean up if bibfiles exist.
521 # 2: Run bibtex when the bbl files are out-of-date
522 # Delete bbl files on clean up.
523 #
524 # In any event bibtex is only run if the log file
525 # indicates that the document uses bbl files.
526
527## Command to invoke makeindex
528$makeindex = 'makeindex %O -o %D %S';
529# Switch(es) to make makeinex silent:
530$makeindex_silent_switch = '-q';
531
532## Command to convert dvi file to pdf file directly:
533$dvipdf = 'dvipdf %O %S %D';
534# N.B. Standard dvipdf runs dvips and gs with their silent switch, so for
535# standard dvipdf $dvipdf_silent_switch is unneeded, but innocuous.
536# But dvipdfmx can be used instead, and it has a silent switch (-q).
537# So implementing $dvipdf_silent_switch is useful.
538
539$dvipdf_silent_switch = '-q';
540
541## Command to convert dvi file to ps file:
542$dvips = 'dvips %O -o %D %S';
543## Command to convert dvi file to ps file in landscape format:
544$dvips_landscape = 'dvips -tlandscape %O -o %D %S';
545# Switch(es) to get dvips to make ps file suitable for conversion to good pdf:
546# (If this is not used, ps file and hence pdf file contains bitmap fonts
547# (type 3), which look horrible under acroread. An appropriate switch
548# ensures type 1 fonts are generated. You can put this switch in the
549# dvips command if you prefer.)
550$dvips_pdf_switch = '-P pdf';
551# Switch(es) to make dvips silent:
552$dvips_silent_switch = '-q';
553
554## Command to convert ps file to pdf file:
555$ps2pdf = 'ps2pdf %O %S %D';
556
557## Command to convert xdv file to pdf file
558$xdvipdfmx = 'xdvipdfmx -o %D %O %S';
559$xdvipdfmx_silent_switch = '-q';
560
561
562## Command to search for tex-related files
563$kpsewhich = 'kpsewhich %S';
564
565## Command to run make:
566$make = 'make';
567
568##Printing:
569$print_type = 'auto'; # When printing, print the postscript file.
570 # Possible values: 'dvi', 'ps', 'pdf', 'auto', 'none'
571 # 'auto' ==> set print type according to the printable
572 # file(s) being made: priority 'ps', 'pdf', 'dvi'
573
574## Which treatment of default extensions and filenames with
575## multiple extensions is used, for given filename on
576## tex/latex's command line? See sub find_basename for the
577## possibilities.
578## Current tex's treat extensions like UNIX teTeX:
579$extension_treatment = 'unix';
580
581# Viewers. These are system dependent, so default to none:
582$pdf_previewer = $ps_previewer = $ps_previewer_landscape = $dvi_previewer = $dvi_previewer_landscape = "NONE";
583
584$dvi_update_signal = undef;
585$ps_update_signal = undef;
586$pdf_update_signal = undef;
587
588$dvi_update_command = undef;
589$ps_update_command = undef;
590$pdf_update_command = undef;
591
592$allow_subdir_creation = 1;
593
594$new_viewer_always = 0; # If 1, always open a new viewer in pvc mode.
595 # If 0, only open a new viewer if no previous
596 # viewer for the same file is detected.
597
598# Commands for printing are highly system dependent, so default to NONE:
599$lpr = 'NONE $lpr variable is not configured to allow printing of ps files';
600$lpr_dvi = 'NONE $lpr_dvi variable is not configured to allow printing of dvi files';
601$lpr_pdf = 'NONE $lpr_pdf variable is not configured to allow printing of pdf files';
602
603
604# The $pscmd below holds a **system-dependent** command to list running
605# processes. It is used to find the process ID of the viewer looking at
606# the current output file. The output of the command must include the
607# process number and the command line of the processes, since the
608# relevant process is identified by the name of file to be viewed.
609# Its use is not essential.
610$pscmd = 'NONE $pscmd variable is not configured to detect running processes';
611$pid_position = -1; # offset of PID in output of pscmd.
612 # Negative means I cannot use ps
613
614
615$quote_filenames = 1; # Quote filenames in external commands
616
617$del_dir = ''; # Directory into which cleaned up files are to be put.
618 # If $del_dir is '', just delete the files
619
620@rc_system_files = ();
621
622#########################################################################
623
624################################################################
625## Special variables for system-dependent fudges, etc.
626$log_file_binary = 0; # Whether to treat log file as binary
627 # Normally not, since the log file SHOULD be pure text.
628 # But Miktex 2.7 sometimes puts binary characters
629 # in it. (Typically in construct \OML ... after
630 # overfull box with mathmode.)
631 # Sometimes there is ctrl/Z, which is not only non-text,
632 # but is end-of-file marker for MS-Win in text mode.
633
634$MSWin_fudge_break = 1; # Give special treatment to ctrl/C and ctrl/break
635 # in -pvc mode under MSWin
636 # Under MSWin32 (at least with perl 5.8 and WinXP)
637 # when latexmk is running another program, and the
638 # user gives ctrl/C or ctrl/break, to stop the
639 # daughter program, not only does it reach
640 # the daughter, but also latexmk/perl, so
641 # latexmk is stopped also. In -pvc mode,
642 # this is not normally desired. So when the
643 # $MSWin_fudge_break variable is set,
644 # latexmk arranges to ignore ctrl/C and
645 # ctrl/break during processing of files;
646 # only the daughter programs receive them.
647 # This fudge is not applied in other
648 # situations, since then having latexmk also
649 # stopping because of the ctrl/C or
650 # ctrl/break signal is desirable.
651 # The fudge is not needed under UNIX (at least
652 # with Perl 5.005 on Solaris 8). Only the
653 # daughter programs receive the signal. In
654 # fact the inverse would be useful: In
655 # normal processing, as opposed to -pvc, if
656 # force mode (-f) is set, a ctrl/C is
657 # received by a daughter program does not
658 # also stop latexmk. Under tcsh, we get
659 # back to a command prompt, while latexmk
660 # keeps running in the background!
661
662## Substitute backslashes in file and directory names for
663## MSWin command line
664$MSWin_back_slash = 1;
665
666## Separator of elements in search_path. Default is unix value
667$search_path_separator = ':';
668
669
670# Directory for temporary files. Default to current directory.
671$tmpdir = ".";
672
673
674# When the aux_dir is on a network share (or the like), its system
675# time may differ from the system time on which latexmk is running.
676# This complicates the tests of whether particular files have been
677# made in a current run of a program or are left over from a previous
678# run. One test, which is needed under some situations, is that a
679# file was made on a previous run when the files modification time is
680# less than the system time when the program is started. (See
681# subroutine test_gen_file; this is only needed in a couple of
682# situations.) The comparison between file and system times must be
683# corrected if there is an offset between system times on the computer
684# running latexmk and the computer hosting the file system containing
685# aux_dir. The offset is measured in subroutine get_filetime_offset
686# by writing a temporary file; the test only needs to be done once.
687#
688# The following variables are used. Since the system-independent
689# values of system and file time are only accurate to a second (or 2
690# seconds for FAT file systems), the offset is also accurate only to a
691# second or two. So thresholds are needed below which differences
692# are insignificant.
693#
694# Note that the making or not making of a file is controlled by the
695# state of the document being compiled and by latexmk's configuration.
696# So a file that is left over from a previous run and not overwritten
697# on the current run will have a file time at least many seconds less
698# than the current time, corresponding to the time scale for a human
699# run-edit-run cycle.
700#
701$filetime_offset_measured = 0; # Measurement not yet done.
702$filetime_offset = 0; # Filetime relative to system time.
703$filetime_causality_threshold = 5; # Threshold for detection of left-over file.
704 # Should be non-negative always, and should
705 # be bigger than 2 secs if a remote
706 # filesystem or network share is used.
707$filetime_offset_report_threshold = 30; # Threshold beyond which filetime offsets
708 # are reported; large offsets indicate
709 # incorrect system time on at least one system.
710
711
712################################################################
713
714
715# System-dependent overrides:
716# Currently, the cases I have tests for are: MSWin32, cygwin, linux and
717# darwin, msys, with the main complications being for MSWin32 and cygwin.
718# Further special treatment may also be useful for MSYS (for which $^O reports
719# "msys"). This is another *nix-emulation/system for MSWindows. At
720# present it is treated as unix-like, but the environment variables
721# are those of Windows. (The test for USERNAME as well as USER was
722# to make latexmk work under MSYS's perl.)
723#
724if ( $^O eq "MSWin32" ) {
725# Pure MSWindows configuration
726 ## Configuration parameters:
727
728 ## Use first existing case for $tmpdir:
729 $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.';
730 $log_file_binary = 1; # Protect against ctrl/Z in log file from
731 # Miktex 2.7.
732
733 ## List of possibilities for the system-wide initialization file.
734 ## The first one found (if any) is used.
735 @rc_system_files = ( "C:/latexmk/LatexMk", "C:/latexmk/latexmkrc" );
736
737 $search_path_separator = ';'; # Separator of elements in search_path
738
739 # For a pdf-file, "start x.pdf" starts the pdf viewer associated with
740 # pdf files, so no program name is needed:
741 $pdf_previewer = 'start %O %S';
742 $ps_previewer = 'start %O %S';
743 $ps_previewer_landscape = $ps_previewer;
744 $dvi_previewer = 'start %O %S';
745 $dvi_previewer_landscape = "$dvi_previewer";
746 # Viewer update methods:
747 # 0 => auto update: viewer watches file (e.g., gv)
748 # 1 => manual update: user must do something: e.g., click on window.
749 # (e.g., ghostview, MSWIN previewers, acroread under UNIX)
750 # 2 => send signal. Number of signal in $dvi_update_signal,
751 # $ps_update_signal, $pdf_update_signal
752 # 3 => viewer can't update, because it locks the file and the file
753 # cannot be updated. (acroread under MSWIN)
754 # 4 => run a command to force the update. The commands are
755 # specified by the variables $dvi_update_command,
756 # $ps_update_command, $pdf_update_command
757 $dvi_update_method = 1;
758 $ps_update_method = 1;
759 $pdf_update_method = 3; # acroread locks the pdf file
760}
761elsif ( $^O eq "cygwin" ) {
762 # The problem is a mixed MSWin32 and UNIX environment.
763 # Perl decides the OS is cygwin in two situations:
764 # 1. When latexmk is run from a cygwin shell under a cygwin
765 # environment. Perl behaves in a UNIX way. This is OK, since
766 # the user is presumably expecting UNIXy behavior.
767 # 2. When CYGWIN exectuables are in the path, but latexmk is run
768 # from a native NT shell. Presumably the user is expecting NT
769 # behavior. But perl behaves more UNIXy. This causes some
770 # clashes.
771 # The issues to handle are:
772 # 1. Perl sees both MSWin32 and cygwin filenames. This is
773 # normally only an advantage.
774 # 2. Perl uses a UNIX shell in the system command
775 # This is a nasty problem: under native NT, there is a
776 # start command that knows about NT file associations, so that
777 # we can do, e.g., (under native NT) system("start file.pdf");
778 # But this won't work when perl has decided the OS is cygwin,
779 # even if it is invoked from a native NT command line. An
780 # NT command processor must be used to deal with this.
781 # 3. External executables can be native NT (which only know
782 # NT-style file names) or cygwin executables (which normally
783 # know both cygwin UNIX-style file names and NT file names,
784 # but not always; some do not know about drive names, for
785 # example).
786 # Cygwin executables for tex and latex may only know cygwin
787 # filenames.
788 # 4. The BIBINPUTS environment variables may be
789 # UNIX-style or MSWin-style depending on whether native NT or
790 # cygwin executables are used. They are therefore parsed
791 # differently. Here is the clash:
792 # a. If a user is running under an NT shell, is using a
793 # native NT installation of tex (e.g., fptex or miktex),
794 # but has the cygwin executables in the path, then perl
795 # detects the OS as cygwin, but the user needs NT
796 # behavior from latexmk.
797 # b. If a user is running under an UNIX shell in a cygwin
798 # environment, and is using the cygwin installation of
799 # tex, then perl detects the OS as cygwin, and the user
800 # needs UNIX behavior from latexmk.
801 # Latexmk has no way of detecting the difference. The two
802 # situations may even arise for the same user on the same
803 # computer simply by changing the order of directories in the
804 # path environment variable
805
806
807 ## Configuration parameters: We'll assume native NT executables.
808 ## The user should override if they are not.
809
810 # This may fail: perl converts MSWin temp directory name to cygwin
811 # format. Names containing this string cannot be handled by native
812 # NT executables.
813 $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.';
814
815 ## List of possibilities for the system-wide initialization file.
816 ## The first one found (if any) is used.
817 ## We could stay with MSWin files here, since cygwin perl understands them
818 ## @rc_system_files = ( 'C:/latexmk/LatexMk', 'C:/latexmk/latexmkrc' );
819 ## But they are deprecated in v. 1.7. So use the UNIX version, prefixed
820 ## with a cygwin equivalent of the MSWin location
821 ## In addition, we need to add the same set of possible locations as with
822 ## unix, so that the user use a unix-style setup.
823 @rc_system_files = ();
824 foreach ( 'LatexMk', 'latexmkrc' ) {
825 push @rc_system_files,
826 ( "/cygdrive/c/latexmk/$_",
827 "/opt/local/share/latexmk/$_",
828 "/usr/local/share/latexmk/$_",
829 "/usr/local/lib/latexmk/$_" );
830 }
831 $search_path_separator = ';'; # Separator of elements in search_path
832 # This is tricky. The search_path_separator depends on the kind
833 # of executable: native NT v. cygwin.
834 # So the user will have to override this.
835
836 # We will assume that files can be viewed by native NT programs.
837 # Then we must fix the start command/directive, so that the
838 # NT-native start command of a cmd.exe is used.
839 # For a pdf-file, "start x.pdf" starts the pdf viewer associated with
840 # pdf files, so no program name is needed:
841 $start_NT = "cmd /c start \"\"";
842 $pdf_previewer = "$start_NT %O %S";
843 $ps_previewer = "$start_NT %O %S";
844 $ps_previewer_landscape = $ps_previewer;
845 $dvi_previewer = "$start_NT %O %S";
846 $dvi_previewer_landscape = $dvi_previewer;
847 # Viewer update methods:
848 # 0 => auto update: viewer watches file (e.g., gv)
849 # 1 => manual update: user must do something: e.g., click on window.
850 # (e.g., ghostview, MSWIN previewers, acroread under UNIX)
851 # 2 => send signal. Number of signal in $dvi_update_signal,
852 # $ps_update_signal, $pdf_update_signal
853 # 3 => viewer can't update, because it locks the file and the file
854 # cannot be updated. (acroread under MSWIN)
855 $dvi_update_method = 1;
856 $ps_update_method = 1;
857 $pdf_update_method = 3; # acroread locks the pdf file
858}
859elsif ( $^O eq "msys" ) {
860 $search_path_separator = ';'; # Separator of elements in search_path
861 # I think MS-Win value is OK, since
862 # msys is running under MS-Win
863 $pdf_previewer = q[sh -c 'start %S'];
864 $ps_previewer = q[sh -c 'start %S'];
865 $dvi_previewer = q[sh -c 'start %S'];
866 $ps_previewer_landscape = $ps_previewer;
867 $dvi_previewer_landscape = "$dvi_previewer";
868}
869else {
870 # Assume anything else is UNIX or clone
871 # Do special cases (e.g., linux, darwin (i.e., OS-X)) inside this block.
872
873 ## Use first existing case for $tmpdir:
874 $tmpdir = $ENV{TMPDIR} || '/tmp';
875
876 ## List of possibilities for the system-wide initialization file.
877 ## The first one found (if any) is used.
878 ## Normally on a UNIX it will be in a subdirectory of /opt/local/share or
879 ## /usr/local/share, depending on the local conventions.
880 ## But /usr/local/lib/latexmk is put in the list for
881 ## compatibility with older versions of latexmk.
882 @rc_system_files = ();
883 foreach ( 'LatexMk', 'latexmkrc' ) {
884 push @rc_system_files,
885 ( "/opt/local/share/latexmk/$_",
886 "/usr/local/share/latexmk/$_",
887 "/usr/local/lib/latexmk/$_" );
888 }
889 $search_path_separator = ':'; # Separator of elements in search_path
890
891 $dvi_update_signal = $signo{USR1}
892 if ( defined $signo{USR1} ); # Suitable for xdvi
893 $ps_update_signal = $signo{HUP}
894 if ( defined $signo{HUP} ); # Suitable for gv
895 $pdf_update_signal = $signo{HUP}
896 if ( defined $signo{HUP} ); # Suitable for gv
897 ## default document processing programs.
898 # Viewer update methods:
899 # 0 => auto update: viewer watches file (e.g., gv)
900 # 1 => manual update: user must do something: e.g., click on window.
901 # (e.g., ghostview, MSWIN previewers, acroread under UNIX)
902 # 2 => send signal. Number of signal in $dvi_update_signal,
903 # $ps_update_signal, $pdf_update_signal
904 # 3 => viewer can't update, because it locks the file and the file
905 # cannot be updated. (acroread under MSWIN)
906 # 4 => Run command to update. Command in $dvi_update_command,
907 # $ps_update_command, $pdf_update_command.
908 $dvi_previewer = 'start xdvi %O %S';
909 $dvi_previewer_landscape = 'start xdvi -paper usr %O %S';
910 if ( defined $dvi_update_signal ) {
911 $dvi_update_method = 2; # xdvi responds to signal to update
912 } else {
913 $dvi_update_method = 1;
914 }
915# if ( defined $ps_update_signal ) {
916# $ps_update_method = 2; # gv responds to signal to update
917# $ps_previewer = 'start gv -nowatch';
918# $ps_previewer_landscape = 'start gv -swap -nowatch';
919# } else {
920# $ps_update_method = 0; # gv -watch watches the ps file
921# $ps_previewer = 'start gv -watch';
922# $ps_previewer_landscape = 'start gv -swap -watch';
923# }
924 # Turn off the fancy options for gv. Regular gv likes -watch etc
925 # GNU gv likes --watch etc. User must configure
926 $ps_update_method = 0; # gv -watch watches the ps file
927 $ps_previewer = 'start gv %O %S';
928 $ps_previewer_landscape = 'start gv -swap %O %S';
929 $pdf_previewer = 'start acroread %O %S';
930 $pdf_update_method = 1; # acroread under unix needs manual update
931 $lpr = 'lpr %O %S'; # Assume lpr command prints postscript files correctly
932 $lpr_dvi =
933 'NONE $lpr_dvi variable is not configured to allow printing of dvi files';
934 $lpr_pdf =
935 'NONE $lpr_pdf variable is not configured to allow printing of pdf files';
936 # The $pscmd below holds a command to list running processes. It
937 # is used to find the process ID of the viewer looking at the
938 # current output file. The output of the command must include the
939 # process number and the command line of the processes, since the
940 # relevant process is identified by the name of file to be viewed.
941 # Uses:
942 # 1. In preview_continuous mode, to save running a previewer
943 # when one is already running on the relevant file.
944 # 2. With xdvi in preview_continuous mode, xdvi must be
945 # signalled to make it read a new dvi file.
946 #
947 # The following works on Solaris, LINUX, HP-UX, IRIX
948 # Use -f to get full listing, including command line arguments.
949 # Use -u $ENV{USER} to get all processes started by current user (not just
950 # those associated with current terminal), but none of other users'
951 # processes.
952 # However, the USER environment variable may not exist. Windows uses
953 # USERNAME instead. (And this propagates to a situation of
954 # unix-emulation software running under Windows.)
955 if ( exists $ENV{USER} ) {
956 $pscmd = "ps -f -u $ENV{USER}";
957 }
958 elsif ( exists $ENV{USERNAME} ) {
959 $pscmd = "ps -f -u $ENV{USERNAME}";
960 }
961 else {
962 $pscmd = "ps -f";
963 }
964 $pid_position = 1; # offset of PID in output of pscmd; first item is 0.
965 if ( $^O eq "linux" ) {
966 # Ps on Redhat (at least v. 7.2) appears to truncate its output
967 # at 80 cols, so that a long command string is truncated.
968 # Fix this with the --width option. This option works under
969 # other versions of linux even if not necessary (at least
970 # for SUSE 7.2).
971 # However the option is not available under other UNIX-type
972 # systems, e.g., Solaris 8.
973 # But (19 Aug 2010), the truncation doesn't happen on RHEL4 and 5,
974 # unless the output is written to a terminal. So the --width
975 # option is now unnecessary
976 # $pscmd = "ps --width 200 -f -u $ENV{USER}";
977 }
978 elsif ( $^O eq "darwin" ) {
979 # OS-X on Macintosh
980 # open starts command associated with a file.
981 # For pdf, this is set by default to OS-X's preview, which is suitable.
982 # Manual update is simply by clicking on window etc, which is OK.
983 # For ps, this is set also to preview. This works, but since it
984 # converts the file to pdf and views the pdf file, it doesn't
985 # see updates, and a refresh cannot be done. This is far from
986 # optimal.
987 # For a full installation of MacTeX, which is probably the most common
988 # on OS-X, an association is created between dvi files and TeXShop.
989 # This also converts the file to pdf, so again while it works, it
990 # does not deal with changed dvi files, as far as I can see.
991 $pdf_previewer = 'open %S';
992 $pdf_update_method = 1; # manual
993 $dvi_previewer = $dvi_previewer_landscape = 'NONE';
994 $ps_previewer = $ps_previewer_landscape = 'NONE';
995 # Others
996 $lpr_pdf = 'lpr %O %S';
997 $pscmd = "ps -ww -u $ENV{USER}";
998 }
999}
1000
1001## default parameters
1002$auto_rc_use = 1; # Whether to read rc files automatically
1003$max_repeat = 5; # Maximum times I repeat latex. Normally
1004 # 3 would be sufficient: 1st run generates aux file,
1005 # 2nd run picks up aux file, and maybe toc, lof which
1006 # contain out-of-date information, e.g., wrong page
1007 # references in toc, lof and index, and unresolved
1008 # references in the middle of lines. But the
1009 # formatting is more-or-less correct. On the 3rd
1010 # run, the page refs etc in toc, lof, etc are about
1011 # correct, but some slight formatting changes may
1012 # occur, which mess up page numbers in the toc and lof,
1013 # Hence a 4th run is conceivably necessary.
1014 # At least one document class (JHEP.cls) works
1015 # in such a way that a 4th run is needed.
1016 # We allow an extra run for safety for a
1017 # maximum of 5. Needing further runs is
1018 # usually an indication of a problem; further
1019 # runs may not resolve the problem, and
1020 # instead could cause an infinite loop.
1021$clean_ext = ""; # space separated extensions of files that are
1022 # to be deleted when doing cleanup, beyond
1023 # standard set
1024$clean_full_ext = ""; # space separated extensions of files that are
1025 # to be deleted when doing cleanup_full, beyond
1026 # standard set and those in $clean_ext
1027@cus_dep_list = (); # Custom dependency list
1028@default_files = ( '*.tex' ); # Array of LaTeX files to process when
1029 # no files are specified on the command line.
1030 # Wildcards allowed
1031 # Best used for project specific files.
1032@default_excluded_files = ( );
1033 # Array of LaTeX files to exclude when using
1034 # @default_files, i.e., when no files are specified
1035 # on the command line.
1036 # Wildcards allowed
1037 # Best used for project specific files.
1038$texfile_search = ""; # Specification for extra files to search for
1039 # when no files are specified on the command line
1040 # and the @default_files variable is empty.
1041 # Space separated, and wildcards allowed.
1042 # These files are IN ADDITION to *.tex in current
1043 # directory.
1044 # This variable is obsolete, and only in here for
1045 # backward compatibility.
1046
1047$fdb_ext = 'fdb_latexmk'; # Extension for the file for latexmk's
1048 # file-database
1049 # Make it long to avoid possible collisions.
1050$fdb_ver = 3; # Version number for kind of fdb_file.
1051
1052$jobname = ''; # Jobname: as with current tex, etc indicates
1053 # basename of generated files.
1054 # Defined so that --jobname=STRING on latexmk's
1055 # command line has same effect as with current
1056 # tex, etc. (If $jobname is non-empty, then
1057 # the --jobname=... option is used on tex.)
1058$out_dir = ''; # Directory for output files.
1059 # Cf. --output-directory of current (pdf)latex
1060$aux_dir = ''; # Directory for aux files (log, aux, etc).
1061 # Cf. --aux-directory of current (pdf)latex in MiKTeX.
1062
1063
1064## default flag settings.
1065$recorder = 1; # Whether to use recorder option on latex/pdflatex
1066$silent = 0; # Silence latex's messages?
1067$silence_logfile_warnings = 0; # Do list warnings in log file
1068$kpsewhich_show = 0; # Show calls to and results from kpsewhich
1069$landscape_mode = 0; # default to portrait mode
1070$analyze_input_log_always = 1; # Always analyze .log for input files in the
1071 # <...> and (...) constructions. Otherwise, only
1072 # do the analysis when fls file doesn't exist or is
1073 # out of date.
1074 # Under normal circumstances, the data in the fls file
1075 # is reliable, and the test of the log file gets lots
1076 # of false positives; usually $analyze_input_log_always
1077 # is best set to zero. But the test of the log file
1078 # is needed at least in the following situation:
1079 # When a user needs to persuade latexmk that a certain
1080 # file is a source file, and latexmk doesn't otherwise
1081 # find it. User code causes line with (...) to be
1082 # written to log file. One important case is for
1083 # lualatex, which doesn't always generate lines in the
1084 # .fls file for input lua files. (The situation with
1085 # lualatex is HIGHLY version dependent, e.g., between
1086 # 2016 and 2017.)
1087 # To keep backward compatibility with older versions
1088 # of latexmk, the default is to set
1089 # $analyze_input_log_always to 1.
1090
1091# The following two arrays contain lists of extensions (without
1092# period) for files that are read in during a (pdf)LaTeX run but that
1093# are generated automatically from the previous run, as opposed to
1094# being user generated files (directly or indirectly from a custom
1095# dependency). These files get two kinds of special treatment:
1096# 1. In clean up, where depending on the kind of clean up, some
1097# or all of these generated files are deleted.
1098# (Note that special treatment is given to aux files.)
1099# 2. In analyzing the results of a run of (pdf)LaTeX, to
1100# determine if another run is needed. With an error free run,
1101# a rerun should be provoked by a change in any source file,
1102# whether a user file or a generated file. But with a run
1103# that ends in an error, only a change in a user file during
1104# the run (which might correct the error) should provoke a
1105# rerun, but a change in a generated file should not.
1106# These arrays can be user-configured.
1107
1108@generated_exts = ( 'aux', 'bcf', 'fls', 'idx', 'ind', 'lof', 'lot',
1109 'out', 'toc' );
1110 # N.B. 'out' is generated by hyperref package
1111
1112# Which kinds of file do I have requests to make?
1113# If no requests at all are made, then I will make dvi file
1114# If particular requests are made then other files may also have to be
1115# made. E.g., ps file requires a dvi file
1116$dvi_mode = 0; # No dvi file requested
1117$postscript_mode = 0; # No postscript file requested
1118$pdf_mode = 0; # No pdf file requested to be made by pdflatex
1119 # Possible values:
1120 # 0 don't create pdf file
1121 # 1 to create pdf file by pdflatex
1122 # 2 to create pdf file by ps2pdf
1123 # 3 to create pdf file by dvipdf
1124 # 4 to create pdf file by lualatex
1125 # 5 to create pdf file by xelatex + xdvipdfmx
1126$view = 'default'; # Default preview is of highest of dvi, ps, pdf
1127$sleep_time = 2; # time to sleep b/w checks for file changes in -pvc mode
1128$banner = 0; # Non-zero if we have a banner to insert
1129$banner_scale = 220; # Original default scale
1130$banner_intensity = 0.95; # Darkness of the banner message
1131$banner_message = 'DRAFT'; # Original default message
1132$do_cd = 0; # Do not do cd to directory of source file.
1133 # Thus behave like latex.
1134$dependents_list = 0; # Whether to display list(s) of dependencies
1135$dependents_phony = 0; # Whether list(s) of dependencies includes phony targets
1136 # (as with 'gcc -MP').
1137$deps_file = '-'; # File for dependency list output. Default stdout.
1138$rules_list = 0; # Whether to display list(s) of dependencies
1139@dir_stack = (); # Stack of pushed directories, each of form of
1140 # pointer to array [ cwd, good_cwd ], where
1141 # good_cwd differs from cwd by being converted
1142 # to native MSWin path when cygwin is used.
1143$cleanup_mode = 0; # No cleanup of nonessential LaTex-related files.
1144 # $cleanup_mode = 0: no cleanup
1145 # $cleanup_mode = 1: full cleanup
1146 # $cleanup_mode = 2: cleanup except for dvi,
1147 # dviF, pdf, ps, psF & xdv
1148$cleanup_fdb = 0; # No removal of file for latexmk's file-database
1149$cleanup_only = 0; # When doing cleanup, do not go on to making files
1150$cleanup_includes_generated = 0;
1151 # Determines whether cleanup deletes files generated by
1152 # custom dependencies
1153$cleanup_includes_cusdep_generated = 0;
1154 # Determines whether cleanup deletes files generated by
1155 # (pdf)latex (found from \openout lines in log file).
1156$diagnostics = 0;
1157$dvi_filter = ''; # DVI filter command
1158$ps_filter = ''; # Postscript filter command
1159
1160$force_mode = 0; # =1 to force processing past errors
1161$go_mode = 0; # =1 to force processing regardless of time-stamps
1162 # =2 full clean-up first
1163$preview_mode = 0;
1164$preview_continuous_mode = 0;
1165$printout_mode = 0; # Don't print the file
1166
1167## Control pvc inactivity timeout:
1168$pvc_timeout = 0;
1169$pvc_timeout_mins = 30;
1170
1171$show_time = 0;
1172@timings = ();
1173$processing_time1 = processing_time();
1174
1175$use_make_for_missing_files = 0; # Whether to use make to try to make missing files.
1176
1177# Do we make view file in temporary then move to final destination?
1178# (To avoid premature updating by viewer).
1179$always_view_file_via_temporary = 0; # Set to 1 if viewed file is always
1180 # made through a temporary.
1181$pvc_view_file_via_temporary = 1; # Set to 1 if only in -pvc mode is viewed
1182 # file made through a temporary.
1183
1184# State variables initialized here:
1185
1186$updated = 0; # Flags when something has been remade
1187 # Used to allow convenient user message in -pvc mode
1188$waiting = 0; # Flags whether we are in loop waiting for an event
1189 # Used to avoid unnecessary repeated o/p in wait loop
1190
1191# Used for some results of parsing log file:
1192$reference_changed = 0;
1193$mult_defined = 0;
1194$bad_reference = 0;
1195$bad_citation = 0;
1196
1197# Cache of expensive-to-compute state variables, e.g., cwd in form
1198# fixed to deal with cygwin issues.
1199%cache = ();
1200&cache_good_cwd;
1201
1202# Set search paths for includes.
1203# Set them early so that they can be overridden
1204$BIBINPUTS = $ENV{'BIBINPUTS'};
1205if (!$BIBINPUTS) { $BIBINPUTS = '.'; }
1206
1207# Convert search paths to arrays:
1208# If any of the paths end in '//' then recursively search the
1209# directory. After these operations, @BIBINPUTS should
1210# have all the directories that need to be searched
1211
1212@BIBINPUTS = find_dirs1( $BIBINPUTS );
1213
1214
1215######################################################################
1216######################################################################
1217#
1218# ??? UPDATE THE FOLLOWING!!
1219#
1220# We will need to determine whether source files for runs of various
1221# programs are out of date. In a normal situation, this is done by
1222# asking whether the times of the source files are later than the
1223# destination files. But this won't work for us, since a common
1224# situation is that a file is written on one run of latex, for
1225# example, and read back in on the next run (e.g., an .aux file).
1226# Some situations of this kind are standard in latex generally; others
1227# occur with particular macro packages or with particular
1228# postprocessors.
1229#
1230# The correct criterion for whether a source is out-of-date is
1231# therefore NOT that its modification time is later than the
1232# destination file, but whether the contents of the source file have
1233# changed since the last successful run. This also handles the case
1234# that the user undoes some changes to a source file by replacing the
1235# source file by reverting to an earlier version, which may well have
1236# an older time stamp. Since a direct comparison of old and new files
1237# would involve storage and access of a large number of backup files,
1238# we instead use the md5 signature of the files. (Previous versions
1239# of latexmk used the backup file method, but restricted to the case
1240# of .aux and .idx files, sufficient for most, but not all,
1241# situations.)
1242#
1243# We will have a database of (time, size, md5) for the relevant
1244# files. If the time and size of a file haven't changed, then the file
1245# is assumed not to have changed; this saves us from having to
1246# determine its md5 signature, which would involve reading the whole
1247# file, which is naturally time-consuming, especially if network file
1248# access to a server is needed, and many files are involved, when most
1249# of them don't change. It is of course possible to change a file
1250# without changing its size, but then to adjust its timestamp
1251# to what it was previously; this requires a certain amount of
1252# perversity. We can safely assume that if the user edits a file or
1253# changes its contents, then the file's timestamp changes. The
1254# interesting case is that the timestamp does change, because the file
1255# has actually been written to, but that the contents do not change;
1256# it is for this that we use the md5 signature. However, since
1257# computing the md5 signature involves reading the whole file, which
1258# may be large, we should avoid computing it more than necessary.
1259#
1260# So we get the following structure:
1261#
1262# 1. For each relevant run (latex, pdflatex, each instance of a
1263# custom dependency) we have a database of the state of the
1264# source files that were last used by the run.
1265# 2. On an initial startup, the database for a primary tex file
1266# is read that was created by a previous run of latex or
1267# pdflatex, if this exists.
1268# 3. If the file doesn't exist, then the criterion for
1269# out-of-dateness for an initial run is that it goes by file
1270# timestamps, as in previous versions of latexmk, with due
1271# (dis)regard to those files that are known to be generated by
1272# latex and re-read on the next run.
1273# 4. Immediately before a run, the database is updated to
1274# represent the current conditions of the run's source files.
1275# 5. After the run, it is determined whether any of the source
1276# files have changed. This covers both files written by the
1277# run, which are therefore in a dependency loop, and files that
1278# the user may have updated during the run. (The last often
1279# happens when latex takes a long time, for a big document,
1280# and the user makes edits before latex has finished. This is
1281# particularly prevalent when latexmk is used with
1282# preview-continuous mode.)
1283# 6. In the case of latex or pdflatex, the custom dependencies
1284# must also be checked and redone if out-of-date.
1285# 7. If any source files have changed, the run is redone,
1286# starting at step 1.
1287# 8. There is naturally a limit on the number of reruns, to avoid
1288# infinite loops from bugs and from pathological or unforeseen
1289# conditions.
1290# 9. After the run is done, the run's file database is updated.
1291# (By hypothesis, the sizes and md5s are correct, if the run
1292# is successful.)
1293# 10. To allow reuse of data from previous runs, the file database
1294# is written to a file after every complete set of passes
1295# through latex or pdflatex. (Note that there is separate
1296# information for latex and pdflatex; the necessary
1297# information won't coincide: Out-of-dateness for the files
1298# for each program concerns the properties of the files when
1299# the other program was run, and the set of source files could
1300# be different, e.g., for graphics files.)
1301#
1302# We therefore maintain the following data structures.:
1303#
1304# a. For each run (latex, pdflatex, each custom dependency) a
1305# database is maintained. This is a hash from filenames to a
1306# reference to an array: [time, size, md5]. The semantics of
1307# the database is that it represents the state of the source
1308# files used in the run. During a run it represents the state
1309# immediately before the run; after a run, with all reruns, it
1310# represents the state of the files used, modified by having
1311# the latest timestamps for generated files.
1312# b. There is a global database for all files, which represents
1313# the current state. This saves having to recompute the md5
1314# signatures of a changed file used in more than one run
1315# (e.g., latex and pdflatex).
1316# c. Each of latex and pdflatex has a list of the relevant custom
1317# dependencies.
1318#
1319# In all the following a fdb-hash is a hash of the form:
1320# filename -> [time, size, md5]
1321# If a file is found to disappear, its entry is removed from the hash.
1322# In returns from fdb access routines, a size entry of -1 indicates a
1323# non-existent file.
1324
1325
1326# List of known rules. Rule types: primary,
1327# external (calls program), internal (calls routine), cusdep.
1328
1329%possible_primaries = ( 'latex' => 'primary', 'pdflatex' => 'primary',
1330 'lualatex' => 'primary', 'xelatex' => 'primary' );
1331%primaries = (); # Hash of rules for primary part of make. Keys are
1332 # currently 'latex', 'pdflatex' or both; also 'lualatex'
1333 # and 'xelatex'. Value is currently irrelevant.
1334 # Use hash for ease of lookup
1335 # Make remove this later, if use rdb_makeB
1336
1337# Hashes, whose keys give names of particular kinds of rule. We use
1338# hashes for ease of lookup.
1339%possible_one_time = ( 'view' => 1, 'print' => 1, 'update_view' => 1, );
1340%requested_filerules = (); # Hash for rules corresponding to requested files.
1341 # The keys are the rulenames and the value is
1342 # currently irrelevant.
1343%one_time = (); # Hash for requested one-time-only rules, currently
1344 # possible values 'print' and 'view'.
1345
1346
1347%rule_db = (); # Database of all rules:
1348 # Hash: rulename -> [array of rule data]
1349 # Rule data:
1350 # 0: [ cmd_type, ext_cmd, int_cmd, test_kind,
1351 # source, dest, base,
1352 # out_of_date, out_of_date_user,
1353 # time_of_last_run, time_of_last_file_check,
1354 # changed
1355 # last_result, last_message,
1356 # default_extra_generated
1357 # ]
1358 # where
1359 # cmd_type is 'primary', 'external', or 'cusdep'
1360 # ext_cmd is string for associated external command
1361 # with substitutions (%D for destination, %S
1362 # for source, %B for base of current rule,
1363 # %R for base of primary tex file, %T for
1364 # texfile name, %O for options,
1365 # %Y for $aux_dir1, and %Z for $out_dir1
1366 # int_cmd specifies any internal command to be
1367 # used to implement the application of the
1368 # rule. If this is present, it overrides
1369 # the external command, and it is the
1370 # responsibility of the perl subroutine
1371 # specified in intcmd to execute the
1372 # external command if this is appropriate.
1373 # This variable intcmd is a reference to an array,
1374 # $$intcmd[0] = internal routine
1375 # $$intcmd[1...] = its arguments (if any)
1376 # test_kind specifies method of determining
1377 # whether a file is out-of-date:
1378 # 0 for never
1379 # 1 for usual: whether there is a source
1380 # file change
1381 # 2 for dest earlier than source
1382 # 3 for method 2 at first run, 1 thereafter
1383 # (used when don't have file data from
1384 # previous run).
1385 # source = name of primary source file, if any
1386 # dest = name of primary destination file,
1387 # if any
1388 # base = base name, if any, of files for
1389 # this rule
1390 # out_of_date = 1 if it has been detected that
1391 # this rule needs to be run
1392 # (typically because a source
1393 # file has changed).
1394 # 0 otherwise
1395 # out_of_date_user is like out_of_date, except
1396 # that the detection of out-of-dateness
1397 # has been made from a change of a
1398 # putative user file, i.e., one that is
1399 # not a generated file (e.g., aux). This
1400 # kind of out-of-dateness should provoke a
1401 # rerun whether or not there was an error
1402 # during a run of (pdf)LaTeX. Normally,
1403 # if there is an error, one should wait
1404 # for the user to correct the error. But
1405 # it is possible the error condition is
1406 # already corrected during the run, e.g.,
1407 # by the user changing a source file in
1408 # response to an error message.
1409 # time_of_last_run = time that this rule was
1410 # last applied. (In standard units
1411 # from perl, to be directly compared
1412 # with file modification times.)
1413 # time_of_last_file_check = last time that a check
1414 # was made for changes in source files.
1415 # changed flags whether special changes have been made
1416 # that require file-existence status to be ignored
1417 # last_result is
1418 # -1 if no run has been made,
1419 # 0 if the last run was successful
1420 # 1 if last run was successful, but
1421 # failed to create an output file
1422 # 2 if last run failed
1423 # 200 if last run gave a warning that is
1424 # important enough to be reported with
1425 # the error summary. The warning
1426 # message is stored in last_message.
1427 # last_message is error message for last run
1428 # default_extra_generated is a reference to an array
1429 # of specifications of extra generated files (beyond
1430 # the main dest file. Standard place holders are used.
1431 # Example ['%Y%R.log'] for (pdf)latex, and ['%R.blg']
1432 # for bibtex. (There's no need for '%R.aux', here,
1433 # since such generated files are detected dynamically.)
1434 # 1: {Hash sourcefile -> [source-file data] }
1435 # Source-file data array:
1436 # 0: time
1437 # 1: size
1438 # 2: md5
1439 # 3: name of rule to make this file
1440 # 4: whether the file is of the kind made by epstopdf.sty
1441 # during a primary run. It will have been read during
1442 # the run, so that even though the file changes during
1443 # a primary run, there is no need to trigger another
1444 # run because of this.
1445 # Size and md5 correspond to the values at the last run.
1446 # But time may be updated to correspond to the time
1447 # for the file, if the file is otherwise unchanged.
1448 # This saves excessive md5 calculations, which would
1449 # otherwise be done everytime the file is checked,
1450 # in the following situation:
1451 # When the file has been rewritten after a run
1452 # has started (commonly aux, bbl files etc),
1453 # but the actual file contents haven't
1454 # changed. Then because the filetime has
1455 # changed, on every file-change check latexmk
1456 # would normally redo the md5 calculation to
1457 # test for actual changes. Once one such
1458 # check is done, and the contents are
1459 # unchanged, later checks are superfluous, and
1460 # can be avoided by changing the file's time
1461 # in the source-file list.
1462 # 2: {Hash generated_file -> 1 }
1463 # This lists all generated files; the values
1464 # are currently unused, only the keys
1465
1466%fdb_current = (); # Fdb-hash for all files used.
1467
1468
1469# User's home directory
1470$HOME = '';
1471if (exists $ENV{'HOME'} ) {
1472 $HOME = $ENV{'HOME'};
1473}
1474elsif (exists $ENV{'USERPROFILE'} ) {
1475 $HOME = $ENV{'USERPROFILE'};
1476}
1477# XDG configuration home
1478$XDG_CONFIG_HOME = '';
1479if (exists $ENV{'XDG_CONFIG_HOME'} ) {
1480 $XDG_CONFIG_HOME = $ENV{'XDG_CONFIG_HOME'};
1481}
1482elsif ($HOME ne '') {
1483 if ( -d "$HOME/.config") {
1484 $XDG_CONFIG_HOME = "$HOME/.config";
1485 }
1486}
1487
1488
1489#==================================================
1490
1491# Options that are to be obeyed before rc files are read:
1492
1493foreach $_ ( @ARGV )
1494{
1495 if (/^-{1,2}norc$/ ) {
1496 $auto_rc_use = 0;
1497 }
1498}
1499
1500#==================================================
1501## Read rc files with this subroutine
1502
1503sub read_first_rc_file_in_list {
1504 foreach my $rc_file ( @_ ) {
1505 #print "===Testing for rc file \"$rc_file\" ...\n";
1506 if ( -d $rc_file ) {
1507 warn "$My_name: I have found a DIRECTORY named \"$rc_file\".\n",
1508 " Have you perhaps misunderstood latexmk's documentation?\n",
1509 " This name is normally used for a latexmk configuration (rc) file,\n",
1510 " and in that case it should be a regular text file, not a directory.\n";
1511 }
1512 elsif ( -e $rc_file ) {
1513 #print "===Reading rc file \"$rc_file\" ...\n";
1514 process_rc_file( $rc_file );
1515 return;
1516 }
1517 }
1518}
1519
1520# Note that each rc file may unset $auto_rc_use to
1521# prevent lower-level rc files from being read.
1522# So test on $auto_rc_use in each case.
1523if ( $auto_rc_use ) {
1524 # System rc file:
1525 read_first_rc_file_in_list( @rc_system_files );
1526}
1527if ( $auto_rc_use && ($HOME ne "" ) ) {
1528 # User rc file:
1529 @user_rc = ();
1530 if ( $XDG_CONFIG_HOME ) {
1531 push @user_rc, "$XDG_CONFIG_HOME/latexmk/latexmkrc";
1532 }
1533 # N.B. $HOME equals "" if latexmk couldn't determine a home directory.
1534 # In that case, we shouldn't look for an rc file there.
1535 if ( $HOME ) {
1536 push @user_rc, "$HOME/.latexmkrc";
1537 }
1538 read_first_rc_file_in_list( @user_rc );
1539}
1540if ( $auto_rc_use ) {
1541 # Rc file in current directory:
1542 read_first_rc_file_in_list( "latexmkrc", ".latexmkrc" );
1543}
1544
1545## Process command line args.
1546@command_line_file_list = ();
1547$bad_options = 0;
1548
1549while ($_ = $ARGV[0])
1550{
1551 # Make -- and - equivalent at beginning of option,
1552 # but save original for possible use in (pdf)latex command line
1553 $original = $_;
1554 s/^--/-/;
1555 shift;
1556 if ( /^-aux-directory=(.*)$/ || /^-auxdir=(.*)$/ ) {
1557 $aux_dir = $1;
1558 }
1559 elsif (/^-bibtex$/) { $bibtex_use = 2; }
1560 elsif (/^-bibtex-$/) { $bibtex_use = 0; }
1561 elsif (/^-nobibtex$/) { $bibtex_use = 0; }
1562 elsif (/^-bibtex-cond$/) { $bibtex_use = 1; }
1563 elsif (/^-bibtex-cond1$/) { $bibtex_use = 1.5; }
1564 elsif (/^-c$/) { $cleanup_mode = 2; $cleanup_fdb = 1; $cleanup_only = 1; }
1565 elsif (/^-C$/ || /^-CA$/ ) { $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 1; }
1566 elsif (/^-CF$/) { $cleanup_fdb = 1; }
1567 elsif (/^-cd$/) { $do_cd = 1; }
1568 elsif (/^-cd-$/) { $do_cd = 0; }
1569 elsif (/^-commands$/) { &print_commands; exit; }
1570 elsif (/^-d$/) { $banner = 1; }
1571 elsif (/^-dependents$/ || /^-deps$/ || /^-M$/ ) { $dependents_list = 1; }
1572 elsif (/^-nodependents$/ || /^-dependents-$/ || /^-deps-$/) { $dependents_list = 0; }
1573 elsif (/^-deps-out=(.*)$/) {
1574 $deps_file = $1;
1575 $dependents_list = 1;
1576 }
1577 elsif (/^-diagnostics/) { $diagnostics = 1; }
1578 elsif (/^-dvi$/) { $dvi_mode = 1; }
1579 elsif (/^-dvi-$/) { $dvi_mode = 0; }
1580 elsif (/^-f$/) { $force_mode = 1; }
1581 elsif (/^-f-$/) { $force_mode = 0; }
1582 elsif (/^-g$/) { $go_mode = 1; }
1583 elsif (/^-g-$/) { $go_mode = 0; }
1584 elsif (/^-gg$/) {
1585 $go_mode = 2; $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 0;
1586 }
1587 elsif ( /^-h$/ || /^-help$/ ) { &print_help; exit;}
1588 elsif (/^-jobname=(.*)$/) {
1589 $jobname = $1;
1590 }
1591 elsif (/^-l$/) { $landscape_mode = 1; }
1592 elsif (/^-l-$/) { $landscape_mode = 0; }
1593 elsif (/^-latex=(.*)$/) {
1594 $latex = $1;
1595 }
1596 elsif (/^-latexoption=(.*)$/) {
1597 push @extra_latex_options, $1;
1598 push @extra_pdflatex_options, $1;
1599 push @extra_lualatex_options, $1;
1600 push @extra_xelatex_options, $1;
1601 }
1602 elsif ( /^-logfilewarninglist$/ || /^-logfilewarnings$/ )
1603 { $silence_logfile_warnings = 0; }
1604 elsif ( /^-logfilewarninglist-$/ || /^-logfilewarnings-$/ )
1605 { $silence_logfile_warnings = 1; }
1606# See above for -M
1607 elsif (/^-MF$/) {
1608 if ( $ARGV[0] eq '' ) {
1609 &exit_help( "No file name specified after -MF switch");
1610 }
1611 $deps_file = $ARGV[0];
1612 shift;
1613 }
1614 elsif ( /^-MP$/ ) { $dependents_phony = 1; }
1615 elsif (/^-new-viewer$/) {
1616 $new_viewer_always = 1;
1617 }
1618 elsif (/^-new-viewer-$/) {
1619 $new_viewer_always = 0;
1620 }
1621 elsif (/^-norc$/ ) {
1622 $auto_rc_use = 0;
1623 # N.B. This has already been obeyed.
1624 }
1625 elsif ( /^-output-directory=(.*)$/ ||/^-outdir=(.*)$/ ) {
1626 $out_dir = $1;
1627 }
1628 elsif (/^-p$/) { $printout_mode = 1;
1629 $preview_continuous_mode = 0; # to avoid conflicts
1630 $preview_mode = 0;
1631 }
1632 elsif (/^-p-$/) { $printout_mode = 0; }
1633 elsif (/^-pdf$/) { $pdf_mode = 1; }
1634 elsif (/^-pdf-$/) { $pdf_mode = 0; }
1635 elsif (/^-pdfdvi$/){ $pdf_mode = 3; }
1636 elsif (/^-pdflua$/){ $pdf_mode = 4; }
1637 elsif (/^-pdfxe$/) { $pdf_mode = 5; }
1638# elsif (/^-pdflatex$/) {
1639# $pdflatex = "pdflatex %O %S";
1640# $pdf_mode = 1;
1641# $dvi_mode = $postscript_mode = 0;
1642# }
1643 elsif (/^-pdflatex=(.*)$/) {
1644 $pdflatex = $1;
1645 }
1646 elsif (/^-pdfps$/) { $pdf_mode = 2; }
1647 elsif (/^-print=(.*)$/) {
1648 $value = $1;
1649 if ( $value =~ /^dvi$|^ps$|^pdf$|^auto$/ ) {
1650 $print_type = $value;
1651 $printout_mode = 1;
1652 }
1653 else {
1654 &exit_help("$My_name: unknown print type '$value' in option '$_'");
1655 }
1656 }
1657 elsif (/^-ps$/) { $postscript_mode = 1; }
1658 elsif (/^-ps-$/) { $postscript_mode = 0; }
1659 elsif (/^-pv$/) { $preview_mode = 1;
1660 $preview_continuous_mode = 0; # to avoid conflicts
1661 $printout_mode = 0;
1662 }
1663 elsif (/^-pv-$/) { $preview_mode = 0; }
1664 elsif (/^-pvc$/) { $preview_continuous_mode = 1;
1665 $force_mode = 0; # So that errors do not cause loops
1666 $preview_mode = 0; # to avoid conflicts
1667 $printout_mode = 0;
1668 }
1669 elsif (/^-pvc-$/) { $preview_continuous_mode = 0; }
1670 elsif (/^-pvctimeout$/) { $pvc_timeout = 1; }
1671 elsif (/^-pvctimeout-$/) { $pvc_timeout = 0; }
1672 elsif (/^-pvctimeoutmins=(.*)$/) { $pvc_timeout_mins = $1; }
1673 elsif (/^-recorder$/ ){ $recorder = 1; }
1674 elsif (/^-recorder-$/ ){ $recorder = 0; }
1675 elsif (/^-rules$/ ) { $rules_list = 1; }
1676 elsif (/^-norules$/ || /^-rules-$/ ) { $rules_list = 0; }
1677 elsif (/^-showextraoptions$/) {
1678 print "List of extra latex and pdflatex options recognized by $my_name.\n",
1679 "These are passed as is to (pdf)latex. They may not be recognized by\n",
1680 "particular versions of (pdf)latex. This list is a combination of those\n",
1681 "for TeXLive and MikTeX.\n",
1682 "\n",
1683 "Note that in addition to the options in this list, there are several\n",
1684 "options known to the (pdf)latex programs that are also recognized by\n",
1685 "latexmk and trigger special behavior by latexmk. Since these options\n",
1686 "appear in the main list given by running 'latexmk --help', they do not\n",
1687 "appear in the following list\n",
1688 "NOTE ALSO: Not all of these options are supported by all versions of (pdf)latex.\n",
1689 "\n";
1690 foreach $option ( sort( keys %allowed_latex_options, keys %allowed_latex_options_with_arg ) ) {
1691 if (exists $allowed_latex_options{$option} ) { print " $allowed_latex_options{$option}\n"; }
1692 if (exists $allowed_latex_options_with_arg{$option} ) { print " $allowed_latex_options_with_arg{$option}\n"; }
1693 }
1694 exit;
1695 }
1696 elsif (/^-silent$/ || /^-quiet$/ ){ $silent = 1; }
1697 elsif (/^-time$/) { $show_time = 1;}
1698 elsif (/^-time-$/) { $show_time = 0;}
1699 elsif (/^-use-make$/) { $use_make_for_missing_files = 1; }
1700 elsif (/^-use-make-$/) { $use_make_for_missing_files = 0; }
1701 elsif (/^-v$/ || /^-version$/) {
1702 print "\n$version_details. Version $version_num\n";
1703 exit;
1704 }
1705 elsif (/^-verbose$/) { $silent = 0; }
1706 elsif (/^-view=default$/) { $view = "default";}
1707 elsif (/^-view=dvi$/) { $view = "dvi";}
1708 elsif (/^-view=none$/) { $view = "none";}
1709 elsif (/^-view=ps$/) { $view = "ps";}
1710 elsif (/^-view=pdf$/) { $view = "pdf"; }
1711 elsif (/^-lualatex$/) {
1712 $pdf_mode = 4;
1713 $dvi_mode = $postscript_mode = 0;
1714 }
1715 elsif (/^-xelatex$/) {
1716 $pdf_mode = 5;
1717 $dvi_mode = $postscript_mode = 0;
1718 }
1719 elsif (/^-e$/) {
1720 if ( $#ARGV < 0 ) {
1721 &exit_help( "No code to execute specified after -e switch");
1722 }
1723 execute_code_string( $ARGV[0] );
1724 shift;
1725 }
1726 elsif (/^-r$/) {
1727 if ( $ARGV[0] eq '' ) {
1728 &exit_help( "No RC file specified after -r switch");
1729 }
1730 if ( -e $ARGV[0] ) {
1731 process_rc_file( $ARGV[0] );
1732 }
1733 else {
1734 die "$My_name: RC file [$ARGV[0]] does not exist\n";
1735 }
1736 shift;
1737 }
1738 elsif (/^-bm$/) {
1739 if ( $ARGV[0] eq '' ) {
1740 &exit_help( "No message specified after -bm switch");
1741 }
1742 $banner = 1; $banner_message = $ARGV[0];
1743 shift;
1744 }
1745 elsif (/^-bi$/) {
1746 if ( $ARGV[0] eq '' ) {
1747 &exit_help( "No intensity specified after -bi switch");
1748 }
1749 $banner_intensity = $ARGV[0];
1750 shift;
1751 }
1752 elsif (/^-bs$/) {
1753 if ( $ARGV[0] eq '' ) {
1754 &exit_help( "No scale specified after -bs switch");
1755 }
1756 $banner_scale = $ARGV[0];
1757 shift;
1758 }
1759 elsif (/^-dF$/) {
1760 if ( $ARGV[0] eq '' ) {
1761 &exit_help( "No dvi filter specified after -dF switch");
1762 }
1763 $dvi_filter = $ARGV[0];
1764 shift;
1765 }
1766 elsif (/^-pF$/) {
1767 if ( $ARGV[0] eq '' ) {
1768 &exit_help( "No ps filter specified after -pF switch");
1769 }
1770 $ps_filter = $ARGV[0];
1771 shift;
1772 }
1773 elsif ( ( exists( $allowed_latex_options{$_} ) )
1774 || ( /^(-.+)=/ && exists( $allowed_latex_options_with_arg{$1} ) )
1775 )
1776 {
1777 push @extra_latex_options, $original;
1778 push @extra_pdflatex_options, $original;
1779 push @extra_lualatex_options, $original;
1780 push @extra_xelatex_options, $original;
1781 }
1782 elsif (/^-/) {
1783 warn "$My_name: $_ bad option\n";
1784 $bad_options++;
1785 }
1786 else {
1787 push @command_line_file_list, $_ ;
1788 }
1789}
1790
1791if ( $bad_options > 0 ) {
1792 &exit_help( "Bad options specified" );
1793}
1794
1795warn "$My_name: This is $version_details, version: $version_num.\n",
1796 unless $silent;
1797
1798
1799if ( ($out_dir ne '') && ($aux_dir eq '') ){
1800 $aux_dir = $out_dir;
1801}
1802
1803# Normalize versions terminating in directory/path separator
1804# and versions referring to current directory
1805$out_dir1 = $out_dir;
1806$aux_dir1 = $aux_dir;
1807foreach ( $aux_dir1, $out_dir1 ) {
1808 if ( ($_ ne '') && ! m([\\/\:]$) ) {
1809 $_ .= '/';
1810 }
1811 while ( s[^\.\/][] ) {}
1812}
1813
1814# At least one widely package (revtex4-1) generates a bib file
1815# (which is used in revtex4-1 for putting footnotes in the reference
1816# list), and bibtex must be run to use it. But latexmk needs to
1817# determine the existence of the bib file by use of kpsewhich, otherwise
1818# there is an error. So cope with this situation (and any analogous
1819# cases by adding the aux_dir to the relevant path search environment
1820# variables. BIBINPUTS seems to be the only one currently affected.
1821foreach ( 'BIBINPUTS' ) {
1822 if ( exists $ENV{$_} ) {
1823 $ENV{$_} = $aux_dir.$search_path_separator.$ENV{$_};
1824 }
1825 else {
1826 $ENV{$_} = $aux_dir.$search_path_separator;
1827 }
1828}
1829
1830
1831if ($bibtex_use > 1) {
1832 push @generated_exts, 'bbl';
1833}
1834
1835# For backward compatibility, convert $texfile_search to @default_files
1836# Since $texfile_search is initialized to "", a nonzero value indicates
1837# that an initialization file has set it.
1838if ( $texfile_search ne "" ) {
1839 @default_files = split /\s+/, "*.tex $texfile_search";
1840}
1841
1842#Glob the filenames command line if the script was not invoked under a
1843# UNIX-like environment.
1844# Cases: (1) MS/MSwin native Glob
1845# (OS detected as MSWin32)
1846# (2) MS/MSwin cygwin Glob [because we do not know whether
1847# the cmd interpreter is UNIXy (and does glob) or is
1848# native MS-Win (and does not glob).]
1849# (OS detected as cygwin)
1850# (3) UNIX Don't glob (cmd interpreter does it)
1851# (Currently, I assume this is everything else)
1852if ( ($^O eq "MSWin32") || ($^O eq "cygwin") ) {
1853 # Preserve ordering of files
1854 @file_list = glob_list1(@command_line_file_list);
1855#print "A1:File list:\n";
1856#for ($i = 0; $i <= $#file_list; $i++ ) { print "$i: '$file_list[$i]'\n"; }
1857}
1858else {
1859 @file_list = @command_line_file_list;
1860}
1861@file_list = uniq1( @file_list );
1862
1863
1864# Check we haven't selected mutually exclusive modes.
1865# Note that -c overrides all other options, but doesn't cause
1866# an error if they are selected.
1867if (($printout_mode && ( $preview_mode || $preview_continuous_mode ))
1868 || ( $preview_mode && $preview_continuous_mode ))
1869{
1870 # Each of the options -p, -pv, -pvc turns the other off.
1871 # So the only reason to arrive here is an incorrect inititalization
1872 # file, or a bug.
1873 &exit_help( "Conflicting options (print, preview, preview_continuous) selected");
1874}
1875
1876if ( @command_line_file_list ) {
1877 # At least one file specified on command line (before possible globbing).
1878 if ( !@file_list ) {
1879 &exit_help( "Wildcards in file names didn't match any files");
1880 }
1881}
1882else {
1883 # No files specified on command line, try and find some
1884 # Evaluate in order specified. The user may have some special
1885 # for wanting processing in a particular order, especially
1886 # if there are no wild cards.
1887 # Preserve ordering of files
1888 my @file_list1 = uniq1( glob_list1(@default_files) );
1889 my @excluded_file_list = uniq1( glob_list1(@default_excluded_files) );
1890 # Make hash of excluded files, for easy checking:
1891 my %excl = ();
1892 foreach my $file (@excluded_file_list) {
1893 $excl{$file} = '';
1894 }
1895 foreach my $file (@file_list1) {
1896 push( @file_list, $file) unless ( exists $excl{$file} );
1897 }
1898 if ( !@file_list ) {
1899 &exit_help( "No file name specified, and I couldn't find any");
1900 }
1901}
1902
1903$num_files = $#file_list + 1;
1904$num_specified = $#command_line_file_list + 1;
1905
1906#print "Command line file list:\n";
1907#for ($i = 0; $i <= $#command_line_file_list; $i++ ) { print "$i: '$command_line_file_list[$i]'\n"; }
1908#print "File list:\n";
1909#for ($i = 0; $i <= $#file_list; $i++ ) { print "$i: '$file_list[$i]'\n"; }
1910
1911
1912# If selected a preview-continuous mode, make sure exactly one filename was specified
1913if ($preview_continuous_mode && ($num_files != 1) ) {
1914 if ($num_specified > 1) {
1915 &exit_help(
1916 "Need to specify exactly one filename for ".
1917 "preview-continuous mode\n".
1918 " but $num_specified were specified"
1919 );
1920 }
1921 elsif ($num_specified == 1) {
1922 &exit_help(
1923 "Need to specify exactly one filename for ".
1924 "preview-continuous mode\n".
1925 " but wildcarding produced $num_files files"
1926 );
1927 }
1928 else {
1929 &exit_help(
1930 "Need to specify exactly one filename for ".
1931 "preview-continuous mode.\n".
1932 " Since none were specified on the command line, I looked for \n".
1933 " files in '@default_files'.\n".
1934 " But I found $num_files files, not 1."
1935 );
1936 }
1937}
1938
1939# If selected jobname, can only apply that to one file:
1940if ( ($jobname ne '') && ($num_files > 1) ) {
1941 &exit_help(
1942 "Need to specify at most one filename if ".
1943 "jobname specified, \n".
1944 " but $num_files were found (after defaults and wildcarding)."
1945 );
1946}
1947
1948
1949# Normalize the commands, to have place-holders for source, dest etc:
1950&fix_cmds;
1951
1952# Add common options
1953add_option( $latex_default_switches, \$latex );
1954add_option( $pdflatex_default_switches, \$pdflatex );
1955add_option( $lualatex_default_switches, \$lualatex );
1956add_option( $xelatex_default_switches, \$xelatex );
1957
1958foreach (@extra_latex_options) { add_option( $_, \$latex ); }
1959foreach (@extra_pdflatex_options) { add_option( $_, \$pdflatex ); }
1960foreach (@extra_lualatex_options) { add_option( $_, \$lualatex ); }
1961foreach (@extra_xelatex_options) { add_option( $_, \$xelatex ); }
1962
1963
1964# If landscape mode, change dvips processor, and the previewers:
1965if ( $landscape_mode )
1966{
1967 $dvips = $dvips_landscape;
1968 $dvi_previewer = $dvi_previewer_landscape;
1969 $ps_previewer = $ps_previewer_landscape;
1970}
1971
1972if ( $silent ) {
1973 add_option( "$latex_silent_switch", \$latex );
1974 add_option( "$pdflatex_silent_switch", \$pdflatex );
1975 add_option( "$lualatex_silent_switch", \$lualatex );
1976 add_option( "$xelatex_silent_switch", \$xelatex );
1977 add_option( "$biber_silent_switch", \$biber );
1978 add_option( "$bibtex_silent_switch", \$bibtex );
1979 add_option( "$makeindex_silent_switch", \$makeindex );
1980 add_option( "$dvipdf_silent_switch", \$dvipdf );
1981 add_option( "$dvips_silent_switch", \$dvips );
1982 add_option( "$xdvipdfmx_silent_switch", \$xdvipdfmx );
1983}
1984
1985if ( $recorder ) {
1986 add_option( "-recorder", \$latex, \$pdflatex, \$lualatex, \$xelatex );
1987}
1988
1989# If the output and/or aux directories are specified, fix the (pdf)latex
1990# commands to use them.
1991# N.B. We'll ensure that the directories actually exist only after a
1992# possible cd to the document directory, since the directories can be
1993# relative to the document.
1994
1995if ( $out_dir ) {
1996 add_option( "-output-directory=\"$out_dir\"",
1997 \$latex, \$pdflatex, \$lualatex, \$xelatex );
1998}
1999if ( $aux_dir && ($aux_dir ne $out_dir) ) {
2000 # N.B. If $aux_dir and $out_dir are the same, then the -output-directory
2001 # option is sufficient, especially because the -aux-directory exists
2002 # only in MiKTeX, not in TeXLive.
2003 add_option( "-aux-directory=\"$aux_dir\"",
2004 \$latex, \$pdflatex, \$lualatex, \$xelatex );
2005}
2006
2007if ( $jobname ne '' ) {
2008 $jobstring = "--jobname=\"$jobname\"";
2009 add_option( "$jobstring", \$latex, \$lualatex, \$pdflatex, \$xelatex );
2010}
2011
2012# Which kind of file do we preview?
2013if ( $view eq "default" ) {
2014 # If default viewer requested, use "highest" of dvi, ps and pdf
2015 # that was requested by user.
2016 # No explicit request means view dvi.
2017 $view = "dvi";
2018 if ( $postscript_mode ) { $view = "ps"; }
2019 if ( $pdf_mode ) { $view = "pdf"; }
2020}
2021
2022# Make sure we make the kind of file we want to view:
2023if ($view eq 'dvi') { $dvi_mode = 1; }
2024if ($view eq 'ps') { $postscript_mode = 1; }
2025if ( ($view eq 'pdf') && ($pdf_mode == 0) ) {
2026 $pdf_mode = 1;
2027}
2028
2029# Make sure that we make something if all requests are turned off
2030if ( ! ( $dvi_mode || $pdf_mode || $postscript_mode || $printout_mode) ) {
2031 print "No specific requests made, so default to dvi by latex\n";
2032 $dvi_mode = 1;
2033}
2034
2035# Set new-style requested rules:
2036if ( $dvi_mode ) { $requested_filerules{'latex'} = 1; }
2037if ( $pdf_mode == 1 ) { $requested_filerules{'pdflatex'} = 1; }
2038elsif ( $pdf_mode == 2 ) {
2039 $requested_filerules{'latex'} = 1;
2040 $requested_filerules{'dvips'} = 1;
2041 $requested_filerules{'ps2pdf'} = 1;
2042}
2043elsif ( $pdf_mode == 3 ) {
2044 $requested_filerules{'latex'} = 1;
2045 $requested_filerules{'dvipdf'} = 1;
2046}
2047elsif ( $pdf_mode == 4 ) {
2048 $requested_filerules{'lualatex'} = 1;
2049}
2050elsif ( $pdf_mode == 5 ) {
2051 $requested_filerules{'xelatex'} = 1;
2052 $requested_filerules{'xdvipdfmx'} = 1;
2053}
2054if ( $postscript_mode ) {
2055 $requested_filerules{'latex'} = 1;
2056 $requested_filerules{'dvips'} = 1;
2057}
2058if ($print_type eq 'auto') {
2059 if ( $postscript_mode ) { $print_type = 'ps'; }
2060 elsif ( $pdf_mode ) { $print_type = 'pdf'; }
2061 elsif ( $dvi_mode ) { $print_type = 'dvi'; }
2062 else { $print_type = 'none'; }
2063}
2064if ( $printout_mode ) {
2065 $one_time{'print'} = 1;
2066 if ($print_type eq 'none'){
2067 warn "$My_name: You have requested printout, but \$print_type is set to 'none'\n";
2068 }
2069}
2070if ( $preview_continuous_mode || $preview_mode ) { $one_time{'view'} = 1; }
2071if ( length($dvi_filter) != 0 ) { $requested_filerules{'dvi_filter'} = 1; }
2072if ( length($ps_filter) != 0 ) { $requested_filerules{'ps_filter'} = 1; }
2073if ( $banner ) { $requested_filerules{'dvips'} = 1; }
2074
2075
2076if ( $pdf_mode == 2 ) {
2077 # We generate pdf from ps. Make sure we have the correct kind of ps.
2078 add_option( "$dvips_pdf_switch", \$dvips );
2079}
2080
2081# Restrict variables to allowed values:
2082
2083if ($filetime_causality_threshold < 0) {
2084 warn "$My_name: Correcting negative value of \$filetime_causality_threshold to zero.\n";
2085 $filetime_causality_threshold = 0;
2086}
2087
2088# Note sleep has granularity of 1 second.
2089# Sleep periods 0 < $sleep_time < 1 give zero delay,
2090# which is probably not what the user intended.
2091# Sleep periods less than zero give infinite delay
2092if ( $sleep_time < 0 ) {
2093 warn "$My_name: Correcting negative sleep_time to 1 sec.\n";
2094 $sleep_time = 1;
2095}
2096elsif ( ($sleep_time < 1) && ( $sleep_time != 0 ) ) {
2097 warn "$My_name: Correcting nonzero sleep_time of less than 1 sec to 1 sec.\n";
2098 $sleep_time = 1;
2099}
2100elsif ( $sleep_time == 0 ) {
2101 warn "$My_name: sleep_time was configured to zero.\n",
2102 " Do you really want to do this? It will give 100% CPU usage.\n";
2103}
2104
2105# Make convenient forms for lookup.
2106# Extensions always have period.
2107
2108# Convert @generated_exts to a hash for ease of look up and deletion
2109# Keep extension without period!
2110%generated_exts_all = ();
2111foreach (@generated_exts ) {
2112 $generated_exts_all{$_} = 1;
2113}
2114
2115if ($aux_dir) {
2116 # Ensure $aux_dir is in TEXINPUTS search path.
2117 # This is used by dvips for files generated by mpost.
2118 if ( ! exists $ENV{TEXINPUTS} ) {
2119 # Note the trailing ":" which ensures that the last item
2120 # in the list of paths is the empty path, which actually
2121 # means the default path, i.e., the following means that
2122 # the TEXINPUTS search path is $aux_dir and the standard
2123 # value.
2124 $ENV{TEXINPUTS} = $aux_dir.$search_path_separator;
2125 }
2126 elsif ( $ENV{TEXINPUTS} !~ /$aux_dir$search_path_separator/ ) {
2127 $ENV{TEXINPUTS} = $aux_dir.$search_path_separator.$ENV{TEXINPUTS};
2128 }
2129}
2130
2131$quell_uptodate_msgs = $silent;
2132 # Whether to quell informational messages when files are uptodate
2133 # Will turn off in -pvc mode
2134
2135$failure_count = 0;
2136@failed_primaries = ();
2137
2138if ($deps_file eq '' ) {
2139 # Standardize name used for stdout
2140 $deps_file = '-';
2141}
2142
2143# In non-pvc mode, the dependency list is global to all processed TeX files,
2144# so we open a single file here, and add items to it after processing each file
2145# But in -pvc mode, the dependency list should be written after round of
2146# processing the single TeX file (as if each round were a separate run of
2147# latexmk). There's undoubtedly some non-optimal structuring here!
2148if ( $dependents_list && ! $preview_continuous_mode ) {
2149 $deps_handle = new FileHandle "> $deps_file";
2150 if (! defined $deps_handle ) {
2151 die "Cannot open '$deps_file' for output of dependency information\n";
2152 }
2153}
2154
2155# Remove leading and trailing space in the following space-separated lists,
2156# and collapse multiple spaces to one,
2157# to avoid getting incorrect blank items when they are split.
2158foreach ($clean_ext, $clean_full_ext) { s/^\s+//; s/\s+$//; s/\s+/ /g; }
2159
2160
2161FILE:
2162foreach $filename ( @file_list )
2163{
2164 # Global variables for making of current file:
2165 $updated = 0;
2166 $failure = 0; # Set nonzero to indicate failure at some point of
2167 # a make. Use value as exit code if I exit.
2168 $failure_msg = ''; # Indicate reason for failure
2169
2170 if ( $do_cd ) {
2171 ($filename, $path) = fileparse( $filename );
2172 warn "$My_name: Changing directory to '$path'\n";
2173 pushd( $path );
2174 }
2175 else {
2176 $path = '';
2177 }
2178
2179 # Ensure the output/auxiliary directories exist, if need be
2180 if ( $out_dir ) {
2181 if ( ! -e $out_dir ) {
2182 warn "$My_name: making output directory '$out_dir'\n"
2183 if ! $silent;
2184 make_path $out_dir;
2185 }
2186 elsif ( ! -d $out_dir ) {
2187 warn "$My_name: you requested output directory '$out_dir',\n",
2188 " but an ordinary file of the same name exists, which will\n",
2189 " probably give an error later\n";
2190 }
2191 }
2192
2193 if ( $aux_dir && ($aux_dir ne $out_dir) ) {
2194 # N.B. If $aux_dir and $out_dir are the same, then the -output-directory
2195 # option is sufficient, especially because the -aux-directory exists
2196 # only in MiKTeX, not in TeXLive.
2197 if ( ! -e $aux_dir ) {
2198 warn "$My_name: making auxiliary directory '$aux_dir'\n"
2199 if ! $silent;
2200 make_path $aux_dir;
2201 }
2202 elsif ( ! -d $aux_dir ) {
2203 warn "$My_name: you requested aux directory '$aux_dir',\n",
2204 " but an ordinary file of the same name exists, which will\n",
2205 " probably give an error later\n";
2206 }
2207 }
2208
2209 ## remove extension from filename if was given.
2210 if ( find_basename($filename, $root_filename, $texfile_name) )
2211 {
2212 if ( $force_mode ) {
2213 warn "$My_name: Could not find file [$texfile_name]\n";
2214 }
2215 else {
2216 &ifcd_popd;
2217 &exit_msg1( "Could not find file [$texfile_name]",
2218 11);
2219 }
2220 }
2221 if ($jobname ne '' ) {
2222 $root_filename = $jobname;
2223 }
2224
2225 $aux_main = "$aux_dir1$root_filename.aux";
2226 $log_name = "$aux_dir1$root_filename.log";
2227 $fdb_name = "$aux_dir1$root_filename.$fdb_ext";
2228
2229 # Initialize basic dependency information:
2230
2231 # For use under error conditions:
2232 @default_includes = ($texfile_name, $aux_main);
2233
2234 # Initialize rule database.
2235 # ?? Should I also initialize file database?
2236 %rule_list = ();
2237 &rdb_make_rule_list;
2238 &rdb_set_rules( \%rule_list, \%extra_rule_spec );
2239
2240 if ( $cleanup_mode > 0 ) {
2241# ?? MAY NEED TO FIX THE FOLLOWING IF $aux_dir or $out_dir IS SET.
2242 my %other_generated = ();
2243 my @index_bibtex_generated = ();
2244 my @aux_files = ();
2245 my @missing_bib_files = ();
2246 my $bibs_all_exist = 0;
2247 $have_fdb = 0;
2248 if ( -e $fdb_name ) {
2249 print "$My_name: Examining fdb file '$fdb_name' for rules ...\n"
2250 if $diagnostics;
2251 $have_fdb = ( 0 == rdb_read( $fdb_name ) );
2252 }
2253 if ( $have_fdb ) {
2254 rdb_for_all(
2255 sub { # Find generated files at rule level
2256 my ($base, $path, $ext) = fileparseA( $$Psource );
2257 $base = $path.$base;
2258 if ( $rule =~ /^makeindex/ ) {
2259 push @index_bibtex_generated, $$Psource, $$Pdest, "$base.ilg";
2260 }
2261 elsif ( $rule =~ /^(bibtex|biber)/ ) {
2262 push @index_bibtex_generated, $$Pdest, "$base.blg";
2263 push @aux_files, $$Psource;
2264 if ( $bibtex_use == 1.5) {
2265 foreach ( keys %$PHsource ) {
2266 if ( ( /\.bib$/ ) && (! -e $_) ) {
2267 push @missing_bib_files, $_;
2268 }
2269 }
2270 }
2271 }
2272 elsif ( exists $other_generated{$$Psource} ) {
2273# print "=========== CHECKING: source file of rule '$rule', '$$Psource'\n",
2274# " is a generated file.\n";
2275 ## OLD with apparent bug:
2276 #$other_generated{$$Pdest};
2277 }
2278 foreach my $key (keys %$PHdest) {
2279 $other_generated{$key} = 1;
2280 }
2281 },
2282 sub { # Find generated files at source file level
2283 if ( $file =~ /\.aux$/ ) { push @aux_files, $file; }
2284 }
2285 );
2286 if ($#missing_bib_files == -1) { $bibs_all_exist = 1; }
2287 }
2288 elsif ( -e $log_name ) {
2289 # No fdb file, but log file exists, so do inferior job by parse_log
2290 print "$My_name: Examining log file '$log_name' for generated files...\n"
2291 if $diagnostics;
2292 # Variables set by parse_log. Can I remove them?
2293 local %generated_log = ();
2294 local %dependents = (); # Maps files to status. Not used here.
2295 local @bbl_files = (); # Not used here.
2296 local %idx_files = (); # Maps idx_file to (ind_file, base). Not used here.
2297 local %conversions = (); # (pdf)latex-performed conversions. Not used here.
2298 # Maps output file created and read by (pdf)latex
2299 # to source file of conversion.
2300 local $primary_out = ''; # Actual output file (dvi or pdf). Not used here.
2301 local $fls_file_analyzed = 0;
2302 &parse_log;
2303 %other_generated = %generated_log;
2304 }
2305 else {
2306 print "$My_name: No fdb or log file, so clean up default set of files ...\n"
2307 if $diagnostics;
2308 }
2309
2310 if ( ($go_mode == 2) && !$silent ) {
2311 warn "$My_name: Removing all generated files\n" unless $silent;
2312 }
2313 my $keep_bbl = 1;
2314 if ( ($bibtex_use > 1.6)
2315 ||
2316 ( ($bibtex_use == 1.5) && ($bibs_all_exist) )
2317 ) {
2318 $keep_bbl = 0;
2319 }
2320 if ($keep_bbl) {
2321 delete $generated_exts_all{'bbl'};
2322 }
2323 # Convert two arrays to hashes:
2324 my %index_bibtex_generated = ();
2325 my %aux_files = ();
2326 my %aux_files_to_save = ();
2327 foreach (@index_bibtex_generated) {
2328 $index_bibtex_generated{$_} = 1
2329 unless ( /\.bbl$/ && ($keep_bbl) );
2330 delete( $other_generated{$_} );
2331 }
2332 foreach (@aux_files) {
2333 if (exists $other_generated{$_} ) {
2334 $aux_files{$_} = 1;
2335 }
2336 else {
2337 $aux_files_to_save{$_} = 1;
2338 }
2339 }
2340
2341 if ($diagnostics) {
2342 show_array( "For deletion, the following were determined from fdb file or log file:\n"
2343 ." Generated (from makeindex and bibtex):",
2344 keys %index_bibtex_generated );
2345 show_array( " Aux files:", keys %aux_files );
2346 show_array( " Other generated files:\n"
2347 ." (only deleted if \$cleanup_includes_generated is set): ",
2348 keys %other_generated );
2349 show_array( " Yet other generated files are specified by patterns:\n".
2350 " Explicit pattern with %R or root-filename.extension:",
2351 keys %generated_exts_all );
2352 show_array( " Aux files to SAVE and not delete:", keys %aux_files_to_save );
2353 }
2354
2355 &cleanup1( $aux_dir1, $fdb_ext, 'blg', 'ilg', 'log', 'aux.bak', 'idx.bak',
2356 split('\s+',$clean_ext),
2357 keys %generated_exts_all
2358 );
2359 unlink_or_move( 'texput.log', "texput.aux", "missfont.log",
2360 keys %index_bibtex_generated,
2361 keys %aux_files );
2362 if ( $dependents_list && ( $deps_file ne '-' ) ) {
2363 unlink_or_move( $deps_file );
2364 }
2365 if ($cleanup_includes_generated) {
2366 unlink_or_move( keys %other_generated );
2367 }
2368 if ( $cleanup_includes_cusdep_generated) {
2369 &cleanup_cusdep_generated;
2370 }
2371 if ( $cleanup_mode == 1 ) {
2372 &cleanup1( $out_dir1, 'dvi', 'dviF', 'ps', 'psF', 'pdf',
2373 'synctex.gz', 'xdv',
2374 split('\s+', $clean_full_ext)
2375 );
2376 }
2377 }
2378 if ($cleanup_fdb) {
2379 unlink_or_move( $fdb_name );
2380 # If the fdb file exists, it will have been read, and therefore changed
2381 # rule database. But deleting the fdb file implies we also want
2382 # a virgin rule database, so we must reset it:
2383 rdb_set_rules( \%rule_list );
2384 }
2385 if ($cleanup_only) { next FILE; }
2386
2387
2388#??? The following are not needed if use rdb_make.
2389# ?? They may be set too early?
2390# Arrays and hashes for picking out accessible rules.
2391# Distinguish rules for making files and others
2392 @accessible_all = sort ( &rdb_accessible( keys %requested_filerules, keys %one_time ));
2393 %accessible_filerules = ();
2394 foreach (@accessible_all) {
2395 unless ( /view/ || /print/ ) { $accessible_filerules{$_} = 1; }
2396 }
2397 @accessible_filerules = sort keys %accessible_filerules;
2398
2399# show_array ( "=======All rules used", @accessible_all );
2400# show_array ( "=======Requested file rules", sort keys %requested_filerules );
2401# show_array ( "=======Rules for files", @accessible_filerules );
2402
2403 if ( $diagnostics ) {
2404 print "$My_name: Rules after start up for '$texfile_name'\n";
2405 rdb_show();
2406 }
2407
2408 %primaries = ();
2409 foreach (@accessible_all) {
2410 if ( ($_ eq 'latex') || ($_ eq 'pdflatex') || ($_ eq 'lualatex')
2411 || ($_ eq 'xelatex') )
2412 { $primaries{$_} = 1; }
2413 }
2414
2415 $have_fdb = 0;
2416 if (! -e $aux_main ) {
2417 # No aux file => set up trivial aux file
2418 # and corresponding fdb_file. Arrange them to provoke one run
2419 # as minimum, but no more if actual aux file is trivial.
2420 # (Useful on big files without cross references.)
2421 # If aux file doesn't exist, then any fdb file is surely
2422 # wrong.
2423 # Previously, I had condition for this as being both aux and
2424 # fdb files failing to exist. But it's not obvious what to
2425 # do if aux exists and fdb doesn't. So I won't do anything.
2426 &set_trivial_aux_fdb;
2427 }
2428
2429 if ( -e $fdb_name ) {
2430 $rdb_errors = rdb_read( $fdb_name );
2431 $have_fdb = ($rdb_errors == 0);
2432 }
2433 if (!$have_fdb) {
2434 # We didn't get a valid set of data on files used in
2435 # previous run. So use filetime criterion for make
2436 # instead of change from previous run, until we have
2437 # done our own make.
2438 rdb_recurse( [keys %possible_primaries],
2439 sub{ if ( $$Ptest_kind == 1 ) { $$Ptest_kind = 3;} }
2440 );
2441 if ( -e $log_name ) {
2442 rdb_for_some( [keys %possible_primaries], \&rdb_set_latex_deps );
2443 }
2444 }
2445 foreach $rule ( rdb_accessible( uniq1( keys %requested_filerules ) ) ){
2446 # For all source files of all accessible rules,
2447 # if the file data are not already set (e.g., from fdb_latexmk
2448 # file, set them from disk.
2449 rdb_one_rule ($rule, undef,
2450 sub{ if ( $$Ptime == 0) { &rdb_update1; } }
2451 );
2452 }
2453
2454 if ($go_mode) {
2455 # Force everything to be remade.
2456 rdb_recurse( [keys %requested_filerules], sub{$$Pout_of_date=1;} );
2457 }
2458
2459
2460 if ( $diagnostics ) {
2461 print "$My_name: Rules after initialization\n";
2462 rdb_show();
2463 }
2464
2465 #************************************************************
2466
2467 if ( $preview_continuous_mode ) {
2468 &make_preview_continuous;
2469 next FILE;
2470 }
2471
2472
2473## Handling of failures:
2474## Variable $failure is set to indicate a failure, with information
2475## put in $failure_msg.
2476## These variables should be set to 0 and '' at any point at which it
2477## should be assumed that no failures have occurred.
2478## When after a routine is called it is found that $failure is set, then
2479## processing should normally be aborted, e.g., by return.
2480## Then there is a cascade of returns back to the outermost level whose
2481## responsibility is to handle the error.
2482## Exception: An outer level routine may reset $failure and $failure_msg
2483## after initial processing, when the error condition may get
2484## ameliorated later.
2485 #Initialize failure flags now.
2486 $failure = 0;
2487 $failure_msg = '';
2488 $failure = rdb_make( keys %requested_filerules );
2489 if ( ( $failure <= 0 ) || $force_mode ) {
2490 rdb_for_some( [keys %one_time], \&rdb_run1 );
2491 }
2492 if ($failure > 0) { next FILE; }
2493} # end FILE
2494continue {
2495 if ($deps_handle) { deps_list($deps_handle); }
2496 # If requested, print the list of rules. But don't do this in -pvc
2497 # mode, since the rules list has already been printed.
2498 if ($rules_list && ! $preview_continuous_mode) { rdb_list(); }
2499 # Handle any errors
2500 $error_message_count = rdb_show_rule_errors();
2501 if ( ($error_message_count == 0) || ($failure > 0) ) {
2502 if ( $failure_msg ) {
2503 #Remove trailing space
2504 $failure_msg =~ s/\s*$//;
2505 warn "$My_name: Did not finish processing file '$filename':\n",
2506 " $failure_msg\n";
2507 $failure = 1;
2508 }
2509 }
2510 if ( ($failure > 0) || ($error_message_count > 0) ) {
2511 $failure_count ++;
2512 push @failed_primaries, $filename;
2513 }
2514 &ifcd_popd;
2515}
2516close($deps_handle) if ( $deps_handle );
2517
2518if ($show_time) { show_timing();}
2519
2520sub show_timing {
2521 my $processing_time = processing_time() - $processing_time1;
2522 print @timings, "Accumulated processing time = $processing_time\n";
2523 @timings = ();
2524 $processing_time1 = processing_time();
2525}
2526
2527# If we get here without going through the continue section:
2528if ( $do_cd && ($#dir_stack > -1) ) {
2529 # Just in case we did an abnormal exit from the loop
2530 warn "$My_name: Potential bug: dir_stack not yet unwound, undoing all directory changes now\n";
2531 &finish_dir_stack;
2532}
2533
2534if ($failure_count > 0) {
2535 if ( $#file_list > 0 ) {
2536 # Error occured, but multiple files were processed, so
2537 # user may not have seen all the error messages
2538 warn "\n------------\n";
2539 show_array(
2540 "$My_name: Some operations failed, for the following tex file(s)",
2541 @failed_primaries);
2542 }
2543 if ( !$force_mode ) {
2544 warn "$My_name: Use the -f option to force complete processing,\n",
2545 " unless error was exceeding maximum runs of latex/pdflatex.\n";
2546 }
2547 exit 12;
2548}
2549
2550
2551
2552# end MAIN PROGRAM
2553#############################################################
2554
2555sub fix_cmds {
2556 # If commands do not have placeholders for %S etc, put them in
2557 foreach ($latex, $pdflatex, $lpr, $lpr_dvi, $lpr_pdf,
2558 $pdf_previewer, $ps_previewer, $ps_previewer_landscape,
2559 $dvi_previewer, $dvi_previewer_landscape,
2560 $kpsewhich
2561 ) {
2562 # Source only
2563 if ( $_ && ! /%/ ) { $_ .= " %O %S"; }
2564 }
2565 foreach ($pdf_previewer, $ps_previewer, $ps_previewer_landscape,
2566 $dvi_previewer, $dvi_previewer_landscape,
2567 ) {
2568 # Run previewers detached
2569 if ( $_ && ! /^(nostart|NONE|internal) / ) {
2570 $_ = "start $_";
2571 }
2572 }
2573 foreach ($biber, $bibtex) {
2574 # Base only
2575 if ( $_ && ! /%/ ) { $_ .= " %O %B"; }
2576 }
2577 foreach ($dvipdf, $ps2pdf) {
2578 # Source and dest without flag for destination
2579 if ( $_ && ! /%/ ) { $_ .= " %O %S %D"; }
2580 }
2581 foreach ($dvips, $makeindex) {
2582 # Source and dest with -o dest before source
2583 if ( $_ && ! /%/ ) { $_ .= " %O -o %D %S"; }
2584 }
2585 foreach ($dvi_filter, $ps_filter) {
2586 # Source and dest, but as filters
2587 if ( $_ && ! /%/ ) { $_ .= " %O <%S >%D"; }
2588 }
2589} #END fix_cmds
2590
2591#############################################################
2592
2593sub add_option {
2594 # Call add_option( $opt, \$cmd ... )
2595 # Add option to one or more commands
2596 my $option = shift;
2597 while (@_) {
2598 if ( ${$_[0]} !~ /%/ ) { &fix_cmds; }
2599 ${$_[0]} =~ s/%O/$option %O/;
2600 shift;
2601 }
2602} #END add_option
2603
2604#############################################################
2605
2606sub rdb_make_rule_list {
2607# Set up specifications for standard rules, adjusted to current conditions
2608# Substitutions: %S = source, %D = dest, %B = this rule's base
2609# %T = texfile, %R = root = base for latex.
2610# %Y for $aux_dir1, %Z for $out_dir1
2611
2612 # Defaults for dvi, ps, and pdf files
2613 # Use local, not my, so these variables can be referenced
2614 local $dvi_final = "%Z%R.dvi";
2615 local $ps_final = "%Z%R.ps";
2616 local $pdf_final = "%Z%R.pdf";
2617 local $xdv_final = "%Z%R.xdv";
2618 if ( length($dvi_filter) > 0) {
2619 $dvi_final = "%Z%R.dviF";
2620 }
2621 if ( length($ps_filter) > 0) {
2622 $ps_final = "%Z%R.psF";
2623 }
2624
2625 my $print_file = '';
2626 my $print_cmd = 'NONE';
2627 if ( $print_type eq 'dvi' ) {
2628 $print_file = $dvi_final;
2629 $print_cmd = $lpr_dvi;
2630 }
2631 elsif ( $print_type eq 'pdf' ) {
2632 $print_file = $pdf_final;
2633 $print_cmd = $lpr_pdf;
2634 }
2635 elsif ( $print_type eq 'ps' ) {
2636 $print_file = $ps_final;
2637 $print_cmd = $lpr;
2638 }
2639 elsif ( $print_type eq 'none' ) {
2640 $print_cmd = 'NONE echo NO PRINTING CONFIGURED';
2641 }
2642
2643 my $view_file = '';
2644 my $viewer = '';
2645 my $viewer_update_method = 0;
2646 my $viewer_update_signal = undef;
2647 my $viewer_update_command = undef;
2648
2649 if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) {
2650 $view_file = ${$view.'_final'};
2651 $viewer = ${$view.'_previewer'};
2652 $viewer_update_method = ${$view.'_update_method'};
2653 $viewer_update_signal = ${$view.'_update_signal'};
2654 if (defined ${$view.'_update_command'}) {
2655 $viewer_update_command = ${$view.'_update_command'};
2656 }
2657 }
2658 # Specification of internal command for viewer update:
2659 my $PA_update = ['do_update_view', $viewer_update_method, $viewer_update_signal, 0, 1];
2660
2661# For test_kind: Use file contents for latex and friends, but file time for the others.
2662# This is because, especially for dvi file, the contents of the file may contain
2663# a pointer to a file to be included, not the contents of the file!
2664 %rule_list = (
2665 'latex' => [ 'primary', "$latex", '', "%T", "%Z%B.dvi", "%R", 1, ["%Y%R.log"] ],
2666 'pdflatex' => [ 'primary', "$pdflatex", '', "%T", "%Z%B.pdf", "%R", 1, ["%Y%R.log"] ],
2667 'lualatex' => [ 'primary', "$lualatex", '', "%T", "%Z%B.pdf", "%R", 1, ["%Y%R.log"] ],
2668 'xelatex' => [ 'primary', "$xelatex", '', "%T", "%Z%B.xdv", "%R", 1, ["%Y%R.log"] ],
2669 'dvipdf' => [ 'external', "$dvipdf", 'do_viewfile', $dvi_final, "%B.pdf", "%Z%R", 2 ],
2670 'xdvipdfmx' => [ 'external', "$xdvipdfmx", 'do_viewfile', $xdv_final, "%B.pdf", "%Z%R", 2 ],
2671 'dvips' => [ 'external', "$dvips", 'do_viewfile', $dvi_final, "%B.ps", "%Z%R", 2 ],
2672 'dvifilter'=> [ 'external', $dvi_filter, 'do_viewfile', "%B.dvi", "%B.dviF", "%Z%R", 2 ],
2673 'ps2pdf' => [ 'external', "$ps2pdf", 'do_viewfile', $ps_final, "%B.pdf", "%Z%R", 2 ],
2674 'psfilter' => [ 'external', $ps_filter, 'do_viewfile', "%B.ps", "%B.psF", "%Z%R", 2 ],
2675 'print' => [ 'external', "$print_cmd", 'if_source', $print_file, "", "", 2 ],
2676 'update_view' => [ 'external', $viewer_update_command, $PA_update,
2677 $view_file, "", "", 2 ],
2678 'view' => [ 'external', "$viewer", 'if_source', $view_file, "", "", 2 ],
2679 );
2680
2681# Ensure we only have one way to make pdf file, and that it is appropriate:
2682 if ($pdf_mode == 2) { delete $rule_list{'dvipdf'}; delete $rule_list{'pdflatex'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; }
2683 elsif ($pdf_mode == 3) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; }
2684 elsif ($pdf_mode == 4) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'dvipdf'}; delete $rule_list{'xelatex'}; }
2685 elsif ($pdf_mode == 5) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'dvipdf'}; delete $rule_list{'lualatex'}; }
2686 else { # Default is to leave pdflatex
2687 delete $rule_list{'dvipdf'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'};
2688 }
2689
2690} # END rdb_make_rule_list
2691
2692#************************************************************
2693
2694sub rdb_set_rules {
2695 # Call rdb_set_rules( \%rule_list, ...)
2696 # Set up rule database from definitions
2697
2698 # Map of files to rules that MAKE them:
2699 %rule_db = ();
2700
2701 foreach my $Prule_list (@_) {
2702 foreach my $rule ( keys %$Prule_list) {
2703 my ( $cmd_type, $ext_cmd, $int_cmd, $source, $dest, $base, $test_kind, $PA_extra_gen ) = @{$$Prule_list{$rule}};
2704 if ( ! $PA_extra_gen ) { $PA_extra_gen = []; }
2705 my $needs_making = 0;
2706 # Substitute in the filename variables, since we will use
2707 # those for determining filenames. But delay expanding $cmd
2708 # until run time, in case of changes.
2709 foreach ($base, $source, $dest, @$PA_extra_gen ) {
2710 s/%R/$root_filename/;
2711 s/%Y/$aux_dir1/;
2712 s/%Z/$out_dir1/;
2713 }
2714 foreach ($source, $dest ) {
2715 s/%B/$base/;
2716 s/%T/$texfile_name/;
2717 }
2718 # print "$rule: $cmd_type, EC='$ext_cmd', IC='$int_cmd', $test_kind,\n",
2719 # " S='$source', D='$dest', B='$base' $needs_making\n";
2720 rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, $test_kind,
2721 $source, $dest, $base,
2722 $needs_making, undef, undef, 1, $PA_extra_gen );
2723# !! ?? Last line was
2724# $needs_making, undef, ($test_kind==1) );
2725 }
2726 } # End arguments of subroutine
2727 &rdb_make_links;
2728} # END rdb_set_rules
2729
2730#************************************************************
2731
2732sub rdb_make_links {
2733# ?? Problem if there are multiple rules for getting a file. Notably pdf.
2734# Which one to choose?
2735 # Create $from_rule if there's a suitable rule.
2736 # Map files to rules:
2737 local %from_rules = ();
2738 rdb_for_all( sub{ if($$Pdest){$from_rules{$$Pdest} = $rule;} } );
2739#?? foreach (sort keys %from_rules) {print "D='$_' F='$from_rules{$_}\n";}
2740 rdb_for_all(
2741 0,
2742 sub{
2743 # Set from_rule, but only if it isn't set or is invalid.
2744 # Don't forget the biber v. bibtex issue
2745 if ( exists $from_rules{$file}
2746 && ( (!$$Pfrom_rule) || (! exists $rule_db{$$Pfrom_rule} ) )
2747 )
2748 { $$Pfrom_rule = $from_rules{$file};
2749 }
2750 }
2751 );
2752 rdb_for_all(
2753 0,
2754 sub{
2755 if ( exists $from_rules{$file} ) {
2756 $$Pfrom_rule = $from_rules{$file};
2757 }
2758 if ( $$Pfrom_rule && (! rdb_rule_exists( $$Pfrom_rule ) ) ) {
2759 $$Pfrom_rule = '';
2760 }
2761#?? print "$rule: $file, $$Pfrom_rule\n";
2762 }
2763 );
2764} # END rdb_make_links
2765
2766#************************************************************
2767
2768sub set_trivial_aux_fdb {
2769 # 1. Write aux file EXACTLY as would be written if the tex file
2770 # had no cross references, etc. I.e., a minimal .aux file.
2771 # 2. Write a corresponding fdb file
2772 # 3. Provoke a run of (pdf)latex (actually of all primaries).
2773
2774 local *aux_file;
2775 open( aux_file, '>', $aux_main )
2776 or die "Cannot write file '$aux_main'\n";
2777 print aux_file "\\relax \n";
2778 close(aux_file);
2779
2780 foreach my $rule (keys %primaries ) {
2781 rdb_ensure_file( $rule, $texfile_name );
2782 rdb_ensure_file( $rule, $aux_main );
2783 rdb_one_rule( $rule,
2784 sub{ $$Pout_of_date = 1; }
2785 );
2786 }
2787 &rdb_write( $fdb_name );
2788} #END set_trivial_aux_fdb
2789
2790#************************************************************
2791#### Particular actions
2792#************************************************************
2793#************************************************************
2794
2795sub do_cusdep {
2796 # Unconditional application of custom-dependency
2797 # except that rule is not applied if the source file source
2798 # does not exist, and an error is returned if the dest is not made.
2799 #
2800 # Assumes rule context for the custom-dependency, and that my first
2801 # argument is the name of the subroutine to apply
2802 my $func_name = $_[0];
2803 my $return = 0;
2804 if ( !-e $$Psource ) {
2805 # Source does not exist. Users of this rule will need to turn
2806 # it off when custom dependencies are reset
2807 if ( !$silent ) {
2808## ??? Was commented out. 1 Sep. 2008 restored, for cusdep no-file-exists issue
2809 warn "$My_name: In trying to apply custom-dependency rule\n",
2810 " to make '$$Pdest' from '$$Psource'\n",
2811 " the source file has disappeared since the last run\n";
2812 }
2813 # Treat as successful
2814 }
2815 elsif ( !$func_name ) {
2816 warn "$My_name: Possible misconfiguration or bug:\n",
2817 " In trying to apply custom-dependency rule\n",
2818 " to make '$$Pdest' from '$$Psource'\n",
2819 " the function name is blank.\n";
2820 }
2821 elsif ( ! defined &$func_name ) {
2822 warn "$My_name: Misconfiguration or bug,",
2823 " in trying to apply custom-dependency rule\n",
2824 " to make '$$Pdest' from '$$Psource'\n",
2825 " function name '$func_name' does not exists.\n";
2826 }
2827 else {
2828 my $cusdep_ret = &$func_name( $$Pbase );
2829 if ( defined $cusdep_ret && ($cusdep_ret != 0) ) {
2830 $return = $cusdep_ret;
2831 if ($return) {
2832 warn "Rule '$rule', function '$func_name'\n",
2833 " failed with return code = $return\n";
2834 }
2835 }
2836 elsif ( !-e $$Pdest ) {
2837 # Destination non-existent, but routine failed to give an error
2838 warn "$My_name: In running custom-dependency rule\n",
2839 " to make '$$Pdest' from '$$Psource'\n",
2840 " function '$func_name' did not make the destination.\n";
2841 $return = -1;
2842 }
2843 }
2844 return $return;
2845} # END do_cusdep
2846
2847#************************************************************
2848
2849sub do_viewfile {
2850 # Unconditionally make file for viewing, going through temporary file if
2851 # Assumes rule context
2852
2853 my $return = 0;
2854 my ($base, $path, $ext) = fileparseA( $$Pdest );
2855 if ( &view_file_via_temporary ) {
2856 if ( $$Pext_cmd =~ /%D/ ) {
2857 my $tmpfile = tempfile1( "${root_filename}_tmp", $ext );
2858 warn "$My_name: Making '$$Pdest' via temporary '$tmpfile'...\n";
2859 $return = &Run_subst( undef, undef, undef, undef, $tmpfile );
2860 move( $tmpfile, $$Pdest );
2861 }
2862 else {
2863 warn "$My_name is configured to make '$$Pdest' via a temporary file\n",
2864 " but the command template '$$Pext_cmd' does not have a slot\n",
2865 " to set the destination file, so I won't use a temporary file\n";
2866 $return = &Run_subst();
2867 }
2868 }
2869 else {
2870 $return = &Run_subst();
2871 }
2872 return $return;
2873} #END do_viewfile
2874
2875#************************************************************
2876
2877sub do_update_view {
2878 # Update viewer
2879 # Assumes rule context
2880 # Arguments: (method, signal, viewer_process)
2881
2882 my $return = 0;
2883
2884 # Although the process is passed as an argument, we'll need to update it.
2885 # So (FUDGE??) bypass the standard interface for the process.
2886 # We might as well do this for all the arguments.
2887 my $viewer_update_method = ${$PAint_cmd}[1];
2888 my $viewer_update_signal = ${$PAint_cmd}[2];
2889 my $Pviewer_process = \${$PAint_cmd}[3];
2890 my $Pneed_to_get_viewer_process = \${$PAint_cmd}[4];
2891
2892 if ($viewer_update_method == 2) {
2893 if ($$Pneed_to_get_viewer_process) {
2894 $$Pviewer_process = &find_process_id( $$Psource );
2895 if ($$Pviewer_process != 0) {
2896 $$Pneed_to_get_viewer_process = 0;
2897 }
2898 }
2899 if ($$Pviewer_process == 0) {
2900 print "$My_name: need to signal viewer for file '$$Psource', but didn't get \n",
2901 " process ID for some reason, e.g., no viewer, bad configuration, bug\n"
2902 if $diagnostics ;
2903 }
2904 elsif ( defined $viewer_update_signal) {
2905 print "$My_name: signalling viewer, process ID $$Pviewer_process ",
2906 "with signal $viewer_update_signal\n"
2907 if $diagnostics ;
2908 kill $viewer_update_signal, $$Pviewer_process;
2909 }
2910 else {
2911 warn "$My_name: viewer is supposed to be sent a signal\n",
2912 " but no signal is defined. Misconfiguration or bug?\n";
2913 $return = 1;
2914 }
2915 }
2916 elsif ($viewer_update_method == 4) {
2917 if (defined $$Pext_cmd) {
2918 $return = &Run_subst();
2919 }
2920 else {
2921 warn "$My_name: viewer is supposed to be updated by running a command,\n",
2922 " but no command is defined. Misconfiguration or bug?\n";
2923 }
2924 }
2925 return $return;
2926} #END do_update_view
2927
2928#************************************************************
2929
2930sub if_source {
2931 # Unconditionally apply rule if source file exists.
2932 # Assumes rule context
2933 if ( -e $$Psource ) {
2934 return &Run_subst();
2935 }
2936 else {
2937 warn "Needed source file '$$Psource' does not exist.\n";
2938 return -1;
2939 }
2940} #END if_source
2941
2942#************************************************************
2943#### Subroutines
2944#************************************************************
2945#************************************************************
2946
2947sub find_basename {
2948 # Finds the basename of the root file
2949 # Arguments:
2950 # 1 - Filename to breakdown
2951 # 2 - Where to place base file
2952 # 3 - Where to place tex file
2953 # Returns non-zero if tex file does not exist
2954 #
2955 # The rules for determining this depend on the implementation of TeX.
2956 # The variable $extension_treatment determines which rules are used.
2957
2958 # !!!!!!!! I still need to implement use of kpsewhich to match behavior
2959 # of (pdf)latex correctly.
2960
2961 local($given_name, $base_name, $ext, $path, $tex_name);
2962 $given_name = $_[0];
2963 if ( "$extension_treatment" eq "miktex_old" ) {
2964 # Miktex v. 1.20d:
2965 # 1. If the filename has an extension, then use it.
2966 # 2. Else append ".tex".
2967 # 3. The basename is obtained from the filename by
2968 # removing the path component, and the extension, if it
2969 # exists. If a filename has a multiple extension, then
2970 # all parts of the extension are removed.
2971 # 4. The names of generated files (log, aux) are obtained by
2972 # appending .log, .aux, etc to the basename. Note that
2973 # these are all in the CURRENT directory, and the drive/path
2974 # part of the originally given filename is ignored.
2975 #
2976 # Thus when the given filename is "\tmp\a.b.c", the tex
2977 # filename is the same, and the basename is "a".
2978
2979 ($base_name, $path, $ext) = fileparse( $given_name, '\..*' );
2980 if ( "$ext" eq "") { $tex_name = "$given_name.tex"; }
2981 else { $tex_name = $given_name; }
2982 $_[1] = $base_name;
2983 $_[2] = $tex_name;
2984 }
2985 elsif ( "$extension_treatment" eq "unix" ) {
2986 # unix (at least TeXLive 2016) =>
2987 # A. Finding of tex file:
2988 # 1. If filename.tex exists, use it,
2989 # 2. else if kpsewhich finds filename.tex, use it
2990 # 3. else if filename exists, use it,
2991 # 4. else if kpsewhich finds filename, use it.
2992 # (Probably can unify the above by
2993 # 1'. If kpsewhich finds filename.tex, use result.
2994 # 2'. else if kpsewhich finds filename, use result.
2995 # 3'. else report file not found.
2996 # B. The base filename is obtained by deleting the path
2997 # component and, if an extension exists, the last
2998 # component of the extension, even if the extension is
2999 # null. (A name ending in "." has a null extension.)
3000 # C. The names of generated files (log, aux) are obtained by
3001 # appending .log, .aux, etc to the basename. Note that
3002 # these are all in the CURRENT directory, and the drive/path
3003 # part of the originally given filename is ignored.
3004 #
3005 # Thus when the given filename is "/tmp/a.b.c", there are two
3006 # cases:
3007 # a. /tmp/a.b.c.tex exists. Then this is the tex file,
3008 # and the basename is "a.b.c".
3009 # b. /tmp/a.b.c.tex does not exist. Then the tex file is
3010 # "/tmp/a.b.c", and the basename is "a.b".
3011 # But there are also modifications of this when a file can be
3012 # found by kpsewhich.
3013
3014 if ( -f "$given_name.tex" ) {
3015 $tex_name = "$given_name.tex";
3016 }
3017 else {
3018 $tex_name = "$given_name";
3019 }
3020 ($base_name, $path, $ext) = fileparse( $tex_name, '\.[^\.]*' );
3021 $_[1] = $base_name;
3022 $_[2] = $tex_name;
3023 }
3024 else {
3025 die "$My_name: Incorrect configuration gives \$extension_treatment=",
3026 "'$extension_treatment'\n";
3027 }
3028 if ($diagnostics) {
3029 print "Given='$given_name', tex='$tex_name', base='$base_name'\n";
3030 }
3031 return ! -e $tex_name;
3032} #END find_basename
3033
3034#************************************************************
3035
3036sub make_preview_continuous {
3037 local @changed = ();
3038 local @disappeared = ();
3039 local @no_dest = (); # Non-existent destination files
3040 local @rules_never_run = ();
3041 local @rules_to_apply = ();
3042
3043 local $failure = 0;
3044 local %rules_applied = ();
3045 local $updated = 0;
3046
3047 # What to make?
3048 my @targets = keys %requested_filerules;
3049
3050 $quell_uptodate_msgs = 1;
3051
3052 local $view_file = '';
3053 rdb_one_rule( 'view', sub{ $view_file = $$Psource; } );
3054
3055 if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) {
3056 warn "Viewing $view\n";
3057 }
3058 elsif ( $view eq 'none' ) {
3059 warn "Not using a previewer\n";
3060 $view_file = '';
3061 }
3062 else {
3063 warn "$My_name: BUG: Invalid preview method '$view'\n";
3064 exit 20;
3065 }
3066
3067 my $viewer_running = 0; # No viewer known to be running yet
3068 # Get information from update_view rule
3069 local $viewer_update_method = 0;
3070 # Pointers so we can update the following:
3071 local $Pviewer_process = undef;
3072 local $Pneed_to_get_viewer_process = undef;
3073 rdb_one_rule( 'update_view',
3074 sub{ $viewer_update_method = $$PAint_cmd[1];
3075 $Pviewer_process = \$$PAint_cmd[3];
3076 $Pneed_to_get_viewer_process = \$$PAint_cmd[4];
3077 }
3078 );
3079 # Note that we don't get the previewer process number from the program
3080 # that starts it; that might only be a script to get things set up and the
3081 # actual previewer could be (and sometimes IS) another process.
3082
3083 if ( ($view_file ne '') && (-e $view_file) && !$new_viewer_always ) {
3084 # Is a viewer already running?
3085 # (We'll save starting up another viewer.)
3086 $$Pviewer_process = &find_process_id( $view_file );
3087 if ( $$Pviewer_process ) {
3088 warn "$My_name: Previewer is already running\n"
3089 if !$silent;
3090 $viewer_running = 1;
3091 $$Pneed_to_get_viewer_process = 0;
3092 }
3093 }
3094
3095 # Loop forever, rebuilding .dvi and .ps as necessary.
3096 # Set $first_time to flag first run (to save unnecessary diagnostics)
3097 my $last_action_time = time();
3098 my $timed_out = 0;
3099CHANGE:
3100 for (my $first_time = 1; 1; $first_time = 0 ) {
3101 my %rules_to_watch = %requested_filerules;
3102 $updated = 0;
3103 $failure = 0;
3104 $failure_msg = '';
3105 if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) {
3106 # Fudge under MSWin32 ONLY, to stop perl/latexmk from
3107 # catching ctrl/C and ctrl/break, and let it only reach
3108 # downstream programs. See comments at first definition of
3109 # $MSWin_fudge_break.
3110 $SIG{BREAK} = $SIG{INT} = 'IGNORE';
3111 }
3112 if ($compiling_cmd) {
3113 Run_subst( $compiling_cmd );
3114 }
3115 $failure = rdb_make( @targets );
3116
3117## warn "=========Viewer PID = $$Pviewer_process; updated=$updated\n";
3118
3119 if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) {
3120 $SIG{BREAK} = $SIG{INT} = 'DEFAULT';
3121 }
3122 # Start viewer if needed.
3123 if ( ($failure > 0) && (! $force_mode) ) {
3124 # No viewer yet
3125 }
3126 elsif ( ($view_file ne '') && (-e $view_file) && $updated && $viewer_running ) {
3127 # A viewer is running. Explicitly get it to update screen if we have to do it:
3128 rdb_one_rule( 'update_view', \&rdb_run1 );
3129 }
3130 elsif ( ($view_file ne '') && (-e $view_file) && !$viewer_running ) {
3131 # Start the viewer
3132 if ( !$silent ) {
3133 if ($new_viewer_always) {
3134 warn "$My_name: starting previewer for '$view_file'\n",
3135 "------------\n";
3136 }
3137 else {
3138 warn "$My_name: I have not found a previewer that ",
3139 "is already running. \n",
3140 " So I will start it for '$view_file'\n",
3141 "------------\n";
3142 }
3143 }
3144 local $retcode = 0;
3145 rdb_one_rule( 'view', sub { $retcode = &rdb_run1;} );
3146 if ( $retcode != 0 ) {
3147 if ($force_mode) {
3148 warn "$My_name: I could not run previewer\n";
3149 }
3150 else {
3151 &exit_msg1( "I could not run previewer", $retcode);
3152 }
3153 }
3154 else {
3155 $viewer_running = 1;
3156 $$Pneed_to_get_viewer_process = 1;
3157 } # end analyze result of trying to run viewer
3158 } # end start viewer
3159 if ( $failure > 0 ) {
3160 if ( !$failure_msg ) {
3161 $failure_msg = 'Failure to make the files correctly';
3162 }
3163 @pre_primary = (); # Array of rules
3164 @post_primary = (); # Array of rules
3165 @unusual_one_time = (); # Array of rules
3166 &rdb_classify_rules( \%possible_primaries, keys %requested_filerules );
3167 # There will be files changed during the run that are irrelevant.
3168 # We need to wait for the user to change the files.
3169
3170 # So set the GENERATED files from (pdf)latex as up-to-date:
3171 rdb_for_some( [keys %current_primaries], \&rdb_update_gen_files );
3172
3173 # And don't watch for changes for post_primary rules (ps and pdf
3174 # from dvi, etc haven't been run after an error in (pdf)latex, so
3175 # are out-of-date by filetime criterion, but they should not be run
3176 # until after another (pdf)latex run:
3177 foreach (@post_primary) { delete $rules_to_watch{$_}; }
3178
3179 $failure_msg =~ s/\s*$//; #Remove trailing space
3180 warn "$My_name: $failure_msg\n",
3181 " ==> You will need to change a source file before I do another run <==\n";
3182 if ($failure_cmd) {
3183 Run_subst( $failure_cmd );
3184 }
3185 }
3186 else {
3187 if ($success_cmd) {
3188 Run_subst( $success_cmd );
3189 }
3190 }
3191 rdb_show_rule_errors();
3192 if ($rules_list) { rdb_list(); }
3193 if ($show_time && ! $first_time) { show_timing(); }
3194 if ( $dependents_list && ($updated || $failure) ) {
3195 my $deps_handle = new FileHandle "> $deps_file";
3196 if ( defined $deps_handle ) {
3197 deps_list($deps_handle);
3198 close($deps_handle);
3199 }
3200 else {
3201 warn "Cannot open '$deps_file' for output of dependency information\n";
3202 }
3203 }
3204 if ( $first_time || $updated || $failure ) {
3205 print "\n=== Watching for updated files. Use ctrl/C to stop ...\n";
3206 }
3207 $waiting = 1; if ($diagnostics) { warn "WAITING\n"; }
3208# During waiting for file changes, handle ctrl/C and ctrl/break here, rather than letting
3209# system handle them by terminating script (and any script that calls it). This allows,
3210# for example, the clean up code in the following command line to work:
3211# latexmk -pvc foo; cleanup;
3212 &catch_break;
3213 $have_break = 0;
3214 $last_action_time = time();
3215 WAIT: while (1) {
3216 sleep( $sleep_time );
3217 if ($have_break) { last WAIT; }
3218 if ( rdb_new_changes(keys %rules_to_watch) ) {
3219 if (!$silent) {
3220 warn "$My_name: Need to remake files.\n";
3221 &rdb_diagnose_changes( ' ' );
3222 }
3223 last WAIT;
3224 }
3225 # Don't count waiting time in processing:
3226 $processing_time1 = processing_time();
3227 # Does this do this job????
3228 local $new_files = 0;
3229 rdb_for_some( [keys %current_primaries], sub{ $new_files += &rdb_find_new_files } );
3230 if ($new_files > 0) {
3231 warn "$My_name: New file(s) found.\n";
3232 last WAIT;
3233 }
3234 if ($have_break) { last WAIT; }
3235 if ($pvc_timeout && ( time() > $last_action_time+60*$pvc_timeout_mins ) ) {
3236 $timed_out = 1;
3237 last WAIT;
3238 }
3239 } # end WAIT:
3240 &default_break;
3241 if ($have_break) {
3242 print "$My_name: User typed ctrl/C or ctrl/break. I'll finish.\n";
3243 return;
3244 }
3245 if ($timed_out) {
3246 print "$My_name: More than $pvc_timeout_mins mins of inactivity. I'll finish.\n";
3247 return;
3248 }
3249 $waiting = 0; if ($diagnostics) { warn "NOT WAITING\n"; }
3250 } #end infinite_loop CHANGE:
3251} #END sub make_preview_continuous
3252
3253#************************************************************
3254
3255sub process_rc_file {
3256 # Usage process_rc_file( filename )
3257 # NEW VERSION
3258 # Run rc_file whose name is given in first argument
3259 # Exit with code 0 on success
3260 # Exit with code 1 if file cannot be read or does not exist.
3261 # Stop if there is a syntax error or other problem.
3262 # PREVIOUSLY:
3263 # Exit with code 2 if is a syntax error or other problem.
3264 my $rc_file = $_[0];
3265 my $ret_code = 0;
3266 warn "$My_name: Executing Perl code in file '$rc_file'...\n"
3267 if $diagnostics;
3268 # I could use the do command of perl, but the preceeding -r test
3269 # to get good diagnostics gets the wrong result under cygwin
3270 # (e.g., on /cygdrive/c/latexmk/LatexMk)
3271 my $RCH = new FileHandle;
3272 if ( !-e $rc_file ) {
3273 warn "$My_name: The rc-file '$rc_file' does not exist\n";
3274 return 1;
3275 }
3276 elsif ( -d $rc_file ) {
3277 warn "$My_name: The supposed rc-file '$rc_file' is a directory; but it\n",
3278 " should be a normal text file\n";
3279 return 1;
3280 }
3281 elsif ( open $RCH, "<$rc_file" ) {
3282 { local $/; eval <$RCH>; }
3283 close $RCH;
3284 }
3285 else {
3286 warn "$My_name: I cannot read the rc-file '$rc_file'\n";
3287 return 1;
3288 }
3289 # PREVIOUS VERSION
3290# if ( ! -r $rc_file ) {
3291# warn "$My_name: I cannot read the rc-file '$rc_file'\n",
3292# " or at least that's what Perl (for $^O) reports\n";
3293# return 1;
3294# }
3295# do( $rc_file );
3296 if ( $@ ) {
3297 # Indent each line of possibly multiline message:
3298 my $message = prefix( $@, " " );
3299 warn "$My_name: Initialization file '$rc_file' gave an error:\n",
3300 "$message\n";
3301 die "$My_name: Stopping because of problem with rc file\n";
3302 # Use the following if want non-fatal error.
3303 return 2;
3304 }
3305 return 0;
3306} #END process_rc_file
3307
3308#************************************************************
3309
3310sub execute_code_string {
3311 # Usage execute_code_string( string_of_code )
3312 # Run the perl code contained in first argument
3313 # Halt if there is a syntax error or other problem.
3314 # ???Should I leave the exiting to the caller (perhaps as an option)?
3315 # But I can always catch it with an eval if necessary.
3316 # That confuses ctrl/C and ctrl/break handling.
3317 my $code = $_[0];
3318 warn "$My_name: Executing initialization code specified by -e:\n",
3319 " '$code'...\n"
3320 if $diagnostics;
3321 eval $code;
3322 # The return value from the eval is not useful, since it is the value of
3323 # the last expression evaluated, which could be anything.
3324 # The correct test of errors is on the value of $@.
3325
3326 if ( $@ ) {
3327 # Indent each line of possibly multiline message:
3328 my $message = prefix( $@, " " );
3329 die "$My_name: ",
3330 "Stopping because executing following code from command line\n",
3331 " $code\n",
3332 "gave an error:\n",
3333 "$message\n";
3334 }
3335} #END execute_code_string
3336
3337#************************************************************
3338
3339sub cleanup1 {
3340 # Usage: cleanup1( directory, exts_without_period, ... )
3341 #
3342 # The directory and the root file name are fixed names, so I must escape
3343 # any glob metacharacters in them:
3344 my $dir = fix_pattern( shift );
3345 my $root_fixed = fix_pattern( $root_filename );
3346 foreach (@_) {
3347 (my $name = /%R/ ? $_ : "%R.$_") =~ s/%R/${dir}${root_fixed}/;
3348 unlink_or_move( my_glob( "$name" ) );
3349 }
3350} #END cleanup1
3351
3352#************************************************************
3353
3354sub cleanup_cusdep_generated {
3355 # Remove files generated by custom dependencies
3356 rdb_for_all( \&cleanup_one_cusdep_generated );
3357} #END cleanup_cusdep_generated
3358
3359#************************************************************
3360
3361sub cleanup_one_cusdep_generated {
3362 # Remove destination file generated by one custom dependency
3363 # Assume rule context, but not that the rule is a custom dependency.
3364 # Only delete destination file if source file exists (so destination
3365 # file can be recreated)
3366 if ( $$Pcmd_type ne 'cusdep' ) {
3367 # NOT cusdep
3368 return;
3369 }
3370 if ( (-e $$Pdest) && (-e $$Psource) ) {
3371 unlink_or_move( $$Pdest );
3372 }
3373 elsif ( (-e $$Pdest) && (!-e $$Psource) ) {
3374 warn "$My_name: For custom dependency '$rule',\n",
3375 " I won't delete destination file '$$Pdest'\n",
3376 " because the source file '$$Psource' doesn't exist,\n",
3377 " so the destination file may not be able to be recreated\n";
3378 }
3379} #END cleanup_one_cusdep_generated
3380
3381#************************************************************
3382#************************************************************
3383#************************************************************
3384
3385# Error handling routines, warning routines, help
3386
3387#************************************************************
3388
3389sub die_trace {
3390 # Call: die_trace( message );
3391 &traceback; # argument(s) passed unchanged
3392 die "\n";
3393} #END die_trace
3394
3395#************************************************************
3396
3397sub traceback {
3398 # Call: &traceback
3399 # or traceback( message, )
3400 my $msg = shift;
3401 if ($msg) { warn "$msg\n"; }
3402 warn "Traceback:\n";
3403 my $i=0; # Start with immediate caller
3404 while ( my ($pack, $file, $line, $func) = caller($i++) ) {
3405 if ($func eq 'die_trace') { next; }
3406 warn " $func called from line $line\n";
3407 }
3408} #END traceback
3409
3410#************************************************************
3411
3412sub exit_msg1
3413{
3414 # exit_msg1( error_message, retcode [, action])
3415 # 1. display error message
3416 # 2. if action set, then restore aux file
3417 # 3. exit with retcode
3418 warn "\n------------\n";
3419 warn "$My_name: $_[0].\n";
3420 warn "-- Use the -f option to force complete processing.\n";
3421
3422 my $retcode = $_[1];
3423 if ($retcode >= 256) {
3424 # Retcode is the kind returned by system from an external command
3425 # which is 256 * command's_retcode
3426 $retcode /= 256;
3427 }
3428 exit $retcode;
3429} #END exit_msg1
3430
3431#************************************************************
3432
3433sub warn_running {
3434 # Message about running program:
3435 if ( $silent ) {
3436 warn "$My_name: @_\n";
3437 }
3438 else {
3439 warn "------------\n@_\n------------\n";
3440 }
3441} #END warn_running
3442
3443#************************************************************
3444
3445sub exit_help
3446# Exit giving diagnostic from arguments and how to get help.
3447{
3448 warn "\n$My_name: @_\n",
3449 "Use\n",
3450 " $my_name -help\nto get usage information\n";
3451 exit 10;
3452} #END exit_help
3453
3454
3455#************************************************************
3456
3457sub print_help
3458{
3459 print
3460 "$My_name $version_num: Automatic LaTeX document generation routine\n\n",
3461 "Usage: $my_name [latexmk_options] [filename ...]\n\n",
3462 " Latexmk_options:\n",
3463 " -aux-directory=dir or -auxdir=dir \n",
3464 " - set name of directory for auxiliary files (aux, log)\n",
3465 " - Currently this only works with MiKTeX\n",
3466 " -bibtex - use bibtex when needed (default)\n",
3467 " -bibtex- - never use bibtex\n",
3468 " -bibtex-cond - use bibtex when needed, but only if the bib file exists\n",
3469 " -bibtex-cond1 - use bibtex when needed, but only if the bib file exists;\n",
3470 " on cleanup delete bbl file only if bib file exists\n",
3471 " -bm <message> - Print message across the page when converting to postscript\n",
3472 " -bi <intensity> - Set contrast or intensity of banner\n",
3473 " -bs <scale> - Set scale for banner\n",
3474 " -commands - list commands used by $my_name for processing files\n",
3475 " -c - clean up (remove) all nonessential files, except\n",
3476 " dvi, ps and pdf files.\n",
3477 " This and the other clean-ups are instead of a regular make.\n",
3478 " -C - clean up (remove) all nonessential files\n",
3479 " including aux, dep, dvi, postscript and pdf files\n",
3480 " and file of database of file information\n",
3481 " -CA - clean up (remove) all nonessential files.\n",
3482 " Equivalent to -C option.\n",
3483 " -CF - Remove file of database of file information before doing \n",
3484 " other actions\n",
3485 " -cd - Change to directory of source file when processing it\n",
3486 " -cd- - Do NOT change to directory of source file when processing it\n",
3487 " -dependents or -deps - Show list of dependent files after processing\n",
3488 " -dependents- or -deps- - Do not show list of dependent files\n",
3489 " -deps-out=file - Set name of output file for dependency list,\n",
3490 " and turn on showing of dependency list\n",
3491 " -dF <filter> - Filter to apply to dvi file\n",
3492 " -dvi - generate dvi\n",
3493 " -dvi- - turn off required dvi\n",
3494 " -e <code> - Execute specified Perl code (as part of latexmk start-up\n",
3495 " code)\n",
3496 " -f - force continued processing past errors\n",
3497 " -f- - turn off forced continuing processing past errors\n",
3498 " -gg - Super go mode: clean out generated files (-CA), and then\n",
3499 " process files regardless of file timestamps\n",
3500 " -g - process regardless of file timestamps\n",
3501 " -g- - Turn off -g\n",
3502 " -h - print help\n",
3503 " -help - print help\n",
3504 " -jobname=STRING - set basename of output file(s) to STRING.\n",
3505 " (Like --jobname=STRING on command line for many current\n",
3506 " implementations of latex/pdflatex.)\n",
3507 " -l - force landscape mode\n",
3508 " -l- - turn off -l\n",
3509 " -latex=<program> - set program used for latex.\n",
3510 " (replace '<program>' by the program name)\n",
3511 " -latexoption=<option> - add the given option to the (pdf)latex command\n",
3512 " -logfilewarninglist or -logfilewarnings \n",
3513 " give list of warnings after run of (pdf)latex\n",
3514 " -logfilewarninglist- or -logfilewarnings- \n",
3515 " do not give list of warnings after run of (pdf)latex\n",
3516 " -lualatex - use lualatex for processing files to pdf\n",
3517 " and turn dvi/ps modes off\n",
3518 " -M - Show list of dependent files after processing\n",
3519 " -MF file - Specifies name of file to receives list dependent files\n",
3520 " -MP - List of dependent files includes phony target for each source file.\n",
3521 " -new-viewer - in -pvc mode, always start a new viewer\n",
3522 " -new-viewer- - in -pvc mode, start a new viewer only if needed\n",
3523 " -nobibtex - never use bibtex\n",
3524 " -nodependents - Do not show list of dependent files after processing\n",
3525 " -norc - omit automatic reading of system, user and project rc files\n",
3526 " -output-directory=dir or -outdir=dir\n",
3527 " - set name of directory for output files\n",
3528 " -pdf - generate pdf by pdflatex\n",
3529 " -pdfdvi - generate pdf by dvipdf\n",
3530 " -pdflatex=<program> - set program used for pdflatex.\n",
3531 " (replace '<program>' by the program name)\n",
3532 " -pdfps - generate pdf by ps2pdf\n",
3533 " -pdflua - generate pdf by lualatex\n",
3534 " -pdfxe - generate pdf by xelatex\n",
3535 " -pdf- - turn off pdf\n",
3536 " -ps - generate postscript\n",
3537 " -ps- - turn off postscript\n",
3538 " -pF <filter> - Filter to apply to postscript file\n",
3539 " -p - print document after generating postscript.\n",
3540 " (Can also .dvi or .pdf files -- see documentation)\n",
3541 " -print=dvi - when file is to be printed, print the dvi file\n",
3542 " -print=ps - when file is to be printed, print the ps file (default)\n",
3543 " -print=pdf - when file is to be printed, print the pdf file\n",
3544 " -pv - preview document. (Side effect turn off continuous preview)\n",
3545 " -pv- - turn off preview mode\n",
3546 " -pvc - preview document and continuously update. (This also turns\n",
3547 " on force mode, so errors do not cause $my_name to stop.)\n",
3548 " (Side effect: turn off ordinary preview mode.)\n",
3549 " -pvc- - turn off -pvc\n",
3550 " -pvctimeout - timeout in pvc mode after period of inactivity\n",
3551 " -pvctimeout- - don't timeout in pvc mode after inactivity\n",
3552 " -pvctimeoutmins=<time> - set period of inactivity (minutes) for pvc timeout\n",
3553 " -quiet - silence progress messages from called programs\n",
3554 " -r <file> - Read custom RC file\n",
3555 " (N.B. This file could override options specified earlier\n",
3556 " on the command line.)\n",
3557 " -recorder - Use -recorder option for (pdf)latex\n",
3558 " (to give list of input and output files)\n",
3559 " -recorder- - Do not use -recorder option for (pdf)latex\n",
3560 " -rules - Show list of rules after processing\n",
3561 " -rules- - Do not show list of rules after processing\n",
3562 " -showextraoptions - Show other allowed options that are simply passed\n",
3563 " as is to latex and pdflatex\n",
3564 " -silent - silence progress messages from called programs\n",
3565 " -time - show CPU time used\n",
3566 " -time- - don't show CPU time used\n",
3567 " -use-make - use the make program to try to make missing files\n",
3568 " -use-make- - don't use the make program to try to make missing files\n",
3569 " -v - display program version\n",
3570 " -verbose - display usual progress messages from called programs\n",
3571 " -version - display program version\n",
3572 " -view=default - viewer is default (dvi, ps, pdf)\n",
3573 " -view=dvi - viewer is for dvi\n",
3574 " -view=none - no viewer is used\n",
3575 " -view=ps - viewer is for ps\n",
3576 " -view=pdf - viewer is for pdf\n",
3577 " -xelatex - use xelatex for processing files to pdf\n",
3578 " and turn dvi/ps modes off\n",
3579 "\n",
3580 " filename = the root filename of LaTeX document\n",
3581 "\n",
3582 "-p, -pv and -pvc are mutually exclusive\n",
3583 "-h, -c and -C override all other options.\n",
3584 "-pv and -pvc require one and only one filename specified\n",
3585 "All options can be introduced by '-' or '--'. (E.g., --help or -help.)\n",
3586 " \n",
3587 "In addition, latexmk recognizes many other options that are passed to\n",
3588 "latex and/or pdflatex without interpretation by latexmk. Run latexmk\n",
3589 "with the option -showextraoptions to see a list of these\n",
3590 "\n",
3591 "Report bugs etc to John Collins <jcc8 at psu.edu>.\n";
3592
3593} #END print_help
3594
3595#************************************************************
3596
3597sub print_commands {
3598 warn "Commands used by $my_name:\n",
3599 " To run latex, I use \"$latex\"\n",
3600 " To run pdflatex, I use \"$pdflatex\"\n",
3601 " To run lualatex, I use \"$lualatex\"\n",
3602 " To run xelatex, I use \"$xelatex\"\n",
3603 " To run biber, I use \"$biber\"\n",
3604 " To run bibtex, I use \"$bibtex\"\n",
3605 " To run makeindex, I use \"$makeindex\"\n",
3606 " To make a ps file from a dvi file, I use \"$dvips\"\n",
3607 " To make a ps file from a dvi file with landscape format, ",
3608 "I use \"$dvips_landscape\"\n",
3609 " To make a pdf file from a dvi file, I use \"$dvipdf\"\n",
3610 " To make a pdf file from a ps file, I use \"$ps2pdf\"\n",
3611 " To make a pdf file from an xdv file, I use \"$xdvipdfmx\"\n",
3612 " To view a pdf file, I use \"$pdf_previewer\"\n",
3613 " To view a ps file, I use \"$ps_previewer\"\n",
3614 " To view a ps file in landscape format, ",
3615 "I use \"$ps_previewer_landscape\"\n",
3616 " To view a dvi file, I use \"$dvi_previewer\"\n",
3617 " To view a dvi file in landscape format, ",
3618 "I use \"$dvi_previewer_landscape\"\n",
3619 " To print a ps file, I use \"$lpr\"\n",
3620 " To print a dvi file, I use \"$lpr_dvi\"\n",
3621 " To print a pdf file, I use \"$lpr_pdf\"\n",
3622 " To find running processes, I use \"$pscmd\", \n",
3623 " and the process number is at position $pid_position\n";
3624 warn "Notes:\n",
3625 " Command starting with \"start\" is run detached\n",
3626 " Command that is just \"start\" without any other command, is\n",
3627 " used under MS-Windows to run the command the operating system\n",
3628 " has associated with the relevant file.\n",
3629 " Command starting with \"NONE\" is not used at all\n";
3630} #END print_commands
3631
3632#************************************************************
3633
3634sub view_file_via_temporary {
3635 return $always_view_file_via_temporary
3636 || ($pvc_view_file_via_temporary && $preview_continuous_mode);
3637} #END view_file_via_temporary
3638
3639#************************************************************
3640#### Tex-related utilities
3641
3642#**************************************************
3643
3644sub check_biber_log {
3645 # Check for biber warnings:
3646 # Usage: check_biber_log( base_of_biber_run, \@biber_source )
3647 # return 0: OK;
3648 # 1: biber warnings;
3649 # 2: biber errors;
3650 # 3: could not open .blg file;
3651 # 4: failed to find one or more source files, except for bibfile;
3652 # 5: failed to find bib file;
3653 # 6: missing file, one of which is control file
3654 # 10: only error is missing \citation commands.
3655 # 11: Malformed bcf file (normally due to error in pdflatex run)
3656 # Side effect: add source files @biber_source
3657 my $base = $_[0];
3658 my $Pbiber_source = $_[1];
3659 my $log_name = "$base.blg";
3660 my $log_file = new FileHandle;
3661 open( $log_file, "<$log_name" )
3662 or return 3;
3663 my $have_warning = 0;
3664 my $have_error = 0;
3665 my $missing_citations = 0;
3666 my $no_citations = 0;
3667 my $error_count = 0; # From my counting of error messages
3668 my $warning_count = 0; # From my counting of warning messages
3669 # The next two occur only from biber
3670 my $bibers_error_count = 0; # From biber's counting of errors
3671 my $bibers_warning_count = 0; # From biber's counting of warnings
3672 my $not_found_count = 0;
3673 my $control_file_missing = 0;
3674 my $control_file_malformed = 0;
3675 while (<$log_file>) {
3676 if (/> WARN /) {
3677 print "Biber warning: $_";
3678 $have_warning = 1;
3679 $warning_count ++;
3680 }
3681 elsif (/> (FATAL|ERROR) /) {
3682 print "Biber error: $_";
3683 if ( /> (FATAL|ERROR) - Cannot find file '([^']+)'/ #'
3684 || /> (FATAL|ERROR) - Cannot find '([^']+)'/ ) { #'
3685 $not_found_count++;
3686 push @$Pbiber_source, $2;
3687 }
3688 elsif ( /> (FATAL|ERROR) - Cannot find control file '([^']+)'/ ) { #'
3689 $not_found_count++;
3690 $control_file_missing = 1;
3691 push @$Pbiber_source, $2;
3692 }
3693 elsif ( /> ERROR - .*\.bcf is malformed/ ) {
3694 # Special treatment: Malformed .bcf file commonly results from error
3695 # in (pdf)latex run. This error must be ignored.
3696 $control_file_malformed = 1;
3697 }
3698 else {
3699 $have_error = 1;
3700 $error_count ++;
3701 if ( /> (FATAL|ERROR) - The file '[^']+' does not contain any citations!/ ) { #'
3702 $no_citations++;
3703 }
3704 }
3705 }
3706 elsif ( /> INFO - Found .* '([^']+)'\s*$/
3707 || /> INFO - Found '([^']+)'\s*$/
3708 || /> INFO - Reading '([^']+)'\s*$/
3709 || /> INFO - Reading (.*)$/
3710 || /> INFO - Processing .* file '([^']+)' .*$/
3711 ) {
3712 if ( defined $Pbiber_source ) {
3713 push @$Pbiber_source, $1;
3714 }
3715 }
3716 elsif ( /> INFO - WARNINGS: ([\d]+)\s*$/ ) {
3717 $bibers_warning_count = $1;
3718 }
3719 elsif ( /> INFO - ERRORS: ([\d]+)\s*$/ ) {
3720 $bibers_error_count = $1;
3721 }
3722 }
3723 close $log_file;
3724 if ($control_file_malformed){return 11;}
3725
3726 my @not_found = &find_file_list1( $Pbiber_source, $Pbiber_source,
3727 '', \@BIBINPUTS );
3728 @$Pbiber_source = uniqs( @$Pbiber_source );
3729 if ( ($#not_found < 0) && ($#$Pbiber_source >= 0) ) {
3730 warn "$My_name: Found biber source file(s) [@$Pbiber_source]\n"
3731 unless $silent;
3732 }
3733 elsif ( ($#not_found == 0) && ($not_found[0] =~ /\.bib$/) ) {
3734 # Special treatment if sole missing file is bib file
3735 # I don't want to treat that as an error
3736 warn "$My_name: Biber did't find bib file [$not_found[0]]\n";
3737 return 5;
3738 }
3739 else {
3740 show_array( "$My_name: Failed to find one or more biber source files:",
3741 @not_found );
3742 if ($force_mode) {
3743 warn "==== Force_mode is on, so I will continue. ",
3744 "But there may be problems ===\n";
3745 }
3746 if ($control_file_missing) {
3747 return 6;
3748 }
3749 return 4;
3750 }
3751# print "$My_name: #Biber errors = $error_count, warning messages = $warning_count,\n ",
3752# "missing citation messages = $missing_citations, no_citations = $no_citations\n";
3753 if ( ! $have_error && $no_citations ) {
3754 # If the only errors are missing citations, or lack of citations, that should
3755 # count as a warning.
3756 # HOWEVER: biber doesn't generate a new bbl. So it is an error condition.
3757 return 10;
3758 }
3759 if ($have_error) {return 2;}
3760 if ($have_warning) {return 1;}
3761 return 0;
3762} #END check_biber_log
3763
3764#**************************************************
3765
3766sub run_bibtex {
3767 my $return = 999;
3768 # Prevent changes we make to environment becoming global:
3769 local %ENV = %ENV;
3770 if ( $aux_dir ) {
3771 # Use \Q and \E round directory name in regex to avoid interpretation
3772 # of metacharacters in directory name:
3773 if ( $$Psource =~ /^\Q$aux_dir1\E/ ) {
3774 # Run bibtex in $aux_dir, fixing input search path
3775 # to allow for finding files in original directory
3776 my ( $base, $path, $ext ) = fileparseA( $$Psource );
3777 my $cwd = good_cwd();
3778 foreach ( 'BIBINPUTS', 'BSTINPUTS' ) {
3779 if ( exists $ENV{$_} ) {
3780 $ENV{$_} = $cwd.$search_path_separator.$ENV{$_};
3781 }
3782 else {
3783 $ENV{$_} = $cwd.$search_path_separator;
3784 }
3785 }
3786 pushd( $path );
3787 $return = &Run_subst( undef, undef, '', $base.$ext, '', $base );
3788 popd();
3789 }
3790 else {
3791 warn "$My_name: Directory in file name '$$Psource' for bibtex\n",
3792 " but it is not the output directory '$aux_dir'\n";
3793 $return = Run_subst();
3794 }
3795 }
3796 else {
3797 $return = Run_subst();
3798 }
3799 return $return;
3800}
3801
3802
3803#**************************************************
3804
3805sub check_bibtex_log {
3806 # Check for bibtex warnings:
3807 # Usage: check_bibtex_log( base_of_bibtex_run )
3808 # return 0: OK, 1: bibtex warnings, 2: bibtex errors,
3809 # 3: could not open .blg file.
3810 # 10: only error is missing \citation commands or a missing aux file
3811 # (which would normally be corrected after a later run of
3812 # (pdf)latex).
3813
3814 my $base = $_[0];
3815 my $log_name = "$base.blg";
3816 my $log_file = new FileHandle;
3817 open( $log_file, "<$log_name" )
3818 or return 3;
3819 my $have_warning = 0;
3820 my $have_error = 0;
3821 my $missing_citations = 0;
3822 my @missing_aux = ();
3823 my $error_count = 0;
3824 while (<$log_file>) {
3825 if (/^Warning--/) {
3826 #print "Bibtex warning: $_";
3827 $have_warning = 1;
3828 }
3829 elsif ( /^I couldn\'t open auxiliary file (.*\.aux)/ ) {
3830 push @missing_aux, $1;
3831 }
3832 elsif ( /^I found no \\citation commands---while reading file/ ) {
3833 $missing_citations++;
3834 }
3835 elsif (/There (were|was) (\d+) error message/) {
3836 $error_count = $2;
3837 #print "Bibtex error: count=$error_count $_";
3838 $have_error = 1;
3839 }
3840 }
3841 close $log_file;
3842 my $missing = $missing_citations + $#missing_aux + 1;
3843
3844 if ( $#missing_aux > -1 ) {
3845 # Need to make the missing files.
3846 warn "$My_name: One or more aux files is missing for bibtex. I'll try\n",
3847 " to get (pdf)latex to remake them.\n";
3848 rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
3849 }
3850 #print "Bibtex errors = $error_count, missing aux files and citations = $missing\n";
3851 if ($have_error && ($error_count <= $missing )
3852 && ($missing > 0) ) {
3853 # If the only error is a missing citation line, that should only
3854 # count as a warning.
3855 # Also a missing aux file should be innocuous; it will be created on
3856 # next run of (pdf)latex. ?? HAVE I HANDLED THAT CORRECTLY?
3857 # But have to deal with the problem that bibtex gives a non-zero
3858 # exit code. So leave things as they are so that the user gets
3859 # a better diagnostic ??????????????????????????
3860# $have_error = 0;
3861# $have_warning = 1;
3862 return 10;
3863 }
3864 if ($have_error) {return 2;}
3865 if ($have_warning) {return 1;}
3866 return 0;
3867} #END check_bibtex_log
3868
3869#**************************************************
3870
3871sub normalize_force_directory {
3872 # Usage, normalize_force_directory( dir, filename )
3873 # Perform the following operations:
3874 # Clean filename
3875 # If filename contains no path component, insert dir in front
3876 # Normalize filename
3877 # Return result
3878 my $default_dir = $_[0];
3879 my $filename = clean_filename( $_[1] );
3880 my ($base_name, $path ) = fileparse( $filename );
3881 if ( $base_name eq $filename ) {
3882 $filename = "$default_dir$filename";
3883 }
3884 return normalize_filename( $filename );
3885} #END normalize force_directory
3886
3887# ------------------------------
3888
3889sub parse_log {
3890
3891# Scan log file for: dependent files
3892# reference_changed, bad_reference, bad_citation
3893# Return value: 1 if success, 0 if no log file.
3894# Put results in UPDATES of global variables (which are normally declared
3895# local in calling routine, to be suitably scoped):
3896# %dependents: maps definite dependents to code:
3897# 0 = from missing-file line
3898# May have no extension
3899# May be missing path
3900# 1 = from 'File: ... Graphic file (type ...)' line
3901# no path. Should exist, but may need a search, by kpsewhich.
3902# 2 = from regular '(...' coding for input file,
3903# Has NO path, which it would do if LaTeX file
3904# Highly likely to be mis-parsed line
3905# 3 = ditto, but has a path character ('/').
3906# Should be LaTeX file that exists.
3907# If it doesn't exist, we have probably a mis-parsed line.
3908# There's no need to do a search.
3909# 4 = definitive, which in this subroutine is only done:
3910# for default dependents,
3911# and for files that exist and are source of conversion
3912# reported by epstopdf et al.
3913# 5 = Had a missing file line. Now the file exists.
3914# 6 = File was written during run. (Overrides 5)
3915# 7 = File was created during run to be read in. (Overrides 5 and 6)
3916# (e.g., by epstopdf)
3917# Treat the following specially, since they have special rules
3918# @bbl_files to list of .bbl files.
3919# %idx_files to map from .idx files to .ind files.
3920# %generated_log: keys give set of files written by (pdf)latex (e.g., aux, idx)
3921# as determined by \openout = ... lines in log file.
3922# @missing_subdirs = list of needed subdirectories of aux_dir
3923# These are needed for writing aux_files when an included file is in
3924# a subdirectory relative to the directory of the main TeX file.
3925# This variable is only set when the needed subdirectories don't exist,
3926# and the aux_dir is non-trivial, which results in an error message in
3927# the log file
3928# %conversions Internally made conversions from one file to another
3929#
3930# These may have earlier found information in them, so they should NOT
3931# be initialized.
3932#
3933# Also SET
3934# $reference_changed, $bad_reference, $bad_citation
3935# $pwd_latex
3936#
3937# Put in trivial or default values if log file does not exist/cannot be opened
3938#
3939# Input globals: $primary_out, $fls_file_analyzed
3940#
3941
3942
3943# Give a quick way of looking up custom-dependency extensions
3944 my %cusdep_from = ();
3945 my %cusdep_to = ();
3946 foreach ( @cus_dep_list ) {
3947 my ($fromext, $toext) = split;
3948 $cusdep_from{$fromext} = $cusdep_from{".$fromext"} = $_;
3949 $cusdep_to{$toext} = $cusdep_to{".$toext"} = $_;
3950 }
3951# print "==== Cusdep from-exts:"; foreach (keys %cusdep_from) {print " '$_'";} print "\n";
3952# print "==== Cusdep to-exts:"; foreach (keys %cusdep_to) {print " '$_'";} print "\n";
3953
3954
3955 # Filenames given in log file may be preceded by a pathname
3956 # denoting current directory. In MiKTeX, this is an absolute
3957 # pathname; in TeXLive, it is './'. Either way, we'll want to
3958 # remove this pathname string --- see the comments in sub
3959 # rdb_set_latex_deps. In order of reliability for use in
3960 # normalizing filenames from the log file, the following forms
3961 # of the cwd are used:
3962 # (a) internally deduced pwd from log file from sequence of lines
3963 # **file
3964 # (dir/file
3965 # if possible. NO THAT'S WRONG if kpsearch is done.
3966 # (b) from PWD line in fls file (if available), passed as $pwd_latex
3967 # (c) system-given cwd as interpreted by sub good_cwd.
3968 # We'll put the first two in @pwd_log
3969 my @pwd_log = ();
3970 if ($pwd_latex) { push @pwd_log, $pwd_latex; }
3971
3972 # $primary_out is actual output file (dvi or pdf)
3973 # It is initialized before the call to this routine, to ensure
3974 # a sensible default in case of misparsing
3975
3976 $reference_changed = 0;
3977 $mult_defined = 0;
3978 $bad_reference = 0;
3979 $bad_citation = 0;
3980
3981 my $log_file = new FileHandle;
3982 if ( ! open( $log_file, "<$log_name" ) ) {
3983 return 0;
3984 }
3985 if ($log_file_binary) { binmode $log_file; }
3986# Collect lines of log file
3987 my @lines = ();
3988 my $line = 0;
3989 my $engine = 'pdfTeX'; # Simple default in case of problems
3990 while(<$log_file>) {
3991 $line++;
3992 # Could use chomp here, but that fails if there is a mismatch
3993 # between the end-of-line sequence used by latex and that
3994 # used by perl. (Notably a problem with MSWin latex and
3995 # cygwin perl!)
3996 s/[\n\r]*$//;
3997 # Handle wrapped lines:
3998 # They are lines brutally broken at exactly $log_wrap chars
3999 # excluding line-end. Sometimes a line $log_wrap chars
4000 # long is an ordinary line, sometimes it is part of a line
4001 # that was wrapped. To handle all cases, I keep both
4002 # options open by putting the line into @lines before
4003 # and after appending the next line:
4004 my $len = length($_);
4005 if ($line == 1) {
4006 if ( /^This is ([^,]+), / ) {
4007 $engine = $1;
4008 print "=== TeX engine is '$engine'\n"
4009 if (!$silent);
4010 }
4011 else {
4012 warn "$My_name: First line of .log file '$log_name' is not in standard format.\n";
4013 }
4014 }
4015 else {
4016 # LuaTeX sometimes wraps at 80 instead of 79, so work around this
4017 while ( ( ($len == $log_wrap) || ( ($engine eq 'LuaTeX') && ($len == $log_wrap+1) ) )
4018 && !eof($log_file) ) {
4019 push @lines, $_;
4020 my $extra = <$log_file>;
4021 $extra =~ s/[\n\r]*$//;
4022 $len = length($extra);
4023 $_ .= $extra;
4024 }
4025 }
4026 push @lines, $_;
4027 }
4028 close $log_file;
4029
4030 push @lines, ""; # Blank line to terminate. So multiline blocks
4031 # are always terminated by non-block line, rather than eof.
4032
4033 $line = 0;
4034 my $state = 0; # 0 => before ** line,
4035 # 1 => after **filename line, before next line (first file-reading line)
4036 # 2 => pwd_log determined.
4037 # For parsing multiple line blocks of info
4038 my $current_pkg = ""; # non-empty string for package name, if in
4039 # middle of parsing multi-line block of form:
4040 # Package name ....
4041 # (name) ...
4042 # ...
4043 my $block_type = ""; # Specify information in such a block
4044 my $delegated_source = ""; # If it is a file conversion, specify source
4045 my $delegated_output = ""; # and output file. (Don't put in
4046 # data structure until block is ended.)
4047 my %new_conversions = ();
4048 my @retries = ();
4049 my $log_silent = ($silent || $silence_logfile_warnings);
4050 my @warning_list = ();
4051LINE:
4052 while( ($line <= $#lines) || ($#retries > -1) ) {
4053 if ($#retries > -1) {
4054 $_ = pop @retries;
4055 }
4056 else {
4057 $_ = $lines[$line];
4058 $line ++;
4059 }
4060 if ( /^! pdfTeX warning/ || /^pdfTeX warning/ ) {
4061 # This kind of warning is produced by some versions of pdftex
4062 # or produced by my reparse of warnings from other
4063 # versions.
4064 next;
4065 }
4066 elsif ( /^(.+)(pdfTeX warning.*)$/ ) {
4067 # Line contains a pdfTeX warnings that may have been
4068 # inserted directly after other material without an
4069 # intervening new line. I think pdfTeX always inserts a
4070 # newline after the warning. (From examination of source
4071 # code.)
4072 push @retries, $1;
4073 # But continue parsing the original line, in case it was a
4074 # misparse, e.g., of a filename ending in 'pdfTeX';
4075 }
4076 if ( $line == 1 ){
4077 if ( /^This is / ) {
4078 # First line OK
4079 next LINE;
4080 } else {
4081 warn "$My_name: Error on first line of '$log_name'.\n".
4082 "This is apparently not a TeX log file. ",
4083 "The first line is:\n$_\n";
4084 $failure = 1;
4085 $failure_msg = "Log file '$log_name' appears to have wrong format.";
4086 return 0;
4087 }
4088 }
4089
4090 if ( ($state == 0) && /^\*\*(.*)$/ ) {
4091 # Line containing first line specified to tex
4092 # It's either a filename or a command starting with \
4093 my $first = $1;
4094 $state = 1;
4095 if ( ! /^\\/ ) {
4096 $source_log = $first;
4097 if ( -e "$source_log.tex" ) { $source_log .= '.tex'; }
4098 }
4099 else {
4100 $state = 2;
4101 }
4102 next LINE;
4103 }
4104 elsif ( $state == 1 ) {
4105 $state = 2;
4106 if (-e $source_log) {
4107 # then the string preceeding $source_log on the line after the
4108 # ** line is probably the PWD as it appears in filenames in the
4109 # log file, except if the file appears in two locations.
4110 if ( m{^\("([^"]*)[/\\]\Q$source_log\E"} ) {
4111 unshift @pwd_log, $1;
4112 }
4113 elsif ( m{^\((.*)[/\\]\Q$source_log\E} ) {
4114 unshift @pwd_log, $1;
4115 }
4116 }
4117 }
4118
4119 if ( $block_type ) {
4120 # In middle of parsing block
4121 if ( /^\($current_pkg\)/ ) {
4122 # Block continues
4123 if ( ($block_type eq 'conversion')
4124 && /^\($current_pkg\)\s+Output file: <([^>]+)>/ )
4125 {
4126 $delegated_output = normalize_clean_filename($1, @pwd_log);
4127 }
4128 next LINE;
4129 }
4130 # Block has ended.
4131 if ($block_type eq 'conversion') {
4132#print "=== $delegated_source -> $delegated_output\n";
4133 $new_conversions{$delegated_source} = $delegated_output;
4134 }
4135 $current_pkg = $block_type
4136 = $delegated_source = $delegated_output = "";
4137 # Then process current line
4138 }
4139
4140 # Check for changed references, bad references and bad citations:
4141 if (/Rerun to get/) {
4142 warn "$My_name: References changed.\n" if ! $log_silent;
4143 $reference_changed = 1;
4144 }
4145 if (/^LaTeX Warning: (Reference[^\001]*undefined on input line .*)\./) {
4146 push @warning_list, $1;
4147 $bad_reference++;
4148 }
4149 elsif (/^LaTeX Warning: (Label [^\001]* multiply defined.*)\./) {
4150 push @warning_list, $1;
4151 $mult_defined++;
4152 }
4153 elsif (/^LaTeX Warning: (Citation[^\001]*undefined on input line .*)\./) {
4154 push @warning_list, $1;
4155 $bad_citation++;
4156 }
4157 elsif (/^Package natbib Warning: (Citation[^\001]*undefined on input line .*)\./) {
4158 push @warning_list, $1;
4159 $bad_citation++;
4160 }
4161 elsif ( /^Document Class: / ) {
4162 # Class sign-on line
4163 next LINE;
4164 }
4165 elsif ( /^\(Font\)/ ) {
4166 # Font info line
4167 next LINE;
4168 }
4169 elsif (/^No pages of output\./) {
4170 $primary_out = '';
4171 warn "$My_name: Log file says no output from latex\n";
4172 next LINE;
4173 }
4174 elsif ( /^Output written on\s+(.*)\s+\(\d+\s+page/ ) {
4175 $primary_out = normalize_clean_filename($1, @pwd_log);
4176 warn "$My_name: Log file says output to '$primary_out'\n"
4177 unless $silent;
4178 next LINE;
4179 }
4180 elsif ( /^Overfull /
4181 || /^Underfull /
4182 || /^or enter new name\. \(Default extension: .*\)/
4183 || /^\*\*\* \(cannot \\read from terminal in nonstop modes\)/
4184 ) {
4185 # Latex error/warning, etc.
4186 next LINE;
4187 }
4188 elsif ( /^\\openout\d+\s*=\s*\`([^\']+)\'\.$/ ) {
4189 # When (pdf)latex is run with an -output-directory
4190 # or an -aux_directory, the file name does not contain
4191 # the output path; fix this, after removing quotes:
4192 $generated_log{normalize_force_directory( $aux_dir1, $1 )} = 1;
4193 next LINE;
4194 }
4195 # Test for conversion produced by package:
4196 elsif ( /^Package (\S+) Info: Source file: <([^>]+)>/ ) {
4197 # Info. produced by epstopdf (and possibly others)
4198 # about file conversion
4199 $current_pkg = normalize_clean_filename($1, @pwd_log);
4200 $delegated_source = normalize_clean_filename($2, @pwd_log);
4201 $block_type = 'conversion';
4202 next LINE;
4203 }
4204# Test for writing of index file. The precise format of the message
4205# depends on which package (makeidx.sty , multind.sty or index.sty) and
4206# which version writes the message.
4207 elsif ( /Writing index file (.*)$/ ) {
4208 my $idx_file = '';
4209 if ( /^Writing index file (.*)$/ ) {
4210 # From makeidx.sty or multind.sty
4211 $idx_file = $1;
4212 }
4213 elsif ( /^index\.sty> Writing index file (.*)$/ ) {
4214 # From old versions of index.sty
4215 $idx_file = $1;
4216 }
4217 elsif ( /^Package \S* Info: Writing index file (.*) on input line/ ) {
4218 # From new versions of index.sty
4219 $idx_file = $1;
4220 }
4221 else {
4222 warn "$My_name: Message indicates index file was written\n",
4223 " ==> but I do not know how to understand it: <==\n",
4224 " '$_'\n";
4225 next LINE;
4226 }
4227 # Typically, there is trailing space, not part of filename:
4228 $idx_file =~ s/\s*$//;
4229 # When (pdf)latex is run with an -output-directory
4230 # or an -aux_directory, the file name does not contain
4231 # the output path; fix this, after removing quotes:
4232 $idx_file = normalize_force_directory( $aux_dir1, $idx_file );
4233 my ($idx_base, $idx_path, $idx_ext) = fileparseA( $idx_file );
4234 $idx_base = $idx_path.$idx_base;
4235 $idx_file = $idx_base.$idx_ext;
4236 if ( $idx_ext eq '.idx' ) {
4237 warn "$My_name: Index file '$idx_file' was written\n"
4238 unless $silent;
4239 $idx_files{$idx_file} = [ "$idx_base.ind", $idx_base ];
4240 }
4241 elsif ( exists $cusdep_from{$idx_ext} ) {
4242 if ( !$silent ) {
4243 warn "$My_name: Index file '$idx_file' was written\n";
4244 warn " Cusdep '$cusdep_from{$idx_ext}' should be used\n";
4245 }
4246 # No action needed here
4247 }
4248 else {
4249 warn "$My_name: Index file '$idx_file' written\n",
4250 " ==> but it has an extension I do not know how to handle <==\n";
4251 }
4252
4253 next LINE;
4254 }
4255 elsif ( /^No file (.*?\.bbl)./ ) {
4256 # When (pdf)latex is run with an -output-directory
4257 # or an -aux_directory, the file name does not contain
4258 # the output path; fix this, after removing quotes:
4259 my $bbl_file = normalize_force_directory( $aux_dir1, $1 );
4260 warn "$My_name: Non-existent bbl file '$bbl_file'\n $_\n";
4261 $dependents{$bbl_file} = 0;
4262 push @bbl_files, $bbl_file;
4263 next LINE;
4264 }
4265 foreach my $pattern (@file_not_found) {
4266 if ( /$pattern/ ) {
4267 my $file = clean_filename($1);
4268 warn "===========$My_name: Missing input file: '$file' from line\n '$_'\n";
4269 warn "$My_name: Missing input file: '$file' from line\n '$_'\n"
4270 unless $silent;
4271 $dependents{normalize_filename($file, @pwd_log)} = 0;
4272 my $file1 = $file;
4273 if ( $aux_dir ) {
4274 # Allow for the possibility that latex generated
4275 # a file in $aux_dir, from which the missing file can
4276 # be created by a cusdep (or other) rule that puts
4277 # the result in $out_dir. If the announced missing file
4278 # has no path, then it would be effectively a missing
4279 # file in $aux_dir, with a path. So give this alternate
4280 # location.
4281 my $file1 = normalize_force_directory( $aux_dir1, $file );
4282 $dependents{$file1} = 0;
4283 }
4284 next LINE;
4285 }
4286 }
4287 if ( (! $fls_file_analyzed)
4288 && /^File: (.+) Graphic file \(type / ) {
4289 # First line of message from includegraphics/x
4290 # But this does NOT include full path information
4291 # (if exact match is not found and a non-trivial
4292 # kpsearch was done by (pdf)latex).
4293 # But the source-file information is in the fls file,
4294 # if we are using it.
4295 $dependents{normalize_clean_filename($1, @pwd_log)} = 1;
4296 next LINE;
4297 }
4298 # Now test for generic lines to ignore, only after special cases!
4299 if ( /^File: / ) {
4300 # Package sign-on line. Includegraphics/x also produces a line
4301 # with this signature, but I've already handled it.
4302 next LINE;
4303 }
4304 if ( /^Package: / ) {
4305 # Package sign-on line
4306 next LINE;
4307 }
4308 if (/^\! LaTeX Error: / ) {
4309 next LINE;
4310 }
4311 if ( m[^! I can't write on file `(.*)/([^/']*)'.\s*$] ) {
4312 my $dir = $1;
4313 my $file = $2;
4314 my $full_dir = $aux_dir1.$dir;
4315 if ( ($aux_dir ne '') && (! -e $full_dir) && ( $file =~ /\.aux$/) ) {
4316 warn "$My_name: === There were problems writing to '$file' in '$full_dir'\n",
4317 " I'll try to make the subdirectory later.\n"
4318 if $diagnostics;
4319 push @missing_subdirs, $full_dir;
4320 }
4321 else {
4322 warn "$My_name: ====== There were problems writing to",
4323 "----- '$file' in '$full_dir'.\n",
4324 "----- But this is not the standard situation of\n",
4325 "----- aux file to subdir of output directory, with\n",
4326 "----- non-existent subdir\n",
4327 }
4328 }
4329
4330 if ( ($fls_file_analyzed) && (! $analyze_input_log_always) ) {
4331 # Skip the last part, which is all about finding input
4332 # file names which should all appear more reliably in the
4333 # fls file.
4334 next LINE;
4335 }
4336
4337 my @new_includes = ();
4338
4339 GRAPHICS_INCLUDE_CANDIDATE:
4340 while ( /<([^>]+)(>|$)/g ) {
4341 if ( -f $1 ) { push @new_includes, $1; }
4342 } # GRAPHICS_INCLUDE_CANDIDATE:
4343
4344 INCLUDE_CANDIDATE:
4345 while ( /\((.*$)/ ) {
4346 # Filename found by
4347 # '(', then filename, then terminator.
4348 # Terminators: obvious candidates: ')': end of reading file
4349 # '(': beginning of next file
4350 # ' ': space is an obvious separator
4351 # ' [': start of page: latex
4352 # and pdflatex put a
4353 # space before the '['
4354 # '[': start of config file
4355 # in pdflatex, after
4356 # basefilename.
4357 # '{': some kind of grouping
4358 # Problem:
4359 # All or almost all special characters are allowed in
4360 # filenames under some OS, notably UNIX. Luckily most cases
4361 # are rare, if only because the special characters need
4362 # escaping. BUT 2 important cases are characters that are
4363 # natural punctuation
4364 # Under MSWin, spaces are common (e.g., "C:\Program Files")
4365 # Under VAX/VMS, '[' delimits directory names. This is
4366 # tricky to handle. But I think few users use this OS
4367 # anymore.
4368 #
4369 # Solution: use ' [', but not '[' as first try at delimiter.
4370 # Then if candidate filename is of form 'name1[name2]', then
4371 # try splitting it. If 'name1' and/or 'name2' exists, put
4372 # it/them in list, else just put 'name1[name2]' in list.
4373 # So form of filename is now:
4374 # '(',
4375 # then any number of characters that are NOT ')', '(', or '{'
4376 # (these form the filename);
4377 # then ' [', or ' (', or ')', or end-of-string.
4378 # That fails for pdflatex
4379 # In log file:
4380 # '(' => start of reading of file, followed by filename
4381 # ')' => end of reading of file
4382 # '[' => start of page (normally preceeded by space)
4383 # Remember:
4384 # filename (on VAX/VMS) may include '[' and ']' (directory
4385 # separators)
4386 # filenames (on MS-Win) commonly include space.
4387 # filenames on UNIX can included space.
4388 # Miktex quotes filenames
4389 # But web2c doesn't. Then
4390 # (string message
4391 # is ambiguous: is the filename "string" or "string message".
4392 # Allow both as candidates, since user filenames with spaces
4393 # are rare. System filenames with spaces are common, but
4394 # they are normally followed by a newline rather than messages.
4395
4396 # First step: replace $_ by whole of line after the '('
4397 # Thus $_ is putative filename followed by other stuff.
4398 $_ = $1;
4399 # Array of new candidate include files; sometimes more than one.
4400 my $quoted = 0;
4401 if ( /^\"([^\"]+)\"/ ) {
4402 # Quoted file name, as from MikTeX
4403 $quoted = 1;
4404 }
4405 elsif ( /^([^\(^\)]*?)\s+[\[\{\<]/ ) {
4406 # Terminator: space then '[' or '{' or '<'
4407 # Use *? in condition: to pick up first ' [' (etc)
4408 # as terminator
4409 }
4410 elsif ( /^([^\(^\)]*)\s+(?=\()/ ) {
4411 # Terminator is ' (', but '(' isn't in matched string,
4412 # so we keep the '(' ready for the next match
4413 }
4414 elsif ( /^([^\(^\)]*)(\))/ ) {
4415 # Terminator is ')'
4416 }
4417 else {
4418 #Terminator is end-of-string
4419 }
4420 $_ = $'; # Put $_ equal to the unmatched tail of string '
4421 my $include_candidate = $1;
4422 $include_candidate =~ s/\s*$//; # Remove trailing space.
4423 if ( !$quoted && ($include_candidate =~ /(\S+)\s/ ) ){
4424 # Non-space-containing filename-candidate
4425 # followed by space followed by message
4426 # (Common)
4427 push @new_includes, $1;
4428 }
4429 if ( $include_candidate eq "[]" ) {
4430 # Part of overfull hbox message
4431 next INCLUDE_CANDIDATE;
4432 }
4433 if ( $include_candidate =~ /^\\/ ) {
4434 # Part of font message
4435 next INCLUDE_CANDIDATE;
4436 }
4437 # Remove quotes around filename, as for MikTeX. I've already
4438 # treated this as a special case. For safety check here:
4439 $include_candidate =~ s/^\"(.*)\"$/$1/;
4440
4441 push @new_includes, $include_candidate;
4442 if ( $include_candidate =~ /^(.+)\[([^\]]+)\]$/ ) {
4443 # Construct of form 'file1[file2]', as produced by pdflatex
4444 if ( -e $1 ) {
4445 # If the first component exists, we probably have the
4446 # pdflatex form
4447 push @new_includes, $1, $2;
4448 }
4449 else {
4450 # We have something else.
4451 # So leave the original candidate in the list
4452 }
4453 }
4454 } # INCLUDE_CANDIDATE
4455
4456 INCLUDE_NAME:
4457 foreach my $include_name (@new_includes) {
4458 $include_name = normalize_filename( $include_name, @pwd_log );
4459 my ($base, $path, $ext) = fileparseB( $include_name );
4460 if ( ($path eq './') || ($path eq '.\\') ) {
4461 $include_name = $base.$ext;
4462 }
4463 if ( $include_name !~ m'[/|\\]' ) {
4464 # Filename does not include a path character
4465 # High potential for misparsed line
4466 $dependents{$include_name} = 2;
4467 } else {
4468 $dependents{$include_name} = 3;
4469 }
4470 if ( $ext eq '.bbl' ) {
4471 warn "$My_name: Found input bbl file '$include_name'\n"
4472 unless $silent;
4473 push @bbl_files, $include_name;
4474 }
4475 } # INCLUDE_NAME
4476 } # LINE
4477
4478 # Default includes are always definitive:
4479 foreach (@default_includes) { $dependents{$_} = 4; }
4480
4481 ###print "New parse: \n";
4482 ###foreach (sort keys %dependents) { print " '$_': $dependents{$_}\n"; }
4483
4484 my @misparsed = ();
4485 my @missing = ();
4486 my @not_found = ();
4487
4488 my %kpsearch_candidates = ();
4489CANDIDATE:
4490 foreach my $candidate (keys %dependents) {
4491 my $code = $dependents{$candidate};
4492 if ( -d $candidate ) {
4493 # If $candidate is directory, it was presumably found from a
4494 # mis-parse, so remove it from the list. (Misparse can
4495 # arise, for example from a mismatch of latexmk's $log_wrap
4496 # value and texmf.cnf value of max_print_line.)
4497 delete $dependents{$candidate};
4498 }
4499 elsif ( -e $candidate ) {
4500 if ( exists $generated_log{$candidate} ){
4501 $dependents{$candidate} = 6;
4502 }
4503 elsif ($code == 0) {
4504 $dependents{$candidate} = 5;
4505 }
4506 else {
4507 $dependents{$candidate} = 4;
4508 }
4509 }
4510 elsif ($code == 1) {
4511 # Graphics file that is supposed to have been read.
4512 # Candidate name is as given in source file, not as path
4513 # to actual file.
4514 # We have already tested that file doesn't exist, as given.
4515 # so use kpsewhich.
4516 # If the file still is not found, assume non-existent;
4517 $kpsearch_candidates{$candidate} = 1;
4518 delete $dependents{$candidate};
4519 }
4520 elsif ($code == 2) {
4521 # Candidate is from '(...' construct in log file, for input file
4522 # which should include pathname if valid input file.
4523 # Name does not have pathname-characteristic character (hence
4524 # $code==2.
4525 # We get here if candidate file does not exist with given name
4526 # Almost surely result of a misparsed line in log file.
4527 delete $dependents{$candidate};
4528 push @misparse, $candidate;
4529 }
4530 elsif ($code == 3) {
4531 # Candidate is from '(...' construct in log file, for input file
4532 # which should include pathname if valid input file.
4533 # Name does have pathname-characteristic character (hence
4534 # $code==3.
4535 # But we get here only if candidate file does not exist with
4536 # given name.
4537 # Almost surely result of a misparsed line in log file.
4538 # But with lower probability than $code == 2
4539 delete $dependents{$candidate};
4540 push @misparse, $candidate;
4541 }
4542 elsif ($code == 0) {
4543 my ($base, $path, $ext) = fileparseA($candidate);
4544 $ext =~ s/^\.//;
4545 if ( ($ext eq '') && (-e "$path$base.tex") ) {
4546 # I don't think the old version was correct.
4547 # If the missing-file report was of a bare
4548 # extensionless file, and a corresponding .tex file
4549 # exists, then the missing file does not correspond
4550 # to the missing file, unless the .tex file was
4551 # created during the run.
4552 # OLD $dependents{"$path$base.tex"} = 4;
4553 # OLD delete $dependents{$candidate};
4554 # NEW:
4555 $dependents{"$path$base.tex"} = 4;
4556 }
4557 push @missing, $candidate;
4558 }
4559 }
4560
4561 my @kpsearch_candidates = keys %kpsearch_candidates;
4562 if (@kpsearch_candidates) {
4563 foreach my $result ( kpsewhich( @kpsearch_candidates ) ) {
4564 $dependents{$result} = 4;
4565 }
4566 }
4567
4568CANDIDATE_PAIR:
4569 foreach my $delegated_source (keys %new_conversions) {
4570 my $delegated_output = $new_conversions{$delegated_source};
4571 my $rule = "Delegated $delegated_source, $delegated_output";
4572 # N.B. $delegated_source eq '' means the output file
4573 # was created without a named input file.
4574 foreach my $candidate ($delegated_source, $delegated_output) {
4575 if (! -e $candidate ) {
4576 # The file might be somewhere that can be found
4577 # in the search path of kpathsea:
4578 my @kpse_result = kpsewhich( $candidate,);
4579 if ($#kpse_result > -1) {
4580 $candidate = $kpse_result[0];
4581 }
4582 }
4583 }
4584 if ( ( (-e $delegated_source) || ($delegated_source eq '') )
4585 && (-e $delegated_output) )
4586 {
4587 $conversions{$delegated_output} = $delegated_source;
4588 $dependents{$delegated_output} = 7;
4589 if ($delegated_source) {
4590 $dependents{$delegated_source} = 4;
4591 }
4592 }
4593 elsif (!$silent) {
4594 print "Logfile claimed conversion from '$delegated_source' ",
4595 "to '$delegated_output'. But:\n";
4596 if (! -e $delegated_output) {
4597 print " Output file does not exist\n";
4598 }
4599 if ( ($delegated_source ne '') && (! -e $delegated_source) ) {
4600 print " Input file does not exist\n";
4601 }
4602 }
4603 }
4604
4605 if ( ($#warning_list >= 0) && !$log_silent ) {
4606 @warning_list = uniqs( @warning_list );
4607 show_array( "$My_name: List of undefined refs and citations:",
4608 @warning_list );
4609 }
4610
4611 if ( $diagnostics ) {
4612 @misparse = uniqs( @misparse );
4613 @missing = uniqs( @missing );
4614 @not_found = uniqs( @not_found );
4615 my @dependents = sort( keys %dependents );
4616
4617 my $dependents = $#dependents + 1;
4618 my $misparse = $#misparse + 1;
4619 my $missing = $#missing + 1;
4620 my $not_found = $#not_found + 1;
4621 my $exist = $dependents - $not_found - $missing;
4622 my $bbl = $#bbl_files + 1;
4623
4624 print "$dependents dependent files detected, of which ",
4625 "$exist exist, $not_found were not found,\n",
4626 " and $missing appear not to exist.\n";
4627 print "Dependents:\n";
4628 foreach (@dependents) {
4629 print " '$_' ";
4630 if ( $dependents{$_} == 6 ) { print " written by (pdf)latex";}
4631 if ( $dependents{$_} == 7 ) { print " converted by (pdf)latex";}
4632 print "\n";
4633 }
4634 if ($not_found > 0) {
4635 print "Not found:\n";
4636 foreach (@not_found) { print " $_\n"; }
4637 }
4638 if ($missing > 0) {
4639 print "Not existent:\n";
4640 foreach (@missing) { print " $_\n"; }
4641 }
4642 if ( $bbl > 0 ) {
4643 print "Input bbl files:\n";
4644 foreach (@bbl_files) { print " $_\n"; }
4645 }
4646
4647 if ( $misparse > 0 ) {
4648 print "Possible input files, perhaps from misunderstood lines in .log file:\n";
4649 foreach ( @misparse ) { print " $_\n"; }
4650 }
4651 }
4652 return 1;
4653} #END parse_log
4654
4655#************************************************************
4656
4657sub parse_fls {
4658 my ($fls_name, $Pinputs, $Poutputs, $Pfirst_read_after_write, $Ppwd_latex ) = @_;
4659 %$Pinputs = %$Poutputs = %$Pfirst_read_after_write = ();
4660 my $fls_file = new FileHandle;
4661 # Make a note of current working directory
4662 # I'll update it from the fls file later
4663 # Currently I don't use this, but it would be useful to use
4664 # this when testing prefix for cwd in a filename, by
4665 # giving (pdf)latex's best view of the cwd. Note that the
4666 # value given by the cwd() function may be mangled, e.g., by cygwin
4667 # compared with native MSWin32.
4668 #
4669 # Two relevant forms of cwd exist: The system one, which we can find, and
4670 # the one reported by (pdf)latex in the fls file. It will be
4671 # useful to remove leading part of cwd in filenames --- see the
4672 # comments in sub rdb_set_latex_deps. Given the possible multiplicity
4673 # of representations of cwd, the one reported in the fls file should
4674 # be definitive in the fls file.
4675
4676 my $cwd = good_cwd();
4677 if ( ! open ($fls_file, "<$fls_name") ) {
4678 return 1;
4679 }
4680 foreach $_ ( <$fls_file> ) {
4681 # Remove trailing CR and LF. Thus we get correct behavior when an fls file
4682 # is produced by MS-Windows program (e.g., in MiKTeX) with CRLF line ends,
4683 # but is read by Unix Perl (which treats LF as line end, and preserves CRLF
4684 # in read-in lines):
4685 $_ =~ s/[\n\r]*$//;
4686 if (/^\s*PWD\s+(.*)$/) {
4687 $cwd = $1;
4688 $$Ppwd_latex = $cwd;
4689 }
4690 elsif (/^\s*INPUT\s+(.*)$/) {
4691 # Take precautions against aliasing of foo, ./foo and other possibilities for cwd.
4692 my $file = $1;
4693 # Remove exactly pwd reported in this file, and following separator.
4694 # MiKTeX reports absolute pathnames, and this way of removing PWD insulates
4695 # us from coding issues if the PWD contains non-ASCII characters. What
4696 # coding scheme (UTF-8, code page, etc) is used depends on OS, TeX
4697 # implementation, ...
4698 $file =~ s(^\Q$$Ppwd_latex\E[\\/])();
4699 $file = normalize_filename( $file );
4700 if ( (exists $$Poutputs{$file}) && (! exists $$Pinputs{$file}) ) {
4701 $$Pfirst_read_after_write{$file} = 1;
4702 }
4703 $$Pinputs{$file} = 1;
4704 }
4705 elsif (/^\s*OUTPUT\s+(.*)$/) {
4706 # Take precautions against aliasing of foo, ./foo and other possibilities for cwd.
4707 my $file = $1;
4708 $file =~ s(^\Q$$Ppwd_latex\E[\\/])();
4709 $$Poutputs{ normalize_filename( $file )} = 1;
4710 }
4711 }
4712 close( $fls_file );
4713 return 0;
4714} #END parse_fls
4715
4716#************************************************************
4717
4718sub clean_filename {
4719 # Convert quoted filename as found in log file to filename without quotes
4720 # Allows arbitrarily embedded double-quoted substrings, includes the
4721 # cases
4722 # 1. `"string".ext', which arises e.g., from \jobname.bbl:
4723 # when the base filename contains spaces, \jobname has quotes.
4724 # and from \includegraphics with basename specified.
4725 # Also deals with filenames written by asymptote.sty
4726 # 2. Or "string.ext" from \includegraphcs with basename and ext specified.
4727 # and from MiKTeX logfile for input files with spaces.
4728 # Doubled quotes (e.g., A""B) don't get converted.
4729 # Neither do unmatched quotes.
4730 my $filename = $_[0];
4731 while ( $filename =~ s/^([^\"]*)\"([^\"]+)\"(.*)$/$1$2$3/ ) {}
4732 return $filename;
4733}
4734
4735# ------------------------------
4736
4737sub normalize_filename {
4738 # Usage: normalize_filename( filename [, extra forms of name of cwd] )
4739 # Returns filename with removal of various forms for cwd, and
4740 # with conversion of directory separator to '/' only
4741 #
4742 my ( $file, @dirs ) = @_;
4743 my $file1 = $file; # Saved original value
4744 my $cwd = good_cwd();
4745 # Normalize files to use / to separate directory components:
4746 # (Note both / and \ are allowed under MSWin.)
4747 foreach ($cwd, $file, @dirs) {
4748 s(\\)(/)g;
4749 }
4750 # Remove initial component equal to current working directory.
4751 # Use \Q and \E round directory name in regex to avoid interpretation
4752 # of metacharacters in directory name:
4753 foreach my $dir ( @dirs, '.', $cwd ) {
4754 if ( $file =~ s(^\Q$dir\E/)() ) {
4755 last;
4756 }
4757 }
4758 return $file;
4759}
4760
4761# ------------------------------
4762
4763sub normalize_clean_filename {
4764 # Usage: normalize_clean_filename( filename [, extra forms of name of cwd] )
4765 # Same as normalize_filename, but first remove any double quotes, as
4766 # done by clean_filename, which is appropriate for filenames from log file.
4767 my ($file, @dirs) = @_;
4768 return normalize_filename( clean_filename( $file ) , @dirs );
4769}
4770
4771#************************************************************
4772
4773sub fix_pattern {
4774 # Escape the characters [ and {, to give a pattern for use in glob
4775 # with these characters taken literally.
4776 my $pattern = shift;
4777 $pattern =~ s/\[/\\\[/g;
4778 $pattern =~ s/\{/\\\{/g;
4779 return $pattern;
4780}
4781
4782#************************************************************
4783
4784sub OS_preferred_filename {
4785 # Usage: OS_preferred_filename(name)
4786 # Returns filename with directory separator '/' converted
4787 # to preferred conventions for current OS.
4788 # Currently implemented: only '\' for MSWin32
4789 my $file = $_[0];
4790 if ( $^O eq 'MSWin32' ) {
4791 $file =~ s(/)(\\)g;
4792 }
4793 return $file;
4794}
4795
4796#************************************************************
4797
4798sub parse_aux {
4799 #Usage: parse_aux( $aux_file, \@new_bib_files, \@new_aux_files, \@new_bst_files )
4800 # Parse aux_file (recursively) for bib files, and bst files.
4801 # If can't open aux file, then
4802 # Return 0 and leave @new_bib_files empty
4803 # Else set @new_bib_files from information in the aux files
4804 # And:
4805 # Return 1 if no problems
4806 # Return 2 with @new_bib_files empty if there are no \bibdata
4807 # lines.
4808 # Return 3 if I couldn't locate all the bib_files
4809 # Set @new_aux_files to aux files parsed
4810
4811 my $aux_file = $_[0];
4812 local $Pbib_files = $_[1];
4813 local $Paux_files = $_[2];
4814 local $Pbst_files = $_[3];
4815
4816 @$Pbib_files = ();
4817 @$Pbst_files = ();
4818 @$Paux_files = ();
4819
4820 parse_aux1( $aux_file );
4821 if ($#{$Paux_files} < 0) {
4822 return 0;
4823 }
4824 @$Pbib_files = uniqs( @$Pbib_files );
4825 @$Pbst_files = uniqs( @$Pbst_files );
4826
4827 if ( $#{$Pbib_files} == -1 ) {
4828 warn "$My_name: No .bib files listed in .aux file '$aux_file' \n",
4829 return 2;
4830 }
4831 my @not_found = &find_file_list1( $Pbib_files, $Pbib_files,
4832 '.bib', \@BIBINPUTS );
4833 @$Pbib_files = uniqs( @$Pbib_files );
4834 &find_file_list1( $Pbst_files, $Pbst_files, '.bst' );
4835 @$Pbst_files = uniqs( @$Pbst_files );
4836 if ( $#not_found < 0) {
4837 warn "$My_name: Found bibliography file(s) [@$Pbib_files]\n"
4838 unless $silent;
4839 }
4840 else {
4841 show_array( "$My_name: Failed to find one or more bibliography files ",
4842 @not_found );
4843 if ($force_mode) {
4844 warn "==== Force_mode is on, so I will continue. ",
4845 "But there may be problems ===\n";
4846 }
4847 else {
4848 #$failure = -1;
4849 #$failure_msg = 'Failed to find one or more bib files';
4850 #warn "$My_name: Failed to find one or more bib files\n";
4851 }
4852 return 3;
4853 }
4854 return 1;
4855} #END parse_aux
4856
4857#************************************************************
4858
4859sub parse_aux1
4860# Parse single aux file for bib files.
4861# Usage: &parse_aux1( aux_file_name )
4862# Append newly found bib_filenames in @$Pbib_files, already
4863# initialized/in use.
4864# Append aux_file_name to @$Paux_files if aux file opened
4865# Recursively check \@input aux files
4866# Return 1 if success in opening $aux_file_name and parsing it
4867# Return 0 if fail to open it
4868{
4869 my $aux_file = $_[0];
4870 my $aux_fh = new FileHandle;
4871 if (! open($aux_fh, $aux_file) ) {
4872 warn "$My_name: Couldn't find aux file '$aux_file'\n";
4873 return 0;
4874 }
4875 push @$Paux_files, $aux_file;
4876AUX_LINE:
4877 while (<$aux_fh>) {
4878 if ( /^\\bibdata\{(.*)\}/ ) {
4879 # \\bibdata{comma_separated_list_of_bib_file_names}
4880 # These are normally without the '.bib' extension.
4881 push @$Pbib_files, split /,/, $1;
4882 }
4883 elsif ( /^\\bibstyle\{(.*)\}/ ) {
4884 # \\bibstyle{bst_file_name}
4885 # Normally without the '.bst' extension.
4886 push @$Pbst_files, split /,/, $1;
4887 }
4888 elsif ( /^\\\@input\{(.*)\}/ ) {
4889 # \\@input{next_aux_file_name}
4890 &parse_aux1( $aux_dir1.$1 );
4891 }
4892 else {
4893 foreach my $Psub (@aux_hooks) {
4894 &$Psub;
4895 }
4896 }
4897 }
4898 close($aux_fh);
4899 return 1;
4900} #END parse_aux1
4901
4902#************************************************************
4903
4904#************************************************************
4905#************************************************************
4906#************************************************************
4907
4908# Manipulations of main file database:
4909
4910#************************************************************
4911
4912sub fdb_get {
4913 # Call: fdb_get(filename [, check_time])
4914 # Returns an array (time, size, md5) for the current state of the
4915 # named file.
4916 # The optional argument check_time is either the run_time of some command
4917 # that may have changed the file or the last time the file was checked
4918 # for changes --- see below.
4919 # For non-existent file, deletes its entry in fdb_current,
4920 # and returns (0,-1,0)
4921 # As an optimization, the md5 value is taken from the cache in
4922 # fdb_current, if the time and size stamp indicate that the
4923 # file has not changed.
4924 # The md5 value is recalculated if
4925 # the current filetime differs from the cached value:
4926 # file has been written
4927 # the current filesize differs from the cached value:
4928 # file has definitely changed
4929 # But the file can also be rewritten without change in filetime when
4930 # file processing happens within the 1-second granularity of the
4931 # timestamp (notably for aux files from latex on a short source file).
4932 # The only case that concerns us is when the file is an input to a program
4933 # at some runtime t, the file is rewritten later by the same or another
4934 # program, with timestamp t, and when the initial file also has
4935 # timestamp t.
4936 # A test is applied for this situation if the check_time argument is
4937 # supplied and is nonzero.
4938
4939 my ($file, $check_time) = @_;
4940 if ( ! defined $check_time ) { $check_time = 0;}
4941 my ($new_time, $new_size) = get_time_size($file);
4942 my @nofile = (0,-1,0); # What we use for initializing
4943 # a new entry in fdb or flagging
4944 # non-existent file
4945 if ( $new_size < 0 ) {
4946 delete $fdb_current{$file};
4947 return @nofile;
4948 }
4949 my $recalculate_md5 = 0;
4950 if ( ! exists $fdb_current{$file} ) {
4951 # Ensure we have a record.
4952 $fdb_current{$file} = [@nofile];
4953 $recalculate_md5 = 1;
4954 }
4955 my $file_data = $fdb_current{$file};
4956 my ( $time, $size, $md5 ) = @$file_data;
4957
4958 if ( ($new_time != $time) || ($new_size != $size)
4959 || ( $check_time && ($check_time == $time ) )
4960 ) {
4961 # Only force recalculation of md5 if time or size changed.
4962 # However, the physical file time may have changed without
4963 # affecting the value of the time coded in $time, because
4964 # times are computed with a 1-second granularity.
4965 # The only case to treat specially is where the file was created,
4966 # then used by the current rule, and then rewritten, all within
4967 # the granularity size, otherwise the value of the reported file
4968 # time changed, and we've handled it. But we may have already
4969 # checked this at an earlier time than the current check. So the
4970 # only dangerous case is where the file time equals a check_time,
4971 # which is either the run_time of the command or the time of a
4972 # previous check.
4973 # Else we assume file is really unchanged.
4974 $recalculate_md5 = 1;
4975 }
4976 if ($recalculate_md5) {
4977#warn "--------- RECALC MD5: $rule $file: (N,O,R,C) \n = $new_time, $time, $$Prun_time, $check_time\n";
4978 @$file_data = ( $new_time, $new_size, get_checksum_md5( $file ) );
4979 }
4980 return @$file_data;;
4981} #END fdb_get
4982
4983#************************************************************
4984
4985sub fdb_set {
4986 # Call: fdb_set(filename, $time, $size, $md5 )
4987 # Set data in file data cache, i.e., %fdb_current
4988 my ($file, $time, $size, $md5 ) = @_;
4989 if ( ! exists $fdb_current{$file} ) {
4990 $fdb_current{$file} = [0, -1, 0];
4991 }
4992 @{$fdb_current{$file}} = ( $time, $size, $md5 );
4993} #END fdb_set
4994
4995#************************************************************
4996
4997sub fdb_show {
4998 # Displays contents of fdb
4999 foreach my $file ( sort keys %fdb_current ) {
5000 print "'$file': @{$fdb_current{$file}}\n";
5001 }
5002} #END fdb_show
5003
5004#************************************************************
5005#************************************************************
5006#************************************************************
5007
5008# Routines for manipulating rule database
5009
5010#************************************************************
5011
5012sub rdb_read {
5013 # Call: rdb_read( $in_name )
5014 # Sets rule database from saved file, in format written by rdb_write.
5015 # Returns -1 if file could not be read else number of errors.
5016 # Thus return value on success is 0
5017 my $in_name = $_[0];
5018 my $in_handle = new FileHandle;
5019 $in_handle->open( $in_name, '<' )
5020 or return ();
5021 my $errors = 0;
5022 my $state = -1; # Values: -1: before start; 0: outside rule;
5023 # 1: in source section; 2: in generated file section;
5024 # 10: ignored rule
5025 my $rule = '';
5026 my $run_time = 0;
5027 my $source = '';
5028 my $dest = '';
5029 my $base = '';
5030 local %new_sources = (); # Hash: rule => { file=>[ time, size, md5, fromrule ] }
5031 my $new_source = undef; # Reference to hash of sources for current rule
5032LINE:
5033 while ( <$in_handle> ) {
5034 # Remove leading and trailing white space.
5035 s/^\s*//;
5036 s/\s*$//;
5037 if ($state == -1) {
5038 if ( ! /^# Fdb version ([\d]+)$/ ) {
5039 warn "$My_name: File-database '$in_name' is not of correct format\n";
5040 return 1;
5041 }
5042 if ( $1 > $fdb_ver) {
5043 warn "$My_name: File-database '$in_name' is of too new version, $1 > $fdb_ver\n";
5044 return 1;
5045 }
5046 $state = 0;
5047 }
5048 # Ignore blank lines and comments
5049 if ( /^$/ || /^#/ || /^%/ ) { next LINE;}
5050 if ( /^\[\"([^\"]+)\"\]/ ) {
5051 # Start of section
5052 $rule = $1;
5053 my $tail = $'; #' Single quote in comment tricks the parser in
5054 # emacs from misparsing an isolated single quote
5055 $run_time = $check_time = 0;
5056 $source = $dest = $base = '';
5057 if ( $tail =~ /^\s*(\S+)\s*$/ ) {
5058 $run_time = $1;
5059 }
5060 elsif ( $tail =~ /^\s*(\S+)\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s*$/ ) {
5061 $run_time = $1;
5062 $source = $2;
5063 $dest = $3;
5064 $base = $4;
5065 }
5066 elsif ( $tail =~ /^\s*(\S+)\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+(\S+)\s*$/ ) {
5067 $run_time = $1;
5068 $source = $2;
5069 $dest = $3;
5070 $base = $4;
5071 $check_time = $5;
5072 }
5073 if ( rdb_rule_exists( $rule ) ) {
5074 rdb_one_rule( $rule,
5075 sub{
5076 if ($$Ptest_kind == 3) { $$Ptest_kind = 1; }
5077 $$Prun_time = $run_time;
5078 $$Pcheck_time = $check_time;
5079 }
5080 );
5081 }
5082 elsif ($rule =~ /^cusdep\s+(\S+)\s+(\S+)\s+(.+)$/ ) {
5083 # Create custom dependency
5084 my $fromext = $1;
5085 my $toext = $2;
5086 my $base = $3;
5087 $source = "$base.$fromext";
5088 $dest = "$base.$toext";
5089 my $PAnew_cmd = ['do_cusdep', ''];
5090 foreach my $dep ( @cus_dep_list ) {
5091 my ($tryfromext,$trytoext,$must,$func_name) = split('\s+',$dep);
5092 if ( ($tryfromext eq $fromext) && ($trytoext eq $toext) ) {
5093 $$PAnew_cmd[1] = $func_name;
5094 }
5095 }
5096 # Set source file as non-existent.
5097 # If it existed on last run, it will be in later
5098 # lines of the fdb file
5099 rdb_create_rule( $rule, 'cusdep', '', $PAnew_cmd, 1,
5100 $source, $dest, $base, 0, $run_time, $check_time, 1 );
5101 }
5102 elsif ( $rule =~ /^(makeindex|bibtex|biber)\s*(.*)$/ ) {
5103 my $PA_extra_gen = [];
5104 my $rule_generic = $1;
5105 my $int_cmd = '';
5106 if ( ! $source ) {
5107 # If fdb_file was old-style (v. 1)
5108 $source = $2;
5109 my $path = '';
5110 my $ext = '';
5111 ($base, $path, $ext) = fileparseA( $source );
5112 $base = $path.$base;
5113 if ($rule_generic eq 'makeindex') {
5114 $dest = "$base.ind";
5115 }
5116 elsif ($rule_generic eq 'bibtex') {
5117 $dest = "$base.bbl";
5118 $source = "$base.aux";
5119 }
5120 elsif ($rule_generic eq 'biber') {
5121 $dest = "$base.bbl";
5122 $source = "$base.bcf";
5123 }
5124 }
5125 if ($rule =~ /^makeindex/) { $PA_extra_gen = [ "$base.ilg" ]; }
5126 if ($rule =~ /^(bibtex|biber)/) { $PA_extra_gen = [ "$base.blg" ]; }
5127 if ($rule =~ /^bibtex/) { $int_cmd = "run_bibtex"; }
5128 warn "$My_name: File-database '$in_name': setting rule '$rule'\n"
5129 if $diagnostics;
5130 my $cmd_type = 'external';
5131 my $ext_cmd = ${$rule_generic};
5132 warn " Rule kind = '$rule_generic'; ext_cmd = '$ext_cmd';\n",
5133 " int_cmd = '$int_cmd';\n",
5134 " source = '$source'; dest = '$dest'; base = '$base';\n"
5135 if $diagnostics;
5136 # Set source file as non-existent.
5137 # If it existed on last run, it will be in later
5138 # lines of the fdb file
5139 rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, 1,
5140 $source, $dest, $base, 0, $run_time, $check_time, 1, $PA_extra_gen );
5141 }
5142 else {
5143 warn "$My_name: In file-database '$in_name' rule '$rule'\n",
5144 " is not in use in this session\n"
5145 if $diagnostics;
5146 $new_source = undef;
5147 $state = 10;
5148 next LINE;
5149 }
5150 $new_source = $new_sources{$rule} = {};
5151 $state = 1; #Reading a section, source part
5152 }
5153 elsif ( ($state <=0) || ($state >= 3) ) {
5154 next LINE;
5155 }
5156 elsif ( /^\(source\)/ ) { $state = 1; next LINE; }
5157 elsif ( /^\(generated\)/ ) { $state = 2; next LINE; }
5158 elsif ( ($state == 1) && /^\"([^\"]*)\"\s+(\S+)\s+(\S+)\s+(\S+)\s+\"([^\"]*)\"/ ) {
5159 # Source file line
5160 my $file = $1;
5161 my $time = $2;
5162 my $size = $3;
5163 my $md5 = $4;
5164 my $from_rule = $5;
5165#?? print " --- File '$file'\n";
5166 if ($state != 1) {
5167 warn "$My_name: In file-database '$in_name' ",
5168 "line $. is outside a section:\n '$_'\n";
5169 $errors++;
5170 next LINE;
5171 }
5172 # Set file in database. But ensure we don't do an unnecessary
5173 # fdb_get, which can trigger a new MD5 calculation, which is
5174 # lengthy for a big file. Ininitially flagging the file
5175 # as non-existent solves the problem:
5176 rdb_ensure_file( $rule, $file, undef, 1 );
5177 rdb_set_file1( $rule, $file, $time, $size, $md5 );
5178 fdb_set( $file, $time, $size, $md5 );
5179 # Save the rest of the data, especially the from_fule until we know all
5180 # the rules, otherwise the from_rule may not exist.
5181 # Also we'll have a better chance of looping through files.
5182 ${$new_source}{$file} = [ $time, $size, $md5, $from_rule ];
5183 }
5184 elsif ( ($state == 2) && /^\"([^\"]*)\"/ ) {
5185 my $file = $1;
5186 rdb_one_rule( $rule, sub{ rdb_add_generated($file); } );
5187 }
5188 else {
5189 warn "$My_name: In file-database '$in_name' ",
5190 "line $. is of wrong format:\n '$_'\n";
5191 $errors++;
5192 next LINE;
5193 }
5194 }
5195 undef $in_handle;
5196 # Set cus dependencies.
5197 &rdb_set_dependents( keys %rule_db );
5198
5199#?? Check from_rules exist.
5200
5201 return $errors;
5202} # END rdb_read
5203
5204#************************************************************
5205
5206sub rdb_write {
5207 # Call: rdb_write( $out_name )
5208 # Writes to the given file name the database of file and rule data
5209 # for all rules needed to make final output
5210 # !!?? Previously was:
5211 # OLD Writes to the given file name the database of file and rule data
5212 # OLD accessible from the primary rules.
5213 # Returns 1 on success, 0 if file couldn't be opened.
5214 local $out_name = $_[0];
5215 local $out_handle = new FileHandle;
5216 if ( ($out_name eq "") || ($out_name eq "-") ) {
5217 # Open STDOUT
5218 $out_handle->open( '>-' );
5219 }
5220 else {
5221 $out_handle->open( $out_name, '>' );
5222 }
5223 if (!$out_handle) { return 0; }
5224
5225 local %current_primaries = (); # Hash whose keys are primary rules
5226 # needed, i.e., known latex-like rules which trigger
5227 # circular dependencies
5228 local @pre_primary = (); # Array of rules
5229 local @post_primary = (); # Array of rules
5230 local @unusual_one_time = (); # Array of rules
5231 &rdb_classify_rules( \%possible_primaries, keys %requested_filerules );
5232
5233 print $out_handle "# Fdb version $fdb_ver\n";
5234# !!?? Rules or rules accessible from primary
5235# my @rules = rdb_accessible( uniq1( keys %possible_primaries ) ) ;
5236 my @rules = rdb_accessible( uniq1( keys %possible_primaries, keys %requested_filerules ) ) ;
5237 # Separate call to sort. Otherwise rdb_accessible seems to get wrong argument.
5238 @rules = sort( @rules );
5239 rdb_for_some(
5240 \@rules,
5241 sub {
5242 # Omit data on a unused and never-run primary rule:
5243 if ( ($$Prun_time == 0)
5244 && exists( $possible_primaries{$rule} )
5245 && ! exists( $current_primaries{$rule} )
5246 )
5247 {
5248 return;
5249 }
5250 print $out_handle "[\"$rule\"] $$Prun_time \"$$Psource\" \"$$Pdest\" \"$$Pbase\" $$Pcheck_time\n";
5251 rdb_do_files(
5252 sub { print $out_handle " \"$file\" $$Ptime $$Psize $$Pmd5 \"$$Pfrom_rule\"\n"; }
5253 );
5254 print $out_handle " (generated)\n";
5255 foreach (keys %$PHdest) {
5256 print $out_handle " \"$_\"\n";
5257 }
5258 }
5259 );
5260 undef $out_handle;
5261 return 1;
5262} #END rdb_write
5263
5264#************************************************************
5265
5266sub rdb_set_latex_deps {
5267 # Assume rule context.
5268 # This is intended to be applied only for a primary (LaTeX-like) rule.
5269 # Set its dependents etc, using information from log, aux, and fls files.
5270 # Use fls file only if $recorder is set, and the fls file was generated
5271 # on this run.
5272
5273 # N.B. A complication which we try and handle in determining
5274 # dependent files is that there may be aliasing of file names,
5275 # especially when characters are used in file and directory
5276 # names that are not pure 7-bit-ASCII. Here is a list of some
5277 # of the difficulties that do arise, between, on the one hand,
5278 # the filenames specified on latexmk's and the cwd found by
5279 # latexmk from the system, and, on the other hand, the filenames
5280 # and their components reported by (pdf)latex in the fls and log
5281 # files:
5282 # 1. Whether the separator of path components is / or \ in
5283 # MSWin.
5284 # 2. Whether the LFN or the SFN is provided.
5285 # 3. Whether the filenames include the cwd or whether they
5286 # are relative to the current directory.
5287 # 4. Under cygwin, whether the absolute filenames are
5288 # specified by UNIX or native MSWin conventions.
5289 # (With cygin, the programs used, including the Perl that
5290 # executes latexmk, can be any combination of native MSWin
5291 # programs and cygwin programs with their UNIX-like
5292 # behavior.)
5293 # 5. Whether UTF-8 or some other coding is used, and under
5294 # which circumstances: e.g., in calls to the OS to access
5295 # files, in files output by programs, on latexmk's command
5296 # line, on other programs' command lines, by the command
5297 # interpreterS.
5298 # 6. If UTF-8 is used, what kind of canonicalization is used,
5299 # if any. (This is a particular bugbear when files are
5300 # transferred between different OSes.)
5301 # 7. Whether the name of a file in the current directory is
5302 # reported as the simple filename or whether it is
5303 # preceeded by ".\" or "./".
5304 # 8. How is it determined whether a pathname is absolute or
5305 # relative? An absolute pathname in MSWin may start with
5306 # a drive letter and a colon, but under UNIX-type systems,
5307 # the colon is an ordinary character.
5308 # 9. Whether a filename reported in an fls or log file can be
5309 # used as is by perl to access a file, or on the command
5310 # line to invoke another program, and whether the use on a
5311 # command line depends on whether the command line is
5312 # executed by a CLI, and by which CLI. (E.g., cmd.exe,
5313 # v. sh v. tcsh, etc.)
5314 # 10. Whether such a filename for the filename on (pdf)latex's
5315 # file agrees with the one on the command line.
5316 # The above questions have arisen from actual experiences and
5317 # tests.
5318 #
5319 # In any case, when determining dependent files, we will try to
5320 # remove an initial directory string from filenames found in the
5321 # fls and log files, whenever it denotes the current
5322 # directory. The directory string may be an absolute pathname,
5323 # such as MiKTeX writes in both fls and log files, or it may be
5324 # simply "./" as given by TeXLive in its log file. There are
5325 # several reasons for removing a directory string when possible:
5326 #
5327 # 1. To avoid having multiple names referring to the same
5328 # file in the list of dependents.
5329 # 2. Because the name may be in a different coding. Thus
5330 # under MSWin 7, cmd.exe and perl (by default) work in an
5331 # "ANSI" coding with some code page, but the filenames
5332 # written by MiKTeX are UTF-8 coded (and if they are non-ASCII
5333 # can't be used for file-processing by Perl without some
5334 # trouble). This is a particular problem if the pathname
5335 # contains non-ASCII characters; the directory names may not
5336 # even be under the user's control, unlike typical filenames.
5337 # 3. When it comes to filenames that are then used in calls to
5338 # bibtex and makeindex, it is bad to use absolute pathnames
5339 # instead of clearly relative pathnames, because the default
5340 # security settings are to prohibit writing files to the
5341 # corresponding directories, which makes the calls to these
5342 # programs unnecessarily fail.
5343 #
5344 # In removing unnecessary directory-specifying strings, to
5345 # convert a filename to a simple specification relative to the
5346 # current directory, it will be important to preferentially use
5347 # a determination of the current directory from the file being
5348 # processed. In the fls file, there is normally a PWD line. In
5349 # the log file, if (pdf)latex is started with a filename instead
5350 # of a command-executing first line, then this can be determined
5351 # from the first few lines of the log file -- see parse_log.
5352 # This gives a more reliable determination of the relevant path
5353 # string; this is especially important in cases where there is a
5354 # mismatch of coding of the current directory, particularly
5355 # notable in the above-mentioned case of non-ASCII characters
5356 # under MSWin. Other inconsistencies happen when there is a
5357 # mixure of cygwin and native MSWin software. There can also be
5358 # inconsistencies between whether the separator of pathname
5359 # components is "/" or "\". So we will allow for this. The
5360 # necessary normalizations of filenames are handled by the
5361 # subroutines normalize_filename and normalize_clean_filename.
5362 #
5363 # I have not tried to handle the (currently rare) cases that the
5364 # OS is neither UNIX-like nor MSWin-like.
5365
5366 # Rules should only be primary
5367 if ( $$Pcmd_type ne 'primary' ) {
5368 warn "\n$My_name: ==========$My_name: Probable BUG======= \n ",
5369 " rdb_set_latex_deps called to set files ",
5370 "for non-primary rule '$rule'\n\n";
5371 return;
5372 }
5373
5374
5375#?? # We'll prune this by all files determined to be needed for source files.
5376#?? my %unneeded_source = %$PHsource;
5377
5378 # Parse log file to find relevant filenames
5379 # Result in the following variables:
5380 local %dependents = (); # Maps files to status
5381 local @bbl_files = ();
5382 local %idx_files = (); # Maps idx_file to (ind_file, base)
5383 local %generated_log = (); # Lists generated files found in log file
5384 local %generated_fls = (); # Lists generated files found in fls file
5385 local %source_fls = (); # Lists source files found in fls file
5386 local %first_read_after_write = (); # Lists source files that are only read
5387 # after being written (so are not true
5388 # source files.
5389 local $primary_out = $$Pdest; # output file (dvi or pdf)
5390 local %conversions = (); # (pdf)latex-performed conversions.
5391 # Maps output file created and read by (pdf)latex
5392 # to source file of conversion.
5393 local @missing_subdirs = (); # Missing subdirectories in aux_dir
5394
5395 local $pwd_latex = undef; # Cwd as reported in fls file by (pdf)latex
5396
5397 # The following are also returned, but are global, to be used by caller
5398 # $reference_changed, $bad_reference $bad_citation, $mult_defined
5399
5400 # Do I have my own eps-to-pdf conversion?
5401 my $epspdf_cusdep = 0;
5402 foreach (@cus_dep_list) {
5403 if ( /^eps pdf / ) { $epspdf_cusdep = 1; last; }
5404 }
5405
5406 # Analyze fls file first. It tells us the working directory as seen by (pdf)latex
5407 # But we'll use the results later, so that they take priority over the findings
5408 # from the log file.
5409 my $fls_name = "$aux_dir1$root_filename.fls";
5410 local $fls_file_analyzed = 0;
5411 if ($recorder && test_gen_file($fls_name) ) {
5412 $fls_file_analyzed =
5413 (0== parse_fls( $fls_name, \%source_fls, \%generated_fls, \%first_read_after_write, \$pwd_latex ));
5414 if (! $fls_file_analyzed ) {
5415 warn "$My_name: fls file '$fls_name' appears to have been made but it couldn't be opened.\n";
5416 }
5417 }
5418
5419 &parse_log;
5420 $missing_dirs = 'none'; # Status of missing directories
5421 if (@missing_subdirs) {
5422 $missing_dirs = 'success';
5423 if ($allow_subdir_creation) {
5424 foreach my $dir ( uniqs( @missing_subdirs ) ) {
5425 if ( -d $dir ) {
5426 $missing_dirs = 'failure';
5427 warn "$My_name: ==== Directory '$dir' is said to be missing\n",
5428 " But it exists!\n";
5429 }
5430 elsif ( (-e $dir) && (!-d $dir) ) {
5431 $missing_dirs = 'failure';
5432 warn "$My_name: ==== Directory '$dir' is said to be missing\n",
5433 " But a non-directory file of this name exists!\n";
5434 }
5435 else {
5436 if (mkdir $dir) {
5437 warn "$My_name: Directory '$dir' created\n";
5438 }
5439 else {
5440 $missing_dirs = 'failure';
5441 warn "$My_name: Couldn't create directory '$dir'.\n",
5442 " System error: '$!'\n";
5443 }
5444 }
5445 }
5446 }
5447 else {
5448 $missing_dirs = 'not allowed';
5449 warn "$My_name: There are missing subdirectories, but their creation\n",
5450 " is not allowed. The subdirectories are:\n";
5451 foreach my $dir ( uniqs( @missing_subdirs ) ) {
5452 warn " '$dir'\n";
5453 }
5454 }
5455 }
5456 # Use results from fls file. (N.B. The hashes will be empty if the fls file
5457 # wasn't used/analyzed, so we don't need a test as to whether the fls file was
5458 # used.
5459 foreach (keys %source_fls) {
5460 $dependents{$_} = 4;
5461 if ( /\.bbl$/ ) { push @bbl_files, $_; }
5462 }
5463 foreach (keys %generated_fls) {
5464 rdb_add_generated( $_ );
5465 if ( exists($dependents{$_}) ) {
5466 $dependents{$_} = 6;
5467 }
5468 }
5469
5470
5471 for my $conv (sort keys %conversions) {
5472 my $conv_source = $conversions{$conv};
5473 if ( $conv =~ /^(.*)-eps-converted-to\.pdf$/ ) {
5474 # Check all the conditions for pdflatex's conversion eps to pdf
5475 # are valid; if they are, treat the converted file as not a
5476 # source file.
5477 my $base = $1;
5478 if ( (-e $conv_source) && (-e $conv) && ( $conv_source eq "$base.eps" ) ) {
5479 # $conv isn't a real source of (pdf)latex
5480 rdb_remove_files( $rule, $conv );
5481 delete $dependents{$conv};
5482 if ($epspdf_cusdep) {
5483 $dependents{"$base.pdf"} = ((-e "$base.pdf") ? 4 : 0 );
5484 }
5485 }
5486 }
5487 }
5488
5489
5490
5491# ?? !! Should also deal with .run.xml file
5492
5493 # Handle result on output file:
5494 # 1. Non-existent output file, which is because of no content.
5495 # This could either be because the source file has genuinely
5496 # no content, or because of a missing input file. Since a
5497 # missing input file might be correctable by a run of some
5498 # other program whose running is provoked AFTER a run of
5499 # (pdf)latex, we'll set a diagnostic and leave it to the
5500 # rdb_make to handle after all circular dependencies are
5501 # resolved.
5502 # 2. The output file might be of a different kind than expected
5503 # (i.e., dvi instead of pdf, or vv). This could
5504 # legitimately occur when the source file (or an invoked
5505 # package or class) sets \pdfoutput.
5506 $missing_dvi_pdf = '';
5507 if ($primary_out eq '') {
5508 warn "$My_name: For rule '$rule', no output was made\n";
5509 $missing_dvi_pdf = $$Pdest;
5510 }
5511 elsif ($primary_out ne $$Pdest) {
5512 warn "$My_name: ===For rule '$rule', actual output '$primary_out'\n",
5513 " ======appears not to match expected output '$$Pdest'\n";
5514 }
5515
5516 IDX_FILE:
5517 foreach my $idx_file ( keys %idx_files ) {
5518 my ($ind_file, $ind_base) = @{$idx_files{$idx_file}};
5519 my $from_rule = "makeindex $idx_file";
5520 if ( ! rdb_rule_exists( $from_rule ) ){
5521 print "!!!===Creating rule '$from_rule': '$ind_file' from '$idx_file'\n"
5522 if ($diagnostics);
5523 rdb_create_rule( $from_rule, 'external', $makeindex, '', 1,
5524 $idx_file, $ind_file, $ind_base, 1, 0, 0, 1, [ "$ind_base.ilg" ] );
5525 print " ===Source file '$ind_file' for '$rule'\n"
5526 if ($diagnostics);
5527 rdb_ensure_file( $rule, $ind_file, $from_rule );
5528 }
5529 # Make sure the .ind file is treated as a detected source file;
5530 # otherwise if the log file has it under a different name (as
5531 # with MiKTeX which gives full directory information), there
5532 # will be problems with the clean-up of the rule concerning
5533 # no-longer-in-use source files:
5534 $dependents{$ind_file} = 4;
5535 if ( ! -e $ind_file ) {
5536 # Failure was non-existence of makable file
5537 # Leave failure issue to other rules.
5538 $failure = 0;
5539 }
5540 }
5541
5542 local %processed_aux_files = ();
5543 BBL_FILE:
5544 foreach my $bbl_file ( uniqs( @bbl_files ) ) {
5545 my ($bbl_base, $bbl_path, $bbl_ext) = fileparseA( $bbl_file );
5546 $bbl_base = $bbl_path.$bbl_base;
5547 my @new_bib_files = ();
5548 my @new_aux_files = ();
5549 my @new_bst_files = ();
5550 my @biber_source = ( "$bbl_base.bcf" );
5551 my $bib_program = 'bibtex';
5552 if ( test_gen_file( "$bbl_base.bcf" ) ) {
5553 $bib_program = 'biber';
5554 }
5555 my $from_rule = "$bib_program $bbl_base";
5556 print "======= Dealing with '$from_rule'\n" if ($diagnostics);
5557 if ($bib_program eq 'biber') {
5558 check_biber_log( $bbl_base, \@biber_source );
5559 # Remove OPPOSITE kind of bbl generation:
5560 rdb_remove_rule( "bibtex $bbl_base" );
5561 }
5562 else {
5563 parse_aux( "$bbl_base.aux", \@new_bib_files, \@new_aux_files, \@new_bst_files );
5564 # Remove OPPOSITE kind of bbl generation:
5565 rdb_remove_rule( "biber $bbl_base" );
5566 }
5567 if ( ! rdb_rule_exists( $from_rule ) ){
5568 print " ===Creating rule '$from_rule'\n" if ($diagnostics);
5569 if ( $bib_program eq 'biber' ) {
5570 rdb_create_rule( $from_rule, 'external', $biber, '', 1,
5571 "$bbl_base.bcf", $bbl_file, $bbl_base, 1, 0, 0, 1, [ "$bbl_base.blg" ] );
5572 }
5573 else {
5574 rdb_create_rule( $from_rule, 'external', $bibtex, 'run_bibtex', 1,
5575 "$bbl_base.aux", $bbl_file, $bbl_base, 1, 0, 0, 1, [ "$bbl_base.blg" ] );
5576 }
5577 }
5578 local %old_sources = ();
5579 rdb_one_rule( $from_rule, sub { %old_sources = %$PHsource; } );
5580 my @new_sources = ( @new_bib_files, @new_aux_files, @new_bst_files );
5581 if ( $bib_program eq 'biber' ) {
5582 push @new_sources, @biber_source;
5583 }
5584 foreach my $source ( @new_sources ) {
5585 print " ===Source file '$source' for '$from_rule'\n"
5586 if ($diagnostics);
5587 rdb_ensure_file( $from_rule, $source );
5588 delete $old_sources{$source};
5589 }
5590 foreach my $source ( @new_aux_files ) {
5591 $processed_aux_files{$source} = 1;
5592 }
5593 if ($diagnostics) {
5594 foreach ( keys %old_sources ) {
5595 print "Removing no-longer-needed dependent '$_' from rule '$from_rule'\n";
5596 }
5597 }
5598 rdb_remove_files( $from_rule, keys %old_sources );
5599 print " ===Source file '$bbl_file' for '$rule'\n"
5600 if ($diagnostics);
5601 rdb_ensure_file( $rule, $bbl_file, $from_rule );
5602 if ( ! -e $bbl_file ) {
5603 # Failure was non-existence of makable file
5604 # Leave failure issue to other rules.
5605 $failure = 0;
5606 }
5607 }
5608
5609 if ( ($#aux_hooks > -1) && ! exists $processed_aux_files{$aux_main} ) {
5610 my @new_bib_files = ();
5611 my @new_aux_files = ();
5612 my @new_bst_files = ();
5613 parse_aux( $aux_main, \@new_bib_files, \@new_aux_files, \@new_bst_files );
5614 foreach my $source ( @new_aux_files ) {
5615 $processed_aux_files{$source} = 1;
5616 }
5617 }
5618
5619NEW_SOURCE:
5620 foreach my $new_source (keys %dependents) {
5621 print " ===Source file for rule '$rule': '$new_source'\n"
5622 if ($diagnostics);
5623 if ( exists $first_read_after_write{$new_source} ) {
5624 if ( dep_at_start($new_source) ) {
5625 #warn "--- READ ONLY AFTER WRITE OF '$new_source'\n";
5626 $dependents{$new_source} = 7;
5627 }
5628 else {
5629 #warn "--- READ ONLY AFTER CREATE OF '$new_source'\n";
5630 $dependents{$new_source} = 6;
5631 }
5632 }
5633 if ( ($dependents{$new_source} == 5)
5634 || ($dependents{$new_source} == 6)
5635 ) {
5636 # (a) File was detected in "No file..." line in log file.
5637 # Typically file was searched for early in run of
5638 # latex/pdflatex, was not found, and then was written
5639 # later in run.
5640 # or (b) File was written during run.
5641 # In both cases, if file doesn't already exist in database, we
5642 # don't know its previous status. Therefore we tell
5643 # rdb_ensure_file that if it needs to add the file to its
5644 # database, then the previous version of the file should be
5645 # treated as non-existent, to ensure another run is forced.
5646 rdb_ensure_file( $rule, $new_source, undef, 1 );
5647 }
5648 elsif ( $dependents{$new_source} == 7 ) {
5649 # File was result of conversion by (pdf)latex.
5650 my $cnv_source = $conversions{$new_source};
5651 rdb_ensure_file( $rule, $new_source );
5652 if ($cnv_source) {
5653 # Conversion from $cnv_source to $new_source
5654 # implies that effectively $cnv_source is a source
5655 # of the (pdf)latex run.
5656 rdb_ensure_file( $rule, $cnv_source );
5657 }
5658 # Flag that changes of the generated file during a run
5659 # do not require a rerun:
5660 rdb_one_file( $new_source, sub{ $$Pcorrect_after_primary = 1; } );
5661 }
5662 else {
5663 # But we don't need special precautions for ordinary user files
5664 # (or for files that are generated outside of latex/pdflatex).
5665 rdb_ensure_file( $rule, $new_source );
5666 }
5667 if ( ($dependents{$new_source} == 6)
5668 || ($dependents{$new_source} == 7)
5669 ) {
5670 rdb_add_generated($new_source);
5671 }
5672 }
5673
5674 my @more_sources = &rdb_set_dependents( $rule );
5675 my $num_new = $#more_sources + 1;
5676 foreach (@more_sources) {
5677 $dependents{$_} = 4;
5678 if ( ! -e $_ ) {
5679 # Failure was non-existence of makable file
5680 # Leave failure issue to other rules.
5681 $failure = 0;
5682 $$Pchanged = 1; # New files can be made. Ignore error.
5683 }
5684 }
5685 if ($diagnostics) {
5686 if ($num_new > 0 ) {
5687 print "$num_new new source files for rule '$rule':\n";
5688 foreach (@more_sources) { print " '$_'\n"; }
5689 }
5690 else {
5691 print "No new source files for rule '$rule':\n";
5692 }
5693 my @first_read_after_write = sort keys %first_read_after_write;
5694 if ($#first_read_after_write >= 0) {
5695 print "The following files were only read after being written:\n";
5696 foreach (@first_read_after_write) {
5697 print " '$_'\n";
5698 }
5699 }
5700 }
5701 my @files_not_needed = ();
5702 foreach (keys %$PHsource) {
5703 if ( ! exists $dependents{$_} ) {
5704 print "Removing no-longer-needed dependent '$_' from rule '$rule'\n"
5705 if $diagnostics;
5706 push @files_not_needed, $_;
5707 }
5708 }
5709 rdb_remove_files( $rule, @files_not_needed );
5710
5711} # END rdb_set_latex_deps
5712
5713#************************************************************
5714
5715sub test_gen_file {
5716 # Usage: test_gen_file( filename )
5717 # Tests whether the file was generated during a run of (pdf)latex.
5718 # Assumes context for primary rule.
5719 # Two kinds of test are used:
5720 # a. From %generated_log, which works after the log file has been parsed,
5721 # but only for certain files and for those TeX engines (not MiKTeX)
5722 # that put \openout lines in log file.
5723 # b. By the file existing and being at least as new as the system
5724 # time at the start of the run. But we allow for a measured
5725 # offset between filetime and system time, which could be
5726 # nonzero if the file is on a different, remote system than the
5727 # one running latexmk. We must also allow a threshold in the
5728 # comparisons of filetimes to allow for the inaccuracy of the
5729 # offset measurement.
5730 my $file = shift;
5731 return exists $generated_log{$file}
5732 || ( -e $file && ( get_mtime( $file ) >= $$Prun_time + $filetime_offset - $filetime_causality_threshold));
5733}
5734
5735#************************************************************
5736
5737sub dep_at_start {
5738 # Usage: dep_at_start( filename )
5739 # Tests whether the file was source file and existed at start of run.
5740 # Assumes context for primary rule.
5741 my $time = undef;
5742 rdb_one_file( shift, sub{ $time = $$Ptime; } );
5743 return (defined $time) && ($time != 0);
5744}
5745
5746#************************************************************
5747
5748sub rdb_find_new_files {
5749 # Call: rdb_find_new_files
5750 # Assumes rule context for primary rule.
5751 # Deal with files which were missing and for which a method
5752 # of finding them has become available:
5753 # (a) A newly available source file for a custom dependency.
5754 # (b) When there was no extension, a file with appropriate
5755 # extension
5756 # (c) When there was no extension, and a newly available source
5757 # file for a custom dependency can make it.
5758
5759 my %new_includes = ();
5760
5761MISSING_FILE:
5762 foreach my $missing ( keys %$PHsource ) {
5763 next if ( $$PHsource{$missing} != 0 );
5764 my ($base, $path, $ext) = fileparseA( $missing );
5765 $ext =~ s/^\.//;
5766 if ( -e "$missing.tex" ) {
5767 $new_includes{"$missing.tex"} = 1;
5768 }
5769 if ( -e $missing ) {
5770 $new_includes{$missing} = 1;
5771 }
5772 if ( $ext ne "" ) {
5773 foreach my $dep (@cus_dep_list){
5774 my ($fromext,$toext) = split('\s+',$dep);
5775 if ( ( "$ext" eq "$toext" )
5776 && ( -e "$path$base.$fromext" )
5777 ) {
5778 # Source file for the missing file exists
5779 # So we have a real include file, and it will be made
5780 # next time by rdb_set_dependents
5781 $new_includes{$missing} = 1;
5782 }
5783 else {
5784 # no point testing the $toext if the file doesn't exist.
5785 }
5786 next MISSING_FILE;
5787 }
5788 }
5789 else {
5790 # $_ doesn't exist, $_.tex doesn't exist,
5791 # and $_ doesn't have an extension
5792 foreach my $dep (@cus_dep_list){
5793 my ($fromext,$toext) = split('\s+',$dep);
5794 if ( -e "$path$base.$fromext" ) {
5795 # Source file for the missing file exists
5796 # So we have a real include file, and it will be made
5797 # next time by &rdb__dependents
5798 $new_includes{"$path$base.$toext"} = 1;
5799# next MISSING_FILE;
5800 }
5801 if ( -e "$path$base.$toext" ) {
5802 # We've found the extension for the missing file,
5803 # and the file exists
5804 $new_includes{"$path$base.$toext"} = 1;
5805# next MISSING_FILE;
5806 }
5807 }
5808 }
5809 } # end MISSING_FILES
5810
5811 # Sometimes bad line-breaks in log file (etc) create the
5812 # impression of a missing file e.g., ./file, but with an incorrect
5813 # extension. The above tests find the file with an extension,
5814 # e.g., ./file.tex, but it is already in the list. So now I will
5815 # remove files in the new_include list that are already in the
5816 # include list. Also handle aliasing of file.tex and ./file.tex.
5817 # For example, I once found:
5818# (./qcdbook.aux (./to-do.aux) (./ideas.aux) (./intro.aux) (./why.aux) (./basics
5819#.aux) (./classics.aux)
5820
5821 my $found = 0;
5822 foreach my $file (keys %new_includes) {
5823 my $stripped = $file;
5824 $stripped =~ s{^\./}{};
5825 if ( exists $PHsource{$file} ) {
5826 delete $new_includes{$file};
5827 }
5828 else {
5829 $found ++;
5830 rdb_ensure_file( $rule, $file );
5831 }
5832 }
5833
5834 if ( $diagnostics && ( $found > 0 ) ) {
5835 warn "$My_name: Detected previously missing files:\n";
5836 foreach ( sort keys %new_includes ) {
5837 warn " '$_'\n";
5838 }
5839 }
5840 return $found;
5841} # END rdb_find_new_files
5842
5843#************************************************************
5844
5845sub rdb_set_dependents {
5846 # Call rdb_set_dependents( rules ...)
5847 # Returns array (sorted), of new source files.
5848 local @new_sources = ();
5849 local @deletions = ();
5850
5851# Shouldn't recurse. The definite rules to be examined are given.
5852 rdb_for_some( [@_], 0, \&rdb_one_dep );
5853# OLD rdb_recurse( [@_], 0, \&rdb_one_dep );
5854 foreach (@deletions) {
5855 my ($rule, $file) = @$_;
5856 rdb_remove_files( $rule, $file );
5857 }
5858 &rdb_make_links;
5859 return uniqs( @new_sources );
5860} #END rdb_set_dependents
5861
5862#************************************************************
5863
5864sub rdb_one_dep {
5865 # Helper for finding dependencies. One case, $rule and $file given
5866 # Assume file (and rule) context for DESTINATION file.
5867
5868 # Only look for dependency if $rule is primary rule (i.e., latex
5869 # or pdflatex) or is a custom dependency:
5870 if ( (! exists $possible_primaries{$rule}) && ($rule !~ /^cusdep/) ) {
5871 return;
5872 }
5873#print "=============ONE_DEP: '$rule' '$file'\n";
5874 local $new_dest = $file;
5875 my ($base_name, $path, $toext) = fileparseA( $new_dest );
5876 $base_name = $path.$base_name;
5877 $toext =~ s/^\.//;
5878 my $Pinput_extensions = $input_extensions{$rule};
5879DEP:
5880 foreach my $dep ( @cus_dep_list ) {
5881 my ($fromext,$proptoext,$must,$func_name) = split('\s+',$dep);
5882 if ( $toext eq $proptoext ) {
5883 my $source = "$base_name.$fromext";
5884 # Found match of rule
5885 if ($diagnostics) {
5886 print "Found cusdep: $source to make $rule:$new_dest ====\n";
5887 }
5888 if ( -e $source ) {
5889 $$Pfrom_rule = "cusdep $fromext $toext $base_name";
5890#?? print "?? Ensuring rule for '$$Pfrom_rule'\n";
5891 local @PAnew_cmd = ( 'do_cusdep', $func_name );
5892 if ( !-e $new_dest ) {
5893 push @new_sources, $new_dest;
5894 }
5895 if (! rdb_rule_exists( $$Pfrom_rule ) ) {
5896 print "=== Creating rule for '$$Pfrom_rule'\n";
5897 rdb_create_rule( $$Pfrom_rule, 'cusdep', '', \@PAnew_cmd, 3,
5898 $source, $new_dest, $base_name, 0 );
5899 }
5900 else {
5901 rdb_one_rule(
5902 $$Pfrom_rule,
5903 sub{ @$PAint_cmd = @PAnew_cmd; $$Pdest = $new_dest;}
5904 );
5905 }
5906 return;
5907 }
5908 else {
5909 # Source file does not exist
5910 if ( !$force_mode && ( $must != 0 ) ) {
5911 # But it is required that the source exist ($must !=0)
5912 $failure = 1;
5913 $failure_msg = "File '$base_name.$fromext' does not exist ".
5914 "to build '$base_name.$toext'";
5915 return;
5916 }
5917 elsif ( $$Pfrom_rule =~ /^cusdep $fromext $toext / ) {
5918 # Source file does not exist, destination has the rule set.
5919 # So turn the from_rule off
5920 $$Pfrom_rule = '';
5921 }
5922 else {
5923 }
5924 }
5925 }
5926 elsif ( ($toext eq '')
5927 && (! -e $file )
5928 && (! -e "$base_name.$proptoext" )
5929 && exists $$Pinput_extensions{$proptoext}
5930 ) {
5931 # Empty extension and non-existent destination
5932 # This normally results from \includegraphics{A}
5933 # without graphics extension for file, when file does
5934 # not exist. So we will try to find something to make it.
5935 my $source = "$base_name.$fromext";
5936 if ( -e $source ) {
5937 $new_dest = "$base_name.$proptoext";
5938 my $from_rule = "cusdep $fromext $proptoext $base_name";
5939 push @new_sources, $new_dest;
5940 print "Ensuring rule for '$from_rule', to make '$new_dest'\n"
5941 if $diagnostics > -1;
5942 local @PAnew_cmd = ( 'do_cusdep', $func_name );
5943 if (! rdb_rule_exists( $from_rule ) ) {
5944 rdb_create_rule( $from_rule, 'cusdep', '', \@PAnew_cmd, 3,
5945 $source, $new_dest, $base_name, 0 );
5946 }
5947 else {
5948 rdb_one_rule(
5949 $$Pfrom_rule,
5950 sub{ @$PAint_cmd = @PAnew_cmd; $$Pdest = $new_dest;}
5951 );
5952 }
5953 rdb_ensure_file( $rule, $new_dest, $from_rule );
5954 # We've now got a spurious file in our rule. But don't mess
5955 # with deleting an item we are in the middle of!
5956 push @deletions, [$rule, $file];
5957 return;
5958 }
5959 } # End of Rule found
5960 } # End DEP
5961 if ( (! -e $file) && $use_make_for_missing_files ) {
5962 # Try to make the missing file
5963 #Set character to surround filenames in commands:
5964 my $q = $quote_filenames ? '"' : '';
5965 if ( $toext ne '' ) {
5966 print "$My_name: '$rule': source file '$file' doesn't exist. I'll try making it...\n";
5967 &Run_subst( "$make $q$file$q" );
5968 if ( -e $file ) {
5969 return;
5970 }
5971 }
5972 else {
5973 print "$My_name: '$rule': source '$file' doesn't exist.\n",
5974 " I'll try making it with allowed extensions \n";
5975 foreach my $try_ext ( keys %$Pinput_extensions ) {
5976 my $new_dest = "$file.$try_ext";
5977 &Run_subst( "$make $q$new_dest$q" );
5978 if ( -e $new_dest ) {
5979 print "SUCCESS in making '$new_dest'\n";
5980 # Put file in rule, without a from_rule, but
5981 # set its state as non-existent, to correspond
5982 # to file's state before the file was made
5983 # This ensures a rerun of (pdf)latex is provoked.
5984 rdb_ensure_file( $rule, $new_dest, undef, 1 );
5985 push @new_sources, $new_dest;
5986 push @deletions, [$rule, $file];
5987 # Flag need for a new run of (pdf)latex despite
5988 # the error due to a missing file.
5989 $$Pout_of_date_user = 1;
5990 return;
5991 }
5992 }
5993 }
5994 }
5995} #END rdb_one_dep
5996
5997#************************************************************
5998
5999sub rdb_list {
6000 # Call: rdb_list()
6001 # List rules and their source files
6002 print "===Rules:\n";
6003 local $count_rules = 0;
6004 my @accessible_all = rdb_accessible( keys %requested_filerules );
6005 rdb_for_some(
6006 \@accessible_all,
6007 sub{ $count_rules++;
6008 print "Rule '$rule' depends on:\n";
6009 },
6010 sub{ print " '$file'\n"; },
6011 sub{ print " and generates:\n";
6012 foreach (keys %$PHdest) { print " '$_'\n"; }
6013# print " default_extra_generated:\n";
6014# foreach (@$PA_extra_generated) { print " '$_'\n"; }
6015 },
6016 );
6017 if ($count_rules <= 0) {
6018 print " ---No rules defined\n";
6019 }
6020} #END rdb_list
6021
6022#************************************************************
6023
6024sub deps_list {
6025 # Call: deps_list(fh)
6026 # List dependent files to file open on fh
6027 my $fh = $_[0];
6028 print $fh "#===Dependents, and related info, for $filename:\n";
6029 my @dest_exts = ();
6030 if ($pdf_mode) {push @dest_exts, '.pdf';}
6031 if ($dvi_mode) {push @dest_exts, '.dvi';}
6032 if ($postscript_mode) {push @dest_exts, '.ps';}
6033 my %source = ( $texfile_name => 1 );
6034 my @generated = ();
6035 my @accessible_all = rdb_accessible( keys %requested_filerules );
6036 rdb_for_some(
6037 \@accessible_all,
6038 sub{
6039# foreach (keys %$PHdest) { print "----- $_\n"; }
6040 push @generated, keys %$PHdest;
6041 },
6042 sub{ $source{$file} = 1; }
6043 );
6044 foreach (keys %generated_exts_all) {
6045 (my $name = /%R/ ? $_ : "%R.$_") =~ s/%R/${aux_dir1}${root_filename}/;
6046 push @generated, $name;
6047 }
6048 show_array( "Generated:", @generated ) if $diagnostics;
6049 foreach (@generated) {
6050 delete $source{$_};
6051 }
6052 show_array( "Sources:", keys %source ) if $diagnostics;
6053 foreach my $ext (@dest_exts) {
6054 # Don't insert name of deps file in targets.
6055 # The previous behavior of inserting the name of the deps file
6056 # matched the method recommended by GNU make for automatically
6057 # generated prerequisites -- see Sec. "Generating Prerequisites
6058 # Automatically" of GNU make manual (v. 4.2). But this can
6059 # cause problems in complicated cases, and as far as I can see,
6060 # it doesn't actually help, despite the reasoning given.
6061 # The only purpose of the deps file is to to determine source
6062 # files for a particular rule. The files whose changes make the
6063 # deps file out-of-date are the same as those that make the real
6064 # target file (e.g., .pdf) out-of-date. So the GNU method seems
6065 # completely unnecessary.
6066 print $fh "${out_dir1}${root_filename}${ext} :";
6067 foreach (sort keys %source) {
6068 print $fh "\\\n $_";
6069 }
6070 print $fh "\n";
6071 }
6072 print $fh "#===End dependents for $filename:\n";
6073 if ($dependents_phony) {
6074 print $fh "\n#===Phony rules for $filename:\n\n";
6075 foreach (sort keys %source) {
6076 print $fh "$_ :\n\n";
6077 }
6078 print $fh "#===End phony rules for $filename:\n";
6079 }
6080} #END deps_list
6081
6082#************************************************************
6083
6084sub rdb_show {
6085 # Call: rdb_show()
6086 # Displays contents of rule data base.
6087 # Side effect: Exercises access routines!
6088 print "===Rules:\n";
6089 local $count_rules = 0;
6090 rdb_for_all(
6091 sub{ $count_rules++;
6092 my @int_cmd = @$PAint_cmd;
6093 foreach (@int_cmd) {
6094 if ( !defined($_) ) { $_='undef';}
6095 }
6096 print " [$rule]: '$$Pcmd_type' '$$Pext_cmd' '@int_cmd' $$Ptest_kind ",
6097 "'$$Psource' '$$Pdest' '$$Pbase' $$Pout_of_date $$Pout_of_date_user\n"; },
6098 sub{ print " '$file': $$Ptime $$Psize $$Pmd5 '$$Pfrom_rule'\n"; }
6099 );
6100 if ($count_rules <= 0) {
6101 print " ---No rules defined\n";
6102 }
6103} #END rdb_show
6104
6105#************************************************************
6106
6107sub rdb_accessible {
6108 # Call: rdb_accessible( rule, ...)
6109 # Returns array of rules accessible from the given rules
6110 local @accessible = ();
6111 rdb_recurse( [@_], sub{ push @accessible, $rule; } );
6112 return @accessible;
6113} #END rdb_accessible
6114
6115#************************************************************
6116#************************************************************
6117#************************************************************
6118
6119sub rdb_make {
6120 # Call: rdb_make( target, ... )
6121 # Makes the targets and prerequisites.
6122 # Leaves one-time rules to last.
6123 # Does appropriate repeated makes to resolve dependency loops
6124
6125 # Returns 0 on success, nonzero on failure.
6126
6127 # General method: Find all accessible rules, then repeatedly make
6128 # them until all accessible rules are up-to-date and the source
6129 # files are unchanged between runs. On termination, all
6130 # accessible rules have stable source files.
6131 #
6132 # One-time rules are view and print rules that should not be
6133 # repeated in an algorithm that repeats rules until the source
6134 # files are stable. It is the calling routine's responsibility to
6135 # arrange to call them, or to use them here with caution.
6136 #
6137 # Note that an update-viewer rule need not be considered
6138 # one-time. It can be legitimately applied everytime the viewed
6139 # file changes.
6140 #
6141 # Note also that the criterion of stability is to be applied to
6142 # source files, not to output files. Repeated application of a
6143 # rule to IDENTICALLY CONSTANT source files may produce different
6144 # output files. This may be for a trivial reason (e.g., the
6145 # output file contains a time stamp, as in the header comments for
6146 # a typical postscript file), or for a non-trivial reason (e.g., a
6147 # stochastic algorithm, as in abcm2ps).
6148 #
6149 # This caused me some actual trouble. In general, circular
6150 # dependencies produce non-termination, and the the following
6151 # situation is an example of a generic situation where certain
6152 # rules must be obeyed in order to obtain proper results:
6153 # 1. A/the latex source file contains specifications for
6154 # certain postprocessing operations. Standard (pdf)latex
6155 # already has this, for indexing and bibliography.
6156 # 2. In the case in point that caused me trouble, the
6157 # specification was for musical tunes that were contained
6158 # in external source files not directly input to
6159 # (pdf)latex. But in the original version, there was a
6160 # style file (abc.sty) that caused latex itself to call
6161 # abcm2ps to make .eps files for each tune that were to be
6162 # read in on the next run of latex.
6163 # 3. Thus the specification can cause a non-terminating loop
6164 # for latexmk, because the output files of abcm2ps changed
6165 # even with identical input.
6166 # 4. The solution was to
6167 # a. Use a style file abc_get.sty that simply wrote the
6168 # specification on the tunes to the .aux file in a
6169 # completely deterministic fashion.
6170 # b. Instead of latex, use a script abclatex.pl that runs
6171 # latex and then extracts the abc contents for each tune
6172 # from the source abc file. This is also
6173 # deterministic.
6174 # c. Use a cusdep rule in latexmk to convert the tune abc
6175 # files to eps. This is non-deterministic, but only
6176 # gets called when the (deterministic) source file
6177 # changes.
6178 # This solves the problem. Latexmk works. Also, it is no
6179 # longer necessary to enable write18 in latex, and multiple
6180 # unnecessary runs of abcm2ps are no longer used.
6181 #
6182 # The order of testing and applying rules is chosen by the
6183 # following heuristics:
6184 # 1. Both latex and pdflatex may be used, but the resulting
6185 # aux files etc may not be completely identical. Define
6186 # latex and pdflatex as primary rules. Apply the general
6187 # method of repeated circulating through all rules until
6188 # the source files are stable for each primary rule
6189 # separately. Naturally the rules are all accessible
6190 # rules, but excluding primary rules except for the current
6191 # primary.
6192 # 2. Assume that the primary rules are relatively
6193 # time-consuming, so that unnecessary passes through them
6194 # to check stability of the source files should be avoided.
6195 # 3. Assume that although circular dependencies exist, the
6196 # rules can nevertheless be thought of as basically
6197 # non-circular, and that many rules are strictly or
6198 # normally non-circular. In particular cusdep rules are
6199 # typically non-circular (e.g., fig2eps), as are normal
6200 # output processing rules like dvi2ps.
6201 # 4. The order for the non-circular approximation is
6202 # determined by applying the assumption that an output file
6203 # from one rule that is read in for an earlier stage is
6204 # unchanged.
6205 # HOWEVER, at a first attempt, the ordering is not needed. It
6206 # only gives an optimization
6207 # 5. (Note that these assumptions could be violated, e.g., if
6208 # $dvips is arranged not only to do the basic dvips
6209 # command, but also to extract information from the ps file
6210 # and feed it back to an input file for (pdf)latex.)
6211 # 6. Nevertheless, the overall algorithm should allow
6212 # circularities. Then the general criterion of stability
6213 # of source files covers the general case, and also
6214 # robustly handles the case that the USER changes source
6215 # files during a run. This is particularly important in
6216 # -pvc mode, given that a full make on a large document can
6217 # be quite lengthy in time, and moreover that a user
6218 # naturally wishes to make corrections in response to
6219 # errors, particularly latex errors, and have them apply
6220 # right away.
6221 # This leads to the following approach:
6222 # 1. Classify accessible rules as: primary, pre-primary
6223 # (typically cusdep, bibtex, makeindex, etc), post-primary
6224 # (typically dvips, etc), and one-time
6225 # 2. Then stratify the rules into an order of application that
6226 # corresponds to the basic feedforward structure, with the
6227 # exclusion of one-time rules.
6228 # 3. Always require that one-time rules are among the
6229 # explicitly requested rules, i.e., the last to be applied,
6230 # were we to apply them. Anything else would not match the
6231 # idea of a one-time rule.
6232 # 4. Then work as follows:
6233 # a. Loop over primaries
6234 # b. For each primary, examine each pre-primary rule and
6235 # apply if needed, then the primary rule and then each
6236 # post-primary rule. The ordering of the pre-primary
6237 # and post-primary rules was found in step 2.
6238 # BUT applying the ordering is not essential
6239 # c. Any time that a pre-primary or primary rule is
6240 # applied, loop back to the beginning of step b. This
6241 # ensures that bibtex etc are applied before rerunning
6242 # (pdf)latex, and also covers changing source files, and
6243 # gives priority to quick pre-primary rules for changing
6244 # source files against slow reruns of latex.
6245 # d. Then apply post-primary rules in order, but not
6246 # looping back after each rule. This non-looping back
6247 # is because the rules are normally feed-forward only.
6248 # BUT applying the ordering is not essential
6249 # e. But after completing post-primary rules do loop back
6250 # to b if any rules were applied. This covers exotic
6251 # circular dependence (and as a byproduct, changing
6252 # source files).
6253 # f. On each case of looping back to b, re-evaluate the
6254 # dependence setup to allow for the effect of changing
6255 # source files.
6256 #
6257
6258 local @requested_targets = @_;
6259 local %current_primaries = (); # Hash whose keys are primary rules
6260 # needed, i.e., known latex-like rules which trigger
6261 # circular dependencies
6262 local @pre_primary = (); # Array of rules
6263 local @post_primary = (); # Array of rules
6264 local @unusual_one_time = (); # Array of rules
6265
6266
6267 # For diagnostics on changed files, etc:
6268 local @changed = ();
6269 local @disappeared = ();
6270 local @no_dest = (); # Non-existent destination files
6271 local @rules_never_run = ();
6272 local @rules_to_apply = ();
6273
6274 &rdb_classify_rules( \%possible_primaries, @requested_targets );
6275
6276 local %pass = ();
6277 local $failure = 0; # General accumulated error flag
6278 local $missing_dvi_pdf = ''; # Did primary run fail to make its output file?
6279 local $runs = 0;
6280 local $too_many_passes = 0;
6281 local %rules_applied = ();
6282 my $retry_msg = 0; # Did I earlier say I was going to attempt
6283 # another pass after a failure?
6284 PRIMARY:
6285 foreach my $primary (keys %current_primaries ) {
6286 foreach my $rule (keys %rule_db) {
6287 $pass{$rule} = 0;
6288 }
6289 PASS:
6290 while (1==1) {
6291 # Exit condition at end of body of loop.
6292 $runs = 0;
6293 my $previous_failure = $failure;
6294 $failure = 0;
6295 local $newrule_nofile = 0; # Flags whether rule created for
6296 # making currently non-existent file, which
6297 # could become a needed source file for a run
6298 # and therefore undo an error condition
6299 if ($diagnostics) {
6300 print "Make: doing pre_primary and primary...\n";
6301 }
6302 # Do the primary run if it is needed. On return $runs == 0
6303 # signals that nothing was run (and hence no output
6304 # files changed), either because no input files
6305 # changed and no run was needed, or because the
6306 # number of passes through the rule exceeded the
6307 # limit. In the second case $too_many_runs is set.
6308 rdb_for_some( [@pre_primary, $primary], \&rdb_make1 );
6309 if ( ($runs > 0) && ! $too_many_passes ) {
6310 $retry_msg = 0;
6311 if ( $force_mode || (! $failure) ) {
6312 next PASS;
6313 }
6314 # Get here on failure, without being in force_mode
6315 if ( $newrule_nofile ) {
6316 $retry_msg = 1;
6317 print "$My_name: Error on run, but found possibility to ",
6318 "make new source files\n";
6319 next PASS;
6320 }
6321 else { last PASS; }
6322 }
6323 if ($runs == 0) {
6324 # $failure not set on this pass, so use value from previous pass:
6325 $failure = $previous_failure;
6326 if ($retry_msg) {
6327 print "But in fact no new files made\n";
6328 }
6329 if ($failure && !$force_mode ) { last PASS; }
6330 }
6331 if ( $missing_dvi_pdf ) {
6332 # No output from primary, after completing circular dependence
6333 warn "Failure to make '$missing_dvi_pdf'\n";
6334 $failure = 1;
6335 last PASS;
6336 }
6337 if ($diagnostics) {
6338 print "Make: doing post_primary...\n";
6339 }
6340 rdb_for_some( [@post_primary], \&rdb_make1 );
6341 if ( ($runs == 0) || $too_many_passes ) {
6342 # If $too_many_passes is set, it should also be that
6343 # $runs == 0; but for safety, I also checked
6344 # $too_many_passes.
6345 last PASS;
6346 }
6347 }
6348 continue {
6349 # Re-evaluate rule classification and accessibility,
6350 # but do not change primaries.
6351 # Problem is that %current_primaries gets altered
6352 my %old_curr_prim = %current_primaries;
6353 &rdb_classify_rules( \%possible_primaries, @requested_targets );
6354 %current_primaries = %old_curr_prim;
6355 &rdb_make_links;
6356 }
6357 }
6358 rdb_for_some( [@unusual_one_time], \&rdb_make1 );
6359 rdb_write( $fdb_name );
6360
6361 if (! $silent) {
6362 if ($failure && $force_mode) {
6363 print "$My_name: Errors, in force_mode: so I tried finishing targets\n";
6364 }
6365 elsif ($failure) {
6366 print "$My_name: Errors, so I did not complete making targets\n";
6367 }
6368 else {
6369 local @dests = ();
6370 rdb_for_some( [@_], sub{ push @dests, $$Pdest if ($$Pdest); } );
6371 print "$My_name: All targets (@dests) are up-to-date\n";
6372 }
6373 }
6374 return $failure;
6375} #END rdb_make
6376
6377#-------------------
6378
6379sub rdb_show_rule_errors {
6380 local @errors = ();
6381 local @warnings = ();
6382 rdb_for_all(
6383 sub{
6384 if ($$Plast_message ne '') {
6385 if ($$Plast_result == 200) {
6386 push @warnings, "$rule: $$Plast_message";
6387 }
6388 else {
6389 push @errors, "$rule: $$Plast_message";
6390 }
6391 }
6392 elsif ($$Plast_result == 1) {
6393 push @errors, "$rule: failed to create output file";
6394 }
6395 elsif ($$Plast_result == 2) {
6396 push @errors, "$rule: gave an error";
6397 }
6398 elsif ($$Prun_time == 0) {
6399 # This can have innocuous causes. So don't report
6400 }
6401 }
6402 );
6403 if ($#warnings > -1) {
6404 warn "Collected warning summary (may duplicate other messages):\n";
6405 foreach (@warnings){
6406 warn " $_\n";
6407 }
6408 }
6409 if ($#errors > -1) {
6410 warn "Collected error summary (may duplicate other messages):\n";
6411 foreach (@errors){
6412 warn " $_\n";
6413 }
6414 }
6415 return $#errors+1;
6416}
6417
6418#-------------------
6419
6420sub rdb_make1 {
6421 # Call: rdb_make1
6422 # Helper routine for rdb_make.
6423 # Carries out make at level of given rule (all data available).
6424 # Assumes contexts for recursion, make, and rule, and
6425 # assumes that source files for the rule are to be considered
6426 # up-to-date.
6427 if ($diagnostics) { print " Make1 $rule\n"; }
6428 if ($failure & ! $force_mode) {return;}
6429 if ( ! defined $pass{$rule} ) {$pass{$rule} = 0; }
6430 &rdb_clear_change_record;
6431
6432 # Special fix up for bibtex:
6433 my $bibtex_not_run = -1; # Flags status as to whether this is a
6434 # bibtex rule and if it is, whether out-of-date condition is to
6435 # be ignored.
6436 # -1 => not a bibtex rule
6437 # 0 => no special treatment
6438 # 1 => don't run bibtex because of non-existent bibfiles
6439 # (and setting to do this test)
6440 # 2 => don't run bibtex because of setting
6441 my @missing_bib_files = ();
6442 if ( $rule =~ /^(bibtex|biber)/ ) {
6443 $bibtex_not_run = 0;
6444 if ($bibtex_use == 0) {
6445 $bibtex_not_run = 2;
6446 }
6447 elsif ( ($bibtex_use == 1) || ($bibtex_use == 1.5) ) {
6448 foreach ( keys %$PHsource ) {
6449 if ( ( /\.bib$/ ) && (! -e $_) ) {
6450 push @missing_bib_files, $_;
6451 $bibtex_not_run = 1;
6452 }
6453 }
6454 }
6455 }
6456
6457 if ( ($$Prun_time == 0) && exists($possible_primaries{$rule}) ) {
6458 push @rules_never_run, $rule;
6459 $$Pout_of_date = 1;
6460 $$Plast_result = -1;
6461 }
6462 else {
6463 if ( $$Pdest && (! -e $$Pdest) ) {
6464 # With a non-existent destination, if we haven't made any passes
6465 # through a rule, rerunning the rule is good, because the file
6466 # may fail to exist because of being deleted by the user (for ex.)
6467 # rather than because of a failure on a previous run.
6468 # (We could do better with a flag in fdb file.)
6469 # But after the first pass, the situation is different.
6470 # For a primary rule (pdf)latex, the lack of a destination file
6471 # could result from there being zero content due to a missing
6472 # essential input file. The input file could be generated
6473 # by a program to be run later (e.g., a cusdep or bibtex),
6474 # so we should wait until all passes are completed before
6475 # deciding a non-existent destination file is an error.
6476 # For a custom dependency, the rule may be obsolete, and
6477 # if the source file does not exist also, we should simply
6478 # not run the rule, but not set an error condition.
6479 # Any error will arise at the (pdf)latex level due to a
6480 # missing source file at that level.
6481 if ( $$Psource && (! -e $$Psource)
6482# OLD && ( ( $$Pcmd_type eq 'cusdep') )
6483# NEW
6484 && ( ( $$Pcmd_type ne 'primary') )
6485 ) {
6486 # Main source file doesn't exist, and rule is NOT primary.
6487 # No action, since a run is pointless. Primary is different:
6488 # file might be found elsewhere (by kpsearch from (pdf)latex),
6489 # while non-existence of main source file is a clear error.
6490 }
6491 elsif ( $$Pcmd_type eq 'delegated' ) {
6492 # Delegate to destination rule
6493 }
6494 elsif ( $pass{$rule}==0) {
6495 push @no_dest, $$Pdest;
6496 $$Pout_of_date = 1;
6497 }
6498 if ( $$Pcmd_type eq 'primary' ) {
6499 $missing_dvi_pdf = $$Pdest;
6500 }
6501 }
6502 }
6503
6504 &rdb_flag_changes_here(0);
6505
6506 if (!$$Pout_of_date) {
6507#?? if ( ($$Pcmd_type eq 'primary') && (! $silent) ) {
6508# print "Rule '$rule' up to date\n";
6509# }
6510 return;
6511 }
6512 if ($diagnostics) { print " remake\n"; }
6513 if (!$silent) {
6514 print "$My_name: applying rule '$rule'...\n";
6515 &rdb_diagnose_changes( "Rule '$rule': " );
6516 }
6517
6518 # We are applying the rule, so its source file state for when it
6519 # was last made is as of now:
6520 # ??IS IT CORRECT TO DO NOTHING IN CURRENT VERSION?
6521
6522 # The actual run
6523 my $return = 0; # Return code from called routine
6524 # Rule may have been created since last run:
6525 if ( ! defined $pass{$rule} ) {$pass{$rule} = 0; }
6526 if ( $pass{$rule} >= $max_repeat ) {
6527 # Avoid infinite loop by having a maximum repeat count
6528 # Getting here represents some kind of weird error.
6529 warn "$My_name: Maximum runs of $rule reached ",
6530 "without getting stable files\n";
6531 $too_many_passes = 1;
6532 # Treat rule as completed, else in -pvc mode get infinite reruns:
6533 $$Pout_of_date = 0;
6534 $failure = 1;
6535 $failure_msg = "'$rule' needed too many passes";
6536 return;
6537 }
6538
6539 $rules_applied{$rule} = 1;
6540 $runs++;
6541
6542 $pass{$rule}++;
6543 if ($bibtex_not_run > 0) {
6544 if ($bibtex_not_run == 1 ) {
6545 show_array ("$My_name: I WON'T RUN '$rule' because I don't find the following files:",
6546 @missing_bib_files);
6547 }
6548 elsif ($bibtex_not_run == 2 ) {
6549 warn "$My_name: I AM CONFIGURED/INVOKED NOT TO RUN '$rule'\n";
6550 }
6551 $return = &rdb_dummy_run1;
6552 }
6553 else {
6554 warn_running( "Run number $pass{$rule} of rule '$rule'" );
6555 if ($$Pcmd_type eq 'primary' ) {
6556 $return = &rdb_primary_run;
6557 }
6558 else { $return = &rdb_run1; }
6559 }
6560 if ($$Pchanged) {
6561 $newrule_nofile = 1;
6562 $return = 0;
6563 }
6564 elsif ( $$Pdest && ( !-e $$Pdest ) && (! $failure) ){
6565 # If there is a destination to make, but for some reason
6566 # it did not get made, and no other error was reported,
6567 # then a priori there appears to be an error condition:
6568 # the run failed. But there are some important cases in
6569 # which this is a wrong diagnosis.
6570 if ( ( $$Pcmd_type eq 'cusdep') && $$Psource && (! -e $$Psource) ) {
6571 # However, if the rule is a custom dependency, this is not by
6572 # itself an error, if also the source file does not exist. In
6573 # that case, we may have the situation that (1) the dest file is no
6574 # longer needed by the tex file, and (2) therefore the user
6575 # has deleted the source and dest files. After the next
6576 # latex run and the consequent analysis of the log file, the
6577 # cusdep rule will no longer be needed, and will be removed.
6578
6579 # So in this case, do NOT report an error
6580 $$Pout_of_date = 0;
6581 }
6582 elsif ($$Pcmd_type eq 'primary' ) {
6583 # For a primary rule, i.e., (pdf)latex, not to produce the
6584 # expected output file may not be an error condition.
6585 # Diagnostics were handled in parsing the log file.
6586 # Special action in main loop in rdb_make
6587 $missing_dvi_pdf = $$Pdest;
6588 }
6589 elsif ($return == -2) {
6590 # Missing output file was reported to be NOT an error
6591 $$Pout_of_date = 0;
6592 }
6593 elsif ( ($bibtex_use <= 1.5) && ($bibtex_not_run > 0) ) {
6594 # Lack of destination file is not to be treated as an error
6595 # for a bibtex rule when latexmk is configured not to treat
6596 # this as an error, and the lack of a destination file is the
6597 # only error.
6598 $$Pout_of_date = 0;
6599 }
6600 else {
6601 $failure = 1;
6602 }
6603 }
6604 if ( ($return != 0) && ($return != -2) ) {
6605 $failure = 1;
6606 $$Plast_result = 2;
6607 if ( !$$Plast_message ) {
6608 $$Plast_message = "Run of rule '$rule' gave a non-zero error code";
6609 }
6610# !!?? $failure_msg = $$Plast_message;
6611
6612 }
6613} #END rdb_make1
6614
6615#************************************************************
6616
6617#??sub rdb_submake {
6618#?? # Call: rdb_submake
6619#?? # Makes all the source files for a given rule.
6620#?? # Assumes contexts for recursion, for make, and rule.
6621#?? %visited = %visited_at_rule_start;
6622#?? local $failure = 0; # Error flag
6623#?? my @v = keys %visited;
6624#?? rdb_do_files( sub{ rdb_recurse_rule( $$Pfrom_rule, 0,0,0, \&rdb_make1 ) } );
6625#?? return $failure;
6626#??} #END rdb_submake
6627
6628#************************************************************
6629
6630sub rdb_classify_rules {
6631 # Usage: rdb_classify_rules( \%allowed_primaries, requested targets )
6632 # Assume the following variables are available (global or local):
6633 # Input:
6634 # @requested_targets # Set to target rules
6635
6636 # Output:
6637 # %current_primaries # Keys are actual primaries
6638 # @pre_primary # Array of rules
6639 # @post_primary # Array of rules
6640 # @unusual_one_time # Array of rules
6641 # @pre_primary and @post_primary are in natural order of application.
6642
6643 local $P_allowed_primaries = shift;
6644 local @requested_targets = @_;
6645 local $state = 0; # Post-primary
6646 local @classify_stack = ();
6647
6648 %current_primaries = ();
6649 @pre_primary = ();
6650 @post_primary = ();
6651 @unusual_one_time = ();
6652
6653 rdb_recurse( \@requested_targets, \&rdb_classify1, 0,0, \&rdb_classify2 );
6654
6655 # Reverse, as tendency is to find last rules first.
6656 @pre_primary = reverse @pre_primary;
6657 @post_primary = reverse @post_primary;
6658
6659 if ($diagnostics) {
6660 print "Rule classification: \n";
6661 if ($#requested_targets < 0) {
6662 print " No requested rules\n";
6663 }
6664 else {
6665 print " Requested rules:\n";
6666 foreach ( @requested_targets ) { print " $_\n"; }
6667 }
6668 if ($#pre_primary < 0) {
6669 print " No pre-primaries\n";
6670 }
6671 else {
6672 print " Pre-primaries:\n";
6673 foreach (@pre_primary) { print " $_\n"; }
6674 }
6675 print " Primaries:\n";
6676 foreach (keys %current_primaries) { print " $_\n"; }
6677 if ($#post_primary < 0) {
6678 print " No post-primaries\n";
6679 }
6680 else {
6681 print " Post-primaries:\n";
6682 foreach (@post_primary) { print " $_\n"; }
6683 }
6684 if ($#unusual_one_time < 0) {
6685 print " No inner-level one_time rules, as expected\n";
6686 }
6687 else {
6688 print " Inner-level one_time rules:\n";
6689 foreach ( @unusual_one_time ) { print " $_\n"; }
6690 }
6691 my @normal_one_time = keys %one_time;
6692 if ($#normal_one_time < 0) {
6693 print " No outer-level one_time rules\n";
6694 }
6695 else {
6696 print " Outer-level one_time rules:\n";
6697 foreach ( @normal_one_time ) { print " $_\n"; }
6698 }
6699 } #end diagnostics
6700
6701} #END rdb_classify_rules
6702
6703#-------------------
6704
6705sub rdb_classify1 {
6706 # Helper routine for rdb_classify_rules
6707 # Applied as rule_act1 in recursion over rules
6708 # Assumes rule context, and local variables from rdb_classify_rules
6709 push @classify_stack, [$state];
6710 if ( exists $possible_one_time{$rule} ) {
6711 # Normally, we will have already extracted the one_time rules,
6712 # and they will never be accessed here. But just in case of
6713 # problems or generalizations, we will cover all possibilities:
6714 if ($depth > 1) {
6715 warn "ONE TIME rule not at outer level '$rule'\n";
6716 }
6717 push @unusual_one_time, $rule;
6718 }
6719 elsif ($state == 0) {
6720 if ( exists ${$P_allowed_primaries}{$rule} ) {
6721 $state = 1; # In primary rule
6722 $current_primaries{ $rule } = 1;
6723 }
6724 else {
6725 push @post_primary, $rule;
6726 }
6727 }
6728 else {
6729 $state = 2; # in post-primary rule
6730 push @pre_primary, $rule;
6731 }
6732} #END rdb_classify1
6733
6734#-------------------
6735
6736sub rdb_classify2 {
6737 # Helper routine for rdb_classify_rules
6738 # Applied as rule_act2 in recursion over rules
6739 # Assumes rule context
6740 ($state) = @{ pop @classify_stack };
6741} #END rdb_classify2
6742
6743#************************************************************
6744
6745
6746sub rdb_run1 {
6747 # Assumes contexts for: rule.
6748 # Unconditionally apply the rule
6749 # Returns return code from applying the rule.
6750 # Otherwise: 0 on other kind of success,
6751 # -1 on error,
6752 # -2 when missing dest_file is to be ignored
6753
6754 # Source file data, by definition, correspond to the file state just
6755 # before the latest run, and the run_time to the time just before the run:
6756 &rdb_update_files;
6757 $$Prun_time = time();
6758 $$Pchanged = 0; # No special changes in files
6759 $$Plast_result = 0;
6760 $$Plast_message = '';
6761
6762 # Return values for external command:
6763 my $return = 0;
6764
6765 # Find any internal command
6766 my @int_args = @$PAint_cmd;
6767 my $int_cmd = shift @int_args;
6768 my @int_args_for_printing = @int_args;
6769 foreach (@int_args_for_printing) {
6770 if ( ! defined $_ ) { $_ = 'undef'; }
6771 }
6772 if ($int_cmd) {
6773 print "For rule '$rule', running '\&$int_cmd( @int_args_for_printing )' ...\n";
6774 $return = &$int_cmd( @int_args );
6775 }
6776 elsif ($$Pext_cmd) {
6777 $return = &Run_subst() / 256;
6778 }
6779 else {
6780 warn "$My_name: Either a bug OR a configuration error:\n",
6781 " No command provided for '$rule'\n";
6782 &traceback();
6783 $return = -1;
6784 $$Plast_result = 2;
6785 $$Plast_message = "Bug or configuration error; incorrect command type";
6786 }
6787 if ( $rule =~ /^biber/ ) {
6788 my @biber_source = ( );
6789 my $retcode = check_biber_log( $$Pbase, \@biber_source );
6790 foreach my $source ( @biber_source ) {
6791 print " ===Source file '$source' for '$rule'\n"
6792 if ($diagnostics);
6793 rdb_ensure_file( $rule, $source );
6794 }
6795 if ($retcode == 5) {
6796 # Special treatment if sole missing file is bib file
6797 # I don't want to treat that as an error
6798 $return = 0;
6799 $$Plast_result = 200;
6800 $$Plast_message = "Could not find bib file for '$$Pbase'";
6801 push @warnings, "Bib file not found for '$$Pbase'";
6802 }
6803 elsif ($retcode == 6) {
6804 # Missing control file. Need to remake it (if possible)
6805 # Don't treat missing bbl file as error.
6806 warn "$My_name: bibtex control file missing. Since that can\n",
6807 " be recreated, I'll try to do so.\n";
6808 $return = -2;
6809 rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
6810 }
6811 elsif ($retcode == 4) {
6812 $$Plast_result = 2;
6813 $$Plast_message = "Could not find all biber source files for '$$Pbase'";
6814 push @warnings, "Not all biber source files found for '$$Pbase'";
6815 }
6816 elsif ($retcode == 3) {
6817 $$Plast_result = 2;
6818 $$Plast_message = "Could not open biber log file for '$$Pbase'";
6819 push @warnings, $$Plast_message;
6820 }
6821 elsif ($retcode == 2) {
6822 $$Plast_message = "Biber errors: See file '$$Pbase.blg'";
6823 push @warnings, $$Plast_message;
6824 }
6825 elsif ($retcode == 1) {
6826 push @warnings, "Biber warnings for '$$Pbase'";
6827 }
6828 elsif ($retcode == 10) {
6829 push @warnings, "Biber found no citations for '$$Pbase'";
6830 # Biber doesn't generate a bbl file in this situation.
6831 $return = -2;
6832 }
6833 elsif ($retcode == 11) {
6834 push @warnings, "Biber: malformed bcf file for '$$Pbase'. IGNORE";
6835 if (!$silent) {
6836 warn "$My_name: biber found malformed bcf file for '$$Pbase'.\n",
6837 " I'll ignore error, and delete any bbl file.\n";
6838 }
6839 # Malformed bcf file is a downstream consequence, normally,
6840 # of an error in (pdf)latex run. So this is not an error
6841 # condition in biber itself.
6842 # Current version of biber deletes bbl file.
6843 # Older versions (pre-2016) made an incorrect bbl file, which
6844 # tended to cause latex errors, and give a self-perpetuating error.
6845 # To be safe, ensure the bbl file doesn't exist.
6846 unlink $$Pdest;
6847 # The missing bbl file is now not an error:
6848 $return = -2;
6849# ??????? BCF
6850# Following is intended to work, but creates infinite loop
6851# in malformed bcf file situation under -pvc.
6852# since on each check for change in ANY file, pvc finds changed file
6853# Need to restrict pvc reruns to case of changed USER files
6854# # To give good properties for (pdf)latex rule, it is best
6855# # to have a valid bbl file that exists:
6856# create_empty_file( $$Pdest );
6857# $return = 0;
6858
6859 }
6860 }
6861 if ( $rule =~ /^bibtex/ ) {
6862 my $retcode = check_bibtex_log($$Pbase);
6863 if ( ! -e $$Psource ) {
6864 $retcode = 10;
6865 rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
6866 }
6867 if ($retcode == 3) {
6868 $$Plast_result = 2;
6869 $$Plast_message = "Could not open bibtex log file for '$$Pbase'";
6870 push @warnings, $$Plast_message;
6871 }
6872 elsif ($retcode == 2) {
6873 $$Plast_message = "Bibtex errors: See file '$$Pbase.blg'";
6874 $failure = 1;
6875 push @warnings, $$Plast_message;
6876 }
6877 elsif ($retcode == 1) {
6878 push @warnings, "Bibtex warnings for '$$Pbase'";
6879 }
6880 elsif ($retcode == 10) {
6881 push @warnings, "Bibtex found no citations for '$$Pbase',\n",
6882 " or bibtex found a missing aux file\n";
6883 if (! -e $$Pdest ) {
6884 warn "$My_name: Bibtex did not produce '$$Pdest'. But that\n",
6885 " was because of missing files, so I will continue.\n";
6886 $return = -2;
6887 }
6888 else {
6889 $return = 0;
6890 }
6891 }
6892 }
6893
6894 $updated = 1;
6895 if ($$Ptest_kind == 3) {
6896 # We are time-criterion first time only. Now switch to
6897 # file-change criterion
6898 $$Ptest_kind = 1;
6899 }
6900 $$Pout_of_date = $$Pout_of_date_user = 0;
6901
6902 if ( ($$Plast_result == 0) && ($return != 0) && ($return != -2) ) {
6903 $$Plast_result = 2;
6904 if ($$Plast_message eq '') {
6905 $$Plast_message = "Command for '$rule' gave return code $return";
6906 if ($rule =~ /^(pdf|lua|xe|)latex/) {
6907 $$Plast_message .= "\n Refer to '$log_name' for details";
6908 }
6909 elsif ($rule =~ /^makeindex/) {
6910 $$Plast_message .= "\n Refer to '${aux_dir1}${root_filename}.ilg' for details";
6911 }
6912 }
6913 }
6914 elsif ( $$Pdest && (! -e $$Pdest) && ($return != -2) ) {
6915 $$Plast_result = 1;
6916 }
6917 return $return;
6918} # END rdb_run1
6919
6920#-----------------
6921
6922sub rdb_dummy_run1 {
6923 # Assumes contexts for: rule.
6924 # Update rule state as if the rule ran successfully,
6925 # but don't run the rule.
6926 # Returns 0 (success code)
6927
6928 # Source file data, by definition, correspond to the file state just before
6929 # the latest run, and the run_time to the time just before the run:
6930 &rdb_update_files;
6931 $$Prun_time = time();
6932 $$Pchanged = 0; # No special changes in files
6933 $$Plast_result = 0;
6934 $$Plast_message = '';
6935
6936 if ($$Ptest_kind == 3) {
6937 # We are time-criterion first time only. Now switch to
6938 # file-change criterion
6939 $$Ptest_kind = 1;
6940 }
6941 $$Pout_of_date = $$Pout_of_date_user = 0;
6942
6943 return 0;
6944} # END rdb_dummy_run1
6945
6946#-----------------
6947
6948sub Run_subst {
6949 # Call: Run_subst( cmd, msg, options, source, dest, base )
6950 # Runs command with substitutions.
6951 # If an argument is omitted or undefined, it is replaced by a default:
6952 # cmd is the command to execute
6953 # msg is whether to print a message:
6954 # 0 for not, 1 according to $silent setting, 2 always
6955 # options, source, dest, base: correspond to placeholders.
6956 # Substitutions:
6957 # %S=source, %D=dest, %B=base, %R=root=base for latex, %O=options,
6958 # %T=texfile, %Y=$aux_dir1, %Z=$out_dir1
6959 # This is a globally usable subroutine, and works in a rule context,
6960 # and outside.
6961 # Defaults:
6962 # cmd: $PPext_cmd if defined, else '';
6963 # msg: 1
6964 # options: ''
6965 # source: $$Psource if defined, else $texfile_name;
6966 # dest: $$Pdest if defined, else $view_file, else '';
6967 # base: $$Pbase if defined, else $root_filename;
6968
6969 my ($ext_cmd, $msg, $options, $source, $dest, $base ) = @_;
6970
6971 $ext_cmd ||= ( $Pext_cmd ? $$Pext_cmd : '' );
6972 $msg = ( defined $msg ? $msg : 1 );
6973 $options ||= '';
6974 $source ||= ( $Psource ? $$Psource : $texfile_name );
6975 $dest ||= ( $Pdest ? $$Pdest : ( $view_file || '' ) );
6976 $base ||= ( $Pbase ? $$Pbase : $root_filename );
6977
6978 if ( $ext_cmd eq '' ) {
6979 return 0;
6980 }
6981
6982 #Set character to surround filenames:
6983 my $q = $quote_filenames ? '"' : '';
6984
6985 my %subst = (
6986 '%O' => $options,
6987 '%R' => $q.$root_filename.$q,
6988 '%B' => $q.$base.$q,
6989 '%T' => $q.$texfile_name.$q,
6990 '%S' => $q.$source.$q,
6991 '%D' => $q.$dest.$q,
6992 '%Y' => $q.$aux_dir1.$q,
6993 '%Z' => $q.$out_dir1.$q,
6994 '%%' => '%' # To allow literal %B, %R, etc, by %%B.
6995 );
6996 if ( ($^O eq "MSWin32" ) && $MSWin_back_slash ) {
6997 foreach ( '%R', '%B', '%T', '%S', '%D', '%Y', '%Z' ) {
6998 $subst{$_} =~ s(/)(\\)g;
6999 }
7000 }
7001
7002 my @tokens = split /(%.)/, $ext_cmd;
7003 foreach (@tokens) {
7004 if (exists($subst{$_})) { $_ = $subst{$_}; }
7005 }
7006 $ext_cmd = join '', @tokens;
7007
7008 my ($pid, $return) =
7009 ( ($msg == 0) || ( ($msg == 1) && $silent ) )
7010 ? &Run($ext_cmd)
7011 : &Run_msg($ext_cmd);
7012 return $return;
7013} #END Run_subst
7014
7015#-----------------
7016
7017sub rdb_primary_run {
7018#?? See multipass_run in previous version Aug 2007 for issues
7019 # Call: rdb_primary_run
7020 # Assumes contexts for: recursion, make, & rule.
7021 # Assumes (a) the rule is a primary,
7022 # (b) a run has to be made,
7023 # (c) source files have been made.
7024 # This routine carries out the run of the rule unconditionally,
7025 # and then parses log file etc.
7026 my $return = 0;
7027
7028 if ( ! $filetime_offset_measured ) {
7029 $filetime_offset = get_filetime_offset( $aux_dir1."tmp" );
7030 if ( (abs($filetime_offset) > $filetime_offset_report_threshold)
7031 && ($diagnostics || ! $silent) )
7032 {
7033 warn "$My_name: I am working around an offset relative to my system time by\n",
7034 " $filetime_offset secs for file times in directory '$aux_dir1'.\n";
7035 }
7036 $filetime_offset_measured = 1;
7037 }
7038
7039 my $return_latex = &rdb_run1;
7040 if (-e $$Pdest) { $missing_dvi_pdf = '';}
7041
7042 ######### Analyze results of run:
7043 if ( ! -e $log_name ) {
7044 $failure = 1;
7045 $$Plast_result = 2;
7046 $$Plast_message = $failure_msg
7047 = "(Pdf)LaTeX failed to generate the expected log file '$log_name'";
7048 return -1;
7049 }
7050
7051 if ($recorder) {
7052 # Handle problem that some version of (pdf)latex give fls files
7053 # of name latex.fls or pdflatex.fls instead of $root_filename.fls.
7054 # Also that setting of -output-directory -aux-directory is not
7055 # respected by (pdf)latex, at least in some versions.
7056 my $std_fls_file = "$aux_dir1$root_filename.fls";
7057 my @other_fls_names = ( );
7058 if ( $rule =~ /^pdflatex/ ) {
7059 push @other_fls_names, "pdflatex.fls";
7060 }
7061 else {
7062 push @other_fls_names, "latex.fls";
7063 }
7064 if ( $aux_dir1 ne '' ) {
7065 push @other_fls_names, "$root_filename.fls";
7066 }
7067 # Find the first non-standard fls file and copy it to the standard
7068 # place. But only do this if the file time is compatible with being
7069 # generated in the current run, as tested by the use of
7070 # test_gen_file; that avoids problems with fls files leftover from
7071 # earlier runs with other versions of latex.
7072 foreach my $cand (@other_fls_names) {
7073 if ( test_gen_file( $cand ) ) {
7074 copy $cand, $std_fls_file;
7075 last;
7076 }
7077 }
7078 if ( ! test_gen_file( $std_fls_file ) ) {
7079 warn "$My_name: fls file doesn't appear to have been made\n";
7080 }
7081 }
7082
7083 # Find current set of source files:
7084 &rdb_set_latex_deps;
7085
7086 # For each file of the kind made by epstopdf.sty during a run,
7087 # if the file has changed during a run, then the new version of
7088 # the file will have been read during the run. Unlike the usual
7089 # case, we will NOT need to redo the primary run because of the
7090 # change of this file during the run. Therefore set the file as
7091 # up-to-date:
7092 rdb_do_files( sub { if ($$Pcorrect_after_primary) {&rdb_update1;} } );
7093
7094#?? # There may be new source files, and the run may have caused
7095#?? # circular-dependency files to be changed. And the regular
7096#?? # source files may have been updated during a lengthy run of
7097#?? # latex. So redo the makes for sources of the current rule:
7098#?? my $submake_return = &rdb_submake;
7099#?? &rdb_clear_change_record;
7100#?? &rdb_flag_changes_here(0);
7101#?? if ($$Pout_of_date && !$silent) {
7102#?? &rdb_diagnose_changes( "Rule '$rule': " );
7103#?? }
7104
7105 $updated = 1; # Flag that some dependent file has been remade
7106
7107#?? # Fix the state of the files as of now: this will solve the
7108#?? # problem of latex and pdflatex interfering with each other,
7109#?? # at the expense of some non-optimality
7110#?? #?? Check this is correct:
7111#?? &rdb_update_files;
7112
7113 if ( $diagnostics ) {
7114 print "$My_name: Rules after run: \n";
7115 rdb_show();
7116 }
7117
7118 $return = $return_latex;
7119
7120# ???? Is the following needed?
7121 if ($return_latex && $$Pout_of_date_user) {
7122 print "Error in (pdf)LaTeX, but change of user file(s), ",
7123 "so ignore error & provoke rerun\n"
7124 if (! $silent);
7125 $return = 0;
7126 }
7127 # Summarize issues that may have escaped notice:
7128 my @warnings = ();
7129 if ($bad_reference) {
7130 push @warnings, "Latex failed to resolve $bad_reference reference(s)";
7131 }
7132 if ($mult_defined) {
7133 push @warnings, "Latex found $mult_defined multiply defined reference(s)";
7134 }
7135 if ($bad_citation) {
7136 push @warnings, "Latex failed to resolve $bad_citation citation(s)";
7137 }
7138 if ($#warnings > -1) {
7139 show_array( "$My_name: Summary of warnings:", @warnings );
7140 }
7141 return $return;
7142} #END rdb_primary_run
7143
7144#************************************************************
7145
7146sub rdb_clear_change_record {
7147 # Initialize diagnostics for reasons for running rule.
7148 @changed = ();
7149 @disappeared = ();
7150 @no_dest = (); # We are not now using this
7151 @rules_never_run = ();
7152 @rules_to_apply = (); # This is used in recursive application
7153 # of rdb_flag_changes_here, to list
7154 # rules that were out-of-date for some reason.
7155} #END rdb_clear_change_record
7156
7157#************************************************************
7158
7159sub rdb_flag_changes_here {
7160 # Flag changes in current rule.
7161 # Assumes rule context.
7162 # Usage: rdb_flag_changes_here( ignore_run_time )
7163 # Argument: if true then fdb_get shouldn't do runtime test
7164 # for recalculation of md5
7165
7166 local $ignore_run_time = $_[0];
7167 if ( ! defined $ignore_run_time ) { $ignore_run_time = 0; }
7168
7169 $$Pcheck_time = time();
7170
7171 local $dest_mtime = 0;
7172 $dest_mtime = get_mtime($$Pdest) if ($$Pdest);
7173 rdb_do_files( \&rdb_file_change1);
7174 if ($$Pout_of_date) {
7175 push @rules_to_apply, $rule;
7176 }
7177#?? print "======== flag: $rule $$Pout_of_date ==========\n";
7178} #END rdb_flag_changes_here
7179
7180#************************************************************
7181
7182sub rdb_file_change1 {
7183 # Call: &rdb_file_change1
7184 # Assumes rule and file context. Assumes $dest_mtime set.
7185 # Flag whether $file in $rule has changed or disappeared.
7186 # Set rule's make flag if there's a change.
7187
7188 my $check_time_argument = 0;
7189 if (! $ignore_run_time ) {
7190 $check_time_argument = max( $$Pcheck_time, $$Prun_time );
7191 }
7192 my ($new_time, $new_size, $new_md5) = fdb_get($file, $check_time_argument );
7193 my $ext_no_period = ext_no_period( $file );
7194 if ( ($new_size < 0) && ($$Psize >= 0) ) {
7195 # print "Disappeared '$file' in '$rule'\n";
7196 push @disappeared, $file;
7197 # No reaction is good.
7198 #$$Pout_of_date = 1;
7199 # ??? 1 Sep. 2008: I do NOT think so, for cusdep no-file-exists issue
7200 # ??? 30 Sep 2008: I think I have this fixed. There were other changes
7201 # needed. No-change-flagged is correct. The array @disappeared flags
7202 # files that have disappeared, if I need to know. But having a source
7203 # file disappear is not a reason for a remake unless I know how to
7204 # make the file. If the file is a destination of a rule, that rule
7205 # will be rerun. It may be that the user is changing another source
7206 # in such a way that the disappeared file won't be needed. Before the
7207 # change is applied we get a superfluous infinite loop.
7208 return;
7209 }
7210 if ( ($new_size < 0) && ($$Psize < 0) ) {
7211 return;
7212 }
7213 # Primarily use md5 signature to determine whether file contents have
7214 # changed.
7215 # Backup by file size change, but only in the case where there is
7216 # no pattern of lines to ignore in testing for a change
7217 if ( ($new_md5 ne $$Pmd5)
7218 || (
7219 (! exists $hash_calc_ignore_pattern{$ext_no_period})
7220 && ($new_size != $$Psize)
7221 )
7222 ) {
7223#print "========= CHANGED: '$file' from '$$Pfrom_rule'\n";
7224 push @changed, $file;
7225 $$Pout_of_date = 1;
7226 if ( ! exists $generated_exts_all{$ext_no_period} ) {
7227 $$Pout_of_date_user = 1;
7228 }
7229 }
7230 elsif ( $new_time != $$Ptime ) {
7231 $$Ptime = $new_time;
7232 }
7233 if ( ( ($$Ptest_kind == 2) || ($$Ptest_kind == 3) )
7234 && (! exists $generated_exts_all{$ext_no_period} )
7235 && ( $new_time > $dest_mtime )
7236 ) {
7237 push @changed, $file;
7238 $$Pout_of_date = $$Pout_of_date_user = 1;
7239 }
7240} #END rdb_file_change1
7241
7242#************************************************************
7243
7244sub rdb_new_changes {
7245 &rdb_clear_change_record;
7246 rdb_recurse( [@_], sub{ &rdb_flag_changes_here(1); } );
7247 return ($#changed >= 0) || ($#no_dest >= 0) || ($#rules_to_apply >= 0);
7248} #END rdb_new_changes
7249
7250#************************************************************
7251
7252sub rdb_diagnose_changes {
7253 # Call: rdb_diagnose_changes or rdb_diagnose_changes( heading )
7254 # List changes on STDERR
7255 # Precede the message by the optional heading, else by "$My_name: "
7256 my $heading = defined($_[0]) ? $_[0] : "$My_name: ";
7257
7258 if ($#rules_never_run >= 0) {
7259 warn "${heading}Rules & subrules not known to be previously run:\n";
7260 foreach (@rules_never_run) { warn " $_\n"; }
7261 }
7262 if ( ($#changed >= 0) || ($#disappeared >= 0) || ($#no_dest >= 0) ) {
7263 warn "${heading}File changes, etc:\n";
7264 if ( $#changed >= 0 ) {
7265 warn " Changed files, or newly in use since previous run(s):\n";
7266 foreach (uniqs(@changed)) { warn " '$_'\n"; }
7267 }
7268 if ( $#disappeared >= 0 ) {
7269 warn " No-longer-existing files:\n";
7270 foreach (uniqs(@disappeared)) { warn " '$_'\n"; }
7271 }
7272 if ( $#no_dest >= 0 ) {
7273 warn " Non-existent destination files:\n";
7274 foreach (uniqs(@no_dest)) { warn " '$_'\n"; }
7275 }
7276 }
7277 elsif ($#rules_to_apply >=0) {
7278 warn "${heading}The following rules & subrules became out-of-date:\n";
7279 foreach (@rules_to_apply) { warn " '$_'\n"; }
7280 }
7281 else {
7282 warn "${heading}No file changes\n";
7283 }
7284} #END rdb_diagnose_changes
7285
7286
7287#************************************************************
7288#************************************************************
7289#************************************************************
7290#************************************************************
7291
7292#************************************************************
7293#************************************************************
7294#************************************************************
7295#************************************************************
7296
7297# Routines for convenient looping and recursion through rule database
7298# ================= NEW VERSION ================
7299
7300# There are several places where we need to loop through or recurse
7301# through rules and files. This tends to involve repeated, tedious
7302# and error-prone coding of much book-keeping detail. In particular,
7303# working on files and rules needs access to the variables involved,
7304# which either involves direct access to the elements of the database,
7305# and consequent fragility against changes and upgrades in the
7306# database structure, or involves lots of routines for reading and
7307# writing data in the database, then with lots of repetitious
7308# house-keeping code.
7309#
7310# The routines below provide a solution. Looping and recursion
7311# through the database are provided by a set of basic routines where
7312# each necessary kind of looping and iteration is coded once. The
7313# actual actions are provided as references to action subroutines.
7314# (These can be either actual references, as in \&routine, or
7315# anonymous subroutines, as in sub{...}, or aas a zero value 0 or an
7316# omitted argument, to indicate that no action is to be performed.)
7317#
7318# When the action subroutine(s) are actually called, a context for the
7319# rule and/or file (as appropriate) is given by setting named
7320## NEW ??
7321# variables to REFERENCES to the relevant data values. These can be
7322# used to retrieve and set the data values. As a convention,
7323# references to scalars are given by variables named start with "$P",
7324# as in "$Pdest", while references to arrays start with "$PA", as in
7325# "$PAint_cmd", and references to hashes with "$PH", as in "$PHsource".
7326# After the action subroutine has finished, checks for data
7327# consistency may be made.
7328## ??? OLD
7329# variables to the relevant data values. After the action subroutine
7330# has finished, the database is updated with the values of these named
7331# variables, with any necessary consistency checks. Thus the action
7332# subroutines can act on sensibly named variables without needed to
7333# know the database structure.
7334#
7335# The only routines that actually use the database structure and need
7336# to be changed if that is changed are: (a) the routines rdb_one_rule
7337# and rdb_one_file that implement the calling of the action subroutines,
7338# (b) routines for creation of single rules and file items, and (c) to
7339# a lesser extent, the routine for destroying a file item.
7340#
7341# Note that no routine is provided for destroying a rule. During a
7342# run, a rule, with its source files, may become inaccessible or
7343# unused. This happens dynamically, depending on the dependencies
7344# caused by changes in the source file or by error conditions that
7345# cause the computation of dependencies, particular of latex files, to
7346# become wrong. In that situation the files certainly come and go in
7347# the database, but subsidiary rules, with their content information
7348# on their source files, need to be retained so that their use can be
7349# reinstated later depending on dynamic changes in other files.
7350#
7351# However, there is a potential memory leak unless some pruning is
7352# done in what is written to the fdb file. (Probably only accessible
7353# rules and those for which source files exist. Other cases have no
7354# relevant information that needs to be preserved between runs.)
7355
7356#
7357#
7358
7359
7360#************************************************************
7361
7362# First the top level routines for recursion and iteration
7363
7364#************************************************************
7365
7366sub rdb_recurse {
7367 # Call: rdb_recurse( rule | [ rules],
7368 # \&rule_act1, \&file_act1, \&file_act2,
7369 # \&rule_act2 )
7370 # The actions are pointers to subroutines, and may be null (0, or
7371 # undefined) to indicate no action to be applied.
7372 # Recursively acts on the given rules and all ancestors:
7373 # foreach rule found:
7374 # apply rule_act1
7375 # loop through its files:
7376 # apply file_act1
7377 # act on its ancestor rule, if any
7378 # apply file_act2
7379 # apply rule_act2
7380 # Guards against loops.
7381 # Access to the rule and file data by local variables, only
7382 # for getting and setting.
7383
7384 # This routine sets a context for anything recursive, with @heads,
7385 # %visited and $depth being set as local variables.
7386
7387 local @heads = ();
7388 my $rules = shift;
7389
7390 # Distinguish between single rule (a string) and a reference to an
7391 # array of rules:
7392 if ( ref $rules eq 'ARRAY' ) { @heads = @$rules; }
7393 else { @heads = ( $rules ); }
7394
7395 # Keep a list of visited rules, used to block loops in recursion:
7396 local %visited = ();
7397 local $depth = 0;
7398
7399 foreach $rule ( @heads ) { rdb_recurse_rule( $rule, @_ ); }
7400
7401} #END rdb_recurse
7402
7403#************************************************************
7404
7405sub rdb_for_all {
7406 # Call: rdb_for_all( \&rule_act1, \&file_act, \&rule_act2 )
7407 # Loops through all rules and their source files, using the
7408 # specified set of actions, which are pointers to subroutines.
7409 # Sorts rules alphabetically.
7410 # See rdb_for_some for details.
7411 rdb_for_some( [ sort keys %rule_db ], @_);
7412} #END rdb_for_all
7413
7414#************************************************************
7415
7416sub rdb_for_some {
7417 # Call: rdb_for_some( rule | [ rules],
7418 # \&rule_act1, \&file_act, \&rule_act2)
7419 # Actions can be zero, and rules at tail of argument list can be
7420 # omitted. E.g. rdb_for_some( rule, 0, \&file_act ).
7421 # Anonymous subroutines can be used, e.g., rdb_for_some( rule, sub{...} ).
7422 #
7423 # Loops through rules and their source files, using the
7424 # specified set of rules:
7425 # foreach rule:
7426 # apply rule_act1
7427 # loop through its files:
7428 # apply file_act
7429 # apply rule_act2
7430 #
7431 # Rule data and file data are made available in local variables
7432 # for access by the subroutines.
7433
7434 local @heads = ();
7435 my $rules = shift;
7436 # Distinguish between single rule (a string) and a reference to an
7437 # array of rules:
7438 if ( ref $rules eq 'ARRAY' ) { @heads = @$rules; }
7439 else { @heads = ( $rules ); }
7440
7441 foreach $rule ( @heads ) {
7442 # $rule is implicitly local
7443 &rdb_one_rule( $rule, @_ );
7444 }
7445} #END rdb_for_some
7446
7447#************************************************************
7448
7449sub rdb_for_one_file {
7450 my $rule = shift;
7451 # Avoid name collisions with general recursion and iteraction routines:
7452 local $file1 = shift;
7453 local $action1 = shift;
7454 rdb_for_some( $rule, sub{rdb_one_file($file1,$action1)} );
7455} #END rdb_for_one_file
7456
7457
7458#************************************************************
7459
7460# Routines for inner part of recursion and iterations
7461
7462#************************************************************
7463
7464sub rdb_recurse_rule {
7465 # Call: rdb_recurse_rule($rule, \&rule_act1, \&file_act1, \&file_act2,
7466 # \&rule_act2 )
7467 # to do the work for one rule, recurisvely called from_rules for
7468 # the sources of the rules.
7469 # Assumes recursion context, i.e. that %visited, @heads, $depth.
7470 # We are overriding actions:
7471 my ($rule, $rule_act1, $new_file_act1, $new_file_act2, $rule_act2)
7472 = @_;
7473 # and must propagate the file actions:
7474 local $file_act1 = $new_file_act1;
7475 local $file_act2 = $new_file_act2;
7476 # Prevent loops:
7477 if ( (! $rule) || exists $visited{$rule} ) { return; }
7478 $visited{$rule} = 1;
7479 # Recursion depth
7480 $depth++;
7481 # We may need to repeat actions on dependent rules, without being
7482 # blocked by the test on visited files. So save %visited:
7483 # NOT CURRENTLY USED!! local %visited_at_rule_start = %visited;
7484 # At end, the last value set for %visited wins.
7485 rdb_one_rule( $rule, $rule_act1, \&rdb_recurse_file, $rule_act2 );
7486 $depth--;
7487 } #END rdb_recurse_rule
7488
7489#************************************************************
7490
7491sub rdb_recurse_file {
7492 # Call: rdb_recurse_file to do the work for one file.
7493 # This has no arguments, since it is used as an action subroutine,
7494 # passed as a reference in calls in higher-level subroutine.
7495 # Assumes contexts set for: Recursion, rule, and file
7496 &$file_act1 if $file_act1;
7497 rdb_recurse_rule( $$Pfrom_rule, $rule_act1, $file_act1, $file_act2,
7498 $rule_act2 )
7499 if $$Pfrom_rule;
7500 &$file_act2 if $file_act2;
7501} #END rdb_recurse_file
7502
7503#************************************************************
7504
7505sub rdb_do_files {
7506 # Assumes rule context, including $PHsource.
7507 # Applies an action to all the source files of the rule.
7508 local $file_act = shift;
7509 my @file_list = sort keys %$PHsource;
7510 foreach my $file ( @file_list ){
7511 rdb_one_file( $file, $file_act );
7512 }
7513} #END rdb_do_files
7514
7515#************************************************************
7516
7517# Routines for action on one rule and one file. These are the main
7518# places (in addition to creation and destruction routines for rules
7519# and files) where the database structure is accessed.
7520
7521#************************************************************
7522
7523sub rdb_one_rule {
7524 # Call: rdb_one_rule( $rule, $rule_act1, $file_act, $rule_act2 )
7525 # Sets context for rule and carries out the actions.
7526#===== Accesses rule part of database structure =======
7527
7528 local ( $rule, $rule_act1, $file_act, $rule_act2 ) = @_;
7529#?? &R1;
7530 if ( (! $rule) || ! rdb_rule_exists($rule) ) { return; }
7531
7532 local ( $PArule_data, $PHsource, $PHdest ) = @{$rule_db{$rule}};
7533 local ($Pcmd_type, $Pext_cmd, $PAint_cmd, $Ptest_kind,
7534 $Psource, $Pdest, $Pbase,
7535 $Pout_of_date, $Pout_of_date_user, $Prun_time, $Pcheck_time,
7536 $Pchanged,
7537 $Plast_result, $Plast_message, $PA_extra_generated )
7538 = Parray( $PArule_data );
7539
7540 &$rule_act1 if $rule_act1;
7541 &rdb_do_files( $file_act ) if $file_act;
7542 &$rule_act2 if $rule_act2;
7543#?? &R2;
7544} #END rdb_one_rule
7545
7546#************************************************************
7547
7548sub rdb_one_file {
7549 # Call: rdb_one_file($file, $file_act)
7550 # Sets context for file and carries out the action.
7551 # Assumes $rule context set.
7552#===== Accesses file part of database structure =======
7553 local ($file, $file_act) = @_;
7554#?? &F1;
7555 if ( (!$file) ||(!exists ${$PHsource}{$file}) ) { return; }
7556 local $PAfile_data = ${$PHsource}{$file};
7557 local ($Ptime, $Psize, $Pmd5, $Pfrom_rule, $Pcorrect_after_primary )
7558 = Parray( $PAfile_data );
7559 &$file_act() if $file_act;
7560 if ( ! rdb_rule_exists( $$Pfrom_rule ) ) {
7561 $$Pfrom_rule = '';
7562 }
7563#?? &F2;
7564} #END rdb_one_file
7565
7566#************************************************************
7567
7568# Routines for creation of rules and file items, and for removing file
7569# items.
7570
7571#************************************************************
7572
7573sub rdb_remove_rule {
7574 # rdb_remove_rule( rule, ... )
7575 foreach my $key (@_) {
7576 delete $rule_db{$key};
7577 }
7578}
7579
7580#************************************************************
7581
7582sub rdb_create_rule {
7583 # rdb_create_rule( rule, command_type, ext_cmd, int_cmd, test_kind,
7584 # source, dest, base,
7585 # needs_making, run_time, check_time, set_file_not_exists,
7586 # ref_to_array_of_specs_of_extra_generated_files )
7587 # int_cmd is either a string naming a perl subroutine or it is a
7588 # reference to an array containing the subroutine name and its
7589 # arguments.
7590 # Makes rule. Error if it already exists.
7591 # Omitted arguments: replaced by 0 or '' as needed.
7592# ==== Sets rule data ====
7593 my ( $rule, $cmd_type, $ext_cmd, $PAint_cmd, $test_kind,
7594 $source, $dest, $base,
7595 $needs_making, $run_time, $check_time, $set_file_not_exists, $extra_gen ) = @_;
7596 my $changed = 0;
7597
7598 # Set defaults, and normalize parameters:
7599 foreach ( $cmd_type, $ext_cmd, $PAint_cmd, $source, $dest, $base,
7600 $set_file_not_exists ) {
7601 if (! defined $_) { $_ = ''; }
7602 }
7603 foreach ( $needs_making, $run_time, $check_time, $test_kind ) {
7604 if (! defined $_) { $_ = 0; }
7605 }
7606 if (!defined $test_kind) {
7607 # Default to test on file change
7608 $test_kind = 1;
7609 }
7610 if ( ref( $PAint_cmd ) eq '' ) {
7611 # It is a single command. Convert to array reference:
7612 $PAint_cmd = [ $PAint_cmd ];
7613 }
7614 else {
7615 # COPY the referenced array:
7616 $PAint_cmd = [ @$PAint_cmd ];
7617 }
7618 my $PA_extra_gen = [];
7619 if ($extra_gen) {
7620 @$PA_extra_gen = @$extra_gen;
7621 }
7622 $rule_db{$rule} =
7623 [ [$cmd_type, $ext_cmd, $PAint_cmd, $test_kind,
7624 $source, $dest, $base,
7625 $needs_making, 0, $run_time, $check_time, $changed,
7626 -1, '', $PA_extra_gen ],
7627 {},
7628 {}
7629 ];
7630 if ($source) {
7631 rdb_ensure_file( $rule, $source, undef, $set_file_not_exists );
7632 }
7633 rdb_one_rule( $rule, \&rdb_initialize_generated );
7634} #END rdb_create_rule
7635
7636#************************************************************
7637
7638sub rdb_initialize_generated {
7639# Assume rule context.
7640# Initialize hash of generated files
7641 %$PHdest = ();
7642 if ($$Pdest) { rdb_add_generated($$Pdest); }
7643 foreach (@$PA_extra_generated) {
7644 rdb_add_generated($_);
7645 }
7646} #END rdb_initialize_generated
7647
7648#************************************************************
7649
7650sub rdb_add_generated {
7651# Assume rule context.
7652# Add arguments to hash of generated files
7653 foreach (@_) {
7654 $$PHdest{$_} = 1;
7655 }
7656} #END rdb_add_generated
7657
7658#************************************************************
7659
7660sub rdb_ensure_file {
7661 # rdb_ensure_file( rule, file[, fromrule[, set_not_exists]] )
7662 # Ensures the source file item exists in the given rule.
7663 # Then if the fromrule is specified, set it for the file item.
7664 # If the item is created, then:
7665 # (a) by default initialize it to current file state.
7666 # (b) but if the fourth argument, set_not_exists, is true,
7667 # initialize the item as if the file does not exist.
7668 # This case is typically used when the log file for a run
7669 # of latex/pdflatex claims that the file was non-existent
7670 # at the beginning of a run.
7671#============ rule and file data set here ======================================
7672 my $rule = shift;
7673 local ( $new_file, $new_from_rule, $set_not_exists ) = @_;
7674 if ( ! rdb_rule_exists( $rule ) ) {
7675 die_trace( "$My_name: BUG in rdb_ensure_file: non-existent rule '$rule'" );
7676 }
7677 if ( ! defined $new_file ) {
7678 die_trace( "$My_name: BUG in rdb_ensure_file: undefined file for '$rule'" );
7679 }
7680 if ( ! defined $set_not_exists ) { $set_not_exists = 0; }
7681 rdb_one_rule( $rule,
7682 sub{
7683 if (! exists ${$PHsource}{$new_file} ) {
7684 if ( $set_not_exists ) {
7685 ${$PHsource}{$new_file} = [0, -1, 0, '', 0];
7686 }
7687 else {
7688 ${$PHsource}{$new_file}
7689 = [fdb_get($new_file, $$Prun_time), '', 0];
7690 }
7691 }
7692 }
7693 );
7694 if (defined $new_from_rule ) {
7695 rdb_for_one_file( $rule, $new_file, sub{ $$Pfrom_rule = $new_from_rule; });
7696 }
7697} #END rdb_ensure_file
7698
7699#************************************************************
7700
7701sub rdb_remove_files {
7702 # rdb_remove_file( rule, file, ... )
7703 # Removes file(s) for the rule.
7704 my $rule = shift;
7705 if (!$rule) { return; }
7706 local @files = @_;
7707 rdb_one_rule( $rule,
7708 sub{ foreach (@files) { delete ${$PHsource}{$_}; } }
7709 );
7710} #END rdb_remove_files
7711
7712#************************************************************
7713
7714sub rdb_list_source {
7715 # rdb_list_source( rule )
7716 # Return array of source files for rule.
7717 my $rule = shift;
7718 my @files = ();
7719 rdb_one_rule( $rule,
7720 sub{ @files = keys %$PHsource; }
7721 );
7722 return @files;
7723} #END rdb_list_source
7724
7725#************************************************************
7726
7727sub rdb_set_source {
7728 # rdb_set_source( rule, file, ... )
7729 my $rule = shift;
7730 if (!$rule) { return; }
7731 my %files = ();
7732 foreach (@_) {
7733 rdb_ensure_file( $rule, $_ );
7734 $files{$_} = 1;
7735 }
7736 foreach ( rdb_list_source($rule) ) {
7737 if ( ! exists $files{$_} ) { rdb_remove_files( $rule, $_ ); }
7738 }
7739 return;
7740} #END rdb_list_source
7741
7742#************************************************************
7743
7744sub rdb_rule_exists {
7745 # Call rdb_rule_exists($rule): Returns whether rule exists.
7746 my $rule = shift;
7747 if (! $rule ) { return 0; }
7748 return exists $rule_db{$rule};
7749} #END rdb_rule_exists
7750
7751#************************************************************
7752
7753sub rdb_file_exists {
7754 # Call rdb_file_exists($rule, $file):
7755 # Returns whether source file item in rule exists.
7756 local ( $rule, $file ) = @_;
7757 local $exists = 0;
7758 rdb_one_rule( $rule,
7759 sub{ $exists = exists( ${$PHsource}{$file} ) ? 1:0; }
7760 );
7761 return $exists;
7762} #END rdb_file_exists
7763
7764#************************************************************
7765
7766sub rdb_update_gen_files {
7767 # Assumes rule context. Update source files of rule to current state.
7768 rdb_do_files(
7769 sub{
7770 if ( exists $generated_exts_all{ ext_no_period($file) } ) {&rdb_update1;}
7771 }
7772 );
7773} #END rdb_update_gen_files
7774
7775#************************************************************
7776
7777sub rdb_update_files {
7778 # Call: rdb_update_files
7779 # Assumes rule context. Update source files of rule to current state.
7780 rdb_do_files( \&rdb_update1 );
7781}
7782
7783#************************************************************
7784
7785sub rdb_update1 {
7786 # Call: rdb_update1.
7787 # Assumes file context. Updates file data to correspond to
7788 # current file state on disk
7789 ($$Ptime, $$Psize, $$Pmd5) = fdb_get($file);
7790}
7791
7792#************************************************************
7793
7794sub rdb_set_file1 {
7795 # Call: fdb_file1(rule, file, new_time, new_size, new_md5)
7796 # Sets file time, size and md5.
7797 my $rule = shift;
7798 my $file = shift;
7799 local @new_file_data = @_;
7800 rdb_for_one_file( $rule, $file, sub{ ($$Ptime,$$Psize,$$Pmd5)=@new_file_data; } );
7801}
7802
7803#************************************************************
7804
7805sub rdb_dummy_file {
7806 # Returns file data for non-existent file
7807# ==== Uses rule_db structure ====
7808 return (0, -1, 0, '');
7809}
7810
7811#************************************************************
7812#************************************************************
7813
7814# Predefined subroutines for custom dependency
7815
7816sub cus_dep_delete_dest {
7817 # This subroutine is used for situations like epstopdf.sty, when
7818 # the destination (target) of the custom dependency invoking
7819 # this subroutine will be made by the primary run provided the
7820 # file (destination of the custom dependency, source of the
7821 # primary run) doesn't exist.
7822 # It is assumed that the resulting file will be read by the
7823 # primary run.
7824
7825 # Remove the destination file, to indicate it needs to be remade:
7826 unlink_or_move( $$Pdest );
7827 # Arrange that the non-existent destination file is not treated as
7828 # an error. The variable changed here is a bit misnamed.
7829 $$Pchanged = 1;
7830 # Ensure a primary run is done
7831 &cus_dep_require_primary_run;
7832 # Return success:
7833 return 0;
7834}
7835
7836#************************************************************
7837
7838sub cus_dep_require_primary_run {
7839 # This subroutine is used for situations like epstopdf.sty, when
7840 # the destination (target) of the custom dependency invoking
7841 # this subroutine will be made by the primary run provided the
7842 # file (destination of the custom dependency, source of the
7843 # primary run) doesn't exist.
7844 # It is assumed that the resulting file will be read by the
7845 # primary run.
7846
7847 local $cus_dep_target = $$Pdest;
7848 # Loop over all rules and source files:
7849 rdb_for_all( 0,
7850 sub { if ($file eq $cus_dep_target) {
7851 $$Pout_of_date = 1;
7852 $$Pcorrect_after_primary = 1;
7853 }
7854 }
7855 );
7856 # Return success:
7857 return 0;
7858}
7859
7860
7861#************************************************************
7862#************************************************************
7863#************************************************************
7864#
7865# UTILITIES:
7866#
7867
7868#************************************************************
7869# Miscellaneous
7870
7871sub show_array {
7872# For use in diagnostics and debugging.
7873# On stderr, print line with $_[0] = label.
7874# Then print rest of @_, one item per line preceeded by some space
7875 warn "$_[0]\n";
7876 shift;
7877 if ($#_ >= 0) { foreach (@_){ warn " $_\n";} }
7878 else { warn " NONE\n"; }
7879}
7880
7881#************************************************************
7882
7883sub Parray {
7884 # Call: Parray( \@A )
7885 # Returns array of references to the elements of @A
7886 # But if an element of @A is already a reference, the
7887 # reference will be returned in the output array, not a
7888 # reference to the reference.
7889 my $PA = shift;
7890 my @P = (undef) x (1+$#$PA);
7891 foreach my $i (0..$#$PA) {
7892 $P[$i] = (ref $$PA[$i]) ? ($$PA[$i]) : (\$$PA[$i]);
7893 }
7894 return @P;
7895}
7896
7897#************************************************************
7898
7899sub glob_list1 {
7900 # Glob a collection of filenames.
7901 # But no sorting or elimination of duplicates
7902 # Usage: e.g., @globbed = glob_list1(string, ...);
7903 # Since perl's glob appears to use space as separator, I'll do a special check
7904 # for existence of non-globbed file (assumed to be tex like)
7905
7906 my @globbed = ();
7907 foreach my $file_spec (@_) {
7908 # Problem, when the PATTERN contains spaces, the space(s) are
7909 # treated as pattern separaters.
7910 # Solution: I now the glob from use File::Glob.
7911 # The following hack avoids issues with glob in the case that a file exists
7912 # with the specified name (possibly with extension .tex):
7913 if ( -e $file_spec || -e "$file_spec.tex" ) {
7914 # Non-globbed file exists, return the file_spec.
7915 # Return $file_spec only because this is not a file-finding subroutine, but
7916 # only a globber
7917 push @globbed, $file_spec;
7918 }
7919 else {
7920 push @globbed, my_glob( "$file_spec" );
7921 }
7922 }
7923 return @globbed;
7924} #END glob_list1
7925
7926#************************************************************
7927# Miscellaneous
7928
7929sub prefix {
7930 #Usage: prefix( string, prefix );
7931 #Return string with prefix inserted at the front of each line
7932 my @line = split( /\n/, $_[0] );
7933 my $prefix = $_[1];
7934 for (my $i = 0; $i <= $#line; $i++ ) {
7935 $line[$i] = $prefix.$line[$i]."\n";
7936 }
7937 return join( "", @line );
7938} #END prefix
7939
7940
7941#===============================
7942
7943sub parse_quotes {
7944 # Split string into words.
7945 # Words are delimited by space, except that strings
7946 # quoted all stay inside a word. E.g.,
7947 # 'asdf B" df "d "jkl"'
7948 # is split to ( 'asdf', 'B df d', 'jkl').
7949 # An array is returned.
7950 my @results = ();
7951 my $item = '';
7952 local $_ = shift;
7953 pos($_) = 0;
7954 ITEM:
7955 while() {
7956 /\G\s*/gc;
7957 if ( /\G$/ ) {
7958 last ITEM;
7959 }
7960 # Now pos (and \G) is at start of item:
7961 PART:
7962 while () {
7963 if (/\G([^\s\"]*)/gc) {
7964 $item .= $1;
7965 }
7966 if ( /\G\"([^\"]*)\"/gc ) {
7967 # Match balanced quotes
7968 $item .= $1;
7969 next PART;
7970 }
7971 elsif ( /\G\"(.*)$/gc ) {
7972 # Match unbalanced quote
7973 $item .= $1;
7974 warn "====Non-matching quotes in\n '$_'\n";
7975 }
7976 push @results, $item;
7977 $item = '';
7978 last PART;
7979 }
7980 }
7981 return @results;
7982} #END parse_quotes
7983
7984#************************************************************
7985#************************************************************
7986# File handling utilities:
7987
7988
7989#************************************************************
7990
7991sub get_latest_mtime
7992# - arguments: each is a filename.
7993# - returns most recent modify time.
7994{
7995 my $return_mtime = 0;
7996 foreach my $include (@_)
7997 {
7998 my $include_mtime = &get_mtime($include);
7999 # The file $include may not exist. If so ignore it, otherwise
8000 # we'll get an undefined variable warning.
8001 if ( ($include_mtime) && ($include_mtime > $return_mtime) )
8002 {
8003 $return_mtime = $include_mtime;
8004 }
8005 }
8006 return $return_mtime;
8007}
8008
8009#************************************************************
8010
8011sub get_mtime_raw
8012{
8013 my $mtime = (stat($_[0]))[9];
8014 return $mtime;
8015}
8016
8017#************************************************************
8018
8019sub get_mtime {
8020 return get_mtime0($_[0]);
8021}
8022
8023#************************************************************
8024
8025sub get_mtime0 {
8026 # Return time of file named in argument
8027 # If file does not exist, return 0;
8028 if ( -e $_[0] ) {
8029 return get_mtime_raw($_[0]);
8030 }
8031 else {
8032 return 0;
8033 }
8034}
8035
8036#************************************************************
8037
8038sub get_size {
8039 # Return time of file named in argument
8040 # If file does not exist, return 0;
8041 if ( -e $_[0] ) {
8042 return get_size_raw($_[0]);
8043 }
8044 else {
8045 return 0;
8046 }
8047}
8048
8049#************************************************************
8050
8051sub get_size_raw
8052{
8053 my $size = (stat($_[0]))[7];
8054 return $size;
8055}
8056
8057#************************************************************
8058
8059sub get_time_size {
8060 # Return time and size of file named in argument
8061 # If file does not exist, return (0,-1);
8062 if ( -e $_[0] ) {
8063 return get_time_size_raw($_[0]);
8064 }
8065 else {
8066 return (0,-1);
8067 }
8068}
8069
8070#************************************************************
8071
8072sub get_time_size_raw
8073{
8074 my $mtime = (stat($_[0]))[9];
8075 my $size = (stat($_[0]))[7];
8076 return ($mtime, $size);
8077}
8078
8079#************************************************************
8080
8081sub processing_time
8082{ my ($user, $system, $cuser, $csystem) = times();
8083 return $user + $system + $cuser + $csystem;
8084}
8085
8086#************************************************************
8087
8088sub get_checksum_md5 {
8089 my $source = shift;
8090 my $input = new FileHandle;
8091 my $md5 = Digest::MD5->new;
8092 my $ignore_pattern = undef;
8093
8094#&traceback;
8095#warn "======= GETTING MD5: $source\n";
8096 if ( $source eq "" ) {
8097 # STDIN:
8098 open( $input, '-' );
8099 }
8100 elsif ( -d $source ) {
8101 # We won't use checksum for directory
8102 return 0;
8103 }
8104 else {
8105 open( $input, '<', $source )
8106 or return 0;
8107 my ($base, $path, $ext) = fileparseA( $source );
8108 $ext =~ s/^\.//;
8109 if ( exists $hash_calc_ignore_pattern{$ext} ) {
8110 $ignore_pattern = $hash_calc_ignore_pattern{$ext};
8111 }
8112 }
8113
8114 if ( defined $ignore_pattern ) {
8115 while (<$input>) {
8116 if ( ! /$ignore_pattern/ ){
8117 $md5->add($_);
8118 }
8119 }
8120 }
8121 else {
8122 $md5->addfile($input);
8123 }
8124 close $input;
8125 return $md5->hexdigest();
8126}
8127
8128#************************************************************
8129#************************************************************
8130
8131sub create_empty_file {
8132 my $name = shift;
8133 my $h = new FileHandle ">$name"
8134 or return 1;
8135 close ($h);
8136 return 0;
8137}
8138
8139#************************************************************
8140#************************************************************
8141
8142sub find_file1 {
8143#?? Need to use kpsewhich, if possible
8144
8145 # Usage: find_file1(name, ref_to_array_search_path)
8146 # Modified find_file, which doesn't die.
8147 # Given filename and path, return array of:
8148 # full name
8149 # retcode
8150 # On success: full_name = full name with path, retcode = 0
8151 # On failure: full_name = given name, retcode = 1
8152
8153 my $name = $_[0];
8154 # Make local copy of path, since we may rewrite it!
8155 my @path = ();
8156 if ($_[1]) {
8157 @path = @{$_[1]};
8158 }
8159 if ( $name =~ /^\// ) {
8160 # Absolute path (if under UNIX)
8161 # This needs fixing, in general
8162 if (-e $name) { return( $name, 0 );}
8163 else { return( $name, 1 );}
8164 }
8165 foreach my $dir ( @path ) {
8166 #??print "-------------dir='$dir', ";
8167 # Make $dir concatenatable, and empty for current dir:
8168 if ( $dir eq '.' ) {
8169 $dir = '';
8170 }
8171 elsif ( $dir =~ /[\/\\:]$/ ) {
8172 #OK if dir ends in / or \ or :
8173 }
8174 elsif ( $dir ne '' ) {
8175 #Append directory separator only to non-empty dir
8176 $dir = "$dir/";
8177 }
8178 #?? print " newdir='$dir'\n";
8179 if (-e "$dir$name") {
8180 return("$dir$name", 0);
8181 }
8182 }
8183 my @kpse_result = kpsewhich( $name );
8184 if ($#kpse_result > -1) {
8185 return( $kpse_result[0], 0);
8186 }
8187 return("$name" , 1);
8188} #END find_file1
8189
8190#************************************************************
8191
8192sub find_file_list1 {
8193 # Modified version of find_file_list that doesn't die.
8194 # Given output and input arrays of filenames, a file suffix, and a path,
8195 # fill the output array with full filenames
8196 # Return array of not-found files.
8197 # Usage: find_file_list1( ref_to_output_file_array,
8198 # ref_to_input_file_array,
8199 # suffix,
8200 # ref_to_array_search_path
8201 # )
8202 # SPECIAL TREATMENT TO .bib extension, because of behavior of bibtex
8203 # OTHER SPECIAL TREATMENT IF EXTENSION IS GIVEN.
8204
8205 my $ref_output = $_[0];
8206 my $ref_input = $_[1];
8207 my $suffix = $_[2];
8208 my $ref_search = $_[3];
8209 my @not_found = ();
8210
8211#?? show_array( "=====find_file_list1. Suffix: '$suffix'\n Source:", @$ref_input );
8212#?? show_array( " Bibinputs:", @$ref_search );
8213
8214 my @return_list = (); # Generate list in local array, since input
8215 # and output arrays may be same
8216 my $retcode = 0;
8217 foreach my $file1 (@$ref_input) {
8218 my $file = $file1;
8219 if ($suffix eq '.bib') { $file =~ s/\.bib$//; }
8220 my ($tmp_file, $find_retcode) = &find_file1( "$file$suffix", $ref_search );
8221 if ($tmp_file) {
8222 push @return_list, $tmp_file;
8223 }
8224 if ( $find_retcode != 0 ) {
8225 push @not_found, $file.$suffix;
8226 }
8227 }
8228 @$ref_output = @return_list;
8229#?? show_array( " Output", @$ref_output );
8230#?? foreach (@$ref_output) { if ( /\/\// ) { print " ====== double slash in '$_'\n"; } }
8231 return @not_found;
8232} #END find_file_list1
8233
8234#************************************************************
8235
8236sub unlink_or_move {
8237 if ( $del_dir eq '' ) {
8238 unlink @_;
8239 }
8240 else {
8241 foreach (@_) {
8242 if (-e $_ && ! rename $_, "$del_dir/$_" ) {
8243 warn "$My_name:Cannot move '$_' to '$del_dir/$_'\n";
8244 }
8245 }
8246 }
8247}
8248
8249#************************************************************
8250
8251sub kpsewhich {
8252# Usage: kpsewhich( filespec, ...)
8253# Returns array of files with paths as found by kpsewhich
8254# kpsewhich( 'try.sty', 'jcc.bib' );
8255# With standard use of kpsewhich (i.e., without -all option), the array
8256# has either 0 or 1 element.
8257# Can also do, e.g.,
8258# kpsewhich( '-format=bib', 'trial.bib', 'file with spaces');
8259 my $cmd = $kpsewhich;
8260 my @args = @_;
8261 if ( ($cmd eq '') || ( $cmd =~ /^NONE($| )/ ) ) {
8262 # Kpsewhich not set up.
8263 warn "$My_name: Kpsewhich command needed but not set up\n";
8264 return ();
8265 }
8266 foreach (@args) {
8267 if ( ! /^-/ ) {
8268 $_ = "\"$_\"";
8269 }
8270 }
8271 $cmd =~ s/%[RBTDO]//g;
8272 $cmd =~ s/%S/@args/g;
8273 my @found = ();
8274 local $fh;
8275 if ( $kpsewhich_show || $diagnostics ) {
8276 print "$My_name.kpsewhich: Running '$cmd'...\n";
8277 }
8278 open $fh, "$cmd|"
8279 or die "Cannot open pipe for \"$cmd\"\n";
8280 while ( <$fh> ) {
8281 s/[\r\n]*$//;
8282 push @found, $_;
8283 }
8284 close $fh;
8285 if ( $kpsewhich_show || $diagnostics ) {
8286 show_array( "$My_name.kpsewhich: '$cmd' ==>", @found );
8287 }
8288 return @found;
8289}
8290
8291####################################################
8292
8293sub add_cus_dep {
8294 # Usage: add_cus_dep( from_ext, to_ext, flag, sub_name )
8295 # Add cus_dep after removing old versions
8296 my ($from_ext, $to_ext, $must, $sub_name) = @_;
8297 remove_cus_dep( $from_ext, $to_ext );
8298 push @cus_dep_list, "$from_ext $to_ext $must $sub_name";
8299}
8300
8301####################################################
8302
8303sub remove_cus_dep {
8304 # Usage: remove_cus_dep( from_ext, to_ext )
8305 my ($from_ext, $to_ext) = @_;
8306 my $i = 0;
8307 while ($i <= $#cus_dep_list) {
8308 # Use \Q and \E round directory name in regex to avoid interpretation
8309 # of metacharacters in directory name:
8310 if ( $cus_dep_list[$i] =~ /^\Q$from_ext $to_ext \E/ ) {
8311 splice @cus_dep_list, $i, 1;
8312 }
8313 else {
8314 $i++;
8315 }
8316 }
8317}
8318
8319####################################################
8320
8321sub show_cus_dep {
8322 show_array( "Custom dependency list:", @cus_dep_list );
8323}
8324
8325####################################################
8326
8327sub add_aux_hook {
8328 # Usage: add_aux_hook( sub_name )
8329 # Add the name subroutine to the array of hooks for
8330 # processing lines of aux files.
8331 # The argument is either a string naming the subroutine, e.g.
8332 # add_aux_hook( 'subname' );
8333 # or a Perl reference to the subroutine, e.g.,
8334 # add_aux_hook( \&subname );
8335 # It is also possible to use an anonymous subroutine, e.g.,
8336 # add_aux_hook( sub{ code of subroutine... } );
8337 my ($sub_name) = @_;
8338 push @aux_hooks, $sub_name;
8339}
8340
8341####################################################
8342
8343sub add_input_ext {
8344 # Usage: add_input_ext( rule, ext, ... )
8345 # Add extension(s) (specified without a leading period) to the
8346 # list of input extensions for the given rule. The rule should be
8347 # 'latex' or 'pdflatex'. These extensions are used when an input
8348 # file without an extension is found by (pdf)latex, as in
8349 # \input{file} or \includegraphics{figure}. When latexmk searches
8350 # custom dependencies to make the missing file, it will assume that
8351 # the file has one of the specified extensions.
8352 my $rule = shift;
8353 if ( ! exists $input_extensions{$rule} ) {
8354 $input_extensions{$rule} = {};
8355 }
8356 my $Prule = $input_extensions{$rule};
8357 foreach (@_) { $$Prule{$_} = 1; }
8358}
8359
8360####################################################
8361
8362sub remove_input_ext {
8363 # Usage: remove_input_ext( rule, ext, ... )
8364 # Remove extension(s) (specified without a leading period) to the
8365 # list of input extensions for the given rule. The rule should be
8366 # 'latex' or 'pdflatex'. See sub add_input_ext for the use.
8367 my $rule = shift;
8368 if ( ! exists $input_extensions{$rule} ) { return; }
8369 my $Prule = $input_extensions{$rule};
8370 foreach (@_) { delete $$Prule{$_}; }
8371}
8372
8373####################################################
8374
8375sub show_input_ext {
8376 # Usage: show_input_ext( rule )
8377 my $rule = shift;
8378 show_array ("Input extensions for rule '$rule': ",
8379 keys %{$input_extensions{$rule}} );
8380}
8381
8382####################################################
8383
8384sub find_dirs1 {
8385 # Same as find_dirs, but argument is single string with directories
8386 # separated by $search_path_separator
8387 find_dirs( &split_search_path( $search_path_separator, ".", $_[0] ) );
8388}
8389
8390
8391#************************************************************
8392
8393sub find_dirs {
8394# @_ is list of directories
8395# return: same list of directories, except that for each directory
8396# name ending in //, a list of all subdirectories (recursive)
8397# is added to the list.
8398# Non-existent directories and non-directories are removed from the list
8399# Trailing "/"s and "\"s are removed
8400 local @result = ();
8401 my $find_action
8402 = sub
8403 { ## Subroutine for use in File::find
8404 ## Check to see if we have a directory
8405 if (-d) { push @result, $File::Find::name; }
8406 };
8407 foreach my $directory (@_) {
8408 my $recurse = ( $directory =~ m[//$] );
8409 # Remove all trailing /s, since directory name with trailing /
8410 # is not always allowed:
8411 $directory =~ s[/+$][];
8412 # Similarly for MSWin reverse slash
8413 $directory =~ s[\\+$][];
8414 if ( ! -e $directory ){
8415 next;
8416 }
8417 elsif ( $recurse ){
8418 # Recursively search directory
8419 find( $find_action, $directory );
8420 }
8421 else {
8422 push @result, $directory;
8423 }
8424 }
8425 return @result;
8426}
8427
8428#************************************************************
8429
8430sub uniq
8431# Read arguments, delete neighboring items that are identical,
8432# return array of results
8433{
8434 my @sort = ();
8435 my ($current, $prev);
8436 my $first = 1;
8437 while (@_)
8438 {
8439 $current = shift;
8440 if ($first || ($current ne $prev) )
8441 {
8442 push @sort, $current;
8443 $prev = $current;
8444 $first = 0;
8445 }
8446 }
8447 return @sort;
8448}
8449
8450#==================================================
8451
8452sub uniq1 {
8453 # Usage: uniq1( strings )
8454 # Returns array of strings with duplicates later in list than
8455 # first occurence deleted. Otherwise preserves order.
8456
8457 my @strings = ();
8458 my %string_hash = ();
8459
8460 foreach my $string (@_) {
8461 if (!exists( $string_hash{$string} )) {
8462 $string_hash{$string} = 1;
8463 push @strings, $string;
8464 }
8465 }
8466 return @strings;
8467}
8468
8469#************************************************************
8470
8471sub uniqs {
8472 # Usage: uniq2( strings )
8473 # Returns array of strings sorted and with duplicates deleted
8474 return uniq( sort @_ );
8475}
8476
8477#************************************************************
8478
8479sub ext {
8480 # Return extension of filename. Extension includes the period
8481 my $file_name = $_[0];
8482 my ($base_name, $path, $ext) = fileparseA( $file_name );
8483 return $ext;
8484 }
8485
8486#************************************************************
8487
8488sub ext_no_period {
8489 # Return extension of filename. Extension excludes the period
8490 my $file_name = $_[0];
8491 my ($base_name, $path, $ext) = fileparseA( $file_name );
8492 $ext =~ s/^\.//;
8493 return $ext;
8494 }
8495
8496#************************************************************
8497
8498sub fileparseA {
8499 # Like fileparse but replace $path for current dir ('./' or '.\') by ''
8500 # Also default second argument to get normal extension.
8501 my $given = $_[0];
8502 my $pattern = '\.[^\.]*';
8503 if ($#_ > 0 ) { $pattern = $_[1]; }
8504 my ($base_name, $path, $ext) = fileparse( $given, $pattern );
8505 if ( ($path eq './') || ($path eq '.\\') ) {
8506 $path = '';
8507 }
8508 return ($base_name, $path, $ext);
8509 }
8510
8511#************************************************************
8512
8513sub fileparseB {
8514 # Like fileparse but with default second argument for normal extension
8515 my $given = $_[0];
8516 my $pattern = '\.[^\.]*';
8517 if ($#_ > 0 ) { $pattern = $_[1]; }
8518 my ($base_name, $path, $ext) = fileparse( $given, $pattern );
8519 return ($base_name, $path, $ext);
8520 }
8521
8522#************************************************************
8523
8524sub split_search_path
8525{
8526# Usage: &split_search_path( separator, default, string )
8527# Splits string by separator and returns array of the elements
8528# Allow empty last component.
8529# Replace empty terms by the default.
8530 my $separator = $_[0];
8531 my $default = $_[1];
8532 my $search_path = $_[2];
8533 my @list = split( /$separator/, $search_path);
8534 if ( $search_path =~ /$separator$/ ) {
8535 # If search path ends in a blank item, the split subroutine
8536 # won't have picked it up.
8537 # So add it to the list by hand:
8538 push @list, "";
8539 }
8540 # Replace each blank argument (default) by current directory:
8541 for ($i = 0; $i <= $#list ; $i++ ) {
8542 if ($list[$i] eq "") {$list[$i] = $default;}
8543 }
8544 return @list;
8545}
8546
8547#################################
8548
8549sub get_filetime_offset {
8550 # Usage: get_filetime_offset( prefix, [suffix] )
8551 # Measures offset between filetime in a directory and system time
8552 # Makes a temporary file of a unique name, and deletes in.
8553 # Filename is of form concatenation of prefix, an integer, suffix.
8554 # Prefix is normally of form dir/ or dir/tmp.
8555 # Default default suffix ".tmp".
8556 my $prefix = $_[0];
8557 my $suffix = $_[1] || '.tmp';
8558 my $tmp_file_count = 0;
8559 while (1==1) {
8560 # Find a new temporary file, and make it.
8561 $tmp_file_count++;
8562 my $tmp_file = "${prefix}${tmp_file_count}${suffix}";
8563 if ( ! -e $tmp_file ) {
8564 open( TMP, ">$tmp_file" )
8565 or die "$My_name.get_filetime_offset: In measuring filetime offset, couldn't write to\n",
8566 " temporary file '$tmp_file'\n";
8567 my $time = time();
8568 close(TMP);
8569 my $offset = get_mtime($tmp_file) - $time;
8570 unlink $tmp_file;
8571 return $offset;
8572 }
8573 }
8574 die "$My_name.get_filetime_offset: BUG TO ARRIVE HERE\n";
8575}
8576
8577#################################
8578
8579sub tempfile1 {
8580 # Makes a temporary file of a unique name. I could use file::temp,
8581 # but it is not present in all versions of perl.
8582 # Filename is of form $tmpdir/$_[0]nnn$suffix, where nnn is an integer
8583 my $tmp_file_count = 0;
8584 my $prefix = $_[0];
8585 my $suffix = $_[1];
8586 while (1==1) {
8587 # Find a new temporary file, and make it.
8588 $tmp_file_count++;
8589 my $tmp_file = "${tmpdir}/${prefix}${tmp_file_count}${suffix}";
8590 if ( ! -e $tmp_file ) {
8591 open( TMP, ">$tmp_file" )
8592 or next;
8593 close(TMP);
8594 return $tmp_file;
8595 }
8596 }
8597 die "$My_name.tempfile1: BUG TO ARRIVE HERE\n";
8598}
8599
8600#################################
8601
8602#************************************************************
8603#************************************************************
8604# Process/subprocess routines
8605
8606sub Run_msg {
8607 # Same as Run, but give message about my running
8608 warn_running( "Running '$_[0]'" );
8609 return Run($_[0]);
8610} #END Run_msg
8611
8612#==================
8613
8614sub Run {
8615 # This is wrapper around Run_no_time to capture timing information
8616 my $time1 = processing_time();
8617 my ($pid, $return) = Run_no_time($_[0]);
8618 my $time = processing_time() - $time1;
8619 push @timings, "'$_[0]': time = $time\n";
8620 return ($pid, $return);
8621} #END Run_msg
8622
8623#==================
8624
8625sub Run_no_time {
8626# Usage: Run_no_time ("command string");
8627# or Run_no_time ("one-or-more keywords command string");
8628# Possible keywords: internal, NONE, start, nostart.
8629#
8630# A command string not started by keywords just gives a call to system with
8631# the specified string, I return after that has finished executing.
8632# Exceptions to this behavior are triggered by keywords.
8633# The general form of the string is
8634# Zero or more occurences of the start keyword,
8635# followed by at most one of the other key words (internal, nostart, NONE),
8636# followed by (a) a command string to be executed by the systerm
8637# or (b) if the command string is specified to be internal, then
8638# it is of the form
8639#
8640# routine arguments
8641#
8642# which implies invocation of the named Perl subroutine
8643# with the given arguments, which are obtained by splitting
8644# the string into words, delimited by spaces, but with
8645# allowance for double quotes.
8646#
8647# The meaning of the keywords is:
8648#
8649# start: The command line is to be running detached, as appropriate for
8650# a previewer. The method is appropriate for the operating system
8651# (and the keyword is inspired by the action of the start command
8652# that implements in under MSWin).
8653# HOWEVER: the start keyword is countermanded by the nostart,
8654# internal, and NONE keywords. This allows rules that do
8655# previewing to insert a start keyword to create a presumption
8656# of detached running unless otherwise.
8657# nostart: Countermands a previous start keyword; the following command
8658# string is then to be obeyed by the system, and any necessary
8659# detaching (as of a previewer) is done by the executed command(s).
8660# internal: The following command string, of the form 'routine arguments'
8661# specifies a call to the named Perl subroutine.
8662# NONE: This does not run anything, but causes an error message to be
8663# printed. This is provided to allow program names defined in the
8664# configuration to flag themselves as unimplemented.
8665# Note that if the word "start" is duplicated at the beginning, that is
8666# equivalent to a single "start".
8667#
8668# Return value is a list (pid, exitcode):
8669# If a process is spawned sucessfully, and I know the PID,
8670# return (pid, 0),
8671# else if process is spawned sucessfully, but I do not know the PID,
8672# return (0, 0),
8673# else if process is run,
8674# return (0, exitcode of process)
8675# else if I fail to run the requested process
8676# return (0, suitable return code)
8677# where return code is 1 if cmdline is null or begins with "NONE" (for
8678# an unimplemented command)
8679# or the return value of the Perl subroutine.
8680 my $cmd_line = $_[0];
8681 if ( $cmd_line eq '' ) {
8682 traceback( "$My_name: Bug OR configuration error\n".
8683 " In run of '$rule', attempt to run a null program" );
8684 return (0, 1);
8685 }
8686 # Deal with latexmk-defined pseudocommands 'start' and 'NONE'
8687 # at front of command line:
8688 my $detach = 0;
8689 while ( $cmd_line =~ s/^start +// ) {
8690 # But first remove extra starts (which may have been inserted
8691 # to force a command to be run detached, when the command
8692 # already contained a "start").
8693 $detach = 1;
8694 }
8695 if ( $cmd_line =~ s/^nostart +// ) {
8696 $detach = 0;
8697 }
8698 if ( $cmd_line =~ /^internal\s+([a-zA-Z_]\w*)\s+(.*)$/ ) {
8699 my $routine = $1;
8700 my @args = parse_quotes( $2 );
8701 warn "$My_name: calling $routine( $2 )\n";
8702 return ( 0, &$routine( @args ) );
8703 }
8704 elsif ( $cmd_line =~ /^internal\s+([a-zA-Z_]\w*)\s*$/ ) {
8705 my $routine = $1;
8706 warn "$My_name: calling $routine()\n";
8707 return ( 0, &$routine() );
8708 }
8709 elsif ( $cmd_line =~ /^NONE/ ) {
8710 warn "$My_name: ",
8711 "Program not implemented for this version. Command line:\n";
8712 warn " '$cmd_line'\n";
8713 return (0, 1);
8714 }
8715 elsif ($detach) {
8716 # Run detached. How to do this depends on the OS
8717 return &Run_Detached( $cmd_line );
8718 }
8719 else {
8720 # The command is given to system as a single argument, to force shell
8721 # metacharacters to be interpreted:
8722 return( 0, system( $cmd_line ) );
8723 }
8724} #END Run
8725
8726#************************************************************
8727
8728sub Run_Detached {
8729# Usage: Run_Detached ("program arguments ");
8730# Runs program detached. Returns 0 on success, 1 on failure.
8731# Under UNIX use a trick to avoid the program being killed when the
8732# parent process, i.e., me, gets a ctrl/C, which is undesirable for pvc
8733# mode. (The simplest method, system("program arguments &"), makes the
8734# child process respond to the ctrl/C.)
8735# Return value is a list (pid, exitcode):
8736# If process is spawned sucessfully, and I know the PID,
8737# return (pid, 0),
8738# else if process is spawned sucessfully, but I do not know the PID,
8739# return (0, 0),
8740# else if I fail to spawn a process
8741# return (0, 1)
8742
8743 my $cmd_line = $_[0];
8744
8745## warn "Running '$cmd_line' detached...\n";
8746 if ( $cmd_line =~ /^NONE / ) {
8747 warn "$My_name: ",
8748 "Program not implemented for this version. Command line:\n";
8749 warn " '$cmd_line'\n";
8750 return (0, 1);
8751 }
8752
8753 if ( "$^O" eq "MSWin32" ){
8754 # Win95, WinNT, etc: Use MS's start command:
8755 # Need extra double quotes to deal with quoted filenames:
8756 # MSWin start takes first quoted argument to be a Window title.
8757 return( 0, system( "start \"\" $cmd_line" ) );
8758 } else {
8759 # Assume anything else is UNIX or clone
8760 # For this purpose cygwin behaves like UNIX.
8761 ## warn "Run_Detached.UNIX: A\n";
8762 my $pid = fork();
8763 ## warn "Run_Detached.UNIX: B pid=$pid\n";
8764 if ( ! defined $pid ) {
8765 ## warn "Run_Detached.UNIX: C\n";
8766 warn "$My_name: Could not fork to run the following command:\n";
8767 warn " '$cmd_line'\n";
8768 return (0, 1);
8769 }
8770 elsif( $pid == 0 ){
8771 ## warn "Run_Detached.UNIX: D\n";
8772 # Forked child process arrives here
8773 # Insulate child process from interruption by ctrl/C to kill parent:
8774 # setpgrp(0,0);
8775 # Perhaps this works if setpgrp doesn't exist
8776 # (and therefore gives fatal error):
8777 eval{ setpgrp(0,0);};
8778 exec( $cmd_line );
8779 # Exec never returns; it replaces current process by new process
8780 die "$My_name forked process: could not run the command\n",
8781 " '$cmd_line'\n";
8782 }
8783 ##warn "Run_Detached.UNIX: E\n";
8784 # Original process arrives here
8785 return ($pid, 0);
8786 }
8787 # NEVER GET HERE.
8788 ##warn "Run_Detached.UNIX: F\n";
8789} #END Run_Detached
8790
8791#************************************************************
8792
8793sub find_process_id {
8794# find_process_id(string) finds id of process containing string and
8795# being run by the present user. Typically the string will be the
8796# name of the process or part of its command line.
8797# On success, this subroutine returns the process ID.
8798# On failure, it returns 0.
8799# This subroutine only works on UNIX systems at the moment.
8800
8801 if ( $pid_position < 0 ) {
8802 # I cannot do a ps on this system
8803 return (0);
8804 }
8805
8806 my $looking_for = $_[0];
8807 my @ps_output = `$pscmd`;
8808 my @ps_lines = ();
8809
8810# There may be multiple processes. Find only latest,
8811# almost surely the one with the highest process number
8812# This will deal with cases like xdvi where a script is used to
8813# run the viewer and both the script and the actual viewer binary
8814# have running processes.
8815 my @found = ();
8816
8817 shift(@ps_output); # Discard the header line from ps
8818 foreach (@ps_output) {
8819 next unless ( /$looking_for/ ) ;
8820 s/^\s*//;
8821 my @ps_line = split ('\s+');
8822 push @found, $ps_line[$pid_position];
8823 push @ps_lines, $_;
8824 }
8825
8826 if ($#found < 0) {
8827 # No luck in finding the specified process.
8828 return(0);
8829 }
8830 @found = reverse sort @found;
8831 if ($diagnostics) {
8832 print "Found the following processes concerning '$looking_for'\n",
8833 " @found\n",
8834 " I will use $found[0]\n";
8835 print " The relevant lines from '$pscmd' were:\n";
8836 foreach (@ps_lines) { print " $_"; }
8837 }
8838 return $found[0];
8839}
8840
8841#************************************************************
8842#************************************************************
8843#************************************************************
8844
8845#============================================
8846
8847sub cache_good_cwd {
8848 # Set cached value of cwd to current cwd.
8849 # Under cygwin, the cwd is converted to a native MSWin path so
8850 # that the result can be used for input to MSWin programs as well
8851 # as cygwin programs.
8852 my $cwd = cwd();
8853 if ( $^O eq "cygwin" ) {
8854 my $cmd = "cygpath -w \"$cwd\"";
8855 my $Win_cwd = `$cmd`;
8856 chomp $Win_cwd;
8857 if ( $Win_cwd ) {
8858 $cwd = $Win_cwd;
8859 }
8860 else {
8861 warn "$My_name: Could not correctly run command\n",
8862 " '$cmd'\n",
8863 " to get MSWin version of cygwin path\n",
8864 " '$cwd'\n",
8865 " The result was\n",
8866 " '$Win_cwd'\n";
8867 }
8868 }
8869 $cache{cwd} = $cwd;
8870} # END cache_good_cwd
8871
8872#============================================
8873
8874sub good_cwd {
8875 # Return cwd, but under cygwin, convert to MSWin path.
8876 # Use cached result
8877 return $cache{cwd};
8878} # END good_cwd
8879
8880#============================================
8881
8882# Directory stack routines
8883
8884sub pushd {
8885 push @dir_stack, [cwd(), $cache{cwd}];
8886 if ( $#_ > -1) {
8887 chdir $_[0];
8888 &cache_good_cwd;
8889 }
8890}
8891
8892#************************************************************
8893
8894sub popd {
8895 if ($#dir_stack > -1 ) {
8896 my $Parr = pop @dir_stack;
8897 chdir $$Parr[0];
8898 $cache{cwd} = $$Parr[1];
8899 }
8900}
8901
8902#************************************************************
8903
8904sub ifcd_popd {
8905 if ( $do_cd ) {
8906 warn "$My_name: Undoing directory change\n";
8907 &popd;
8908 }
8909}
8910
8911#************************************************************
8912
8913sub finish_dir_stack {
8914 while ($#dir_stack > -1 ) { &popd; }
8915}
8916
8917#************************************************************
8918#************************************************************
8919# Break handling routines (for wait-loop in preview continuous)
8920
8921sub end_wait {
8922 # Handler for break: Set global variable $have_break to 1.
8923 # Some systems (e.g., MSWin reset) appear to reset the handler.
8924 # So I'll re-enable it
8925 &catch_break;
8926 $have_break = 1;
8927}
8928
8929#========================
8930
8931sub catch_break {
8932# Capture ctrl/C and ctrl/break.
8933# $SIG{INT} corresponds to ctrl/C on LINUX/?UNIX and MSWin
8934# $SIG{BREAK} corresponds to ctrl/break on MSWin, doesn't exist on LINUX
8935 $SIG{INT} = \&end_wait;
8936 if ( exists $SIG{BREAK} ) {
8937 $SIG{BREAK} = \&end_wait;
8938 }
8939}
8940
8941#========================
8942
8943sub default_break {
8944# Arrange for ctrl/C and ctrl/break to give default behavior
8945 $SIG{INT} = 'DEFAULT';
8946 if ( exists $SIG{BREAK} ) {
8947 $SIG{BREAK} = 'DEFAULT';
8948 }
8949}
8950
8951#************************************************************
8952#************************************************************