summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Master/tlpkg/dev/multi-updmap.pl312
1 files changed, 290 insertions, 22 deletions
diff --git a/Master/tlpkg/dev/multi-updmap.pl b/Master/tlpkg/dev/multi-updmap.pl
index def1831e8aa..7680da76339 100644
--- a/Master/tlpkg/dev/multi-updmap.pl
+++ b/Master/tlpkg/dev/multi-updmap.pl
@@ -14,6 +14,8 @@
# limitation.
#
+my ($TEXMFROOT, $TEXMFMAIN, $TEXMFVAR);
+
BEGIN {
$^W=1;
$TEXMFROOT = `kpsewhich -var-value=TEXMFROOT`;
@@ -21,7 +23,10 @@ BEGIN {
print STDERR "updmap: Cannot find TEXMFROOT, aborting!\n";
exit 1;
}
- chomp($TEXMFROOT = `kpsewhich -var-value=TEXMFROOT`);
+ chomp($TEXMFROOT);
+ chomp($TEXMFMAIN =`kpsewhich --var-value=TEXMFMAIN`);
+ chomp($TEXMFVAR = `kpsewhich -var-value=TEXMFVAR`);
+ chomp($TEXMFCONFIG = `kpsewhich -var-value=TEXMFCONFIG`);
unshift (@INC, "$TEXMFROOT/tlpkg");
}
@@ -32,11 +37,39 @@ use TeXLive::TLUtils qw(mkdirhier mktexupd win32 log);
use Getopt::Long qw(:config no_autoabbrev ignore_case_always);
use Pod::Usage;
-my $short_progname = "updmap";
+my $prg = TeXLive::TLUtils::basename($0);
+# used for testing only
use Data::Dumper;
-my %opts;
+my %opts = ( quiet => 0, nohash => 0, nomkmap => 0 );
+my @cmdline_options = (
+ "cnffile=s@",
+ "copy",
+ "disable=s@",
+ "dvipdfmoutputdir=s",
+ "dvipsoutputdir=s",
+ "enable=s{1,2}",
+ "edit",
+ "force",
+ "listavailablemaps",
+ "listmaps|l",
+ "nohash",
+ "nomkmap",
+ "dry-run|n",
+ "outputdir=s",
+ "pdftexoutputdir=s",
+ "quiet|silent|q",
+ # the following is a correct specification of an option according
+ # to the manual, but it does not work!
+ # we will treat that option by itself in processOptions
+ #"setoption=s@{1,2}",
+ "showoptions=s@",
+ "syncwithtrees",
+ "version",
+ "help|h"
+ );
+
my %settings = (
dvipsPreferOutline => [ qw/true false/ ],
LW35 => [ qw/URW URWkb ADOBE ADOBEkb/ ],
@@ -50,17 +83,211 @@ my %settings = (
###############
sub main {
- testmain();
+ processOptions();
+
+ help() if $opts{'help'};
+
+ if ($opts{'showoptions'}) {
+ showOptions(@{$opts{'showoptions'}});
+ exit 0;
+ }
+
+ # determine which config files shold be used
+ # replaces the former "setupCfgFile"
+ if ($opts{'cnffile'}) {
+ for my $f (@{$opts{'cnffile'}}) {
+ if (! -f $f) {
+ die "$prg: Config file \"$f\" not found.";
+ }
+ }
+ } else {
+ @{$opts{'cnffile'}} = `kpsewhich -all updmap.cfg`;
+ chomp(@{$opts{'cnffile'}});
+ }
+
+ if ($opts{'listmaps'}) {
+ listMaps();
+ exit 0;
+ }
+
+ if ($opts{'syncwithtrees'}) {
+ warning("NOT IMPLEMENTED syncwithtrees!\n");
+ exit 1;
+ }
+
+ # we do changes always in the used config file with the highest
+ # priority
+ my ($top_config_file) = @{$opts{'cnffile'}};
+ my $bakFile = $top_config_file;
+ $bakFile =~ s/\.cfg$/.bak/;
+ &copyFile($top_config_file, $bakFile);
+
+ my $cmd;
+ my $data = read_updmap_files(@{$opts{'cnffile'}});
+ if ($opts{'edit'}) {
+ # it's not a good idea to edit updmap.cfg manually these days,
+ # but for compatibility we'll silently keep the option.
+ $cmd = 'edit';
+ my $editor = $ENV{'VISUAL'} || $ENV{'EDITOR'};
+ $editor ||= (&win32 ? "notepad" : "vi");
+ system($editor, $top_config_file);
+ } elsif ($opts{'setoption'}) {
+ $cmd = 'setOption';
+ warning("NOT IMPLEMENTED setoption!\n");
+ exit 1;
+ } elsif ($opts{'enable'}) {
+ $cmd = 'enableMap';
+ warning("NOT IMPLEMENTED enable!\n");
+ exit 1;
+ } elsif ($opts{'disable'}) {
+ $cmd = 'disableMap';
+ warning("NOT IMPLEMENTED disable!\n");
+ exit 1;
+ }
+
+ if ($cmd && !$opts{'force'} && files_are_equal($bakFile, $top_config_file)) {
+ print "$top_config_file unchanged. Map files not recreated.\n"
+ if !$opts{'quiet'};
+ } else {
+ if (!$opts{'nomkmap'}) {
+ setupOutputDir("dvips");
+ setupOutputDir("pdftex");
+ mkMaps($data);
+ }
+ unlink ($bakFile);
+ }
+
+ my $updLSR = &mktexupd();
+ $updLSR->{mustexist}(0);
+ if (!$opts{'nohash'}) {
+ print "$prg: Updating ls-R files.\n" if !$opts{'quiet'};
+ $updLSR->{exec}();
+ }
}
-sub testmain {
+
+sub mkMaps {
+ warning("NOT IMPLEMENTED mkMaps ... dumping data structure for now!\n");
$Data::Dumper::Indent = 1;
- my $data = read_updmap_files();
+ my $data = read_updmap_files(@{$opts{'cnffile'}});
$data = read_map_files($data);
+ $data = merge_data($data);
print Data::Dumper->Dump([$data], [qw(mapdata)]);
}
-#####################
+
+sub processOptions {
+ # first process the stupid setoption= s@{1,2} which is not accepted
+ my $oldconfig = Getopt::Long::Configure(qw(pass_through));
+ my @setoptions;
+ GetOptions("setoption=s{1,2}" => \@setoptions) or
+ die "Try \"$prg --help\" for more information.\n";
+ Getopt::Long::Configure($oldconfig);
+
+ # now revamp the @setoptions that they have the proper style
+ my @realset;
+ while (@setoptions) {
+ my $t = shift @setoptions;
+ if ($t =~ m/=/) {
+ push @realset, $t;
+ } else {
+ my $tt = shift @setoptions;
+ die "Try \"$prg --help\" for more information.\n"
+ if !defined($tt);
+ push @realset, "$t=$tt";
+ }
+ }
+ if (@realset) {
+ @{$opts{'setoption'}} = @realset;
+ }
+
+ # now continue with normal option handling
+
+ GetOptions(\%opts, @cmdline_options) or
+ die "Try \"$prg --help\" for more information.\n";
+}
+
+# determines the output dir for driver from cmd line, or if not given
+# from TEXMFVAR
+sub setupOutputDir {
+ my $driver = shift;
+ if (!$opts{$driver . "outputdir"}) {
+ if ($opts{'outputdir'}) {
+ $opts{$driver . "outputdir"} = $opts{'outputdir'};
+ } else {
+ $opts{$driver . "outputdir"} = "$TEXMFVAR/fonts/map/$driver/updmap";
+ }
+ }
+ my $od = $opts{$driver . "outputdir"};
+ &mkdirhier($od);
+ if (! -w $od) {
+ die "$prg: Directory \"$od\" isn't writable: $!";
+ }
+ print "$driver output dir: \"$od\"\n" if !$opts{'quiet'};
+ return $od;
+}
+
+#############################################################################
+# showOptions(item)
+# show Options for an item
+#
+sub showOptions {
+ foreach my $item (@_) {
+ if ($item eq "LW35") {
+ print "URWkb URW ADOBE ADOBEkb\n";
+ }
+ elsif ($item =~
+m/(dvipsPreferOutline|(dvipdfm|pdftex)DownloadBase14|dvipsDownloadBase35)/) {
+ print "true false\n";
+ }
+ else {
+ print "Unknown item \"$item\"; should be one of LW35, dvipsPreferOutline,\n"
+ . " dvipsDownloadBase35, or pdftexDownloadBase14\n";
+ }
+ }
+ exit 0
+}
+
+#
+# listMaps
+#
+# list all maps in the format
+# Maptype Mapname 'enabled'|'disabled' 'in' updmap_cfg_filename
+#
+sub listMaps {
+ my $data = read_updmap_files(@{$opts{'cnffile'}});
+ for my $m (keys %{$data->{'maps'}}) {
+ my $origin = $data->{'maps'}{$m}{'origin'};
+ print $data->{'updmap'}{$origin}{'maps'}{$m}{'type'}, " $m ",
+ $data->{'updmap'}{$origin}{'maps'}{$m}{'status'}, " in $origin\n";
+ }
+}
+
+###############################################################################
+# copyFile()
+# copy file $src to $dst, sets $dst creation and mod time
+#
+sub copyFile {
+ my ($src, $dst) = @_;
+ my $dir;
+ ($dir=$dst)=~s/(.*)\/.*/$1/;
+ mkdirhier $dir;
+
+ $src eq $dst && return "can't copy $src to itself!\n";
+
+ open IN, "<$src" or die "$0: can't open source file $src for copying: $!";
+ open OUT, ">$dst";
+
+ binmode(IN);
+ binmode(OUT);
+ print OUT <IN>;
+ close(OUT);
+ close(IN);
+ my @t = stat($src);
+ utime($t[8], $t[9], $dst);
+}
+
+#################################################################
#
# reading updmap-cfg files and the actual map files
#
@@ -71,20 +298,23 @@ sub testmain {
# initialized by read_updmap_files
# $data->{'order'} = [ list of updmap in decreasing priority ]
# $data->{'updmap'}{$full_path_name_of_updmap}{'setting'}{$key} = $val
-# $data->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}
+# $data->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'type'}
# = 'Map'|'MixedMap'|'disabled'
+# $data->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'status'}
+# = 'enabled'|'disabled'
+# $data->{'maps'}{$m}{'origin'} = $updmap_path_name
#
# initialized by read_map_files
-# $data->{'maps'}{$m}{$font} = $rest
+# $data->{'maps'}{$m}{'fonts'}{$font} = $rest
#
# initialized by merge_data
# $data->{'merged'}{'setting'}{$key} = $val
-# $data->{'merged'}{'fonts'}{$fontdef} = $rest
+# $data->{'merged'}{'allMaps'}{'fonts'}{$fontdef} = $rest
+# $data->{'merged'}{'noMixedMaps'}{'fonts'}{$fontdef} = $rest
#
sub read_updmap_files {
- my (@l) = `kpsewhich -all updmap.cfg`;
- chomp(@l);
+ my (@l) = @_;
my %data;
for my $l (@l) {
my $updmap = read_updmap_file($l);
@@ -95,11 +325,23 @@ sub read_updmap_files {
}
if (defined($updmap->{'maps'})) {
for my $k (keys %{$updmap->{'maps'}}) {
- $data{'updmap'}{$l}{'maps'}{$k} = $updmap->{'maps'}{$k};
+ $data{'updmap'}{$l}{'maps'}{$k}{'type'} = $updmap->{'maps'}{$k}{'type'};
+ $data{'updmap'}{$l}{'maps'}{$k}{'status'} = $updmap->{'maps'}{$k}{'status'};
}
}
}
$data{'order'} = \@l;
+ # first round determine which maps should be used and which type, as
+ # different updmap.cfg files might specify different types of maps
+ # (MixedMap or Map).
+ # Again, we have to do that in reverse order
+ for my $l (reverse @l) {
+ if (defined($data{'updmap'}{$l}{'maps'})) {
+ for my $m (keys %{$data{'updmap'}{$l}{'maps'}}) {
+ $data{'maps'}{$m}{'origin'} = $l;
+ }
+ }
+ }
return \%data;
}
@@ -118,6 +360,8 @@ sub read_updmap_file {
next if /^\s*#$/;
next if /^\s*#[^!]/;
next if /^#![^ ]/;
+ # allow for commands on the line itself
+ s/([^#].*)#.*$/$1/;
my ($a, $b, @rest) = split ' ';
if ($a eq "#!") {
if ($b eq "Map" || $b eq "MixedMap") {
@@ -128,7 +372,8 @@ sub read_updmap_file {
if (defined($data{'maps'}{$c})) {
warning("updmap: double mentioning of $c in $fn\n");
}
- $data{'maps'}{$c} = 'disabled';
+ $data{'maps'}{$c}{'status'} = 'disabled';
+ $data{'maps'}{$c}{'type'} = $b;
}
}
next;
@@ -144,10 +389,11 @@ sub read_updmap_file {
warning("updmap: unknown setting for $a: $b, ignored!\n");
}
} elsif ($a eq "Map" || $a eq "MixedMap") {
- if (defined($data{'maps'}{$b}) && $data{'maps'}{$b} ne $a) {
+ if (defined($data{'maps'}{$b}) && $data{'maps'}{$b}{'type'} ne $a) {
warning("updmap: double mentioning of $b with conflicting types in $fn\n");
} else {
- $data{'maps'}{$b} = $a;
+ $data{'maps'}{$b}{'type'} = $a;
+ $data{'maps'}{$b}{'status'} = 'enabled';
}
} else {
warning("updmap: unrecognized line $i in $fn: $_\n");
@@ -167,11 +413,11 @@ sub read_map_files {
for my $m (keys %{$data->{'updmap'}{$f}{'maps'}}) {
# we do not read a map file multiple times, if $data{'maps'}{$m} is
# defined we expect that it was read and do skip it
- next if defined($data->{'maps'}{$m});
+ next if defined($data->{'maps'}{$m}{'fonts'});
my $ret = read_map_file($m);
if (defined($ret)) {
for my $font (keys %$ret) {
- $data->{'maps'}{$m}{$font} = $ret->{$font};
+ $data->{'maps'}{$m}{'fonts'}{$font} = $ret->{$font};
}
}
}
@@ -197,10 +443,17 @@ sub read_map_file {
}
-
+#
+# merging the various font definitions
+#
sub merge_data {
my $data = shift;
my @l = @{$data->{'order'}};
+ #
+ # for security clean out everything that was there
+ %{$data->{'merged'}} = ();
+ #
+ # first read in the settings
# we read it in *reverse* order and simple fill up the combined data
# thus if there are multiple definitions/settings, the one coming from
# the first in the original list will win!
@@ -212,6 +465,21 @@ sub merge_data {
}
}
}
+ #
+ # now merge the data
+ #
+ for my $m (keys %{$data->{'maps'}}) {
+ my $origin = $data->{'maps'}{$m}{'origin'};
+ next if ($data->{'updmap'}{$origin}{'maps'}{$m}{'status'} eq "disabled");
+ for my $f (keys %{$data->{'maps'}{$m}{'fonts'}}) {
+ $data->{'merged'}{'allMaps'}{'fonts'}{$f} =
+ $data->{'maps'}{$m}{'fonts'}{$f};
+ $data->{'merged'}{'noMixedMaps'}{'fonts'}{$f} =
+ $data->{'maps'}{$m}{'fonts'}{$f}
+ if ($data->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "Map");
+ }
+ }
+ return $data;
}
sub warning {
@@ -223,14 +491,14 @@ sub warning {
#
sub version {
- my $ret = sprintf "%s (TeX Live, multi) version %s\n", $short_progname, $version;
+ my $ret = sprintf "%s (TeX Live, multi) version %s\n", $prg, $version;
return $ret;
}
sub help {
my $usage = <<"EOF";
-Usage: $short_progname [OPTION] ... [COMMAND]
- or: $short_progname-sys [OPTION] ... [COMMAND]
+Usage: $prg [OPTION] ... [COMMAND]
+ or: $prg-sys [OPTION] ... [COMMAND]
Update the default font map files used by pdftex, dvips, and dvipdfm(x),
as determined by the configuration file updmap.cfg (the one returned by