summaryrefslogtreecommitdiff
path: root/Master/tlpkg/dev
diff options
context:
space:
mode:
authorNorbert Preining <preining@logic.at>2011-08-20 02:00:47 +0000
committerNorbert Preining <preining@logic.at>2011-08-20 02:00:47 +0000
commit8c4f0fbddf73041e3a8c0fb9fd127de72a7ef33d (patch)
treec94689867189a24c811a3c4c39f98fb3eb9c4771 /Master/tlpkg/dev
parente81cc1e43828e385897776460f69b9b32aa95660 (diff)
multi-updmap: allow setting of options in the top config file
git-svn-id: svn://tug.org/texlive/trunk@23611 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/dev')
-rw-r--r--Master/tlpkg/dev/multi-updmap.pl308
1 files changed, 244 insertions, 64 deletions
diff --git a/Master/tlpkg/dev/multi-updmap.pl b/Master/tlpkg/dev/multi-updmap.pl
index 7680da76339..2d93452b621 100644
--- a/Master/tlpkg/dev/multi-updmap.pl
+++ b/Master/tlpkg/dev/multi-updmap.pl
@@ -43,6 +43,8 @@ my $prg = TeXLive::TLUtils::basename($0);
use Data::Dumper;
my %opts = ( quiet => 0, nohash => 0, nomkmap => 0 );
+my $alldata;
+
my @cmdline_options = (
"cnffile=s@",
"copy",
@@ -120,21 +122,22 @@ sub main {
my ($top_config_file) = @{$opts{'cnffile'}};
my $bakFile = $top_config_file;
$bakFile =~ s/\.cfg$/.bak/;
- &copyFile($top_config_file, $bakFile);
+ my $changed = 0;
my $cmd;
- my $data = read_updmap_files(@{$opts{'cnffile'}});
+ 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");
+ &copyFile($top_config_file, $bakFile);
system($editor, $top_config_file);
+ $changed = files_are_different($bakFile, $top_config_file);
} elsif ($opts{'setoption'}) {
$cmd = 'setOption';
- warning("NOT IMPLEMENTED setoption!\n");
- exit 1;
+ $changed = setOptions (@{$opts{'setoption'}});
} elsif ($opts{'enable'}) {
$cmd = 'enableMap';
warning("NOT IMPLEMENTED enable!\n");
@@ -145,16 +148,16 @@ sub main {
exit 1;
}
- if ($cmd && !$opts{'force'} && files_are_equal($bakFile, $top_config_file)) {
+ if ($cmd && !$opts{'force'} && !$changed) {
print "$top_config_file unchanged. Map files not recreated.\n"
if !$opts{'quiet'};
} else {
if (!$opts{'nomkmap'}) {
setupOutputDir("dvips");
setupOutputDir("pdftex");
- mkMaps($data);
+ mkMaps();
}
- unlink ($bakFile);
+ unlink ($bakFile) if (-r $bakFile);
}
my $updLSR = &mktexupd();
@@ -169,10 +172,10 @@ sub main {
sub mkMaps {
warning("NOT IMPLEMENTED mkMaps ... dumping data structure for now!\n");
$Data::Dumper::Indent = 1;
- my $data = read_updmap_files(@{$opts{'cnffile'}});
- $data = read_map_files($data);
- $data = merge_data($data);
- print Data::Dumper->Dump([$data], [qw(mapdata)]);
+ read_updmap_files(@{$opts{'cnffile'}});
+ read_map_files();
+ merge_data();
+ print Data::Dumper->Dump([$alldata], [qw(mapdata)]);
}
@@ -227,6 +230,131 @@ sub setupOutputDir {
return $od;
}
+###############################################################################
+# setOption (@options)
+# parse @options for "key=value" (one element of @options)
+# we can only have "key=value" since that is the way it was prepared
+# in process_options
+# (These were the values provided to --setoption.)
+#
+sub setOptions {
+ my (@options) = @_;
+ for (my $i = 0; $i < @options; $i++) {
+ my $o = $options[$i];
+
+ my ($key,$val) = split (/=/, $o, 2);
+
+ die "$prg: unexpected empty key or val for options (@options), goodbye.\n"
+ if !$key || !$val;
+ &setOption ($key, $val);
+ }
+ return save_updmap($alldata->{'top_config'});
+}
+
+# returns 1 if actually saved due to changes
+sub save_updmap {
+ my $fn = shift;
+ my %upd = %{$alldata->{'updmap'}{$fn}};
+ if ($upd{'changed'}) {
+ open (FN, ">$fn") || die "$prg: can't write to $fn: $!";
+ # collect the lines with data
+ my %line_to_setting;
+ my %line_to_map;
+ my @add_setting;
+ my @add_map;
+ if (defined($upd{'setting'})) {
+ for my $k (keys %{$upd{'setting'}}) {
+ if ($upd{'setting'}{$k}{'line'} == -1) {
+ push @add_setting, $k;
+ } else {
+ $line_to_setting{$upd{'setting'}{$k}{'line'}} = $k;
+ }
+ }
+ }
+ if (defined($upd{'maps'})) {
+ for my $k (keys %{$upd{'maps'}}) {
+ if ($upd{'maps'}{$k}{'line'} == -1) {
+ push @add_map, $k;
+ } else {
+ $line_to_map{$upd{'maps'}{$k}{'line'}} = $k;
+ }
+ }
+ }
+ my @lines = @{$upd{'lines'}};
+ for my $i (0..$#lines) {
+ if (defined($line_to_setting{$i})) {
+ my $k = $line_to_setting{$i};
+ my $v = $upd{'setting'}{$k}{'val'};
+ print FN "$k $v\n";
+ } elsif (defined($line_to_map{$i})) {
+ my $m = $line_to_map{$i};
+ my $t = $upd{'maps'}{$m}{'type'};
+ my $p = ($upd{'maps'}{$m}{'status'} eq "disabled" ? "#! " : "");
+ print FN "$p$t $m\n";
+ } else {
+ print "$lines[$i]\n";
+ }
+ }
+ # add the new settings and maps
+ for my $k (@add_setting) {
+ my $v = $upd{'setting'}{$k}{'val'};
+ print FN "$k $v\n";
+ }
+ for my $m (@add_map) {
+ my $t = $upd{'maps'}{$m}{'type'};
+ my $p = ($upd{'maps'}{$m}{'status'} eq "disabled" ? "#! " : "");
+ print FN "$p$t $m\n";
+ }
+ close(FN) || warn("Cannot close file handle for $fn: $!");
+ delete $alldata->{'updmap'}{$fn}{'changed'};
+ return 1;
+ }
+ return 0;
+}
+
+###############################################################################
+# setOption (conf_file, option, value)
+# sets option to value in the config file (replacing the existing setting
+# or by adding a new line to the config file).
+#
+sub setOption {
+ my ($opt, $val) = @_;
+
+ if ($opt eq "LW35") {
+ if ($val !~ m/^(URWkb|URW|ADOBE|ADOBEkb)$/) {
+ die "$0: Invalid value $val for option $opt.\n";
+ }
+ } elsif ($opt =~
+m/^(dvipsPreferOutline|dvipsDownloadBase35|(pdftex|dvipdfm)DownloadBase14)$/) {
+ if ($val !~ m/^(true|false)$/) {
+ die "$0: Invalid value $val for option $opt; should be \"true\" or \"false\".\n";
+ }
+ } else {
+ die "$0: Unsupported option $opt.\n";
+ }
+
+ # silently accept this old option name, just in case.
+ return if $opt eq "dvipdfmDownloadBase14";
+
+ #print "Setting option $opt to $val...\n" if !$quiet;
+ my $tc = $alldata->{'top_config'};
+ if (!defined($alldata->{'updmap'}{$tc})) {
+ die "$prg: top config file $tc has not been read.";
+ }
+ if (defined($alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'})) {
+ if ($alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'} eq $val) {
+ return;
+ }
+ $alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'} = $val;
+ $alldata->{'updmap'}{$tc}{'changed'} = 1;
+ } else {
+ $alldata->{'updmap'}{$tc}{'setting'}{$opt}{'val'} = $val;
+ $alldata->{'updmap'}{$tc}{'setting'}{$opt}{'line'} = -1;
+ $alldata->{'updmap'}{$tc}{'changed'} = 1;
+ }
+}
+
+
#############################################################################
# showOptions(item)
# show Options for an item
@@ -255,11 +383,11 @@ m/(dvipsPreferOutline|(dvipdfm|pdftex)DownloadBase14|dvipsDownloadBase35)/) {
# 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";
+ read_updmap_files(@{$opts{'cnffile'}});
+ for my $m (keys %{$alldata->{'maps'}}) {
+ my $origin = $alldata->{'maps'}{$m}{'origin'};
+ print $alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'}, " $m ",
+ $alldata->{'updmap'}{$origin}{'maps'}{$m}{'status'}, " in $origin\n";
}
}
@@ -287,6 +415,47 @@ sub copyFile {
utime($t[8], $t[9], $dst);
}
+###############################################################################
+# files_are_different(file_A, file_B[, comment_char])
+# compare two equalized files.
+#
+sub files_are_different {
+ my $file_A=shift;
+ my $file_B=shift;
+ my $comment=shift;
+ my $retval=0;
+
+ my $A=equalize_file("$file_A", $comment);
+ my $B=equalize_file("$file_B", $comment);
+ $retval=1 unless ($A eq $B);
+ return $retval;
+}
+
+###############################################################################
+# equalize_file(filename[, comment_char])
+# read a file and return its processed content as a string.
+# look into the source code for more details.
+#
+sub equalize_file {
+ my $file=shift;
+ my $comment=shift;
+ my @temp;
+
+ open IN, "$file";
+ my @lines = (<IN>);
+ close IN;
+ chomp(@lines);
+
+ for (@lines) {
+ s/\s*${comment}.*// if (defined $comment); # remove comments
+ next if /^\s*$/; # remove empty lines
+ s/\s+/ /g; # replace multiple whitespace chars by a single one
+ push @temp, $_;
+ }
+ return join('X', sort(@temp));
+}
+
+
#################################################################
#
# reading updmap-cfg files and the actual map files
@@ -296,53 +465,61 @@ sub copyFile {
# we only read what is necessary (speed!)
#
# 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}{'type'}
+# $alldata->{'top_config'} = first element of the following list, where
+# all the changes are executed
+# $alldata->{'order'} = [ list of updmap in decreasing priority ]
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'lines'} = \@lines
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'setting'}{$key}{'val'} = $val
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'setting'}{$key}{'line'} = $i
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'type'}
# = 'Map'|'MixedMap'|'disabled'
-# $data->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'status'}
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'status'}
# = 'enabled'|'disabled'
-# $data->{'maps'}{$m}{'origin'} = $updmap_path_name
+# $alldata->{'updmap'}{$full_path_name_of_updmap}{'maps'}{$mapname}{'line'} = $i
+# $alldata->{'maps'}{$m}{'origin'} = $updmap_path_name
#
# initialized by read_map_files
-# $data->{'maps'}{$m}{'fonts'}{$font} = $rest
+# $alldata->{'maps'}{$m}{'fonts'}{$font} = $rest
#
# initialized by merge_data
-# $data->{'merged'}{'setting'}{$key} = $val
-# $data->{'merged'}{'allMaps'}{'fonts'}{$fontdef} = $rest
-# $data->{'merged'}{'noMixedMaps'}{'fonts'}{$fontdef} = $rest
+# $alldata->{'merged'}{'setting'}{$key} = $val
+# $alldata->{'merged'}{'allMaps'}{'fonts'}{$fontdef} = $rest
+# $alldata->{'merged'}{'noMixedMaps'}{'fonts'}{$fontdef} = $rest
#
sub read_updmap_files {
my (@l) = @_;
- my %data;
for my $l (@l) {
my $updmap = read_updmap_file($l);
+ $alldata->{'updmap'}{$l}{'lines'} = $updmap->{'lines'};
if (defined($updmap->{'setting'})) {
for my $k (keys %{$updmap->{'setting'}}) {
- $data{'updmap'}{$l}{'setting'}{$k} = $updmap->{'setting'}{$k};
+ $alldata->{'updmap'}{$l}{'setting'}{$k}{'val'} = $updmap->{'setting'}{$k}{'val'};
+ $alldata->{'updmap'}{$l}{'setting'}{$k}{'line'} = $updmap->{'setting'}{$k}{'line'};
}
}
if (defined($updmap->{'maps'})) {
for my $k (keys %{$updmap->{'maps'}}) {
- $data{'updmap'}{$l}{'maps'}{$k}{'type'} = $updmap->{'maps'}{$k}{'type'};
- $data{'updmap'}{$l}{'maps'}{$k}{'status'} = $updmap->{'maps'}{$k}{'status'};
+ $alldata->{'updmap'}{$l}{'maps'}{$k}{'type'} = $updmap->{'maps'}{$k}{'type'};
+ $alldata->{'updmap'}{$l}{'maps'}{$k}{'status'} = $updmap->{'maps'}{$k}{'status'};
+ $alldata->{'updmap'}{$l}{'maps'}{$k}{'line'} = $updmap->{'maps'}{$k}{'line'};
}
}
}
- $data{'order'} = \@l;
+ $alldata->{'order'} = \@l;
+ # get the first config file where we will do all the changes
+ $alldata->{'top_config'} = $l[0];
# 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;
+ if (defined($alldata->{'updmap'}{$l}{'maps'})) {
+ for my $m (keys %{$alldata->{'updmap'}{$l}{'maps'}}) {
+ $alldata->{'maps'}{$m}{'origin'} = $l;
}
}
}
- return \%data;
}
sub read_updmap_file {
@@ -351,9 +528,14 @@ sub read_updmap_file {
log("Cannot read $fn: $!");
return;
}
- my $i = 0;
+ # we count lines from 0 ..!!!!
+ my $i = -1;
my %data;
- while (<FN>) {
+ my @lines = <FN>;
+ chomp(@lines);
+ $data{'lines'} = [ @lines ];
+ close(FN) || warn("Cannot close $fn: $!");
+ for (@lines) {
$i++;
chomp;
next if /^\s*$/;
@@ -374,6 +556,7 @@ sub read_updmap_file {
}
$data{'maps'}{$c}{'status'} = 'disabled';
$data{'maps'}{$c}{'type'} = $b;
+ $data{'maps'}{$c}{'line'} = $i;
}
}
next;
@@ -384,7 +567,8 @@ sub read_updmap_file {
if (defined($settings{$a})) {
my @possible_values = @{$settings{$a}};
if (scalar(grep($_ eq $b, @possible_values))) {
- $data{'setting'}{$a} = $b;
+ $data{'setting'}{$a}{'val'} = $b;
+ $data{'setting'}{$a}{'line'} = $i;
} else {
warning("updmap: unknown setting for $a: $b, ignored!\n");
}
@@ -394,35 +578,33 @@ sub read_updmap_file {
} else {
$data{'maps'}{$b}{'type'} = $a;
$data{'maps'}{$b}{'status'} = 'enabled';
+ $data{'maps'}{$b}{'line'} = $i;
}
} else {
warning("updmap: unrecognized line $i in $fn: $_\n");
}
}
- close(FN) || warn("Cannot close $fn: $!");
return \%data;
}
sub read_map_files {
- my $data = shift;
- if (!defined($data->{'updmap'})) {
- return $data;
+ if (!defined($alldata->{'updmap'})) {
+ return $alldata;
}
- for my $f (keys %{$data->{'updmap'}}) {
- next if !defined($data->{'updmap'}{$f}{'maps'});
- for my $m (keys %{$data->{'updmap'}{$f}{'maps'}}) {
- # we do not read a map file multiple times, if $data{'maps'}{$m} is
+ for my $f (keys %{$alldata->{'updmap'}}) {
+ next if !defined($alldata->{'updmap'}{$f}{'maps'});
+ for my $m (keys %{$alldata->{'updmap'}{$f}{'maps'}}) {
+ # we do not read a map file multiple times, if $alldata{'maps'}{$m} is
# defined we expect that it was read and do skip it
- next if defined($data->{'maps'}{$m}{'fonts'});
+ next if defined($alldata->{'maps'}{$m}{'fonts'});
my $ret = read_map_file($m);
if (defined($ret)) {
for my $font (keys %$ret) {
- $data->{'maps'}{$m}{'fonts'}{$font} = $ret->{$font};
+ $alldata->{'maps'}{$m}{'fonts'}{$font} = $ret->{$font};
}
}
}
}
- return $data;
}
sub read_map_file {
@@ -447,11 +629,10 @@ sub read_map_file {
# merging the various font definitions
#
sub merge_data {
- my $data = shift;
- my @l = @{$data->{'order'}};
+ my @l = @{$alldata->{'order'}};
#
# for security clean out everything that was there
- %{$data->{'merged'}} = ();
+ %{$alldata->{'merged'}} = ();
#
# first read in the settings
# we read it in *reverse* order and simple fill up the combined data
@@ -459,27 +640,26 @@ sub merge_data {
# the first in the original list will win!
for my $l (reverse @l) {
# merge settings
- if (defined($data->{'updmap'}{$l}{'setting'})) {
- for my $k (keys %{$data->{'updmap'}{$l}{'setting'}}) {
- $data->{'merged'}{'setting'}{$k} = $data->{'updmap'}{$l}{'setting'}{$k};
+ if (defined($alldata->{'updmap'}{$l}{'setting'})) {
+ for my $k (keys %{$alldata->{'updmap'}{$l}{'setting'}}) {
+ $alldata->{'merged'}{'setting'}{$k} = $alldata->{'updmap'}{$l}{'setting'}{$k}{'val'};
}
}
}
#
# 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");
+ for my $m (keys %{$alldata->{'maps'}}) {
+ my $origin = $alldata->{'maps'}{$m}{'origin'};
+ next if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'status'} eq "disabled");
+ for my $f (keys %{$alldata->{'maps'}{$m}{'fonts'}}) {
+ $alldata->{'merged'}{'allMaps'}{'fonts'}{$f} =
+ $alldata->{'maps'}{$m}{'fonts'}{$f};
+ $alldata->{'merged'}{'noMixedMaps'}{'fonts'}{$f} =
+ $alldata->{'maps'}{$m}{'fonts'}{$f}
+ if ($alldata->{'updmap'}{$origin}{'maps'}{$m}{'type'} eq "Map");
}
}
- return $data;
}
sub warning {