Advertisement
Guest User

Untitled

a guest
Dec 18th, 2018
333
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 360.16 KB | None | 0 0
  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.  
  26. use warnings;
  27.  
  28. # Delete #??!! when working
  29.  
  30. # See ?? <===============================
  31.  
  32. ## ?? Issues with clean-up
  33. ## List of aux files deleted is those read, not those generated.
  34. ## Other files are generated by (pdf)latex; should they be deleted?
  35. ## (I have hooks for this).
  36.  
  37.  
  38.  
  39. #=======================================
  40.  
  41. #??  Force mode doesn't appear to do force (if error in latex file)
  42. #??? Get banner back in.
  43. #??  CORRECT DIAGNOSTICS ON CHANGED FILES IF THEY DIDN'T EXIST BEFORE
  44. #??  Further corrections to deal with disappeared source files for custom dependencies.
  45. #       Message repeatedly appears about remake when source file of cusdep doesn't exist.
  46. #??  logfile w/o fdb file: don't set changed file, perhaps for generated exts.
  47. #    Reconsider
  48. #??  Do proper run-stuff for bibtex, makeindex, cus-deps.  OK I think
  49. #    Parse and correctly find ist files
  50.  
  51.  
  52. # ATTEMPT TO ALLOW FILENAMES WITH SPACES:
  53. #    (as of 1 Apr 2006, and then 14 Sep. 2007)
  54.  
  55. # Problems:
  56. # A.  Quoting filenames will not always work.  
  57. #        a.  Under UNIX, quotes are legal in filenames, so when PERL
  58. #            directly runs a binary, a quoted filename will be treated as
  59. #            as a filename containing a quote character.  But when it calls
  60. #            a shell, the quotes are handled by the shell as quotes.
  61. #        b.  Under MSWin32, quotes are illegal filename characters, and tend
  62. #            to be handled correctly.
  63. #        c.  But under cygwin, results are not so clear (there are many
  64. #            combinations: native v. cygwin perl, native v cygwin programs
  65. #            NT v. unix scripts, which shell is called.
  66. # B.  TeX doesn't always handle filenames with spaces gracefully.
  67. #        a.  UNIX/LINUX: The version on gluon2 Mar 31, 2006 to Sep. 2007)
  68. #            doesn't handle them at all.  (TeX treats space as separator.)
  69. #        b.  At least some later versions actually do (Brad Miller e-mail,
  70. #            Sep. 2007).
  71. #        c.  fptex [[e-TeXk, Version 3.141592-2.1 (Web2c 7.5.2)] does, on
  72. #            my MSWin at home.  In \input the filename must be in quotes.
  73. #        d.  Bibtex [BibTeX (Web2c 7.5.2) 0.99c on my MSWin system at home,
  74. #            Sep. 2007] does not allow names of bibfiles to have spaces.
  75. # C.  =====> Using the shell for command lines is not safe, since special
  76. #     characters can cause lots of mayhem.
  77. #     It will therefore be a good idea to sanitize filenames.
  78. #
  79. # I've sanitized all calls out:
  80. #     a. system and exec use a single argument, which forces
  81. #        use of shell, under all circumstances
  82. #        Thus I can safely use quotes on filenames:  They will be handled by
  83. #        the shell under UNIX, and simply passed on to the program under MSWin32.
  84. #     b. I reorganized Run, Run_Detached to use single command line
  85. #     c. All calls to Run and Run_Detached have quoted filenames.
  86. #     d. So if a space-free filename with wildcards is given on latexmk's
  87. #        command line, and it globs to space-containing filename(s), that
  88. #        works (fptex on home computer, native NT tex)
  89. #     e. ====> But globbing fails: the glob function takes space as filename
  90. #        separator.   ====================
  91.  
  92. #================= TO DO ================
  93. #
  94. # 1.  See ??  ESPECIALLY $MSWin_fudge_break
  95. # 2.  Check fudged conditions in looping and make_files
  96. # 3.  Should not completely abort after a run that ends in failure from latex
  97. #     Missing input files (including via custom dependency) should be checked for
  98. #     a change in status
  99. #         If sources for missing files from custom dependency
  100. #             are available, then do a rerun
  101. #         If sources of any kind become available rerun (esp. for pvc)
  102. #             rerun
  103. #         Must parse log_file after unsuccessful run of latex: it may give
  104. #             information about missing files.
  105. # 4.  Check file of bug reports and requests
  106. # 5.  Rationalize bibtex warnings and errors.  Two almost identical routines.
  107. #         Should 1. Use single routine
  108. #                2. Convert errors to failure only in calling routine
  109. #                3. Save first warning/error.
  110.  
  111. # ?? Use of generated_exts arrays and hashes needs rationalization
  112.  
  113. # To do:
  114. #   Rationalize again handling of include files.
  115. #     Now I use kpsewhich to do searches, if file not found
  116. #        (How do I avoid getting slowed down too much?)
  117. #   Document the assumptions at each stage of processing algorithm.
  118. #   Option to restart previewer automatically, if it dies under -pvc
  119. #   Test for already running previewer gets wrong answer if another
  120. #     process has the viewed file in its command line
  121.  
  122. $my_name = 'latexmk';
  123. $My_name = 'Latexmk';
  124. $version_num = '4.55';
  125. $version_details = "$My_name, John Collins, 17 Jan. 2018";
  126.  
  127. use Config;
  128. use File::Basename;
  129. use File::Copy;
  130.  
  131. # If possible, use better glob, which does not use space as item separator.
  132. # It's either File::Glob::bsd_glob or File::Glob::glob
  133. # The first does not exist in old versions of Perl, while the second
  134. # is deprecated in more recent versions and will be removed
  135. $have_bsd_glob = 0;
  136. sub my_glob {
  137.     if ($have_bsd_glob) { return bsd_glob( $_[0] ); }
  138.     else { return glob( $_[0] ); }
  139. }
  140. use File::Glob;
  141. if ( eval{ File::Glob->import('bsd_glob'); 1; } ) {
  142.     # Success in importing bsd_glob
  143.     $have_bsd_glob = 1;
  144. }
  145. elsif ( eval{ File::Glob->import('glob'); 1; } ) {
  146.     warn "$My_name: I could not import File::Glob:bsd_glob, probably because your\n",
  147.      "  Perl is too old.  I have arranged to use the deprecated File::Glob:glob\n",
  148.      "  instead.\n",
  149.      "  WARNING: It may malfunction on clean up operation on filenames containing\n",
  150.      "           spaces.\n";
  151.     $have_bsd_glob = 0;
  152. }
  153. else {
  154.     die "Could not import 'File::Glob:bsd_glob' or 'File::Glob:glob'\n";
  155. }
  156.  
  157. use File::Path 2.08 qw( make_path );
  158. use FileHandle;
  159. use File::Find;
  160. use List::Util qw( max );
  161. use Cwd;            # To be able to change cwd
  162. use Cwd "chdir";    # Ensure $ENV{PWD}  tracks cwd
  163. use Digest::MD5;
  164.  
  165. #use strict;
  166.  
  167. # The following variables are assigned once and then used in symbolic
  168. #     references, so we need to avoid warnings 'name used only once':
  169. use vars qw( $dvi_update_command $ps_update_command $pdf_update_command );
  170.  
  171. # Translation of signal names to numbers and vv:
  172. %signo = ();
  173. @signame = ();
  174. if ( defined $Config{sig_name} ) {
  175.    $i = 0;
  176.    foreach $name (split('\s+', $Config{sig_name})) {
  177.       $signo{$name} = $i;
  178.       $signame[$i] = $name;
  179.       $i++;
  180.    }
  181. }
  182. else {
  183.    warn "Something wrong with the perl configuration: No signals?\n";
  184. }
  185.  
  186. ## Copyright John Collins 1998-2018
  187. ##           (username jcc8 at node psu.edu)
  188. ##      (and thanks to David Coppit (username david at node coppit.org)
  189. ##           for suggestions)
  190. ## Copyright Evan McLean
  191. ##         (modifications up to version 2)
  192. ## Copyright 1992 by David J. Musliner and The University of Michigan.
  193. ##         (original version)
  194. ##
  195. ##    This program is free software; you can redistribute it and/or modify
  196. ##    it under the terms of the GNU General Public License as published by
  197. ##    the Free Software Foundation; either version 2 of the License, or
  198. ##    (at your option) any later version.
  199. ##
  200. ##    This program is distributed in the hope that it will be useful,
  201. ##    but WITHOUT ANY WARRANTY; without even the implied warranty of
  202. ##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  203. ##    GNU General Public License for more details.
  204. ##
  205. ##    You should have received a copy of the GNU General Public License
  206. ##    along with this program; if not, write to the Free Software
  207. ##    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  208. ##
  209. ##
  210. ##
  211. ##   NEW FEATURES, since v. 2.0:
  212. ##     1.  Correct algorithm for deciding how many times to run latex:
  213. ##         based on whether source file(s) change between runs
  214. ##     2.  Continuous preview works, and can be of ps file or dvi file
  215. ##     3.  pdf creation by pdflatex possible
  216. ##     4.  Defaults for commands are OS dependent.
  217. ##     5.  Parsing of log file instead of source file is used to
  218. ##         obtain dependencies, by default.
  219. ##
  220. ##   Modification log from 9 Dec 2011 onwards in detail
  221. ##
  222. ##   12 Jan 2012 STILL NEED TO DOCUMENT some items below
  223. ##
  224. ##    17 Jan 2018   John Collins  Version number to 4.55.  Ready for release.
  225. ##    15, 16 Jan 2018   John Collins  Correct bug in measuring filetime offset.
  226. ##    14 Jan 2018   John Collins  Correct issue with possible filetime offset
  227. ##                                  on remote file system.
  228. ##                                Define defaults for configuration variables
  229. ##                                  that didn't have defaults.
  230. ##    12 Jan 2018   John Collins  Implement pvc timeout
  231. ##    10 Jan 2018   John Collins  Ensure $search_path_separator is defined.
  232. ##                                Set it to MS-Win value for msys.
  233. ##    12 Dec 2017   John Collins  Further correct bsd_glob fudge (to be in subroutine my_glob)
  234. ##     8 Dec 2017   John Collins  Correct bsd_glob fudge
  235. ##     2 Dec 2017   John Collins  Fudge on bsd_glob if it doesn't exist
  236. ##    20 Nov 2017   John Collins  Ver. 4.54
  237. ##
  238. ##   1998-2017, John Collins.  Many improvements and fixes.
  239. ##       See CHANGE-log.txt for full list, and CHANGES for summary
  240. ##
  241. ##   Modified by Evan McLean (no longer available for support)
  242. ##   Original script (RCS version 2.3) called "go" written by David J. Musliner
  243. ##
  244. ##-----------------------------------------------------------------------
  245.  
  246.  
  247. ## Explicit exit codes:
  248. ##             10 = bad command line arguments
  249. ##             11 = file specified on command line not found
  250. ##                  or other file not found
  251. ##             12 = failure in some part of making files
  252. ##             13 = error in initialization file
  253. ##             20 = probable bug
  254. ##             or retcode from called program.
  255.  
  256.  
  257. # Line length in log file that indicates wrapping.  
  258. # This number EXCLUDES line-end characters, and is one-based.
  259. # It is the parameter max_print_line in the TeX program.  (tex.web)
  260. $log_wrap = 79;
  261.  
  262. #########################################################################
  263. ## Default parsing and file-handling settings
  264.  
  265. ## Array of reg-exps for patterns in log-file for file-not-found
  266. ## Each item is the string in a regexp, without the enclosing slashes.
  267. ## First parenthesized part is the filename.
  268. ## Note the need to quote slashes and single right quotes to make them
  269. ## appear in the regexp.
  270. ## Add items by push, e.g.,
  271. ##     push @file_not_found, '^No data file found `([^\\\']*)\\\'';
  272. ## will give match to line starting "No data file found `filename'"
  273. @file_not_found = (
  274.     '^No file\\s*(.*)\\.$',
  275.     '^\\! LaTeX Error: File `([^\\\']*)\\\' not found\\.',
  276.     '.*?:\\d*: LaTeX Error: File `([^\\\']*)\\\' not found\\.',
  277.     '^LaTeX Warning: File `([^\\\']*)\\\' not found',
  278.     '^Package .* [fF]ile `([^\\\']*)\\\' not found',
  279.     '^Package .* No file `([^\\\']*)\\\'',
  280.     'Error: pdflatex \(file ([^\)]*)\): cannot find image file',
  281.     ': File (.*) not found:\s*$',
  282.     '! Unable to load picture or PDF file \\\'([^\\\']+)\\\'.',
  283. );
  284.  
  285. ## Hash mapping file extension (w/o period, e.g., 'eps') to a single regexp,
  286. #  whose matching by a line in a file with that extension indicates that the
  287. #  line is to be ignored in the calculation of the hash number (md5 checksum)
  288. #  for the file.  Typically used for ignoring datestamps in testing whether
  289. #  a file has changed.
  290. #  Add items e.g., by
  291. #     $hash_calc_ignore_pattern{'eps'} = '^%%CreationDate: ';
  292. #  This makes the hash calculation for an eps file ignore lines starting with
  293. #  '%%CreationDate: '
  294. #  ?? Note that a file will be considered changed if
  295. #       (a) its size changes
  296. #    or (b) its hash changes
  297. #  So it is useful to ignore lines in the hash calculation only if they
  298. #  are of a fixed size (as with a date/time stamp).
  299. %hash_calc_ignore_pattern =();
  300.  
  301.  
  302. # Specification of templates for extra rules.
  303. # See subroutine rdb_make_rule_list for examples of rule templates.
  304. # See subroutine rdb_set_rules for how they get used to construct rules.
  305. # (Documentation obviously needs to be improved!)
  306. %extra_rule_spec = ();
  307.  
  308.  
  309. # Hooks for customized extra processing on aux files.  The following
  310. # variable is an array of references to function.  Each function is
  311. # invoked in turn when a line of an aux file is processed (if none
  312. # of the built-in actions have been done).  On entry to the function,
  313. # the following variables are set:
  314. #    $_ = current line of aux file
  315. #    $rule = name of rule during the invocation of which, the aux file
  316. #            was supposed to have been generated.
  317. @aux_hooks = ();
  318.  
  319. #########################################################################
  320. ## Default document processing programs, and related settings,
  321. ## These are mostly the same on all systems.
  322. ## Most of these variables represents the external command needed to
  323. ## perform a certain action.  Some represent switches.
  324.  
  325. ## Commands to invoke latex, pdflatex, etc
  326. $latex  = 'latex %O %S';
  327. $pdflatex = 'pdflatex %O %S';
  328. $lualatex = 'lualatex %O %S';
  329. # xelatex is used to give xdv file, not pdf file
  330. $xelatex = 'xelatex -no-pdf %O %S';
  331.  
  332. ## Default switches:
  333. $latex_default_switches = '';
  334. $pdflatex_default_switches = '';
  335. $lualatex_default_switches = '';
  336. $xelatex_default_switches = '';
  337.  
  338. ## Switch(es) to make them silent:
  339. $latex_silent_switch  = '-interaction=batchmode';
  340. $pdflatex_silent_switch  = '-interaction=batchmode';
  341. $lualatex_silent_switch  = '-interaction=batchmode';
  342. $xelatex_silent_switch  = '-interaction=batchmode';
  343.  
  344. # %input_extensions maps primary_rule_name to pointer to hash of file extensions
  345. #    used for extensionless files specified in the source file by constructs
  346. #    like \input{file}  \includegraphics{file}
  347. #  Could write
  348. #%input_extensions = ( 'latex' => { 'tex' => 1, 'eps' => 1 };,
  349. #        'pdflatex' => { 'tex' => 1, 'pdf' => 1, 'jpg' => 1, 'png' => 1 }; );
  350. # Instead we'll exercise the user-friendly access routines:
  351. add_input_ext( 'latex', 'tex', 'eps' );
  352. add_input_ext( 'pdflatex', 'tex', 'jpg', 'pdf', 'png' );
  353. add_input_ext( 'lualatex', 'tex', 'jpg', 'pdf', 'png' );
  354. add_input_ext( 'xelatex', 'tex', 'jpg', 'pdf', 'png' );
  355. #show_input_ext( 'latex' ); show_input_ext( 'pdflatex' );
  356.  
  357. # Information about options to latex and pdflatex that latexmk will simply
  358. #   pass through to (pdf)latex
  359. # Option without arg. maps to itself.
  360. # Option with arg. maps the option part to the full specification
  361. #  e.g., -kpathsea-debug => -kpathsea-debug=NUMBER
  362. %allowed_latex_options = ();
  363. %allowed_latex_options_with_arg = ();
  364. foreach (
  365.   #####
  366.   # TeXLive options
  367.     "-draftmode              switch on draft mode (generates no output PDF)",
  368.     "-enc                    enable encTeX extensions such as \\mubyte",
  369.     "-etex                   enable e-TeX extensions",
  370.     "-file-line-error        enable file:line:error style messages",
  371.     "-no-file-line-error     disable file:line:error style messages",
  372.     "-fmt=FMTNAME            use FMTNAME instead of program name or a %& line",
  373.     "-halt-on-error          stop processing at the first error",
  374.     "-interaction=STRING     set interaction mode (STRING=batchmode/nonstopmode/\n".
  375.     "                           scrollmode/errorstopmode)",
  376.     "-ipc                    send DVI output to a socket as well as the usual\n".
  377.     "                           output file",
  378.     "-ipc-start              as -ipc, and also start the server at the other end",
  379.     "-kpathsea-debug=NUMBER  set path searching debugging flags according to\n".
  380.     "                           the bits of NUMBER",
  381.     "-mktex=FMT              enable mktexFMT generation (FMT=tex/tfm/pk)",
  382.     "-no-mktex=FMT           disable mktexFMT generation (FMT=tex/tfm/pk)",
  383.     "-mltex                  enable MLTeX extensions such as \charsubdef",
  384.     "-output-comment=STRING  use STRING for DVI file comment instead of date\n".
  385.     "                           (no effect for PDF)",
  386.     "-output-format=FORMAT   use FORMAT for job output; FORMAT is `dvi\" or `pdf\"",
  387.     "-parse-first-line       enable parsing of first line of input file",
  388.     "-no-parse-first-line    disable parsing of first line of input file",
  389.     "-progname=STRING        set program (and fmt) name to STRING",
  390.     "-shell-escape           enable \\write18{SHELL COMMAND}",
  391.     "-no-shell-escape        disable \\write18{SHELL COMMAND}",
  392.     "-shell-restricted       enable restricted \\write18",
  393.     "-src-specials           insert source specials into the DVI file",
  394.     "-src-specials=WHERE     insert source specials in certain places of\n".
  395.     "                           the DVI file. WHERE is a comma-separated value\n".
  396.     "                           list: cr display hbox math par parend vbox",
  397.     "-synctex=NUMBER         generate SyncTeX data for previewers if nonzero",
  398.     "-translate-file=TCXNAME use the TCX file TCXNAME",
  399.     "-8bit                   make all characters printable by default",
  400.  
  401.   #####
  402.   # MikTeX options not in TeXLive
  403.     "-alias=app              pretend to be app",
  404.     "-buf-size=n             maximum number of characters simultaneously present\n".
  405.     "                           in current lines",
  406.     "-c-style-errors         C-style error messages",
  407.     "-disable-installer      disable automatic installation of missing packages",
  408.     "-disable-pipes          disable input (output) from (to) child processes",
  409.     "-disable-write18        disable the \\write18{command} construct",
  410.     "-dont-parse-first-line  disable checking whether the first line of the main\n".
  411.     "                           input file starts with %&",
  412.     "-enable-enctex          enable encTeX extensions such as \\mubyte",
  413.     "-enable-installer       enable automatic installation of missing packages",
  414.     "-enable-mltex           enable MLTeX extensions such as \charsubdef",
  415.     "-enable-pipes           enable input (output) from (to) child processes",
  416.     "-enable-write18         fully enable the \\write18{command} construct",
  417.     "-error-line=n           set the width of context lines on terminal error\n".
  418.     "                           messages",
  419.     "-extra-mem-bot=n        set the extra size (in memory words) for large data\n".
  420.     "                           structures",
  421.     "-extra-mem-top=n        set the extra size (in memory words) for chars,\n".
  422.     "                           tokens, et al",
  423.     "-font-max=n             set the maximum internal font number",
  424.     "-font-mem-size=n        set the size, in TeX memory words, of the font memory",
  425.     "-half-error-line=n      set the width of first lines of contexts in terminal\n".
  426.     "                           error messages",
  427.     "-hash-extra=n           set the extra space for the hash table of control\n".
  428.     "                           sequences",
  429.     "-job-time=file          set the time-stamp of all output files equal to\n".
  430.     "                           file's time-stamp",
  431.     "-main-memory=n          change the total size (in memory words) of the main\n".
  432.     "                           memory array",
  433.     "-max-in-open=n          set the maximum number of input files and error\n".
  434.     "                           insertions that can be going on simultaneously",
  435.     "-max-print-line=n       set the width of longest text lines output",
  436.     "-max-strings=n          set the maximum number of strings",
  437.     "-nest-size=n            set the maximum number of semantic levels\n".
  438.     "                           simultaneously active",
  439.     "-no-c-style-errors      standard error messages",
  440.     "-param-size=n           set the the maximum number of simultaneous macro\n".
  441.     "                           parameters",
  442.     "-pool-size=n            set the maximum number of characters in strings",
  443.     "-record-package-usages=file record all package usages and write them into\n".
  444.     "                           file",
  445.     "-restrict-write18       partially enable the \\write18{command} construct",
  446.     "-save-size=n            set the the amount of space for saving values\n".
  447.     "                           outside of current group",
  448.     "-stack-size=n           set the maximum number of simultaneous input sources",
  449.     "-string-vacancies=n     set the minimum number of characters that should be\n".
  450.     "                           available for the user's control sequences and font\n".
  451.     "                           names",
  452.     "-tcx=name               process the TCX table name",
  453.     "-time-statistics        show processing time statistics",
  454.     "-trace                  enable trace messages",
  455.     "-trace=tracestreams     enable trace messages. The tracestreams argument is\n".
  456.     "                           a comma-separated list of trace stream names",
  457.     "-trie-size=n            set the amount of space for hyphenation patterns",
  458.     "-undump=name            use name as the name of the format to be used,\n".
  459.     "                           instead of the name by which the program was\n".
  460.     "                           called or a %& line.",
  461.  
  462.   #####
  463.     # Options passed to (pdf)latex that have special processing by latexmk,
  464.     #   so they are commented out here.
  465.     #-jobname=STRING         set the job name to STRING
  466.     #-aux-directory=dir    Set the directory dir to which auxiliary files are written
  467.     #-output-directory=DIR   use existing DIR as the directory to write files in
  468.     #-quiet
  469.     #-recorder               enable filename recorder
  470.     #
  471.     # Options with different processing by latexmk than (pdf)latex
  472.     #-help
  473.     #-version
  474.     #
  475.     # Options NOT used by latexmk
  476.     #-includedirectory=dir    prefix dir to the search path
  477.     #-initialize              become the INI variant of the compiler
  478.     #-ini                     be pdfinitex, for dumping formats; this is implicitly
  479.     #                          true if the program name is `pdfinitex'
  480. ) {
  481.     if ( /^([^\s=]+)=/ ) {
  482.         $allowed_latex_options_with_arg{$1} = $_;
  483.     }
  484.     elsif ( /^([^\s=]+)\s/ ) {
  485.         $allowed_latex_options{$1} = $_;
  486.     }
  487.     else {
  488.         $allowed_latex_options{$_} = $_;
  489.     }
  490. }
  491.  
  492. # Arrays of options that will be added to latex and pdflatex.
  493. # These need to be stored until after the command line parsing is finished,
  494. #  in case the values of $latex and/or $pdflatex change after an option
  495. #  is added.
  496. @extra_latex_options = ();
  497. @extra_pdflatex_options = ();
  498. @extra_lualatex_options = ();
  499. @extra_xelatex_options = ();
  500.  
  501.  
  502. ## Command to invoke biber & bibtex
  503. $biber  = 'biber %O %B';
  504. $bibtex  = 'bibtex %O %B';
  505. # Switch(es) to make biber & bibtex silent:
  506. $biber_silent_switch  = '--onlylog';
  507. $bibtex_silent_switch  = '-terse';
  508. $bibtex_use = 1;   # Whether to actually run bibtex to update bbl files.
  509.                    # This variable is also used in deciding whether to
  510.                    #   delete bbl files in clean up operations.
  511.                    # 0:  Never run bibtex.
  512.                    #     Do NOT delete bbl files on clean up.
  513.                    # 1:  Run bibtex only if the bibfiles exists
  514.                    #     according to kpsewhich, and the bbl files
  515.                    #     appear to be out-of-date.
  516.                    #     Do NOT delete bbl files on clean up.
  517.                    # 1.5:  Run bibtex only if the bibfiles exists
  518.                    #     according to kpsewhich, and the bbl files
  519.                    #     appear to be out-of-date.
  520.                    #     Only delete bbl files on clean up if bibfiles exist.
  521.                    # 2:  Run bibtex when the bbl files are out-of-date
  522.                    #     Delete bbl files on clean up.
  523.                    #
  524.                    # In any event bibtex is only run if the log file
  525.                    #   indicates that the document uses bbl files.
  526.  
  527. ## Command to invoke makeindex
  528. $makeindex  = 'makeindex %O -o %D %S';
  529. # Switch(es) to make makeinex silent:
  530. $makeindex_silent_switch  = '-q';
  531.  
  532. ## Command to convert dvi file to pdf file directly:
  533. $dvipdf  = 'dvipdf %O %S %D';
  534. # N.B. Standard dvipdf runs dvips and gs with their silent switch, so for
  535. #      standard dvipdf $dvipdf_silent_switch is unneeded, but innocuous.
  536. #      But dvipdfmx can be used instead, and it has a silent switch (-q).
  537. #      So implementing $dvipdf_silent_switch is useful.
  538.  
  539. $dvipdf_silent_switch  = '-q';
  540.  
  541. ## Command to convert dvi file to ps file:
  542. $dvips  = 'dvips %O -o %D %S';
  543. ## Command to convert dvi file to ps file in landscape format:
  544. $dvips_landscape = 'dvips -tlandscape %O -o %D %S';
  545. # Switch(es) to get dvips to make ps file suitable for conversion to good pdf:
  546. #    (If this is not used, ps file and hence pdf file contains bitmap fonts
  547. #       (type 3), which look horrible under acroread.  An appropriate switch
  548. #       ensures type 1 fonts are generated.  You can put this switch in the
  549. #       dvips command if you prefer.)
  550. $dvips_pdf_switch = '-P pdf';
  551. # Switch(es) to make dvips silent:
  552. $dvips_silent_switch  = '-q';
  553.  
  554. ## Command to convert ps file to pdf file:
  555. $ps2pdf = 'ps2pdf  %O %S %D';
  556.  
  557. ## Command to convert xdv file to pdf file
  558. $xdvipdfmx  = 'xdvipdfmx -o %D %O %S';
  559. $xdvipdfmx_silent_switch  = '-q';
  560.  
  561.  
  562. ## Command to search for tex-related files
  563. $kpsewhich = 'kpsewhich %S';
  564.  
  565. ## Command to run make:
  566. $make = 'make';
  567.  
  568. ##Printing:
  569. $print_type = 'auto';   # When printing, print the postscript file.
  570.                         # Possible values: 'dvi', 'ps', 'pdf', 'auto', 'none'
  571.                         # 'auto' ==> set print type according to the printable
  572.                         # file(s) being made: priority 'ps', 'pdf', 'dvi'
  573.  
  574. ## Which treatment of default extensions and filenames with
  575. ##   multiple extensions is used, for given filename on
  576. ##   tex/latex's command line?  See sub find_basename for the
  577. ##   possibilities.
  578. ## Current tex's treat extensions like UNIX teTeX:
  579. $extension_treatment = 'unix';
  580.  
  581. # Viewers.  These are system dependent, so default to none:
  582. $pdf_previewer = $ps_previewer  = $ps_previewer_landscape  = $dvi_previewer  = $dvi_previewer_landscape = "NONE";
  583.  
  584. $dvi_update_signal = undef;
  585. $ps_update_signal = undef;
  586. $pdf_update_signal = undef;
  587.  
  588. $dvi_update_command = undef;
  589. $ps_update_command = undef;
  590. $pdf_update_command = undef;
  591.  
  592. $allow_subdir_creation = 1;
  593.  
  594. $new_viewer_always = 0;     # If 1, always open a new viewer in pvc mode.
  595.                             # If 0, only open a new viewer if no previous
  596.                             #     viewer for the same file is detected.
  597.  
  598. # Commands for printing are highly system dependent, so default to NONE:
  599. $lpr = 'NONE $lpr variable is not configured to allow printing of ps files';
  600. $lpr_dvi = 'NONE $lpr_dvi variable is not configured to allow printing of dvi files';
  601. $lpr_pdf = 'NONE $lpr_pdf variable is not configured to allow printing of pdf files';
  602.  
  603.  
  604. # The $pscmd below holds a **system-dependent** command to list running
  605. # processes.  It is used to find the process ID of the viewer looking at
  606. # the current output file.  The output of the command must include the
  607. # process number and the command line of the processes, since the
  608. # relevant process is identified by the name of file to be viewed.
  609. # Its use is not essential.
  610. $pscmd =  'NONE $pscmd variable is not configured to detect running processes';
  611. $pid_position = -1;     # offset of PID in output of pscmd.  
  612.                         # Negative means I cannot use ps
  613.  
  614.  
  615. $quote_filenames = 1;       # Quote filenames in external commands
  616.  
  617. $del_dir = '';        # Directory into which cleaned up files are to be put.
  618.                       # If $del_dir is '', just delete the files
  619.  
  620. @rc_system_files = ();
  621.  
  622. #########################################################################
  623.  
  624. ################################################################
  625. ##  Special variables for system-dependent fudges, etc.
  626. $log_file_binary = 0;   # Whether to treat log file as binary
  627.                         # Normally not, since the log file SHOULD be pure text.
  628.                         # But Miktex 2.7 sometimes puts binary characters
  629.                         #    in it.  (Typically in construct \OML ... after
  630.                         #    overfull box with mathmode.)
  631.                         # Sometimes there is ctrl/Z, which is not only non-text,
  632.                         #    but is end-of-file marker for MS-Win in text mode.  
  633.  
  634. $MSWin_fudge_break = 1; # Give special treatment to ctrl/C and ctrl/break
  635.                         #    in -pvc mode under MSWin
  636.                         # Under MSWin32 (at least with perl 5.8 and WinXP)
  637.                         #   when latexmk is running another program, and the
  638.                         #   user gives ctrl/C or ctrl/break, to stop the
  639.                         #   daughter program, not only does it reach
  640.                         #   the daughter, but also latexmk/perl, so
  641.                         #   latexmk is stopped also.  In -pvc mode,
  642.                         #   this is not normally desired.  So when the
  643.                         #   $MSWin_fudge_break variable is set,
  644.                         #   latexmk arranges to ignore ctrl/C and
  645.                         #   ctrl/break during processing of files;
  646.                         #   only the daughter programs receive them.
  647.                         # This fudge is not applied in other
  648.                         #   situations, since then having latexmk also
  649.                         #   stopping because of the ctrl/C or
  650.                         #   ctrl/break signal is desirable.
  651.                         # The fudge is not needed under UNIX (at least
  652.                         #   with Perl 5.005 on Solaris 8).  Only the
  653.                         #   daughter programs receive the signal.  In
  654.                         #   fact the inverse would be useful: In
  655.                         #   normal processing, as opposed to -pvc, if
  656.                         #   force mode (-f) is set, a ctrl/C is
  657.                         #   received by a daughter program does not
  658.                         #   also stop latexmk.  Under tcsh, we get
  659.                         #   back to a command prompt, while latexmk
  660.                         #   keeps running in the background!
  661.  
  662. ## Substitute backslashes in file and directory names for
  663. ##  MSWin command line
  664. $MSWin_back_slash = 1;
  665.  
  666. ## Separator of elements in search_path.  Default is unix value
  667. $search_path_separator = ':';
  668.  
  669.  
  670. # Directory for temporary files.  Default to current directory.
  671. $tmpdir = ".";
  672.  
  673.  
  674. # When the aux_dir is on a network share (or the like), its system
  675. # time may differ from the system time on which latexmk is running.
  676. # This complicates the tests of whether particular files have been
  677. # made in a current run of a program or are left over from a previous
  678. # run.  One test, which is needed under some situations, is that a
  679. # file was made on a previous run when the files modification time is
  680. # less than the system time when the program is started.  (See
  681. # subroutine test_gen_file; this is only needed in a couple of
  682. # situations.)  The comparison between file and system times must be
  683. # corrected if there is an offset between system times on the computer
  684. # running latexmk and the computer hosting the file system containing
  685. # aux_dir.  The offset is measured in subroutine get_filetime_offset
  686. # by writing a temporary file; the test only needs to be done once.
  687. #
  688. # The following variables are used.  Since the system-independent
  689. # values of system and file time are only accurate to a second (or 2
  690. # seconds for FAT file systems), the offset is also accurate only to a
  691. # second or two.  So thresholds are needed below which differences
  692. # are insignificant.
  693. #
  694. # Note that the making or not making of a file is controlled by the
  695. # state of the document being compiled and by latexmk's configuration.
  696. # So a file that is left over from a previous run and not overwritten
  697. # on the current run will have a file time at least many seconds less
  698. # than the current time, corresponding to the time scale for a human
  699. # run-edit-run cycle.
  700. #
  701. $filetime_offset_measured = 0;       # Measurement not yet done.
  702. $filetime_offset = 0;                # Filetime relative to system time.
  703. $filetime_causality_threshold = 5;   # Threshold for detection of left-over file.
  704.                                      # Should be non-negative always, and should
  705.                                      # be bigger than 2 secs if a remote
  706.                                      # filesystem or network share is used.
  707. $filetime_offset_report_threshold = 30; # Threshold beyond which filetime offsets
  708.                                      # are reported; large offsets indicate
  709.                                      # incorrect system time on at least one system.
  710.  
  711.  
  712. ################################################################
  713.  
  714.  
  715. # System-dependent overrides:
  716. # Currently, the cases I have tests for are: MSWin32, cygwin, linux and
  717. #   darwin, msys, with the main complications being for MSWin32 and cygwin.
  718. # Further special treatment may also be useful for MSYS (for which $^O reports
  719. #   "msys").  This is another *nix-emulation/system for MSWindows.  At
  720. #   present it is treated as unix-like, but the environment variables
  721. #   are those of Windows.  (The test for USERNAME as well as USER was
  722. #   to make latexmk work under MSYS's perl.)
  723. #
  724. if ( $^O eq "MSWin32" ) {
  725. # Pure MSWindows configuration
  726.     ## Configuration parameters:
  727.  
  728.     ## Use first existing case for $tmpdir:
  729.     $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.';
  730.     $log_file_binary = 1;   # Protect against ctrl/Z in log file from
  731.                             # Miktex 2.7.
  732.  
  733.     ## List of possibilities for the system-wide initialization file.  
  734.     ## The first one found (if any) is used.
  735.     @rc_system_files = ( "C:/latexmk/LatexMk", "C:/latexmk/latexmkrc" );
  736.  
  737.     $search_path_separator = ';';  # Separator of elements in search_path
  738.  
  739.     # For a pdf-file, "start x.pdf" starts the pdf viewer associated with
  740.     #   pdf files, so no program name is needed:
  741.     $pdf_previewer = 'start %O %S';
  742.     $ps_previewer  = 'start %O %S';
  743.     $ps_previewer_landscape  = $ps_previewer;
  744.     $dvi_previewer  = 'start %O %S';
  745.     $dvi_previewer_landscape = "$dvi_previewer";
  746.     # Viewer update methods:
  747.     #    0 => auto update: viewer watches file (e.g., gv)
  748.     #    1 => manual update: user must do something: e.g., click on window.
  749.     #         (e.g., ghostview, MSWIN previewers, acroread under UNIX)
  750.     #    2 => send signal.  Number of signal in $dvi_update_signal,
  751.     #                         $ps_update_signal, $pdf_update_signal
  752.     #    3 => viewer can't update, because it locks the file and the file
  753.     #         cannot be updated.  (acroread under MSWIN)
  754.     #    4 => run a command to force the update.  The commands are
  755.     #         specified by the variables $dvi_update_command,
  756.     #         $ps_update_command, $pdf_update_command
  757.     $dvi_update_method = 1;
  758.     $ps_update_method = 1;
  759.     $pdf_update_method = 3; # acroread locks the pdf file
  760. }
  761. elsif ( $^O eq "cygwin" ) {
  762.     # The problem is a mixed MSWin32 and UNIX environment.
  763.     # Perl decides the OS is cygwin in two situations:
  764.     # 1. When latexmk is run from a cygwin shell under a cygwin
  765.     #    environment.  Perl behaves in a UNIX way.  This is OK, since
  766.     #    the user is presumably expecting UNIXy behavior.  
  767.     # 2. When CYGWIN exectuables are in the path, but latexmk is run
  768.     #    from a native NT shell.  Presumably the user is expecting NT
  769.     #    behavior. But perl behaves more UNIXy.  This causes some
  770.     #    clashes.
  771.     # The issues to handle are:
  772.     # 1.  Perl sees both MSWin32 and cygwin filenames.  This is
  773.     #     normally only an advantage.
  774.     # 2.  Perl uses a UNIX shell in the system command
  775.     #     This is a nasty problem: under native NT, there is a
  776.     #     start command that knows about NT file associations, so that
  777.     #     we can do, e.g., (under native NT) system("start file.pdf");
  778.     #     But this won't work when perl has decided the OS is cygwin,
  779.     #     even if it is invoked from a native NT command line.  An
  780.     #     NT command processor must be used to deal with this.
  781.     # 3.  External executables can be native NT (which only know
  782.     #     NT-style file names) or cygwin executables (which normally
  783.     #     know both cygwin UNIX-style file names and NT file names,
  784.     #     but not always; some do not know about drive names, for
  785.     #     example).
  786.     #     Cygwin executables for tex and latex may only know cygwin
  787.     #     filenames.
  788.     # 4.  The BIBINPUTS environment variables may be
  789.     #     UNIX-style or MSWin-style depending on whether native NT or
  790.     #     cygwin executables are used.  They are therefore parsed
  791.     #     differently.  Here is the clash:
  792.     #        a. If a user is running under an NT shell, is using a
  793.     #           native NT installation of tex (e.g., fptex or miktex),
  794.     #           but has the cygwin executables in the path, then perl
  795.     #           detects the OS as cygwin, but the user needs NT
  796.     #           behavior from latexmk.
  797.     #        b. If a user is running under an UNIX shell in a cygwin
  798.     #           environment, and is using the cygwin installation of
  799.     #           tex, then perl detects the OS as cygwin, and the user
  800.     #           needs UNIX behavior from latexmk.
  801.     #     Latexmk has no way of detecting the difference.  The two
  802.     #     situations may even arise for the same user on the same
  803.     #     computer simply by changing the order of directories in the
  804.     #     path environment variable
  805.  
  806.  
  807.     ## Configuration parameters: We'll assume native NT executables.
  808.     ## The user should override if they are not.
  809.  
  810.     # This may fail: perl converts MSWin temp directory name to cygwin
  811.     # format. Names containing this string cannot be handled by native
  812.     # NT executables.
  813.     $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.';
  814.  
  815.     ## List of possibilities for the system-wide initialization file.  
  816.     ## The first one found (if any) is used.
  817.     ## We could stay with MSWin files here, since cygwin perl understands them
  818.     ## @rc_system_files = ( 'C:/latexmk/LatexMk', 'C:/latexmk/latexmkrc' );
  819.     ## But they are deprecated in v. 1.7.  So use the UNIX version, prefixed
  820.     ##   with a cygwin equivalent of the MSWin location
  821.     ## In addition, we need to add the same set of possible locations as with
  822.     ## unix, so that the user use a unix-style setup.
  823.     @rc_system_files = ();
  824.     foreach ( 'LatexMk', 'latexmkrc' ) {
  825.        push @rc_system_files,
  826.             ( "/cygdrive/c/latexmk/$_",
  827.               "/opt/local/share/latexmk/$_",
  828.               "/usr/local/share/latexmk/$_",
  829.               "/usr/local/lib/latexmk/$_" );
  830.     }
  831.     $search_path_separator = ';';  # Separator of elements in search_path
  832.     # This is tricky.  The search_path_separator depends on the kind
  833.     # of executable: native NT v. cygwin.  
  834.     # So the user will have to override this.
  835.  
  836.     # We will assume that files can be viewed by native NT programs.
  837.     #  Then we must fix the start command/directive, so that the
  838.     #  NT-native start command of a cmd.exe is used.
  839.     # For a pdf-file, "start x.pdf" starts the pdf viewer associated with
  840.     #   pdf files, so no program name is needed:
  841.     $start_NT = "cmd /c start \"\"";
  842.     $pdf_previewer = "$start_NT %O %S";
  843.     $ps_previewer  = "$start_NT %O %S";
  844.     $ps_previewer_landscape  = $ps_previewer;
  845.     $dvi_previewer  = "$start_NT %O %S";
  846.     $dvi_previewer_landscape = $dvi_previewer;
  847.     # Viewer update methods:
  848.     #    0 => auto update: viewer watches file (e.g., gv)
  849.     #    1 => manual update: user must do something: e.g., click on window.
  850.     #         (e.g., ghostview, MSWIN previewers, acroread under UNIX)
  851.     #    2 => send signal.  Number of signal in $dvi_update_signal,
  852.     #                         $ps_update_signal, $pdf_update_signal
  853.     #    3 => viewer can't update, because it locks the file and the file
  854.     #         cannot be updated.  (acroread under MSWIN)
  855.     $dvi_update_method = 1;
  856.     $ps_update_method = 1;
  857.     $pdf_update_method = 3; # acroread locks the pdf file
  858. }
  859. elsif ( $^O eq "msys" ) {
  860.     $search_path_separator = ';';  # Separator of elements in search_path
  861.                                    # I think MS-Win value is OK, since
  862.                                    # msys is running under MS-Win
  863.     $pdf_previewer = q[sh -c 'start %S'];
  864.     $ps_previewer = q[sh -c 'start %S'];
  865.     $dvi_previewer = q[sh -c 'start %S'];
  866.     $ps_previewer_landscape  = $ps_previewer;
  867.     $dvi_previewer_landscape = "$dvi_previewer";
  868. }
  869. else {
  870.     # Assume anything else is UNIX or clone
  871.     # Do special cases (e.g., linux, darwin (i.e., OS-X)) inside this block.
  872.  
  873.     ## Use first existing case for $tmpdir:
  874.     $tmpdir = $ENV{TMPDIR} || '/tmp';
  875.  
  876.     ## List of possibilities for the system-wide initialization file.  
  877.     ## The first one found (if any) is used.
  878.     ## Normally on a UNIX it will be in a subdirectory of /opt/local/share or
  879.     ## /usr/local/share, depending on the local conventions.
  880.     ## But /usr/local/lib/latexmk is put in the list for
  881.     ## compatibility with older versions of latexmk.
  882.     @rc_system_files = ();
  883.     foreach ( 'LatexMk', 'latexmkrc' ) {
  884.        push @rc_system_files,
  885.             ( "/opt/local/share/latexmk/$_",
  886.               "/usr/local/share/latexmk/$_",
  887.               "/usr/local/lib/latexmk/$_" );
  888.     }
  889.     $search_path_separator = ':';  # Separator of elements in search_path
  890.  
  891.     $dvi_update_signal = $signo{USR1}
  892.          if ( defined $signo{USR1} ); # Suitable for xdvi
  893.     $ps_update_signal = $signo{HUP}
  894.          if ( defined $signo{HUP} );  # Suitable for gv
  895.     $pdf_update_signal = $signo{HUP}
  896.          if ( defined $signo{HUP} );  # Suitable for gv
  897.     ## default document processing programs.
  898.     # Viewer update methods:
  899.     #    0 => auto update: viewer watches file (e.g., gv)
  900.     #    1 => manual update: user must do something: e.g., click on window.
  901.     #         (e.g., ghostview, MSWIN previewers, acroread under UNIX)
  902.     #    2 => send signal.  Number of signal in $dvi_update_signal,
  903.     #                         $ps_update_signal, $pdf_update_signal
  904.     #    3 => viewer can't update, because it locks the file and the file
  905.     #         cannot be updated.  (acroread under MSWIN)
  906.     #    4 => Run command to update.  Command in $dvi_update_command,
  907.     #    $ps_update_command, $pdf_update_command.
  908.     $dvi_previewer  = 'start xdvi %O %S';
  909.     $dvi_previewer_landscape = 'start xdvi -paper usr %O %S';
  910.     if ( defined $dvi_update_signal ) {
  911.         $dvi_update_method = 2;  # xdvi responds to signal to update
  912.     } else {
  913.         $dvi_update_method = 1;  
  914.     }
  915. #    if ( defined $ps_update_signal ) {
  916. #        $ps_update_method = 2;  # gv responds to signal to update
  917. #        $ps_previewer  = 'start gv -nowatch';
  918. #        $ps_previewer_landscape  = 'start gv -swap -nowatch';
  919. #    } else {
  920. #        $ps_update_method = 0;  # gv -watch watches the ps file
  921. #        $ps_previewer  = 'start gv -watch';
  922. #        $ps_previewer_landscape  = 'start gv -swap -watch';
  923. #    }
  924.     # Turn off the fancy options for gv.  Regular gv likes -watch etc
  925.     #   GNU gv likes --watch etc.  User must configure
  926.     $ps_update_method = 0;  # gv -watch watches the ps file
  927.     $ps_previewer  = 'start gv %O %S';
  928.     $ps_previewer_landscape  = 'start gv -swap %O %S';
  929.     $pdf_previewer = 'start acroread %O %S';
  930.     $pdf_update_method = 1;  # acroread under unix needs manual update
  931.     $lpr = 'lpr %O %S';         # Assume lpr command prints postscript files correctly
  932.     $lpr_dvi =
  933.         'NONE $lpr_dvi variable is not configured to allow printing of dvi files';
  934.     $lpr_pdf =
  935.         'NONE $lpr_pdf variable is not configured to allow printing of pdf files';
  936.     # The $pscmd below holds a command to list running processes.  It
  937.     # is used to find the process ID of the viewer looking at the
  938.     # current output file.  The output of the command must include the
  939.     # process number and the command line of the processes, since the
  940.     # relevant process is identified by the name of file to be viewed.
  941.     # Uses:
  942.     #   1.  In preview_continuous mode, to save running a previewer
  943.     #       when one is already running on the relevant file.
  944.     #   2.  With xdvi in preview_continuous mode, xdvi must be
  945.     #       signalled to make it read a new dvi file.
  946.     #
  947.     # The following works on Solaris, LINUX, HP-UX, IRIX
  948.     # Use -f to get full listing, including command line arguments.
  949.     # Use -u $ENV{USER} to get all processes started by current user (not just
  950.     #   those associated with current terminal), but none of other users'
  951.     #   processes.
  952.     # However, the USER environment variable may not exist.  Windows uses
  953.     #   USERNAME instead.  (And this propagates to a situation of
  954.     #   unix-emulation software running under Windows.)
  955.     if ( exists $ENV{USER} ) {
  956.        $pscmd = "ps -f -u $ENV{USER}";
  957.     }
  958.     elsif ( exists $ENV{USERNAME} ) {
  959.        $pscmd = "ps -f -u $ENV{USERNAME}";
  960.     }
  961.     else {
  962.        $pscmd = "ps -f";
  963.     }
  964.     $pid_position = 1; # offset of PID in output of pscmd; first item is 0.  
  965.     if ( $^O eq "linux" ) {
  966.         # Ps on Redhat (at least v. 7.2) appears to truncate its output
  967.         #    at 80 cols, so that a long command string is truncated.
  968.         # Fix this with the --width option.  This option works under
  969.         #    other versions of linux even if not necessary (at least
  970.         #    for SUSE 7.2).
  971.         # However the option is not available under other UNIX-type
  972.         #    systems, e.g., Solaris 8.
  973.         # But (19 Aug 2010), the truncation doesn't happen on RHEL4 and 5,
  974.         #    unless the output is written to a terminal.  So the --width
  975.         #    option is now unnecessary
  976.         # $pscmd = "ps --width 200 -f -u $ENV{USER}";
  977.     }
  978.     elsif ( $^O eq "darwin" ) {
  979.         # OS-X on Macintosh
  980.         # open starts command associated with a file.
  981.         # For pdf, this is set by default to OS-X's preview, which is suitable.
  982.         #     Manual update is simply by clicking on window etc, which is OK.
  983.         # For ps, this is set also to preview.  This works, but since it
  984.         #     converts the file to pdf and views the pdf file, it doesn't
  985.         #     see updates, and a refresh cannot be done.  This is far from
  986.         #     optimal.
  987.         # For a full installation of MacTeX, which is probably the most common
  988.         #     on OS-X, an association is created between dvi files and TeXShop.
  989.         #     This also converts the file to pdf, so again while it works, it
  990.         #     does not deal with changed dvi files, as far as I can see.
  991.         $pdf_previewer = 'open %S';
  992.         $pdf_update_method = 1;     # manual
  993.         $dvi_previewer = $dvi_previewer_landscape = 'NONE';
  994.         $ps_previewer = $ps_previewer_landscape = 'NONE';
  995.         # Others
  996.         $lpr_pdf  = 'lpr %O %S';
  997.         $pscmd = "ps -ww -u $ENV{USER}";
  998.     }
  999. }
  1000.  
  1001. ## default parameters
  1002. $auto_rc_use = 1;       # Whether to read rc files automatically
  1003. $max_repeat = 5;        # Maximum times I repeat latex.  Normally
  1004.                         # 3 would be sufficient: 1st run generates aux file,
  1005.                         # 2nd run picks up aux file, and maybe toc, lof which
  1006.                         # contain out-of-date information, e.g., wrong page
  1007.                         # references in toc, lof and index, and unresolved
  1008.                         # references in the middle of lines.  But the
  1009.                         # formatting is more-or-less correct.  On the 3rd
  1010.                         # run, the page refs etc in toc, lof, etc are about
  1011.                         # correct, but some slight formatting changes may
  1012.                         # occur, which mess up page numbers in the toc and lof,
  1013.                         # Hence a 4th run is conceivably necessary.
  1014.                         # At least one document class (JHEP.cls) works
  1015.                         # in such a way that a 4th run is needed.  
  1016.                         # We allow an extra run for safety for a
  1017.                         # maximum of 5. Needing further runs is
  1018.                         # usually an indication of a problem; further
  1019.                         # runs may not resolve the problem, and
  1020.                         # instead could cause an infinite loop.
  1021. $clean_ext = "";        # space separated extensions of files that are
  1022.                         # to be deleted when doing cleanup, beyond
  1023.                         # standard set
  1024. $clean_full_ext = "";   # space separated extensions of files that are
  1025.                         # to be deleted when doing cleanup_full, beyond
  1026.                         # standard set and those in $clean_ext
  1027. @cus_dep_list = ();     # Custom dependency list
  1028. @default_files = ( '*.tex' );   # Array of LaTeX files to process when
  1029.                         # no files are specified on the command line.
  1030.                         # Wildcards allowed
  1031.                         # Best used for project specific files.
  1032. @default_excluded_files = ( );  
  1033.                         # Array of LaTeX files to exclude when using
  1034.                         # @default_files, i.e., when no files are specified
  1035.                         # on the command line.
  1036.                         # Wildcards allowed
  1037.                         # Best used for project specific files.
  1038. $texfile_search = "";   # Specification for extra files to search for
  1039.                         # when no files are specified on the command line
  1040.                         # and the @default_files variable is empty.
  1041.                         # Space separated, and wildcards allowed.
  1042.                         # These files are IN ADDITION to *.tex in current
  1043.                         # directory.
  1044.                         # This variable is obsolete, and only in here for
  1045.                         # backward compatibility.
  1046.  
  1047. $fdb_ext = 'fdb_latexmk'; # Extension for the file for latexmk's
  1048.                           # file-database
  1049.                           # Make it long to avoid possible collisions.
  1050. $fdb_ver = 3;             # Version number for kind of fdb_file.
  1051.  
  1052. $jobname = '';          # Jobname: as with current tex, etc indicates
  1053.                         # basename of generated files.
  1054.                         # Defined so that --jobname=STRING on latexmk's
  1055.                         # command line has same effect as with current
  1056.                         # tex, etc.  (If $jobname is non-empty, then
  1057.                         # the --jobname=... option is used on tex.)
  1058. $out_dir = '';          # Directory for output files.  
  1059.                         # Cf. --output-directory of current (pdf)latex
  1060. $aux_dir = '';          # Directory for aux files (log, aux, etc).
  1061.                         # Cf. --aux-directory of current (pdf)latex in MiKTeX.
  1062.  
  1063.  
  1064. ## default flag settings.
  1065. $recorder = 1;          # Whether to use recorder option on latex/pdflatex
  1066. $silent = 0;            # Silence latex's messages?
  1067. $silence_logfile_warnings = 0; # Do list warnings in log file
  1068. $kpsewhich_show = 0;    # Show calls to and results from kpsewhich
  1069. $landscape_mode = 0;    # default to portrait mode
  1070. $analyze_input_log_always = 1; # Always analyze .log for input files in the
  1071.                         #  <...> and (...) constructions.  Otherwise, only
  1072.                         # do the analysis when fls file doesn't exist or is
  1073.                         # out of date.
  1074.                         # Under normal circumstances, the data in the fls file
  1075.                         # is reliable, and the test of the log file gets lots
  1076.                         # of false positives; usually $analyze_input_log_always
  1077.                         # is best set to zero.  But the test of the log file
  1078.                         # is needed at least in the following situation:
  1079.                         # When a user needs to persuade latexmk that a certain
  1080.                         # file is a source file, and latexmk doesn't otherwise
  1081.                         # find it.  User code causes line with (...) to be
  1082.                         # written to log file.  One important case is for
  1083.                         # lualatex, which doesn't always generate lines in the
  1084.                         # .fls file for input lua files.  (The situation with
  1085.                         # lualatex is HIGHLY version dependent, e.g., between
  1086.                         # 2016 and 2017.)
  1087.                         # To keep backward compatibility with older versions
  1088.                         # of latexmk, the default is to set
  1089.                         # $analyze_input_log_always to 1.
  1090.  
  1091. # The following two arrays contain lists of extensions (without
  1092. # period) for files that are read in during a (pdf)LaTeX run but that
  1093. # are generated automatically from the previous run, as opposed to
  1094. # being user generated files (directly or indirectly from a custom
  1095. # dependency).  These files get two kinds of special treatment:
  1096. #     1.  In clean up, where depending on the kind of clean up, some
  1097. #         or all of these generated files are deleted.
  1098. #         (Note that special treatment is given to aux files.)
  1099. #     2.  In analyzing the results of a run of (pdf)LaTeX, to
  1100. #         determine if another run is needed.  With an error free run,
  1101. #         a rerun should be provoked by a change in any source file,
  1102. #         whether a user file or a generated file.  But with a run
  1103. #         that ends in an error, only a change in a user file during
  1104. #         the run (which might correct the error) should provoke a
  1105. #         rerun, but a change in a generated file should not.
  1106. # These arrays can be user-configured.
  1107.  
  1108. @generated_exts = ( 'aux', 'bcf', 'fls', 'idx', 'ind', 'lof', 'lot',
  1109.                     'out', 'toc' );
  1110.      # N.B. 'out' is generated by hyperref package
  1111.  
  1112. # Which kinds of file do I have requests to make?
  1113. # If no requests at all are made, then I will make dvi file
  1114. # If particular requests are made then other files may also have to be
  1115. # made.  E.g., ps file requires a dvi file
  1116. $dvi_mode = 0;          # No dvi file requested
  1117. $postscript_mode = 0;           # No postscript file requested
  1118. $pdf_mode = 0;          # No pdf file requested to be made by pdflatex
  1119.                         # Possible values:
  1120.                         #     0 don't create pdf file
  1121.                         #     1 to create pdf file by pdflatex
  1122.                         #     2 to create pdf file by ps2pdf
  1123.                         #     3 to create pdf file by dvipdf
  1124.                         #     4 to create pdf file by lualatex
  1125.                         #     5 to create pdf file by xelatex + xdvipdfmx
  1126. $view = 'default';      # Default preview is of highest of dvi, ps, pdf
  1127. $sleep_time = 2;        # time to sleep b/w checks for file changes in -pvc mode
  1128. $banner = 0;            # Non-zero if we have a banner to insert
  1129. $banner_scale = 220;    # Original default scale
  1130. $banner_intensity = 0.95;  # Darkness of the banner message
  1131. $banner_message = 'DRAFT'; # Original default message
  1132. $do_cd = 0;     # Do not do cd to directory of source file.
  1133.                 #   Thus behave like latex.
  1134. $dependents_list = 0;   # Whether to display list(s) of dependencies
  1135. $dependents_phony = 0;  # Whether list(s) of dependencies includes phony targets
  1136.                         # (as with 'gcc -MP').
  1137. $deps_file = '-';       # File for dependency list output.  Default stdout.
  1138. $rules_list = 0;        # Whether to display list(s) of dependencies
  1139. @dir_stack = ();        # Stack of pushed directories, each of form of
  1140.                         # pointer to array  [ cwd, good_cwd ], where
  1141.                         # good_cwd differs from cwd by being converted
  1142.                         # to native MSWin path when cygwin is used.
  1143. $cleanup_mode = 0;      # No cleanup of nonessential LaTex-related files.
  1144.                         # $cleanup_mode = 0: no cleanup
  1145.                         # $cleanup_mode = 1: full cleanup
  1146.                         # $cleanup_mode = 2: cleanup except for dvi,
  1147.                         #                    dviF, pdf, ps, psF & xdv
  1148. $cleanup_fdb  = 0;      # No removal of file for latexmk's file-database
  1149. $cleanup_only = 0;      # When doing cleanup, do not go on to making files
  1150. $cleanup_includes_generated = 0;
  1151.                         # Determines whether cleanup deletes files generated by
  1152.                         #    custom dependencies
  1153. $cleanup_includes_cusdep_generated = 0;
  1154.                         # Determines whether cleanup deletes files generated by
  1155.                         #    (pdf)latex (found from \openout lines in log file).
  1156. $diagnostics = 0;
  1157. $dvi_filter = '';       # DVI filter command
  1158. $ps_filter = '';        # Postscript filter command
  1159.  
  1160. $force_mode = 0;        # =1 to force processing past errors
  1161. $go_mode = 0;           # =1 to force processing regardless of time-stamps
  1162.                         # =2 full clean-up first
  1163. $preview_mode = 0;
  1164. $preview_continuous_mode  = 0;
  1165. $printout_mode = 0;     # Don't print the file
  1166.  
  1167. ## Control pvc inactivity timeout:
  1168. $pvc_timeout = 0;
  1169. $pvc_timeout_mins = 30;
  1170.  
  1171. $show_time = 0;
  1172. @timings = ();
  1173. $processing_time1 = processing_time();
  1174.  
  1175. $use_make_for_missing_files = 0;   # Whether to use make to try to make missing files.
  1176.  
  1177. # Do we make view file in temporary then move to final destination?
  1178. #  (To avoid premature updating by viewer).
  1179. $always_view_file_via_temporary = 0;      # Set to 1 if  viewed file is always
  1180.                                    #    made through a temporary.
  1181. $pvc_view_file_via_temporary = 1;  # Set to 1 if only in -pvc mode is viewed
  1182.                                    #    file made through a temporary.
  1183.  
  1184. # State variables initialized here:
  1185.  
  1186. $updated = 0;           # Flags when something has been remade
  1187.                         # Used to allow convenient user message in -pvc mode
  1188. $waiting = 0;           # Flags whether we are in loop waiting for an event
  1189.                         # Used to avoid unnecessary repeated o/p in wait loop
  1190.  
  1191. # Used for some results of parsing log file:
  1192. $reference_changed = 0;
  1193. $mult_defined = 0;
  1194. $bad_reference = 0;
  1195. $bad_citation = 0;
  1196.  
  1197. # Cache of expensive-to-compute state variables, e.g., cwd in form
  1198. # fixed to deal with cygwin issues.
  1199. %cache = ();
  1200. &cache_good_cwd;
  1201.  
  1202. # Set search paths for includes.
  1203. # Set them early so that they can be overridden
  1204. $BIBINPUTS = $ENV{'BIBINPUTS'};
  1205. if (!$BIBINPUTS) { $BIBINPUTS = '.'; }
  1206.  
  1207. # Convert search paths to arrays:
  1208. # If any of the paths end in '//' then recursively search the
  1209. # directory.  After these operations, @BIBINPUTS  should
  1210. # have all the directories that need to be searched
  1211.  
  1212. @BIBINPUTS = find_dirs1( $BIBINPUTS );
  1213.  
  1214.  
  1215. ######################################################################
  1216. ######################################################################
  1217. #
  1218. #  ???  UPDATE THE FOLLOWING!!
  1219. #
  1220. # We will need to determine whether source files for runs of various
  1221. # programs are out of date.  In a normal situation, this is done by
  1222. # asking whether the times of the source files are later than the
  1223. # destination files.  But this won't work for us, since a common
  1224. # situation is that a file is written on one run of latex, for
  1225. # example, and read back in on the next run (e.g., an .aux file).
  1226. # Some situations of this kind are standard in latex generally; others
  1227. # occur with particular macro packages or with particular
  1228. # postprocessors.
  1229. #
  1230. # The correct criterion for whether a source is out-of-date is
  1231. # therefore NOT that its modification time is later than the
  1232. # destination file, but whether the contents of the source file have
  1233. # changed since the last successful run.  This also handles the case
  1234. # that the user undoes some changes to a source file by replacing the
  1235. # source file by reverting to an earlier version, which may well have
  1236. # an older time stamp.  Since a direct comparison of old and new files
  1237. # would involve storage and access of a large number of backup files,
  1238. # we instead use the md5 signature of the files.  (Previous versions
  1239. # of latexmk used the backup file method, but restricted to the case
  1240. # of .aux and .idx files, sufficient for most, but not all,
  1241. # situations.)
  1242. #
  1243. # We will have a database of (time, size, md5) for the relevant
  1244. # files. If the time and size of a file haven't changed, then the file
  1245. # is assumed not to have changed; this saves us from having to
  1246. # determine its md5 signature, which would involve reading the whole
  1247. # file, which is naturally time-consuming, especially if network file
  1248. # access to a server is needed, and many files are involved, when most
  1249. # of them don't change.  It is of course possible to change a file
  1250. # without changing its size, but then to adjust its timestamp
  1251. # to what it was previously; this requires a certain amount of
  1252. # perversity.  We can safely assume that if the user edits a file or
  1253. # changes its contents, then the file's timestamp changes.  The
  1254. # interesting case is that the timestamp does change, because the file
  1255. # has actually been written to, but that the contents do not change;
  1256. # it is for this that we use the md5 signature.  However, since
  1257. # computing the md5 signature involves reading the whole file, which
  1258. # may be large, we should avoid computing it more than necessary.
  1259. #
  1260. # So we get the following structure:
  1261. #
  1262. #     1.  For each relevant run (latex, pdflatex, each instance of a
  1263. #         custom dependency) we have a database of the state of the
  1264. #         source files that were last used by the run.
  1265. #     2.  On an initial startup, the database for a primary tex file
  1266. #         is read that was created by a previous run of latex or
  1267. #         pdflatex, if this exists.  
  1268. #     3.  If the file doesn't exist, then the criterion for
  1269. #         out-of-dateness for an initial run is that it goes by file
  1270. #         timestamps, as in previous versions of latexmk, with due
  1271. #         (dis)regard to those files that are known to be generated by
  1272. #         latex and re-read on the next run.
  1273. #     4.  Immediately before a run, the database is updated to
  1274. #         represent the current conditions of the run's source files.
  1275. #     5.  After the run, it is determined whether any of the source
  1276. #         files have changed.  This covers both files written by the
  1277. #         run, which are therefore in a dependency loop, and files that
  1278. #         the user may have updated during the run.  (The last often
  1279. #         happens when latex takes a long time, for a big document,
  1280. #         and the user makes edits before latex has finished.  This is
  1281. #         particularly prevalent when latexmk is used with
  1282. #         preview-continuous mode.)
  1283. #     6.  In the case of latex or pdflatex, the custom dependencies
  1284. #         must also be checked and redone if out-of-date.
  1285. #     7.  If any source files have changed, the run is redone,
  1286. #         starting at step 1.
  1287. #     8.  There is naturally a limit on the number of reruns, to avoid
  1288. #         infinite loops from bugs and from pathological or unforeseen
  1289. #         conditions.
  1290. #     9.  After the run is done, the run's file database is updated.
  1291. #         (By hypothesis, the sizes and md5s are correct, if the run
  1292. #         is successful.)
  1293. #    10.  To allow reuse of data from previous runs, the file database
  1294. #         is written to a file after every complete set of passes
  1295. #         through latex or pdflatex.  (Note that there is separate
  1296. #         information for latex and pdflatex; the necessary
  1297. #         information won't coincide: Out-of-dateness for the files
  1298. #         for each program concerns the properties of the files when
  1299. #         the other program was run, and the set of source files could
  1300. #         be different, e.g., for graphics files.)  
  1301. #
  1302. # We therefore maintain the following data structures.:
  1303. #
  1304. #     a.  For each run (latex, pdflatex, each custom dependency) a
  1305. #         database is maintained.  This is a hash from filenames to a
  1306. #         reference to an array:  [time, size, md5].  The semantics of
  1307. #         the database is that it represents the state of the source
  1308. #         files used in the run.  During a run it represents the state
  1309. #         immediately before the run; after a run, with all reruns, it
  1310. #         represents the state of the files used, modified by having
  1311. #         the latest timestamps for generated files.
  1312. #     b.  There is a global database for all files, which represents
  1313. #         the current state.  This saves having to recompute the md5
  1314. #         signatures of a changed file used in more than one run
  1315. #         (e.g., latex and pdflatex).
  1316. #     c.  Each of latex and pdflatex has a list of the relevant custom
  1317. #         dependencies.
  1318. #
  1319. # In all the following a fdb-hash is a hash of the form:
  1320. #                      filename -> [time, size, md5]
  1321. # If a file is found to disappear, its entry is removed from the hash.
  1322. # In returns from fdb access routines, a size entry of -1 indicates a
  1323. # non-existent file.
  1324.  
  1325.  
  1326. # List of known rules.  Rule types: primary,
  1327. #     external (calls program), internal (calls routine), cusdep.
  1328.  
  1329. %possible_primaries = ( 'latex'  => 'primary',  'pdflatex'  => 'primary',
  1330.                         'lualatex'  => 'primary', 'xelatex'  => 'primary' );
  1331. %primaries = ();    # Hash of rules for primary part of make.  Keys are
  1332.                     # currently 'latex', 'pdflatex' or both; also 'lualatex'
  1333.                     # and 'xelatex'.  Value is currently irrelevant.
  1334.                     # Use hash for ease of lookup
  1335.    # Make remove this later, if use rdb_makeB
  1336.  
  1337. # Hashes, whose keys give names of particular kinds of rule.  We use
  1338. # hashes for ease of lookup.
  1339. %possible_one_time = ( 'view' => 1, 'print' => 1, 'update_view' => 1,  );
  1340. %requested_filerules = ();  # Hash for rules corresponding to requested files.  
  1341.                     # The keys are the rulenames and the value is
  1342.                     # currently irrelevant.
  1343. %one_time = ();     # Hash for requested one-time-only rules, currently
  1344.                     # possible values 'print' and 'view'.  
  1345.  
  1346.  
  1347. %rule_db = ();      # Database of all rules:
  1348.                     # Hash: rulename -> [array of rule data]
  1349.                     # Rule data:
  1350.                     #   0: [ cmd_type, ext_cmd, int_cmd, test_kind,
  1351.                     #       source, dest, base,
  1352.                     #       out_of_date, out_of_date_user,
  1353.                     #       time_of_last_run, time_of_last_file_check,
  1354.                     #       changed
  1355.                     #       last_result, last_message,
  1356.                     #       default_extra_generated
  1357.                     #      ]
  1358.                     # where
  1359.                     #     cmd_type is 'primary', 'external', or 'cusdep'
  1360.                     #     ext_cmd is string for associated external command
  1361.                     #       with substitutions (%D for destination, %S
  1362.                     #       for source, %B for base of current rule,
  1363.                     #       %R for base of primary tex file, %T for
  1364.                     #       texfile name, %O for options,
  1365.                     #       %Y for $aux_dir1, and %Z for $out_dir1
  1366.                     #     int_cmd specifies any internal command to be
  1367.                     #       used to implement the application of the
  1368.                     #       rule.  If this is present, it overrides
  1369.                     #       the external command, and it is the
  1370.                     #       responsibility of the perl subroutine
  1371.                     #       specified in intcmd to execute the
  1372.                     #       external command if this is appropriate.
  1373.                     #       This variable intcmd is a reference to an array,  
  1374.                     #       $$intcmd[0] = internal routine
  1375.                     #       $$intcmd[1...] = its arguments (if any)
  1376.                     #     test_kind specifies method of determining
  1377.                     #       whether a file is out-of-date:
  1378.                     #         0 for never
  1379.                     #         1 for usual: whether there is a source
  1380.                     #              file change
  1381.                     #         2 for dest earlier than source
  1382.                     #         3 for method 2 at first run, 1 thereafter
  1383.                     #              (used when don't have file data from
  1384.                     #              previous run).
  1385.                     #     source = name of primary source file, if any
  1386.                     #     dest   = name of primary destination file,
  1387.                     #              if any
  1388.                     #     base   = base name, if any, of files for
  1389.                     #              this rule
  1390.                     #     out_of_date = 1 if it has been detected that
  1391.                     #                     this rule needs to be run
  1392.                     #                     (typically because a source
  1393.                     #                     file has changed).
  1394.                     #                   0 otherwise
  1395.                     #     out_of_date_user is like out_of_date, except
  1396.                     #         that the detection of out-of-dateness
  1397.                     #         has been made from a change of a
  1398.                     #         putative user file, i.e., one that is
  1399.                     #         not a generated file (e.g., aux). This
  1400.                     #         kind of out-of-dateness should provoke a
  1401.                     #         rerun whether or not there was an error
  1402.                     #         during a run of (pdf)LaTeX.  Normally,
  1403.                     #         if there is an error, one should wait
  1404.                     #         for the user to correct the error.  But
  1405.                     #         it is possible the error condition is
  1406.                     #         already corrected during the run, e.g.,
  1407.                     #         by the user changing a source file in
  1408.                     #         response to an error message.
  1409.                     #     time_of_last_run = time that this rule was
  1410.                     #              last applied.  (In standard units
  1411.                     #              from perl, to be directly compared
  1412.                     #              with file modification times.)
  1413.                     #     time_of_last_file_check = last time that a check
  1414.                     #              was made for changes in source files.
  1415.                     #     changed flags whether special changes have been made
  1416.                     #          that require file-existence status to be ignored
  1417.                     #     last_result is
  1418.                     #                 -1 if no run has been made,
  1419.                     #                  0 if the last run was successful
  1420.                     #                  1 if last run was successful, but
  1421.                     #                    failed to create an output file
  1422.                     #                  2 if last run failed
  1423.                     #                  200 if last run gave a warning that is
  1424.                     #                    important enough to be reported with
  1425.                     #                    the error summary.  The warning
  1426.                     #                    message is stored in last_message.
  1427.                     #     last_message is error message for last run
  1428.                     #     default_extra_generated is a reference to an array
  1429.                     #       of specifications of extra generated files (beyond
  1430.                     #       the main dest file.  Standard place holders are used.
  1431.                     #       Example ['%Y%R.log'] for (pdf)latex, and ['%R.blg']
  1432.                     #          for bibtex.  (There's no need for '%R.aux', here,
  1433.                     #          since such generated files are detected dynamically.)
  1434.                     #   1: {Hash sourcefile -> [source-file data] }
  1435.                     # Source-file data array:
  1436.                     #   0: time
  1437.                     #   1: size
  1438.                     #   2: md5
  1439.                     #   3: name of rule to make this file
  1440.                     #   4: whether the file is of the kind made by epstopdf.sty
  1441.                     #      during a primary run.  It will have been read during
  1442.                     #      the run, so that even though the file changes during
  1443.                     #      a primary run, there is no need to trigger another
  1444.                     #      run because of this.
  1445.                     #  Size and md5 correspond to the values at the last run.
  1446.                     #  But time may be updated to correspond to the time
  1447.                     #  for the file, if the file is otherwise unchanged.
  1448.                     #  This saves excessive md5 calculations, which would
  1449.                     #  otherwise be done everytime the file is checked,
  1450.                     #  in the following situation:
  1451.                     #     When the file has been rewritten after a run
  1452.                     #     has started (commonly aux, bbl files etc),
  1453.                     #     but the actual file contents haven't
  1454.                     #     changed.  Then because the filetime has
  1455.                     #     changed, on every file-change check latexmk
  1456.                     #     would normally redo the md5 calculation to
  1457.                     #     test for actual changes.  Once one such
  1458.                     #     check is done, and the contents are
  1459.                     #     unchanged, later checks are superfluous, and
  1460.                     #     can be avoided by changing the file's time
  1461.                     #     in the source-file list.
  1462.                     #   2: {Hash generated_file -> 1 }
  1463.                     #      This lists all generated files; the values
  1464.                     #          are currently unused, only the keys
  1465.  
  1466. %fdb_current = ();  # Fdb-hash for all files used.
  1467.  
  1468.  
  1469. # User's home directory
  1470. $HOME = '';
  1471. if (exists $ENV{'HOME'} ) {
  1472.     $HOME = $ENV{'HOME'};
  1473. }
  1474. elsif (exists $ENV{'USERPROFILE'} ) {
  1475.     $HOME = $ENV{'USERPROFILE'};
  1476. }
  1477. # XDG configuration home
  1478. $XDG_CONFIG_HOME = '';
  1479. if (exists $ENV{'XDG_CONFIG_HOME'} ) {
  1480.     $XDG_CONFIG_HOME = $ENV{'XDG_CONFIG_HOME'};
  1481. }
  1482. elsif ($HOME ne '') {
  1483.     if ( -d "$HOME/.config") {
  1484.         $XDG_CONFIG_HOME = "$HOME/.config";
  1485.     }
  1486. }
  1487.  
  1488.  
  1489. #==================================================
  1490.  
  1491. # Options that are to be obeyed before rc files are read:
  1492.  
  1493. foreach $_ ( @ARGV )
  1494. {
  1495.     if (/^-{1,2}norc$/ ) {
  1496.         $auto_rc_use = 0;
  1497.     }
  1498. }
  1499.  
  1500. #==================================================
  1501. ## Read rc files with this subroutine
  1502.  
  1503. sub read_first_rc_file_in_list {
  1504.     foreach my $rc_file ( @_ ) {
  1505.         #print "===Testing for rc file \"$rc_file\" ...\n";
  1506.         if ( -d $rc_file ) {
  1507.             warn "$My_name: I have found a DIRECTORY named \"$rc_file\".\n",
  1508.                  "   Have you perhaps misunderstood latexmk's documentation?\n",
  1509.                  "   This name is normally used for a latexmk configuration (rc) file,\n",
  1510.                  "   and in that case it should be a regular text file, not a directory.\n";
  1511.         }
  1512.         elsif ( -e $rc_file ) {
  1513.             #print "===Reading rc file \"$rc_file\" ...\n";
  1514.             process_rc_file( $rc_file );
  1515.             return;
  1516.         }
  1517.     }
  1518. }
  1519.  
  1520. # Note that each rc file may unset $auto_rc_use to
  1521. # prevent lower-level rc files from being read.
  1522. # So test on $auto_rc_use in each case.
  1523. if ( $auto_rc_use ) {
  1524.     # System rc file:
  1525.     read_first_rc_file_in_list( @rc_system_files );
  1526. }
  1527. if ( $auto_rc_use && ($HOME ne "" ) ) {
  1528.     # User rc file:
  1529.     @user_rc = ();
  1530.     if ( $XDG_CONFIG_HOME ) {
  1531.        push @user_rc, "$XDG_CONFIG_HOME/latexmk/latexmkrc";
  1532.     }
  1533.     # N.B. $HOME equals "" if latexmk couldn't determine a home directory.
  1534.     # In that case, we shouldn't look for an rc file there.
  1535.     if ( $HOME ) {
  1536.        push @user_rc, "$HOME/.latexmkrc";
  1537.     }
  1538.     read_first_rc_file_in_list( @user_rc );
  1539. }
  1540. if ( $auto_rc_use ) {
  1541.     # Rc file in current directory:
  1542.     read_first_rc_file_in_list( "latexmkrc", ".latexmkrc" );
  1543. }
  1544.  
  1545. ## Process command line args.
  1546. @command_line_file_list = ();
  1547. $bad_options = 0;
  1548.  
  1549. while ($_ = $ARGV[0])
  1550. {
  1551.   # Make -- and - equivalent at beginning of option,
  1552.   # but save original for possible use in (pdf)latex command line
  1553.   $original = $_;
  1554.   s/^--/-/;
  1555.   shift;
  1556.   if ( /^-aux-directory=(.*)$/ || /^-auxdir=(.*)$/ ) {
  1557.       $aux_dir = $1;
  1558.   }
  1559.   elsif (/^-bibtex$/) { $bibtex_use = 2; }
  1560.   elsif (/^-bibtex-$/) { $bibtex_use = 0; }
  1561.   elsif (/^-nobibtex$/) { $bibtex_use = 0; }
  1562.   elsif (/^-bibtex-cond$/) { $bibtex_use = 1; }
  1563.   elsif (/^-bibtex-cond1$/) { $bibtex_use = 1.5; }
  1564.   elsif (/^-c$/)        { $cleanup_mode = 2; $cleanup_fdb = 1; $cleanup_only = 1; }
  1565.   elsif (/^-C$/ || /^-CA$/ ) { $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 1; }
  1566.   elsif (/^-CF$/)    { $cleanup_fdb = 1; }
  1567.   elsif (/^-cd$/)    { $do_cd = 1; }
  1568.   elsif (/^-cd-$/)   { $do_cd = 0; }
  1569.   elsif (/^-commands$/) { &print_commands; exit; }
  1570.   elsif (/^-d$/)     { $banner = 1; }
  1571.   elsif (/^-dependents$/ || /^-deps$/ || /^-M$/ ) { $dependents_list = 1; }
  1572.   elsif (/^-nodependents$/ || /^-dependents-$/ || /^-deps-$/) { $dependents_list = 0; }
  1573.   elsif (/^-deps-out=(.*)$/) {
  1574.       $deps_file = $1;
  1575.       $dependents_list = 1;
  1576.   }
  1577.   elsif (/^-diagnostics/) { $diagnostics = 1; }
  1578.   elsif (/^-dvi$/)   { $dvi_mode = 1; }
  1579.   elsif (/^-dvi-$/)  { $dvi_mode = 0; }
  1580.   elsif (/^-f$/)     { $force_mode = 1; }
  1581.   elsif (/^-f-$/)    { $force_mode = 0; }
  1582.   elsif (/^-g$/)     { $go_mode = 1; }
  1583.   elsif (/^-g-$/)    { $go_mode = 0; }
  1584.   elsif (/^-gg$/)    {
  1585.      $go_mode = 2; $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 0;
  1586.   }
  1587.   elsif ( /^-h$/ || /^-help$/ )   { &print_help; exit;}
  1588.   elsif (/^-jobname=(.*)$/) {
  1589.       $jobname = $1;
  1590.   }
  1591.   elsif (/^-l$/)     { $landscape_mode = 1; }
  1592.   elsif (/^-l-$/)    { $landscape_mode = 0; }
  1593.   elsif (/^-latex=(.*)$/) {
  1594.       $latex = $1;
  1595.   }
  1596.   elsif (/^-latexoption=(.*)$/) {
  1597.       push @extra_latex_options, $1;
  1598.       push @extra_pdflatex_options, $1;
  1599.       push @extra_lualatex_options, $1;
  1600.       push @extra_xelatex_options, $1;
  1601.   }
  1602.   elsif ( /^-logfilewarninglist$/ || /^-logfilewarnings$/ )
  1603.       { $silence_logfile_warnings = 0; }
  1604.   elsif ( /^-logfilewarninglist-$/ || /^-logfilewarnings-$/ )
  1605.       { $silence_logfile_warnings = 1; }
  1606. # See above for -M
  1607.   elsif (/^-MF$/) {
  1608.      if ( $ARGV[0] eq '' ) {
  1609.         &exit_help( "No file name specified after -MF switch");
  1610.      }
  1611.      $deps_file = $ARGV[0];
  1612.      shift;
  1613.   }
  1614.   elsif ( /^-MP$/ ) { $dependents_phony = 1; }
  1615.   elsif (/^-new-viewer$/) {
  1616.       $new_viewer_always = 1;
  1617.   }
  1618.   elsif (/^-new-viewer-$/) {
  1619.       $new_viewer_always = 0;
  1620.   }
  1621.   elsif (/^-norc$/ ) {
  1622.       $auto_rc_use = 0;
  1623.       # N.B. This has already been obeyed.
  1624.   }
  1625.   elsif ( /^-output-directory=(.*)$/ ||/^-outdir=(.*)$/ ) {
  1626.       $out_dir = $1;
  1627.   }
  1628.   elsif (/^-p$/)     { $printout_mode = 1;
  1629.                        $preview_continuous_mode = 0; # to avoid conflicts
  1630.                        $preview_mode = 0;  
  1631.                      }
  1632.   elsif (/^-p-$/)    { $printout_mode = 0; }
  1633.   elsif (/^-pdf$/)   { $pdf_mode = 1; }
  1634.   elsif (/^-pdf-$/)  { $pdf_mode = 0; }
  1635.   elsif (/^-pdfdvi$/){ $pdf_mode = 3; }
  1636.   elsif (/^-pdflua$/){ $pdf_mode = 4; }
  1637.   elsif (/^-pdfxe$/) { $pdf_mode = 5; }
  1638. #  elsif (/^-pdflatex$/) {
  1639. #      $pdflatex = "pdflatex %O %S";
  1640. #      $pdf_mode = 1;
  1641. #      $dvi_mode = $postscript_mode = 0;
  1642. #  }
  1643.   elsif (/^-pdflatex=(.*)$/) {
  1644.       $pdflatex = $1;
  1645.   }
  1646.   elsif (/^-pdfps$/) { $pdf_mode = 2; }
  1647.   elsif (/^-print=(.*)$/) {
  1648.       $value = $1;
  1649.       if ( $value =~ /^dvi$|^ps$|^pdf$|^auto$/ ) {
  1650.           $print_type = $value;
  1651.           $printout_mode = 1;
  1652.       }
  1653.       else {
  1654.           &exit_help("$My_name: unknown print type '$value' in option '$_'");
  1655.       }
  1656.   }
  1657.   elsif (/^-ps$/)    { $postscript_mode = 1; }
  1658.   elsif (/^-ps-$/)   { $postscript_mode = 0; }
  1659.   elsif (/^-pv$/)    { $preview_mode = 1;
  1660.                        $preview_continuous_mode = 0; # to avoid conflicts
  1661.                        $printout_mode = 0;
  1662.                      }
  1663.   elsif (/^-pv-$/)   { $preview_mode = 0; }
  1664.   elsif (/^-pvc$/)   { $preview_continuous_mode = 1;
  1665.                        $force_mode = 0;    # So that errors do not cause loops
  1666.                        $preview_mode = 0;  # to avoid conflicts
  1667.                        $printout_mode = 0;
  1668.                      }
  1669.   elsif (/^-pvc-$/)  { $preview_continuous_mode = 0; }
  1670.   elsif (/^-pvctimeout$/) { $pvc_timeout = 1; }
  1671.   elsif (/^-pvctimeout-$/) { $pvc_timeout = 0; }
  1672.   elsif (/^-pvctimeoutmins=(.*)$/) { $pvc_timeout_mins = $1; }
  1673.   elsif (/^-recorder$/ ){ $recorder = 1; }
  1674.   elsif (/^-recorder-$/ ){ $recorder = 0; }
  1675.   elsif (/^-rules$/ ) { $rules_list = 1; }
  1676.   elsif (/^-norules$/ || /^-rules-$/ ) { $rules_list = 0; }
  1677.   elsif (/^-showextraoptions$/) {
  1678.      print "List of extra latex and pdflatex options recognized by $my_name.\n",
  1679.            "These are passed as is to (pdf)latex.  They may not be recognized by\n",
  1680.            "particular versions of (pdf)latex.  This list is a combination of those\n",
  1681.            "for TeXLive and MikTeX.\n",
  1682.            "\n",
  1683.            "Note that in addition to the options in this list, there are several\n",
  1684.            "options known to the (pdf)latex programs that are also recognized by\n",
  1685.            "latexmk and trigger special behavior by latexmk.  Since these options\n",
  1686.            "appear in the main list given by running 'latexmk --help', they do not\n",
  1687.        "appear in the following list\n",
  1688.        "NOTE ALSO: Not all of these options are supported by all versions of (pdf)latex.\n",
  1689.            "\n";
  1690.      foreach $option ( sort( keys %allowed_latex_options, keys %allowed_latex_options_with_arg ) ) {
  1691.        if (exists $allowed_latex_options{$option} ) { print "   $allowed_latex_options{$option}\n"; }
  1692.        if (exists $allowed_latex_options_with_arg{$option} ) { print "   $allowed_latex_options_with_arg{$option}\n"; }
  1693.      }
  1694.      exit;
  1695.   }
  1696.   elsif (/^-silent$/ || /^-quiet$/ ){ $silent = 1; }
  1697.   elsif (/^-time$/) { $show_time = 1;}
  1698.   elsif (/^-time-$/) { $show_time = 0;}
  1699.   elsif (/^-use-make$/)  { $use_make_for_missing_files = 1; }
  1700.   elsif (/^-use-make-$/)  { $use_make_for_missing_files = 0; }
  1701.   elsif (/^-v$/ || /^-version$/)   {
  1702.       print "\n$version_details. Version $version_num\n";
  1703.       exit;
  1704.   }
  1705.   elsif (/^-verbose$/)  { $silent = 0; }
  1706.   elsif (/^-view=default$/) { $view = "default";}
  1707.   elsif (/^-view=dvi$/)     { $view = "dvi";}
  1708.   elsif (/^-view=none$/)    { $view = "none";}
  1709.   elsif (/^-view=ps$/)      { $view = "ps";}
  1710.   elsif (/^-view=pdf$/)     { $view = "pdf"; }
  1711.   elsif (/^-lualatex$/)      {
  1712.       $pdf_mode = 4;
  1713.       $dvi_mode = $postscript_mode = 0;
  1714.   }
  1715.   elsif (/^-xelatex$/)      {
  1716.       $pdf_mode = 5;
  1717.       $dvi_mode = $postscript_mode = 0;
  1718.   }
  1719.   elsif (/^-e$/) {  
  1720.      if ( $#ARGV < 0 ) {
  1721.         &exit_help( "No code to execute specified after -e switch");
  1722.      }
  1723.      execute_code_string( $ARGV[0] );
  1724.      shift;
  1725.   }
  1726.   elsif (/^-r$/) {  
  1727.      if ( $ARGV[0] eq '' ) {
  1728.         &exit_help( "No RC file specified after -r switch");
  1729.      }
  1730.      if ( -e $ARGV[0] ) {
  1731.         process_rc_file( $ARGV[0] );
  1732.      }
  1733.      else {
  1734.         die "$My_name: RC file [$ARGV[0]] does not exist\n";
  1735.      }
  1736.      shift;
  1737.   }
  1738.   elsif (/^-bm$/) {
  1739.      if ( $ARGV[0] eq '' ) {
  1740.         &exit_help( "No message specified after -bm switch");
  1741.      }
  1742.      $banner = 1; $banner_message = $ARGV[0];
  1743.      shift;
  1744.   }
  1745.   elsif (/^-bi$/) {
  1746.      if ( $ARGV[0] eq '' ) {
  1747.         &exit_help( "No intensity specified after -bi switch");
  1748.      }
  1749.      $banner_intensity = $ARGV[0];
  1750.      shift;
  1751.   }
  1752.   elsif (/^-bs$/) {
  1753.      if ( $ARGV[0] eq '' ) {
  1754.         &exit_help( "No scale specified after -bs switch");
  1755.      }
  1756.      $banner_scale = $ARGV[0];
  1757.      shift;
  1758.   }
  1759.   elsif (/^-dF$/) {
  1760.      if ( $ARGV[0] eq '' ) {
  1761.         &exit_help( "No dvi filter specified after -dF switch");
  1762.      }
  1763.      $dvi_filter = $ARGV[0];
  1764.      shift;
  1765.   }
  1766.   elsif (/^-pF$/) {
  1767.      if ( $ARGV[0] eq '' ) {
  1768.         &exit_help( "No ps filter specified after -pF switch");
  1769.      }
  1770.      $ps_filter = $ARGV[0];
  1771.      shift;
  1772.   }
  1773.   elsif ( ( exists( $allowed_latex_options{$_} ) )
  1774.           || ( /^(-.+)=/ && exists( $allowed_latex_options_with_arg{$1} ) )
  1775.         )
  1776.   {
  1777.       push @extra_latex_options, $original;
  1778.       push @extra_pdflatex_options, $original;
  1779.       push @extra_lualatex_options, $original;
  1780.       push @extra_xelatex_options, $original;
  1781.   }
  1782.   elsif (/^-/) {
  1783.      warn "$My_name: $_ bad option\n";
  1784.      $bad_options++;
  1785.   }
  1786.   else {
  1787.      push @command_line_file_list, $_ ;
  1788.   }
  1789. }
  1790.  
  1791. if ( $bad_options > 0 ) {
  1792.     &exit_help( "Bad options specified" );
  1793. }
  1794.  
  1795. warn "$My_name: This is $version_details, version: $version_num.\n",
  1796.    unless $silent;
  1797.  
  1798.  
  1799. if ( ($out_dir ne '') && ($aux_dir eq '') ){
  1800.     $aux_dir = $out_dir;
  1801. }
  1802.  
  1803. # Normalize versions terminating in directory/path separator
  1804. # and versions referring to current directory
  1805. $out_dir1 = $out_dir;
  1806. $aux_dir1 = $aux_dir;
  1807. foreach ( $aux_dir1, $out_dir1 ) {
  1808.     if ( ($_ ne '')  && ! m([\\/\:]$) ) {
  1809.        $_ .= '/';
  1810.     }
  1811.     while ( s[^\.\/][] ) {}
  1812. }
  1813.  
  1814. # At least one widely package (revtex4-1) generates a bib file
  1815. # (which is used in revtex4-1 for putting footnotes in the reference
  1816. # list), and bibtex must be run to use it.  But latexmk needs to
  1817. # determine the existence of the bib file by use of kpsewhich, otherwise
  1818. # there is an error.  So cope with this situation (and any analogous
  1819. # cases by adding the aux_dir to the relevant path search environment
  1820. # variables.  BIBINPUTS seems to be the only one currently affected.
  1821. foreach ( 'BIBINPUTS' ) {
  1822.     if ( exists $ENV{$_} ) {
  1823.         $ENV{$_} = $aux_dir.$search_path_separator.$ENV{$_};
  1824.     }
  1825.     else {
  1826.         $ENV{$_} = $aux_dir.$search_path_separator;
  1827.     }
  1828. }
  1829.  
  1830.  
  1831. if ($bibtex_use > 1) {
  1832.     push @generated_exts, 'bbl';
  1833. }
  1834.  
  1835. # For backward compatibility, convert $texfile_search to @default_files
  1836. # Since $texfile_search is initialized to "", a nonzero value indicates
  1837. # that an initialization file has set it.
  1838. if ( $texfile_search ne "" ) {
  1839.     @default_files = split /\s+/, "*.tex $texfile_search";
  1840. }
  1841.  
  1842. #Glob the filenames command line if the script was not invoked under a
  1843. #   UNIX-like environment.
  1844. #   Cases: (1) MS/MSwin native    Glob
  1845. #                      (OS detected as MSWin32)
  1846. #          (2) MS/MSwin cygwin    Glob [because we do not know whether
  1847. #                  the cmd interpreter is UNIXy (and does glob) or is
  1848. #                  native MS-Win (and does not glob).]
  1849. #                      (OS detected as cygwin)
  1850. #          (3) UNIX               Don't glob (cmd interpreter does it)
  1851. #                      (Currently, I assume this is everything else)
  1852. if ( ($^O eq "MSWin32") || ($^O eq "cygwin") ) {
  1853.     # Preserve ordering of files
  1854.     @file_list = glob_list1(@command_line_file_list);
  1855. #print "A1:File list:\n";
  1856. #for ($i = 0; $i <= $#file_list; $i++ ) {  print "$i: '$file_list[$i]'\n"; }
  1857. }
  1858. else {
  1859.     @file_list = @command_line_file_list;
  1860. }
  1861. @file_list = uniq1( @file_list );
  1862.  
  1863.  
  1864. # Check we haven't selected mutually exclusive modes.
  1865. # Note that -c overrides all other options, but doesn't cause
  1866. # an error if they are selected.
  1867. if (($printout_mode && ( $preview_mode || $preview_continuous_mode ))
  1868.     || ( $preview_mode && $preview_continuous_mode ))
  1869. {
  1870.   # Each of the options -p, -pv, -pvc turns the other off.
  1871.   # So the only reason to arrive here is an incorrect inititalization
  1872.   #   file, or a bug.
  1873.   &exit_help( "Conflicting options (print, preview, preview_continuous) selected");
  1874. }
  1875.  
  1876. if ( @command_line_file_list ) {  
  1877.     # At least one file specified on command line (before possible globbing).
  1878.     if ( !@file_list ) {
  1879.         &exit_help( "Wildcards in file names didn't match any files");
  1880.     }
  1881. }
  1882. else {
  1883.     # No files specified on command line, try and find some
  1884.     # Evaluate in order specified.  The user may have some special
  1885.     #   for wanting processing in a particular order, especially
  1886.     #   if there are no wild cards.
  1887.     # Preserve ordering of files
  1888.     my @file_list1 = uniq1( glob_list1(@default_files) );
  1889.     my @excluded_file_list = uniq1( glob_list1(@default_excluded_files) );
  1890.     # Make hash of excluded files, for easy checking:
  1891.     my %excl = ();
  1892.     foreach my $file (@excluded_file_list) {
  1893.         $excl{$file} = '';
  1894.     }
  1895.     foreach my $file (@file_list1) {
  1896.         push( @file_list, $file)  unless ( exists $excl{$file} );
  1897.     }    
  1898.     if ( !@file_list ) {
  1899.         &exit_help( "No file name specified, and I couldn't find any");
  1900.     }
  1901. }
  1902.  
  1903. $num_files = $#file_list + 1;
  1904. $num_specified = $#command_line_file_list + 1;
  1905.  
  1906. #print "Command line file list:\n";
  1907. #for ($i = 0; $i <= $#command_line_file_list; $i++ ) {  print "$i: '$command_line_file_list[$i]'\n"; }
  1908. #print "File list:\n";
  1909. #for ($i = 0; $i <= $#file_list; $i++ ) {  print "$i: '$file_list[$i]'\n"; }
  1910.  
  1911.  
  1912. # If selected a preview-continuous mode, make sure exactly one filename was specified
  1913. if ($preview_continuous_mode && ($num_files != 1) ) {
  1914.     if ($num_specified > 1) {
  1915.         &exit_help(
  1916.           "Need to specify exactly one filename for ".
  1917.               "preview-continuous mode\n".
  1918.           "    but $num_specified were specified"
  1919.         );
  1920.     }
  1921.     elsif ($num_specified == 1) {
  1922.         &exit_help(
  1923.           "Need to specify exactly one filename for ".
  1924.               "preview-continuous mode\n".
  1925.           "    but wildcarding produced $num_files files"
  1926.         );
  1927.     }
  1928.     else {
  1929.         &exit_help(
  1930.           "Need to specify exactly one filename for ".
  1931.               "preview-continuous mode.\n".
  1932.           "    Since none were specified on the command line, I looked for \n".
  1933.           "    files in '@default_files'.\n".
  1934.           "    But I found $num_files files, not 1."
  1935.         );
  1936.     }
  1937. }
  1938.  
  1939. # If selected jobname, can only apply that to one file:
  1940. if ( ($jobname ne '') && ($num_files > 1) ) {
  1941.     &exit_help(
  1942.           "Need to specify at most one filename if ".
  1943.           "jobname specified, \n".
  1944.           "    but $num_files were found (after defaults and wildcarding)."
  1945.         );
  1946. }
  1947.  
  1948.  
  1949. # Normalize the commands, to have place-holders for source, dest etc:
  1950. &fix_cmds;
  1951.  
  1952. # Add common options
  1953. add_option( $latex_default_switches, \$latex );
  1954. add_option( $pdflatex_default_switches, \$pdflatex );
  1955. add_option( $lualatex_default_switches, \$lualatex );
  1956. add_option( $xelatex_default_switches, \$xelatex );
  1957.  
  1958. foreach (@extra_latex_options) { add_option( $_, \$latex ); }
  1959. foreach (@extra_pdflatex_options) { add_option( $_, \$pdflatex ); }
  1960. foreach (@extra_lualatex_options) { add_option( $_, \$lualatex ); }
  1961. foreach (@extra_xelatex_options) { add_option( $_, \$xelatex ); }
  1962.  
  1963.  
  1964. # If landscape mode, change dvips processor, and the previewers:
  1965. if ( $landscape_mode )
  1966. {
  1967.   $dvips = $dvips_landscape;
  1968.   $dvi_previewer = $dvi_previewer_landscape;
  1969.   $ps_previewer = $ps_previewer_landscape;
  1970. }
  1971.  
  1972. if ( $silent ) {
  1973.     add_option( "$latex_silent_switch", \$latex );
  1974.     add_option( "$pdflatex_silent_switch", \$pdflatex );
  1975.     add_option( "$lualatex_silent_switch", \$lualatex );
  1976.     add_option( "$xelatex_silent_switch", \$xelatex );
  1977.     add_option( "$biber_silent_switch", \$biber );
  1978.     add_option( "$bibtex_silent_switch", \$bibtex );
  1979.     add_option( "$makeindex_silent_switch", \$makeindex );
  1980.     add_option( "$dvipdf_silent_switch", \$dvipdf );
  1981.     add_option( "$dvips_silent_switch", \$dvips );
  1982.     add_option( "$xdvipdfmx_silent_switch", \$xdvipdfmx );
  1983. }
  1984.  
  1985. if ( $recorder ) {
  1986.     add_option( "-recorder", \$latex, \$pdflatex, \$lualatex, \$xelatex );
  1987. }
  1988.  
  1989. # If the output and/or aux directories are specified, fix the (pdf)latex
  1990. #   commands to use them.
  1991. # N.B. We'll ensure that the directories actually exist only after a
  1992. #   possible cd to the document directory, since the directories can be
  1993. #   relative to the document.
  1994.  
  1995. if ( $out_dir ) {
  1996.     add_option( "-output-directory=\"$out_dir\"",
  1997.                 \$latex, \$pdflatex, \$lualatex, \$xelatex );
  1998. }
  1999. if ( $aux_dir && ($aux_dir ne $out_dir) ) {
  2000.     # N.B. If $aux_dir and $out_dir are the same, then the -output-directory
  2001.     # option is sufficient, especially because the -aux-directory exists
  2002.     # only in MiKTeX, not in TeXLive.
  2003.     add_option( "-aux-directory=\"$aux_dir\"",
  2004.                 \$latex, \$pdflatex, \$lualatex, \$xelatex );
  2005. }
  2006.  
  2007. if ( $jobname ne '' ) {
  2008.     $jobstring = "--jobname=\"$jobname\"";
  2009.     add_option( "$jobstring", \$latex, \$lualatex, \$pdflatex, \$xelatex );
  2010. }
  2011.  
  2012. # Which kind of file do we preview?
  2013. if ( $view eq "default" ) {
  2014.     # If default viewer requested, use "highest" of dvi, ps and pdf
  2015.     #    that was requested by user.  
  2016.     # No explicit request means view dvi.
  2017.     $view = "dvi";
  2018.     if ( $postscript_mode ) { $view = "ps"; }
  2019.     if ( $pdf_mode ) { $view = "pdf"; }
  2020. }
  2021.  
  2022. # Make sure we make the kind of file we want to view:
  2023. if ($view eq 'dvi') { $dvi_mode = 1; }
  2024. if ($view eq 'ps') { $postscript_mode = 1; }
  2025. if ( ($view eq 'pdf') && ($pdf_mode == 0) ) {
  2026.     $pdf_mode = 1;
  2027. }
  2028.  
  2029. # Make sure that we make something if all requests are turned off
  2030. if ( ! ( $dvi_mode || $pdf_mode || $postscript_mode || $printout_mode) ) {
  2031.     print "No specific requests made, so default to dvi by latex\n";
  2032.     $dvi_mode = 1;
  2033. }
  2034.  
  2035. # Set new-style requested rules:
  2036. if ( $dvi_mode ) { $requested_filerules{'latex'} = 1; }
  2037. if ( $pdf_mode == 1 ) { $requested_filerules{'pdflatex'} = 1; }
  2038. elsif ( $pdf_mode == 2 ) {
  2039.    $requested_filerules{'latex'} = 1;
  2040.    $requested_filerules{'dvips'} = 1;
  2041.    $requested_filerules{'ps2pdf'} = 1;
  2042. }
  2043. elsif ( $pdf_mode == 3 ) {
  2044.    $requested_filerules{'latex'} = 1;
  2045.    $requested_filerules{'dvipdf'} = 1;
  2046. }
  2047. elsif ( $pdf_mode == 4 ) {
  2048.    $requested_filerules{'lualatex'} = 1;
  2049. }
  2050. elsif ( $pdf_mode == 5 ) {
  2051.    $requested_filerules{'xelatex'} = 1;
  2052.    $requested_filerules{'xdvipdfmx'} = 1;
  2053. }
  2054. if ( $postscript_mode ) {
  2055.    $requested_filerules{'latex'} = 1;
  2056.    $requested_filerules{'dvips'} = 1;
  2057. }
  2058. if ($print_type eq 'auto') {
  2059.     if ( $postscript_mode ) { $print_type = 'ps'; }
  2060.     elsif ( $pdf_mode )     { $print_type = 'pdf'; }
  2061.     elsif ( $dvi_mode )     { $print_type = 'dvi'; }
  2062.     else                    { $print_type = 'none'; }
  2063. }
  2064. if ( $printout_mode ) {
  2065.     $one_time{'print'} = 1;
  2066.     if ($print_type eq 'none'){
  2067.         warn "$My_name: You have requested printout, but \$print_type is set to 'none'\n";
  2068.     }
  2069. }
  2070. if ( $preview_continuous_mode || $preview_mode ) { $one_time{'view'} = 1; }
  2071. if ( length($dvi_filter) != 0 ) { $requested_filerules{'dvi_filter'} = 1; }
  2072. if ( length($ps_filter) != 0 )  { $requested_filerules{'ps_filter'} = 1; }
  2073. if ( $banner ) { $requested_filerules{'dvips'} = 1; }
  2074.  
  2075.  
  2076. if ( $pdf_mode == 2 ) {
  2077.     # We generate pdf from ps.  Make sure we have the correct kind of ps.
  2078.     add_option( "$dvips_pdf_switch", \$dvips );
  2079. }
  2080.  
  2081. # Restrict variables to allowed values:
  2082.  
  2083. if ($filetime_causality_threshold < 0) {
  2084.     warn "$My_name: Correcting negative value of \$filetime_causality_threshold to zero.\n";
  2085.     $filetime_causality_threshold = 0;
  2086. }
  2087.  
  2088. # Note sleep has granularity of 1 second.
  2089. # Sleep periods 0 < $sleep_time < 1 give zero delay,
  2090. #    which is probably not what the user intended.
  2091. # Sleep periods less than zero give infinite delay
  2092. if ( $sleep_time < 0 ) {
  2093.      warn "$My_name: Correcting negative sleep_time to 1 sec.\n";
  2094.      $sleep_time = 1;
  2095. }
  2096. elsif ( ($sleep_time < 1) && ( $sleep_time != 0 ) ) {
  2097.      warn "$My_name: Correcting nonzero sleep_time of less than 1 sec to 1 sec.\n";
  2098.      $sleep_time = 1;
  2099. }
  2100. elsif ( $sleep_time == 0 ) {
  2101.      warn "$My_name: sleep_time was configured to zero.\n",
  2102.     "    Do you really want to do this?  It will give 100% CPU usage.\n";
  2103. }
  2104.  
  2105. # Make convenient forms for lookup.
  2106. # Extensions always have period.
  2107.  
  2108. # Convert @generated_exts to a hash for ease of look up and deletion
  2109. # Keep extension without period!
  2110. %generated_exts_all = ();
  2111. foreach (@generated_exts ) {
  2112.     $generated_exts_all{$_} = 1;
  2113. }
  2114.  
  2115. if ($aux_dir) {
  2116.     # Ensure $aux_dir is in TEXINPUTS search path.
  2117.     # This is used by dvips for files generated by mpost.
  2118.     if ( ! exists $ENV{TEXINPUTS} ) {
  2119.         # Note the trailing ":" which ensures that the last item
  2120.         # in the list of paths is the empty path, which actually
  2121.         # means the default path, i.e., the following means that
  2122.         # the TEXINPUTS search path is $aux_dir and the standard
  2123.         # value.
  2124.         $ENV{TEXINPUTS} = $aux_dir.$search_path_separator;
  2125.     }
  2126.     elsif ( $ENV{TEXINPUTS} !~ /$aux_dir$search_path_separator/ ) {
  2127.         $ENV{TEXINPUTS} = $aux_dir.$search_path_separator.$ENV{TEXINPUTS};
  2128.     }
  2129. }
  2130.  
  2131. $quell_uptodate_msgs = $silent;
  2132.    # Whether to quell informational messages when files are uptodate
  2133.    # Will turn off in -pvc mode
  2134.  
  2135. $failure_count = 0;
  2136. @failed_primaries = ();
  2137.  
  2138. if ($deps_file eq '' ) {
  2139.     # Standardize name used for stdout
  2140.     $deps_file = '-';
  2141. }
  2142.  
  2143. # In non-pvc mode, the dependency list is global to all processed TeX files,
  2144. # so we open a single file here, and add items to it after processing each file
  2145. # But in -pvc mode, the dependency list should be written after round of
  2146. # processing the single TeX file (as if each round were a separate run of
  2147. # latexmk).  There's undoubtedly some non-optimal structuring here!
  2148. if ( $dependents_list && ! $preview_continuous_mode ) {
  2149.     $deps_handle = new FileHandle "> $deps_file";
  2150.     if (! defined $deps_handle ) {
  2151.         die "Cannot open '$deps_file' for output of dependency information\n";
  2152.     }
  2153. }
  2154.  
  2155. # Remove leading and trailing space in the following space-separated lists,
  2156. #   and collapse multiple spaces to one,
  2157. #   to avoid getting incorrect blank items when they are split.
  2158. foreach ($clean_ext, $clean_full_ext) { s/^\s+//; s/\s+$//; s/\s+/ /g; }
  2159.  
  2160.  
  2161. FILE:
  2162. foreach $filename ( @file_list )
  2163. {
  2164.     # Global variables for making of current file:
  2165.     $updated = 0;
  2166.     $failure = 0;        # Set nonzero to indicate failure at some point of
  2167.                          # a make.  Use value as exit code if I exit.
  2168.     $failure_msg = '';   # Indicate reason for failure
  2169.  
  2170.     if ( $do_cd ) {
  2171.        ($filename, $path) = fileparse( $filename );
  2172.        warn "$My_name: Changing directory to '$path'\n";
  2173.        pushd( $path );
  2174.     }
  2175.     else {
  2176.         $path = '';
  2177.     }
  2178.  
  2179.     # Ensure the output/auxiliary directories exist, if need be
  2180.     if ( $out_dir ) {
  2181.         if ( ! -e $out_dir ) {
  2182.              warn "$My_name: making output directory '$out_dir'\n"
  2183.                 if ! $silent;
  2184.              make_path $out_dir;
  2185.         }
  2186.         elsif ( ! -d $out_dir ) {
  2187.             warn "$My_name: you requested output directory '$out_dir',\n",
  2188.                  "     but an ordinary file of the same name exists, which will\n",
  2189.                  "     probably give an error later\n";
  2190.     }
  2191.     }
  2192.  
  2193.     if ( $aux_dir && ($aux_dir ne $out_dir) ) {
  2194.         # N.B. If $aux_dir and $out_dir are the same, then the -output-directory
  2195.         # option is sufficient, especially because the -aux-directory exists
  2196.         # only in MiKTeX, not in TeXLive.
  2197.         if ( ! -e $aux_dir ) {
  2198.             warn "$My_name: making auxiliary directory '$aux_dir'\n"
  2199.                if ! $silent;
  2200.             make_path $aux_dir;
  2201.     }
  2202.         elsif ( ! -d $aux_dir ) {
  2203.             warn "$My_name: you requested aux directory '$aux_dir',\n",
  2204.                  "     but an ordinary file of the same name exists, which will\n",
  2205.                  "     probably give an error later\n";
  2206.     }
  2207.     }
  2208.  
  2209.     ## remove extension from filename if was given.
  2210.     if ( find_basename($filename, $root_filename, $texfile_name) )
  2211.     {
  2212.         if ( $force_mode ) {
  2213.            warn "$My_name: Could not find file [$texfile_name]\n";
  2214.         }
  2215.         else {
  2216.             &ifcd_popd;
  2217.             &exit_msg1( "Could not find file [$texfile_name]",
  2218.                         11);
  2219.         }
  2220.     }
  2221.     if ($jobname ne '' ) {
  2222.         $root_filename = $jobname;
  2223.     }
  2224.  
  2225.     $aux_main = "$aux_dir1$root_filename.aux";
  2226.     $log_name = "$aux_dir1$root_filename.log";
  2227.     $fdb_name = "$aux_dir1$root_filename.$fdb_ext";
  2228.  
  2229.     # Initialize basic dependency information:
  2230.  
  2231.     # For use under error conditions:
  2232.     @default_includes = ($texfile_name, $aux_main);
  2233.  
  2234.     # Initialize rule database.  
  2235.     # ?? Should I also initialize file database?
  2236.     %rule_list = ();
  2237.     &rdb_make_rule_list;
  2238.     &rdb_set_rules( \%rule_list, \%extra_rule_spec );
  2239.  
  2240.     if ( $cleanup_mode > 0 ) {
  2241. # ?? MAY NEED TO FIX THE FOLLOWING IF $aux_dir or $out_dir IS SET.
  2242.         my %other_generated = ();
  2243.         my @index_bibtex_generated = ();
  2244.         my @aux_files = ();
  2245.         my @missing_bib_files = ();
  2246.     my $bibs_all_exist = 0;
  2247.         $have_fdb = 0;
  2248.         if ( -e $fdb_name ) {
  2249.             print "$My_name: Examining fdb file '$fdb_name' for rules ...\n"
  2250.               if $diagnostics;
  2251.             $have_fdb = ( 0 == rdb_read( $fdb_name ) );
  2252.         }
  2253.         if ( $have_fdb ) {
  2254.             rdb_for_all(
  2255.                 sub {  # Find generated files at rule level
  2256.                     my ($base, $path, $ext) = fileparseA( $$Psource );
  2257.                     $base = $path.$base;
  2258.                     if ( $rule =~ /^makeindex/ ) {
  2259.                         push @index_bibtex_generated, $$Psource, $$Pdest, "$base.ilg";
  2260.                     }
  2261.                     elsif ( $rule =~ /^(bibtex|biber)/ ) {
  2262.                         push @index_bibtex_generated, $$Pdest, "$base.blg";
  2263.                         push @aux_files, $$Psource;
  2264.                         if ( $bibtex_use == 1.5) {
  2265.                             foreach ( keys %$PHsource ) {
  2266.                                 if ( ( /\.bib$/ ) && (! -e $_) ) {
  2267.                                     push @missing_bib_files, $_;
  2268.                     }
  2269.                 }
  2270.             }
  2271.             }
  2272.                     elsif ( exists $other_generated{$$Psource} ) {
  2273. #           print "=========== CHECKING: source file of rule '$rule', '$$Psource'\n",
  2274. #                              "  is a generated file.\n";
  2275.             ## OLD with apparent bug:
  2276.                         #$other_generated{$$Pdest};
  2277.                     }
  2278.             foreach my $key (keys %$PHdest) {
  2279.             $other_generated{$key} = 1;
  2280.             }
  2281.                 },
  2282.                 sub {  # Find generated files at source file level
  2283.                     if ( $file =~ /\.aux$/ ) { push @aux_files, $file; }
  2284.                 }
  2285.         );
  2286.         if ($#missing_bib_files == -1) { $bibs_all_exist = 1; }
  2287.         }
  2288.         elsif ( -e $log_name ) {
  2289.             # No fdb file, but log file exists, so do inferior job by parse_log
  2290.             print "$My_name: Examining log file '$log_name' for generated files...\n"
  2291.               if $diagnostics;
  2292.             # Variables set by parse_log. Can I remove them?
  2293.             local %generated_log = ();
  2294.             local %dependents = ();    # Maps files to status.  Not used here.
  2295.             local @bbl_files = ();     # Not used here.
  2296.             local %idx_files = ();     # Maps idx_file to (ind_file, base). Not used here.
  2297.             local %conversions = ();   # (pdf)latex-performed conversions.  Not used here.
  2298.                          # Maps output file created and read by (pdf)latex
  2299.                          #    to source file of conversion.
  2300.             local $primary_out = '';   # Actual output file (dvi or pdf). Not used here.
  2301.         local $fls_file_analyzed = 0;
  2302.             &parse_log;
  2303.             %other_generated = %generated_log;
  2304.         }
  2305.         else {
  2306.             print "$My_name: No fdb or log file, so clean up default set of files ...\n"
  2307.               if $diagnostics;
  2308.         }
  2309.  
  2310.         if ( ($go_mode == 2) && !$silent ) {
  2311.             warn "$My_name: Removing all generated files\n" unless $silent;
  2312.         }
  2313.     my $keep_bbl = 1;
  2314.     if ( ($bibtex_use > 1.6)
  2315.          ||
  2316.              (  ($bibtex_use == 1.5) && ($bibs_all_exist) )
  2317.        ) {
  2318.                $keep_bbl = 0;
  2319.     }
  2320.     if ($keep_bbl) {
  2321.             delete $generated_exts_all{'bbl'};
  2322.         }
  2323.         # Convert two arrays to hashes:
  2324.         my %index_bibtex_generated = ();
  2325.         my %aux_files = ();
  2326.         my %aux_files_to_save = ();
  2327.         foreach (@index_bibtex_generated) {
  2328.             $index_bibtex_generated{$_} = 1
  2329.                unless ( /\.bbl$/ && ($keep_bbl) );
  2330.             delete( $other_generated{$_} );
  2331.         }
  2332.         foreach (@aux_files) {
  2333.         if (exists $other_generated{$_} ) {
  2334.         $aux_files{$_} = 1;
  2335.         }
  2336.         else {
  2337.         $aux_files_to_save{$_} = 1;
  2338.         }
  2339.         }
  2340.  
  2341.         if ($diagnostics) {
  2342.             show_array( "For deletion, the following were determined from fdb file or log file:\n"
  2343.                        ." Generated (from makeindex and bibtex):",
  2344.                         keys %index_bibtex_generated );
  2345.             show_array( " Aux files:", keys %aux_files );
  2346.             show_array( " Other generated files:\n"
  2347.                        ." (only deleted if \$cleanup_includes_generated is set): ",
  2348.                         keys %other_generated );
  2349.             show_array( " Yet other generated files are specified by patterns:\n".
  2350.                         " Explicit pattern with %R or root-filename.extension:",
  2351.                         keys %generated_exts_all );
  2352.             show_array( " Aux files to SAVE and not delete:", keys %aux_files_to_save );
  2353.         }
  2354.  
  2355.         &cleanup1( $aux_dir1, $fdb_ext, 'blg', 'ilg', 'log', 'aux.bak', 'idx.bak',
  2356.                    split('\s+',$clean_ext),
  2357.                    keys %generated_exts_all
  2358.                  );
  2359.         unlink_or_move( 'texput.log', "texput.aux", "missfont.log",
  2360.                 keys %index_bibtex_generated,
  2361.                 keys %aux_files );
  2362.         if ( $dependents_list && ( $deps_file ne '-' ) ) {
  2363.             unlink_or_move( $deps_file );
  2364.         }
  2365.         if ($cleanup_includes_generated) {
  2366.             unlink_or_move( keys %other_generated );
  2367.         }
  2368.         if ( $cleanup_includes_cusdep_generated) {
  2369.             &cleanup_cusdep_generated;
  2370.         }
  2371.         if ( $cleanup_mode == 1 ) {
  2372.             &cleanup1( $out_dir1, 'dvi', 'dviF', 'ps', 'psF', 'pdf',
  2373.                        'synctex.gz', 'xdv',
  2374.                        split('\s+', $clean_full_ext)
  2375.                      );
  2376.         }
  2377.     }
  2378.     if ($cleanup_fdb) {
  2379.        unlink_or_move( $fdb_name );
  2380.        # If the fdb file exists, it will have been read, and therefore changed
  2381.        #   rule database.  But deleting the fdb file implies we also want
  2382.        #   a virgin rule database, so we must reset it:
  2383.        rdb_set_rules( \%rule_list );
  2384.     }
  2385.     if ($cleanup_only) { next FILE; }
  2386.  
  2387.  
  2388. #??? The following are not needed if use rdb_make.  
  2389. #    ?? They may be set too early?
  2390. # Arrays and hashes for picking out accessible rules.
  2391. # Distinguish rules for making files and others
  2392.     @accessible_all = sort ( &rdb_accessible( keys %requested_filerules, keys %one_time ));
  2393.     %accessible_filerules = ();
  2394.     foreach (@accessible_all) {
  2395.         unless ( /view/ || /print/ ) { $accessible_filerules{$_} = 1; }
  2396.     }
  2397.     @accessible_filerules = sort  keys %accessible_filerules;
  2398.  
  2399. #    show_array ( "=======All rules used", @accessible_all );
  2400. #    show_array ( "=======Requested file rules", sort keys %requested_filerules );
  2401. #    show_array ( "=======Rules for files", @accessible_filerules );
  2402.  
  2403.     if ( $diagnostics ) {
  2404.        print "$My_name: Rules after start up for '$texfile_name'\n";
  2405.        rdb_show();
  2406.     }
  2407.  
  2408.     %primaries = ();
  2409.     foreach (@accessible_all) {
  2410.         if ( ($_ eq 'latex') || ($_ eq 'pdflatex') || ($_ eq 'lualatex')
  2411.                              || ($_ eq 'xelatex') )
  2412.         { $primaries{$_} = 1; }
  2413.     }
  2414.  
  2415.     $have_fdb = 0;
  2416.     if (! -e $aux_main ) {
  2417.         # No aux file => set up trivial aux file
  2418.         #    and corresponding fdb_file.  Arrange them to provoke one run
  2419.         #    as minimum, but no more if actual aux file is trivial.
  2420.         #    (Useful on big files without cross references.)
  2421.         # If aux file doesn't exist, then any fdb file is surely
  2422.     #    wrong.
  2423.     # Previously, I had condition for this as being both aux and
  2424.     #    fdb files failing to exist.  But it's not obvious what to
  2425.     #    do if aux exists and fdb doesn't.  So I won't do anything.
  2426.         &set_trivial_aux_fdb;
  2427.     }
  2428.  
  2429.     if ( -e $fdb_name ) {
  2430.         $rdb_errors = rdb_read( $fdb_name );
  2431.         $have_fdb = ($rdb_errors == 0);
  2432.     }
  2433.     if (!$have_fdb) {
  2434.         # We didn't get a valid set of data on files used in
  2435.         # previous run.  So use filetime criterion for make
  2436.         # instead of change from previous run, until we have
  2437.         # done our own make.
  2438.         rdb_recurse( [keys %possible_primaries],
  2439.                       sub{ if ( $$Ptest_kind == 1 ) { $$Ptest_kind = 3;} }
  2440.         );
  2441.         if ( -e $log_name ) {
  2442.             rdb_for_some( [keys %possible_primaries], \&rdb_set_latex_deps );
  2443.         }
  2444.     }
  2445.     foreach $rule ( rdb_accessible( uniq1( keys %requested_filerules  )  ) ){
  2446.         # For all source files of all accessible rules,
  2447.         #    if the file data are not already set (e.g., from fdb_latexmk
  2448.         #    file, set them from disk.
  2449.         rdb_one_rule ($rule, undef,
  2450.                       sub{ if ( $$Ptime == 0) { &rdb_update1; } }
  2451.         );
  2452.     }
  2453.  
  2454.     if ($go_mode) {
  2455.         # Force everything to be remade.
  2456.         rdb_recurse( [keys %requested_filerules], sub{$$Pout_of_date=1;}  );
  2457.     }
  2458.  
  2459.  
  2460.     if ( $diagnostics ) {
  2461.        print "$My_name: Rules after initialization\n";
  2462.        rdb_show();
  2463.     }
  2464.  
  2465.     #************************************************************
  2466.  
  2467.     if ( $preview_continuous_mode ) {
  2468.         &make_preview_continuous;
  2469.         next FILE;
  2470.     }
  2471.  
  2472.  
  2473. ## Handling of failures:
  2474. ##    Variable $failure is set to indicate a failure, with information
  2475. ##       put in $failure_msg.  
  2476. ##    These variables should be set to 0 and '' at any point at which it
  2477. ##       should be assumed that no failures have occurred.
  2478. ##    When after a routine is called it is found that $failure is set, then
  2479. ##       processing should normally be aborted, e.g., by return.
  2480. ##    Then there is a cascade of returns back to the outermost level whose
  2481. ##       responsibility is to handle the error.
  2482. ##    Exception: An outer level routine may reset $failure and $failure_msg
  2483. ##       after initial processing, when the error condition may get
  2484. ##       ameliorated later.
  2485.     #Initialize failure flags now.
  2486.     $failure = 0;
  2487.     $failure_msg = '';
  2488.     $failure = rdb_make( keys %requested_filerules );
  2489.     if ( ( $failure <= 0 ) || $force_mode ) {
  2490.       rdb_for_some( [keys %one_time], \&rdb_run1 );
  2491.     }
  2492.     if ($failure > 0) { next FILE; }
  2493. } # end FILE
  2494. continue {
  2495.     if ($deps_handle) { deps_list($deps_handle); }
  2496.     # If requested, print the list of rules.  But don't do this in -pvc
  2497.     # mode, since the rules list has already been printed.
  2498.     if ($rules_list && ! $preview_continuous_mode) { rdb_list(); }
  2499.     # Handle any errors
  2500.     $error_message_count = rdb_show_rule_errors();
  2501.     if ( ($error_message_count == 0) || ($failure > 0) ) {
  2502.         if ( $failure_msg ) {
  2503.             #Remove trailing space
  2504.             $failure_msg =~ s/\s*$//;
  2505.             warn "$My_name: Did not finish processing file '$filename':\n",
  2506.                  "   $failure_msg\n";
  2507.             $failure = 1;
  2508.         }
  2509.     }
  2510.     if ( ($failure > 0) || ($error_message_count > 0) ) {
  2511.         $failure_count ++;
  2512.         push @failed_primaries, $filename;
  2513.     }
  2514.     &ifcd_popd;
  2515. }
  2516. close($deps_handle) if ( $deps_handle );
  2517.  
  2518. if ($show_time) { show_timing();}
  2519.  
  2520. sub show_timing {
  2521.     my $processing_time = processing_time() - $processing_time1;
  2522.     print @timings, "Accumulated processing time = $processing_time\n";
  2523.     @timings = ();
  2524.     $processing_time1 = processing_time();
  2525. }
  2526.  
  2527. # If we get here without going through the continue section:
  2528. if ( $do_cd && ($#dir_stack > -1) ) {
  2529.    # Just in case we did an abnormal exit from the loop
  2530.    warn "$My_name: Potential bug: dir_stack not yet unwound, undoing all directory changes now\n";
  2531.    &finish_dir_stack;
  2532. }
  2533.  
  2534. if ($failure_count > 0) {
  2535.     if ( $#file_list > 0 ) {
  2536.         # Error occured, but multiple files were processed, so
  2537.         #     user may not have seen all the error messages
  2538.         warn "\n------------\n";
  2539.         show_array(
  2540.            "$My_name: Some operations failed, for the following tex file(s)",
  2541.            @failed_primaries);
  2542.     }
  2543.     if ( !$force_mode ) {
  2544.       warn "$My_name: Use the -f option to force complete processing,\n",
  2545.            " unless error was exceeding maximum runs of latex/pdflatex.\n";
  2546.     }
  2547.     exit 12;
  2548. }
  2549.  
  2550.  
  2551.  
  2552. # end MAIN PROGRAM
  2553. #############################################################
  2554.  
  2555. sub fix_cmds {
  2556.    # If commands do not have placeholders for %S etc, put them in
  2557.     foreach ($latex, $pdflatex, $lpr, $lpr_dvi, $lpr_pdf,
  2558.              $pdf_previewer, $ps_previewer, $ps_previewer_landscape,
  2559.              $dvi_previewer, $dvi_previewer_landscape,
  2560.              $kpsewhich
  2561.     ) {
  2562.         # Source only
  2563.         if ( $_ && ! /%/ ) { $_ .= " %O %S"; }
  2564.     }
  2565.     foreach ($pdf_previewer, $ps_previewer, $ps_previewer_landscape,
  2566.              $dvi_previewer, $dvi_previewer_landscape,
  2567.     ) {
  2568.         # Run previewers detached
  2569.         if ( $_ && ! /^(nostart|NONE|internal) / ) {
  2570.             $_ = "start $_";
  2571.         }
  2572.     }
  2573.     foreach ($biber, $bibtex) {
  2574.         # Base only
  2575.         if ( $_ && ! /%/ ) { $_ .= " %O %B"; }
  2576.     }
  2577.     foreach ($dvipdf, $ps2pdf) {
  2578.         # Source and dest without flag for destination
  2579.         if ( $_ && ! /%/ ) { $_ .= " %O %S %D"; }
  2580.     }
  2581.     foreach ($dvips, $makeindex) {
  2582.         # Source and dest with -o dest before source
  2583.         if ( $_ && ! /%/ ) { $_ .= " %O -o %D %S"; }
  2584.     }
  2585.     foreach ($dvi_filter, $ps_filter) {
  2586.         # Source and dest, but as filters
  2587.         if ( $_ && ! /%/ ) { $_ .= " %O <%S >%D"; }
  2588.     }
  2589. } #END fix_cmds
  2590.  
  2591. #############################################################
  2592.  
  2593. sub add_option {
  2594.     # Call add_option( $opt, \$cmd ... )
  2595.     # Add option to one or more commands
  2596.     my $option = shift;
  2597.     while (@_) {
  2598.         if ( ${$_[0]} !~ /%/ ) { &fix_cmds; }
  2599.         ${$_[0]} =~ s/%O/$option %O/;
  2600.         shift;
  2601.     }
  2602. } #END add_option
  2603.  
  2604. #############################################################
  2605.  
  2606. sub rdb_make_rule_list {
  2607. # Set up specifications for standard rules, adjusted to current conditions
  2608. # Substitutions: %S = source, %D = dest, %B = this rule's base
  2609. #                %T = texfile, %R = root = base for latex.
  2610. #                %Y for $aux_dir1, %Z for $out_dir1
  2611.  
  2612.     # Defaults for dvi, ps, and pdf files
  2613.     # Use local, not my, so these variables can be referenced
  2614.     local $dvi_final = "%Z%R.dvi";
  2615.     local $ps_final  = "%Z%R.ps";
  2616.     local $pdf_final = "%Z%R.pdf";
  2617.     local $xdv_final = "%Z%R.xdv";
  2618.     if ( length($dvi_filter) > 0) {
  2619.         $dvi_final = "%Z%R.dviF";
  2620.     }
  2621.     if ( length($ps_filter) > 0) {
  2622.         $ps_final = "%Z%R.psF";
  2623.     }
  2624.  
  2625.     my $print_file = '';
  2626.     my $print_cmd = 'NONE';
  2627.     if ( $print_type eq 'dvi' ) {
  2628.         $print_file = $dvi_final;
  2629.         $print_cmd = $lpr_dvi;
  2630.     }
  2631.     elsif ( $print_type eq 'pdf' ) {
  2632.         $print_file = $pdf_final;
  2633.         $print_cmd = $lpr_pdf;
  2634.     }
  2635.     elsif ( $print_type eq 'ps' ) {
  2636.         $print_file = $ps_final;
  2637.         $print_cmd = $lpr;
  2638.     }
  2639.     elsif ( $print_type eq 'none' ) {
  2640.         $print_cmd = 'NONE echo NO PRINTING CONFIGURED';
  2641.     }
  2642.  
  2643.     my $view_file = '';
  2644.     my $viewer = '';
  2645.     my $viewer_update_method = 0;
  2646.     my $viewer_update_signal = undef;
  2647.     my $viewer_update_command = undef;
  2648.  
  2649.     if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) {
  2650.         $view_file = ${$view.'_final'};
  2651.         $viewer = ${$view.'_previewer'};
  2652.         $viewer_update_method = ${$view.'_update_method'};
  2653.         $viewer_update_signal = ${$view.'_update_signal'};
  2654.         if (defined ${$view.'_update_command'}) {
  2655.            $viewer_update_command = ${$view.'_update_command'};
  2656.         }
  2657.     }
  2658.     # Specification of internal command for viewer update:
  2659.     my $PA_update = ['do_update_view', $viewer_update_method, $viewer_update_signal, 0, 1];
  2660.  
  2661. # For test_kind: Use file contents for latex and friends, but file time for the others.
  2662. # This is because, especially for dvi file, the contents of the file may contain
  2663. #    a pointer to a file to be included, not the contents of the file!
  2664.     %rule_list = (
  2665.         'latex'    => [ 'primary',  "$latex",     '',            "%T",        "%Z%B.dvi",  "%R",   1, ["%Y%R.log"] ],
  2666.         'pdflatex' => [ 'primary',  "$pdflatex",  '',            "%T",        "%Z%B.pdf",  "%R",   1, ["%Y%R.log"] ],
  2667.         'lualatex' => [ 'primary',  "$lualatex",  '',            "%T",        "%Z%B.pdf",  "%R",   1, ["%Y%R.log"] ],
  2668.         'xelatex' =>  [ 'primary',  "$xelatex",   '',            "%T",        "%Z%B.xdv",  "%R",   1, ["%Y%R.log"] ],
  2669.         'dvipdf'   => [ 'external', "$dvipdf",    'do_viewfile', $dvi_final,  "%B.pdf",    "%Z%R", 2 ],
  2670.         'xdvipdfmx' => [ 'external', "$xdvipdfmx", 'do_viewfile', $xdv_final, "%B.pdf",    "%Z%R", 2 ],
  2671.         'dvips'    => [ 'external', "$dvips",     'do_viewfile', $dvi_final,  "%B.ps",     "%Z%R", 2 ],
  2672.         'dvifilter'=> [ 'external', $dvi_filter,  'do_viewfile', "%B.dvi",    "%B.dviF",   "%Z%R", 2 ],
  2673.         'ps2pdf'   => [ 'external', "$ps2pdf",    'do_viewfile', $ps_final,   "%B.pdf",    "%Z%R", 2 ],
  2674.         'psfilter' => [ 'external', $ps_filter,   'do_viewfile', "%B.ps",     "%B.psF",    "%Z%R", 2 ],
  2675.         'print'    => [ 'external', "$print_cmd", 'if_source',   $print_file, "",          "",     2 ],
  2676.         'update_view' => [ 'external', $viewer_update_command, $PA_update,
  2677.                                $view_file,  "",        "",   2 ],
  2678.         'view'     => [ 'external', "$viewer",    'if_source',   $view_file,  "",        "",   2 ],
  2679.     );
  2680.  
  2681. # Ensure we only have one way to make pdf file, and that it is appropriate:
  2682.     if    ($pdf_mode == 2) { delete $rule_list{'dvipdf'}; delete $rule_list{'pdflatex'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; }
  2683.     elsif ($pdf_mode == 3) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; }
  2684.     elsif ($pdf_mode == 4) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'dvipdf'}; delete $rule_list{'xelatex'}; }
  2685.     elsif ($pdf_mode == 5) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'dvipdf'}; delete $rule_list{'lualatex'}; }
  2686.     else                   { # Default is to leave pdflatex
  2687.                              delete $rule_list{'dvipdf'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'};
  2688.                            }
  2689.  
  2690. } # END rdb_make_rule_list
  2691.  
  2692. #************************************************************
  2693.  
  2694. sub rdb_set_rules {
  2695.     # Call rdb_set_rules( \%rule_list, ...)
  2696.     # Set up rule database from definitions
  2697.  
  2698.     # Map of files to rules that MAKE them:
  2699.     %rule_db = ();
  2700.  
  2701.     foreach my $Prule_list (@_) {
  2702.         foreach my $rule ( keys %$Prule_list) {
  2703.             my ( $cmd_type, $ext_cmd, $int_cmd, $source, $dest, $base, $test_kind, $PA_extra_gen ) = @{$$Prule_list{$rule}};
  2704.             if ( ! $PA_extra_gen ) { $PA_extra_gen = []; }
  2705.             my $needs_making = 0;
  2706.             # Substitute in the filename variables, since we will use
  2707.             # those for determining filenames.  But delay expanding $cmd
  2708.             # until run time, in case of changes.
  2709.             foreach ($base, $source, $dest, @$PA_extra_gen ) {
  2710.                 s/%R/$root_filename/;
  2711.                 s/%Y/$aux_dir1/;
  2712.                 s/%Z/$out_dir1/;
  2713.             }
  2714.             foreach ($source, $dest ) {
  2715.                 s/%B/$base/;
  2716.                 s/%T/$texfile_name/;
  2717.             }
  2718.     #        print "$rule: $cmd_type, EC='$ext_cmd', IC='$int_cmd', $test_kind,\n",
  2719.     #              "    S='$source', D='$dest', B='$base' $needs_making\n";
  2720.             rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, $test_kind,
  2721.                              $source, $dest, $base,
  2722.                              $needs_making, undef, undef, 1, $PA_extra_gen );
  2723. # !! ?? Last line was
  2724. #                            $needs_making, undef, ($test_kind==1) );
  2725.         }
  2726.     } # End arguments of subroutine
  2727.     &rdb_make_links;
  2728. } # END rdb_set_rules
  2729.  
  2730. #************************************************************
  2731.  
  2732. sub rdb_make_links {
  2733. # ?? Problem if there are multiple rules for getting a file.  Notably pdf.
  2734. #    Which one to choose?
  2735.     # Create $from_rule if there's a suitable rule.
  2736.     # Map files to rules:
  2737.     local %from_rules = ();
  2738.     rdb_for_all( sub{ if($$Pdest){$from_rules{$$Pdest} = $rule;} } );
  2739. #??    foreach (sort keys %from_rules) {print "D='$_' F='$from_rules{$_}\n";}
  2740.     rdb_for_all(
  2741.         0,
  2742.         sub{
  2743.             # Set from_rule, but only if it isn't set or is invalid.
  2744.             # Don't forget the biber v. bibtex issue
  2745.             if ( exists $from_rules{$file}
  2746.                  && ( (!$$Pfrom_rule) || (! exists $rule_db{$$Pfrom_rule} ) )
  2747.                )
  2748.             { $$Pfrom_rule = $from_rules{$file};
  2749.             }
  2750.         }
  2751.     );
  2752.     rdb_for_all(
  2753.         0,
  2754.         sub{
  2755.             if ( exists $from_rules{$file} ) {
  2756.                 $$Pfrom_rule = $from_rules{$file};
  2757.             }
  2758.             if ( $$Pfrom_rule && (! rdb_rule_exists( $$Pfrom_rule ) ) ) {
  2759.                 $$Pfrom_rule = '';
  2760.             }
  2761. #??            print "$rule: $file, $$Pfrom_rule\n";
  2762.         }
  2763.     );
  2764. } # END rdb_make_links
  2765.  
  2766. #************************************************************
  2767.  
  2768. sub set_trivial_aux_fdb {
  2769.     # 1. Write aux file EXACTLY as would be written if the tex file
  2770.     #    had no cross references, etc. I.e., a minimal .aux file.
  2771.     # 2. Write a corresponding fdb file
  2772.     # 3. Provoke a run of (pdf)latex (actually of all primaries).
  2773.  
  2774.     local *aux_file;
  2775.     open( aux_file, '>', $aux_main )
  2776.         or die "Cannot write file '$aux_main'\n";
  2777.     print aux_file "\\relax \n";
  2778.     close(aux_file);
  2779.  
  2780.     foreach my $rule (keys %primaries ) {
  2781.         rdb_ensure_file( $rule, $texfile_name );
  2782.         rdb_ensure_file( $rule, $aux_main );
  2783.         rdb_one_rule(  $rule,  
  2784.                        sub{ $$Pout_of_date = 1; }
  2785.                     );
  2786.     }
  2787.     &rdb_write( $fdb_name );
  2788. } #END set_trivial_aux_fdb
  2789.  
  2790. #************************************************************
  2791. #### Particular actions
  2792. #************************************************************
  2793. #************************************************************
  2794.  
  2795. sub do_cusdep {
  2796.     # Unconditional application of custom-dependency
  2797.     # except that rule is not applied if the source file source
  2798.     # does not exist, and an error is returned if the dest is not made.
  2799.     #
  2800.     # Assumes rule context for the custom-dependency, and that my first
  2801.     # argument is the name of the subroutine to apply
  2802.     my $func_name = $_[0];
  2803.     my $return = 0;
  2804.     if ( !-e $$Psource ) {
  2805.         # Source does not exist.  Users of this rule will need to turn
  2806.         # it off when custom dependencies are reset
  2807.         if ( !$silent ) {
  2808. ## ??? Was commented out.  1 Sep. 2008 restored, for cusdep no-file-exists issue
  2809.             warn "$My_name: In trying to apply custom-dependency rule\n",
  2810.             "  to make '$$Pdest' from '$$Psource'\n",
  2811.             "  the source file has disappeared since the last run\n";
  2812.         }
  2813.         # Treat as successful
  2814.     }
  2815.     elsif ( !$func_name ) {
  2816.         warn "$My_name: Possible misconfiguration or bug:\n",
  2817.         "  In trying to apply custom-dependency rule\n",
  2818.         "  to make '$$Pdest' from '$$Psource'\n",
  2819.         "  the function name is blank.\n";
  2820.     }
  2821.     elsif ( ! defined &$func_name ) {
  2822.         warn "$My_name: Misconfiguration or bug,",
  2823.         " in trying to apply custom-dependency rule\n",
  2824.         "  to make '$$Pdest' from '$$Psource'\n",
  2825.         "  function name '$func_name' does not exists.\n";
  2826.     }
  2827.     else {
  2828.         my $cusdep_ret = &$func_name( $$Pbase );
  2829.         if ( defined $cusdep_ret && ($cusdep_ret != 0) ) {
  2830.             $return = $cusdep_ret;
  2831.             if ($return) {
  2832.                 warn "Rule '$rule', function '$func_name'\n",
  2833.                      "   failed with return code = $return\n";
  2834.             }
  2835.         }
  2836.         elsif ( !-e $$Pdest ) {
  2837.             # Destination non-existent, but routine failed to give an error
  2838.             warn "$My_name: In running custom-dependency rule\n",
  2839.             "  to make '$$Pdest' from '$$Psource'\n",
  2840.             "  function '$func_name' did not make the destination.\n";
  2841.             $return = -1;
  2842.         }
  2843.     }
  2844.     return $return;
  2845. }  # END do_cusdep
  2846.  
  2847. #************************************************************
  2848.  
  2849. sub do_viewfile {
  2850.     # Unconditionally make file for viewing, going through temporary file if
  2851.     # Assumes rule context
  2852.  
  2853.     my $return = 0;
  2854.     my ($base, $path, $ext) = fileparseA( $$Pdest );
  2855.     if ( &view_file_via_temporary ) {
  2856.         if ( $$Pext_cmd =~ /%D/ ) {
  2857.             my $tmpfile = tempfile1( "${root_filename}_tmp", $ext );
  2858.             warn "$My_name: Making '$$Pdest' via temporary '$tmpfile'...\n";
  2859.             $return = &Run_subst( undef, undef, undef, undef, $tmpfile );
  2860.             move( $tmpfile, $$Pdest );
  2861.         }
  2862.         else {
  2863.             warn "$My_name is configured to make '$$Pdest' via a temporary file\n",
  2864.                  "    but the command template '$$Pext_cmd' does not have a slot\n",
  2865.             "    to set the destination file, so I won't use a temporary file\n";
  2866.             $return = &Run_subst();
  2867.         }
  2868.     }
  2869.     else {
  2870.         $return = &Run_subst();
  2871.     }
  2872.     return $return;
  2873. } #END do_viewfile
  2874.  
  2875. #************************************************************
  2876.  
  2877. sub do_update_view {
  2878.     # Update viewer
  2879.     # Assumes rule context
  2880.     # Arguments: (method, signal, viewer_process)
  2881.  
  2882.     my $return = 0;
  2883.  
  2884.     # Although the process is passed as an argument, we'll need to update it.
  2885.     # So (FUDGE??) bypass the standard interface for the process.
  2886.     # We might as well do this for all the arguments.
  2887.     my $viewer_update_method = ${$PAint_cmd}[1];
  2888.     my $viewer_update_signal = ${$PAint_cmd}[2];
  2889.     my $Pviewer_process             = \${$PAint_cmd}[3];
  2890.     my $Pneed_to_get_viewer_process = \${$PAint_cmd}[4];
  2891.    
  2892.     if ($viewer_update_method == 2) {
  2893.         if ($$Pneed_to_get_viewer_process) {
  2894.             $$Pviewer_process = &find_process_id( $$Psource );
  2895.             if ($$Pviewer_process != 0) {
  2896.                 $$Pneed_to_get_viewer_process = 0;
  2897.             }
  2898.         }
  2899.         if ($$Pviewer_process == 0) {
  2900.             print "$My_name: need to signal viewer for file '$$Psource', but didn't get \n",
  2901.                   "   process ID for some reason, e.g., no viewer, bad configuration, bug\n"
  2902.                 if $diagnostics ;            
  2903.         }
  2904.         elsif ( defined $viewer_update_signal) {
  2905.             print "$My_name: signalling viewer, process ID $$Pviewer_process ",
  2906.                   "with signal $viewer_update_signal\n"
  2907.                 if $diagnostics ;
  2908.             kill $viewer_update_signal, $$Pviewer_process;
  2909.         }
  2910.         else {
  2911.             warn "$My_name: viewer is supposed to be sent a signal\n",
  2912.                  "  but no signal is defined.  Misconfiguration or bug?\n";
  2913.             $return = 1;
  2914.         }
  2915.     }
  2916.     elsif ($viewer_update_method == 4) {
  2917.         if (defined $$Pext_cmd) {
  2918.             $return = &Run_subst();
  2919.         }
  2920.         else {
  2921.             warn "$My_name: viewer is supposed to be updated by running a command,\n",
  2922.                  "  but no command is defined.  Misconfiguration or bug?\n";
  2923.         }
  2924.     }
  2925.     return $return;
  2926. } #END do_update_view
  2927.  
  2928. #************************************************************
  2929.  
  2930. sub if_source {
  2931.     # Unconditionally apply rule if source file exists.
  2932.     # Assumes rule context
  2933.     if ( -e $$Psource ) {
  2934.         return &Run_subst();
  2935.     }
  2936.     else {
  2937.         warn "Needed source file '$$Psource' does not exist.\n";
  2938.         return -1;
  2939.     }
  2940. } #END if_source
  2941.  
  2942. #************************************************************
  2943. #### Subroutines
  2944. #************************************************************
  2945. #************************************************************
  2946.  
  2947. sub find_basename {
  2948.     # Finds the basename of the root file
  2949.     # Arguments:
  2950.     #  1 - Filename to breakdown
  2951.     #  2 - Where to place base file
  2952.     #  3 - Where to place tex file
  2953.     #  Returns non-zero if tex file does not exist
  2954.     #
  2955.     # The rules for determining this depend on the implementation of TeX.
  2956.     # The variable $extension_treatment determines which rules are used.
  2957.  
  2958.     # !!!!!!!! I still need to implement use of kpsewhich to match behavior
  2959.     # of (pdf)latex correctly.
  2960.  
  2961.   local($given_name, $base_name, $ext, $path, $tex_name);
  2962.   $given_name = $_[0];
  2963.   if ( "$extension_treatment" eq "miktex_old" ) {
  2964.        # Miktex v. 1.20d:
  2965.        #   1. If the filename has an extension, then use it.
  2966.        #   2. Else append ".tex".
  2967.        #   3. The basename is obtained from the filename by
  2968.        #      removing the path component, and the extension, if it
  2969.        #      exists.  If a filename has a multiple extension, then
  2970.        #      all parts of the extension are removed.
  2971.        #   4. The names of generated files (log, aux) are obtained by
  2972.        #      appending .log, .aux, etc to the basename.  Note that
  2973.        #      these are all in the CURRENT directory, and the drive/path
  2974.        #      part of the originally given filename is ignored.
  2975.        #
  2976.        #   Thus when the given filename is "\tmp\a.b.c", the tex
  2977.        #   filename is the same, and the basename is "a".
  2978.  
  2979.        ($base_name, $path, $ext) = fileparse( $given_name, '\..*' );
  2980.        if ( "$ext" eq "") { $tex_name = "$given_name.tex"; }
  2981.        else { $tex_name = $given_name; }
  2982.        $_[1] = $base_name;
  2983.        $_[2] = $tex_name;
  2984.   }
  2985.   elsif ( "$extension_treatment" eq "unix" ) {
  2986.        # unix (at least TeXLive 2016) =>
  2987.        #  A. Finding of tex file:
  2988.        #   1. If filename.tex exists, use it,
  2989.        #   2. else if kpsewhich finds filename.tex, use it
  2990.        #   3. else if filename exists, use it,
  2991.        #   4. else if kpsewhich finds filename, use it.
  2992.        #   (Probably can unify the above by
  2993.        #       1'. If kpsewhich finds filename.tex, use result.
  2994.        #       2'. else if kpsewhich finds filename, use result.
  2995.        #       3'. else report file not found.
  2996.        # B. The base filename is obtained by deleting the path
  2997.        #    component and, if an extension exists, the last
  2998.        #    component of the extension, even if the extension is
  2999.        #    null.  (A name ending in "." has a null extension.)
  3000.        # C. The names of generated files (log, aux) are obtained by
  3001.        #    appending .log, .aux, etc to the basename.  Note that
  3002.        #    these are all in the CURRENT directory, and the drive/path
  3003.        #    part of the originally given filename is ignored.
  3004.        #
  3005.        #   Thus when the given filename is "/tmp/a.b.c", there are two
  3006.        #   cases:
  3007.        #      a.  /tmp/a.b.c.tex exists.  Then this is the tex file,
  3008.        #          and the basename is "a.b.c".
  3009.        #      b.  /tmp/a.b.c.tex does not exist.  Then the tex file is
  3010.        #          "/tmp/a.b.c", and the basename is "a.b".
  3011.        #   But there are also modifications of this when a file can be
  3012.        #   found by kpsewhich.
  3013.  
  3014.       if ( -f "$given_name.tex" ) {
  3015.          $tex_name = "$given_name.tex";
  3016.       }
  3017.       else {
  3018.          $tex_name = "$given_name";
  3019.       }
  3020.       ($base_name, $path, $ext) = fileparse( $tex_name, '\.[^\.]*' );
  3021.       $_[1] = $base_name;
  3022.       $_[2] = $tex_name;
  3023.   }
  3024.   else {
  3025.      die "$My_name: Incorrect configuration gives \$extension_treatment=",
  3026.          "'$extension_treatment'\n";
  3027.   }
  3028.    if ($diagnostics) {
  3029.       print "Given='$given_name', tex='$tex_name', base='$base_name'\n";
  3030.   }
  3031.   return ! -e $tex_name;
  3032. } #END find_basename
  3033.  
  3034. #************************************************************
  3035.  
  3036. sub make_preview_continuous {
  3037.     local @changed = ();
  3038.     local @disappeared = ();
  3039.     local @no_dest = ();       # Non-existent destination files
  3040.     local @rules_never_run = ();
  3041.     local @rules_to_apply = ();
  3042.  
  3043.     local $failure = 0;
  3044.     local %rules_applied = ();
  3045.     local $updated = 0;
  3046.  
  3047.     # What to make?
  3048.     my @targets = keys %requested_filerules;
  3049.  
  3050.     $quell_uptodate_msgs = 1;
  3051.  
  3052.     local $view_file = '';
  3053.     rdb_one_rule( 'view', sub{ $view_file = $$Psource; } );
  3054.  
  3055.     if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) {
  3056.         warn "Viewing $view\n";
  3057.     }
  3058.     elsif ( $view eq 'none' ) {
  3059.         warn "Not using a previewer\n";
  3060.         $view_file = '';
  3061.     }
  3062.     else {
  3063.         warn "$My_name:  BUG: Invalid preview method '$view'\n";
  3064.         exit 20;
  3065.     }
  3066.  
  3067.     my $viewer_running = 0;    # No viewer known to be running yet
  3068.     # Get information from update_view rule
  3069.     local $viewer_update_method = 0;
  3070.     # Pointers so we can update the following:
  3071.     local $Pviewer_process = undef;    
  3072.     local $Pneed_to_get_viewer_process = undef;
  3073.     rdb_one_rule( 'update_view',
  3074.                   sub{ $viewer_update_method = $$PAint_cmd[1];
  3075.                        $Pviewer_process = \$$PAint_cmd[3];
  3076.                        $Pneed_to_get_viewer_process = \$$PAint_cmd[4];
  3077.                      }
  3078.                 );
  3079.     # Note that we don't get the previewer process number from the program
  3080.     # that starts it; that might only be a script to get things set up and the
  3081.     # actual previewer could be (and sometimes IS) another process.
  3082.  
  3083.     if ( ($view_file ne '') && (-e $view_file) && !$new_viewer_always ) {
  3084.         # Is a viewer already running?
  3085.         #    (We'll save starting up another viewer.)
  3086.         $$Pviewer_process = &find_process_id( $view_file );
  3087.         if ( $$Pviewer_process ) {
  3088.             warn "$My_name: Previewer is already running\n"
  3089.               if !$silent;
  3090.             $viewer_running = 1;
  3091.             $$Pneed_to_get_viewer_process = 0;
  3092.         }
  3093.     }
  3094.  
  3095.     # Loop forever, rebuilding .dvi and .ps as necessary.
  3096.     # Set $first_time to flag first run (to save unnecessary diagnostics)
  3097.     my $last_action_time = time();
  3098.     my $timed_out = 0;
  3099. CHANGE:
  3100.     for (my $first_time = 1; 1; $first_time = 0 ) {
  3101.         my %rules_to_watch = %requested_filerules;
  3102.         $updated = 0;
  3103.         $failure = 0;
  3104.         $failure_msg = '';
  3105.         if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) {
  3106.             # Fudge under MSWin32 ONLY, to stop perl/latexmk from
  3107.             #   catching ctrl/C and ctrl/break, and let it only reach
  3108.             #   downstream programs. See comments at first definition of
  3109.             #   $MSWin_fudge_break.
  3110.             $SIG{BREAK} = $SIG{INT} = 'IGNORE';
  3111.         }
  3112.         if ($compiling_cmd) {
  3113.             Run_subst( $compiling_cmd );
  3114.         }
  3115.         $failure = rdb_make( @targets );
  3116.  
  3117. ##     warn "=========Viewer PID = $$Pviewer_process; updated=$updated\n";
  3118.  
  3119.         if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) {
  3120.             $SIG{BREAK} = $SIG{INT} = 'DEFAULT';
  3121.         }
  3122.         # Start viewer if needed.
  3123.         if ( ($failure > 0) && (! $force_mode) ) {
  3124.             # No viewer yet
  3125.         }
  3126.         elsif ( ($view_file ne '') && (-e $view_file) && $updated && $viewer_running ) {
  3127.             # A viewer is running.  Explicitly get it to update screen if we have to do it:
  3128.             rdb_one_rule( 'update_view', \&rdb_run1 );
  3129.         }
  3130.         elsif ( ($view_file ne '') && (-e $view_file) && !$viewer_running ) {
  3131.             # Start the viewer
  3132.             if ( !$silent ) {
  3133.                 if ($new_viewer_always) {
  3134.                     warn "$My_name: starting previewer for '$view_file'\n",
  3135.                          "------------\n";
  3136.                 }
  3137.                 else {
  3138.                     warn "$My_name: I have not found a previewer that ",
  3139.                          "is already running. \n",
  3140.                          "   So I will start it for '$view_file'\n",
  3141.                          "------------\n";
  3142.                }
  3143.             }
  3144.             local $retcode = 0;
  3145.             rdb_one_rule( 'view', sub { $retcode = &rdb_run1;} );
  3146.             if ( $retcode != 0 ) {
  3147.                 if ($force_mode) {
  3148.                     warn "$My_name: I could not run previewer\n";
  3149.                 }
  3150.                 else {
  3151.                     &exit_msg1( "I could not run previewer", $retcode);
  3152.                 }
  3153.             }
  3154.             else {
  3155.                 $viewer_running = 1;
  3156.                 $$Pneed_to_get_viewer_process = 1;
  3157.             } # end analyze result of trying to run viewer
  3158.         } # end start viewer
  3159.         if ( $failure > 0 ) {
  3160.             if ( !$failure_msg ) {
  3161.                 $failure_msg = 'Failure to make the files correctly';
  3162.             }
  3163.             @pre_primary = ();   # Array of rules
  3164.             @post_primary = ();  # Array of rules
  3165.             @unusual_one_time = ();      # Array of rules
  3166.             &rdb_classify_rules( \%possible_primaries, keys %requested_filerules );
  3167.             # There will be files changed during the run that are irrelevant.
  3168.             # We need to wait for the user to change the files.
  3169.  
  3170.             # So set the GENERATED files from (pdf)latex as up-to-date:
  3171.             rdb_for_some( [keys %current_primaries], \&rdb_update_gen_files );
  3172.  
  3173.             # And don't watch for changes for post_primary rules (ps and pdf
  3174.             # from dvi, etc haven't been run after an error in (pdf)latex, so
  3175.             # are out-of-date by filetime criterion, but they should not be run
  3176.             # until after another (pdf)latex run:
  3177.             foreach (@post_primary) { delete $rules_to_watch{$_}; }
  3178.  
  3179.             $failure_msg =~ s/\s*$//;  #Remove trailing space
  3180.             warn "$My_name: $failure_msg\n",
  3181.     "    ==> You will need to change a source file before I do another run <==\n";
  3182.             if ($failure_cmd) {
  3183.                 Run_subst( $failure_cmd );
  3184.             }
  3185.         }
  3186.         else {
  3187.             if ($success_cmd) {
  3188.                 Run_subst( $success_cmd );
  3189.             }
  3190.         }
  3191.         rdb_show_rule_errors();
  3192.         if ($rules_list) { rdb_list(); }
  3193.         if ($show_time && ! $first_time) { show_timing(); }
  3194.         if ( $dependents_list && ($updated || $failure) ) {
  3195.            my $deps_handle = new FileHandle "> $deps_file";
  3196.            if ( defined $deps_handle ) {
  3197.                deps_list($deps_handle);
  3198.                close($deps_handle);
  3199.            }
  3200.            else {
  3201.                warn "Cannot open '$deps_file' for output of dependency information\n";
  3202.            }
  3203.          }
  3204.         if ( $first_time || $updated || $failure ) {
  3205.             print "\n=== Watching for updated files. Use ctrl/C to stop ...\n";
  3206.         }
  3207.         $waiting = 1; if ($diagnostics) { warn "WAITING\n"; }
  3208. # During waiting for file changes, handle ctrl/C and ctrl/break here, rather than letting
  3209. #   system handle them by terminating script (and any script that calls it).  This allows,
  3210. #   for example, the clean up code in the following command line to work:
  3211. #          latexmk -pvc foo; cleanup;
  3212.         &catch_break;
  3213.         $have_break = 0;
  3214.         $last_action_time = time();
  3215.   WAIT: while (1) {
  3216.            sleep( $sleep_time );
  3217.            if ($have_break) { last WAIT; }
  3218.            if ( rdb_new_changes(keys %rules_to_watch) ) {
  3219.                if (!$silent) {
  3220.                    warn "$My_name: Need to remake files.\n";
  3221.                    &rdb_diagnose_changes( '  ' );
  3222.                }
  3223.                last WAIT;
  3224.            }
  3225.            #  Don't count waiting time in processing:
  3226.            $processing_time1 = processing_time();
  3227.         # Does this do this job????
  3228.            local $new_files = 0;
  3229.            rdb_for_some( [keys %current_primaries], sub{ $new_files += &rdb_find_new_files } );
  3230.            if ($new_files > 0) {
  3231.                warn "$My_name: New file(s) found.\n";
  3232.                last WAIT;
  3233.            }
  3234.            if ($have_break) { last WAIT; }
  3235.            if ($pvc_timeout && ( time() > $last_action_time+60*$pvc_timeout_mins ) ) {
  3236.            $timed_out = 1;
  3237.            last WAIT;
  3238.            }
  3239.      } # end WAIT:
  3240.      &default_break;
  3241.      if ($have_break) {
  3242.           print "$My_name: User typed ctrl/C or ctrl/break.  I'll finish.\n";
  3243.           return;
  3244.      }
  3245.      if ($timed_out) {
  3246.          print "$My_name: More than $pvc_timeout_mins mins of inactivity.  I'll finish.\n";
  3247.          return;
  3248.      }
  3249.      $waiting = 0; if ($diagnostics) { warn "NOT       WAITING\n"; }
  3250.   } #end infinite_loop CHANGE:
  3251. } #END sub make_preview_continuous
  3252.  
  3253. #************************************************************
  3254.  
  3255. sub process_rc_file {
  3256.     # Usage process_rc_file( filename )
  3257.     # NEW VERSION
  3258.     # Run rc_file whose name is given in first argument
  3259.     #    Exit with code 0 on success
  3260.     #    Exit with code 1 if file cannot be read or does not exist.
  3261.     #    Stop if there is a syntax error or other problem.
  3262.     # PREVIOUSLY:
  3263.     #    Exit with code 2 if is a syntax error or other problem.
  3264.     my $rc_file = $_[0];
  3265.     my $ret_code = 0;
  3266.     warn "$My_name: Executing Perl code in file '$rc_file'...\n"
  3267.         if  $diagnostics;
  3268.     # I could use the do command of perl, but the preceeding -r test
  3269.     # to get good diagnostics gets the wrong result under cygwin
  3270.     # (e.g., on /cygdrive/c/latexmk/LatexMk)
  3271.     my $RCH = new FileHandle;
  3272.     if ( !-e $rc_file ) {
  3273.         warn "$My_name: The rc-file '$rc_file' does not exist\n";
  3274.         return 1;
  3275.     }
  3276.     elsif ( -d $rc_file ) {
  3277.         warn "$My_name: The supposed rc-file '$rc_file' is a directory; but it\n",
  3278.              "          should be a normal text file\n";
  3279.         return 1;
  3280.     }
  3281.     elsif ( open $RCH, "<$rc_file" ) {
  3282.         { local $/; eval <$RCH>; }
  3283.         close $RCH;
  3284.     }
  3285.     else {
  3286.         warn "$My_name: I cannot read the rc-file '$rc_file'\n";
  3287.         return 1;
  3288.     }
  3289.     # PREVIOUS VERSION
  3290. #    if ( ! -r $rc_file ) {
  3291. #        warn "$My_name: I cannot read the rc-file '$rc_file'\n",
  3292. #            "          or at least that's what Perl (for $^O) reports\n";
  3293. #        return 1;
  3294. #    }
  3295. #    do( $rc_file );
  3296.     if ( $@ ) {
  3297.         # Indent each line of possibly multiline message:
  3298.         my $message = prefix( $@, "     " );
  3299.         warn "$My_name: Initialization file '$rc_file' gave an error:\n",
  3300.              "$message\n";
  3301.         die "$My_name: Stopping because of problem with rc file\n";
  3302.         # Use the following if want non-fatal error.
  3303.         return 2;
  3304.     }
  3305.     return 0;
  3306. } #END process_rc_file
  3307.  
  3308. #************************************************************
  3309.  
  3310. sub execute_code_string {
  3311.     # Usage execute_code_string( string_of_code )
  3312.     # Run the perl code contained in first argument
  3313.     #    Halt if there is a syntax error or other problem.
  3314.     # ???Should I leave the exiting to the caller (perhaps as an option)?
  3315.     #     But I can always catch it with an eval if necessary.
  3316.     #     That confuses ctrl/C and ctrl/break handling.
  3317.     my $code = $_[0];
  3318.     warn "$My_name: Executing initialization code specified by -e:\n",
  3319.          "   '$code'...\n"
  3320.         if  $diagnostics;
  3321.     eval $code;
  3322.     # The return value from the eval is not useful, since it is the value of
  3323.     #    the last expression evaluated, which could be anything.
  3324.     # The correct test of errors is on the value of $@.
  3325.  
  3326.     if ( $@ ) {
  3327.         # Indent each line of possibly multiline message:
  3328.         my $message = prefix( $@, "    " );
  3329.         die "$My_name: ",
  3330.             "Stopping because executing following code from command line\n",
  3331.             "    $code\n",
  3332.             "gave an error:\n",
  3333.             "$message\n";
  3334.     }
  3335. } #END execute_code_string
  3336.  
  3337. #************************************************************
  3338.  
  3339. sub cleanup1 {
  3340.     # Usage: cleanup1( directory, exts_without_period, ... )
  3341.     #
  3342.     # The directory and the root file name are fixed names, so I must escape
  3343.     #   any glob metacharacters in them:
  3344.     my $dir = fix_pattern( shift );
  3345.     my $root_fixed = fix_pattern( $root_filename );
  3346.     foreach (@_) {
  3347.         (my $name = /%R/ ? $_ : "%R.$_") =~ s/%R/${dir}${root_fixed}/;
  3348.         unlink_or_move( my_glob( "$name" ) );
  3349.     }
  3350. } #END cleanup1
  3351.  
  3352. #************************************************************
  3353.  
  3354. sub cleanup_cusdep_generated {
  3355.     # Remove files generated by custom dependencies
  3356.     rdb_for_all( \&cleanup_one_cusdep_generated );
  3357. } #END cleanup_cusdep_generated
  3358.  
  3359. #************************************************************
  3360.  
  3361. sub cleanup_one_cusdep_generated {
  3362.     # Remove destination file generated by one custom dependency
  3363.     # Assume rule context, but not that the rule is a custom dependency.
  3364.     # Only delete destination file if source file exists (so destination
  3365.     #   file can be recreated)
  3366.     if ( $$Pcmd_type ne 'cusdep' ) {
  3367.        # NOT cusdep
  3368.        return;
  3369.     }
  3370.     if ( (-e $$Pdest) && (-e $$Psource) ) {
  3371.         unlink_or_move( $$Pdest );
  3372.     }
  3373.     elsif ( (-e $$Pdest) && (!-e $$Psource) ) {
  3374.         warn "$My_name: For custom dependency '$rule',\n",
  3375.              "    I won't delete destination file '$$Pdest'\n",
  3376.              "    because the source file '$$Psource' doesn't exist,\n",
  3377.              "    so the destination file may not be able to be recreated\n";
  3378.     }
  3379. } #END cleanup_one_cusdep_generated
  3380.  
  3381. #************************************************************
  3382. #************************************************************
  3383. #************************************************************
  3384.  
  3385. #   Error handling routines, warning routines, help
  3386.  
  3387. #************************************************************
  3388.  
  3389. sub die_trace {
  3390.     # Call: die_trace( message );
  3391.     &traceback;   # argument(s) passed unchanged
  3392.     die "\n";
  3393. } #END die_trace
  3394.  
  3395. #************************************************************
  3396.  
  3397. sub traceback {
  3398.     # Call: &traceback
  3399.     # or traceback( message,  )
  3400.     my $msg = shift;
  3401.     if ($msg) { warn "$msg\n"; }
  3402.     warn "Traceback:\n";
  3403.     my $i=0;     # Start with immediate caller
  3404.     while ( my ($pack, $file, $line, $func) = caller($i++) ) {
  3405.         if ($func eq 'die_trace') { next; }
  3406.         warn "   $func called from line $line\n";
  3407.     }
  3408. } #END traceback
  3409.  
  3410. #************************************************************
  3411.  
  3412. sub exit_msg1
  3413. {
  3414.   # exit_msg1( error_message, retcode [, action])
  3415.   #    1. display error message
  3416.   #    2. if action set, then restore aux file
  3417.   #    3. exit with retcode
  3418.   warn "\n------------\n";
  3419.   warn "$My_name: $_[0].\n";
  3420.   warn "-- Use the -f option to force complete processing.\n";
  3421.  
  3422.   my $retcode = $_[1];
  3423.   if ($retcode >= 256) {
  3424.      # Retcode is the kind returned by system from an external command
  3425.      # which is 256 * command's_retcode
  3426.      $retcode /= 256;
  3427.   }
  3428.   exit $retcode;
  3429. } #END exit_msg1
  3430.  
  3431. #************************************************************
  3432.  
  3433. sub warn_running {
  3434.    # Message about running program:
  3435.     if ( $silent ) {
  3436.         warn "$My_name: @_\n";
  3437.     }
  3438.     else {
  3439.         warn "------------\n@_\n------------\n";
  3440.     }
  3441. } #END warn_running
  3442.  
  3443. #************************************************************
  3444.  
  3445. sub exit_help
  3446. # Exit giving diagnostic from arguments and how to get help.
  3447. {
  3448.     warn "\n$My_name: @_\n",
  3449.          "Use\n",
  3450.          "   $my_name -help\nto get usage information\n";
  3451.     exit 10;
  3452. } #END exit_help
  3453.  
  3454.  
  3455. #************************************************************
  3456.  
  3457. sub print_help
  3458. {
  3459.   print
  3460.   "$My_name $version_num: Automatic LaTeX document generation routine\n\n",
  3461.   "Usage: $my_name [latexmk_options] [filename ...]\n\n",
  3462.   "  Latexmk_options:\n",
  3463.   "   -aux-directory=dir or -auxdir=dir \n",
  3464.   "                 - set name of directory for auxiliary files (aux, log)\n",
  3465.   "                 - Currently this only works with MiKTeX\n",
  3466.   "   -bibtex       - use bibtex when needed (default)\n",
  3467.   "   -bibtex-      - never use bibtex\n",
  3468.   "   -bibtex-cond  - use bibtex when needed, but only if the bib file exists\n",
  3469.   "   -bibtex-cond1 - use bibtex when needed, but only if the bib file exists;\n",
  3470.   "                   on cleanup delete bbl file only if bib file exists\n",
  3471.   "   -bm <message> - Print message across the page when converting to postscript\n",
  3472.   "   -bi <intensity> - Set contrast or intensity of banner\n",
  3473.   "   -bs <scale> - Set scale for banner\n",
  3474.   "   -commands  - list commands used by $my_name for processing files\n",
  3475.   "   -c     - clean up (remove) all nonessential files, except\n",
  3476.   "            dvi, ps and pdf files.\n",
  3477.   "            This and the other clean-ups are instead of a regular make.\n",
  3478.   "   -C     - clean up (remove) all nonessential files\n",
  3479.   "            including aux, dep, dvi, postscript and pdf files\n",
  3480.   "            and file of database of file information\n",
  3481.   "   -CA     - clean up (remove) all nonessential files.\n",
  3482.   "            Equivalent to -C option.\n",
  3483.   "   -CF     - Remove file of database of file information before doing \n",
  3484.   "            other actions\n",
  3485.   "   -cd    - Change to directory of source file when processing it\n",
  3486.   "   -cd-   - Do NOT change to directory of source file when processing it\n",
  3487.   "   -dependents or -deps - Show list of dependent files after processing\n",
  3488.   "   -dependents- or -deps- - Do not show list of dependent files\n",
  3489.   "   -deps-out=file - Set name of output file for dependency list,\n",
  3490.   "                    and turn on showing of dependency list\n",
  3491.   "   -dF <filter> - Filter to apply to dvi file\n",
  3492.   "   -dvi   - generate dvi\n",
  3493.   "   -dvi-  - turn off required dvi\n",
  3494.   "   -e <code> - Execute specified Perl code (as part of latexmk start-up\n",
  3495.   "               code)\n",
  3496.   "   -f     - force continued processing past errors\n",
  3497.   "   -f-    - turn off forced continuing processing past errors\n",
  3498.   "   -gg    - Super go mode: clean out generated files (-CA), and then\n",
  3499.   "            process files regardless of file timestamps\n",
  3500.   "   -g     - process regardless of file timestamps\n",
  3501.   "   -g-    - Turn off -g\n",
  3502.   "   -h     - print help\n",
  3503.   "   -help - print help\n",
  3504.   "   -jobname=STRING - set basename of output file(s) to STRING.\n",
  3505.   "            (Like --jobname=STRING on command line for many current\n",
  3506.   "            implementations of latex/pdflatex.)\n",
  3507.   "   -l     - force landscape mode\n",
  3508.   "   -l-    - turn off -l\n",
  3509.   "   -latex=<program> - set program used for latex.\n",
  3510.   "                      (replace '<program>' by the program name)\n",
  3511.   "   -latexoption=<option> - add the given option to the (pdf)latex command\n",
  3512.   "   -logfilewarninglist or -logfilewarnings \n",
  3513.   "               give list of warnings after run of (pdf)latex\n",
  3514.   "   -logfilewarninglist- or -logfilewarnings- \n",
  3515.   "               do not give list of warnings after run of (pdf)latex\n",
  3516.   "   -lualatex     - use lualatex for processing files to pdf\n",
  3517.   "                   and turn dvi/ps modes off\n",
  3518.   "   -M     - Show list of dependent files after processing\n",
  3519.   "   -MF file - Specifies name of file to receives list dependent files\n",
  3520.   "   -MP    - List of dependent files includes phony target for each source file.\n",
  3521.   "   -new-viewer    - in -pvc mode, always start a new viewer\n",
  3522.   "   -new-viewer-   - in -pvc mode, start a new viewer only if needed\n",
  3523.   "   -nobibtex      - never use bibtex\n",
  3524.   "   -nodependents  - Do not show list of dependent files after processing\n",
  3525.   "   -norc          - omit automatic reading of system, user and project rc files\n",
  3526.   "   -output-directory=dir or -outdir=dir\n",
  3527.   "                  - set name of directory for output files\n",
  3528.   "   -pdf   - generate pdf by pdflatex\n",
  3529.   "   -pdfdvi - generate pdf by dvipdf\n",
  3530.   "   -pdflatex=<program> - set program used for pdflatex.\n",
  3531.   "                      (replace '<program>' by the program name)\n",
  3532.   "   -pdfps - generate pdf by ps2pdf\n",
  3533.   "   -pdflua - generate pdf by lualatex\n",
  3534.   "   -pdfxe - generate pdf by xelatex\n",
  3535.   "   -pdf-  - turn off pdf\n",
  3536.   "   -ps    - generate postscript\n",
  3537.   "   -ps-   - turn off postscript\n",
  3538.   "   -pF <filter> - Filter to apply to postscript file\n",
  3539.   "   -p     - print document after generating postscript.\n",
  3540.   "            (Can also .dvi or .pdf files -- see documentation)\n",
  3541.   "   -print=dvi     - when file is to be printed, print the dvi file\n",
  3542.   "   -print=ps      - when file is to be printed, print the ps file (default)\n",
  3543.   "   -print=pdf     - when file is to be printed, print the pdf file\n",
  3544.   "   -pv    - preview document.  (Side effect turn off continuous preview)\n",
  3545.   "   -pv-   - turn off preview mode\n",
  3546.   "   -pvc   - preview document and continuously update.  (This also turns\n",
  3547.   "                on force mode, so errors do not cause $my_name to stop.)\n",
  3548.   "            (Side effect: turn off ordinary preview mode.)\n",
  3549.   "   -pvc-  - turn off -pvc\n",
  3550.   "   -pvctimeout    - timeout in pvc mode after period of inactivity\n",
  3551.   "   -pvctimeout-   - don't timeout in pvc mode after inactivity\n",
  3552.   "   -pvctimeoutmins=<time> - set period of inactivity (minutes) for pvc timeout\n",
  3553.   "   -quiet    - silence progress messages from called programs\n",
  3554.   "   -r <file> - Read custom RC file\n",
  3555.   "               (N.B. This file could override options specified earlier\n",
  3556.   "               on the command line.)\n",
  3557.   "   -recorder - Use -recorder option for (pdf)latex\n",
  3558.   "               (to give list of input and output files)\n",
  3559.   "   -recorder- - Do not use -recorder option for (pdf)latex\n",
  3560.   "   -rules    - Show list of rules after processing\n",
  3561.   "   -rules-   - Do not show list of rules after processing\n",
  3562.   "   -showextraoptions  - Show other allowed options that are simply passed\n",
  3563.   "               as is to latex and pdflatex\n",
  3564.   "   -silent   - silence progress messages from called programs\n",
  3565.   "   -time     - show CPU time used\n",
  3566.   "   -time-    - don't show CPU time used\n",
  3567.   "   -use-make - use the make program to try to make missing files\n",
  3568.   "   -use-make- - don't use the make program to try to make missing files\n",
  3569.   "   -v        - display program version\n",
  3570.   "   -verbose  - display usual progress messages from called programs\n",
  3571.   "   -version      - display program version\n",
  3572.   "   -view=default - viewer is default (dvi, ps, pdf)\n",
  3573.   "   -view=dvi     - viewer is for dvi\n",
  3574.   "   -view=none    - no viewer is used\n",
  3575.   "   -view=ps      - viewer is for ps\n",
  3576.   "   -view=pdf     - viewer is for pdf\n",
  3577.   "   -xelatex      - use xelatex for processing files to pdf\n",
  3578.   "                   and turn dvi/ps modes off\n",
  3579.   "\n",
  3580.   "   filename = the root filename of LaTeX document\n",
  3581.   "\n",
  3582.   "-p, -pv and -pvc are mutually exclusive\n",
  3583.   "-h, -c and -C override all other options.\n",
  3584.   "-pv and -pvc require one and only one filename specified\n",
  3585.   "All options can be introduced by '-' or '--'.  (E.g., --help or -help.)\n",
  3586.   " \n",
  3587.   "In addition, latexmk recognizes many other options that are passed to\n",
  3588.   "latex and/or pdflatex without interpretation by latexmk.  Run latexmk\n",
  3589.   "with the option -showextraoptions to see a list of these\n",
  3590.   "\n",
  3591.   "Report bugs etc to John Collins <jcc8 at psu.edu>.\n";
  3592.  
  3593. } #END print_help
  3594.  
  3595. #************************************************************
  3596.  
  3597. sub print_commands {
  3598.   warn "Commands used by $my_name:\n",
  3599.        "   To run latex, I use \"$latex\"\n",
  3600.        "   To run pdflatex, I use \"$pdflatex\"\n",
  3601.        "   To run lualatex, I use \"$lualatex\"\n",
  3602.        "   To run xelatex, I use \"$xelatex\"\n",
  3603.        "   To run biber, I use \"$biber\"\n",
  3604.        "   To run bibtex, I use \"$bibtex\"\n",
  3605.        "   To run makeindex, I use \"$makeindex\"\n",
  3606.        "   To make a ps file from a dvi file, I use \"$dvips\"\n",
  3607.        "   To make a ps file from a dvi file with landscape format, ",
  3608.            "I use \"$dvips_landscape\"\n",
  3609.        "   To make a pdf file from a dvi file, I use \"$dvipdf\"\n",
  3610.        "   To make a pdf file from a ps file, I use \"$ps2pdf\"\n",
  3611.        "   To make a pdf file from an xdv file, I use \"$xdvipdfmx\"\n",
  3612.        "   To view a pdf file, I use \"$pdf_previewer\"\n",
  3613.        "   To view a ps file, I use \"$ps_previewer\"\n",
  3614.        "   To view a ps file in landscape format, ",
  3615.             "I use \"$ps_previewer_landscape\"\n",
  3616.        "   To view a dvi file, I use \"$dvi_previewer\"\n",
  3617.        "   To view a dvi file in landscape format, ",
  3618.             "I use \"$dvi_previewer_landscape\"\n",
  3619.        "   To print a ps file, I use \"$lpr\"\n",
  3620.        "   To print a dvi file, I use \"$lpr_dvi\"\n",
  3621.        "   To print a pdf file, I use \"$lpr_pdf\"\n",
  3622.        "   To find running processes, I use \"$pscmd\", \n",
  3623.        "      and the process number is at position $pid_position\n";
  3624.    warn "Notes:\n",
  3625.         "  Command starting with \"start\" is run detached\n",
  3626.         "  Command that is just \"start\" without any other command, is\n",
  3627.         "     used under MS-Windows to run the command the operating system\n",
  3628.         "     has associated with the relevant file.\n",
  3629.         "  Command starting with \"NONE\" is not used at all\n";
  3630. } #END print_commands
  3631.  
  3632. #************************************************************
  3633.  
  3634. sub view_file_via_temporary {
  3635.     return $always_view_file_via_temporary
  3636.            || ($pvc_view_file_via_temporary && $preview_continuous_mode);
  3637. } #END view_file_via_temporary
  3638.  
  3639. #************************************************************
  3640. #### Tex-related utilities
  3641.  
  3642. #**************************************************
  3643.  
  3644. sub check_biber_log {
  3645.     # Check for biber warnings:
  3646.     # Usage: check_biber_log( base_of_biber_run, \@biber_source )
  3647.     # return 0: OK;
  3648.     #        1: biber warnings;
  3649.     #        2: biber errors;
  3650.     #        3: could not open .blg file;
  3651.     #        4: failed to find one or more source files, except for bibfile;
  3652.     #        5: failed to find bib file;
  3653.     #        6: missing file, one of which is control file
  3654.     #       10: only error is missing \citation commands.
  3655.     #       11: Malformed bcf file (normally due to error in pdflatex run)
  3656.     # Side effect: add source files @biber_source
  3657.     my $base = $_[0];
  3658.     my $Pbiber_source = $_[1];
  3659.     my $log_name = "$base.blg";
  3660.     my $log_file = new FileHandle;
  3661.     open( $log_file, "<$log_name" )
  3662.       or return 3;
  3663.     my $have_warning = 0;
  3664.     my $have_error = 0;
  3665.     my $missing_citations = 0;
  3666.     my $no_citations = 0;
  3667.     my $error_count = 0;            # From my counting of error messages
  3668.     my $warning_count = 0;          # From my counting of warning messages
  3669.     # The next two occur only from biber
  3670.     my $bibers_error_count = 0;     # From biber's counting of errors
  3671.     my $bibers_warning_count = 0;   # From biber's counting of warnings
  3672.     my $not_found_count = 0;
  3673.     my $control_file_missing = 0;
  3674.     my $control_file_malformed = 0;
  3675.     while (<$log_file>) {
  3676.         if (/> WARN /) {
  3677.             print "Biber warning: $_";
  3678.             $have_warning = 1;
  3679.             $warning_count ++;
  3680.         }
  3681.         elsif (/> (FATAL|ERROR) /) {
  3682.             print "Biber error: $_";
  3683.             if ( /> (FATAL|ERROR) - Cannot find file '([^']+)'/    #'
  3684.                  || /> (FATAL|ERROR) - Cannot find '([^']+)'/ ) {  #'
  3685.                 $not_found_count++;
  3686.                 push @$Pbiber_source, $2;
  3687.             }
  3688.             elsif ( /> (FATAL|ERROR) - Cannot find control file '([^']+)'/ ) {  #'
  3689.                 $not_found_count++;
  3690.                 $control_file_missing = 1;
  3691.                 push @$Pbiber_source, $2;
  3692.             }
  3693.             elsif ( /> ERROR - .*\.bcf is malformed/ ) {
  3694.         #  Special treatment: Malformed .bcf file commonly results from error
  3695.         #  in (pdf)latex run.  This error must be ignored.
  3696.         $control_file_malformed = 1;
  3697.         }
  3698.             else {
  3699.                 $have_error = 1;
  3700.                 $error_count ++;
  3701.                 if ( /> (FATAL|ERROR) - The file '[^']+' does not contain any citations!/ ) { #'
  3702.                     $no_citations++;
  3703.                 }
  3704.             }
  3705.         }
  3706.         elsif ( /> INFO - Found .* '([^']+)'\s*$/
  3707.                 || /> INFO - Found '([^']+)'\s*$/
  3708.                 || /> INFO - Reading '([^']+)'\s*$/
  3709.                 || /> INFO - Reading (.*)$/
  3710.                 || /> INFO - Processing .* file '([^']+)' .*$/
  3711.               ) {
  3712.             if ( defined $Pbiber_source ) {
  3713.                 push @$Pbiber_source, $1;
  3714.             }
  3715.         }
  3716.         elsif ( /> INFO - WARNINGS: ([\d]+)\s*$/ ) {
  3717.             $bibers_warning_count = $1;
  3718.         }
  3719.         elsif ( /> INFO - ERRORS: ([\d]+)\s*$/ ) {
  3720.             $bibers_error_count = $1;
  3721.         }
  3722.     }
  3723.     close $log_file;
  3724.     if ($control_file_malformed){return 11;}
  3725.  
  3726.     my @not_found = &find_file_list1( $Pbiber_source, $Pbiber_source,
  3727.                                       '', \@BIBINPUTS );
  3728.     @$Pbiber_source = uniqs( @$Pbiber_source );
  3729.     if ( ($#not_found < 0) && ($#$Pbiber_source >= 0) ) {
  3730.         warn "$My_name: Found biber source file(s) [@$Pbiber_source]\n"
  3731.         unless $silent;
  3732.     }
  3733.     elsif ( ($#not_found == 0) && ($not_found[0] =~ /\.bib$/) ) {
  3734.         # Special treatment if sole missing file is bib file
  3735.         # I don't want to treat that as an error
  3736.         warn "$My_name: Biber did't find bib file [$not_found[0]]\n";
  3737.         return 5;
  3738.     }
  3739.     else {
  3740.         show_array( "$My_name: Failed to find one or more biber source files:",
  3741.                     @not_found );
  3742.         if ($force_mode) {
  3743.             warn "==== Force_mode is on, so I will continue.  ",
  3744.                  "But there may be problems ===\n";
  3745.         }
  3746.         if ($control_file_missing) {
  3747.             return 6;
  3748.         }
  3749.         return 4;
  3750.     }
  3751. #    print "$My_name: #Biber errors = $error_count, warning messages = $warning_count,\n  ",
  3752. #          "missing citation messages = $missing_citations, no_citations = $no_citations\n";
  3753.     if ( ! $have_error && $no_citations ) {
  3754.         # If the only errors are missing citations, or lack of citations, that should
  3755.         # count as a warning.
  3756.         # HOWEVER: biber doesn't generate a new bbl.  So it is an error condition.
  3757.         return 10;
  3758.     }
  3759.     if ($have_error) {return 2;}
  3760.     if ($have_warning) {return 1;}
  3761.     return 0;
  3762. } #END check_biber_log
  3763.  
  3764. #**************************************************
  3765.  
  3766. sub run_bibtex {
  3767.     my $return = 999;
  3768.     # Prevent changes we make to environment becoming global:
  3769.     local %ENV = %ENV;
  3770.     if ( $aux_dir ) {
  3771.         # Use \Q and \E round directory name in regex to avoid interpretation
  3772.         #   of metacharacters in directory name:
  3773.         if ( $$Psource =~ /^\Q$aux_dir1\E/ ) {
  3774.             # Run bibtex in $aux_dir, fixing input search path
  3775.             # to allow for finding files in original directory
  3776.             my ( $base, $path, $ext ) = fileparseA( $$Psource );
  3777.             my $cwd = good_cwd();
  3778.             foreach ( 'BIBINPUTS', 'BSTINPUTS' ) {
  3779.                 if ( exists $ENV{$_} ) {
  3780.                     $ENV{$_} = $cwd.$search_path_separator.$ENV{$_};
  3781.                 }
  3782.                 else {
  3783.                     $ENV{$_} = $cwd.$search_path_separator;
  3784.                 }
  3785.             }
  3786.             pushd( $path );
  3787.             $return = &Run_subst( undef, undef, '', $base.$ext, '', $base );
  3788.             popd();
  3789.         }
  3790.         else {
  3791.             warn "$My_name: Directory in file name '$$Psource' for bibtex\n",
  3792.                  "   but it is not the output directory '$aux_dir'\n";
  3793.             $return = Run_subst();
  3794.         }
  3795.     }
  3796.     else {
  3797.         $return = Run_subst();
  3798.     }
  3799.     return $return;
  3800. }
  3801.  
  3802.  
  3803. #**************************************************
  3804.  
  3805. sub check_bibtex_log {
  3806.     # Check for bibtex warnings:
  3807.     # Usage: check_bibtex_log( base_of_bibtex_run )
  3808.     # return 0: OK, 1: bibtex warnings, 2: bibtex errors,
  3809.     #        3: could not open .blg file.
  3810.     #       10: only error is missing \citation commands or a missing aux file
  3811.     #           (which would normally be corrected after a later run of
  3812.     #           (pdf)latex).
  3813.  
  3814.     my $base = $_[0];
  3815.     my $log_name = "$base.blg";
  3816.     my $log_file = new FileHandle;
  3817.     open( $log_file, "<$log_name" )
  3818.       or return 3;
  3819.     my $have_warning = 0;
  3820.     my $have_error = 0;
  3821.     my $missing_citations = 0;
  3822.     my @missing_aux = ();
  3823.     my $error_count = 0;
  3824.     while (<$log_file>) {
  3825.         if (/^Warning--/) {
  3826.             #print "Bibtex warning: $_";
  3827.             $have_warning = 1;
  3828.         }
  3829.         elsif ( /^I couldn\'t open auxiliary file (.*\.aux)/ ) {
  3830.             push @missing_aux, $1;
  3831.         }
  3832.         elsif ( /^I found no \\citation commands---while reading file/ ) {
  3833.             $missing_citations++;
  3834.         }
  3835.         elsif (/There (were|was) (\d+) error message/) {
  3836.             $error_count = $2;
  3837.             #print "Bibtex error: count=$error_count $_";
  3838.             $have_error = 1;
  3839.         }
  3840.     }
  3841.     close $log_file;
  3842.     my $missing = $missing_citations + $#missing_aux + 1;
  3843.  
  3844.     if ( $#missing_aux > -1 ) {
  3845.         # Need to make the missing files.
  3846.         warn "$My_name: One or more aux files is missing for bibtex. I'll try\n",
  3847.              "          to get (pdf)latex to remake them.\n";
  3848.         rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
  3849.     }
  3850.     #print "Bibtex errors = $error_count, missing aux files and citations = $missing\n";
  3851.     if ($have_error && ($error_count <= $missing )
  3852.         && ($missing > 0) ) {
  3853.         # If the only error is a missing citation line, that should only
  3854.         # count as a warning.
  3855.         # Also a missing aux file should be innocuous; it will be created on
  3856.         # next run of (pdf)latex.  ?? HAVE I HANDLED THAT CORRECTLY?
  3857.         # But have to deal with the problem that bibtex gives a non-zero
  3858.         # exit code.  So leave things as they are so that the user gets
  3859.         # a better diagnostic ??????????????????????????
  3860. #        $have_error = 0;
  3861. #        $have_warning = 1;
  3862.         return 10;
  3863.     }
  3864.     if ($have_error) {return 2;}
  3865.     if ($have_warning) {return 1;}
  3866.     return 0;
  3867. } #END check_bibtex_log
  3868.  
  3869. #**************************************************
  3870.  
  3871. sub normalize_force_directory {
  3872.     #  Usage, normalize_force_directory( dir, filename )
  3873.     #  Perform the following operations:
  3874.     #    Clean filename
  3875.     #    If filename contains no path component, insert dir in front
  3876.     #    Normalize filename
  3877.     #  Return result
  3878.     my $default_dir = $_[0];
  3879.     my $filename = clean_filename( $_[1] );
  3880.     my ($base_name, $path ) = fileparse( $filename );
  3881.     if ( $base_name eq $filename ) {
  3882.        $filename = "$default_dir$filename";
  3883.     }
  3884.     return normalize_filename( $filename );
  3885. } #END normalize force_directory
  3886.  
  3887. # ------------------------------
  3888.  
  3889. sub parse_log {
  3890.  
  3891. # Scan log file for: dependent files
  3892. #    reference_changed, bad_reference, bad_citation
  3893. # Return value: 1 if success, 0 if no log file.
  3894. # Put results in UPDATES of global variables (which are normally declared
  3895. # local in calling routine, to be suitably scoped):
  3896. #   %dependents: maps definite dependents to code:
  3897. #      0 = from missing-file line
  3898. #            May have no extension
  3899. #            May be missing path
  3900. #      1 = from 'File: ... Graphic file (type ...)' line
  3901. #            no path.  Should exist, but may need a search, by kpsewhich.
  3902. #      2 = from regular '(...' coding for input file,
  3903. #            Has NO path, which it would do if LaTeX file
  3904. #            Highly likely to be mis-parsed line
  3905. #      3 = ditto, but has a path character ('/').  
  3906. #            Should be LaTeX file that exists.
  3907. #            If it doesn't exist, we have probably a mis-parsed line.
  3908. #            There's no need to do a search.
  3909. #      4 = definitive, which in this subroutine is only done:
  3910. #             for default dependents,
  3911. #             and for files that exist and are source of conversion
  3912. #                reported by epstopdf et al.
  3913. #      5 = Had a missing file line.  Now the file exists.
  3914. #      6 = File was written during run.  (Overrides 5)
  3915. #      7 = File was created during run to be read in.  (Overrides 5 and 6)
  3916. #          (e.g., by epstopdf)
  3917. # Treat the following specially, since they have special rules
  3918. #   @bbl_files to list of .bbl files.
  3919. #   %idx_files to map from .idx files to .ind files.
  3920. # %generated_log: keys give set of files written by (pdf)latex (e.g., aux, idx)
  3921. #   as determined by \openout = ... lines in log file.
  3922. # @missing_subdirs = list of needed subdirectories of aux_dir
  3923. #   These are needed for writing aux_files when an included file is in
  3924. #   a subdirectory relative to the directory of the main TeX file.
  3925. #   This variable is only set when the needed subdirectories don't exist,
  3926. #   and the aux_dir is non-trivial, which results in an error message in
  3927. #   the log file
  3928. #  %conversions Internally made conversions from one file to another
  3929. #
  3930. #  These may have earlier found information in them, so they should NOT
  3931. #  be initialized.
  3932. #
  3933. # Also SET
  3934. #   $reference_changed, $bad_reference, $bad_citation
  3935. #   $pwd_latex
  3936. #
  3937. # Put in trivial or default values if log file does not exist/cannot be opened
  3938. #
  3939. # Input globals: $primary_out, $fls_file_analyzed
  3940. #
  3941.    
  3942.    
  3943. # Give a quick way of looking up custom-dependency extensions
  3944.     my %cusdep_from = ();
  3945.     my %cusdep_to = ();
  3946.     foreach ( @cus_dep_list ) {
  3947.         my ($fromext, $toext) = split;
  3948.         $cusdep_from{$fromext} = $cusdep_from{".$fromext"} = $_;
  3949.         $cusdep_to{$toext} = $cusdep_to{".$toext"} = $_;
  3950.     }
  3951. #    print "==== Cusdep from-exts:"; foreach (keys %cusdep_from) {print " '$_'";} print "\n";
  3952. #    print "==== Cusdep to-exts:"; foreach (keys %cusdep_to) {print " '$_'";} print "\n";
  3953.  
  3954.  
  3955.     # Filenames given in log file may be preceded by a pathname
  3956.     #   denoting current directory.  In MiKTeX, this is an absolute
  3957.     #   pathname; in TeXLive, it is './'. Either way, we'll want to
  3958.     #   remove this pathname string --- see the comments in sub
  3959.     #   rdb_set_latex_deps.  In order of reliability for use in
  3960.     #   normalizing filenames from the log file, the following forms
  3961.     #   of the cwd are used:
  3962.     # (a) internally deduced pwd from log file from sequence of lines
  3963.     #                  **file
  3964.     #                  (dir/file
  3965.     #     if possible.  NO THAT'S WRONG if kpsearch is done.
  3966.     # (b) from PWD line in fls file (if available), passed as $pwd_latex
  3967.     # (c) system-given cwd as interpreted by sub good_cwd.
  3968.     # We'll put the first two in  @pwd_log
  3969.     my @pwd_log = ();
  3970.     if ($pwd_latex) { push @pwd_log, $pwd_latex; }
  3971.  
  3972.     # $primary_out is actual output file (dvi or pdf)
  3973.     # It is initialized before the call to this routine, to ensure
  3974.     # a sensible default in case of misparsing
  3975.  
  3976.     $reference_changed = 0;
  3977.     $mult_defined = 0;
  3978.     $bad_reference = 0;
  3979.     $bad_citation = 0;
  3980.  
  3981.     my $log_file = new FileHandle;
  3982.     if ( ! open( $log_file, "<$log_name" ) ) {
  3983.         return 0;
  3984.     }
  3985.     if ($log_file_binary) { binmode $log_file; }
  3986. # Collect lines of log file
  3987.     my @lines = ();
  3988.     my $line = 0;
  3989.     my $engine = 'pdfTeX';  # Simple default in case of problems
  3990.     while(<$log_file>) {
  3991.     $line++;
  3992.         # Could use chomp here, but that fails if there is a mismatch
  3993.         #    between the end-of-line sequence used by latex and that
  3994.         #    used by perl.  (Notably a problem with MSWin latex and
  3995.         #    cygwin perl!)
  3996.         s/[\n\r]*$//;
  3997.         # Handle wrapped lines:
  3998.         # They are lines brutally broken at exactly $log_wrap chars
  3999.         #    excluding line-end.  Sometimes a line $log_wrap chars
  4000.         #    long is an ordinary line, sometimes it is part of a line
  4001.         #    that was wrapped.  To handle all cases, I keep both
  4002.         #    options open by putting the line into @lines before
  4003.         #    and after appending the next line:  
  4004.         my $len = length($_);
  4005.     if ($line == 1) {
  4006.         if ( /^This is ([^,]+), / ) {
  4007.         $engine = $1;
  4008.         print "=== TeX engine is '$engine'\n"
  4009.             if (!$silent);
  4010.         }
  4011.         else {
  4012.         warn "$My_name: First line of .log file '$log_name' is not in standard format.\n";
  4013.         }
  4014.     }
  4015.     else {
  4016.         # LuaTeX sometimes wraps at 80 instead of 79, so work around this
  4017.             while ( ( ($len == $log_wrap) || ( ($engine eq 'LuaTeX') && ($len == $log_wrap+1) ) )
  4018.                     && !eof($log_file) ) {
  4019.                 push @lines, $_;
  4020.                 my $extra = <$log_file>;
  4021.                 $extra =~ s/[\n\r]*$//;
  4022.                 $len = length($extra);
  4023.                 $_ .= $extra;
  4024.         }
  4025.         }
  4026.         push @lines, $_;
  4027.     }
  4028.     close $log_file;
  4029.  
  4030.     push @lines, "";   # Blank line to terminate.  So multiline blocks
  4031.               # are always terminated by non-block line, rather than eof.
  4032.    
  4033.     $line = 0;
  4034.     my $state = 0;   # 0 => before ** line,
  4035.                      # 1 => after **filename line, before next line (first file-reading line)
  4036.                      # 2 => pwd_log determined.
  4037.     # For parsing multiple line blocks of info
  4038.     my $current_pkg = "";   # non-empty string for package name, if in
  4039.                             # middle of parsing multi-line block of form:
  4040.                             #       Package name ....
  4041.                             #       (name) ...
  4042.                             #       ...
  4043.     my $block_type = "";         # Specify information in such a block
  4044.     my $delegated_source = "";   # If it is a file conversion, specify source
  4045.     my $delegated_output = "";   #    and output file.  (Don't put in
  4046.                                  #    data structure until block is ended.)
  4047.     my %new_conversions = ();
  4048.     my @retries = ();
  4049.     my $log_silent = ($silent ||  $silence_logfile_warnings);
  4050.     my @warning_list = ();
  4051. LINE:
  4052.     while( ($line <= $#lines) || ($#retries > -1) ) {
  4053.         if ($#retries > -1) {
  4054.             $_ = pop @retries;
  4055.         }
  4056.         else {
  4057.             $_ = $lines[$line];
  4058.             $line ++;
  4059.         }
  4060.         if ( /^! pdfTeX warning/ || /^pdfTeX warning/ ) {
  4061.             # This kind of warning is produced by some versions of pdftex
  4062.             # or produced by my reparse of warnings from other
  4063.             # versions.
  4064.             next;
  4065.         }
  4066.         elsif ( /^(.+)(pdfTeX warning.*)$/ ) {
  4067.             # Line contains a pdfTeX warnings that may have been
  4068.             # inserted directly after other material without an
  4069.             # intervening new line.  I think pdfTeX always inserts a
  4070.             # newline after the warning.  (From examination of source
  4071.             # code.)
  4072.             push @retries, $1;
  4073.             # But continue parsing the original line, in case it was a
  4074.             # misparse, e.g., of a filename ending in 'pdfTeX';
  4075.         }
  4076.         if ( $line == 1 ){
  4077.             if ( /^This is / ) {
  4078.                 # First line OK
  4079.                 next LINE;
  4080.             } else {
  4081.                 warn "$My_name: Error on first line of '$log_name'.\n".
  4082.                     "This is apparently not a TeX log file.  ",
  4083.                     "The first line is:\n$_\n";
  4084.                 $failure = 1;
  4085.                 $failure_msg = "Log file '$log_name' appears to have wrong format.";
  4086.                 return 0;
  4087.             }
  4088.         }
  4089.  
  4090.         if ( ($state == 0) && /^\*\*(.*)$/ ) {
  4091.             # Line containing first line specified to tex
  4092.             # It's either a filename or a command starting with \
  4093.             my $first = $1;
  4094.             $state = 1;
  4095.             if ( ! /^\\/ ) {
  4096.                 $source_log = $first;
  4097.                 if ( -e "$source_log.tex" ) { $source_log .= '.tex'; }
  4098.             }
  4099.             else {
  4100.                 $state = 2;
  4101.             }
  4102.             next LINE;
  4103.         }
  4104.         elsif ( $state == 1 ) {
  4105.             $state = 2;
  4106.         if (-e $source_log) {
  4107.         # then the string preceeding $source_log on the line after the
  4108.         # ** line is probably the PWD as it appears in filenames in the
  4109.                 # log file, except if the file appears in two locations.
  4110.                 if ( m{^\("([^"]*)[/\\]\Q$source_log\E"} ) {
  4111.                    unshift @pwd_log, $1;
  4112.             }
  4113.                elsif ( m{^\((.*)[/\\]\Q$source_log\E} ) {
  4114.                    unshift @pwd_log, $1;
  4115.                }
  4116.         }
  4117.        }
  4118.  
  4119.        if ( $block_type ) {
  4120.            # In middle of parsing block
  4121.            if ( /^\($current_pkg\)/ ) {
  4122.                # Block continues
  4123.                if ( ($block_type eq 'conversion')
  4124.                     && /^\($current_pkg\)\s+Output file: <([^>]+)>/ )
  4125.                {
  4126.                    $delegated_output = normalize_clean_filename($1, @pwd_log);
  4127.                }
  4128.                next LINE;
  4129.            }
  4130.            # Block has ended.
  4131.            if ($block_type eq 'conversion') {
  4132. #print "=== $delegated_source -> $delegated_output\n";
  4133.                 $new_conversions{$delegated_source} =  $delegated_output;
  4134.            }
  4135.            $current_pkg = $block_type
  4136.                 = $delegated_source = $delegated_output = "";
  4137.            # Then process current line
  4138.        }
  4139.  
  4140.        # Check for changed references, bad references and bad citations:
  4141.        if (/Rerun to get/) {
  4142.            warn "$My_name: References changed.\n" if ! $log_silent;
  4143.            $reference_changed = 1;
  4144.        }
  4145.        if (/^LaTeX Warning: (Reference[^\001]*undefined on input line .*)\./) {
  4146.            push @warning_list, $1;
  4147.            $bad_reference++;
  4148.        }
  4149.        elsif (/^LaTeX Warning: (Label [^\001]* multiply defined.*)\./) {
  4150.            push @warning_list, $1;
  4151.            $mult_defined++;
  4152.        }
  4153.        elsif (/^LaTeX Warning: (Citation[^\001]*undefined on input line .*)\./) {
  4154.            push @warning_list, $1;
  4155.            $bad_citation++;
  4156.        }
  4157.        elsif (/^Package natbib Warning: (Citation[^\001]*undefined on input line .*)\./) {
  4158.            push @warning_list, $1;
  4159.            $bad_citation++;
  4160.        }
  4161.        elsif ( /^Document Class: / ) {
  4162.            # Class sign-on line
  4163.            next LINE;
  4164.        }
  4165.        elsif ( /^\(Font\)/ ) {
  4166.            # Font info line
  4167.            next LINE;
  4168.        }
  4169.        elsif (/^No pages of output\./) {
  4170.            $primary_out = '';
  4171.            warn "$My_name: Log file says no output from latex\n";
  4172.            next LINE;
  4173.        }
  4174.        elsif ( /^Output written on\s+(.*)\s+\(\d+\s+page/ ) {
  4175.            $primary_out = normalize_clean_filename($1, @pwd_log);
  4176.            warn "$My_name: Log file says output to '$primary_out'\n"
  4177.               unless $silent;
  4178.            next LINE;
  4179.        }
  4180.        elsif ( /^Overfull /
  4181.             || /^Underfull /
  4182.             || /^or enter new name\. \(Default extension: .*\)/
  4183.             || /^\*\*\* \(cannot \\read from terminal in nonstop modes\)/
  4184.           ) {
  4185.            # Latex error/warning, etc.
  4186.            next LINE;
  4187.        }
  4188.        elsif ( /^\\openout\d+\s*=\s*\`([^\']+)\'\.$/ ) {
  4189.                #  When (pdf)latex is run with an -output-directory
  4190.                #    or an -aux_directory, the file name does not contain
  4191.                #    the output path; fix this, after removing quotes:
  4192.            $generated_log{normalize_force_directory( $aux_dir1, $1 )} = 1;
  4193.            next LINE;
  4194.        }
  4195.        # Test for conversion produced by package:
  4196.        elsif ( /^Package (\S+) Info: Source file: <([^>]+)>/ ) {
  4197.            # Info. produced by epstopdf (and possibly others)
  4198.            #    about file conversion
  4199.            $current_pkg = normalize_clean_filename($1, @pwd_log);
  4200.            $delegated_source = normalize_clean_filename($2, @pwd_log);
  4201.            $block_type = 'conversion';
  4202.            next LINE;
  4203.        }
  4204. #    Test for writing of index file.  The precise format of the message
  4205. #    depends on which package (makeidx.sty , multind.sty or index.sty) and
  4206. #    which version writes the message.
  4207.        elsif ( /Writing index file (.*)$/ ) {
  4208.            my $idx_file = '';
  4209.            if ( /^Writing index file (.*)$/ ) {
  4210.                # From makeidx.sty or multind.sty
  4211.                $idx_file = $1;
  4212.            }
  4213.            elsif ( /^index\.sty> Writing index file (.*)$/ ) {
  4214.                # From old versions of index.sty
  4215.                $idx_file = $1;
  4216.            }
  4217.            elsif ( /^Package \S* Info: Writing index file (.*) on input line/ ) {
  4218.                # From new versions of index.sty
  4219.                $idx_file = $1;                
  4220.            }
  4221.            else {
  4222.                warn "$My_name: Message indicates index file was written\n",
  4223.                     "  ==> but I do not know how to understand it: <==\n",
  4224.                     "  '$_'\n";
  4225.                next LINE;
  4226.            }
  4227.                # Typically, there is trailing space, not part of filename:
  4228.            $idx_file =~ s/\s*$//;
  4229.                #  When (pdf)latex is run with an -output-directory
  4230.                #    or an -aux_directory, the file name does not contain
  4231.                #    the output path; fix this, after removing quotes:
  4232.            $idx_file = normalize_force_directory( $aux_dir1, $idx_file );
  4233.            my ($idx_base, $idx_path, $idx_ext) = fileparseA( $idx_file );
  4234.            $idx_base = $idx_path.$idx_base;
  4235.            $idx_file = $idx_base.$idx_ext;
  4236.            if ( $idx_ext eq '.idx' ) {
  4237.                warn "$My_name: Index file '$idx_file' was written\n"
  4238.                  unless $silent;
  4239.                $idx_files{$idx_file} = [ "$idx_base.ind", $idx_base ];
  4240.            }
  4241.            elsif ( exists $cusdep_from{$idx_ext} ) {
  4242.                if ( !$silent ) {
  4243.                    warn "$My_name: Index file '$idx_file' was written\n";
  4244.                    warn "   Cusdep '$cusdep_from{$idx_ext}' should be used\n";
  4245.                }
  4246.                # No action needed here
  4247.            }
  4248.            else {
  4249.                warn "$My_name: Index file '$idx_file' written\n",
  4250.                     "  ==> but it has an extension I do not know how to handle <==\n";
  4251.            }
  4252.  
  4253.            next LINE;
  4254.        }
  4255.        elsif ( /^No file (.*?\.bbl)./ ) {
  4256.                #  When (pdf)latex is run with an -output-directory
  4257.                #    or an -aux_directory, the file name does not contain
  4258.                #    the output path; fix this, after removing quotes:
  4259.            my $bbl_file = normalize_force_directory( $aux_dir1, $1 );
  4260.            warn "$My_name: Non-existent bbl file '$bbl_file'\n $_\n";
  4261.            $dependents{$bbl_file} = 0;
  4262.            push @bbl_files, $bbl_file;
  4263.            next LINE;
  4264.        }
  4265.        foreach my $pattern (@file_not_found) {
  4266.            if ( /$pattern/ ) {
  4267.                my $file = clean_filename($1);
  4268.                warn "===========$My_name: Missing input file: '$file' from line\n  '$_'\n";
  4269.                warn "$My_name: Missing input file: '$file' from line\n  '$_'\n"
  4270.                    unless $silent;
  4271.                $dependents{normalize_filename($file, @pwd_log)} = 0;
  4272.                my $file1 = $file;
  4273.                if ( $aux_dir ) {
  4274.                      # Allow for the possibility that latex generated
  4275.                      # a file in $aux_dir, from which the missing file can
  4276.                      # be created by a cusdep (or other) rule that puts
  4277.                      # the result in $out_dir.  If the announced missing file
  4278.                      # has no path, then it would be effectively a missing
  4279.                      # file in $aux_dir, with a path.  So give this alternate
  4280.                      # location.
  4281.                      my $file1 = normalize_force_directory( $aux_dir1, $file );
  4282.                      $dependents{$file1} = 0;
  4283.                }
  4284.                next LINE;
  4285.            }
  4286.        }
  4287.        if ( (! $fls_file_analyzed)
  4288.             && /^File: (.+) Graphic file \(type / ) {
  4289.            # First line of message from includegraphics/x
  4290.         # But this does NOT include full path information
  4291.         #   (if exact match is not found and a non-trivial
  4292.         #   kpsearch was done by (pdf)latex).
  4293.         # But the source-file information is in the fls file,
  4294.         #   if we are using it.
  4295.            $dependents{normalize_clean_filename($1, @pwd_log)} = 1;
  4296.            next LINE;
  4297.        }
  4298.        # Now test for generic lines to ignore, only after special cases!
  4299.        if ( /^File: / ) {
  4300.           # Package sign-on line. Includegraphics/x also produces a line
  4301.           # with this signature, but I've already handled it.
  4302.           next LINE;
  4303.        }
  4304.        if ( /^Package: / ) {
  4305.            # Package sign-on line
  4306.            next LINE;
  4307.        }
  4308.        if (/^\! LaTeX Error: / ) {
  4309.            next LINE;
  4310.        }
  4311.        if ( m[^! I can't write on file `(.*)/([^/']*)'.\s*$] ) {
  4312.            my $dir = $1;
  4313.            my $file = $2;
  4314.            my $full_dir = $aux_dir1.$dir;
  4315.            if ( ($aux_dir ne '') && (! -e $full_dir) && ( $file =~ /\.aux$/) ) {
  4316.                warn "$My_name: === There were problems writing to '$file' in '$full_dir'\n",
  4317.                     "    I'll try to make the subdirectory later.\n"
  4318.                  if $diagnostics;
  4319.                push @missing_subdirs, $full_dir;
  4320.            }
  4321.            else {
  4322.                warn "$My_name: ====== There were problems writing to",
  4323.                     "----- '$file' in '$full_dir'.\n",
  4324.                     "----- But this is not the standard situation of\n",
  4325.                     "----- aux file to subdir of output directory, with\n",
  4326.                     "----- non-existent subdir\n",
  4327.            }
  4328.        }
  4329.  
  4330.     if ( ($fls_file_analyzed) && (! $analyze_input_log_always) ) {
  4331.         # Skip the last part, which is all about finding input
  4332.         # file names which should all appear more reliably in the
  4333.         # fls file.
  4334.         next LINE;
  4335.     }
  4336.    
  4337.        my @new_includes = ();
  4338.    
  4339.   GRAPHICS_INCLUDE_CANDIDATE:
  4340.        while ( /<([^>]+)(>|$)/g ) {
  4341.         if ( -f $1 ) { push @new_includes, $1; }
  4342.         }  # GRAPHICS_INCLUDE_CANDIDATE:
  4343.  
  4344.   INCLUDE_CANDIDATE:
  4345.        while ( /\((.*$)/ ) {
  4346.        # Filename found by
  4347.        # '(', then filename, then terminator.
  4348.        # Terminators: obvious candidates: ')':  end of reading file
  4349.        #                                  '(':  beginning of next file
  4350.        #                                  ' ':  space is an obvious separator
  4351.        #                                  ' [': start of page: latex
  4352.        #                                        and pdflatex put a
  4353.        #                                        space before the '['
  4354.        #                                  '[':  start of config file
  4355.        #                                        in pdflatex, after
  4356.        #                                        basefilename.
  4357.        #                                  '{':  some kind of grouping
  4358.        # Problem:
  4359.        #   All or almost all special characters are allowed in
  4360.        #   filenames under some OS, notably UNIX.  Luckily most cases
  4361.        #   are rare, if only because the special characters need
  4362.        #   escaping.  BUT 2 important cases are characters that are
  4363.        #   natural punctuation
  4364.        #   Under MSWin, spaces are common (e.g., "C:\Program Files")
  4365.        #   Under VAX/VMS, '[' delimits directory names.  This is
  4366.        #   tricky to handle.  But I think few users use this OS
  4367.        #   anymore.
  4368.        #
  4369.        # Solution: use ' [', but not '[' as first try at delimiter.
  4370.        # Then if candidate filename is of form 'name1[name2]', then
  4371.        #   try splitting it.  If 'name1' and/or 'name2' exists, put
  4372.        #   it/them in list, else just put 'name1[name2]' in list.
  4373.        # So form of filename is now:
  4374.        #  '(',
  4375.        # then any number of characters that are NOT ')', '(', or '{'
  4376.        #   (these form the filename);
  4377.        # then ' [', or ' (', or ')', or end-of-string.
  4378.        # That fails for pdflatex
  4379.        # In log file:
  4380.        #   '(' => start of reading of file, followed by filename
  4381.        #   ')' => end of reading of file
  4382.        #   '[' => start of page (normally preceeded by space)
  4383.        # Remember:
  4384.        #    filename (on VAX/VMS) may include '[' and ']' (directory
  4385.        #             separators)
  4386.        #    filenames (on MS-Win) commonly include space.
  4387.        #    filenames on UNIX can included space.
  4388.        #    Miktex quotes filenames
  4389.        #    But web2c doesn't.  Then
  4390.         #       (string  message
  4391.         #    is ambiguous: is the filename "string" or "string message".
  4392.         #    Allow both as candidates, since user filenames with spaces
  4393.         #    are rare.  System filenames with spaces are common, but
  4394.         #    they are normally followed by a newline rather than messages.
  4395.  
  4396.         # First step: replace $_ by whole of line after the '('
  4397.         #             Thus $_ is putative filename followed by other stuff.
  4398.             $_ = $1;
  4399.             # Array of new candidate include files; sometimes more than one.
  4400.             my $quoted = 0;
  4401.             if ( /^\"([^\"]+)\"/ ) {
  4402.                # Quoted file name, as from MikTeX
  4403.                 $quoted = 1;
  4404.             }
  4405.             elsif ( /^([^\(^\)]*?)\s+[\[\{\<]/ ) {
  4406.                 # Terminator: space then '[' or '{' or '<'
  4407.                 # Use *? in condition: to pick up first ' [' (etc)
  4408.                 # as terminator
  4409.             }
  4410.             elsif ( /^([^\(^\)]*)\s+(?=\()/ ) {
  4411.                 # Terminator is ' (', but '(' isn't in matched string,
  4412.                 # so we keep the '(' ready for the next match
  4413.             }
  4414.             elsif  ( /^([^\(^\)]*)(\))/ ) {
  4415.                 # Terminator is ')'
  4416.             }
  4417.             else {
  4418.                 #Terminator is end-of-string
  4419.             }
  4420.             $_ = $';       # Put $_ equal to the unmatched tail of string '
  4421.             my $include_candidate = $1;
  4422.             $include_candidate =~ s/\s*$//;   # Remove trailing space.
  4423.             if ( !$quoted && ($include_candidate =~ /(\S+)\s/ ) ){
  4424.                 # Non-space-containing filename-candidate
  4425.                 # followed by space followed by message
  4426.                 # (Common)
  4427.                 push @new_includes, $1;
  4428.             }
  4429.             if ( $include_candidate eq "[]" ) {
  4430.                 # Part of overfull hbox message
  4431.                 next INCLUDE_CANDIDATE;
  4432.             }
  4433.             if ( $include_candidate =~ /^\\/ ) {
  4434.                 # Part of font message
  4435.                 next INCLUDE_CANDIDATE;
  4436.             }
  4437.             # Remove quotes around filename, as for MikTeX.  I've already
  4438.             # treated this as a special case.  For safety check here:
  4439.             $include_candidate =~ s/^\"(.*)\"$/$1/;
  4440.  
  4441.             push @new_includes, $include_candidate;
  4442.             if ( $include_candidate =~ /^(.+)\[([^\]]+)\]$/ ) {
  4443.                 # Construct of form 'file1[file2]', as produced by pdflatex
  4444.                 if ( -e $1 ) {
  4445.                     # If the first component exists, we probably have the
  4446.                     #   pdflatex form
  4447.                     push @new_includes, $1, $2;
  4448.                 }
  4449.                 else {
  4450.                     # We have something else.
  4451.                     # So leave the original candidate in the list
  4452.                 }
  4453.             }
  4454.         } # INCLUDE_CANDIDATE
  4455.  
  4456.     INCLUDE_NAME:
  4457.         foreach my $include_name (@new_includes) {
  4458.             $include_name = normalize_filename( $include_name, @pwd_log );
  4459.             my ($base, $path, $ext) = fileparseB( $include_name );
  4460.             if ( ($path eq './') || ($path eq '.\\') ) {
  4461.                 $include_name = $base.$ext;
  4462.             }
  4463.             if ( $include_name !~ m'[/|\\]' ) {
  4464.                 # Filename does not include a path character
  4465.                 # High potential for misparsed line
  4466.                 $dependents{$include_name} = 2;
  4467.             } else {
  4468.                 $dependents{$include_name} = 3;
  4469.             }
  4470.             if ( $ext eq '.bbl' ) {
  4471.                 warn "$My_name: Found input bbl file '$include_name'\n"
  4472.                    unless $silent;
  4473.                 push @bbl_files, $include_name;
  4474.             }
  4475.         } # INCLUDE_NAME
  4476.     } # LINE
  4477.  
  4478.     # Default includes are always definitive:
  4479.     foreach (@default_includes) { $dependents{$_} = 4; }
  4480.  
  4481.     ###print "New parse: \n";
  4482.     ###foreach (sort keys %dependents) { print "  '$_': $dependents{$_}\n"; }
  4483.  
  4484.     my @misparsed = ();
  4485.     my @missing = ();
  4486.     my @not_found = ();
  4487.  
  4488.     my %kpsearch_candidates = ();
  4489. CANDIDATE:
  4490.     foreach my $candidate (keys %dependents) {
  4491.         my $code = $dependents{$candidate};
  4492.         if ( -d $candidate ) {
  4493.             #  If $candidate is directory, it was presumably found from a
  4494.             #     mis-parse, so remove it from the list.  (Misparse can
  4495.             #     arise, for example from a mismatch of latexmk's $log_wrap
  4496.             #     value and texmf.cnf value of max_print_line.)
  4497.             delete $dependents{$candidate};
  4498.         }
  4499.         elsif ( -e $candidate ) {
  4500.             if ( exists $generated_log{$candidate} ){
  4501.                 $dependents{$candidate} = 6;
  4502.             }
  4503.             elsif ($code == 0) {
  4504.                 $dependents{$candidate} = 5;
  4505.             }
  4506.             else {
  4507.                 $dependents{$candidate} = 4;
  4508.             }
  4509.         }
  4510.         elsif ($code == 1) {
  4511.             # Graphics file that is supposed to have been read.
  4512.             # Candidate name is as given in source file, not as path
  4513.             #   to actual file.
  4514.             # We have already tested that file doesn't exist, as given.
  4515.             #   so use kpsewhich.  
  4516.             # If the file still is not found, assume non-existent;
  4517.             $kpsearch_candidates{$candidate} = 1;
  4518.         delete $dependents{$candidate};
  4519.         }
  4520.         elsif ($code == 2) {
  4521.             # Candidate is from '(...' construct in log file, for input file
  4522.             #    which should include pathname if valid input file.
  4523.             # Name does not have pathname-characteristic character (hence
  4524.             #    $code==2.
  4525.             # We get here if candidate file does not exist with given name
  4526.             # Almost surely result of a misparsed line in log file.
  4527.             delete $dependents{$candidate};
  4528.             push @misparse, $candidate;
  4529.         }
  4530.         elsif ($code == 3) {
  4531.             # Candidate is from '(...' construct in log file, for input file
  4532.             #    which should include pathname if valid input file.
  4533.             # Name does have pathname-characteristic character (hence
  4534.             #    $code==3.
  4535.             # But we get here only if candidate file does not exist with
  4536.             # given name.  
  4537.             # Almost surely result of a misparsed line in log file.
  4538.             # But with lower probability than $code == 2
  4539.             delete $dependents{$candidate};
  4540.             push @misparse, $candidate;
  4541.         }
  4542.         elsif ($code == 0) {
  4543.             my ($base, $path, $ext) = fileparseA($candidate);
  4544.             $ext =~ s/^\.//;
  4545.             if ( ($ext eq '') && (-e "$path$base.tex") ) {
  4546.                 # I don't think the old version was correct.
  4547.                 # If the missing-file report was of a bare
  4548.                 #    extensionless file, and a corresponding .tex file
  4549.                 #    exists, then the missing file does not correspond
  4550.                 #    to the missing file, unless the .tex file was
  4551.                 #    created during the run.  
  4552.                 # OLD $dependents{"$path$base.tex"} = 4;
  4553.                 # OLD delete $dependents{$candidate};
  4554.                 # NEW:
  4555.                 $dependents{"$path$base.tex"} = 4;
  4556.             }
  4557.             push @missing, $candidate;
  4558.         }
  4559.     }
  4560.  
  4561.     my @kpsearch_candidates = keys %kpsearch_candidates;
  4562.     if (@kpsearch_candidates) {
  4563.     foreach my $result ( kpsewhich( @kpsearch_candidates ) ) {
  4564.         $dependents{$result} = 4;
  4565.     }
  4566.     }
  4567.        
  4568. CANDIDATE_PAIR:
  4569.     foreach my $delegated_source (keys %new_conversions) {
  4570.         my $delegated_output = $new_conversions{$delegated_source};
  4571.         my $rule = "Delegated $delegated_source, $delegated_output";
  4572.         # N.B. $delegated_source eq '' means the output file
  4573.         #      was created without a named input file.
  4574.         foreach my $candidate ($delegated_source, $delegated_output) {
  4575.             if (! -e $candidate ) {
  4576.                 # The file might be somewhere that can be found
  4577.                 #   in the search path of kpathsea:
  4578.                 my @kpse_result = kpsewhich( $candidate,);
  4579.                 if ($#kpse_result > -1) {
  4580.                     $candidate = $kpse_result[0];
  4581.                 }
  4582.             }
  4583.         }
  4584.         if ( ( (-e $delegated_source) || ($delegated_source eq '') )
  4585.               && (-e $delegated_output) )
  4586.         {
  4587.             $conversions{$delegated_output} = $delegated_source;
  4588.             $dependents{$delegated_output} = 7;
  4589.             if ($delegated_source) {
  4590.                 $dependents{$delegated_source} = 4;
  4591.             }
  4592.         }
  4593.         elsif (!$silent) {
  4594.             print "Logfile claimed conversion from '$delegated_source' ",
  4595.                   "to '$delegated_output'.  But:\n";
  4596.             if (! -e $delegated_output) {
  4597.                 print  "   Output file does not exist\n";
  4598.             }
  4599.             if ( ($delegated_source ne '') && (! -e $delegated_source) ) {
  4600.                 print  "   Input file does not exist\n";
  4601.             }
  4602.         }
  4603.     }
  4604.  
  4605.     if ( ($#warning_list >= 0) && !$log_silent ) {
  4606.     @warning_list = uniqs( @warning_list );
  4607.         show_array( "$My_name: List of undefined refs and citations:",
  4608.                     @warning_list );
  4609.     }
  4610.    
  4611.     if ( $diagnostics ) {
  4612.         @misparse = uniqs( @misparse );
  4613.         @missing = uniqs( @missing );
  4614.         @not_found = uniqs( @not_found );
  4615.         my @dependents = sort( keys %dependents );
  4616.  
  4617.         my $dependents = $#dependents + 1;
  4618.         my $misparse = $#misparse + 1;
  4619.         my $missing = $#missing + 1;
  4620.         my $not_found = $#not_found + 1;
  4621.         my $exist = $dependents - $not_found - $missing;
  4622.         my $bbl = $#bbl_files + 1;
  4623.  
  4624.         print "$dependents dependent files detected, of which ",
  4625.               "$exist exist, $not_found were not found,\n",
  4626.               "   and $missing appear not to exist.\n";
  4627.         print "Dependents:\n";
  4628.         foreach (@dependents) {
  4629.             print "   '$_' ";
  4630.             if ( $dependents{$_} == 6 ) { print " written by (pdf)latex";}
  4631.             if ( $dependents{$_} == 7 ) { print " converted by (pdf)latex";}
  4632.             print "\n";
  4633.         }
  4634.         if ($not_found > 0) {
  4635.             print "Not found:\n";
  4636.             foreach (@not_found) { print "   $_\n"; }
  4637.         }
  4638.         if ($missing > 0) {
  4639.             print "Not existent:\n";
  4640.             foreach (@missing) { print "   $_\n"; }
  4641.         }
  4642.         if ( $bbl > 0 ) {
  4643.             print "Input bbl files:\n";
  4644.             foreach (@bbl_files) { print "   $_\n"; }
  4645.         }
  4646.  
  4647.         if ( $misparse > 0 ) {
  4648.             print "Possible input files, perhaps from misunderstood lines in .log file:\n";
  4649.             foreach ( @misparse ) { print "   $_\n"; }
  4650.         }
  4651.     }
  4652.     return 1;
  4653. } #END parse_log
  4654.  
  4655. #************************************************************
  4656.  
  4657. sub parse_fls {
  4658.     my ($fls_name, $Pinputs, $Poutputs, $Pfirst_read_after_write, $Ppwd_latex ) = @_;
  4659.     %$Pinputs = %$Poutputs = %$Pfirst_read_after_write = ();
  4660.     my $fls_file = new FileHandle;
  4661.     # Make a note of current working directory
  4662.     # I'll update it from the fls file later
  4663.     # Currently I don't use this, but it would be useful to use
  4664.     # this when testing prefix for cwd in a filename, by
  4665.     # giving (pdf)latex's best view of the cwd.  Note that the
  4666.     # value given by the cwd() function may be mangled, e.g., by cygwin
  4667.     # compared with native MSWin32.
  4668.     #
  4669.     # Two relevant forms of cwd exist: The system one, which we can find, and
  4670.     # the one reported by (pdf)latex in the fls file.  It will be
  4671.     # useful to remove leading part of cwd in filenames --- see the
  4672.     # comments in sub rdb_set_latex_deps.  Given the possible multiplicity
  4673.     # of representations of cwd, the one reported in the fls file should
  4674.     # be definitive in the fls file.
  4675.  
  4676.     my $cwd = good_cwd();
  4677.     if ( ! open ($fls_file, "<$fls_name") ) {
  4678.         return 1;
  4679.     }
  4680.     foreach $_ ( <$fls_file> ) {
  4681.         # Remove trailing CR and LF. Thus we get correct behavior when an fls file
  4682.         #  is produced by MS-Windows program (e.g., in MiKTeX) with CRLF line ends,
  4683.         #  but is read by Unix Perl (which treats LF as line end, and preserves CRLF
  4684.         #  in read-in lines):
  4685.         $_ =~ s/[\n\r]*$//;
  4686.         if (/^\s*PWD\s+(.*)$/) {
  4687.             $cwd = $1;
  4688.             $$Ppwd_latex = $cwd;
  4689.         }
  4690.         elsif (/^\s*INPUT\s+(.*)$/) {
  4691.             # Take precautions against aliasing of foo, ./foo and other possibilities for cwd.
  4692.             my $file = $1;
  4693.             # Remove exactly pwd reported in this file, and following separator.
  4694.             # MiKTeX reports absolute pathnames, and this way of removing PWD insulates
  4695.             #   us from coding issues if the PWD contains non-ASCII characters.  What
  4696.             #   coding scheme (UTF-8, code page, etc) is used depends on OS, TeX
  4697.             #   implementation, ...
  4698.             $file =~ s(^\Q$$Ppwd_latex\E[\\/])();
  4699.             $file = normalize_filename( $file );
  4700.             if ( (exists $$Poutputs{$file}) && (! exists $$Pinputs{$file}) ) {
  4701.                 $$Pfirst_read_after_write{$file} = 1;
  4702.             }
  4703.             $$Pinputs{$file} = 1;
  4704.         }
  4705.         elsif (/^\s*OUTPUT\s+(.*)$/) {
  4706.             # Take precautions against aliasing of foo, ./foo and other possibilities for cwd.
  4707.             my $file = $1;
  4708.             $file =~ s(^\Q$$Ppwd_latex\E[\\/])();
  4709.             $$Poutputs{ normalize_filename( $file )} = 1;
  4710.         }
  4711.     }
  4712.     close( $fls_file );
  4713.     return 0;
  4714. } #END parse_fls
  4715.  
  4716. #************************************************************
  4717.  
  4718. sub clean_filename {
  4719.     # Convert quoted filename as found in log file to filename without quotes
  4720.     # Allows arbitrarily embedded double-quoted substrings, includes the
  4721.     # cases
  4722.     # 1. `"string".ext', which arises e.g., from \jobname.bbl:
  4723.     #    when the base filename contains spaces, \jobname has quotes.
  4724.     #    and from \includegraphics with basename specified.
  4725.     #    Also deals with filenames written by asymptote.sty
  4726.     # 2. Or "string.ext" from \includegraphcs with basename and ext specified.
  4727.     #    and from MiKTeX logfile for input files with spaces.
  4728.     # Doubled quotes (e.g., A""B) don't get converted.
  4729.     # Neither do unmatched quotes.
  4730.     my $filename = $_[0];
  4731.     while ( $filename =~ s/^([^\"]*)\"([^\"]+)\"(.*)$/$1$2$3/ ) {}
  4732.     return $filename;
  4733. }
  4734.  
  4735. # ------------------------------
  4736.  
  4737. sub normalize_filename {
  4738.    # Usage: normalize_filename( filename [, extra forms of name of cwd] )
  4739.    # Returns filename with removal of various forms for cwd, and
  4740.    # with conversion of directory separator to '/' only
  4741.    #
  4742.    my ( $file, @dirs ) = @_;
  4743.    my $file1 = $file;   # Saved original value
  4744.    my $cwd = good_cwd();
  4745.    # Normalize files to use / to separate directory components:
  4746.    # (Note both / and \ are allowed under MSWin.)
  4747.    foreach ($cwd, $file,  @dirs) {
  4748.        s(\\)(/)g;
  4749.    }
  4750.    # Remove initial component equal to current working directory.
  4751.    # Use \Q and \E round directory name in regex to avoid interpretation
  4752.    #   of metacharacters in directory name:
  4753.    foreach my $dir ( @dirs, '.', $cwd ) {
  4754.      if ( $file =~ s(^\Q$dir\E/)() ) {
  4755.         last;
  4756.      }
  4757.    }
  4758.    return $file;
  4759. }
  4760.  
  4761. # ------------------------------
  4762.  
  4763. sub normalize_clean_filename {
  4764.    # Usage: normalize_clean_filename( filename [, extra forms of name of cwd] )
  4765.    # Same as normalize_filename, but first remove any double quotes, as
  4766.    # done by clean_filename, which is appropriate for filenames from log file.
  4767.     my ($file, @dirs) = @_;
  4768.     return normalize_filename( clean_filename( $file ) , @dirs );
  4769. }
  4770.  
  4771. #************************************************************
  4772.  
  4773. sub fix_pattern {
  4774.    # Escape the characters [ and {, to give a pattern for use in glob
  4775.    #    with these characters taken literally.
  4776.    my $pattern = shift;
  4777.    $pattern =~ s/\[/\\\[/g;
  4778.    $pattern =~ s/\{/\\\{/g;
  4779.    return $pattern;
  4780. }
  4781.  
  4782. #************************************************************
  4783.  
  4784. sub OS_preferred_filename {
  4785.    # Usage: OS_preferred_filename(name)
  4786.    # Returns filename with directory separator '/' converted
  4787.    # to preferred conventions for current OS.
  4788.    # Currently implemented: only '\' for MSWin32
  4789.    my $file = $_[0];
  4790.    if ( $^O eq 'MSWin32' ) {
  4791.       $file =~ s(/)(\\)g;
  4792.     }
  4793.    return $file;
  4794. }
  4795.  
  4796. #************************************************************
  4797.  
  4798. sub parse_aux {
  4799.     #Usage: parse_aux( $aux_file, \@new_bib_files, \@new_aux_files, \@new_bst_files )
  4800.     # Parse aux_file (recursively) for bib files, and bst files.  
  4801.     # If can't open aux file, then
  4802.     #    Return 0 and leave @new_bib_files empty
  4803.     # Else set @new_bib_files from information in the aux files
  4804.     #    And:
  4805.     #    Return 1 if no problems
  4806.     #    Return 2 with @new_bib_files empty if there are no \bibdata
  4807.     #      lines.
  4808.     #    Return 3 if I couldn't locate all the bib_files
  4809.     # Set @new_aux_files to aux files parsed
  4810.  
  4811.     my $aux_file = $_[0];
  4812.     local $Pbib_files = $_[1];
  4813.     local $Paux_files = $_[2];
  4814.     local $Pbst_files = $_[3];
  4815.    
  4816.     @$Pbib_files = ();
  4817.     @$Pbst_files = ();
  4818.     @$Paux_files = ();
  4819.  
  4820.     parse_aux1( $aux_file );
  4821.     if ($#{$Paux_files} < 0) {
  4822.        return 0;
  4823.     }
  4824.     @$Pbib_files = uniqs( @$Pbib_files );
  4825.     @$Pbst_files = uniqs( @$Pbst_files );
  4826.  
  4827.     if ( $#{$Pbib_files} == -1 ) {
  4828.         warn "$My_name: No .bib files listed in .aux file '$aux_file' \n",
  4829.         return 2;
  4830.     }
  4831.     my @not_found = &find_file_list1( $Pbib_files, $Pbib_files,
  4832.                                       '.bib', \@BIBINPUTS );
  4833.     @$Pbib_files = uniqs( @$Pbib_files );
  4834.     &find_file_list1( $Pbst_files, $Pbst_files, '.bst' );
  4835.     @$Pbst_files = uniqs( @$Pbst_files );
  4836.     if ( $#not_found < 0) {
  4837.         warn "$My_name: Found bibliography file(s) [@$Pbib_files]\n"
  4838.         unless $silent;
  4839.     }
  4840.     else {
  4841.         show_array( "$My_name: Failed to find one or more bibliography files ",
  4842.                     @not_found );
  4843.         if ($force_mode) {
  4844.             warn "==== Force_mode is on, so I will continue.  ",
  4845.                  "But there may be problems ===\n";
  4846.         }
  4847.         else {
  4848.             #$failure = -1;
  4849.             #$failure_msg = 'Failed to find one or more bib files';
  4850.             #warn "$My_name: Failed to find one or more bib files\n";
  4851.         }
  4852.         return 3;
  4853.     }
  4854.     return 1;
  4855. } #END parse_aux
  4856.  
  4857. #************************************************************
  4858.  
  4859. sub parse_aux1
  4860. # Parse single aux file for bib files.  
  4861. # Usage: &parse_aux1( aux_file_name )
  4862. #   Append newly found bib_filenames in @$Pbib_files, already
  4863. #        initialized/in use.
  4864. #   Append aux_file_name to @$Paux_files if aux file opened
  4865. #   Recursively check \@input aux files
  4866. #   Return 1 if success in opening $aux_file_name and parsing it
  4867. #   Return 0 if fail to open it
  4868. {
  4869.    my $aux_file = $_[0];
  4870.    my $aux_fh = new FileHandle;
  4871.    if (! open($aux_fh, $aux_file) ) {
  4872.        warn "$My_name: Couldn't find aux file '$aux_file'\n";
  4873.        return 0;
  4874.    }
  4875.    push @$Paux_files, $aux_file;
  4876. AUX_LINE:
  4877.    while (<$aux_fh>) {
  4878.       if ( /^\\bibdata\{(.*)\}/ ) {
  4879.           # \\bibdata{comma_separated_list_of_bib_file_names}
  4880.           # These are normally without the '.bib' extension.
  4881.           push @$Pbib_files, split /,/, $1;
  4882.       }
  4883.       elsif ( /^\\bibstyle\{(.*)\}/ ) {
  4884.           # \\bibstyle{bst_file_name}
  4885.           # Normally without the '.bst' extension.
  4886.           push @$Pbst_files, split /,/, $1;
  4887.       }
  4888.       elsif ( /^\\\@input\{(.*)\}/ ) {
  4889.           # \\@input{next_aux_file_name}
  4890.           &parse_aux1( $aux_dir1.$1 );
  4891.       }
  4892.       else {
  4893.           foreach my $Psub (@aux_hooks) {
  4894.               &$Psub;
  4895.           }
  4896.       }
  4897.    }
  4898.    close($aux_fh);
  4899.    return 1;
  4900. } #END parse_aux1
  4901.  
  4902. #************************************************************
  4903.  
  4904. #************************************************************
  4905. #************************************************************
  4906. #************************************************************
  4907.  
  4908. #   Manipulations of main file database:
  4909.  
  4910. #************************************************************
  4911.  
  4912. sub fdb_get {
  4913.     # Call: fdb_get(filename [, check_time])
  4914.     # Returns an array (time, size, md5) for the current state of the
  4915.     #    named file.
  4916.     # The optional argument check_time is either the run_time of some command
  4917.     #    that may have changed the file or the last time the file was checked
  4918.     #    for changes --- see below.
  4919.     # For non-existent file, deletes its entry in fdb_current,
  4920.     #    and returns (0,-1,0)  
  4921.     # As an optimization, the md5 value is taken from the cache in
  4922.     #    fdb_current, if the time and size stamp indicate that the
  4923.     #    file has not changed.
  4924.     # The md5 value is recalculated if
  4925.     #    the current filetime differs from the cached value:
  4926.     #               file has been written
  4927.     #    the current filesize differs from the cached value:
  4928.     #               file has definitely changed
  4929.     # But the file can also be rewritten without change in filetime when
  4930.     #    file processing happens within the 1-second granularity of the
  4931.     #    timestamp (notably for aux files from latex on a short source file).
  4932.     # The only case that concerns us is when the file is an input to a program
  4933.     #    at some runtime t, the file is rewritten later by the same or another
  4934.     #    program, with timestamp t, and when the initial file also has
  4935.     #    timestamp t.
  4936.     # A test is applied for this situation if the check_time argument is
  4937.     #    supplied and is nonzero.
  4938.  
  4939.     my ($file, $check_time) = @_;
  4940.     if ( ! defined $check_time ) { $check_time = 0;}
  4941.     my ($new_time, $new_size) = get_time_size($file);
  4942.     my @nofile =  (0,-1,0);     # What we use for initializing
  4943.                                 # a new entry in fdb or flagging
  4944.                                 # non-existent file
  4945.     if ( $new_size < 0 ) {
  4946.         delete $fdb_current{$file};
  4947.         return @nofile;
  4948.     }
  4949.     my $recalculate_md5 = 0;
  4950.     if ( ! exists $fdb_current{$file} ) {
  4951.         # Ensure we have a record.  
  4952.         $fdb_current{$file} = [@nofile];
  4953.         $recalculate_md5 = 1;
  4954.     }
  4955.     my $file_data = $fdb_current{$file};
  4956.     my ( $time, $size, $md5 ) = @$file_data;
  4957.  
  4958.     if ( ($new_time != $time) || ($new_size != $size)
  4959.          || ( $check_time && ($check_time == $time ) )
  4960.        ) {
  4961.         # Only force recalculation of md5 if time or size changed.
  4962.         # However, the physical file time may have changed without
  4963.         #   affecting the value of the time coded in $time, because
  4964.         #   times are computed with a 1-second granularity.
  4965.         #   The only case to treat specially is where the file was created,
  4966.         #   then used by the current rule, and then rewritten, all within
  4967.         #   the granularity size, otherwise the value of the reported file
  4968.         #   time changed, and we've handled it.  But we may have already
  4969.         #   checked this at an earlier time than the current check.  So the
  4970.         #   only dangerous case is where the file time equals a check_time,
  4971.         #   which is either the run_time of the command or the time of a
  4972.         #   previous check.
  4973.         # Else we assume file is really unchanged.
  4974.         $recalculate_md5 = 1;
  4975.     }
  4976.     if ($recalculate_md5) {
  4977. #warn "--------- RECALC MD5: $rule $file: (N,O,R,C) \n  = $new_time, $time, $$Prun_time, $check_time\n";
  4978.         @$file_data = ( $new_time, $new_size, get_checksum_md5( $file ) );
  4979.     }
  4980.     return @$file_data;;
  4981. } #END fdb_get
  4982.  
  4983. #************************************************************
  4984.  
  4985. sub fdb_set {
  4986.     # Call: fdb_set(filename, $time, $size, $md5 )
  4987.     # Set data in file data cache, i.e., %fdb_current
  4988.     my ($file, $time, $size, $md5 ) = @_;
  4989.     if ( ! exists $fdb_current{$file} ) {
  4990.         $fdb_current{$file} = [0, -1, 0];
  4991.     }
  4992.     @{$fdb_current{$file}} = ( $time, $size, $md5 );
  4993. } #END fdb_set
  4994.  
  4995. #************************************************************
  4996.  
  4997. sub fdb_show {
  4998.     # Displays contents of fdb
  4999.     foreach my $file ( sort keys %fdb_current ) {
  5000.         print "'$file': @{$fdb_current{$file}}\n";
  5001.     }
  5002. } #END fdb_show
  5003.  
  5004. #************************************************************
  5005. #************************************************************
  5006. #************************************************************
  5007.  
  5008. # Routines for manipulating rule database
  5009.  
  5010. #************************************************************
  5011.  
  5012. sub rdb_read {
  5013.     # Call: rdb_read( $in_name  )
  5014.     # Sets rule database from saved file, in format written by rdb_write.
  5015.     # Returns -1 if file could not be read else number of errors.
  5016.     # Thus return value on success is 0
  5017.     my $in_name = $_[0];
  5018.     my $in_handle = new FileHandle;
  5019.     $in_handle->open( $in_name, '<' )
  5020.        or return ();
  5021.     my $errors = 0;
  5022.     my $state = -1;   # Values: -1: before start; 0: outside rule;
  5023.                       # 1: in source section; 2: in generated file section;
  5024.                       # 10: ignored rule
  5025.     my $rule = '';
  5026.     my $run_time = 0;
  5027.     my $source = '';
  5028.     my $dest = '';
  5029.     my $base = '';
  5030.     local %new_sources = ();  # Hash: rule => { file=>[ time, size, md5, fromrule ] }
  5031.     my $new_source = undef;   # Reference to hash of sources for current rule
  5032. LINE:
  5033.     while ( <$in_handle> ) {
  5034.         # Remove leading and trailing white space.
  5035.         s/^\s*//;
  5036.         s/\s*$//;
  5037.         if ($state == -1) {
  5038.             if ( ! /^# Fdb version ([\d]+)$/ ) {
  5039.                 warn "$My_name: File-database '$in_name' is not of correct format\n";
  5040.                 return 1;
  5041.             }
  5042.             if ( $1 > $fdb_ver) {
  5043.                 warn "$My_name: File-database '$in_name' is of too new version, $1 > $fdb_ver\n";
  5044.                 return 1;
  5045.             }
  5046.             $state = 0;
  5047.         }
  5048.         # Ignore blank lines and comments
  5049.         if ( /^$/ || /^#/ || /^%/ ) { next LINE;}
  5050.         if ( /^\[\"([^\"]+)\"\]/ ) {
  5051.             # Start of section
  5052.             $rule = $1;
  5053.             my $tail = $'; #'  Single quote in comment tricks the parser in
  5054.                            # emacs from misparsing an isolated single quote
  5055.             $run_time = $check_time = 0;
  5056.             $source = $dest = $base = '';
  5057.             if ( $tail =~ /^\s*(\S+)\s*$/ ) {
  5058.                 $run_time = $1;
  5059.             }
  5060.             elsif ( $tail =~ /^\s*(\S+)\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s*$/ ) {
  5061.                 $run_time = $1;
  5062.                 $source = $2;
  5063.                 $dest = $3;
  5064.                 $base = $4;
  5065.             }
  5066.             elsif ( $tail =~ /^\s*(\S+)\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+(\S+)\s*$/ ) {
  5067.                 $run_time = $1;
  5068.                 $source = $2;
  5069.                 $dest = $3;
  5070.                 $base = $4;
  5071.                 $check_time = $5;
  5072.             }
  5073.             if ( rdb_rule_exists( $rule ) ) {
  5074.                 rdb_one_rule( $rule,
  5075.                               sub{
  5076.                                    if ($$Ptest_kind == 3) { $$Ptest_kind = 1; }
  5077.                                    $$Prun_time = $run_time;
  5078.                                    $$Pcheck_time = $check_time;
  5079.                                  }                                      
  5080.                              );
  5081.             }
  5082.             elsif ($rule =~ /^cusdep\s+(\S+)\s+(\S+)\s+(.+)$/ ) {
  5083.                 # Create custom dependency
  5084.                 my $fromext = $1;
  5085.                 my $toext = $2;
  5086.                 my $base = $3;
  5087.                 $source = "$base.$fromext";
  5088.                 $dest =   "$base.$toext";
  5089.                 my $PAnew_cmd = ['do_cusdep', ''];
  5090.                 foreach my $dep ( @cus_dep_list ) {
  5091.                     my ($tryfromext,$trytoext,$must,$func_name) = split('\s+',$dep);
  5092.                     if ( ($tryfromext eq $fromext) && ($trytoext eq $toext) ) {
  5093.                        $$PAnew_cmd[1] = $func_name;
  5094.                     }
  5095.                 }
  5096.                 # Set source file as non-existent.  
  5097.                 # If it existed on last run, it will be in later
  5098.                 #    lines of the fdb file
  5099.                 rdb_create_rule( $rule, 'cusdep', '', $PAnew_cmd, 1,
  5100.                                  $source, $dest, $base, 0, $run_time, $check_time, 1 );
  5101.             }
  5102.             elsif ( $rule =~ /^(makeindex|bibtex|biber)\s*(.*)$/ ) {
  5103.                 my $PA_extra_gen = [];
  5104.                 my $rule_generic = $1;
  5105.                 my $int_cmd = '';
  5106.                 if ( ! $source ) {
  5107.                     # If fdb_file was old-style (v. 1)
  5108.                     $source = $2;
  5109.                     my $path = '';
  5110.                     my $ext = '';
  5111.                     ($base, $path, $ext) = fileparseA( $source );
  5112.                     $base = $path.$base;
  5113.                     if ($rule_generic eq 'makeindex') {
  5114.                         $dest = "$base.ind";
  5115.                     }
  5116.                     elsif ($rule_generic eq 'bibtex') {
  5117.                         $dest = "$base.bbl";
  5118.                         $source = "$base.aux";
  5119.                     }
  5120.                     elsif ($rule_generic eq 'biber') {
  5121.                         $dest = "$base.bbl";
  5122.                         $source = "$base.bcf";
  5123.                     }
  5124.                 }
  5125.                 if ($rule =~ /^makeindex/) { $PA_extra_gen = [ "$base.ilg" ]; }
  5126.                 if ($rule =~ /^(bibtex|biber)/) { $PA_extra_gen = [ "$base.blg" ]; }
  5127.                 if ($rule =~ /^bibtex/) { $int_cmd = "run_bibtex"; }
  5128.                 warn "$My_name: File-database '$in_name': setting rule '$rule'\n"
  5129.                    if $diagnostics;
  5130.                 my $cmd_type = 'external';
  5131.                 my $ext_cmd = ${$rule_generic};
  5132.                 warn "  Rule kind = '$rule_generic'; ext_cmd = '$ext_cmd';\n",
  5133.                      "  int_cmd = '$int_cmd';\n",
  5134.                      "  source = '$source'; dest = '$dest'; base = '$base';\n"
  5135.                    if $diagnostics;
  5136.                 # Set source file as non-existent.  
  5137.                 # If it existed on last run, it will be in later
  5138.                 #    lines of the fdb file
  5139.                 rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, 1,
  5140.                                  $source, $dest, $base, 0, $run_time,  $check_time, 1, $PA_extra_gen );
  5141.             }
  5142.             else {
  5143.                 warn "$My_name: In file-database '$in_name' rule '$rule'\n",
  5144.                      "   is not in use in this session\n"
  5145.                 if $diagnostics;
  5146.                 $new_source = undef;
  5147.                 $state = 10;
  5148.                 next LINE;
  5149.             }
  5150.             $new_source = $new_sources{$rule} = {};
  5151.             $state = 1;  #Reading a section, source part
  5152.         }
  5153.         elsif ( ($state <=0) || ($state >= 3) ) {
  5154.             next LINE;
  5155.         }
  5156.         elsif ( /^\(source\)/ ) { $state = 1; next LINE; }
  5157.         elsif ( /^\(generated\)/ ) { $state = 2; next LINE; }
  5158.         elsif ( ($state == 1) && /^\"([^\"]*)\"\s+(\S+)\s+(\S+)\s+(\S+)\s+\"([^\"]*)\"/ ) {
  5159.             # Source file line
  5160.             my $file = $1;
  5161.             my $time = $2;
  5162.             my $size = $3;
  5163.             my $md5 = $4;
  5164.             my $from_rule = $5;
  5165. #??            print "  --- File '$file'\n";
  5166.             if ($state != 1) {
  5167.                 warn "$My_name: In file-database '$in_name' ",
  5168.                      "line $. is outside a section:\n   '$_'\n";
  5169.                 $errors++;
  5170.                 next LINE;
  5171.             }
  5172.             # Set file in database.  But ensure we don't do an unnecessary
  5173.             #    fdb_get, which can trigger a new MD5 calculation, which is
  5174.             #    lengthy for a big file.  Ininitially flagging the file
  5175.             #    as non-existent solves the problem:
  5176.             rdb_ensure_file( $rule, $file, undef, 1 );
  5177.             rdb_set_file1( $rule, $file, $time, $size, $md5 );
  5178.             fdb_set( $file, $time, $size, $md5 );
  5179.             # Save the rest of the data, especially the from_fule until we know all
  5180.             #   the rules, otherwise the from_rule may not exist.
  5181.             # Also we'll have a better chance of looping through files.
  5182.             ${$new_source}{$file} = [ $time, $size, $md5, $from_rule ];
  5183.         }
  5184.         elsif ( ($state == 2) && /^\"([^\"]*)\"/ ) {
  5185.             my $file = $1;
  5186.             rdb_one_rule( $rule, sub{ rdb_add_generated($file); } );
  5187.         }
  5188.         else {
  5189.             warn "$My_name: In file-database '$in_name' ",
  5190.                  "line $. is of wrong format:\n   '$_'\n";
  5191.             $errors++;
  5192.             next LINE;
  5193.         }
  5194.     }
  5195.     undef $in_handle;
  5196.     # Set cus dependencies.
  5197.     &rdb_set_dependents( keys %rule_db );
  5198.  
  5199. #?? Check from_rules exist.
  5200.  
  5201.     return $errors;
  5202. }  # END rdb_read
  5203.  
  5204. #************************************************************
  5205.  
  5206. sub rdb_write {
  5207.     # Call: rdb_write( $out_name )
  5208.     # Writes to the given file name the database of file and rule data
  5209.     #   for all rules needed to make final output
  5210.     # !!?? Previously was:
  5211.     # OLD Writes to the given file name the database of file and rule data
  5212.     # OLD   accessible from the primary rules.
  5213.     # Returns 1 on success, 0 if file couldn't be opened.
  5214.     local $out_name = $_[0];
  5215.     local $out_handle = new FileHandle;
  5216.     if ( ($out_name eq "") || ($out_name eq "-") ) {
  5217.         # Open STDOUT
  5218.         $out_handle->open( '>-' );
  5219.     }
  5220.     else {
  5221.        $out_handle->open( $out_name, '>' );
  5222.     }
  5223.     if (!$out_handle) { return 0; }
  5224.  
  5225.     local %current_primaries = ();   # Hash whose keys are primary rules
  5226.                 # needed, i.e., known latex-like rules which trigger
  5227.                 # circular dependencies
  5228.     local @pre_primary = ();   # Array of rules
  5229.     local @post_primary = ();  # Array of rules
  5230.     local @unusual_one_time = ();      # Array of rules
  5231.     &rdb_classify_rules( \%possible_primaries, keys %requested_filerules );
  5232.  
  5233.     print $out_handle "# Fdb version $fdb_ver\n";
  5234. # !!??   Rules or rules accessible from primary
  5235. #    my @rules = rdb_accessible( uniq1( keys %possible_primaries )  ) ;
  5236.     my @rules = rdb_accessible( uniq1( keys %possible_primaries, keys %requested_filerules  )  ) ;
  5237.     # Separate call to sort.  Otherwise rdb_accessible seems to get wrong argument.
  5238.     @rules = sort( @rules );
  5239.     rdb_for_some(
  5240.        \@rules,
  5241.        sub {
  5242.            # Omit data on a unused and never-run primary rule:
  5243.            if ( ($$Prun_time == 0)
  5244.                 && exists( $possible_primaries{$rule} )
  5245.                 && ! exists( $current_primaries{$rule} )
  5246.               )
  5247.            {
  5248.                return;
  5249.            }
  5250.            print $out_handle "[\"$rule\"] $$Prun_time \"$$Psource\" \"$$Pdest\" \"$$Pbase\" $$Pcheck_time\n";
  5251.            rdb_do_files(
  5252.              sub { print $out_handle "  \"$file\" $$Ptime $$Psize $$Pmd5 \"$$Pfrom_rule\"\n"; }
  5253.            );
  5254.            print $out_handle "  (generated)\n";
  5255.            foreach (keys %$PHdest) {
  5256.                print $out_handle "  \"$_\"\n";
  5257.            }
  5258.        }
  5259.     );
  5260.     undef $out_handle;
  5261.     return 1;
  5262. } #END rdb_write
  5263.  
  5264. #************************************************************
  5265.  
  5266. sub rdb_set_latex_deps {
  5267.     # Assume rule context.  
  5268.     # This is intended to be applied only for a primary (LaTeX-like) rule.
  5269.     # Set its dependents etc, using information from log, aux, and fls files.
  5270.     # Use fls file only if $recorder is set, and the fls file was generated
  5271.     # on this run.
  5272.  
  5273.     # N.B.  A complication which we try and handle in determining
  5274.     #   dependent files is that there may be aliasing of file names,
  5275.     #   especially when characters are used in file and directory
  5276.     #   names that are not pure 7-bit-ASCII.  Here is a list of some
  5277.     #   of the difficulties that do arise, between, on the one hand,
  5278.     #   the filenames specified on latexmk's and the cwd found by
  5279.     #   latexmk from the system, and, on the other hand, the filenames
  5280.     #   and their components reported by (pdf)latex in the fls and log
  5281.     #   files:
  5282.     #      1. Whether the separator of path components is / or \ in
  5283.     #         MSWin.
  5284.     #      2. Whether the LFN or the SFN is provided.
  5285.     #      3. Whether the filenames include the cwd or whether they
  5286.     #         are relative to the current directory.
  5287.     #      4. Under cygwin, whether the absolute filenames are
  5288.     #         specified by UNIX or native MSWin conventions.
  5289.     #         (With cygin, the programs used, including the Perl that
  5290.     #         executes latexmk, can be any combination of native MSWin
  5291.     #         programs and cygwin programs with their UNIX-like
  5292.     #         behavior.)
  5293.     #      5. Whether UTF-8 or some other coding is used, and under
  5294.     #         which circumstances: e.g., in calls to the OS to access
  5295.     #         files, in files output by programs, on latexmk's command
  5296.     #         line, on other programs' command lines, by the command
  5297.     #         interpreterS.
  5298.     #      6. If UTF-8 is used, what kind of canonicalization is used,
  5299.     #         if any.  (This is a particular bugbear when files are
  5300.     #         transferred between different OSes.)
  5301.     #      7. Whether the name of a file in the current directory is
  5302.     #         reported as the simple filename or whether it is
  5303.     #         preceeded by ".\" or "./".
  5304.     #      8. How is it determined whether a pathname is absolute or
  5305.     #         relative?  An absolute pathname in MSWin may start with
  5306.     #         a drive letter and a colon, but under UNIX-type systems,
  5307.     #         the colon is an ordinary character.
  5308.     #      9. Whether a filename reported in an fls or log file can be
  5309.     #         used as is by perl to access a file, or on the command
  5310.     #         line to invoke another program, and whether the use on a
  5311.     #         command line depends on whether the command line is
  5312.     #         executed by a CLI, and by which CLI.  (E.g., cmd.exe,
  5313.     #         v. sh v. tcsh, etc.)
  5314.     #     10. Whether such a filename for the filename on (pdf)latex's
  5315.     #         file agrees with the one on the command line.
  5316.     #   The above questions have arisen from actual experiences and
  5317.     #   tests.
  5318.     #
  5319.     #   In any case, when determining dependent files, we will try to
  5320.     #   remove an initial directory string from filenames found in the
  5321.     #   fls and log files, whenever it denotes the current
  5322.     #   directory. The directory string may be an absolute pathname,
  5323.     #   such as MiKTeX writes in both fls and log files, or it may be
  5324.     #   simply "./" as given by TeXLive in its log file. There are
  5325.     #   several reasons for removing a directory string when possible:
  5326.     #
  5327.     #      1. To avoid having multiple names referring to the same
  5328.     #         file in the list of dependents.
  5329.     #      2. Because the name may be in a different coding.  Thus
  5330.     #         under MSWin 7, cmd.exe and perl (by default) work in an
  5331.     #         "ANSI" coding with some code page, but the filenames
  5332.     #         written by MiKTeX are UTF-8 coded (and if they are non-ASCII
  5333.     #         can't be used for file-processing by Perl without some
  5334.     #         trouble).  This is a particular problem if the pathname
  5335.     #         contains non-ASCII characters; the directory names may not
  5336.     #         even be under the user's control, unlike typical filenames.
  5337.     #      3. When it comes to filenames that are then used in calls to
  5338.     #         bibtex and makeindex, it is bad to use absolute pathnames
  5339.     #         instead of clearly relative pathnames, because the default
  5340.     #         security settings are to prohibit writing files to the
  5341.     #         corresponding directories, which makes the calls to these
  5342.     #         programs unnecessarily fail.
  5343.     #
  5344.     #   In removing unnecessary directory-specifying strings, to
  5345.     #   convert a filename to a simple specification relative to the
  5346.     #   current directory, it will be important to preferentially use
  5347.     #   a determination of the current directory from the file being
  5348.     #   processed.  In the fls file, there is normally a PWD line.  In
  5349.     #   the log file, if (pdf)latex is started with a filename instead
  5350.     #   of a command-executing first line, then this can be determined
  5351.     #   from the first few lines of the log file -- see parse_log.
  5352.     #   This gives a more reliable determination of the relevant path
  5353.     #   string; this is especially important in cases where there is a
  5354.     #   mismatch of coding of the current directory, particularly
  5355.     #   notable in the above-mentioned case of non-ASCII characters
  5356.     #   under MSWin.  Other inconsistencies happen when there is a
  5357.     #   mixure of cygwin and native MSWin software. There can also be
  5358.     #   inconsistencies between whether the separator of pathname
  5359.     #   components is "/" or "\".  So we will allow for this.  The
  5360.     #   necessary normalizations of filenames are handled by the
  5361.     #   subroutines normalize_filename and normalize_clean_filename.
  5362.     #
  5363.     #   I have not tried to handle the (currently rare) cases that the
  5364.     #   OS is neither UNIX-like nor MSWin-like.
  5365.  
  5366.     # Rules should only be primary
  5367.     if ( $$Pcmd_type ne 'primary' ) {
  5368.         warn "\n$My_name: ==========$My_name: Probable BUG======= \n   ",
  5369.              "   rdb_set_latex_deps called to set files ",
  5370.              "for non-primary rule '$rule'\n\n";
  5371.         return;
  5372.     }
  5373.  
  5374.  
  5375. #??    # We'll prune this by all files determined to be needed for source files.
  5376. #??    my %unneeded_source = %$PHsource;
  5377.  
  5378.     # Parse log file to find relevant filenames
  5379.     # Result in the following variables:
  5380.     local %dependents = ();    # Maps files to status
  5381.     local @bbl_files = ();
  5382.     local %idx_files = ();     # Maps idx_file to (ind_file, base)
  5383.     local %generated_log = (); # Lists generated files found in log file
  5384.     local %generated_fls = (); # Lists generated files found in fls file
  5385.     local %source_fls = ();    # Lists source files found in fls file
  5386.     local %first_read_after_write = (); # Lists source files that are only read
  5387.                                   # after being written (so are not true
  5388.                                   # source files.
  5389.     local $primary_out = $$Pdest;  # output file (dvi or pdf)
  5390.     local %conversions = ();   # (pdf)latex-performed conversions.
  5391.                      # Maps output file created and read by (pdf)latex
  5392.                      #    to source file of conversion.
  5393.     local @missing_subdirs = ();  # Missing subdirectories in aux_dir
  5394.  
  5395.     local $pwd_latex = undef;     # Cwd as reported in fls file by (pdf)latex
  5396.  
  5397.     # The following are also returned, but are global, to be used by caller
  5398.     # $reference_changed, $bad_reference $bad_citation, $mult_defined
  5399.  
  5400.     # Do I have my own eps-to-pdf conversion?
  5401.     my $epspdf_cusdep = 0;
  5402.     foreach (@cus_dep_list) {
  5403.         if ( /^eps pdf / ) { $epspdf_cusdep = 1; last; }
  5404.     }
  5405.  
  5406.     # Analyze fls file first.  It tells us the working directory as seen by (pdf)latex
  5407.     # But we'll use the results later, so that they take priority over the findings
  5408.     # from the log file.
  5409.     my $fls_name = "$aux_dir1$root_filename.fls";
  5410.     local $fls_file_analyzed = 0;
  5411.     if ($recorder && test_gen_file($fls_name) ) {
  5412.     $fls_file_analyzed =
  5413.         (0== parse_fls( $fls_name, \%source_fls, \%generated_fls, \%first_read_after_write, \$pwd_latex ));
  5414.     if (! $fls_file_analyzed ) {
  5415.         warn "$My_name: fls file '$fls_name' appears to have been made but it couldn't be opened.\n";
  5416.     }
  5417.     }
  5418.  
  5419.     &parse_log;
  5420.     $missing_dirs = 'none';      # Status of missing directories
  5421.     if (@missing_subdirs) {
  5422.         $missing_dirs = 'success';
  5423.         if ($allow_subdir_creation) {
  5424.             foreach my $dir ( uniqs( @missing_subdirs ) ) {
  5425.                 if ( -d $dir ) {
  5426.                     $missing_dirs = 'failure';
  5427.                     warn "$My_name: ==== Directory '$dir' is said to be missing\n",
  5428.                          "     But it exists!\n";
  5429.                 }
  5430.                 elsif ( (-e $dir) && (!-d $dir) ) {
  5431.                     $missing_dirs = 'failure';
  5432.                     warn "$My_name: ==== Directory '$dir' is said to be missing\n",
  5433.                          "     But a non-directory file of this name exists!\n";
  5434.                 }
  5435.                 else {
  5436.                     if (mkdir $dir) {
  5437.                         warn "$My_name: Directory '$dir' created\n";
  5438.                     }
  5439.                     else {
  5440.                         $missing_dirs = 'failure';
  5441.                         warn "$My_name: Couldn't create directory '$dir'.\n",
  5442.                              "    System error: '$!'\n";
  5443.                     }
  5444.                 }
  5445.             }
  5446.         }
  5447.         else {
  5448.             $missing_dirs = 'not allowed';
  5449.             warn "$My_name: There are missing subdirectories, but their creation\n",
  5450.                  "    is not allowed.  The subdirectories are:\n";
  5451.             foreach my $dir ( uniqs( @missing_subdirs ) ) {
  5452.                 warn "   '$dir'\n";
  5453.             }
  5454.        }
  5455.     }
  5456.     # Use results from fls file.  (N.B. The hashes will be empty if the fls file
  5457.     # wasn't used/analyzed, so we don't need a test as to whether the fls file was
  5458.     # used.
  5459.     foreach (keys %source_fls) {
  5460.         $dependents{$_} = 4;
  5461.     if ( /\.bbl$/ ) { push @bbl_files, $_; }
  5462.     }
  5463.     foreach (keys %generated_fls) {
  5464.         rdb_add_generated( $_ );
  5465.         if ( exists($dependents{$_}) ) {
  5466.             $dependents{$_} = 6;
  5467.         }
  5468.      }
  5469.  
  5470.  
  5471.     for my $conv (sort keys %conversions) {
  5472.         my $conv_source = $conversions{$conv};
  5473.         if ( $conv =~ /^(.*)-eps-converted-to\.pdf$/ ) {
  5474.             # Check all the conditions for pdflatex's conversion eps to pdf
  5475.             # are valid; if they are, treat the converted file as not a
  5476.             # source file.
  5477.             my $base = $1;
  5478.             if ( (-e $conv_source) && (-e $conv) && ( $conv_source eq "$base.eps" ) ) {
  5479.                 # $conv isn't a real source of (pdf)latex
  5480.                 rdb_remove_files( $rule, $conv );
  5481.                 delete $dependents{$conv};
  5482.                 if ($epspdf_cusdep) {
  5483.             $dependents{"$base.pdf"} = ((-e "$base.pdf") ? 4 : 0 );
  5484.                 }
  5485.         }
  5486.     }
  5487.     }
  5488.  
  5489.  
  5490.  
  5491. # ?? !! Should also deal with .run.xml file
  5492.  
  5493.     # Handle result on output file:
  5494.     #   1.  Non-existent output file, which is because of no content.
  5495.     #         This could either be because the source file has genuinely
  5496.     #         no content, or because of a missing input file.  Since a
  5497.     #         missing input file might be correctable by a run of some
  5498.     #         other program whose running is provoked AFTER a run of
  5499.     #         (pdf)latex, we'll set a diagnostic and leave it to the
  5500.     #         rdb_make to handle after all circular dependencies are
  5501.     #         resolved.
  5502.     #   2.  The output file might be of a different kind than expected
  5503.     #         (i.e., dvi instead of pdf, or vv).  This could
  5504.     #         legitimately occur when the source file (or an invoked
  5505.     #         package or class) sets \pdfoutput.
  5506.     $missing_dvi_pdf = '';
  5507.     if ($primary_out eq '')  {
  5508.         warn "$My_name: For rule '$rule', no output was made\n";
  5509.         $missing_dvi_pdf = $$Pdest;
  5510.     }
  5511.     elsif ($primary_out ne $$Pdest) {
  5512.         warn "$My_name: ===For rule '$rule', actual output '$primary_out'\n",
  5513.              "       ======appears not to match expected output '$$Pdest'\n";
  5514.     }
  5515.  
  5516.   IDX_FILE:
  5517.     foreach my $idx_file ( keys %idx_files ) {
  5518.         my ($ind_file, $ind_base) = @{$idx_files{$idx_file}};
  5519.         my $from_rule = "makeindex $idx_file";
  5520.         if ( ! rdb_rule_exists( $from_rule ) ){
  5521.             print "!!!===Creating rule '$from_rule': '$ind_file' from '$idx_file'\n"
  5522.                   if ($diagnostics);
  5523.             rdb_create_rule( $from_rule, 'external', $makeindex, '', 1,
  5524.                              $idx_file, $ind_file, $ind_base, 1, 0, 0, 1, [ "$ind_base.ilg" ] );
  5525.             print "  ===Source file '$ind_file' for '$rule'\n"
  5526.                   if ($diagnostics);
  5527.             rdb_ensure_file( $rule, $ind_file, $from_rule );
  5528.         }
  5529.         # Make sure the .ind file is treated as a detected source file;
  5530.         # otherwise if the log file has it under a different name (as
  5531.         # with MiKTeX which gives full directory information), there
  5532.         # will be problems with the clean-up of the rule concerning
  5533.         # no-longer-in-use source files:
  5534.         $dependents{$ind_file} = 4;
  5535.         if ( ! -e $ind_file ) {
  5536.             # Failure was non-existence of makable file
  5537.             # Leave failure issue to other rules.
  5538.             $failure = 0;
  5539.         }
  5540.     }
  5541.  
  5542.     local %processed_aux_files = ();
  5543.   BBL_FILE:
  5544.     foreach my $bbl_file ( uniqs( @bbl_files ) ) {
  5545.         my ($bbl_base, $bbl_path, $bbl_ext) = fileparseA( $bbl_file );
  5546.         $bbl_base = $bbl_path.$bbl_base;
  5547.         my @new_bib_files = ();
  5548.         my @new_aux_files = ();
  5549.         my @new_bst_files = ();
  5550.         my @biber_source = ( "$bbl_base.bcf" );
  5551.         my $bib_program = 'bibtex';
  5552.         if ( test_gen_file( "$bbl_base.bcf" ) ) {
  5553.              $bib_program = 'biber';
  5554.         }
  5555.         my $from_rule = "$bib_program $bbl_base";
  5556.         print "=======  Dealing with '$from_rule'\n" if ($diagnostics);
  5557.         if ($bib_program eq 'biber') {
  5558.             check_biber_log( $bbl_base, \@biber_source );
  5559.             # Remove OPPOSITE kind of bbl generation:
  5560.             rdb_remove_rule( "bibtex $bbl_base" );
  5561.         }
  5562.         else {
  5563.             parse_aux( "$bbl_base.aux", \@new_bib_files, \@new_aux_files, \@new_bst_files );
  5564.             # Remove OPPOSITE kind of bbl generation:
  5565.             rdb_remove_rule( "biber $bbl_base" );
  5566.         }
  5567.         if ( ! rdb_rule_exists( $from_rule ) ){
  5568.             print "   ===Creating rule '$from_rule'\n" if ($diagnostics);
  5569.             if ( $bib_program eq 'biber' ) {
  5570.                 rdb_create_rule( $from_rule, 'external', $biber, '', 1,
  5571.                                  "$bbl_base.bcf", $bbl_file, $bbl_base, 1, 0, 0, 1, [ "$bbl_base.blg" ]  );
  5572.              }
  5573.              else {
  5574.                  rdb_create_rule( $from_rule, 'external', $bibtex, 'run_bibtex', 1,
  5575.                                   "$bbl_base.aux", $bbl_file, $bbl_base, 1, 0, 0, 1, [ "$bbl_base.blg" ]  );
  5576.                }
  5577.         }
  5578.         local %old_sources = ();
  5579.         rdb_one_rule( $from_rule, sub { %old_sources = %$PHsource; } );
  5580.     my @new_sources = ( @new_bib_files, @new_aux_files, @new_bst_files );
  5581.         if ( $bib_program eq 'biber' ) {
  5582.         push @new_sources, @biber_source;
  5583.         }
  5584.         foreach my $source ( @new_sources ) {
  5585.             print "  ===Source file '$source' for '$from_rule'\n"
  5586.                if ($diagnostics);
  5587.             rdb_ensure_file( $from_rule, $source );
  5588.             delete $old_sources{$source};
  5589.         }
  5590.         foreach my $source ( @new_aux_files ) {
  5591.             $processed_aux_files{$source} = 1;
  5592.         }
  5593.         if ($diagnostics) {
  5594.             foreach ( keys %old_sources ) {
  5595.                 print "Removing no-longer-needed dependent '$_' from rule '$from_rule'\n";
  5596.             }
  5597.         }
  5598.         rdb_remove_files( $from_rule, keys %old_sources );
  5599.         print "  ===Source file '$bbl_file' for '$rule'\n"
  5600.             if ($diagnostics);
  5601.         rdb_ensure_file( $rule, $bbl_file, $from_rule );
  5602.         if ( ! -e $bbl_file ) {
  5603.             # Failure was non-existence of makable file
  5604.             # Leave failure issue to other rules.
  5605.             $failure = 0;
  5606.         }
  5607.     }
  5608.  
  5609.     if ( ($#aux_hooks > -1) && ! exists $processed_aux_files{$aux_main} ) {
  5610.         my @new_bib_files = ();
  5611.         my @new_aux_files = ();
  5612.         my @new_bst_files = ();
  5613.         parse_aux( $aux_main, \@new_bib_files, \@new_aux_files, \@new_bst_files );
  5614.         foreach my $source ( @new_aux_files ) {
  5615.             $processed_aux_files{$source} = 1;
  5616.         }
  5617.     }
  5618.  
  5619. NEW_SOURCE:
  5620.     foreach my $new_source (keys %dependents) {
  5621.         print "  ===Source file for rule '$rule': '$new_source'\n"
  5622.             if ($diagnostics);
  5623.     if ( exists $first_read_after_write{$new_source} ) {
  5624.         if ( dep_at_start($new_source) ) {
  5625.             #warn "--- READ ONLY AFTER WRITE OF '$new_source'\n";
  5626.         $dependents{$new_source} = 7;
  5627.         }
  5628.         else {
  5629.             #warn "--- READ ONLY AFTER CREATE OF '$new_source'\n";
  5630.         $dependents{$new_source} = 6;
  5631.         }
  5632.         }
  5633.         if ( ($dependents{$new_source} == 5)
  5634.              || ($dependents{$new_source} == 6)
  5635.         ) {
  5636.             # (a) File was detected in "No file..." line in log file.
  5637.             #     Typically file was searched for early in run of
  5638.             #     latex/pdflatex, was not found, and then was written
  5639.             #     later in run.
  5640.             # or (b) File was written during run.
  5641.             # In both cases, if file doesn't already exist in database, we
  5642.             #    don't know its previous status.  Therefore we tell
  5643.             #    rdb_ensure_file that if it needs to add the file to its
  5644.             #    database, then the previous version of the file should be
  5645.             #    treated as non-existent, to ensure another run is forced.
  5646.             rdb_ensure_file( $rule, $new_source, undef, 1 );
  5647.         }
  5648.         elsif ( $dependents{$new_source} == 7 )  {
  5649.             # File was result of conversion by (pdf)latex.
  5650.             my $cnv_source = $conversions{$new_source};
  5651.             rdb_ensure_file( $rule, $new_source );
  5652.             if ($cnv_source) {
  5653.                 # Conversion from $cnv_source to $new_source
  5654.                 #   implies that effectively $cnv_source is a source
  5655.                 #   of the (pdf)latex run.
  5656.                 rdb_ensure_file( $rule, $cnv_source );
  5657.             }
  5658.             # Flag that changes of the generated file during a run
  5659.             #    do not require a rerun:
  5660.             rdb_one_file( $new_source, sub{ $$Pcorrect_after_primary = 1; } );
  5661.         }
  5662.         else {
  5663.             # But we don't need special precautions for ordinary user files
  5664.             #    (or for files that are generated outside of latex/pdflatex).
  5665.             rdb_ensure_file( $rule, $new_source );
  5666.         }
  5667.         if ( ($dependents{$new_source} == 6)
  5668.              || ($dependents{$new_source} == 7)
  5669.            ) {
  5670.             rdb_add_generated($new_source);
  5671.         }
  5672.     }
  5673.  
  5674.     my @more_sources = &rdb_set_dependents( $rule );
  5675.     my $num_new = $#more_sources + 1;
  5676.     foreach (@more_sources) {
  5677.         $dependents{$_} = 4;
  5678.         if ( ! -e $_ ) {
  5679.             # Failure was non-existence of makable file
  5680.             # Leave failure issue to other rules.
  5681.             $failure = 0;
  5682.             $$Pchanged = 1; # New files can be made.  Ignore error.
  5683.         }
  5684.     }
  5685.     if ($diagnostics) {
  5686.         if ($num_new > 0 ) {
  5687.             print "$num_new new source files for rule '$rule':\n";
  5688.             foreach (@more_sources) { print "   '$_'\n"; }
  5689.         }
  5690.         else {
  5691.             print "No new source files for rule '$rule':\n";
  5692.         }
  5693.         my @first_read_after_write = sort keys %first_read_after_write;
  5694.         if ($#first_read_after_write >= 0) {
  5695.             print "The following files were only read after being written:\n";
  5696.             foreach (@first_read_after_write) {
  5697.                 print "   '$_'\n";
  5698.             }
  5699.           }
  5700.     }
  5701.     my @files_not_needed = ();
  5702.     foreach (keys %$PHsource) {
  5703.         if ( ! exists $dependents{$_} ) {
  5704.             print "Removing no-longer-needed dependent '$_' from rule '$rule'\n"
  5705.               if $diagnostics;
  5706.             push @files_not_needed, $_;
  5707.         }
  5708.     }
  5709.     rdb_remove_files( $rule, @files_not_needed );
  5710.  
  5711. } # END rdb_set_latex_deps
  5712.  
  5713. #************************************************************
  5714.  
  5715. sub test_gen_file {
  5716.     # Usage: test_gen_file( filename )
  5717.     # Tests whether the file was generated during a run of (pdf)latex.
  5718.     # Assumes context for primary rule.
  5719.     # Two kinds of test are used:
  5720.     # a. From %generated_log, which works after the log file has been parsed,
  5721.     #    but only for certain files and for those TeX engines (not MiKTeX)
  5722.     #    that put \openout lines in log file.
  5723.     # b. By the file existing and being at least as new as the system
  5724.     #    time at the start of the run. But we allow for a measured
  5725.     #    offset between filetime and system time, which could be
  5726.     #    nonzero if the file is on a different, remote system than the
  5727.     #    one running latexmk. We must also allow a threshold in the
  5728.     #    comparisons of filetimes to allow for the inaccuracy of the
  5729.     #    offset measurement.
  5730.     my $file = shift;
  5731.     return exists $generated_log{$file}
  5732.            || ( -e $file && ( get_mtime( $file ) >= $$Prun_time + $filetime_offset - $filetime_causality_threshold));
  5733. }
  5734.  
  5735. #************************************************************
  5736.  
  5737. sub dep_at_start {
  5738.     # Usage: dep_at_start( filename )
  5739.     # Tests whether the file was source file and existed at start of run.
  5740.     # Assumes context for primary rule.
  5741.     my $time = undef;
  5742.     rdb_one_file( shift, sub{ $time = $$Ptime; } );
  5743.     return (defined $time) && ($time != 0);
  5744. }
  5745.  
  5746. #************************************************************
  5747.  
  5748. sub rdb_find_new_files {
  5749.     # Call: rdb_find_new_files
  5750.     # Assumes rule context for primary rule.
  5751.     # Deal with files which were missing and for which a method
  5752.     # of finding them has become available:
  5753.     #   (a) A newly available source file for a custom dependency.
  5754.     #   (b) When there was no extension, a file with appropriate
  5755.     #       extension
  5756.     #   (c) When there was no extension, and a newly available source
  5757.     #       file for a custom dependency can make it.
  5758.  
  5759.     my %new_includes = ();
  5760.  
  5761. MISSING_FILE:
  5762.     foreach my $missing ( keys %$PHsource ) {
  5763.         next if ( $$PHsource{$missing} != 0 );
  5764.         my ($base, $path, $ext) = fileparseA( $missing );
  5765.         $ext =~ s/^\.//;
  5766.         if ( -e "$missing.tex" ) {
  5767.             $new_includes{"$missing.tex"} = 1;
  5768.         }
  5769.         if ( -e $missing ) {
  5770.             $new_includes{$missing} = 1;
  5771.         }
  5772.         if ( $ext ne "" ) {
  5773.             foreach my $dep (@cus_dep_list){
  5774.                my ($fromext,$toext) = split('\s+',$dep);
  5775.                if ( ( "$ext" eq "$toext" )
  5776.                     && ( -e "$path$base.$fromext" )
  5777.                   )  {
  5778.                   # Source file for the missing file exists
  5779.                   # So we have a real include file, and it will be made
  5780.                   # next time by rdb_set_dependents
  5781.                   $new_includes{$missing} = 1;
  5782.                }
  5783.                else {
  5784.                    # no point testing the $toext if the file doesn't exist.
  5785.                }
  5786.                next MISSING_FILE;
  5787.             }
  5788.        }
  5789.        else {
  5790.            # $_ doesn't exist, $_.tex doesn't exist,
  5791.            # and $_ doesn't have an extension
  5792.            foreach my $dep (@cus_dep_list){
  5793.               my ($fromext,$toext) = split('\s+',$dep);
  5794.               if ( -e "$path$base.$fromext" ) {
  5795.                   # Source file for the missing file exists
  5796.                   # So we have a real include file, and it will be made
  5797.                   # next time by &rdb__dependents
  5798.                   $new_includes{"$path$base.$toext"} = 1;
  5799. #                  next MISSING_FILE;
  5800.               }
  5801.               if ( -e "$path$base.$toext" ) {
  5802.                   # We've found the extension for the missing file,
  5803.                   # and the file exists
  5804.                   $new_includes{"$path$base.$toext"} = 1;
  5805. #                  next MISSING_FILE;
  5806.               }
  5807.            }
  5808.        }
  5809.     } # end MISSING_FILES
  5810.  
  5811.     # Sometimes bad line-breaks in log file (etc) create the
  5812.     # impression of a missing file e.g., ./file, but with an incorrect
  5813.     # extension.  The above tests find the file with an extension,
  5814.     # e.g., ./file.tex, but it is already in the list.  So now I will
  5815.     # remove files in the new_include list that are already in the
  5816.     # include list.  Also handle aliasing of file.tex and ./file.tex.
  5817.     # For example, I once found:
  5818. # (./qcdbook.aux (./to-do.aux) (./ideas.aux) (./intro.aux) (./why.aux) (./basics
  5819. #.aux) (./classics.aux)
  5820.  
  5821.     my $found = 0;
  5822.     foreach my $file (keys %new_includes) {
  5823.         my $stripped = $file;
  5824.         $stripped =~ s{^\./}{};
  5825.         if ( exists $PHsource{$file} ) {
  5826.             delete $new_includes{$file};
  5827.         }
  5828.         else {
  5829.             $found ++;
  5830.             rdb_ensure_file( $rule, $file );
  5831.         }
  5832.     }
  5833.  
  5834.     if ( $diagnostics && ( $found > 0 ) ) {
  5835.         warn "$My_name: Detected previously missing files:\n";
  5836.         foreach ( sort keys %new_includes ) {
  5837.             warn "   '$_'\n";
  5838.         }
  5839.     }
  5840.     return $found;
  5841. } # END rdb_find_new_files
  5842.  
  5843. #************************************************************
  5844.  
  5845. sub rdb_set_dependents {
  5846.     # Call rdb_set_dependents( rules ...)
  5847.     # Returns array (sorted), of new source files.
  5848.     local @new_sources = ();
  5849.     local @deletions = ();
  5850.  
  5851. # Shouldn't recurse.  The definite rules to be examined are given.
  5852.     rdb_for_some( [@_],  0, \&rdb_one_dep );
  5853. # OLD    rdb_recurse( [@_],  0, \&rdb_one_dep );
  5854.     foreach (@deletions) {
  5855.         my ($rule, $file) = @$_;
  5856.         rdb_remove_files( $rule, $file );
  5857.     }
  5858.     &rdb_make_links;
  5859.     return uniqs( @new_sources );
  5860. } #END rdb_set_dependents
  5861.  
  5862. #************************************************************
  5863.  
  5864. sub rdb_one_dep {
  5865.     # Helper for finding dependencies.  One case, $rule and $file given
  5866.     # Assume file (and rule) context for DESTINATION file.
  5867.  
  5868.     # Only look for dependency if $rule is primary rule (i.e., latex
  5869.     # or pdflatex) or is a custom dependency:
  5870.     if ( (! exists $possible_primaries{$rule}) && ($rule !~ /^cusdep/) ) {
  5871.         return;
  5872.     }
  5873. #print "=============ONE_DEP: '$rule' '$file'\n";
  5874.     local $new_dest = $file;
  5875.     my ($base_name, $path, $toext) = fileparseA( $new_dest );
  5876.     $base_name = $path.$base_name;
  5877.     $toext =~ s/^\.//;
  5878.     my $Pinput_extensions = $input_extensions{$rule};
  5879. DEP:
  5880.     foreach my $dep ( @cus_dep_list ) {
  5881.         my ($fromext,$proptoext,$must,$func_name) = split('\s+',$dep);
  5882.         if ( $toext eq $proptoext ) {
  5883.             my $source = "$base_name.$fromext";
  5884.             # Found match of rule
  5885.             if ($diagnostics) {
  5886.                 print "Found cusdep:  $source to make $rule:$new_dest ====\n";
  5887.             }
  5888.             if ( -e $source ) {
  5889.                 $$Pfrom_rule = "cusdep $fromext $toext $base_name";
  5890. #??             print "?? Ensuring rule for '$$Pfrom_rule'\n";
  5891.                 local @PAnew_cmd = ( 'do_cusdep', $func_name );
  5892.                 if ( !-e $new_dest ) {
  5893.                     push @new_sources, $new_dest;
  5894.                 }
  5895.                 if (! rdb_rule_exists( $$Pfrom_rule ) ) {
  5896.                     print "=== Creating rule for '$$Pfrom_rule'\n";
  5897.                     rdb_create_rule( $$Pfrom_rule, 'cusdep', '', \@PAnew_cmd, 3,
  5898.                                      $source, $new_dest, $base_name, 0 );
  5899.                 }
  5900.                 else {
  5901.                     rdb_one_rule(
  5902.                        $$Pfrom_rule,
  5903.                        sub{ @$PAint_cmd = @PAnew_cmd; $$Pdest = $new_dest;}
  5904.                     );
  5905.                 }
  5906.                 return;
  5907.             }
  5908.             else {
  5909.                 # Source file does not exist
  5910.                 if ( !$force_mode && ( $must != 0 ) ) {
  5911.                     # But it is required that the source exist ($must !=0)
  5912.                     $failure = 1;
  5913.                     $failure_msg = "File '$base_name.$fromext' does not exist ".
  5914.                                    "to build '$base_name.$toext'";
  5915.                     return;
  5916.                 }
  5917.                 elsif ( $$Pfrom_rule =~ /^cusdep $fromext $toext / )  {
  5918.                     # Source file does not exist, destination has the rule set.
  5919.                     # So turn the from_rule off
  5920.                     $$Pfrom_rule = '';
  5921.                 }
  5922.                 else {
  5923.                 }
  5924.             }
  5925.         }
  5926.         elsif ( ($toext eq '')
  5927.                 && (! -e $file )
  5928.                 && (! -e "$base_name.$proptoext" )
  5929.                 && exists $$Pinput_extensions{$proptoext}
  5930.               ) {
  5931.             # Empty extension and non-existent destination
  5932.             #   This normally results from  \includegraphics{A}
  5933.             #    without graphics extension for file, when file does
  5934.             #    not exist.  So we will try to find something to make it.
  5935.             my $source = "$base_name.$fromext";
  5936.             if ( -e $source ) {
  5937.                 $new_dest = "$base_name.$proptoext";
  5938.                 my $from_rule = "cusdep $fromext $proptoext $base_name";
  5939.                 push @new_sources, $new_dest;
  5940.                 print "Ensuring rule for '$from_rule', to make '$new_dest'\n"
  5941.                     if $diagnostics > -1;
  5942.                 local @PAnew_cmd = ( 'do_cusdep', $func_name );
  5943.                 if (! rdb_rule_exists( $from_rule ) ) {
  5944.                     rdb_create_rule( $from_rule, 'cusdep', '', \@PAnew_cmd, 3,
  5945.                                      $source, $new_dest, $base_name, 0 );
  5946.                 }
  5947.                 else {
  5948.                     rdb_one_rule(
  5949.                        $$Pfrom_rule,
  5950.                        sub{ @$PAint_cmd = @PAnew_cmd; $$Pdest = $new_dest;}
  5951.                     );
  5952.                 }
  5953.                 rdb_ensure_file( $rule, $new_dest, $from_rule );
  5954.                 # We've now got a spurious file in our rule.  But don't mess
  5955.                 # with deleting an item we are in the middle of!
  5956.                 push @deletions, [$rule, $file];
  5957.                 return;
  5958.             }
  5959.         } # End of Rule found
  5960.     } # End DEP
  5961.     if ( (! -e $file) && $use_make_for_missing_files ) {
  5962.         # Try to make the missing file
  5963.         #Set character to surround filenames in commands:
  5964.         my $q = $quote_filenames ? '"' : '';
  5965.         if ( $toext ne '' ) {
  5966.              print "$My_name: '$rule': source file '$file' doesn't exist. I'll try making it...\n";
  5967.              &Run_subst( "$make $q$file$q" );
  5968.              if ( -e $file ) {
  5969.                  return;
  5970.              }
  5971.         }
  5972.         else {
  5973.              print "$My_name: '$rule': source '$file' doesn't exist.\n",
  5974.                    "   I'll try making it with allowed extensions \n";
  5975.              foreach my $try_ext ( keys %$Pinput_extensions ) {
  5976.                  my $new_dest = "$file.$try_ext";
  5977.                  &Run_subst( "$make $q$new_dest$q" );
  5978.                  if ( -e $new_dest ) {
  5979.                      print "SUCCESS in making '$new_dest'\n";
  5980.                      # Put file in rule, without a from_rule, but
  5981.                      # set its state as non-existent, to correspond
  5982.                      # to file's state before the file was made
  5983.                      # This ensures a rerun of (pdf)latex is provoked.
  5984.                      rdb_ensure_file( $rule, $new_dest, undef, 1 );
  5985.                      push @new_sources, $new_dest;
  5986.                      push @deletions, [$rule, $file];
  5987.                      # Flag need for a new run of (pdf)latex despite
  5988.                      # the error due to a missing file.
  5989.                      $$Pout_of_date_user = 1;
  5990.                      return;
  5991.                  }
  5992.            }
  5993.         }
  5994.     }
  5995. } #END rdb_one_dep
  5996.  
  5997. #************************************************************
  5998.  
  5999. sub rdb_list {
  6000.     # Call: rdb_list()
  6001.     # List rules and their source files
  6002.     print "===Rules:\n";
  6003.     local $count_rules = 0;
  6004.     my @accessible_all = rdb_accessible( keys %requested_filerules );
  6005.     rdb_for_some(
  6006.         \@accessible_all,
  6007.         sub{ $count_rules++;
  6008.              print "Rule '$rule' depends on:\n";
  6009.            },
  6010.         sub{ print "    '$file'\n"; },
  6011.         sub{ print "  and generates:\n";
  6012.              foreach (keys %$PHdest) { print "    '$_'\n"; }
  6013. #             print "  default_extra_generated:\n";
  6014. #             foreach (@$PA_extra_generated) { print "    '$_'\n"; }
  6015.            },
  6016.     );
  6017.     if ($count_rules <= 0) {
  6018.         print "   ---No rules defined\n";
  6019.     }
  6020. } #END rdb_list
  6021.  
  6022. #************************************************************
  6023.  
  6024. sub deps_list {
  6025.     # Call: deps_list(fh)
  6026.     # List dependent files to file open on fh
  6027.     my $fh = $_[0];
  6028.     print $fh "#===Dependents, and related info, for $filename:\n";
  6029.     my @dest_exts = ();
  6030.     if ($pdf_mode) {push @dest_exts, '.pdf';}
  6031.     if ($dvi_mode) {push @dest_exts, '.dvi';}
  6032.     if ($postscript_mode) {push @dest_exts, '.ps';}
  6033.     my %source = ( $texfile_name => 1 );
  6034.     my @generated = ();
  6035.     my @accessible_all = rdb_accessible( keys %requested_filerules );
  6036.     rdb_for_some(
  6037.         \@accessible_all,
  6038.         sub{
  6039. #             foreach (keys %$PHdest) { print "-----   $_\n"; }
  6040.              push @generated, keys %$PHdest;
  6041.            },
  6042.         sub{ $source{$file} = 1; }
  6043.     );
  6044.     foreach (keys %generated_exts_all) {
  6045.         (my $name = /%R/ ? $_ : "%R.$_") =~ s/%R/${aux_dir1}${root_filename}/;
  6046.         push @generated, $name;
  6047.     }
  6048.     show_array( "Generated:", @generated )  if $diagnostics;
  6049.     foreach (@generated) {
  6050.         delete $source{$_};
  6051.     }
  6052.     show_array( "Sources:", keys %source ) if $diagnostics;
  6053.     foreach my $ext (@dest_exts) {
  6054.          # Don't insert name of deps file in targets.
  6055.          # The previous behavior of inserting the name of the deps file
  6056.          # matched the method recommended by GNU make for automatically
  6057.          # generated prerequisites -- see Sec. "Generating Prerequisites
  6058.          # Automatically" of GNU make manual (v. 4.2).  But this can
  6059.          # cause problems in complicated cases, and as far as I can see,
  6060.          # it doesn't actually help, despite the reasoning given.
  6061.          # The only purpose of the deps file is to to determine source
  6062.          # files for a particular rule.  The files whose changes make the
  6063.          # deps file out-of-date are the same as those that make the real
  6064.          # target file (e.g., .pdf) out-of-date. So the GNU method seems
  6065.          # completely unnecessary.
  6066.        print $fh "${out_dir1}${root_filename}${ext} :";
  6067.        foreach (sort keys %source) {
  6068.            print $fh "\\\n    $_";
  6069.        }
  6070.        print $fh "\n";
  6071.     }
  6072.     print $fh "#===End dependents for $filename:\n";
  6073.     if ($dependents_phony) {
  6074.         print $fh "\n#===Phony rules for $filename:\n\n";
  6075.         foreach (sort keys %source) {
  6076.             print $fh "$_ :\n\n";
  6077.         }
  6078.         print $fh "#===End phony rules for $filename:\n";
  6079.     }
  6080. } #END deps_list
  6081.  
  6082. #************************************************************
  6083.  
  6084. sub rdb_show {
  6085.     # Call: rdb_show()
  6086.     # Displays contents of rule data base.
  6087.     # Side effect: Exercises access routines!
  6088.     print "===Rules:\n";
  6089.     local $count_rules = 0;
  6090.     rdb_for_all(
  6091.         sub{ $count_rules++;
  6092.              my @int_cmd = @$PAint_cmd;
  6093.              foreach (@int_cmd) {
  6094.                  if ( !defined($_) ) { $_='undef';}
  6095.              }
  6096.              print "  [$rule]: '$$Pcmd_type' '$$Pext_cmd' '@int_cmd' $$Ptest_kind ",
  6097.                    "'$$Psource' '$$Pdest' '$$Pbase' $$Pout_of_date $$Pout_of_date_user\n"; },
  6098.         sub{ print "    '$file': $$Ptime $$Psize $$Pmd5 '$$Pfrom_rule'\n"; }
  6099.     );
  6100.     if ($count_rules <= 0) {
  6101.         print "   ---No rules defined\n";
  6102.     }
  6103. } #END rdb_show
  6104.  
  6105. #************************************************************
  6106.  
  6107. sub rdb_accessible {
  6108.     # Call: rdb_accessible( rule, ...)
  6109.     # Returns array of rules accessible from the given rules
  6110.     local @accessible = ();
  6111.     rdb_recurse( [@_], sub{ push @accessible, $rule; } );
  6112.     return @accessible;
  6113. } #END rdb_accessible
  6114.  
  6115. #************************************************************
  6116. #************************************************************
  6117. #************************************************************
  6118.  
  6119. sub rdb_make {
  6120.     # Call: rdb_make( target, ... )
  6121.     # Makes the targets and prerequisites.  
  6122.     # Leaves one-time rules to last.
  6123.     # Does appropriate repeated makes to resolve dependency loops
  6124.  
  6125.     # Returns 0 on success, nonzero on failure.
  6126.  
  6127.     # General method: Find all accessible rules, then repeatedly make
  6128.     # them until all accessible rules are up-to-date and the source
  6129.     # files are unchanged between runs.  On termination, all
  6130.     # accessible rules have stable source files.
  6131.     #
  6132.     # One-time rules are view and print rules that should not be
  6133.     # repeated in an algorithm that repeats rules until the source
  6134.     # files are stable.  It is the calling routine's responsibility to
  6135.     # arrange to call them, or to use them here with caution.
  6136.     #
  6137.     # Note that an update-viewer rule need not be considered
  6138.     # one-time.  It can be legitimately applied everytime the viewed
  6139.     # file changes.
  6140.     #
  6141.     # Note also that the criterion of stability is to be applied to
  6142.     # source files, not to output files.  Repeated application of a
  6143.     # rule to IDENTICALLY CONSTANT source files may produce different
  6144.     # output files.  This may be for a trivial reason (e.g., the
  6145.     # output file contains a time stamp, as in the header comments for
  6146.     # a typical postscript file), or for a non-trivial reason (e.g., a
  6147.     # stochastic algorithm, as in abcm2ps).  
  6148.     #
  6149.     # This caused me some actual trouble.  In general, circular
  6150.     # dependencies produce non-termination, and the the following
  6151.     # situation is an example of a generic situation where certain
  6152.     # rules must be obeyed in order to obtain proper results:
  6153.     #    1.  A/the latex source file contains specifications for
  6154.     #        certain postprocessing operations.  Standard (pdf)latex
  6155.     #        already has this, for indexing and bibliography.
  6156.     #    2.  In the case in point that caused me trouble, the
  6157.     #        specification was for musical tunes that were contained
  6158.     #        in external source files not directly input to
  6159.     #        (pdf)latex.  But in the original version, there was a
  6160.     #        style file (abc.sty) that caused latex itself to call
  6161.     #        abcm2ps to make .eps files for each tune that were to be
  6162.     #        read in on the next run of latex.
  6163.     #    3.  Thus the specification can cause a non-terminating loop
  6164.     #        for latexmk, because the output files of abcm2ps changed
  6165.     #        even with identical input.  
  6166.     #    4.  The solution was to
  6167.     #        a. Use a style file abc_get.sty that simply wrote the
  6168.     #           specification on the tunes to the .aux file in a
  6169.     #           completely deterministic fashion.
  6170.     #        b. Instead of latex, use a script abclatex.pl that runs
  6171.     #           latex and then extracts the abc contents for each tune
  6172.     #           from the source abc file.  This is also
  6173.     #           deterministic.
  6174.     #        c. Use a cusdep rule in latexmk to convert the tune abc
  6175.     #           files to eps.  This is non-deterministic, but only
  6176.     #           gets called when the (deterministic) source file
  6177.     #           changes.
  6178.     #        This solves the problem.  Latexmk works.  Also, it is no
  6179.     #        longer necessary to enable write18 in latex, and multiple
  6180.     #        unnecessary runs of abcm2ps are no longer used.
  6181.     #
  6182.     # The order of testing and applying rules is chosen by the
  6183.     # following heuristics:
  6184.     #    1.  Both latex and pdflatex may be used, but the resulting
  6185.     #        aux files etc may not be completely identical.  Define
  6186.     #        latex and pdflatex as primary rules.  Apply the general
  6187.     #        method of repeated circulating through all rules until
  6188.     #        the source files are stable for each primary rule
  6189.     #        separately.  Naturally the rules are all accessible
  6190.     #        rules, but excluding primary rules except for the current
  6191.     #        primary.
  6192.     #    2.  Assume that the primary rules are relatively
  6193.     #        time-consuming, so that unnecessary passes through them
  6194.     #        to check stability of the source files should be avoided.
  6195.     #    3.  Assume that although circular dependencies exist, the
  6196.     #        rules can nevertheless be thought of as basically
  6197.     #        non-circular, and that many rules are strictly or
  6198.     #        normally non-circular.  In particular cusdep rules are
  6199.     #        typically non-circular (e.g., fig2eps), as are normal
  6200.     #        output processing rules like dvi2ps.  
  6201.     #    4.  The order for the non-circular approximation is
  6202.     #        determined by applying the assumption that an output file
  6203.     #        from one rule that is read in for an earlier stage is
  6204.     #        unchanged.
  6205.     #    HOWEVER, at a first attempt, the ordering is not needed.  It
  6206.     #    only gives an optimization
  6207.     #    5.  (Note that these assumptions could be violated, e.g., if
  6208.     #        $dvips is arranged not only to do the basic dvips
  6209.     #        command, but also to extract information from the ps file
  6210.     #        and feed it back to an input file for (pdf)latex.)
  6211.     #    6.  Nevertheless, the overall algorithm should allow
  6212.     #        circularities.  Then the general criterion of stability
  6213.     #        of source files covers the general case, and also
  6214.     #        robustly handles the case that the USER changes source
  6215.     #        files during a run.  This is particularly important in
  6216.     #        -pvc mode, given that a full make on a large document can
  6217.     #        be quite lengthy in time, and moreover that a user
  6218.     #        naturally wishes to make corrections in response to
  6219.     #        errors, particularly latex errors, and have them apply
  6220.     #        right away.
  6221.     # This leads to the following approach:
  6222.     #    1.  Classify accessible rules as: primary, pre-primary
  6223.     #        (typically cusdep, bibtex, makeindex, etc), post-primary
  6224.     #        (typically dvips, etc), and one-time
  6225.     #    2.  Then stratify the rules into an order of application that
  6226.     #        corresponds to the basic feedforward structure, with the
  6227.     #        exclusion of one-time rules.
  6228.     #    3.  Always require that one-time rules are among the
  6229.     #        explicitly requested rules, i.e., the last to be applied,
  6230.     #        were we to apply them.  Anything else would not match the
  6231.     #        idea of a one-time rule.  
  6232.     #    4.  Then work as follows:
  6233.     #        a. Loop over primaries
  6234.     #        b. For each primary, examine each pre-primary rule and
  6235.     #           apply if needed, then the primary rule and then each
  6236.     #           post-primary rule.  The ordering of the pre-primary
  6237.     #           and post-primary rules was found in step 2.
  6238.     #      BUT applying the ordering is not essential
  6239.     #        c. Any time that a pre-primary or primary rule is
  6240.     #           applied, loop back to the beginning of step b.  This
  6241.     #           ensures that bibtex etc are applied before rerunning
  6242.     #           (pdf)latex, and also covers changing source files, and
  6243.     #           gives priority to quick pre-primary rules for changing
  6244.     #           source files against slow reruns of latex.
  6245.     #        d. Then apply post-primary rules in order, but not
  6246.     #           looping back after each rule.  This non-looping back
  6247.     #           is because the rules are normally feed-forward only.
  6248.     #      BUT applying the ordering is not essential
  6249.     #        e. But after completing post-primary rules do loop back
  6250.     #           to b if any rules were applied.  This covers exotic
  6251.     #           circular dependence (and as a byproduct, changing
  6252.     #           source files).
  6253.     #        f. On each case of looping back to b, re-evaluate the
  6254.     #           dependence setup to allow for the effect of changing
  6255.     #           source files.  
  6256.     #    
  6257.  
  6258.     local @requested_targets = @_;
  6259.     local %current_primaries = ();   # Hash whose keys are primary rules
  6260.                 # needed, i.e., known latex-like rules which trigger
  6261.                 # circular dependencies
  6262.     local @pre_primary = ();   # Array of rules
  6263.     local @post_primary = ();  # Array of rules
  6264.     local @unusual_one_time = ();      # Array of rules
  6265.  
  6266.  
  6267.     # For diagnostics on changed files, etc:
  6268.     local @changed = ();
  6269.     local @disappeared = ();
  6270.     local @no_dest = ();       # Non-existent destination files
  6271.     local @rules_never_run = ();
  6272.     local @rules_to_apply = ();
  6273.  
  6274.     &rdb_classify_rules( \%possible_primaries, @requested_targets );
  6275.  
  6276.     local %pass = ();
  6277.     local $failure = 0;        # General accumulated error flag
  6278.     local $missing_dvi_pdf = ''; # Did primary run fail to make its output file?
  6279.     local $runs = 0;
  6280.     local $too_many_passes = 0;
  6281.     local %rules_applied = ();
  6282.     my $retry_msg = 0;         # Did I earlier say I was going to attempt
  6283.                                # another pass after a failure?
  6284.   PRIMARY:
  6285.     foreach my $primary (keys %current_primaries ) {
  6286.         foreach my $rule (keys %rule_db) {
  6287.             $pass{$rule} = 0;
  6288.         }
  6289.       PASS:
  6290.         while (1==1) {
  6291.             # Exit condition at end of body of loop.
  6292.             $runs = 0;
  6293.             my $previous_failure = $failure;
  6294.             $failure = 0;
  6295.             local $newrule_nofile = 0;  # Flags whether rule created for
  6296.                            # making currently non-existent file, which
  6297.                            # could become a needed source file for a run
  6298.                            # and therefore undo an error condition
  6299.             if ($diagnostics) {
  6300.                 print "Make: doing pre_primary and primary...\n";
  6301.             }
  6302.             # Do the primary run if it is needed. On return $runs == 0
  6303.             #       signals that nothing was run (and hence no output
  6304.             #       files changed), either because no input files
  6305.             #       changed and no run was needed, or because the
  6306.             #       number of passes through the rule exceeded the
  6307.             #       limit.  In the second case $too_many_runs is set.
  6308.             rdb_for_some( [@pre_primary, $primary], \&rdb_make1 );
  6309.             if ( ($runs > 0) && ! $too_many_passes ) {
  6310.                 $retry_msg = 0;
  6311.                 if ( $force_mode || (! $failure) ) {
  6312.                     next PASS;
  6313.         }
  6314.                 # Get here on failure, without being in force_mode
  6315.                 if ( $newrule_nofile ) {
  6316.                     $retry_msg = 1;
  6317.                     print "$My_name: Error on run, but found possibility to ",
  6318.                           "make new source files\n";
  6319.                     next PASS;
  6320.         }
  6321.                 else { last PASS; }
  6322.             }
  6323.             if ($runs == 0) {
  6324.                 # $failure not set on this pass, so use value from previous pass:
  6325.                 $failure = $previous_failure;
  6326.                 if ($retry_msg) {
  6327.                     print "But in fact no new files made\n";
  6328.         }
  6329.                 if ($failure && !$force_mode ) { last PASS; }
  6330.             }
  6331.             if ( $missing_dvi_pdf ) {
  6332.                # No output from primary, after completing circular dependence
  6333.                warn "Failure to make '$missing_dvi_pdf'\n";
  6334.                $failure = 1;
  6335.                last PASS;
  6336.             }    
  6337.             if ($diagnostics) {
  6338.                 print "Make: doing post_primary...\n";
  6339.             }
  6340.             rdb_for_some( [@post_primary], \&rdb_make1 );
  6341.             if ( ($runs == 0) || $too_many_passes ) {
  6342.                 # If $too_many_passes is set, it should also be that
  6343.                 # $runs == 0; but for safety, I also checked
  6344.                 # $too_many_passes.
  6345.                 last PASS;
  6346.             }
  6347.         }
  6348.         continue {
  6349.             # Re-evaluate rule classification and accessibility,
  6350.             # but do not change primaries.
  6351.             # Problem is that %current_primaries gets altered
  6352.             my %old_curr_prim = %current_primaries;
  6353.             &rdb_classify_rules( \%possible_primaries, @requested_targets );
  6354.             %current_primaries = %old_curr_prim;
  6355.             &rdb_make_links;
  6356.         }
  6357.     }
  6358.     rdb_for_some( [@unusual_one_time], \&rdb_make1 );
  6359.     rdb_write( $fdb_name );
  6360.  
  6361.     if (! $silent) {
  6362.         if ($failure && $force_mode) {
  6363.             print "$My_name: Errors, in force_mode: so I tried finishing targets\n";
  6364.         }
  6365.         elsif ($failure) {
  6366.             print "$My_name: Errors, so I did not complete making targets\n";
  6367.         }
  6368.         else {
  6369.             local @dests = ();
  6370.             rdb_for_some( [@_], sub{ push @dests, $$Pdest if ($$Pdest); } );
  6371.             print "$My_name: All targets (@dests) are up-to-date\n";
  6372.         }
  6373.     }
  6374.     return $failure;
  6375. } #END rdb_make
  6376.  
  6377. #-------------------
  6378.  
  6379. sub rdb_show_rule_errors {
  6380.     local @errors = ();
  6381.     local @warnings = ();
  6382.     rdb_for_all(
  6383.                sub{
  6384.                    if ($$Plast_message ne '') {
  6385.                        if ($$Plast_result == 200) {
  6386.                           push @warnings, "$rule: $$Plast_message";
  6387.                        }
  6388.                        else {
  6389.                           push @errors, "$rule: $$Plast_message";
  6390.                        }
  6391.                    }
  6392.                    elsif ($$Plast_result == 1) {
  6393.                        push @errors, "$rule: failed to create output file";
  6394.                    }
  6395.                    elsif ($$Plast_result == 2) {
  6396.                        push @errors, "$rule: gave an error";
  6397.                    }
  6398.                    elsif ($$Prun_time == 0) {
  6399.                        #  This can have innocuous causes.  So don't report
  6400.                    }
  6401.                }
  6402.               );
  6403.     if ($#warnings > -1) {
  6404.         warn "Collected warning summary (may duplicate other messages):\n";
  6405.         foreach (@warnings){
  6406.             warn "  $_\n";
  6407.         }
  6408.     }
  6409.     if ($#errors > -1) {
  6410.         warn "Collected error summary (may duplicate other messages):\n";
  6411.         foreach (@errors){
  6412.             warn "  $_\n";
  6413.         }
  6414.     }
  6415.     return $#errors+1;
  6416. }
  6417.  
  6418. #-------------------
  6419.  
  6420. sub rdb_make1 {
  6421.     # Call: rdb_make1
  6422.     # Helper routine for rdb_make.
  6423.     # Carries out make at level of given rule (all data available).
  6424.     # Assumes contexts for recursion, make, and rule, and
  6425.     # assumes that source files for the rule are to be considered
  6426.     # up-to-date.
  6427.     if ($diagnostics) { print "  Make1 $rule\n"; }
  6428.     if ($failure & ! $force_mode) {return;}
  6429.     if ( ! defined $pass{$rule} ) {$pass{$rule} = 0; }
  6430.     &rdb_clear_change_record;
  6431.  
  6432.     # Special fix up for bibtex:
  6433.     my $bibtex_not_run = -1;   # Flags status as to whether this is a
  6434.         # bibtex rule and if it is, whether out-of-date condition is to
  6435.         # be ignored.
  6436.         #  -1 => not a bibtex rule
  6437.         #   0 => no special treatment
  6438.         #   1 => don't run bibtex because of non-existent bibfiles
  6439.         #           (and setting to do this test)
  6440.         #   2 => don't run bibtex because of setting
  6441.     my @missing_bib_files = ();
  6442.     if ( $rule =~ /^(bibtex|biber)/ ) {
  6443.         $bibtex_not_run = 0;
  6444.         if ($bibtex_use == 0) {
  6445.            $bibtex_not_run = 2;
  6446.         }
  6447.         elsif ( ($bibtex_use == 1) || ($bibtex_use == 1.5) ) {
  6448.             foreach ( keys %$PHsource ) {
  6449.                 if ( ( /\.bib$/ ) && (! -e $_) ) {
  6450.                     push @missing_bib_files, $_;
  6451.                     $bibtex_not_run = 1;
  6452.                 }
  6453.             }
  6454.         }
  6455.     }
  6456.  
  6457.     if ( ($$Prun_time == 0) && exists($possible_primaries{$rule}) ) {
  6458.         push @rules_never_run, $rule;
  6459.         $$Pout_of_date = 1;
  6460.         $$Plast_result = -1;
  6461.     }
  6462.     else {
  6463.         if ( $$Pdest && (! -e $$Pdest) ) {
  6464.             # With a non-existent destination, if we haven't made any passes
  6465.             #   through a rule, rerunning the rule is good, because the file
  6466.             #   may fail to exist because of being deleted by the user (for ex.)
  6467.             #   rather than because of a failure on a previous run.
  6468.             # (We could do better with a flag in fdb file.)
  6469.             # But after the first pass, the situation is different.  
  6470.             #   For a primary rule (pdf)latex, the lack of a destination file
  6471.             #      could result from there being zero content due to a missing
  6472.             #      essential input file.  The input file could be generated
  6473.             #      by a program to be run later (e.g., a cusdep or bibtex),
  6474.             #      so we should wait until all passes are completed before
  6475.             #      deciding a non-existent destination file is an error.
  6476.             #   For a custom dependency, the rule may be obsolete, and
  6477.             #      if the source file does not exist also, we should simply
  6478.             #      not run the rule, but not set an error condition.
  6479.             #      Any error will arise at the (pdf)latex level due to a
  6480.             #      missing source file at that level.
  6481.             if ( $$Psource && (! -e $$Psource)
  6482. # OLD                && ( ( $$Pcmd_type eq 'cusdep') )
  6483. # NEW
  6484.                  && ( ( $$Pcmd_type ne 'primary') )
  6485.                ) {
  6486.                 # Main source file doesn't exist, and rule is NOT primary.
  6487.                 # No action, since a run is pointless.  Primary is different:
  6488.                 # file might be found elsewhere (by kpsearch from (pdf)latex),
  6489.                 # while non-existence of main source file is a clear error.
  6490.             }
  6491.             elsif ( $$Pcmd_type eq 'delegated' ) {
  6492.                 # Delegate to destination rule
  6493.             }
  6494.             elsif ( $pass{$rule}==0) {
  6495.                 push @no_dest, $$Pdest;
  6496.                 $$Pout_of_date = 1;
  6497.             }
  6498.             if ( $$Pcmd_type eq 'primary' ) {
  6499.                 $missing_dvi_pdf = $$Pdest;
  6500.             }
  6501.         }
  6502.     }
  6503.  
  6504.     &rdb_flag_changes_here(0);
  6505.  
  6506.     if (!$$Pout_of_date) {
  6507. #??     if ( ($$Pcmd_type eq 'primary') && (! $silent) ) {
  6508. #            print "Rule '$rule' up to date\n";
  6509. #        }
  6510.         return;
  6511.     }
  6512.     if ($diagnostics) { print "     remake\n"; }
  6513.     if (!$silent) {
  6514.         print "$My_name: applying rule '$rule'...\n";
  6515.         &rdb_diagnose_changes( "Rule '$rule': " );
  6516.     }
  6517.  
  6518.     # We are applying the rule, so its source file state for when it
  6519.     # was last made is as of now:
  6520.     # ??IS IT CORRECT TO DO NOTHING IN CURRENT VERSION?
  6521.  
  6522.     # The actual run
  6523.     my $return = 0;   # Return code from called routine
  6524.     # Rule may have been created since last run:
  6525.     if ( ! defined $pass{$rule} ) {$pass{$rule} = 0; }
  6526.     if ( $pass{$rule} >= $max_repeat ) {
  6527.         # Avoid infinite loop by having a maximum repeat count
  6528.         # Getting here represents some kind of weird error.
  6529.         warn "$My_name: Maximum runs of $rule reached ",
  6530.              "without getting stable files\n";
  6531.         $too_many_passes = 1;
  6532.         # Treat rule as completed, else in -pvc mode get infinite reruns:
  6533.         $$Pout_of_date = 0;
  6534.         $failure = 1;
  6535.         $failure_msg = "'$rule' needed too many passes";
  6536.         return;
  6537.     }
  6538.  
  6539.     $rules_applied{$rule} = 1;
  6540.     $runs++;
  6541.  
  6542.     $pass{$rule}++;
  6543.     if ($bibtex_not_run > 0) {
  6544.         if ($bibtex_not_run == 1 ) {
  6545.             show_array ("$My_name: I WON'T RUN '$rule' because I don't find the following files:",
  6546.                         @missing_bib_files);
  6547.         }
  6548.         elsif ($bibtex_not_run == 2 ) {
  6549.             warn "$My_name: I AM CONFIGURED/INVOKED NOT TO RUN '$rule'\n";
  6550.         }
  6551.         $return = &rdb_dummy_run1;
  6552.     }
  6553.     else {
  6554.         warn_running( "Run number $pass{$rule} of rule '$rule'" );
  6555.         if ($$Pcmd_type eq 'primary' ) {
  6556.             $return = &rdb_primary_run;
  6557.         }
  6558.         else { $return = &rdb_run1; }
  6559.     }
  6560.     if ($$Pchanged) {
  6561.         $newrule_nofile = 1;
  6562.         $return = 0;
  6563.     }
  6564.     elsif ( $$Pdest && ( !-e $$Pdest ) && (! $failure) ){
  6565.         # If there is a destination to make, but for some reason
  6566.         #    it did not get made, and no other error was reported,
  6567.         #    then a priori there appears to be an error condition:
  6568.         #    the run failed.   But there are some important cases in
  6569.         #    which this is a wrong diagnosis.
  6570.         if ( ( $$Pcmd_type eq 'cusdep') && $$Psource && (! -e $$Psource) ) {
  6571.             # However, if the rule is a custom dependency, this is not by
  6572.             #  itself an error, if also the source file does not exist.  In
  6573.             #  that case, we may have the situation that (1) the dest file is no
  6574.             #  longer needed by the tex file, and (2) therefore the user
  6575.             #  has deleted the source and dest files.  After the next
  6576.             #  latex run and the consequent analysis of the log file, the
  6577.             #  cusdep rule will no longer be needed, and will be removed.
  6578.  
  6579.             # So in this case, do NOT report an error          
  6580.             $$Pout_of_date = 0;
  6581.         }
  6582.         elsif ($$Pcmd_type eq 'primary' ) {
  6583.             # For a primary rule, i.e., (pdf)latex, not to produce the
  6584.             #    expected output file may not be an error condition.  
  6585.             # Diagnostics were handled in parsing the log file.
  6586.             # Special action in main loop in rdb_make
  6587.             $missing_dvi_pdf = $$Pdest;
  6588.         }
  6589.         elsif ($return == -2) {
  6590.            # Missing output file was reported to be NOT an error
  6591.            $$Pout_of_date = 0;
  6592.         }
  6593.         elsif ( ($bibtex_use <= 1.5) && ($bibtex_not_run > 0) ) {
  6594.            # Lack of destination file is not to be treated as an error
  6595.            # for a bibtex rule when latexmk is configured not to treat
  6596.            # this as an error, and the lack of a destination file is the
  6597.            # only error.
  6598.            $$Pout_of_date = 0;
  6599.         }
  6600.         else {
  6601.             $failure = 1;
  6602.         }
  6603.     }
  6604.     if ( ($return != 0) && ($return != -2) ) {
  6605.         $failure = 1;
  6606.         $$Plast_result = 2;
  6607.         if ( !$$Plast_message ) {
  6608.             $$Plast_message = "Run of rule '$rule' gave a non-zero error code";
  6609.         }
  6610. # !!??        $failure_msg = $$Plast_message;
  6611.        
  6612.     }
  6613. }  #END rdb_make1
  6614.  
  6615. #************************************************************
  6616.  
  6617. #??sub rdb_submake {
  6618. #??    # Call: rdb_submake
  6619. #??    # Makes all the source files for a given rule.
  6620. #??    # Assumes contexts for recursion, for make, and rule.
  6621. #??    %visited = %visited_at_rule_start;
  6622. #??    local $failure = 0;  # Error flag
  6623. #??    my @v = keys %visited;
  6624. #??    rdb_do_files( sub{ rdb_recurse_rule( $$Pfrom_rule, 0,0,0, \&rdb_make1 ) } );
  6625. #??    return $failure;
  6626. #??}  #END rdb_submake
  6627.  
  6628. #************************************************************
  6629.  
  6630. sub rdb_classify_rules {
  6631.     # Usage: rdb_classify_rules( \%allowed_primaries, requested targets )
  6632.     # Assume the following variables are available (global or local):
  6633.     # Input:
  6634.     #    @requested_targets    # Set to target rules
  6635.    
  6636.     # Output:
  6637.     #    %current_primaries    # Keys are actual primaries
  6638.     #    @pre_primary          # Array of rules
  6639.     #    @post_primary         # Array of rules
  6640.     #    @unusual_one_time     # Array of rules
  6641.     # @pre_primary and @post_primary are in natural order of application.
  6642.  
  6643.     local $P_allowed_primaries = shift;
  6644.     local @requested_targets = @_;
  6645.     local $state = 0;       # Post-primary
  6646.     local @classify_stack = ();
  6647.  
  6648.     %current_primaries = ();
  6649.     @pre_primary = ();
  6650.     @post_primary = ();
  6651.     @unusual_one_time = ();
  6652.  
  6653.     rdb_recurse( \@requested_targets, \&rdb_classify1, 0,0, \&rdb_classify2 );
  6654.  
  6655.     # Reverse, as tendency is to find last rules first.
  6656.     @pre_primary = reverse @pre_primary;
  6657.     @post_primary = reverse @post_primary;
  6658.  
  6659.     if ($diagnostics) {
  6660.         print "Rule classification: \n";
  6661.         if ($#requested_targets < 0) {
  6662.             print "  No requested rules\n";
  6663.         }
  6664.         else {
  6665.             print "  Requested rules:\n";
  6666.             foreach ( @requested_targets ) { print "    $_\n"; }
  6667.         }
  6668.         if ($#pre_primary < 0) {
  6669.             print "  No pre-primaries\n";
  6670.         }
  6671.         else {
  6672.             print "  Pre-primaries:\n";
  6673.             foreach (@pre_primary) { print "    $_\n"; }
  6674.         }
  6675.         print "  Primaries:\n";
  6676.         foreach (keys %current_primaries) { print "    $_\n"; }
  6677.         if ($#post_primary < 0) {
  6678.             print "  No post-primaries\n";
  6679.         }
  6680.         else {
  6681.             print "  Post-primaries:\n";
  6682.             foreach (@post_primary) { print "    $_\n"; }
  6683.         }
  6684.         if ($#unusual_one_time < 0) {
  6685.             print "  No inner-level one_time rules, as expected\n";
  6686.         }
  6687.         else {
  6688.             print "  Inner-level one_time rules:\n";
  6689.             foreach ( @unusual_one_time ) { print "    $_\n"; }
  6690.         }
  6691.         my @normal_one_time = keys %one_time;
  6692.         if ($#normal_one_time < 0) {
  6693.             print "  No outer-level one_time rules\n";
  6694.         }
  6695.         else {
  6696.             print "  Outer-level one_time rules:\n";
  6697.             foreach ( @normal_one_time ) { print "    $_\n"; }
  6698.         }
  6699.     } #end diagnostics
  6700.  
  6701. } #END rdb_classify_rules
  6702.  
  6703. #-------------------
  6704.  
  6705. sub rdb_classify1 {
  6706.     # Helper routine for rdb_classify_rules
  6707.     # Applied as rule_act1 in recursion over rules
  6708.     # Assumes rule context, and local variables from rdb_classify_rules
  6709.     push @classify_stack, [$state];
  6710.     if ( exists $possible_one_time{$rule} ) {
  6711.         # Normally, we will have already extracted the one_time rules,
  6712.         # and they will never be accessed here.  But just in case of
  6713.         # problems or generalizations, we will cover all possibilities:
  6714.         if ($depth > 1) {
  6715.            warn "ONE TIME rule not at outer level '$rule'\n";
  6716.         }
  6717.         push @unusual_one_time, $rule;
  6718.     }
  6719.     elsif ($state == 0) {
  6720.        if ( exists ${$P_allowed_primaries}{$rule} ) {
  6721.            $state = 1;   # In primary rule
  6722.            $current_primaries{ $rule } = 1;
  6723.        }
  6724.        else {
  6725.            push @post_primary, $rule;
  6726.        }
  6727.     }
  6728.     else {
  6729.         $state = 2;     # in post-primary rule
  6730.         push @pre_primary, $rule;
  6731.     }
  6732. } #END rdb_classify1
  6733.  
  6734. #-------------------
  6735.  
  6736. sub rdb_classify2 {
  6737.     # Helper routine for rdb_classify_rules
  6738.     # Applied as rule_act2 in recursion over rules
  6739.     # Assumes rule context
  6740.     ($state) = @{ pop @classify_stack };
  6741. } #END rdb_classify2
  6742.  
  6743. #************************************************************
  6744.  
  6745.  
  6746. sub rdb_run1 {
  6747.     # Assumes contexts for: rule.
  6748.     # Unconditionally apply the rule
  6749.     # Returns return code from applying the rule.
  6750.     # Otherwise: 0 on other kind of success,
  6751.     #            -1 on error,
  6752.     #            -2 when missing dest_file is to be ignored
  6753.  
  6754.     # Source file data, by definition, correspond to the file state just
  6755.     # before the latest run, and the run_time to the time just before the run:
  6756.     &rdb_update_files;
  6757.     $$Prun_time = time();
  6758.     $$Pchanged = 0;       # No special changes in files
  6759.     $$Plast_result = 0;
  6760.     $$Plast_message = '';
  6761.  
  6762.     # Return values for external command:
  6763.     my $return = 0;
  6764.  
  6765.     # Find any internal command
  6766.     my @int_args = @$PAint_cmd;
  6767.     my $int_cmd = shift @int_args;
  6768.     my @int_args_for_printing = @int_args;
  6769.     foreach (@int_args_for_printing) {
  6770.         if ( ! defined $_ ) { $_ = 'undef'; }
  6771.     }
  6772.     if ($int_cmd) {
  6773.         print "For rule '$rule', running '\&$int_cmd( @int_args_for_printing )' ...\n";
  6774.         $return = &$int_cmd( @int_args );
  6775.     }
  6776.     elsif ($$Pext_cmd) {
  6777.         $return = &Run_subst() / 256;
  6778.     }
  6779.     else {
  6780.         warn "$My_name: Either a bug OR a configuration error:\n",
  6781.              "    No command provided for '$rule'\n";
  6782.         &traceback();
  6783.         $return = -1;
  6784.         $$Plast_result = 2;
  6785.         $$Plast_message = "Bug or configuration error; incorrect command type";
  6786.     }
  6787.     if ( $rule =~ /^biber/ ) {
  6788.         my @biber_source = ( );
  6789.         my $retcode = check_biber_log( $$Pbase, \@biber_source );
  6790.         foreach my $source ( @biber_source ) {
  6791.             print "  ===Source file '$source' for '$rule'\n"
  6792.                if ($diagnostics);
  6793.             rdb_ensure_file( $rule, $source );
  6794.         }
  6795.         if ($retcode == 5) {
  6796.         # Special treatment if sole missing file is bib file
  6797.         # I don't want to treat that as an error
  6798.             $return = 0;
  6799.             $$Plast_result = 200;
  6800.             $$Plast_message = "Could not find bib file for '$$Pbase'";
  6801.             push @warnings, "Bib file not found for '$$Pbase'";
  6802.         }
  6803.         elsif ($retcode == 6) {
  6804.            # Missing control file.  Need to remake it (if possible)
  6805.            # Don't treat missing bbl file as error.
  6806.            warn "$My_name: bibtex control file missing.  Since that can\n",
  6807.                 "   be recreated, I'll try to do so.\n";
  6808.            $return = -2;
  6809.            rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
  6810.         }
  6811.         elsif ($retcode == 4) {
  6812.             $$Plast_result = 2;
  6813.             $$Plast_message = "Could not find all biber source files for '$$Pbase'";
  6814.             push @warnings, "Not all biber source files found for '$$Pbase'";
  6815.         }
  6816.         elsif ($retcode == 3) {
  6817.             $$Plast_result = 2;
  6818.             $$Plast_message = "Could not open biber log file for '$$Pbase'";
  6819.             push @warnings, $$Plast_message;
  6820.         }
  6821.         elsif ($retcode == 2) {
  6822.             $$Plast_message = "Biber errors: See file '$$Pbase.blg'";
  6823.             push @warnings, $$Plast_message;
  6824.         }
  6825.         elsif ($retcode == 1) {
  6826.             push @warnings, "Biber warnings for '$$Pbase'";
  6827.         }
  6828.         elsif ($retcode == 10) {
  6829.             push @warnings, "Biber found no citations for '$$Pbase'";
  6830.             # Biber doesn't generate a bbl file in this situation.
  6831.             $return = -2;
  6832.         }
  6833.         elsif ($retcode == 11) {
  6834.             push @warnings, "Biber: malformed bcf file for '$$Pbase'.  IGNORE";
  6835.         if (!$silent) {
  6836.                warn "$My_name: biber found malformed bcf file for '$$Pbase'.\n",
  6837.                 "  I'll ignore error, and delete any bbl file.\n";
  6838.         }
  6839.         # Malformed bcf file is a downstream consequence, normally,
  6840.             # of an error in (pdf)latex run.  So this is not an error
  6841.         # condition in biber itself.
  6842.         # Current version of biber deletes bbl file.
  6843.         # Older versions (pre-2016) made an incorrect bbl file, which
  6844.             # tended to cause latex errors, and give a self-perpetuating error.
  6845.         # To be safe, ensure the bbl file doesn't exist.
  6846.         unlink $$Pdest;
  6847.         # The missing bbl file is now not an error:
  6848.             $return = -2;
  6849. # ??????? BCF
  6850. # Following is intended to work, but creates infinite loop
  6851. # in malformed bcf file situation under -pvc.
  6852. # since on each check for change in ANY file, pvc finds changed file
  6853. # Need to restrict pvc reruns to case of changed USER files
  6854. #       # To give good properties for (pdf)latex rule, it is best
  6855. #       # to have a valid bbl file that exists:
  6856. #       create_empty_file( $$Pdest );
  6857. #            $return = 0;
  6858.        
  6859.         }
  6860.     }
  6861.     if ( $rule =~ /^bibtex/ ) {
  6862.         my $retcode = check_bibtex_log($$Pbase);
  6863.         if ( ! -e $$Psource ) {
  6864.             $retcode = 10;
  6865.             rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
  6866.         }
  6867.         if ($retcode == 3) {
  6868.             $$Plast_result = 2;
  6869.             $$Plast_message = "Could not open bibtex log file for '$$Pbase'";
  6870.             push @warnings, $$Plast_message;
  6871.         }
  6872.         elsif ($retcode == 2) {
  6873.             $$Plast_message = "Bibtex errors: See file '$$Pbase.blg'";
  6874.             $failure = 1;
  6875.             push @warnings, $$Plast_message;
  6876.         }
  6877.         elsif ($retcode == 1) {
  6878.             push @warnings, "Bibtex warnings for '$$Pbase'";
  6879.         }
  6880.         elsif ($retcode == 10) {
  6881.             push @warnings, "Bibtex found no citations for '$$Pbase',\n",
  6882.                             "    or bibtex found a missing aux file\n";
  6883.             if (! -e $$Pdest ) {
  6884.                 warn "$My_name: Bibtex did not produce '$$Pdest'.  But that\n",
  6885.                      "     was because of missing files, so I will continue.\n";
  6886.                 $return = -2;
  6887.             }
  6888.             else {
  6889.                 $return = 0;
  6890.             }
  6891.         }
  6892.     }
  6893.  
  6894.     $updated = 1;
  6895.     if ($$Ptest_kind == 3) {
  6896.         # We are time-criterion first time only.  Now switch to
  6897.         # file-change criterion
  6898.         $$Ptest_kind = 1;
  6899.     }
  6900.     $$Pout_of_date = $$Pout_of_date_user = 0;
  6901.  
  6902.     if ( ($$Plast_result == 0) && ($return != 0) && ($return != -2) ) {
  6903.         $$Plast_result = 2;
  6904.         if ($$Plast_message eq '') {
  6905.             $$Plast_message = "Command for '$rule' gave return code $return";
  6906.         if ($rule =~ /^(pdf|lua|xe|)latex/) {
  6907.         $$Plast_message .= "\n      Refer to '$log_name' for details";
  6908.         }
  6909.             elsif ($rule =~ /^makeindex/) {
  6910.         $$Plast_message .= "\n      Refer to '${aux_dir1}${root_filename}.ilg' for details";
  6911.         }
  6912.         }
  6913.     }
  6914.     elsif ( $$Pdest && (! -e $$Pdest) && ($return != -2) ) {
  6915.         $$Plast_result = 1;
  6916.     }
  6917.     return $return;
  6918. }  # END rdb_run1
  6919.  
  6920. #-----------------
  6921.  
  6922. sub rdb_dummy_run1 {
  6923.     # Assumes contexts for: rule.
  6924.     # Update rule state as if the rule ran successfully,
  6925.     #    but don't run the rule.
  6926.     # Returns 0 (success code)
  6927.  
  6928.     # Source file data, by definition, correspond to the file state just before
  6929.     # the latest run, and the run_time to the time just before the run:
  6930.     &rdb_update_files;
  6931.     $$Prun_time = time();
  6932.     $$Pchanged = 0;       # No special changes in files
  6933.     $$Plast_result = 0;
  6934.     $$Plast_message = '';
  6935.  
  6936.     if ($$Ptest_kind == 3) {
  6937.         # We are time-criterion first time only.  Now switch to
  6938.         # file-change criterion
  6939.         $$Ptest_kind = 1;
  6940.     }
  6941.     $$Pout_of_date = $$Pout_of_date_user = 0;
  6942.  
  6943.     return 0;
  6944. }  # END rdb_dummy_run1
  6945.  
  6946. #-----------------
  6947.  
  6948. sub Run_subst {
  6949.     # Call: Run_subst( cmd, msg, options, source, dest, base )
  6950.     # Runs command with substitutions.
  6951.     # If an argument is omitted or undefined, it is replaced by a default:
  6952.     #    cmd is the command to execute
  6953.     #    msg is whether to print a message:
  6954.     #           0 for not, 1 according to $silent setting, 2 always
  6955.     #    options, source, dest, base: correspond to placeholders.
  6956.     # Substitutions:
  6957.     #    %S=source, %D=dest, %B=base, %R=root=base for latex, %O=options,
  6958.     #    %T=texfile, %Y=$aux_dir1, %Z=$out_dir1
  6959.     # This is a globally usable subroutine, and works in a rule context,
  6960.     #    and outside.
  6961.     # Defaults:
  6962.     #     cmd: $PPext_cmd if defined, else '';
  6963.     #     msg: 1
  6964.     #     options: ''
  6965.     #     source:  $$Psource if defined, else $texfile_name;
  6966.     #     dest:    $$Pdest if defined, else $view_file, else '';
  6967.     #     base:    $$Pbase if defined, else $root_filename;
  6968.  
  6969.     my ($ext_cmd, $msg, $options, $source, $dest, $base ) = @_;
  6970.  
  6971.     $ext_cmd ||= ( $Pext_cmd ? $$Pext_cmd : '' );
  6972.     $msg     =   ( defined $msg ? $msg : 1 );
  6973.     $options ||= '';
  6974.     $source  ||= ( $Psource ? $$Psource : $texfile_name );
  6975.     $dest    ||= ( $Pdest ? $$Pdest : ( $view_file || '' ) );
  6976.     $base    ||= ( $Pbase ? $$Pbase : $root_filename );
  6977.  
  6978.     if ( $ext_cmd eq '' ) {
  6979.          return 0;
  6980.     }
  6981.  
  6982.     #Set character to surround filenames:
  6983.     my $q = $quote_filenames ? '"' : '';
  6984.  
  6985.     my %subst = (
  6986.        '%O' => $options,
  6987.        '%R' => $q.$root_filename.$q,
  6988.        '%B' => $q.$base.$q,
  6989.        '%T' => $q.$texfile_name.$q,
  6990.        '%S' => $q.$source.$q,
  6991.        '%D' => $q.$dest.$q,
  6992.        '%Y' => $q.$aux_dir1.$q,
  6993.        '%Z' => $q.$out_dir1.$q,
  6994.        '%%' => '%'         # To allow literal %B, %R, etc, by %%B.
  6995.     );
  6996.     if ( ($^O eq "MSWin32" ) && $MSWin_back_slash ) {
  6997.         foreach ( '%R', '%B', '%T', '%S', '%D', '%Y', '%Z' ) {
  6998.             $subst{$_} =~ s(/)(\\)g;
  6999.         }
  7000.     }
  7001.  
  7002.     my @tokens = split /(%.)/, $ext_cmd;
  7003.     foreach (@tokens) {
  7004.         if (exists($subst{$_})) { $_ = $subst{$_}; }
  7005.     }
  7006.     $ext_cmd = join '', @tokens;
  7007.  
  7008.     my ($pid, $return) =
  7009.           ( ($msg == 0) || ( ($msg == 1) && $silent ) )
  7010.              ? &Run($ext_cmd)
  7011.              : &Run_msg($ext_cmd);
  7012.     return $return;
  7013. } #END Run_subst
  7014.  
  7015. #-----------------
  7016.  
  7017. sub rdb_primary_run {
  7018. #?? See multipass_run in previous version Aug 2007 for issues
  7019.     # Call: rdb_primary_run
  7020.     # Assumes contexts for: recursion, make, & rule.
  7021.     # Assumes (a) the rule is a primary,
  7022.     #         (b) a run has to be made,
  7023.     #         (c) source files have been made.
  7024.     # This routine carries out the run of the rule unconditionally,
  7025.     # and then parses log file etc.
  7026.     my $return = 0;
  7027.  
  7028.     if ( ! $filetime_offset_measured ) {
  7029.     $filetime_offset = get_filetime_offset( $aux_dir1."tmp" );
  7030.     if ( (abs($filetime_offset) > $filetime_offset_report_threshold)
  7031.              && ($diagnostics || ! $silent) )
  7032.         {
  7033.         warn "$My_name: I am working around an offset relative to my system time by\n",
  7034.                  "   $filetime_offset secs for file times in directory '$aux_dir1'.\n";
  7035.     }
  7036.     $filetime_offset_measured = 1;
  7037.     }
  7038.  
  7039.     my $return_latex = &rdb_run1;
  7040.     if (-e $$Pdest) { $missing_dvi_pdf = '';}
  7041.  
  7042.     ######### Analyze results of run:
  7043.     if ( ! -e $log_name ) {
  7044.         $failure = 1;
  7045.         $$Plast_result = 2;
  7046.         $$Plast_message = $failure_msg
  7047.            = "(Pdf)LaTeX failed to generate the expected log file '$log_name'";
  7048.         return -1;
  7049.     }
  7050.  
  7051.     if ($recorder) {
  7052.         # Handle problem that some version of (pdf)latex give fls files
  7053.         #    of name latex.fls or pdflatex.fls instead of $root_filename.fls.
  7054.         # Also that setting of -output-directory -aux-directory is not
  7055.         #    respected by (pdf)latex, at least in some versions.
  7056.         my $std_fls_file = "$aux_dir1$root_filename.fls";
  7057.         my @other_fls_names = ( );
  7058.         if ( $rule =~ /^pdflatex/ ) {
  7059.             push @other_fls_names, "pdflatex.fls";
  7060.         }
  7061.         else {
  7062.             push @other_fls_names, "latex.fls";
  7063.         }
  7064.         if ( $aux_dir1 ne '' ) {
  7065.            push @other_fls_names, "$root_filename.fls";
  7066.         }
  7067.         # Find the first non-standard fls file and copy it to the standard
  7068.         # place. But only do this if the file time is compatible with being
  7069.         # generated in the current run, as tested by the use of
  7070.         # test_gen_file; that avoids problems with fls files leftover from
  7071.         # earlier runs with other versions of latex.
  7072.         foreach my $cand (@other_fls_names) {
  7073.             if ( test_gen_file( $cand ) ) {
  7074.                 copy $cand, $std_fls_file;
  7075.                 last;
  7076.             }
  7077.         }
  7078.         if ( ! test_gen_file( $std_fls_file ) ) {
  7079.             warn "$My_name: fls file doesn't appear to have been made\n";
  7080.         }
  7081.     }
  7082.  
  7083.     # Find current set of source files:
  7084.     &rdb_set_latex_deps;
  7085.  
  7086.     # For each file of the kind made by epstopdf.sty during a run,
  7087.     #   if the file has changed during a run, then the new version of
  7088.     #   the file will have been read during the run.  Unlike the usual
  7089.     #   case, we will NOT need to redo the primary run because of the
  7090.     #   change of this file during the run.  Therefore set the file as
  7091.     #   up-to-date:
  7092.     rdb_do_files( sub { if ($$Pcorrect_after_primary) {&rdb_update1;} } );
  7093.  
  7094. #??    # There may be new source files, and the run may have caused
  7095. #??    # circular-dependency files to be changed.  And the regular
  7096. #??    # source files may have been updated during a lengthy run of
  7097. #??    # latex.  So redo the makes for sources of the current rule:
  7098. #??    my $submake_return = &rdb_submake;
  7099. #??    &rdb_clear_change_record;
  7100. #??    &rdb_flag_changes_here(0);
  7101. #??    if ($$Pout_of_date && !$silent) {
  7102. #??        &rdb_diagnose_changes( "Rule '$rule': " );
  7103. #??    }
  7104.  
  7105.     $updated = 1;    # Flag that some dependent file has been remade
  7106.  
  7107. #??    # Fix the state of the files as of now: this will solve the
  7108. #??    # problem of latex and pdflatex interfering with each other,
  7109. #??    # at the expense of some non-optimality
  7110. #??    #??  Check this is correct:
  7111. #??    &rdb_update_files;
  7112.  
  7113.     if ( $diagnostics ) {
  7114.         print "$My_name: Rules after run: \n";
  7115.         rdb_show();
  7116.     }
  7117.  
  7118.     $return = $return_latex;
  7119.  
  7120. # ???? Is the following needed?
  7121.     if ($return_latex && $$Pout_of_date_user) {
  7122.        print "Error in (pdf)LaTeX, but change of user file(s), ",
  7123.              "so ignore error & provoke rerun\n"
  7124.           if (! $silent);
  7125.        $return = 0;
  7126.     }
  7127.     # Summarize issues that may have escaped notice:
  7128.     my @warnings = ();
  7129.     if ($bad_reference) {
  7130.         push @warnings, "Latex failed to resolve $bad_reference reference(s)";
  7131.     }
  7132.     if ($mult_defined) {
  7133.         push @warnings, "Latex found $mult_defined multiply defined reference(s)";
  7134.     }
  7135.     if ($bad_citation) {
  7136.         push @warnings, "Latex failed to resolve $bad_citation citation(s)";
  7137.     }
  7138.     if ($#warnings > -1) {
  7139.         show_array( "$My_name: Summary of warnings:", @warnings );
  7140.     }
  7141.     return $return;
  7142. } #END rdb_primary_run
  7143.  
  7144. #************************************************************
  7145.  
  7146. sub rdb_clear_change_record {
  7147.     # Initialize diagnostics for reasons for running rule.
  7148.     @changed = ();
  7149.     @disappeared = ();
  7150.     @no_dest = ();          # We are not now using this
  7151.     @rules_never_run = ();
  7152.     @rules_to_apply = ();   # This is used in recursive application
  7153.                             # of rdb_flag_changes_here, to list
  7154.                             # rules that were out-of-date for some reason.
  7155. } #END rdb_clear_change_record
  7156.  
  7157. #************************************************************
  7158.  
  7159. sub rdb_flag_changes_here {
  7160.     # Flag changes in current rule.  
  7161.     # Assumes rule context.
  7162.     # Usage: rdb_flag_changes_here( ignore_run_time )
  7163.     # Argument: if true then fdb_get shouldn't do runtime test
  7164.     #             for recalculation of md5
  7165.  
  7166.     local $ignore_run_time = $_[0];
  7167.     if ( ! defined $ignore_run_time ) { $ignore_run_time = 0; }
  7168.  
  7169.     $$Pcheck_time = time();
  7170.  
  7171.     local $dest_mtime = 0;
  7172.     $dest_mtime = get_mtime($$Pdest) if ($$Pdest);
  7173.     rdb_do_files( \&rdb_file_change1);
  7174.     if ($$Pout_of_date) {
  7175.         push @rules_to_apply, $rule;
  7176.     }
  7177. #??     print "======== flag: $rule $$Pout_of_date ==========\n";
  7178. } #END rdb_flag_changes_here
  7179.  
  7180. #************************************************************
  7181.  
  7182. sub rdb_file_change1 {
  7183.     # Call: &rdb_file_change1
  7184.     # Assumes rule and file context.  Assumes $dest_mtime set.
  7185.     # Flag whether $file in $rule has changed or disappeared.
  7186.     # Set rule's make flag if there's a change.
  7187.  
  7188.     my $check_time_argument = 0;
  7189.     if (! $ignore_run_time ) {
  7190.         $check_time_argument = max( $$Pcheck_time, $$Prun_time );
  7191.     }
  7192.     my ($new_time, $new_size, $new_md5) = fdb_get($file, $check_time_argument );
  7193.     my $ext_no_period = ext_no_period( $file );
  7194.     if ( ($new_size < 0) && ($$Psize >= 0) ) {
  7195.         # print "Disappeared '$file' in '$rule'\n";
  7196.         push @disappeared, $file;
  7197.         # No reaction is good.  
  7198.         #$$Pout_of_date = 1;
  7199.         # ??? 1 Sep. 2008: I do NOT think so, for cusdep no-file-exists issue
  7200.         # ??? 30 Sep 2008: I think I have this fixed.  There were other changes
  7201.         #  needed.  No-change-flagged is correct.  The array @disappeared flags
  7202.         #  files that have disappeared, if I need to know.  But having a source
  7203.         #  file disappear is not a reason for a remake unless I know how to
  7204.         #  make the file.  If the file is a destination of a rule, that rule
  7205.         #  will be rerun.  It may be that the user is changing another source
  7206.         #  in such a way that the disappeared file won't be needed.  Before the
  7207.         #  change is applied we get a superfluous infinite loop.
  7208.         return;
  7209.     }
  7210.     if ( ($new_size < 0) && ($$Psize < 0) ) {
  7211.         return;
  7212.     }
  7213.     # Primarily use md5 signature to determine whether file contents have
  7214.     #   changed.
  7215.     # Backup by file size change, but only in the case where there is
  7216.     #   no pattern of lines to ignore in testing for a change
  7217.     if ( ($new_md5 ne $$Pmd5)
  7218.          || (
  7219.               (! exists $hash_calc_ignore_pattern{$ext_no_period})
  7220.               && ($new_size != $$Psize)  
  7221.             )
  7222.        ) {
  7223. #print "========= CHANGED: '$file' from '$$Pfrom_rule'\n";
  7224.         push @changed, $file;
  7225.         $$Pout_of_date = 1;
  7226.         if ( ! exists $generated_exts_all{$ext_no_period} ) {
  7227.             $$Pout_of_date_user = 1;
  7228.         }
  7229.     }
  7230.     elsif ( $new_time != $$Ptime ) {
  7231.         $$Ptime = $new_time;
  7232.     }
  7233.     if ( ( ($$Ptest_kind == 2) || ($$Ptest_kind == 3) )
  7234.          && (! exists $generated_exts_all{$ext_no_period} )
  7235.          && ( $new_time > $dest_mtime )
  7236.         ) {
  7237.             push @changed, $file;
  7238.             $$Pout_of_date = $$Pout_of_date_user = 1;
  7239.     }
  7240. } #END rdb_file_change1
  7241.  
  7242. #************************************************************
  7243.  
  7244. sub rdb_new_changes {
  7245.     &rdb_clear_change_record;
  7246.     rdb_recurse( [@_], sub{ &rdb_flag_changes_here(1); } );
  7247.     return ($#changed >= 0) || ($#no_dest >= 0) || ($#rules_to_apply >= 0);
  7248. } #END rdb_new_changes
  7249.  
  7250. #************************************************************
  7251.  
  7252. sub rdb_diagnose_changes {
  7253.     # Call: rdb_diagnose_changes or rdb_diagnose_changes( heading )
  7254.     # List changes on STDERR
  7255.     # Precede the message by the optional heading, else by "$My_name: "
  7256.     my $heading = defined($_[0]) ?   $_[0]  :  "$My_name: ";
  7257.  
  7258.     if ($#rules_never_run >= 0) {
  7259.         warn "${heading}Rules & subrules not known to be previously run:\n";
  7260.         foreach (@rules_never_run) { warn "   $_\n"; }
  7261.     }
  7262.     if ( ($#changed >= 0) || ($#disappeared >= 0) || ($#no_dest >= 0) ) {
  7263.         warn "${heading}File changes, etc:\n";
  7264.         if ( $#changed >= 0 ) {
  7265.             warn "   Changed files, or newly in use since previous run(s):\n";
  7266.             foreach (uniqs(@changed)) { warn "      '$_'\n"; }
  7267.         }
  7268.         if ( $#disappeared >= 0 ) {
  7269.             warn "   No-longer-existing files:\n";
  7270.             foreach (uniqs(@disappeared)) { warn "      '$_'\n"; }
  7271.         }
  7272.         if ( $#no_dest >= 0 ) {
  7273.             warn "   Non-existent destination files:\n";
  7274.             foreach (uniqs(@no_dest)) { warn "      '$_'\n"; }
  7275.         }
  7276.     }
  7277.     elsif ($#rules_to_apply >=0) {
  7278.          warn "${heading}The following rules & subrules became out-of-date:\n";
  7279.          foreach (@rules_to_apply) { warn "      '$_'\n"; }
  7280.     }
  7281.     else {
  7282.         warn "${heading}No file changes\n";
  7283.     }
  7284. }     #END rdb_diagnose_changes
  7285.  
  7286.  
  7287. #************************************************************
  7288. #************************************************************
  7289. #************************************************************
  7290. #************************************************************
  7291.  
  7292. #************************************************************
  7293. #************************************************************
  7294. #************************************************************
  7295. #************************************************************
  7296.  
  7297. # Routines for convenient looping and recursion through rule database
  7298. # ================= NEW VERSION ================
  7299.  
  7300. # There are several places where we need to loop through or recurse
  7301. # through rules and files.  This tends to involve repeated, tedious
  7302. # and error-prone coding of much book-keeping detail.  In particular,
  7303. # working on files and rules needs access to the variables involved,
  7304. # which either involves direct access to the elements of the database,
  7305. # and consequent fragility against changes and upgrades in the
  7306. # database structure, or involves lots of routines for reading and
  7307. # writing data in the database, then with lots of repetitious
  7308. # house-keeping code.
  7309. #
  7310. # The routines below provide a solution.  Looping and recursion
  7311. # through the database are provided by a set of basic routines where
  7312. # each necessary kind of looping and iteration is coded once.  The
  7313. # actual actions are provided as references to action subroutines.
  7314. # (These can be either actual references, as in \&routine, or
  7315. # anonymous subroutines, as in sub{...}, or aas a zero value 0 or an
  7316. # omitted argument, to indicate that no action is to be performed.)
  7317. #
  7318. # When the action subroutine(s) are actually called, a context for the
  7319. # rule and/or file (as appropriate) is given by setting named
  7320. ## NEW ??
  7321. # variables to REFERENCES to the relevant data values.  These can be
  7322. # used to retrieve and set the data values.  As a convention,
  7323. # references to scalars are given by variables named start with "$P",
  7324. # as in "$Pdest", while references to arrays start with "$PA", as in
  7325. # "$PAint_cmd", and references to hashes with "$PH", as in "$PHsource".
  7326. # After the action subroutine has finished, checks for data
  7327. # consistency may be made.
  7328. ## ??? OLD
  7329. # variables to the relevant data values.  After the action subroutine
  7330. # has finished, the database is updated with the values of these named
  7331. # variables, with any necessary consistency checks.  Thus the action
  7332. # subroutines can act on sensibly named variables without needed to
  7333. # know the database structure.  
  7334. #
  7335. # The only routines that actually use the database structure and need
  7336. # to be changed if that is changed are:  (a) the routines rdb_one_rule
  7337. # and rdb_one_file that implement the calling of the action subroutines,
  7338. # (b) routines for creation of single rules and file items, and (c) to
  7339. # a lesser extent, the routine for destroying a file item.  
  7340. #
  7341. # Note that no routine is provided for destroying a rule.  During a
  7342. # run, a rule, with its source files, may become inaccessible or
  7343. # unused.  This happens dynamically, depending on the dependencies
  7344. # caused by changes in the source file or by error conditions that
  7345. # cause the computation of dependencies, particular of latex files, to
  7346. # become wrong.  In that situation the files certainly come and go in
  7347. # the database, but subsidiary rules, with their content information
  7348. # on their source files, need to be retained so that their use can be
  7349. # reinstated later depending on dynamic changes in other files.
  7350. #
  7351. # However, there is a potential memory leak unless some pruning is
  7352. # done in what is written to the fdb file.  (Probably only accessible
  7353. # rules and those for which source files exist.  Other cases have no
  7354. # relevant information that needs to be preserved between runs.)
  7355.  
  7356. #
  7357. #
  7358.  
  7359.  
  7360. #************************************************************
  7361.  
  7362. # First the top level routines for recursion and iteration
  7363.  
  7364. #************************************************************
  7365.  
  7366. sub rdb_recurse {
  7367.     # Call: rdb_recurse( rule | [ rules],
  7368.     #                    \&rule_act1, \&file_act1, \&file_act2,
  7369.     #                    \&rule_act2 )
  7370.     # The actions are pointers to subroutines, and may be null (0, or
  7371.     # undefined) to indicate no action to be applied.
  7372.     # Recursively acts on the given rules and all ancestors:
  7373.     #   foreach rule found:
  7374.     #       apply rule_act1
  7375.     #       loop through its files:
  7376.     #          apply file_act1
  7377.     #          act on its ancestor rule, if any
  7378.     #          apply file_act2
  7379.     #       apply rule_act2
  7380.     # Guards against loops.  
  7381.     # Access to the rule and file data by local variables, only
  7382.     #   for getting and setting.
  7383.  
  7384.     # This routine sets a context for anything recursive, with @heads,
  7385.     # %visited  and $depth being set as local variables.
  7386.  
  7387.     local @heads = ();
  7388.     my $rules = shift;
  7389.  
  7390.     # Distinguish between single rule (a string) and a reference to an
  7391.     # array of rules:
  7392.     if ( ref $rules eq 'ARRAY' ) { @heads = @$rules; }
  7393.     else { @heads = ( $rules ); }
  7394.  
  7395.     # Keep a list of visited rules, used to block loops in recursion:
  7396.     local %visited = ();
  7397.     local $depth = 0;
  7398.  
  7399.     foreach $rule ( @heads ) { rdb_recurse_rule( $rule, @_ ); }
  7400.  
  7401. } #END rdb_recurse
  7402.  
  7403. #************************************************************
  7404.  
  7405. sub rdb_for_all {
  7406.     # Call: rdb_for_all( \&rule_act1, \&file_act, \&rule_act2 )
  7407.     # Loops through all rules and their source files, using the
  7408.     #   specified set of actions, which are pointers to subroutines.
  7409.     # Sorts rules alphabetically.
  7410.     # See rdb_for_some for details.
  7411.     rdb_for_some( [ sort keys %rule_db ], @_);
  7412. } #END rdb_for_all
  7413.  
  7414. #************************************************************
  7415.  
  7416. sub rdb_for_some {
  7417.     # Call: rdb_for_some( rule | [ rules],
  7418.     #                    \&rule_act1, \&file_act, \&rule_act2)
  7419.     # Actions can be zero, and rules at tail of argument list can be
  7420.     # omitted.  E.g. rdb_for_some( rule, 0, \&file_act ).  
  7421.     # Anonymous subroutines can be used, e.g., rdb_for_some( rule, sub{...} ).  
  7422.     #
  7423.     # Loops through rules and their source files, using the
  7424.     # specified set of rules:
  7425.     #   foreach rule:
  7426.     #       apply rule_act1
  7427.     #       loop through its files:
  7428.     #          apply file_act
  7429.     #       apply rule_act2
  7430.     #
  7431.     # Rule data and file data are made available in local variables
  7432.     # for access by the subroutines.
  7433.  
  7434.     local @heads = ();
  7435.     my $rules = shift;
  7436.     # Distinguish between single rule (a string) and a reference to an
  7437.     # array of rules:
  7438.     if ( ref $rules eq 'ARRAY' ) { @heads = @$rules; }
  7439.     else { @heads = ( $rules ); }
  7440.  
  7441.     foreach $rule ( @heads ) {
  7442.         # $rule is implicitly local
  7443.         &rdb_one_rule( $rule, @_ );
  7444.     }
  7445. }  #END rdb_for_some
  7446.  
  7447. #************************************************************
  7448.  
  7449. sub rdb_for_one_file {
  7450.     my $rule = shift;
  7451.     # Avoid name collisions with general recursion and iteraction routines:
  7452.     local $file1 = shift;
  7453.     local $action1 = shift;
  7454.     rdb_for_some( $rule, sub{rdb_one_file($file1,$action1)} );
  7455. } #END rdb_for_one_file
  7456.  
  7457.  
  7458. #************************************************************
  7459.  
  7460. #   Routines for inner part of recursion and iterations
  7461.  
  7462. #************************************************************
  7463.  
  7464. sub rdb_recurse_rule {
  7465.     # Call: rdb_recurse_rule($rule, \&rule_act1, \&file_act1, \&file_act2,
  7466.     #                    \&rule_act2 )
  7467.     # to do the work for one rule, recurisvely called from_rules for
  7468.     # the sources of the rules.
  7469.     # Assumes recursion context, i.e. that %visited, @heads, $depth.
  7470.     # We are overriding actions:
  7471.     my ($rule, $rule_act1, $new_file_act1, $new_file_act2, $rule_act2)
  7472.         = @_;
  7473.     # and must propagate the file actions:
  7474.     local $file_act1 = $new_file_act1;
  7475.     local $file_act2 = $new_file_act2;
  7476.     # Prevent loops:
  7477.     if ( (! $rule) || exists $visited{$rule} ) { return; }
  7478.     $visited{$rule} = 1;
  7479.     # Recursion depth
  7480.     $depth++;
  7481.     # We may need to repeat actions on dependent rules, without being
  7482.     # blocked by the test on visited files.  So save %visited:
  7483.     # NOT CURRENTLY USED!!    local %visited_at_rule_start = %visited;
  7484.     # At end, the last value set for %visited wins.
  7485.     rdb_one_rule( $rule, $rule_act1, \&rdb_recurse_file, $rule_act2 );
  7486.     $depth--;
  7487.  } #END rdb_recurse_rule
  7488.  
  7489. #************************************************************
  7490.  
  7491. sub rdb_recurse_file {
  7492.     # Call: rdb_recurse_file to do the work for one file.
  7493.     # This has no arguments, since it is used as an action subroutine,
  7494.     # passed as a reference in calls in higher-level subroutine.
  7495.     # Assumes contexts set for: Recursion, rule, and file
  7496.     &$file_act1 if $file_act1;
  7497.     rdb_recurse_rule( $$Pfrom_rule, $rule_act1, $file_act1, $file_act2,
  7498.                       $rule_act2 )
  7499.         if $$Pfrom_rule;
  7500.     &$file_act2 if $file_act2;
  7501. } #END rdb_recurse_file
  7502.  
  7503. #************************************************************
  7504.  
  7505. sub rdb_do_files {
  7506.     # Assumes rule context, including $PHsource.
  7507.     # Applies an action to all the source files of the rule.
  7508.     local $file_act = shift;
  7509.     my @file_list = sort keys %$PHsource;
  7510.     foreach my $file ( @file_list ){
  7511.         rdb_one_file( $file, $file_act );
  7512.     }
  7513. } #END rdb_do_files
  7514.  
  7515. #************************************************************
  7516.  
  7517. # Routines for action on one rule and one file.  These are the main
  7518. # places (in addition to creation and destruction routines for rules
  7519. # and files) where the database structure is accessed.
  7520.  
  7521. #************************************************************
  7522.  
  7523. sub rdb_one_rule {
  7524.     # Call: rdb_one_rule( $rule, $rule_act1, $file_act, $rule_act2 )
  7525.     # Sets context for rule and carries out the actions.
  7526. #===== Accesses rule part of database structure =======
  7527.  
  7528.     local ( $rule, $rule_act1, $file_act, $rule_act2 ) = @_;
  7529. #??    &R1;
  7530.     if ( (! $rule) || ! rdb_rule_exists($rule) ) { return; }
  7531.  
  7532.     local ( $PArule_data, $PHsource, $PHdest ) = @{$rule_db{$rule}};
  7533.     local ($Pcmd_type, $Pext_cmd, $PAint_cmd, $Ptest_kind,
  7534.            $Psource, $Pdest, $Pbase,
  7535.            $Pout_of_date, $Pout_of_date_user, $Prun_time, $Pcheck_time,
  7536.            $Pchanged,
  7537.            $Plast_result, $Plast_message, $PA_extra_generated )
  7538.         = Parray( $PArule_data );
  7539.  
  7540.     &$rule_act1 if $rule_act1;
  7541.     &rdb_do_files( $file_act ) if $file_act;
  7542.     &$rule_act2 if $rule_act2;
  7543. #??    &R2;
  7544. } #END rdb_one_rule
  7545.  
  7546. #************************************************************
  7547.  
  7548. sub rdb_one_file {
  7549.     # Call: rdb_one_file($file, $file_act)
  7550.     # Sets context for file and carries out the action.
  7551.     # Assumes $rule context set.
  7552. #===== Accesses file part of database structure =======
  7553.     local ($file, $file_act) = @_;
  7554. #??    &F1;
  7555.     if ( (!$file) ||(!exists ${$PHsource}{$file}) ) { return; }
  7556.     local $PAfile_data = ${$PHsource}{$file};
  7557.     local ($Ptime, $Psize, $Pmd5, $Pfrom_rule, $Pcorrect_after_primary )
  7558.           = Parray( $PAfile_data );
  7559.     &$file_act() if $file_act;
  7560.     if ( ! rdb_rule_exists( $$Pfrom_rule ) ) {
  7561.         $$Pfrom_rule = '';
  7562.     }
  7563. #??    &F2;
  7564. } #END rdb_one_file
  7565.  
  7566. #************************************************************
  7567.  
  7568. # Routines for creation of rules and file items, and for removing file
  7569. # items.
  7570.  
  7571. #************************************************************
  7572.  
  7573. sub rdb_remove_rule {
  7574.     # rdb_remove_rule( rule, ...  )
  7575.     foreach my $key (@_) {
  7576.        delete $rule_db{$key};
  7577.     }
  7578. }
  7579.  
  7580. #************************************************************
  7581.  
  7582. sub rdb_create_rule {
  7583.     # rdb_create_rule( rule, command_type, ext_cmd, int_cmd, test_kind,
  7584.     #                  source, dest, base,
  7585.     #                  needs_making, run_time, check_time, set_file_not_exists,
  7586.     #                  ref_to_array_of_specs_of_extra_generated_files )
  7587.     # int_cmd is either a string naming a perl subroutine or it is a
  7588.     # reference to an array containing the subroutine name and its
  7589.     # arguments.
  7590.     # Makes rule.  Error if it already exists.
  7591.     # Omitted arguments: replaced by 0 or '' as needed.    
  7592. # ==== Sets rule data ====
  7593.     my ( $rule, $cmd_type, $ext_cmd, $PAint_cmd, $test_kind,
  7594.          $source, $dest, $base,
  7595.          $needs_making, $run_time, $check_time, $set_file_not_exists, $extra_gen ) = @_;
  7596.     my $changed = 0;
  7597.  
  7598.     # Set defaults, and normalize parameters:
  7599.     foreach ( $cmd_type, $ext_cmd, $PAint_cmd, $source, $dest, $base,
  7600.               $set_file_not_exists ) {
  7601.         if (! defined $_) { $_ = ''; }
  7602.     }
  7603.     foreach ( $needs_making, $run_time, $check_time, $test_kind ) {
  7604.         if (! defined $_) { $_ = 0; }
  7605.     }
  7606.     if (!defined $test_kind) {
  7607.         # Default to test on file change
  7608.         $test_kind = 1;
  7609.     }
  7610.     if ( ref( $PAint_cmd ) eq '' ) {
  7611.         #  It is a single command.  Convert to array reference:
  7612.         $PAint_cmd = [ $PAint_cmd ];
  7613.     }
  7614.     else {
  7615.         # COPY the referenced array:
  7616.         $PAint_cmd = [ @$PAint_cmd ];
  7617.     }
  7618.     my $PA_extra_gen = [];
  7619.     if ($extra_gen) {
  7620.         @$PA_extra_gen = @$extra_gen;
  7621.     }
  7622.     $rule_db{$rule} =
  7623.         [  [$cmd_type, $ext_cmd, $PAint_cmd, $test_kind,
  7624.             $source, $dest, $base,
  7625.             $needs_making, 0, $run_time, $check_time, $changed,
  7626.             -1, '', $PA_extra_gen ],
  7627.            {},
  7628.            {}
  7629.         ];
  7630.     if ($source) {
  7631.        rdb_ensure_file( $rule, $source, undef, $set_file_not_exists );  
  7632.     }
  7633.     rdb_one_rule( $rule, \&rdb_initialize_generated );
  7634. } #END rdb_create_rule
  7635.  
  7636. #************************************************************
  7637.  
  7638. sub rdb_initialize_generated {
  7639. # Assume rule context.
  7640. # Initialize hash of generated files
  7641.     %$PHdest = ();
  7642.     if ($$Pdest) { rdb_add_generated($$Pdest); }
  7643.     foreach (@$PA_extra_generated) {
  7644.         rdb_add_generated($_);
  7645.     }
  7646. } #END rdb_initialize_generated
  7647.  
  7648. #************************************************************
  7649.  
  7650. sub rdb_add_generated {
  7651. # Assume rule context.
  7652. # Add arguments to hash of generated files
  7653.     foreach (@_) {
  7654.         $$PHdest{$_} = 1;
  7655.     }
  7656. } #END rdb_add_generated
  7657.  
  7658. #************************************************************
  7659.  
  7660. sub rdb_ensure_file {
  7661.     # rdb_ensure_file( rule, file[, fromrule[, set_not_exists]] )
  7662.     # Ensures the source file item exists in the given rule.
  7663.     # Then if the fromrule is specified, set it for the file item.
  7664.     # If the item is created, then:
  7665.     #    (a) by default initialize it to current file state.
  7666.     #    (b) but if the fourth argument, set_not_exists, is true,
  7667.     #        initialize the item as if the file does not exist.
  7668.     #        This case is typically used when the log file for a run
  7669.     #        of latex/pdflatex claims that the file was non-existent
  7670.     #        at the beginning of a run.
  7671. #============ rule and file data set here ======================================
  7672.     my $rule = shift;
  7673.     local ( $new_file, $new_from_rule, $set_not_exists ) = @_;
  7674.     if ( ! rdb_rule_exists( $rule ) ) {
  7675.         die_trace( "$My_name: BUG in rdb_ensure_file: non-existent rule '$rule'" );
  7676.     }
  7677.     if ( ! defined $new_file ) {
  7678.         die_trace( "$My_name: BUG in rdb_ensure_file: undefined file for '$rule'" );
  7679.     }
  7680.     if ( ! defined $set_not_exists ) { $set_not_exists = 0; }
  7681.     rdb_one_rule( $rule,
  7682.                   sub{
  7683.                       if (! exists ${$PHsource}{$new_file} ) {
  7684.                           if ( $set_not_exists ) {
  7685.                               ${$PHsource}{$new_file} = [0, -1, 0, '', 0];
  7686.                           }
  7687.                           else {
  7688.                               ${$PHsource}{$new_file}
  7689.                               = [fdb_get($new_file, $$Prun_time), '', 0];
  7690.                           }
  7691.                       }
  7692.                   }
  7693.     );
  7694.     if (defined $new_from_rule ) {
  7695.         rdb_for_one_file( $rule, $new_file, sub{ $$Pfrom_rule = $new_from_rule; });
  7696.     }
  7697. } #END rdb_ensure_file
  7698.  
  7699. #************************************************************
  7700.  
  7701. sub rdb_remove_files {
  7702.     # rdb_remove_file( rule, file, ... )
  7703.     # Removes file(s) for the rule.  
  7704.     my $rule = shift;
  7705.     if (!$rule) { return; }
  7706.     local @files = @_;
  7707.     rdb_one_rule( $rule,
  7708.                   sub{ foreach (@files) { delete ${$PHsource}{$_}; }  }
  7709.     );
  7710. } #END rdb_remove_files
  7711.  
  7712. #************************************************************
  7713.  
  7714. sub rdb_list_source {
  7715.     # rdb_list_source( rule )
  7716.     # Return array of source files for rule.
  7717.     my $rule = shift;
  7718.     my @files = ();
  7719.     rdb_one_rule( $rule,
  7720.                   sub{ @files = keys %$PHsource; }
  7721.     );
  7722.     return @files;
  7723. } #END rdb_list_source
  7724.  
  7725. #************************************************************
  7726.  
  7727. sub rdb_set_source {
  7728.     # rdb_set_source( rule, file, ... )
  7729.     my $rule = shift;
  7730.     if (!$rule) { return; }
  7731.     my %files = ();
  7732.     foreach (@_) {
  7733.     rdb_ensure_file( $rule, $_ );
  7734.     $files{$_} = 1;
  7735.     }
  7736.     foreach ( rdb_list_source($rule) ) {
  7737.         if ( ! exists $files{$_} ) { rdb_remove_files( $rule, $_ ); }
  7738.     }    
  7739.     return;
  7740. } #END rdb_list_source
  7741.  
  7742. #************************************************************
  7743.  
  7744. sub rdb_rule_exists {
  7745.     # Call rdb_rule_exists($rule): Returns whether rule exists.
  7746.     my $rule = shift;
  7747.     if (! $rule ) { return 0; }
  7748.     return exists $rule_db{$rule};
  7749. } #END rdb_rule_exists
  7750.  
  7751. #************************************************************
  7752.  
  7753. sub rdb_file_exists {
  7754.     # Call rdb_file_exists($rule, $file):
  7755.     # Returns whether source file item in rule exists.
  7756.     local ( $rule, $file ) = @_;
  7757.     local $exists = 0;
  7758.     rdb_one_rule( $rule,
  7759.                   sub{ $exists =  exists( ${$PHsource}{$file} ) ? 1:0; }
  7760.                 );
  7761.     return $exists;
  7762. } #END rdb_file_exists
  7763.  
  7764. #************************************************************
  7765.  
  7766. sub rdb_update_gen_files {
  7767.     # Assumes rule context.  Update source files of rule to current state.
  7768.     rdb_do_files(
  7769.         sub{
  7770.             if ( exists $generated_exts_all{ ext_no_period($file) } ) {&rdb_update1;}
  7771.         }
  7772.     );
  7773. } #END rdb_update_gen_files
  7774.  
  7775. #************************************************************
  7776.  
  7777. sub rdb_update_files {
  7778.     # Call: rdb_update_files
  7779.     # Assumes rule context.  Update source files of rule to current state.
  7780.     rdb_do_files( \&rdb_update1 );
  7781. }
  7782.  
  7783. #************************************************************
  7784.  
  7785. sub rdb_update1 {
  7786.     # Call: rdb_update1.  
  7787.     # Assumes file context.  Updates file data to correspond to
  7788.     # current file state on disk
  7789.     ($$Ptime, $$Psize, $$Pmd5) = fdb_get($file);
  7790. }
  7791.  
  7792. #************************************************************
  7793.  
  7794. sub rdb_set_file1 {
  7795.     # Call: fdb_file1(rule, file, new_time, new_size, new_md5)
  7796.     # Sets file time, size and md5.
  7797.     my $rule = shift;
  7798.     my $file = shift;
  7799.     local @new_file_data = @_;
  7800.     rdb_for_one_file( $rule, $file, sub{ ($$Ptime,$$Psize,$$Pmd5)=@new_file_data; } );
  7801. }
  7802.  
  7803. #************************************************************
  7804.  
  7805. sub rdb_dummy_file {
  7806.     # Returns file data for non-existent file
  7807. # ==== Uses rule_db structure ====
  7808.     return (0, -1, 0, '');
  7809. }
  7810.  
  7811. #************************************************************
  7812. #************************************************************
  7813.  
  7814. # Predefined subroutines for custom dependency
  7815.  
  7816. sub cus_dep_delete_dest {
  7817.     # This subroutine is used for situations like epstopdf.sty, when
  7818.     #   the destination (target) of the custom dependency invoking
  7819.     #   this subroutine will be made by the primary run provided the
  7820.     #   file (destination of the custom dependency, source of the
  7821.     #   primary run) doesn't exist.
  7822.     # It is assumed that the resulting file will be read by the
  7823.     #   primary run.
  7824.  
  7825.     # Remove the destination file, to indicate it needs to be remade:
  7826.     unlink_or_move( $$Pdest );
  7827.     # Arrange that the non-existent destination file is not treated as
  7828.     #   an error.  The variable changed here is a bit misnamed.
  7829.     $$Pchanged = 1;
  7830.     # Ensure a primary run is done
  7831.     &cus_dep_require_primary_run;
  7832.     # Return success:
  7833.     return 0;
  7834. }
  7835.  
  7836. #************************************************************
  7837.  
  7838. sub cus_dep_require_primary_run {
  7839.     # This subroutine is used for situations like epstopdf.sty, when
  7840.     #   the destination (target) of the custom dependency invoking
  7841.     #   this subroutine will be made by the primary run provided the
  7842.     #   file (destination of the custom dependency, source of the
  7843.     #   primary run) doesn't exist.
  7844.     # It is assumed that the resulting file will be read by the
  7845.     #   primary run.
  7846.  
  7847.     local $cus_dep_target = $$Pdest;
  7848.     # Loop over all rules and source files:
  7849.     rdb_for_all( 0,
  7850.                  sub { if ($file eq $cus_dep_target) {
  7851.                             $$Pout_of_date = 1;
  7852.                             $$Pcorrect_after_primary = 1;
  7853.                        }
  7854.                      }
  7855.                );
  7856.     # Return success:
  7857.     return 0;
  7858. }
  7859.  
  7860.  
  7861. #************************************************************
  7862. #************************************************************
  7863. #************************************************************
  7864. #
  7865. #      UTILITIES:
  7866. #
  7867.  
  7868. #************************************************************
  7869. # Miscellaneous
  7870.  
  7871. sub show_array {
  7872. # For use in diagnostics and debugging.
  7873. #  On stderr, print line with $_[0] = label.  
  7874. #  Then print rest of @_, one item per line preceeded by some space
  7875.     warn "$_[0]\n";
  7876.     shift;
  7877.     if ($#_ >= 0) {  foreach (@_){ warn "  $_\n";} }
  7878.     else { warn "  NONE\n"; }
  7879. }
  7880.  
  7881. #************************************************************
  7882.  
  7883. sub Parray {
  7884.     # Call: Parray( \@A )
  7885.     # Returns array of references to the elements of @A
  7886.     # But if an element of @A is already a reference, the
  7887.     # reference will be returned in the output array, not a
  7888.     # reference to the reference.
  7889.     my $PA = shift;
  7890.     my @P = (undef) x (1+$#$PA);
  7891.     foreach my $i (0..$#$PA) {
  7892.         $P[$i] = (ref $$PA[$i]) ? ($$PA[$i]) : (\$$PA[$i]);
  7893.       }
  7894.     return @P;
  7895. }
  7896.  
  7897. #************************************************************
  7898.  
  7899. sub glob_list1 {
  7900.     # Glob a collection of filenames.  
  7901.     # But no sorting or elimination of duplicates
  7902.     # Usage: e.g., @globbed = glob_list1(string, ...);
  7903.     # Since perl's glob appears to use space as separator, I'll do a special check
  7904.     # for existence of non-globbed file (assumed to be tex like)
  7905.  
  7906.     my @globbed = ();
  7907.     foreach my $file_spec (@_) {
  7908.         # Problem, when the PATTERN contains spaces, the space(s) are
  7909.         # treated as pattern separaters.
  7910.         # Solution: I now the glob from use File::Glob.
  7911.         # The following hack avoids issues with glob in the case that a file exists
  7912.         # with the specified name (possibly with extension .tex):
  7913.         if ( -e $file_spec || -e "$file_spec.tex" ) {
  7914.            # Non-globbed file exists, return the file_spec.
  7915.            # Return $file_spec only because this is not a file-finding subroutine, but
  7916.            #   only a globber
  7917.            push @globbed, $file_spec;
  7918.         }
  7919.         else {
  7920.             push @globbed, my_glob( "$file_spec" );
  7921.         }
  7922.     }
  7923.     return @globbed;
  7924. } #END glob_list1
  7925.  
  7926. #************************************************************
  7927. # Miscellaneous
  7928.  
  7929. sub prefix {
  7930.    #Usage: prefix( string, prefix );
  7931.    #Return string with prefix inserted at the front of each line
  7932.    my @line = split( /\n/, $_[0] );
  7933.    my $prefix = $_[1];
  7934.    for (my $i = 0; $i <= $#line; $i++ ) {
  7935.        $line[$i] = $prefix.$line[$i]."\n";
  7936.    }
  7937.    return join( "", @line );
  7938. } #END prefix
  7939.  
  7940.  
  7941. #===============================
  7942.  
  7943. sub parse_quotes {
  7944.     # Split string into words.
  7945.     # Words are delimited by space, except that strings
  7946.     # quoted all stay inside a word.  E.g.,
  7947.     #   'asdf B" df "d "jkl"'
  7948.     # is split to ( 'asdf', 'B df d', 'jkl').
  7949.     # An array is returned.
  7950.     my @results = ();
  7951.     my $item = '';
  7952.     local $_ = shift;
  7953.     pos($_) = 0;
  7954.   ITEM:
  7955.     while() {
  7956.         /\G\s*/gc;
  7957.         if ( /\G$/ ) {
  7958.             last ITEM;
  7959.         }
  7960.         # Now pos (and \G) is at start of item:
  7961.       PART:
  7962.         while () {
  7963.             if (/\G([^\s\"]*)/gc) {
  7964.                 $item .= $1;
  7965.             }
  7966.             if ( /\G\"([^\"]*)\"/gc ) {
  7967.                 # Match balanced quotes
  7968.                 $item .= $1;
  7969.                 next PART;
  7970.             }
  7971.             elsif ( /\G\"(.*)$/gc ) {
  7972.                 # Match unbalanced quote
  7973.                 $item .= $1;
  7974.                 warn "====Non-matching quotes in\n    '$_'\n";
  7975.             }
  7976.             push @results, $item;
  7977.             $item = '';
  7978.             last PART;
  7979.         }
  7980.     }
  7981.     return @results;
  7982. } #END parse_quotes
  7983.  
  7984. #************************************************************
  7985. #************************************************************
  7986. #      File handling utilities:
  7987.  
  7988.  
  7989. #************************************************************
  7990.  
  7991. sub get_latest_mtime
  7992. # - arguments: each is a filename.
  7993. # - returns most recent modify time.
  7994. {
  7995.   my $return_mtime = 0;
  7996.   foreach my $include (@_)
  7997.   {
  7998.     my $include_mtime = &get_mtime($include);
  7999.     # The file $include may not exist.  If so ignore it, otherwise
  8000.     # we'll get an undefined variable warning.
  8001.     if ( ($include_mtime) && ($include_mtime >  $return_mtime) )
  8002.     {
  8003.       $return_mtime = $include_mtime;
  8004.     }
  8005.   }
  8006.   return $return_mtime;
  8007. }
  8008.  
  8009. #************************************************************
  8010.  
  8011. sub get_mtime_raw
  8012. {
  8013.   my $mtime = (stat($_[0]))[9];
  8014.   return $mtime;
  8015. }
  8016.  
  8017. #************************************************************
  8018.  
  8019. sub get_mtime {
  8020.     return get_mtime0($_[0]);
  8021. }
  8022.  
  8023. #************************************************************
  8024.  
  8025. sub get_mtime0 {
  8026.    # Return time of file named in argument
  8027.    # If file does not exist, return 0;
  8028.    if ( -e $_[0] ) {
  8029.        return get_mtime_raw($_[0]);
  8030.    }
  8031.    else {
  8032.        return 0;
  8033.    }
  8034. }
  8035.  
  8036. #************************************************************
  8037.  
  8038. sub get_size {
  8039.    # Return time of file named in argument
  8040.    # If file does not exist, return 0;
  8041.    if ( -e $_[0] ) {
  8042.        return get_size_raw($_[0]);
  8043.    }
  8044.    else {
  8045.        return 0;
  8046.    }
  8047. }
  8048.  
  8049. #************************************************************
  8050.  
  8051. sub get_size_raw
  8052. {
  8053.   my $size = (stat($_[0]))[7];
  8054.   return $size;
  8055. }
  8056.  
  8057. #************************************************************
  8058.  
  8059. sub get_time_size {
  8060.    # Return time and size of file named in argument
  8061.    # If file does not exist, return (0,-1);
  8062.    if ( -e $_[0] ) {
  8063.        return get_time_size_raw($_[0]);
  8064.    }
  8065.    else {
  8066.        return (0,-1);
  8067.    }
  8068. }
  8069.  
  8070. #************************************************************
  8071.  
  8072. sub get_time_size_raw
  8073. {
  8074.   my $mtime = (stat($_[0]))[9];
  8075.   my $size = (stat($_[0]))[7];
  8076.   return ($mtime, $size);
  8077. }
  8078.  
  8079. #************************************************************
  8080.  
  8081. sub processing_time
  8082. {  my ($user, $system, $cuser, $csystem) = times();
  8083.    return $user + $system + $cuser + $csystem;
  8084. }
  8085.  
  8086. #************************************************************
  8087.  
  8088. sub get_checksum_md5 {
  8089.     my $source = shift;
  8090.     my $input = new FileHandle;
  8091.     my $md5 = Digest::MD5->new;
  8092.     my $ignore_pattern = undef;
  8093.  
  8094. #&traceback;
  8095. #warn "======= GETTING MD5: $source\n";
  8096.     if ( $source eq "" ) {
  8097.        # STDIN:
  8098.        open( $input, '-' );
  8099.     }
  8100.     elsif ( -d $source ) {
  8101.         # We won't use checksum for directory
  8102.         return 0;
  8103.     }
  8104.     else {
  8105.         open( $input, '<', $source )
  8106.         or return 0;
  8107.         my ($base, $path, $ext) = fileparseA( $source );
  8108.         $ext =~ s/^\.//;
  8109.         if ( exists $hash_calc_ignore_pattern{$ext} ) {
  8110.             $ignore_pattern = $hash_calc_ignore_pattern{$ext};
  8111.         }
  8112.     }
  8113.  
  8114.     if ( defined $ignore_pattern ) {
  8115.         while (<$input>) {
  8116.             if ( ! /$ignore_pattern/ ){
  8117.                 $md5->add($_);
  8118.             }
  8119.         }
  8120.     }
  8121.     else {
  8122.         $md5->addfile($input);
  8123.     }
  8124.     close $input;
  8125.     return $md5->hexdigest();
  8126. }
  8127.  
  8128. #************************************************************
  8129. #************************************************************
  8130.  
  8131. sub create_empty_file {
  8132.     my $name = shift;
  8133.     my $h = new FileHandle ">$name"
  8134.     or return 1;
  8135.     close ($h);
  8136.     return 0;
  8137. }
  8138.  
  8139. #************************************************************
  8140. #************************************************************
  8141.  
  8142. sub find_file1 {
  8143. #?? Need to use kpsewhich, if possible
  8144.  
  8145.     # Usage: find_file1(name, ref_to_array_search_path)
  8146.     # Modified find_file, which doesn't die.
  8147.     # Given filename and path, return array of:
  8148.     #             full name
  8149.     #             retcode
  8150.     # On success: full_name = full name with path, retcode = 0
  8151.     # On failure: full_name = given name, retcode = 1
  8152.  
  8153.     my $name = $_[0];
  8154.     # Make local copy of path, since we may rewrite it!
  8155.     my @path = ();
  8156.     if ($_[1]) {
  8157.         @path = @{$_[1]};
  8158.     }
  8159.     if ( $name =~ /^\// ) {
  8160.         # Absolute path (if under UNIX)
  8161.         # This needs fixing, in general
  8162.         if (-e $name) { return( $name, 0 );}
  8163.         else { return( $name, 1 );}
  8164.     }
  8165.     foreach my $dir ( @path ) {
  8166.         #??print "-------------dir='$dir',  ";
  8167.         # Make $dir concatenatable, and empty for current dir:
  8168.         if ( $dir eq '.' ) {
  8169.             $dir = '';
  8170.         }
  8171.         elsif ( $dir =~ /[\/\\:]$/ ) {
  8172.             #OK if dir ends in / or \ or :
  8173.         }
  8174.         elsif ( $dir ne '' ) {
  8175.             #Append directory separator only to non-empty dir
  8176.             $dir = "$dir/";
  8177.         }
  8178.         #?? print " newdir='$dir'\n";
  8179.         if (-e "$dir$name") {
  8180.             return("$dir$name", 0);
  8181.         }
  8182.     }
  8183.     my @kpse_result = kpsewhich( $name );
  8184.     if ($#kpse_result > -1) {
  8185.         return( $kpse_result[0], 0);
  8186.     }
  8187.     return("$name" , 1);
  8188. } #END find_file1
  8189.  
  8190. #************************************************************
  8191.  
  8192. sub find_file_list1 {
  8193.     # Modified version of find_file_list that doesn't die.
  8194.     # Given output and input arrays of filenames, a file suffix, and a path,
  8195.     # fill the output array with full filenames
  8196.     # Return array of not-found files.
  8197.     # Usage: find_file_list1( ref_to_output_file_array,
  8198.     #                         ref_to_input_file_array,
  8199.     #                         suffix,
  8200.     #                         ref_to_array_search_path
  8201.     #                       )
  8202.     # SPECIAL TREATMENT TO .bib extension, because of behavior of bibtex
  8203.     # OTHER SPECIAL TREATMENT IF EXTENSION IS GIVEN.
  8204.  
  8205.   my $ref_output = $_[0];
  8206.   my $ref_input  = $_[1];
  8207.   my $suffix     = $_[2];
  8208.   my $ref_search = $_[3];
  8209.   my @not_found = ();
  8210.  
  8211. #??  show_array( "=====find_file_list1.  Suffix: '$suffix'\n Source:",  @$ref_input );
  8212. #??  show_array( " Bibinputs:",  @$ref_search );
  8213.  
  8214.   my @return_list = ();    # Generate list in local array, since input
  8215.                            # and output arrays may be same
  8216.   my $retcode = 0;
  8217.   foreach my $file1 (@$ref_input) {
  8218.     my $file = $file1;
  8219.     if ($suffix eq '.bib') { $file =~ s/\.bib$//; }
  8220.     my ($tmp_file, $find_retcode) = &find_file1( "$file$suffix", $ref_search );
  8221.     if ($tmp_file)  {
  8222.         push @return_list, $tmp_file;
  8223.     }
  8224.     if ( $find_retcode != 0 ) {
  8225.         push @not_found, $file.$suffix;
  8226.     }
  8227.   }
  8228.   @$ref_output = @return_list;
  8229. #??  show_array( " Output", @$ref_output );
  8230. #??  foreach (@$ref_output) { if ( /\/\// ) {  print " ====== double slash in  '$_'\n"; }  }
  8231.   return @not_found;
  8232. } #END find_file_list1
  8233.  
  8234. #************************************************************
  8235.  
  8236. sub unlink_or_move {
  8237.     if ( $del_dir eq '' ) {
  8238.         unlink @_;
  8239.     }
  8240.     else {
  8241.         foreach (@_) {
  8242.             if (-e $_ && ! rename $_, "$del_dir/$_" ) {
  8243.                 warn "$My_name:Cannot move '$_' to '$del_dir/$_'\n";
  8244.             }
  8245.         }
  8246.     }
  8247. }
  8248.  
  8249. #************************************************************
  8250.  
  8251. sub kpsewhich {
  8252. # Usage: kpsewhich( filespec, ...)
  8253. # Returns array of files with paths as found by kpsewhich
  8254. #    kpsewhich( 'try.sty', 'jcc.bib' );
  8255. # With standard use of kpsewhich (i.e., without -all option), the array
  8256. # has either 0 or 1 element.
  8257. # Can also do, e.g.,
  8258. #    kpsewhich( '-format=bib', 'trial.bib', 'file with spaces');
  8259.     my $cmd = $kpsewhich;
  8260.     my @args = @_;
  8261.     if ( ($cmd eq '') || ( $cmd =~ /^NONE($| )/ ) ) {
  8262.     # Kpsewhich not set up.
  8263.     warn "$My_name: Kpsewhich command needed but not set up\n";
  8264.     return ();
  8265.     }
  8266.     foreach (@args) {
  8267.         if ( ! /^-/ ) {
  8268.             $_ = "\"$_\"";
  8269.         }
  8270.     }
  8271.     $cmd =~ s/%[RBTDO]//g;
  8272.     $cmd =~ s/%S/@args/g;
  8273.     my @found = ();
  8274.     local $fh;
  8275.     if ( $kpsewhich_show || $diagnostics ) {
  8276.         print "$My_name.kpsewhich: Running '$cmd'...\n";
  8277.     }
  8278.     open $fh, "$cmd|"
  8279.         or die "Cannot open pipe for \"$cmd\"\n";
  8280.     while ( <$fh> ) {
  8281.         s/[\r\n]*$//;
  8282.         push @found, $_;
  8283.     }
  8284.     close $fh;
  8285.     if ( $kpsewhich_show || $diagnostics ) {
  8286.     show_array( "$My_name.kpsewhich: '$cmd' ==>", @found );
  8287.     }
  8288.     return @found;
  8289. }
  8290.  
  8291. ####################################################
  8292.  
  8293. sub add_cus_dep {
  8294.     # Usage: add_cus_dep( from_ext, to_ext, flag, sub_name )
  8295.     # Add cus_dep after removing old versions
  8296.     my ($from_ext, $to_ext, $must, $sub_name) = @_;
  8297.     remove_cus_dep( $from_ext, $to_ext );
  8298.     push @cus_dep_list, "$from_ext $to_ext $must $sub_name";
  8299. }
  8300.  
  8301. ####################################################
  8302.  
  8303. sub remove_cus_dep {
  8304.     # Usage: remove_cus_dep( from_ext, to_ext )
  8305.     my ($from_ext, $to_ext) = @_;
  8306.     my $i = 0;
  8307.     while ($i <= $#cus_dep_list) {
  8308.         # Use \Q and \E round directory name in regex to avoid interpretation
  8309.         #   of metacharacters in directory name:
  8310.         if ( $cus_dep_list[$i] =~ /^\Q$from_ext $to_ext \E/ ) {
  8311.             splice @cus_dep_list, $i, 1;
  8312.         }
  8313.         else {
  8314.             $i++;
  8315.         }
  8316.     }
  8317. }
  8318.  
  8319. ####################################################
  8320.  
  8321. sub show_cus_dep {
  8322.     show_array( "Custom dependency list:", @cus_dep_list );
  8323. }
  8324.  
  8325. ####################################################
  8326.  
  8327. sub add_aux_hook {
  8328.     # Usage: add_aux_hook( sub_name )
  8329.     # Add the name subroutine to the array of hooks for
  8330.     # processing lines of aux files.
  8331.     # The argument is either a string naming the subroutine, e.g.
  8332.     #     add_aux_hook( 'subname' );
  8333.     # or a Perl reference to the subroutine, e.g.,
  8334.     #     add_aux_hook( \&subname );
  8335.     # It is also possible to use an anonymous subroutine, e.g.,
  8336.     #     add_aux_hook( sub{  code of subroutine... } );
  8337.     my ($sub_name) = @_;
  8338.     push @aux_hooks, $sub_name;
  8339. }
  8340.  
  8341. ####################################################
  8342.  
  8343. sub add_input_ext {
  8344.     # Usage: add_input_ext( rule, ext, ... )
  8345.     # Add extension(s) (specified without a leading period) to the
  8346.     # list of input extensions for the given rule.  The rule should be
  8347.     # 'latex' or 'pdflatex'.  These extensions are used when an input
  8348.     # file without an extension is found by (pdf)latex, as in
  8349.     # \input{file} or \includegraphics{figure}.  When latexmk searches
  8350.     # custom dependencies to make the missing file, it will assume that
  8351.     # the file has one of the specified extensions.
  8352.     my $rule = shift;
  8353.     if ( ! exists $input_extensions{$rule} ) {
  8354.        $input_extensions{$rule} = {};
  8355.     }
  8356.     my $Prule = $input_extensions{$rule};
  8357.     foreach (@_) { $$Prule{$_} = 1; }
  8358. }
  8359.  
  8360. ####################################################
  8361.  
  8362. sub remove_input_ext {
  8363.     # Usage: remove_input_ext( rule, ext, ... )
  8364.     # Remove extension(s) (specified without a leading period) to the
  8365.     # list of input extensions for the given rule.  The rule should be
  8366.     # 'latex' or 'pdflatex'.  See sub add_input_ext for the use.
  8367.     my $rule = shift;
  8368.     if ( ! exists $input_extensions{$rule} ) { return; }
  8369.     my $Prule = $input_extensions{$rule};
  8370.     foreach (@_) { delete $$Prule{$_}; }
  8371. }
  8372.  
  8373. ####################################################
  8374.  
  8375. sub show_input_ext {
  8376.     # Usage: show_input_ext( rule )
  8377.     my $rule = shift;
  8378.     show_array ("Input extensions for rule '$rule': ",
  8379.                 keys %{$input_extensions{$rule}} );
  8380. }
  8381.  
  8382. ####################################################
  8383.  
  8384. sub find_dirs1 {
  8385.    # Same as find_dirs, but argument is single string with directories
  8386.    # separated by $search_path_separator
  8387.    find_dirs( &split_search_path( $search_path_separator, ".", $_[0] ) );
  8388. }
  8389.  
  8390.  
  8391. #************************************************************
  8392.  
  8393. sub find_dirs {
  8394. # @_ is list of directories
  8395. # return: same list of directories, except that for each directory
  8396. #         name ending in //, a list of all subdirectories (recursive)
  8397. #         is added to the list.
  8398. #   Non-existent directories and non-directories are removed from the list
  8399. #   Trailing "/"s and "\"s are removed
  8400.     local @result = ();
  8401.     my $find_action
  8402.         = sub
  8403.           { ## Subroutine for use in File::find
  8404.             ## Check to see if we have a directory
  8405.                if (-d) { push @result, $File::Find::name; }
  8406.           };
  8407.     foreach my $directory (@_) {
  8408.         my $recurse = ( $directory =~ m[//$] );
  8409.         # Remove all trailing /s, since directory name with trailing /
  8410.         #   is not always allowed:
  8411.         $directory =~ s[/+$][];
  8412.         # Similarly for MSWin reverse slash
  8413.         $directory =~ s[\\+$][];
  8414.         if ( ! -e $directory ){
  8415.             next;
  8416.         }
  8417.         elsif ( $recurse ){
  8418.             # Recursively search directory
  8419.             find( $find_action, $directory );
  8420.         }
  8421.         else {
  8422.             push @result, $directory;
  8423.         }
  8424.     }
  8425.     return @result;
  8426. }
  8427.  
  8428. #************************************************************
  8429.  
  8430. sub uniq
  8431. # Read arguments, delete neighboring items that are identical,
  8432. # return array of results
  8433. {
  8434.     my @sort = ();
  8435.     my ($current, $prev);
  8436.     my $first = 1;
  8437.     while (@_)
  8438.     {
  8439.         $current = shift;
  8440.         if ($first || ($current ne $prev) )
  8441.         {
  8442.             push @sort, $current;
  8443.             $prev = $current;
  8444.             $first = 0;
  8445.         }
  8446.     }
  8447.     return @sort;
  8448. }
  8449.  
  8450. #==================================================
  8451.  
  8452. sub uniq1 {
  8453.    # Usage: uniq1( strings )
  8454.    # Returns array of strings with duplicates later in list than
  8455.    # first occurence deleted.  Otherwise preserves order.
  8456.  
  8457.     my @strings = ();
  8458.     my %string_hash = ();
  8459.  
  8460.     foreach my $string (@_) {
  8461.         if (!exists( $string_hash{$string} )) {
  8462.             $string_hash{$string} = 1;
  8463.             push @strings, $string;
  8464.         }
  8465.     }
  8466.     return @strings;
  8467. }
  8468.  
  8469. #************************************************************
  8470.  
  8471. sub uniqs {
  8472.     # Usage: uniq2( strings )
  8473.     # Returns array of strings sorted and with duplicates deleted
  8474.     return uniq( sort @_ );
  8475. }
  8476.  
  8477. #************************************************************
  8478.  
  8479. sub ext {
  8480.     # Return extension of filename.  Extension includes the period
  8481.     my $file_name = $_[0];
  8482.     my ($base_name, $path, $ext) = fileparseA( $file_name );
  8483.     return $ext;
  8484.  }
  8485.  
  8486. #************************************************************
  8487.  
  8488. sub ext_no_period {
  8489.     # Return extension of filename.  Extension excludes the period
  8490.     my $file_name = $_[0];
  8491.     my ($base_name, $path, $ext) = fileparseA( $file_name );
  8492.     $ext =~ s/^\.//;
  8493.     return $ext;
  8494.  }
  8495.  
  8496. #************************************************************
  8497.  
  8498. sub fileparseA {
  8499.     # Like fileparse but replace $path for current dir ('./' or '.\') by ''
  8500.     # Also default second argument to get normal extension.
  8501.     my $given = $_[0];
  8502.     my $pattern = '\.[^\.]*';
  8503.     if  ($#_ > 0 ) { $pattern = $_[1]; }
  8504.     my ($base_name, $path, $ext) = fileparse( $given, $pattern );
  8505.     if ( ($path eq './') || ($path eq '.\\') ) {
  8506.         $path = '';
  8507.     }
  8508.     return ($base_name, $path, $ext);
  8509.  }
  8510.  
  8511. #************************************************************
  8512.  
  8513. sub fileparseB {
  8514.     # Like fileparse but with default second argument for normal extension
  8515.     my $given = $_[0];
  8516.     my $pattern = '\.[^\.]*';
  8517.     if  ($#_ > 0 ) { $pattern = $_[1]; }
  8518.     my ($base_name, $path, $ext) = fileparse( $given, $pattern );
  8519.     return ($base_name, $path, $ext);
  8520.  }
  8521.  
  8522. #************************************************************
  8523.  
  8524. sub split_search_path
  8525. {
  8526. # Usage: &split_search_path( separator, default, string )
  8527. # Splits string by separator and returns array of the elements
  8528. # Allow empty last component.
  8529. # Replace empty terms by the default.
  8530.     my $separator = $_[0];
  8531.     my $default = $_[1];
  8532.     my $search_path = $_[2];
  8533.     my @list = split( /$separator/, $search_path);
  8534.     if ( $search_path =~ /$separator$/ ) {
  8535.         # If search path ends in a blank item, the split subroutine
  8536.         #    won't have picked it up.
  8537.         # So add it to the list by hand:
  8538.         push @list, "";
  8539.     }
  8540.     # Replace each blank argument (default) by current directory:
  8541.     for ($i = 0; $i <= $#list ; $i++ ) {
  8542.         if ($list[$i] eq "") {$list[$i] = $default;}
  8543.     }
  8544.     return @list;
  8545. }
  8546.  
  8547. #################################
  8548.  
  8549. sub get_filetime_offset {
  8550.     # Usage: get_filetime_offset( prefix, [suffix] )
  8551.     # Measures offset between filetime in a directory and system time
  8552.     # Makes a temporary file of a unique name, and deletes in.
  8553.     # Filename is of form concatenation of prefix, an integer, suffix.
  8554.     # Prefix is normally of form dir/ or dir/tmp.
  8555.     # Default default suffix ".tmp".
  8556.     my $prefix = $_[0];
  8557.     my $suffix = $_[1] || '.tmp';
  8558.     my $tmp_file_count = 0;
  8559.     while (1==1) {
  8560.         # Find a new temporary file, and make it.
  8561.         $tmp_file_count++;
  8562.         my $tmp_file = "${prefix}${tmp_file_count}${suffix}";
  8563.         if ( ! -e $tmp_file ) {
  8564.             open( TMP, ">$tmp_file" )
  8565.         or die "$My_name.get_filetime_offset: In measuring filetime offset, couldn't write to\n",
  8566.                "    temporary file '$tmp_file'\n";
  8567.         my $time = time();
  8568.             close(TMP);
  8569.         my $offset = get_mtime($tmp_file) - $time;
  8570.         unlink $tmp_file;
  8571.             return $offset;
  8572.          }
  8573.      }
  8574.      die "$My_name.get_filetime_offset: BUG TO ARRIVE HERE\n";
  8575. }
  8576.  
  8577. #################################
  8578.  
  8579. sub tempfile1 {
  8580.     # Makes a temporary file of a unique name.  I could use file::temp,
  8581.     # but it is not present in all versions of perl.
  8582.     # Filename is of form $tmpdir/$_[0]nnn$suffix, where nnn is an integer
  8583.     my $tmp_file_count = 0;
  8584.     my $prefix = $_[0];
  8585.     my $suffix = $_[1];
  8586.     while (1==1) {
  8587.         # Find a new temporary file, and make it.
  8588.         $tmp_file_count++;
  8589.         my $tmp_file = "${tmpdir}/${prefix}${tmp_file_count}${suffix}";
  8590.         if ( ! -e $tmp_file ) {
  8591.             open( TMP, ">$tmp_file" )
  8592.                or next;
  8593.             close(TMP);
  8594.             return $tmp_file;
  8595.          }
  8596.      }
  8597.      die "$My_name.tempfile1: BUG TO ARRIVE HERE\n";
  8598. }
  8599.  
  8600. #################################
  8601.  
  8602. #************************************************************
  8603. #************************************************************
  8604. #      Process/subprocess routines
  8605.  
  8606. sub Run_msg {
  8607.     # Same as Run, but give message about my running
  8608.     warn_running( "Running '$_[0]'" );
  8609.     return Run($_[0]);
  8610. } #END Run_msg
  8611.  
  8612. #==================
  8613.  
  8614. sub Run {
  8615.     # This is wrapper around Run_no_time to capture timing information
  8616.     my $time1 = processing_time();
  8617.     my ($pid, $return) = Run_no_time($_[0]);
  8618.     my $time = processing_time() - $time1;
  8619.     push @timings, "'$_[0]': time = $time\n";
  8620.     return ($pid, $return);
  8621. } #END Run_msg
  8622.  
  8623. #==================
  8624.  
  8625. sub Run_no_time {
  8626. # Usage: Run_no_time ("command string");
  8627. #    or  Run_no_time ("one-or-more keywords command string");
  8628. # Possible keywords: internal, NONE, start, nostart.
  8629. #
  8630. # A command string not started by keywords just gives a call to system with
  8631. #   the specified string, I return after that has finished executing.
  8632. # Exceptions to this behavior are triggered by keywords.
  8633. # The general form of the string is
  8634. #    Zero or more occurences of the start keyword,
  8635. #    followed by at most one of the other key words (internal, nostart, NONE),
  8636. #    followed by (a) a command string to be executed by the systerm
  8637. #             or (b) if the command string is specified to be internal, then
  8638. #                    it is of the form
  8639. #
  8640. #                       routine arguments
  8641. #
  8642. #                    which implies invocation of the named Perl subroutine
  8643. #                    with the given arguments, which are obtained by splitting
  8644. #                    the string into words, delimited by spaces, but with
  8645. #                    allowance for double quotes.
  8646. #
  8647. # The meaning of the keywords is:
  8648. #
  8649. #    start: The command line is to be running detached, as appropriate for
  8650. #             a previewer.  The method is appropriate for the operating system
  8651. #             (and the keyword is inspired by the action of the start command
  8652. #             that implements in under MSWin).
  8653. #           HOWEVER: the start keyword is countermanded by the nostart,
  8654. #             internal, and NONE keywords.  This allows rules that do
  8655. #             previewing to insert a start keyword to create a presumption
  8656. #             of detached running unless otherwise.
  8657. #   nostart: Countermands a previous start keyword; the following command
  8658. #             string is then to be obeyed by the system, and any necessary
  8659. #             detaching (as of a previewer) is done by the executed command(s).
  8660. #   internal: The following command string, of the form 'routine arguments'
  8661. #             specifies a call to the named Perl subroutine.
  8662. #   NONE:   This does not run anything, but causes an error message to be
  8663. #             printed.  This is provided to allow program names defined in the
  8664. #             configuration to flag themselves as unimplemented.
  8665. # Note that if the word "start" is duplicated at the beginning, that is
  8666. #   equivalent to a single "start".
  8667. #
  8668. # Return value is a list (pid, exitcode):
  8669. #   If a process is spawned sucessfully, and I know the PID,
  8670. #       return (pid, 0),
  8671. #   else if process is spawned sucessfully, but I do not know the PID,
  8672. #       return (0, 0),
  8673. #   else if process is run,
  8674. #       return (0, exitcode of process)
  8675. #   else if I fail to run the requested process
  8676. #       return (0, suitable return code)
  8677. #   where return code is 1 if cmdline is null or begins with "NONE" (for
  8678. #       an unimplemented command)
  8679. #       or the return value of the Perl subroutine.
  8680.     my $cmd_line = $_[0];
  8681.     if ( $cmd_line eq '' ) {
  8682.         traceback( "$My_name: Bug OR configuration error\n".
  8683.                    "   In run of '$rule', attempt to run a null program" );
  8684.         return (0, 1);
  8685.     }
  8686.     # Deal with latexmk-defined pseudocommands 'start' and 'NONE'
  8687.     # at front of command line:
  8688.     my $detach = 0;
  8689.     while ( $cmd_line =~ s/^start +// ) {
  8690.         # But first remove extra starts (which may have been inserted
  8691.         # to force a command to be run detached, when the command
  8692.         # already contained a "start").
  8693.         $detach = 1;
  8694.     }
  8695.     if ( $cmd_line =~ s/^nostart +// ) {
  8696.         $detach = 0;
  8697.     }
  8698.     if ( $cmd_line =~ /^internal\s+([a-zA-Z_]\w*)\s+(.*)$/ ) {
  8699.         my $routine = $1;
  8700.         my @args = parse_quotes( $2 );
  8701.         warn "$My_name: calling $routine( $2 )\n";
  8702.         return ( 0, &$routine( @args ) );
  8703.     }
  8704.     elsif ( $cmd_line =~ /^internal\s+([a-zA-Z_]\w*)\s*$/ ) {
  8705.         my $routine = $1;
  8706.         warn "$My_name: calling $routine()\n";
  8707.         return ( 0, &$routine() );
  8708.     }
  8709.     elsif ( $cmd_line =~ /^NONE/ ) {
  8710.         warn "$My_name: ",
  8711.              "Program not implemented for this version.  Command line:\n";
  8712.         warn "   '$cmd_line'\n";
  8713.         return (0, 1);
  8714.     }
  8715.     elsif ($detach) {
  8716.         # Run detached.  How to do this depends on the OS
  8717.         return &Run_Detached( $cmd_line );
  8718.     }
  8719.     else {
  8720.        # The command is given to system as a single argument, to force shell
  8721.        # metacharacters to be interpreted:
  8722.        return( 0, system( $cmd_line ) );
  8723.    }
  8724. }  #END Run
  8725.  
  8726. #************************************************************
  8727.  
  8728. sub Run_Detached {
  8729. # Usage: Run_Detached ("program arguments ");
  8730. # Runs program detached.  Returns 0 on success, 1 on failure.
  8731. # Under UNIX use a trick to avoid the program being killed when the
  8732. #    parent process, i.e., me, gets a ctrl/C, which is undesirable for pvc
  8733. #    mode.  (The simplest method, system("program arguments &"), makes the
  8734. #    child process respond to the ctrl/C.)
  8735. # Return value is a list (pid, exitcode):
  8736. #   If process is spawned sucessfully, and I know the PID,
  8737. #       return (pid, 0),
  8738. #   else if process is spawned sucessfully, but I do not know the PID,
  8739. #       return (0, 0),
  8740. #   else if I fail to spawn a process
  8741. #       return (0, 1)
  8742.  
  8743.     my $cmd_line = $_[0];
  8744.  
  8745. ##    warn "Running '$cmd_line' detached...\n";
  8746.     if ( $cmd_line =~ /^NONE / ) {
  8747.         warn "$My_name: ",
  8748.              "Program not implemented for this version.  Command line:\n";
  8749.         warn "   '$cmd_line'\n";
  8750.         return (0, 1);
  8751.     }
  8752.  
  8753.     if ( "$^O" eq "MSWin32" ){
  8754.         # Win95, WinNT, etc: Use MS's start command:
  8755.         # Need extra double quotes to deal with quoted filenames:
  8756.         #    MSWin start takes first quoted argument to be a Window title.
  8757.         return( 0, system( "start \"\" $cmd_line" ) );
  8758.     } else {
  8759.         # Assume anything else is UNIX or clone
  8760.         # For this purpose cygwin behaves like UNIX.
  8761.         ## warn "Run_Detached.UNIX: A\n";
  8762.         my $pid = fork();
  8763.         ## warn "Run_Detached.UNIX: B pid=$pid\n";
  8764.         if ( ! defined $pid ) {
  8765.             ## warn "Run_Detached.UNIX: C\n";
  8766.             warn "$My_name: Could not fork to run the following command:\n";
  8767.             warn "   '$cmd_line'\n";
  8768.             return (0, 1);
  8769.         }
  8770.         elsif( $pid == 0 ){
  8771.            ## warn "Run_Detached.UNIX: D\n";
  8772.            # Forked child process arrives here
  8773.            # Insulate child process from interruption by ctrl/C to kill parent:
  8774.            #     setpgrp(0,0);
  8775.            # Perhaps this works if setpgrp doesn't exist
  8776.            #    (and therefore gives fatal error):
  8777.            eval{ setpgrp(0,0);};
  8778.            exec( $cmd_line );
  8779.            # Exec never returns; it replaces current process by new process
  8780.            die "$My_name forked process: could not run the command\n",
  8781.                "  '$cmd_line'\n";
  8782.         }
  8783.         ##warn "Run_Detached.UNIX: E\n";
  8784.         # Original process arrives here
  8785.         return ($pid, 0);
  8786.     }
  8787.     # NEVER GET HERE.
  8788.     ##warn "Run_Detached.UNIX: F\n";
  8789. } #END Run_Detached
  8790.  
  8791. #************************************************************
  8792.  
  8793. sub find_process_id {
  8794. # find_process_id(string) finds id of process containing string and
  8795. # being run by the present user.  Typically the string will be the
  8796. # name of the process or part of its command line.
  8797. # On success, this subroutine returns the process ID.
  8798. # On failure, it returns 0.
  8799. # This subroutine only works on UNIX systems at the moment.
  8800.  
  8801.     if ( $pid_position < 0 ) {
  8802.         # I cannot do a ps on this system
  8803.         return (0);
  8804.     }
  8805.  
  8806.     my $looking_for = $_[0];
  8807.     my @ps_output = `$pscmd`;
  8808.     my @ps_lines = ();
  8809.  
  8810. # There may be multiple processes.  Find only latest,
  8811. #   almost surely the one with the highest process number
  8812. # This will deal with cases like xdvi where a script is used to
  8813. #   run the viewer and both the script and the actual viewer binary
  8814. #   have running processes.
  8815.     my @found = ();
  8816.  
  8817.     shift(@ps_output);  # Discard the header line from ps
  8818.     foreach (@ps_output)   {
  8819.         next unless ( /$looking_for/ ) ;
  8820.     s/^\s*//;
  8821.         my @ps_line = split ('\s+');
  8822.         push @found, $ps_line[$pid_position];
  8823.         push @ps_lines, $_;
  8824.     }
  8825.  
  8826.     if ($#found < 0) {
  8827.        # No luck in finding the specified process.
  8828.        return(0);
  8829.     }
  8830.     @found = reverse sort @found;
  8831.     if ($diagnostics) {
  8832.        print "Found the following processes concerning '$looking_for'\n",
  8833.              "   @found\n",
  8834.              "   I will use $found[0]\n";
  8835.        print "   The relevant lines from '$pscmd' were:\n";
  8836.        foreach (@ps_lines) { print "   $_"; }
  8837.     }
  8838.     return $found[0];
  8839. }
  8840.  
  8841. #************************************************************
  8842. #************************************************************
  8843. #************************************************************
  8844.  
  8845. #============================================
  8846.  
  8847. sub cache_good_cwd {
  8848.     # Set cached value of cwd to current cwd.
  8849.     # Under cygwin, the cwd is converted to a native MSWin path so
  8850.     # that the result can be used for input to MSWin programs as well
  8851.     # as cygwin programs.
  8852.     my $cwd = cwd();
  8853.     if ( $^O eq "cygwin" ) {
  8854.         my $cmd = "cygpath -w \"$cwd\"";
  8855.         my $Win_cwd = `$cmd`;
  8856.         chomp $Win_cwd;
  8857.         if ( $Win_cwd ) {
  8858.             $cwd = $Win_cwd;
  8859.         }
  8860.         else {
  8861.             warn "$My_name: Could not correctly run command\n",
  8862.                  "      '$cmd'\n",
  8863.                  "  to get MSWin version of cygwin path\n",
  8864.                  "     '$cwd'\n",
  8865.                  "  The result was\n",
  8866.                  "     '$Win_cwd'\n";
  8867.         }
  8868.     }
  8869.     $cache{cwd} = $cwd;
  8870. }  # END cache_good_cwd
  8871.  
  8872. #============================================
  8873.  
  8874. sub good_cwd {
  8875.     # Return cwd, but under cygwin, convert to MSWin path.
  8876.     # Use cached result
  8877.     return $cache{cwd};
  8878. }  # END good_cwd
  8879.  
  8880. #============================================
  8881.  
  8882. #   Directory stack routines
  8883.  
  8884. sub pushd {
  8885.     push @dir_stack, [cwd(), $cache{cwd}];
  8886.     if ( $#_ > -1) {
  8887.         chdir $_[0];
  8888.         &cache_good_cwd;
  8889.     }
  8890. }
  8891.  
  8892. #************************************************************
  8893.  
  8894. sub popd {
  8895.     if ($#dir_stack > -1 ) {
  8896.         my $Parr = pop @dir_stack;
  8897.         chdir $$Parr[0];
  8898.         $cache{cwd} = $$Parr[1];
  8899.     }
  8900. }
  8901.  
  8902. #************************************************************
  8903.  
  8904. sub ifcd_popd {
  8905.     if ( $do_cd ) {
  8906.         warn "$My_name: Undoing directory change\n";
  8907.         &popd;
  8908.     }
  8909. }
  8910.  
  8911. #************************************************************
  8912.  
  8913. sub finish_dir_stack {
  8914.     while ($#dir_stack > -1 ) { &popd; }
  8915. }
  8916.  
  8917. #************************************************************
  8918. #************************************************************
  8919. # Break handling routines (for wait-loop in preview continuous)
  8920.  
  8921. sub end_wait {
  8922.     #  Handler for break: Set global variable $have_break to 1.
  8923.     # Some systems (e.g., MSWin reset) appear to reset the handler.
  8924.     # So I'll re-enable it
  8925.     &catch_break;
  8926.     $have_break = 1;
  8927. }
  8928.  
  8929. #========================
  8930.  
  8931. sub catch_break {
  8932. # Capture ctrl/C and ctrl/break.
  8933. # $SIG{INT} corresponds to ctrl/C on LINUX/?UNIX and MSWin
  8934. # $SIG{BREAK} corresponds to ctrl/break on MSWin, doesn't exist on LINUX
  8935.     $SIG{INT} = \&end_wait;
  8936.     if ( exists $SIG{BREAK} ) {
  8937.         $SIG{BREAK} = \&end_wait;
  8938.     }
  8939. }
  8940.  
  8941. #========================
  8942.  
  8943. sub default_break {
  8944. # Arrange for ctrl/C and ctrl/break to give default behavior
  8945.     $SIG{INT} = 'DEFAULT';
  8946.     if ( exists $SIG{BREAK} ) {
  8947.         $SIG{BREAK} = 'DEFAULT';
  8948.     }
  8949. }
  8950.  
  8951. #************************************************************
  8952. #************************************************************
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement