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