diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /systems/texlive/tlnet/tlpkg/installer |
Initial commit
Diffstat (limited to 'systems/texlive/tlnet/tlpkg/installer')
37 files changed, 8596 insertions, 0 deletions
diff --git a/systems/texlive/tlnet/tlpkg/installer/COPYING.MinGW-runtime.txt b/systems/texlive/tlnet/tlpkg/installer/COPYING.MinGW-runtime.txt new file mode 100644 index 0000000000..5c4c5d4ee1 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/COPYING.MinGW-runtime.txt @@ -0,0 +1,257 @@ +MinGW runtime licensing +*********************** + +According to <http://mingw.org/license>, the MinGW runtime is in the +public domain. However, this is contradicted by the source package +mingwrt-3.17-mingw32-src.tar.gz containing copyrighted files that +evidently end up in the final runtime in compiled form. Therefore it +seems at least prudent (and probably required) to include the following +notices. + +The Windows binaries in TeX Live compiled against the mingw runtime are +xz, xzdec, xindy, the lcdf-typetools utilities, and jbig2. + +The below is a copy of the mingw-w64 runtime notice. We hope/believe +that is a superset of the required notices for mingw. +http://mingw-w64.svn.sourceforge.net/viewvc/mingw-w64/trunk/COPYING.MinGW-w64-runtime/ + +The first section here is clearly about mingw-64 and not mingw and so is +irrelevant to mingw as stated, but we leave it as their presumed +statement of intent. + +If the mingw maintainers create a definitive file for runtime notices, +we will more than happily use it! + +--TeX Live (http://tug.org/texlive) +--W32TeX (http://w32tex.org/) + +======================== +Overall copyright notice +======================== + +Copyright (c) 2009, 2010 by the mingw-w64 project + +This license has been certified as open source. It has also been designated +as GPL compatible by the Free Software Foundation (FSF). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions in source code must retain the accompanying copyright + notice, this list of conditions, and the following disclaimer. + 2. Redistributions in binary form must reproduce the accompanying + copyright notice, this list of conditions, and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + 3. Names of the copyright holders must not be used to endorse or promote + products derived from this software without prior written permission + from the copyright holders. + 4. The right to distribute this software or to use it for any purpose does + not give you the right to use Servicemarks (sm) or Trademarks (tm) of + the copyright holders. Use of them is covered by separate agreement + with the copyright holders. + 5. If any files are modified, you must cause the modified files to carry + prominent notices stating that you changed the files and the date of + any change. + +Disclaimer + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +======================================== +getopt, getopt_long, and getop_long_only +======================================== + +Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Sponsored in part by the Defense Advanced Research Projects +Agency (DARPA) and Air Force Research Laboratory, Air Force +Materiel Command, USAF, under agreement number F39502-99-1-0512. + + * * * * * * * + +Copyright (c) 2000 The NetBSD Foundation, Inc. +All rights reserved. + +This code is derived from software contributed to The NetBSD Foundation +by Dieter Baron and Thomas Klausner. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +=============================================================== +gdtoa: Converting between IEEE floating point numbers and ASCII +=============================================================== + +The author of this software is David M. Gay. + +Copyright (C) 1997, 1998, 1999, 2000, 2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + + * * * * * * * + +The author of this software is David M. Gay. + +Copyright (C) 2005 by David M. Gay +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that the copyright notice and this permission notice and warranty +disclaimer appear in supporting documentation, and that the name of +the author or any of his current or former employers not be used in +advertising or publicity pertaining to distribution of the software +without specific, written prior permission. + +THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN +NO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS BE +LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + + * * * * * * * + +The author of this software is David M. Gay. + +Copyright (C) 2004 by David M. Gay. +All Rights Reserved +Based on material in the rest of /netlib/fp/gdota.tar.gz, +which is copyright (C) 1998, 2000 by Lucent Technologies. + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + + +========================= +Parts of the math library +========================= + +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + +Developed at SunSoft, a Sun Microsystems, Inc. business. +Permission to use, copy, modify, and distribute this +software is freely granted, provided that this notice +is preserved. + + * * * * * * * + +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + +Developed at SunPro, a Sun Microsystems, Inc. business. +Permission to use, copy, modify, and distribute this +software is freely granted, provided that this notice +is preserved. + + * * * * * * * + +FIXME: Cephes math lib +Copyright (C) 1984-1998 Stephen L. Moshier + +It sounds vague, but as to be found at +<http://lists.debian.org/debian-legal/2004/12/msg00295.html>, it gives an +impression that the author could be willing to give an explicit +permission to distribute those files e.g. under a BSD style license. So +probably there is no problem here, although it could be good to get a +permission from the author and then add a license into the Cephes files +in MinGW runtime. At least on follow-up it is marked that debian sees the +version a-like BSD one. As MinGW.org (where those cephes parts are coming +from) distributes them now over 6 years, it should be fine. + +=================================== +Headers and IDLs imported from Wine +=================================== + +Some header and IDL files were imported from the Wine project. These files +are prominent maked in source. Their copyright belongs to contributors and +they are distributed under LGPL license. + +Disclaimer + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. diff --git a/systems/texlive/tlnet/tlpkg/installer/DirSelect.pm b/systems/texlive/tlnet/tlpkg/installer/DirSelect.pm new file mode 100644 index 0000000000..520a0db0bb --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/DirSelect.pm @@ -0,0 +1,503 @@ +#=============================================================================== +# Tk/DirSelect.pm +# Copyright (C) 2000-2001 Kristi Thompson <kristi@kristi.ca> +# Copyright (C) 2002-2005,2010 Michael Carman <mjcarman@mchsi.com> +# Last Modified: 2/16/2010 +#=============================================================================== +BEGIN { require 5.004 } + +package Tk::DirSelect; +use Cwd; +use File::Spec; +use Tk 800; +require Tk::Frame; +require Tk::BrowseEntry; +require Tk::Button; +require Tk::Label; +require Tk::DirTree; + +use strict; +use base 'Tk::Toplevel'; +Construct Tk::Widget 'DirSelect'; + +use vars qw'$VERSION'; +$VERSION = '1.12'; + +my %colors; +my $isWin32; + +#------------------------------------------------------------------------------- +# Subroutine : ClassInit() +# Purpose : Class initialzation. +# Notes : +#------------------------------------------------------------------------------- +sub ClassInit { + my ($class, $mw) = @_; + $class->SUPER::ClassInit($mw); + + $isWin32 = $^O eq 'MSWin32'; + + # Get system colors from a Text widget for use in DirTree + my $t = $mw->Text(); + foreach my $x (qw'-background -selectbackground -selectforeground') { + $colors{$x} = $t->cget($x); + } + $t->destroy(); +} + + +#------------------------------------------------------------------------------- +# Subroutine : Populate() +# Purpose : Create the DirSelect widget +# Notes : +#------------------------------------------------------------------------------- +sub Populate { + my ($w, $args) = @_; + my $directory = delete $args->{-dir} || cwd(); + my $title = delete $args->{-title} || 'Select Directory'; + + $w->withdraw; + $w->SUPER::Populate($args); + $w->ConfigSpecs(-title => ['METHOD', 'title', 'Title', $title]); + $w->bind('<Escape>', sub { $w->{dir} = undef }); + + my %f = ( + drive => $w->Frame->pack(-anchor => 'n', -fill => 'x'), + button => $w->Frame->pack(-side => 'bottom', -anchor => 's', -fill => 'x', -ipady => 6), + tree => $w->Frame->pack(-fill => 'both', -expand => 1), + ); + + $w->{tree} = $f{tree}->Scrolled('DirTree', + -scrollbars => 'osoe', + -selectmode => 'single', + -ignoreinvoke => 0, + -width => 50, + -height => 15, + %colors, + %$args, + )->pack(-fill => 'both', -expand => 1); + + $w->{tree}->configure(-command => sub { $w->{tree}->opencmd($_[0]) }); + $w->{tree}->configure(-browsecmd => sub { $w->{tree}->anchorClear }); + + $f{button}->Button( + -width => 7, + -text => 'OK', + -command => sub { $w->{dir} = $w->{tree}->selectionGet() }, + )->pack(-side => 'left', -expand => 1); + + $f{button}->Button( + -width => 7, + -text => 'Cancel', + -command => sub { $w->{dir} = undef }, + )->pack(-side => 'left', -expand => 1); + + if ($isWin32) { + $f{drive}->Label(-text => 'Drive:')->pack(-side => 'left'); + $w->{drive} = $f{drive}->BrowseEntry( + -variable => \$w->{selected_drive}, + -browsecmd => [\&_browse, $w->{tree}], + -state => 'readonly', + )->pack(-side => 'left', -fill => 'x', -expand => 1); + + if ($Tk::VERSION >= 804) { + # widget is readonly, but shouldn't appear disabled + for my $e ($w->{drive}->Subwidget('entry')->Subwidget('entry')) { + $e->configure(-disabledforeground => $colors{-foreground}); + $e->configure(-disabledbackground => $colors{-background}); + } + } + } + else { + $f{drive}->destroy; + } + + # right-click context menu + my $menu = $w->Menu( + -tearoff => 0, + -menuitems => [ + [qw/command ~New/, -command => [\&_mkdir , $w]], + [qw/command ~Rename/, -command => [\&_rename, $w]], + [qw/command ~Delete/, -command => [\&_rmdir, $w]], + ], + ); + $menu->bind('<FocusOut>' => sub {$menu->unpost}); + $w->{tree}->bind('<Button-3>' => [\&_context, $menu, Ev('X'), Ev('Y')]); + + # popup overlay for renaming directories + $w->{renameval} = undef; + $w->{popup} = $w->Toplevel(); + $w->{rename} = $w->{popup}->Entry( + -relief => 'groove', + -borderwidth => 1, + )->pack(-fill => 'x', -expand => 1); + $w->{popup}->overrideredirect(1); + $w->{popup}->withdraw; + $w->{rename}->bind('<Escape>', sub {$w->{renameval} = undef}); + $w->{rename}->bind('<FocusOut>', sub {$w->{renameval} = undef}); + $w->{rename}->bind('<KeyPress-Return>', sub {$w->{renameval} = $w->{rename}->get}); + + return $w; +} + + +#------------------------------------------------------------------------------- +# Subroutine : Show() +# Purpose : Display the DirSelect widget. +# Notes : +#------------------------------------------------------------------------------- +sub Show { + my $w = shift; + my $dir = shift; + my $cwd = cwd(); + my $focus = $w->focusSave; + my $grab = $w->grabSave; + + $dir = $cwd unless defined $dir && -d $dir; + chdir($dir); + + if ($isWin32) { + # populate the drive list + my @drives = _get_volume_info(); + $w->{drive}->delete(0, 'end'); + my $startdrive = _drive($dir); + + foreach my $d (@drives) { + $w->{drive}->insert('end', $d); + if ($startdrive eq _drive($d)) { + $w->{selected_drive} = $d; + } + } + } + + # show initial directory + _showdir($w->{tree}, $dir); + + $w->Popup(@_); # show widget + $w->focus; # seize focus + $w->grab; # seize grab + $w->waitVariable(\$w->{dir}); # wait for user selection (or cancel) + $w->grabRelease; # release grab + $w->withdraw; # run and hide + $focus->(); # restore prior focus + $grab->(); # restore prior grab + chdir($cwd) # restore working directory + or warn "Could not chdir() back to '$cwd' [$!]\n"; + + # HList SelectionGet() behavior changed around Tk 804.025 + if (ref $w->{dir} eq 'ARRAY') { + $w->{dir} = $w->{dir}[0]; + } + + { + local $^W; + $w->{dir} .= '/' if ($isWin32 && $w->{dir} =~ /:$/); + } + + return $w->{dir}; +} + + +#------------------------------------------------------------------------------- +# Subroutine : _browse() +# Purpose : Browse to a mounted filesystem (Win32) +# Notes : +#------------------------------------------------------------------------------- +sub _browse { + my ($w, undef, $d) = @_; + $d = _drive($d) . '/'; + chdir($d); + _showdir($w, $d); + + # Workaround: Under Win* versions of Perl/Tk, scrollbars have a tendancy + # to show up but be disabled. + $w->yview(scroll => 1, 'units'); + $w->update; + $w->yview(scroll => -1, 'units'); +} + + +#------------------------------------------------------------------------------- +# Subroutine : _showdir() +# Purpose : Show the requested directory +# Notes : +#------------------------------------------------------------------------------- +sub _showdir { + my $w = shift; + my $dir = shift; + $w->delete('all'); + $w->chdir($dir); +} + + +#------------------------------------------------------------------------------- +# Subroutine : _get_volume_info() +# Purpose : Get volume information (Win32) +# Notes : +#------------------------------------------------------------------------------- +sub _get_volume_info { + require Win32API::File; + + my @drivetype = ( + 'Unknown', + 'No root directory', + 'Removable disk drive', + 'Fixed disk drive', + 'Network drive', + 'CD-ROM drive', + 'RAM Disk', + ); + + my @drives; + foreach my $ld (Win32API::File::getLogicalDrives()) { + my $drive = _drive($ld); + my $type = $drivetype[Win32API::File::GetDriveType($drive)]; + my $label; + + Win32API::File::GetVolumeInformation( + $drive, $label, [], [], [], [], [], []); + + push @drives, "$drive [$label] $type"; + } + + return @drives; +} + + +#------------------------------------------------------------------------------- +# Subroutine : _drive() +# Purpose : Get the drive letter (Win32) +# Notes : +#------------------------------------------------------------------------------- +sub _drive { + shift =~ /^(\w:)/; + return uc $1; +} + + +#------------------------------------------------------------------------------- +# Method : _context +# Purpose : Display the context menu +# Notes : +#------------------------------------------------------------------------------- +sub _context { + my ($w, $m, $x, $y) = @_; + my $wy = $y - $w->rooty; + $w->selectionClear(); + $w->selectionSet($w->nearest($wy)); + $m->post($x, $y); + $m->focus; +} + + +#------------------------------------------------------------------------------- +# Method : _mkdir +# Purpose : Create a new directory under the current selection +# Notes : +#------------------------------------------------------------------------------- +sub _mkdir { + my $w = shift; + my $dt = $w->{tree}; + my ($sel) = $dt->selectionGet(); + + my $cwd = Cwd::cwd(); + if (chdir($sel)) { + my $base = 'NewDirectory'; + my $name = $base; + my $i = 1; + + while (-d $name && $i < 1000) { + $name = $base . $i++; + } + + unless (-d $name) { + if (mkdir($name)) { + _showdir($dt, $sel); + $dt->selectionClear(); + $dt->selectionSet($sel . '/' . $name); + $w->_rename(); + } + else { + $w->messageBox( + -title => 'Unable to create directory', + -message => "The directory '$name' could not be created.\n$!", + -icon => 'error', + -type => 'OK', + ); + } + } + + chdir($cwd); + } + else { + warn "Unable to chdir() for mkdir() [$!]\n"; + } +} + + +#------------------------------------------------------------------------------- +# Method : _rmdir +# Purpose : Delete the selected directory +# Notes : +#------------------------------------------------------------------------------- +sub _rmdir { + my $w = shift; + my $dt = $w->{tree}; + my ($sel) = $dt->selectionGet(); + + my @path = File::Spec->splitdir($sel); + my $dir = pop @path; + my $pdir = File::Spec->catdir(@path); + + my $cwd = Cwd::cwd(); + if (chdir($pdir)) { + if (rmdir($dir)) { + _showdir($dt, $pdir); + } + else { + $w->messageBox( + -title => 'Unable to delete directory', + -message => "The directory '$dir' could not be deleted.\n$!", + -icon => 'error', + -type => 'OK', + ); + } + chdir($cwd); + } + else { + warn "Unable to chdir() for rmdir() [$!]\n"; + } +} + +#------------------------------------------------------------------------------- +# Method : _rename +# Purpose : Rename the selected directory +# Notes : +#------------------------------------------------------------------------------- +sub _rename { + my $w = shift; + my $dt = $w->{tree}; + my $popup = $w->{popup}; + my $entry = $w->{rename}; + my ($sel) = $dt->selectionGet(); + my ($x, $y, $x1, $y1) = $dt->infoBbox($sel); + + my @path = File::Spec->splitdir($sel); + my $dir = pop @path; + my $pdir = File::Spec->catdir(@path); + + $entry->delete(0, 'end'); + $entry->insert(0, $dir); + $entry->selectionRange(0, 'end'); + $entry->focus; + + my $font = ($entry->configure(-font))[4]; + my $text = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '; + my $width = $entry->fontMeasure($font, $text) / length($text); + $entry->configure(-width => ($x1 - $x) / $width); + + $popup->Post($dt->rootx + $x, $dt->rooty + $y); + $popup->waitVariable(\$w->{renameval}); + $popup->withdraw; + + if (defined $w->{renameval} && $w->{renameval} ne $dir) { + my $cwd = Cwd::cwd(); + + if (chdir($pdir)) { + unless (rename($dir, $w->{renameval})) { + $w->messageBox( + -title => 'Unable to rename directory', + -message => "The directory '$dir' could not be renamed.\n$!", + -icon => 'error', + -type => 'OK', + ); + } + chdir($cwd); + _showdir($dt, $pdir); # rebrowse to update the display + } + else { + warn "Unable to chdir() for rename() [$!]\n"; + } + } +} + + +1; + +__END__ +=pod + +=head1 NAME + +Tk::DirSelect - Cross-platform directory selection widget. + +=head1 SYNOPSIS + + use Tk::DirSelect; + my $ds = $mw->DirSelect(); + my $dir = $ds->Show(); + +=head1 DESCRIPTION + +This module provides a cross-platform directory selection widget. For +systems running Microsoft Windows, this includes selection of local and +mapped network drives. A context menu (right-click or E<lt>Button3E<gt>) +allows the creation, renaming, and deletion of directories while +browsing. + +Note: Perl/Tk 804 added the C<chooseDirectory> method which uses native +system dialogs where available. (i.e. Windows) If you want a native feel +for your program, you probably want to use that method instead -- +possibly using this module as a fallback for systems with older versions +of Tk installed. + +=head1 METHODS + +=head2 C<DirSelect([-title =E<gt> 'title'], [options])> + +Constructs a new DirSelect widget as a child of the invoking object +(usually a MainWindow). + +The title for the widget can be set by specifying C<-title =E<gt> +'Title'>. Any other options provided will be passed through to the +DirTree widget that displays directories, so be sure they're appropriate +(e.g. C<-width>) + +=head2 C<Show([directory], [options])> + +Displays the DirSelect widget and returns the user selected directory or +C<undef> if the operation is canceled. + +All arguments are optional. The first argument (if defined) is the +initial directory to display. The default is to display the current +working directory. Any additional options are passed through to the +Popup() method. This means that you can do something like + + $ds->Show(undef, -popover => $mw); + +to center the dialog over your application. + +=head1 DEPENDENCIES + +=over 4 + +=item * Perl 5.004 + +=item * Tk 800 + +=item * Win32API::File (under Microsoft Windows only) + +=back + +=head1 LICENSE AND COPYRIGHT + +Copyright 2000-2001 Kristi Thompson <kristi@kristi.ca> +Copyright 2002-2005,2010 Michael Carman <mjcarman@cpan.org> + +This program is free software; you can redistribute it and/or modify it +under the terms of either: the GNU General Public License as published +by the Free Software Foundation; or the Artistic License. + +See http://dev.perl.org/licenses/ for more information. + +=cut diff --git a/systems/texlive/tlnet/tlpkg/installer/config.guess b/systems/texlive/tlnet/tlpkg/installer/config.guess new file mode 100644 index 0000000000..97ad073330 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/config.guess @@ -0,0 +1,1662 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2019 Free Software Foundation, Inc. + +timestamp='2019-07-24' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <https://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to <config-patches@gnu.org>. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2019 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if test -f /.attbin/uname ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "$UNAME_SYSTEM" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #include <features.h> + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)` + case "$UNAME_MACHINE_ARCH" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown + ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "$UNAME_VERSION" in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "$machine-${os}${release}${abi-}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" + exit ;; + *:ekkoBSD:*:*) + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" + exit ;; + *:SolidBSD:*:*) + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + *:OS108:*:*) + echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:MirBSD:*:*) + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix"$UNAME_RELEASE" + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux"$UNAME_RELEASE" + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos"$UNAME_RELEASE" + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos"$UNAME_RELEASE" + ;; + sun4) + echo sparc-sun-sunos"$UNAME_RELEASE" + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos"$UNAME_RELEASE" + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint"$UNAME_RELEASE" + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint"$UNAME_RELEASE" + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint"$UNAME_RELEASE" + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten"$UNAME_RELEASE" + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten"$UNAME_RELEASE" + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix"$UNAME_RELEASE" + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix"$UNAME_RELEASE" + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix"$UNAME_RELEASE" + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos"$UNAME_RELEASE" + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + then + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] + then + echo m88k-dg-dgux"$UNAME_RELEASE" + else + echo m88k-dg-dguxbcs"$UNAME_RELEASE" + fi + else + echo i586-dg-dgux"$UNAME_RELEASE" + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "$HP_ARCH" = "" ]; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ "$HP_ARCH" = hppa2.0w ] + then + set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" + exit ;; + 3050*:HI-UX:*:*) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo "$UNAME_MACHINE"-unknown-osf1mk + else + echo "$UNAME_MACHINE"-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:BSD/OS:*:*) + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf + fi + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case "$UNAME_PROCESSOR" in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + i*:CYGWIN*:*) + echo "$UNAME_MACHINE"-pc-cygwin + exit ;; + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 + exit ;; + *:MINGW*:*) + echo "$UNAME_MACHINE"-pc-mingw32 + exit ;; + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys + exit ;; + i*:PW*:*) + echo "$UNAME_MACHINE"-pc-pw32 + exit ;; + *:Interix*:*) + case "$UNAME_MACHINE" in + x86) + echo i586-pc-interix"$UNAME_RELEASE" + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix"$UNAME_RELEASE" + exit ;; + IA64) + echo ia64-unknown-interix"$UNAME_RELEASE" + exit ;; + esac ;; + i*:UWIN*:*) + echo "$UNAME_MACHINE"-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-pc-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + *:GNU:*:*) + # the GNU system + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + exit ;; + *:Minix:*:*) + echo "$UNAME_MACHINE"-unknown-minix + exit ;; + aarch64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arm*:Linux:*:*) + set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + else + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + cris:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + crisv32:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + frv:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + hexagon:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + ia64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m32r*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m68*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + MIPS_ENDIAN=el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + MIPS_ENDIAN= + #else + MIPS_ENDIAN= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-"$LIBC" + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-"$LIBC" + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-"$LIBC" + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" + exit ;; + sh64*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sh*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + vax:Linux:*:*) + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" + exit ;; + x86_64:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + xtensa*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo "$UNAME_MACHINE"-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo "$UNAME_MACHINE"-unknown-stop + exit ;; + i*86:atheos:*:*) + echo "$UNAME_MACHINE"-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo "$UNAME_MACHINE"-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos"$UNAME_RELEASE" + exit ;; + i*86:*DOS:*:*) + echo "$UNAME_MACHINE"-pc-msdosdjgpp + exit ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL" + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos"$UNAME_RELEASE" + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos"$UNAME_RELEASE" + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv"$UNAME_RELEASE" + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo "$UNAME_MACHINE"-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo "$UNAME_MACHINE"-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux"$UNAME_RELEASE" + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv"$UNAME_RELEASE" + else + echo mips-unknown-sysv"$UNAME_RELEASE" + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux"$UNAME_RELEASE" + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux"$UNAME_RELEASE" + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux"$UNAME_RELEASE" + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Rhapsody:*:*) + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + # shellcheck disable=SC2154 + if test "$cputype" = 386; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo "$UNAME_MACHINE"-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux"$UNAME_RELEASE" + exit ;; + *:DragonFly:*:*) + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "$UNAME_MACHINE" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + exit ;; + i*86:rdos:*:*) + echo "$UNAME_MACHINE"-pc-rdos + exit ;; + i*86:AROS:*:*) + echo "$UNAME_MACHINE"-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" + exit ;; +esac + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" <<EOF +#ifdef _SEQUENT_ +#include <sys/types.h> +#include <sys/utsname.h> +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include <signal.h> +#if defined(_SIZE_T_) || defined(SIGLOST) +#include <sys/utsname.h> +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include <sys/param.h> +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <<EOF + +NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize +the system type. Please install a C compiler and try again. +EOF + ;; +esac + +cat >&2 <<EOF + +This script (version $timestamp), has failed to recognize the +operating system you are using. If your script is old, overwrite *all* +copies of config.guess and config.sub with the latest versions from: + + https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +and + https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl new file mode 100644 index 0000000000..7aee474fcf --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl @@ -0,0 +1,172 @@ +$mirrors = { + 'Africa' => { + 'Algeria' => { + 'http://ctan.epst-tlemcen.dz/tex-archive/' => 1 + }, + 'South Africa' => { + 'http://ftp.leg.uct.ac.za/pub/packages/ctan/' => 1, + 'http://ftp.sun.ac.za/ftp/CTAN/' => 1, + 'http://mirror.ufs.ac.za/ctan/' => 1 + } + }, + 'Asia' => { + 'China' => { + 'http://mirror.lzu.edu.cn/CTAN/' => 1, + 'http://mirrors.cqu.edu.cn/CTAN/' => 1, + 'http://mirrors.geekpie.club/CTAN/' => 1, + 'http://mirrors.sjtug.sjtu.edu.cn/ctan/' => 1, + 'http://mirrors.tuna.tsinghua.edu.cn/CTAN/' => 1 + }, + 'India' => { + 'http://ctan.imsc.res.in/' => 1, + 'http://mirror.iopb.res.in/tex-archive/' => 1 + }, + 'Iran' => { + 'http://ctan.asis.ai/' => 1, + 'http://ctan.yazd.ac.ir/' => 1 + }, + 'Japan' => { + 'ftp://ftp.kddilabs.jp/CTAN/' => 1, + 'ftp://ftp.u-aizu.ac.jp/pub/tex/CTAN/' => 1, + 'http://ftp.jaist.ac.jp/pub/CTAN/' => 1, + 'http://ftp.yz.yamagata-u.ac.jp/pub/CTAN/' => 1 + }, + 'Korea' => { + 'http://ftp.harukasan.org/CTAN/' => 1, + 'http://ftp.kaist.ac.kr/pub/tex-archive/' => 1, + 'http://ftp.ktug.org/tex-archive/' => 1, + 'http://mirror.navercorp.com/CTAN/' => 1 + }, + 'Philippines' => { + 'http://mirror.pregi.net/tex-archive/' => 1 + }, + 'Taiwan' => { + 'ftp://ftp.ccu.edu.tw/pub/tex/' => 1, + 'http://ftp.yzu.edu.tw/CTAN/' => 1 + } + }, + 'Europe' => { + 'Austria' => { + 'http://mirror.easyname.at/ctan/' => 1, + 'http://mirror.kumi.systems/ctan/' => 1 + }, + 'Belarus' => { + 'http://mirror.datacenter.by/pub/mirrors/CTAN/' => 1 + }, + 'Czech Republic' => { + 'http://ftp.cvut.cz/tex-archive/' => 1 + }, + 'Denmark' => { + 'http://mirrors.dotsrc.org/ctan/' => 1 + }, + 'Finland' => { + 'ftp://ftp.funet.fi/pub/TeX/CTAN/' => 1 + }, + 'France' => { + 'http://ctan.crest.fr/tex-archive/' => 1, + 'http://ctan.mines-albi.fr/' => 1, + 'http://ctan.tetaneutral.net/' => 1, + 'http://distrib-coffee.ipsl.jussieu.fr/pub/mirrors/ctan/' => 1, + 'http://mirror.ibcp.fr/pub/CTAN/' => 1, + 'http://mirrors.ircam.fr/pub/CTAN/' => 1, + 'http://mirrors.standaloneinstaller.com/ctan/' => 1 + }, + 'Germany' => { + 'ftp://ftp.fu-berlin.de/tex/CTAN/' => 1, + 'ftp://ftp.rrzn.uni-hannover.de/pub/mirror/tex-archive/' => 1, + 'ftp://ftp.tu-chemnitz.de/pub/tex/' => 1, + 'http://ctan.mirror.norbert-ruehl.de/' => 1, + 'http://ctan.space-pro.be/tex-archive/' => 1, + 'http://ftp.fau.de/ctan/' => 1, + 'http://mirror.informatik.hs-fulda.de/tex-archive/' => 1, + 'http://packages.oth-regensburg.de/ctan/' => 1, + 'http://vesta.informatik.rwth-aachen.de/ftp/pub/mirror/ctan/' => 1 + }, + 'Greece' => { + 'http://ftp.cc.uoc.gr/mirrors/CTAN/' => 1 + }, + 'Italy' => { + 'http://ctan.mirror.garr.it/mirrors/CTAN/' => 1 + }, + 'Netherlands' => { + 'http://ctan.cs.uu.nl/' => 1, + 'http://ctan.triasinformatica.nl/' => 1, + 'http://ftp.snt.utwente.nl/pub/software/tex/' => 1, + 'http://mirror.koddos.net/CTAN/' => 1 + }, + 'Norway' => { + 'http://ctan.uib.no/' => 1 + }, + 'Poland' => { + 'ftp://ftp.gust.org.pl/TeX/' => 1, + 'ftp://sunsite.icm.edu.pl/pub/CTAN/' => 1, + 'http://piotrkosoft.net/pub/mirrors/CTAN/' => 1 + }, + 'Portugal' => { + 'ftp://ftp.di.uminho.pt/pub/ctan/' => 1, + 'http://mirrors.up.pt/pub/CTAN/' => 1 + }, + 'Romania' => { + 'http://mirrors.nxthost.com/ctan/' => 1 + }, + 'Russia' => { + 'http://ctan.altspu.ru/' => 1, + 'http://mirror.macomnet.net/pub/CTAN/' => 1, + 'http://mirrors.mi.ras.ru/CTAN/' => 1 + }, + 'Serbia' => { + 'http://ctan.mirror.ftn.uns.ac.rs/' => 1 + }, + 'Slovenia' => { + 'http://ctan.ijs.si/tex-archive/' => 1 + }, + 'Spain' => { + 'http://osl.ugr.es/CTAN/' => 1 + }, + 'Sweden' => { + 'http://ftp.acc.umu.se/mirror/CTAN/' => 1 + }, + 'Switzerland' => { + 'http://www.pirbot.com/mirrors/ctan/' => 1 + }, + 'UK' => { + 'http://anorien.csc.warwick.ac.uk/mirrors/CTAN/' => 1 + } + }, + 'North America' => { + 'Canada' => { + 'http://ctan.forsale.plus/' => 1, + 'http://ctan.math.ca/tex-archive/' => 1, + 'http://ctan.mirror.colo-serv.net/' => 1, + 'http://ctan.mirror.rafal.ca/' => 1, + 'http://mirror.its.dal.ca/ctan/' => 1, + 'http://muug.ca/mirror/ctan/' => 1 + }, + 'Costa Rica' => { + 'http://mirrors.ucr.ac.cr/CTAN/' => 1 + }, + 'USA' => { + 'http://ctan.math.illinois.edu/' => 1, + 'http://ctan.math.washington.edu/tex-archive/' => 1, + 'http://ctan.mirrors.hoobly.com/' => 1, + 'http://mirror.las.iastate.edu/tex-archive/' => 1, + 'http://mirror.utexas.edu/ctan/' => 1, + 'http://mirrors.concertpass.com/tex-archive/' => 1, + 'http://mirrors.ibiblio.org/pub/mirrors/CTAN/' => 1, + 'http://mirrors.rit.edu/CTAN/' => 1 + } + }, + 'Oceania' => { + 'Australia' => { + 'http://mirror.aarnet.edu.au/pub/CTAN/' => 1 + }, + 'New Zealand' => { + 'http://mirror.aut.ac.nz/CTAN/' => 1 + } + }, + 'South America' => { + 'Brazil' => { + 'http://linorg.usp.br/CTAN/' => 1 + } + } +}; diff --git a/systems/texlive/tlnet/tlpkg/installer/install-menu-extl.pl b/systems/texlive/tlnet/tlpkg/installer/install-menu-extl.pl new file mode 100644 index 0000000000..926141cf36 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/install-menu-extl.pl @@ -0,0 +1,209 @@ +#!/usr/bin/env perl +# install-menu-extl.pl + +# tell the frontend about all configurable options and terminate +# this output with an agreed-upon termination string. the frontend +# will get the required package database information from the back +# end. From this, it can deduce collections, schemes and platforms, +# but not the names of platforms. + +# needed info: + +# binaries + descriptions +# schemes +# collections, probably per scheme +# maybe directories to be configured + +# current options: + +# paper size a4 | letter +# allow restricted toggle +# generate formats +# install docs +# install sources +# create symlinks | 2 aspects of desktop integration +# switch to online CTAN + +# then read the selected options back from the frontend + +# when run_menu_extl reads 'startinst' from the frontend, +# run_menu_extl returns to install-tl. +# by then, the frontend has switched to non-blocking i/o +# and will capture the output of the actual installation +# on the fly inside a log window + +our %vars; # only contains simple scalars + +# from install-tl: +# The global variable %vars is an associative list which contains all +# variables and their values which can be changed by the user. +# needs to be our since TeXLive::TLUtils uses it + +our $opt_in_place; +our $tlpdb; +our $media; +our $previoustlpdb; +our @collections_std; +our $texlive_release; + +our $MENU_INSTALL = 0; +our $MENU_ABORT = 1; # no cleanup afterwards +our $MENU_QUIT = 2; + +my $RETURN = $MENU_INSTALL; + +# @fileassocdesc also defined in install-tl +$::fileassocdesc[0] = "None"; +$::fileassocdesc[1] = "Only new"; +$::fileassocdesc[2] = "All"; + +$::deskintdesc[0] = "None"; +$::deskintdesc[1] = "Menu shortcuts"; +$::deskintdesc[2] = "Launcher"; + +do_remote_init(); +print STDOUT "endload\n\n"; + +# %vars hash should eventually include each binary, collection and scheme +# as individual schalars. +# the above sub adds all platforms and collections to %vars +# but maybe not schemes so we add these now: + +foreach my $pkg ($tlpdb->schemes) { + $vars{$pkg}=($vars{'selected_scheme'} eq $pkg)? 1:0; +} +$vars{'scheme-custom'} = 0 unless defined $vars{'scheme-custom'}; + +# reading back current %vars from the frontend +sub read_vars { + my $l = <STDIN>; + chomp $l; + if ($l ne 'vars') { + return 0; + } + while (1) { + $l = <STDIN>; + chomp $l; + if ($l =~ /^([^:]+): (.*)$/) { + $vars{$1} = $2; + } elsif ($l eq 'endvars') { + return 1; + } else { + return 0; + } + } + return 0; +} + +# for each scheme and collection, print name, category and short description +sub print_descs { + print "descs\n"; + foreach my $p ($tlpdb->schemes) { + my $pkg = $tlpdb->get_package($p); + print $pkg->name, ': ', $pkg->category, ' ', $pkg->shortdesc || "", "\n"; + } + foreach my $p ($tlpdb->collections) { + my $pkg = $tlpdb->get_package($p); + print $pkg->name, ': ', $pkg->category, ' ', $pkg->shortdesc || "", "\n"; + } + print "enddescs\n"; +} + +sub print_vars { + print "vars\n"; + foreach my $key (sort keys %vars) { + print $key, ': ', $vars{$key}, "\n"; + } + print "endvars\n"; +} + +# run_menu_extl should be invoked by install-tl + +sub run_menu_extl { + # make sure we have a value for total_size: + calc_depends(); + print "menudata\n"; + print "year: $texlive_release\n"; + print "svn: $::installerrevision\n"; + # for windows, add a key indicating elevated permissions + if (win32()) { + print "admin: ". TeXLive::TLWinGoo::admin() . "\n"; + } + print_descs(); + + print_vars(); + + # tell the frontend the preferred order for schemes + my @schemes = schemes_ordered_for_presentation(); + push @schemes, "scheme-custom"; + print "schemes_order: ", join(' ', @schemes), "\n"; + + # binaries + print "binaries\n"; + # binaries aren't packages; list their descriptions here + my @binaries = $tlpdb->available_architectures; + @binaries=sort TeXLive::TLUtils::sort_archs @binaries; + foreach my $b (@binaries) { + print $b, ': ', platform_desc($b), "\n"; + } + print "endbinaries\n"; + + print "endmenudata\n"; # this triggers the frontend menu + + # read input from frontend / install-tl-gui.tcl. + # Four cases to consider: + # 'calc': the frontend wants to update its ::vars array + # after some menu choices + # 'checkdir': check whether $vars{TEXDIR} is creatable + # 'startinst': done with choices, tell install-tl to + # start installation + # 'quit': tell install-tl to clean up and quit + + # read from frontend + while (1) { + my $l = <STDIN>; + chomp($l); + if ($l eq 'quit') { + return $MENU_QUIT; + } elsif ($l eq 'calc') { + if (read_vars()) { + if ($vars{'selected_scheme'} eq 'scheme-custom') { + calc_depends(); + } else { + select_scheme($vars{'selected_scheme'}); + } + $vars{'n_collections_selected'} = 0; + foreach my $v (keys %vars) { + if (substr($v, 0, 11) eq 'collection-' && $vars{$v}) { + $vars{'n_collections_selected'} += 1; + } + } + print_vars(); + } else { + log("Illegal input '$l' from frontend"); + return $MENU_ABORT; + } + } elsif ($l eq 'checkdir') { + my $td = <STDIN>; + chomp $td; + if (TeXLive::TLUtils::texdir_check($td)) { + print "1\n"; + } else { + print "0\n"; + } + } elsif ($l eq 'startinst') { + if (read_vars()) { + calc_depends(); + return $MENU_INSTALL; + } else { + return $MENU_ABORT; + } + } else { + return $MENU_ABORT; + } + } +} # run_menu_extl + +$::run_menu = \&run_menu_extl; + +1; diff --git a/systems/texlive/tlnet/tlpkg/installer/install-menu-perltk.pl b/systems/texlive/tlnet/tlpkg/installer/install-menu-perltk.pl new file mode 100644 index 0000000000..06c2829b47 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/install-menu-perltk.pl @@ -0,0 +1,1291 @@ +#!/usr/bin/env perl +# $Id: install-menu-perltk.pl 48774 2018-09-27 15:05:00Z preining $ +# +# Copyright 2008-2014 Norbert Preining +# Copyright 2008 Reinhard Kotucha +# This file is licensed under the GNU General Public License version 2 +# or any later version. + +use strict; +$^W = 1; + +my $svnrev = '$Revision: 48774 $'; +$svnrev =~ m/: ([0-9]+) /; +$::menurevision = ($1 ? $1 : 'unknown'); + +require Tk; +require Tk::Dialog; +require Tk::DialogBox; +require Tk::PNG; +require Tk::BrowseEntry; + +use utf8; +no utf8; + +our %vars; +our $opt_in_place; +our $tlpdb; +our @collections_std; +our $texlive_release; +our @media_available; +our $media; + +our $MENU_INSTALL = 0; +our $MENU_ABORT = 1; +our $MENU_QUIT = 2; +our $MENU_ALREADYDONE = 3; + +my $return = $MENU_INSTALL; + +our $LANG; +our %TRANS; +require("TeXLive/trans.pl"); +load_translations(); + +require("$::installerdir/tlpkg/installer/texdirsel.pl"); + +# @fileassocdesc also defined in install-tl +$::fileassocdesc[0] = __("None"); +$::fileassocdesc[1] = __("Only new"); +$::fileassocdesc[2] = __("All"); + +$::letterdesc[0] = __('A4'); +$::letterdesc[1] = __('letter'); + +$::deskintdesc[0] = __("No shortcuts"); +$::deskintdesc[1] = __("TeX Live menu"); +if (win32() && is_seven()) { $::deskintdesc[2] = __("Launcher entry"); } + +# generic option strings: +$::yesno[0] = __('No'); +$::yesno[1] = __('Yes'); + +our $mw; +my $subframe; +my $mainwindow; +my $bin_toggle_button; +my $scheme_toggle_button; +my $collection_toggle_button; +my $portable_toggle_button; +my $texdir_toggle_button; +my $paper_toggle_button; +my $write_eighteen_toggle_button; +my $format_toggle_button; +my $doc_files_toggle_button; +my $src_files_toggle_button; +my $texworks_toggle_button; +my $load_remote_button; +my $adjustrepo_toggle_button; +my $bintextbutton; +my $schemebutton; +my $tmflocalbutton; +my $tmfsysvarbutton; +my $tmfsysconfigbutton; +my $tmfhomebutton; +my $pathbutton; +my $deskintbutton; +my $assocbutton; +my $adminbutton; +my $installbutton; +my $collectionstext; +my $texmflocaltext; +my $texmfsysvartext; +my $texmfsysconfigtext; +my $texmfhometext; +my $texdirtext; +my $optletterstate; +my $optfmtstate; +my $optsrcstate; +my $optdocstate; +my $portableyesno; +my $letteryesno; +my $fmtyesno; +my $srcyesno; +my $deskintyesno; +my $pathadjyesno; +my $fileassocyesno; +my $editoryesno; +my $adminallyesno; +my $docyesno; +my $restrictedyesno; +my $adjustrepoyesno; + +my $sep = ($^O =~ /^MSWin32/) ? "\\" : "/"; + +$::run_menu = \&run_menu_perltk; + + +#################################################################### +# From here on only function definitions +# ################################################################## + +sub setup_perltk_local_strings { + $portableyesno = $::yesno[$vars{'instopt_portable'}]; + $letteryesno = $::letterdesc[$vars{'instopt_letter'}]; + $fmtyesno = $::yesno[$vars{'tlpdbopt_create_formats'}]; + $srcyesno = $::yesno[$vars{'tlpdbopt_install_srcfiles'}]; + $deskintyesno = $::deskintdesc[$vars{'tlpdbopt_desktop_integration'}]; + $pathadjyesno = $::yesno[$vars{'instopt_adjustpath'}]; + $fileassocyesno = $::fileassocdesc[$vars{'tlpdbopt_file_assocs'}]; + $editoryesno = $::yesno[$vars{'collection-texworks'}]; + $adminallyesno = $::yesno[$vars{'tlpdbopt_w32_multi_user'}]; + $docyesno = $::yesno[$vars{'tlpdbopt_install_docfiles'}]; + $restrictedyesno = $::yesno[$vars{'instopt_write18_restricted'}]; + $adjustrepoyesno = $::yesno[$vars{'instopt_adjustrepo'}]; +} + +sub menu_abort { + $return = $MENU_ABORT; + $mainwindow->destroy; +} + +sub menu_do_it { + $return = $MENU_INSTALL; + $mainwindow->destroy; +} + +sub disable_buttons { + change_button_state('disabled'); +} +sub enable_buttons { + change_button_state('normal'); +} + +sub change_button_state { + my $what = shift; + $installbutton->configure(-state => $what); + $tmflocalbutton->configure(-state => $what); + $tmfsysvarbutton->configure(-state => $what); + $tmfsysconfigbutton->configure(-state => $what); + $tmfhomebutton->configure(-state => $what); + $bin_toggle_button->configure(-state => $what); + $scheme_toggle_button->configure(-state => $what); + $collection_toggle_button->configure(-state => $what); + $portable_toggle_button->configure(-state => $what); + $texdir_toggle_button->configure(-state => $what); + $paper_toggle_button->configure(-state => $what); + $write_eighteen_toggle_button->configure(-state => $what); + $format_toggle_button->configure(-state => $what); + $adjustrepo_toggle_button->configure(-state => $what); + $pathbutton->configure(-state => $what); + $doc_files_toggle_button->configure(-state => $what) + if defined($doc_files_toggle_button); + $src_files_toggle_button->configure(-state => $what) + if defined($src_files_toggle_button); + $texworks_toggle_button->configure(-state => $what) + if defined($texworks_toggle_button); +} + +sub run_menu_perltk { + if ($::opt_select_repository) { + } else { + do_remote_init(); + setup_perltk_local_strings(); + calc_depends(); + } + $mainwindow = Tk::MainWindow->new; + $mainwindow->protocol('WM_DELETE_WINDOW' => \&menu_abort); + + # Taco once reported for 2010 that using these scrolled pane + # on Windows just died + # with the proliferation of netbooks and a new perl installed + # let us try to go back to using scrolled pane on both unix and windows + require Tk::Pane; + $subframe = $mainwindow->Scrolled("Frame", -scrollbars => "oe"); + $mw = $subframe->Frame; + + # image frame on the left + my $fl = $mw->Frame(-background => "#0078b8"); + my $img = $fl->Photo(-format => 'png', + -file => "$::installerdir/tlpkg/installer/texlive.png"); + $fl->Label(-image => $img, -background => "#0078b8") + ->pack(-expand => 1, -fill => "y"); + $fl->Label( + -text => "v$::installerrevision/$::menurevision", + -background => "#0078b8")->pack; + + # data frame on the right + my $fr = $mw->Frame; + $fl->pack(-side => 'left', -expand => 1, -fill => "y"); + $fr->pack(-side => 'right'); + + + my $row = 1; + $fr->Label( + -text => __("TeX Live %s Installation", $TeXLive::TLConfig::ReleaseYear)) + ->grid(-row => $row, -column => 1, -columnspan => 3); + + if ($::opt_select_repository) { + $row++; + my @mirror_list; + my @netlst; + my @loclst; + if ($#media_available >= 0) { + for my $l (@media_available) { + my ($a, $b) = split ('#', $l); + if ($a eq 'local_compressed' || $a eq 'local_uncompressed') { + push @loclst, " $b"; + } elsif ($a eq 'NET') { + push @netlst, " " . __("Command line repository") . ": $b"; + } else { + tlwarn("Unknown media $l\n"); + } + } + if ($#loclst >= 0) { + push @mirror_list, __("LOCAL REPOSITORIES"); + push @mirror_list, @loclst; + } + } + push @mirror_list, __("NETWORK REPOSITORIES"); + push @mirror_list, + " " . __("Default remote repository") . ": http://mirror.ctan.org"; + push @mirror_list, @netlst; + push @mirror_list, TeXLive::TLUtils::create_mirror_list(); + my $mirror_entry; + $fr->Label( + -text => __('Select repository'), + -anchor => 'w')->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->BrowseEntry( + -state => 'readonly', + -listheight => 12, + -listwidth => 400, + -width => 35, + -autolistwidth => 1, + -choices => \@mirror_list, + -browsecmd => + sub { + if ($mirror_entry !~ m/^ /) { + $mirror_entry = ""; + } elsif ($mirror_entry =~ m!(http|ftp)://!) { + $mirror_entry = + TeXLive::TLUtils::extract_mirror_entry($mirror_entry); + } else { + $mirror_entry =~ s/^\s*//; + # $mirror_entry = + # TeXLive::TLUtils::extract_mirror_entry($mirror_entry); + } + }, + -variable => \$mirror_entry) + ->grid(-row => $row, -column => 2, -sticky => 'w'); + $load_remote_button = $fr->Button(-text => __("Load"), + -command => sub { + $::init_remote_needed = 1; + my $mfull = $mirror_entry; + only_load_remote($mfull); + if (!only_load_remote($mfull)) { + $fr->Dialog(-title => __("Warning"), + -text => __('Could not load remote TeX Live Database:') . $mfull + . "\n\n" . + __('Please select a different mirror.'), + -buttons => [ __("Ok") ])->Show; + $mirror_entry = ""; + } elsif (!do_version_agree()) { + $fr->Dialog( + -title => __("Warning"), + -text => __( + 'The TeX Live versions of the local installation and the repository being accessed are not compatible: + local: %s + repository: %s +Please select a different mirror.', + $TeXLive::TLConfig::ReleaseYear, $texlive_release), + -buttons => [ __("Ok") ])->Show; + $mirror_entry = ""; + } else { + $load_remote_button->configure(-state => 'disable'); + final_remote_init($mfull); + setup_perltk_local_strings(); + calc_depends(); + menu_update_texts(); + enable_buttons(); + } + })->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + } + if (!$opt_in_place) { + + $row++; + $fr->Label(-text => "------- " . __("Basic Information") . " -------") + ->grid(-row => $row, -column => 1, -columnspan => 3); + + # binary system line + if (!win32()) { + $row++; + $fr->Label(-text => __('Binary system(s)'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $bintextbutton = $fr->Label(-anchor => 'w'); + $bintextbutton->grid(-row => $row, -column => 2, -padx => "2m"); + $bin_toggle_button = $fr->Button( + -text => __("Change"), -command => sub { menu_select_binsystems(); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + } + + $row++; + + # scheme line + $fr->Label(-text => __('Selected scheme'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $schemebutton = $fr->Label(-anchor => 'w'); + $schemebutton->grid(-row => $row, -column => 2, -padx => "2m"); + $scheme_toggle_button = $fr->Button( + -text => __("Change"), -command => sub { menu_select_scheme(); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + $row++; + + # further customization + $fr->Label(-text => "------- " . __("Further Customization") . " -------") + ->grid(-row => $row, -column => 1,-columnspan => 3); + + $row++; + # collection line + $fr->Label(-text => __('Installation collections'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $collection_toggle_button = $fr->Button( + -text => __("Change"), + -command => sub { menu_select_standard_collections(); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + $row++; + $collectionstext = $fr->Label(); + $collectionstext->grid(-row => $row, -column => 1, -columnspan => 3); + } + + $row++; + # further customization + $fr->Label(-text => "------- " . __("Directory setup") . " -------") + ->grid(-row => $row, -column => 1, -columnspan => 3); + + $row++; + $fr->Label(-text => __('Portable setup'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$portableyesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + $portable_toggle_button = $fr->Button( + -text => __("Toggle"), + -command => sub { toggle_portable(); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + $row++; + # texdir line + $fr->Label(-text => __('TEXDIR (the main TeX directory)'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $texdirtext = $fr->Label(-anchor => 'w') + ->grid(-row => $row, -column => 2, -padx => "2m"); + if (!$opt_in_place) { + $texdir_toggle_button = $fr->Button( + -text => __("Change"), -command => \&change_path) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + } + + + $row++; + # texmflocal line + $fr->Label( + -text => __('TEXMFLOCAL (directory for site-wide local files)'), + -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $texmflocaltext = $fr->Label(-anchor => 'w') + ->grid(-row => $row, -column => 2, -padx => "2m"); + $tmflocalbutton = $fr->Button( + -text => __("Change"), + -command => sub { menu_edit_vars_value("TEXMFLOCAL"); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + $row++; + # texmfsysvar line + $fr->Label( + -text => __('TEXMFSYSVAR (directory for autogenerated data)'), + -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $texmfsysvartext = $fr->Label(-anchor => 'w') + ->grid(-row => $row, -column => 2, -padx => "2m"); + $tmfsysvarbutton = $fr->Button( + -text => __("Change"), + -command => sub { menu_edit_vars_value("TEXMFSYSVAR"); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + $row++; + # texmfsysconfig line + $fr->Label( + -text => __('TEXMFSYSCONFIG (directory for local config)'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $texmfsysconfigtext = $fr->Label(-anchor => 'w') + ->grid(-row => $row, -column => 2, -padx => "2m"); + $tmfsysconfigbutton = $fr->Button( + -text => __("Change"), + -command => sub { menu_edit_vars_value("TEXMFSYSCONFIG"); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + $row++; + # texmfhome line + $fr->Label( + -text => __('TEXMFHOME (directory for user-specific files)'), + -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $texmfhometext = $fr->Label(-anchor => 'w') + ->grid(-row => $row, -column => 2, -padx => "2m"); + $tmfhomebutton = $fr->Button( + -text => __("Change"), + -command => sub { menu_edit_vars_value("TEXMFHOME"); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + if ($vars{'instopt_portable'}) { + for my $b ( + $tmflocalbutton, $tmfsysvarbutton, $tmfsysconfigbutton, $tmfhomebutton) { + $b->configure(-state => 'disabled') + } + } + + $row++; + # Options + $fr->Label(-text => "------- " . __("Options") . " -------") + ->grid(-row => $row, -column => 1, -columnspan => 3); + + $row++; + # optpaper + $fr->Label(-text => __('Default paper size'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$letteryesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + $paper_toggle_button = $fr->Button( + -text => __("Toggle"), + -command => sub { + toggle_and_set_opt_variable( + \$vars{'instopt_letter'}, \$letteryesno, \@::letterdesc); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + $row++; + $fr->Label( + -text => __('Allow execution of restricted list of programs via \write18'), + -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$restrictedyesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + $write_eighteen_toggle_button = $fr->Button( + -text => __("Toggle"), + -command => sub { + toggle_and_set_opt_variable( + \$vars{'instopt_write18_restricted'}, + \$restrictedyesno); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + $row++; + $fr->Label( + -text => __('Create all format files'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$fmtyesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + $format_toggle_button = $fr->Button( + -text => __("Toggle"), + -command => sub { + toggle_and_set_opt_variable(\$vars{'tlpdbopt_create_formats'}, \$fmtyesno); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + if ($vars{'doc_splitting_supported'} and !$opt_in_place) { + $row++; + $fr->Label(-text => __('Install font/macro doc tree'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$docyesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + $doc_files_toggle_button = $fr->Button( + -text => __("Toggle"), + -command => sub { + toggle_and_set_opt_variable(\$vars{'tlpdbopt_install_docfiles'}, \$docyesno); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + } + + if ($vars{'src_splitting_supported'} and !$opt_in_place) { + $row++; + $fr->Label(-text => __('Install font/macro source tree'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$srcyesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + $src_files_toggle_button = $fr->Button( + -text => __("Toggle"), + -command => sub { + toggle_and_set_opt_variable(\$vars{'tlpdbopt_install_srcfiles'}, \$srcyesno); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + } + + $row++; + $fr->Label( + -text => (win32()) ? __('Adjust PATH setting in registry') : + __('Create symlinks in system directories'), + -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$pathadjyesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + if (unix()) { + $pathbutton = $fr->Button( + -text => __("Change"), -command => sub { menu_select_symlink(); }); + } else { + $pathbutton = $fr->Button( + -text => __("Toggle"), + -command => sub { + toggle_and_set_opt_variable(\$vars{'instopt_adjustpath'}, \$pathadjyesno); }); + } + $pathbutton->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + if ($::opt_all_options || win32()) { + $row++; + $fr->Label(-text => __('Add menu shortcuts'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$deskintyesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + $deskintbutton = $fr->Button( + -text => __("Change"), + -command => sub { + toggle_and_set_opt_variable( + \$vars{'tlpdbopt_desktop_integration'}, + \$deskintyesno, \@::deskintdesc); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + $row++; + $fr->Label(-text => __('Change file associations'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$fileassocyesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + $assocbutton = $fr->Button( + -text => __("Change"), + -command => sub { + toggle_and_set_opt_variable( + \$vars{'tlpdbopt_file_assocs'}, \$fileassocyesno, \@::fileassocdesc); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + + if ($::opt_all_options || admin()) { + $row++; + $fr->Label(-text => __('Installation for all users'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$adminallyesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + $adminbutton = $fr->Button( + -text => __("Toggle"), + -command => sub { + toggle_and_set_opt_variable( + \$vars{'tlpdbopt_w32_multi_user'}, \$adminallyesno); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + } + + $row++; + $fr->Label(-text => __('Install TeXworks front end'), -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$editoryesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + if (!$opt_in_place) { + $texworks_toggle_button = $fr->Button( + -text => __("Toggle"), + -command => sub { + toggle_and_set_opt_variable( + \$vars{'collection-texworks'}, \$editoryesno); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + } + } + if ($media ne 'NET') { + $row++; + $fr->Label( + -text => __('After install, set CTAN as source for package updates'), + -anchor => 'w') + ->grid(-row => $row, -column => 1, -sticky => 'w'); + $fr->Label(-anchor => 'w', -textvariable => \$adjustrepoyesno) + ->grid(-row => $row, -column => 2, -padx => "2m"); + $adjustrepo_toggle_button = $fr->Button( + -text => __("Toggle"), + -command => sub { + toggle_and_set_opt_variable( + \$vars{'instopt_adjustrepo'}, \$adjustrepoyesno); }) + ->grid(-row => $row, -column => 3, -sticky => "ew", -padx => "2m"); + } + + if ($vars{'instopt_portable'}) { + for $b ($pathbutton, $deskintbutton, $assocbutton, $adminbutton) { + $b->configure(-state => 'disabled') if $b; + } + } + + # install/cancel buttons + my $f3 = $fr->Frame; + $f3->Button( + -text => __("About"), + -command => sub { + my $sw = $mw->DialogBox(-title => __("About"), + -buttons => [ __("Ok") ]); + $sw->add("Label", -text => " +TeX Live $TeXLive::TLConfig::ReleaseYear +Please see http://www.tug.org/texlive +GUI installer +Copyright 2009-$TeXLive::TLConfig::ReleaseYear The TeX Live Team +Licensed under the GNU General Public License version 2 or higher + +In case of problems, please contact: texlive\@tug.org" + )->pack(-ipadx => "2m", -ipady => "2m"); + $sw->Show; + })->pack(-side => 'left', -padx => "2m", -pady => "2m"); + + + + $installbutton = $f3->Button( + -text => __("Install TeX Live"), + -command => \&menu_do_it + )->pack(-side => 'left', -padx => "2m", -pady => "2m")->focus(); + my $quitbutton = $f3->Button( + -text => __("Quit"), + -command => \&menu_abort + )->pack(-side => 'right', -padx => "2m", -pady => "2m"); + $mw->bind('<Escape>', [ $quitbutton, 'Invoke' ]); + #my $wizardbutton = $f3->Button( + # -text => __("Wizard"), + # -command => sub { + # $mainwindow->destroy; + # require("installer/install-menu-wizard.pl"); + # setup_hooks_wizard(); + # $return = run_menu_wizard(); + # })->pack(-side => 'right', -padx => "2m", -pady => "2m"); + $row++; + $f3->grid(-row => $row, -column => 1, -columnspan => 3); + if (!$::opt_select_repository) { + menu_update_texts(); + } else { + disable_buttons(); + } + $fr->gridColumnconfigure(2, -minsize => 300); + $mw->pack(-expand => 1, -fill => "both"); + $mw->update; + my $rh = $mw->reqheight; + my $rw = $mw->reqwidth; + my $maxheight = $mainwindow->screenheight() - 20; + debug( + "Requested height: $rh, requested width: $rw, max height: $maxheight\n"); + if ($rh > $maxheight) { + $rh = $maxheight; + $rw += 20; # for the scrollbar = = + } + $subframe->configure(-height => $rh, -width=>$rw); + $subframe->pack(-expand => 1, -fill => "both"); + $mainwindow->configure(-height => $rh, -width=>$rw); + $mainwindow->geometry("=${rw}x${rh}"); + #$mw->pack(-expand => 1, -fill => "both"); + + if (win32() && pre_warn($mainwindow)) { return $MENU_ABORT; } + + Tk::MainLoop(); + return($return); +} + +sub pre_warn { + my $parent = shift; + require TeXLive::TLWinGoo; + my ($b_quit, $b_cont) = (__('Quit'), __('Continue')); + my $wrn = __( + 'In case of trouble, try disabling your virus scanner during installation.'); + if (!admin()) { + $wrn .= "\n\n". + __("The installer does not have adminstrative permissions;\nso can only install for current user."); + if (is_vista()) { + $wrn .= "\n\n". + __("Right-click install-tl-advanced and select \"run as administrator\"\n if you want to install for all users."); + } + } + my $ans = $parent->Dialog( + -title => __("TeX Live %s Installation", $TeXLive::TLConfig::ReleaseYear), + -text => $wrn, + -default_button => $b_cont, + -buttons => [$b_quit, $b_cont])->Show(); + return $ans eq $b_quit; +} + +# this sub will not be called if $opt_in_place +sub menu_edit_texdir { + my $key = shift; + our $addyear = 1; + our $addtexlive = 1; + my $val = $vars{$key}; + our $currsel; + our $entry; + sub update_label { + my $t = $currsel; + $t .= "/texlive" if ($addtexlive); + $t .= "/$texlive_release" if ($addyear); + $entry->configure(-text => "$t"); + } + my $hint_var; + if ($key ne 'TEXMFHOME') { + $hint_var = win32() ? $ENV{'USERPROFILE'} : $ENV{'HOME'}; + } else { + $hint_var = win32() ? '%USERPROFILE%' : '$HOME'; + } + if ($val =~ m!^(.*)/texlive/$texlive_release$!) { + $currsel = "$1"; + $addyear = 1; + $addtexlive = 1; + } elsif ($val =~ m!^(.*)/$texlive_release$!) { + $currsel = "$1"; + $addyear = 1; + $addtexlive = 0; + } elsif ($val =~ m!^(.*)/texlive$!) { + $currsel = "$1"; + $addyear = 0; + $addtexlive = 1; + } else { + $addyear = 0; + $addtexlive = 0; + $currsel = $val; + } + my $sw = $mainwindow->Toplevel(-title => __("Change variable value")); + $sw->transient($mainwindow); + $sw->grab(); + $sw->Label(-text => __("Enter path for %s (use ~ for %s)", $key, $hint_var)) + ->pack(-padx => "2m", -pady => "2m"); + $entry = $sw->Entry(-width => 60)->pack(-padx => "2m", -pady => "2m"); + my $f = $sw->Frame; + my $c1 = $f->Checkbutton( + -text => 'Add "texlive"', + -variable => \$addtexlive, + -command => \&update_label); + my $c2 = $f->Checkbutton( + -text => "Add \"$texlive_release\"", -variable => \$addyear, + -command => \&update_label); + my $foo = $sw->Scrolled( + "DirTree", -scrollbars => "osoe", + -browsecmd => sub { my ($d) = @_; $currsel = $d; update_label(); }, + -directory => "$currsel"); + my $ff = $sw->Frame; + my $ok = $ff->Button( + -text => __("Ok"), + -command => sub { + $val = $entry->get; + callback_edit_directories($key,$val); + $sw->destroy; }); + my $cancel = $ff->Button( + -text => __("Cancel"), + -command => sub { $sw->destroy; }); + update_label(); + $c1->pack(-side => "left", -padx => "2m", -pady => "2m"); + $c2->pack(-side => "right", -padx => "2m", -pady => "2m"); + $f->pack; + $foo->pack(-fill => "both", -expand => 1); + $ok->pack(-side => 'left' , -padx => "2m", -pady => "2m"); + $cancel->pack(-side => 'right', -padx => "2m", -pady => "2m"); + $ff->pack; + # bindings + $sw->bind('<Return>' => [ $ok, 'Invoke']); + $sw->bind('<Escape>' => [ $cancel, 'Invoke']); +} + +sub menu_edit_vars_value { + my $key = shift; + my $sw = $mainwindow->Toplevel(-title => __("Change variable value")); + $sw->transient($mainwindow); + $sw->grab(); + my $val = $vars{$key}; + my $hint_var; + if ($key ne 'TEXMFHOME') { + $hint_var = win32() ? $ENV{'USERPROFILE'} : $ENV{'HOME'}; + } else { + $hint_var = win32() ? '%USERPROFILE%' : '$HOME'; + } + $sw->Label(-text => __("Enter path for %s (use ~ for %s)", $key, $hint_var)) + ->pack(-padx => "2m", -pady => "2m"); + my $entry = $sw->Entry(-text => native_slashify($val), -width => 60); + $entry->pack(-padx => "2m", -pady => "2m")->focus(); + my $f = $sw->Frame; + my $okbutton = $f->Button( + -text => __("Ok"), + -command => sub { + $val = forward_slashify($entry->get); + callback_edit_directories($key,$val) ; + $sw->destroy }) + ->pack(-side => 'left', -padx => "2m", -pady => "2m"); + my $cancelbutton = $f->Button( + -text => __("Cancel"), + -command => sub { $sw->destroy }) + ->pack(-side => 'right', -padx => "2m", -pady => "2m"); + $f->pack(-expand => 'x'); + # bindings + $sw->bind('<Return>' => [ $okbutton, 'Invoke']); + $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']); +} + + +sub menu_select_scheme { + my $sw = $mainwindow->Toplevel(-title => __('Selected scheme')); + $sw->transient($mainwindow); + $sw->grab(); + my @schemes; + foreach my $pkg ($tlpdb->list_packages) { + my $tlpobj = $tlpdb->{'tlps'}{$pkg}; + if ($tlpobj->category eq "Scheme") { + push @schemes, $pkg; + $vars{"$pkg"}=($vars{'selected_scheme'} eq $pkg)? 1:0; + } + } + my @scheme_order = schemes_ordered_for_presentation(); + push @scheme_order, "scheme-custom"; + my $selected = $vars{'selected_scheme'}; + $sw->Label(-text => __("Selected scheme")) + ->pack(-padx => "2m", -pady => "2m"); + my $f2 = $sw->Frame; + foreach my $scheme (@scheme_order) { + my $desc; + if ($scheme ne "scheme-custom") { + my $tlpobj = $tlpdb->get_package("$scheme"); + $desc = $tlpobj->shortdesc; + } else { + $desc = __("custom selection of collections"); + } + my $b; + $b = $f2->Radiobutton( + -variable => \$selected, -value => $scheme, + -text => __($desc), + -justify => 'left', -wraplength => 500) + ->pack(-anchor => 'w', -pady => "1m"); + if ($selected eq $scheme) { + $b->focus(); + } + } + $f2->pack; + my $f3 = $sw->Frame; + my $okbutton = $f3->Button( + -text => __("Ok"), + -command => sub { callback_select_scheme($selected) ; $sw->destroy }) + ->pack(-side => 'left', -padx => "2m", -pady => "2m"); + my $cancelbutton = $f3->Button( + -text => __("Cancel"), -command => sub { $sw->destroy }) + ->pack(-side => 'left', -padx => "2m", -pady => "2m"); + $f3->pack(-expand => 'x'); + $sw->bind('<Return>' => [ $okbutton, 'Invoke']); + $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']); +} + +sub menu_select_standard_collections { + my $sw = $mainwindow->Toplevel(-title => __('Installation collections')); + $sw->transient($mainwindow); + $sw->grab(); + my $fb = $sw->Frame; + my $fc = $sw->Frame; + my $fd = $sw->Frame; + my $f1 = $fb->Frame; + my $f2 = $fb->Frame; + my $f3 = $fb->Frame; + my %lvars = %vars; + $sw->Label(-text => __("Select the collections to be installed")) + ->pack(-padx => "2m", -pady => "2m"); + my $onethirdcol = $#collections_std / 3; + my $twothirdcol = 2 * $onethirdcol; + my $i = 0; + foreach my $coll (sort @collections_std) { + my $tlpobj = $tlpdb->get_package("$coll"); + if ($i < $onethirdcol) { + $f1->Checkbutton( + -variable => \$lvars{$coll}, -text => __($tlpobj->shortdesc)) + ->pack(-anchor => 'w'); + } elsif ($i < $twothirdcol) { + $f2->Checkbutton( + -variable => \$lvars{$coll}, -text => __($tlpobj->shortdesc)) + ->pack(-anchor => 'w'); + } else { + $f3->Checkbutton( + -variable => \$lvars{$coll}, -text => __($tlpobj->shortdesc)) + ->pack(-anchor => 'w'); + } + $i++; + } + $f1->pack(-side => 'left', -padx => "2m", -pady => "2m"); + $f2->pack(-side => 'left', -padx => "2m", -pady => "2m"); + $f3->pack(-side => 'left', -padx => "2m", -pady => "2m"); + $fb->pack(-padx => "2m", -pady => "2m"); + $fc->pack(-side => 'left', -expand => 'x', -padx => "2m", -pady => "2m"); + $fc->Button( + -text => __("Select All"), + -command => sub { select_collections(\%lvars, @collections_std) }) + ->pack(-side => 'left', -padx => "2m", -pady => "2m")->focus(); + $fc->Button( + -text => __("Deselect All"), + -command => sub { deselect_collections(\%lvars, @collections_std) }) + ->pack(-side => 'right', -padx => "2m", -pady => "2m"); + $fd->pack(-side => 'left', -expand => 'x', -padx => "2m", -pady => "2m"); + my $okbutton = $fd->Button(-text => __("Ok"), + -command => sub { + # we call the update only if something has changed + my $changed = 0; + for my $k (keys %lvars) { + if ($vars{$k} ne $lvars{$k}) { + $changed = 1; + last; + } + } + if ($changed) { + %vars = %lvars; + callback_select_collection(); + } + $sw->destroy; + })->pack(-side => 'left', -padx => "2m", -pady => "2m"); + my $cancelbutton = $fd->Button( + -text => __("Cancel"), -command => sub { $sw->destroy }) + ->pack(-side => 'right', -padx => "2m", -pady => "2m"); + $sw->bind('<Return>' => [ $okbutton, 'Invoke']); + $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']); +} + +sub menu_select_symlink { + our ($lbin,$lman,$linfo); + our $osym = $vars{'instopt_adjustpath'}; + our ($binlab,$binb,$manlab,$manb,$infolab,$infob); + sub set_unset_buttons { + $lbin = ($osym ? $vars{'tlpdbopt_sys_bin'} : ''); + $linfo = ($osym ? $vars{'tlpdbopt_sys_info'} : ''); + $lman = ($osym ? $vars{'tlpdbopt_sys_man'} : ''); + if ($osym) { + $binb->configure (-state => 'normal'); + $manb->configure (-state => 'normal'); + $infob->configure(-state => 'normal'); + } else { + $infob->configure(-state => 'disabled'); + $manb->configure (-state => 'disabled'); + $binb->configure (-state => 'disabled'); + } + } + sub return_callback { + if ($osym) { + my $home = getenv('HOME'); + $home = getenv('USERPROFILE') if (win32()); + $home ||= '~'; + $lbin =~ s/^~/$home/; + $linfo =~ s/^~/$home/; + $lman =~ s/^~/$home/; + $vars{'tlpdbopt_sys_bin'} = $lbin; + $vars{'tlpdbopt_sys_info'} = $linfo; + $vars{'tlpdbopt_sys_man'} = $lman; + } + toggle_and_set_opt_variable(\$vars{'instopt_adjustpath'}, \$osym); + $pathadjyesno = $osym; + } + my $sw = $mainwindow->Toplevel( + -title => __('Create symlinks in system directories')); + $sw->transient($mainwindow); + $sw->grab(); + $sw->Checkbutton( + -variable => \$osym, + -text => __("create symlinks in standard directories"), + -command => sub { set_unset_buttons(); } ) + ->grid(-column => 1, -row => 1, -columnspan => 2, -padx => "2m"); + $binlab = $sw->Label(-text => __("binaries to")); + $binb = $sw->Entry(-textvariable => \$lbin); + $manlab = $sw->Label(-text => __("manpages to")); + $manb = $sw->Entry(-textvariable => \$lman); + $infolab = $sw->Label(-text => __("info to")); + $infob = $sw->Entry(-textvariable => \$linfo); + $binlab->grid(-row => 2, -column => 1, -sticky => "w", -padx => "2m"); + $binb->grid(-row => 2, -column => 2, -sticky => "ew", -padx => "2m"); + $manlab->grid(-row => 3, -column => 1, -sticky => "w", -padx => "2m"); + $manb->grid(-row => 3, -column => 2, -sticky => "ew", -padx => "2m"); + $infolab->grid(-row => 4, -column => 1, -sticky => "w", -padx => "2m"); + $infob->grid(-row => 4, -column => 2, -sticky => "ew", -padx => "2m"); + set_unset_buttons(); + my $f2 = $sw->Frame; $f2->grid(-column => 1, -columnspan => 2, -row => 5); + my $okbutton = $f2->Button( + -text => __("Ok"), -command => sub { return_callback(); $sw->destroy }) + ->pack(-side => 'left'); + my $cancelbutton = $f2->Button(-text => __("Cancel"), + -command => sub { $sw->destroy })->pack(-side => 'right'); + $sw->bind('<Return>' => [ $okbutton, 'Invoke']); + $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']); +} + +sub menu_select_binsystems { + my $f2r; + my $f2; + my $sw = $mainwindow->Toplevel(-title => __('Binary system(s)')); + $sw->transient($mainwindow); + $sw->grab(); + my @diskarchs = (); + foreach my $key (keys %vars) { + if ($key=~/binary_(.*)/) { + push @diskarchs, $1; + } + } + $sw->Label(-text => __("Select arch-os"))->pack(-padx => "2m", -pady => "2m"); + $f2 = $sw->Frame; + my $f2l = $f2->Frame; + foreach my $sys (sort TeXLive::TLUtils::sort_archs @diskarchs) { + $f2l->Checkbutton(-variable => \$vars{"binary_$sys"}, + -command => sub { check_on_removal($sw, $sys); }, + -text => platform_desc($sys))->pack(-anchor => 'w'); + } + $f2l->pack(-side => 'left'); + $f2->pack(-padx => "2m", -pady => "2m"); + my $f3 = $sw->Frame; + my $okbutton = $f3->Button( + -text => __("Ok"), + -command => sub { callback_select_systems() ; $sw->destroy }) + ->pack(-side => 'left', -padx => "2m", -pady => "2m"); + my $cancelbutton = $f3->Button( + -text => __("Cancel"), + -command => sub { $sw->destroy }) + ->pack(-side => 'right', -padx => "2m", -pady => "2m"); + $f3->pack(-expand => 'x'); + $sw->bind('<Return>' => [ $okbutton, 'Invoke']); + $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']); +} + +sub check_on_removal { + my $arch_frame = shift; + my $a = shift; + if (!$vars{"binary_$a"} && $a eq $vars{'this_platform'}) { + # removal not supported + $vars{"binary_$a"} = 1; + $arch_frame->Dialog( + -title => __("Warning"), + -text => __("Removals of the main platform not possible!"), + -buttons => [ __("Ok") ])->Show; + } +} + + +sub menu_set_text { + my $w = shift; + my $t = shift; + # if in_place or portable not a complete interface + $w->configure(-text => $t, @_) if $w; +} + +sub menu_set_schemebutton_text { + menu_set_text($schemebutton, "$vars{'selected_scheme'}"); +} + +sub menu_set_binbutton_text { + if (!win32()) { + if ($vars{'n_systems_selected'} == 1) { + my $selsys; + foreach my $key (keys %vars) { + if ($key=~/binary_(.*)/) { + if ($vars{$key}) { + $selsys = $1; + # we have only one system selected, stop here + last; + } + } + } + menu_set_text($bintextbutton, $selsys); + } else { + menu_set_text( + $bintextbutton, __( + "%s out of %s", $vars{'n_systems_selected'}, + $vars{'n_systems_available'})); + } + } +} + +sub menu_set_collections_text { + menu_set_text($collectionstext, __("%s collections out of %s", + $vars{'n_collections_selected'}, $vars{'n_collections_available'}) + . " (" . __("disk space required:") . " $vars{'total_size'} MB)"); +} + +sub menu_set_pathes_text { + if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) { + menu_set_text( + $texdirtext, native_slashify($vars{'TEXDIR'}), + -foreground => "black"); + } else { + menu_set_text( + $texdirtext, + __("(default not allowed or not writable - please change!)"), + -foreground => "red"); + } + menu_set_text($texmflocaltext, native_slashify($vars{'TEXMFLOCAL'})); + if ((-w $vars{'TEXMFSYSVAR'}) || (-w dirname($vars{'TEXMFSYSVAR'}))) { + menu_set_text( + $texmfsysvartext, native_slashify($vars{'TEXMFSYSVAR'}), + -foreground => "black"); + } elsif ("$vars{'TEXMFSYSVAR'}" =~ m;^$vars{'TEXDIR'};) { + if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) { + menu_set_text( + $texmfsysvartext, native_slashify($vars{'TEXMFSYSVAR'}), + -foreground => "black"); + } else { + menu_set_text( + $texmfsysvartext, __("(please change TEXDIR first!)"), + -foreground => "red"); + } + } else { + menu_set_text( + $texmfsysvartext, __("(default not writable - please change!)")); + } + if ((-w $vars{'TEXMFSYSCONFIG'}) || (-w dirname($vars{'TEXMFSYSCONFIG'}))) { + menu_set_text( + $texmfsysconfigtext, native_slashify($vars{'TEXMFSYSCONFIG'}), + -foreground => "black"); + } elsif ("$vars{'TEXMFSYSCONFIG'}" =~ m;^$vars{'TEXDIR'};) { + if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) { + menu_set_text( + $texmfsysconfigtext, native_slashify($vars{'TEXMFSYSCONFIG'}), + -foreground => "black"); + } else { + menu_set_text( + $texmfsysconfigtext, __("(please change TEXDIR first!)"), + -foreground => "red"); + } + } else { + menu_set_text( + $texmfsysconfigtext, __("(default not writable - please change!)")); + } + menu_set_text($texmfhometext, native_slashify($vars{'TEXMFHOME'})); +} + + +sub menu_update_texts { + menu_set_pathes_text; + menu_set_collections_text; + menu_set_binbutton_text; + menu_set_schemebutton_text; + $optletterstate = $::letterdesc[$vars{'instopt_letter'}]; + $optfmtstate = ($vars{'tlpdbopt_create_formats'} ? __("Yes") : __("No")); + $optsrcstate = ($vars{'tlpdbopt_install_srcfiles'} ? __("Yes") : __("No")); + $optdocstate = ($vars{'tlpdbopt_install_docfiles'} ? __("Yes") : __("No")); +} + +sub callback_select_scheme { + my $s = shift; + select_scheme($s); + $editoryesno = ($vars{'collection-texworks'} ? __("Yes") : __("No")); + menu_update_texts(); +} + +sub callback_select_collection { + # special case for collection-texworks: + $editoryesno = ($vars{'collection-texworks'} ? __("Yes") : __("No")); + calc_depends(); + select_scheme("scheme-custom"); + update_numbers(); + menu_update_texts(); +} + +sub callback_select_systems() { + if ($vars{"binary_win32"}) { + $vars{"collection-wintools"} = 1; + } else { + $vars{"collection-wintools"} = 0; + } + calc_depends(); + update_numbers(); + menu_update_texts(); +} + +sub callback_change_texdir { + my $val = shift; + callback_edit_directories('TEXDIR', $val); +} + +sub callback_edit_directories { + my ($key,$val) = @_; + my $home = getenv('HOME'); + if (win32()) { + $home = getenv('USERPROFILE'); + $home =~ s!\\!/!g; + } + $home ||= '~'; + $val =~ s!\\!/!g; + $vars{$key} = $val; + $vars{'TEXDIR'} =~ s/^~/$home/; + $vars{'TEXMFLOCAL'} =~ s/^~/$home/; + $vars{'TEXMFSYSVAR'} =~ s/^~/$home/; + $vars{'TEXMFSYSCONFIG'} =~ s/^~/$home/; + # only if we set TEXDIR we set the others in parallel + my $texdirnoslash; + if ($key eq "TEXDIR") { + if ($vars{'TEXDIR'}=~/^(.*)\/$texlive_release$/) { + $texdirnoslash = $1; + $vars{'TEXMFLOCAL'}="$texdirnoslash/texmf-local"; + $vars{'TEXMFSYSVAR'}="$texdirnoslash/$texlive_release/texmf-var"; + $vars{'TEXMFSYSCONFIG'}="$texdirnoslash/$texlive_release/texmf-config"; + } elsif ($vars{'TEXDIR'}=~/^(.*)$/) { + $texdirnoslash = $1; + $texdirnoslash =~ s!/$!!; + $vars{'TEXMFLOCAL'}="$texdirnoslash/texmf-local"; + $vars{'TEXMFSYSVAR'}="$texdirnoslash/texmf-var"; + $vars{'TEXMFSYSCONFIG'}="$texdirnoslash/texmf-config"; + } + } + menu_update_texts(); +} + +sub callback_edit_var() { + my ($key,$val) = @_; + $vars{$key} = $val; + menu_update_texts(); +} + +#sub dump_vars_stdout { +# foreach my $k (keys %vars) { +# print "DEBUG: vars{$k} = $vars{$k}\n"; +# } +#} + +sub toggle_portable { + my $td = $vars{'TEXDIR'}; + my $b; + if ($vars{'instopt_portable'}) { + $vars{'instopt_portable'} = 0; + $portableyesno = __('No'); + # enable some buttons + for $b ( + $tmflocalbutton, $tmfsysvarbutton, $tmfsysconfigbutton, $tmfhomebutton) { + $b->configure(-state => 'normal'); + } + for $b ($pathbutton, $deskintbutton, $assocbutton, $adminbutton) { + $b->configure(-state => 'normal') if $b; + } + } else { + $vars{'instopt_portable'} = 1; + $portableyesno = __('Yes'); + # disable some buttons. These should get a name first. + for $b ( + $tmflocalbutton, $tmfsysvarbutton, $tmfsysconfigbutton, $tmfhomebutton) { + $b->configure(-state => 'disabled'); + } + $vars{'instopt_adjustpath'} = 0; + $vars{'tlpdbopt_desktop_integration'} = 0; + $vars{'tlpdbopt_file_assocs'} = 0; + $vars{'tlpdbopt_w32_multi_user'} = 0; + $deskintyesno = __("No"); + $pathadjyesno = __("No"); + $fileassocyesno = __("None"); + $adminallyesno = __("No"); + for $b ($pathbutton, $deskintbutton, $assocbutton, $adminbutton) { + $b->configure(-state => 'disabled') if $b; + } + } + set_texlive_default_dirs(); # this sub tests for portable and in_place + $mw -> messageBox( + -title => __('Warning'), + -message => + __("Portable option changed;\nDirectories have been reinitialized"), + -type => 'OK', -icon => 'warning'); + menu_set_pathes_text(); + # same for some options +} + +sub toggle_and_set_opt_variable { + # $varsref: the variable to be changed + # $toggleref: the string representation of the value of $varsref; + # $choicesref: array ref of possible values for $toggleref + my ($varsref, $toggleref, $choicesref) = @_; + $choicesref = \@::yesno unless defined $choicesref; + + my $n_opts = @$choicesref; + $$varsref += 1; + $$varsref = 0 if $$varsref >= $n_opts; + $$toggleref = $$choicesref[$$varsref]; + calc_depends(); + menu_update_texts(); +} + +1; + +__END__ + +### Local Variables: +### perl-indent-level: 2 +### tab-width: 2 +### indent-tabs-mode: nil +### End: +# vim:set tabstop=2 expandtab: # diff --git a/systems/texlive/tlnet/tlpkg/installer/install-menu-text.pl b/systems/texlive/tlnet/tlpkg/installer/install-menu-text.pl new file mode 100644 index 0000000000..3adbb519b9 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/install-menu-text.pl @@ -0,0 +1,1153 @@ +#!/usr/bin/env perl +# $Id: install-menu-text.pl 50297 2019-03-08 23:16:36Z karl $ +# install-menu-txt.pl +# +# Copyright 2007-2017 Norbert Preining, Karl Berry +# Copyright 2007-2008 Reinhard Kotucha +# This file is licensed under the GNU General Public License version 2 +# or any later version. +# +# This file implements the text based menu system for the TeX Live installer. + +use vars qw(@::end_install_hook $::opt_no_cls); + +our %vars; +our $opt_in_place; +our $tlpdb; +our @media_available; +our $media; +our $previoustlpdb; +our @collections_std; +our $texlive_release; + +my $MENU_CONTINUE = -1; +our $MENU_INSTALL = 0; +our $MENU_ABORT = 1; +our $MENU_QUIT = 2; + + +my $RETURN = $MENU_CONTINUE; + +my $portable_toggled = 0; +my $ptoggle_alert = "\n". + " !! Portable option changed;\n" . + " !! Directories have been reinitialized!\n"; + +# @fileassocdesc also defined in install-tl +$::fileassocdesc[0] = "None"; +$::fileassocdesc[1] = "Only new"; +$::fileassocdesc[2] = "All"; + +$::deskintdesc[0] = "None"; +$::deskintdesc[1] = "Menu shortcuts"; +if (win32() && is_seven()) { $::deskintdesc[2] = "Launcher"; } + +sub clear_screen { + return 0 if ($::opt_no_cls); + system (unix() ? 'clear' : 'cls'); +} + +sub string_to_list { + my $string=shift; + return split(//, $string); +} + +# ___, defined in install-tl, replaces the GUI translating function +*::__ = \&::___; + +sub button { # for main menu: 1 char + my $val=shift; + my $vals=shift; # array ref to descriptions of possible values + if (defined $vals) { + return "[$val]"; + } else { # just yes/no + return ($val)? '[X]':'[ ]'; + } +} + +sub obutton { # for options menu: more chars allowed + my $val=shift; + my $vals=shift; # array ref to descriptions of possible values + $vals = [' ', 'X'] unless defined $vals; + return "[$$vals[$val]]"; +} + +sub hbar { + return '=' x79, "\n"; +} + +sub toggle { + my $var=shift; + my $vals=shift; # array ref to descriptions of possible values + $vals = [' ', 'X'] unless defined $vals; + my $n_vals = @$vals; + $vars{$var} += 1; + $vars{$var} = 0 unless $vars{$var} < $n_vals; +} + +sub menu_head { + my $text = shift; + clear_screen; + print hbar(), "$text\n\n"; +} + +sub other_options { + my @options=@_; + my %opts=( + '-' => 'deselect all', + '+' => 'select all', + 'H' => 'help', + 'R' => 'return to main menu', + 'P' => 'save installation profile to \'texlive.profile\' and exit', + 'Q' => 'quit' + ); + + $opts{'I'}=$vars{'instopt_portable'} ? 'start portable installation' : + 'start installation to hard disk'; + + print "\nActions:"; + if ($options[$#options] eq 'diskspace') { + pop @options; + calc_depends (); + print " (disk space required: $vars{'total_size'} MB)"; + } + print "\n"; + + for my $option (@options) { + if (defined $opts{"$option"}) { + printf " <%s> %s\n", $option, $opts{$option}; + } else { + die "other_options: $opts{$option} undefined.\n"; + } + } +} + +sub prompt { + my $prompt = shift; + print "\n$prompt: "; + my $answer = <STDIN>; + $answer = "q" if !defined($answer); + chomp($answer); + return "$answer"; +} + +# The menu loop. A menu is a function. Its return value is a +# reference to another menu or to itself. +sub run_menu_text { + my (@args) = @_; + my $default = 0; + # select mirror if -select-mirror is given + if ($::opt_select_repository) { + # network is always available + my @mirror_list = TeXLive::TLUtils::create_mirror_list(); + print "Please select a repository:\n"; + print "Network repositories:" if ($#media_available >= 0); + my @sel_to_index; + my $selind = 0; + # this is for 0 mirror.ctan.org, but it is printed last! + push @sel_to_index, 0; + $selind++; + for my $i (0..$#mirror_list) { + if ($mirror_list[$i] !~ m/^ /) { + print "\n$mirror_list[$i]\n"; + } else { + print " " if 1 <= $selind && $selind <= 9; # align + print "[$selind] $mirror_list[$i]\n"; + push @sel_to_index, $i; + $selind++; + } + } + print "----\n"; + print "[0] default mirror http://mirror.ctan.org\n"; + my $local_ind = "a"; + if ($#media_available >= 0) { + print "Local repositories:\n"; + # we have some local media present, propose to use it + for my $l (@media_available) { + my ($a, $b) = split ('#', $l); + if ($a eq 'local_compressed') { + print "[$local_ind] compressed archive at $b\n"; + $default = $local_ind; + #$local_ind = chr(ord($local_ind)+1); + $local_ind++; + } elsif ($a eq 'local_uncompressed') { + print "[$local_ind] uncompressed archive at $b\n"; + $default = $local_ind; + $local_ind++; + } elsif ($a eq 'NET') { + print "[$local_ind] cmd line repository: $b\n"; + $default = $local_ind; + $local_ind++; + } else { + warn "$0: Unknown media $l"; + } + } + } + print "[q] quit\n"; + $selind--; + my $selstr = "Your selection "; + if ($local_ind ne "a") { + # we got at least some local repository + if ($local_ind eq "b") { + $selstr .= "(a,0-$selind,q)"; + $local_ind = chr(ord($local_ind)-1); + } else { + # that does not work!!! + #$local_ind--; + $local_ind = chr(ord($local_ind)-1); + $selstr .= "(a-$local_ind,0-$selind,q)"; + } + } + $selstr .= " [$default]: "; + my $got_answer = 0; + my $ans = undef; + while (!defined($ans)) { + print $selstr; + $ans = readline(*STDIN); + if (!defined($ans)) { + print "Please select `q' to quit the program!\n"; + } else { + chomp($ans); + $ans = $default if ($ans eq ""); + if ($ans =~ m/^[0-9]+$/) { + if (0 <= $ans && $ans <= $selind) { + my $mfull; + if ($ans == 0) { + $::init_remote_needed = 'ctan'; + } else { + # only if something else but the predefined mirror is selected + # we something here + $mfull = TeXLive::TLUtils::extract_mirror_entry($mirror_list[$sel_to_index[$ans]]); + print "selected mirror: ", $mfull, "\n"; + $::init_remote_needed = $mfull; + } + } + } elsif ($ans =~ m/^[a-$local_ind]$/) { + my $i = ord($ans) - ord('a'); + my $t = $media_available[$i]; + $t =~ s/^[^#]*#//; + $::init_remote_needed = $t; + } elsif ($ans eq 'q' || $ans eq 'Q') { + print "Goodbye.\n"; + exit 0; + } else { + print "Not a valid answer: $ans.\n"; + $ans = undef; + } + } + } + } + + # run remote init + if (!do_remote_init($::init_remote_needed)) { + warn "\n"; + warn "Please select a different mirror! See info above.\n"; + print STDERR "Press Enter to exit... "; + $ans = readline (*STDIN); + exit (1); + } + + # the text mode installer does not take look at any argument + # except -old-installation-found. + while (@args) { + my $f = shift @args; + if ($f =~ m/^-old-installation-found=(.*)$/) { + my $dn = $1; + print "\nAn old installation of TeX Live has been found in $dn\n"; + print " +If you want the selection of schemes/collections and various options being +taken over press `y', otherwise anything else. + +Import settings from previous TeX Live installation: (y/n): "; + chomp(my $yn = <STDIN>); + if ($yn =~ m/^y$/i) { + import_settings_from_old_tlpdb($dn); + } + } + } + my $menu=\&main_menu; + while ($RETURN == $MENU_CONTINUE) { + $menu=$menu->(); + } + return($RETURN); +} +$::run_menu = \&run_menu_text; + +sub binary_menu { + my %command=( + 'self' => \&binary_menu, + 'R' => \&main_menu, + 'Q' => \&quit + ); + + my @binaries; + my @keys=string_to_list "abcdefghijklmopstuvwxyz"; + my $index=0; + my %keyval; + my $selected_platform; + + menu_head "Available platforms:"; + + foreach my $key (keys %vars) { + if ($key =~ /binary_(.*)/) { + push @binaries, $1; + } + } + + @binaries=sort TeXLive::TLUtils::sort_archs @binaries; + + foreach my $binary (@binaries) { + printf " %s %s %s (%s)\n", $keys[$index], + button($vars{"binary_$binary"}), + platform_desc($binary), + "$binary"; + $keyval{"$keys[$index]"} = "binary_$binary"; + ++$index; + } + other_options qw(- + R Q diskspace); + + my $answer = prompt 'Enter letter(s) to (de)select platforms'; + + my @keystrokes=string_to_list $answer; + + foreach my $keystroke (@keystrokes) { + if ($keystroke eq '-') { + for my $binary (@binaries) { + $vars{"binary_$binary"}=0 if defined $vars{"binary_$binary"}; + } + } + if ($keystroke eq '+') { + for my $binary (@binaries) { + $vars{"binary_$binary"}=1 if defined $vars{"binary_$binary"}; + } + } + if (defined $keyval{$keystroke}) { + toggle "$keyval{$keystroke}"; + } elsif (!defined $command{"\u$answer"}) { + print "Unknown command: $answer\n\n"; + } + } + if ($vars{"binary_win32"}) { + $vars{"collection-wintools"} = 1; + } else { + $vars{"collection-wintools"} = 0; + } + if (defined $command{"\u$answer"}) { + return $command{"\u$answer"}->(); + } else { + return $command{'self'}->(); + } +} + + +sub scheme_menu { + my %command=( + 'self' => \&scheme_menu, + 'R' => \&main_menu, + 'Q' => \&quit + ); + + my @schemes; + my @keys=string_to_list "abcdefghijklmnopstuvwxyz"; + my %keyval; + my $index=0; + + menu_head 'Select scheme:'; + + @schemes = schemes_ordered_for_presentation(); + foreach my $pkg (@schemes) { + $vars{"$pkg"}=($vars{'selected_scheme'} eq $pkg)? 1:0; + } + push @schemes, "scheme-custom"; + + foreach my $scheme (@schemes) { + $keyval{$keys[$index]}="$scheme"; + if ($scheme ne "scheme-custom") { + my $tlpobj = $tlpdb->get_package("$scheme"); + printf " %s %s %s\n", $keys[$index], button($vars{"$scheme"}), + $tlpobj->shortdesc; + } else { + printf " %s %s custom selection of collections\n", + $keys[$index], button($vars{'selected_scheme'} eq "scheme-custom"); + } + ++$index; + } + + select_scheme($vars{'selected_scheme'}); + + if ($vars{"binary_win32"}) { + $vars{"collection-wintools"} = 1; + } else { + $vars{"collection-wintools"} = 0; + } + + other_options qw(R Q diskspace); + my $answer = prompt 'Enter letter to select scheme'; + + if (defined $keyval{"$answer"}) { + $vars{'selected_scheme'}=$keyval{"$answer"}; + select_scheme($vars{'selected_scheme'}); + return $command{'self'}->(); + } + if (defined $command{"\u$answer"}) { + return $command{"\u$answer"}->(); + } else { + print "Unknown command: $answer\n\n"; + return $command{'self'}->(); + } +} + + +sub collection_menu { + my %command=( + 'self' => \&collection_menu, + 'R' => \&main_menu, + 'Q' => \&quit + ); + + my @collections; + my @keys=string_to_list "abcdefghijklmnopstuvwxyzABCDEFGHIJKLMNOPSTUVWXYZ"; + my %keyval; + my $index=0; + my @coll_short_desc; + my @coll_long_desc; + + menu_head 'Select collections:'; + + @collections=sort @collections_std; + + foreach my $collection (@collections) { + next if ($collection eq 'collection-perl'); + my $tlpobj = $tlpdb->get_package("$collection"); + if (length $tlpobj->shortdesc>30) { + push @coll_long_desc, $collection; + } else { + push @coll_short_desc, $collection; + } + } + my $singlecolumn_index=@coll_short_desc-1; + +##<cols=2> + my $lines=@coll_short_desc/2; + ++$lines if (@coll_short_desc%2); + for (0..$lines-1) { + $index=$_; + my $collection=$coll_short_desc[$index]; + my $tlpobj = $tlpdb->get_package("$collection"); + $keyval{$keys[$index]}="$collection"; + printf " %s %s %-33s", $keys[$index], button($vars{"$collection"}), + substr($tlpobj->shortdesc,0,33); + if (defined $coll_short_desc[$index+$lines]) { + my $collection=$coll_short_desc[$index+$lines]; + my $tlpobj=$tlpdb->get_package("$collection"); + $keyval{$keys[$index+$lines]}="$collection"; + printf " %s %s %-32s\n", $keys[$index+$lines], + button($vars{"$collection"}), substr($tlpobj->shortdesc,0,32); + } else { + print "\n"; + } + } +##</cols=2> + $index=$singlecolumn_index; +# print "\n$index\n\n"; + foreach my $collection (@coll_long_desc) { + my $tlpobj=$tlpdb->get_package("$collection"); + $keyval{$keys[$index+1]}="$collection"; + printf " %s %s %s\n", $keys[$index+1], button($vars{"$collection"}), + $tlpobj->shortdesc; + ++$index; + } +##</cols=1> + + other_options qw(- + R Q diskspace); + my $answer = prompt 'Enter letter(s) to (de)select collection(s)'; + + my @keystrokes=string_to_list $answer; + + foreach my $keystroke (@keystrokes) { + if ($keystroke eq '-') { + for my $collection (@collections) { + $vars{"$collection"}=0 if defined $vars{"$collection"}; + } + } + if ($keystroke eq '+') { + for my $collection (@collections) { + $vars{"$collection"}=1 if defined $vars{"$collection"}; + } + } + if (defined $keyval{$keystroke}) { + toggle "$keyval{$keystroke}"; + } elsif (!defined $command{"\u$answer"}) { + print "Unknown command: $answer\n\n"; + } + } + + if (defined $command{"\u$answer"}) { + # if we play around with collections we also select custom-scheme + # but we do not switch back to originally afterwards, too complicated + # to be done + select_scheme("scheme-custom"); + return $command{"\u$answer"}->(); + } else { + return $command{'self'}->(); + } +} + + +sub directories_menu +{ + my %command=( + 'self' => \&directories_menu, + 'R' => \&main_menu, + 'Q' => \&quit + ); + + menu_head "Directories customization:"; + if (!TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) { + print "!! The default location as given below is forbidden or +!! can't be written to. +!! Either change the destination directory using <1> or create it +!! outside this script. +"; + } + my $texmfdir = $vars{'TEXDIR'} . + ($vars{'TEXDIR'} =~ /\/$/ ? 'texmf-dist' : '/texmf-dist'); + if (!$opt_in_place) { + print <<"EOF"; + <1> TEXDIR: $vars{'TEXDIR'} + main tree: $texmfdir +EOF + } else { + print <<"EOF"; + TEXDIR: $vars{'TEXDIR'} + main tree: $texmfdir +EOF + } + if (!$vars{'instopt_portable'}) { + print <<"EOF"; + + <2> TEXMFLOCAL: $vars{'TEXMFLOCAL'} + <3> TEXMFSYSVAR: $vars{'TEXMFSYSVAR'} + <4> TEXMFSYSCONFIG: $vars{'TEXMFSYSCONFIG'} + + <5> TEXMFVAR: $vars{'TEXMFVAR'} + <6> TEXMFCONFIG: $vars{'TEXMFCONFIG'} + <7> TEXMFHOME: $vars{'TEXMFHOME'} + +EOF + + if (win32) { + print " Note: ~ will expand to %USERPROFILE%\n"; + } else { + print " Note: ~ will expand to \$HOME (or to %USERPROFILE% on Windows)\n"; + } + } + + other_options qw(R Q); + my $answer = prompt 'Enter command'; + + if ("\u$answer" eq '1' and !$opt_in_place) { + print "New value for TEXDIR [$vars{'TEXDIR'}]: "; + $answer = &input_dirname (); + $vars{'TEXDIR'} = $answer if $answer ne ""; + my $texdirnoslash; + if ($vars{'TEXDIR'}=~/^(.*)\/$texlive_release$/) { + $texdirnoslash = $1; + $vars{'TEXMFLOCAL'}="$texdirnoslash/texmf-local"; + $vars{'TEXMFSYSVAR'}="$texdirnoslash/$texlive_release/texmf-var"; + $vars{'TEXMFSYSCONFIG'}="$texdirnoslash/$texlive_release/texmf-config"; + } elsif ($vars{'TEXDIR'}=~/^(.*)$/) { + $texdirnoslash = $1; + $texdirnoslash =~ s!/$!!; + $vars{'TEXMFLOCAL'}="$texdirnoslash/texmf-local"; + $vars{'TEXMFSYSVAR'}="$texdirnoslash/texmf-var"; + $vars{'TEXMFSYSCONFIG'}="$texdirnoslash/texmf-config"; + } + return $command{'self'}; + + } elsif ("\u$answer" eq '2' and !$vars{'instopt_portable'}) { + print "New value for TEXMFLOCAL [$vars{'TEXMFLOCAL'}]: "; + $answer = &input_dirname (); + $vars{'TEXMFLOCAL'} = $answer if $answer ne ""; + return $command{'self'}; + + } elsif ("\u$answer" eq '3' and !$vars{'instopt_portable'}) { + print "New value for TEXMFSYSVAR [$vars{'TEXMFSYSVAR'}]: "; + $answer = &input_dirname (); + $vars{'TEXMFSYSVAR'} = $answer if $answer ne ""; + return $command{'self'}; + + } elsif ("\u$answer" eq '4' and !$vars{'instopt_portable'}) { + print "New value for TEXMFSYSCONFIG [$vars{'TEXMFSYSCONFIG'}]: "; + $answer = &input_dirname (); + $vars{'TEXMFSYSCONFIG'} = $answer if $answer ne ""; + return $command{'self'}; + + } elsif ("\u$answer" eq '5' and !$vars{'instopt_portable'}) { + print "New value for TEXMFVAR [$vars{'TEXMFVAR'}]: "; + $answer = &input_dirname ("noexpansion"); + $vars{'TEXMFVAR'} = $answer if $answer ne ""; + return $command{'self'}; + + } elsif ("\u$answer" eq '6' and !$vars{'instopt_portable'}) { + print "New value for TEXMFCONFIG [$vars{'TEXMFCONFIG'}]: "; + $answer = &input_dirname ("noexpansion"); + $vars{'TEXMFCONFIG'} = $answer if $answer ne ""; + return $command{'self'}; + + } elsif ("\u$answer" eq '7' and !$vars{'instopt_portable'}) { + print "New value for TEXMFHOME [$vars{'TEXMFHOME'}]: "; + $answer = &input_dirname ("noexpansion"); + $vars{'TEXMFHOME'} = $answer if $answer ne ""; + return $command{'self'}; + } + + if (defined $command{"\u$answer"}) { + return $command{"\u$answer"}->(); + } else { + print "Unknown command: $answer\n\n"; + return $command{'self'}->(); + } +} + + +# Helper function to read a directory name and clean it up. +# Unless NO_EXPANSION is true, convert to absolute path. +# +sub input_dirname +{ + my $noexpansion = shift; + chomp (my $answer = <STDIN>); + return "" if $answer eq ""; + + $answer =~ s!\\!/!g if win32(); # switch to forward slashes + + if (!$noexpansion) { + my $home = getenv('HOME'); + $home = getenv('USERPROFILE') if win32(); + $home ||= '~'; + $answer =~ s/^~/$home/; # $home expansion + } + + if ($answer !~ m/^~/) { + # relative paths are unlikely to work in texmf.cnf, et al., + # and don't have any apparent practical use. Convert to absolute. + if (! File::Spec->file_name_is_absolute($answer)) { + $answer = TeXLive::TLUtils::tl_abs_path($answer); + $answer = "" unless defined $answer; + } + } + return $answer; +} + + +$vars{'page'}=0; + +sub html2text { + my $filename=shift; + my @text; + open IN, "$filename"; + @all_lines=<IN>; + close IN; + chomp @all_lines; + + my $itemcnt; + my $ordered_list=0; + my $h1_indent=25; + my $h2_indent=3; + my $h3_indent=6; + + for (@all_lines) { + next if /DOCTYPE/; + next if /<!--/; + next if /<title/i; + next if /<\/?body/i; + next if /<\/?html/i; + next if /<\/?head/i; + next if /<\/?meta/i; + next if /^\s*$/; # ignore empty lines + + s/<i>/"/gi; s/<\/i>/"/gi; # italics + s/<tt>/'/gi; s/<\/tt>/'/gi; # typewriter + s/<p>.*//gi; # paragraphs + s/<\/ul>.*//gi; # unsorted lists + s/<\/ol>.*//gi; # ordered lists + s/—/--/gi; # mdash + s/</</gi; s/>/>/gi; # < and > + if (/<h1>(.*?)<\/h1>/i) { + push @text, " " x $h1_indent. "$1\n"; + push @text, " " x $h1_indent. "=" x (length $1). "\n"; + push @text, "\n"; + } elsif (/<h2>(.*?)<\/h2>/i) { + push @text, "\n"; + push @text, " " x $h2_indent. "$1\n"; + push @text, " " x $h2_indent. "~" x (length $1). "\n"; + push @text, "\n"; + } elsif (/<h3>(.*?)<\/h3>/i) { + push @text, "\n"; + push @text, " " x $h3_indent. "$1\n"; + push @text, " " x $h3_indent. "-" x (length $1). "\n"; + push @text, "\n"; + } elsif (/<ol>/i) { + $ordered_list=1; + $itemcnt=1; + } elsif (/<ul>/i) { + $ordered_list=0; + } elsif (/^\s*<li>\s*(.*)/) { + if ($ordered_list) { + push @text, "\n"; + push @text, " $itemcnt. $1\n"; + ++$itemcnt; + } else { + push @text, "\n"; + push @text, " * $1\n"; + } + } else { + push @text, "$_\n"; + } + } + return @text; +} + + +sub help_menu { + my %command=( + 'self' => \&help_menu, + 'R' => \&main_menu, + 'Q' => \&quit + ); + my $installer_help="$installerdir/tlpkg/installer/install-tl.html"; + + clear_screen; + + my @text=html2text "$installer_help"; + my $lines=(@text); + my $overlap=3; + my $lps=32; # lines per screen - overlap + my $firstline=$vars{'page'}*$lps; + my $lastline=$firstline+$lps+$overlap; + my $line=0; +# print "<<<$firstline>>> <<<$lastline>>>\n"; + for (@text) { + print "$_" if ($line>=$firstline and $line<=$lastline); + ++$line; + } + print "\n", hbar, + " <T> top <N> next page <P> previous page <R> return" + . " <Q> quit --", $vars{'page'}+1, "--\n"; + + my $answer = prompt 'Enter command'; + + if ("\u$answer" eq 'T') { + $vars{'page'}=0; + return $command{'self'}; + + } elsif ("\u$answer" eq 'N') { + $vars{'page'}+=1 unless $lastline>$lines; + return $command{'self'}; + + } elsif ("\u$answer" eq 'P') { + $vars{'page'}-=1 if $vars{'page'}>=1; + return $command{'self'}; + + } elsif (defined $command{"\u$answer"}) { + return $command{"\u$answer"}; + + } else { + print "Unknown command: $answer\n\n"; + return $command{'self'}; + } +} + + +sub options_menu { + my $b_path=obutton($vars{'instopt_adjustpath'}); + my $b_doc=obutton($vars{'tlpdbopt_install_docfiles'}); + my $b_src=obutton($vars{'tlpdbopt_install_srcfiles'}); + my $b_fmt=obutton($vars{'tlpdbopt_create_formats'}); + my $b_letter=obutton($vars{'instopt_letter'}); + my $b_adjustrepo=obutton($vars{'instopt_adjustrepo'}); + my $b_deskint=obutton( + $vars{'tlpdbopt_desktop_integration'}, \@::deskintdesc); + my $b_admin=obutton($vars{'tlpdbopt_w32_multi_user'}); + my $b_addoneditor=obutton($vars{'collection-texworks'}); + my $b_restricted=obutton($vars{'instopt_write18_restricted'}); + + my $sys_bin=$vars{'tlpdbopt_sys_bin'}; + my $sys_man=$vars{'tlpdbopt_sys_man'}; + my $sys_info=$vars{'tlpdbopt_sys_info'}; + + my $t_sys_bin=($vars{'instopt_adjustpath'})? $vars{'tlpdbopt_sys_bin'}:''; + my $t_sys_man=($vars{'instopt_adjustpath'})? $vars{'tlpdbopt_sys_man'}:''; + my $t_sys_info=($vars{'instopt_adjustpath'})? $vars{'tlpdbopt_sys_info'}:''; + + my %command=( + 'self' => \&options_menu, + 'R' => \&main_menu, + 'Q' => \&quit + ); + + clear_screen; + menu_head "Options customization:"; + + print <<"EOF"; + <P> use letter size instead of A4 by default: $b_letter + <E> execution of restricted list of programs: $b_restricted + <F> create all format files: $b_fmt +EOF +; + if ($vars{'doc_splitting_supported'} and !$opt_in_place) { + print " <D> install font/macro doc tree: $b_doc\n"; + } + if ($vars{'src_splitting_supported'} and !$opt_in_place) { + print " <S> install font/macro source tree: $b_src\n"; + } + if (!$vars{'instopt_portable'}) { + if (unix() || $::opt_all_options) { + print <<"EOF"; + <L> create symlinks in standard directories: $b_path + binaries to: $t_sys_bin + manpages to: $t_sys_man + info to: $t_sys_info +EOF +; + } else { + print <<"EOF"; + <L> adjust registry entry for path: $b_path +EOF +; + } + if ((win32() && !$vars{'instopt_portable'}) || $::opt_all_options) { + print " <M> Start menu shortcuts / launcher: ".obutton( + $vars{'tlpdbopt_desktop_integration'}, \@::deskintdesc)."\n"; + print " <N> update file associations: ".obutton( + $vars{'tlpdbopt_file_assocs'}, \@::fileassocdesc)."\n"; + if ($::opt_all_options || TeXLive::TLWinGoo::admin()) { + # if we are admin we allow normal user installation, too + print " <U> make installation available to all users: $b_admin\n"; + } + } + } + if (win32() || $::opt_all_options) { + print " <W> install TeXworks front end: $b_addoneditor\n"; + } + if ($media ne "NET") { + print " <Y> after install, set CTAN as source for package updates: $b_adjustrepo\n"; + } + other_options qw(R Q diskspace); + my $answer = prompt 'Enter command'; + + # instopt_adjustpath + + if (unix()) { + if (("\u$answer" eq 'L') and !$vars{'instopt_portable'}) { + my $home = getenv('HOME'); + $home = getenv('USERPROFILE') if (win32()); + $home ||= '~'; + toggle 'instopt_adjustpath'; + if ($vars{'instopt_adjustpath'}) { + print "New value for binary directory [$sys_bin]: "; + chomp($answer=<STDIN>); + $vars{'tlpdbopt_sys_bin'} = "$answer" if (length $answer); + $vars{'tlpdbopt_sys_bin'} =~ s@\\@/@g if (win32()); + $vars{'tlpdbopt_sys_bin'} =~ s/^~/$home/; + if ($vars{'tlpdbopt_sys_bin'}=~/^(.*)\/bin$/) { + $vars{'tlpdbopt_sys_man'}="$1/man"; + $vars{'tlpdbopt_sys_info'}="$1/info"; + } + print "New value for man directory [$vars{'tlpdbopt_sys_man'}]: "; + chomp($answer=<STDIN>); + $vars{'tlpdbopt_sys_man'}="$answer" if (length $answer); + $vars{'tlpdbopt_sys_man'} =~ s@\\@/@g if (win32()); + $vars{'tlpdbopt_sys_man'} =~ s/^~/$home/; + + print "New value for info directory [$vars{'tlpdbopt_sys_info'}]: "; + chomp($answer=<STDIN>); + $vars{'tlpdbopt_sys_info'}="$answer" if (length $answer); + $vars{'tlpdbopt_sys_info'} =~ s@\\@/@g if (win32()); + $vars{'tlpdbopt_sys_info'} =~ s/^~/$home/; + } + return $command{'self'}; + } + } else { + if (("\u$answer" eq 'L') and !$vars{'instopt_portable'}) { + my $home = getenv('HOME'); + $home = getenv('USERPROFILE') if (win32()); + $home ||= '~'; + toggle 'instopt_adjustpath'; + return $command{'self'}; + } + } + +# # tlpdbopt_desktop_integration, tlpdbopt_file_assocs +# +# if (win32() || $::opt_all_options) { +# if ("\u$answer" eq 'M' and !$vars{'instopt_portable'}) { +# toggle 'tlpdbopt_desktop_integration'; +# return $command{'self'}; +# +# } elsif ("\u$answer" eq 'N' and !$vars{'instopt_portable'}) { +# print "New value for file_assocs:\n"; +# print " 0 -- don't tweak the file associations\n"; +# print " 1 -- only add new file associations, don't overwrite old ones\n"; +# print " 2 -- always create file associations to TeX Live programs\n"; +# print "New value for file_assocs [$vars{'tlpdbopt_file_assocs'}]: "; +# chomp (my $a = <STDIN>); +# if ($a eq "0" || $a eq "1" || $a eq "2") { +# $vars{'tlpdbopt_file_assocs'} = $a; +# } +# return $command{'self'}; +# +# } elsif ("\u$answer" eq 'U' and !$vars{'instopt_portable'}) { +# toggle 'tlpdbopt_w32_multi_user'; +# return $command{'self'}; +# } +# } + + # other options + + if (("\u$answer" eq 'M') && !$vars{'instopt_portable'}) { + toggle ('tlpdbopt_desktop_integration', \@::deskintdesc); + return $command{'self'}; + + } elsif (("\u$answer" eq 'N') && !$vars{'instopt_portable'}) { + toggle ('tlpdbopt_file_assocs', \@::fileassocdesc); + return $command{'self'}; + + } elsif ("\u$answer" eq 'P') { + toggle 'instopt_letter'; + return $command{'self'}; + + } elsif ("\u$answer" eq 'F') { + toggle 'tlpdbopt_create_formats'; + return $command{'self'}; + + } elsif ("\u$answer" eq 'E') { + toggle 'instopt_write18_restricted'; + return $command{'self'}; + + } elsif ("\u$answer" eq 'S' and !$opt_in_place) { + toggle 'tlpdbopt_install_srcfiles'; + return $command{'self'}; + + } elsif ("\u$answer" eq 'D' and !$opt_in_place) { + toggle 'tlpdbopt_install_docfiles'; + return $command{'self'}; + + } elsif (defined $command{"\u$answer"}) { + return $command{"\u$answer"}; + + } elsif (("\u$answer" eq 'W') && ($::opt_all_options || win32()) && + !$opt_in_place ) { + toggle 'collection-texworks'; + return $command{'self'}; + + } elsif ("\u$answer" eq 'Y' and $media ne "NET") { + toggle 'instopt_adjustrepo'; + return $command{'self'}; + + } else { + print "Unknown or unsupported command: $answer\n\n"; + return $command{'self'}; + } +} + + +sub quit { + exit 0; + $RETURN = $MENU_QUIT; +} + +sub do_install { + $RETURN = $MENU_INSTALL; +} + +sub toggle_portable { + if ($vars{'instopt_portable'}) { + $vars{'instopt_portable'} = 0; + $vars{'tlpdbopt_desktop_integration'} = 0; + $vars{'instopt_adjustpath'} = 0; + $vars{'tlpdbopt_file_assocs'} = 0; + $vars{'tlpdbopt_w32_multi_user'} = 0; + } else { + $vars{'instopt_portable'} = 1; + $vars{'tlpdbopt_desktop_integration'} = 1; + $vars{'instopt_adjustpath'} = 1; + $vars{'tlpdbopt_file_assocs'} = 1; + $vars{'tlpdbopt_w32_multi_user'} = 1; + } + $portable_toggled = 1; + set_texlive_default_dirs(); # this sub tests for portable and in_place + main_menu; +} + +sub callback_save_profile { + create_profile("texlive.profile"); + print "Installation profile saved to 'texlive.profile', exiting.\n"; + exit(0); +} + +sub main_menu { + my $this_platform=platform_desc($vars{'this_platform'}); + + my $b_path=button($vars{'instopt_adjustpath'}); + my $b_doc=button($vars{'tlpdbopt_install_docfiles'}); + my $b_src=button($vars{'tlpdbopt_install_srcfiles'}); + my $b_fmt=button($vars{'tlpdbopt_create_formats'}); + my $b_letter=button($vars{'instopt_letter'}); + my $b_deskint=button($vars{'tlpdbopt_desktop_integration'}, \@::deskintdesc); + if (win32()) { + my $b_fileassoc=button($vars{'tlpdbopt_file_assocs'}, \@::fileassocdesc); + } + my $b_admin=button($vars{'tlpdbopt_w32_multi_user'}); + my $b_addoneditor=button($vars{'collection-texworks'}); + my $b_restricted=button($vars{'instopt_write18_restricted'}); + my $b_adjustrepo=button($vars{'instopt_adjustrepo'}); + + my $warn_nobin; + + $warn_nobin=set_install_platform; + + $vars{'n_systems_selected'}=0; + $vars{'n_collections_selected'}=0; + foreach my $key (keys %vars) { + if ($key=~/^binary.*/) { + ++$vars{'n_systems_selected'} if $vars{$key}==1; + } + if ($key=~/^collection/) { + ++$vars{'n_collections_selected'} if $vars{$key}==1; + } + } + calc_depends(); + + my %command = ( + 'self' => \&main_menu, + 'D' => \&directories_menu, + 'H' => \&help_menu, + 'I' => \&do_install, + 'O' => \&options_menu, + 'Q' => \&quit, + 'V' => \&toggle_portable, + 'P' => \&callback_save_profile, + ); + if (!$opt_in_place) { + $command{'B'} = \&binary_menu if unix(); + $command{'C'} = \&collection_menu; + $command{'S'} = \&scheme_menu; + } + + clear_screen; + print <<"EOF"; +======================> TeX Live installation procedure <===================== + +======> Letters/digits in <angle brackets> indicate <======= +======> menu items for actions or customizations <======= + + Detected platform: $this_platform + $warn_nobin +EOF + + if (!$opt_in_place) { + print <<"EOF"; + <B> set binary platforms: $vars{'n_systems_selected'} out of $vars{'n_systems_available'} + + <S> set installation scheme: $vars{'selected_scheme'} + + <C> set installation collections: + $vars{'n_collections_selected'} collections out of $vars{'n_collections_available'}, disk space required: $vars{'total_size'} MB +EOF + + } + if ($portable_toggled) { + print $ptoggle_alert; + $portable_toggled = 0; + } + print <<"EOF"; + + <D> set directories: + TEXDIR (the main TeX directory): +EOF + + if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) { + print " $vars{'TEXDIR'}\n"; + } else { + print " !! default location: $vars{'TEXDIR'}\n"; + print " !! is not writable or not allowed, please select a different one!\n"; + } + print <<"EOF"; + TEXMFLOCAL (directory for site-wide local files): + $vars{'TEXMFLOCAL'} + TEXMFSYSVAR (directory for variable and automatically generated data): + $vars{'TEXMFSYSVAR'} + TEXMFSYSCONFIG (directory for local config): + $vars{'TEXMFSYSCONFIG'} + TEXMFVAR (personal directory for variable and automatically generated data): + $vars{'TEXMFVAR'} + TEXMFCONFIG (personal directory for local config): + $vars{'TEXMFCONFIG'} + TEXMFHOME (directory for user-specific files): + $vars{'TEXMFHOME'} + +EOF + +print <<"EOF"; + <O> options: + $b_letter use letter size instead of A4 by default + $b_restricted allow execution of restricted list of programs via \\write18 + $b_fmt create all format files +EOF + + if (!$opt_in_place) { + if ($vars{'doc_splitting_supported'}) { + print " $b_doc install macro/font doc tree\n"; + } + if ($vars{'src_splitting_supported'}) { + print " $b_src install macro/font source tree\n"; + } + } + if (win32()) { + if (!$vars{'instopt_portable'}) { + print " $b_path adjust search path\n"; + print " $b_deskint add menu items, shortcuts, etc.\n"; + print " [$vars{'tlpdbopt_file_assocs'}] update file associations\n"; + if (admin()) { + print " $b_admin make installation available to all users\n"; + } + } + print " $b_addoneditor install TeXworks front end\n"; + } + + print " $b_path create symlinks to standard directories\n" + unless ($vars{'instopt_portable'} || win32()); + + print " $b_adjustrepo after install, set CTAN as source " + . "for package updates\n" + unless ($media eq 'NET'); + + if ($vars{'instopt_portable'}) { + print "\n <V> set up for regular installation to hard disk\n"; + } else { + print "\n <V> set up for portable installation\n"; + } + + other_options qw(I P H Q); + my $answer = prompt 'Enter command'; + + if (defined $command{"\u$answer"}) { + return $command{"\u$answer"}; + } else { + print "Unknown command: $answer\n\n"; + return $command{'self'}; + } +} +# needs a terminal 1 for require to succeed! +1; + +__END__ + +### Local Variables: +### perl-indent-level: 2 +### tab-width: 2 +### indent-tabs-mode: nil +### End: +# vim:set tabstop=2 expandtab: # diff --git a/systems/texlive/tlnet/tlpkg/installer/install-menu-wizard.pl b/systems/texlive/tlnet/tlpkg/installer/install-menu-wizard.pl new file mode 100644 index 0000000000..6a468a8757 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/install-menu-wizard.pl @@ -0,0 +1,622 @@ +#!/usr/bin/env perl +# $Id: install-menu-wizard.pl 48774 2018-09-27 15:05:00Z preining $ +# Copyright 2009-2016 Norbert Preining +# This file is licensed under the GNU General Public License version 2 +# or any later version. + +use strict; +$^W = 1; + +my $svnrev = '$Revision: 11925 $'; +$svnrev =~ m/: ([0-9]+) /; +$::menurevision = ($1 ? $1 : 'unknown'); + +require("TeXLive/trans.pl"); +load_translations(); + +require("$::installerdir/tlpkg/installer/texdirsel.pl"); + +# +# the following lists define which options are shown in the Option screen +# for unix and windows. On W32 with admin privileges both @w32 list options +# are shown +# the values are keys into the %vars array +my @unix_opts = qw/instopt_letter/; +my @w32_opts = qw/instopt_letter + tlpdbopt_desktop_integration + collection-texworks + /; +my @w32_admin_opts = qw/tlpdbopt_w32_multi_user/; + +my @opts_list = (); +if (win32()) { + push @opts_list, @w32_opts; + if (admin()) { + push @opts_list, @w32_admin_opts; + } +} else { + push @opts_list, @unix_opts; +} +my %opts_to_str = ( + "instopt_letter" => __("Default paper size"), + "tlpdbopt_desktop_integration" => __("Add menu shortcuts"), + "tlpdbopt_file_assocs" => __("Change file associations"), + "instopt_adjustpath" => __("Adjust PATH setting in registry"), + "tlpdbopt_w32_multi_user" => __("Installation for all users"), + "collection-texworks" => __("Install TeXworks front end"), +); +my %opts_choices = ( + "instopt_letter" => ["A4", "letter"], +); + + + +our %vars; +our $tlpdb; +our $texlive_release; +our @media_available; + +our $MENU_INSTALL = 0; +our $MENU_ABORT = 1; +our $MENU_QUIT = 2; +our $MENU_ALREADYDONE = 3; + + +my $return = $MENU_INSTALL; + +require Tk; +require Tk::BrowseEntry; +require Tk::Dialog; +require Tk::DialogBox; +require Tk::PNG; +#require Tk::ROText; +#require Tk::ProgressBar; +require Tk::Font; + +use utf8; +no utf8; + +# +# +my $tit; +my $can; +my $prv; +my $nxt; +my $img; +my $dest_display; +my $warning; +our $mw; +my $usedfont; +my $fmain; +my $fbuttons; +my $ftitle; +my $counter; +my $lineskip; + +$::init_remote_needed = 0; + +my $LEFT = 130; +my $RIGHT = 50; +my $TOP = 50; +my $BOTTOM = 50; +my $INF = 300; +my $MWIDTH = 730; +my $MHEIGHT = 480; +my $TITLEHEIGHT = 30; +my $BUTTONSHEIGHT = 50; +my $INNERWIDTH = ($MWIDTH - $LEFT - $RIGHT); +my $INNERHEIGHT = ($MHEIGHT - $TOP - $TITLEHEIGHT - $BOTTOM - $BUTTONSHEIGHT); + +# the main installer runs %{$::run_menu} +$::run_menu = \&run_menu_wizard; + +###################################################################### +# From here on only function definitions +# #################################################################### + +sub menu_abort { + $return = $MENU_ABORT; + $mw->destroy; +} + +################# WELCOME SCREEN ###################################### + +sub run_menu_wizard { + $mw = Tk::MainWindow->new(-width => $MWIDTH, -height => $MHEIGHT); + $mw->protocol('WM_DELETE_WINDOW' => \&menu_abort); + #setup_hooks_wizard(); + + my $img = $mw->Photo(-format => 'png', -file => "$::installerdir/tlpkg/installer/texlive.png"); + $mw->Label(-image => $img, -background => "#0078b8")->place(-x => 0, -y => 0); + + $ftitle = $mw->Frame(-height => $TITLEHEIGHT, -width => $INNERWIDTH); + $ftitle->update; + $ftitle->place(-x => $LEFT, -y => $TOP); + + $tit = $ftitle->Label(-text => __('TeX Live %s Installation', $TeXLive::TLConfig::ReleaseYear)); + + $usedfont= $tit->cget("-font"); + $lineskip = $usedfont->metrics("-linespace"); + + $tit->place(-x => 0, -y => 0); + + $counter = $ftitle->Label(-text => "1/4"); + $counter->place(-x => $INNERWIDTH, -y => 0, -anchor => "ne"); + + $fmain = $mw->Frame(-height => $INNERHEIGHT, -width => $INNERWIDTH); + #, -borderwidth => 1, -relief => "ridge"); + $fmain->place(-x => $LEFT, -y => ($TOP + $TITLEHEIGHT)); + + + $can = $mw->Button(-width => 10, -relief => "ridge", -text => __('Quit'), + -command => \&menu_abort); + $prv = $mw->Button(-width => 10, -relief => "ridge", -text => __('< Back')); + $nxt = $mw->Button(-width => 10, -relief => "ridge", -text => __('Next >')); + + $can->place(-x => $LEFT, -y => ($MHEIGHT - $BOTTOM), -anchor => "sw"); + + my $rb = $MWIDTH - $RIGHT; + $nxt->place(-x => ($MWIDTH - $RIGHT) , + -y => ($MHEIGHT - $BOTTOM), -anchor => "se")->focus(); + + reset_start(); + + Tk::MainLoop(); + return($return); +} + +sub reset_start { + for ($fmain->children) { + $_->destroy; + } + $counter->configure(-text => "1/4"); + $prv->placeForget; + + my $inf = $fmain->Label( + -text => __("Welcome to the installation of TeX Live %s\nhttp://tug.org/texlive\n\nThis wizard will guide you through the installation.", $TeXLive::TLConfig::ReleaseYear) + . ( (win32()) ? "\n\n" . __("In case of trouble, try to disable your virus scanner during installation.") : "" ) + . "\n\n" + . __("For an advanced, customizable installation, please consult\nthe web pages or installation guide.") + . "\n" + . ( (win32()) + ? __("Or use install-tl-advanced.bat.") + : __("Or specify --gui expert to install-tl.") ), + -justify => "left"); + $inf->place(-x => 0, -y => 50); + + # by default, if local media is present, we don't show this option + # unless the command line option -select_repository is given + my $adjust_mirror = 0; + if ($#media_available == -1 || $::opt_select_repository) { + my $mirror_selector = $fmain->Checkbutton( + -text => __("Change default repository"), + -variable => \$adjust_mirror + ); + $mirror_selector->place(-x => 0, -y => 250); + } + + $nxt->configure(-text => __("Next >") , + -command => sub { + if ($adjust_mirror) { + ask_mirror(); + } else { + $::init_remote_needed = 1; + load_remote_screen(); + } + }); + $nxt->configure(-state => "normal"); + $can->place(-x => $LEFT, -y => ($MHEIGHT - $BOTTOM), -anchor => "sw"); +} + +################## MIRROR SCREEN ################################ + +sub ask_mirror { + for ($fmain->children) { + $_->destroy; + } + $counter->configure(-text => "1-1/4"); + + my @mirror_list; + my @netlst; + my @loclst; + if ($#media_available >= 0) { + for my $l (@media_available) { + my ($a, $b) = split ('#', $l); + if ($a eq 'local_compressed' || $a eq 'local_uncompressed') { + push @loclst, " $b"; + } elsif ($a eq 'NET') { + #push @netlst, " cmd line repository: $b"; + push @netlst, " " . __("Command line repository") . ": $b"; + } else { + tlwarn("Unknown media $l\n"); + } + } + if ($#loclst >= 0) { + push @mirror_list, __("LOCAL REPOSITORIES"); + push @mirror_list, @loclst; + } + } + push @mirror_list, __("NETWORK REPOSITORIES"); + push @mirror_list, " " . __("Default remote repository") . ": http://mirror.ctan.org"; + push @mirror_list, @netlst; + push @mirror_list, TeXLive::TLUtils::create_mirror_list(); + + my $mirror_entry; + + $fmain->Label(-text => __("Select repository") . ":")->place( + -x => 0, -y => 0); + $fmain->Label(-text => __("Mirror:"))->place(-x => 0, -y => 50); + $fmain->BrowseEntry(-state => 'readonly', + -listheight => 12, + -listwidth => 400, + -width => 35, + -autolistwidth => 1, + -choices => \@mirror_list, + -browsecmd => + sub { + if ($mirror_entry !~ m/^ /) { + $mirror_entry = ""; + } elsif ($mirror_entry =~ m!(http|ftp)://!) { + $mirror_entry = TeXLive::TLUtils::extract_mirror_entry($mirror_entry); + } else { + $mirror_entry =~ s/^\s*//; + # $mirror_entry = TeXLive::TLUtils::extract_mirror_entry($mirror_entry); + } + }, + -variable => \$mirror_entry)->place(-x => 150, -y => 50); + + $prv->configure(-text => __('< Back'), -command => \&reset_start ); + $nxt->configure(-text => __('Next >'), + -command => + sub { $::init_remote_needed = 1; load_remote_screen($mirror_entry); }); + + my $rb = $MWIDTH - $RIGHT; + $rb -= $nxt->width; + $rb -= 30; + + $prv->place(-x => $rb, -y => ($MHEIGHT - $BOTTOM), -anchor => "se"); + $can->place(-x => $LEFT, -y => ($MHEIGHT - $BOTTOM), -anchor => "sw"); +} + +sub ask_mirror_hierarchical { + for ($fmain->children) { + $_->destroy; + } + $counter->configure(-text => "1-1/4"); + + our $mirrors; + require("installer/mirrors.pl"); + + my @continents = sort keys %$mirrors; + my @countries; + my @mirrors; + $fmain->Label(-text => "Select mirror for installation:")->place( + -x => 0, -y => 0); + my $continent = ""; + my $country = ""; + my $mirror = ""; + my $cbrowser; + my $mbrowser; + $fmain->Label(-text => __("Continent"))->place(-x => 0, -y => 50); + $fmain->BrowseEntry(-state => 'readonly', + -listheight => $#continents + 1, -choices => \@continents, + -variable => \$continent, + -browsecmd => + sub { + $cbrowser->delete(0,"end"); + @countries = sort keys %{$mirrors->{$continent}}; + for my $c (@countries) { + $cbrowser->insert("end", $c); + } + $mirror = ""; + $country = ""; + })->place(-x => 150, -y => 50); + $fmain->Label(-text => __("Countries"))->place(-x => 0, -y => 100); + $cbrowser = $fmain->BrowseEntry(-state => 'readonly', + -listheight => 5, -choices => \@countries, + -variable => \$country, + -browsecmd => + sub { + $mbrowser->delete(0,"end"); + @mirrors = sort keys %{$mirrors->{$continent}{$country}}; + for my $m (@mirrors) { + $mbrowser->insert("end", $m); + } + # always select the first mirror in the list + if ($#mirrors >= 0) { + $mirror = $mirrors[0]; + } else { + $mirror = ""; + } + })->place(-x => 150, -y => 100); + $fmain->Label(-text => __("Mirrors"))->place(-x => 0, -y => 150); + $mbrowser = $fmain->BrowseEntry(-state => 'readonly', + -listheight => 5, -choices => \@mirrors, + -variable => \$mirror,)->place(-x => 150, -y => 150); + + $prv->configure(-text => __('< Back'), -command => \&reset_start ); + $nxt->configure(-text => __('Next >'), + -command => + sub { + if (!defined($continent) || !defined($country) || !defined($mirror) || + $continent eq "" || $country eq "" || $mirror eq "") { + # do nothing, we just use the default mirror + $::init_remote_needed = 1; + load_remote_screen(); + } else { + my %m = %{$mirrors->{$continent}->{$country}->{$mirror}->{'protocols_path'}}; + my $mfull; + $mfull = "ftp://" . $m{'ftp'} if defined($m{'ftp'}); + $mfull = "http://" . $m{'http'} if defined($m{'http'}); + # remove terminal / if present + $mfull =~ s!/$!!; + $mfull .= "/" . $TeXLive::TLConfig::TeXLiveServerPath; + # set the selected location before going on! + $::init_remote_needed = 1; + load_remote_screen($mfull); + } + }); + + my $rb = $MWIDTH - $RIGHT; + $rb -= $nxt->width; + $rb -= 30; + + $prv->place(-x => $rb, -y => ($MHEIGHT - $BOTTOM), -anchor => "se"); + $can->place(-x => $LEFT, -y => ($MHEIGHT - $BOTTOM), -anchor => "sw"); +} + + +################## PATH SCREEN ################################ + +sub load_remote_screen { + my $remote_path = shift; + for ($fmain->children) { + $_->destroy; + } + $counter->configure(-text => "1-2/4"); + + if ($::init_remote_needed) { + my $labela = $fmain->Label(-text => __('Please wait while the repository database is loaded.'))->place(-x => 0, -y => 50); + my $labelb = $fmain->Label(-text => __('This will take some time!'))->place(-x => 0, -y => 150); + $prv->placeForget; + $nxt->placeForget; + $can->configure(-text => __('Cancel'), + -command => sub { $return = $MENU_ABORT; $mw->destroy; }); + $mw->update; + if (!only_load_remote($remote_path)) { + $labela->configure(-text => __('Could not load remote TeX Live Database:') . $remote_path); + $labelb->configure(-text => __('Please go back and select a different mirror.')); + $prv->configure(-text => __('< Back'), -command => \&reset_start ); + } elsif (!do_version_agree()) { + $labela->configure(-text => __('The TeX Live versions of the local installation +and the repository being accessed are not compatible: + local: %s +repository: %s', $TeXLive::TLConfig::ReleaseYear, $texlive_release)); + $labelb->configure(-text => __('Please go back and select a different mirror.')); + $prv->configure(-text => __('< Back'), -command => \&reset_start ); + } else { + final_remote_init($remote_path); + ask_path(); + } + } else { + ask_path(); + } + + my $rb = $MWIDTH - $RIGHT; + $rb -= $nxt->width; + $rb -= 30; + + $prv->place(-x => $rb, -y => ($MHEIGHT - $BOTTOM), -anchor => "se"); + $nxt->place(-x => ($MWIDTH - $RIGHT) , + -y => ($MHEIGHT - $BOTTOM), -anchor => "se")->focus(); +} + +sub ask_path { + for ($fmain->children) { + $_->destroy; + } + + $counter->configure(-text => "2/4"); + + $dest_display = native_slashify($vars{'TEXDIR'}); + + my $lab = $fmain->Label(-text => __('Destination folder:')); + my $val = $fmain->Label(-textvar => \$dest_display); + my $but = $fmain->Button(-text => __("Change"), -command => \&change_path, + -relief => "ridge", -width => 10); + + # texworks will be anyway installed in scheme-full + #my $but_tw = $fmain->Checkbutton(-text => __("Install TeXworks front end'), + # -variable => \$vars{"addon_editor"}); + + # + # disable the "Advanced Configuration" button switching to the + # perltk installer + # + #my $cb = $fmain->Button(-text => __("Advanced Configuration"), + # -relief => "ridge", + # -command => sub { $mw->destroy; + # require("installer/install-menu-perltk.pl"); + # setup_hooks_perltk(); + # $return = run_menu_perltk(); + # }); + + calc_depends(); + + + $fmain->Label(-text => __("The destination folder will contain the installation.\nIt is strongly recommended to keep the year as the last component."), + -justify => "left")->place(-x => 0, -y => 20); + + my $ytmp = 100; + $lab->place(-x => 0, -y => $ytmp, -anchor => "w"); + $ytmp += ($lineskip + 10); + $val->place(-x => 0, -y => $ytmp, -anchor => "w"); + + $but->place(-x => $INNERWIDTH, -y => $ytmp, -anchor => "e"); + + $warning = $fmain->Label(-foreground => "red"); + check_show_warning(); + $ytmp += ($lineskip + 10); + $warning->place(-x => 0, -y => $ytmp, -anchor => "w"); + + + #if (win32()) { + # $but_tw->place(-x => 0, -y => $ytmp + 60); + #} + + #$cb->place(-x => $INNERWIDTH, -y => $INNERHEIGHT, -anchor => "se"); + + $fmain->Label(-text => __('disk space required:') . " $vars{'total_size'} MB", + -justify => "left" + )->place(-x => 0, -y => $fmain->height, -anchor => "sw"); + + $prv->configure(-text => __('< Back'), -command => \&reset_start ); + $nxt->configure(-text => __('Next >'), -command => \&ask_options ); + + my $rb = $MWIDTH - $RIGHT; + $rb -= $nxt->width; + $rb -= 30; + + $prv->place(-x => $rb, -y => ($MHEIGHT - $BOTTOM), -anchor => "se"); + $can->place(-x => $LEFT, -y => ($MHEIGHT - $BOTTOM), -anchor => "sw"); +} + +sub check_show_warning { + if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) { + $warning->configure(-text => ""); + $nxt->configure(-state => "normal"); + } else { + $warning->configure(-text => __('(default not allowed or not writable - please change!)')); + $nxt->configure(-state => "disabled"); + } +} + +sub callback_change_texdir { + my ($val) = @_; + my $home = getenv('HOME'); + my $texdirnoslash; + if (win32()) { + $home = getenv('USERPROFILE'); + $home =~ s!\\!/!g; + } + $home ||= '~'; + $val =~ s!\\!/!g; + $vars{'TEXDIR'} = $val; + $vars{'TEXDIR'} =~ s/^~/$home/; + $vars{'TEXMFLOCAL'} =~ s/^~/$home/; + $vars{'TEXMFSYSVAR'} =~ s/^~/$home/; + $vars{'TEXMFSYSCONFIG'} =~ s/^~/$home/; + # only if we set TEXDIR we set the others in parallel + if ($vars{'TEXDIR'}=~/^(.*)\/$texlive_release$/) { + $vars{'TEXMFLOCAL'}="$1/texmf-local"; + $vars{'TEXMFSYSVAR'}="$1/$texlive_release/texmf-var"; + $vars{'TEXMFSYSCONFIG'}="$1/$texlive_release/texmf-config"; + } elsif ($vars{'TEXDIR'}=~/^(.*)$/) { + $texdirnoslash = $1; + $texdirnoslash =~ s!/$!!; + $vars{'TEXMFLOCAL'}="$texdirnoslash/texmf-local"; + $vars{'TEXMFSYSVAR'}="$texdirnoslash/texmf-var"; + $vars{'TEXMFSYSCONFIG'}="$texdirnoslash/texmf-config"; + } + #$dest = $vars{'TEXDIR'}; + $dest_display = native_slashify($vars{'TEXDIR'}); # useful as -textvar value in Labels + check_show_warning(); +} + +################## OPTIONS SCREEN ################################ + +sub ask_options { + for ($fmain->children) { + $_->destroy; + } + $counter->configure(-text => "3/4"); + + my $inf = $fmain->Label(-text => __("This screen allows you to configure some options"), -justify => "left"); + $inf->place(-x => 0, -y => 20); + + calc_depends(); + + my $ytmp = 60; + + for my $o (@opts_list) { + if (exists($opts_choices{$o})) { + my $fopt = $fmain->Frame()->place(-x => 0, -y => $ytmp); + $fopt->Label( + -text => $opts_to_str{$o} . ":\t" + )->pack(-side => 'left'); + for (my $i = 0; $i < @{$opts_choices{$o}}; $i++) { + $fopt->Radiobutton( + -text => __($opts_choices{$o}->[$i]), + -variable => \$vars{$o}, + -value => $i, + )->pack(-side => 'left'); + } + } else { + $fmain->Checkbutton(-text => $opts_to_str{$o}, + -variable => \$vars{$o})->place(-x => 0, -y => $ytmp); + } + $ytmp += 50; + } + + $prv->configure(-text => __('< Back'), -command => \&ask_path ); + $nxt->configure(-text => __('Next >'), -command => \&ask_go ); + + my $rb = $MWIDTH - $RIGHT; + $rb -= $nxt->width; + $rb -= 30; + + $prv->place(-x => $rb, -y => ($MHEIGHT - $BOTTOM), -anchor => "se"); +} + + +################## INSTALL SCREEN ############################# + +sub ask_go { + for ($fmain->children) { + $_->destroy; + } + $counter->configure(-text => "4/4"); + my $inf = $fmain->Label(-justify => "left", -text => __("We are ready to install TeX Live %s.\nThe following settings will be used.\nIf you want to change something please go back,\notherwise press the \"Install\" button.", $TeXLive::TLConfig::ReleaseYear)); + + + $inf->place(-x => 0, -y => 80); + + my $ytmp = 170; + + $fmain->Label(-justify => "left", + -text => __("Destination folder:") . "\t $dest_display")->place(-x => 0, -y => $ytmp); + $ytmp += 20; + + for my $o (@opts_list) { + my $text = $opts_to_str{$o} . ":\t"; + if (exists ($opts_choices{$o})) { + $text .= $opts_choices{$o}->[$vars{$o}]; + } else { + $text .= $vars{$o} ? __("Yes") : __("No"); + } + $fmain->Label(-justify => "left", + -text => $text)->place(-x => 0, -y => $ytmp); + $ytmp += 20; + } + + + + $nxt->configure(-text => __('Install'), + -command => sub { $return = $MENU_INSTALL; $mw->destroy; }); +# -command => \&wizard_installation_window); + $prv->configure(-text => __('< Back'), -command => \&ask_options); + $can->place(-x => $LEFT, -y => ($MHEIGHT - $BOTTOM), -anchor => "sw"); +} + +################### END OF MODULE RETURN 1 FOR REQUIRE ########### + +1; + +__END__ + +### Local Variables: +### perl-indent-level: 2 +### tab-width: 2 +### indent-tabs-mode: nil +### End: +# vim:set tabstop=2 expandtab: # diff --git a/systems/texlive/tlnet/tlpkg/installer/install-tl-gui.tcl b/systems/texlive/tlnet/tlpkg/installer/install-tl-gui.tcl new file mode 100644 index 0000000000..69a653fc87 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/install-tl-gui.tcl @@ -0,0 +1,2063 @@ +#!/usr/bin/env wish + +# Copyright 2018, 2019 Siep Kroonenberg + +# This file is licensed under the GNU General Public License version 2 +# or any later version. + +# Tcl/Tk frontend for TeX Live installer + +# Installation can be divided into three stages: +# +# 1. preliminaries. This stage may involve some interaction with the user, +# which can be channeled through message boxes +# 2. a menu +# 3. the actual installation +# +# During stage 1. and 3. this wrapper collects stdout and stderr from +# the perl installer, with stderr being redirected to stdout. +# This output will be displayed in a text widget during stage 3, +# and in debug mode also in stage 1. +# During stage 3, we shall use event-driven, non-blocking I/O, which is +# needed for a scrolling display of installer output. +# +# Main window: +# filled successively with: +# - a logo, and 'loading...' label, by way of splash +# - a menu for stage 2 +# - a log text widget for tracking stage 3 +# ::out_log should be cleared before stage 3. +# +# In profile mode, the menu stage is skipped. + +package require Tk + +# security: disable send +catch {rename send {}} + +# This file should be in $::instroot/tlpkg/installer. +# On non-windows platforms, install-tl functions as a wrapper +# for this file if it encounters a parameter '-gui tcl'. +# This allows automatic inclusion of a '--' parameter to separate +# tcl parameters from script parameters. + +set ::instroot [file normalize [info script]] +set ::instroot [file dirname [file dirname [file dirname $::instroot]]] + +# declarations, initializations and procs shared with tlshell.tcl +source [file join $::instroot "tlpkg" "tltcl" "tltcl.tcl"] + +### initialize some globals ### + +# perl installer process id +set ::perlpid 0 + +set ::out_log {}; # list of strings + +set ::perlbin "perl" +if {$::tcl_platform(platform) eq "windows"} { + # the batch wrapper should have put perl.exe on the searchpath + set ::perlbin "perl.exe" +} + +# menu modes +set ::advanced 0 +set ::alltrees 0 + +# interactively select repository +set ::select_repo 0 + +proc kill_perl {} { + if $::perlpid { + catch { + if {$::tcl_platform(platform) eq "unix"} { + exec -ignorestderr kill $::perlpid >& /dev/null + } else { + exec -ignorestderr taskkill /pid $::perlpid /t /f + } + } + } +} + +proc err_exit {{mess ""}} { + if {$mess eq ""} {set mess "Error"} + append mess "\n" [get_stacktrace] + tk_messageBox -icon error -message $mess + # kill perl process, just in case + kill_perl + exit +} ; # err_exit + +# warning about non-empty target tree +set ::td_warned 0 + +proc is_nonempty {td} { + if {! [file exists $td]} {return 0} + return [expr {[llength [glob -nocomplain -directory $td *]] > 0}] +} + +proc td_warn {td} { + set ans [tk_messageBox -icon warning -type ok \ + -message [__ "Target directory %s non-empty;\nmay cause trouble!" $td]] + set ::td_warned 1 +} + +proc td_question {td} { + set ans [tk_messageBox -icon warning -type yesno \ + -message [__ "Target directory %s non-empty;\nare you sure?" $td]] + set ::td_warned 1 + return $ans +} + +### procedures, mostly organized bottom-up ### + +# the procedures which provide the menu with the necessary backend data, +# i.e. read_descs, read_vars and read_menu_data, are defined near the end. + +set clock0 [clock milliseconds] +set profiling 0 +proc show_time {s} { + if $::profiling { + puts [format "%s: %d" $s [expr {[clock milliseconds] - $::clock0}]] + } +} + +# for debugging frontend-backend communication: +# write to a logfile which is shared with the backend. +# both parties open, append and close every time. + +set dblogdir "/tmp" +if [info exists ::env(TMPDIR)] { + set dblogdir $::env(TMPDIR) +} elseif [info exists ::env(TMP)] { + set dblogdir $::env(TMP) +} elseif [info exists ::env(TEMP)] { + set dblogdir $::env(TEMP) +} +set ::dblfile [file join $dblogdir "dblog"] +unset dblogdir + +proc dblog {s} { + set db [open $::dblfile a] + set t [get_stacktrace] + puts $db "TCL: $s\n$t" + close $db +} + +proc maybe_print_welcome {} { + # if the last non-empty line was "All done", then installation is completed. + # otherwise, it was help output or an interrupted installation. + # we allow for spurious empty lines at the end of the backend output. + + set all_done 0 + for {set i [.log.tx count -lines 1.0 end]} {$i > 0} {incr i -1} { + set l [.log.tx get ${i}.0 ${i}.end] + if {$l ne ""} { + if {[string range $l 0 11] eq "Installed on"} { + set all_done 1 + } + break + } + } + if {!$all_done} return + # need TEXDIR and this_platform in case of profile install + if {! [info exists ::vars(this_platform)] || \ + ! [info exists ::vars(TEXDIR)]} { + if [regexp {^Installed on platform (.*) at (.*)$} $l m p r] { + set ::vars(this_platform) $p + set ::vars(TEXDIR) $r + } else { + set ::vars(this_platform) "PLATFORM" + set ::vars(TEXDIR) "ROOT" + } + } + + .log.tx configure -state normal + .log.tx tag configure center -justify center + .log.tx delete ${i}.0 end + .log.tx insert end "\n\n" + .log.tx insert end [__ "Welcome to TeX Live!"] center + .log.tx insert end "\n\n" + # tags appear to interfere with --/::msgcat::mc !?! + set s [__ "See %s/index.html for links to documentation.\nThe TeX Live web site (https://tug.org/texlive/) contains any updates and corrections. TeX Live is a joint project of the TeX user groups around the world; please consider supporting it by joining the group best for you. The list of groups is available on the web at https://tug.org/usergroups.html." $::vars(TEXDIR)] + .log.tx insert end $s center + if {$::tcl_platform(platform) ne "windows"} { + .log.tx insert end "\n\n" + set s [__ "Add %s/texmf-dist/doc/man to MANPATH.\nAdd %s/texmf-dist/doc/info to INFOPATH.\nMost importantly, add %s/bin/%s\nto your PATH for current and future sessions." $::vars(TEXDIR) $::vars(TEXDIR) $::vars(TEXDIR) $::vars(this_platform)] + .log.tx insert end $s center + } + .log.tx insert end "\n" + .log.tx yview moveto 1 + if {$::tcl_platform(os) ne "Darwin"} {.log.tx configure -state disabled} +} + +# regular read_line +proc read_line {} { + while 1 { + if [catch {chan gets $::inst l} len] { + # catch [chan close $::inst] + err_exit " +Error while reading from Perl back end. +This should not have happened!" + } elseif {$len < 0} { + # catch [chan close $::inst] + return [list -1 ""] + } elseif {[string range $l 0 1] eq "D:" || [string range $l 0 2] eq "DD:" \ + || [string range $l 0 3] eq "DDD:"} { + lappend ::out_log $l + } else { + return [list $len $l] + } + } +}; # read_line + +proc read_line_no_eof {} { + set ll [read_line] + if {[lindex $ll 0] < 0} { + log_exit " +Unexpected closed backend. +This should not have happened!" + } + set l [lindex $ll 1] + # TODO: test under debug mode + return $l +}; # read_line_no_eof + +# non-blocking i/o: callback for "readable" while the splash screen is up +# and the back end tries to contact the repository +proc read_line_loading {} { + set l "" ; # will contain the line to be read + if {([catch {chan gets $::inst l} len] || [chan eof $::inst])} { + catch {chan close $::inst} + # note. the normal way to terminate is terminating the GUI shell. + # This closes stdin of the child + } elseif {$len >= 0} { + if {$l eq "endload"} { + chan configure $::inst -blocking 1 + chan event $::inst readable {} + set ::loaded 1 + } + } +}; # read_line_loading + +# non-blocking i/o: callback for "readable" during stage 3, installation +# ::out_log should no longer be needed +proc read_line_cb {} { + set l "" ; # will contain the line to be read + if {([catch {chan gets $::inst l} len] || [chan eof $::inst])} { + catch {chan close $::inst} + # note. the normal way to terminate is terminating the GUI shell. + # This closes stdin of the child + .close state !disabled + if [winfo exists .abort] {.abort state disabled} + maybe_print_welcome + } elseif {$len >= 0} { + # regular output + .log.tx configure -state normal + .log.tx insert end "$l\n" + .log.tx yview moveto 1 + if {$::tcl_platform(os) ne "Darwin"} {.log.tx configure -state disabled} + } +}; # read_line_cb + +proc maybe_abort {} { + set ans [tk_messageBox -message [__ "Really abort?"] -type yesno \ + -default no] + if {$ans eq "no"} { + return + } + catch {chan close $::inst} + kill_perl + exit +} + +# modify parameter list for either restarting gui installer +# or for starting back end + +proc replace_lang_parameter {} { + # edit original command line by removing any language parameter + # and adding a repository parameter $m. same for language + set i [llength $::argv] + while {$i > 0} { + incr i -1 + set p [lindex $::argv $i] + if {$p eq "-lang" || $p eq "-gui-lang"} { + set j [expr {$i+1}] + if {$j < [llength $::argv]} { + set ::argv [lreplace $::argv $i $j] + } else { + set ::argv [lreplace $::argv $i] + } + set ::argv [lreplace $::argv $i [expr {$i+1}]] + } + } + lappend ::argv "-lang" $::lang +} + +proc replace_repo_parameter {m} { + # edit original command line by removing any repository parameter + # and adding a repository parameter $m. same for language + set i $::argc + while {$i > 0} { + incr i -1 + set p [lindex $::argv $i] + if {$p in [list "-location" "-url" "-repository" "-repos" "-repo"]} { + set j [expr {$i+1}] + if {$j < [llength $::argv]} { + set ::argv [lreplace $::argv $i $j] + } else { + set ::argv [lreplace $::argv $i] + } + } + } + lappend ::argv "-repository" $m +} + +# restart installer with chosen repository +proc restart_with_mir {m} { + # edit original command line by removing any repository parameter + # and adding a repository parameter $m. same for language + replace_repo_parameter $m + replace_lang_parameter + set cmd [linsert $::argv 0 [info nameofexecutable] [info script] "--"] + + # terminate back end + catch {chan close $::inst} + kill_perl + + # restart install-tl with edited command-line + exec {*}$cmd & + exit +} ; # restart_with_mir + +proc continue_with_mir {m} { + replace_repo_parameter $m + set ::mir_selected 1 ; # this will cause select_mirror to finish up +} + +# add $::instroot as local repository if applicable +proc mirror_menu_plus {wnd cmd} { + set have_local 0 + if [file isdirectory [file join $::instroot "archive"]] { + set have_local 1 + } elseif [file readable \ + [file join $::instroot "texmf-dist" "web2c" "texmf.cnf"]] { + set have_local 1 + } + mirror_menu $wnd $cmd + if {[winfo class $wnd] ne "TMenubutton"} { + error_exit "No mirror list found" + } else { + if $have_local { + $wnd.m insert 0 command -label "$::instroot ([__ "Local repository"])" \ + -command "$cmd $::instroot" + } + } + return $wnd +} + +############################################################## + +##### special-purpose uses of main window: select_mirror, splash, log ##### + +proc pre_splash {} { + # build splash window minus buttons + wm withdraw . + + # picture and logo + catch { + image create photo tlimage -file \ + [file join $::instroot "tlpkg" "installer" "texlion.gif"] + pack [frame .white -background white] -side top -fill x -expand 1 + label .image -image tlimage -background white + pack .image -in .white + } + + # wallpaper for remaining widgets + pack [ttk::frame .bg -padding 3] -fill both -expand 1 + + # buttons: abort button, mirrors dropdown menu + pack [ttk::frame .splfb] -in .bg -side bottom -fill x +} + +proc select_mirror {} { + + # buttons: abort button, mirrors dropdown menu, continue + ppack [mirror_menu_plus .splfb.slmir_m continue_with_mir] \ + -side right + ppack [ttk::button .splfb.slmir_a -text [__ "Abort"] -command maybe_abort] \ + -side right + + wm attributes . -topmost + update + wm state . normal + raise . + vwait ::mir_selected +} ; # select_mirror + +proc make_splash {} { + + foreach c [winfo children .splfb] { + catch {destroy $c} + } + update + + ppack [ttk::button .spl_a -text [__ "Abort"] -command maybe_abort] \ + -side right -in .splfb + ppack [mirror_menu_plus .spl_o restart_with_mir] -side right -in .splfb + + # some text + ppack [ttk::label .text -text [__ "TeX Live Installer"] \ + -font bigfont] -in .bg + if {! $::select_repo} { + ppack [ttk::label .loading -text [__ "Trying to load %s. + +If this takes too long, press Abort or choose another repository." \ + $::prelocation]] -in .bg + } + + wm attributes . -topmost + update + wm state . normal + raise . +}; # make_splash + +# ATM ::out_log will be shown only at the end +proc show_log {{do_abort 0}} { + wm withdraw . + foreach c [winfo children .] { + catch {destroy $c} + } + + # wallpaper + pack [ttk::frame .bg -padding 3] -fill both -expand 1 + + # buttons at bottom + pack [ttk::frame .bottom] -in .bg -side bottom -fill x + ttk::button .close -text [__ "Close"] -command exit + ppack .close -in .bottom -side right + if $do_abort { + ttk::button .abort -text [__ "Abort"] -command maybe_abort + ppack .abort -in .bottom -side right + } + bind . <Escape> { + if {[winfo exists .close] && ! [.close instate disabled]} {.close invoke} + } + + # logs plus their scrollbars + pack [ttk::frame .log] -in .bg -fill both -expand 1 + pack [ttk::scrollbar .log.scroll -command ".log.tx yview"] \ + -side right -fill y + ppack [text .log.tx -height 10 -wrap word -font TkDefaultFont \ + -yscrollcommand ".log.scroll set"] \ + -expand 1 -fill both + .log.tx configure -state normal + .log.tx delete 1.0 end + foreach l $::out_log { + .log.tx insert end "$l\n" + } + if {$::tcl_platform(os) ne "Darwin"} {.log.tx configure -state disabled} + .log.tx yview moveto 1 + + wm resizable . 1 1 + wm overrideredirect . 0 + wm attributes . -topmost + update + wm state . normal + raise . +}; # show_log + +proc log_exit {{mess ""}} { + if {$mess ne ""} {lappend ::out_log $mess} + catch {chan close $::inst} ; # should terminate perl + if {[llength $::out_log] > 0} { + if {[llength $::out_log] < 10} { + tk_messageBox -icon info -message [join $::out_log "\n"] + exit + } else { + show_log ; # its close button exits + } + } else { + exit + } +}; # log_exit + +############################################################# + +########################################################## + +##### installation root ##### + +proc update_full_path {} { + set val [file join \ + [.tltd.prefix_l cget -text] \ + [.tltd.name_l cget -text] \ + [.tltd.rel_l cget -text]] + set val [native_slashify $val] + .tltd.path_l configure -text $val + # ask perl to check path + chan puts $::inst "checkdir" + chan puts $::inst [forward_slashify [.tltd.path_l cget -text]] + chan flush $::inst + if {[read_line_no_eof] eq "0"} { + .tltd.path_l configure -text \ + [__ "Cannot be created or cannot be written to"] \ + -foreground red + .tltd.ok_b state disabled + } else { + .tltd.path_l configure -text $val -foreground $::blk + .tltd.ok_b state !disabled + } + return +} ; # update_full_path + +proc edit_name {} { + create_dlg .tled .tltd + wm title .tled [__ "Directory name..."] + if $::plain_unix {wm attributes .tled -type dialog} + + # wallpaper + pack [ttk::frame .tled.bg -padding 3] -fill both -expand 1 + + # widgets + ttk::label .tled.l -text [__ "Change name (slashes not allowed)"] + pack .tled.l -in .tled.bg -padx 5 -pady 5 + ttk::entry .tled.e -width 20 + .tled.e state !disabled + pack .tled.e -in .tled.bg -pady 5 + .tled.e insert 0 [.tltd.name_l cget -text] + + # now frame with ok and cancel buttons + pack [ttk::frame .tled.buttons] -in .tled.bg -fill x + ttk::button .tled.ok_b -text [__ "Ok"] -command { + if [regexp {[\\/]} [.tled.e get]] { + tk_messageBox -type ok -icon error -message [__ "No slashes allowed"] + } else { + .tltd.name_l configure -text [.tled.e get] + update_full_path + end_dlg "" .tled + } + } + ppack .tled.ok_b -in .tled.buttons -side right -padx 5 -pady 5 + ttk::button .tled.q_b -text [__ "Cancel"] -command {end_dlg "" .tled} + ppack .tled.q_b -in .tled.buttons -side right -padx 5 -pady 5 + bind .tled <Escape> {.tled.q_b invoke} + + wm protocol .tled WM_DELETE_WINDOW {.tled.q_b invoke} + wm resizable .tled 0 0 + place_dlg .tled .tltd +} ; # edit_name + +proc toggle_rel {} { + if {[.tltd.rel_l cget -text] ne ""} { + set ans \ + [tk_messageBox -message \ + [__ "TL release component highly recommended!\nAre you sure?"] \ + -title [__ "Warning"] \ + -type yesno \ + -default no] + if {$ans eq no} { + return + } + .tltd.rel_l configure -text "" + .tltd.sep1_l configure -text " " + .tltd.rel_b configure -text [__ "Add year"] + } else { + .tltd.rel_l configure -text $::release_year + .tltd.sep1_l configure -text [file separator] + .tltd.rel_b configure -text [__ "Remove year"] + } + update_full_path +} ; # toggle_rel + +proc commit_canonical_local {} { + if {[file tail $::vars(TEXDIR)] eq $::release_year} { + set l [file dirname $::vars(TEXDIR)] + } else { + set l $::vars(TEXDIR) + } + if {[forward_slashify $l] ne \ + [forward_slashify [file dirname $::vars(TEXMFLOCAL)]]} { + set ::vars(TEXMFLOCAL) [forward_slashify [file join $l "texmf-local"]] + } +} + +proc commit_root {} { + set td [.tltd.path_l cget -text] + set ::td_warned 0 + if [is_nonempty $td] { + if {[td_question $td] ne yes} return + } + set ::vars(TEXDIR) [forward_slashify [.tltd.path_l cget -text]] + set ::vars(TEXMFSYSVAR) "$::vars(TEXDIR)/texmf-var" + set ::vars(TEXMFSYSCONFIG) "$::vars(TEXDIR)/texmf-config" + if [winfo exists .tspvl] { + .tspvl configure -text [file join $::vars(TEXDIR) "texmf-dist"] + } + commit_canonical_local + + if {$::vars(instopt_portable)} reset_personal_dirs + destroy .tltd +} + +### main directory dialog ### + +proc texdir_setup {} { + + ### widgets ### + + create_dlg .tltd . + wm title .tltd [__ "Installation root"] + + # wallpaper + pack [ttk::frame .tltd.bg -padding 3] -expand 1 -fill both + + # full path + pack [ttk::label .tltd.path_l -font lfont -anchor center] \ + -in .tltd.bg -pady 10 -fill x -expand 1 + + # installation root components, gridded + pack [ttk::frame .tltd.fr1 -borderwidth 2 -relief groove] \ + -in .tltd.bg -fill x -expand 1 + grid columnconfigure .tltd.fr1 0 -weight 1 + grid columnconfigure .tltd.fr1 2 -weight 1 + grid columnconfigure .tltd.fr1 4 -weight 1 + set rw -1 + # path components, as labels + incr rw + pgrid [ttk::label .tltd.prefix_l] -in .tltd.fr1 -row $rw -column 0 + pgrid [ttk::label .tltd.sep0_l -text "/"] \ + -in .tltd.fr1 -row $rw -column 1 + pgrid [ttk::label .tltd.name_l] -in .tltd.fr1 -row $rw -column 2 + pgrid [ttk::label .tltd.sep1_l -text "/"] \ + -in .tltd.fr1 -row $rw -column 3 + pgrid [ttk::label .tltd.rel_l -width 6] \ + -in .tltd.fr1 -row $rw -column 4 + # corresponding buttons + incr rw + pgrid [ttk::button .tltd.prefix_b -text [__ "Browse..."] \ + -command {if [dirbrowser2widget .tltd.prefix_l] update_full_path}] \ + -in .tltd.fr1 -row $rw -column 0 + pgrid [ttk::button .tltd.name_b -text [__ "Change"] -command edit_name] \ + -in .tltd.fr1 -row $rw -column 2 + pgrid [ttk::button .tltd.rel_b -text [__ "Remove year"] \ + -command toggle_rel] \ + -in .tltd.fr1 -row $rw -column 4 + + # windows: note about localized names + if {$::tcl_platform(platform) eq "windows"} { + ttk::label .tltd.loc -anchor w + .tltd.loc configure -text \ + [__ "Localized directory names will be replaced by their real names"] + ppack .tltd.loc -in .tltd.bg -fill x + } + + # ok/cancel buttons + pack [ttk::frame .tltd.frbt] -in .tltd.bg -pady [list 10 0] -fill x + ttk::button .tltd.ok_b -text [__ "Ok"] -command commit_root + ppack .tltd.ok_b -in .tltd.frbt -side right + ttk::button .tltd.cancel_b -text [__ "Cancel"] \ + -command {destroy .tltd} + ppack .tltd.cancel_b -in .tltd.frbt -side right + bind .tltd <Escape> {.tltd.cancel_b invoke} + + ### initialization and callbacks ### + + set val [native_slashify [file normalize $::vars(TEXDIR)]] + regsub {[\\/]$} $val {} val + + set initdir $val + set name "" + set rel "" + + # TL release subdirectory at the end? + set rel_pat {[\\/](} + append rel_pat $::release_year {)$} + if [regexp $rel_pat $initdir m rel] { + set rel $::release_year + regsub $rel_pat $initdir {} initdir + } + .tltd.rel_l configure -text $rel + + # next-last component + regexp {^(.*)[\\/]([^\\/]*)$} $initdir m initdir name + .tltd.name_l configure -text $name + + # backtrack remaining initdir to something that exists + # and assign it to prefix + set initprev "" + while {! [file isdirectory $initdir]} { + set initprev $initdir + regexp {^(.*)[\\/]([^\\/]*)} $initdir m initdir m1 + if {$initprev eq $initdir} break + } + + if {$initdir eq "" || \ + ($::tcl_platform(platform) eq "windows" && \ + [string index $initdir end] eq ":")} { + append initdir "/" + } + .tltd.prefix_l configure -text $initdir + update_full_path + + bind .tltd <Return> commit_root + bind .tltd <Escape> {destroy .tltd} + + wm protocol .tltd WM_DELETE_WINDOW {.tltd.cancel_b invoke} + wm resizable .tltd 1 0 + place_dlg .tltd +} ; # texdir_setup + +##### other directories: TEXMFLOCAL, TEXMFHOME, portable ##### + +proc edit_dir {d} { + create_dlg .td . + wm title .td $d + if $::plain_unix {wm attributes .td -type dialog} + + # wallpaper + pack [ttk::frame .td.bg -padding 3] -fill both -expand 1 + + if {$d eq "TEXMFHOME"} { + # explain tilde + if {$::tcl_platform(platform) eq "windows"} { + set ev "%USERPROFILE%" + set xpl $::env(USERPROFILE) + } else { + set ev "\$HOME" + set xpl $::env(HOME) + } + ppack [ttk::label .td.tilde \ + -text [__ "'~' equals %s, e.g. %s" $ev $xpl]] \ + -in .td.bg -anchor w + } + + # other widgets + + ppack [ttk::entry .td.e -width 60] -in .td.bg -fill x + .td.e insert 0 [native_slashify $::vars($d)] + + pack [ttk::frame .td.f] -fill x -expand 1 + ttk::button .td.ok -text [__ "Ok"] -command {end_dlg [.td.e get] .td} + ppack .td.ok -in .td.f -side right + ttk::button .td.cancel -text [__ "Cancel"] -command {end_dlg "" .td} + ppack .td.cancel -in .td.f -side right + bind .td <Escape> {.td.cancel invoke} + + wm protocol .td WM_DELETE_WINDOW {.td.cancel invoke} + wm resizable .td 1 0 + place_dlg .td . + tkwait window .td + if {$::dialog_ans ne ""} { + set ::vars($d) [forward_slashify $::dialog_ans] + if $::vars(instopt_portable) { + if {$d eq "TEXMFLOCAL"} {set ::vars(TEXMFHOME) $::vars($d)} + if {$d eq "TEXMFSYSVAR"} {set ::vars(TEXMFVAR) $::vars($d)} + if {$d eq "TEXMFSYSCONFIG"} {set ::vars(TEXMFCONFIG) $::vars($d)} + update + } + } +} + +proc port_dis_or_activate {toggled} { + if {!$::advanced} return + set yn [yes_no $::vars(instopt_portable)] + .dirportvl configure -text $yn + if {$::vars(instopt_portable)} { + set ::vars(TEXMFHOME) $::vars(TEXMFLOCAL) + set ::vars(TEXMFVAR) $::vars(TEXMFSYSVAR) + set ::vars(TEXMFCONFIG) $::vars(TEXMFSYSCONFIG) + .thomeb state disabled + if $::alltrees { + .tvb state disabled + .tcb state disabled + } + if {$::tcl_platform(platform) eq "windows"} { + # adjust_path + set ::vars(instopt_adjustpath) 0 + .pathb state disabled + .pathl configure -foreground $::gry + # desktop integration + set ::vars(instopt_desktop_integration) 0 + .dkintb state disabled + .dkintl configure -foreground $::gry + # file associations + set ::vars(instopt_file_assocs) 0 + .assocb state disabled + .assocl configure -foreground $::gry + # multi-user + if $::is_admin { + set ::vars(instopt_w32_multi_user) 0 + .adminb state disabled + .adminl configure -foreground $::gry + } + } else { + set ::vars(instopt_adjustpath) 0 + .symspec state disabled + .pathb state disabled + .pathl configure -foreground $::gry + } + } else { + if $toggled { + set ::vars(TEXMFHOME) "~/texmf" + set ::vars(TEXMFVAR) "~/.texlive${::release_year}/texmf-var" + set ::vars(TEXMFCONFIG) "~/.texlive${::release_year}/texmf-config" + } ; # else leave alone + #.tlocb state !disabled + .thomeb state !disabled + if $::alltrees { + #.tsysvb state !disabled + #.tsyscb state !disabled + .tvb state !disabled + .tcb state !disabled + } + if {$::tcl_platform(platform) eq "windows"} { + # adjust_path + set ::vars(instopt_adjustpath) 1 + .pathb state !disabled + .pathl configure -foreground $::blk + # desktop integration + set ::vars(instopt_desktop_integration) 1 + .dkintb state !disabled + .dkintl configure -foreground $::blk + # file associations + set ::vars(instopt_file_assocs) 1 + .assocb state !disabled + .assocl configure -foreground $::blk + # multi-user + if $::is_admin { + set ::vars(instopt_w32_multi_user) 1 + .adminb state !disabled + .adminl configure -foreground $::blk + } + } else { + # set ::vars(instopt_adjustpath) 0 + # leave false, still depends on symlink paths + .symspec state !disabled + if [dis_enable_symlink_option] { + .pathb state !disabled + .pathl configure -foreground $::blk + } + } + } +} + +proc toggle_port {} { + set ::vars(instopt_portable) [expr {!$::vars(instopt_portable)}] + port_dis_or_activate 1 + commit_canonical_local +}; # toggle_port + +############################################################# + +##### selections: binaries, scheme, collections ##### + +proc show_stats {} { + # n. of additional platforms + if [winfo exists .binlm] { + if {$::vars(n_systems_selected) < 2} { + .binlm configure -text [__ "None"] + } else { + .binlm configure -text [expr {$::vars(n_systems_selected) - 1}] + } + } + # n. out of n. packages + if [winfo exists .lcolv] { + .lcolv configure -text \ + [format "%d / %d" \ + $::vars(n_collections_selected) \ + $::vars(n_collections_available)] + } + if [winfo exists .schml] { + .schml configure -text [__ $::scheme_descs($::vars(selected_scheme))] + } + # diskspace: can use -textvariable here + # paper size +}; # show_stats + +############################################################# + +### binaries ### + +# toggle platform in treeview widget, but not in underlying data +proc toggle_bin {b} { + if {$b eq $::vars(this_platform)} { + tk_messageBox -message [__ "Cannot deselect own platform"] + return + } + set m [.tlbin.lst set $b "mk"] + if {$m eq [mark_sym 0]} { + .tlbin.lst set $b "mk" [mark_sym 1] + } else { + .tlbin.lst set $b "mk" [mark_sym 0] + } +}; # toggle_bin + +proc save_bin_selections {} { + set ::vars(n_systems_selected) 0 + foreach b [.tlbin.lst children {}] { + set bb "binary_$b" + if {[.tlbin.lst set $b "mk"] ne [mark_sym 0]} { + incr ::vars(n_systems_selected) + set ::vars($bb) 1 + } else { + set ::vars($bb) 0 + } + if {$b eq "win32"} { + set ::vars(collection-wintools) $::vars($bb) + } + } + update_vars + show_stats +}; # save_bin_selections + +proc sort_bins_by_value {n m} { + return [string compare [__ $::bin_descs($n)] [__ $::bin_descs($m)]] +} + +proc select_binaries {} { + create_dlg .tlbin . + wm title .tlbin [__ "Binaries"] + + # wallpaper + pack [ttk::frame .tlbin.bg -padding 3] -expand 1 -fill both + + # ok, cancel buttons + pack [ttk::frame .tlbin.buts] -in .tlbin.bg -side bottom -fill x + ttk::button .tlbin.ok -text [__ "Ok"] -command \ + {save_bin_selections; update_vars; end_dlg 1 .tlbin} + ppack .tlbin.ok -in .tlbin.buts -side right + ttk::button .tlbin.cancel -text [__ "Cancel"] -command {end_dlg 0 .tlbin} + ppack .tlbin.cancel -in .tlbin.buts -side right + bind .tlbin <Escape> {.tlbin.cancel invoke} + + #set max_width 0 + #foreach b [array names ::bin_descs] { + # set bl [font measure TkTextFont [__ $::bin_descs($b)]] + # if {$bl > $max_width} {set max_width $bl} + #} + #incr max_width 10 + + # treeview for binaries, with checkbox column and vertical scrollbar + pack [ttk::frame .tlbin.binsf] -in .tlbin.bg -expand 1 -fill both + + ttk::treeview .tlbin.lst -columns {mk desc} -show {} \ + -selectmode extended -yscrollcommand {.tlbin.binsc set} + + ttk::scrollbar .tlbin.binsc -orient vertical -command {.tlbin.lst yview} + .tlbin.lst column mk -stretch 0 -width [expr {$::cw * 3}] + .tlbin.lst column desc -stretch 1 + foreach b [lsort -command sort_bins_by_value [array names ::bin_descs]] { + set bb "binary_$b" + .tlbin.lst insert {} end -id $b -values \ + [list [mark_sym $::vars($bb)] [__ $::bin_descs($b)]] + } + pgrid .tlbin.lst -in .tlbin.binsf -row 0 -column 0 -sticky news + pgrid .tlbin.binsc -in .tlbin.binsf -row 0 -column 1 -sticky ns + grid columnconfigure .tlbin.binsf 0 -weight 1 + grid rowconfigure .tlbin.binsf 0 -weight 1 + bind .tlbin.lst <space> {toggle_bin [.tlbin.lst focus]} + bind .tlbin.lst <Return> {toggle_bin [.tlbin.lst focus]} + bind .tlbin.lst <ButtonRelease-1> \ + {toggle_bin [.tlbin.lst identify item %x %y]} + + wm protocol .tlbin WM_DELETE_WINDOW {.tlbin.cancel invoke} + wm resizable .tlbin 1 1 + place_dlg .tlbin . +}; # select_binaries + +############################################################# + +### scheme ### + +proc select_scheme {} { + create_dlg .tlschm . + wm title .tlschm [__ "Schemes"] + + # wallpaper + pack [ttk::frame .tlschm.bg -padding 3] -fill both -expand 1 + + # buttons at bottom + pack [ttk::frame .tlschm.buts] -in .tlschm.bg -side bottom -fill x + ttk::button .tlschm.ok -text [__ "Ok"] -command { + # tree selection is a list: + set ::vars(selected_scheme) [lindex [.tlschm.lst selection] 0] + foreach v [array names ::vars] { + if {[string range $v 0 6] eq "scheme-"} { + if {$v eq $::vars(selected_scheme)} { + set ::vars($v) 1 + } else { + set ::vars($v) 0 + } + } + } + update_vars + show_stats + end_dlg 1 .tlschm + } + ppack .tlschm.ok -in .tlschm.buts -side right + ttk::button .tlschm.cancel -text [__ "Cancel"] -command {end_dlg 0 .tlschm} + ppack .tlschm.cancel -in .tlschm.buts -side right + bind .tlschm <Escape> {.tlschm.cancel invoke} + + # schemes list + #set max_width 0 + #foreach s $::schemes_order { + # set sl [font measure TkTextFont [__ $::scheme_descs($s)]] + # if {$sl > $max_width} {set max_width $sl} + #} + #incr max_width 10 + ttk::treeview .tlschm.lst -columns {desc} -show {} -selectmode browse \ + -height [llength $::schemes_order] + .tlschm.lst column "desc" -stretch 1; # -minwidth $max_width + ppack .tlschm.lst -in .tlschm.bg -fill both -expand 1 + foreach s $::schemes_order { + .tlschm.lst insert {} end -id $s -values [list [__ $::scheme_descs($s)]] + } + # we already made sure that $::vars(selected_scheme) has a valid value + .tlschm.lst selection set [list $::vars(selected_scheme)] + + wm protocol .tlschm WM_DELETE_WINDOW {tlschm.cancel invoke} + wm resizable .tlschm 1 0 + place_dlg .tlschm . +}; # select_scheme + +############################################################# + +### collections ### + +# toggle collection in treeview widget, but not in underlying data +proc toggle_coll {cs c} { + # cs: treeview widget; c: selected child item + set m [$cs set $c "mk"] + if {$m eq [mark_sym 0]} { + $cs set $c "mk" [mark_sym 1] + } else { + $cs set $c "mk" [mark_sym 0] + } +}; # toggle_coll + +proc save_coll_selections {} { + foreach wgt {.tlcoll.other .tlcoll.lang} { + foreach c [$wgt children {}] { + if {[$wgt set $c "mk"] eq [mark_sym 0]} { + set ::vars($c) 0 + } else { + set ::vars($c) 1 + } + } + } + set ::vars(selected_scheme) "scheme-custom" + update_vars + show_stats +}; # save_coll_selections + +proc sort_colls_by_value {n m} { + return [string compare [__ $::coll_descs($n)] [__ $::coll_descs($m)]] +} + +proc select_collections {} { + # 2018: more than 40 collections + # The tcl installer acquires collections from install-menu-extl.pl, + # but install-tl also has an array of collections. + # Use treeview for checkbox column and display of + # collection descriptions rather than names. + # buttons: select all, select none, ok, cancel + # should some collections be excluded? Check install-menu-* code. + create_dlg .tlcoll . + wm title .tlcoll [__ "Collections"] + + # wallpaper + pack [ttk::frame .tlcoll.bg -padding 3] -fill both -expand 1 + + # frame at bottom with ok and cancel buttons + pack [ttk::frame .tlcoll.butf] -in .tlcoll.bg -side bottom -fill x + ttk::button .tlcoll.ok -text [__ "Ok"] -command \ + {save_coll_selections; end_dlg 1 .tlcoll} + ppack .tlcoll.ok -in .tlcoll.butf -side right + ttk::button .tlcoll.cancel -text [__ "Cancel"] -command {end_dlg 0 .tlcoll} + ppack .tlcoll.cancel -in .tlcoll.butf -side right + bind .tlcoll <Escape> {.tlcoll.cancel invoke} + + # Treeview and scrollbar for non-language- and language collections resp. + pack [ttk::frame .tlcoll.both] -in .tlcoll.bg -expand 1 -fill both + + foreach t {"lang" "other"} { + + # frames with select all/none buttons, separately for lang and others + set wgb .tlcoll.b$t + ttk::frame $wgb + ttk::label ${wgb}sel -text [__ "Select"] + ttk::button ${wgb}all -text [__ "All"] -padding 1 -command \ + "foreach c \[.tlcoll.$t children {}\] \{ + .tlcoll.$t set \$c mk \[mark_sym 1\]\}" + ttk::button ${wgb}none -text [__ "None"] -padding 1 -command \ + "foreach c \[.tlcoll.$t children {}\] \{ + .tlcoll.$t set \$c mk \[mark_sym 0\]\}" + pack ${wgb}sel ${wgb}all ${wgb}none -in $wgb \ + -side left -padx 3 -pady 3 + + # trees with collections and markers, lang and other separately + set wgt ".tlcoll.$t" + ttk::treeview $wgt -columns {mk desc} -show {headings} \ + -selectmode extended -yscrollcommand "${wgt}sc set" + $wgt heading "mk" -text "" + if {$t eq "lang"} { + $wgt heading "desc" -text [__ "Languages"] + } else { + $wgt heading "desc" -text [__ "Other collections"] + } + # and their vertical scrollbars + ttk::scrollbar ${wgt}sc -orient vertical -command "$wgt yview" + $wgt column mk -width [expr {$::cw * 3}] -stretch 0 + $wgt column desc -stretch 1 + + bind $wgt <space> {toggle_coll %W [%W focus]} + bind $wgt <Return> {toggle_coll %W [%W focus]} + bind $wgt <ButtonRelease-1> {toggle_coll %W [%W identify item %x %y]} + } + grid .tlcoll.blang x .tlcoll.bother -in .tlcoll.both -sticky w + grid .tlcoll.lang .tlcoll.langsc .tlcoll.other .tlcoll.othersc \ + -in .tlcoll.both + grid columnconfigure .tlcoll.both 0 -weight 1 + grid columnconfigure .tlcoll.both 1 -weight 0 + grid columnconfigure .tlcoll.both 2 -weight 2 + grid columnconfigure .tlcoll.both 3 -weight 0 + grid configure .tlcoll.lang .tlcoll.other .tlcoll.langsc .tlcoll.othersc \ + -sticky nsew + grid rowconfigure .tlcoll.both 1 -weight 1 + + + foreach c [lsort -command sort_colls_by_value [array names ::coll_descs]] { + if [string equal -length 15 "collection-lang" $c] { + set wgt ".tlcoll.lang" + } else { + set wgt ".tlcoll.other" + } + $wgt insert {} end -id $c -values \ + [list [mark_sym $::vars($c)] [__ $::coll_descs($c)]] + } + + wm protocol .tlcoll WM_DELETE_WINDOW {.tlcoll.cancel invoke} + wm resizable .tlcoll 1 1 + place_dlg .tlcoll . +}; # select_collections + +################################################## + +# option handling + +# for multi-value options: +# below, $c is a combobox with values $l. The index of the current value in $l +# corresponds to the value of $::vars($v). + +proc var2combo {v c} { + $c current $::vars($v) +} +proc combo2var {c v} { + set ::vars($v) [$c current] +} +# if the variable has an impact on what to install: +proc combo2var_calc {c v} { + combo2var c v + update_vars + show_stats +} + +##### desktop integration; platform-specific ##### + +if {$::tcl_platform(platform) ne "windows"} { + + ### symlinks into standard directories ### + + # 'file writable' is only a check of unix permissions + proc dest_ok {d} { + if {$d eq ""} {return 0} + set its 1 + while 1 { + if [file exists $d] { + if {! [file isdirectory $d]} { + return 0 + } elseif {! [file writable $d]} { + return 0 + } else { + return 1 + } + } ; # if file exists + # try a level up + set d [file dirname $d] + set its [expr {$its + 1}] + if {$its > 3} {return 0} + } + return 0 + } + + proc dis_enable_symlink_option {} { + set ok 1 + foreach v {"bin" "man" "info"} { + set vv "tlpdbopt_sys_$v" + if {! [info exists ::vars($vv)]} {set ok 0; break} + set d $::vars($vv) + if {![dest_ok $d]} {set ok 0; break} + } + if {$ok && !$::vars(instopt_portable)} { + .pathb state !disabled + .pathl configure -foreground $::blk + } else { + set ok 0 + .pathb state disabled + .pathl configure -foreground $::gry + set ::vars(instopt_adjustpath) 0 + } + return $ok + } + + # check validity of all three proposed symlink target directories. + # do not dis/enable .pathb until return from .edsyms dialog. + proc check_sym_entries {} { + set ok 1 + foreach v {"bin" "man" "info"} { + if [dest_ok [.edsyms.${v}e get]] { + .edsyms.${v}mk configure -text "\u2714" -foreground $::blk + } else { + .edsyms.${v}mk configure -text "\u2718" -foreground red + set ok 0 + } + } + if $ok { + .edsyms.warn configure -text "" + } else { + .edsyms.warn configure -text \ + [__ "Warning. Not all configured directories are writable!"] + } + } + + proc commit_sym_entries {} { + foreach v {"bin" "man" "info"} { + set vv "tlpdbopt_sys_$v" + set ::vars($vv) [.edsyms.${v}e get] + if {[string index $::vars($vv) 0] eq "~"} { + set ::vars($vv) "$::env(HOME)[string range $::vars($vv) 1 end]" + } + } + if [dis_enable_symlink_option] { + set ::vars(instopt_adjustpath) 1 + } + } + + proc edit_symlinks {} { + + create_dlg .edsyms . + wm title .edsyms [__ "Symlinks"] + + pack [ttk::frame .edsyms.bg -padding 3] -expand 1 -fill both + set rw -1 + + pack [ttk::frame .edsyms.fr0] -in .edsyms.bg -expand 1 -fill both + foreach v {"bin" "man" "info"} { + incr rw + # description + pgrid [ttk::label .edsyms.${v}l -text ""] \ + -in .edsyms.fr0 -row $rw -column 0 -sticky e + # ok mark + pgrid [ttk::label .edsyms.${v}mk -text ""] \ + -in .edsyms.fr0 -row $rw -column 1 + # entry widget + pgrid [ttk::entry .edsyms.${v}e -width 40] \ + -in .edsyms.fr0 -row $rw -column 2 + set vv "tlpdbopt_sys_$v" + if [info exists ::vars($vv)] { + .edsyms.${v}e insert 0 $::vars($vv) + }; # else leave empty + bind .edsyms.${v}e <KeyRelease> {+check_sym_entries} + # browse button + pgrid [ttk::button .edsyms.${v}br -text [__ "Browse..."] -command \ + "dirbrowser2widget .edsyms.${v}e; check_sym_entries"] \ + -in .edsyms.fr0 -row $rw -column 3 + } + .edsyms.binl configure -text [__ "Binaries"] + .edsyms.manl configure -text [__ "Man pages"] + .edsyms.infol configure -text [__ "Info pages"] + + # warning about read-only target directories + incr rw + pgrid [ttk::label .edsyms.warn -foreground red] \ + -in .edsyms.fr0 -column 2 -columnspan 2 -sticky w + + grid columnconfigure .edsyms.fr0 0 -weight 0 + grid columnconfigure .edsyms.fr0 1 -weight 0 + grid columnconfigure .edsyms.fr0 2 -weight 1 + grid columnconfigure .edsyms.fr0 3 -weight 0 + + # ok, cancel + pack [ttk::frame .edsyms.fr1] -expand 1 -fill both + ppack [ttk::button .edsyms.ok -text [__ "Ok"] -command { + commit_sym_entries; end_dlg 1 .edsyms}] -in .edsyms.fr1 -side right + ppack [ttk::button .edsyms.cancel -text [__ "Cancel"] -command { + end_dlg 0 .edsyms}] -in .edsyms.fr1 -side right + bind .edsyms <Escape> {.edsyms.cancel invoke} + + check_sym_entries + + wm protocol .edsyms WM_DELETE_WINDOW {.edsyms.cancel invoke} + wm resizable .edsyms 1 0 + place_dlg .edsyms . + } ; # edit_symlinks +} ; # $::tcl_platform(platform) ne "windows" + +############################################################# + +# the main menu interface will at certain events send the current values of +# the ::vars array to install-tl[-tcl], which will send back an updated version +# of this array. +# We still use blocking i/o: frontend and backend wait for each other. + +# idea: follow submenu organization of text installer +# for 3-way options, create an extra level of children +# instead of wizard install, supppress some options + +proc run_menu {} { + if [info exists ::env(dbgui)] { + #puts "\ndbgui: run_menu: advanced is now $::advanced" + #puts "dbgui: run_menu: alltrees is now $::alltrees" + } + wm withdraw . + foreach c [winfo children .] { + catch {destroy $c} + } + + # wallpaper + pack [ttk::frame .bg -padding 3] -fill both -expand 1 + + # title + ttk::label .title -text [__ "TeX Live %s Installer" $::release_year] \ + -font titlefont + pack .title -pady {10 1} -in .bg + pack [ttk::label .svn -text "r. $::svn"] -in .bg + + pack [ttk::separator .seph0 -orient horizontal] \ + -in .bg -pady 3 -fill x + + # frame at bottom with install/quit buttons + pack [ttk::frame .final] \ + -in .bg -side bottom -pady [list 5 2] -fill x + ppack [ttk::button .install -text [__ "Install"] -command { + set ::menu_ans "startinst"}] -in .final -side right + ppack [ttk::button .quit -text [__ "Quit"] -command { + set ::out_log {} + set ::menu_ans "no_inst"}] -in .final -side right + bind . <Escape> whataboutclose + if {!$::advanced} { + ppack [ttk::button .adv -text [__ "Advanced"] -command { + set ::menu_ans "advanced" + #if [info exists ::env(dbgui)] {puts "dbgui: requested advanced"} + }] -in .final -side left + } + pack [ttk::separator .seph1 -orient horizontal] \ + -in .bg -side bottom -pady 3 -fill x + + # directories, selections + # advanced and basic have different frame setups + if $::advanced { + pack [ttk::frame .left] -in .bg -side left -fill both -expand 1 + set curf .left + } else { + pack [ttk::frame .main] -in .bg -side top -fill both -expand 1 + set curf .main + } + + # directory section + pack [ttk::frame .dirf] -in $curf -fill x + grid columnconfigure .dirf 1 -weight 1 + set rw -1 + + if $::advanced { + incr rw + # labelframes do not look quite right on macos, + # instead, separate label widget for title + pgrid [ttk::label .dirftitle -text [__ "Installation root"] \ + -font hfont] \ + -in .dirf -row $rw -column 0 -columnspan 3 -sticky w + .dirftitle configure -text [__ "Directories"] + } + + incr rw + pgrid [ttk::label .tdirll] -in .dirf -row $rw -column 0 -sticky nw + set s [__ "Installation root"] + if $::advanced { + .tdirll configure -text "TEXDIR:\n$s" + } else { + .tdirll configure -text $s + } + pgrid [ttk::label .tdirvl -textvariable ::vars(TEXDIR)] \ + -in .dirf -row $rw -column 1 -sticky nw + pgrid [ttk::button .tdirb -text [__ "Change"] -command texdir_setup] \ + -in .dirf -row $rw -column 2 -sticky new + + if $::advanced { + if $::alltrees { + incr rw + pgrid [ttk::label .tspll -text [__ "Main tree"]] \ + -in .dirf -row $rw -column 0 -sticky nw + pgrid [ttk::label .tspvl] -in .dirf -row $rw -column 1 -sticky nw + .tspvl configure -text [file join $::vars(TEXDIR) "texmf-dist"] + + incr rw + pgrid [ttk::label .tsysvll -text "TEXMFSYSVAR"] \ + -in .dirf -row $rw -column 0 -sticky nw + pgrid [ttk::label .tsysvvl -textvariable ::vars(TEXMFSYSVAR)] \ + -in .dirf -row $rw -column 1 -sticky nw + ttk::button .tsysvb -text [__ "Change"] -command {edit_dir "TEXMFSYSVAR"} + pgrid .tsysvb -in .dirf -row $rw -column 2 -sticky new + + incr rw + pgrid [ttk::label .tsyscll -text "TEXMFSYSCONFIG"] \ + -in .dirf -row $rw -column 0 -sticky nw + pgrid [ttk::label .tsyscvl -textvariable ::vars(TEXMFSYSCONFIG)] \ + -in .dirf -row $rw -column 1 -sticky nw + ttk::button .tsyscb -text [__ "Change"] \ + -command {edit_dir "TEXMFSYSCONFIG"} + pgrid .tsyscb -in .dirf -row $rw -column 2 -sticky new + } + incr rw + set s [__ "Local additions"] + pgrid [ttk::label .tlocll -text "TEXMFLOCAL:\n$s"] \ + -in .dirf -row $rw -column 0 -sticky nw + pgrid [ttk::label .tlocvl -textvariable ::vars(TEXMFLOCAL)] \ + -in .dirf -row $rw -column 1 -sticky nw + ttk::button .tlocb -text [__ "Change"] -command {edit_dir "TEXMFLOCAL"} + pgrid .tlocb -in .dirf -row $rw -column 2 -sticky new + + incr rw + set s [__ "Per-user additions"] + pgrid [ttk::label .thomell -text "TEXMFHOME:\n$s"] \ + -in .dirf -row $rw -column 0 -sticky nw + pgrid [ttk::label .thomevl -textvariable ::vars(TEXMFHOME)] \ + -in .dirf -row $rw -column 1 -sticky nw + ttk::button .thomeb -text [__ "Change"] -command {edit_dir "TEXMFHOME"} + pgrid .thomeb -in .dirf -row $rw -column 2 -sticky ne + if $::alltrees { + incr rw + pgrid [ttk::label .tvll -text "TEXMFVAR"] \ + -in .dirf -row $rw -column 0 -sticky nw + pgrid [ttk::label .tvvl -textvariable ::vars(TEXMFVAR)] \ + -in .dirf -row $rw -column 1 -sticky nw + ttk::button .tvb -text [__ "Change"] -command {edit_dir "TEXMFVAR"} + pgrid .tvb -in .dirf -row $rw -column 2 -sticky new + incr rw + pgrid [ttk::label .tcll -text "TEXMFCONFIG"] \ + -in .dirf -row $rw -column 0 -sticky nw + pgrid [ttk::label .tcvl -textvariable ::vars(TEXMFCONFIG)] \ + -in .dirf -row $rw -column 1 -sticky nw + ttk::button .tcb -text [__ "Change"] \ + -command {edit_dir "TEXMFCONFIG"} + pgrid .tcb -in .dirf -row $rw -column 2 -sticky new + } + + incr rw + if {!$::alltrees} { + ttk::button .tmoreb -text [__ "More ..."] -command { + set ::menu_ans "alltrees" + #if [info exists ::env(dbgui)] {puts "dbgui: requested alltrees"} + } + pgrid .tmoreb -in .dirf -row $rw -column 2 -sticky ne + } + + incr rw + pgrid [ttk::label .dirportll \ + -text [__ "Portable setup:\nMay reset TEXMFLOCAL\nand TEXMFHOME"]] \ + -in .dirf -row $rw -column 0 -sticky nw + pgrid [ttk::label .dirportvl] -in .dirf -row $rw -column 1 -sticky nw + pgrid [ttk::button .tportb -text [__ "Toggle"] -command toggle_port] \ + -in .dirf -row $rw -column 2 -sticky ne + .dirportvl configure -text [yes_no $::vars(instopt_portable)] + + # platforms section + if {$::tcl_platform(platform) ne "windows"} { + pack [ttk::frame .platf] -in .left -fill x + grid columnconfigure .platf 1 -weight 1 + set rw -1 + + incr rw + pgrid [ttk::label .binftitle -text [__ "Platforms"] -font hfont] \ + -in .platf -row $rw -column 0 -columnspan 3 -sticky w + + # current platform + incr rw + ttk::label .binl0 \ + -text [__ "Current platform:"] + pgrid .binl0 -in .platf -row $rw -column 0 -sticky w + ttk::label .binl1 \ + -text [__ "$::bin_descs($::vars(this_platform))"] + pgrid .binl1 -in .platf -row $rw -column 1 -sticky w + # additional platforms + incr rw + pgrid [ttk::label .binll -text [__ "N. of additional platform(s):"]] \ + -in .platf -row $rw -column 0 -sticky w + pgrid [ttk::label .binlm] -in .platf -row $rw -column 1 -sticky w + pgrid [ttk::button .binb -text [__ "Change"] -command select_binaries] \ + -in .platf -row $rw -column 2 -sticky e + } + + # Selections section + pack [ttk::frame .selsf] -in .left -fill x + grid columnconfigure .selsf 1 -weight 1 + set rw -1 + + incr rw + pgrid [ttk::label .selftitle -text [__ "Selections"] -font hfont] \ + -in .selsf -row $rw -column 0 -columnspan 3 -sticky w + + # schemes + incr rw + pgrid [ttk::label .schmll -text [__ "Scheme:"]] \ + -in .selsf -row $rw -column 0 -sticky w + pgrid [ttk::label .schml -text ""] \ + -in .selsf -row $rw -column 1 -sticky w + pgrid [ttk::button .schmb -text [__ "Change"] -command select_scheme] \ + -in .selsf -row $rw -column 2 -sticky e + + # collections + incr rw + pgrid [ttk::label .lcoll -text [__ "N. of collections:"]] \ + -in .selsf -row $rw -column 0 -sticky w + pgrid [ttk::label .lcolv] -in .selsf -row $rw -column 1 -sticky w + pgrid [ttk::button .collb -text [__ "Customize"] \ + -command select_collections] \ + -in .selsf -row $rw -column 2 -sticky e + } + + # total size + # curf: current frame + set curf [expr {$::advanced ? ".selsf" : ".dirf"}] + incr rw + ttk::label .lsize -text [__ "Disk space required (in MB):"] + ttk::label .size_req -textvariable ::vars(total_size) + pgrid .lsize -in $curf -row $rw -column 0 -sticky w + pgrid .size_req -in $curf -row $rw -column 1 -sticky w + + ######################################################## + # right side: options + # 3 columns. Column 1 can be merged with either 0 or 2. + + if $::advanced { + + pack [ttk::separator .sepv -orient vertical] \ + -in .bg -side left -padx 3 -fill y + pack [ttk::frame .options] -in .bg -side right -fill both -expand 1 + + set curf .options + grid columnconfigure .options 0 -weight 1 + set rw -1 + + incr rw + pgrid [ttk::label .optitle -text [__ "Options"] -font hfont] \ + -in $curf -row $rw -column 0 -columnspan 3 -sticky w + } else { + set curf .dirf + } + + # instopt_letter + set ::lpapers [list "A4" "letter"] + incr rw + pgrid [ttk::label .paperl -text [__ "Default paper size"]] \ + -in $curf -row $rw -column 0 -sticky w + pgrid [ttk::combobox .paperb -values $::lpapers -state readonly -width 8] \ + -in $curf -row $rw -column 1 -columnspan 2 -sticky e + var2combo "instopt_letter" .paperb + bind .paperb <<ComboboxSelected>> {+combo2var .paperb "instopt_letter"} + + if $::advanced { + # instopt_write18_restricted + incr rw + pgrid [ttk::label .write18l -text \ + [__ "Allow execution of restricted list of programs via \\write18"]] \ + -in $curf -row $rw -column 0 -columnspan 2 -sticky w + ttk::checkbutton .write18b -variable ::vars(instopt_write18_restricted) + pgrid .write18b -in $curf -row $rw -column 2 -sticky e + + # tlpdbopt_create_formats + incr rw + pgrid [ttk::label .formatsl -text [__ "Create all format files"]] \ + -in $curf -row $rw -column 0 -columnspan 2 -sticky w + ttk::checkbutton .formatsb -variable ::vars(tlpdbopt_create_formats) + pgrid .formatsb -in $curf -row $rw -column 2 -sticky e + + # tlpdbopt_install_docfiles + if $::vars(doc_splitting_supported) { + incr rw + pgrid [ttk::label .docl -text [__ "Install font/macro doc tree"]] \ + -in $curf -row $rw -column 0 -columnspan 2 -sticky w + ttk::checkbutton .docb -variable ::vars(tlpdbopt_install_docfiles) \ + -command {update_vars; show_stats} + pgrid .docb -in $curf -row $rw -column 2 -sticky e + } + + # tlpdbopt_install_srcfiles + if $::vars(src_splitting_supported) { + incr rw + pgrid [ttk::label .srcl -text [__ "Install font/macro source tree"]] \ + -in $curf -row $rw -column 0 -columnspan 2 -sticky w + ttk::checkbutton .srcb -variable ::vars(tlpdbopt_install_srcfiles) \ + -command {update_vars; show_stats} + pgrid .srcb -in $curf -row $rw -column 2 -sticky e + } + } + + if {$::tcl_platform(platform) eq "windows"} { + + if $::advanced { + # instopt_adjustpath + incr rw + pgrid [ttk::label .pathl -text [__ "Adjust searchpath"]] \ + -in $curf -row $rw -column 0 -columnspan 2 -sticky w + ttk::checkbutton .pathb -variable ::vars(instopt_adjustpath) + pgrid .pathb -in $curf -row $rw -column 2 -sticky e + + # tlpdbopt_desktop_integration + set ::desk_int \ + [list [__ "No shortcuts"] [__ "TeX Live menu"] [__ "Launcher entry"]] + incr rw + pgrid [ttk::label .dkintl -text [__ "Desktop integration"]] \ + -in $curf -row $rw -column 0 -sticky w + pgrid [ttk::combobox .dkintb -values $::desk_int -state readonly \ + -width 20] \ + -in $curf -row $rw -column 1 -columnspan 2 -sticky e + var2combo "tlpdbopt_desktop_integration" .dkintb + bind .dkintb <<ComboboxSelected>> \ + {+combo2var .dkintb "tlpdbopt_desktop_integration"} + + # tlpdbopt_file_assocs + set ::assoc [list [__ "None"] [__ "Only new"] [__ "All"]] + incr rw + pgrid [ttk::label .assocl -text [__ "File associations"]] \ + -in $curf -row $rw -column 0 -sticky w + pgrid [ttk::combobox .assocb -values $::assoc -state readonly -width 12] \ + -in $curf -row $rw -column 1 -columnspan 2 -sticky e + var2combo "tlpdbopt_file_assocs" .assocb + bind .assocb <<ComboboxSelected>> \ + {+combo2var .assocb "tlpdbopt_file_assocs"} + } + + # tlpdbopt_w32_multi_user + incr rw + pgrid [ttk::label .adminl -text [__ "Install for all users"]] \ + -in $curf -row $rw -column 0 -columnspan 2 -sticky w + ttk::checkbutton .adminb -variable ::vars(tlpdbopt_w32_multi_user) + pgrid .adminb -in $curf -row $rw -column 2 -sticky e + if {!$::is_admin} { + .adminb state disabled + .adminl configure -foreground $::gry + } + + # collection-texworks + incr rw + pgrid [ttk::label .texwl -text [__ "Install TeXworks front end"]] \ + -in $curf -row $rw -column 0 -columnspan 2 -sticky w + ttk::checkbutton .texwb -variable ::vars(collection-texworks) + pgrid .texwb -in $curf -row $rw -column 2 -sticky e + bind .texwb <ButtonRelease> {+ + set ::vars(selected_scheme) "scheme-custom"; update_vars; show_stats} + bind .texwb <Return> {+ + set ::vars(selected_scheme) "scheme-custom"; update_vars; show_stats} + bind .texwb <space> {+ + set ::vars(selected_scheme) "scheme-custom"; update_vars; show_stats} + + } else { + if $::advanced { + # instopt_adjustpath, unix edition: symlinks + # tlpdbopt_sys_[bin|info|man] + incr rw + pgrid [ttk::label .pathl \ + -text [__ "Create symlinks in standard directories"]] \ + -in $curf -row $rw -column 0 -columnspan 2 -sticky w + pgrid [ttk::checkbutton .pathb -variable ::vars(instopt_adjustpath)] \ + -in $curf -row $rw -column 2 -sticky e + dis_enable_symlink_option; # enable only if standard directories ok + incr rw + pgrid [ttk::button .symspec -text [__ "Specify directories"] \ + -command edit_symlinks] \ + -in $curf -row $rw -column 1 -columnspan 2 -sticky e + } + } + + if $::advanced { + # spacer/filler + incr rw + pgrid [ttk::label .spaces -text " "] -in $curf -row $rw -column 0 + grid rowconfigure $curf $rw -weight 1 + # final entry: instopt_adjustrepo + incr rw + pgrid [ttk::label .ctanl -text \ + [__ "After install, set CTAN as source for package updates"]] \ + -in $curf -row $rw -column 0 -columnspan 2 -sticky w + pgrid [ttk::checkbutton .ctanb -variable ::vars(instopt_adjustrepo)] \ + -in $curf -row $rw -column 2 -sticky e + } + + if $::advanced {port_dis_or_activate 0} + show_stats + wm overrideredirect . 0 + wm attributes . -topmost + wm resizable . 0 0 + update + wm state . normal + raise . + if {[is_nonempty $::vars(TEXDIR)] && ! $::td_warned} { + td_warn $::vars(TEXDIR) + } + #if [info exists ::env(dbgui)] {puts "dbgui: unsetting menu_ans"} + unset -nocomplain ::menu_ans + vwait ::menu_ans + #if [info exists ::env(dbgui)] {puts "dbgui0: menu_ans is $::menu_ans"} + return $::menu_ans +}; # run_menu + +############################################################# + +# we need data from the backend. +# choices of schemes, platforms and options impact choices of +# collections and required disk space. +# the vars array contains all this variable information. +# the calc_depends proc communicates with the backend to update this array. + +proc read_descs {} { + set l [read_line_no_eof] + if {$l ne "descs"} { + err_exit "'descs' expected but $l found" + } + while 1 { + set l [read_line_no_eof] + if [regexp {^([^:]+): (\S+) (.*)$} $l m p c d] { + if {$c eq "Collection"} { + set ::coll_descs($p) $d + } elseif {$c eq "Scheme"} { + set ::scheme_descs($p) $d + } + } elseif {$l eq "enddescs"} { + break + } else { + err_exit "Illegal line $l in descs section" + } + } + set ::scheme_descs(scheme-custom) [__ "Custom scheme"] +} + +proc read_vars {} { + set l [read_line_no_eof] + if {$l ne "vars"} { + err_exit "'vars' expected but $l found" + } + while 1 { + set l [read_line_no_eof] + if [regexp {^([^:]+): (.*)$} $l m k v] { + set ::vars($k) $v + } elseif {$l eq "endvars"} { + break + } else { + err_exit "Illegal line $l in vars section" + } + } + if {"total_size" ni [array names ::vars]} { + set ::vars(total_size) 0 + } +}; # read_vars + +proc write_vars {} { + chan puts $::inst "vars" + foreach v [array names ::vars] {chan puts $::inst "$v: $::vars($v)"} + chan puts $::inst "endvars" + chan flush $::inst +} + +proc update_vars {} { + chan puts $::inst "calc" + write_vars + read_vars +} + +proc read_menu_data {} { + # the expected order is: year, svn, descs, vars, schemes (one line), binaries + # note. lindex returns an empty string if the index argument is too high. + # empty lines result in an err_exit. + + # year; should be first line + set l [read_line_no_eof] + if [regexp {^year: (\S+)$} $l d y] { + set ::release_year $y + } else { + err_exit "year expected but $l found" + } + + # revision; should be second line + set l [read_line_no_eof] + if [regexp {^svn: (\S+)$} $l d y] { + set ::svn $y + } else { + err_exit "revision expected but $l found" + } + + # windows: admin status + if {$::tcl_platform(platform) eq "windows"} { + set l [read_line_no_eof] + if [regexp {^admin: ([01])$} $l d a] { + set ::is_admin $a + } else { + err_exit "admin: \[0|1\] expected but $l found" + } + } + + read_descs + + read_vars + + # schemes order (one line) + set l [read_line_no_eof] + if [regexp {^schemes_order: (.*)$} $l m sl] { + set ::schemes_order $sl + } else { + err_exit "schemes_order expected but $l found" + } + if {"selected_scheme" ni [array names ::vars] || \ + $::vars(selected_scheme) ni $::schemes_order} { + set ::vars(selected_scheme) [lindex $::schemes_order 0] + } + + # binaries + set l [read_line_no_eof] + if {$l ne "binaries"} { + err_exit "'binaries' expected but $l found" + } + while 1 { + set l [read_line_no_eof] + if [regexp {^([^:]+): (.*)$} $l m k v] { + set ::bin_descs($k) $v + } elseif {$l eq "endbinaries"} { + break + } else { + err_exit "Illegal line $l in binaries section" + } + } + + set l [read_line_no_eof] + if {$l ne "endmenudata"} { + err_exit "'endmenudata' expected but $l found" + } +}; # read_menu_data + +proc answer_to_perl {} { + # we just got a line "mess_yesno" from perl + # finish reading the message text, put it in a message box + # and write back the answer + set mess {} + while 1 { + set ll [read_line] + if {[lindex $ll 0] < 0} { + err_exit "Error while reading from Perl backend" + } else { + set l [lindex $ll 1] + } + if {$l eq "endmess"} { + break + } else { + lappend mess $l + } + } + set m [join $mess "\n"] + set ans [tk_messageBox -type yesno -icon question -message $m] + chan puts $::inst [expr {$ans eq yes ? "y" : "n"}] + chan flush $::inst +}; # answer_to_perl + +proc run_installer {} { + set ::out_log {} + show_log 1; # 1: with abort button + .close state disabled + if $::did_gui { + chan puts $::inst "startinst" + write_vars + } + # the backend was already running and needs no further encouragement + + # switch to non-blocking i/o + chan configure $::inst -buffering line -blocking 0 + chan event $::inst readable read_line_cb +}; # run_installer + +proc whataboutclose {} { + if [winfo exists .abort] { + # log window with abort + .abort invoke + } elseif [winfo exists .log] { + # log window without abort + .close invoke + } elseif [winfo exists .quit] { + # menu window + .quit invoke + } + # no action for close button of splash screen +} + +proc main_prog {} { + + wm title . [__ "TeX Live Installer"] + wm protocol . WM_DELETE_WINDOW whataboutclose + + if {[file exists $::dblfile]} {file delete $::dblfile} + + # handle some command-line arguments. + # the argument list should already be normalized: '--' => '-', "=" => ' ' + set i 0 + set do_splash 1 + set ::prelocation "..." + set ::mir_selected 1 ; # i.e. default or set by parameter + set i [llength $::argv] + while {$i > 0} { + incr i -1 + set p [lindex $::argv $i] + if {$p eq "-profile"} { + # check for profile argument: no splash screen if present + set do_splash 0 + } elseif {$p in [list "-location" "-url" "-repository" "-repos" "-repo"]} { + # check for repository argument: bail out if obviously invalid + set j [expr {$i+1}] + if {$j<[llength $::argv]} { + set p [lindex $::argv $j] + unset j + if {$p ne "ctan" && ! [possible_repository $p]} { + tk_messageBox -message [__ "%s not a local or remote repository" $p] \ + -title [__ "Error"] -type ok -icon error + exit + } + set ::prelocation $p + } else { + tk_messageBox -message [__ "%s requires an argument" $p] \ + -title [__ "Error"] -type ok -icon error + exit + } + } elseif {$p eq "-select-repository"} { + # in this case, we start with selecting a repository + # from a mirror list and modify ::argv to take the selection + # into account before contacting the perl back end. + unset -nocomplain ::mir_selected + # remove this argument + set ::argv [lreplace $::argv $i $i] + } + } + unset i + + if {$do_splash || ! [info exists ::mir_selected]} pre_splash + + if {! [info exists ::mir_selected]} { + select_mirror + } + + if $do_splash make_splash + unset do_splash + + if {! [info exist ::mir_selected]} { + vwait ::mir_selected + } + + # start install-tl-[tcl] via a pipe. + set cmd [list "|${::perlbin}" "${::instroot}/install-tl" \ + "-from_ext_gui" {*}$::argv 2>@1] + show_time "opening pipe" + if [catch {open $cmd r+} ::inst] { + err_exit "Error starting Perl backend" + } + + show_time "opened pipe" + set ::perlpid [pid $::inst] + + # for windows < 10: make sure the main window is still on top + wm attributes . -topmost + + chan configure $::inst -buffering line -blocking 1 + + # possible input from perl until the menu starts: + # - question about prior canceled installation + # - location (actual repository) + # - menu data, help, version, print-platform + set ::did_gui 0 + set answer "" + unset -nocomplain ::loaded + while 1 { ; # initial perl output + set ll [read_line] + if {[lindex $ll 0] < 0} { + break + } + set l [lindex $ll 1] + # There may be occasion for a dialog + if {$l eq "mess_yesno"} { + answer_to_perl + } elseif [string match "location: ?*" $l] { + # this one comes straight from install-tl, rather than + # from install-tl-extl.pl + # installer about to contact repository, which may + # fail and cause an indefinite delay + chan configure $::inst -blocking 0 + chan event $::inst readable read_line_loading + if [winfo exists .loading] { + .loading configure -text [__ "Trying to load %s. + +If this takes too long, press Abort or choose another repository." \ + [string range $l 10 end]] + update + } + break + } + } + # waiting till the repository has been loaded + vwait ::loaded + unset ::loaded + #puts stderr "done loading" + # resume reading from back end in blocking mode + while 1 { + set ll [read_line] + if {[lindex $ll 0] < 0} { + break + } + set l [lindex $ll 1] + if {$l eq "menudata"} { + # so we do want a menu and expect menu data, + # parsing which may take a while + read_menu_data + show_time "read menu data from perl" + set ::advanced 0 + set ::alltrees 0 + set answer [run_menu] + #if [info exists ::env(dbgui)] {puts "dbgui1: menu_ans is $::menu_ans"} + if {$answer eq "advanced"} { + # this could only happen if $::advanced was 0 + set ::advanced 1 + #if [info exists ::env(dbgui)] {puts "dbgui: Setting advanced to 1"} + set answer [run_menu] + if {$answer eq "alltrees"} { + set ::alltrees 1 + #if [info exists ::env(dbgui)] {puts "dbgui: Setting alltrees to 1"} + set answer [run_menu] + } + } + set ::did_gui 1 + break + } elseif {$l eq "startinst"} { + # use an existing profile: + set ::out_log {} + set answer "startinst" + break + } else { + lappend ::out_log $l + } + } + if {$answer eq "startinst"} { + run_installer + # invokes show_log which first destroys previous children + } else { + log_exit + } +}; # main_prog + +#file delete $::dblfile + +main_prog diff --git a/systems/texlive/tlnet/tlpkg/installer/install-tl.html b/systems/texlive/tlnet/tlpkg/installer/install-tl.html new file mode 100644 index 0000000000..18a1e4e327 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/install-tl.html @@ -0,0 +1,121 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> +<title>The TeX Live installer</title> +</head> +<body bgcolor="#FFFFFF" text="#000000"> +<!-- $Id: --> +<h1>The TeX Live installer</h1> +This is the installation program of the TeX Live distribution. +<p> +The installation procedure is simple: just go through the +menus until you are happy with the way all options are set up, +and then do <tt><I></tt> (start installation). +<p> +To select a menu item (a letter or a number marked with brackets) +just enter the corresponding letter or number and press return +(the letters are case insensitive except when collections +are being selected). Do not enter the angle brackets <tt><></tt> themselves. +<p> +We will now consider each menu item in more detail: + +<h2>The binary systems menu (<tt><B></tt>)</h2> + +The systems menu allows you to select and deselect the binary +packages for various different platforms. You cannot install Unix +binaries on Windows but vice versa. + +<h2>The schemes menu (<tt><S></tt>)</h2> + +You can choose from a number of different installation schemes +for TeX Live. Selecting one of these selects some collections +in the Collections and Languages lists which you can subsequently +modify. + +<h2>The collections menu (<tt><C></tt>)</h2> + +The collections menu allows you to select and deselect standard +collections. Each collection — TeX macro files, Metafont font +families, and so on — consists of several packages. +<p> +More than one collection can be selected/deselected at the same time. + +<h2>The language collections menu (<tt><L></tt>)</h2> + +The language collections menu allows you to select and deselect +language support collections. Each collection consists of several +packages, which provide features like hyphenation files and fonts. +<p> +More than one collection can be selected/deselected at the same time. + +<h2>The directories menu (<tt><D></tt>)</h2> + +The TeX Live distribution will be installed in a single directory tree +(<tt>TEXDIR</tt>). You may choose any directory you like since there are +no absolute paths compiled into the binaries. Instead, the Kpathsea +library selfdir feature ensures that all paths are relative to the +plocation of the binaries. +<p> +The platform independent files are stored in a directory tree in +<tt>TEXDIR/texmf</tt>. There are also extra directories for performing +administrative tasks like change of configuration and languages. They +default to <tt>TEXDIR/texmf-var</tt> and <tt>TEXDIR/texmf-config</tt>. +<p> +This system allows you to mount your <tt>TEXDIR/texmf</tt> tree read-only. + +<h2>The options menu (<tt><O></tt>)</h2> + +The options are not applicable to all installations. Set them as +appropriate for yours. + +<h3>use letter size instead of a4 by default</h3> + +You can choose letter as the default paper size for some programs. + +<h3>create all format files</h3> + +If this option is set, format files are created for system-wide use +by the installer. Otherwise they are will be created automatically +when needed. +<p> +In the latter case format files are stored in user's directory trees +and in some cases have to be re-created when new packages are +installed. + +<h3>install doc or source trees</h3> + +Normally all packages are installed with the source and documentation, +but these are not needed to actually run the software. If you +are installing a system for other people, it would be unfriendly to +select these options; if you know what you are doing and need a +minimal disk footprint, go ahead + +<h3>symlinks in standard directories (UNIX only)</h3> + +You can make the binaries, man pages, and info files available on your +system in either (or both) of two ways: +<ol> + <li> install them in <i>standard places</i> that are searched for these files + <li> change your search paths to include the new directories +</ol> +If you select the <i>symlinks</i> option, symbolic links will be installed in +the directories you choose. Note that if you share the TeX Live installation +accross several machines across NFS and if the chosen <i>standard places</i> are +not shared, you need to create the symbolic links on each client, too +(or use method 2 on your clients). +<p> +If you do not use the <i>symlinks</i> option, you probably need to set up +your search paths (<tt>PATH</tt>, <tt>MANPATH</tt>, <tt>INFOPATH</tt>). + +<h2>Install for running from DVD (<tt><V></tt>)</h2> + +This option sets up a minimal setup which allows TeX Live to +be run directly from the DVD. +<p> +A few directories on the hard disk have to be created for files +created by the TeX system itsef and for modified configuration files. +Please change <tt>TEXDIRW</tt> first in the directories menu <tt><D></tt>. + +</body> +</html> diff --git a/systems/texlive/tlnet/tlpkg/installer/installer-options.txt b/systems/texlive/tlnet/tlpkg/installer/installer-options.txt new file mode 100644 index 0000000000..8ea6eed42a --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/installer-options.txt @@ -0,0 +1,84 @@ +(last status change 2009-07-02) + +%vars key default text perltk wizard + $tlpdb->option("key") + description + used in install-tl/tlmgr/TLMedia +---------------------------------------------------------------------------- +tlpdbopt_install_docfiles 1 x x + option("install_docfiles") + install doc files + install-tl: sub do_install_packages + TLMedia.pm: sub install_package + +tlpdbopt_install_srcfiles 1 x x + option("install_srcfiles") + install src files + install-tl: sub do_install_packages + TLMedia.pm: sub install_package + +tlpdbopt_create_formats 1 x x + option("create_formats") + create all formats + install-tl: sub do_postinst_stuff + tlmgr: sub handle_execute_actions + +tlpdbopt_file_assocs 1 w32 w32 + option("file_assocs") + file associations and file type + file type is always done + file associations: + 0: do nothing + 1: do only new/unchanged + 2: always do + install-tl: sub do_tlpdb_postactions + TLMedia: remove_package, install_package + +tlpdbopt_desktop_integration 1 w32 w32 w32 + option("desktop_integration") + shortcuts etc + currently effects w32 only + install-tl: sub do_tlpdb_postactions + TLMedia: remove_package, install_package + +tlpdbopt_post_code 1 + option("post_code") + postaction code + install-tl: sub do_tlpdb_postactions + TLMedia: remove_package, install_package + +tlpdbopt_sys_bin/man/info /u/l/... unix unix + option("sys_bin") ... + unix link dests (if instopt_adjustpath == 1) + TLPDB add/remove_symlinks + (via tlmgr action_symlinks and install-tl do_path_adjustments) + +tlpdbopt_w32_multi_user 1 w32 w32 w32 + option("w32_multi_user") + sysadmin as multi user + install-tl: sub do_path_adjustments + TLMedia: remove_package, install_package + +instopt_letter 0 x x x + not saved into the local TLPDB + only for install time setting + use letter + install-tl: sub do_postinst_stuff + +instopt_adjustpath 0 unix/1 win x x + path adjustment + not saved into the local TLPDB + only for install time setting + (unix symlinks, w32 reg) + +addon_editor 0 w32 w32 - + not saved into the local TLPDB + only for install time setting + install texworks + +unix are things only visible on unix +w32 are things only visible on w32 +(x) are things that should be done +?? are things I am not sure +- are things that are not relevant + diff --git a/systems/texlive/tlnet/tlpkg/installer/texdirsel.pl b/systems/texlive/tlnet/tlpkg/installer/texdirsel.pl new file mode 100644 index 0000000000..dffced3bea --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/texdirsel.pl @@ -0,0 +1,277 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +$^W = 1; + +require Cwd; +require File::Spec; + +our $texlive_release; +our %vars; +our $mw; + +my $sep; +if (win32()) { + $sep = "\\"; +} else { + $sep = "/"; +} + +sub change_path { + + ### GUI SETUP ### + + my $sw; + $sw->destroy if Tk::Exists($sw); + $sw = $mw->Toplevel(-title => "Changing TEXDIR"); + $sw->transient($mw); + $sw->withdraw; + $sw->grab(); + + # define a larger font + my $lfont = $sw->fontCreate(); + $sw->fontConfigure( + $lfont, -size => 1.2 * $mw->fontConfigure($lfont, -size)); + + my $fr0 = $sw->Frame(-padx => 10, -pady => 5)->pack; + $sw->Label(-text => __("Installation directory").": ", -font => $lfont) + ->pack(-in => $fr0, -side => 'left'); + my $path_l = $sw->Label(-font => $lfont) + ->pack(-in => $fr0, -side => 'left'); + + my $fr = $sw->Frame->pack; + my $prefix_l = $sw->Label(-justify => 'right', -padx => 5) + ->grid(-in => $fr, -column => 0, -row => 0, -sticky => 'e'); + $sw->Label(-text => $sep) + ->grid(-in => $fr, -column => 1, -row => 0); + my $name_l = $sw->Label(-justify => 'center', -padx => 5) + ->grid(-in => $fr, -column => 2, -row => 0); + $sw->Label(-text => $sep) + ->grid(-in => $fr, -column => 3, -row => 0); + my $rel_l = $sw->Label(-justify => 'left', -padx => 5) + ->grid(-in => $fr, -column => 4, -row => 0, -sticky => 'w'); + + my $prefix_b = $sw->Button( + -text => __("Change". '...'), -padx => 1, -pady => 3, -bd => 1) + ->grid(-in => $fr, -column => 0, -row => 1, -sticky => 'ew'); + my $name_b = $sw->Button( + -text => __("Change"), -padx => 1, -pady => 3, -bd => 1) + ->grid(-in => $fr, -column => 2, -row => 1, -sticky => 'ew', -padx => 2); + my $rel_b = $sw->Button( + -text => __("Toggle"), -padx => 1, -pady => 3, -bd => 1) + ->grid(-in => $fr, -column => 4, -row => 1, -sticky => 'ew'); + + # warning about year component + my $warn_yr_l = $sw->Label(-anchor => 'e', -foreground => 'red') + ->pack(-fill =>'x', -expand => 1); + + # ok and cancel buttons + my $frb = $sw->Frame->pack(-fill => 'x', -expand => 1); + my $ok_b = $sw->Button( + -text => __("Ok"), + -command => sub { + callback_change_texdir(forward_slashify($path_l->cget(-text))); + $sw->destroy; + })->pack(-in => $frb, -side => 'right'); + my $q = $sw->Button(-text => __("Cancel"), -command => sub {$sw->destroy;}) + ->pack(-in => $frb, -side => 'right'); + + if (win32()) { + $frb->Label( + -text => + __("Localized directory names will be replaced by their real names")) + ->pack(-side => 'left'); + } + + # array of widgets needed by callbacks + my @wg = ($path_l, $prefix_l, $name_l, $rel_l, $ok_b, $warn_yr_l); + + # callbacks which use @wg + $prefix_b->configure(-command => [\&browse_path, $sw, @wg]); + $name_b->configure(-command => [\&edit_name, $sw, @wg]); + $rel_b->configure(-command => [\&toggle_rel, @wg]); + + # bindings + $sw->bind('<Return>' => [ $ok_b, 'Invoke']); + $sw->bind('<Escape>' => [ $q, 'Invoke']); + + ### END GUI SETUP ### + + my $val = $vars{'TEXDIR'}; + $val = native_slashify($val); + $path_l->configure(-text => $val); + + # release subdirectory at the end? + my $rel_pat = "[\\\\/]".$texlive_release."[\\\\/]?\$"; + + # calculate initial values based on existing $val (copied from TEXDIR) + my $initdir = File::Spec->rel2abs($val); + my $rel = ""; + my $name = ""; + # check for release subdirectory at the end and remove from initdir + if ($initdir =~ $rel_pat) { + $initdir =~ s!$rel_pat!!; + $rel = $texlive_release; + $rel_l->configure(-text => $texlive_release); + } + # now assign remaining final path component to name_l + if ($initdir =~ /[\\\/]([^\\\/]+)[\\\/]?$/) { + $name_l->configure(-text => $1); + $initdir =~ s/[\\\/][^\\\/]+[\\\/]?$//; + } + + # backtrack remaining initdir to something that exists + # and assign it to prefix + while (! -d $initdir) { + my $initprev = $initdir; + $initdir =~ s/[\\\/][^\\\/]+[\\\/]?$//; + last if ($initdir eq $initprev); + } + if ($initdir eq "" or (win32() and $initdir =~ /:$/)) { + $initdir = $initdir . (win32() ? "\\" : "/"); + } + $prefix_l->configure(-text => $initdir); + # display complete path in $path_l + update_full_path( @wg ); + $sw->deiconify(); + $sw->raise($mw); + $sw->grab(); +} # change_path + +sub update_full_path { + my $path_l = shift; + my $prefix_l = shift; + my $name_l = shift; + my $rel_l = shift; + my $ok_b = shift; + my $warn_yr_l = shift; + + my $prefix = $prefix_l->cget(-text); + if ($prefix eq "" or (win32() and $prefix =~ /:$/)) { + $prefix_l->insert('end', $sep); + $prefix .= $sep; + } + my $name = $name_l->cget(-text); + if ($name =~ m![\\/]!) { + $name =~ s![\\/]!!g; + $name_l->delete(0, 'end'); + $name_l->insert(0, $name); + } + $path_l->configure( + -text => File::Spec->catdir($prefix, $name, $rel_l->cget(-text))); + if (-d $prefix) { + $ok_b->configure(-state => 'normal'); + } else { + $ok_b->configure(-state => 'disabled'); + } + # check for release component + if ($rel_l->cget(-text) ne '') { + $warn_yr_l->configure(-text => ''); + } else { + $warn_yr_l->configure( + -text => __('Release year component highly recommended!')); + } + return; +} # update_full_path + +sub toggle_rel { + my $path_l = shift; + my $prefix_l = shift; + my $name_l = shift; + my $rel_l = shift; + my $ok_b = shift; + my $warn_yr_l = shift; + + if ($rel_l->cget(-text) eq '') { + $rel_l->configure(-text => $texlive_release); + } else { + $rel_l->configure(-text => ''); + } + update_full_path($path_l, $prefix_l, $name_l, $rel_l, $ok_b, $warn_yr_l); +} # toggle_rel + +sub edit_name { + my $sw = shift; # parent window + my $path_l = shift; + my $prefix_l = shift; + my $name_l = shift; + my $rel_l = shift; + my $ok_b = shift; + my $warn_yr_l = shift; + my $ednm; + $ednm->destroy if Tk::Exists($ednm); + $ednm = $sw->Toplevel(-title => __("Changing directory name")); + $ednm->transient($sw); + $ednm->withdraw(); + + $ednm->Label(-text => __("Change name (slashes not allowed)")) + ->pack(-padx => 5, -pady => 5); + my $nm_e = $ednm->Entry(-width => 20)->pack(-pady => 5); + $nm_e->insert(0, $name_l->cget(-text)); + my $fr = $ednm->Frame->pack(-fill => 'x', -expand => 1); + my $ok = $ednm->Button( + -text => __("OK"), + -command => sub { + my $nm = $nm_e->get; + if ($nm !~ m![\\/]!) { + $name_l->configure(-text => $nm); + update_full_path( + $path_l, $prefix_l, $name_l, $rel_l, $ok_b, $warn_yr_l); + $ednm->destroy(); + } else { + $ednm->messageBox( + -icon => 'error', + -type => 'Ok', + -message => __("Illegal name")); + } + })->pack(-in => $fr, -side => 'right', -pady => 5, -padx => 5); + my $cancel = $ednm->Button( + -text => __("Cancel"), + -command => sub { $ednm->destroy(); }) + ->pack(-in => $fr, -side => 'right'); + $ednm->deiconify(); + $ednm->raise($sw); + $ednm->grab(); +} # edit_name + +sub browse_path { + my $mw = shift; + my $path_l = shift; + my $prefix_l = shift; + my $name_l = shift; + my $rel_l = shift; + my $ok_b = shift; + my $warn_yr_l = shift; + + my $retval = $prefix_l->cget(-text); + my $use_native = 0; # choice of directory browser + if ($^O =~ /^MSWin/i) { + $use_native = 1; + } else { + eval { require Tk::DirSelect; }; + if ($@) { + eval { require installer::DirSelect; }; + if ($@) { + $use_native = 1; + } + } + } + if ($use_native) { + $retval = $mw->chooseDirectory( + -initialdir => $retval, + -parent => $mw, + -title => __("Select prefix destination directory"), + ); + } else { + my $fsdia = $mw->DirSelect( + -title => __("Select prefix destination directory")); + $retval = $fsdia->Show($retval, -popover => $mw); + $fsdia->destroy; + } + if (defined $retval and $retval ne "") { + $prefix_l->configure(-text => File::Spec->rel2abs($retval)); + update_full_path($path_l, $prefix_l, $name_l, $rel_l, $ok_b, $warn_yr_l); + } + return; +} # browse_path diff --git a/systems/texlive/tlnet/tlpkg/installer/texlion.gif b/systems/texlive/tlnet/tlpkg/installer/texlion.gif Binary files differnew file mode 100644 index 0000000000..2b7afd5584 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/texlion.gif diff --git a/systems/texlive/tlnet/tlpkg/installer/texlive.png b/systems/texlive/tlnet/tlpkg/installer/texlive.png Binary files differnew file mode 100644 index 0000000000..eb8603ab6b --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/texlive.png diff --git a/systems/texlive/tlnet/tlpkg/installer/tl-cmd.bat b/systems/texlive/tlnet/tlpkg/installer/tl-cmd.bat new file mode 100644 index 0000000000..747d308823 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/tl-cmd.bat @@ -0,0 +1,15 @@ +@echo off + +rem This batchfile starts a command prompt with the TeX Live +rem Windows binary directory as first path component. + +rem Public domain + +@echo off +setlocal enableextensions + +rem Add bin dir to beginning of PATH only if it is not already there +for /f "tokens=1,2 delims=;" %%I in ("%~dp0..\..\bin\win32;%PATH%") do if not "%%~fI"=="%%~fJ" set "PATH=%%~fI;%PATH%" + +rem Start new console +start "TeX Live" "%COMSPEC%" diff --git a/systems/texlive/tlnet/tlpkg/installer/tl-tray-menu.ini b/systems/texlive/tlnet/tlpkg/installer/tl-tray-menu.ini new file mode 100644 index 0000000000..dcf3822660 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/tl-tray-menu.ini @@ -0,0 +1,28 @@ +; Example configuration file for TeX Live Menu utility +; (to be placed in the same directory as the menu executable) +; +; * All lines starting with a semicolon are ignored +; * Each line after [menu] must be in the format: +; <menu label>=<command to execute> +; * No blank lines are allowed nor whitespace around the equal sign +; * Optional '&' in the menu label marks the character for keyboard accelaration +; * Menu commands can contain additional arguments and use environment variables +; (e.g., %WINDIR%). +; * A program to execute in the menu command can be specified by its name only +; (if it is located on the search PATH) or by an absolute or relative file +; path. Relative file paths are resolved relative to the location of the menu +; program (at the root of your TeX Live installation). +; * Alternatively, the 'program' can be a file which Windows knows how to open. +; Its location can be an absolute or relative path; see previous item. +; * The directory <menu dir>\bin\win32, where <menu dir> is the directory with +; the menu program, is automatically added to the beginning of the search PATH +; * Number of menu items is limited to 30 and their total size to 32KB +; +[menu] +&Package Manager=tlshell.exe +&Documentation=doc.html +&Editor=texworks.exe +;Your own choice of portable editor: +;&My editor=..\my_editor\my_editor.exe +Notepad="%windir%\system32\notepad.exe" +&Command Prompt=cmd /k "title TeX Live"
\ No newline at end of file diff --git a/systems/texlive/tlnet/tlpkg/installer/tracked-install.pl b/systems/texlive/tlnet/tlpkg/installer/tracked-install.pl new file mode 100644 index 0000000000..1f46eed826 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/tracked-install.pl @@ -0,0 +1,139 @@ +#!/usr/bin/env perl +# $Id: tracked-install.pl 48057 2018-06-20 02:14:01Z preining $ +# +# Copyright 2008-2017 Norbert Preining +# Copyright 2008 Reinhard Kotucha +# This file is licensed under the GNU General Public License version 2 +# or any later version. + +use strict; +$^W = 1; + +my $svnrev = '$Revision: 41176 $'; +$svnrev =~ m/: ([0-9]+) /; +$::menurevision = $1; + +require Tk; +require Tk::ROText; +require Tk::ProgressBar; + +use utf8; +no utf8; + +sub installer_tracker { + my $ret; + # create a progress bar window + $::sww = Tk::MainWindow->new; + $::sww->Label(-text => __("Installation process"))->pack; + #warn "Debug!! Creating text window"; + $::progressw = $::sww->Scrolled( + "ROText", -wrap => "word", -scrollbars => "e", -height => 18); + #warn "Debug!! Created text window"; + $::progressw->pack(-expand => 1, -fill => "both"); + #warn "Debug!! Placed text window"; + my $percent_done = 0; + $::progress = $::sww->ProgressBar(-variable => \$percent_done, + -width => 20, -length => 400, -from => 0, -to => 100, -blocks => 10, + -colors => [ 0, '#0078b8' ]); + $::progress->pack(-fill => "x"); + #my $f = $::sww->Frame; + my $b = $::sww->Button( + -text => __("Cancel"), + -command => sub { + do_cleanup(); $::sww->destroy; + # POSIX::exit prevents Tk error message 'Tk::Error: ("after" script)' + POSIX::exit(1); + })->pack(-pady => "2m"); + $b->focus(); + # $f->pack; + setup_hooks_perltk(); + + $ret = do_installation(); + + if (@::WARNLINES) { + foreach my $t (@::WARNLINES) { + tlwarn ("$t\n"); + } + } + if ($::env_warns) { + tlwarn($::env_warns); + } + $::progressw->tagConfigure('centered', -justify => 'center'); + # basic welcome message + foreach my $t (@::welcome_arr) { + info("$t\n"); + } + $::progressw->insert("end", "\n"); + + do_cleanup(); + + # additional info + if ($::LOGFILENAME) { + $::progressw->insert ("end", "Logfile: $::LOGFILENAME"); + } else { + # do_cleanup sets $::LOGFILENAME to "" + #if no logfile could be written + $::progressw->insert ("end", + "Cannot create logfile $::vars{'TEXDIR'}/install-tl.log: $!"); + } + if (@::WARNLINES or $::env_vars or !$::LOGFILENAME) { + $::progressw->insert("end", "\n"); + $::progressw->insert("end", __("Scroll back to inspect warnings")); + } + $::progressw->insert("end", "\n"); + my $linechar = $::progressw->index("end"); + $::progressw->see("end"); + $::progressw->tagAdd("centered", $linechar, "end"); + $::progressw->tagConfigure("centered", -justify => "center"); + $b->configure( + -text => __("Finish"), + -command => sub { + $::sww->destroy; return $ret; + }); + + Tk::MainLoop(); + return $ret; +} # installer_tracker + +#sub tracked_installation { +# # undo binding, since this should run only once +# my $b = shift; +# $b->bind('<Map>' => ''); +# $ret = do_installation(); +# $::sww->destroy; +#} + +sub setup_hooks_perltk { + @::info_hook = (); + push @::info_hook, + sub { + update_status(join(" ",@_)); + $::sww->update; + }; + push @::warn_hook, + sub { + return unless defined $::sww ; + update_status(join(" ",@_)); + }; + @::install_packages_hook = (); + push @::install_packages_hook, \&update_progressbar; + push @::install_packages_hook, + sub { + return unless defined $::sww; + $::sww->update; + }; +} + +sub update_status { + my ($p) = @_; + return unless defined $::progressw; + $::progressw->insert("end", "$p"); + $::progressw->see("end"); +} +sub update_progressbar { + my ($n,$total) = @_; + return unless defined $::progress; + if (defined($n) && defined($total)) { + $::progress->value(int($n*100/$total)); + } +} diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-freebsd b/systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-freebsd Binary files differnew file mode 100644 index 0000000000..6485623c52 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-freebsd diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-netbsd b/systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-netbsd Binary files differnew file mode 100644 index 0000000000..62f371c8b8 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-netbsd diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-freebsd b/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-freebsd Binary files differnew file mode 100644 index 0000000000..712d0bbc43 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-freebsd diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-netbsd b/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-netbsd Binary files differnew file mode 100644 index 0000000000..3910a9b244 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-netbsd diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwin b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwin Binary files differnew file mode 100644 index 0000000000..380a4f6cc0 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwin diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwinlegacy b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwinlegacy Binary files differnew file mode 100644 index 0000000000..f7a2eac5e6 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwinlegacy diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-linuxmusl b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-linuxmusl Binary files differnew file mode 100644 index 0000000000..0bd3884db1 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-linuxmusl diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.aarch64-linux b/systems/texlive/tlnet/tlpkg/installer/xz/xz.aarch64-linux Binary files differnew file mode 100644 index 0000000000..31162201a5 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.aarch64-linux diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-freebsd b/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-freebsd Binary files differnew file mode 100644 index 0000000000..6c5ba6890a --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-freebsd diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-netbsd b/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-netbsd Binary files differnew file mode 100644 index 0000000000..5edea8129c --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-netbsd diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.armhf-linux b/systems/texlive/tlnet/tlpkg/installer/xz/xz.armhf-linux Binary files differnew file mode 100644 index 0000000000..6b5c7a69e0 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.armhf-linux diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-freebsd b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-freebsd Binary files differnew file mode 100644 index 0000000000..82fd157850 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-freebsd diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-linux b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-linux Binary files differnew file mode 100644 index 0000000000..1fc7b6d068 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-linux diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-netbsd b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-netbsd Binary files differnew file mode 100644 index 0000000000..c215d1a4d9 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-netbsd diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-solaris b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-solaris Binary files differnew file mode 100644 index 0000000000..1e4381ebc1 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-solaris diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwin b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwin Binary files differnew file mode 100644 index 0000000000..2bfc00e429 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwin diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwinlegacy b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwinlegacy Binary files differnew file mode 100644 index 0000000000..617e2307d7 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwinlegacy diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linux b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linux Binary files differnew file mode 100644 index 0000000000..e3509948b5 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linux diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linuxmusl b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linuxmusl Binary files differnew file mode 100644 index 0000000000..80abb2ac34 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linuxmusl diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-solaris b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-solaris Binary files differnew file mode 100644 index 0000000000..d4fbaffe01 --- /dev/null +++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-solaris |