summaryrefslogtreecommitdiff
path: root/systems/texlive/tlnet/tlpkg/installer
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /systems/texlive/tlnet/tlpkg/installer
Initial commit
Diffstat (limited to 'systems/texlive/tlnet/tlpkg/installer')
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/COPYING.MinGW-runtime.txt257
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/DirSelect.pm503
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/config.guess1662
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl172
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/install-menu-extl.pl209
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/install-menu-perltk.pl1291
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/install-menu-text.pl1153
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/install-menu-wizard.pl622
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/install-tl-gui.tcl2063
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/install-tl.html121
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/installer-options.txt84
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/texdirsel.pl277
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/texlion.gifbin0 -> 26224 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/texlive.pngbin0 -> 15879 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/tl-cmd.bat15
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/tl-tray-menu.ini28
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/tracked-install.pl139
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-freebsdbin0 -> 643552 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-netbsdbin0 -> 607784 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-freebsdbin0 -> 551196 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-netbsdbin0 -> 543968 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwinbin0 -> 631060 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwinlegacybin0 -> 693816 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-linuxmuslbin0 -> 754648 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.aarch64-linuxbin0 -> 166608 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-freebsdbin0 -> 177720 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-netbsdbin0 -> 187240 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.armhf-linuxbin0 -> 169992 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-freebsdbin0 -> 173000 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-linuxbin0 -> 206940 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-netbsdbin0 -> 203396 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-solarisbin0 -> 171604 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwinbin0 -> 187264 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwinlegacybin0 -> 189528 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linuxbin0 -> 183552 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linuxmuslbin0 -> 1004404 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-solarisbin0 -> 188472 bytes
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/&mdash;/--/gi; # mdash
+ s/&lt;/</gi; s/&gt;/>/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>&lt;I&gt;</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>&lt;&gt;</tt> themselves.
+<p>
+We will now consider each menu item in more detail:
+
+<h2>The binary systems menu (<tt>&lt;B&gt;</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>&lt;S&gt;</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>&lt;C&gt;</tt>)</h2>
+
+The collections menu allows you to select and deselect standard
+collections. Each collection &mdash; TeX macro files, Metafont font
+families, and so on &mdash; consists of several packages.
+<p>
+More than one collection can be selected/deselected at the same time.
+
+<h2>The language collections menu (<tt>&lt;L&gt;</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>&lt;D&gt;</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>&lt;O&gt;</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>&lt;V&gt;</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>&lt;D&gt;</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
new file mode 100644
index 0000000000..2b7afd5584
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/texlion.gif
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/texlive.png b/systems/texlive/tlnet/tlpkg/installer/texlive.png
new file mode 100644
index 0000000000..eb8603ab6b
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/texlive.png
Binary files differ
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
new file mode 100644
index 0000000000..6485623c52
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-freebsd
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-netbsd b/systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-netbsd
new file mode 100644
index 0000000000..62f371c8b8
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.amd64-netbsd
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-freebsd b/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-freebsd
new file mode 100644
index 0000000000..712d0bbc43
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-freebsd
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-netbsd b/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-netbsd
new file mode 100644
index 0000000000..3910a9b244
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.i386-netbsd
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwin b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwin
new file mode 100644
index 0000000000..380a4f6cc0
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwin
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwinlegacy b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwinlegacy
new file mode 100644
index 0000000000..f7a2eac5e6
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-darwinlegacy
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-linuxmusl b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-linuxmusl
new file mode 100644
index 0000000000..0bd3884db1
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/wget/wget.x86_64-linuxmusl
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.aarch64-linux b/systems/texlive/tlnet/tlpkg/installer/xz/xz.aarch64-linux
new file mode 100644
index 0000000000..31162201a5
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.aarch64-linux
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-freebsd b/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-freebsd
new file mode 100644
index 0000000000..6c5ba6890a
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-freebsd
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-netbsd b/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-netbsd
new file mode 100644
index 0000000000..5edea8129c
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.amd64-netbsd
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.armhf-linux b/systems/texlive/tlnet/tlpkg/installer/xz/xz.armhf-linux
new file mode 100644
index 0000000000..6b5c7a69e0
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.armhf-linux
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-freebsd b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-freebsd
new file mode 100644
index 0000000000..82fd157850
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-freebsd
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-linux b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-linux
new file mode 100644
index 0000000000..1fc7b6d068
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-linux
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-netbsd b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-netbsd
new file mode 100644
index 0000000000..c215d1a4d9
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-netbsd
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-solaris b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-solaris
new file mode 100644
index 0000000000..1e4381ebc1
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.i386-solaris
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwin b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwin
new file mode 100644
index 0000000000..2bfc00e429
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwin
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwinlegacy b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwinlegacy
new file mode 100644
index 0000000000..617e2307d7
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-darwinlegacy
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linux b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linux
new file mode 100644
index 0000000000..e3509948b5
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linux
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linuxmusl b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linuxmusl
new file mode 100644
index 0000000000..80abb2ac34
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-linuxmusl
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-solaris b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-solaris
new file mode 100644
index 0000000000..d4fbaffe01
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/installer/xz/xz.x86_64-solaris
Binary files differ