dotfiles

configuration files for shell, text editor, graphical environment, etc.
git clone git://src.adamsgaard.dk/dotfiles
Log | Files | Refs | README | LICENSE Back to index

latexmk (380607B)


      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.61';
    125 $version_details = "$My_name, John Collins, 25 October 2018";
    126 
    127 use Config;
    128 use File::Basename;
    129 use File::Copy;
    130 use File::Spec;
    131 
    132 # If possible, use better glob, which does not use space as item separator.
    133 # It's either File::Glob::bsd_glob or File::Glob::glob
    134 # The first does not exist in old versions of Perl, while the second
    135 # is deprecated in more recent versions and will be removed
    136 $have_bsd_glob = 0;
    137 sub my_glob {
    138     if ($have_bsd_glob) { return bsd_glob( $_[0] ); }
    139     else { return glob( $_[0] ); }
    140 }
    141 use File::Glob;
    142 if ( eval{ File::Glob->import('bsd_glob'); 1; } ) {
    143     # Success in importing bsd_glob
    144     $have_bsd_glob = 1;
    145 }
    146 elsif ( eval{ File::Glob->import('glob'); 1; } ) {
    147     warn "$My_name: I could not import File::Glob:bsd_glob, probably because your\n",
    148 	 "  Perl is too old.  I have arranged to use the deprecated File::Glob:glob\n",
    149 	 "  instead.\n",
    150 	 "  WARNING: It may malfunction on clean up operation on filenames containing\n",
    151   	 "           spaces.\n";
    152     $have_bsd_glob = 0;
    153 }
    154 else {
    155     die "Could not import 'File::Glob:bsd_glob' or 'File::Glob:glob'\n";
    156 }
    157 
    158 use File::Path 2.08 qw( make_path );
    159 use FileHandle;
    160 use File::Find;
    161 use List::Util qw( max );
    162 use Cwd;            # To be able to change cwd
    163 use Cwd "chdir";    # Ensure $ENV{PWD}  tracks cwd
    164 use Digest::MD5;
    165 
    166 #use strict;
    167 
    168 # The following variables are assigned once and then used in symbolic 
    169 #     references, so we need to avoid warnings 'name used only once':
    170 use vars qw( $dvi_update_command $ps_update_command $pdf_update_command );
    171 
    172 # Translation of signal names to numbers and vv:
    173 %signo = ();
    174 @signame = ();
    175 if ( defined $Config{sig_name} ) {
    176    $i = 0;
    177    foreach $name (split('\s+', $Config{sig_name})) {
    178       $signo{$name} = $i;
    179       $signame[$i] = $name;
    180       $i++;
    181    }
    182 }
    183 else {
    184    warn "Something wrong with the perl configuration: No signals?\n";
    185 }
    186 
    187 ## Copyright John Collins 1998-2018
    188 ##           (username jcc8 at node psu.edu)
    189 ##      (and thanks to David Coppit (username david at node coppit.org) 
    190 ##           for suggestions) 
    191 ## Copyright Evan McLean
    192 ##         (modifications up to version 2)
    193 ## Copyright 1992 by David J. Musliner and The University of Michigan.
    194 ##         (original version)
    195 ##
    196 ##    This program is free software; you can redistribute it and/or modify
    197 ##    it under the terms of the GNU General Public License as published by
    198 ##    the Free Software Foundation; either version 2 of the License, or
    199 ##    (at your option) any later version.
    200 ##
    201 ##    This program is distributed in the hope that it will be useful,
    202 ##    but WITHOUT ANY WARRANTY; without even the implied warranty of
    203 ##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    204 ##    GNU General Public License for more details.
    205 ##
    206 ##    You should have received a copy of the GNU General Public License
    207 ##    along with this program; if not, write to the Free Software
    208 ##    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
    209 ##
    210 ##
    211 ##
    212 ##   NEW FEATURES, since v. 2.0:
    213 ##     1.  Correct algorithm for deciding how many times to run latex:
    214 ##         based on whether source file(s) change between runs
    215 ##     2.  Continuous preview works, and can be of ps file or dvi file
    216 ##     3.  pdf creation by pdflatex possible
    217 ##     4.  Defaults for commands are OS dependent.
    218 ##     5.  Parsing of log file instead of source file is used to
    219 ##         obtain dependencies, by default.
    220 ##
    221 ##   Modification log from 9 Dec 2011 onwards in detail
    222 ##
    223 ## 12 Jan 2012 STILL NEED TO DOCUMENT some items below
    224 ##
    225 ## 25 Oct 2018 John Collins  Fix definition of clean up substitution for %R
    226 ##                             so that something with intermediate %R works,
    227 ##                             as in 'pythontex-files-%R/*'.
    228 ## 24 Oct 2018 John Collins  V. 4.61
    229 ## 16 Oct 2018 John Collins  Routines for setting all of $latex, etc.
    230 ##                           Variables, options, substitutable parameters
    231 ##                             for executing code in *latex before inputting
    232 ##                             source file.
    233 ## 10 Oct 2018 John Collins  Fix problem that if biber gets a remote file,
    234 ##                              it would be deleted and latexmk would report
    235 ##                              it as missing, incorrectly.
    236 ##  8 Oct 2018 John Collins  Report count of warnings about missing characters
    237 ##                             (typically unavailable Unicode characters).
    238 ##                             Messages about this may appear only in the .log
    239 ##                             file and are therefore easily missed by the user.
    240 ##                           V. 4.60a
    241 ## 21 Sep 2018 John Collins  Fix bug that --gg with --deps-file doesn't
    242 ##                             create deps file.
    243 ##  3 Sep 2018 John Collins  -pdfxelatex and -pdflualatex options
    244 ##  3 Sep 2018 John Collins  V. 4.60
    245 ##  7 Aug 2018 John Collins  V. 4.59  Released on CTAN
    246 ##  1 Aug 2018 John Collins  Correct sub rdb_find_source_file.
    247 ## 30 Jul 2018 John Collins  Change handling of warnings for a difference 
    248 ##                             between actual and expected output filenames
    249 ##                             for a run of a primary rule.  Only give a
    250 ##                             warning if the extensions differ.
    251 ##                           In all other cases, there were significant
    252 ##                             numbers of false positives and no true positives.
    253 ##                           Improve providing of -no-pdf option to xelatex, to
    254 ##                             ensure it's used even after a user redefinition
    255 ##                             of $xelatex.  Works if %O is in definition.
    256 ## 25 Jul 2018 John Collins  Clean up of code.
    257 ## 24 Jul 2018 John Collins  Fatal error when filename has initial '&'.  This
    258 ##                             is not allowed for TeX file, since TeX et al
    259 ##                             treat the initial '&' as specifying the format.
    260 ## 20,21,23 Jul 2018 John Collins  Improve quoting in file-not-found messages
    261 ##                                 On MS-Win change \ to / on files on command line
    262 ## 18,19 Jul 2018 John Collins Complete TEXINPUTS stuff
    263 ##                             Fix reading of file database file when
    264 ##                               custom dependency no longer exists.
    265 ## 13,17 Jul 2018 John Collins Deal with double quotes in specified filename,
    266 ##                               and filenames not allowed by TeX.
    267 ##                             Illegal characters and unbalanced quotes give fatal error.
    268 ## 10 Jul 2018 John Collins  Use TEXINPUTS for finding source file for cus dep.
    269 ##                              Version 4.58.
    270 ## 21 Jun 2018 John Collins  Version 4.57.
    271 ##                           In get_checksum_md5, open file with mode :bytes,
    272 ##                             to avoid error about malformed utf8 characters
    273 ##                             that can happen if PERL_UNICODE is set.
    274 ## 15 Jun 2018 John Collins  Configuration to be able to turn off bibtex fudge.
    275 ## 24,25 May 2018 John Collins  Fix problem of .bib files not found with msys.
    276 ##                             Add use of environment variable LATEXMKRCSYS
    277 ## 12 May 2018 John Collins  Simplify code in run_bibtex.
    278 ##  3,9 May 2018 John Collins  Improved diagnostics on mismatch of output filenames
    279 ## 28,30 Apr 2018 John Collins  Improve error messages for bib files not found
    280 ## 26 Apr 2018 John Collins  In testing for different expected and actual
    281 ##                             output of primary run, normalize $$Pdest, to
    282 ##                             avoid spurious warnings.
    283 ##
    284 ## 1998-2018, John Collins.  Many improvements and fixes.
    285 ##   See CHANGE-log.txt for full list, and CHANGES for summary
    286 ##
    287 ## Modified by Evan McLean (no longer available for support)
    288 ## Original script (RCS version 2.3) called "go" written by David J. Musliner
    289 ##
    290 ##-----------------------------------------------------------------------
    291 
    292 
    293 ## Explicit exit codes: 
    294 ##             10 = bad command line arguments
    295 ##             11 = file specified on command line not found
    296 ##                  or other file not found
    297 ##             12 = failure in some part of making files
    298 ##             13 = error in initialization file
    299 ##             20 = probable bug
    300 ##             or retcode from called program.
    301 
    302 
    303 # Line length in log file that indicates wrapping.  
    304 # This number EXCLUDES line-end characters, and is one-based.
    305 # It is the parameter max_print_line in the TeX program.  (tex.web)
    306 $log_wrap = 79;
    307 
    308 #########################################################################
    309 ## Default parsing and file-handling settings
    310 
    311 ## Array of reg-exps for patterns in log-file for file-not-found
    312 ## Each item is the string in a regexp, without the enclosing slashes.
    313 ## First parenthesized part is the filename.
    314 ## Note the need to quote slashes and single right quotes to make them 
    315 ## appear in the regexp.
    316 ## Add items by push, e.g.,
    317 ##     push @file_not_found, '^No data file found `([^\\\']*)\\\'';
    318 ## will give match to line starting "No data file found `filename'"
    319 @file_not_found = (
    320     '^No file\\s*(.*)\\.$',
    321     '^\\! LaTeX Error: File `([^\\\']*)\\\' not found\\.',
    322     '.*?:\\d*: LaTeX Error: File `([^\\\']*)\\\' not found\\.',
    323     '^LaTeX Warning: File `([^\\\']*)\\\' not found',
    324     '^Package .* [fF]ile `([^\\\']*)\\\' not found',
    325     '^Package .* No file `([^\\\']*)\\\'',
    326     'Error: pdflatex \(file ([^\)]*)\): cannot find image file',
    327     ': File (.*) not found:\s*$',
    328     '! Unable to load picture or PDF file \\\'([^\\\']+)\\\'.',
    329 );
    330 
    331 # Characters that we won't allow in the name of a TeX file.
    332 # Notes: Some are disallowed by TeX itself.
    333 #        '\' results in TeX macro expansion
    334 #        '$' results in possible variable substitution by kpsewhich called from tex.
    335 #        '"' gets special treatment.
    336 #        See subroutine test_fix_texnames and its call for their use.
    337 $illegal_in_texname = "\x00\t\f\n\r\$%\\~\x7F";
    338 
    339 
    340 ## Hash mapping file extension (w/o period, e.g., 'eps') to a single regexp,
    341 #  whose matching by a line in a file with that extension indicates that the 
    342 #  line is to be ignored in the calculation of the hash number (md5 checksum)
    343 #  for the file.  Typically used for ignoring datestamps in testing whether 
    344 #  a file has changed.
    345 #  Add items e.g., by
    346 #     $hash_calc_ignore_pattern{'eps'} = '^%%CreationDate: ';
    347 #  This makes the hash calculation for an eps file ignore lines starting with
    348 #  '%%CreationDate: '
    349 #  ?? Note that a file will be considered changed if 
    350 #       (a) its size changes
    351 #    or (b) its hash changes
    352 #  So it is useful to ignore lines in the hash calculation only if they
    353 #  are of a fixed size (as with a date/time stamp).
    354 %hash_calc_ignore_pattern =();
    355 
    356 
    357 # Specification of templates for extra rules.
    358 # See subroutine rdb_make_rule_list for examples of rule templates.
    359 # See subroutine rdb_set_rules for how they get used to construct rules.
    360 # (Documentation obviously needs to be improved!)
    361 %extra_rule_spec = ();
    362 
    363 
    364 # Hooks for customized extra processing on aux files.  The following
    365 # variable is an array of references to function.  Each function is
    366 # invoked in turn when a line of an aux file is processed (if none
    367 # of the built-in actions have been done).  On entry to the function,
    368 # the following variables are set:
    369 #    $_ = current line of aux file
    370 #    $rule = name of rule during the invocation of which, the aux file
    371 #            was supposed to have been generated.
    372 @aux_hooks = ();
    373 
    374 #########################################################################
    375 ## Default document processing programs, and related settings,
    376 ## These are mostly the same on all systems.
    377 ## Most of these variables represents the external command needed to 
    378 ## perform a certain action.  Some represent switches.
    379 
    380 
    381 ## Which TeX distribution is being used
    382 ## E.g., "MiKTeX 2.9", "TeX Live 2018"
    383 ## "" means not determined. Obtain from first line of .log file.
    384 $tex_distribution = '';
    385 
    386 &std_tex_cmds;
    387 
    388 # Possible code to execute by *latex before inputting source file.
    389 # Not used by default.
    390 $pre_tex_code = '';
    391 
    392 ## Default switches:
    393 $latex_default_switches = '';
    394 $pdflatex_default_switches = '';
    395 $lualatex_default_switches = '';
    396     # Note that xelatex is used to give xdv file, not pdf file, hence 
    397     # we need the -no-pdf option.
    398 $xelatex_default_switches = '-no-pdf';
    399 
    400 ## Switch(es) to make them silent:
    401 $latex_silent_switch  = '-interaction=batchmode';
    402 $pdflatex_silent_switch  = '-interaction=batchmode';
    403 $lualatex_silent_switch  = '-interaction=batchmode';
    404 $xelatex_silent_switch  = '-interaction=batchmode';
    405 
    406 # %input_extensions maps primary_rule_name to pointer to hash of file extensions
    407 #    used for extensionless files specified in the source file by constructs
    408 #    like \input{file}  \includegraphics{file}
    409 #  Could write
    410 #%input_extensions = ( 'latex' => { 'tex' => 1, 'eps' => 1 };, 
    411 #        'pdflatex' => { 'tex' => 1, 'pdf' => 1, 'jpg' => 1, 'png' => 1 }; );
    412 # Instead we'll exercise the user-friendly access routines:
    413 add_input_ext( 'latex', 'tex', 'eps' );
    414 add_input_ext( 'pdflatex', 'tex', 'jpg', 'pdf', 'png' );
    415 add_input_ext( 'lualatex', 'tex', 'jpg', 'pdf', 'png' );
    416 add_input_ext( 'xelatex', 'tex', 'jpg', 'pdf', 'png' );
    417 #show_input_ext( 'latex' ); show_input_ext( 'pdflatex' );
    418 
    419 %allowed_output_ext = ( ".dvi" => 1, ".xdv" => 1, ".pdf" => 1 );
    420 
    421 # Information about options to latex and pdflatex that latexmk will simply
    422 #   pass through to (pdf)latex
    423 # Option without arg. maps to itself.
    424 # Option with arg. maps the option part to the full specification
    425 #  e.g., -kpathsea-debug => -kpathsea-debug=NUMBER
    426 %allowed_latex_options = ();
    427 %allowed_latex_options_with_arg = ();
    428 foreach ( 
    429   #####
    430   # TeXLive options
    431     "-draftmode              switch on draft mode (generates no output PDF)",
    432     "-enc                    enable encTeX extensions such as \\mubyte",
    433     "-etex                   enable e-TeX extensions",
    434     "-file-line-error        enable file:line:error style messages",
    435     "-no-file-line-error     disable file:line:error style messages",
    436     "-fmt=FMTNAME            use FMTNAME instead of program name or a %& line",
    437     "-halt-on-error          stop processing at the first error",
    438     "-interaction=STRING     set interaction mode (STRING=batchmode/nonstopmode/\n".
    439     "                           scrollmode/errorstopmode)",
    440     "-ipc                    send DVI output to a socket as well as the usual\n".
    441     "                           output file",
    442     "-ipc-start              as -ipc, and also start the server at the other end",
    443     "-kpathsea-debug=NUMBER  set path searching debugging flags according to\n".
    444     "                           the bits of NUMBER",
    445     "-mktex=FMT              enable mktexFMT generation (FMT=tex/tfm/pk)",
    446     "-no-mktex=FMT           disable mktexFMT generation (FMT=tex/tfm/pk)",
    447     "-mltex                  enable MLTeX extensions such as \charsubdef",
    448     "-output-comment=STRING  use STRING for DVI file comment instead of date\n".
    449     "                           (no effect for PDF)",
    450     "-output-format=FORMAT   use FORMAT for job output; FORMAT is `dvi\" or `pdf\"",
    451     "-parse-first-line       enable parsing of first line of input file",
    452     "-no-parse-first-line    disable parsing of first line of input file",
    453     "-progname=STRING        set program (and fmt) name to STRING",
    454     "-shell-escape           enable \\write18{SHELL COMMAND}",
    455     "-no-shell-escape        disable \\write18{SHELL COMMAND}",
    456     "-shell-restricted       enable restricted \\write18",
    457     "-src-specials           insert source specials into the DVI file",
    458     "-src-specials=WHERE     insert source specials in certain places of\n".
    459     "                           the DVI file. WHERE is a comma-separated value\n".
    460     "                           list: cr display hbox math par parend vbox",
    461     "-synctex=NUMBER         generate SyncTeX data for previewers if nonzero",
    462     "-translate-file=TCXNAME use the TCX file TCXNAME",
    463     "-8bit                   make all characters printable by default",
    464 
    465   #####
    466   # MikTeX options not in TeXLive
    467     "-alias=app              pretend to be app",
    468     "-buf-size=n             maximum number of characters simultaneously present\n".
    469     "                           in current lines",
    470     "-c-style-errors         C-style error messages",
    471     "-disable-installer      disable automatic installation of missing packages",
    472     "-disable-pipes          disable input (output) from (to) child processes",
    473     "-disable-write18        disable the \\write18{command} construct",
    474     "-dont-parse-first-line  disable checking whether the first line of the main\n".
    475     "                           input file starts with %&",
    476     "-enable-enctex          enable encTeX extensions such as \\mubyte",
    477     "-enable-installer       enable automatic installation of missing packages",
    478     "-enable-mltex           enable MLTeX extensions such as \charsubdef",
    479     "-enable-pipes           enable input (output) from (to) child processes",
    480     "-enable-write18         fully enable the \\write18{command} construct",
    481     "-error-line=n           set the width of context lines on terminal error\n".
    482     "                           messages",
    483     "-extra-mem-bot=n        set the extra size (in memory words) for large data\n".
    484     "                           structures",
    485     "-extra-mem-top=n        set the extra size (in memory words) for chars,\n".
    486     "                           tokens, et al",
    487     "-font-max=n             set the maximum internal font number",
    488     "-font-mem-size=n        set the size, in TeX memory words, of the font memory",
    489     "-half-error-line=n      set the width of first lines of contexts in terminal\n".
    490     "                           error messages",
    491     "-hash-extra=n           set the extra space for the hash table of control\n".
    492     "                           sequences",
    493     "-job-time=file          set the time-stamp of all output files equal to\n".
    494     "                           file's time-stamp",
    495     "-main-memory=n          change the total size (in memory words) of the main\n".
    496     "                           memory array",
    497     "-max-in-open=n          set the maximum number of input files and error\n".
    498     "                           insertions that can be going on simultaneously",
    499     "-max-print-line=n       set the width of longest text lines output",
    500     "-max-strings=n          set the maximum number of strings",
    501     "-nest-size=n            set the maximum number of semantic levels\n".
    502     "                           simultaneously active",
    503     "-no-c-style-errors      standard error messages",
    504     "-param-size=n           set the the maximum number of simultaneous macro\n".
    505     "                           parameters",
    506     "-pool-size=n            set the maximum number of characters in strings",
    507     "-record-package-usages=file record all package usages and write them into\n".
    508     "                           file",
    509     "-restrict-write18       partially enable the \\write18{command} construct",
    510     "-save-size=n            set the the amount of space for saving values\n".
    511     "                           outside of current group",
    512     "-stack-size=n           set the maximum number of simultaneous input sources",
    513     "-string-vacancies=n     set the minimum number of characters that should be\n".
    514     "                           available for the user's control sequences and font\n".
    515     "                           names",
    516     "-tcx=name               process the TCX table name",
    517     "-time-statistics        show processing time statistics",
    518     "-trace                  enable trace messages",
    519     "-trace=tracestreams     enable trace messages. The tracestreams argument is\n".
    520     "                           a comma-separated list of trace stream names",
    521     "-trie-size=n            set the amount of space for hyphenation patterns",
    522     "-undump=name            use name as the name of the format to be used,\n".
    523     "                           instead of the name by which the program was\n".
    524     "                           called or a %& line.",
    525 
    526   #####
    527     # Options passed to (pdf)latex that have special processing by latexmk,
    528     #   so they are commented out here.
    529     #-jobname=STRING         set the job name to STRING
    530     #-aux-directory=dir    Set the directory dir to which auxiliary files are written
    531     #-output-directory=DIR   use existing DIR as the directory to write files in
    532     #-quiet
    533     #-recorder               enable filename recorder
    534     #
    535     # Options with different processing by latexmk than (pdf)latex
    536     #-help
    537     #-version
    538     #
    539     # Options NOT used by latexmk
    540     #-includedirectory=dir    prefix dir to the search path
    541     #-initialize              become the INI variant of the compiler
    542     #-ini                     be pdfinitex, for dumping formats; this is implicitly
    543     #                          true if the program name is `pdfinitex'
    544 ) {
    545     if ( /^([^\s=]+)=/ ) {
    546         $allowed_latex_options_with_arg{$1} = $_;
    547     }
    548     elsif ( /^([^\s=]+)\s/ ) {
    549         $allowed_latex_options{$1} = $_;
    550     }
    551     else {
    552         $allowed_latex_options{$_} = $_;
    553     }
    554 }
    555 
    556 # Arrays of options that will be added to latex and pdflatex.
    557 # These need to be stored until after the command line parsing is finished,
    558 #  in case the values of $latex and/or $pdflatex change after an option
    559 #  is added.
    560 @extra_latex_options = ();
    561 @extra_pdflatex_options = ();
    562 @extra_lualatex_options = ();
    563 @extra_xelatex_options = ();
    564 
    565 
    566 ## Command to invoke biber & bibtex
    567 $biber  = 'biber %O %B';
    568 $bibtex  = 'bibtex %O %B';
    569 # Switch(es) to make biber & bibtex silent:
    570 $bibtex_fudge = 1; # Use hack to get bibtex working in old versions that
    571                    #    don't handle output-directory.
    572 $biber_silent_switch  = '--onlylog';
    573 $bibtex_silent_switch  = '-terse';
    574 $bibtex_use = 1;   # Whether to actually run bibtex to update bbl files.
    575                    # This variable is also used in deciding whether to
    576                    #   delete bbl files in clean up operations.
    577                    # 0:  Never run bibtex.
    578                    #     Do NOT delete bbl files on clean up.
    579                    # 1:  Run bibtex only if the bibfiles exists 
    580                    #     according to kpsewhich, and the bbl files
    581                    #     appear to be out-of-date.
    582                    #     Do NOT delete bbl files on clean up.
    583                    # 1.5:  Run bibtex only if the bibfiles exists 
    584                    #     according to kpsewhich, and the bbl files
    585                    #     appear to be out-of-date.
    586                    #     Only delete bbl files on clean up if bibfiles exist.
    587                    # 2:  Run bibtex when the bbl files are out-of-date
    588                    #     Delete bbl files on clean up.
    589                    #
    590                    # In any event bibtex is only run if the log file
    591                    #   indicates that the document uses bbl files.
    592 
    593 ## Command to invoke makeindex
    594 $makeindex  = 'makeindex %O -o %D %S';
    595 # Switch(es) to make makeinex silent:
    596 $makeindex_silent_switch  = '-q';
    597 
    598 ## Command to convert dvi file to pdf file directly:
    599 $dvipdf  = 'dvipdf %O %S %D';
    600 # N.B. Standard dvipdf runs dvips and gs with their silent switch, so for
    601 #      standard dvipdf $dvipdf_silent_switch is unneeded, but innocuous. 
    602 #      But dvipdfmx can be used instead, and it has a silent switch (-q).
    603 #      So implementing $dvipdf_silent_switch is useful.
    604 
    605 $dvipdf_silent_switch  = '-q';
    606 
    607 ## Command to convert dvi file to ps file:
    608 $dvips  = 'dvips %O -o %D %S';
    609 ## Command to convert dvi file to ps file in landscape format:
    610 $dvips_landscape = 'dvips -tlandscape %O -o %D %S';
    611 # Switch(es) to get dvips to make ps file suitable for conversion to good pdf:
    612 #    (If this is not used, ps file and hence pdf file contains bitmap fonts
    613 #       (type 3), which look horrible under acroread.  An appropriate switch
    614 #       ensures type 1 fonts are generated.  You can put this switch in the 
    615 #       dvips command if you prefer.)
    616 $dvips_pdf_switch = '-P pdf';
    617 # Switch(es) to make dvips silent:
    618 $dvips_silent_switch  = '-q';
    619 
    620 ## Command to convert ps file to pdf file:
    621 $ps2pdf = 'ps2pdf  %O %S %D';
    622 
    623 ## Command to convert xdv file to pdf file
    624 $xdvipdfmx  = 'xdvipdfmx -o %D %O %S';
    625 $xdvipdfmx_silent_switch  = '-q';
    626 
    627 
    628 ## Command to search for tex-related files
    629 $kpsewhich = 'kpsewhich %S';
    630 
    631 ## Command to run make:
    632 $make = 'make';
    633 
    634 ##Printing:
    635 $print_type = 'auto';   # When printing, print the postscript file.
    636                         # Possible values: 'dvi', 'ps', 'pdf', 'auto', 'none'
    637                         # 'auto' ==> set print type according to the printable
    638                         # file(s) being made: priority 'ps', 'pdf', 'dvi'
    639 
    640 ## Which treatment of default extensions and filenames with
    641 ##   multiple extensions is used, for given filename on
    642 ##   tex/latex's command line?  See sub find_basename for the
    643 ##   possibilities. 
    644 ## Current tex's treat extensions like UNIX teTeX:
    645 $extension_treatment = 'unix';
    646 
    647 # Viewers.  These are system dependent, so default to none:
    648 $pdf_previewer = $ps_previewer  = $ps_previewer_landscape  = $dvi_previewer  = $dvi_previewer_landscape = "NONE";
    649 
    650 $dvi_update_signal = undef;
    651 $ps_update_signal = undef;
    652 $pdf_update_signal = undef;
    653 
    654 $dvi_update_command = undef;
    655 $ps_update_command = undef;
    656 $pdf_update_command = undef;
    657 
    658 $allow_subdir_creation = 1;
    659 
    660 $new_viewer_always = 0;     # If 1, always open a new viewer in pvc mode.
    661                             # If 0, only open a new viewer if no previous
    662                             #     viewer for the same file is detected.
    663 
    664 # Commands for use in pvc mode for compiling, success, warnings, and failure;
    665 # they default to empty, i.e., not to use:
    666 $compiling_cmd = $success_cmd = $warning_cmd = $failure_cmd = "";
    667 
    668 # Commands for printing are highly system dependent, so default to NONE:
    669 $lpr = 'NONE $lpr variable is not configured to allow printing of ps files';
    670 $lpr_dvi = 'NONE $lpr_dvi variable is not configured to allow printing of dvi files';
    671 $lpr_pdf = 'NONE $lpr_pdf variable is not configured to allow printing of pdf files';
    672 
    673 
    674 # The $pscmd below holds a **system-dependent** command to list running
    675 # processes.  It is used to find the process ID of the viewer looking at
    676 # the current output file.  The output of the command must include the
    677 # process number and the command line of the processes, since the
    678 # relevant process is identified by the name of file to be viewed.
    679 # Its use is not essential.
    680 $pscmd =  'NONE $pscmd variable is not configured to detect running processes';
    681 $pid_position = -1;     # offset of PID in output of pscmd.  
    682                         # Negative means I cannot use ps
    683 
    684 
    685 $quote_filenames = 1;       # Quote filenames in external commands
    686 
    687 $del_dir = '';        # Directory into which cleaned up files are to be put.
    688                       # If $del_dir is '', just delete the files
    689 
    690 @rc_system_files = ();
    691 
    692 #########################################################################
    693 
    694 ################################################################
    695 ##  Special variables for system-dependent fudges, etc.
    696 $log_file_binary = 0;   # Whether to treat log file as binary
    697                         # Normally not, since the log file SHOULD be pure text.
    698                         # But Miktex 2.7 sometimes puts binary characters
    699                         #    in it.  (Typically in construct \OML ... after
    700                         #    overfull box with mathmode.)
    701                         # Sometimes there is ctrl/Z, which is not only non-text, 
    702                         #    but is end-of-file marker for MS-Win in text mode.  
    703 
    704 $MSWin_fudge_break = 1; # Give special treatment to ctrl/C and ctrl/break
    705                         #    in -pvc mode under MSWin
    706                         # Under MSWin32 (at least with perl 5.8 and WinXP)
    707                         #   when latexmk is running another program, and the 
    708                         #   user gives ctrl/C or ctrl/break, to stop the 
    709                         #   daughter program, not only does it reach
    710                         #   the daughter, but also latexmk/perl, so
    711                         #   latexmk is stopped also.  In -pvc mode,
    712                         #   this is not normally desired.  So when the
    713                         #   $MSWin_fudge_break variable is set,
    714                         #   latexmk arranges to ignore ctrl/C and
    715                         #   ctrl/break during processing of files;
    716                         #   only the daughter programs receive them.
    717                         # This fudge is not applied in other
    718                         #   situations, since then having latexmk also
    719                         #   stopping because of the ctrl/C or
    720                         #   ctrl/break signal is desirable.
    721                         # The fudge is not needed under UNIX (at least
    722                         #   with Perl 5.005 on Solaris 8).  Only the
    723                         #   daughter programs receive the signal.  In
    724                         #   fact the inverse would be useful: In
    725                         #   normal processing, as opposed to -pvc, if
    726                         #   force mode (-f) is set, a ctrl/C is
    727                         #   received by a daughter program does not
    728                         #   also stop latexmk.  Under tcsh, we get
    729                         #   back to a command prompt, while latexmk
    730                         #   keeps running in the background!
    731 
    732 ## Substitute backslashes in file and directory names for
    733 ##  MSWin command line
    734 $MSWin_back_slash = 1;
    735 
    736 ## Separator of elements in search_path.  Default is unix value
    737 $search_path_separator = ':'; 
    738 
    739 
    740 # Directory for temporary files.  Default to current directory.
    741 $tmpdir = ".";
    742 
    743 
    744 # When the aux_dir is on a network share (or the like), its system
    745 # time may differ from the system time on which latexmk is running.
    746 # This complicates the tests of whether particular files have been
    747 # made in a current run of a program or are left over from a previous
    748 # run.  One test, which is needed under some situations, is that a
    749 # file was made on a previous run when the files modification time is
    750 # less than the system time when the program is started.  (See
    751 # subroutine test_gen_file; this is only needed in a couple of
    752 # situations.)  The comparison between file and system times must be
    753 # corrected if there is an offset between system times on the computer
    754 # running latexmk and the computer hosting the file system containing
    755 # aux_dir.  The offset is measured in subroutine get_filetime_offset
    756 # by writing a temporary file; the test only needs to be done once.
    757 #
    758 # The following variables are used.  Since the system-independent
    759 # values of system and file time are only accurate to a second (or 2
    760 # seconds for FAT file systems), the offset is also accurate only to a
    761 # second or two.  So thresholds are needed below which differences
    762 # are insignificant.
    763 #
    764 # Note that the making or not making of a file is controlled by the
    765 # state of the document being compiled and by latexmk's configuration.
    766 # So a file that is left over from a previous run and not overwritten
    767 # on the current run will have a file time at least many seconds less
    768 # than the current time, corresponding to the time scale for a human
    769 # run-edit-run cycle.
    770 #
    771 $filetime_offset_measured = 0;       # Measurement not yet done.
    772 $filetime_offset = 0;                # Filetime relative to system time.
    773 $filetime_causality_threshold = 5;   # Threshold for detection of left-over file.
    774                                      # Should be non-negative always, and should
    775                                      # be bigger than 2 secs if a remote
    776                                      # filesystem or network share is used.
    777 $filetime_offset_report_threshold = 30; # Threshold beyond which filetime offsets
    778                                      # are reported; large offsets indicate
    779                                      # incorrect system time on at least one system.
    780 
    781 
    782 ################################################################
    783 
    784 
    785 # System-dependent overrides:
    786 # Currently, the cases I have tests for are: MSWin32, cygwin, linux and 
    787 #   darwin, msys, with the main complications being for MSWin32 and cygwin.
    788 # Further special treatment may also be useful for MSYS (for which $^O reports 
    789 #   "msys").  This is another *nix-emulation/system for MSWindows.  At
    790 #   present it is treated as unix-like, but the environment variables
    791 #   are those of Windows.  (The test for USERNAME as well as USER was
    792 #   to make latexmk work under MSYS's perl.)
    793 #
    794 if ( $^O eq "MSWin32" ) {
    795 # Pure MSWindows configuration
    796     ## Configuration parameters:
    797 
    798     ## Use first existing case for $tmpdir:
    799     $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.';
    800     $log_file_binary = 1;   # Protect against ctrl/Z in log file from
    801                             # Miktex 2.7.
    802 
    803     ## List of possibilities for the system-wide initialization file.  
    804     ## The first one found (if any) is used.
    805     @rc_system_files = ( "C:/latexmk/LatexMk", "C:/latexmk/latexmkrc" );
    806 
    807     $search_path_separator = ';';  # Separator of elements in search_path
    808 
    809     # For a pdf-file, "start x.pdf" starts the pdf viewer associated with
    810     #   pdf files, so no program name is needed:
    811     $pdf_previewer = 'start %O %S';
    812     $ps_previewer  = 'start %O %S';
    813     $ps_previewer_landscape  = $ps_previewer;
    814     $dvi_previewer  = 'start %O %S';
    815     $dvi_previewer_landscape = "$dvi_previewer";
    816     # Viewer update methods: 
    817     #    0 => auto update: viewer watches file (e.g., gv)
    818     #    1 => manual update: user must do something: e.g., click on window.
    819     #         (e.g., ghostview, MSWIN previewers, acroread under UNIX)
    820     #    2 => send signal.  Number of signal in $dvi_update_signal,
    821     #                         $ps_update_signal, $pdf_update_signal
    822     #    3 => viewer can't update, because it locks the file and the file 
    823     #         cannot be updated.  (acroread under MSWIN)
    824     #    4 => run a command to force the update.  The commands are 
    825     #         specified by the variables $dvi_update_command, 
    826     #         $ps_update_command, $pdf_update_command
    827     $dvi_update_method = 1;
    828     $ps_update_method = 1;
    829     $pdf_update_method = 3; # acroread locks the pdf file
    830 }
    831 elsif ( $^O eq "cygwin" ) {
    832     # The problem is a mixed MSWin32 and UNIX environment. 
    833     # Perl decides the OS is cygwin in two situations:
    834     # 1. When latexmk is run from a cygwin shell under a cygwin
    835     #    environment.  Perl behaves in a UNIX way.  This is OK, since
    836     #    the user is presumably expecting UNIXy behavior.  
    837     # 2. When CYGWIN exectuables are in the path, but latexmk is run
    838     #    from a native NT shell.  Presumably the user is expecting NT
    839     #    behavior. But perl behaves more UNIXy.  This causes some
    840     #    clashes. 
    841     # The issues to handle are:
    842     # 1.  Perl sees both MSWin32 and cygwin filenames.  This is 
    843     #     normally only an advantage.
    844     # 2.  Perl uses a UNIX shell in the system command
    845     #     This is a nasty problem: under native NT, there is a
    846     #     start command that knows about NT file associations, so that
    847     #     we can do, e.g., (under native NT) system("start file.pdf");
    848     #     But this won't work when perl has decided the OS is cygwin,
    849     #     even if it is invoked from a native NT command line.  An
    850     #     NT command processor must be used to deal with this.
    851     # 3.  External executables can be native NT (which only know
    852     #     NT-style file names) or cygwin executables (which normally
    853     #     know both cygwin UNIX-style file names and NT file names,
    854     #     but not always; some do not know about drive names, for
    855     #     example).
    856     #     Cygwin executables for tex and latex may only know cygwin
    857     #     filenames. 
    858     # 4.  The BIBINPUTS environment variables may be
    859     #     UNIX-style or MSWin-style depending on whether native NT or
    860     #     cygwin executables are used.  They are therefore parsed
    861     #     differently.  Here is the clash:
    862     #        a. If a user is running under an NT shell, is using a
    863     #           native NT installation of tex (e.g., fptex or miktex),
    864     #           but has the cygwin executables in the path, then perl
    865     #           detects the OS as cygwin, but the user needs NT
    866     #           behavior from latexmk.
    867     #        b. If a user is running under an UNIX shell in a cygwin
    868     #           environment, and is using the cygwin installation of
    869     #           tex, then perl detects the OS as cygwin, and the user
    870     #           needs UNIX behavior from latexmk.
    871     #     Latexmk has no way of detecting the difference.  The two
    872     #     situations may even arise for the same user on the same
    873     #     computer simply by changing the order of directories in the
    874     #     path environment variable
    875 
    876 
    877     ## Configuration parameters: We'll assume native NT executables.
    878     ## The user should override if they are not.
    879 
    880     # This may fail: perl converts MSWin temp directory name to cygwin
    881     # format. Names containing this string cannot be handled by native
    882     # NT executables.
    883     $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.';
    884 
    885     ## List of possibilities for the system-wide initialization file.  
    886     ## The first one found (if any) is used.
    887     ## We could stay with MSWin files here, since cygwin perl understands them
    888     ## @rc_system_files = ( 'C:/latexmk/LatexMk', 'C:/latexmk/latexmkrc' );
    889     ## But they are deprecated in v. 1.7.  So use the UNIX version, prefixed
    890     ##   with a cygwin equivalent of the MSWin location
    891     ## In addition, we need to add the same set of possible locations as with
    892     ## unix, so that the user use a unix-style setup.
    893     @rc_system_files = ();
    894     foreach ( 'LatexMk', 'latexmkrc' ) {
    895        push @rc_system_files,
    896             ( "/cygdrive/c/latexmk/$_", 
    897               "/opt/local/share/latexmk/$_", 
    898               "/usr/local/share/latexmk/$_",
    899               "/usr/local/lib/latexmk/$_" );
    900     }
    901     $search_path_separator = ';';  # Separator of elements in search_path
    902     # This is tricky.  The search_path_separator depends on the kind
    903     # of executable: native NT v. cygwin.  
    904     # So the user will have to override this.
    905 
    906     # We will assume that files can be viewed by native NT programs.
    907     #  Then we must fix the start command/directive, so that the
    908     #  NT-native start command of a cmd.exe is used.
    909     # For a pdf-file, "start x.pdf" starts the pdf viewer associated with
    910     #   pdf files, so no program name is needed:
    911     $start_NT = "cmd /c start \"\"";
    912     $pdf_previewer = "$start_NT %O %S";
    913     $ps_previewer  = "$start_NT %O %S";
    914     $ps_previewer_landscape  = $ps_previewer;
    915     $dvi_previewer  = "$start_NT %O %S";
    916     $dvi_previewer_landscape = $dvi_previewer;
    917     # Viewer update methods: 
    918     #    0 => auto update: viewer watches file (e.g., gv)
    919     #    1 => manual update: user must do something: e.g., click on window.
    920     #         (e.g., ghostview, MSWIN previewers, acroread under UNIX)
    921     #    2 => send signal.  Number of signal in $dvi_update_signal,
    922     #                         $ps_update_signal, $pdf_update_signal
    923     #    3 => viewer can't update, because it locks the file and the file 
    924     #         cannot be updated.  (acroread under MSWIN)
    925     $dvi_update_method = 1;
    926     $ps_update_method = 1;
    927     $pdf_update_method = 3; # acroread locks the pdf file
    928 }
    929 elsif ( $^O eq "msys" ) {
    930     $search_path_separator = ';';  # Separator of elements in search_path
    931                                    # I think MS-Win value is OK, since
    932                                    # msys is running under MS-Win
    933     $pdf_previewer = q[sh -c 'start %S'];
    934     $ps_previewer = q[sh -c 'start %S'];
    935     $dvi_previewer = q[sh -c 'start %S'];
    936     $ps_previewer_landscape  = $ps_previewer;
    937     $dvi_previewer_landscape = "$dvi_previewer";
    938 }
    939 else {
    940     # Assume anything else is UNIX or clone
    941     # Do special cases (e.g., linux, darwin (i.e., OS-X)) inside this block.
    942 
    943     ## Use first existing case for $tmpdir:
    944     $tmpdir = $ENV{TMPDIR} || '/tmp';
    945 
    946     ## List of possibilities for the system-wide initialization file.  
    947     ## The first one found (if any) is used.
    948     ## Normally on a UNIX it will be in a subdirectory of /opt/local/share or
    949     ## /usr/local/share, depending on the local conventions.
    950     ## But /usr/local/lib/latexmk is put in the list for
    951     ## compatibility with older versions of latexmk.
    952     @rc_system_files = ();
    953     foreach ( 'LatexMk', 'latexmkrc' ) {
    954        push @rc_system_files,
    955             ( "/opt/local/share/latexmk/$_", 
    956               "/usr/local/share/latexmk/$_",
    957               "/usr/local/lib/latexmk/$_" );
    958     }
    959     $search_path_separator = ':';  # Separator of elements in search_path
    960 
    961     $dvi_update_signal = $signo{USR1} 
    962          if ( defined $signo{USR1} ); # Suitable for xdvi
    963     $ps_update_signal = $signo{HUP} 
    964          if ( defined $signo{HUP} );  # Suitable for gv
    965     $pdf_update_signal = $signo{HUP} 
    966          if ( defined $signo{HUP} );  # Suitable for gv
    967     ## default document processing programs.
    968     # Viewer update methods: 
    969     #    0 => auto update: viewer watches file (e.g., gv)
    970     #    1 => manual update: user must do something: e.g., click on window.
    971     #         (e.g., ghostview, MSWIN previewers, acroread under UNIX)
    972     #    2 => send signal.  Number of signal in $dvi_update_signal,
    973     #                         $ps_update_signal, $pdf_update_signal
    974     #    3 => viewer can't update, because it locks the file and the file 
    975     #         cannot be updated.  (acroread under MSWIN)
    976     #    4 => Run command to update.  Command in $dvi_update_command, 
    977     #    $ps_update_command, $pdf_update_command.
    978     $dvi_previewer  = 'start xdvi %O %S';
    979     $dvi_previewer_landscape = 'start xdvi -paper usr %O %S';
    980     if ( defined $dvi_update_signal ) { 
    981         $dvi_update_method = 2;  # xdvi responds to signal to update
    982     } else {
    983         $dvi_update_method = 1;  
    984     }
    985 #    if ( defined $ps_update_signal ) { 
    986 #        $ps_update_method = 2;  # gv responds to signal to update
    987 #        $ps_previewer  = 'start gv -nowatch';
    988 #        $ps_previewer_landscape  = 'start gv -swap -nowatch';
    989 #    } else {
    990 #        $ps_update_method = 0;  # gv -watch watches the ps file
    991 #        $ps_previewer  = 'start gv -watch';
    992 #        $ps_previewer_landscape  = 'start gv -swap -watch';
    993 #    }
    994     # Turn off the fancy options for gv.  Regular gv likes -watch etc
    995     #   GNU gv likes --watch etc.  User must configure
    996     $ps_update_method = 0;  # gv -watch watches the ps file
    997     $ps_previewer  = 'start gv %O %S';
    998     $ps_previewer_landscape  = 'start gv -swap %O %S';
    999     $pdf_previewer = 'start acroread %O %S';
   1000     $pdf_update_method = 1;  # acroread under unix needs manual update
   1001     $lpr = 'lpr %O %S';         # Assume lpr command prints postscript files correctly
   1002     $lpr_dvi =
   1003         'NONE $lpr_dvi variable is not configured to allow printing of dvi files';
   1004     $lpr_pdf =
   1005         'NONE $lpr_pdf variable is not configured to allow printing of pdf files';
   1006     # The $pscmd below holds a command to list running processes.  It
   1007     # is used to find the process ID of the viewer looking at the
   1008     # current output file.  The output of the command must include the
   1009     # process number and the command line of the processes, since the
   1010     # relevant process is identified by the name of file to be viewed.
   1011     # Uses:
   1012     #   1.  In preview_continuous mode, to save running a previewer
   1013     #       when one is already running on the relevant file.
   1014     #   2.  With xdvi in preview_continuous mode, xdvi must be
   1015     #       signalled to make it read a new dvi file.
   1016     #
   1017     # The following works on Solaris, LINUX, HP-UX, IRIX
   1018     # Use -f to get full listing, including command line arguments.
   1019     # Use -u $ENV{USER} to get all processes started by current user (not just
   1020     #   those associated with current terminal), but none of other users' 
   1021     #   processes. 
   1022     # However, the USER environment variable may not exist.  Windows uses 
   1023     #   USERNAME instead.  (And this propagates to a situation of 
   1024     #   unix-emulation software running under Windows.) 
   1025     if ( exists $ENV{USER} ) {
   1026        $pscmd = "ps -f -u $ENV{USER}"; 
   1027     }
   1028     elsif ( exists $ENV{USERNAME} ) {
   1029        $pscmd = "ps -f -u $ENV{USERNAME}"; 
   1030     }
   1031     else {
   1032        $pscmd = "ps -f"; 
   1033     }
   1034     $pid_position = 1; # offset of PID in output of pscmd; first item is 0.  
   1035     if ( $^O eq "linux" ) {
   1036         # Ps on Redhat (at least v. 7.2) appears to truncate its output
   1037         #    at 80 cols, so that a long command string is truncated.
   1038         # Fix this with the --width option.  This option works under 
   1039         #    other versions of linux even if not necessary (at least 
   1040         #    for SUSE 7.2). 
   1041         # However the option is not available under other UNIX-type 
   1042         #    systems, e.g., Solaris 8.
   1043         # But (19 Aug 2010), the truncation doesn't happen on RHEL4 and 5,
   1044         #    unless the output is written to a terminal.  So the --width 
   1045         #    option is now unnecessary
   1046         # $pscmd = "ps --width 200 -f -u $ENV{USER}"; 
   1047     }
   1048     elsif ( $^O eq "darwin" ) {
   1049         # OS-X on Macintosh
   1050         # open starts command associated with a file.
   1051         # For pdf, this is set by default to OS-X's preview, which is suitable.
   1052         #     Manual update is simply by clicking on window etc, which is OK.
   1053         # For ps, this is set also to preview.  This works, but since it
   1054         #     converts the file to pdf and views the pdf file, it doesn't
   1055         #     see updates, and a refresh cannot be done.  This is far from
   1056         #     optimal.
   1057         # For a full installation of MacTeX, which is probably the most common
   1058         #     on OS-X, an association is created between dvi files and TeXShop.
   1059         #     This also converts the file to pdf, so again while it works, it
   1060         #     does not deal with changed dvi files, as far as I can see.
   1061         $pdf_previewer = 'open %S';
   1062         $pdf_update_method = 1;     # manual
   1063         $dvi_previewer = $dvi_previewer_landscape = 'NONE';
   1064         $ps_previewer = $ps_previewer_landscape = 'NONE';
   1065         # Others
   1066         $lpr_pdf  = 'lpr %O %S';
   1067         $pscmd = "ps -ww -u $ENV{USER}"; 
   1068     }
   1069 }
   1070 
   1071 ## default parameters
   1072 $auto_rc_use = 1;       # Whether to read rc files automatically
   1073 $max_repeat = 5;        # Maximum times I repeat latex.  Normally
   1074                         # 3 would be sufficient: 1st run generates aux file,
   1075                         # 2nd run picks up aux file, and maybe toc, lof which 
   1076                         # contain out-of-date information, e.g., wrong page
   1077                         # references in toc, lof and index, and unresolved
   1078                         # references in the middle of lines.  But the 
   1079                         # formatting is more-or-less correct.  On the 3rd
   1080                         # run, the page refs etc in toc, lof, etc are about
   1081                         # correct, but some slight formatting changes may
   1082                         # occur, which mess up page numbers in the toc and lof,
   1083                         # Hence a 4th run is conceivably necessary. 
   1084                         # At least one document class (JHEP.cls) works
   1085                         # in such a way that a 4th run is needed.  
   1086                         # We allow an extra run for safety for a
   1087                         # maximum of 5. Needing further runs is
   1088                         # usually an indication of a problem; further
   1089                         # runs may not resolve the problem, and
   1090                         # instead could cause an infinite loop.
   1091 $clean_ext = "";        # space separated extensions of files that are
   1092                         # to be deleted when doing cleanup, beyond
   1093                         # standard set
   1094 $clean_full_ext = "";   # space separated extensions of files that are
   1095                         # to be deleted when doing cleanup_full, beyond
   1096                         # standard set and those in $clean_ext
   1097 @cus_dep_list = ();     # Custom dependency list
   1098 @default_files = ( '*.tex' );   # Array of LaTeX files to process when 
   1099                         # no files are specified on the command line.
   1100                         # Wildcards allowed
   1101                         # Best used for project specific files.
   1102 @default_excluded_files = ( );   
   1103                         # Array of LaTeX files to exclude when using
   1104                         # @default_files, i.e., when no files are specified
   1105                         # on the command line.
   1106                         # Wildcards allowed
   1107                         # Best used for project specific files.
   1108 $texfile_search = "";   # Specification for extra files to search for
   1109                         # when no files are specified on the command line
   1110                         # and the @default_files variable is empty.
   1111                         # Space separated, and wildcards allowed.
   1112                         # These files are IN ADDITION to *.tex in current 
   1113                         # directory. 
   1114                         # This variable is obsolete, and only in here for
   1115                         # backward compatibility.
   1116 
   1117 $fdb_ext = 'fdb_latexmk'; # Extension for the file for latexmk's
   1118                           # file-database
   1119                           # Make it long to avoid possible collisions.
   1120 $fdb_ver = 3;             # Version number for kind of fdb_file.
   1121 
   1122 $jobname = '';          # Jobname: as with current tex, etc indicates
   1123                         # basename of generated files.
   1124                         # Defined so that --jobname=STRING on latexmk's
   1125                         # command line has same effect as with current
   1126                         # tex, etc.  (If $jobname is non-empty, then
   1127                         # the --jobname=... option is used on tex.)
   1128 $out_dir = '';          # Directory for output files.  
   1129                         # Cf. --output-directory of current (pdf)latex
   1130 $aux_dir = '';          # Directory for aux files (log, aux, etc).
   1131                         # Cf. --aux-directory of current (pdf)latex in MiKTeX.
   1132 
   1133 
   1134 ## default flag settings.
   1135 $recorder = 1;          # Whether to use recorder option on latex/pdflatex
   1136 $silent = 0;            # Silence latex's messages?
   1137 $warnings_as_errors = 0;# Treat warnings as errors and exit with non-zero exit code
   1138 $silence_logfile_warnings = 0; # Do list warnings in log file
   1139 $kpsewhich_show = 0;    # Show calls to and results from kpsewhich
   1140 $landscape_mode = 0;    # default to portrait mode
   1141 $analyze_input_log_always = 1; # Always analyze .log for input files in the
   1142                         #  <...> and (...) constructions.  Otherwise, only
   1143                         # do the analysis when fls file doesn't exist or is
   1144                         # out of date.
   1145                         # Under normal circumstances, the data in the fls file
   1146                         # is reliable, and the test of the log file gets lots
   1147                         # of false positives; usually $analyze_input_log_always
   1148                         # is best set to zero.  But the test of the log file
   1149                         # is needed at least in the following situation:
   1150                         # When a user needs to persuade latexmk that a certain
   1151                         # file is a source file, and latexmk doesn't otherwise
   1152                         # find it.  User code causes line with (...) to be
   1153                         # written to log file.  One important case is for 
   1154                         # lualatex, which doesn't always generate lines in the
   1155                         # .fls file for input lua files.  (The situation with
   1156                         # lualatex is HIGHLY version dependent, e.g., between
   1157                         # 2016 and 2017.)
   1158                         # To keep backward compatibility with older versions
   1159                         # of latexmk, the default is to set
   1160                         # $analyze_input_log_always to 1.
   1161 
   1162 # The following two arrays contain lists of extensions (without
   1163 # period) for files that are read in during a (pdf)LaTeX run but that
   1164 # are generated automatically from the previous run, as opposed to
   1165 # being user generated files (directly or indirectly from a custom
   1166 # dependency).  These files get two kinds of special treatment:
   1167 #     1.  In clean up, where depending on the kind of clean up, some
   1168 #         or all of these generated files are deleted.
   1169 #         (Note that special treatment is given to aux files.)
   1170 #     2.  In analyzing the results of a run of (pdf)LaTeX, to
   1171 #         determine if another run is needed.  With an error free run,
   1172 #         a rerun should be provoked by a change in any source file,
   1173 #         whether a user file or a generated file.  But with a run
   1174 #         that ends in an error, only a change in a user file during
   1175 #         the run (which might correct the error) should provoke a
   1176 #         rerun, but a change in a generated file should not.
   1177 # These arrays can be user-configured.
   1178 
   1179 @generated_exts = ( 'aux', 'bcf', 'fls', 'idx', 'ind', 'lof', 'lot', 
   1180                     'out', 'toc' );
   1181      # N.B. 'out' is generated by hyperref package
   1182 
   1183 # Which kinds of file do I have requests to make?
   1184 # If no requests at all are made, then I will make dvi file
   1185 # If particular requests are made then other files may also have to be
   1186 # made.  E.g., ps file requires a dvi file
   1187 $dvi_mode = 0;          # No dvi file requested
   1188 $postscript_mode = 0;           # No postscript file requested
   1189 $pdf_mode = 0;          # No pdf file requested to be made by pdflatex
   1190                         # Possible values: 
   1191                         #     0 don't create pdf file
   1192                         #     1 to create pdf file by pdflatex
   1193                         #     2 to create pdf file by ps2pdf
   1194                         #     3 to create pdf file by dvipdf
   1195                         #     4 to create pdf file by lualatex
   1196                         #     5 to create pdf file by xelatex + xdvipdfmx
   1197 $view = 'default';      # Default preview is of highest of dvi, ps, pdf
   1198 $sleep_time = 2;        # time to sleep b/w checks for file changes in -pvc mode
   1199 $banner = 0;            # Non-zero if we have a banner to insert
   1200 $banner_scale = 220;    # Original default scale
   1201 $banner_intensity = 0.95;  # Darkness of the banner message
   1202 $banner_message = 'DRAFT'; # Original default message
   1203 $do_cd = 0;     # Do not do cd to directory of source file.
   1204                 #   Thus behave like latex.
   1205 $dependents_list = 0;   # Whether to display list(s) of dependencies
   1206 $dependents_phony = 0;  # Whether list(s) of dependencies includes phony targets
   1207                         # (as with 'gcc -MP').
   1208 $deps_file = '-';       # File for dependency list output.  Default stdout.
   1209 $rules_list = 0;        # Whether to display list(s) of dependencies
   1210 @dir_stack = ();        # Stack of pushed directories, each of form of 
   1211                         # pointer to array  [ cwd, good_cwd ], where
   1212                         # good_cwd differs from cwd by being converted
   1213                         # to native MSWin path when cygwin is used.
   1214 $cleanup_mode = 0;      # No cleanup of nonessential LaTex-related files.
   1215                         # $cleanup_mode = 0: no cleanup
   1216                         # $cleanup_mode = 1: full cleanup 
   1217                         # $cleanup_mode = 2: cleanup except for dvi,
   1218                         #                    dviF, pdf, ps, psF & xdv
   1219 $cleanup_fdb  = 0;      # No removal of file for latexmk's file-database
   1220 $cleanup_only = 0;      # When doing cleanup, do not go on to making files
   1221 $cleanup_includes_generated = 0; 
   1222                         # Determines whether cleanup deletes files generated by
   1223                         #    (pdf)latex (found from \openout lines in log file).
   1224                         # It's more than that.  BUG
   1225 $cleanup_includes_cusdep_generated = 0;
   1226                         # Determines whether cleanup deletes files generated by
   1227                         #    custom dependencies
   1228 $diagnostics = 0;
   1229 $dvi_filter = '';       # DVI filter command
   1230 $ps_filter = '';        # Postscript filter command
   1231 
   1232 $force_mode = 0;        # =1 to force processing past errors
   1233 $go_mode = 0;           # =1 to force processing regardless of time-stamps
   1234                         # =2 full clean-up first
   1235 $preview_mode = 0;
   1236 $preview_continuous_mode  = 0;
   1237 $printout_mode = 0;     # Don't print the file
   1238 
   1239 ## Control pvc inactivity timeout:
   1240 $pvc_timeout = 0;
   1241 $pvc_timeout_mins = 30;
   1242 
   1243 $show_time = 0;
   1244 @timings = ();
   1245 $processing_time1 = processing_time();
   1246 
   1247 $use_make_for_missing_files = 0;   # Whether to use make to try to make missing files.
   1248 
   1249 # Do we make view file in temporary then move to final destination?
   1250 #  (To avoid premature updating by viewer).
   1251 $always_view_file_via_temporary = 0;      # Set to 1 if  viewed file is always
   1252                                    #    made through a temporary.
   1253 $pvc_view_file_via_temporary = 1;  # Set to 1 if only in -pvc mode is viewed 
   1254                                    #    file made through a temporary.
   1255 
   1256 # State variables initialized here:
   1257 
   1258 $updated = 0;           # Flags when something has been remade
   1259                         # Used to allow convenient user message in -pvc mode
   1260 $waiting = 0;           # Flags whether we are in loop waiting for an event
   1261                         # Used to avoid unnecessary repeated o/p in wait loop
   1262 
   1263 # The following are used for some results of parsing log file
   1264 # Global variables, so results can be reported in main program. 
   1265 $reference_changed = 0;
   1266 $mult_defined = 0;
   1267 $bad_reference = 0;
   1268 $bad_character = 0;
   1269 $bad_citation = 0;
   1270 @primary_warning_summary = ();
   1271 
   1272 # Cache of expensive-to-compute state variables, e.g., cwd in form
   1273 # fixed to deal with cygwin issues.
   1274 %cache = ();
   1275 &cache_good_cwd;
   1276 
   1277 # Set search paths for includes.
   1278 # Set them early so that they can be overridden
   1279 $BIBINPUTS = $ENV{'BIBINPUTS'};
   1280 if (!$BIBINPUTS) { $BIBINPUTS = '.'; }
   1281 
   1282 # Convert search paths to arrays:
   1283 # If any of the paths end in '//' then recursively search the
   1284 # directory.  After these operations, @BIBINPUTS  should
   1285 # have all the directories that need to be searched
   1286 
   1287 @BIBINPUTS = find_dirs1( $BIBINPUTS );
   1288 
   1289 
   1290 ######################################################################
   1291 ######################################################################
   1292 #
   1293 #  ???  UPDATE THE FOLLOWING!!
   1294 #
   1295 # We will need to determine whether source files for runs of various
   1296 # programs are out of date.  In a normal situation, this is done by
   1297 # asking whether the times of the source files are later than the
   1298 # destination files.  But this won't work for us, since a common
   1299 # situation is that a file is written on one run of latex, for
   1300 # example, and read back in on the next run (e.g., an .aux file).
   1301 # Some situations of this kind are standard in latex generally; others
   1302 # occur with particular macro packages or with particular
   1303 # postprocessors. 
   1304 #
   1305 # The correct criterion for whether a source is out-of-date is
   1306 # therefore NOT that its modification time is later than the
   1307 # destination file, but whether the contents of the source file have
   1308 # changed since the last successful run.  This also handles the case
   1309 # that the user undoes some changes to a source file by replacing the
   1310 # source file by reverting to an earlier version, which may well have
   1311 # an older time stamp.  Since a direct comparison of old and new files
   1312 # would involve storage and access of a large number of backup files,
   1313 # we instead use the md5 signature of the files.  (Previous versions
   1314 # of latexmk used the backup file method, but restricted to the case
   1315 # of .aux and .idx files, sufficient for most, but not all,
   1316 # situations.)
   1317 #
   1318 # We will have a database of (time, size, md5) for the relevant
   1319 # files. If the time and size of a file haven't changed, then the file
   1320 # is assumed not to have changed; this saves us from having to
   1321 # determine its md5 signature, which would involve reading the whole 
   1322 # file, which is naturally time-consuming, especially if network file
   1323 # access to a server is needed, and many files are involved, when most
   1324 # of them don't change.  It is of course possible to change a file
   1325 # without changing its size, but then to adjust its timestamp 
   1326 # to what it was previously; this requires a certain amount of
   1327 # perversity.  We can safely assume that if the user edits a file or
   1328 # changes its contents, then the file's timestamp changes.  The
   1329 # interesting case is that the timestamp does change, because the file
   1330 # has actually been written to, but that the contents do not change;
   1331 # it is for this that we use the md5 signature.  However, since
   1332 # computing the md5 signature involves reading the whole file, which
   1333 # may be large, we should avoid computing it more than necessary. 
   1334 #
   1335 # So we get the following structure:
   1336 #
   1337 #     1.  For each relevant run (latex, pdflatex, each instance of a
   1338 #         custom dependency) we have a database of the state of the
   1339 #         source files that were last used by the run.
   1340 #     2.  On an initial startup, the database for a primary tex file
   1341 #         is read that was created by a previous run of latex or
   1342 #         pdflatex, if this exists.  
   1343 #     3.  If the file doesn't exist, then the criterion for
   1344 #         out-of-dateness for an initial run is that it goes by file
   1345 #         timestamps, as in previous versions of latexmk, with due
   1346 #         (dis)regard to those files that are known to be generated by
   1347 #         latex and re-read on the next run.
   1348 #     4.  Immediately before a run, the database is updated to
   1349 #         represent the current conditions of the run's source files.
   1350 #     5.  After the run, it is determined whether any of the source
   1351 #         files have changed.  This covers both files written by the
   1352 #         run, which are therefore in a dependency loop, and files that
   1353 #         the user may have updated during the run.  (The last often
   1354 #         happens when latex takes a long time, for a big document,
   1355 #         and the user makes edits before latex has finished.  This is
   1356 #         particularly prevalent when latexmk is used with
   1357 #         preview-continuous mode.)
   1358 #     6.  In the case of latex or pdflatex, the custom dependencies
   1359 #         must also be checked and redone if out-of-date.
   1360 #     7.  If any source files have changed, the run is redone,
   1361 #         starting at step 1.
   1362 #     8.  There is naturally a limit on the number of reruns, to avoid
   1363 #         infinite loops from bugs and from pathological or unforeseen
   1364 #         conditions. 
   1365 #     9.  After the run is done, the run's file database is updated.
   1366 #         (By hypothesis, the sizes and md5s are correct, if the run
   1367 #         is successful.)
   1368 #    10.  To allow reuse of data from previous runs, the file database
   1369 #         is written to a file after every complete set of passes
   1370 #         through latex or pdflatex.  (Note that there is separate
   1371 #         information for latex and pdflatex; the necessary
   1372 #         information won't coincide: Out-of-dateness for the files
   1373 #         for each program concerns the properties of the files when
   1374 #         the other program was run, and the set of source files could
   1375 #         be different, e.g., for graphics files.)  
   1376 #
   1377 # We therefore maintain the following data structures.:
   1378 #
   1379 #     a.  For each run (latex, pdflatex, each custom dependency) a
   1380 #         database is maintained.  This is a hash from filenames to a
   1381 #         reference to an array:  [time, size, md5].  The semantics of
   1382 #         the database is that it represents the state of the source
   1383 #         files used in the run.  During a run it represents the state
   1384 #         immediately before the run; after a run, with all reruns, it
   1385 #         represents the state of the files used, modified by having
   1386 #         the latest timestamps for generated files.
   1387 #     b.  There is a global database for all files, which represents
   1388 #         the current state.  This saves having to recompute the md5
   1389 #         signatures of a changed file used in more than one run
   1390 #         (e.g., latex and pdflatex).
   1391 #     c.  Each of latex and pdflatex has a list of the relevant custom
   1392 #         dependencies. 
   1393 #
   1394 # In all the following a fdb-hash is a hash of the form:
   1395 #                      filename -> [time, size, md5] 
   1396 # If a file is found to disappear, its entry is removed from the hash.
   1397 # In returns from fdb access routines, a size entry of -1 indicates a
   1398 # non-existent file.
   1399 
   1400 
   1401 # List of known rules.  Rule types: primary, 
   1402 #     external (calls program), internal (calls routine), cusdep.
   1403 
   1404 %possible_primaries = ( 'latex'  => 'primary',  'pdflatex'  => 'primary',
   1405                         'lualatex'  => 'primary', 'xelatex'  => 'primary' );
   1406 %primaries = ();    # Hash of rules for primary part of make.  Keys are 
   1407                     # currently 'latex', 'pdflatex' or both; also 'lualatex'
   1408                     # and 'xelatex'.  Value is currently irrelevant.
   1409                     # Use hash for ease of lookup
   1410    # Make remove this later, if use rdb_makeB
   1411 
   1412 # Hashes, whose keys give names of particular kinds of rule.  We use
   1413 # hashes for ease of lookup.
   1414 %possible_one_time = ( 'view' => 1, 'print' => 1, 'update_view' => 1,  );
   1415 %requested_filerules = ();  # Hash for rules corresponding to requested files.  
   1416                     # The keys are the rulenames and the value is 
   1417                     # currently irrelevant.
   1418 %one_time = ();     # Hash for requested one-time-only rules, currently
   1419                     # possible values 'print' and 'view'.  
   1420 
   1421 
   1422 %rule_db = ();      # Database of all rules:
   1423                     # Hash: rulename -> [array of rule data]
   1424                     # Rule data:
   1425                     #   0: [ cmd_type, ext_cmd, int_cmd, test_kind, 
   1426                     #       source, dest, base,
   1427                     #       out_of_date, out_of_date_user,
   1428                     #       time_of_last_run, time_of_last_file_check,
   1429                     #       changed
   1430                     #       last_result, last_message,
   1431                     #       default_extra_generated
   1432                     #      ]
   1433                     # where 
   1434                     #     cmd_type is 'primary', 'external', or 'cusdep'
   1435                     #     ext_cmd is string for associated external command
   1436                     #       with substitutions (%D for destination, %S
   1437                     #       for source, %B for base of current rule,
   1438                     #       %R for base of primary tex file, %T for
   1439                     #       texfile name, %O for options,
   1440                     #       %Y for $aux_dir1, and %Z for $out_dir1
   1441                     #     int_cmd specifies any internal command to be
   1442                     #       used to implement the application of the
   1443                     #       rule.  If this is present, it overrides
   1444                     #       the external command, and it is the
   1445                     #       responsibility of the perl subroutine
   1446                     #       specified in intcmd to execute the
   1447                     #       external command if this is appropriate.
   1448                     #       This variable intcmd is a reference to an array,  
   1449                     #       $$intcmd[0] = internal routine
   1450                     #       $$intcmd[1...] = its arguments (if any)
   1451                     #     test_kind specifies method of determining
   1452                     #       whether a file is out-of-date:
   1453                     #         0 for never
   1454                     #         1 for usual: whether there is a source
   1455                     #              file change 
   1456                     #         2 for dest earlier than source
   1457                     #         3 for method 2 at first run, 1 thereafter
   1458                     #              (used when don't have file data from
   1459                     #              previous run).
   1460                     #     source = name of primary source file, if any
   1461                     #     dest   = name of primary destination file,
   1462                     #              if any
   1463                     #     base   = base name, if any, of files for
   1464                     #              this rule
   1465                     #     out_of_date = 1 if it has been detected that
   1466                     #                     this rule needs to be run
   1467                     #                     (typically because a source
   1468                     #                     file has changed).
   1469                     #                   0 otherwise
   1470                     #     out_of_date_user is like out_of_date, except
   1471                     #         that the detection of out-of-dateness
   1472                     #         has been made from a change of a
   1473                     #         putative user file, i.e., one that is
   1474                     #         not a generated file (e.g., aux). This
   1475                     #         kind of out-of-dateness should provoke a
   1476                     #         rerun whether or not there was an error
   1477                     #         during a run of (pdf)LaTeX.  Normally,
   1478                     #         if there is an error, one should wait
   1479                     #         for the user to correct the error.  But
   1480                     #         it is possible the error condition is
   1481                     #         already corrected during the run, e.g.,
   1482                     #         by the user changing a source file in
   1483                     #         response to an error message. 
   1484                     #     time_of_last_run = time that this rule was
   1485                     #              last applied.  (In standard units
   1486                     #              from perl, to be directly compared
   1487                     #              with file modification times.)
   1488                     #     time_of_last_file_check = last time that a check
   1489                     #              was made for changes in source files.
   1490                     #     changed flags whether special changes have been made
   1491                     #          that require file-existence status to be ignored
   1492                     #     last_result is 
   1493                     #                 -1 if no run has been made,
   1494                     #                  0 if the last run was successful
   1495                     #                  1 if last run was successful, but
   1496                     #                    failed to create an output file
   1497                     #                  2 if last run failed
   1498                     #                  200 if last run gave a warning that is
   1499                     #                    important enough to be reported with 
   1500                     #                    the error summary.  The warning
   1501                     #                    message is stored in last_message.
   1502                     #     last_message is error message for last run
   1503                     #     default_extra_generated is a reference to an array
   1504                     #       of specifications of extra generated files (beyond
   1505                     #       the main dest file.  Standard place holders are used.
   1506                     #       Example ['%Y%R.log'] for (pdf)latex, and ['%R.blg'] 
   1507                     #          for bibtex.  (There's no need for '%R.aux', here,
   1508                     #          since such generated files are detected dynamically.)
   1509                     #   1: {Hash sourcefile -> [source-file data] }
   1510                     # Source-file data array: 
   1511                     #   0: time
   1512                     #   1: size
   1513                     #   2: md5
   1514                     #   3: name of rule to make this file
   1515                     #   4: whether the file is of the kind made by epstopdf.sty 
   1516                     #      during a primary run.  It will have been read during
   1517                     #      the run, so that even though the file changes during
   1518                     #      a primary run, there is no need to trigger another 
   1519                     #      run because of this.
   1520                     #  Size and md5 correspond to the values at the last run.
   1521                     #  But time may be updated to correspond to the time
   1522                     #  for the file, if the file is otherwise unchanged.
   1523                     #  This saves excessive md5 calculations, which would
   1524                     #  otherwise be done everytime the file is checked, 
   1525                     #  in the following situation:
   1526                     #     When the file has been rewritten after a run
   1527                     #     has started (commonly aux, bbl files etc),
   1528                     #     but the actual file contents haven't
   1529                     #     changed.  Then because the filetime has
   1530                     #     changed, on every file-change check latexmk
   1531                     #     would normally redo the md5 calculation to
   1532                     #     test for actual changes.  Once one such
   1533                     #     check is done, and the contents are
   1534                     #     unchanged, later checks are superfluous, and
   1535                     #     can be avoided by changing the file's time
   1536                     #     in the source-file list.
   1537                     #   2: {Hash generated_file -> 1 }
   1538                     #      This lists all generated files; the values
   1539                     #          are currently unused, only the keys
   1540 
   1541 %fdb_current = ();  # Fdb-hash for all files used.
   1542 
   1543 
   1544 # User's home directory
   1545 $HOME = '';
   1546 if (exists $ENV{'HOME'} ) {
   1547     $HOME = $ENV{'HOME'};
   1548 }
   1549 elsif (exists $ENV{'USERPROFILE'} ) {
   1550     $HOME = $ENV{'USERPROFILE'};
   1551 }
   1552 # XDG configuration home
   1553 $XDG_CONFIG_HOME = '';
   1554 if (exists $ENV{'XDG_CONFIG_HOME'} ) {
   1555     $XDG_CONFIG_HOME = $ENV{'XDG_CONFIG_HOME'};
   1556 }
   1557 elsif ($HOME ne '') {
   1558     if ( -d "$HOME/.config") {
   1559         $XDG_CONFIG_HOME = "$HOME/.config";
   1560     }
   1561 }
   1562 
   1563 
   1564 #==================================================
   1565 
   1566 # Options that are to be obeyed before rc files are read:
   1567 
   1568 foreach $_ ( @ARGV )
   1569 {
   1570     if (/^-{1,2}norc$/ ) {
   1571         $auto_rc_use = 0;
   1572     }
   1573 }
   1574 
   1575 #==================================================
   1576 ## Read rc files with this subroutine
   1577 
   1578 sub read_first_rc_file_in_list {
   1579     foreach my $rc_file ( @_ ) {
   1580         #print "===Testing for rc file \"$rc_file\" ...\n";
   1581         if ( -d $rc_file ) {
   1582             warn "$My_name: I have found a DIRECTORY named \"$rc_file\".\n",
   1583                  "   Have you perhaps misunderstood latexmk's documentation?\n",
   1584                  "   This name is normally used for a latexmk configuration (rc) file,\n",
   1585                  "   and in that case it should be a regular text file, not a directory.\n";
   1586         }
   1587         elsif ( -e $rc_file ) {
   1588             #print "===Reading rc file \"$rc_file\" ...\n";
   1589             process_rc_file( $rc_file );
   1590             return;
   1591         }
   1592     }
   1593 }
   1594 
   1595 # Note that each rc file may unset $auto_rc_use to
   1596 # prevent lower-level rc files from being read.
   1597 # So test on $auto_rc_use in each case.
   1598 if ( $auto_rc_use ) {
   1599     # System rc file:
   1600     if (exists $ENV{LATEXMKRCSYS} ) {
   1601 	push @rc_system_files, $ENV{LATEXMKRCSYS};
   1602 	if ( !-e $ENV{LATEXMKRCSYS} ) {
   1603 	    warn "$My_name: you've specified a system rc file `$ENV{LATEXMKRCSYS}`\n",
   1604 		 "   in environment variable LATEXMKRCSYS, but the file doesn't exist.\n",
   1605 		 "   I won't read any system rc file.\n";
   1606 	}
   1607 	else {
   1608            process_rc_file( $ENV{LATEXMKRCSYS} );
   1609 	}
   1610     }
   1611     else {
   1612         read_first_rc_file_in_list( @rc_system_files );
   1613     }
   1614 }
   1615 if ( $auto_rc_use && ($HOME ne "" ) ) {
   1616     # User rc file:
   1617     @user_rc = ();
   1618     if ( $XDG_CONFIG_HOME ) { 
   1619        push @user_rc, "$XDG_CONFIG_HOME/latexmk/latexmkrc";
   1620     }
   1621     # N.B. $HOME equals "" if latexmk couldn't determine a home directory.
   1622     # In that case, we shouldn't look for an rc file there.
   1623     if ( $HOME ) { 
   1624        push @user_rc, "$HOME/.latexmkrc";
   1625     }
   1626     read_first_rc_file_in_list( @user_rc );
   1627 }
   1628 if ( $auto_rc_use ) { 
   1629     # Rc file in current directory:
   1630     read_first_rc_file_in_list( "latexmkrc", ".latexmkrc" );
   1631 }
   1632 
   1633 ## Process command line args.
   1634 @command_line_file_list = ();
   1635 $bad_options = 0;
   1636 
   1637 while ($_ = $ARGV[0])
   1638 {
   1639   # Make -- and - equivalent at beginning of option,
   1640   # but save original for possible use in (pdf)latex command line
   1641   $original = $_;
   1642   s/^--/-/;
   1643   shift;
   1644   if ( /^-aux-directory=(.*)$/ || /^-auxdir=(.*)$/ ) {
   1645       $aux_dir = $1;
   1646   }
   1647   elsif (/^-bibtex$/) { $bibtex_use = 2; }
   1648   elsif (/^-bibtex-$/) { $bibtex_use = 0; }
   1649   elsif (/^-nobibtex$/) { $bibtex_use = 0; }
   1650   elsif (/^-bibtex-cond$/) { $bibtex_use = 1; }
   1651   elsif (/^-bibtex-cond1$/) { $bibtex_use = 1.5; }
   1652   elsif (/^-c$/)        { $cleanup_mode = 2; $cleanup_fdb = 1; $cleanup_only = 1; }
   1653   elsif (/^-C$/ || /^-CA$/ ) { $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 1; }
   1654   elsif (/^-CF$/)    { $cleanup_fdb = 1; }
   1655   elsif (/^-cd$/)    { $do_cd = 1; }
   1656   elsif (/^-cd-$/)   { $do_cd = 0; }
   1657   elsif (/^-commands$/) { &print_commands; exit; }
   1658   elsif (/^-d$/)     { $banner = 1; }
   1659   elsif (/^-dependents$/ || /^-deps$/ || /^-M$/ ) { $dependents_list = 1; }
   1660   elsif (/^-nodependents$/ || /^-dependents-$/ || /^-deps-$/) { $dependents_list = 0; }
   1661   elsif (/^-deps-out=(.*)$/) {
   1662       $deps_file = $1;
   1663       $dependents_list = 1; 
   1664   }
   1665   elsif (/^-diagnostics/) { $diagnostics = 1; }
   1666   elsif (/^-dvi$/)   { $dvi_mode = 1; }
   1667   elsif (/^-dvi-$/)  { $dvi_mode = 0; }
   1668   elsif (/^-f$/)     { $force_mode = 1; }
   1669   elsif (/^-f-$/)    { $force_mode = 0; }
   1670   elsif (/^-g$/)     { $go_mode = 1; }
   1671   elsif (/^-g-$/)    { $go_mode = 0; }
   1672   elsif (/^-gg$/)    { 
   1673      $go_mode = 2; $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 0; 
   1674   }
   1675   elsif ( /^-h$/ || /^-help$/ )   { &print_help; exit;}
   1676   elsif (/^-jobname=(.*)$/) {
   1677       $jobname = $1;
   1678   }
   1679   elsif (/^-l$/)     { $landscape_mode = 1; }
   1680   elsif (/^-l-$/)    { $landscape_mode = 0; }
   1681   elsif (/^-latex=(.*)$/) {
   1682       $latex = $1;
   1683   }
   1684   elsif (/^-latexoption=(.*)$/) {
   1685       push @extra_latex_options, $1;
   1686       push @extra_pdflatex_options, $1;
   1687       push @extra_lualatex_options, $1;
   1688       push @extra_xelatex_options, $1;
   1689   }
   1690   elsif ( /^-logfilewarninglist$/ || /^-logfilewarnings$/ )
   1691       { $silence_logfile_warnings = 0; }
   1692   elsif ( /^-logfilewarninglist-$/ || /^-logfilewarnings-$/ )
   1693       { $silence_logfile_warnings = 1; }
   1694 # See above for -M
   1695   elsif (/^-MF$/) {
   1696      if ( $ARGV[0] eq '' ) {
   1697         &exit_help( "No file name specified after -MF switch");
   1698      }
   1699      $deps_file = $ARGV[0];
   1700      shift; 
   1701   }
   1702   elsif ( /^-MP$/ ) { $dependents_phony = 1; }
   1703   elsif (/^-new-viewer$/) {
   1704       $new_viewer_always = 1; 
   1705   }
   1706   elsif (/^-new-viewer-$/) {
   1707       $new_viewer_always = 0;
   1708   }
   1709   elsif (/^-norc$/ ) {
   1710       $auto_rc_use = 0;
   1711       # N.B. This has already been obeyed.
   1712   }
   1713   elsif ( /^-output-directory=(.*)$/ ||/^-outdir=(.*)$/ ) {
   1714       $out_dir = $1;
   1715   }
   1716   elsif (/^-p$/)     { $printout_mode = 1; 
   1717                        $preview_continuous_mode = 0; # to avoid conflicts
   1718                        $preview_mode = 0;  
   1719                      }
   1720   elsif (/^-p-$/)    { $printout_mode = 0; }
   1721   elsif (/^-pdf$/)   { $pdf_mode = 1; }
   1722   elsif (/^-pdf-$/)  { $pdf_mode = 0; }
   1723   elsif (/^-pdfdvi$/){ $pdf_mode = 3; }
   1724   elsif (/^-pdflua$/){ $pdf_mode = 4; }
   1725   elsif (/^-pdfps$/) { $pdf_mode = 2; }
   1726   elsif (/^-pdfxe$/) { $pdf_mode = 5; }
   1727 #  elsif (/^-pdflatex$/) {
   1728 #      $pdflatex = "pdflatex %O %S";
   1729 #      $pdf_mode = 1;
   1730 #      $dvi_mode = $postscript_mode = 0; 
   1731 #  }
   1732   elsif (/^-pdflatex=(.*)$/) {
   1733       $pdflatex = $1;
   1734   }
   1735   elsif (/^-pdflualatex=(.*)$/) {
   1736       $lualatex = $1;
   1737   }
   1738   elsif (/^-pdfxelatex=(.*)$/) {
   1739       $xelatex = $1;
   1740   }
   1741   elsif (/^-pretex=(.*)$/) {
   1742       $pre_tex_code = $1;
   1743   }
   1744   elsif (/^-print=(.*)$/) {
   1745       $value = $1;
   1746       if ( $value =~ /^dvi$|^ps$|^pdf$|^auto$/ ) {
   1747           $print_type = $value;
   1748           $printout_mode = 1;
   1749       }
   1750       else {
   1751           &exit_help("$My_name: unknown print type '$value' in option '$_'");
   1752       }
   1753   }
   1754   elsif (/^-ps$/)    { $postscript_mode = 1; }
   1755   elsif (/^-ps-$/)   { $postscript_mode = 0; }
   1756   elsif (/^-pv$/)    { $preview_mode = 1; 
   1757                        $preview_continuous_mode = 0; # to avoid conflicts
   1758                        $printout_mode = 0; 
   1759                      }
   1760   elsif (/^-pv-$/)   { $preview_mode = 0; }
   1761   elsif (/^-pvc$/)   { $preview_continuous_mode = 1;
   1762                        $force_mode = 0;    # So that errors do not cause loops
   1763                        $preview_mode = 0;  # to avoid conflicts
   1764                        $printout_mode = 0; 
   1765                      }
   1766   elsif (/^-pvc-$/)  { $preview_continuous_mode = 0; }
   1767   elsif (/^-pvctimeout$/) { $pvc_timeout = 1; }
   1768   elsif (/^-pvctimeout-$/) { $pvc_timeout = 0; }
   1769   elsif (/^-pvctimeoutmins=(.*)$/) { $pvc_timeout_mins = $1; }
   1770   elsif (/^-recorder$/ ){ $recorder = 1; }
   1771   elsif (/^-recorder-$/ ){ $recorder = 0; }
   1772   elsif (/^-rules$/ ) { $rules_list = 1; }
   1773   elsif (/^-norules$/ || /^-rules-$/ ) { $rules_list = 0; }
   1774   elsif (/^-showextraoptions$/) {
   1775      print "List of extra latex and pdflatex options recognized by $my_name.\n",
   1776            "These are passed as is to (pdf)latex.  They may not be recognized by\n",
   1777            "particular versions of (pdf)latex.  This list is a combination of those\n",
   1778            "for TeXLive and MikTeX.\n",
   1779            "\n",
   1780            "Note that in addition to the options in this list, there are several\n",
   1781            "options known to the (pdf)latex programs that are also recognized by\n",
   1782            "latexmk and trigger special behavior by latexmk.  Since these options\n",
   1783            "appear in the main list given by running 'latexmk --help', they do not\n",
   1784 	   "appear in the following list\n",
   1785 	   "NOTE ALSO: Not all of these options are supported by all versions of (pdf)latex.\n",
   1786            "\n";
   1787      foreach $option ( sort( keys %allowed_latex_options, keys %allowed_latex_options_with_arg ) ) {
   1788        if (exists $allowed_latex_options{$option} ) { print "   $allowed_latex_options{$option}\n"; }
   1789        if (exists $allowed_latex_options_with_arg{$option} ) { print "   $allowed_latex_options_with_arg{$option}\n"; }
   1790      }
   1791      exit;
   1792   }
   1793   elsif (/^-silent$/ || /^-quiet$/ ){ $silent = 1; }
   1794   elsif (/^-stdtexcmds$/) { &std_tex_cmds; }
   1795   elsif (/^-time$/) { $show_time = 1;}
   1796   elsif (/^-time-$/) { $show_time = 0;}
   1797   elsif (/^-use-make$/)  { $use_make_for_missing_files = 1; }
   1798   elsif (/^-use-make-$/)  { $use_make_for_missing_files = 0; }
   1799   elsif (/^-usepretex$/) { &alt_tex_cmds; }
   1800   elsif (/^-usepretex=(.*)$/) {
   1801       &alt_tex_cmds;
   1802       $pre_tex_code = $1;
   1803   }
   1804   elsif (/^-v$/ || /^-version$/)   { 
   1805       print "\n$version_details. Version $version_num\n";
   1806       exit;
   1807   }
   1808   elsif (/^-verbose$/)  { $silent = 0; }
   1809   elsif (/^-view=default$/) { $view = "default";}
   1810   elsif (/^-view=dvi$/)     { $view = "dvi";}
   1811   elsif (/^-view=none$/)    { $view = "none";}
   1812   elsif (/^-view=ps$/)      { $view = "ps";}
   1813   elsif (/^-view=pdf$/)     { $view = "pdf"; }
   1814   elsif (/^-Werror$/){ $warnings_as_errors = 1; }
   1815   elsif (/^-lualatex$/)      { 
   1816       $pdf_mode = 4;
   1817       $dvi_mode = $postscript_mode = 0; 
   1818   }
   1819   elsif (/^-xelatex$/)      { 
   1820       $pdf_mode = 5;
   1821       $dvi_mode = $postscript_mode = 0; 
   1822   }
   1823   elsif (/^-e$/) {  
   1824      if ( $#ARGV < 0 ) {
   1825         &exit_help( "No code to execute specified after -e switch"); 
   1826      }
   1827      execute_code_string( $ARGV[0] );
   1828      shift;
   1829   }
   1830   elsif (/^-r$/) {  
   1831      if ( $ARGV[0] eq '' ) {
   1832         &exit_help( "No RC file specified after -r switch"); 
   1833      }
   1834      if ( -e $ARGV[0] ) {
   1835         process_rc_file( $ARGV[0] );
   1836      } 
   1837      else {
   1838         die "$My_name: RC file [$ARGV[0]] does not exist\n"; 
   1839      }
   1840      shift; 
   1841   }
   1842   elsif (/^-bm$/) {
   1843      if ( $ARGV[0] eq '' ) {
   1844         &exit_help( "No message specified after -bm switch");
   1845      }
   1846      $banner = 1; $banner_message = $ARGV[0];
   1847      shift; 
   1848   }
   1849   elsif (/^-bi$/) {
   1850      if ( $ARGV[0] eq '' ) {
   1851         &exit_help( "No intensity specified after -bi switch");
   1852      }
   1853      $banner_intensity = $ARGV[0];
   1854      shift; 
   1855   }
   1856   elsif (/^-bs$/) {
   1857      if ( $ARGV[0] eq '' ) {
   1858         &exit_help( "No scale specified after -bs switch");
   1859      }
   1860      $banner_scale = $ARGV[0];
   1861      shift; 
   1862   }
   1863   elsif (/^-dF$/) {
   1864      if ( $ARGV[0] eq '' ) {
   1865         &exit_help( "No dvi filter specified after -dF switch");
   1866      }
   1867      $dvi_filter = $ARGV[0];
   1868      shift; 
   1869   }
   1870   elsif (/^-pF$/) {
   1871      if ( $ARGV[0] eq '' ) {
   1872         &exit_help( "No ps filter specified after -pF switch");
   1873      }
   1874      $ps_filter = $ARGV[0];
   1875      shift; 
   1876   }
   1877   elsif ( ( exists( $allowed_latex_options{$_} ) )
   1878           || ( /^(-.+)=/ && exists( $allowed_latex_options_with_arg{$1} ) )
   1879         )
   1880   {
   1881       push @extra_latex_options, $original;
   1882       push @extra_pdflatex_options, $original;
   1883       push @extra_lualatex_options, $original;
   1884       push @extra_xelatex_options, $original;
   1885   }
   1886   elsif (/^-/) {
   1887      warn "$My_name: $_ bad option\n"; 
   1888      $bad_options++;
   1889   }
   1890   else {
   1891      push @command_line_file_list, $_ ; 
   1892   }
   1893 }
   1894 
   1895 if ( $bad_options > 0 ) {
   1896     &exit_help( "Bad options specified" );
   1897 }
   1898 
   1899 warn "$My_name: This is $version_details, version: $version_num.\n",
   1900    unless $silent;
   1901 
   1902 
   1903 if ( ($out_dir ne '') && ($aux_dir eq '') ){
   1904     $aux_dir = $out_dir;
   1905 }
   1906 
   1907 # Save original values for use in diagnositics.
   1908 # We may change $aux_dir and $out_dir after a detection
   1909 #  of results of misconfiguration.
   1910 $aux_dir_requested = $aux_dir;
   1911 $out_dir_requested = $out_dir;
   1912 # The following reports results of diagnostics on location of .log file
   1913 #   after the first run of a latex engine, when actually used aux_dir
   1914 #   may not be the expected one, due to a configuration error.
   1915 # Values: -1 uninitialized (before first run)
   1916 #          0 log file not found;
   1917 #          1 log file in aux_dir;
   1918 #          2 log file **not** in aux_dir but in out_dir;
   1919 #          3 log file **not** in aux_dir or out_dir, but in cwd.
   1920 $where_log = -1;  
   1921 
   1922 &set_dirs_etc;
   1923 
   1924 if ($bibtex_use > 1) {
   1925     push @generated_exts, 'bbl';
   1926 }
   1927 
   1928 # For backward compatibility, convert $texfile_search to @default_files
   1929 # Since $texfile_search is initialized to "", a nonzero value indicates
   1930 # that an initialization file has set it.
   1931 if ( $texfile_search ne "" ) {
   1932     @default_files = split /\s+/, "*.tex $texfile_search";
   1933 }
   1934 
   1935 #Glob the filenames command line if the script was not invoked under a 
   1936 #   UNIX-like environment.
   1937 #   Cases: (1) MS/MSwin native    Glob
   1938 #                      (OS detected as MSWin32)
   1939 #          (2) MS/MSwin cygwin    Glob [because we do not know whether
   1940 #                  the cmd interpreter is UNIXy (and does glob) or is
   1941 #                  native MS-Win (and does not glob).]
   1942 #                      (OS detected as cygwin)
   1943 #          (3) UNIX               Don't glob (cmd interpreter does it)
   1944 #                      (Currently, I assume this is everything else)
   1945 if ( ($^O eq "MSWin32") || ($^O eq "cygwin") ) {
   1946     # Preserve ordering of files
   1947     @file_list = glob_list1(@command_line_file_list);
   1948 #print "A1:File list:\n";
   1949 #for ($i = 0; $i <= $#file_list; $i++ ) {  print "$i: '$file_list[$i]'\n"; }
   1950 }
   1951 else {
   1952     @file_list = @command_line_file_list;
   1953 }
   1954 @file_list = uniq1( @file_list );
   1955 
   1956 
   1957 # Check we haven't selected mutually exclusive modes.
   1958 # Note that -c overrides all other options, but doesn't cause
   1959 # an error if they are selected.
   1960 if (($printout_mode && ( $preview_mode || $preview_continuous_mode ))
   1961     || ( $preview_mode && $preview_continuous_mode ))
   1962 {
   1963   # Each of the options -p, -pv, -pvc turns the other off.
   1964   # So the only reason to arrive here is an incorrect inititalization
   1965   #   file, or a bug.
   1966   &exit_help( "Conflicting options (print, preview, preview_continuous) selected");
   1967 }
   1968 
   1969 if ( @command_line_file_list ) {   
   1970     # At least one file specified on command line (before possible globbing).
   1971     if ( !@file_list ) {
   1972         &exit_help( "Wildcards in file names didn't match any files");
   1973     }
   1974 }
   1975 else {
   1976     # No files specified on command line, try and find some
   1977     # Evaluate in order specified.  The user may have some special
   1978     #   for wanting processing in a particular order, especially
   1979     #   if there are no wild cards.
   1980     # Preserve ordering of files
   1981     my @file_list1 = uniq1( glob_list1(@default_files) );
   1982     my @excluded_file_list = uniq1( glob_list1(@default_excluded_files) );
   1983     # Make hash of excluded files, for easy checking:
   1984     my %excl = ();
   1985     foreach my $file (@excluded_file_list) {
   1986         $excl{$file} = '';
   1987     }
   1988     foreach my $file (@file_list1) {
   1989         push( @file_list, $file)  unless ( exists $excl{$file} );
   1990     }    
   1991     if ( !@file_list ) {
   1992         &exit_help( "No file name specified, and I couldn't find any");
   1993     }
   1994 }
   1995 
   1996 $num_files = $#file_list + 1;
   1997 $num_specified = $#command_line_file_list + 1;
   1998 
   1999 #print "Command line file list:\n";
   2000 #for ($i = 0; $i <= $#command_line_file_list; $i++ ) {  print "$i: '$command_line_file_list[$i]'\n"; }
   2001 #print "File list:\n";
   2002 #for ($i = 0; $i <= $#file_list; $i++ ) {  print "$i: '$file_list[$i]'\n"; }
   2003 
   2004 
   2005 # If selected a preview-continuous mode, make sure exactly one filename was specified
   2006 if ($preview_continuous_mode && ($num_files != 1) ) {
   2007     if ($num_specified > 1) {
   2008         &exit_help( 
   2009           "Need to specify exactly one filename for ".
   2010               "preview-continuous mode\n".
   2011           "    but $num_specified were specified"
   2012         );
   2013     }
   2014     elsif ($num_specified == 1) {
   2015         &exit_help( 
   2016           "Need to specify exactly one filename for ".
   2017               "preview-continuous mode\n".
   2018           "    but wildcarding produced $num_files files"
   2019         );
   2020     }
   2021     else {
   2022         &exit_help( 
   2023           "Need to specify exactly one filename for ".
   2024               "preview-continuous mode.\n".
   2025           "    Since none were specified on the command line, I looked for \n".
   2026           "    files in '@default_files'.\n".
   2027           "    But I found $num_files files, not 1."
   2028         );
   2029     }
   2030 }
   2031 
   2032 # If selected jobname, can only apply that to one file:
   2033 if ( ($jobname ne '') && ($num_files > 1) ) {
   2034     &exit_help( 
   2035           "Need to specify at most one filename if ".
   2036           "jobname specified, \n".
   2037           "    but $num_files were found (after defaults and wildcarding)."
   2038         );
   2039 }
   2040 
   2041 # Normalize the commands, to have place-holders for source, dest etc:
   2042 &fix_cmds;
   2043 
   2044 # Add common options
   2045 add_option( $latex_default_switches,    \$latex );
   2046 add_option( $pdflatex_default_switches, \$pdflatex );
   2047 add_option( $lualatex_default_switches, \$lualatex );
   2048 add_option( $xelatex_default_switches,  \$xelatex );
   2049 
   2050 foreach (@extra_latex_options)    { add_option( $_, \$latex ); }
   2051 foreach (@extra_pdflatex_options) { add_option( $_, \$pdflatex ); }
   2052 foreach (@extra_lualatex_options) { add_option( $_, \$lualatex ); }
   2053 foreach (@extra_xelatex_options)  { add_option( $_, \$xelatex ); }
   2054 
   2055 
   2056 # If landscape mode, change dvips processor, and the previewers:
   2057 if ( $landscape_mode )
   2058 {
   2059   $dvips = $dvips_landscape;
   2060   $dvi_previewer = $dvi_previewer_landscape;
   2061   $ps_previewer = $ps_previewer_landscape;
   2062 }
   2063 
   2064 if ( $silent ) { 
   2065     add_option( "$latex_silent_switch", \$latex );
   2066     add_option( "$pdflatex_silent_switch", \$pdflatex );
   2067     add_option( "$lualatex_silent_switch", \$lualatex );
   2068     add_option( "$xelatex_silent_switch", \$xelatex );
   2069     add_option( "$biber_silent_switch", \$biber );
   2070     add_option( "$bibtex_silent_switch", \$bibtex );
   2071     add_option( "$makeindex_silent_switch", \$makeindex );
   2072     add_option( "$dvipdf_silent_switch", \$dvipdf );
   2073     add_option( "$dvips_silent_switch", \$dvips );
   2074     add_option( "$xdvipdfmx_silent_switch", \$xdvipdfmx );
   2075 }
   2076 
   2077 if ( $recorder ) {
   2078     add_option( "-recorder", \$latex, \$pdflatex, \$lualatex, \$xelatex );
   2079 }
   2080 
   2081 # If the output and/or aux directories are specified, fix the (pdf)latex
   2082 #   commands to use them.
   2083 # N.B. We'll ensure that the directories actually exist only after a
   2084 #   possible cd to the document directory, since the directories can be
   2085 #   relative to the document.
   2086 
   2087 if ( $out_dir ) {
   2088     add_option( "-output-directory=\"$out_dir\"",
   2089                 \$latex, \$pdflatex, \$lualatex, \$xelatex );
   2090 }
   2091 if ( $aux_dir && ($aux_dir ne $out_dir) ) {
   2092     # N.B. If $aux_dir and $out_dir are the same, then the -output-directory
   2093     # option is sufficient, especially because the -aux-directory exists
   2094     # only in MiKTeX, not in TeXLive.
   2095     add_option( "-aux-directory=\"$aux_dir\"",
   2096                 \$latex, \$pdflatex, \$lualatex, \$xelatex );
   2097 }
   2098 
   2099 if ( $jobname ne '' ) { 
   2100     $jobstring = "--jobname=\"$jobname\"";
   2101     add_option( "$jobstring", \$latex, \$lualatex, \$pdflatex, \$xelatex );
   2102 }
   2103 
   2104 # Which kind of file do we preview?
   2105 if ( $view eq "default" ) {
   2106     # If default viewer requested, use "highest" of dvi, ps and pdf
   2107     #    that was requested by user.  
   2108     # No explicit request means view dvi.
   2109     $view = "dvi";
   2110     if ( $postscript_mode ) { $view = "ps"; }
   2111     if ( $pdf_mode ) { $view = "pdf"; }
   2112 }
   2113 
   2114 # Make sure we make the kind of file we want to view:
   2115 if ($view eq 'dvi') { $dvi_mode = 1; }
   2116 if ($view eq 'ps') { $postscript_mode = 1; }
   2117 if ( ($view eq 'pdf') && ($pdf_mode == 0) ) { 
   2118     $pdf_mode = 1; 
   2119 }
   2120 
   2121 # Make sure that we make something if all requests are turned off
   2122 if ( ! ( $dvi_mode || $pdf_mode || $postscript_mode || $printout_mode) ) {
   2123     print "No specific requests made, so default to dvi by latex\n";
   2124     $dvi_mode = 1;
   2125 }
   2126 
   2127 # Set new-style requested rules:
   2128 if ( $dvi_mode ) { $requested_filerules{'latex'} = 1; }
   2129 if ( $pdf_mode == 1 ) { $requested_filerules{'pdflatex'} = 1; }
   2130 elsif ( $pdf_mode == 2 ) { 
   2131    $requested_filerules{'latex'} = 1;
   2132    $requested_filerules{'dvips'} = 1;
   2133    $requested_filerules{'ps2pdf'} = 1; 
   2134 }
   2135 elsif ( $pdf_mode == 3 ) { 
   2136    $requested_filerules{'latex'} = 1;
   2137    $requested_filerules{'dvipdf'} = 1; 
   2138 }
   2139 elsif ( $pdf_mode == 4 ) { 
   2140    $requested_filerules{'lualatex'} = 1;
   2141 }
   2142 elsif ( $pdf_mode == 5 ) { 
   2143    $requested_filerules{'xelatex'} = 1;
   2144    $requested_filerules{'xdvipdfmx'} = 1; 
   2145 }
   2146 if ( $postscript_mode ) { 
   2147    $requested_filerules{'latex'} = 1; 
   2148    $requested_filerules{'dvips'} = 1; 
   2149 }
   2150 if ($print_type eq 'auto') {
   2151     if ( $postscript_mode ) { $print_type = 'ps'; }
   2152     elsif ( $pdf_mode )     { $print_type = 'pdf'; }
   2153     elsif ( $dvi_mode )     { $print_type = 'dvi'; }
   2154     else                    { $print_type = 'none'; }
   2155 }
   2156 if ( $printout_mode ) {
   2157     $one_time{'print'} = 1;
   2158     if ($print_type eq 'none'){
   2159         warn "$My_name: You have requested printout, but \$print_type is set to 'none'\n";
   2160     }
   2161 }
   2162 if ( $preview_continuous_mode || $preview_mode ) { $one_time{'view'} = 1; }
   2163 if ( length($dvi_filter) != 0 ) { $requested_filerules{'dvi_filter'} = 1; }
   2164 if ( length($ps_filter) != 0 )  { $requested_filerules{'ps_filter'} = 1; }
   2165 if ( $banner ) { $requested_filerules{'dvips'} = 1; }
   2166 
   2167 
   2168 if ( $pdf_mode == 2 ) {
   2169     # We generate pdf from ps.  Make sure we have the correct kind of ps.
   2170     add_option( "$dvips_pdf_switch", \$dvips );
   2171 }
   2172 
   2173 # Restrict variables to allowed values:
   2174 
   2175 if ($filetime_causality_threshold < 0) {
   2176     warn "$My_name: Correcting negative value of \$filetime_causality_threshold to zero.\n";
   2177     $filetime_causality_threshold = 0;
   2178 }
   2179 
   2180 # Note sleep has granularity of 1 second.
   2181 # Sleep periods 0 < $sleep_time < 1 give zero delay,
   2182 #    which is probably not what the user intended.
   2183 # Sleep periods less than zero give infinite delay
   2184 if ( $sleep_time < 0 ) {
   2185      warn "$My_name: Correcting negative sleep_time to 1 sec.\n";
   2186      $sleep_time = 1;
   2187 }
   2188 elsif ( ($sleep_time < 1) && ( $sleep_time != 0 ) ) {
   2189      warn "$My_name: Correcting nonzero sleep_time of less than 1 sec to 1 sec.\n";
   2190      $sleep_time = 1;
   2191 }
   2192 elsif ( $sleep_time == 0 ) {
   2193      warn "$My_name: sleep_time was configured to zero.\n",
   2194     "    Do you really want to do this?  It will give 100% CPU usage.\n";
   2195 }
   2196 
   2197 # Make convenient forms for lookup.
   2198 # Extensions always have period.
   2199 
   2200 # Convert @generated_exts to a hash for ease of look up and deletion
   2201 # Keep extension without period!
   2202 %generated_exts_all = ();
   2203 foreach (@generated_exts ) {
   2204     $generated_exts_all{$_} = 1;
   2205 }
   2206 
   2207 $quell_uptodate_msgs = $silent; 
   2208    # Whether to quell informational messages when files are uptodate
   2209    # Will turn off in -pvc mode
   2210 
   2211 $failure_count = 0;
   2212 @failed_primaries = ();
   2213 
   2214 if ($deps_file eq '' ) {
   2215     # Standardize name used for stdout
   2216     $deps_file = '-';
   2217 }
   2218 
   2219 # Since deps_file is global (common to all processed files), we must
   2220 # delete it here when doing a clean up, and not in the FILE loop, where
   2221 # per-file processing (including clean-up) is done
   2222 if ( ($cleanup_mode > 0) &&  $dependents_list && ( $deps_file ne '-' ) ) {
   2223     unlink_or_move( $deps_file );
   2224 }
   2225 
   2226 # In non-pvc mode, the dependency list is global to all processed TeX files,
   2227 #   so we open a single file here, and add items to it after processing
   2228 #   each file.  But in -pvc mode, the dependency list should be written
   2229 #   after round of processing the single TeX file (as if each round were
   2230 #   a separate run of latexmk).
   2231 # If we are cleaning up ($cleanup_mode != 0) AND NOT continuing to
   2232 #   make files (--gg option and $go_mode == 2), deps_file should not be
   2233 #   created.
   2234 # I will use definedness of $deps_handle as flag for global deps file having
   2235 #   been opened and therefore being available to be written to after
   2236 #   compiling a file.
   2237 $deps_handle = undef;
   2238 if ( $dependents_list
   2239      && ! $preview_continuous_mode
   2240      && ( ($cleanup_mode == 0) || ($go_mode == 2) )
   2241    ) {
   2242     $deps_handle = new FileHandle "> $deps_file";
   2243     if (! $deps_handle ) {
   2244         die "Cannot open '$deps_file' for output of dependency information\n";
   2245     }
   2246 }
   2247 
   2248 # Remove leading and trailing space in the following space-separated lists,
   2249 #   and collapse multiple spaces to one,
   2250 #   to avoid getting incorrect blank items when they are split.
   2251 foreach ($clean_ext, $clean_full_ext) { s/^\s+//; s/\s+$//; s/\s+/ /g; }
   2252 
   2253 # Deal with illegal and problematic characters in filename:
   2254 test_fix_texnames( @file_list );
   2255 
   2256 FILE:
   2257 foreach $filename ( @file_list )
   2258 {
   2259     # Global variables for making of current file:
   2260     $updated = 0;
   2261     $failure = 0;        # Set nonzero to indicate failure at some point of 
   2262                          # a make.  Use value as exit code if I exit.
   2263     $failure_msg = '';   # Indicate reason for failure
   2264 
   2265     if ( $do_cd ) {
   2266        ($filename, $path) = fileparse( $filename );
   2267        warn "$My_name: Changing directory to '$path'\n";
   2268        pushd( $path );
   2269     }
   2270     else {
   2271         $path = '';
   2272     }
   2273 
   2274     # Ensure the output/auxiliary directories exist, if need be
   2275     if ( $out_dir ) {
   2276         if ( ! -e $out_dir ) {
   2277              warn "$My_name: making output directory '$out_dir'\n"
   2278                 if ! $silent;
   2279              make_path $out_dir;
   2280         }
   2281         elsif ( ! -d $out_dir ) {
   2282             warn "$My_name: you requested output directory '$out_dir',\n",
   2283                  "     but an ordinary file of the same name exists, which will\n",
   2284                  "     probably give an error later\n";
   2285 	}
   2286     }
   2287 
   2288     if ( $aux_dir && ($aux_dir ne $out_dir) ) {
   2289         # N.B. If $aux_dir and $out_dir are the same, then the -output-directory
   2290         # option is sufficient, especially because the -aux-directory exists
   2291         # only in MiKTeX, not in TeXLive.
   2292         if ( ! -e $aux_dir ) {
   2293             warn "$My_name: making auxiliary directory '$aux_dir'\n"
   2294                if ! $silent;
   2295             make_path $aux_dir;
   2296 	}
   2297         elsif ( ! -d $aux_dir ) {
   2298             warn "$My_name: you requested aux directory '$aux_dir',\n",
   2299                  "     but an ordinary file of the same name exists, which will\n",
   2300                  "     probably give an error later\n";
   2301 	}
   2302     }
   2303 
   2304     ## remove extension from filename if was given.
   2305     if ( find_basename($filename, $root_filename, $texfile_name) )
   2306     {
   2307         if ( $force_mode ) {
   2308            warn "$My_name: Could not find file '$texfile_name'\n";
   2309         }
   2310         else {
   2311             &ifcd_popd;
   2312             &exit_msg1( "Could not find file '$texfile_name'",
   2313                         11);
   2314         }
   2315     }
   2316     if ($jobname ne '' ) {
   2317         $root_filename = $jobname;
   2318     }
   2319 
   2320     &set_names;
   2321 
   2322     # Initialize basic dependency information:
   2323 
   2324     # For use under error conditions:
   2325     @default_includes = ($texfile_name, $aux_main);
   2326 
   2327     # Initialize rule database.  
   2328     # ?? Should I also initialize file database?
   2329     %rule_list = ();
   2330     &rdb_make_rule_list;
   2331     &rdb_set_rules( \%rule_list, \%extra_rule_spec );
   2332 
   2333     if ( $cleanup_mode > 0 ) {
   2334 # ?? MAY NEED TO FIX THE FOLLOWING IF $aux_dir or $out_dir IS SET.
   2335         my %other_generated = ();
   2336         my @index_bibtex_generated = ();
   2337         my @aux_files = ();
   2338         my @missing_bib_files = ();
   2339 	my $bibs_all_exist = 0;
   2340         $have_fdb = 0;
   2341         if ( -e $fdb_name ) {
   2342             print "$My_name: Examining fdb file '$fdb_name' for rules ...\n"
   2343               if $diagnostics;
   2344             $have_fdb = ( 0 == rdb_read( $fdb_name ) );
   2345         }
   2346         if ( $have_fdb ) {
   2347             rdb_for_all(
   2348                 sub {  # Find generated files at rule level
   2349                     my ($base, $path, $ext) = fileparseA( $$Psource );
   2350                     $base = $path.$base;
   2351                     if ( $rule =~ /^makeindex/ ) {
   2352                         push @index_bibtex_generated, $$Psource, $$Pdest, "$base.ilg";
   2353                     }
   2354                     elsif ( $rule =~ /^(bibtex|biber)/ ) {
   2355                         push @index_bibtex_generated, $$Pdest, "$base.blg";
   2356                         push @aux_files, $$Psource;
   2357                         if ( $bibtex_use == 1.5) {
   2358                             foreach ( keys %$PHsource ) {
   2359                                 if ( ( /\.bib$/ ) && (! -e $_) ) {
   2360                                     push @missing_bib_files, $_;
   2361 			        }
   2362 			    }
   2363 			}
   2364 		    }
   2365                     elsif ( exists $other_generated{$$Psource} ) {
   2366 #			print "=========== CHECKING: source file of rule '$rule', '$$Psource'\n",
   2367 #                              "  is a generated file.\n";
   2368 			## OLD with apparent bug:
   2369                         #$other_generated{$$Pdest};
   2370                     }
   2371 		    foreach my $key (keys %$PHdest) {
   2372 			$other_generated{$key} = 1;
   2373 		    }
   2374                 },
   2375                 sub {  # Find generated files at source file level
   2376                     if ( $file =~ /\.aux$/ ) { push @aux_files, $file; }
   2377                 }
   2378 	    );
   2379    	    if ($#missing_bib_files == -1) { $bibs_all_exist = 1; }
   2380         }
   2381         elsif ( -e $log_name ) {
   2382             # No fdb file, but log file exists, so do inferior job by parse_log
   2383             print "$My_name: Examining log file '$log_name' for generated files...\n"
   2384               if $diagnostics;
   2385             # Variables set by parse_log. Can I remove them?
   2386             local %generated_log = ();
   2387             local %dependents = ();    # Maps files to status.  Not used here.
   2388             local @bbl_files = ();     # Not used here.
   2389             local %idx_files = ();     # Maps idx_file to (ind_file, base). Not used here.
   2390             local %conversions = ();   # (pdf)latex-performed conversions.  Not used here.
   2391                          # Maps output file created and read by (pdf)latex
   2392                          #    to source file of conversion.
   2393             local $primary_out = '';   # Actual output file (dvi or pdf). Not used here.
   2394 	    local $fls_file_analyzed = 0;
   2395             &parse_log;
   2396             %other_generated = %generated_log;
   2397         }
   2398         else {
   2399             print "$My_name: No fdb or log file, so clean up default set of files ...\n"
   2400               if $diagnostics;
   2401         }
   2402 
   2403         if ( ($go_mode == 2) && !$silent ) {
   2404             warn "$My_name: Removing all generated files\n" unless $silent;
   2405         }
   2406 	my $keep_bbl = 1;
   2407 	if ( ($bibtex_use > 1.6)
   2408 	     ||
   2409              (  ($bibtex_use == 1.5) && ($bibs_all_exist) )
   2410 	   ) {
   2411                $keep_bbl = 0;
   2412 	}
   2413 	if ($keep_bbl) {
   2414             delete $generated_exts_all{'bbl'}; 
   2415         }
   2416         # Convert two arrays to hashes:
   2417         my %index_bibtex_generated = ();
   2418         my %aux_files = ();
   2419         my %aux_files_to_save = ();
   2420         foreach (@index_bibtex_generated) {
   2421             $index_bibtex_generated{$_} = 1
   2422                unless ( /\.bbl$/ && ($keep_bbl) );
   2423             delete( $other_generated{$_} );
   2424         }
   2425         foreach (@aux_files) {
   2426 	    if (exists $other_generated{$_} ) {
   2427 		$aux_files{$_} = 1;
   2428 	    }
   2429 	    else {
   2430 		$aux_files_to_save{$_} = 1;
   2431 	    }
   2432         }
   2433 
   2434         if ($diagnostics) {
   2435             show_array( "For deletion, the following were determined from fdb file or log file:\n"
   2436                        ." Generated (from makeindex and bibtex):", 
   2437                         keys %index_bibtex_generated );
   2438             show_array( " Aux files:", keys %aux_files );
   2439             show_array( " Other generated files:\n"
   2440                        ." (only deleted if \$cleanup_includes_generated is set): ",
   2441                         keys %other_generated );
   2442             show_array( " Yet other generated files are specified by patterns:\n".
   2443                         " Explicit pattern with %R or root-filename.extension:",
   2444                         keys %generated_exts_all );
   2445             show_array( " Aux files to SAVE and not delete:", keys %aux_files_to_save );
   2446         }
   2447 
   2448         &cleanup1( $aux_dir1, $fdb_ext, 'blg', 'ilg', 'log', 'aux.bak', 'idx.bak',
   2449                    split('\s+',$clean_ext),
   2450                    keys %generated_exts_all 
   2451                  );
   2452         unlink_or_move( 'texput.log', "texput.aux", "missfont.log",
   2453                 keys %index_bibtex_generated, 
   2454                 keys %aux_files );
   2455         if ($cleanup_includes_generated) {
   2456             unlink_or_move( keys %other_generated );
   2457         }
   2458         if ( $cleanup_includes_cusdep_generated) {
   2459             &cleanup_cusdep_generated;
   2460         }
   2461         if ( $cleanup_mode == 1 ) { 
   2462             &cleanup1( $out_dir1, 'dvi', 'dviF', 'ps', 'psF', 'pdf', 
   2463                        'synctex.gz', 'xdv',
   2464                        split('\s+', $clean_full_ext)
   2465                      );
   2466         }
   2467     }
   2468     if ($cleanup_fdb) {
   2469        unlink_or_move( $fdb_name );
   2470        # If the fdb file exists, it will have been read, and therefore changed
   2471        #   rule database.  But deleting the fdb file implies we also want
   2472        #   a virgin rule database, so we must reset it:
   2473        rdb_set_rules( \%rule_list );
   2474     }
   2475     if ($cleanup_only) { next FILE; }
   2476 
   2477 
   2478 #??? The following are not needed if use rdb_make.  
   2479 #    ?? They may be set too early?
   2480 # Arrays and hashes for picking out accessible rules.
   2481 # Distinguish rules for making files and others
   2482     @accessible_all = sort ( &rdb_accessible( keys %requested_filerules, keys %one_time ));
   2483     %accessible_filerules = ();
   2484     foreach (@accessible_all) {
   2485         unless ( /view/ || /print/ ) { $accessible_filerules{$_} = 1; }
   2486     }
   2487     @accessible_filerules = sort  keys %accessible_filerules;
   2488 
   2489 #    show_array ( "=======All rules used", @accessible_all );
   2490 #    show_array ( "=======Requested file rules", sort keys %requested_filerules );
   2491 #    show_array ( "=======Rules for files", @accessible_filerules );
   2492 
   2493     if ( $diagnostics ) {
   2494        print "$My_name: Rules after start up for '$texfile_name'\n";
   2495        rdb_show();
   2496     }
   2497 
   2498     %primaries = ();
   2499     foreach (@accessible_all) {
   2500         if ( ($_ eq 'latex') || ($_ eq 'pdflatex') || ($_ eq 'lualatex')
   2501                              || ($_ eq 'xelatex') )
   2502         { $primaries{$_} = 1; }
   2503     }
   2504 
   2505     $have_fdb = 0;
   2506     if (! -e $aux_main ) {
   2507         # No aux file => set up trivial aux file 
   2508         #    and corresponding fdb_file.  Arrange them to provoke one run 
   2509         #    as minimum, but no more if actual aux file is trivial.
   2510         #    (Useful on big files without cross references.)
   2511         # If aux file doesn't exist, then any fdb file is surely
   2512 	#    wrong.
   2513 	# Previously, I had condition for this as being both aux and
   2514 	#    fdb files failing to exist.  But it's not obvious what to
   2515 	#    do if aux exists and fdb doesn't.  So I won't do anything.
   2516         &set_trivial_aux_fdb;
   2517     }
   2518 
   2519     if ( -e $fdb_name ) {
   2520         $rdb_errors = rdb_read( $fdb_name );
   2521         $have_fdb = ($rdb_errors == 0);
   2522     }
   2523     if (!$have_fdb) { 
   2524         # We didn't get a valid set of data on files used in
   2525         # previous run.  So use filetime criterion for make
   2526         # instead of change from previous run, until we have
   2527         # done our own make.
   2528         rdb_recurse( [keys %possible_primaries],
   2529                       sub{ if ( $$Ptest_kind == 1 ) { $$Ptest_kind = 3;} }
   2530         );
   2531         if ( -e $log_name ) {
   2532             rdb_for_some( [keys %possible_primaries], \&rdb_set_latex_deps );
   2533         }
   2534     }
   2535     foreach $rule ( rdb_accessible( uniq1( keys %requested_filerules  )  ) ){
   2536         # For all source files of all accessible rules, 
   2537         #    if the file data are not already set (e.g., from fdb_latexmk
   2538         #    file, set them from disk.
   2539         rdb_one_rule ($rule, undef, 
   2540                       sub{ if ( $$Ptime == 0) { &rdb_update1; } }
   2541         );
   2542     }
   2543 
   2544     if ($go_mode) {
   2545         # Force everything to be remade.
   2546         rdb_recurse( [keys %requested_filerules], sub{$$Pout_of_date=1;}  );
   2547     }
   2548 
   2549 
   2550     if ( $diagnostics ) {
   2551        print "$My_name: Rules after initialization\n";
   2552        rdb_show();
   2553     }
   2554 
   2555     #************************************************************
   2556 
   2557     if ( $preview_continuous_mode ) { 
   2558         &make_preview_continuous; 
   2559         next FILE;
   2560     }
   2561 
   2562 
   2563 ## Handling of failures:
   2564 ##    Variable $failure is set to indicate a failure, with information
   2565 ##       put in $failure_msg.  
   2566 ##    These variables should be set to 0 and '' at any point at which it
   2567 ##       should be assumed that no failures have occurred.
   2568 ##    When after a routine is called it is found that $failure is set, then
   2569 ##       processing should normally be aborted, e.g., by return.
   2570 ##    Then there is a cascade of returns back to the outermost level whose 
   2571 ##       responsibility is to handle the error.
   2572 ##    Exception: An outer level routine may reset $failure and $failure_msg
   2573 ##       after initial processing, when the error condition may get 
   2574 ##       ameliorated later.
   2575     #Initialize failure flags now.
   2576     $failure = 0;
   2577     $failure_msg = '';
   2578     $failure = rdb_make( keys %requested_filerules );
   2579     if ( ( $failure <= 0 ) || $force_mode ) {
   2580       rdb_for_some( [keys %one_time], \&rdb_run1 );
   2581     }
   2582     if ($#primary_warning_summary > -1) {
   2583 	# N.B. $mult_defined, $bad_reference, $bad_character, $bad_citation also available here.
   2584         if ($warnings_as_errors) {
   2585             $failure = 1;
   2586 	    $failure_msg = "Warning(s) from latex (or c.) for '$filename'; treated as error";
   2587         }
   2588     }
   2589     if ($failure > 0) { next FILE; }
   2590 } # end FILE
   2591 continue {
   2592     if ($deps_handle) { deps_list($deps_handle); }
   2593     # If requested, print the list of rules.  But don't do this in -pvc
   2594     # mode, since the rules list has already been printed.
   2595     if ($rules_list && ! $preview_continuous_mode) { rdb_list(); }
   2596     # Handle any errors
   2597     $error_message_count = rdb_show_rule_errors();
   2598     if ( ($error_message_count == 0) || ($failure > 0) ) {
   2599         if ( $failure_msg ) {
   2600             #Remove trailing space
   2601             $failure_msg =~ s/\s*$//;
   2602 	    warn "----------------------\n";
   2603 	    warn "This message may duplicate earlier message.\n";
   2604             warn "$My_name: Failure in processing file '$filename':\n",
   2605                  "   $failure_msg\n";
   2606 	    warn "----------------------\n";
   2607             $failure = 1;
   2608         }
   2609     }
   2610     if ( ($failure > 0) || ($error_message_count > 0) ) {
   2611         $failure_count ++;
   2612         push @failed_primaries, $filename;
   2613     }
   2614     &ifcd_popd;
   2615 }
   2616 close($deps_handle) if ( $deps_handle );
   2617 
   2618 if ($show_time) { show_timing();}
   2619 
   2620 sub show_timing {
   2621     my $processing_time = processing_time() - $processing_time1;
   2622     print @timings, "Accumulated processing time = $processing_time\n"; 
   2623     @timings = (); 
   2624     $processing_time1 = processing_time();
   2625 }
   2626 
   2627 # If we get here without going through the continue section:
   2628 if ( $do_cd && ($#dir_stack > -1) ) {
   2629    # Just in case we did an abnormal exit from the loop
   2630    warn "$My_name: Potential bug: dir_stack not yet unwound, undoing all directory changes now\n";
   2631    &finish_dir_stack;
   2632 }
   2633 
   2634 if ($failure_count > 0) {
   2635     if ( $#file_list > 0 ) {
   2636         # Error occured, but multiple files were processed, so
   2637         #     user may not have seen all the error messages
   2638         warn "\n------------\n";
   2639         show_array( 
   2640            "$My_name: Some operations failed, for the following tex file(s)", 
   2641            @failed_primaries);
   2642     }
   2643     if ( !$force_mode ) {
   2644       warn "$My_name: Use the -f option to force complete processing,\n",
   2645            " unless error was exceeding maximum runs, or warnings treated as errors.\n";
   2646     }
   2647     exit 12;
   2648 }
   2649 
   2650 if ( $where_log == 2 ) {
   2651     warn "$My_name: You requested aux_dir '$aux_dir_requested',\n".
   2652 	 "  but '$aux_dir' was used by the (pdf)latex engine.\n".
   2653 	 "  That indicates a configuration error.\n";
   2654     if ( ($tex_distribution !~ /^MiKTeX/i) && ($aux_dir_requested ne $out_dir_requested) ) {
   2655 	warn "  Probably you set different aux and out directories,\n".
   2656 	     "  but that is not supported by your TeX distribution.\n".
   2657  	     "  The only current distribution supporting this is MiKTeX.\n";
   2658     }
   2659 }
   2660 
   2661 
   2662 
   2663 # end MAIN PROGRAM
   2664 #############################################################
   2665 #############################################################
   2666 
   2667 sub set_tex_cmds {
   2668     # Usage, e.g., set_tex_cmds( '%O %S' )
   2669     my $args = $_[0];
   2670     foreach my $cmd ('latex', 'lualatex', 'pdflatex', 'xelatex' ) {
   2671 	${$cmd} = "$cmd $args";
   2672     }
   2673     # N.B. See setting of $latex_default_switches, ...,
   2674     # $xelatex_default_switches, etc, for any special options needed.
   2675 }
   2676 
   2677 sub std_tex_cmds { set_tex_cmds( '%O %S' ); }
   2678 
   2679 sub alt_tex_cmds { set_tex_cmds( '%O %P' ); }
   2680 
   2681 #========================
   2682 
   2683 sub test_fix_texnames {
   2684     my $illegal_char = 0;
   2685     my $unbalanced_quote = 0;
   2686     my $balanced_quote = 0;
   2687     foreach (@_) {
   2688         if ( $^O eq "MSWin32" ) {
   2689             # On MS-Win, change directory separator '\' to '/', as needed
   2690 	    # by the TeX engines, for which '\' introduces a macro name.
   2691 	    # Remember that '/' is a valid directory separator in MS-Win.
   2692             s[\\][/]g;
   2693         }
   2694 	if ( /[\Q$illegal_in_texname\E]/ ) {
   2695             $illegal_char++;
   2696 	    warn "$My_name: Filename '$_' contains character not allowed for TeX file.\n";
   2697 	}
   2698         my ($filename, $path) = fileparse( $_ );
   2699         if ( $do_cd && ($filename =~ /^&/) ) {
   2700             $illegal_char++;
   2701 	    warn "$My_name: Filename part of '$_' contains initial '&', which is\n",
   2702 		 "   not allowed for TeX file in my -cd mode.\n";
   2703         }
   2704         elsif ( /^&/ ) {
   2705             $illegal_char++;
   2706 	    warn "$My_name: Filename '$_' contains initial '&', which is not allowed for TeX file.\n";
   2707         }
   2708         my $count_q = ($_ =~ tr/\"//);
   2709         if ( ($count_q % 2) != 0 ) {
   2710             warn "$My_name: Filename '$_' contains unbalanced quotes, not allowed.\n";
   2711 	    $unbalanced_quote++;
   2712         }
   2713         elsif ( $count_q > 0 ) {
   2714             warn "$My_name: Removed (balanced quotes) from filename '$_',\n";
   2715             s/\"//g;
   2716             warn "   and obtained '$_'.\n";
   2717             $balanced_quote++;
   2718         }
   2719     }
   2720     if ($illegal_char || $unbalanced_quote) {
   2721 	die "$My_name: Stopping because of bad filename(s).\n";
   2722     }
   2723 }
   2724 
   2725 #############################################################
   2726 
   2727 sub ensure_path {
   2728     # Usage: ensure_path( $var, values ...)
   2729     # $ENV{$var} is an environment variable (e.g. $ENV{TEXINPUTS}.
   2730     # Ensure the values are in it, prepending them if not, and
   2731     # creating the environment variable if it doesn't already exist.
   2732     my $var = shift;
   2733     my %cmpts = ();
   2734     if ( exists $ENV{$var} ) {
   2735 	foreach ( split $search_path_separator, $ENV{$var} ) {
   2736 	    if ($_ ne '') { $cmpts{$_} = 1; }
   2737 	}
   2738     }
   2739     foreach (@_) {
   2740         next if ( ($_ eq '') || (exists $cmpts{$_}) );
   2741 	if (exists $ENV{$var}) {
   2742 	    $ENV{$var} = $_ . $search_path_separator . $ENV{$var};
   2743 	}
   2744 	else {
   2745 	    $ENV{$var} = $_ . $search_path_separator;
   2746 	}
   2747     }
   2748 }
   2749 
   2750 #############################################################
   2751 
   2752 sub set_dirs_etc {
   2753     # Normalize versions terminating in directory/path separator
   2754     # and versions referring to current directory
   2755     # These actions in a subroutine so they can be used elsewhere.
   2756     $out_dir1 = $out_dir;
   2757     $aux_dir1 = $aux_dir;
   2758     foreach ( $aux_dir1, $out_dir1 ) {
   2759         if ( ($_ ne '')  && ! m([\\/\:]$) ) {
   2760             $_ .= '/';
   2761         }
   2762         while ( s[^\.\/][] ) {}
   2763     }
   2764     if ($aux_dir) {
   2765 	# Ensure $aux_dir is in BIBINPUTS and TEXINPUTS search paths.
   2766 	# TEXINPUTS is used by dvips for files generated by mpost.
   2767 	# For BIBINPUTS, 
   2768 	# at least one widely package (revtex4-1) generates a bib file
   2769 	# (which is used in revtex4-1 for putting footnotes in the reference
   2770 	# list), and bibtex must be run to use it.  But latexmk needs to
   2771 	# determine the existence of the bib file by use of kpsewhich, otherwise
   2772 	# there is an error.  So cope with this situation (and any analogous
   2773 	# cases by adding the aux_dir to the relevant path search environment
   2774 	# variables.  BIBINPUTS seems to be the only one currently affected.
   2775 	foreach ( 'BIBINPUTS', 'TEXINPUTS' ) {
   2776 	    ensure_path( $_, $aux_dir );
   2777 	}
   2778     }
   2779 }
   2780 
   2781 #############################################################
   2782 
   2783 sub fix_cmds {
   2784    # If commands do not have placeholders for %S etc, put them in
   2785     foreach ($latex, $lualatex, $pdflatex, $xelatex, $lpr, $lpr_dvi, $lpr_pdf,
   2786              $pdf_previewer, $ps_previewer, $ps_previewer_landscape,
   2787              $dvi_previewer, $dvi_previewer_landscape,
   2788              $kpsewhich
   2789     ) {
   2790         # Source only
   2791         if ( $_ && ! /%/ ) { $_ .= " %O %S"; }
   2792     }
   2793     foreach ($pdf_previewer, $ps_previewer, $ps_previewer_landscape,
   2794              $dvi_previewer, $dvi_previewer_landscape,
   2795     ) {
   2796         # Run previewers detached
   2797         if ( $_ && ! /^(nostart|NONE|internal) / ) {
   2798             $_ = "start $_";
   2799         }
   2800     }
   2801     foreach ($biber, $bibtex) {
   2802         # Base only
   2803         if ( $_ && ! /%/ ) { $_ .= " %O %B"; }
   2804     }
   2805     foreach ($dvipdf, $ps2pdf) {
   2806         # Source and dest without flag for destination
   2807         if ( $_ && ! /%/ ) { $_ .= " %O %S %D"; }
   2808     }
   2809     foreach ($dvips, $makeindex) {
   2810         # Source and dest with -o dest before source
   2811         if ( $_ && ! /%/ ) { $_ .= " %O -o %D %S"; }
   2812     }
   2813     foreach ($dvi_filter, $ps_filter) {
   2814         # Source and dest, but as filters
   2815         if ( $_ && ! /%/ ) { $_ .= " %O <%S >%D"; }
   2816     }
   2817 } #END fix_cmds
   2818 
   2819 #############################################################
   2820 
   2821 sub add_option {
   2822     # Call add_option( $opt, \$cmd ... )
   2823     # Add option to one or more commands
   2824     my $option = shift;
   2825     while (@_) {
   2826         if ( ${$_[0]} !~ /%/ ) { &fix_cmds; }
   2827         ${$_[0]} =~ s/%O/$option %O/;
   2828         shift;
   2829     }
   2830 } #END add_option
   2831 
   2832 #############################################################
   2833 
   2834 sub rdb_make_rule_list {
   2835 # Set up specifications for standard rules, adjusted to current conditions
   2836 # Substitutions: %S = source, %D = dest, %B = this rule's base
   2837 #                %T = texfile, %R = root = base for latex.
   2838 #                %Y for $aux_dir1, %Z for $out_dir1
   2839 
   2840     # Defaults for dvi, ps, and pdf files
   2841     # Use local, not my, so these variables can be referenced
   2842     local $dvi_final = "%Z%R.dvi";
   2843     local $ps_final  = "%Z%R.ps";
   2844     local $pdf_final = "%Z%R.pdf";
   2845     local $xdv_final = "%Z%R.xdv";
   2846     if ( length($dvi_filter) > 0) {
   2847         $dvi_final = "%Z%R.dviF";
   2848     }
   2849     if ( length($ps_filter) > 0) {
   2850         $ps_final = "%Z%R.psF";
   2851     }
   2852 
   2853     my $print_file = '';
   2854     my $print_cmd = 'NONE';
   2855     if ( $print_type eq 'dvi' ) {
   2856         $print_file = $dvi_final;
   2857         $print_cmd = $lpr_dvi;
   2858     }
   2859     elsif ( $print_type eq 'pdf' ) {
   2860         $print_file = $pdf_final;
   2861         $print_cmd = $lpr_pdf;
   2862     }
   2863     elsif ( $print_type eq 'ps' ) {
   2864         $print_file = $ps_final;
   2865         $print_cmd = $lpr;
   2866     }
   2867     elsif ( $print_type eq 'none' ) {
   2868         $print_cmd = 'NONE echo NO PRINTING CONFIGURED';
   2869     }
   2870 
   2871     my $view_file = '';
   2872     my $viewer = '';
   2873     my $viewer_update_method = 0;
   2874     my $viewer_update_signal = undef;
   2875     my $viewer_update_command = undef;
   2876 
   2877     if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) { 
   2878         $view_file = ${$view.'_final'};
   2879         $viewer = ${$view.'_previewer'};
   2880         $viewer_update_method = ${$view.'_update_method'};
   2881         $viewer_update_signal = ${$view.'_update_signal'};
   2882         if (defined ${$view.'_update_command'}) {
   2883            $viewer_update_command = ${$view.'_update_command'};
   2884         }
   2885     }
   2886     # Specification of internal command for viewer update:
   2887     my $PA_update = ['do_update_view', $viewer_update_method, $viewer_update_signal, 0, 1];
   2888 
   2889 # For test_kind: Use file contents for latex and friends, but file time for the others.
   2890 # This is because, especially for dvi file, the contents of the file may contain
   2891 #    a pointer to a file to be included, not the contents of the file! 
   2892     %rule_list = (
   2893         'latex'    => [ 'primary',  "$latex",     '',            "%T",        "%Z%B.dvi",  "%R",   1, ["%Y%R.log"] ],
   2894         'pdflatex' => [ 'primary',  "$pdflatex",  '',            "%T",        "%Z%B.pdf",  "%R",   1, ["%Y%R.log"] ],
   2895         'lualatex' => [ 'primary',  "$lualatex",  '',            "%T",        "%Z%B.pdf",  "%R",   1, ["%Y%R.log"] ],
   2896         'xelatex' =>  [ 'primary',  "$xelatex",   '',            "%T",        "%Z%B.xdv",  "%R",   1, ["%Y%R.log"] ],
   2897         'dvipdf'   => [ 'external', "$dvipdf",    'do_viewfile', $dvi_final,  "%B.pdf",    "%Z%R", 2 ],
   2898         'xdvipdfmx' => [ 'external', "$xdvipdfmx", 'do_viewfile', $xdv_final, "%B.pdf",    "%Z%R", 2 ],
   2899         'dvips'    => [ 'external', "$dvips",     'do_viewfile', $dvi_final,  "%B.ps",     "%Z%R", 2 ],
   2900         'dvifilter'=> [ 'external', $dvi_filter,  'do_viewfile', "%B.dvi",    "%B.dviF",   "%Z%R", 2 ],
   2901         'ps2pdf'   => [ 'external', "$ps2pdf",    'do_viewfile', $ps_final,   "%B.pdf",    "%Z%R", 2 ],
   2902         'psfilter' => [ 'external', $ps_filter,   'do_viewfile', "%B.ps",     "%B.psF",    "%Z%R", 2 ],
   2903         'print'    => [ 'external', "$print_cmd", 'if_source',   $print_file, "",          "",     2 ],
   2904         'update_view' => [ 'external', $viewer_update_command, $PA_update,
   2905                                $view_file,  "",        "",   2 ],
   2906         'view'     => [ 'external', "$viewer",    'if_source',   $view_file,  "",        "",   2 ],
   2907     );
   2908 
   2909 # Ensure we only have one way to make pdf file, and that it is appropriate:
   2910     if    ($pdf_mode == 2) { delete $rule_list{'dvipdf'}; delete $rule_list{'pdflatex'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; }
   2911     elsif ($pdf_mode == 3) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; }
   2912     elsif ($pdf_mode == 4) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'dvipdf'}; delete $rule_list{'xelatex'}; }
   2913     elsif ($pdf_mode == 5) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'dvipdf'}; delete $rule_list{'lualatex'}; }
   2914     else                   { # Default is to leave pdflatex
   2915                              delete $rule_list{'dvipdf'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; 
   2916                            }
   2917 
   2918 } # END rdb_make_rule_list 
   2919 
   2920 #************************************************************
   2921 
   2922 sub rdb_set_rules {
   2923     # Call rdb_set_rules( \%rule_list, ...)
   2924     # Set up rule database from definitions
   2925 
   2926     # Map of files to rules that MAKE them:
   2927     %rule_db = ();
   2928 
   2929     foreach my $Prule_list (@_) {
   2930         foreach my $rule ( keys %$Prule_list) {
   2931             my ( $cmd_type, $ext_cmd, $int_cmd, $source, $dest, $base, $test_kind, $PA_extra_gen ) = @{$$Prule_list{$rule}};
   2932             if ( ! $PA_extra_gen ) { $PA_extra_gen = []; }
   2933             my $needs_making = 0;
   2934             # Substitute in the filename variables, since we will use
   2935             # those for determining filenames.  But delay expanding $cmd 
   2936             # until run time, in case of changes.
   2937             foreach ($base, $source, $dest, @$PA_extra_gen ) {
   2938                 s/%R/$root_filename/;
   2939                 s/%Y/$aux_dir1/;
   2940                 s/%Z/$out_dir1/;
   2941             }
   2942             foreach ($source, $dest ) { 
   2943                 s/%B/$base/;
   2944                 s/%T/$texfile_name/;
   2945             }
   2946     #        print "$rule: $cmd_type, EC='$ext_cmd', IC='$int_cmd', $test_kind,\n",
   2947     #              "    S='$source', D='$dest', B='$base' $needs_making\n";
   2948             rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, $test_kind, 
   2949                              $source, $dest, $base,
   2950                              $needs_making, undef, undef, 1, $PA_extra_gen );
   2951 # !! ?? Last line was
   2952 #                            $needs_making, undef, ($test_kind==1) );
   2953         }
   2954     } # End arguments of subroutine
   2955     &rdb_make_links;
   2956 } # END rdb_set_rules
   2957 
   2958 #************************************************************
   2959 
   2960 sub rdb_make_links {
   2961 # ?? Problem if there are multiple rules for getting a file.  Notably pdf.
   2962 #    Which one to choose?
   2963     # Create $from_rule if there's a suitable rule.
   2964     # Map files to rules:
   2965     local %from_rules = ();
   2966     rdb_for_all( sub{ if($$Pdest){$from_rules{$$Pdest} = $rule;} } );
   2967 #??    foreach (sort keys %from_rules) {print "D='$_' F='$from_rules{$_}\n";}
   2968     rdb_for_all( 
   2969         0,
   2970         sub{
   2971             # Set from_rule, but only if it isn't set or is invalid.
   2972             # Don't forget the biber v. bibtex issue
   2973             if ( exists $from_rules{$file}
   2974                  && ( (!$$Pfrom_rule) || (! exists $rule_db{$$Pfrom_rule} ) )
   2975                ) 
   2976             { $$Pfrom_rule = $from_rules{$file}; 
   2977             }
   2978         }
   2979     );
   2980     rdb_for_all( 
   2981         0,
   2982         sub{ 
   2983             if ( exists $from_rules{$file} ) { 
   2984                 $$Pfrom_rule = $from_rules{$file}; 
   2985             }
   2986             if ( $$Pfrom_rule && (! rdb_rule_exists( $$Pfrom_rule ) ) ) {
   2987                 $$Pfrom_rule = '';
   2988             }
   2989 #??            print "$rule: $file, $$Pfrom_rule\n";
   2990         }
   2991     );
   2992 } # END rdb_make_links
   2993 
   2994 #************************************************************
   2995 
   2996 sub set_trivial_aux_fdb {
   2997     # 1. Write aux file EXACTLY as would be written if the tex file
   2998     #    had no cross references, etc. I.e., a minimal .aux file. 
   2999     # 2. Write a corresponding fdb file
   3000     # 3. Provoke a run of (pdf)latex (actually of all primaries). 
   3001 
   3002     local *aux_file;
   3003     open( aux_file, '>', $aux_main )
   3004         or die "Cannot write file '$aux_main'\n";
   3005     print aux_file "\\relax \n";
   3006     close(aux_file);
   3007 
   3008     foreach my $rule (keys %primaries ) { 
   3009         rdb_ensure_file( $rule, $texfile_name );
   3010         rdb_ensure_file( $rule, $aux_main );
   3011         rdb_one_rule(  $rule,  
   3012                        sub{ $$Pout_of_date = 1; }
   3013                     );
   3014     }
   3015     &rdb_write( $fdb_name );
   3016 } #END set_trivial_aux_fdb
   3017 
   3018 #************************************************************
   3019 #### Particular actions
   3020 #************************************************************
   3021 #************************************************************
   3022 
   3023 sub do_cusdep {
   3024     # Unconditional application of custom-dependency
   3025     # except that rule is not applied if the source file source 
   3026     # does not exist, and an error is returned if the dest is not made.
   3027     #
   3028     # Assumes rule context for the custom-dependency, and that my first 
   3029     # argument is the name of the subroutine to apply
   3030     my $func_name = $_[0];
   3031     my $return = 0;
   3032     if ( !-e $$Psource ) {
   3033         # Source does not exist.  Users of this rule will need to turn
   3034         # it off when custom dependencies are reset
   3035         if ( !$silent ) {
   3036 ## ??? Was commented out.  1 Sep. 2008 restored, for cusdep no-file-exists issue
   3037             warn "$My_name: In trying to apply custom-dependency rule\n",
   3038             "  to make '$$Pdest' from '$$Psource'\n",
   3039             "  the source file has disappeared since the last run\n";
   3040         }
   3041         # Treat as successful
   3042     }
   3043     elsif ( !$func_name ) {
   3044         warn "$My_name: Possible misconfiguration or bug:\n",
   3045         "  In trying to apply custom-dependency rule\n",
   3046         "  to make '$$Pdest' from '$$Psource'\n",
   3047         "  the function name is blank.\n";
   3048     }
   3049     elsif ( ! defined &$func_name ) {
   3050         warn "$My_name: Misconfiguration or bug,",
   3051         " in trying to apply custom-dependency rule\n",
   3052         "  to make '$$Pdest' from '$$Psource'\n",
   3053         "  function name '$func_name' does not exists.\n";
   3054     }
   3055     else {
   3056         my $cusdep_ret = &$func_name( $$Pbase );
   3057         if ( defined $cusdep_ret && ($cusdep_ret != 0) ) {
   3058             $return = $cusdep_ret;
   3059             if ($return) {
   3060                 warn "Rule '$rule', function '$func_name'\n",
   3061                      "   failed with return code = $return\n";
   3062             }
   3063         }
   3064         elsif ( !-e $$Pdest ) {
   3065             # Destination non-existent, but routine failed to give an error
   3066             warn "$My_name: In running custom-dependency rule\n",
   3067             "  to make '$$Pdest' from '$$Psource'\n",
   3068             "  function '$func_name' did not make the destination.\n";
   3069             $return = -1;
   3070         }
   3071     }
   3072     return $return;
   3073 }  # END do_cusdep
   3074 
   3075 #************************************************************
   3076 
   3077 sub do_viewfile {
   3078     # Unconditionally make file for viewing, going through temporary file if
   3079     # Assumes rule context
   3080 
   3081     my $return = 0;
   3082     my ($base, $path, $ext) = fileparseA( $$Pdest );
   3083     if ( &view_file_via_temporary ) {
   3084         if ( $$Pext_cmd =~ /%D/ ) {
   3085             my $tmpfile = tempfile1( "${root_filename}_tmp", $ext );
   3086             warn "$My_name: Making '$$Pdest' via temporary '$tmpfile'...\n";
   3087             $return = &Run_subst( undef, undef, undef, undef, $tmpfile );
   3088             move( $tmpfile, $$Pdest );
   3089         }
   3090         else {
   3091             warn "$My_name is configured to make '$$Pdest' via a temporary file\n",
   3092                  "    but the command template '$$Pext_cmd' does not have a slot\n",
   3093             "    to set the destination file, so I won't use a temporary file\n";
   3094             $return = &Run_subst();
   3095         }
   3096     }
   3097     else {
   3098         $return = &Run_subst();
   3099     }
   3100     return $return;
   3101 } #END do_viewfile
   3102 
   3103 #************************************************************
   3104 
   3105 sub do_update_view {
   3106     # Update viewer
   3107     # Assumes rule context
   3108     # Arguments: (method, signal, viewer_process)
   3109 
   3110     my $return = 0;
   3111 
   3112     # Although the process is passed as an argument, we'll need to update it.
   3113     # So (FUDGE??) bypass the standard interface for the process.
   3114     # We might as well do this for all the arguments.
   3115     my $viewer_update_method = ${$PAint_cmd}[1];
   3116     my $viewer_update_signal = ${$PAint_cmd}[2];
   3117     my $Pviewer_process             = \${$PAint_cmd}[3];
   3118     my $Pneed_to_get_viewer_process = \${$PAint_cmd}[4];
   3119     
   3120     if ($viewer_update_method == 2) {
   3121         if ($$Pneed_to_get_viewer_process) {
   3122             $$Pviewer_process = &find_process_id( $$Psource );
   3123             if ($$Pviewer_process != 0) {
   3124                 $$Pneed_to_get_viewer_process = 0;
   3125             }
   3126         }
   3127         if ($$Pviewer_process == 0) {
   3128             print "$My_name: need to signal viewer for file '$$Psource', but didn't get \n",
   3129                   "   process ID for some reason, e.g., no viewer, bad configuration, bug\n"
   3130                 if $diagnostics ;             
   3131         }
   3132         elsif ( defined $viewer_update_signal) {
   3133             print "$My_name: signalling viewer, process ID $$Pviewer_process ",
   3134                   "with signal $viewer_update_signal\n"
   3135                 if $diagnostics ;
   3136             kill $viewer_update_signal, $$Pviewer_process;
   3137         }
   3138         else {
   3139             warn "$My_name: viewer is supposed to be sent a signal\n",
   3140                  "  but no signal is defined.  Misconfiguration or bug?\n";
   3141             $return = 1;
   3142         }
   3143     }
   3144     elsif ($viewer_update_method == 4) {
   3145         if (defined $$Pext_cmd) {
   3146             $return = &Run_subst();
   3147         }
   3148         else {
   3149             warn "$My_name: viewer is supposed to be updated by running a command,\n",
   3150                  "  but no command is defined.  Misconfiguration or bug?\n";
   3151         }
   3152     }
   3153     return $return;
   3154 } #END do_update_view
   3155 
   3156 #************************************************************
   3157 
   3158 sub if_source {
   3159     # Unconditionally apply rule if source file exists.
   3160     # Assumes rule context
   3161     if ( -e $$Psource ) {
   3162         return &Run_subst();
   3163     }
   3164     else {
   3165         warn "Needed source file '$$Psource' does not exist.\n";
   3166         return -1;
   3167     }
   3168 } #END if_source
   3169 
   3170 #************************************************************
   3171 #### Subroutines
   3172 #************************************************************
   3173 #************************************************************
   3174 
   3175 sub find_basename {
   3176     # Finds the basename of the root file
   3177     # Arguments:
   3178     #  1 - Filename to breakdown
   3179     #  2 - Where to place base file
   3180     #  3 - Where to place tex file
   3181     #  Returns non-zero if tex file does not exist
   3182     #
   3183     # The rules for determining this depend on the implementation of TeX.
   3184     # The variable $extension_treatment determines which rules are used.
   3185 
   3186     # !!!!!!!! I still need to implement use of kpsewhich to match behavior
   3187     # of (pdf)latex correctly.
   3188 
   3189   local($given_name, $base_name, $ext, $path, $tex_name);
   3190   $given_name = $_[0];
   3191   if ( "$extension_treatment" eq "miktex_old" ) {
   3192        # Miktex v. 1.20d: 
   3193        #   1. If the filename has an extension, then use it.
   3194        #   2. Else append ".tex".
   3195        #   3. The basename is obtained from the filename by
   3196        #      removing the path component, and the extension, if it
   3197        #      exists.  If a filename has a multiple extension, then
   3198        #      all parts of the extension are removed. 
   3199        #   4. The names of generated files (log, aux) are obtained by
   3200        #      appending .log, .aux, etc to the basename.  Note that
   3201        #      these are all in the CURRENT directory, and the drive/path
   3202        #      part of the originally given filename is ignored.
   3203        #
   3204        #   Thus when the given filename is "\tmp\a.b.c", the tex
   3205        #   filename is the same, and the basename is "a".
   3206 
   3207        ($base_name, $path, $ext) = fileparse( $given_name, '\..*' );
   3208        if ( "$ext" eq "") { $tex_name = "$given_name.tex"; }
   3209        else { $tex_name = $given_name; }
   3210        $_[1] = $base_name;
   3211        $_[2] = $tex_name;
   3212   }
   3213   elsif ( "$extension_treatment" eq "unix" ) {
   3214        # unix (at least TeXLive 2016) =>
   3215        #  A. Finding of tex file:
   3216        #   1. If filename.tex exists, use it,
   3217        #   2. else if kpsewhich finds filename.tex, use it
   3218        #   3. else if filename exists, use it,
   3219        #   4. else if kpsewhich finds filename, use it.
   3220        #   (Probably can unify the above by
   3221        #       1'. If kpsewhich finds filename.tex, use result.
   3222        #       2'. else if kpsewhich finds filename, use result.
   3223        #       3'. else report file not found.
   3224        # B. The base filename is obtained by deleting the path
   3225        #    component and, if an extension exists, the last
   3226        #    component of the extension, even if the extension is
   3227        #    null.  (A name ending in "." has a null extension.)
   3228        # C. The names of generated files (log, aux) are obtained by
   3229        #    appending .log, .aux, etc to the basename.  Note that
   3230        #    these are all in the CURRENT directory, and the drive/path
   3231        #    part of the originally given filename is ignored.
   3232        #
   3233        #   Thus when the given filename is "/tmp/a.b.c", there are two
   3234        #   cases: 
   3235        #      a.  /tmp/a.b.c.tex exists.  Then this is the tex file,
   3236        #          and the basename is "a.b.c".
   3237        #      b.  /tmp/a.b.c.tex does not exist.  Then the tex file is
   3238        #          "/tmp/a.b.c", and the basename is "a.b".
   3239        #   But there are also modifications of this when a file can be
   3240        #   found by kpsewhich.
   3241 
   3242       if ( -f "$given_name.tex" ) {
   3243          $tex_name = "$given_name.tex";
   3244       }
   3245       else {
   3246          $tex_name = "$given_name";
   3247       }
   3248       ($base_name, $path, $ext) = fileparse( $tex_name, '\.[^\.]*' );
   3249       $_[1] = $base_name;
   3250       $_[2] = $tex_name;
   3251   }
   3252   else {
   3253      die "$My_name: Incorrect configuration gives \$extension_treatment=",
   3254          "'$extension_treatment'\n";
   3255   }
   3256    if ($diagnostics) {
   3257       print "Given='$given_name', tex='$tex_name', base='$base_name'\n";
   3258   }
   3259   return ! -e $tex_name;
   3260 } #END find_basename
   3261 
   3262 #************************************************************
   3263 
   3264 sub make_preview_continuous {
   3265     local @changed = ();
   3266     local @disappeared = ();
   3267     local @no_dest = ();       # Non-existent destination files
   3268     local @rules_never_run = ();
   3269     local @rules_to_apply = ();
   3270 
   3271     local $failure = 0;
   3272     local %rules_applied = ();
   3273     local $updated = 0;
   3274 
   3275     # What to make?
   3276     my @targets = keys %requested_filerules;
   3277 
   3278     $quell_uptodate_msgs = 1;
   3279 
   3280     local $view_file = '';
   3281     rdb_one_rule( 'view', sub{ $view_file = $$Psource; } );
   3282   
   3283     if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) { 
   3284         warn "Viewing $view\n";
   3285     }
   3286     elsif ( $view eq 'none' ) {
   3287         warn "Not using a previewer\n";
   3288         $view_file = '';
   3289     }
   3290     else {
   3291         warn "$My_name:  BUG: Invalid preview method '$view'\n";
   3292         exit 20;
   3293     }
   3294 
   3295     my $viewer_running = 0;    # No viewer known to be running yet
   3296     # Get information from update_view rule
   3297     local $viewer_update_method = 0;
   3298     # Pointers so we can update the following:
   3299     local $Pviewer_process = undef;    
   3300     local $Pneed_to_get_viewer_process = undef;
   3301     rdb_one_rule( 'update_view', 
   3302                   sub{ $viewer_update_method = $$PAint_cmd[1]; 
   3303                        $Pviewer_process = \$$PAint_cmd[3]; 
   3304                        $Pneed_to_get_viewer_process = \$$PAint_cmd[4]; 
   3305                      } 
   3306                 );
   3307     # Note that we don't get the previewer process number from the program
   3308     # that starts it; that might only be a script to get things set up and the 
   3309     # actual previewer could be (and sometimes IS) another process.
   3310 
   3311     if ( ($view_file ne '') && (-e $view_file) && !$new_viewer_always ) {
   3312         # Is a viewer already running?
   3313         #    (We'll save starting up another viewer.)
   3314         $$Pviewer_process = &find_process_id( $view_file );
   3315         if ( $$Pviewer_process ) {
   3316             warn "$My_name: Previewer is already running\n" 
   3317               if !$silent;
   3318             $viewer_running = 1;
   3319             $$Pneed_to_get_viewer_process = 0;
   3320         }
   3321     }
   3322 
   3323     # Loop forever, rebuilding .dvi and .ps as necessary.
   3324     # Set $first_time to flag first run (to save unnecessary diagnostics)
   3325     my $last_action_time = time();
   3326     my $timed_out = 0;
   3327 CHANGE:
   3328     for (my $first_time = 1; 1; $first_time = 0 ) {
   3329         my %rules_to_watch = %requested_filerules;
   3330         $updated = 0;
   3331         $failure = 0;
   3332         $failure_msg = '';
   3333         if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) {
   3334             # Fudge under MSWin32 ONLY, to stop perl/latexmk from
   3335             #   catching ctrl/C and ctrl/break, and let it only reach
   3336             #   downstream programs. See comments at first definition of
   3337             #   $MSWin_fudge_break.
   3338             $SIG{BREAK} = $SIG{INT} = 'IGNORE';
   3339         }
   3340         if ($compiling_cmd) {
   3341             Run_subst( $compiling_cmd );
   3342         }
   3343         $failure = rdb_make( @targets );
   3344 
   3345 ##     warn "=========Viewer PID = $$Pviewer_process; updated=$updated\n";
   3346 
   3347         if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) {
   3348             $SIG{BREAK} = $SIG{INT} = 'DEFAULT';
   3349         }
   3350         # Start viewer if needed.
   3351         if ( ($failure > 0) && (! $force_mode) ) {
   3352             # No viewer yet
   3353         }
   3354         elsif ( ($view_file ne '') && (-e $view_file) && $updated && $viewer_running ) {
   3355             # A viewer is running.  Explicitly get it to update screen if we have to do it:
   3356             rdb_one_rule( 'update_view', \&rdb_run1 );
   3357         }
   3358         elsif ( ($view_file ne '') && (-e $view_file) && !$viewer_running ) {
   3359             # Start the viewer
   3360             if ( !$silent ) {
   3361                 if ($new_viewer_always) {
   3362                     warn "$My_name: starting previewer for '$view_file'\n",
   3363                          "------------\n";
   3364                 }
   3365                 else {
   3366                     warn "$My_name: I have not found a previewer that ",
   3367                          "is already running. \n",
   3368                          "   So I will start it for '$view_file'\n",
   3369                          "------------\n";
   3370                }
   3371             }
   3372             local $retcode = 0;
   3373             rdb_one_rule( 'view', sub { $retcode = &rdb_run1;} );
   3374             if ( $retcode != 0 ) {
   3375                 if ($force_mode) {
   3376                     warn "$My_name: I could not run previewer\n";
   3377                 }
   3378                 else {
   3379                     &exit_msg1( "I could not run previewer", $retcode);
   3380                 }
   3381             }
   3382             else {
   3383                 $viewer_running = 1;
   3384                 $$Pneed_to_get_viewer_process = 1;
   3385             } # end analyze result of trying to run viewer
   3386         } # end start viewer
   3387         if ( $failure > 0 ) {
   3388             if ( !$failure_msg ) {
   3389                 $failure_msg = 'Failure to make the files correctly';
   3390             }
   3391             @pre_primary = ();   # Array of rules
   3392             @post_primary = ();  # Array of rules
   3393             @unusual_one_time = ();      # Array of rules
   3394             &rdb_classify_rules( \%possible_primaries, keys %requested_filerules );
   3395             # There will be files changed during the run that are irrelevant.
   3396             # We need to wait for the user to change the files.
   3397 
   3398             # So set the GENERATED files from (pdf)latex as up-to-date:
   3399             rdb_for_some( [keys %current_primaries], \&rdb_update_gen_files );
   3400 
   3401             # And don't watch for changes for post_primary rules (ps and pdf 
   3402             # from dvi, etc haven't been run after an error in (pdf)latex, so
   3403             # are out-of-date by filetime criterion, but they should not be run
   3404             # until after another (pdf)latex run:
   3405             foreach (@post_primary) { delete $rules_to_watch{$_}; }
   3406 
   3407             $failure_msg =~ s/\s*$//;  #Remove trailing space
   3408             warn "$My_name: $failure_msg\n",
   3409     "    ==> You will need to change a source file before I do another run <==\n";
   3410             if ($failure_cmd) {
   3411                 Run_subst( $failure_cmd );
   3412             }
   3413         }
   3414         else {
   3415 	    if ( ($#primary_warning_summary > -1) && $warning_cmd ) {
   3416                 Run_subst( $warning_cmd );
   3417             }
   3418 	    elsif ( ($#primary_warning_summary > -1) && $warnings_as_errors && $failure_cmd ) {
   3419                 Run_subst( $failure_cmd );
   3420             }
   3421             elsif ($success_cmd) {
   3422                 Run_subst( $success_cmd );
   3423             }
   3424         }
   3425         rdb_show_rule_errors();
   3426         if ($rules_list) { rdb_list(); }
   3427         if ($show_time && ! $first_time) { show_timing(); }
   3428         if ( $dependents_list && ($updated || $failure) ) {
   3429            my $deps_handle = new FileHandle "> $deps_file";
   3430            if ( defined $deps_handle ) {
   3431                deps_list($deps_handle);
   3432                close($deps_handle);
   3433            }
   3434            else {
   3435                warn "Cannot open '$deps_file' for output of dependency information\n";
   3436            }
   3437          }
   3438         if ( $first_time || $updated || $failure ) {
   3439             system("notify-send", "latexmk complete", "--expire-time=1000");
   3440             print "\n=== Watching for updated files. Use ctrl/C to stop ...\n";
   3441         }
   3442         $waiting = 1; if ($diagnostics) { warn "WAITING\n"; }
   3443 # During waiting for file changes, handle ctrl/C and ctrl/break here, rather than letting
   3444 #   system handle them by terminating script (and any script that calls it).  This allows,
   3445 #   for example, the clean up code in the following command line to work:
   3446 #          latexmk -pvc foo; cleanup;
   3447         &catch_break;
   3448         $have_break = 0;
   3449         $last_action_time = time();
   3450   WAIT: while (1) {
   3451            sleep( $sleep_time );
   3452            if ($have_break) { last WAIT; }
   3453            if ( rdb_new_changes(keys %rules_to_watch) ) { 
   3454                if (!$silent) {
   3455                    warn "$My_name: Need to remake files.\n";
   3456                    &rdb_diagnose_changes( '  ' );
   3457                }
   3458                last WAIT;
   3459            }
   3460            #  Don't count waiting time in processing:
   3461            $processing_time1 = processing_time();
   3462         # Does this do this job????
   3463            local $new_files = 0;
   3464            rdb_for_some( [keys %current_primaries], sub{ $new_files += &rdb_find_new_files } );
   3465            if ($new_files > 0) {
   3466                warn "$My_name: New file(s) found.\n";
   3467                last WAIT; 
   3468            }
   3469            if ($have_break) { last WAIT; }
   3470            if ($pvc_timeout && ( time() > $last_action_time+60*$pvc_timeout_mins ) ) {
   3471 	       $timed_out = 1;
   3472 	       last WAIT;
   3473            }
   3474      } # end WAIT:
   3475      &default_break;
   3476      if ($have_break) { 
   3477           print "$My_name: User typed ctrl/C or ctrl/break.  I'll finish.\n";
   3478           return;
   3479      }
   3480      if ($timed_out) {
   3481          print "$My_name: More than $pvc_timeout_mins mins of inactivity.  I'll finish.\n";
   3482          return;
   3483      }
   3484      $waiting = 0; if ($diagnostics) { warn "NOT       WAITING\n"; }
   3485   } #end infinite_loop CHANGE:
   3486 } #END sub make_preview_continuous
   3487 
   3488 #************************************************************
   3489 
   3490 sub process_rc_file {
   3491     # Usage process_rc_file( filename )
   3492     # NEW VERSION
   3493     # Run rc_file whose name is given in first argument
   3494     #    Exit with code 0 on success
   3495     #    Exit with code 1 if file cannot be read or does not exist.
   3496     #    Stop if there is a syntax error or other problem.
   3497     # PREVIOUSLY: 
   3498     #    Exit with code 2 if is a syntax error or other problem.
   3499     my $rc_file = $_[0];
   3500     my $ret_code = 0;
   3501     warn "$My_name: Executing Perl code in file '$rc_file'...\n" 
   3502         if  $diagnostics;
   3503     # I could use the do command of perl, but the preceeding -r test
   3504     # to get good diagnostics gets the wrong result under cygwin
   3505     # (e.g., on /cygdrive/c/latexmk/LatexMk)
   3506     my $RCH = new FileHandle;
   3507     if ( !-e $rc_file ) {
   3508         warn "$My_name: The rc-file '$rc_file' does not exist\n";
   3509         return 1;
   3510     }
   3511     elsif ( -d $rc_file ) {
   3512         warn "$My_name: The supposed rc-file '$rc_file' is a directory; but it\n",
   3513              "          should be a normal text file\n";
   3514         return 1;
   3515     }
   3516     elsif ( open $RCH, "<$rc_file" ) {
   3517         { local $/; eval <$RCH>; }
   3518         close $RCH;
   3519     }
   3520     else {
   3521         warn "$My_name: I cannot read the rc-file '$rc_file'\n";
   3522         return 1;
   3523     }
   3524     # PREVIOUS VERSION
   3525 #    if ( ! -r $rc_file ) {
   3526 #        warn "$My_name: I cannot read the rc-file '$rc_file'\n",
   3527 #            "          or at least that's what Perl (for $^O) reports\n";
   3528 #        return 1;
   3529 #    }
   3530 #    do( $rc_file );
   3531     if ( $@ ) {
   3532         # Indent each line of possibly multiline message:
   3533         my $message = prefix( $@, "     " );
   3534         warn "$My_name: Initialization file '$rc_file' gave an error:\n",
   3535              "$message\n";
   3536         die "$My_name: Stopping because of problem with rc file\n";
   3537         # Use the following if want non-fatal error.
   3538         return 2;
   3539     }
   3540     return 0;
   3541 } #END process_rc_file
   3542 
   3543 #************************************************************
   3544 
   3545 sub execute_code_string {
   3546     # Usage execute_code_string( string_of_code )
   3547     # Run the perl code contained in first argument
   3548     #    Halt if there is a syntax error or other problem.
   3549     # ???Should I leave the exiting to the caller (perhaps as an option)?
   3550     #     But I can always catch it with an eval if necessary.
   3551     #     That confuses ctrl/C and ctrl/break handling.
   3552     my $code = $_[0];
   3553     warn "$My_name: Executing initialization code specified by -e:\n",
   3554          "   '$code'...\n" 
   3555         if  $diagnostics;
   3556     eval $code;
   3557     # The return value from the eval is not useful, since it is the value of 
   3558     #    the last expression evaluated, which could be anything.
   3559     # The correct test of errors is on the value of $@.
   3560 
   3561     if ( $@ ) {
   3562         # Indent each line of possibly multiline message:
   3563         my $message = prefix( $@, "    " );
   3564         die "$My_name: ",
   3565             "Stopping because executing following code from command line\n",
   3566             "    $code\n",
   3567             "gave an error:\n",
   3568             "$message\n";
   3569     }
   3570 } #END execute_code_string
   3571 
   3572 #************************************************************
   3573 
   3574 sub cleanup1 {
   3575     # Usage: cleanup1( directory, exts_without_period, ... )
   3576     #
   3577     # The directory and the root file name are fixed names, so I must escape
   3578     #   any glob metacharacters in them:
   3579     my $dir = fix_pattern( shift );
   3580     my $root_fixed = fix_pattern( $root_filename );
   3581     foreach (@_) { 
   3582         my $name = /%R/ ? $_ : "%R.$_";
   3583 	$name =~ s/%R/${root_fixed}/;
   3584 	$name = $dir.$name;
   3585         unlink_or_move( my_glob( "$name" ) );
   3586     }
   3587 } #END cleanup1
   3588 
   3589 #************************************************************
   3590 
   3591 sub cleanup_cusdep_generated {
   3592     # Remove files generated by custom dependencies
   3593     rdb_for_all( \&cleanup_one_cusdep_generated );
   3594 } #END cleanup_cusdep_generated
   3595 
   3596 #************************************************************
   3597 
   3598 sub cleanup_one_cusdep_generated {
   3599     # Remove destination file generated by one custom dependency
   3600     # Assume rule context, but not that the rule is a custom dependency.
   3601     # Only delete destination file if source file exists (so destination 
   3602     #   file can be recreated)
   3603     if ( $$Pcmd_type ne 'cusdep' ) {
   3604        # NOT cusdep
   3605        return;
   3606     }
   3607     if ( (-e $$Pdest) && (-e $$Psource) ) {
   3608         unlink_or_move( $$Pdest );
   3609     }
   3610     elsif ( (-e $$Pdest) && (!-e $$Psource) ) {
   3611         warn "$My_name: For custom dependency '$rule',\n",
   3612              "    I won't delete destination file '$$Pdest'\n",
   3613              "    because the source file '$$Psource' doesn't exist,\n",
   3614              "    so the destination file may not be able to be recreated\n";
   3615     }
   3616 } #END cleanup_one_cusdep_generated
   3617 
   3618 #************************************************************
   3619 #************************************************************
   3620 #************************************************************
   3621 
   3622 #   Error handling routines, warning routines, help
   3623 
   3624 #************************************************************
   3625 
   3626 sub die_trace {
   3627     # Call: die_trace( message );
   3628     &traceback;   # argument(s) passed unchanged
   3629     die "\n";
   3630 } #END die_trace
   3631 
   3632 #************************************************************
   3633 
   3634 sub traceback {
   3635     # Call: &traceback 
   3636     # or traceback( message,  )
   3637     my $msg = shift;
   3638     if ($msg) { warn "$msg\n"; }
   3639     warn "Traceback:\n";
   3640     my $i=0;     # Start with immediate caller
   3641     while ( my ($pack, $file, $line, $func) = caller($i++) ) {
   3642         if ($func eq 'die_trace') { next; }
   3643         warn "   $func called from line $line\n";
   3644     }
   3645 } #END traceback
   3646 
   3647 #************************************************************
   3648 
   3649 sub exit_msg1
   3650 {
   3651   # exit_msg1( error_message, retcode [, action])
   3652   #    1. display error message
   3653   #    2. if action set, then restore aux file
   3654   #    3. exit with retcode
   3655   warn "\n------------\n";
   3656   warn "$My_name: $_[0].\n";
   3657   warn "-- Use the -f option to force complete processing.\n";
   3658 
   3659   my $retcode = $_[1];
   3660   if ($retcode >= 256) {
   3661      # Retcode is the kind returned by system from an external command
   3662      # which is 256 * command's_retcode
   3663      $retcode /= 256;
   3664   }
   3665   exit $retcode;
   3666 } #END exit_msg1
   3667 
   3668 #************************************************************
   3669 
   3670 sub warn_running {
   3671    # Message about running program:
   3672     if ( $silent ) {
   3673         warn "$My_name: @_\n";
   3674     }
   3675     else {
   3676         warn "------------\n@_\n------------\n";
   3677     }
   3678 } #END warn_running
   3679 
   3680 #************************************************************
   3681 
   3682 sub exit_help
   3683 # Exit giving diagnostic from arguments and how to get help.
   3684 {
   3685     warn "\n$My_name: @_\n",
   3686          "Use\n",
   3687          "   $my_name -help\nto get usage information\n";
   3688     exit 10;
   3689 } #END exit_help
   3690 
   3691 
   3692 #************************************************************
   3693 
   3694 sub print_help
   3695 {
   3696   print
   3697   "$My_name $version_num: Automatic LaTeX document generation routine\n\n",
   3698   "Usage: $my_name [latexmk_options] [filename ...]\n\n",
   3699   "  Latexmk_options:\n",
   3700   "   -aux-directory=dir or -auxdir=dir \n",
   3701   "                 - set name of directory for auxiliary files (aux, log)\n",
   3702   "                 - Currently this only works with MiKTeX\n",
   3703   "   -bibtex       - use bibtex when needed (default)\n",
   3704   "   -bibtex-      - never use bibtex\n",
   3705   "   -bibtex-cond  - use bibtex when needed, but only if the bib file exists\n",
   3706   "   -bibtex-cond1 - use bibtex when needed, but only if the bib file exists;\n",
   3707   "                   on cleanup delete bbl file only if bib file exists\n",
   3708   "   -bm <message> - Print message across the page when converting to postscript\n",
   3709   "   -bi <intensity> - Set contrast or intensity of banner\n",
   3710   "   -bs <scale> - Set scale for banner\n",
   3711   "   -commands  - list commands used by $my_name for processing files\n",
   3712   "   -c     - clean up (remove) all nonessential files, except\n",
   3713   "            dvi, ps and pdf files.\n",
   3714   "            This and the other clean-ups are instead of a regular make.\n",
   3715   "   -C     - clean up (remove) all nonessential files\n",
   3716   "            including aux, dep, dvi, postscript and pdf files\n",
   3717   "            and file of database of file information\n",
   3718   "   -CA     - clean up (remove) all nonessential files.\n",
   3719   "            Equivalent to -C option.\n",
   3720   "   -CF     - Remove file of database of file information before doing \n",
   3721   "            other actions\n",
   3722   "   -cd    - Change to directory of source file when processing it\n",
   3723   "   -cd-   - Do NOT change to directory of source file when processing it\n",
   3724   "   -dependents or -deps - Show list of dependent files after processing\n",
   3725   "   -dependents- or -deps- - Do not show list of dependent files\n",
   3726   "   -deps-out=file - Set name of output file for dependency list,\n",
   3727   "                    and turn on showing of dependency list\n",
   3728   "   -dF <filter> - Filter to apply to dvi file\n",
   3729   "   -dvi   - generate dvi\n",
   3730   "   -dvi-  - turn off required dvi\n",
   3731   "   -e <code> - Execute specified Perl code (as part of latexmk start-up\n",
   3732   "               code)\n",
   3733   "   -f     - force continued processing past errors\n",
   3734   "   -f-    - turn off forced continuing processing past errors\n",
   3735   "   -gg    - Super go mode: clean out generated files (-CA), and then\n",
   3736   "            process files regardless of file timestamps\n",
   3737   "   -g     - process regardless of file timestamps\n",
   3738   "   -g-    - Turn off -g\n",
   3739   "   -h     - print help\n",
   3740   "   -help - print help\n",
   3741   "   -jobname=STRING - set basename of output file(s) to STRING.\n",
   3742   "            (Like --jobname=STRING on command line for many current\n",
   3743   "            implementations of latex/pdflatex.)\n",
   3744   "   -l     - force landscape mode\n",
   3745   "   -l-    - turn off -l\n",
   3746   "   -latex=<program> - set program used for latex.\n",
   3747   "                      (replace '<program>' by the program name)\n",
   3748   "   -latexoption=<option> - add the given option to the (pdf)latex command\n",
   3749   "   -logfilewarninglist or -logfilewarnings \n",
   3750   "               give list of warnings after run of (pdf)latex\n",
   3751   "   -logfilewarninglist- or -logfilewarnings- \n",
   3752   "               do not give list of warnings after run of (pdf)latex\n",
   3753   "   -lualatex     - use lualatex for processing files to pdf\n",
   3754   "                   and turn dvi/ps modes off\n",
   3755   "   -M     - Show list of dependent files after processing\n",
   3756   "   -MF file - Specifies name of file to receives list dependent files\n",
   3757   "   -MP    - List of dependent files includes phony target for each source file.\n",
   3758   "   -new-viewer    - in -pvc mode, always start a new viewer\n",
   3759   "   -new-viewer-   - in -pvc mode, start a new viewer only if needed\n",
   3760   "   -nobibtex      - never use bibtex\n",
   3761   "   -nodependents  - Do not show list of dependent files after processing\n",
   3762   "   -norc          - omit automatic reading of system, user and project rc files\n",
   3763   "   -output-directory=dir or -outdir=dir\n",
   3764   "                  - set name of directory for output files\n",
   3765   "   -pdf   - generate pdf by pdflatex\n",
   3766   "   -pdfdvi - generate pdf by dvipdf\n",
   3767   "   -pdflatex=<program> - set program used for pdflatex.\n",
   3768   "                      (replace '<program>' by the program name)\n",
   3769   "   -pdflualatex=<program> - set program used for lualatex.\n",
   3770   "                      (replace '<program>' by the program name)\n",
   3771   "   -pdfps - generate pdf by ps2pdf\n",
   3772   "   -pdflua - generate pdf by lualatex\n",
   3773   "   -pdfxe - generate pdf by xelatex\n",
   3774   "   -pdfxelatex=<program> - set program used for xelatex.\n",
   3775   "                      (replace '<program>' by the program name)\n",
   3776   "   -pdf-  - turn off pdf\n",
   3777   "   -ps    - generate postscript\n",
   3778   "   -ps-   - turn off postscript\n",
   3779   "   -pF <filter> - Filter to apply to postscript file\n",
   3780   "   -p     - print document after generating postscript.\n",
   3781   "            (Can also .dvi or .pdf files -- see documentation)\n",
   3782   "   -pretex=<TeX code> - Sets TeX code to be executed before inputting source\n",
   3783   "                    file, if commands suitable configured\n",    
   3784   "   -print=dvi     - when file is to be printed, print the dvi file\n",
   3785   "   -print=ps      - when file is to be printed, print the ps file (default)\n",
   3786   "   -print=pdf     - when file is to be printed, print the pdf file\n",
   3787   "   -pv    - preview document.  (Side effect turn off continuous preview)\n",
   3788   "   -pv-   - turn off preview mode\n",
   3789   "   -pvc   - preview document and continuously update.  (This also turns\n",
   3790   "                on force mode, so errors do not cause $my_name to stop.)\n",
   3791   "            (Side effect: turn off ordinary preview mode.)\n",
   3792   "   -pvc-  - turn off -pvc\n",
   3793   "   -pvctimeout    - timeout in pvc mode after period of inactivity\n",
   3794   "   -pvctimeout-   - don't timeout in pvc mode after inactivity\n",
   3795   "   -pvctimeoutmins=<time> - set period of inactivity (minutes) for pvc timeout\n",
   3796   "   -quiet    - silence progress messages from called programs\n",
   3797   "   -r <file> - Read custom RC file\n",
   3798   "               (N.B. This file could override options specified earlier\n",
   3799   "               on the command line.)\n",
   3800   "   -recorder - Use -recorder option for (pdf)latex\n",
   3801   "               (to give list of input and output files)\n",
   3802   "   -recorder- - Do not use -recorder option for (pdf)latex\n",
   3803   "   -rules    - Show list of rules after processing\n",
   3804   "   -rules-   - Do not show list of rules after processing\n",
   3805   "   -showextraoptions  - Show other allowed options that are simply passed\n",
   3806   "               as is to latex and pdflatex\n",
   3807   "   -silent   - silence progress messages from called programs\n",
   3808   "   -stdtexcmds - Sets standard commands for *latex\n",    
   3809   "   -time     - show CPU time used\n",
   3810   "   -time-    - don't show CPU time used\n",
   3811   "   -use-make - use the make program to try to make missing files\n",
   3812   "   -use-make- - don't use the make program to try to make missing files\n",
   3813   "   -usepretex - Sets commands for *latex to use extra code before inputting\n",
   3814   "                source file\n",    
   3815   "   -usepretex=<TeX code> - Equivalent to -pretex=<TeX code> -usepretex\n",
   3816   "   -v        - display program version\n",
   3817   "   -verbose  - display usual progress messages from called programs\n",
   3818   "   -version      - display program version\n",
   3819   "   -view=default - viewer is default (dvi, ps, pdf)\n",
   3820   "   -view=dvi     - viewer is for dvi\n",
   3821   "   -view=none    - no viewer is used\n",
   3822   "   -view=ps      - viewer is for ps\n",
   3823   "   -view=pdf     - viewer is for pdf\n",
   3824   "   -Werror   - treat warnings from called programs as errors\n",
   3825   "   -xelatex      - use xelatex for processing files to pdf\n",
   3826   "                   and turn dvi/ps modes off\n",
   3827   "\n",
   3828   "   filename = the root filename of LaTeX document\n",
   3829   "\n",
   3830   "-p, -pv and -pvc are mutually exclusive\n",
   3831   "-h, -c and -C override all other options.\n",
   3832   "-pv and -pvc require one and only one filename specified\n",
   3833   "All options can be introduced by '-' or '--'.  (E.g., --help or -help.)\n",
   3834   " \n",
   3835   "In addition, latexmk recognizes many other options that are passed to\n",
   3836   "latex and/or pdflatex without interpretation by latexmk.  Run latexmk\n",
   3837   "with the option -showextraoptions to see a list of these\n",
   3838   "\n",
   3839   "Report bugs etc to John Collins <jcc8 at psu.edu>.\n";
   3840 
   3841 } #END print_help
   3842 
   3843 #************************************************************
   3844 
   3845 sub print_commands {
   3846   warn "Commands used by $my_name:\n",
   3847        "   To run latex, I use \"$latex\"\n",
   3848        "   To run pdflatex, I use \"$pdflatex\"\n",
   3849        "   To run lualatex, I use \"$lualatex\"\n",
   3850        "   To run xelatex, I use \"$xelatex\"\n",
   3851        "   To run biber, I use \"$biber\"\n",
   3852        "   To run bibtex, I use \"$bibtex\"\n",
   3853        "   To run makeindex, I use \"$makeindex\"\n",
   3854        "   To make a ps file from a dvi file, I use \"$dvips\"\n",
   3855        "   To make a ps file from a dvi file with landscape format, ",
   3856            "I use \"$dvips_landscape\"\n",
   3857        "   To make a pdf file from a dvi file, I use \"$dvipdf\"\n",
   3858        "   To make a pdf file from a ps file, I use \"$ps2pdf\"\n",
   3859        "   To make a pdf file from an xdv file, I use \"$xdvipdfmx\"\n",
   3860        "   To view a pdf file, I use \"$pdf_previewer\"\n",
   3861        "   To view a ps file, I use \"$ps_previewer\"\n",
   3862        "   To view a ps file in landscape format, ",
   3863             "I use \"$ps_previewer_landscape\"\n",
   3864        "   To view a dvi file, I use \"$dvi_previewer\"\n",
   3865        "   To view a dvi file in landscape format, ",
   3866             "I use \"$dvi_previewer_landscape\"\n",
   3867        "   To print a ps file, I use \"$lpr\"\n",
   3868        "   To print a dvi file, I use \"$lpr_dvi\"\n",
   3869        "   To print a pdf file, I use \"$lpr_pdf\"\n",
   3870        "   To find running processes, I use \"$pscmd\", \n",
   3871        "      and the process number is at position $pid_position\n";
   3872    warn "Notes:\n",
   3873         "  Command starting with \"start\" is run detached\n",
   3874         "  Command that is just \"start\" without any other command, is\n",
   3875         "     used under MS-Windows to run the command the operating system\n",
   3876         "     has associated with the relevant file.\n",
   3877         "  Command starting with \"NONE\" is not used at all\n";
   3878 } #END print_commands
   3879 
   3880 #************************************************************
   3881 
   3882 sub view_file_via_temporary {
   3883     return $always_view_file_via_temporary 
   3884            || ($pvc_view_file_via_temporary && $preview_continuous_mode);
   3885 } #END view_file_via_temporary
   3886 
   3887 #************************************************************
   3888 #### Tex-related utilities
   3889 
   3890 #**************************************************
   3891 
   3892 sub check_biber_log {
   3893     # Check for biber warnings:
   3894     # Usage: check_biber_log( base_of_biber_run, \@biber_source )
   3895     # return 0: OK;
   3896     #        1: biber warnings;
   3897     #        2: biber errors;
   3898     #        3: could not open .blg file;
   3899     #        4: failed to find one or more source files, except for bibfile;
   3900     #        5: failed to find bib file;
   3901     #        6: missing file, one of which is control file
   3902     #       10: only error is missing \citation commands.
   3903     #       11: Malformed bcf file (normally due to error in pdflatex run)
   3904     # Side effect: add source files @biber_source
   3905     my $base = $_[0];
   3906     my $Pbiber_source = $_[1];
   3907     my $log_name = "$base.blg";
   3908     my $log_file = new FileHandle;
   3909     open( $log_file, "<$log_name" )
   3910       or return 3;
   3911     my $have_warning = 0;
   3912     my $have_error = 0;
   3913     my $missing_citations = 0;
   3914     my $no_citations = 0;
   3915     my $error_count = 0;            # From my counting of error messages
   3916     my $warning_count = 0;          # From my counting of warning messages
   3917     # The next two occur only from biber
   3918     my $bibers_error_count = 0;     # From biber's counting of errors
   3919     my $bibers_warning_count = 0;   # From biber's counting of warnings
   3920     my $not_found_count = 0;
   3921     my $control_file_missing = 0;
   3922     my $control_file_malformed = 0;
   3923     my %remote = ();                # List of extensions of remote files
   3924     while (<$log_file>) {
   3925         if (/> WARN /) { 
   3926             print "Biber warning: $_"; 
   3927             $have_warning = 1;
   3928             $warning_count ++;
   3929         }
   3930         elsif (/> (FATAL|ERROR) /) {
   3931             print "Biber error: $_"; 
   3932             if ( /> (FATAL|ERROR) - Cannot find file '([^']+)'/    #'
   3933                  || /> (FATAL|ERROR) - Cannot find '([^']+)'/ ) {  #'
   3934                 $not_found_count++;
   3935                 push @$Pbiber_source, $2;
   3936             }
   3937             elsif ( /> (FATAL|ERROR) - Cannot find control file '([^']+)'/ ) {  #'
   3938                 $not_found_count++;
   3939                 $control_file_missing = 1;
   3940                 push @$Pbiber_source, $2;
   3941             }
   3942             elsif ( /> ERROR - .*\.bcf is malformed/ ) {
   3943 		#  Special treatment: Malformed .bcf file commonly results from error
   3944 		#  in (pdf)latex run.  This error must be ignored.
   3945 		$control_file_malformed = 1;
   3946 	    }
   3947             else {
   3948                 $have_error = 1;
   3949                 $error_count ++;
   3950                 if ( /> (FATAL|ERROR) - The file '[^']+' does not contain any citations!/ ) { #'
   3951                     $no_citations++;
   3952                 }
   3953             }
   3954         }
   3955         elsif ( /> INFO - Data source '([^']*)' is a remote BibTeX data source - fetching/
   3956 	    ){
   3957 	    my $spec = $1;
   3958             my ( $base, $path, $ext ) = fileparseA( $spec );
   3959             $remote{$ext} = 1;
   3960 	}
   3961         elsif ( /> INFO - Found .* '([^']+)'\s*$/
   3962                 || /> INFO - Found '([^']+)'\s*$/
   3963                 || /> INFO - Reading '([^']+)'\s*$/
   3964                 || /> INFO - Processing .* file '([^']+)' .*$/
   3965 	    ) {
   3966 	    my $file = $1;
   3967             my ( $base, $path, $ext ) = fileparseA( $file );
   3968 	    if ($remote{$ext} && ( $base =~ /^biber_remote_data_source/ ) && 1) {
   3969 		# Ignore the file, which appears to be a temporary local copy
   3970 		# of a remote file. Treating the file as a source file will
   3971 		# be misleading, since it will normally have been deleted by
   3972 		# biber itself.
   3973 	    }
   3974             elsif ( (defined $Pbiber_source) && (-e $file) ) {
   3975 		# Note that biber log file gives full path to file. (No search is
   3976 		# needed to find it.)  The file must have existed when biber was
   3977 		# run.  If it doesn't exist now, a few moments later, it must
   3978 		# have gotten deleted, probably by biber (e.g., because it is a
   3979 		# copy of a remote file).
   3980 		# So I have included a condition above that the file must
   3981 		# exist to be included in the source-file list.
   3982                 push @$Pbiber_source, $file;
   3983             }
   3984         }
   3985         elsif ( /> INFO - WARNINGS: ([\d]+)\s*$/ ) {
   3986             $bibers_warning_count = $1;
   3987         }
   3988         elsif ( /> INFO - ERRORS: ([\d]+)\s*$/ ) {
   3989             $bibers_error_count = $1;
   3990         }
   3991     }
   3992     close $log_file;
   3993     if ($control_file_malformed){return 11;} 
   3994 
   3995     my @not_found = &find_file_list1( $Pbiber_source, $Pbiber_source,
   3996                                       '', \@BIBINPUTS );
   3997     @$Pbiber_source = uniqs( @$Pbiber_source );
   3998 
   3999     if ( ($#not_found < 0) && ($#$Pbiber_source >= 0) ) {
   4000         warn "$My_name: Found biber source file(s) [@$Pbiber_source]\n"
   4001         unless $silent;
   4002     }
   4003     elsif ( ($#not_found == 0) && ($not_found[0] =~ /\.bib$/) ) {
   4004         # Special treatment if sole missing file is bib file
   4005         # I don't want to treat that as an error
   4006         warn "$My_name: Biber did't find bib file [$not_found[0]]\n";
   4007         return 5;
   4008     }
   4009     else {
   4010         warn "$My_name: Failed to find one or more biber source files:\n";
   4011         foreach (@not_found) { warn "    '$_'\n"; }
   4012         if ($force_mode) {
   4013             warn "==== Force_mode is on, so I will continue.  ",
   4014                  "But there may be problems ===\n";
   4015         }
   4016         if ($control_file_missing) {
   4017             return 6;
   4018         }
   4019         return 4;
   4020     }
   4021 #    print "$My_name: #Biber errors = $error_count, warning messages = $warning_count,\n  ",
   4022 #          "missing citation messages = $missing_citations, no_citations = $no_citations\n";
   4023     if ( ! $have_error && $no_citations ) {
   4024         # If the only errors are missing citations, or lack of citations, that should
   4025         # count as a warning.
   4026         # HOWEVER: biber doesn't generate a new bbl.  So it is an error condition.
   4027         return 10;
   4028     }
   4029     if ($have_error) {return 2;}
   4030     if ($have_warning) {return 1;}
   4031     return 0;
   4032 } #END check_biber_log
   4033 
   4034 #**************************************************
   4035 
   4036 sub run_bibtex {
   4037     my $return = 999;
   4038     # Prevent changes we make to environment becoming global:
   4039     local %ENV = %ENV;
   4040     my ( $base, $path, $ext ) = fileparseA( $$Psource );
   4041     if ( $path && $bibtex_fudge ) {
   4042 	# Since (e.g.,) 'bibtex output/main.aux' doesn't find subsidiary .aux
   4043         #   files, as from \@include{chap.aux}, we change directory to the
   4044 	#   directory of the top-level .aux file to run bibtex.  But we have to
   4045 	#   fix search paths for .bib and .bst, since they may be specified
   4046 	#   relative to the document directory.
   4047         my $cwd = good_cwd();
   4048         foreach ( 'BIBINPUTS', 'BSTINPUTS' ) {
   4049             if ( exists $ENV{$_} ) {
   4050                 $ENV{$_} = $cwd.$search_path_separator.$ENV{$_};
   4051             }
   4052             else {
   4053                 $ENV{$_} = $cwd.$search_path_separator;
   4054             }
   4055 	}
   4056         pushd( $path );
   4057 	if (!$silent) {
   4058 	    print "$My_name: changed directory to '$path'\n",
   4059 		  "Set BIBINPUTS='$ENV{BIBINPUTS}'\n",
   4060   		  "Set BSTINPUTS='$ENV{BSTINPUTS}'\n";
   4061 	}
   4062         $return = &Run_subst( undef, undef, '', $base.$ext, '', $base );
   4063         popd();
   4064 	if (!$silent) {
   4065 	    print "$My_name: changed directory back to '", cwd(), "'\n";
   4066 	}
   4067     }
   4068     else {
   4069         $return = Run_subst();
   4070     }
   4071     return $return;
   4072 }
   4073 
   4074 
   4075 #**************************************************
   4076 
   4077 sub check_bibtex_log {
   4078     # Check for bibtex warnings:
   4079     # Usage: check_bibtex_log( base_of_bibtex_run )
   4080     # return 0: OK, 1: bibtex warnings, 2: bibtex errors, 
   4081     #        3: could not open .blg file.
   4082     #       10: only error is missing \citation commands or a missing aux file
   4083     #           (which would normally be corrected after a later run of 
   4084     #           (pdf)latex).
   4085 
   4086     my $base = $_[0];
   4087     my $log_name = "$base.blg";
   4088     my $log_file = new FileHandle;
   4089     open( $log_file, "<$log_name" )
   4090       or return 3;
   4091     my $have_warning = 0;
   4092     my $have_error = 0;
   4093     my $missing_citations = 0;
   4094     my @missing_aux = ();
   4095     my $error_count = 0;
   4096     while (<$log_file>) {
   4097         if (/^Warning--/) { 
   4098             #print "Bibtex warning: $_"; 
   4099             $have_warning = 1;
   4100         }
   4101         elsif ( /^I couldn\'t open auxiliary file (.*\.aux)/ ) {
   4102             push @missing_aux, $1;
   4103         }
   4104         elsif ( /^I found no \\citation commands---while reading file/ ) {
   4105             $missing_citations++;
   4106         }
   4107         elsif (/There (were|was) (\d+) error message/) {
   4108             $error_count = $2;
   4109             #print "Bibtex error: count=$error_count $_"; 
   4110             $have_error = 1;
   4111         }
   4112     }
   4113     close $log_file;
   4114     my $missing = $missing_citations + $#missing_aux + 1;
   4115 
   4116     if ( $#missing_aux > -1 ) {
   4117         # Need to make the missing files.
   4118         warn "$My_name: One or more aux files is missing for bibtex. I'll try\n",
   4119              "          to get (pdf)latex to remake them.\n";
   4120         rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
   4121     }
   4122     #print "Bibtex errors = $error_count, missing aux files and citations = $missing\n";
   4123     if ($have_error && ($error_count <= $missing )
   4124         && ($missing > 0) ) {
   4125         # If the only error is a missing citation line, that should only
   4126         # count as a warning.
   4127         # Also a missing aux file should be innocuous; it will be created on
   4128         # next run of (pdf)latex.  ?? HAVE I HANDLED THAT CORRECTLY?
   4129         # But have to deal with the problem that bibtex gives a non-zero 
   4130         # exit code.  So leave things as they are so that the user gets
   4131         # a better diagnostic ??????????????????????????
   4132 #        $have_error = 0;
   4133 #        $have_warning = 1;
   4134         return 10;
   4135     }
   4136     if ($have_error) {return 2;}
   4137     if ($have_warning) {return 1;}
   4138     return 0;
   4139 } #END check_bibtex_log
   4140 
   4141 #**************************************************
   4142 
   4143 sub normalize_force_directory {
   4144     #  Usage, normalize_force_directory( dir, filename )
   4145     #  Perform the following operations:
   4146     #    Clean filename
   4147     #    If filename contains no path component, insert dir in front
   4148     #    Normalize filename
   4149     #  Return result
   4150     my $default_dir = $_[0];
   4151     my $filename = clean_filename( $_[1] );
   4152     my ($base_name, $path ) = fileparse( $filename );
   4153     if ( $base_name eq $filename ) {
   4154        $filename = "$default_dir$filename";
   4155     }
   4156     return normalize_filename( $filename );
   4157 } #END normalize force_directory
   4158 
   4159 #**************************************************
   4160 
   4161 sub set_names {
   4162     # Set names of standard files:
   4163     $aux_main = "$aux_dir1$root_filename.aux";
   4164     $log_name = "$aux_dir1$root_filename.log";
   4165     $fdb_name = "$aux_dir1$root_filename.$fdb_ext";
   4166 }
   4167 
   4168 #**************************************************
   4169 
   4170 sub parse_log {
   4171 # Scan log file for: dependent files
   4172 #    reference_changed, bad_reference, bad_citation
   4173 # Return value: 1 if success, 0 if no log file.
   4174 # Put results in UPDATES of global variables (which are normally declared
   4175 # local in calling routine, to be suitably scoped):
   4176 #   %dependents: maps definite dependents to code:
   4177 #      0 = from missing-file line
   4178 #            May have no extension
   4179 #            May be missing path
   4180 #      1 = from 'File: ... Graphic file (type ...)' line
   4181 #            no path.  Should exist, but may need a search, by kpsewhich.
   4182 #      2 = from regular '(...' coding for input file, 
   4183 #            Has NO path, which it would do if LaTeX file
   4184 #            Highly likely to be mis-parsed line
   4185 #      3 = ditto, but has a path character ('/').  
   4186 #            Should be LaTeX file that exists.
   4187 #            If it doesn't exist, we have probably a mis-parsed line.
   4188 #            There's no need to do a search.
   4189 #      4 = definitive, which in this subroutine is only done:
   4190 #             for default dependents, 
   4191 #             and for files that exist and are source of conversion
   4192 #                reported by epstopdf et al.
   4193 #      5 = Had a missing file line.  Now the file exists.
   4194 #      6 = File was written during run.  (Overrides 5)
   4195 #      7 = File was created during run to be read in.  (Overrides 5 and 6)
   4196 #          (e.g., by epstopdf)
   4197 # Treat the following specially, since they have special rules
   4198 #   @bbl_files to list of .bbl files.
   4199 #   %idx_files to map from .idx files to .ind files.
   4200 # %generated_log: keys give set of files written by (pdf)latex (e.g., aux, idx)
   4201 #   as determined by \openout = ... lines in log file.
   4202 # @missing_subdirs = list of needed subdirectories of aux_dir
   4203 #   These are needed for writing aux_files when an included file is in
   4204 #   a subdirectory relative to the directory of the main TeX file.
   4205 #   This variable is only set when the needed subdirectories don't exist,
   4206 #   and the aux_dir is non-trivial, which results in an error message in 
   4207 #   the log file
   4208 #  %conversions Internally made conversions from one file to another
   4209 #
   4210 #  These may have earlier found information in them, so they should NOT
   4211 #  be initialized.
   4212 #
   4213 # Also SET
   4214 #   $reference_changed, $bad_reference, $bad_citation
   4215 #   $pwd_latex
   4216 #
   4217 # Put in trivial or default values if log file does not exist/cannot be opened
   4218 #
   4219 # Input globals: $primary_out, $fls_file_analyzed
   4220 #
   4221    
   4222    
   4223 # Give a quick way of looking up custom-dependency extensions
   4224     my %cusdep_from = ();
   4225     my %cusdep_to = ();
   4226     foreach ( @cus_dep_list ) {
   4227         my ($fromext, $toext) = split;
   4228         $cusdep_from{$fromext} = $cusdep_from{".$fromext"} = $_;
   4229         $cusdep_to{$toext} = $cusdep_to{".$toext"} = $_;
   4230     }
   4231 #    print "==== Cusdep from-exts:"; foreach (keys %cusdep_from) {print " '$_'";} print "\n";
   4232 #    print "==== Cusdep to-exts:"; foreach (keys %cusdep_to) {print " '$_'";} print "\n";
   4233 
   4234 
   4235     # Filenames given in log file may be preceded by a pathname
   4236     #   denoting current directory.  In MiKTeX, this is an absolute
   4237     #   pathname; in TeXLive, it is './'. Either way, we'll want to
   4238     #   remove this pathname string --- see the comments in sub
   4239     #   rdb_set_latex_deps.  In order of reliability for use in
   4240     #   normalizing filenames from the log file, the following forms
   4241     #   of the cwd are used:
   4242     # (a) internally deduced pwd from log file from sequence of lines
   4243     #                  **file
   4244     #                  (dir/file
   4245     #     if possible.  NO THAT'S WRONG if kpsearch is done.
   4246     # (b) from PWD line in fls file (if available), passed as $pwd_latex
   4247     # (c) system-given cwd as interpreted by sub good_cwd.
   4248     # We'll put the first two in  @pwd_log
   4249     my @pwd_log = ();
   4250     if ($pwd_latex) { push @pwd_log, $pwd_latex; }
   4251 
   4252     # $primary_out is actual output file (dvi or pdf)
   4253     # It is initialized before the call to this routine, to ensure
   4254     # a sensible default in case of misparsing
   4255 
   4256     $reference_changed = 0;
   4257     $mult_defined = 0;
   4258     $bad_reference = 0;
   4259     $bad_character = 0;
   4260     $bad_citation = 0;
   4261 
   4262     my $log_file = new FileHandle;
   4263     if ( ! open( $log_file, "<$log_name" ) ) {
   4264         return 0;
   4265     }
   4266     if ($log_file_binary) { binmode $log_file; }
   4267 # Collect lines of log file
   4268     my @lines = ();
   4269     my $line = 0;
   4270     my $engine = 'pdfTeX';  # Simple default in case of problems
   4271     while(<$log_file>) {
   4272 	$line++;
   4273         # Could use chomp here, but that fails if there is a mismatch
   4274         #    between the end-of-line sequence used by latex and that
   4275         #    used by perl.  (Notably a problem with MSWin latex and
   4276         #    cygwin perl!)
   4277         s/[\n\r]*$//;
   4278         # Handle wrapped lines:
   4279         # They are lines brutally broken at exactly $log_wrap chars 
   4280         #    excluding line-end.  Sometimes a line $log_wrap chars 
   4281         #    long is an ordinary line, sometimes it is part of a line
   4282         #    that was wrapped.  To handle all cases, I keep both
   4283         #    options open by putting the line into @lines before
   4284         #    and after appending the next line:  
   4285         my $len = length($_);
   4286 	if ($line == 1) {
   4287 	    if ( /^This is ([^,]+), / ) {
   4288 		$engine = $1;
   4289 		print "=== TeX engine is '$engine'\n"
   4290 		    if (!$silent);
   4291    	        if ( /^This is ([^,]+), [^\(]*\(([^\)]+)\)/ ) {
   4292 		    $tex_distribution = $2;
   4293 		    print "=== TeX distribution is '$tex_distribution'\n"
   4294 		        if ($diagnostics);
   4295 		}
   4296 	    }
   4297 	    else {
   4298 		warn "$My_name: First line of .log file '$log_name' is not in standard format.\n";
   4299 	    }
   4300 	}
   4301 	else {
   4302 	    # LuaTeX sometimes wraps at 80 instead of 79, so work around this
   4303             while ( ( ($len == $log_wrap) || ( ($engine eq 'LuaTeX') && ($len == $log_wrap+1) ) )
   4304                     && !eof($log_file) ) {
   4305                 push @lines, $_;
   4306                 my $extra = <$log_file>;
   4307                 $extra =~ s/[\n\r]*$//;
   4308                 $len = length($extra);
   4309                 $_ .= $extra;
   4310 	    }
   4311         }
   4312         push @lines, $_;
   4313     }
   4314     close $log_file;
   4315 
   4316     push @lines, "";   # Blank line to terminate.  So multiline blocks 
   4317               # are always terminated by non-block line, rather than eof.
   4318     
   4319     $line = 0;
   4320     my $state = 0;   # 0 => before ** line,
   4321                      # 1 => after **filename line, before next line (first file-reading line)
   4322                      # 2 => pwd_log determined.
   4323     # For parsing multiple line blocks of info
   4324     my $current_pkg = "";   # non-empty string for package name, if in 
   4325                             # middle of parsing multi-line block of form:
   4326                             #       Package name ....
   4327                             #       (name) ...
   4328                             #       ...
   4329     my $block_type = "";         # Specify information in such a block
   4330     my $delegated_source = "";   # If it is a file conversion, specify source
   4331     my $delegated_output = "";   #    and output file.  (Don't put in
   4332                                  #    data structure until block is ended.)
   4333     my %new_conversions = ();
   4334     my @retries = ();
   4335     my $log_silent = ($silent ||  $silence_logfile_warnings);
   4336     my @warning_list = ();
   4337 LINE:
   4338     while( ($line <= $#lines) || ($#retries > -1) ) { 
   4339         if ($#retries > -1) {
   4340             $_ = pop @retries;
   4341         }
   4342         else {
   4343             $_ = $lines[$line];
   4344             $line ++;
   4345         }
   4346         if ( /^! pdfTeX warning/ || /^pdfTeX warning/ ) {
   4347             # This kind of warning is produced by some versions of pdftex
   4348             # or produced by my reparse of warnings from other
   4349             # versions.
   4350             next;
   4351         }
   4352         elsif ( /^(.+)(pdfTeX warning.*)$/ ) {
   4353             # Line contains a pdfTeX warnings that may have been
   4354             # inserted directly after other material without an
   4355             # intervening new line.  I think pdfTeX always inserts a
   4356             # newline after the warning.  (From examination of source
   4357             # code.) 
   4358             push @retries, $1;
   4359             # But continue parsing the original line, in case it was a
   4360             # misparse, e.g., of a filename ending in 'pdfTeX';
   4361         }
   4362         if ( $line == 1 ){
   4363             if ( /^This is / ) {
   4364                 # First line OK
   4365                 next LINE;
   4366             } else {
   4367                 warn "$My_name: Error on first line of '$log_name'.\n".
   4368                     "This is apparently not a TeX log file.  ",
   4369                     "The first line is:\n$_\n";
   4370                 $failure = 1;
   4371                 $failure_msg = "Log file '$log_name' appears to have wrong format.";
   4372                 return 0;
   4373             }
   4374         }
   4375 
   4376         if ( ($state == 0) && /^\*\*(.*)$/ ) {
   4377             # Line containing first line specified to tex
   4378             # It's either a filename or a command starting with \
   4379             my $first = $1;
   4380             $state = 1;
   4381             if ( ! /^\\/ ) {
   4382                 $source_log = $first;
   4383                 if ( -e "$source_log.tex" ) { $source_log .= '.tex'; }
   4384             }
   4385             else {
   4386                 $state = 2;
   4387             }
   4388             next LINE;
   4389         }
   4390         elsif ( $state == 1 ) {
   4391             $state = 2;
   4392 	    if (-e $source_log) {
   4393 		# then the string preceeding $source_log on the line after the
   4394 		# ** line is probably the PWD as it appears in filenames in the
   4395                 # log file, except if the file appears in two locations.
   4396                 if ( m{^\("([^"]*)[/\\]\Q$source_log\E"} ) {
   4397                     unshift @pwd_log, $1;
   4398    	        }
   4399                 elsif ( m{^\((.*)[/\\]\Q$source_log\E} ) {
   4400                     unshift @pwd_log, $1;
   4401                 }
   4402 	    }
   4403         }
   4404 
   4405         if ( $block_type ) {
   4406             # In middle of parsing block
   4407             if ( /^\($current_pkg\)/ ) {
   4408                 # Block continues
   4409                 if ( ($block_type eq 'conversion') 
   4410                      && /^\($current_pkg\)\s+Output file: <([^>]+)>/ ) 
   4411                 {
   4412                     $delegated_output = normalize_clean_filename($1, @pwd_log);
   4413                 }
   4414                 next LINE;
   4415             }
   4416             # Block has ended.
   4417             if ($block_type eq 'conversion') {
   4418 #print "=== $delegated_source -> $delegated_output\n";
   4419                  $new_conversions{$delegated_source} =  $delegated_output;
   4420             }
   4421             $current_pkg = $block_type 
   4422                  = $delegated_source = $delegated_output = "";
   4423             # Then process current line
   4424         }
   4425 
   4426         # Check for changed references, bad references and bad citations:
   4427         if (/Rerun to get/) { 
   4428             warn "$My_name: References changed.\n" if ! $log_silent;
   4429             $reference_changed = 1;
   4430         } 
   4431         if (/^LaTeX Warning: (Reference[^\001]*undefined on input line .*)\./) {
   4432             push @warning_list, $1;
   4433             $bad_reference++;
   4434         } 
   4435         elsif (/^LaTeX Warning: (Label [^\001]* multiply defined.*)\./) {
   4436             push @warning_list, $1;
   4437             $mult_defined++;
   4438         }
   4439         elsif (/^LaTeX Warning: (Citation[^\001]*undefined on input line .*)\./) {
   4440             push @warning_list, $1;
   4441             $bad_citation++;
   4442         }
   4443         elsif (/^Package natbib Warning: (Citation[^\001]*undefined on input line .*)\./) {
   4444             push @warning_list, $1;
   4445             $bad_citation++;
   4446         }
   4447         elsif ( /^Missing character: There is no /
   4448   	        || /^! Package inputenc Error: Unicode character /
   4449 	        || /^! Bad character code /
   4450 	    ) {
   4451             $bad_character++;
   4452         } 
   4453         elsif ( /^Document Class: / ) {
   4454             # Class sign-on line
   4455             next LINE;
   4456         }
   4457         elsif ( /^\(Font\)/ ) {
   4458             # Font info line
   4459             next LINE;
   4460         }
   4461         elsif (/^No pages of output\./) {
   4462             $primary_out = ''; 
   4463             warn "$My_name: Log file says no output from latex\n";
   4464             next LINE;
   4465         }
   4466         elsif ( /^Output written on\s+(.*)\s+\(\d+\s+page/ ) {
   4467             $primary_out = normalize_clean_filename($1, @pwd_log);
   4468             warn "$My_name: Log file says output to '$primary_out'\n"
   4469                unless $silent;
   4470             next LINE;
   4471         }
   4472         elsif ( /^Overfull / 
   4473              || /^Underfull / 
   4474              || /^or enter new name\. \(Default extension: .*\)/ 
   4475              || /^\*\*\* \(cannot \\read from terminal in nonstop modes\)/
   4476            ) {
   4477             # Latex error/warning, etc.
   4478             next LINE;
   4479         }
   4480         elsif ( /^\\openout\d+\s*=\s*\`([^\']+)\'\.$/ ) {
   4481                 #  When (pdf)latex is run with an -output-directory 
   4482                 #    or an -aux_directory, the file name does not contain
   4483                 #    the output path; fix this, after removing quotes:
   4484             $generated_log{normalize_force_directory( $aux_dir1, $1 )} = 1;
   4485             next LINE;
   4486         }
   4487         # Test for conversion produced by package:
   4488         elsif ( /^Package (\S+) Info: Source file: <([^>]+)>/ ) {
   4489             # Info. produced by epstopdf (and possibly others) 
   4490             #    about file conversion
   4491             $current_pkg = normalize_clean_filename($1, @pwd_log);
   4492             $delegated_source = normalize_clean_filename($2, @pwd_log);
   4493             $block_type = 'conversion';
   4494             next LINE;
   4495         }
   4496 #    Test for writing of index file.  The precise format of the message 
   4497 #    depends on which package (makeidx.sty , multind.sty or index.sty) and 
   4498 #    which version writes the message.
   4499         elsif ( /Writing index file (.*)$/ ) {
   4500             my $idx_file = '';
   4501             if ( /^Writing index file (.*)$/ ) {
   4502                 # From makeidx.sty or multind.sty
   4503                 $idx_file = $1;
   4504             }
   4505             elsif ( /^index\.sty> Writing index file (.*)$/ ) {
   4506                 # From old versions of index.sty
   4507                 $idx_file = $1;
   4508             }
   4509             elsif ( /^Package \S* Info: Writing index file (.*) on input line/ ) {
   4510                 # From new versions of index.sty
   4511                 $idx_file = $1;                
   4512             }
   4513             else {
   4514                 warn "$My_name: Message indicates index file was written\n",
   4515                      "  ==> but I do not know how to understand it: <==\n",
   4516                      "  '$_'\n";
   4517                 next LINE;
   4518             }
   4519                 # Typically, there is trailing space, not part of filename:
   4520             $idx_file =~ s/\s*$//;
   4521                 #  When (pdf)latex is run with an -output-directory 
   4522                 #    or an -aux_directory, the file name does not contain
   4523                 #    the output path; fix this, after removing quotes:
   4524             $idx_file = normalize_force_directory( $aux_dir1, $idx_file );
   4525             my ($idx_base, $idx_path, $idx_ext) = fileparseA( $idx_file );
   4526             $idx_base = $idx_path.$idx_base;
   4527             $idx_file = $idx_base.$idx_ext;
   4528             if ( $idx_ext eq '.idx' ) {
   4529                 warn "$My_name: Index file '$idx_file' was written\n"
   4530                   unless $silent;
   4531                 $idx_files{$idx_file} = [ "$idx_base.ind", $idx_base ];
   4532             }
   4533             elsif ( exists $cusdep_from{$idx_ext} ) {
   4534                 if ( !$silent ) {
   4535                     warn "$My_name: Index file '$idx_file' was written\n";
   4536                     warn "   Cusdep '$cusdep_from{$idx_ext}' should be used\n";
   4537                 }
   4538                 # No action needed here
   4539             }
   4540             else {
   4541                 warn "$My_name: Index file '$idx_file' written\n",
   4542                      "  ==> but it has an extension I do not know how to handle <==\n";
   4543             }
   4544 
   4545             next LINE;
   4546         }
   4547         elsif ( /^No file (.*?\.bbl)./ ) {
   4548                 #  When (pdf)latex is run with an -output-directory 
   4549                 #    or an -aux_directory, the file name does not contain
   4550                 #    the output path; fix this, after removing quotes:
   4551             my $bbl_file = normalize_force_directory( $aux_dir1, $1 );
   4552             warn "$My_name: Non-existent bbl file '$bbl_file'\n $_\n";
   4553             $dependents{$bbl_file} = 0;
   4554             push @bbl_files, $bbl_file;
   4555             next LINE;
   4556         }
   4557         foreach my $pattern (@file_not_found) {
   4558             if ( /$pattern/ ) {
   4559                 my $file = clean_filename($1);
   4560                 warn "$My_name: Missing input file: '$file' from line\n  '$_'\n"
   4561                     unless $silent;
   4562                 $dependents{normalize_filename($file, @pwd_log)} = 0;
   4563                 my $file1 = $file;
   4564                 if ( $aux_dir ) {
   4565                       # Allow for the possibility that latex generated
   4566                       # a file in $aux_dir, from which the missing file can
   4567                       # be created by a cusdep (or other) rule that puts
   4568                       # the result in $out_dir.  If the announced missing file
   4569                       # has no path, then it would be effectively a missing
   4570                       # file in $aux_dir, with a path.  So give this alternate
   4571                       # location.
   4572                       my $file1 = normalize_force_directory( $aux_dir1, $file );
   4573                       $dependents{$file1} = 0;
   4574                 }
   4575                 next LINE;
   4576             }
   4577         }
   4578         if ( (! $fls_file_analyzed)
   4579              && /^File: (.+) Graphic file \(type / ) {
   4580             # First line of message from includegraphics/x
   4581 	    # But this does NOT include full path information
   4582 	    #   (if exact match is not found and a non-trivial
   4583 	    #   kpsearch was done by (pdf)latex).
   4584 	    # But the source-file information is in the fls file,
   4585 	    #   if we are using it.
   4586             $dependents{normalize_clean_filename($1, @pwd_log)} = 1;
   4587             next LINE;
   4588         }
   4589         # Now test for generic lines to ignore, only after special cases!
   4590         if ( /^File: / ) {
   4591            # Package sign-on line. Includegraphics/x also produces a line 
   4592            # with this signature, but I've already handled it.
   4593            next LINE;
   4594         }
   4595         if ( /^Package: / ) {
   4596             # Package sign-on line
   4597             next LINE;
   4598         }
   4599         if (/^\! LaTeX Error: / ) {
   4600             next LINE;
   4601         }
   4602         if ( m[^! I can't write on file `(.*)/([^/']*)'.\s*$] ) {
   4603             my $dir = $1;
   4604             my $file = $2;
   4605             my $full_dir = $aux_dir1.$dir;
   4606             if ( ($aux_dir ne '') && (! -e $full_dir) && ( $file =~ /\.aux$/) ) {
   4607                 warn "$My_name: === There were problems writing to '$file' in '$full_dir'\n",
   4608                      "    I'll try to make the subdirectory later.\n"
   4609                   if $diagnostics;
   4610                 push @missing_subdirs, $full_dir;
   4611             }
   4612             else {
   4613                 warn "$My_name: ====== There were problems writing to",
   4614                      "----- '$file' in '$full_dir'.\n",
   4615                      "----- But this is not the standard situation of\n",
   4616                      "----- aux file to subdir of output directory, with\n",
   4617                      "----- non-existent subdir\n",
   4618             }
   4619         }
   4620 
   4621 	if ( ($fls_file_analyzed) && (! $analyze_input_log_always) ) {
   4622 	    # Skip the last part, which is all about finding input
   4623 	    # file names which should all appear more reliably in the
   4624 	    # fls file.
   4625 	    next LINE;
   4626 	}
   4627 	
   4628         my @new_includes = ();
   4629 	
   4630    GRAPHICS_INCLUDE_CANDIDATE:
   4631         while ( /<([^>]+)(>|$)/g ) {
   4632 	    if ( -f $1 ) { push @new_includes, $1; }
   4633          }  # GRAPHICS_INCLUDE_CANDIDATE:
   4634 
   4635    INCLUDE_CANDIDATE:
   4636         while ( /\((.*$)/ ) {
   4637         # Filename found by
   4638         # '(', then filename, then terminator.
   4639         # Terminators: obvious candidates: ')':  end of reading file
   4640         #                                  '(':  beginning of next file
   4641         #                                  ' ':  space is an obvious separator
   4642         #                                  ' [': start of page: latex
   4643         #                                        and pdflatex put a
   4644         #                                        space before the '['
   4645         #                                  '[':  start of config file
   4646         #                                        in pdflatex, after
   4647         #                                        basefilename.
   4648         #                                  '{':  some kind of grouping
   4649         # Problem: 
   4650         #   All or almost all special characters are allowed in
   4651         #   filenames under some OS, notably UNIX.  Luckily most cases
   4652         #   are rare, if only because the special characters need
   4653         #   escaping.  BUT 2 important cases are characters that are
   4654         #   natural punctuation
   4655         #   Under MSWin, spaces are common (e.g., "C:\Program Files")
   4656         #   Under VAX/VMS, '[' delimits directory names.  This is
   4657         #   tricky to handle.  But I think few users use this OS
   4658         #   anymore.
   4659         #
   4660         # Solution: use ' [', but not '[' as first try at delimiter.
   4661         # Then if candidate filename is of form 'name1[name2]', then
   4662         #   try splitting it.  If 'name1' and/or 'name2' exists, put
   4663         #   it/them in list, else just put 'name1[name2]' in list.
   4664         # So form of filename is now:
   4665         #  '(', 
   4666         # then any number of characters that are NOT ')', '(', or '{'
   4667         #   (these form the filename);
   4668         # then ' [', or ' (', or ')', or end-of-string.
   4669         # That fails for pdflatex
   4670         # In log file:
   4671         #   '(' => start of reading of file, followed by filename
   4672         #   ')' => end of reading of file
   4673         #   '[' => start of page (normally preceeded by space)
   4674         # Remember: 
   4675         #    filename (on VAX/VMS) may include '[' and ']' (directory
   4676         #             separators) 
   4677         #    filenames (on MS-Win) commonly include space.
   4678         #    filenames on UNIX can included space.
   4679         #    Miktex quotes filenames
   4680         #    But web2c doesn't.  Then 
   4681         #       (string  message
   4682         #    is ambiguous: is the filename "string" or "string message".
   4683         #    Allow both as candidates, since user filenames with spaces 
   4684         #    are rare.  System filenames with spaces are common, but
   4685         #    they are normally followed by a newline rather than messages. 
   4686 
   4687         # First step: replace $_ by whole of line after the '('
   4688         #             Thus $_ is putative filename followed by other stuff.
   4689             $_ = $1; 
   4690             # Array of new candidate include files; sometimes more than one.
   4691             my $quoted = 0;
   4692             if ( /^\"([^\"]+)\"/ ) {
   4693                # Quoted file name, as from MikTeX
   4694                 $quoted = 1;
   4695             }
   4696             elsif ( /^([^\(^\)]*?)\s+[\[\{\<]/ ) {
   4697                 # Terminator: space then '[' or '{' or '<'
   4698                 # Use *? in condition: to pick up first ' [' (etc) 
   4699                 # as terminator
   4700             }
   4701             elsif ( /^([^\(^\)]*)\s+(?=\()/ ) {
   4702                 # Terminator is ' (', but '(' isn't in matched string,
   4703                 # so we keep the '(' ready for the next match
   4704             }
   4705             elsif  ( /^([^\(^\)]*)(\))/ ) {
   4706                 # Terminator is ')'
   4707             }
   4708             else {
   4709                 #Terminator is end-of-string
   4710             }
   4711             $_ = $';       # Put $_ equal to the unmatched tail of string '
   4712             my $include_candidate = $1;
   4713             $include_candidate =~ s/\s*$//;   # Remove trailing space.
   4714             if ( !$quoted && ($include_candidate =~ /(\S+)\s/ ) ){
   4715                 # Non-space-containing filename-candidate
   4716                 # followed by space followed by message
   4717                 # (Common)
   4718                 push @new_includes, $1;
   4719             }
   4720             if ( $include_candidate eq "[]" ) {
   4721                 # Part of overfull hbox message
   4722                 next INCLUDE_CANDIDATE;
   4723             }
   4724             if ( $include_candidate =~ /^\\/ ) {
   4725                 # Part of font message
   4726                 next INCLUDE_CANDIDATE;
   4727             }
   4728             # Remove quotes around filename, as for MikTeX.  I've already
   4729             # treated this as a special case.  For safety check here:
   4730             $include_candidate =~ s/^\"(.*)\"$/$1/;
   4731 
   4732             push @new_includes, $include_candidate;
   4733             if ( $include_candidate =~ /^(.+)\[([^\]]+)\]$/ ) {
   4734                 # Construct of form 'file1[file2]', as produced by pdflatex
   4735                 if ( -e $1 ) {
   4736                     # If the first component exists, we probably have the
   4737                     #   pdflatex form
   4738                     push @new_includes, $1, $2;
   4739                 }
   4740                 else {
   4741                     # We have something else.
   4742                     # So leave the original candidate in the list
   4743                 }
   4744             }
   4745         } # INCLUDE_CANDIDATE
   4746 
   4747     INCLUDE_NAME:
   4748         foreach my $include_name (@new_includes) {
   4749             $include_name = normalize_filename( $include_name, @pwd_log );
   4750             my ($base, $path, $ext) = fileparseB( $include_name );
   4751             if ( ($path eq './') || ($path eq '.\\') ) {
   4752                 $include_name = $base.$ext;
   4753             }
   4754             if ( $include_name !~ m'[/|\\]' ) {
   4755                 # Filename does not include a path character
   4756                 # High potential for misparsed line
   4757                 $dependents{$include_name} = 2;
   4758             } else {
   4759                 $dependents{$include_name} = 3;
   4760             }
   4761             if ( $ext eq '.bbl' ) {
   4762                 warn "$My_name: Found input bbl file '$include_name'\n"
   4763                    unless $silent;
   4764                 push @bbl_files, $include_name;
   4765             }
   4766         } # INCLUDE_NAME
   4767     } # LINE
   4768 
   4769     # Default includes are always definitive:
   4770     foreach (@default_includes) { $dependents{$_} = 4; }
   4771 
   4772     ###print "New parse: \n";
   4773     ###foreach (sort keys %dependents) { print "  '$_': $dependents{$_}\n"; }
   4774 
   4775     my @misparsed = ();
   4776     my @missing = ();
   4777     my @not_found = ();
   4778 
   4779     my %kpsearch_candidates = ();
   4780 CANDIDATE:
   4781     foreach my $candidate (keys %dependents) {
   4782         my $code = $dependents{$candidate};
   4783         if ( -d $candidate ) {
   4784             #  If $candidate is directory, it was presumably found from a 
   4785             #     mis-parse, so remove it from the list.  (Misparse can 
   4786             #     arise, for example from a mismatch of latexmk's $log_wrap
   4787             #     value and texmf.cnf value of max_print_line.)
   4788             delete $dependents{$candidate};
   4789         }
   4790         elsif ( -e $candidate ) {
   4791             if ( exists $generated_log{$candidate} ){
   4792                 $dependents{$candidate} = 6;
   4793             }
   4794             elsif ($code == 0) {
   4795                 $dependents{$candidate} = 5;
   4796             }
   4797             else {
   4798                 $dependents{$candidate} = 4;
   4799             }
   4800         }
   4801         elsif ($code == 1) {
   4802             # Graphics file that is supposed to have been read.
   4803             # Candidate name is as given in source file, not as path
   4804             #   to actual file.
   4805             # We have already tested that file doesn't exist, as given.
   4806             #   so use kpsewhich.  
   4807             # If the file still is not found, assume non-existent;
   4808             $kpsearch_candidates{$candidate} = 1;
   4809 	    delete $dependents{$candidate};
   4810         }
   4811         elsif ($code == 2) {
   4812             # Candidate is from '(...' construct in log file, for input file
   4813             #    which should include pathname if valid input file.
   4814             # Name does not have pathname-characteristic character (hence
   4815             #    $code==2.
   4816             # We get here if candidate file does not exist with given name
   4817             # Almost surely result of a misparsed line in log file.
   4818             delete $dependents{$candidate};
   4819             push @misparse, $candidate;
   4820         }
   4821         elsif ($code == 3) {
   4822             # Candidate is from '(...' construct in log file, for input file
   4823             #    which should include pathname if valid input file.
   4824             # Name does have pathname-characteristic character (hence
   4825             #    $code==3.
   4826             # But we get here only if candidate file does not exist with 
   4827             # given name.  
   4828             # Almost surely result of a misparsed line in log file.
   4829             # But with lower probability than $code == 2
   4830             delete $dependents{$candidate};
   4831             push @misparse, $candidate;
   4832         }
   4833         elsif ($code == 0) {
   4834             my ($base, $path, $ext) = fileparseA($candidate);
   4835             $ext =~ s/^\.//;
   4836             if ( ($ext eq '') && (-e "$path$base.tex") ) {
   4837                 # I don't think the old version was correct.
   4838                 # If the missing-file report was of a bare
   4839                 #    extensionless file, and a corresponding .tex file
   4840                 #    exists, then the missing file does not correspond
   4841                 #    to the missing file, unless the .tex file was
   4842                 #    created during the run.  
   4843                 # OLD $dependents{"$path$base.tex"} = 4;
   4844                 # OLD delete $dependents{$candidate};
   4845                 # NEW:
   4846                 $dependents{"$path$base.tex"} = 4;
   4847             }
   4848             push @missing, $candidate;
   4849         }
   4850     }
   4851 
   4852     my @kpsearch_candidates = keys %kpsearch_candidates;
   4853     if (@kpsearch_candidates) {
   4854 	foreach my $result ( kpsewhich( @kpsearch_candidates ) ) {
   4855 	    $dependents{$result} = 4;
   4856 	}
   4857     }
   4858         
   4859 CANDIDATE_PAIR:
   4860     foreach my $delegated_source (keys %new_conversions) {
   4861         my $delegated_output = $new_conversions{$delegated_source};
   4862         my $rule = "Delegated $delegated_source, $delegated_output";
   4863         # N.B. $delegated_source eq '' means the output file
   4864         #      was created without a named input file.
   4865         foreach my $candidate ($delegated_source, $delegated_output) {
   4866             if (! -e $candidate ) {
   4867                 # The file might be somewhere that can be found
   4868                 #   in the search path of kpathsea:
   4869                 my @kpse_result = kpsewhich( $candidate,);
   4870                 if ($#kpse_result > -1) {
   4871                     $candidate = $kpse_result[0];
   4872                 }
   4873             }
   4874         }
   4875         if ( ( (-e $delegated_source) || ($delegated_source eq '') )
   4876               && (-e $delegated_output) )
   4877         {
   4878             $conversions{$delegated_output} = $delegated_source;
   4879             $dependents{$delegated_output} = 7;
   4880             if ($delegated_source) {
   4881                 $dependents{$delegated_source} = 4;
   4882             }
   4883         }
   4884         elsif (!$silent) {
   4885             print "Logfile claimed conversion from '$delegated_source' ",
   4886                   "to '$delegated_output'.  But:\n";
   4887             if (! -e $delegated_output) {
   4888                 print  "   Output file does not exist\n";
   4889             }
   4890             if ( ($delegated_source ne '') && (! -e $delegated_source) ) {
   4891                 print  "   Input file does not exist\n";
   4892             }
   4893         }
   4894     }
   4895 
   4896     if ( ($#warning_list >= 0) && !$log_silent ) {
   4897 	@warning_list = uniqs( @warning_list );
   4898         show_array( "$My_name: List of undefined refs and citations:",
   4899                     @warning_list );
   4900     }
   4901     
   4902     if ( $diagnostics ) {
   4903         @misparse = uniqs( @misparse );
   4904         @missing = uniqs( @missing );
   4905         @not_found = uniqs( @not_found );
   4906         my @dependents = sort( keys %dependents );
   4907 
   4908         my $dependents = $#dependents + 1;
   4909         my $misparse = $#misparse + 1;
   4910         my $missing = $#missing + 1;
   4911         my $not_found = $#not_found + 1;
   4912         my $exist = $dependents - $not_found - $missing;
   4913         my $bbl = $#bbl_files + 1;
   4914 
   4915         print "$dependents dependent files detected, of which ",
   4916               "$exist exist, $not_found were not found,\n",
   4917               "   and $missing appear not to exist.\n";
   4918         print "Dependents:\n";
   4919         foreach (@dependents) { 
   4920             print "   '$_' "; 
   4921             if ( $dependents{$_} == 6 ) { print " written by (pdf)latex";}
   4922             if ( $dependents{$_} == 7 ) { print " converted by (pdf)latex";}
   4923             print "\n";
   4924         }
   4925         if ($not_found > 0) {
   4926             print "Not found:\n";
   4927             foreach (@not_found) { print "   $_\n"; }
   4928         }
   4929         if ($missing > 0) {
   4930             print "Not existent:\n";
   4931             foreach (@missing) { print "   $_\n"; }
   4932         }
   4933         if ( $bbl > 0 ) {
   4934             print "Input bbl files:\n";
   4935             foreach (@bbl_files) { print "   $_\n"; }
   4936         }
   4937 
   4938         if ( $misparse > 0 ) {
   4939             print "Possible input files, perhaps from misunderstood lines in .log file:\n";
   4940             foreach ( @misparse ) { print "   $_\n"; }
   4941         }
   4942     }
   4943     return 1;
   4944 } #END parse_log
   4945 
   4946 #************************************************************
   4947 
   4948 sub find_set_log {
   4949     # Locate the log file, if possible.  This allows for possible configuration
   4950     # errors, e.g., because the command for (*)latex was such that it did not 
   4951     # do the setting of -output-directory or -aux-directory that the user intended,
   4952     # or because the version used did not support one or other of these options.
   4953     # Put result in $where_log (see its initial declaration/definition for details).
   4954     # Change $aux_dir and/or $out_dir as appropriate, and make consequent changes.
   4955     #
   4956     # Probably further attention to location of output file (.dvi, .pdf, or .xdv)
   4957     # could be done, to get $out_dir and $$Pdest more accurately set.
   4958     #
   4959     # Typical configuration errors that lead to the need for this subroutine:
   4960     #        %O not used in command definition, so directory options don't getpassed
   4961     #           to (*)latex.
   4962     #        Use of $aux_dir different to $out_dir, when (*)latex doesn't support
   4963     #           the -aux-directory option (notably with TeXLive distribution).
   4964     if ($where_log >= 0) {
   4965 	# .log file was found on previous run.  No need to repeat search, since
   4966 	# if the location were to change from run to run, we'd have other
   4967 	# serious difficulties that are to hard to deal with.
   4968 	return;
   4969     }
   4970     if ( test_gen_file( "$aux_dir1$root_filename.log" ) ) {
   4971 	# .log file is in expected place.
   4972 	$where_log = 1;
   4973     }
   4974     elsif ( test_gen_file( "$out_dir1$root_filename.log" ) ) {
   4975 	# .log file is in out_dir not in aux_dir.
   4976 	# Presumably there is a configuration error
   4977 	# that prevents aux_dir from being used by latex.
   4978 	# So change $aux_dir to the actually used value.
   4979 	$where_log = 2;
   4980 	$aux_dir = $out_dir;
   4981     }
   4982     elsif ( test_gen_file( "$root_filename.log" ) ) {
   4983 	# .log file is not in out_dir nor in aux_dir, but is in cwd.
   4984 	# Presumably there is a configuration error
   4985 	# that prevents the directories from being used by latex.
   4986 	# So change $aux_dir to the actually used value.
   4987 	$where_log = 3;
   4988 	$aux_dir = "";
   4989     }
   4990     else {
   4991 	# No .log file found
   4992 	$failure = 1;
   4993 	$$Plast_result = 2;
   4994 	$where_log = 0;
   4995 	$failure_msg 
   4996 	    = "(Pdf)LaTeX didn't generate the expected log file '$log_name'\n";
   4997     }
   4998     if ($where_log > 1) {
   4999 	warn "$My_name: Changed aux_dir from '$aux_dir_requested' to '$aux_dir'\n".
   5000 	     "          to allow for probable configuration error\n";
   5001 	# Allow for the changes associated with change of $aux_dir:
   5002 	&set_dirs_etc;
   5003 	&set_names;
   5004 	warn "$My_name: Actual .log file is\n",
   5005              "     '$log_name'\n",
   5006              "  instead of the value\n",
   5007              "     '$aux_dir_requested/$root_filename.log'\n",
   5008              "   that seemed to be intended.\n";
   5009     }
   5010 }
   5011 
   5012 #************************************************************
   5013 
   5014 sub parse_fls {
   5015     my ($fls_name, $Pinputs, $Poutputs, $Pfirst_read_after_write, $Ppwd_latex ) = @_;
   5016     %$Pinputs = %$Poutputs = %$Pfirst_read_after_write = ();
   5017     my $fls_file = new FileHandle;
   5018     # Make a note of current working directory
   5019     # I'll update it from the fls file later
   5020     # Currently I don't use this, but it would be useful to use
   5021     # this when testing prefix for cwd in a filename, by
   5022     # giving (pdf)latex's best view of the cwd.  Note that the
   5023     # value given by the cwd() function may be mangled, e.g., by cygwin
   5024     # compared with native MSWin32.
   5025     #
   5026     # Two relevant forms of cwd exist: The system one, which we can find, and
   5027     # the one reported by (pdf)latex in the fls file.  It will be
   5028     # useful to remove leading part of cwd in filenames --- see the
   5029     # comments in sub rdb_set_latex_deps.  Given the possible multiplicity
   5030     # of representations of cwd, the one reported in the fls file should
   5031     # be definitive in the fls file.
   5032 
   5033     my $cwd = good_cwd();
   5034     if ( ! open ($fls_file, "<$fls_name") ) {
   5035         return 1;
   5036     }
   5037     foreach $_ ( <$fls_file> ) {
   5038         # Remove trailing CR and LF. Thus we get correct behavior when an fls file
   5039         #  is produced by MS-Windows program (e.g., in MiKTeX) with CRLF line ends,
   5040         #  but is read by Unix Perl (which treats LF as line end, and preserves CRLF
   5041         #  in read-in lines):
   5042         $_ =~ s/[\n\r]*$//;
   5043         if (/^\s*PWD\s+(.*)$/) {
   5044             $cwd = $1;
   5045             $$Ppwd_latex = $cwd;
   5046     	    if ( $cwd =~ /\"/ ) {
   5047 		warn "$My_name: The working directory has a '\"' character in its name:\n",
   5048                      "  '$cwd'\n  This can cause me trouble. Beware!\n";
   5049 	    }
   5050         }
   5051         elsif (/^\s*INPUT\s+(.*)$/) {
   5052             # Take precautions against aliasing of foo, ./foo and other possibilities for cwd.
   5053             my $file = $1;
   5054             # Remove exactly pwd reported in this file, and following separator.
   5055             # MiKTeX reports absolute pathnames, and this way of removing PWD insulates
   5056             #   us from coding issues if the PWD contains non-ASCII characters.  What
   5057             #   coding scheme (UTF-8, code page, etc) is used depends on OS, TeX
   5058             #   implementation, ...
   5059 	    if ( defined $$Ppwd_latex ) { 
   5060                 $file =~ s(^\Q$$Ppwd_latex\E[\\/])();
   5061 	    }
   5062             $file = normalize_filename( $file );
   5063             if ( (exists $$Poutputs{$file}) && (! exists $$Pinputs{$file}) ) {
   5064                 $$Pfirst_read_after_write{$file} = 1;
   5065             }
   5066             $$Pinputs{$file} = 1;
   5067         }
   5068         elsif (/^\s*OUTPUT\s+(.*)$/) {
   5069             # Take precautions against aliasing of foo, ./foo and other possibilities for cwd.
   5070             my $file = $1;
   5071             $file =~ s(^\Q$$Ppwd_latex\E[\\/])();
   5072             $file = normalize_filename( $file );
   5073             $$Poutputs{$file} = 1;
   5074         }
   5075     }
   5076     close( $fls_file );
   5077     return 0;
   5078 } #END parse_fls
   5079 
   5080 #************************************************************
   5081 
   5082 sub clean_filename {
   5083     # Convert quoted filename as found in log file to filename without quotes
   5084     # Allows arbitrarily embedded double-quoted substrings, includes the
   5085     # cases
   5086     # 1. `"string".ext', which arises e.g., from \jobname.bbl:
   5087     #    when the base filename contains spaces, \jobname has quotes.
   5088     #    and from \includegraphics with basename specified.
   5089     #    Also deals with filenames written by asymptote.sty
   5090     # 2. Or "string.ext" from \includegraphcs with basename and ext specified.
   5091     #    and from MiKTeX logfile for input files with spaces. 
   5092     # Doubled quotes (e.g., A""B) don't get converted.
   5093     # Neither do unmatched quotes.
   5094     my $filename = $_[0];
   5095     while ( $filename =~ s/^([^\"]*)\"([^\"]+)\"(.*)$/$1$2$3/ ) {}
   5096     return $filename;
   5097 }
   5098 
   5099 # ------------------------------
   5100 
   5101 sub normalize_filename {
   5102    # Usage: normalize_filename( filename [, extra forms of name of cwd] )
   5103    # Returns filename with removal of various forms for cwd, and
   5104    # with conversion of directory separator to '/' only
   5105    #
   5106    my ( $file, @dirs ) = @_;
   5107    my $file1 = $file;   # Saved original value
   5108    my $cwd = good_cwd();
   5109    # Normalize files to use / to separate directory components:
   5110    # (Note both / and \ are allowed under MSWin.)
   5111    foreach ($cwd, $file,  @dirs) {
   5112        s(\\)(/)g;
   5113    }
   5114    # Remove initial component equal to current working directory.
   5115    # Use \Q and \E round directory name in regex to avoid interpretation
   5116    #   of metacharacters in directory name:
   5117    foreach my $dir ( @dirs, '.', $cwd ) {
   5118      if ( $file =~ s(^\Q$dir\E/)() ) {
   5119         last;
   5120      }
   5121    }
   5122    return $file;
   5123 }
   5124 
   5125 # ------------------------------
   5126 
   5127 sub normalize_clean_filename {
   5128    # Usage: normalize_clean_filename( filename [, extra forms of name of cwd] )
   5129    # Same as normalize_filename, but first remove any double quotes, as
   5130    # done by clean_filename, which is appropriate for filenames from log file.
   5131     my ($file, @dirs) = @_;
   5132     return normalize_filename( clean_filename( $file ) , @dirs );
   5133 }
   5134 
   5135 #************************************************************
   5136 
   5137 sub fix_pattern {
   5138    # Escape the characters [ and {, to give a pattern for use in glob
   5139    #    with these characters taken literally.
   5140    my $pattern = shift;
   5141    $pattern =~ s/\[/\\\[/g;
   5142    $pattern =~ s/\{/\\\{/g;
   5143    return $pattern;
   5144 }
   5145 
   5146 #************************************************************
   5147 
   5148 sub parse_aux {
   5149     #Usage: parse_aux( $aux_file, \@new_bib_files, \@new_aux_files, \@new_bst_files )
   5150     # Parse aux_file (recursively) for bib files, and bst files.  
   5151     # If can't open aux file, then
   5152     #    Return 0 and leave @new_bib_files empty
   5153     # Else set @new_bib_files from information in the aux files
   5154     #    And:
   5155     #    Return 1 if no problems
   5156     #    Return 2 with @new_bib_files empty if there are no \bibdata
   5157     #      lines. 
   5158     #    Return 3 if I couldn't locate all the bib_files
   5159     # Set @new_aux_files to aux files parsed
   5160 
   5161     my $aux_file = $_[0];
   5162     local $Pbib_files = $_[1];
   5163     local $Paux_files = $_[2];
   5164     local $Pbst_files = $_[3];
   5165    
   5166     @$Pbib_files = ();
   5167     @$Pbst_files = ();
   5168     @$Paux_files = ();
   5169 
   5170     parse_aux1( $aux_file );
   5171     if ($#{$Paux_files} < 0) {
   5172        return 0;
   5173     }
   5174     @$Pbib_files = uniqs( @$Pbib_files );
   5175     @$Pbst_files = uniqs( @$Pbst_files );
   5176 
   5177     if ( $#{$Pbib_files} == -1 ) {
   5178         warn "$My_name: No .bib files listed in .aux file '$aux_file' \n",
   5179         return 2;
   5180     }
   5181     my @not_found = &find_file_list1( $Pbib_files, $Pbib_files,
   5182                                       '.bib', \@BIBINPUTS );
   5183     @$Pbib_files = uniqs( @$Pbib_files );
   5184     &find_file_list1( $Pbst_files, $Pbst_files, '.bst' );
   5185     @$Pbst_files = uniqs( @$Pbst_files );
   5186     my @bad_bib = ();
   5187     foreach ( @$Pbib_files ) {
   5188 	if ( /\s/ ) { push @bad_bib, $_; }
   5189     }
   5190     if ($#bad_bib >= 0)  {
   5191 	    warn "$My_name: White space in an argument list for \\bibliography.\n",
   5192                  "    which is not allowed by bibtex.  Bad arguments:\n";
   5193             foreach (@bad_bib ) { warn "    '$_'\n"; }
   5194 	    return 3;
   5195     }
   5196     if ( $#not_found < 0) {
   5197         warn "$My_name: Found bibliography file(s) [@$Pbib_files]\n"
   5198         unless $silent;
   5199     }
   5200     else {
   5201         warn "$My_name: Failed to find one or more bibliography files:\n";
   5202         foreach (@not_found) { warn "    '$_'\n"; }
   5203         if ($force_mode) {
   5204             warn "==== Force_mode is on, so I will continue.  ",
   5205                  "But there may be problems ===\n";
   5206         }
   5207         return 3;
   5208     }
   5209     return 1;
   5210 } #END parse_aux
   5211 
   5212 #************************************************************
   5213 
   5214 sub parse_aux1
   5215 # Parse single aux file for bib files.  
   5216 # Usage: &parse_aux1( aux_file_name )
   5217 #   Append newly found bib_filenames in @$Pbib_files, already 
   5218 #        initialized/in use.
   5219 #   Append aux_file_name to @$Paux_files if aux file opened
   5220 #   Recursively check \@input aux files
   5221 #   Return 1 if success in opening $aux_file_name and parsing it
   5222 #   Return 0 if fail to open it
   5223 {
   5224    my $aux_file = $_[0];
   5225    my $aux_fh = new FileHandle;
   5226    if (! open($aux_fh, $aux_file) ) { 
   5227        warn "$My_name: Couldn't find aux file '$aux_file'\n";
   5228        return 0; 
   5229    }
   5230    push @$Paux_files, $aux_file;
   5231 AUX_LINE:
   5232    while (<$aux_fh>) {
   5233       if ( /^\\bibdata\{(.*)\}/ ) { 
   5234           # \\bibdata{comma_separated_list_of_bib_file_names}
   5235           # These are normally without the '.bib' extension.
   5236           push @$Pbib_files, split /,/, $1;
   5237       }
   5238       elsif ( /^\\bibstyle\{(.*)\}/ ) { 
   5239           # \\bibstyle{bst_file_name}
   5240           # Normally without the '.bst' extension.
   5241           push @$Pbst_files, split /,/, $1;
   5242       }
   5243       elsif ( /^\\\@input\{(.*)\}/ ) { 
   5244           # \\@input{next_aux_file_name}
   5245           &parse_aux1( $aux_dir1.$1 );
   5246       }
   5247       else {
   5248           foreach my $Psub (@aux_hooks) {
   5249               &$Psub;
   5250           }
   5251       }
   5252    }
   5253    close($aux_fh);
   5254    return 1;
   5255 } #END parse_aux1
   5256 
   5257 #************************************************************
   5258 
   5259 #************************************************************
   5260 #************************************************************
   5261 #************************************************************
   5262 
   5263 #   Manipulations of main file database:
   5264 
   5265 #************************************************************
   5266 
   5267 sub fdb_get {
   5268     # Call: fdb_get(filename [, check_time])
   5269     # Returns an array (time, size, md5) for the current state of the
   5270     #    named file.
   5271     # The optional argument check_time is either the run_time of some command
   5272     #    that may have changed the file or the last time the file was checked
   5273     #    for changes --- see below.
   5274     # For non-existent file, deletes its entry in fdb_current, 
   5275     #    and returns (0,-1,0)  
   5276     # As an optimization, the md5 value is taken from the cache in 
   5277     #    fdb_current, if the time and size stamp indicate that the 
   5278     #    file has not changed.
   5279     # The md5 value is recalculated if
   5280     #    the current filetime differs from the cached value: 
   5281     #               file has been written
   5282     #    the current filesize differs from the cached value: 
   5283     #               file has definitely changed
   5284     # But the file can also be rewritten without change in filetime when 
   5285     #    file processing happens within the 1-second granularity of the 
   5286     #    timestamp (notably for aux files from latex on a short source file).
   5287     # The only case that concerns us is when the file is an input to a program
   5288     #    at some runtime t, the file is rewritten later by the same or another
   5289     #    program, with timestamp t, and when the initial file also has 
   5290     #    timestamp t.
   5291     # A test is applied for this situation if the check_time argument is
   5292     #    supplied and is nonzero.
   5293 
   5294     my ($file, $check_time) = @_;
   5295     if ( ! defined $check_time ) { $check_time = 0;}
   5296     my ($new_time, $new_size) = get_time_size($file);
   5297     my @nofile =  (0,-1,0);     # What we use for initializing
   5298                                 # a new entry in fdb or flagging
   5299                                 # non-existent file
   5300     if ( $new_size < 0 ) {
   5301         delete $fdb_current{$file};
   5302         return @nofile;
   5303     }
   5304     my $recalculate_md5 = 0;
   5305     if ( ! exists $fdb_current{$file} ) {
   5306         # Ensure we have a record.  
   5307         $fdb_current{$file} = [@nofile];
   5308         $recalculate_md5 = 1;
   5309     }
   5310     my $file_data = $fdb_current{$file};
   5311     my ( $time, $size, $md5 ) = @$file_data;
   5312 
   5313     if ( ($new_time != $time) || ($new_size != $size) 
   5314          || ( $check_time && ($check_time == $time ) )
   5315        ) {
   5316         # Only force recalculation of md5 if time or size changed.
   5317         # However, the physical file time may have changed without
   5318         #   affecting the value of the time coded in $time, because
   5319         #   times are computed with a 1-second granularity.
   5320         #   The only case to treat specially is where the file was created,
   5321         #   then used by the current rule, and then rewritten, all within
   5322         #   the granularity size, otherwise the value of the reported file
   5323         #   time changed, and we've handled it.  But we may have already
   5324         #   checked this at an earlier time than the current check.  So the
   5325         #   only dangerous case is where the file time equals a check_time,
   5326         #   which is either the run_time of the command or the time of a
   5327         #   previous check.
   5328         # Else we assume file is really unchanged.
   5329         $recalculate_md5 = 1;
   5330     }
   5331     if ($recalculate_md5) {
   5332 #warn "--------- RECALC MD5: $rule $file: (N,O,R,C) \n  = $new_time, $time, $$Prun_time, $check_time\n";
   5333         @$file_data = ( $new_time, $new_size, get_checksum_md5( $file ) );
   5334     }
   5335     return @$file_data;;
   5336 } #END fdb_get
   5337 
   5338 #************************************************************
   5339 
   5340 sub fdb_set {
   5341     # Call: fdb_set(filename, $time, $size, $md5 )
   5342     # Set data in file data cache, i.e., %fdb_current
   5343     my ($file, $time, $size, $md5 ) = @_;
   5344     if ( ! exists $fdb_current{$file} ) {
   5345         $fdb_current{$file} = [0, -1, 0];
   5346     }
   5347     @{$fdb_current{$file}} = ( $time, $size, $md5 );
   5348 } #END fdb_set
   5349 
   5350 #************************************************************
   5351 
   5352 sub fdb_show {
   5353     # Displays contents of fdb
   5354     foreach my $file ( sort keys %fdb_current ) {
   5355         print "'$file': @{$fdb_current{$file}}\n";
   5356     }
   5357 } #END fdb_show
   5358 
   5359 #************************************************************
   5360 #************************************************************
   5361 #************************************************************
   5362 
   5363 # Routines for manipulating rule database
   5364 
   5365 #************************************************************
   5366 
   5367 sub rdb_read {
   5368     # Call: rdb_read( $in_name  )
   5369     # Sets rule database from saved file, in format written by rdb_write.
   5370     # Returns -1 if file could not be read else number of errors.
   5371     # Thus return value on success is 0
   5372     my $in_name = $_[0];
   5373     my $in_handle = new FileHandle;
   5374     $in_handle->open( $in_name, '<' )
   5375        or return ();
   5376     my $errors = 0;
   5377     my $state = -1;   # Values: -1: before start; 0: outside rule;
   5378                       # 1: in source section;
   5379                       # 2: in generated file section;
   5380                       # 10: ignored rule.
   5381     my $rule = '';
   5382     my $run_time = 0;
   5383     my $source = '';
   5384     my $dest = '';
   5385     my $base = '';
   5386     local %new_sources = ();  # Hash: rule => { file=>[ time, size, md5, fromrule ] }
   5387     my $new_source = undef;   # Reference to hash of sources for current rule
   5388 LINE:
   5389     while ( <$in_handle> ) {
   5390         # Remove leading and trailing white space.
   5391         s/^\s*//;
   5392         s/\s*$//;
   5393         if ($state == -1) {
   5394             if ( ! /^# Fdb version ([\d]+)$/ ) {
   5395                 warn "$My_name: File-database '$in_name' is not of correct format\n";
   5396                 return 1;
   5397             }
   5398             if ( $1 > $fdb_ver) {
   5399                 warn "$My_name: File-database '$in_name' is of too new version, $1 > $fdb_ver\n";
   5400                 return 1;
   5401             }
   5402             $state = 0;
   5403         }
   5404         # Ignore blank lines and comments
   5405         if ( /^$/ || /^#/ || /^%/ ) { next LINE;}
   5406         if ( /^\[\"([^\"]+)\"\]/ ) {
   5407             # Start of section
   5408             $rule = $1;
   5409             my $tail = $'; #'  Single quote in comment tricks the parser in
   5410                            # emacs from misparsing an isolated single quote
   5411             $run_time = $check_time = 0;
   5412             $source = $dest = $base = '';
   5413             if ( $tail =~ /^\s*(\S+)\s*$/ ) {
   5414                 $run_time = $1;
   5415             }
   5416             elsif ( $tail =~ /^\s*(\S+)\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s*$/ ) {
   5417                 $run_time = $1;
   5418                 $source = $2;
   5419                 $dest = $3;
   5420                 $base = $4;
   5421             }
   5422             elsif ( $tail =~ /^\s*(\S+)\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+\"([^\"]*)\"\s+(\S+)\s*$/ ) {
   5423                 $run_time = $1;
   5424                 $source = $2;
   5425                 $dest = $3;
   5426                 $base = $4;
   5427                 $check_time = $5;
   5428             }
   5429             if ( rdb_rule_exists( $rule ) ) {
   5430                 rdb_one_rule( $rule, 
   5431                               sub{ 
   5432                                    if ($$Ptest_kind == 3) { $$Ptest_kind = 1; }
   5433                                    $$Prun_time = $run_time;
   5434                                    $$Pcheck_time = $check_time;
   5435                                  }                                      
   5436                              );
   5437             }
   5438             elsif ($rule =~ /^cusdep\s+(\S+)\s+(\S+)\s+(.+)$/ ) {
   5439                 # Create custom dependency
   5440                 my $fromext = $1;
   5441                 my $toext = $2;
   5442                 my $base = $3;
   5443                 $source = "$base.$fromext";
   5444 #                $dest =   "$base.$toext";
   5445                 my $func_name = '';
   5446                 foreach my $dep ( @cus_dep_list ) {
   5447                     my ($tryfromext,$trytoext,$must,$try_func_name) = split('\s+',$dep);
   5448                     if ( ($tryfromext eq $fromext) && ($trytoext eq $toext) ) {
   5449 			$func_name = $try_func_name;
   5450                     }
   5451                 }
   5452 		if ($func_name) {
   5453 		    my $PAnew_cmd = ['do_cusdep', $func_name];
   5454                     # Set source file as non-existent.  
   5455                     # If it existed on last run, it will be in later 
   5456                     #    lines of the fdb file
   5457                     rdb_create_rule( $rule, 'cusdep', '', $PAnew_cmd, 1, 
   5458                                      $source, $dest, $base, 0, $run_time, $check_time, 1 );
   5459 		}
   5460 		else {
   5461 		    warn "$My_name: In file-database '$in_name', the custom-dependency rule\n",
   5462  			 "  '$rule' is not available in this session.\n",
   5463 			 "  Presumably it's no longer in your configuration for latexmk.\n";
   5464 		    $state = 10;
   5465 		    next LINE;
   5466 		}
   5467             }
   5468             elsif ( $rule =~ /^(makeindex|bibtex|biber)\s*(.*)$/ ) {
   5469                 my $PA_extra_gen = [];
   5470                 my $rule_generic = $1;
   5471                 my $int_cmd = '';
   5472                 if ( ! $source ) {
   5473                     # If fdb_file was old-style (v. 1)
   5474                     $source = $2;
   5475                     my $path = '';
   5476                     my $ext = '';
   5477                     ($base, $path, $ext) = fileparseA( $source );
   5478                     $base = $path.$base;
   5479                     if ($rule_generic eq 'makeindex') {
   5480                         $dest = "$base.ind";
   5481                     }
   5482                     elsif ($rule_generic eq 'bibtex') {
   5483                         $dest = "$base.bbl";
   5484                         $source = "$base.aux";
   5485                     }
   5486                     elsif ($rule_generic eq 'biber') {
   5487                         $dest = "$base.bbl";
   5488                         $source = "$base.bcf";
   5489                     }
   5490                 }
   5491                 if ($rule =~ /^makeindex/) { $PA_extra_gen = [ "$base.ilg" ]; }
   5492                 if ($rule =~ /^(bibtex|biber)/) { $PA_extra_gen = [ "$base.blg" ]; }
   5493                 if ($rule =~ /^bibtex/) { $int_cmd = "run_bibtex"; }
   5494                 warn "$My_name: File-database '$in_name': setting rule '$rule'\n"
   5495                    if $diagnostics;
   5496                 my $cmd_type = 'external';
   5497                 my $ext_cmd = ${$rule_generic};
   5498                 warn "  Rule kind = '$rule_generic'; ext_cmd = '$ext_cmd';\n",
   5499                      "  int_cmd = '$int_cmd';\n",
   5500                      "  source = '$source'; dest = '$dest'; base = '$base';\n"
   5501                    if $diagnostics;
   5502                 # Set source file as non-existent.  
   5503                 # If it existed on last run, it will be in later 
   5504                 #    lines of the fdb file
   5505                 rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, 1, 
   5506                                  $source, $dest, $base, 0, $run_time,  $check_time, 1, $PA_extra_gen );
   5507             }
   5508             else {
   5509                 warn "$My_name: In file-database '$in_name' rule '$rule'\n",
   5510                      "   is not in use in this session\n"
   5511                 if $diagnostics;
   5512                 $new_source = undef;
   5513                 $state = 10;
   5514                 next LINE;
   5515             }
   5516             $new_source = $new_sources{$rule} = {};
   5517             $state = 1;  #Reading a section, source part
   5518         }
   5519         elsif ( ($state <=0) || ($state >= 3) ) {
   5520             next LINE;
   5521         }
   5522         elsif ( /^\(source\)/ ) { $state = 1; next LINE; }
   5523         elsif ( /^\(generated\)/ ) { $state = 2; next LINE; }
   5524         elsif ( ($state == 1) && /^\"([^\"]*)\"\s+(\S+)\s+(\S+)\s+(\S+)\s+\"([^\"]*)\"/ ) {
   5525             # Source file line
   5526             my $file = $1;
   5527             my $time = $2;
   5528             my $size = $3;
   5529             my $md5 = $4;
   5530             my $from_rule = $5;
   5531 #??            print "  --- File '$file'\n";
   5532             if ($state != 1) {
   5533                 warn "$My_name: In file-database '$in_name' ",
   5534                      "line $. is outside a section:\n   '$_'\n";
   5535                 $errors++;
   5536                 next LINE;
   5537             }
   5538             # Set file in database.  But ensure we don't do an unnecessary 
   5539             #    fdb_get, which can trigger a new MD5 calculation, which is
   5540             #    lengthy for a big file.  Ininitially flagging the file
   5541             #    as non-existent solves the problem:
   5542             rdb_ensure_file( $rule, $file, undef, 1 ); 
   5543             rdb_set_file1( $rule, $file, $time, $size, $md5 );
   5544             fdb_set( $file, $time, $size, $md5 );
   5545             # Save the rest of the data, especially the from_fule until we know all 
   5546             #   the rules, otherwise the from_rule may not exist.
   5547             # Also we'll have a better chance of looping through files.
   5548             ${$new_source}{$file} = [ $time, $size, $md5, $from_rule ];
   5549         }
   5550         elsif ( ($state == 2) && /^\"([^\"]*)\"/ ) {
   5551             my $file = $1;
   5552             rdb_one_rule( $rule, sub{ rdb_add_generated($file); } );
   5553         }
   5554         else {
   5555             warn "$My_name: In file-database '$in_name' ",
   5556                  "line $. is of wrong format:\n   '$_'\n";
   5557             $errors++;
   5558             next LINE;
   5559         }
   5560     }
   5561     undef $in_handle;
   5562     # Set cus dependencies.
   5563     &rdb_set_dependents( keys %rule_db );
   5564 
   5565 #?? Check from_rules exist.
   5566 
   5567     return $errors;
   5568 }  # END rdb_read
   5569 
   5570 #************************************************************
   5571 
   5572 sub rdb_write {
   5573     # Call: rdb_write( $out_name )
   5574     # Writes to the given file name the database of file and rule data
   5575     #   for all rules needed to make final output
   5576     # !!?? Previously was:
   5577     # OLD Writes to the given file name the database of file and rule data
   5578     # OLD   accessible from the primary rules.
   5579     # Returns 1 on success, 0 if file couldn't be opened.
   5580     local $out_name = $_[0];
   5581     local $out_handle = new FileHandle;
   5582     if ( ($out_name eq "") || ($out_name eq "-") ) {
   5583         # Open STDOUT
   5584         $out_handle->open( '>-' );
   5585     }
   5586     else {
   5587        $out_handle->open( $out_name, '>' );
   5588     }
   5589     if (!$out_handle) { return 0; }
   5590 
   5591     local %current_primaries = ();   # Hash whose keys are primary rules 
   5592                 # needed, i.e., known latex-like rules which trigger
   5593                 # circular dependencies
   5594     local @pre_primary = ();   # Array of rules
   5595     local @post_primary = ();  # Array of rules
   5596     local @unusual_one_time = ();      # Array of rules
   5597     &rdb_classify_rules( \%possible_primaries, keys %requested_filerules );
   5598 
   5599     print $out_handle "# Fdb version $fdb_ver\n";
   5600 # !!??   Rules or rules accessible from primary
   5601 #    my @rules = rdb_accessible( uniq1( keys %possible_primaries )  ) ;
   5602     my @rules = rdb_accessible( uniq1( keys %possible_primaries, keys %requested_filerules  )  ) ;
   5603     # Separate call to sort.  Otherwise rdb_accessible seems to get wrong argument.
   5604     @rules = sort( @rules );
   5605     rdb_for_some(
   5606        \@rules,
   5607        sub { 
   5608            # Omit data on a unused and never-run primary rule:
   5609            if ( ($$Prun_time == 0) 
   5610                 && exists( $possible_primaries{$rule} )
   5611                 && ! exists( $current_primaries{$rule} )
   5612               )
   5613            { 
   5614                return;
   5615            }
   5616            print $out_handle "[\"$rule\"] $$Prun_time \"$$Psource\" \"$$Pdest\" \"$$Pbase\" $$Pcheck_time\n";
   5617            rdb_do_files(
   5618              sub { print $out_handle "  \"$file\" $$Ptime $$Psize $$Pmd5 \"$$Pfrom_rule\"\n"; }
   5619            );
   5620            print $out_handle "  (generated)\n";
   5621            foreach (keys %$PHdest) {
   5622                print $out_handle "  \"$_\"\n";
   5623            }
   5624        }
   5625     );
   5626     undef $out_handle;
   5627     return 1;
   5628 } #END rdb_write
   5629 
   5630 #************************************************************
   5631 
   5632 sub rdb_set_latex_deps {
   5633     # Assume rule context.  
   5634     # This is intended to be applied only for a primary (LaTeX-like) rule.
   5635     # Set its dependents etc, using information from log, aux, and fls files.
   5636     # Use fls file only if $recorder is set, and the fls file was generated
   5637     # on this run.
   5638 
   5639     # N.B.  A complication which we try and handle in determining
   5640     #   dependent files is that there may be aliasing of file names,
   5641     #   especially when characters are used in file and directory
   5642     #   names that are not pure 7-bit-ASCII.  Here is a list of some
   5643     #   of the difficulties that do arise, between, on the one hand,
   5644     #   the filenames specified on latexmk's and the cwd found by
   5645     #   latexmk from the system, and, on the other hand, the filenames
   5646     #   and their components reported by (pdf)latex in the fls and log
   5647     #   files:
   5648     #      1. Whether the separator of path components is / or \ in
   5649     #         MSWin.
   5650     #      2. Whether the LFN or the SFN is provided.
   5651     #      3. Whether the filenames include the cwd or whether they
   5652     #         are relative to the current directory.
   5653     #      4. Under cygwin, whether the absolute filenames are
   5654     #         specified by UNIX or native MSWin conventions.
   5655     #         (With cygin, the programs used, including the Perl that
   5656     #         executes latexmk, can be any combination of native MSWin
   5657     #         programs and cygwin programs with their UNIX-like
   5658     #         behavior.)
   5659     #      5. Whether UTF-8 or some other coding is used, and under
   5660     #         which circumstances: e.g., in calls to the OS to access
   5661     #         files, in files output by programs, on latexmk's command
   5662     #         line, on other programs' command lines, by the command
   5663     #         interpreterS. 
   5664     #      6. If UTF-8 is used, what kind of canonicalization is used,
   5665     #         if any.  (This is a particular bugbear when files are
   5666     #         transferred between different OSes.)
   5667     #      7. Whether the name of a file in the current directory is
   5668     #         reported as the simple filename or whether it is
   5669     #         preceeded by ".\" or "./".
   5670     #      8. How is it determined whether a pathname is absolute or
   5671     #         relative?  An absolute pathname in MSWin may start with
   5672     #         a drive letter and a colon, but under UNIX-type systems,
   5673     #         the colon is an ordinary character.
   5674     #      9. Whether a filename reported in an fls or log file can be
   5675     #         used as is by perl to access a file, or on the command
   5676     #         line to invoke another program, and whether the use on a
   5677     #         command line depends on whether the command line is
   5678     #         executed by a CLI, and by which CLI.  (E.g., cmd.exe,
   5679     #         v. sh v. tcsh, etc.)
   5680     #     10. Whether such a filename for the filename on (pdf)latex's
   5681     #         file agrees with the one on the command line.
   5682     #   The above questions have arisen from actual experiences and
   5683     #   tests.
   5684     #
   5685     #   In any case, when determining dependent files, we will try to
   5686     #   remove an initial directory string from filenames found in the
   5687     #   fls and log files, whenever it denotes the current
   5688     #   directory. The directory string may be an absolute pathname,
   5689     #   such as MiKTeX writes in both fls and log files, or it may be
   5690     #   simply "./" as given by TeXLive in its log file. There are
   5691     #   several reasons for removing a directory string when possible:
   5692     #
   5693     #      1. To avoid having multiple names referring to the same
   5694     #         file in the list of dependents.
   5695     #      2. Because the name may be in a different coding.  Thus
   5696     #         under MSWin 7, cmd.exe and perl (by default) work in an
   5697     #         "ANSI" coding with some code page, but the filenames
   5698     #         written by MiKTeX are UTF-8 coded (and if they are non-ASCII
   5699     #         can't be used for file-processing by Perl without some
   5700     #         trouble).  This is a particular problem if the pathname
   5701     #         contains non-ASCII characters; the directory names may not
   5702     #         even be under the user's control, unlike typical filenames.
   5703     #      3. When it comes to filenames that are then used in calls to
   5704     #         bibtex and makeindex, it is bad to use absolute pathnames
   5705     #         instead of clearly relative pathnames, because the default
   5706     #         security settings are to prohibit writing files to the
   5707     #         corresponding directories, which makes the calls to these
   5708     #         programs unnecessarily fail.
   5709     #
   5710     #   In removing unnecessary directory-specifying strings, to
   5711     #   convert a filename to a simple specification relative to the
   5712     #   current directory, it will be important to preferentially use
   5713     #   a determination of the current directory from the file being
   5714     #   processed.  In the fls file, there is normally a PWD line.  In
   5715     #   the log file, if (pdf)latex is started with a filename instead
   5716     #   of a command-executing first line, then this can be determined
   5717     #   from the first few lines of the log file -- see parse_log.
   5718     #   This gives a more reliable determination of the relevant path
   5719     #   string; this is especially important in cases where there is a
   5720     #   mismatch of coding of the current directory, particularly
   5721     #   notable in the above-mentioned case of non-ASCII characters
   5722     #   under MSWin.  Other inconsistencies happen when there is a
   5723     #   mixure of cygwin and native MSWin software. There can also be
   5724     #   inconsistencies between whether the separator of pathname
   5725     #   components is "/" or "\".  So we will allow for this.  The
   5726     #   necessary normalizations of filenames are handled by the
   5727     #   subroutines normalize_filename and normalize_clean_filename.
   5728     #
   5729     #   I have not tried to handle the (currently rare) cases that the
   5730     #   OS is neither UNIX-like nor MSWin-like.
   5731 
   5732     # Rules should only be primary
   5733     if ( $$Pcmd_type ne 'primary' ) {
   5734         warn "\n$My_name: ==========$My_name: Probable BUG======= \n   ",
   5735              "   rdb_set_latex_deps called to set files ",
   5736              "for non-primary rule '$rule'\n\n";
   5737         return;
   5738     }
   5739 
   5740 #??    # We'll prune this by all files determined to be needed for source files.
   5741 #??    my %unneeded_source = %$PHsource;
   5742 
   5743     # Parse log file to find relevant filenames
   5744     # Result in the following variables:
   5745     local %dependents = ();    # Maps files to status
   5746     local @bbl_files = ();
   5747     local %idx_files = ();     # Maps idx_file to (ind_file, base)
   5748     local %generated_log = (); # Lists generated files found in log file
   5749     local %generated_fls = (); # Lists generated files found in fls file
   5750     local %source_fls = ();    # Lists source files found in fls file
   5751     local %first_read_after_write = (); # Lists source files that are only read
   5752                                   # after being written (so are not true
   5753                                   # source files.
   5754     local $primary_out = $$Pdest;  # output file (dvi or pdf)
   5755     local %conversions = ();   # (pdf)latex-performed conversions.
   5756                      # Maps output file created and read by (pdf)latex
   5757                      #    to source file of conversion.
   5758     local @missing_subdirs = ();  # Missing subdirectories in aux_dir
   5759 
   5760     local $pwd_latex = undef;     # Cwd as reported in fls file by (pdf)latex
   5761 
   5762     # The following are also returned, but are global, to be used by caller
   5763     # $reference_changed, $bad_reference, $bad_character, $bad_citation, $mult_defined
   5764 
   5765     # Do I have my own eps-to-pdf conversion?
   5766     my $epspdf_cusdep = 0;
   5767     foreach (@cus_dep_list) {
   5768         if ( /^eps pdf / ) { $epspdf_cusdep = 1; last; }
   5769     }
   5770 
   5771     # Analyze fls file first.  It tells us the working directory as seen by (pdf)latex
   5772     # But we'll use the results later, so that they take priority over the findings
   5773     # from the log file.
   5774     my $fls_name = "$aux_dir1$root_filename.fls";
   5775     local $fls_file_analyzed = 0;
   5776     if ($recorder && test_gen_file($fls_name) ) {
   5777 	$fls_file_analyzed = 
   5778 	    (0== parse_fls( $fls_name, \%source_fls, \%generated_fls, \%first_read_after_write, \$pwd_latex ));
   5779 	if (! $fls_file_analyzed ) {
   5780 	    warn "$My_name: fls file '$fls_name' appears to have been made but it couldn't be opened.\n";
   5781 	}
   5782     }
   5783  
   5784     &parse_log;
   5785     $missing_dirs = 'none';      # Status of missing directories
   5786     if (@missing_subdirs) {
   5787         $missing_dirs = 'success';
   5788         if ($allow_subdir_creation) {
   5789             foreach my $dir ( uniqs( @missing_subdirs ) ) {
   5790                 if ( -d $dir ) {
   5791                     $missing_dirs = 'failure';
   5792                     warn "$My_name: ==== Directory '$dir' is said to be missing\n",
   5793                          "     But it exists!\n";
   5794                 }
   5795                 elsif ( (-e $dir) && (!-d $dir) ) {
   5796                     $missing_dirs = 'failure';
   5797                     warn "$My_name: ==== Directory '$dir' is said to be missing\n",
   5798                          "     But a non-directory file of this name exists!\n";
   5799                 }
   5800                 else {
   5801                     if (mkdir $dir) {
   5802                         warn "$My_name: Directory '$dir' created\n";
   5803                     }
   5804                     else {
   5805                         $missing_dirs = 'failure';
   5806                         warn "$My_name: Couldn't create directory '$dir'.\n",
   5807                              "    System error: '$!'\n";
   5808                     }
   5809                 }
   5810             }
   5811         }
   5812         else {
   5813             $missing_dirs = 'not allowed';
   5814             warn "$My_name: There are missing subdirectories, but their creation\n",
   5815                  "    is not allowed.  The subdirectories are:\n";
   5816             foreach my $dir ( uniqs( @missing_subdirs ) ) {
   5817                 warn "   '$dir'\n";
   5818             }
   5819        }
   5820     }
   5821     # Use results from fls file.  (N.B. The hashes will be empty if the fls file
   5822     # wasn't used/analyzed, so we don't need a test as to whether the fls file was
   5823     # used.
   5824     foreach (keys %source_fls) {
   5825         if (! -e ) {
   5826 	    # File is listed in .fls file as read, but doesn't exist now.
   5827 	    # Therefore it is not a true source file, surely.
   5828 	    # Sometimes this is caused by a bug (e.g., lualatex in TeXLive 2016, 
   5829 	    #   2017) when there is an incorrect line in .fls file.  (This
   5830 	    #   would deserve a warning.)
   5831             # But sometimes (e.g., with minted package), the file could be
   5832 	    #  created during a run, read, and then deleted.
   5833            next;
   5834         }
   5835         $dependents{$_} = 4;
   5836 	if ( /\.bbl$/ ) { push @bbl_files, $_; }
   5837     }
   5838     foreach (keys %generated_fls) {
   5839         if (! -e ) {
   5840 	    # File is listed in .fls file as written, but doesn't exist now.
   5841 	    # Therefore it is not a true externally visible generated file.
   5842 	    # (Typically, e.g., with the minted package, it is a temporary
   5843 	    #   file created during a run and then deleted during the run.)
   5844             next;
   5845         }
   5846         rdb_add_generated( $_ );
   5847         if ( exists($dependents{$_}) ) {
   5848             $dependents{$_} = 6;
   5849         }
   5850      }
   5851 
   5852 
   5853     for my $conv (sort keys %conversions) {
   5854         my $conv_source = $conversions{$conv};
   5855         if ( $conv =~ /^(.*)-eps-converted-to\.pdf$/ ) {
   5856             # Check all the conditions for pdflatex's conversion eps to pdf
   5857             # are valid; if they are, treat the converted file as not a
   5858             # source file.
   5859             my $base = $1;
   5860             if ( (-e $conv_source) && (-e $conv) && ( $conv_source eq "$base.eps" ) ) {
   5861                 # $conv isn't a real source of (pdf)latex
   5862                 rdb_remove_files( $rule, $conv );
   5863                 delete $dependents{$conv};
   5864                 if ($epspdf_cusdep) {
   5865 		    $dependents{"$base.pdf"} = ((-e "$base.pdf") ? 4 : 0 );
   5866                 }
   5867 	    }
   5868 	}
   5869     }
   5870 
   5871 
   5872 
   5873 # ?? !! Should also deal with .run.xml file
   5874 
   5875     # Handle result on output file:
   5876     #   1.  Non-existent output file, which is because of no content.
   5877     #         This could either be because the source file has genuinely
   5878     #         no content, or because of a missing input file.  Since a
   5879     #         missing input file might be correctable by a run of some
   5880     #         other program whose running is provoked AFTER a run of
   5881     #         (pdf)latex, we'll set a diagnostic and leave it to the
   5882     #         rdb_make to handle after all circular dependencies are
   5883     #         resolved. 
   5884     #   2.  The output file might be of a different kind than expected
   5885     #         (i.e., dvi instead of pdf, or vv).  This could
   5886     #         legitimately occur when the source file (or an invoked
   5887     #         package or class) sets \pdfoutput. 
   5888     $missing_dvi_pdf = '';
   5889     if ($primary_out eq '')  {
   5890         warn "$My_name: For rule '$rule', no output was made\n";
   5891         $missing_dvi_pdf = $$Pdest;
   5892     }
   5893     elsif ($primary_out ne normalize_filename($$Pdest) ) {
   5894         my ($actual_base, $actual_path, $actual_ext) = fileparseA( $primary_out );
   5895         my ($intended_base, $intended_path, $intended_ext) = fileparseA( $$Pdest );
   5896 	if ( $actual_ext ne $intended_ext ) {
   5897             warn "$My_name: ===For rule '$rule', the extensions differ between the\n",
   5898                  "   actual output file '$primary_out',\n",
   5899                  "   and the expected output '$$Pdest'.\n";
   5900 	    if ( ! exists $allowed_output_ext{$actual_ext} ) {
   5901 		warn "   Actual output file has an extension '$actual_ext' that\n",
   5902 		     "   is not one I know about\n";
   5903 	    }
   5904 	    if ( (($actual_ext eq '.pdf') && ($intended_ext eq '.dvi'))
   5905 		 || (($actual_ext eq '.dvi') && ($intended_ext eq '.pdf'))
   5906                )
   5907             {
   5908 		warn "   This could arise from use of \\pdfoutput in the source file,\n",
   5909  		     "   or from a configuration error\n";
   5910 	    }
   5911 	    else {
   5912                 warn "   This indicates a probable configuration error\n";
   5913 	    }
   5914 	    warn "   A future version of $my_name should be able to make dynamically\n",
   5915 		 "   adjustments to deal with this problem\n";
   5916 	}
   5917     }
   5918 
   5919   IDX_FILE:
   5920     foreach my $idx_file ( keys %idx_files ) {
   5921         my ($ind_file, $ind_base) = @{$idx_files{$idx_file}};
   5922         my $from_rule = "makeindex $idx_file";
   5923         if ( ! rdb_rule_exists( $from_rule ) ){
   5924             print "!!!===Creating rule '$from_rule': '$ind_file' from '$idx_file'\n"
   5925                   if ($diagnostics);
   5926             rdb_create_rule( $from_rule, 'external', $makeindex, '', 1, 
   5927                              $idx_file, $ind_file, $ind_base, 1, 0, 0, 1, [ "$ind_base.ilg" ] );
   5928             print "  ===Source file '$ind_file' for '$rule'\n"
   5929                   if ($diagnostics);
   5930             rdb_ensure_file( $rule, $ind_file, $from_rule );
   5931         }
   5932         # Make sure the .ind file is treated as a detected source file;
   5933         # otherwise if the log file has it under a different name (as
   5934         # with MiKTeX which gives full directory information), there
   5935         # will be problems with the clean-up of the rule concerning
   5936         # no-longer-in-use source files:
   5937         $dependents{$ind_file} = 4;
   5938         if ( ! -e $ind_file ) { 
   5939             # Failure was non-existence of makable file
   5940             # Leave failure issue to other rules.
   5941             $failure = 0;
   5942         }
   5943     }
   5944 
   5945     local %processed_aux_files = ();
   5946   BBL_FILE:
   5947     foreach my $bbl_file ( uniqs( @bbl_files ) ) {
   5948         my ($bbl_base, $bbl_path, $bbl_ext) = fileparseA( $bbl_file );
   5949         $bbl_base = $bbl_path.$bbl_base;
   5950         my @new_bib_files = ();
   5951         my @new_aux_files = ();
   5952         my @new_bst_files = ();
   5953         my @biber_source = ( "$bbl_base.bcf" );
   5954         my $bib_program = 'bibtex';
   5955         if ( test_gen_file( "$bbl_base.bcf" ) ) {
   5956              $bib_program = 'biber';
   5957         }
   5958         my $from_rule = "$bib_program $bbl_base";
   5959         print "=======  Dealing with '$from_rule'\n" if ($diagnostics);
   5960         if ($bib_program eq 'biber') {
   5961             check_biber_log( $bbl_base, \@biber_source );
   5962             # Remove OPPOSITE kind of bbl generation:
   5963             rdb_remove_rule( "bibtex $bbl_base" );
   5964         }
   5965         else {
   5966             parse_aux( "$bbl_base.aux", \@new_bib_files, \@new_aux_files, \@new_bst_files );
   5967             # Remove OPPOSITE kind of bbl generation:
   5968             rdb_remove_rule( "biber $bbl_base" );
   5969         }
   5970         if ( ! rdb_rule_exists( $from_rule ) ){
   5971             print "   ===Creating rule '$from_rule'\n" if ($diagnostics);
   5972             if ( $bib_program eq 'biber' ) {
   5973                 rdb_create_rule( $from_rule, 'external', $biber, '', 1,
   5974                                  "$bbl_base.bcf", $bbl_file, $bbl_base, 1, 0, 0, 1, [ "$bbl_base.blg" ]  );
   5975              }
   5976              else {
   5977                  rdb_create_rule( $from_rule, 'external', $bibtex, 'run_bibtex', 1,
   5978                                   "$bbl_base.aux", $bbl_file, $bbl_base, 1, 0, 0, 1, [ "$bbl_base.blg" ]  );
   5979                }
   5980         }
   5981         local %old_sources = ();
   5982         rdb_one_rule( $from_rule, sub { %old_sources = %$PHsource; } );
   5983 	my @new_sources = ( @new_bib_files, @new_aux_files, @new_bst_files );
   5984         if ( $bib_program eq 'biber' ) {
   5985 	    push @new_sources, @biber_source;
   5986         }
   5987         foreach my $source ( @new_sources ) {
   5988             print "  ===Source file '$source' for '$from_rule'\n"
   5989                if ($diagnostics);
   5990             rdb_ensure_file( $from_rule, $source );
   5991             delete $old_sources{$source};
   5992         }
   5993         foreach my $source ( @new_aux_files ) {
   5994             $processed_aux_files{$source} = 1;
   5995         }
   5996         if ($diagnostics) {
   5997             foreach ( keys %old_sources ) {
   5998                 print "Removing no-longer-needed dependent '$_' from rule '$from_rule'\n";
   5999             }
   6000         }
   6001         rdb_remove_files( $from_rule, keys %old_sources );
   6002         print "  ===Source file '$bbl_file' for '$rule'\n"
   6003             if ($diagnostics);
   6004         rdb_ensure_file( $rule, $bbl_file, $from_rule );
   6005         if ( ! -e $bbl_file ) { 
   6006             # Failure was non-existence of makable file
   6007             # Leave failure issue to other rules.
   6008             $failure = 0;
   6009         }
   6010     }
   6011 
   6012     if ( ($#aux_hooks > -1) && ! exists $processed_aux_files{$aux_main} ) {
   6013         my @new_bib_files = ();
   6014         my @new_aux_files = ();
   6015         my @new_bst_files = ();
   6016         parse_aux( $aux_main, \@new_bib_files, \@new_aux_files, \@new_bst_files );
   6017         foreach my $source ( @new_aux_files ) {
   6018             $processed_aux_files{$source} = 1;
   6019         }
   6020     }
   6021 
   6022 NEW_SOURCE:
   6023     foreach my $new_source (keys %dependents) {
   6024         print "  ===Source file for rule '$rule': '$new_source'\n"
   6025             if ($diagnostics);
   6026 	if ( exists $first_read_after_write{$new_source} ) {
   6027 	    if ( dep_at_start($new_source) ) {
   6028  	        #warn "--- READ ONLY AFTER WRITE OF '$new_source'\n";
   6029 		$dependents{$new_source} = 7;
   6030 	    }
   6031 	    else {
   6032  	        #warn "--- READ ONLY AFTER CREATE OF '$new_source'\n";
   6033 		$dependents{$new_source} = 6;
   6034 	    }
   6035         }
   6036         if ( ($dependents{$new_source} == 5)
   6037              || ($dependents{$new_source} == 6)
   6038 	    ) {
   6039             # (a) File was detected in "No file..." line in log file. 
   6040             #     Typically file was searched for early in run of 
   6041             #     latex/pdflatex, was not found, and then was written 
   6042             #     later in run.
   6043             # or (b) File was written during run. 
   6044             # In both cases, if file doesn't already exist in database, we 
   6045             #    don't know its previous status.  Therefore we tell 
   6046             #    rdb_ensure_file that if it needs to add the file to its 
   6047             #    database, then the previous version of the file should be 
   6048             #    treated as non-existent, to ensure another run is forced.
   6049             rdb_ensure_file( $rule, $new_source, undef, 1 );
   6050         }
   6051         elsif ( $dependents{$new_source} == 7 )  {
   6052             # File was result of conversion by (pdf)latex.
   6053             my $cnv_source = $conversions{$new_source};
   6054             rdb_ensure_file( $rule, $new_source );
   6055 #            if ($cnv_source && ($cnv_source !~ /\"/ ) ) {
   6056              if ($cnv_source ) {
   6057                 # Conversion from $cnv_source to $new_source
   6058                 #   implies that effectively $cnv_source is a source
   6059                 #   of the (pdf)latex run.
   6060                 rdb_ensure_file( $rule, $cnv_source );
   6061             }
   6062             # Flag that changes of the generated file during a run 
   6063             #    do not require a rerun:
   6064             rdb_one_file( $new_source, sub{ $$Pcorrect_after_primary = 1; } );
   6065         }
   6066         else {
   6067             # But we don't need special precautions for ordinary user files 
   6068             #    (or for files that are generated outside of latex/pdflatex). 
   6069             rdb_ensure_file( $rule, $new_source );
   6070         }
   6071         if ( ($dependents{$new_source} == 6) 
   6072              || ($dependents{$new_source} == 7) 
   6073            ) {
   6074             rdb_add_generated($new_source);
   6075         }
   6076     }
   6077 
   6078     my @more_sources = &rdb_set_dependents( $rule );
   6079     my $num_new = $#more_sources + 1;
   6080     foreach (@more_sources) { 
   6081         $dependents{$_} = 4;
   6082         if ( ! -e $_ ) { 
   6083             # Failure was non-existence of makable file
   6084             # Leave failure issue to other rules.
   6085             $failure = 0; 
   6086             $$Pchanged = 1; # New files can be made.  Ignore error.
   6087         }
   6088     }
   6089     if ($diagnostics) {
   6090         if ($num_new > 0 ) {
   6091             print "$num_new new source files for rule '$rule':\n";
   6092             foreach (@more_sources) { print "   '$_'\n"; }
   6093         }
   6094         else {
   6095             print "No new source files for rule '$rule':\n";
   6096         }
   6097         my @first_read_after_write = sort keys %first_read_after_write;
   6098         if ($#first_read_after_write >= 0) {
   6099             print "The following files were only read after being written:\n";
   6100             foreach (@first_read_after_write) {
   6101                 print "   '$_'\n";
   6102             }
   6103           }
   6104     }
   6105     my @files_not_needed = ();
   6106     foreach (keys %$PHsource) { 
   6107         if ( ! exists $dependents{$_} ) {
   6108             print "Removing no-longer-needed dependent '$_' from rule '$rule'\n"
   6109               if $diagnostics;
   6110             push @files_not_needed, $_;
   6111         }
   6112     }
   6113     rdb_remove_files( $rule, @files_not_needed );
   6114 
   6115 } # END rdb_set_latex_deps
   6116 
   6117 #************************************************************
   6118 
   6119 sub test_gen_file {
   6120     # Usage: test_gen_file( filename )
   6121     # Tests whether the file was generated during a run of (pdf)latex.
   6122     # Assumes context for primary rule.
   6123     # Two kinds of test are used:
   6124     # a. From %generated_log, which works after the log file has been parsed,
   6125     #    but only for certain files and for those TeX engines (not MiKTeX)
   6126     #    that put \openout lines in log file.
   6127     # b. By the file existing and being at least as new as the system
   6128     #    time at the start of the run. But we allow for a measured
   6129     #    offset between filetime and system time, which could be
   6130     #    nonzero if the file is on a different, remote system than the
   6131     #    one running latexmk. We must also allow a threshold in the
   6132     #    comparisons of filetimes to allow for the inaccuracy of the
   6133     #    offset measurement.
   6134     my $file = shift;
   6135     return exists $generated_log{$file}
   6136            || ( -e $file && ( get_mtime( $file ) >= $$Prun_time + $filetime_offset - $filetime_causality_threshold));
   6137 }
   6138 
   6139 #************************************************************
   6140 
   6141 sub dep_at_start {
   6142     # Usage: dep_at_start( filename )
   6143     # Tests whether the file was source file and existed at start of run.
   6144     # Assumes context for primary rule.
   6145     my $time = undef;
   6146     rdb_one_file( shift, sub{ $time = $$Ptime; } );
   6147     return (defined $time) && ($time != 0);
   6148 }
   6149 
   6150 #************************************************************
   6151 
   6152 sub rdb_find_new_files {
   6153     # Call: rdb_find_new_files
   6154     # Assumes rule context for primary rule.
   6155     # Deal with files which were missing and for which a method
   6156     # of finding them has become available:
   6157     #   (a) A newly available source file for a custom dependency.
   6158     #   (b) When there was no extension, a file with appropriate
   6159     #       extension
   6160     #   (c) When there was no extension, and a newly available source 
   6161     #       file for a custom dependency can make it.
   6162 
   6163     my %new_includes = ();
   6164 
   6165 MISSING_FILE:
   6166     foreach my $missing ( keys %$PHsource ) {
   6167         next if ( $$PHsource{$missing} != 0 ); 
   6168         my ($base, $path, $ext) = fileparseA( $missing );
   6169         $ext =~ s/^\.//;
   6170         if ( -e "$missing.tex" ) { 
   6171             $new_includes{"$missing.tex"} = 1;
   6172         }
   6173         elsif ( -e $missing ) { 
   6174             $new_includes{$missing} = 1;
   6175         }
   6176         elsif ( $ext ne "" ) {
   6177             foreach my $dep (@cus_dep_list){
   6178                my ($fromext,$toext) = split('\s+',$dep);
   6179                if ( ( "$ext" eq "$toext" )
   6180                     && ( -e "$path$base.$fromext" )
   6181                   )  {
   6182                   # Source file for the missing file exists
   6183                   # So we have a real include file, and it will be made
   6184                   # next time by rdb_set_dependents
   6185                   $new_includes{$missing} = 1;
   6186                }
   6187                else {
   6188                    # no point testing the $toext if the file doesn't exist.
   6189                }
   6190                next MISSING_FILE;
   6191             }
   6192        }
   6193        else {
   6194            # $_ doesn't exist, $_.tex doesn't exist,
   6195            # and $_ doesn't have an extension
   6196            foreach my $dep (@cus_dep_list){
   6197               my ($fromext,$toext) = split('\s+',$dep);
   6198               if ( -e "$path$base.$fromext" ) {
   6199                   # Source file for the missing file exists
   6200                   # So we have a real include file, and it will be made
   6201                   # next time by &rdb__dependents
   6202                   $new_includes{"$path$base.$toext"} = 1;
   6203 #                  next MISSING_FILE;
   6204               }
   6205               if ( -e "$path$base.$toext" ) {
   6206                   # We've found the extension for the missing file,
   6207                   # and the file exists
   6208                   $new_includes{"$path$base.$toext"} = 1;
   6209 #                  next MISSING_FILE;
   6210               }
   6211            }
   6212        }
   6213     } # end MISSING_FILES
   6214 
   6215     # Sometimes bad line-breaks in log file (etc) create the
   6216     # impression of a missing file e.g., ./file, but with an incorrect
   6217     # extension.  The above tests find the file with an extension,
   6218     # e.g., ./file.tex, but it is already in the list.  So now I will
   6219     # remove files in the new_include list that are already in the
   6220     # include list.  Also handle aliasing of file.tex and ./file.tex.
   6221     # For example, I once found:
   6222 # (./qcdbook.aux (./to-do.aux) (./ideas.aux) (./intro.aux) (./why.aux) (./basics
   6223 #.aux) (./classics.aux)
   6224 
   6225     my $found = 0;
   6226     foreach my $file (keys %new_includes) {
   6227 #	if ( $file =~ /\"/ ) {next; }
   6228         my $stripped = $file;
   6229         $stripped =~ s{^\./}{};
   6230         if ( exists $PHsource{$file} ) {
   6231             delete $new_includes{$file};
   6232         }
   6233         else {
   6234             $found ++;
   6235             rdb_ensure_file( $rule, $file );
   6236         }
   6237     }
   6238 
   6239     if ( $diagnostics && ( $found > 0 ) ) {
   6240         warn "$My_name: Detected previously missing files:\n";
   6241         foreach ( sort keys %new_includes ) {
   6242             warn "   '$_'\n";
   6243         }
   6244     }
   6245     return $found;
   6246 } # END rdb_find_new_files
   6247 
   6248 #************************************************************
   6249 
   6250 sub rdb_set_dependents {
   6251     # Call rdb_set_dependents( rules ...)
   6252     # Returns array (sorted), of new source files.
   6253     local @new_sources = ();
   6254     local @deletions = ();
   6255 
   6256 # Shouldn't recurse.  The definite rules to be examined are given.
   6257     rdb_for_some( [@_],  0, \&rdb_one_dep );
   6258 # OLD    rdb_recurse( [@_],  0, \&rdb_one_dep );
   6259     foreach (@deletions) {
   6260         my ($rule, $file) = @$_;
   6261         rdb_remove_files( $rule, $file );
   6262     }
   6263     &rdb_make_links;
   6264     return uniqs( @new_sources );
   6265 } #END rdb_set_dependents
   6266 
   6267 #************************************************************
   6268 
   6269 sub rdb_find_source_file {
   6270     # Helper for searching dependencies in all paths inside the TEXINPUTS
   6271     # environment variable.
   6272     my $test = "$_[0].$_[1]";
   6273     if ( -e $test ) {
   6274         return $_[0];
   6275     }
   6276     if ( exists $ENV{TEXINPUTS} ) {
   6277 	foreach my $searchpath (split $search_path_separator, $ENV{TEXINPUTS}) {
   6278 	    my $file = File::Spec->catfile($searchpath,$_[0]);
   6279 	    my $test = "$file.$_[1]";
   6280 	    if ( -e $test ) {
   6281 		return $file;
   6282 	    }
   6283 	}
   6284     }
   6285     return "$_[0]";
   6286 }
   6287 
   6288 #************************************************************
   6289 
   6290 sub rdb_one_dep {
   6291     # Helper for finding dependencies.  One case, $rule and $file given
   6292     # Assume file (and rule) context for DESTINATION file.
   6293 
   6294     # Only look for dependency if $rule is primary rule (i.e., latex
   6295     # or pdflatex) or is a custom dependency:
   6296     if ( (! exists $possible_primaries{$rule}) && ($rule !~ /^cusdep/) ) {
   6297         return;
   6298     }
   6299 #print "=============ONE_DEP: '$rule' '$file'\n";
   6300     local $new_dest = $file;
   6301     my ($base_name, $path, $toext) = fileparseA( $new_dest );
   6302     $base_name = $path.$base_name;
   6303     $toext =~ s/^\.//;
   6304     my $Pinput_extensions = $input_extensions{$rule};
   6305 DEP:
   6306     foreach my $dep ( @cus_dep_list ) {
   6307         my ($fromext,$proptoext,$must,$func_name) = split('\s+',$dep);
   6308         if ( $toext eq $proptoext ) {
   6309             $base_name = rdb_find_source_file($base_name, $fromext);
   6310             my $source = "$base_name.$fromext";
   6311             # Found match of rule
   6312             if ($diagnostics) {
   6313                 print "Found cusdep:  $source to make $rule:$new_dest ====\n";
   6314             }
   6315             if ( -e $source ) {
   6316                 $$Pfrom_rule = "cusdep $fromext $toext $base_name";
   6317 		my $new_new_dest = "$base_name.$toext";
   6318 		if ($new_new_dest ne $new_dest) {
   6319 		    rdb_ensure_file( $rule, $new_new_dest );
   6320 		    $new_dest = $new_new_dest;
   6321 		}
   6322                 local @PAnew_cmd = ( 'do_cusdep', $func_name );
   6323                 if ( !-e $new_dest ) {
   6324                     push @new_sources, $new_dest;
   6325                 }
   6326                 if (! rdb_rule_exists( $$Pfrom_rule ) ) {
   6327                     print "$My_name: === Creating rule '$$Pfrom_rule'\n" if $diagnostics;
   6328                     rdb_create_rule( $$Pfrom_rule, 'cusdep', '', \@PAnew_cmd, 3, 
   6329                                      $source, $new_dest, $base_name, 0 );
   6330                 }
   6331                 return;
   6332             }
   6333             else {
   6334                 # Source file does not exist
   6335                 if ( !$force_mode && ( $must != 0 ) ) {
   6336                     # But it is required that the source exist ($must !=0)
   6337                     $failure = 1;
   6338                     $failure_msg = "File '$base_name.$fromext' does not exist ".
   6339                                    "to build '$base_name.$toext'";
   6340                     return;
   6341                 }
   6342                 elsif ( $$Pfrom_rule =~ /^cusdep $fromext $toext / )  {
   6343                     # Source file does not exist, destination has the rule set.
   6344                     # So turn the from_rule off
   6345                     $$Pfrom_rule = '';
   6346                 }
   6347                 else {
   6348                 }
   6349             }
   6350         }
   6351         elsif ( ($toext eq '') 
   6352                 && (! -e $file ) 
   6353                 && (! -e "$base_name.$proptoext" ) 
   6354                 && exists $$Pinput_extensions{$proptoext}
   6355               ) {
   6356             # Empty extension and non-existent destination
   6357             #   This normally results from  \includegraphics{A}
   6358             #    without graphics extension for file, when file does
   6359             #    not exist.  So we will try to find something to make it.
   6360             $base_name = rdb_find_source_file($base_name, $fromext);
   6361             my $source = "$base_name.$fromext";
   6362             if ( -e $source ) {
   6363                 $new_dest = "$base_name.$proptoext";
   6364                 my $from_rule = "cusdep $fromext $proptoext $base_name";
   6365                 push @new_sources, $new_dest;
   6366                 print "Ensuring rule for '$from_rule', to make '$new_dest'\n"
   6367                     if $diagnostics > -1;
   6368                 local @PAnew_cmd = ( 'do_cusdep', $func_name );
   6369                 if (! rdb_rule_exists( $from_rule ) ) {
   6370                     print "$My_name: === Creating rule '$$Pfrom_rule'\n" if $diagnostics;
   6371                     rdb_create_rule( $from_rule, 'cusdep', '', \@PAnew_cmd, 3, 
   6372                                      $source, $new_dest, $base_name, 0 );
   6373                 }
   6374                 rdb_ensure_file( $rule, $new_dest, $from_rule );
   6375                 # We've now got a spurious file in our rule.  But don't mess
   6376                 # with deleting an item we are in the middle of!
   6377                 push @deletions, [$rule, $file];
   6378                 return;
   6379             }
   6380         } # End of Rule found
   6381     } # End DEP
   6382     if ( (! -e $file) && $use_make_for_missing_files ) {
   6383         # Try to make the missing file
   6384         #Set character to surround filenames in commands:
   6385         my $q = $quote_filenames ? '"' : '';
   6386         if ( $toext ne '' ) {
   6387              print "$My_name: '$rule': source file '$file' doesn't exist. I'll try making it...\n";
   6388              &Run_subst( "$make $q$file$q" );
   6389              if ( -e $file ) {
   6390                  return;
   6391              }
   6392         }
   6393         else {
   6394              print "$My_name: '$rule': source '$file' doesn't exist.\n",
   6395                    "   I'll try making it with allowed extensions \n";
   6396              foreach my $try_ext ( keys %$Pinput_extensions ) {
   6397                  my $new_dest = "$file.$try_ext";
   6398                  &Run_subst( "$make $q$new_dest$q" );
   6399                  if ( -e $new_dest ) {
   6400                      print "SUCCESS in making '$new_dest'\n";
   6401                      # Put file in rule, without a from_rule, but
   6402                      # set its state as non-existent, to correspond
   6403                      # to file's state before the file was made
   6404                      # This ensures a rerun of (pdf)latex is provoked.
   6405                      rdb_ensure_file( $rule, $new_dest, undef, 1 );
   6406                      push @new_sources, $new_dest;
   6407                      push @deletions, [$rule, $file];
   6408                      # Flag need for a new run of (pdf)latex despite
   6409                      # the error due to a missing file.
   6410                      $$Pout_of_date_user = 1;
   6411                      return;
   6412                  }
   6413            }
   6414         }
   6415     }
   6416 } #END rdb_one_dep
   6417 
   6418 #************************************************************
   6419 
   6420 sub rdb_list {
   6421     # Call: rdb_list()
   6422     # List rules and their source files
   6423     print "===Rules:\n";
   6424     local $count_rules = 0;
   6425     my @accessible_all = rdb_accessible( keys %requested_filerules ); 
   6426     rdb_for_some( 
   6427         \@accessible_all,
   6428         sub{ $count_rules++; 
   6429              print "Rule '$rule' depends on:\n"; 
   6430            },
   6431         sub{ print "    '$file'\n"; },
   6432         sub{ print "  and generates:\n";
   6433              foreach (keys %$PHdest) { print "    '$_'\n"; }
   6434 #             print "  default_extra_generated:\n";
   6435 #             foreach (@$PA_extra_generated) { print "    '$_'\n"; }
   6436            },
   6437     );
   6438     if ($count_rules <= 0) {
   6439         print "   ---No rules defined\n";
   6440     }
   6441 } #END rdb_list
   6442 
   6443 #************************************************************
   6444 
   6445 sub deps_list {
   6446     # Call: deps_list(fh)
   6447     # List dependent files to file open on fh
   6448     my $fh = $_[0];
   6449     print $fh "#===Dependents, and related info, for $filename:\n";
   6450     my @dest_exts = ();
   6451     if ($pdf_mode) {push @dest_exts, '.pdf';}
   6452     if ($dvi_mode) {push @dest_exts, '.dvi';}
   6453     if ($postscript_mode) {push @dest_exts, '.ps';}
   6454     my %source = ( $texfile_name => 1 );
   6455     my @generated = ();
   6456     my @accessible_all = rdb_accessible( keys %requested_filerules );
   6457     rdb_for_some(
   6458         \@accessible_all,
   6459         sub{
   6460 #             foreach (keys %$PHdest) { print "-----   $_\n"; }
   6461              push @generated, keys %$PHdest; 
   6462            },
   6463         sub{ $source{$file} = 1; }
   6464     );
   6465     foreach (keys %generated_exts_all) {
   6466         (my $name = /%R/ ? $_ : "%R.$_") =~ s/%R/${aux_dir1}${root_filename}/;
   6467         push @generated, $name;
   6468     }
   6469     show_array( "Generated:", @generated )  if $diagnostics;
   6470     foreach (@generated) {
   6471         delete $source{$_};
   6472     }
   6473     show_array( "Sources:", keys %source ) if $diagnostics;
   6474     foreach my $ext (@dest_exts) {
   6475          # Don't insert name of deps file in targets.
   6476          # The previous behavior of inserting the name of the deps file
   6477          # matched the method recommended by GNU make for automatically
   6478          # generated prerequisites -- see Sec. "Generating Prerequisites
   6479          # Automatically" of GNU make manual (v. 4.2).  But this can
   6480          # cause problems in complicated cases, and as far as I can see,
   6481          # it doesn't actually help, despite the reasoning given.
   6482          # The only purpose of the deps file is to to determine source
   6483          # files for a particular rule.  The files whose changes make the
   6484          # deps file out-of-date are the same as those that make the real
   6485          # target file (e.g., .pdf) out-of-date. So the GNU method seems
   6486          # completely unnecessary.
   6487        print $fh "${out_dir1}${root_filename}${ext} :";
   6488        foreach (sort keys %source) {
   6489            print $fh "\\\n    $_";
   6490        }
   6491        print $fh "\n";
   6492     }
   6493     print $fh "#===End dependents for $filename:\n";
   6494     if ($dependents_phony) {
   6495         print $fh "\n#===Phony rules for $filename:\n\n";
   6496         foreach (sort keys %source) {
   6497             print $fh "$_ :\n\n";
   6498         }
   6499         print $fh "#===End phony rules for $filename:\n";
   6500     }
   6501 } #END deps_list
   6502 
   6503 #************************************************************
   6504 
   6505 sub rdb_show {
   6506     # Call: rdb_show()
   6507     # Displays contents of rule data base.
   6508     # Side effect: Exercises access routines!
   6509     print "===Rules:\n";
   6510     local $count_rules = 0;
   6511     rdb_for_all( 
   6512         sub{ $count_rules++; 
   6513              my @int_cmd = @$PAint_cmd;
   6514              foreach (@int_cmd) {
   6515                  if ( !defined($_) ) { $_='undef';}
   6516              }
   6517              print "  [$rule]: '$$Pcmd_type' '$$Pext_cmd' '@int_cmd' $$Ptest_kind ",
   6518                    "'$$Psource' '$$Pdest' '$$Pbase' $$Pout_of_date $$Pout_of_date_user\n"; },
   6519         sub{ print "    '$file': $$Ptime $$Psize $$Pmd5 '$$Pfrom_rule'\n"; }
   6520     );
   6521     if ($count_rules <= 0) {
   6522         print "   ---No rules defined\n";
   6523     }
   6524 } #END rdb_show
   6525 
   6526 #************************************************************
   6527 
   6528 sub rdb_accessible {
   6529     # Call: rdb_accessible( rule, ...)
   6530     # Returns array of rules accessible from the given rules
   6531     local @accessible = ();
   6532     rdb_recurse( [@_], sub{ push @accessible, $rule; } );
   6533     return @accessible;
   6534 } #END rdb_accessible
   6535 
   6536 #************************************************************
   6537 #************************************************************
   6538 #************************************************************
   6539 
   6540 sub rdb_make {
   6541     # Call: rdb_make( target, ... )
   6542     # Makes the targets and prerequisites.  
   6543     # Leaves one-time rules to last.
   6544     # Does appropriate repeated makes to resolve dependency loops
   6545 
   6546     # Returns 0 on success, nonzero on failure.
   6547 
   6548     # General method: Find all accessible rules, then repeatedly make
   6549     # them until all accessible rules are up-to-date and the source
   6550     # files are unchanged between runs.  On termination, all
   6551     # accessible rules have stable source files.
   6552     #
   6553     # One-time rules are view and print rules that should not be
   6554     # repeated in an algorithm that repeats rules until the source
   6555     # files are stable.  It is the calling routine's responsibility to
   6556     # arrange to call them, or to use them here with caution.
   6557     #
   6558     # Note that an update-viewer rule need not be considered
   6559     # one-time.  It can be legitimately applied everytime the viewed
   6560     # file changes.
   6561     #
   6562     # Note also that the criterion of stability is to be applied to
   6563     # source files, not to output files.  Repeated application of a
   6564     # rule to IDENTICALLY CONSTANT source files may produce different
   6565     # output files.  This may be for a trivial reason (e.g., the
   6566     # output file contains a time stamp, as in the header comments for
   6567     # a typical postscript file), or for a non-trivial reason (e.g., a
   6568     # stochastic algorithm, as in abcm2ps).   
   6569     #
   6570     # This caused me some actual trouble.  In general, circular
   6571     # dependencies produce non-termination, and the the following
   6572     # situation is an example of a generic situation where certain
   6573     # rules must be obeyed in order to obtain proper results:
   6574     #    1.  A/the latex source file contains specifications for
   6575     #        certain postprocessing operations.  Standard (pdf)latex 
   6576     #        already has this, for indexing and bibliography.
   6577     #    2.  In the case in point that caused me trouble, the
   6578     #        specification was for musical tunes that were contained
   6579     #        in external source files not directly input to
   6580     #        (pdf)latex.  But in the original version, there was a
   6581     #        style file (abc.sty) that caused latex itself to call
   6582     #        abcm2ps to make .eps files for each tune that were to be
   6583     #        read in on the next run of latex. 
   6584     #    3.  Thus the specification can cause a non-terminating loop
   6585     #        for latexmk, because the output files of abcm2ps changed
   6586     #        even with identical input.  
   6587     #    4.  The solution was to 
   6588     #        a. Use a style file abc_get.sty that simply wrote the
   6589     #           specification on the tunes to the .aux file in a
   6590     #           completely deterministic fashion.
   6591     #        b. Instead of latex, use a script abclatex.pl that runs
   6592     #           latex and then extracts the abc contents for each tune
   6593     #           from the source abc file.  This is also
   6594     #           deterministic. 
   6595     #        c. Use a cusdep rule in latexmk to convert the tune abc
   6596     #           files to eps.  This is non-deterministic, but only
   6597     #           gets called when the (deterministic) source file
   6598     #           changes.
   6599     #        This solves the problem.  Latexmk works.  Also, it is no
   6600     #        longer necessary to enable write18 in latex, and multiple
   6601     #        unnecessary runs of abcm2ps are no longer used. 
   6602     #
   6603     # The order of testing and applying rules is chosen by the
   6604     # following heuristics: 
   6605     #    1.  Both latex and pdflatex may be used, but the resulting
   6606     #        aux files etc may not be completely identical.  Define
   6607     #        latex and pdflatex as primary rules.  Apply the general
   6608     #        method of repeated circulating through all rules until
   6609     #        the source files are stable for each primary rule
   6610     #        separately.  Naturally the rules are all accessible
   6611     #        rules, but excluding primary rules except for the current
   6612     #        primary.
   6613     #    2.  Assume that the primary rules are relatively
   6614     #        time-consuming, so that unnecessary passes through them
   6615     #        to check stability of the source files should be avoided.
   6616     #    3.  Assume that although circular dependencies exist, the
   6617     #        rules can nevertheless be thought of as basically
   6618     #        non-circular, and that many rules are strictly or
   6619     #        normally non-circular.  In particular cusdep rules are
   6620     #        typically non-circular (e.g., fig2eps), as are normal
   6621     #        output processing rules like dvi2ps.  
   6622     #    4.  The order for the non-circular approximation is
   6623     #        determined by applying the assumption that an output file
   6624     #        from one rule that is read in for an earlier stage is
   6625     #        unchanged. 
   6626     #    HOWEVER, at a first attempt, the ordering is not needed.  It
   6627     #    only gives an optimization
   6628     #    5.  (Note that these assumptions could be violated, e.g., if
   6629     #        $dvips is arranged not only to do the basic dvips
   6630     #        command, but also to extract information from the ps file
   6631     #        and feed it back to an input file for (pdf)latex.)
   6632     #    6.  Nevertheless, the overall algorithm should allow
   6633     #        circularities.  Then the general criterion of stability
   6634     #        of source files covers the general case, and also
   6635     #        robustly handles the case that the USER changes source
   6636     #        files during a run.  This is particularly important in
   6637     #        -pvc mode, given that a full make on a large document can
   6638     #        be quite lengthy in time, and moreover that a user
   6639     #        naturally wishes to make corrections in response to
   6640     #        errors, particularly latex errors, and have them apply
   6641     #        right away.
   6642     # This leads to the following approach:
   6643     #    1.  Classify accessible rules as: primary, pre-primary
   6644     #        (typically cusdep, bibtex, makeindex, etc), post-primary
   6645     #        (typically dvips, etc), and one-time
   6646     #    2.  Then stratify the rules into an order of application that
   6647     #        corresponds to the basic feedforward structure, with the
   6648     #        exclusion of one-time rules.
   6649     #    3.  Always require that one-time rules are among the
   6650     #        explicitly requested rules, i.e., the last to be applied,
   6651     #        were we to apply them.  Anything else would not match the
   6652     #        idea of a one-time rule.  
   6653     #    4.  Then work as follows:
   6654     #        a. Loop over primaries
   6655     #        b. For each primary, examine each pre-primary rule and
   6656     #           apply if needed, then the primary rule and then each
   6657     #           post-primary rule.  The ordering of the pre-primary
   6658     #           and post-primary rules was found in step 2.
   6659     #      BUT applying the ordering is not essential
   6660     #        c. Any time that a pre-primary or primary rule is
   6661     #           applied, loop back to the beginning of step b.  This
   6662     #           ensures that bibtex etc are applied before rerunning
   6663     #           (pdf)latex, and also covers changing source files, and
   6664     #           gives priority to quick pre-primary rules for changing
   6665     #           source files against slow reruns of latex.
   6666     #        d. Then apply post-primary rules in order, but not
   6667     #           looping back after each rule.  This non-looping back
   6668     #           is because the rules are normally feed-forward only.
   6669     #      BUT applying the ordering is not essential
   6670     #        e. But after completing post-primary rules do loop back
   6671     #           to b if any rules were applied.  This covers exotic
   6672     #           circular dependence (and as a byproduct, changing
   6673     #           source files).
   6674     #        f. On each case of looping back to b, re-evaluate the
   6675     #           dependence setup to allow for the effect of changing
   6676     #           source files.  
   6677     #    
   6678 
   6679     local @requested_targets = @_;
   6680     local %current_primaries = ();   # Hash whose keys are primary rules 
   6681                 # needed, i.e., known latex-like rules which trigger
   6682                 # circular dependencies
   6683     local @pre_primary = ();   # Array of rules
   6684     local @post_primary = ();  # Array of rules
   6685     local @unusual_one_time = ();      # Array of rules
   6686 
   6687 
   6688     # For diagnostics on changed files, etc:
   6689     local @changed = ();
   6690     local @disappeared = ();
   6691     local @no_dest = ();       # Non-existent destination files
   6692     local @rules_never_run = ();
   6693     local @rules_to_apply = ();
   6694 
   6695     &rdb_classify_rules( \%possible_primaries, @requested_targets );
   6696 
   6697     local %pass = ();
   6698     local $failure = 0;        # General accumulated error flag
   6699     local $missing_dvi_pdf = ''; # Did primary run fail to make its output file?
   6700     local $runs = 0;
   6701     local $too_many_passes = 0;
   6702     local %rules_applied = ();
   6703     my $retry_msg = 0;         # Did I earlier say I was going to attempt 
   6704                                # another pass after a failure?
   6705   PRIMARY:
   6706     foreach my $primary (keys %current_primaries ) {
   6707         foreach my $rule (keys %rule_db) { 
   6708             $pass{$rule} = 0; 
   6709         }
   6710       PASS:
   6711         while (1==1) {
   6712             # Exit condition at end of body of loop.
   6713             $runs = 0;
   6714             my $previous_failure = $failure;
   6715             $failure = 0;
   6716             local $newrule_nofile = 0;  # Flags whether rule created for
   6717                            # making currently non-existent file, which
   6718                            # could become a needed source file for a run
   6719                            # and therefore undo an error condition
   6720             if ($diagnostics) {
   6721                 print "Make: doing pre_primary and primary...\n";
   6722             }
   6723             # Do the primary run if it is needed. On return $runs == 0
   6724             #       signals that nothing was run (and hence no output
   6725             #       files changed), either because no input files
   6726             #       changed and no run was needed, or because the
   6727             #       number of passes through the rule exceeded the
   6728             #       limit.  In the second case $too_many_runs is set.
   6729             rdb_for_some( [@pre_primary, $primary], \&rdb_make1 );
   6730             if ( ($runs > 0) && ! $too_many_passes ) {
   6731                 $retry_msg = 0;
   6732                 if ( $force_mode || (! $failure) ) {
   6733                     next PASS;
   6734 		}
   6735                 # Get here on failure, without being in force_mode
   6736                 if ( $newrule_nofile ) { 
   6737                     $retry_msg = 1;
   6738                     print "$My_name: Error on run, but found possibility to ",
   6739                           "make new source files\n";
   6740                     next PASS;
   6741 		}
   6742                 else { last PASS; }
   6743             }
   6744             if ($runs == 0) {
   6745                 # $failure not set on this pass, so use value from previous pass:
   6746                 $failure = $previous_failure;
   6747                 if ($retry_msg) {
   6748                     print "But in fact no new files made\n";
   6749 		}
   6750                 if ($failure && !$force_mode ) { last PASS; }
   6751             }
   6752             if ( $missing_dvi_pdf ) { 
   6753                # No output from primary, after completing circular dependence
   6754                warn "Failure to make '$missing_dvi_pdf'\n";
   6755                $failure = 1; 
   6756                last PASS;
   6757             }    
   6758             if ($diagnostics) {
   6759                 print "Make: doing post_primary...\n";
   6760             }
   6761             rdb_for_some( [@post_primary], \&rdb_make1 );
   6762             if ( ($runs == 0) || $too_many_passes ) {
   6763                 # If $too_many_passes is set, it should also be that
   6764                 # $runs == 0; but for safety, I also checked
   6765                 # $too_many_passes.
   6766                 last PASS;
   6767             }
   6768         }
   6769         continue {
   6770             # Re-evaluate rule classification and accessibility,
   6771             # but do not change primaries.
   6772             # Problem is that %current_primaries gets altered
   6773             my %old_curr_prim = %current_primaries;
   6774             &rdb_classify_rules( \%possible_primaries, @requested_targets );
   6775             %current_primaries = %old_curr_prim;
   6776             &rdb_make_links;
   6777         }
   6778     }
   6779     rdb_for_some( [@unusual_one_time], \&rdb_make1 );
   6780     rdb_write( $fdb_name );
   6781 
   6782     if ($#primary_warning_summary > -1) {
   6783 	# N.B. $mult_defined, $bad_reference, $bad_character, $bad_citation also available here.
   6784         show_array( "$My_name: Summary of warnings from last run of (pdf)latex:", 
   6785                     @primary_warning_summary );
   6786     }
   6787     if (! $silent) {
   6788         if ($failure && $force_mode) {
   6789             print "$My_name: Errors, in force_mode: so I tried finishing targets\n";
   6790         }
   6791         elsif ($failure) {
   6792             print "$My_name: Errors, so I did not complete making targets\n";
   6793         }
   6794         else {
   6795             local @dests = ();
   6796             rdb_for_some( [@_], sub{ push @dests, $$Pdest if ($$Pdest); } );
   6797             print "$My_name: All targets (@dests) are up-to-date\n";
   6798         }
   6799     }
   6800     return $failure;
   6801 } #END rdb_make
   6802 
   6803 #-------------------
   6804 
   6805 sub rdb_show_rule_errors {
   6806     local @errors = ();
   6807     local @warnings = ();
   6808     rdb_for_all( 
   6809                sub{
   6810                    if ($$Plast_message ne '') {
   6811                        if ($$Plast_result == 200) {
   6812                           push @warnings, "$rule: $$Plast_message";
   6813                        }
   6814                        else {
   6815                           push @errors, "$rule: $$Plast_message";
   6816                        }
   6817                    }
   6818                    elsif ($$Plast_result == 1) {
   6819                        push @errors, "$rule: failed to create output file";
   6820                    }
   6821                    elsif ($$Plast_result == 2) {
   6822                        push @errors, "$rule: gave an error";
   6823                    }
   6824                    elsif ($$Prun_time == 0) {
   6825                        #  This can have innocuous causes.  So don't report
   6826                    }
   6827                }
   6828               );
   6829     if ($#warnings > -1) { 
   6830         warn "Collected warning summary (may duplicate other messages):\n";
   6831         foreach (@warnings){
   6832             warn "  $_\n";
   6833         }
   6834     }
   6835     if ($#errors > -1) { 
   6836         warn "Collected error summary (may duplicate other messages):\n";
   6837         foreach (@errors){
   6838             warn "  $_\n";
   6839         }
   6840     }
   6841     return $#errors+1;
   6842 }
   6843 
   6844 #-------------------
   6845 
   6846 sub rdb_make1 {
   6847     # Call: rdb_make1
   6848     # Helper routine for rdb_make.
   6849     # Carries out make at level of given rule (all data available).
   6850     # Assumes contexts for recursion, make, and rule, and
   6851     # assumes that source files for the rule are to be considered
   6852     # up-to-date.
   6853     if ($diagnostics) { print "  Make1 $rule\n"; }
   6854     if ($failure & ! $force_mode) {return;}
   6855     if ( ! defined $pass{$rule} ) {$pass{$rule} = 0; } 
   6856     &rdb_clear_change_record;
   6857 
   6858     # Special fix up for bibtex:
   6859     my $bibtex_not_run = -1;   # Flags status as to whether this is a
   6860         # bibtex rule and if it is, whether out-of-date condition is to
   6861         # be ignored.
   6862         #  -1 => not a bibtex rule
   6863         #   0 => no special treatment
   6864         #   1 => don't run bibtex because of non-existent bibfiles
   6865         #           (and setting to do this test)
   6866         #   2 => don't run bibtex because of setting
   6867     my @missing_bib_files = ();
   6868     if ( $rule =~ /^(bibtex|biber)/ ) {
   6869         $bibtex_not_run = 0;
   6870         if ($bibtex_use == 0) {
   6871            $bibtex_not_run = 2;
   6872         }
   6873         elsif ( ($bibtex_use == 1) || ($bibtex_use == 1.5) ) {
   6874             foreach ( keys %$PHsource ) {
   6875                 if ( ( /\.bib$/ ) && (! -e $_) ) {
   6876                     push @missing_bib_files, $_;
   6877                     $bibtex_not_run = 1;
   6878                 }
   6879             }
   6880         }
   6881     }
   6882 
   6883     if ( ($$Prun_time == 0) && exists($possible_primaries{$rule}) ) {
   6884         push @rules_never_run, $rule;
   6885         $$Pout_of_date = 1;
   6886         $$Plast_result = -1;
   6887     }
   6888     else {
   6889         if ( $$Pdest && (! -e $$Pdest) ) {
   6890             # With a non-existent destination, if we haven't made any passes
   6891             #   through a rule, rerunning the rule is good, because the file
   6892             #   may fail to exist because of being deleted by the user (for ex.)
   6893             #   rather than because of a failure on a previous run. 
   6894             # (We could do better with a flag in fdb file.)
   6895             # But after the first pass, the situation is different.  
   6896             #   For a primary rule (pdf)latex, the lack of a destination file 
   6897             #      could result from there being zero content due to a missing
   6898             #      essential input file.  The input file could be generated 
   6899             #      by a program to be run later (e.g., a cusdep or bibtex), 
   6900             #      so we should wait until all passes are completed before 
   6901             #      deciding a non-existent destination file is an error.
   6902             #   For a custom dependency, the rule may be obsolete, and
   6903             #      if the source file does not exist also, we should simply
   6904             #      not run the rule, but not set an error condition.
   6905             #      Any error will arise at the (pdf)latex level due to a 
   6906             #      missing source file at that level.
   6907             if ( $$Psource && (! -e $$Psource)
   6908 # OLD                && ( ( $$Pcmd_type eq 'cusdep') )
   6909 # NEW
   6910                  && ( ( $$Pcmd_type ne 'primary') )
   6911                ) {
   6912                 # Main source file doesn't exist, and rule is NOT primary.
   6913                 # No action, since a run is pointless.  Primary is different:
   6914                 # file might be found elsewhere (by kpsearch from (pdf)latex),
   6915                 # while non-existence of main source file is a clear error.
   6916             }
   6917             elsif ( $$Pcmd_type eq 'delegated' ) {
   6918                 # Delegate to destination rule
   6919             }
   6920             elsif ( $pass{$rule}==0) {
   6921                 push @no_dest, $$Pdest;
   6922                 $$Pout_of_date = 1;
   6923             }
   6924             if ( $$Pcmd_type eq 'primary' ) {
   6925                 $missing_dvi_pdf = $$Pdest;
   6926             }
   6927         }
   6928     }
   6929 
   6930     &rdb_flag_changes_here(0);
   6931 
   6932     if (!$$Pout_of_date) {
   6933 #??     if ( ($$Pcmd_type eq 'primary') && (! $silent) ) {
   6934 #            print "Rule '$rule' up to date\n";
   6935 #        }
   6936         return;
   6937     }
   6938     if ($diagnostics) { print "     remake\n"; }
   6939     if (!$silent) { 
   6940         print "$My_name: applying rule '$rule'...\n"; 
   6941         &rdb_diagnose_changes( "Rule '$rule': " );
   6942     }
   6943 
   6944     # We are applying the rule, so its source file state for when it
   6945     # was last made is as of now:
   6946     # ??IS IT CORRECT TO DO NOTHING IN CURRENT VERSION?
   6947 
   6948     # The actual run
   6949     my $return = 0;   # Return code from called routine
   6950     # Rule may have been created since last run:
   6951     if ( ! defined $pass{$rule} ) {$pass{$rule} = 0; }
   6952     if ( $pass{$rule} >= $max_repeat ) {
   6953         # Avoid infinite loop by having a maximum repeat count
   6954         # Getting here represents some kind of weird error.
   6955         warn "$My_name: Maximum runs of $rule reached ",
   6956              "without getting stable files\n";
   6957         $too_many_passes = 1;
   6958         # Treat rule as completed, else in -pvc mode get infinite reruns:
   6959         $$Pout_of_date = 0;
   6960         $failure = 1;
   6961         $failure_msg = "'$rule' needed too many passes";
   6962         return;
   6963     }
   6964 
   6965     $rules_applied{$rule} = 1;
   6966     $runs++;
   6967 
   6968     $pass{$rule}++; 
   6969     if ($bibtex_not_run > 0) {
   6970         if ($bibtex_not_run == 1 ) {
   6971             show_array ("$My_name: I WON'T RUN '$rule' because I don't find the following files:",
   6972                         @missing_bib_files);
   6973         }
   6974         elsif ($bibtex_not_run == 2 ) {
   6975             warn "$My_name: I AM CONFIGURED/INVOKED NOT TO RUN '$rule'\n"; 
   6976         }
   6977         $return = &rdb_dummy_run1;
   6978     }
   6979     else {
   6980         warn_running( "Run number $pass{$rule} of rule '$rule'" );
   6981         if ($$Pcmd_type eq 'primary' ) { 
   6982             $return = &rdb_primary_run;
   6983         }
   6984         else { $return = &rdb_run1; }
   6985     }
   6986     if ($$Pchanged) {
   6987         $newrule_nofile = 1;
   6988         $return = 0;
   6989     }
   6990     elsif ( $$Pdest && ( !-e $$Pdest ) && (! $failure) ){
   6991         # If there is a destination to make, but for some reason
   6992         #    it did not get made, and no other error was reported, 
   6993         #    then a priori there appears to be an error condition:
   6994         #    the run failed.   But there are some important cases in
   6995         #    which this is a wrong diagnosis.
   6996         if ( ( $$Pcmd_type eq 'cusdep') && $$Psource && (! -e $$Psource) ) {
   6997             # However, if the rule is a custom dependency, this is not by
   6998             #  itself an error, if also the source file does not exist.  In 
   6999             #  that case, we may have the situation that (1) the dest file is no
   7000             #  longer needed by the tex file, and (2) therefore the user
   7001             #  has deleted the source and dest files.  After the next
   7002             #  latex run and the consequent analysis of the log file, the
   7003             #  cusdep rule will no longer be needed, and will be removed.
   7004 
   7005             # So in this case, do NOT report an error          
   7006             $$Pout_of_date = 0;
   7007         }
   7008         elsif ($$Pcmd_type eq 'primary' ) { 
   7009             # For a primary rule, i.e., (pdf)latex, not to produce the 
   7010             #    expected output file may not be an error condition.  
   7011             # Diagnostics were handled in parsing the log file.
   7012             # Special action in main loop in rdb_make
   7013             $missing_dvi_pdf = $$Pdest;
   7014         }
   7015         elsif ($return == -2) {
   7016            # Missing output file was reported to be NOT an error
   7017            $$Pout_of_date = 0;
   7018         }
   7019         elsif ( ($bibtex_use <= 1.5) && ($bibtex_not_run > 0) ) {
   7020            # Lack of destination file is not to be treated as an error
   7021            # for a bibtex rule when latexmk is configured not to treat
   7022            # this as an error, and the lack of a destination file is the
   7023            # only error.
   7024            $$Pout_of_date = 0;
   7025         }
   7026         else {
   7027             $failure = 1;
   7028         }
   7029     }
   7030     if ( ($return != 0) && ($return != -2) ) {
   7031         $failure = 1; 
   7032         $$Plast_result = 2;
   7033         if ( !$$Plast_message ) {
   7034             $$Plast_message = "Run of rule '$rule' gave a non-zero error code";
   7035         }
   7036 # !!??        $failure_msg = $$Plast_message;
   7037         
   7038     }
   7039 }  #END rdb_make1
   7040 
   7041 #************************************************************
   7042 
   7043 #??sub rdb_submake {
   7044 #??    # Call: rdb_submake
   7045 #??    # Makes all the source files for a given rule.
   7046 #??    # Assumes contexts for recursion, for make, and rule.
   7047 #??    %visited = %visited_at_rule_start;
   7048 #??    local $failure = 0;  # Error flag
   7049 #??    my @v = keys %visited;
   7050 #??    rdb_do_files( sub{ rdb_recurse_rule( $$Pfrom_rule, 0,0,0, \&rdb_make1 ) } );
   7051 #??    return $failure;
   7052 #??}  #END rdb_submake
   7053 
   7054 #************************************************************
   7055 
   7056 sub rdb_classify_rules {
   7057     # Usage: rdb_classify_rules( \%allowed_primaries, requested targets )
   7058     # Assume the following variables are available (global or local):
   7059     # Input:
   7060     #    @requested_targets    # Set to target rules
   7061     
   7062     # Output:
   7063     #    %current_primaries    # Keys are actual primaries
   7064     #    @pre_primary          # Array of rules
   7065     #    @post_primary         # Array of rules
   7066     #    @unusual_one_time     # Array of rules
   7067     # @pre_primary and @post_primary are in natural order of application.
   7068 
   7069     local $P_allowed_primaries = shift;
   7070     local @requested_targets = @_;
   7071     local $state = 0;       # Post-primary
   7072     local @classify_stack = ();
   7073 
   7074     %current_primaries = ();
   7075     @pre_primary = ();
   7076     @post_primary = ();
   7077     @unusual_one_time = ();
   7078 
   7079     rdb_recurse( \@requested_targets, \&rdb_classify1, 0,0, \&rdb_classify2 );
   7080 
   7081     # Reverse, as tendency is to find last rules first.
   7082     @pre_primary = reverse @pre_primary;
   7083     @post_primary = reverse @post_primary;
   7084 
   7085     if ($diagnostics) {
   7086         print "Rule classification: \n";
   7087         if ($#requested_targets < 0) {
   7088             print "  No requested rules\n";
   7089         }
   7090         else {
   7091             print "  Requested rules:\n";
   7092             foreach ( @requested_targets ) { print "    $_\n"; }
   7093         }
   7094         if ($#pre_primary < 0) {
   7095             print "  No pre-primaries\n";
   7096         }
   7097         else {
   7098             print "  Pre-primaries:\n";
   7099             foreach (@pre_primary) { print "    $_\n"; }
   7100         }
   7101         print "  Primaries:\n";
   7102         foreach (keys %current_primaries) { print "    $_\n"; }
   7103         if ($#post_primary < 0) {
   7104             print "  No post-primaries\n";
   7105         }
   7106         else {
   7107             print "  Post-primaries:\n";
   7108             foreach (@post_primary) { print "    $_\n"; }
   7109         }
   7110         if ($#unusual_one_time < 0) {
   7111             print "  No inner-level one_time rules, as expected\n";
   7112         }
   7113         else {
   7114             print "  Inner-level one_time rules:\n";
   7115             foreach ( @unusual_one_time ) { print "    $_\n"; }
   7116         }
   7117         my @normal_one_time = keys %one_time;
   7118         if ($#normal_one_time < 0) {
   7119             print "  No outer-level one_time rules\n";
   7120         }
   7121         else {
   7122             print "  Outer-level one_time rules:\n";
   7123             foreach ( @normal_one_time ) { print "    $_\n"; }
   7124         }
   7125     } #end diagnostics
   7126 
   7127 } #END rdb_classify_rules
   7128 
   7129 #-------------------
   7130 
   7131 sub rdb_classify1 {
   7132     # Helper routine for rdb_classify_rules
   7133     # Applied as rule_act1 in recursion over rules
   7134     # Assumes rule context, and local variables from rdb_classify_rules
   7135     push @classify_stack, [$state];
   7136     if ( exists $possible_one_time{$rule} ) {
   7137         # Normally, we will have already extracted the one_time rules,
   7138         # and they will never be accessed here.  But just in case of
   7139         # problems or generalizations, we will cover all possibilities:
   7140         if ($depth > 1) {
   7141            warn "ONE TIME rule not at outer level '$rule'\n";
   7142         }
   7143         push @unusual_one_time, $rule;
   7144     }
   7145     elsif ($state == 0) {
   7146        if ( exists ${$P_allowed_primaries}{$rule} ) {
   7147            $state = 1;   # In primary rule
   7148            $current_primaries{ $rule } = 1;
   7149        }
   7150        else {
   7151            push @post_primary, $rule;
   7152        }
   7153     }
   7154     else {
   7155         $state = 2;     # in post-primary rule
   7156         push @pre_primary, $rule;
   7157     }
   7158 } #END rdb_classify1
   7159 
   7160 #-------------------
   7161 
   7162 sub rdb_classify2 {
   7163     # Helper routine for rdb_classify_rules
   7164     # Applied as rule_act2 in recursion over rules
   7165     # Assumes rule context
   7166     ($state) = @{ pop @classify_stack };
   7167 } #END rdb_classify2
   7168 
   7169 #************************************************************
   7170 
   7171 
   7172 sub rdb_run1 {
   7173     # Assumes contexts for: rule.
   7174     # Unconditionally apply the rule
   7175     # Returns return code from applying the rule.
   7176     # Otherwise: 0 on other kind of success, 
   7177     #            -1 on error, 
   7178     #            -2 when missing dest_file is to be ignored
   7179 
   7180     # Source file data, by definition, correspond to the file state just
   7181     # before the latest run, and the run_time to the time just before the run:
   7182     &rdb_update_files;
   7183     $$Prun_time = time();
   7184     $$Pchanged = 0;       # No special changes in files
   7185     $$Plast_result = 0;
   7186     $$Plast_message = '';
   7187 
   7188     # Return values for external command:
   7189     my $return = 0;
   7190 
   7191     # Find any internal command
   7192     my @int_args = @$PAint_cmd;
   7193     my $int_cmd = shift @int_args;
   7194     my @int_args_for_printing = @int_args;
   7195     foreach (@int_args_for_printing) {
   7196         if ( ! defined $_ ) { $_ = 'undef'; }
   7197     }
   7198     if ($int_cmd) {
   7199         print "For rule '$rule', running '\&$int_cmd( @int_args_for_printing )' ...\n";
   7200         $return = &$int_cmd( @int_args ); 
   7201     }
   7202     elsif ($$Pext_cmd) {
   7203         $return = &Run_subst() / 256;
   7204     }
   7205     else {
   7206         warn "$My_name: Either a bug OR a configuration error:\n",
   7207              "    No command provided for '$rule'\n";
   7208         &traceback();
   7209         $return = -1;
   7210         $$Plast_result = 2;
   7211         $$Plast_message = "Bug or configuration error; incorrect command type";
   7212     }
   7213     if ( $rule =~ /^biber/ ) {
   7214         my @biber_source = ( );
   7215         my $retcode = check_biber_log( $$Pbase, \@biber_source );
   7216         foreach my $source ( @biber_source ) {
   7217 #	    if ( $source =~ /\"/ ) {next; }
   7218             print "  ===Source file '$source' for '$rule'\n"
   7219                if ($diagnostics);
   7220             rdb_ensure_file( $rule, $source );
   7221         }
   7222         if ($retcode == 5) {
   7223         # Special treatment if sole missing file is bib file
   7224         # I don't want to treat that as an error
   7225             $return = 0;
   7226             $$Plast_result = 200;
   7227             $$Plast_message = "Could not find bib file for '$$Pbase'";
   7228             push @warnings, "Bib file not found for '$$Pbase'";
   7229         }
   7230         elsif ($retcode == 6) {
   7231            # Missing control file.  Need to remake it (if possible)
   7232            # Don't treat missing bbl file as error.
   7233            warn "$My_name: bibtex control file missing.  Since that can\n",
   7234                 "   be recreated, I'll try to do so.\n";
   7235            $return = -2;
   7236            rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
   7237         }
   7238         elsif ($retcode == 4) {
   7239             $$Plast_result = 2;
   7240             $$Plast_message = "Could not find all biber source files for '$$Pbase'";
   7241             push @warnings, "Not all biber source files found for '$$Pbase'";
   7242         }
   7243         elsif ($retcode == 3) {
   7244             $$Plast_result = 2;
   7245             $$Plast_message = "Could not open biber log file for '$$Pbase'";
   7246             push @warnings, $$Plast_message;
   7247         }
   7248         elsif ($retcode == 2) {
   7249             $$Plast_message = "Biber errors: See file '$$Pbase.blg'";
   7250             push @warnings, $$Plast_message;
   7251         }
   7252         elsif ($retcode == 1) {
   7253             push @warnings, "Biber warnings for '$$Pbase'";
   7254         }
   7255         elsif ($retcode == 10) {
   7256             push @warnings, "Biber found no citations for '$$Pbase'";
   7257             # Biber doesn't generate a bbl file in this situation.
   7258             $return = -2;
   7259         }
   7260         elsif ($retcode == 11) {
   7261             push @warnings, "Biber: malformed bcf file for '$$Pbase'.  IGNORE";
   7262 	    if (!$silent) {
   7263                warn "$My_name: biber found malformed bcf file for '$$Pbase'.\n",
   7264    	            "  I'll ignore error, and delete any bbl file.\n";
   7265 	    }
   7266 	    # Malformed bcf file is a downstream consequence, normally,
   7267             # of an error in (pdf)latex run.  So this is not an error
   7268 	    # condition in biber itself.
   7269 	    # Current version of biber deletes bbl file.
   7270 	    # Older versions (pre-2016) made an incorrect bbl file, which
   7271             # tended to cause latex errors, and give a self-perpetuating error.
   7272 	    # To be safe, ensure the bbl file doesn't exist.
   7273 	    unlink $$Pdest;
   7274 	    # The missing bbl file is now not an error:
   7275             $return = -2;
   7276 # ??????? BCF
   7277 # Following is intended to work, but creates infinite loop
   7278 # in malformed bcf file situation under -pvc.
   7279 # since on each check for change in ANY	file, pvc finds changed file
   7280 # Need to restrict pvc reruns to case of changed USER files
   7281 #	    # To give good properties for (pdf)latex rule, it is best
   7282 #	    # to have a valid bbl file that exists:
   7283 #	    create_empty_file( $$Pdest );
   7284 #            $return = 0;
   7285 	    
   7286         }
   7287     }
   7288     if ( $rule =~ /^bibtex/ ) {
   7289         my $retcode = check_bibtex_log($$Pbase);
   7290         if ( ! -e $$Psource ) {
   7291             $retcode = 10;
   7292             rdb_for_some( [keys %current_primaries], sub{ $$Pout_of_date = 1; } );
   7293         }
   7294         if ($retcode == 3) {
   7295             $$Plast_result = 2;
   7296             $$Plast_message = "Could not open bibtex log file for '$$Pbase'";
   7297             push @warnings, $$Plast_message;
   7298         }
   7299         elsif ($retcode == 2) {
   7300             $$Plast_message = "Bibtex errors: See file '$$Pbase.blg'";
   7301             $failure = 1;
   7302             push @warnings, $$Plast_message;
   7303         }
   7304         elsif ($retcode == 1) {
   7305             push @warnings, "Bibtex warnings for '$$Pbase'";
   7306         }
   7307         elsif ($retcode == 10) {
   7308             push @warnings, "Bibtex found no citations for '$$Pbase',\n",
   7309                             "    or bibtex found a missing aux file\n";
   7310             if (! -e $$Pdest ) {
   7311                 warn "$My_name: Bibtex did not produce '$$Pdest'.  But that\n",
   7312                      "     was because of missing files, so I will continue.\n";
   7313                 $return = -2;
   7314             }
   7315             else {
   7316                 $return = 0;
   7317             }
   7318         }
   7319     }
   7320 
   7321     $updated = 1;
   7322     if ($$Ptest_kind == 3) { 
   7323         # We are time-criterion first time only.  Now switch to
   7324         # file-change criterion
   7325         $$Ptest_kind = 1; 
   7326     }
   7327     $$Pout_of_date = $$Pout_of_date_user = 0;
   7328 
   7329     if ( ($$Plast_result == 0) && ($return != 0) && ($return != -2) ) {
   7330         $$Plast_result = 2;
   7331         if ($$Plast_message eq '') {
   7332             $$Plast_message = "Command for '$rule' gave return code $return";
   7333 	    if ($rule =~ /^(pdf|lua|xe|)latex/) {
   7334 		$$Plast_message .= "\n      Refer to '$log_name' for details";
   7335 	    }
   7336             elsif ($rule =~ /^makeindex/) {
   7337 		$$Plast_message .= "\n      Refer to '${aux_dir1}${root_filename}.ilg' for details";
   7338 	    }
   7339         }
   7340     }
   7341     elsif ( $$Pdest && (! -e $$Pdest) && ($return != -2) ) {
   7342         $$Plast_result = 1;
   7343     }
   7344     return $return;
   7345 }  # END rdb_run1
   7346 
   7347 #-----------------
   7348 
   7349 sub rdb_dummy_run1 {
   7350     # Assumes contexts for: rule.
   7351     # Update rule state as if the rule ran successfully,
   7352     #    but don't run the rule.
   7353     # Returns 0 (success code)
   7354 
   7355     # Source file data, by definition, correspond to the file state just before 
   7356     # the latest run, and the run_time to the time just before the run:
   7357     &rdb_update_files;
   7358     $$Prun_time = time();
   7359     $$Pchanged = 0;       # No special changes in files
   7360     $$Plast_result = 0;
   7361     $$Plast_message = '';
   7362 
   7363     if ($$Ptest_kind == 3) { 
   7364         # We are time-criterion first time only.  Now switch to
   7365         # file-change criterion
   7366         $$Ptest_kind = 1; 
   7367     }
   7368     $$Pout_of_date = $$Pout_of_date_user = 0;
   7369 
   7370     return 0;
   7371 }  # END rdb_dummy_run1
   7372 
   7373 #-----------------
   7374 
   7375 sub Run_subst {
   7376     # Call: Run_subst( cmd, msg, options, source, dest, base )
   7377     # Runs command with substitutions.
   7378     # If an argument is omitted or undefined, it is replaced by a default:
   7379     #    cmd is the command to execute
   7380     #    msg is whether to print a message: 
   7381     #           0 for not, 1 according to $silent setting, 2 always
   7382     #    options, source, dest, base: correspond to placeholders.
   7383     # Substitutions:
   7384     #    %S=source, %D=dest, %B=base, %R=root=base for latex, %O=options, 
   7385     #    %T=texfile, %Y=$aux_dir1, %Z=$out_dir1
   7386     # This is a globally usable subroutine, and works in a rule context,
   7387     #    and outside.
   7388     # Defaults:
   7389     #     cmd: $PPext_cmd if defined, else '';
   7390     #     msg: 1
   7391     #     options: ''
   7392     #     source:  $$Psource if defined, else $texfile_name;
   7393     #     dest:    $$Pdest if defined, else $view_file, else '';
   7394     #     base:    $$Pbase if defined, else $root_filename;
   7395 
   7396     my ($ext_cmd, $msg, $options, $source, $dest, $base ) = @_;
   7397 
   7398     $ext_cmd ||= ( $Pext_cmd ? $$Pext_cmd : '' );
   7399     $msg     =   ( defined $msg ? $msg : 1 );
   7400     $options ||= '';
   7401     $source  ||= ( $Psource ? $$Psource : $texfile_name );
   7402     $dest    ||= ( $Pdest ? $$Pdest : ( $view_file || '' ) );
   7403     $base    ||= ( $Pbase ? $$Pbase : $root_filename );
   7404 
   7405     if ( $ext_cmd eq '' ) {
   7406          return 0;
   7407     }
   7408 
   7409     #Set character to surround filenames:
   7410     my $q = $quote_filenames ? '"' : '';
   7411 
   7412     my %subst = ( 
   7413        '%B' => $q.$base.$q,
   7414        '%D' => $q.$dest.$q,
   7415        '%O' => $options,
   7416        '%S' => $q.$source.$q,
   7417        '%R' => $q.$root_filename.$q,
   7418        '%S' => $q.$source.$q,
   7419        '%T' => $q.$texfile_name.$q,
   7420        '%Y' => $q.$aux_dir1.$q,
   7421        '%Z' => $q.$out_dir1.$q,
   7422        '%%' => '%'         # To allow literal %B, %R, etc, by %%B.
   7423 	);
   7424     if ($pre_tex_code) {
   7425 	$subst{'%U'} = $q.$pre_tex_code.$q;
   7426 	$subst{'%P'} = "$q$pre_tex_code\\input{$source}$q";
   7427     }
   7428     else {
   7429 	$subst{'%U'} = '';
   7430 	$subst{'%P'} = $subst{'%S'};
   7431     }
   7432     if ( ($^O eq "MSWin32" ) && $MSWin_back_slash ) {
   7433         foreach ( '%R', '%B', '%T', '%S', '%D', '%Y', '%Z' ) {
   7434             $subst{$_} =~ s(/)(\\)g;
   7435         }
   7436     }
   7437 
   7438     my @tokens = split /(%.)/, $ext_cmd;
   7439     foreach (@tokens) {
   7440         if (exists($subst{$_})) { $_ = $subst{$_}; }
   7441     }
   7442     $ext_cmd = join '', @tokens;
   7443 
   7444     my ($pid, $return) = 
   7445           ( ($msg == 0) || ( ($msg == 1) && $silent ) )
   7446              ? &Run($ext_cmd)
   7447              : &Run_msg($ext_cmd);
   7448     return $return;
   7449 } #END Run_subst
   7450 
   7451 #-----------------
   7452 
   7453 sub rdb_primary_run {
   7454 #?? See multipass_run in previous version Aug 2007 for issues
   7455     # Call: rdb_primary_run
   7456     # Assumes contexts for: recursion, make, & rule.
   7457     # Assumes (a) the rule is a primary, 
   7458     #         (b) a run has to be made,
   7459     #         (c) source files have been made.
   7460     # This routine carries out the run of the rule unconditionally,
   7461     # and then parses log file etc.
   7462     my $return = 0;
   7463 
   7464     if ( ! $filetime_offset_measured ) {
   7465 	$filetime_offset = get_filetime_offset( $aux_dir1."tmp" );
   7466 	if ( (abs($filetime_offset) > $filetime_offset_report_threshold)
   7467              && ($diagnostics || ! $silent) )
   7468         {
   7469 	    warn "$My_name: I am working around an offset relative to my system time by\n",
   7470                  "   $filetime_offset secs for file times in directory '$aux_dir1'.\n";
   7471 	}
   7472 	$filetime_offset_measured = 1;
   7473     }
   7474 
   7475     my $return_latex = &rdb_run1;
   7476 
   7477     # Need to worry about changed directory, changed output extension
   7478     # Where else is $missing_dvi_pdf set?  Was it initialized?
   7479     if (-e $$Pdest) { $missing_dvi_pdf = '';}
   7480 
   7481     # Handle case that log file is caused to be in an unexpected place,
   7482     #   from a configuration error:
   7483     &find_set_log;
   7484 
   7485     if ($recorder) {
   7486         # Handle problem that some version of (pdf)latex give fls files
   7487         #    of name latex.fls or pdflatex.fls instead of $root_filename.fls.
   7488         # Also that setting of -output-directory -aux-directory is not 
   7489         #    respected by (pdf)latex, at least in some versions.
   7490         my $std_fls_file = "$aux_dir1$root_filename.fls";
   7491         my @other_fls_names = ( );
   7492         if ( $rule =~ /^pdflatex/ ) {
   7493             push @other_fls_names, "pdflatex.fls";
   7494         }
   7495         else {
   7496             push @other_fls_names, "latex.fls";
   7497         }
   7498         if ( $aux_dir1 ne '' ) {
   7499            push @other_fls_names, "$root_filename.fls";
   7500         }
   7501         # Find the first non-standard fls file and copy it to the standard
   7502         # place. But only do this if the file time is compatible with being
   7503         # generated in the current run, as tested by the use of
   7504         # test_gen_file; that avoids problems with fls files leftover from
   7505         # earlier runs with other versions of latex.
   7506         foreach my $cand (@other_fls_names) {
   7507             if ( test_gen_file( $cand ) ) {
   7508                 copy $cand, $std_fls_file;
   7509                 last;
   7510             }
   7511         }
   7512         if ( ! test_gen_file( $std_fls_file ) ) {
   7513             warn "$My_name: fls file doesn't appear to have been made.\n";
   7514         }
   7515     }
   7516 
   7517     # Find current set of source files:
   7518     &rdb_set_latex_deps;
   7519 
   7520     # For each file of the kind made by epstopdf.sty during a run, 
   7521     #   if the file has changed during a run, then the new version of
   7522     #   the file will have been read during the run.  Unlike the usual
   7523     #   case, we will NOT need to redo the primary run because of the
   7524     #   change of this file during the run.  Therefore set the file as
   7525     #   up-to-date:
   7526     rdb_do_files( sub { if ($$Pcorrect_after_primary) {&rdb_update1;} } );
   7527 
   7528 #??    # There may be new source files, and the run may have caused
   7529 #??    # circular-dependency files to be changed.  And the regular
   7530 #??    # source files may have been updated during a lengthy run of
   7531 #??    # latex.  So redo the makes for sources of the current rule:
   7532 #??    my $submake_return = &rdb_submake;
   7533 #??    &rdb_clear_change_record;
   7534 #??    &rdb_flag_changes_here(0);
   7535 #??    if ($$Pout_of_date && !$silent) { 
   7536 #??        &rdb_diagnose_changes( "Rule '$rule': " );
   7537 #??    }
   7538 
   7539     $updated = 1;    # Flag that some dependent file has been remade
   7540 
   7541 #??    # Fix the state of the files as of now: this will solve the
   7542 #??    # problem of latex and pdflatex interfering with each other,
   7543 #??    # at the expense of some non-optimality
   7544 #??    #??  Check this is correct:
   7545 #??    &rdb_update_files;
   7546 
   7547     if ( $diagnostics ) {
   7548         print "$My_name: Rules after run: \n";
   7549         rdb_show();
   7550     }
   7551 
   7552     $return = $return_latex;
   7553 
   7554 # ???? Is the following needed?
   7555     if ($return_latex && $$Pout_of_date_user) {
   7556        print "Error in (pdf)LaTeX, but change of user file(s), ",
   7557              "so ignore error & provoke rerun\n"
   7558           if (! $silent);
   7559        $return = 0;
   7560     }
   7561     # Summarize issues that may have escaped notice:
   7562     @primary_warning_summary = ();
   7563     if ($bad_reference) {
   7564         push @primary_warning_summary,
   7565              "Latex failed to resolve $bad_reference reference(s)";
   7566     }
   7567     if ($mult_defined) {
   7568         push @primary_warning_summary,
   7569              "Latex found $mult_defined multiply defined reference(s)";
   7570     }
   7571     if ($bad_character) {
   7572         push @primary_warning_summary,
   7573 	    "=====Latex reported missing or unavailable character(s).\n".
   7574 	    "=====See log file for details.";
   7575     }
   7576     if ($bad_citation) {
   7577         push @primary_warning_summary,
   7578              "Latex failed to resolve $bad_citation citation(s)";
   7579     }
   7580     if ( $diagnostics && ($#primary_warning_summary > -1) ) {
   7581        show_array( "$My_name: Summary of warnings:", @primary_warning_summary );
   7582     }
   7583     return $return;
   7584 } #END rdb_primary_run
   7585 
   7586 #************************************************************
   7587 
   7588 sub rdb_clear_change_record {
   7589     # Initialize diagnostics for reasons for running rule.
   7590     @changed = ();
   7591     @disappeared = ();
   7592     @no_dest = ();          # We are not now using this
   7593     @rules_never_run = ();
   7594     @rules_to_apply = ();   # This is used in recursive application
   7595                             # of rdb_flag_changes_here, to list
   7596                             # rules that were out-of-date for some reason.
   7597 } #END rdb_clear_change_record 
   7598 
   7599 #************************************************************
   7600 
   7601 sub rdb_flag_changes_here {
   7602     # Flag changes in current rule.  
   7603     # Assumes rule context.
   7604     # Usage: rdb_flag_changes_here( ignore_run_time )
   7605     # Argument: if true then fdb_get shouldn't do runtime test
   7606     #             for recalculation of md5
   7607 
   7608     local $ignore_run_time = $_[0];
   7609     if ( ! defined $ignore_run_time ) { $ignore_run_time = 0; }
   7610 
   7611     $$Pcheck_time = time();
   7612 
   7613     local $dest_mtime = 0;
   7614     $dest_mtime = get_mtime($$Pdest) if ($$Pdest);
   7615     rdb_do_files( \&rdb_file_change1);
   7616     if ($$Pout_of_date) {
   7617         push @rules_to_apply, $rule;
   7618     }
   7619 #??     print "======== flag: $rule $$Pout_of_date ==========\n";
   7620 } #END rdb_flag_changes_here
   7621 
   7622 #************************************************************
   7623 
   7624 sub rdb_file_change1 {
   7625     # Call: &rdb_file_change1
   7626     # Assumes rule and file context.  Assumes $dest_mtime set.
   7627     # Flag whether $file in $rule has changed or disappeared.
   7628     # Set rule's make flag if there's a change.
   7629 
   7630     my $check_time_argument = 0;
   7631     if (! $ignore_run_time ) {
   7632         $check_time_argument = max( $$Pcheck_time, $$Prun_time );
   7633     }
   7634     my ($new_time, $new_size, $new_md5) = fdb_get($file, $check_time_argument );
   7635     my $ext_no_period = ext_no_period( $file );
   7636     if ( ($new_size < 0) && ($$Psize >= 0) ) {
   7637         # print "Disappeared '$file' in '$rule'\n";
   7638         push @disappeared, $file;
   7639         # No reaction is good.  
   7640         #$$Pout_of_date = 1;
   7641         # ??? 1 Sep. 2008: I do NOT think so, for cusdep no-file-exists issue
   7642         # ??? 30 Sep 2008: I think I have this fixed.  There were other changes
   7643         #  needed.  No-change-flagged is correct.  The array @disappeared flags 
   7644         #  files that have disappeared, if I need to know.  But having a source
   7645         #  file disappear is not a reason for a remake unless I know how to 
   7646         #  make the file.  If the file is a destination of a rule, that rule
   7647         #  will be rerun.  It may be that the user is changing another source 
   7648         #  in such a way that the disappeared file won't be needed.  Before the
   7649         #  change is applied we get a superfluous infinite loop.
   7650         return;
   7651     }
   7652     if ( ($new_size < 0) && ($$Psize < 0) ) {
   7653         return;
   7654     }
   7655     # Primarily use md5 signature to determine whether file contents have
   7656     #   changed.
   7657     # Backup by file size change, but only in the case where there is
   7658     #   no pattern of lines to ignore in testing for a change
   7659     if ( ($new_md5 ne $$Pmd5) 
   7660          || (
   7661               (! exists $hash_calc_ignore_pattern{$ext_no_period})
   7662               && ($new_size != $$Psize)   
   7663             )
   7664        ) {
   7665 #print "========= CHANGED: '$file' from '$$Pfrom_rule'\n";
   7666         push @changed, $file;
   7667         $$Pout_of_date = 1;
   7668         if ( ! exists $generated_exts_all{$ext_no_period} ) {
   7669             $$Pout_of_date_user = 1;
   7670         }
   7671     }
   7672     elsif ( $new_time != $$Ptime ) {
   7673         $$Ptime = $new_time;
   7674     }
   7675     if ( ( ($$Ptest_kind == 2) || ($$Ptest_kind == 3) )
   7676          && (! exists $generated_exts_all{$ext_no_period} )
   7677          && ( $new_time > $dest_mtime )
   7678         ) {
   7679             push @changed, $file;
   7680             $$Pout_of_date = $$Pout_of_date_user = 1;
   7681     }
   7682 } #END rdb_file_change1
   7683 
   7684 #************************************************************
   7685 
   7686 sub rdb_new_changes {
   7687     &rdb_clear_change_record;
   7688     rdb_recurse( [@_], sub{ &rdb_flag_changes_here(1); } );
   7689     return ($#changed >= 0) || ($#no_dest >= 0) || ($#rules_to_apply >= 0);
   7690 } #END rdb_new_changes
   7691 
   7692 #************************************************************
   7693 
   7694 sub rdb_diagnose_changes {
   7695     # Call: rdb_diagnose_changes or rdb_diagnose_changes( heading )
   7696     # List changes on STDERR
   7697     # Precede the message by the optional heading, else by "$My_name: " 
   7698     my $heading = defined($_[0]) ?   $_[0]  :  "$My_name: "; 
   7699 
   7700     if ($#rules_never_run >= 0) {
   7701         warn "${heading}Rules & subrules not known to be previously run:\n";
   7702         foreach (@rules_never_run) { warn "   $_\n"; }
   7703     }
   7704     if ( ($#changed >= 0) || ($#disappeared >= 0) || ($#no_dest >= 0) ) {
   7705         warn "${heading}File changes, etc:\n";
   7706         if ( $#changed >= 0 ) {
   7707             warn "   Changed files, or newly in use since previous run(s):\n";
   7708             foreach (uniqs(@changed)) { warn "      '$_'\n"; }
   7709         }
   7710         if ( $#disappeared >= 0 ) {
   7711             warn "   No-longer-existing files:\n";
   7712             foreach (uniqs(@disappeared)) { warn "      '$_'\n"; }
   7713         }
   7714         if ( $#no_dest >= 0 ) {
   7715             warn "   Non-existent destination files:\n";
   7716             foreach (uniqs(@no_dest)) { warn "      '$_'\n"; }
   7717         }
   7718     }
   7719     elsif ($#rules_to_apply >=0) {
   7720          warn "${heading}The following rules & subrules became out-of-date:\n";
   7721          foreach (@rules_to_apply) { warn "      '$_'\n"; }
   7722     }
   7723     else {
   7724         warn "${heading}No file changes\n";
   7725     }
   7726 }     #END rdb_diagnose_changes
   7727 
   7728 
   7729 #************************************************************
   7730 #************************************************************
   7731 #************************************************************
   7732 #************************************************************
   7733 
   7734 #************************************************************
   7735 #************************************************************
   7736 #************************************************************
   7737 #************************************************************
   7738 
   7739 # Routines for convenient looping and recursion through rule database
   7740 # ================= NEW VERSION ================
   7741 
   7742 # There are several places where we need to loop through or recurse
   7743 # through rules and files.  This tends to involve repeated, tedious
   7744 # and error-prone coding of much book-keeping detail.  In particular,
   7745 # working on files and rules needs access to the variables involved,
   7746 # which either involves direct access to the elements of the database,
   7747 # and consequent fragility against changes and upgrades in the
   7748 # database structure, or involves lots of routines for reading and
   7749 # writing data in the database, then with lots of repetitious
   7750 # house-keeping code.
   7751 #
   7752 # The routines below provide a solution.  Looping and recursion
   7753 # through the database are provided by a set of basic routines where
   7754 # each necessary kind of looping and iteration is coded once.  The
   7755 # actual actions are provided as references to action subroutines.
   7756 # (These can be either actual references, as in \&routine, or
   7757 # anonymous subroutines, as in sub{...}, or aas a zero value 0 or an
   7758 # omitted argument, to indicate that no action is to be performed.)
   7759 #
   7760 # When the action subroutine(s) are actually called, a context for the
   7761 # rule and/or file (as appropriate) is given by setting named
   7762 ## NEW ??
   7763 # variables to REFERENCES to the relevant data values.  These can be
   7764 # used to retrieve and set the data values.  As a convention,
   7765 # references to scalars are given by variables named start with "$P",
   7766 # as in "$Pdest", while references to arrays start with "$PA", as in 
   7767 # "$PAint_cmd", and references to hashes with "$PH", as in "$PHsource".
   7768 # After the action subroutine has finished, checks for data
   7769 # consistency may be made. 
   7770 ## ??? OLD
   7771 # variables to the relevant data values.  After the action subroutine
   7772 # has finished, the database is updated with the values of these named
   7773 # variables, with any necessary consistency checks.  Thus the action
   7774 # subroutines can act on sensibly named variables without needed to
   7775 # know the database structure.  
   7776 #
   7777 # The only routines that actually use the database structure and need
   7778 # to be changed if that is changed are:  (a) the routines rdb_one_rule
   7779 # and rdb_one_file that implement the calling of the action subroutines,
   7780 # (b) routines for creation of single rules and file items, and (c) to
   7781 # a lesser extent, the routine for destroying a file item.  
   7782 #
   7783 # Note that no routine is provided for destroying a rule.  During a
   7784 # run, a rule, with its source files, may become inaccessible or
   7785 # unused.  This happens dynamically, depending on the dependencies
   7786 # caused by changes in the source file or by error conditions that
   7787 # cause the computation of dependencies, particular of latex files, to
   7788 # become wrong.  In that situation the files certainly come and go in
   7789 # the database, but subsidiary rules, with their content information
   7790 # on their source files, need to be retained so that their use can be
   7791 # reinstated later depending on dynamic changes in other files.
   7792 #
   7793 # However, there is a potential memory leak unless some pruning is
   7794 # done in what is written to the fdb file.  (Probably only accessible
   7795 # rules and those for which source files exist.  Other cases have no
   7796 # relevant information that needs to be preserved between runs.)
   7797 
   7798 #
   7799 #
   7800 
   7801 
   7802 #************************************************************
   7803 
   7804 # First the top level routines for recursion and iteration
   7805 
   7806 #************************************************************
   7807 
   7808 sub rdb_recurse {
   7809     # Call: rdb_recurse( rule | [ rules],
   7810     #                    \&rule_act1, \&file_act1, \&file_act2, 
   7811     #                    \&rule_act2 )
   7812     # The actions are pointers to subroutines, and may be null (0, or
   7813     # undefined) to indicate no action to be applied.
   7814     # Recursively acts on the given rules and all ancestors:
   7815     #   foreach rule found:
   7816     #       apply rule_act1
   7817     #       loop through its files:
   7818     #          apply file_act1
   7819     #          act on its ancestor rule, if any
   7820     #          apply file_act2
   7821     #       apply rule_act2
   7822     # Guards against loops.  
   7823     # Access to the rule and file data by local variables, only
   7824     #   for getting and setting.
   7825 
   7826     # This routine sets a context for anything recursive, with @heads,
   7827     # %visited  and $depth being set as local variables.
   7828 
   7829     local @heads = ();
   7830     my $rules = shift;
   7831 
   7832     # Distinguish between single rule (a string) and a reference to an
   7833     # array of rules:
   7834     if ( ref $rules eq 'ARRAY' ) { @heads = @$rules; }
   7835     else { @heads = ( $rules ); }
   7836 
   7837     # Keep a list of visited rules, used to block loops in recursion:
   7838     local %visited = (); 
   7839     local $depth = 0;
   7840 
   7841     foreach $rule ( @heads ) { rdb_recurse_rule( $rule, @_ ); }
   7842 
   7843 } #END rdb_recurse
   7844 
   7845 #************************************************************
   7846 
   7847 sub rdb_for_all {
   7848     # Call: rdb_for_all( \&rule_act1, \&file_act, \&rule_act2 )
   7849     # Loops through all rules and their source files, using the 
   7850     #   specified set of actions, which are pointers to subroutines.
   7851     # Sorts rules alphabetically.
   7852     # See rdb_for_some for details.
   7853     rdb_for_some( [ sort keys %rule_db ], @_);
   7854 } #END rdb_for_all
   7855 
   7856 #************************************************************
   7857 
   7858 sub rdb_for_some {
   7859     # Call: rdb_for_some( rule | [ rules],
   7860     #                    \&rule_act1, \&file_act, \&rule_act2)
   7861     # Actions can be zero, and rules at tail of argument list can be
   7862     # omitted.  E.g. rdb_for_some( rule, 0, \&file_act ).  
   7863     # Anonymous subroutines can be used, e.g., rdb_for_some( rule, sub{...} ).  
   7864     #
   7865     # Loops through rules and their source files, using the 
   7866     # specified set of rules:
   7867     #   foreach rule:
   7868     #       apply rule_act1
   7869     #       loop through its files:
   7870     #          apply file_act
   7871     #       apply rule_act2
   7872     #
   7873     # Rule data and file data are made available in local variables 
   7874     # for access by the subroutines.
   7875 
   7876     local @heads = ();
   7877     my $rules = shift;
   7878     # Distinguish between single rule (a string) and a reference to an
   7879     # array of rules:
   7880     if ( ref $rules eq 'ARRAY' ) { @heads = @$rules; }
   7881     else { @heads = ( $rules ); }
   7882 
   7883     foreach $rule ( @heads ) {
   7884         # $rule is implicitly local
   7885         &rdb_one_rule( $rule, @_ );
   7886     }
   7887 }  #END rdb_for_some
   7888 
   7889 #************************************************************
   7890 
   7891 sub rdb_for_one_file {
   7892     my $rule = shift;
   7893     # Avoid name collisions with general recursion and iteraction routines:
   7894     local $file1 = shift;
   7895     local $action1 = shift;
   7896     rdb_for_some( $rule, sub{rdb_one_file($file1,$action1)} );
   7897 } #END rdb_for_one_file
   7898 
   7899 
   7900 #************************************************************
   7901 
   7902 #   Routines for inner part of recursion and iterations
   7903 
   7904 #************************************************************
   7905 
   7906 sub rdb_recurse_rule {
   7907     # Call: rdb_recurse_rule($rule, \&rule_act1, \&file_act1, \&file_act2, 
   7908     #                    \&rule_act2 )
   7909     # to do the work for one rule, recurisvely called from_rules for
   7910     # the sources of the rules.
   7911     # Assumes recursion context, i.e. that %visited, @heads, $depth.
   7912     # We are overriding actions:
   7913     my ($rule, $rule_act1, $new_file_act1, $new_file_act2, $rule_act2)
   7914         = @_;
   7915     # and must propagate the file actions:
   7916     local $file_act1 = $new_file_act1;
   7917     local $file_act2 = $new_file_act2;
   7918     # Prevent loops:
   7919     if ( (! $rule) || exists $visited{$rule} ) { return; }
   7920     $visited{$rule} = 1;
   7921     # Recursion depth
   7922     $depth++;
   7923     # We may need to repeat actions on dependent rules, without being
   7924     # blocked by the test on visited files.  So save %visited:
   7925     # NOT CURRENTLY USED!!    local %visited_at_rule_start = %visited;
   7926     # At end, the last value set for %visited wins.
   7927     rdb_one_rule( $rule, $rule_act1, \&rdb_recurse_file, $rule_act2 );
   7928     $depth--;
   7929  } #END rdb_recurse_rule 
   7930 
   7931 #************************************************************
   7932 
   7933 sub rdb_recurse_file {
   7934     # Call: rdb_recurse_file to do the work for one file.
   7935     # This has no arguments, since it is used as an action subroutine,
   7936     # passed as a reference in calls in higher-level subroutine.
   7937     # Assumes contexts set for: Recursion, rule, and file
   7938     &$file_act1 if $file_act1;
   7939     rdb_recurse_rule( $$Pfrom_rule, $rule_act1, $file_act1, $file_act2,
   7940                       $rule_act2 )
   7941         if $$Pfrom_rule;
   7942     &$file_act2 if $file_act2;
   7943 } #END rdb_recurse_file
   7944 
   7945 #************************************************************
   7946 
   7947 sub rdb_do_files {
   7948     # Assumes rule context, including $PHsource.
   7949     # Applies an action to all the source files of the rule.
   7950     local $file_act = shift;
   7951     my @file_list = sort keys %$PHsource;
   7952     foreach my $file ( @file_list ){
   7953         rdb_one_file( $file, $file_act );
   7954     }
   7955 } #END rdb_do_files
   7956 
   7957 #************************************************************
   7958 
   7959 # Routines for action on one rule and one file.  These are the main
   7960 # places (in addition to creation and destruction routines for rules
   7961 # and files) where the database structure is accessed.
   7962 
   7963 #************************************************************
   7964 
   7965 sub rdb_one_rule {
   7966     # Call: rdb_one_rule( $rule, $rule_act1, $file_act, $rule_act2 )
   7967     # Sets context for rule and carries out the actions.
   7968 #===== Accesses rule part of database structure =======
   7969 
   7970     local ( $rule, $rule_act1, $file_act, $rule_act2 ) = @_;
   7971 #??    &R1;
   7972     if ( (! $rule) || ! rdb_rule_exists($rule) ) { return; }
   7973 
   7974     local ( $PArule_data, $PHsource, $PHdest ) = @{$rule_db{$rule}};
   7975     local ($Pcmd_type, $Pext_cmd, $PAint_cmd, $Ptest_kind, 
   7976            $Psource, $Pdest, $Pbase,
   7977            $Pout_of_date, $Pout_of_date_user, $Prun_time, $Pcheck_time,
   7978            $Pchanged,
   7979            $Plast_result, $Plast_message, $PA_extra_generated )
   7980         = Parray( $PArule_data );
   7981 
   7982     &$rule_act1 if $rule_act1;
   7983     &rdb_do_files( $file_act ) if $file_act;
   7984     &$rule_act2 if $rule_act2;
   7985 #??    &R2;
   7986 } #END rdb_one_rule
   7987 
   7988 #************************************************************
   7989 
   7990 sub rdb_one_file {
   7991     # Call: rdb_one_file($file, $file_act)
   7992     # Sets context for file and carries out the action.
   7993     # Assumes $rule context set.
   7994 #===== Accesses file part of database structure =======
   7995     local ($file, $file_act) = @_;
   7996 #??    &F1;
   7997     if ( (!$file) ||(!exists ${$PHsource}{$file}) ) { return; }
   7998     local $PAfile_data = ${$PHsource}{$file};
   7999     local ($Ptime, $Psize, $Pmd5, $Pfrom_rule, $Pcorrect_after_primary ) 
   8000           = Parray( $PAfile_data );
   8001     &$file_act() if $file_act;
   8002     if ( ! rdb_rule_exists( $$Pfrom_rule ) ) {
   8003         $$Pfrom_rule = '';
   8004     }
   8005 #??    &F2;
   8006 } #END rdb_one_file
   8007 
   8008 #************************************************************
   8009 
   8010 # Routines for creation of rules and file items, and for removing file
   8011 # items. 
   8012 
   8013 #************************************************************
   8014 
   8015 sub rdb_remove_rule {
   8016     # rdb_remove_rule( rule, ...  )
   8017     foreach my $key (@_) {
   8018        delete $rule_db{$key};
   8019     }
   8020 }
   8021 
   8022 #************************************************************
   8023 
   8024 sub rdb_create_rule {
   8025     # rdb_create_rule( rule, command_type, ext_cmd, int_cmd, test_kind,
   8026     #                  source, dest, base, 
   8027     #                  needs_making, run_time, check_time, set_file_not_exists,
   8028     #                  ref_to_array_of_specs_of_extra_generated_files )
   8029     # int_cmd is either a string naming a perl subroutine or it is a
   8030     # reference to an array containing the subroutine name and its
   8031     # arguments. 
   8032     # Makes rule.  Error if it already exists.
   8033     # Omitted arguments: replaced by 0 or '' as needed.    
   8034 # ==== Sets rule data ====
   8035     my ( $rule, $cmd_type, $ext_cmd, $PAint_cmd, $test_kind, 
   8036          $source, $dest, $base, 
   8037          $needs_making, $run_time, $check_time, $set_file_not_exists, $extra_gen ) = @_;
   8038     my $changed = 0;
   8039 
   8040     # Set defaults, and normalize parameters:
   8041     foreach ( $cmd_type, $ext_cmd, $PAint_cmd, $source, $dest, $base, 
   8042               $set_file_not_exists ) {
   8043         if (! defined $_) { $_ = ''; }
   8044     }
   8045     if ( ($source =~ /\"/) || ($dest =~ /\"/) || ($base =~ /\"/) ) {
   8046 	die "$My_name: Error. In rdb_create_rule there is a double quote in one of\n",
   8047 	    "  source, destination or base parameters:\n",
   8048 	    "    '$source', '$dest', '$base'\n",
   8049 	    "  I cannot handle this.\n";
   8050     }
   8051     foreach ( $needs_making, $run_time, $check_time, $test_kind ) {
   8052         if (! defined $_) { $_ = 0; }
   8053     }
   8054     if (!defined $test_kind) {
   8055         # Default to test on file change
   8056         $test_kind = 1; 
   8057     }
   8058     if ( ref( $PAint_cmd ) eq '' ) {
   8059         #  It is a single command.  Convert to array reference:
   8060         $PAint_cmd = [ $PAint_cmd ];
   8061     }
   8062     else {
   8063         # COPY the referenced array:
   8064         $PAint_cmd = [ @$PAint_cmd ];
   8065     }
   8066     my $PA_extra_gen = [];
   8067     if ($extra_gen) {
   8068         @$PA_extra_gen = @$extra_gen;
   8069     }
   8070     $rule_db{$rule} = 
   8071         [  [$cmd_type, $ext_cmd, $PAint_cmd, $test_kind, 
   8072             $source, $dest, $base,
   8073             $needs_making, 0, $run_time, $check_time, $changed,
   8074             -1, '', $PA_extra_gen ],
   8075            {},
   8076            {}
   8077         ];
   8078     if ($source) {
   8079        rdb_ensure_file( $rule, $source, undef, $set_file_not_exists );  
   8080     }
   8081     rdb_one_rule( $rule, \&rdb_initialize_generated );
   8082 } #END rdb_create_rule
   8083 
   8084 #************************************************************
   8085 
   8086 sub rdb_initialize_generated {
   8087 # Assume rule context.
   8088 # Initialize hash of generated files
   8089     %$PHdest = ();
   8090     if ($$Pdest) { rdb_add_generated($$Pdest); }
   8091     foreach (@$PA_extra_generated) {
   8092         rdb_add_generated($_);
   8093     }
   8094 } #END rdb_initialize_generated
   8095 
   8096 #************************************************************
   8097 
   8098 sub rdb_add_generated {
   8099 # Assume rule context.
   8100 # Add arguments to hash of generated files
   8101     foreach (@_) {
   8102         $$PHdest{$_} = 1;
   8103     }
   8104 } #END rdb_add_generated
   8105 
   8106 #************************************************************
   8107 
   8108 sub rdb_remove_generated {
   8109 # Assume rule context.
   8110 # Remove arguments from hash of generated files
   8111     foreach (@_) {
   8112         delete $$PHdest{$_};
   8113     }
   8114 } #END rdb_remove_generated
   8115 
   8116 #************************************************************
   8117 
   8118 sub rdb_ensure_file {
   8119     # rdb_ensure_file( rule, file[, fromrule[, set_not_exists]] )
   8120     # Ensures the source file item exists in the given rule.
   8121     # Then if the fromrule is specified, set it for the file item.
   8122     # If the item is created, then:
   8123     #    (a) by default initialize it to current file state.
   8124     #    (b) but if the fourth argument, set_not_exists, is true, 
   8125     #        initialize the item as if the file does not exist.
   8126     #        This case is typically used when the log file for a run
   8127     #        of latex/pdflatex claims that the file was non-existent
   8128     #        at the beginning of a run. 
   8129 #============ rule and file data set here ======================================
   8130     my $rule = shift;
   8131     local ( $new_file, $new_from_rule, $set_not_exists ) = @_;
   8132     if ( ! rdb_rule_exists( $rule ) ) {
   8133         die_trace( "$My_name: BUG in call to rdb_ensure_file: non-existent rule '$rule'" );
   8134     }
   8135     if ( ! defined $new_file ) {
   8136         die_trace( "$My_name: BUG in call to rdb_ensure_file: undefined file for '$rule'" );
   8137     }
   8138     if ( $new_file =~ /\"/ ) {
   8139 	warn "$My_name: in rdb_ensure_file for rule '$rule', there is a double quote in\n",
   8140 	     "  the filename: '$new_file'.\n",
   8141  	     "  I cannot handle this, will ignore this file.\n";
   8142 	return;
   8143     }
   8144     if ( ! defined $set_not_exists ) { $set_not_exists = 0; }
   8145     rdb_one_rule( $rule, 
   8146                   sub{
   8147                       if (! exists ${$PHsource}{$new_file} ) {
   8148                           if ( $set_not_exists ) {
   8149                               ${$PHsource}{$new_file} = [0, -1, 0, '', 0];
   8150                           }
   8151                           else {
   8152                               ${$PHsource}{$new_file} 
   8153                               = [fdb_get($new_file, $$Prun_time), '', 0];
   8154                           }
   8155                       }
   8156                   }
   8157     );
   8158     if (defined $new_from_rule ) {
   8159         rdb_for_one_file( $rule, $new_file, sub{ $$Pfrom_rule = $new_from_rule; });
   8160     }
   8161 } #END rdb_ensure_file 
   8162 
   8163 #************************************************************
   8164 
   8165 sub rdb_remove_files {
   8166     # rdb_remove_file( rule, file, ... )
   8167     # Removes file(s) for the rule.  
   8168     my $rule = shift;
   8169     if (!$rule) { return; }
   8170     local @files = @_;
   8171     rdb_one_rule( $rule, 
   8172                   sub{ foreach (@files) { delete ${$PHsource}{$_}; }  }
   8173     );
   8174 } #END rdb_remove_files
   8175 
   8176 #************************************************************
   8177 
   8178 sub rdb_list_source {
   8179     # rdb_list_source( rule )
   8180     # Return array of source files for rule.
   8181     my $rule = shift;
   8182     my @files = ();
   8183     rdb_one_rule( $rule, 
   8184                   sub{ @files = keys %$PHsource; }
   8185     );
   8186     return @files;
   8187 } #END rdb_list_source
   8188 
   8189 #************************************************************
   8190 
   8191 sub rdb_set_source {
   8192     # rdb_set_source( rule, file, ... )
   8193     my $rule = shift;
   8194     if (!$rule) { return; }
   8195     my %files = ();
   8196     foreach (@_) {
   8197 #	if ( /\"/ ) {next; }
   8198 	rdb_ensure_file( $rule, $_ );
   8199 	$files{$_} = 1;
   8200     }
   8201     foreach ( rdb_list_source($rule) ) {
   8202         if ( ! exists $files{$_} ) { rdb_remove_files( $rule, $_ ); }
   8203     }    
   8204     return;
   8205 } #END rdb_list_source
   8206 
   8207 #************************************************************
   8208 
   8209 sub rdb_change_dest {
   8210    # Assumes rule context.
   8211    # Usage change_dest( new_dest [, flag] )
   8212    # Changes destination for this rule. Fixes from_rule links.
   8213    # If flag set, make the new_dest a source file in any rule
   8214    # for which the old destination is already set.
   8215    # No action if there's no change of destination.
   8216    local ($new_dest, $flag) = @_;
   8217    local $old_dest = $$Pdest;
   8218    if ($old_dest eq $new_dest) { return; }
   8219 #   if ( $new_dest =~ /\"/ ) { return; }
   8220    rdb_remove_generated( $old_dest );
   8221    rdb_add_generated( $new_dest );
   8222    if ($flag) {
   8223       print "rdb_change_dest: fixing dependencies\n";
   8224       rdb_for_all( sub{ if ( rdb_file_exists( $rule, $old_dest ) ) {
   8225 	                    rdb_ensure_file( $rule, $new_dest );
   8226 	                    rdb_remove_files( $rule, $old_dest );
   8227                         }
   8228                       }
   8229 		 );
   8230    }
   8231    $$Pdest = $new_dest;
   8232    # ??? Do I need to fix from_rule setting?
   8233    #&rdb_make_links;
   8234    return;
   8235 } #END rdb_change_dest
   8236 
   8237 #************************************************************
   8238 
   8239 sub rdb_rule_exists { 
   8240     # Call rdb_rule_exists($rule): Returns whether rule exists.
   8241     my $rule = shift;
   8242     if (! $rule ) { return 0; }
   8243     return exists $rule_db{$rule}; 
   8244 } #END rdb_rule_exists
   8245 
   8246 #************************************************************
   8247 
   8248 sub rdb_file_exists { 
   8249     # Call rdb_file_exists($rule, $file): 
   8250     # Returns whether source file item in rule exists.
   8251     local ( $rule, $file ) = @_;
   8252     local $exists = 0;
   8253     rdb_one_rule( $rule, 
   8254                   sub{ $exists =  exists( ${$PHsource}{$file} ) ? 1:0; } 
   8255                 );
   8256     return $exists; 
   8257 } #END rdb_file_exists
   8258 
   8259 #************************************************************
   8260 
   8261 sub rdb_update_gen_files {
   8262     # Assumes rule context.  Update source files of rule to current state.
   8263     rdb_do_files( 
   8264         sub{
   8265             if ( exists $generated_exts_all{ ext_no_period($file) } ) {&rdb_update1;} 
   8266         }
   8267     );
   8268 } #END rdb_update_gen_files
   8269 
   8270 #************************************************************
   8271 
   8272 sub rdb_update_files {
   8273     # Call: rdb_update_files
   8274     # Assumes rule context.  Update source files of rule to current state.
   8275     rdb_do_files( \&rdb_update1 );
   8276 }
   8277 
   8278 #************************************************************
   8279 
   8280 sub rdb_update1 {
   8281     # Call: rdb_update1.  
   8282     # Assumes file context.  Updates file data to correspond to
   8283     # current file state on disk
   8284     ($$Ptime, $$Psize, $$Pmd5) = fdb_get($file);
   8285 }
   8286 
   8287 #************************************************************
   8288 
   8289 sub rdb_set_file1 {
   8290     # Call: fdb_file1(rule, file, new_time, new_size, new_md5)
   8291     # Sets file time, size and md5.
   8292     my $rule = shift;
   8293     my $file = shift;
   8294     local @new_file_data = @_;
   8295     rdb_for_one_file( $rule, $file, sub{ ($$Ptime,$$Psize,$$Pmd5)=@new_file_data; } );
   8296 }
   8297 
   8298 #************************************************************
   8299 
   8300 sub rdb_dummy_file {
   8301     # Returns file data for non-existent file
   8302 # ==== Uses rule_db structure ====
   8303     return (0, -1, 0, '');
   8304 }
   8305 
   8306 #************************************************************
   8307 #************************************************************
   8308 
   8309 # Predefined subroutines for custom dependency
   8310 
   8311 sub cus_dep_delete_dest {
   8312     # This subroutine is used for situations like epstopdf.sty, when
   8313     #   the destination (target) of the custom dependency invoking
   8314     #   this subroutine will be made by the primary run provided the
   8315     #   file (destination of the custom dependency, source of the
   8316     #   primary run) doesn't exist.
   8317     # It is assumed that the resulting file will be read by the
   8318     #   primary run.
   8319 
   8320     # Remove the destination file, to indicate it needs to be remade:
   8321     unlink_or_move( $$Pdest );
   8322     # Arrange that the non-existent destination file is not treated as
   8323     #   an error.  The variable changed here is a bit misnamed.
   8324     $$Pchanged = 1;
   8325     # Ensure a primary run is done
   8326     &cus_dep_require_primary_run;
   8327     # Return success:
   8328     return 0;
   8329 }
   8330 
   8331 #************************************************************
   8332 
   8333 sub cus_dep_require_primary_run {
   8334     # This subroutine is used for situations like epstopdf.sty, when
   8335     #   the destination (target) of the custom dependency invoking
   8336     #   this subroutine will be made by the primary run provided the
   8337     #   file (destination of the custom dependency, source of the
   8338     #   primary run) doesn't exist.
   8339     # It is assumed that the resulting file will be read by the
   8340     #   primary run.
   8341 
   8342     local $cus_dep_target = $$Pdest;
   8343     # Loop over all rules and source files:
   8344     rdb_for_all( 0, 
   8345                  sub { if ($file eq $cus_dep_target) {
   8346                             $$Pout_of_date = 1;
   8347                             $$Pcorrect_after_primary = 1;
   8348                        }
   8349                      }
   8350                );
   8351     # Return success:
   8352     return 0;
   8353 }
   8354 
   8355 
   8356 #************************************************************
   8357 #************************************************************
   8358 #************************************************************
   8359 #
   8360 #      UTILITIES:
   8361 #
   8362 
   8363 #************************************************************
   8364 # Miscellaneous
   8365 
   8366 sub show_array {
   8367 # For use in diagnostics and debugging. 
   8368 #  On stderr, print line with $_[0] = label.  
   8369 #  Then print rest of @_, one item per line preceeded by some space
   8370     warn "$_[0]\n";
   8371     shift;
   8372     if ($#_ >= 0) {  foreach (@_){ warn "  $_\n";} }
   8373     else { warn "  NONE\n"; }
   8374 }
   8375 
   8376 #************************************************************
   8377 
   8378 sub Parray {
   8379     # Call: Parray( \@A )
   8380     # Returns array of references to the elements of @A
   8381     # But if an element of @A is already a reference, the
   8382     # reference will be returned in the output array, not a
   8383     # reference to the reference.
   8384     my $PA = shift;
   8385     my @P = (undef) x (1+$#$PA);
   8386     foreach my $i (0..$#$PA) {
   8387         $P[$i] = (ref $$PA[$i]) ? ($$PA[$i]) : (\$$PA[$i]);
   8388       }
   8389     return @P;
   8390 }
   8391 
   8392 #************************************************************
   8393 
   8394 sub glob_list1 {
   8395     # Glob a collection of filenames.  
   8396     # But no sorting or elimination of duplicates
   8397     # Usage: e.g., @globbed = glob_list1(string, ...);
   8398     # Since perl's glob appears to use space as separator, I'll do a special check
   8399     # for existence of non-globbed file (assumed to be tex like)
   8400 
   8401     my @globbed = ();
   8402     foreach my $file_spec (@_) {
   8403         # Problem, when the PATTERN contains spaces, the space(s) are
   8404         # treated as pattern separaters.
   8405         # Solution: I now the glob from use File::Glob.
   8406         # The following hack avoids issues with glob in the case that a file exists
   8407         # with the specified name (possibly with extension .tex):
   8408         if ( -e $file_spec || -e "$file_spec.tex" ) { 
   8409            # Non-globbed file exists, return the file_spec.
   8410            # Return $file_spec only because this is not a file-finding subroutine, but
   8411            #   only a globber
   8412            push @globbed, $file_spec; 
   8413         }
   8414         else { 
   8415             push @globbed, my_glob( "$file_spec" );
   8416         }
   8417     }
   8418     return @globbed;
   8419 } #END glob_list1
   8420 
   8421 #************************************************************
   8422 # Miscellaneous
   8423 
   8424 sub prefix {
   8425    #Usage: prefix( string, prefix );
   8426    #Return string with prefix inserted at the front of each line
   8427    my @line = split( /\n/, $_[0] );
   8428    my $prefix = $_[1];
   8429    for (my $i = 0; $i <= $#line; $i++ ) {
   8430        $line[$i] = $prefix.$line[$i]."\n";
   8431    }
   8432    return join( "", @line );
   8433 } #END prefix
   8434 
   8435 
   8436 #===============================
   8437 
   8438 sub parse_quotes {
   8439     # Split string into words.
   8440     # Words are delimited by space, except that strings
   8441     # quoted all stay inside a word.  E.g., 
   8442     #   'asdf B" df "d "jkl"'
   8443     # is split to ( 'asdf', 'B df d', 'jkl').
   8444     # An array is returned.
   8445     my @results = ();
   8446     my $item = '';
   8447     local $_ = shift;
   8448     pos($_) = 0;
   8449   ITEM:
   8450     while() {
   8451         /\G\s*/gc;
   8452         if ( /\G$/ ) {
   8453             last ITEM;
   8454         }
   8455         # Now pos (and \G) is at start of item:
   8456       PART:
   8457         while () {
   8458             if (/\G([^\s\"]*)/gc) {
   8459                 $item .= $1;
   8460             }
   8461             if ( /\G\"([^\"]*)\"/gc ) {
   8462                 # Match balanced quotes
   8463                 $item .= $1;
   8464                 next PART;
   8465             }
   8466             elsif ( /\G\"(.*)$/gc ) {
   8467                 # Match unbalanced quote
   8468                 $item .= $1;
   8469                 warn "====Non-matching quotes in\n    '$_'\n";
   8470             }
   8471             push @results, $item;
   8472             $item = '';
   8473             last PART;
   8474         }
   8475     }
   8476     return @results;
   8477 } #END parse_quotes
   8478 
   8479 #************************************************************
   8480 #************************************************************
   8481 #      File handling utilities:
   8482 
   8483 
   8484 #************************************************************
   8485 
   8486 sub get_latest_mtime
   8487 # - arguments: each is a filename.
   8488 # - returns most recent modify time.
   8489 {
   8490   my $return_mtime = 0;
   8491   foreach my $include (@_)
   8492   {
   8493     my $include_mtime = &get_mtime($include);
   8494     # The file $include may not exist.  If so ignore it, otherwise
   8495     # we'll get an undefined variable warning.
   8496     if ( ($include_mtime) && ($include_mtime >  $return_mtime) )
   8497     {
   8498       $return_mtime = $include_mtime;
   8499     }
   8500   }
   8501   return $return_mtime;
   8502 }
   8503 
   8504 #************************************************************
   8505 
   8506 sub get_mtime_raw
   8507 { 
   8508   my $mtime = (stat($_[0]))[9];
   8509   return $mtime;
   8510 }
   8511 
   8512 #************************************************************
   8513 
   8514 sub get_mtime { 
   8515     return get_mtime0($_[0]);
   8516 }
   8517 
   8518 #************************************************************
   8519 
   8520 sub get_mtime0 {
   8521    # Return time of file named in argument
   8522    # If file does not exist, return 0;
   8523    if ( -e $_[0] ) {
   8524        return get_mtime_raw($_[0]);
   8525    }
   8526    else {
   8527        return 0;
   8528    }
   8529 }
   8530 
   8531 #************************************************************
   8532 
   8533 sub get_size {
   8534    # Return time of file named in argument
   8535    # If file does not exist, return 0;
   8536    if ( -e $_[0] ) {
   8537        return get_size_raw($_[0]);
   8538    }
   8539    else {
   8540        return 0;
   8541    }
   8542 }
   8543 
   8544 #************************************************************
   8545 
   8546 sub get_size_raw
   8547 { 
   8548   my $size = (stat($_[0]))[7];
   8549   return $size;
   8550 }
   8551 
   8552 #************************************************************
   8553 
   8554 sub get_time_size {
   8555    # Return time and size of file named in argument
   8556    # If file does not exist, return (0,-1);
   8557    if ( -e $_[0] ) {
   8558        return get_time_size_raw($_[0]);
   8559    }
   8560    else {
   8561        return (0,-1);
   8562    }
   8563 }
   8564 
   8565 #************************************************************
   8566 
   8567 sub get_time_size_raw
   8568 { 
   8569   my $mtime = (stat($_[0]))[9];
   8570   my $size = (stat($_[0]))[7];
   8571   return ($mtime, $size);
   8572 }
   8573 
   8574 #************************************************************
   8575 
   8576 sub processing_time
   8577 {  my ($user, $system, $cuser, $csystem) = times();
   8578    return $user + $system + $cuser + $csystem;
   8579 }
   8580 
   8581 #************************************************************
   8582 
   8583 sub get_checksum_md5 {
   8584     my $source = shift;
   8585     my $input = new FileHandle;
   8586     my $md5 = Digest::MD5->new;
   8587     my $ignore_pattern = undef;
   8588 
   8589 #&traceback;
   8590 #warn "======= GETTING MD5: $source\n";
   8591     if ( -d $source ) {
   8592         # We won't use checksum for directory
   8593         return 0;
   8594     }
   8595     else {
   8596         open( $input, '<:bytes', $source )
   8597         or return 0;
   8598         my ($base, $path, $ext) = fileparseA( $source );
   8599         $ext =~ s/^\.//;
   8600         if ( exists $hash_calc_ignore_pattern{$ext} ) {
   8601             $ignore_pattern = $hash_calc_ignore_pattern{$ext};
   8602         }
   8603     }
   8604     if ( defined $ignore_pattern ) {
   8605         while (<$input>) {
   8606             if ( ! /$ignore_pattern/ ){
   8607                 $md5->add($_);
   8608             }
   8609         }
   8610     }
   8611     else {
   8612         $md5->addfile($input);
   8613     }
   8614     close $input;
   8615     return $md5->hexdigest();
   8616 }
   8617 
   8618 #************************************************************
   8619 #************************************************************
   8620 
   8621 sub create_empty_file {
   8622     my $name = shift;
   8623     my $h = new FileHandle ">$name"
   8624 	or return 1;
   8625     close ($h);
   8626     return 0;
   8627 }
   8628 
   8629 #************************************************************
   8630 #************************************************************
   8631 
   8632 sub find_file1 {
   8633 #?? Need to use kpsewhich, if possible
   8634 
   8635     # Usage: find_file1(name, ref_to_array_search_path)
   8636     # Modified find_file, which doesn't die.
   8637     # Given filename and path, return array of:
   8638     #             full name 
   8639     #             retcode
   8640     # On success: full_name = full name with path, retcode = 0
   8641     # On failure: full_name = given name, retcode = 1
   8642 
   8643     my $name = $_[0];
   8644     # Make local copy of path, since we may rewrite it!
   8645     my @path = ();
   8646     if ($_[1]) {
   8647         @path = @{$_[1]};
   8648     }
   8649     if ( $name =~ /^\// ) {
   8650         # Absolute path (if under UNIX)
   8651         # This needs fixing, in general
   8652         if (-e $name) { return( $name, 0 );}
   8653         else { return( $name, 1 );}
   8654     }
   8655     foreach my $dir ( @path ) {
   8656         #??print "-------------dir='$dir',  ";
   8657         # Make $dir concatenatable, and empty for current dir:
   8658         if ( $dir eq '.' ) { 
   8659             $dir = ''; 
   8660         }
   8661         elsif ( $dir =~ /[\/\\:]$/ ) { 
   8662             #OK if dir ends in / or \ or :
   8663         }
   8664         elsif ( $dir ne '' ) { 
   8665             #Append directory separator only to non-empty dir
   8666             $dir = "$dir/"; 
   8667         }
   8668         #?? print " newdir='$dir'\n";
   8669         if (-e "$dir$name") {
   8670             return("$dir$name", 0);
   8671         }
   8672     }
   8673     my @kpse_result = kpsewhich( $name );
   8674     if ($#kpse_result > -1) {
   8675         return( $kpse_result[0], 0);
   8676     }
   8677     return("$name" , 1);
   8678 } #END find_file1
   8679 
   8680 #************************************************************
   8681 
   8682 sub find_file_list1 {
   8683     # Modified version of find_file_list that doesn't die.
   8684     # Given output and input arrays of filenames, a file suffix, and a path, 
   8685     # fill the output array with full filenames
   8686     # Return array of not-found files.
   8687     # Usage: find_file_list1( ref_to_output_file_array,
   8688     #                         ref_to_input_file_array,
   8689     #                         suffix,
   8690     #                         ref_to_array_search_path
   8691     #                       )
   8692     # SPECIAL TREATMENT TO .bib extension, because of behavior of bibtex
   8693     # OTHER SPECIAL TREATMENT IF EXTENSION IS GIVEN.
   8694 
   8695   my $ref_output = $_[0];
   8696   my $ref_input  = $_[1];
   8697   my $suffix     = $_[2];
   8698   my $ref_search = $_[3];
   8699   my @not_found = ();
   8700 
   8701 #??  show_array( "=====find_file_list1.  Suffix: '$suffix'\n Source:",  @$ref_input );
   8702 #??  show_array( " Bibinputs:",  @$ref_search );
   8703 
   8704   my @return_list = ();    # Generate list in local array, since input 
   8705                            # and output arrays may be same
   8706   my $retcode = 0;
   8707   foreach my $file1 (@$ref_input) {
   8708     my $file = $file1;
   8709     if ($suffix eq '.bib') { $file =~ s/\.bib$//; }
   8710     my ($tmp_file, $find_retcode) = &find_file1( "$file$suffix", $ref_search );
   8711     if ($tmp_file)  {
   8712         push @return_list, $tmp_file;
   8713     }
   8714     if ( $find_retcode != 0 ) {
   8715         push @not_found, $file.$suffix;
   8716     }
   8717   }
   8718   @$ref_output = @return_list;
   8719 #??  show_array( " Output", @$ref_output );
   8720 #??  foreach (@$ref_output) { if ( /\/\// ) {  print " ====== double slash in  '$_'\n"; }  }
   8721   return @not_found;
   8722 } #END find_file_list1
   8723 
   8724 #************************************************************
   8725 
   8726 sub unlink_or_move {
   8727     if ( $del_dir eq '' ) {
   8728         unlink @_;
   8729     }
   8730     else {
   8731         foreach (@_) {
   8732             if (-e $_ && ! rename $_, "$del_dir/$_" ) {
   8733                 warn "$My_name:Cannot move '$_' to '$del_dir/$_'\n";
   8734             }
   8735         }
   8736     }
   8737 }
   8738 
   8739 #************************************************************
   8740 
   8741 sub kpsewhich {
   8742 # Usage: kpsewhich( filespec, ...)
   8743 # Returns array of files with paths as found by kpsewhich
   8744 #    kpsewhich( 'try.sty', 'jcc.bib' );
   8745 # With standard use of kpsewhich (i.e., without -all option), the array
   8746 # has either 0 or 1 element.
   8747 # Can also do, e.g.,
   8748 #    kpsewhich( '-format=bib', 'trial.bib', 'file with spaces');
   8749     my $cmd = $kpsewhich;
   8750     my @args = @_;
   8751     if ( ($cmd eq '') || ( $cmd =~ /^NONE($| )/ ) ) {
   8752 	# Kpsewhich not set up.
   8753 	warn "$My_name: Kpsewhich command needed but not set up\n";
   8754 	return ();
   8755     }
   8756     foreach (@args) {
   8757         if ( ! /^-/ ) {
   8758             $_ = "\"$_\"";
   8759         }
   8760     }
   8761     $cmd =~ s/%[RBTDO]//g;
   8762     $cmd =~ s/%S/@args/g;
   8763     my @found = ();
   8764     local $fh;
   8765     if ( $kpsewhich_show || $diagnostics ) {
   8766         print "$My_name.kpsewhich: Running '$cmd'...\n";
   8767     }
   8768     open $fh, "$cmd|"
   8769         or die "Cannot open pipe for \"$cmd\"\n";
   8770     while ( <$fh> ) {
   8771         s/[\r\n]*$//;
   8772         push @found, $_;
   8773     }
   8774     close $fh;
   8775     if ( $kpsewhich_show || $diagnostics ) {
   8776 	show_array( "$My_name.kpsewhich: '$cmd' ==>", @found );
   8777     }
   8778     return @found;
   8779 }
   8780 
   8781 ####################################################
   8782 
   8783 sub add_cus_dep {
   8784     # Usage: add_cus_dep( from_ext, to_ext, flag, sub_name )
   8785     # Add cus_dep after removing old versions
   8786     my ($from_ext, $to_ext, $must, $sub_name) = @_;
   8787     remove_cus_dep( $from_ext, $to_ext );
   8788     push @cus_dep_list, "$from_ext $to_ext $must $sub_name";
   8789 }
   8790 
   8791 ####################################################
   8792 
   8793 sub remove_cus_dep {
   8794     # Usage: remove_cus_dep( from_ext, to_ext )
   8795     my ($from_ext, $to_ext) = @_;
   8796     my $i = 0;
   8797     while ($i <= $#cus_dep_list) {
   8798         # Use \Q and \E round directory name in regex to avoid interpretation
   8799         #   of metacharacters in directory name:
   8800         if ( $cus_dep_list[$i] =~ /^\Q$from_ext $to_ext \E/ ) {
   8801             splice @cus_dep_list, $i, 1;
   8802         }
   8803         else {
   8804             $i++;
   8805         }
   8806     }
   8807 }
   8808 
   8809 ####################################################
   8810 
   8811 sub show_cus_dep {
   8812     show_array( "Custom dependency list:", @cus_dep_list );
   8813 }
   8814 
   8815 ####################################################
   8816 
   8817 sub add_aux_hook {
   8818     # Usage: add_aux_hook( sub_name )
   8819     # Add the name subroutine to the array of hooks for
   8820     # processing lines of aux files.
   8821     # The argument is either a string naming the subroutine, e.g.
   8822     #     add_aux_hook( 'subname' );
   8823     # or a Perl reference to the subroutine, e.g.,
   8824     #     add_aux_hook( \&subname );
   8825     # It is also possible to use an anonymous subroutine, e.g.,
   8826     #     add_aux_hook( sub{  code of subroutine... } );
   8827     my ($sub_name) = @_;
   8828     push @aux_hooks, $sub_name;
   8829 }
   8830 
   8831 ####################################################
   8832 
   8833 sub add_input_ext {
   8834     # Usage: add_input_ext( rule, ext, ... )
   8835     # Add extension(s) (specified without a leading period) to the 
   8836     # list of input extensions for the given rule.  The rule should be
   8837     # 'latex' or 'pdflatex'.  These extensions are used when an input
   8838     # file without an extension is found by (pdf)latex, as in
   8839     # \input{file} or \includegraphics{figure}.  When latexmk searches
   8840     # custom dependencies to make the missing file, it will assume that
   8841     # the file has one of the specified extensions.
   8842     my $rule = shift;
   8843     if ( ! exists $input_extensions{$rule} ) {
   8844        $input_extensions{$rule} = {};
   8845     }
   8846     my $Prule = $input_extensions{$rule};
   8847     foreach (@_) { $$Prule{$_} = 1; }
   8848 }
   8849 
   8850 ####################################################
   8851 
   8852 sub remove_input_ext {
   8853     # Usage: remove_input_ext( rule, ext, ... )
   8854     # Remove extension(s) (specified without a leading period) to the 
   8855     # list of input extensions for the given rule.  The rule should be
   8856     # 'latex' or 'pdflatex'.  See sub add_input_ext for the use.
   8857     my $rule = shift;
   8858     if ( ! exists $input_extensions{$rule} ) { return; }
   8859     my $Prule = $input_extensions{$rule};
   8860     foreach (@_) { delete $$Prule{$_}; }
   8861 }
   8862 
   8863 ####################################################
   8864 
   8865 sub show_input_ext {
   8866     # Usage: show_input_ext( rule )
   8867     my $rule = shift;
   8868     show_array ("Input extensions for rule '$rule': ", 
   8869                 keys %{$input_extensions{$rule}} );
   8870 }
   8871 
   8872 ####################################################
   8873 
   8874 sub find_dirs1 {
   8875    # Same as find_dirs, but argument is single string with directories
   8876    # separated by $search_path_separator
   8877    find_dirs( &split_search_path( $search_path_separator, ".", $_[0] ) );
   8878 }
   8879 
   8880 
   8881 #************************************************************
   8882 
   8883 sub find_dirs {
   8884 # @_ is list of directories
   8885 # return: same list of directories, except that for each directory 
   8886 #         name ending in //, a list of all subdirectories (recursive)
   8887 #         is added to the list.
   8888 #   Non-existent directories and non-directories are removed from the list
   8889 #   Trailing "/"s and "\"s are removed
   8890     local @result = ();
   8891     my $find_action 
   8892         = sub 
   8893           { ## Subroutine for use in File::find
   8894             ## Check to see if we have a directory
   8895                if (-d) { push @result, $File::Find::name; }
   8896           };
   8897     foreach my $directory (@_) {
   8898         my $recurse = ( $directory =~ m[//$] );
   8899         # Remove all trailing /s, since directory name with trailing /
   8900         #   is not always allowed:
   8901         $directory =~ s[/+$][];
   8902         # Similarly for MSWin reverse slash
   8903         $directory =~ s[\\+$][];
   8904         if ( ! -e $directory ){
   8905             next;
   8906         }
   8907         elsif ( $recurse ){
   8908             # Recursively search directory
   8909             find( $find_action, $directory );
   8910         }
   8911         else {
   8912             push @result, $directory;
   8913         }
   8914     }
   8915     return @result;
   8916 }
   8917 
   8918 #************************************************************
   8919 
   8920 sub uniq 
   8921 # Read arguments, delete neighboring items that are identical,
   8922 # return array of results
   8923 {
   8924     my @sort = ();
   8925     my ($current, $prev);
   8926     my $first = 1;
   8927     while (@_)
   8928     {
   8929         $current = shift;
   8930         if ($first || ($current ne $prev) )
   8931         {
   8932             push @sort, $current; 
   8933             $prev = $current;
   8934             $first = 0;
   8935         }
   8936     }
   8937     return @sort;
   8938 }
   8939 
   8940 #==================================================
   8941 
   8942 sub uniq1 {
   8943    # Usage: uniq1( strings )
   8944    # Returns array of strings with duplicates later in list than
   8945    # first occurence deleted.  Otherwise preserves order.
   8946 
   8947     my @strings = ();
   8948     my %string_hash = ();
   8949 
   8950     foreach my $string (@_) {
   8951         if (!exists( $string_hash{$string} )) { 
   8952             $string_hash{$string} = 1;
   8953             push @strings, $string; 
   8954         }
   8955     }
   8956     return @strings;
   8957 }
   8958 
   8959 #************************************************************
   8960 
   8961 sub uniqs {
   8962     # Usage: uniq2( strings )
   8963     # Returns array of strings sorted and with duplicates deleted
   8964     return uniq( sort @_ );
   8965 }
   8966 
   8967 #************************************************************
   8968 
   8969 sub ext {
   8970     # Return extension of filename.  Extension includes the period
   8971     my $file_name = $_[0];
   8972     my ($base_name, $path, $ext) = fileparseA( $file_name );
   8973     return $ext;
   8974  }
   8975 
   8976 #************************************************************
   8977 
   8978 sub ext_no_period {
   8979     # Return extension of filename.  Extension excludes the period
   8980     my $file_name = $_[0];
   8981     my ($base_name, $path, $ext) = fileparseA( $file_name );
   8982     $ext =~ s/^\.//;
   8983     return $ext;
   8984  }
   8985 
   8986 #************************************************************
   8987 
   8988 sub fileparseA {
   8989     # Like fileparse but replace $path for current dir ('./' or '.\') by ''
   8990     # Also default second argument to get normal extension.
   8991     my $given = $_[0];
   8992     my $pattern = '\.[^\.]*';
   8993     if  ($#_ > 0 ) { $pattern = $_[1]; }
   8994     my ($base_name, $path, $ext) = fileparse( $given, $pattern );
   8995     if ( ($path eq './') || ($path eq '.\\') ) { 
   8996         $path = ''; 
   8997     }
   8998     return ($base_name, $path, $ext);
   8999 }
   9000 
   9001 #************************************************************
   9002 
   9003 sub fileparseB {
   9004     # Like fileparse but with default second argument for normal extension
   9005     my $given = $_[0];
   9006     my $pattern = '\.[^\.]*';
   9007     if  ($#_ > 0 ) { $pattern = $_[1]; }
   9008     my ($base_name, $path, $ext) = fileparse( $given, $pattern );
   9009     return ($base_name, $path, $ext);
   9010 }
   9011 
   9012 #************************************************************
   9013 
   9014 sub split_search_path 
   9015 {
   9016 # Usage: &split_search_path( separator, default, string )
   9017 # Splits string by separator and returns array of the elements
   9018 # Allow empty last component.
   9019 # Replace empty terms by the default.
   9020     my $separator = $_[0]; 
   9021     my $default = $_[1]; 
   9022     my $search_path = $_[2]; 
   9023     my @list = split( /$separator/, $search_path);
   9024     if ( $search_path =~ /$separator$/ ) {
   9025         # If search path ends in a blank item, the split subroutine
   9026         #    won't have picked it up.
   9027         # So add it to the list by hand:
   9028         push @list, "";
   9029     }
   9030     # Replace each blank argument (default) by current directory:
   9031     for ($i = 0; $i <= $#list ; $i++ ) {
   9032         if ($list[$i] eq "") {$list[$i] = $default;}
   9033     }
   9034     return @list;
   9035 }
   9036 
   9037 #################################
   9038 
   9039 sub get_filetime_offset {
   9040     # Usage: get_filetime_offset( prefix, [suffix] )
   9041     # Measures offset between filetime in a directory and system time
   9042     # Makes a temporary file of a unique name, and deletes in.
   9043     # Filename is of form concatenation of prefix, an integer, suffix.
   9044     # Prefix is normally of form dir/ or dir/tmp.
   9045     # Default default suffix ".tmp".
   9046     my $prefix = $_[0];
   9047     my $suffix = $_[1] || '.tmp';
   9048     my $tmp_file_count = 0;
   9049     while (1==1) {
   9050         # Find a new temporary file, and make it.
   9051         $tmp_file_count++;
   9052         my $tmp_file = "${prefix}${tmp_file_count}${suffix}";
   9053         if ( ! -e $tmp_file ) {
   9054             open( TMP, ">$tmp_file" ) 
   9055 		or die "$My_name.get_filetime_offset: In measuring filetime offset, couldn't write to\n",
   9056  		       "    temporary file '$tmp_file'\n";
   9057 	    my $time = time();
   9058             close(TMP);
   9059 	    my $offset = get_mtime($tmp_file) - $time;
   9060 	    unlink $tmp_file;
   9061             return $offset;
   9062          }
   9063      }
   9064      die "$My_name.get_filetime_offset: BUG TO ARRIVE HERE\n";
   9065 }
   9066 
   9067 #################################
   9068 
   9069 sub tempfile1 {
   9070     # Makes a temporary file of a unique name.  I could use file::temp,
   9071     # but it is not present in all versions of perl.
   9072     # Filename is of form $tmpdir/$_[0]nnn$suffix, where nnn is an integer
   9073     my $tmp_file_count = 0;
   9074     my $prefix = $_[0];
   9075     my $suffix = $_[1];
   9076     while (1==1) {
   9077         # Find a new temporary file, and make it.
   9078         $tmp_file_count++;
   9079         my $tmp_file = "${tmpdir}/${prefix}${tmp_file_count}${suffix}";
   9080         if ( ! -e $tmp_file ) {
   9081             open( TMP, ">$tmp_file" ) 
   9082                or next;
   9083             close(TMP);
   9084             return $tmp_file;
   9085          }
   9086      }
   9087      die "$My_name.tempfile1: BUG TO ARRIVE HERE\n";
   9088 }
   9089 
   9090 #################################
   9091 
   9092 #************************************************************
   9093 #************************************************************
   9094 #      Process/subprocess routines
   9095 
   9096 sub Run_msg {
   9097     # Same as Run, but give message about my running
   9098     warn_running( "Running '$_[0]'" );
   9099     return Run($_[0]);
   9100 } #END Run_msg
   9101 
   9102 #==================
   9103 
   9104 sub Run {
   9105     # This is wrapper around Run_no_time to capture timing information
   9106     my $time1 = processing_time();
   9107     my ($pid, $return) = Run_no_time($_[0]);
   9108     my $time = processing_time() - $time1;
   9109     push @timings, "'$_[0]': time = $time\n"; 
   9110     return ($pid, $return);
   9111 } #END Run_msg
   9112 
   9113 #==================
   9114 
   9115 sub Run_no_time {
   9116 # Usage: Run_no_time ("command string");
   9117 #    or  Run_no_time ("one-or-more keywords command string");
   9118 # Possible keywords: internal, NONE, start, nostart.
   9119 #
   9120 # A command string not started by keywords just gives a call to system with
   9121 #   the specified string, I return after that has finished executing.
   9122 # Exceptions to this behavior are triggered by keywords.
   9123 # The general form of the string is
   9124 #    Zero or more occurences of the start keyword,
   9125 #    followed by at most one of the other key words (internal, nostart, NONE),
   9126 #    followed by (a) a command string to be executed by the systerm
   9127 #             or (b) if the command string is specified to be internal, then
   9128 #                    it is of the form
   9129 #
   9130 #                       routine arguments
   9131 #
   9132 #                    which implies invocation of the named Perl subroutine
   9133 #                    with the given arguments, which are obtained by splitting
   9134 #                    the string into words, delimited by spaces, but with
   9135 #                    allowance for double quotes.
   9136 #
   9137 # The meaning of the keywords is:
   9138 #
   9139 #    start: The command line is to be running detached, as appropriate for
   9140 #             a previewer.  The method is appropriate for the operating system
   9141 #             (and the keyword is inspired by the action of the start command
   9142 #             that implements in under MSWin).
   9143 #           HOWEVER: the start keyword is countermanded by the nostart,
   9144 #             internal, and NONE keywords.  This allows rules that do
   9145 #             previewing to insert a start keyword to create a presumption
   9146 #             of detached running unless otherwise.
   9147 #   nostart: Countermands a previous start keyword; the following command
   9148 #             string is then to be obeyed by the system, and any necessary
   9149 #             detaching (as of a previewer) is done by the executed command(s).
   9150 #   internal: The following command string, of the form 'routine arguments'
   9151 #             specifies a call to the named Perl subroutine.
   9152 #   NONE:   This does not run anything, but causes an error message to be
   9153 #             printed.  This is provided to allow program names defined in the
   9154 #             configuration to flag themselves as unimplemented.
   9155 # Note that if the word "start" is duplicated at the beginning, that is
   9156 #   equivalent to a single "start".
   9157 #
   9158 # Return value is a list (pid, exitcode):
   9159 #   If a process is spawned sucessfully, and I know the PID,
   9160 #       return (pid, 0),
   9161 #   else if process is spawned sucessfully, but I do not know the PID,
   9162 #       return (0, 0),
   9163 #   else if process is run, 
   9164 #       return (0, exitcode of process)
   9165 #   else if I fail to run the requested process
   9166 #       return (0, suitable return code)
   9167 #   where return code is 1 if cmdline is null or begins with "NONE" (for
   9168 #       an unimplemented command)
   9169 #       or the return value of the Perl subroutine.
   9170     my $cmd_line = $_[0];
   9171     if ( $cmd_line eq '' ) {
   9172         traceback( "$My_name: Bug OR configuration error\n".
   9173                    "   In run of '$rule', attempt to run a null program" );
   9174         return (0, 1);
   9175     }
   9176     # Deal with latexmk-defined pseudocommands 'start' and 'NONE' 
   9177     # at front of command line:
   9178     my $detach = 0;
   9179     while ( $cmd_line =~ s/^start +// ) {
   9180         # But first remove extra starts (which may have been inserted
   9181         # to force a command to be run detached, when the command
   9182         # already contained a "start").
   9183         $detach = 1;
   9184     }
   9185     if ( $cmd_line =~ s/^nostart +// ) {
   9186         $detach = 0;
   9187     }
   9188     if ( $cmd_line =~ /^internal\s+([a-zA-Z_]\w*)\s+(.*)$/ ) {
   9189         my $routine = $1;
   9190         my @args = parse_quotes( $2 );
   9191         warn "$My_name: calling $routine( $2 )\n";
   9192         return ( 0, &$routine( @args ) );
   9193     }
   9194     elsif ( $cmd_line =~ /^internal\s+([a-zA-Z_]\w*)\s*$/ ) {
   9195         my $routine = $1;
   9196         warn "$My_name: calling $routine()\n";
   9197         return ( 0, &$routine() );
   9198     }
   9199     elsif ( $cmd_line =~ /^NONE/ ) {
   9200         warn "$My_name: ",
   9201              "Program not implemented for this version.  Command line:\n";
   9202         warn "   '$cmd_line'\n";
   9203         return (0, 1);
   9204     }
   9205     elsif ($detach) {
   9206         # Run detached.  How to do this depends on the OS
   9207         return &Run_Detached( $cmd_line );
   9208     }
   9209     else { 
   9210        # The command is given to system as a single argument, to force shell
   9211        # metacharacters to be interpreted:
   9212        return( 0, system( $cmd_line ) );
   9213    }
   9214 }  #END Run
   9215 
   9216 #************************************************************
   9217 
   9218 sub Run_Detached {
   9219 # Usage: Run_Detached ("program arguments ");
   9220 # Runs program detached.  Returns 0 on success, 1 on failure.
   9221 # Under UNIX use a trick to avoid the program being killed when the 
   9222 #    parent process, i.e., me, gets a ctrl/C, which is undesirable for pvc 
   9223 #    mode.  (The simplest method, system("program arguments &"), makes the 
   9224 #    child process respond to the ctrl/C.)
   9225 # Return value is a list (pid, exitcode):
   9226 #   If process is spawned sucessfully, and I know the PID,
   9227 #       return (pid, 0),
   9228 #   else if process is spawned sucessfully, but I do not know the PID,
   9229 #       return (0, 0),
   9230 #   else if I fail to spawn a process
   9231 #       return (0, 1)
   9232 
   9233     my $cmd_line = $_[0];
   9234 
   9235 ##    warn "Running '$cmd_line' detached...\n";
   9236     if ( $cmd_line =~ /^NONE / ) {
   9237         warn "$My_name: ",
   9238              "Program not implemented for this version.  Command line:\n";
   9239         warn "   '$cmd_line'\n";
   9240         return (0, 1);
   9241     }
   9242 
   9243     if ( "$^O" eq "MSWin32" ){
   9244         # Win95, WinNT, etc: Use MS's start command:
   9245         # Need extra double quotes to deal with quoted filenames: 
   9246         #    MSWin start takes first quoted argument to be a Window title. 
   9247         return( 0, system( "start \"\" $cmd_line" ) );
   9248     } else {
   9249         # Assume anything else is UNIX or clone
   9250         # For this purpose cygwin behaves like UNIX.
   9251         ## warn "Run_Detached.UNIX: A\n";
   9252         my $pid = fork();
   9253         ## warn "Run_Detached.UNIX: B pid=$pid\n";
   9254         if ( ! defined $pid ) {
   9255             ## warn "Run_Detached.UNIX: C\n";
   9256             warn "$My_name: Could not fork to run the following command:\n";
   9257             warn "   '$cmd_line'\n";
   9258             return (0, 1);
   9259         }
   9260         elsif( $pid == 0 ){
   9261            ## warn "Run_Detached.UNIX: D\n";
   9262            # Forked child process arrives here
   9263            # Insulate child process from interruption by ctrl/C to kill parent:
   9264            #     setpgrp(0,0);
   9265            # Perhaps this works if setpgrp doesn't exist 
   9266            #    (and therefore gives fatal error):
   9267            eval{ setpgrp(0,0);};
   9268            exec( $cmd_line );
   9269            # Exec never returns; it replaces current process by new process
   9270            die "$My_name forked process: could not run the command\n",
   9271                "  '$cmd_line'\n";
   9272         }
   9273         ##warn "Run_Detached.UNIX: E\n";
   9274         # Original process arrives here
   9275         return ($pid, 0);
   9276     }
   9277     # NEVER GET HERE.
   9278     ##warn "Run_Detached.UNIX: F\n";
   9279 } #END Run_Detached
   9280 
   9281 #************************************************************
   9282 
   9283 sub find_process_id {
   9284 # find_process_id(string) finds id of process containing string and
   9285 # being run by the present user.  Typically the string will be the
   9286 # name of the process or part of its command line.
   9287 # On success, this subroutine returns the process ID.
   9288 # On failure, it returns 0.
   9289 # This subroutine only works on UNIX systems at the moment.
   9290 
   9291     if ( $pid_position < 0 ) {
   9292         # I cannot do a ps on this system
   9293         return (0);
   9294     }
   9295 
   9296     my $looking_for = $_[0];
   9297     my @ps_output = `$pscmd`;
   9298     my @ps_lines = ();
   9299 
   9300 # There may be multiple processes.  Find only latest, 
   9301 #   almost surely the one with the highest process number
   9302 # This will deal with cases like xdvi where a script is used to 
   9303 #   run the viewer and both the script and the actual viewer binary
   9304 #   have running processes.
   9305     my @found = ();
   9306 
   9307     shift(@ps_output);  # Discard the header line from ps
   9308     foreach (@ps_output)   {
   9309         next unless ( /$looking_for/ ) ;
   9310 	s/^\s*//;
   9311         my @ps_line = split ('\s+');
   9312         push @found, $ps_line[$pid_position];
   9313         push @ps_lines, $_;
   9314     }
   9315 
   9316     if ($#found < 0) {
   9317        # No luck in finding the specified process.
   9318        return(0);
   9319     }
   9320     @found = reverse sort @found;
   9321     if ($diagnostics) {
   9322        print "Found the following processes concerning '$looking_for'\n",
   9323              "   @found\n",
   9324              "   I will use $found[0]\n";
   9325        print "   The relevant lines from '$pscmd' were:\n";
   9326        foreach (@ps_lines) { print "   $_"; }
   9327     }
   9328     return $found[0];
   9329 }
   9330 
   9331 #************************************************************
   9332 #************************************************************
   9333 #************************************************************
   9334 
   9335 #============================================
   9336 
   9337 sub cache_good_cwd {
   9338     # Set cached value of cwd to current cwd.
   9339     # Under cygwin, the cached value is converted to a native MSWin path so
   9340     # that the result can be used for input to MSWin programs as well
   9341     # as cygwin programs.
   9342     # Similarly for msys.
   9343     my $cwd = cwd();
   9344     if ( $^O eq "cygwin" ) {
   9345         my $cmd = "cygpath -w \"$cwd\"";
   9346         my $Win_cwd = `$cmd`;
   9347         chomp $Win_cwd;
   9348         if ( $Win_cwd ) {
   9349             $cwd = $Win_cwd;
   9350         }
   9351         else {
   9352             warn "$My_name: Could not correctly run command\n",
   9353                  "      '$cmd'\n",
   9354                  "  to get MSWin version of cygwin path\n",
   9355                  "     '$cwd'\n",
   9356                  "  The result was\n",
   9357                  "     '$Win_cwd'\n";
   9358         }
   9359     }
   9360     elsif ( $^O eq "msys" ) {
   9361 	$cwd =~ s[^/([a-z])/][\u$1:/];
   9362     }
   9363     $cache{cwd} = $cwd;
   9364 }  # END cache_good_cwd
   9365 
   9366 #============================================
   9367 
   9368 sub good_cwd {
   9369     # Return cwd, but under cygwin (or ...), convert to MSWin path.
   9370     # Use cached result, to save a possible expensive computation (running 
   9371     #  of extenal program under cygwin).
   9372     return $cache{cwd};
   9373 }  # END good_cwd
   9374 
   9375 #============================================
   9376 
   9377 #   Directory stack routines
   9378 
   9379 sub pushd {
   9380     push @dir_stack, [cwd(), $cache{cwd}];
   9381     if ( $#_ > -1) {
   9382         chdir $_[0]; 
   9383         &cache_good_cwd;
   9384     }
   9385 }
   9386 
   9387 #************************************************************
   9388 
   9389 sub popd {
   9390     if ($#dir_stack > -1 ) { 
   9391         my $Parr = pop @dir_stack;
   9392         chdir $$Parr[0]; 
   9393         $cache{cwd} = $$Parr[1];
   9394     }
   9395 }
   9396 
   9397 #************************************************************
   9398 
   9399 sub ifcd_popd {
   9400     if ( $do_cd ) {
   9401         warn "$My_name: Undoing directory change\n";
   9402         &popd;
   9403     }
   9404 }
   9405 
   9406 #************************************************************
   9407 
   9408 sub finish_dir_stack {
   9409     while ($#dir_stack > -1 ) { &popd; }
   9410 }
   9411 
   9412 #************************************************************
   9413 #************************************************************
   9414 # Break handling routines (for wait-loop in preview continuous)
   9415 
   9416 sub end_wait {
   9417     #  Handler for break: Set global variable $have_break to 1.
   9418     # Some systems (e.g., MSWin reset) appear to reset the handler.
   9419     # So I'll re-enable it
   9420     &catch_break;
   9421     $have_break = 1;
   9422 }
   9423 
   9424 #========================
   9425 
   9426 sub catch_break {
   9427 # Capture ctrl/C and ctrl/break.
   9428 # $SIG{INT} corresponds to ctrl/C on LINUX/?UNIX and MSWin
   9429 # $SIG{BREAK} corresponds to ctrl/break on MSWin, doesn't exist on LINUX
   9430     $SIG{INT} = \&end_wait;
   9431     if ( exists $SIG{BREAK} ) {
   9432         $SIG{BREAK} = \&end_wait;
   9433     }
   9434 }
   9435 
   9436 #========================
   9437 
   9438 sub default_break {
   9439 # Arrange for ctrl/C and ctrl/break to give default behavior
   9440     $SIG{INT} = 'DEFAULT';
   9441     if ( exists $SIG{BREAK} ) {
   9442         $SIG{BREAK} = 'DEFAULT';
   9443     }
   9444 }
   9445 
   9446 #************************************************************
   9447 #************************************************************