diff options
author | Karl Berry <karl@freefriends.org> | 2015-12-08 23:55:42 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2015-12-08 23:55:42 +0000 |
commit | 764327a56d9427a905c325daf151f344d31b7117 (patch) | |
tree | 4c251e4b0bfbc846c51d4e3d421ad60c1cf4ef01 | |
parent | 32dfcb4c5c886d97931290e76ed02234e8dbe485 (diff) |
* fmtutil.pl
(top level): separate @cmdline_cmds from @cmdline_options.
print_info final exit status.
(main): check for multiple cmds, or no cmd, given.
Check for non-option argument given.
Return instead of exit systematically.
--nohash: don't do ls-R stuff.
--catcfg: treat as a no-op option instead of an erroneous command.
--byfmt: allow .fmt|.mem|.bas[e] in argument value.
(callback_build_formats): keep track of and report $total number of
formats, and which @err formats failed to build.
Report if nothing actually happened.
If --strict, return error count (else 0).
(rebuild_one_format): print_info $fmt and $eng[ine] up front.
Specify $cmdline once and reuse it.
If --nohash, don't do ls-R stuff.
(save_fmtutil): If --nohash, don't do ls-R stuff.
(help) <$usage>: describe where formats are written, etc.
(throughout): msg wording, doc fixes, formatting.
git-svn-id: svn://tug.org/texlive/trunk@39056 c570f23f-e606-0410-a88d-b1316a301751
-rwxr-xr-x | Master/texmf-dist/scripts/texlive/fmtutil.pl | 473 |
1 files changed, 276 insertions, 197 deletions
diff --git a/Master/texmf-dist/scripts/texlive/fmtutil.pl b/Master/texmf-dist/scripts/texlive/fmtutil.pl index fd3cf4aee11..682d85ea03b 100755 --- a/Master/texmf-dist/scripts/texlive/fmtutil.pl +++ b/Master/texmf-dist/scripts/texlive/fmtutil.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# $Id: fmtutil.pl 38835 2015-11-13 22:32:58Z preining $ +# $Id$ # fmtutil - utility to maintain format files. # (Maintained in TeX Live:Master/texmf-dist/scripts/texlive.) # @@ -24,12 +24,11 @@ BEGIN { TeX::Update->import(); } - -my $svnid = '$Id: fmtutil.pl 38834 2015-11-12 22:32:58Z preining $'; -my $lastchdate = '$Date: 2015-11-12 09:30:58 +0900 (Fri, 13 Nov 2015) $'; +my $svnid = '$Id$'; +my $lastchdate = '$Date$'; $lastchdate =~ s/^\$Date:\s*//; $lastchdate =~ s/ \(.*$//; -my $svnrev = '$Revision: 38834 $'; +my $svnrev = '$Revision$'; $svnrev =~ s/^\$Revision:\s*//; $svnrev =~ s/\s*\$$//; my $version = "r$svnrev ($lastchdate)"; @@ -40,18 +39,11 @@ use File::Basename; use File::Copy; use Cwd; - -# # don't import anything automatically, this requires us to explicitly # call functions with TeXLive::TLUtils prefix, and makes it easier to # find and if necessary remove references to TLUtils use TeXLive::TLUtils qw(); -#use Data::Dumper; -#$Data::Dumper::Indent = 1; - - -# # numerical constants my $FMT_NOTSELECTED = 0; my $FMT_DISABLED = 1; @@ -97,20 +89,12 @@ our $texmfconfig = $TEXMFCONFIG; our $texmfvar = $TEXMFVAR; our $alldata; our %opts = ( quiet => 0 ); -our @cmdline_options = ( - "sys", - "cnffile=s@", - "fmtdir=s", - "no-engine-subdir", - "no-error-if-no-engine=s", - "no-error-if-no-format", - "quiet|silent|q", - "test", - "dolinks", - "force", + +# make a list of all the commands (as opposed to options), so we can +# reasonably check for multiple commands being (erroneously) given. +my @cmdline_cmds = ( # in same order as help message "all", "missing", - "nohash", "refresh", "byengine=s", "byfmt=s", @@ -118,25 +102,44 @@ our @cmdline_options = ( "enablefmt=s", "disablefmt=s", "listcfg", - "catcfg", "showhyphen=s", - "edit", +); + +our @cmdline_options = ( # in same order as help message + "sys", + "cnffile=s@", + "fmtdir=s", + "no-engine-subdir", + "no-error-if-no-engine=s", + "no-error-if-no-format", + "nohash", + "recorder", + "strict", + "quiet|silent|q", + "catcfg", + "dolinks", + "force", + "test", +# + @cmdline_cmds, "version", "help|h", - "strict", - "recorder", - "_dumpdata", +# + "edit", # omitted from help to discourage use + "_dumpdata", # omitted from help, data structure dump for debugging ); my $updLSR; my $mktexfmtMode = 0; -# make sure we only echo out *one* line in mktexfmt mode +# make sure we echo only *one* line in mktexfmt mode my $mktexfmtFirst = 1; -&main(); +my $status = &main(); +print_info("exiting with status $status\n"); +exit $status; -############### +# sub main { if ($prg eq "mktexfmt") { # mktexfmtMode: if called as mktexfmt, set to true. Will echo the @@ -144,9 +147,9 @@ sub main { # (and nothing else), since kpathsea can only deal with one. $mktexfmtMode = 1; GetOptions ( "help" => \$opts{'help'}, "version" => \$opts{'version'} ) - or die "Unknown option in command line arguments\n"; + or die "Unknown option in mktexfmt command line arguments\n"; if ($ARGV[0]) { - if ($ARGV[0] =~ m/^(.*)\.(fmt|mem|base)$/) { + if ($ARGV[0] =~ m/^(.*)\.(fmt|mem|base?)$/) { $opts{'byfmt'} = $1; } elsif ($ARGV[0] =~ m/\./) { die "unknown format type: $ARGV[0]"; @@ -154,43 +157,63 @@ sub main { $opts{'byfmt'} = $ARGV[0]; } } else { - die "missing argument to mktexmft"; + die "missing argument to mktexfmt"; } } else { - GetOptions(\%opts, @cmdline_options) or - die "Try \"$prg --help\" for more information.\n"; + # fmtutil mode. + GetOptions(\%opts, @cmdline_options) + || die "Try \"$prg --help\" for more information.\n"; + if (@ARGV) { + die "$0: Unexpected non-option argument(s): @ARGV\n" + . "Try \"$prg --help\" for more information.\n"; + } } - - help() if $opts{'help'}; + help() if $opts{'help'}; if ($opts{'version'}) { print version(); - exit (0); + exit 0; # no final print_info } - - # these two functions should go to TLUtils! + { # if two commands were given, complain and give up. + my @cmds = (); + for my $c (@cmdline_cmds) { + $c =~ s,=.*$,,; # remove =s getopt spec + push(@cmds, $c) if exists $opts{$c}; # remember if getopt found it + # we could save/report the specified arg too, but maybe not worth it. + } + if (@cmds > 1) { + print_error("multiple commands found: @cmds\n" + . "Try $prg --help if you need it.\n"); + return 1; + } elsif (@cmds == 0) { + print_error("no command specified; try $prg --help if you need it.\n"); + return 1; + } + } + + # these two functions should go to TLUtils (for use in updmap) check_hidden_sysmode(); determine_config_files("fmtutil.cnf"); my $changes_config_file = $alldata->{'changes_config'}; - - read_fmtutil_files(@{$opts{'cnffile'}}); - - # we do changes always in the used config file with the highest - # priority + # we do changes always in the used config file with the highest priority my $bakFile = $changes_config_file; $bakFile =~ s/\.cfg$/.bak/; my $changed = 0; - # should be replaces by new mktexlsr perl version - $updLSR = new TeX::Update; - $updLSR->mustexist(0); + read_fmtutil_files(@{$opts{'cnffile'}}); + + unless ($opts{"nohash"}) { + # should be replaced by new mktexlsr perl version + $updLSR = new TeX::Update; + $updLSR->mustexist(0); + } my $cmd; if ($opts{'edit'}) { if ($opts{"dry-run"}) { printf STDERR "No, are you joking, you want to edit with --dry-run?\n"; - exit 1; + return 1; } # it's not a good idea to edit fmtutil.cnf manually these days, # but for compatibility we'll silently keep the option. @@ -205,6 +228,7 @@ sub main { } system($editor, $changes_config_file); $changed = files_are_different($bakFile, $changes_config_file); + } elsif ($opts{'showhyphen'}) { my $f = $opts{'showhyphen'}; if ($alldata->{'merged'}{$f}) { @@ -212,7 +236,7 @@ sub main { for my $e (sort @all_engines) { my $hf = $alldata->{'merged'}{$f}{$e}{'hyphen'}; next if ($hf eq '-'); - my $ff = `kpsewhich -progname=$f -format=tex $hf`; + my $ff = `kpsewhich -progname='$f' -format=tex '$hf'`; chomp($ff); if ($ff ne "") { if ($#all_engines > 0) { @@ -220,48 +244,57 @@ sub main { } printf "$ff\n"; } else { - print_warning("hyphenfile $hf (for $f/$e) not found!\n"); - abort(); + print_warning("hyphenfile (for $f/$e) not found: $hf\n"); + return 1; } } } - } elsif ($opts{'catcfg'}) { - print_warning("--catcfg command not supported anymore!\n"); - exit(1); + } elsif ($opts{'listcfg'}) { return callback_list_cfg(); - exit(1); + } elsif ($opts{'disablefmt'}) { return callback_enable_disable_format($changes_config_file, $opts{'disablefmt'}, 'disabled'); } elsif ($opts{'enablefmt'}) { return callback_enable_disable_format($changes_config_file, $opts{'enablefmt'}, 'enabled'); - } elsif ($opts{'byfmt'}) { - return callback_build_formats('byfmt', $opts{'byfmt'}); } elsif ($opts{'byengine'}) { return callback_build_formats('byengine', $opts{'byengine'}); + + } elsif ($opts{'byfmt'}) { + # for this option, allow/ignore an extension. + (my $fmtname = $opts{'byfmt'}) =~ s,\.(fmt|mem|base?)$,,; + return callback_build_formats('byfmt', $fmtname); + } elsif ($opts{'byhyphen'}) { return callback_build_formats('byhyphen', $opts{'byhyphen'}); + } elsif ($opts{'refresh'}) { return callback_build_formats('refresh'); + } elsif ($opts{'missing'}) { return callback_build_formats('missing'); + } elsif ($opts{'all'}) { return callback_build_formats('all'); + } elsif ($opts{'_dumpdata'}) { dump_data(); - exit(0); + } else { - print_error("missing command; try fmtutil --help if you need it.\n"); - exit(1); + # redundant with check above, but just in case ... + print_error("missing command; try $prg --help if you need it.\n"); + return 1; } - if (!$opts{'nohash'}) { - print "$prg: Updating ls-R files.\n" if !$opts{'quiet'}; + unless ($opts{'nohash'}) { + # TODO should only do this if built something, e.g., not --listcfg + print_info("updating ls-R files\n"); $updLSR->exec() unless $opts{"dry-run"}; } + # some simpler options return 0; } @@ -273,17 +306,14 @@ sub dump_data { } -# build_formats -# (re)builds the formats as selected - +# callback_build_formats - (re)builds the formats as selected, +# returns exit status or dies. Exit status is always zero unless +# --strict is specified, in which case it's the number of failed builds +# (presumably always less than 256 :). +# sub callback_build_formats { my ($what, $whatarg) = @_; - my $suc = 0; - my $err = 0; - my $disabled = 0; - my $nobuild = 0; - my $notavail = 0; - # + # set up a tmp dir # On W32 it seems that File::Temp creates restrictive permissions (ok) # that are copied over with the files created inside it (not ok). @@ -307,17 +337,18 @@ sub callback_build_formats { $tmpdir = File::Temp::tempdir(CLEANUP => 1); } # set up destination directory - $opts{'fmtdir'} || ( $opts{'fmtdir'} = "$texmfvar/web2c" ) ; + $opts{'fmtdir'} ||= "$texmfvar/web2c"; TeXLive::TLUtils::mkdirhier($opts{'fmtdir'}) if (! -d $opts{'fmtdir'}); if (! -w $opts{'fmtdir'}) { - print_error("format directory \`" . $opts{'fmtdir'} ."' is not writable\n"); - exit (1); + print_error("format directory not writable: $opts{fmtdir}\n"); + exit 1; } # since the directory does not exist, we can make it absolute with abs_path # without any trickery around non-existing dirs $opts{'fmtdir'} = Cwd::abs_path($opts{'fmtdir'}); # for safety, check again - die ("abs_path didn't succeed, that is strange: $?") if !$opts{'fmtdir'}; + die "abs_path failed, strange: $!" if !$opts{'fmtdir'}; + print_info("writing formats under $opts{fmtdir}\n"); # report # code taken over from the original shell script for KPSE_DOT etc my $thisdir = cwd(); @@ -325,68 +356,89 @@ sub callback_build_formats { # due to KPSE_DOT, we don't search the current directory, so include # it explicitly for formats that \write and later on \read - $ENV{'TEXINPUTS'} = "$tmpdir$sep" . ($ENV{'TEXINPUTS'} ? $ENV{'TEXINPUTS'} : ""); + $ENV{'TEXINPUTS'} ||= ""; + $ENV{'TEXINPUTS'} = "$tmpdir$sep$ENV{TEXINPUTS}"; + # # for formats that load other formats (e.g., jadetex loads latex.fmt), # add the current directory to TEXFORMATS, too. Currently unnecessary # for MFBASES and MPMEMS. - $ENV{'TEXFORMATS'} = "$tmpdir$sep" . ($ENV{'TEXFORMATS'} ? $ENV{'TEXFORMATS'} : ""); + $ENV{'TEXFORMATS'} ||= ""; + $ENV{'TEXFORMATS'} = "$tmpdir$sep$ENV{TEXFORMATS}"; - # # switch to temporary directory for format generation - chdir($tmpdir) || die("Cannot change to directory $tmpdir: $?"); + chdir($tmpdir) || die "Cannot change to directory $tmpdir: $!"; # we rebuild formats in two rounds: # round 1: only formats with the same name as engine (pdftex/pdftex) # round 2: all other formats # reason: later formats might need earlier formats to be already - # initialized (xmltex is one of these examples AFAIR) - my $val; + # initialized, e.g., xmltex. + my $suc = 0; + my $err = 0; + my @err = (); + my $disabled = 0; + my $nobuild = 0; + my $notavail = 0; + my $total = 0; for my $fmt (keys %{$alldata->{'merged'}}) { for my $eng (keys %{$alldata->{'merged'}{$fmt}}) { next if ($fmt ne $eng); - $val = select_and_rebuild_format($fmt, $eng, $what, $whatarg); - if ($val == $FMT_DISABLED) { $disabled++; } + $total++; + my $val = select_and_rebuild_format($fmt, $eng, $what, $whatarg); + if ($val == $FMT_DISABLED) { $disabled++; } elsif ($val == $FMT_NOTSELECTED) { $nobuild++; } - elsif ($val == $FMT_FAILURE) { $err++; } + elsif ($val == $FMT_FAILURE) { $err++; push (@err, "$eng/$fmt"); } elsif ($val == $FMT_SUCCESS) { $suc++; } elsif ($val == $FMT_NOTAVAIL) { $notavail++; } - else { print_error("callback_build_format: unknown return from select_and_rebuild.\n"); } + else { print_error("callback_build_format (round 1): unknown return " + . "from select_and_rebuild.\n"); } } } for my $fmt (keys %{$alldata->{'merged'}}) { for my $eng (keys %{$alldata->{'merged'}{$fmt}}) { next if ($fmt eq $eng); - $val = select_and_rebuild_format($fmt, $eng, $what, $whatarg); - if ($val == $FMT_DISABLED) { $disabled++; } + $total++; + my $val = select_and_rebuild_format($fmt, $eng, $what, $whatarg); + if ($val == $FMT_DISABLED) { $disabled++; } elsif ($val == $FMT_NOTSELECTED) { $nobuild++; } - elsif ($val == $FMT_FAILURE) { $err++; } + elsif ($val == $FMT_FAILURE) { $err++; push (@err, "$eng/$fmt"); } elsif ($val == $FMT_SUCCESS) { $suc++; } elsif ($val == $FMT_NOTAVAIL) { $notavail++; } - else { print_error("callback_build_format: unknown return from select_and_rebuild.\n"); } + else { print_error("callback_build_format (round 2): unknown return " + . "from select_and_rebuild.\n"); } } } + + # if the user asked to rebuild something, but we did nothing, report. + if ($err + $suc == 0) { + print_info("did not find entry for $what=$whatarg, skipped\n"); + } my $stdo = ($mktexfmtMode ? \*STDERR : \*STDOUT); for (@deferred_stdout) { print $stdo $_; } for (@deferred_stderr) { print STDERR $_; } - print_info("Disabled formats: $disabled\n") if ($disabled); - print_info("Successfully rebuild formats: $suc\n") if ($suc); - print_info("Not selected formats: $nobuild\n") if ($nobuild); - print_info("Not available formats: $notavail\n") if ($notavail); - print_info("Failure during builds: $err\n") if ($err); - chdir($thisdir) || warn("chdir($thisdir) failed: $!"); + # + print_info("Disabled formats: $disabled\n") if ($disabled); + print_info("Successfully rebuilt formats: $suc\n") if ($suc); + print_info("Not selected formats: $nobuild\n") if ($nobuild); + print_info("Not available formats: $notavail\n") if ($notavail); + print_info("Failed to build: $err (@err)\n") if ($err); + print_info("Total formats: $total\n"); + chdir($thisdir) || warn "chdir($thisdir) failed: $!"; if (win32()) { # try to remove the tmpdir with all files TeXLive::TLUtils::rmtree($tmpdir); } - return 0; + # return + return $opts{"strict"} ? $err : 0; } -# select_and_rebuild_format +# select_and_rebuild_format # check condition and rebuild the format if selected # return values: $FMT_* +# sub select_and_rebuild_format { my ($fmt, $eng, $what, $whatarg) = @_; - return($FMT_DISABLED) + return $FMT_DISABLED if ($alldata->{'merged'}{$fmt}{$eng}{'status'} eq 'disabled'); my $doit = 0; # we just identify 'all', 'refresh', 'missing' @@ -397,8 +449,8 @@ sub select_and_rebuild_format { $doit = 1 if ($what eq 'byengine' && $eng eq $whatarg); $doit = 1 if ($what eq 'byfmt' && $fmt eq $whatarg); # TODO - # original fmtutil.sh was more strict about existence of the hyphen file - # not sure how we proceed here + # original fmtutil.sh was stricter about existence of the hyphen file + # not sure how we proceed here; let's implicitly ignore. $doit = 1 if ($what eq 'byhyphen' && $whatarg eq (split(/,/ , $alldata->{'merged'}{$fmt}{$eng}{'hyphen'}))[0]); @@ -409,11 +461,13 @@ sub select_and_rebuild_format { } } -# rebuild_one_format +# rebuild_one_format # takes fmt/eng and rebuilds it, irrelevant of any setting -# return value FMT_ +# return value FMT_* +# sub rebuild_one_format { my ($fmt, $eng) = @_; + print_info("--- remaking $fmt with $eng\n"); # get variables my $hyphen = $alldata->{'merged'}{$fmt}{$eng}{'hyphen'}; @@ -434,7 +488,6 @@ sub rebuild_one_format { unlink glob "*.pool"; - # addargs processing: # can contain: # nls stuff (pool/tcx) see below @@ -452,7 +505,7 @@ sub rebuild_one_format { if ($eng eq "mpost") { $fmtfile .= ".mem" ; $kpsefmt = "mp" ; - $texengine = "metapost"; + $texengine = "metapost"; # the directory, not the executable } elsif ($eng =~ m/^mf(w|-nowin)?$/) { $fmtfile .= ".base" ; $kpsefmt = "mf" ; @@ -487,14 +540,15 @@ sub rebuild_one_format { if ($pool) { chomp ( my $poolfile = `kpsewhich -progname=$eng $pool.poo 2>$nul` ); if ($poolfile && -f $poolfile) { - print_verbose ("attempting to create localized format using pool=$pool and tcx=$tcx.\n"); + print_verbose("attempting to create localized format " + . "using pool=$pool and tcx=$tcx.\n"); File::Copy($poolfile, "$eng.pool"); $tcxflag = "-translate-file=$tcx" if ($tcx); $localpool = 1; } } - # Check for infinite recursion before running the iniTeX: + # Check for infinite recursion before running the iniengine: # We do this check only if we are running in mktexfmt mode # otherwise double format definitions will create an infinite loop, too if ($mktexfmtMode) { @@ -521,7 +575,9 @@ sub rebuild_one_format { } } - print_verbose("running \`$eng -ini $tcxflag $jobswitch $prgswitch $texargs' ...\n"); + my $cmdline = "$eng -ini $tcxflag $recorderswitch $jobswitch " + . "$prgswitch $texargs"; + print_verbose("running \`$cmdline' ...\n"); { my $texpool = $ENV{'TEXPOOL'}; @@ -529,17 +585,16 @@ sub rebuild_one_format { $ENV{'TEXPOOL'} = cwd() . $sep . ($texpool ? $texpool : ""); } - # in mktexfmtMode we need to redirect *all* output to stderr - my $cmdline = "$eng -ini $tcxflag $recorderswitch $jobswitch $prgswitch $texargs"; + # in mktexfmtMode we must redirect *all* output to stderr $cmdline .= " >&2" if $mktexfmtMode; $cmdline .= " <$nul"; my $retval = system($cmdline); if ($retval != 0) { $retval /= 256 if ($retval > 0); - print_deferred_error("call to \`$eng -ini $tcxflag $jobswitch $prgswitch $texargs' returned error code $retval\n"); + print_deferred_error("running \`$cmdline' return status $retval\n"); # # original shell script did *not* check the return value - # we keep this behaviour, but add an option --strict that + # we keep this behavior, but add an option --strict that # errors out on all failures. if ($opts{'strict'}) { print_deferred_error("return error due to options --strict\n"); @@ -557,10 +612,9 @@ sub rebuild_one_format { } - # # check and install of fmt and log files if (! -f $fmtfile) { - print_deferred_error("\`$eng -ini $tcxflag $jobswitch $prgswitch $texargs' failed\n"); + print_deferred_error("\`$cmdline' failed (no $fmtfile)\n"); return $FMT_FAILURE; } @@ -569,11 +623,12 @@ sub rebuild_one_format { return $FMT_FAILURE; } - open LOGFILE, "<$fmt.log" || print_deferred_warning("cannot open $fmt.log?\n"); + open (LOGFILE, "<$fmt.log") + || print_deferred_warning("cannot open $fmt.log, strange: $!\n"); my @logfile = <LOGFILE>; close LOGFILE; if (grep(/^!/, @logfile) > 0) { - print_deferred_error("\`$eng -ini $tcxflag $jobswitch $prgswitch $texargs' had errors.\n"); + print_deferred_error("\`$cmdline' had errors.\n"); } my $fulldestdir; @@ -588,6 +643,9 @@ sub rebuild_one_format { print_deferred_error("Cannot move $fmt.log to $fulldestdir.\n"); } if ($opts{'recorder'}) { + # the recorder output is used by check-fmttriggers to determine + # package dependencies for each format. Unfortunately omega-based + # engines gratuitiously changed the extension from .fls to .ofl. my $recfile = $fmt . ($fmt =~ m/^(aleph|lamed)$/ ? ".ofl" : ".fls"); if (!File::Copy::move( $recfile, "$fulldestdir/$recfile")) { print_deferred_error("Cannot move $recfile to $fulldestdir.\n"); @@ -620,7 +678,7 @@ sub rebuild_one_format { # if cp "$destfile" "$mplib_mem_file" </dev/null; then # mktexupd "$fulldestdir" "$mplib_mem_name" # else - # # failure to copy merits failure handling: e.g., full file system. + # # failure to copy merits failure handling: e.g., full file system. # log_failure "cp $destfile $mplib_mem_file failed." # fi # else @@ -633,27 +691,31 @@ sub rebuild_one_format { $mktexfmtFirst = 0; } - $updLSR->add($destfile); - $updLSR->exec(); - $updLSR->reset(); + unless ($opts{'nohash'}) { + $updLSR->add($destfile); + $updLSR->exec(); + $updLSR->reset(); + } return $FMT_SUCCESS; + } else { print_deferred_error("Cannot move $fmtfile to $destfile.\n"); if (-f $destfile) { - # remove the empty file possibly left over if a near-full file system. - print_verbose("Removing partial file $destfile after move failure ...\n"); - unlink($destfile) || print_deferred_error("Removing $destfile failed.\n"); + # remove the empty file possibly left over if near-full file system. + print_verbose("Removing partial file after move failure: $destfile\n"); + unlink($destfile) + || print_deferred_error("unlink($destfile) failed: $!\n"); } return $FMT_FAILURE; } - print_deferred_error("we should not be here $fmt/$eng\n"); + print_deferred_error("we should not be here! $fmt/$eng\n"); return $FMT_FAILURE; } -# +# # enable_disable_format_engine # assumes that format/engine is already defined somewhere, # i.e., it $alldata->{'merged'}{$fmt}{$eng} is defined @@ -685,7 +747,7 @@ sub enable_disable_format_engine { } } else { print_error("enable_disable_format_engine: unknown mode $mode\n"); - exit(1); + exit 1; } } @@ -715,7 +777,7 @@ sub callback_enable_disable_format { if ($alldata->{'merged'}{$fmt}{$eng}) { return enable_disable_format_engine($tc, $fmt, $eng, $mode); } else { - print_warning("Format/engine combination: $fmt/$eng is not defined.\n"); + print_warning("Format/engine combination $fmt/$eng is not defined.\n"); print_warning("Cannot (de)activate it.\n"); return -1; } @@ -745,6 +807,7 @@ sub callback_enable_disable_format { } } + sub callback_list_cfg { my @lines; for my $f (keys %{$alldata->{'merged'}}) { @@ -764,6 +827,9 @@ sub callback_list_cfg { print @lines; } + +# sets %alldata. +# sub read_fmtutil_files { my (@l) = @_; for my $l (@l) { read_fmtutil_file($l); } @@ -795,11 +861,11 @@ sub read_fmtutil_files { } } +# sub read_fmtutil_file { my $fn = shift; - if (!open(FN,"<$fn")) { - die ("Cannot read $fn: $!"); - } + open(FN, "<$fn") || die "Cannot read $fn: $!"; + # # we count lines from 0 ..!!!! my $i = -1; my @lines = <FN>; @@ -832,7 +898,8 @@ sub read_fmtutil_file { } else { $alldata->{'fmtutil'}{$fn}{'formats'}{$a}{$b}{'hyphen'} = $c; $alldata->{'fmtutil'}{$fn}{'formats'}{$a}{$b}{'args'} = "@rest"; - $alldata->{'fmtutil'}{$fn}{'formats'}{$a}{$b}{'status'} = ($disabled ? 'disabled' : 'enabled'); + $alldata->{'fmtutil'}{$fn}{'formats'}{$a}{$b}{'status'} + = ($disabled ? 'disabled' : 'enabled'); $alldata->{'fmtutil'}{$fn}{'formats'}{$a}{$b}{'line'} = $i; } } @@ -840,10 +907,9 @@ sub read_fmtutil_file { -# +# # FUNCTIONS THAT SHOULD GO INTO TLUTILS.PM # and also be reused in updmap.pl!!! -# sub check_hidden_sysmode { @@ -864,8 +930,6 @@ sub check_hidden_sysmode { } } - - if ($opts{'sys'}) { # we are running as updmap-sys, make sure that the right tree is used $texmfconfig = $TEXMFSYSCONFIG; @@ -874,6 +938,9 @@ sub check_hidden_sysmode { } +# sets global $alldata->{'changes_config'} to the config file to be +# changed if requested. +# sub determine_config_files { my $fn = shift; @@ -991,11 +1058,13 @@ sub save_fmtutil { open (FN, ">$fn") || die "$prg: can't write to $fn: $!"; my @lines = @{$fmtf{'lines'}}; if (!@lines) { - print "Creating new config file $fn\n"; - # update lsR database - $updLSR->add($fn); - $updLSR->exec(); - $updLSR->reset(); + print_verbose ("Creating new config file $fn\n"); + unless ($opts{"nohash"}) { + # update lsR database + $updLSR->add($fn); + $updLSR->exec(); + $updLSR->reset(); + } } # collect the lines with data my %line_to_fmt; @@ -1080,12 +1149,11 @@ sub reset_root_home { } } -# # printing to stdout (in mktexfmtMode also going to stderr!) -# print_info can be supressed with --quiet +# print_info can be suppressed with --quiet # print_verbose cannot be suppressed # printing to stderr -# print_warning can be supressed with --quiet +# print_warning can be suppressed with --quiet # print_error cannot be suppressed # sub print_info { @@ -1135,7 +1203,7 @@ sub win32 { -# help, version. +# version, help. sub version { my $ret = sprintf "%s version %s\n", $prg, $version; @@ -1148,52 +1216,55 @@ Usage: $prg [OPTION] ... [COMMAND] or: $prg-sys [OPTION] ... [COMMAND] or: mktexfmt FORMAT.fmt|BASE.base|MEM.mem|FMTNAME.EXT -Rebuild and manage TeX formats, Metafont bases and MetaPost mems. +Rebuild and manage TeX fmts, Metafont bases and MetaPost mems, +collectively called "formats" here. If the command name ends in mktexfmt, only one format can be created. The only options supported are --help and --version, and the command -line must consist of either a format name, with its extension, or a -plain name that is passed as the argument to --byfmt (see below). The -full name of the generated file (if any) is written to stdout, and -nothing else. +line must be either a format name, with extension, or a plain name that +is passed as the argument to --byfmt (see below). The full name of the +generated file (if any) is written to stdout, and nothing else. -If not operating in mktexfmt mode, the command line can be more general, -and multiple formats can be generated, as follows. +If not operating in mktexfmt mode, exactly one command must be given, +extensions should generally not be specified, no non-option arguments +are allowed, and multiple formats can be generated, as follows. Options: - --cnffile FILE read FILE instead of fmtutil.cnf - (can be given multiple times, in which case - all the files are used) - --fmtdir DIRECTORY - --no-engine-subdir don't use engine-specific subdir of the fmtdir - --no-error-if-no-format exit successfully if no format is selected + --sys use TEXMFSYS{VAR,CONFIG} instead of TEXMF{VAR,CONFIG} + --cnffile FILE read FILE instead of fmtutil.cnf + (can be given multiple times, in which case + all the files are used) + --fmtdir DIR write formats under DIR instead of TEXMF[SYS]VAR + --no-engine-subdir don't use engine-specific subdir of the fmtdir + --no-error-if-no-format exit successfully if no format is selected --no-error-if-no-engine=ENGINE1,ENGINE2,... - exit successfully even if the required engine - is missing, if it is included in the list. - --quiet be silent - --recorder pass the -recorder option and save .fls files - --test (not implemented, just for compatibility) - --dolinks (not implemented, just for compatibility) - --force (not implemented, just for compatibility) + exit successfully even if a required engine + is missing, if it is included in the list. + --nohash don't update ls-R files + --recorder pass the -recorder option and save .fls files + --strict exit with bad status if a format fails to build + --quiet be silent + --catcfg (does nothing, exists for compatibility) + --dolinks (does nothing, exists for compatibility) + --force (does nothing, exists for compatibility) + --test (does nothing, exists for compatibility) Commands: - --all recreate all format files - --missing create all missing format files - --refresh recreate only existing format files - --byengine ENGINENAME (re)create formats using ENGINENAME - --byfmt FORMATNAME (re)create format for FORMATNAME - --byhyphen HYPHENFILE (re)create formats that depend on HYPHENFILE - --enablefmt FORMATNAME[/ENGINE] enable formatname in config file - --disablefmt FORMATNAME[/ENGINE] disable formatname in config file - If multiple formats have the same name but - different engines, the /ENGINE specifier is - required. - --listcfg list (enabled and disabled) configurations, - filtered to available formats - --catcfg output the content of the config file - --showhyphen FORMATNAME print name of hyphenfile for format FORMATNAME - --version show version information and exit - --help show this message and exit + --all recreate all format files + --missing create all missing format files + --refresh recreate only existing format files + --byengine ENGINE (re)create formats built with ENGINE + --byfmt FORMAT (re)create format FORMAT + --byhyphen HYPHENFILE (re)create formats that depend on HYPHENFILE + --enablefmt FORMAT[/ENGINE] enable FORMAT, as built with ENGINE + --disablefmt FORMAT[/ENGINE] disable FORMAT, as built with ENGINE + If multiple formats have the same name and + different engines, /ENGINE specifier is required. + --listcfg list (enabled and disabled) configurations, + filtered to available formats + --showhyphen FORMAT print name of hyphen file for FORMAT + --version show version information and exit + --help show this message and exit Explanation of trees and files normally used: @@ -1229,7 +1300,19 @@ Explanation of trees and files normally used: According to the actions, fmtutil might write to one of the given files or create a new fmtutil.cnf, described further below. -Where changes are saved: +Where formats are written: + + By default, format files are (re)written in TEXMFSYSVAR/ENGINE by + fmtutil-sys, and TEXMFVAR/ENGINE by fmtutil, where /ENGINE is a + subdirectory named for the engine used, such as "pdftex". + + If the --fmtdir=DIR option is specified, DIR is used instead of + TEXMF[SYS]VAR, but the /ENGINE subdir is still used by default. + + In any case, if the --no-engine-subdir option is specified, the + /ENGINE subdir is omitted. + +Where configuration changes are saved: If config files are given on the command line, then the first one given will be used to save any changes from --enable or --disable. @@ -1246,8 +1329,8 @@ Where changes are saved: In general, the idea is that if a given config file is not writable, a higher-level one can be used. That way, the distribution's settings - can be overridden for system-wide using TEXMFLOCAL, and then system - settings can be overridden again in a particular user's TEXMFHOME. + can be overridden system-wide using TEXMFLOCAL, and system settings + can be overridden again in a particular user's TEXMFHOME. Resolving multiple definitions of a format: @@ -1257,18 +1340,16 @@ Resolving multiple definitions of a format: Disabling formats: fmtutil.cnf files with higher priority (listed earlier) can disable - formats mentioned in lower priority (listed later) fmtutil.cnf files by - writing, e.g., + formats in lower priority (listed later) fmtutil.cnf files by + writing a line like \#! <fmtname> <enginename> <hyphen> <args> - in the higher-priority fmtutil.cnf file. (The \#! must be at the + in the higher-priority fmtutil.cnf file. The \#! must be at the beginning of the line, with at least one space or tab afterward, and - whitespace between each word on the list.) + there must be whitespace between each word on the list. - As an example, suppose you have want to disable the luajitlatex format. - You can create the file \$TEXMFCONFIG/web2c/fmtutil.cnf with the content + For example, you can disable the luajitlatex format by creating + the file \$TEXMFCONFIG/web2c/fmtutil.cnf with the line #! luajitlatex luajittex language.dat,language.dat.lua lualatex.ini - and call $prg. - (As it happens, the luajittex-related formats are precisely why the --no-error-if-no-engine option exists, since luajittex cannot be compiled on all platforms.) @@ -1289,11 +1370,9 @@ EOF ; print &version(); print $usage; - exit 0; + exit 0; # no final print_info } - - ### Local Variables: ### perl-indent-level: 2 ### tab-width: 2 |