From 467f3c0b94ec8190767721a7485a07bfa7221ca5 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 29 Apr 2024 17:24:23 +0000 Subject: intermediate epstopdf.pl from John Collins to better detect Msys vs. Cygwin vs. native Windows git-svn-id: svn://tug.org/texlive/trunk@71120 c570f23f-e606-0410-a88d-b1316a301751 --- Build/extra/epstopdf/epstopdf.pl | 136 +++++++++++++++++++++++++++++++-------- 1 file changed, 110 insertions(+), 26 deletions(-) diff --git a/Build/extra/epstopdf/epstopdf.pl b/Build/extra/epstopdf/epstopdf.pl index 4773841f42e..59df3b60582 100755 --- a/Build/extra/epstopdf/epstopdf.pl +++ b/Build/extra/epstopdf/epstopdf.pl @@ -1,4 +1,14 @@ #!/usr/bin/env perl +use warnings; + +# Note by JCC 14 Apr 2024: Maybe put code +# for detecting TL Windows etc +# for Windows setting of $GS +# after parsing of options etc, but before testing for existence of programs. +# But will need to revise help text about gs name. +# Hive off the detecting of TL Windows to subroutine. + + # $Id$ # (Copyright lines below.) # @@ -35,7 +45,21 @@ # # emacs-page # -my $ver = "2.33"; +my $ver = "2.34.JCC.2"; +# 2024/04/14 2.34.JCC.2 (John Collins) +# * Msys PATH separator is :. +# * Do immediate decomposition of path to array on start up, and use array +# instead of separate uses of split. +# * On Windows, msys and Cygwin, normalize directory separator to /. +# * Detect invocation via Windows TL (and epstopdf.exe wrapper script) by +# presence of TL's private gs in PATH. (Directory ending in /tlgs/bin.) +# In this case change behavior under Cygwin to be of the Windows instead of +# Unix. +# * On cygwin and msys, put temporary file in current directory instead of +# default, which is normally /tmp. That's so that the pathname to the +# temporary file remains valid no matter which kind of gs its passed to: +# native Windows, msys or Cygwin. +# * Pretty print PATH, one directory per line, in error about program not in PATH. # 2023/09/15 2.33 (Karl Berry) # * Cygwin PATH separator is :. Report from Alois Steindl, # https://tug.org/pipermail/tex-live/2023-September/049474.html @@ -214,18 +238,81 @@ There is NO WARRANTY, to the extent permitted by law. END_COPYRIGHT my $title = "$program $ident\n"; -my $on_windows = $^O =~ /^(MSWin|msys$)/; -my $on_windows_or_cygwin = $on_windows || $^O eq "cygwin"; +my $on_cygwin = ($^O eq 'cygwin'); +my $on_msys = ($^O eq 'msys'); +my $on_windows = ($^O =~ /^MSWin/) || $on_msys; +my $on_windows_or_cygwin = $on_windows || $on_cygwin; + +# Which TL? + +my $path_sep = ( ($^O =~ /^MSWin/) ? ';' : ':' ); +my @pdirs = split($path_sep, $ENV{PATH}); +# Normalize directory separators to /. Always valid on Windows. +if ($on_windows_or_cygwin) { + foreach (@pdirs) { s !\\!/!g; } +} + +# Default values for commands +# Ghostscript, which is always needed. Override for Windows +my $GS = 'gs'; +# Kpsewhich, only used in restricted mode. +my $kpsewhich = 'kpsewhich'; + +# Determine if I was invoked from a standard Windows TL installation via the +# wrapper script epstopdf.exe: +my $TL_Windows_bin = undef; +my $TL_tlgs = undef; +if ($on_windows_or_cygwin) { + # Doesn't work for current placement of this block of code + # Command line options not yet parsed, so debug does nothing. + debug( "Looking for symptoms of wrapper .exe and Windows TL:" ); + for (@pdirs) { + if ( m!^(.+)/tlpkg/tlgs/bin$! ) { + debug( "Found Windows tlgs item '$_' in PATH" ); + # I was probably invoked via runscript by .exe file in native TL + # Windows, since then a tlgs/bin item is inserted in PATH, + # so that Windows TL's private installation of gs, with its executables + # gswin64c.exe and/or gswin32c.exe gets used. + # Anything else giving the same symptom is surely a deliberate + # configuration to imitate that the TL Windows behavior. + my $TL_root = $1; + $TL_tlgs = $_; + $TL_Windows_bin = "$TL_root/bin/windows"; + last; + } + } + if ($TL_tlgs) { + # Confirm by existence of expected directories and files. + # If those do not exist, we don't have a standard native + # Windows TL installation. + if ( (-x "$TL_Windows_bin/kpsewhich.exe") + && ( (-x "$TL_tlgs/gswin64c.exe") || (-x "$TL_tlgs/gswin32c.exe") ) + ) { + # The files I need exist. + # Note that runscript ensures that the tlgs and the binary directory + # of its own installation are in PATH ahead of any directories that + #may contains other versions. + } + else { + warning( + "I appear to be run from native TeX Live Windows with bin and tlgs dirs\n". + " '$TL_Windows_bin'\n". + " '$TL_tlgs'.\n". + "But the expected files that I need don't exist (kpsewhich, and gswin64c or\n". + "gswin32c). So we don't have a correct standard TeX Live Windows installation.\n" ); + $TL_Windows_bin = undef; + $TL_tlgs = undef; + } + } + else { debug( "Nothing relevant found" ); } +} -### ghostscript command name -my $GS = "gs"; -if ($on_windows) { +if ($on_windows || defined $TL_tlgs) { $GS = "gswin32c"; if ($ENV{"PROCESSOR_ARCHITECTURE"} eq "AMD64" || $ENV{"PROCESSOR_ARCHITEW6432"} eq "AMD64") { # prefer gswin64c.exe if on search path. - my @pdirs = split(/;/, $ENV{"PATH"}); - foreach $d (@pdirs) { + foreach my $d (@pdirs) { $d = substr ($d, 1, -1) if (substr ($d,1,1) eq '"'); if (-f $d . "/gswin64c.exe") { $GS = "gswin64c"; @@ -500,21 +587,9 @@ sub warnerr { $restricted ? error(@_) : warning(@_); } ### debug messages debug "on_windows=$on_windows, on_windows_or_cygwin=$on_windows_or_cygwin"; +debug "on_msys=$on_msys, on_cygwin = $on_cygwin"; debug "Restricted mode activated" if $restricted; -### safer external commands for Windows in restricted mode -my $kpsewhich = 'kpsewhich'; -if ($restricted && $on_windows) { - use File::Basename; - my $mydirname = dirname $0; - # $mydirname is the location of the Perl script - $kpsewhich = "$mydirname/../../../bin/windows/$kpsewhich"; - debug "Restricted Windows kpsewhich: $kpsewhich"; - $GS = "$mydirname/../../../tlpkg/tlgs/bin/$GS"; - debug "Restricted Windows gs: $GS"; -} -debug "kpsewhich command: $kpsewhich"; - ### check that PROG is in PATH and executable, abort if not. It'd be # better to actually try running the program, but then we'd have to # either replicate Perl's logic for finding the command interpreter @@ -528,7 +603,6 @@ sub check_prog_exists { my ($prog) = @_; my @w_ext = ("exe", "com", "bat"); debug " Checking if $prog is in PATH"; - # absolute unix if (! $on_windows_or_cygwin && $prog =~ m,^((\.(\.)?)?/),) { return 1 if -x $prog; # absolute or explicitly relative @@ -545,7 +619,7 @@ sub check_prog_exists { } # not absolute, check path - for my $dir (split ($on_windows ? ";" : ":", $ENV{"PATH"})) { + for my $dir (@pdirs) { $dir = "." if $dir eq ""; # empty path element debug " Checking dir $dir"; if (-x "$dir/$prog") { @@ -558,7 +632,10 @@ sub check_prog_exists { } # if made it through the whole loop, not found, so quit. - error "Required program $prog not found in PATH ($ENV{PATH})"; + my @path_pretty = (); + for (@pdirs) { push @path_pretty, " '$_'\n"; } +# error "Required program $prog not found in PATH ($ENV{PATH})"; + error "Required program $prog not found in PATH, which contains:\n", @path_pretty; } check_prog_exists ($kpsewhich); @@ -806,8 +883,15 @@ if ($::opt_gs) { debug "Ghostscript pipe: @GS"; open($OUT, '|-', @GS) or error "Cannot open Ghostscript for piped input: @GS"; - } else { # use a temporary file on Windows/Cygwin. - ($OUT, $tmp_filename) = tempfile(UNLINK => 1); + } else { + # use a temporary file on Windows/msys/Cygwin. + if ($on_cygwin || $on_msys) { + # Use current directory for temporary file, to avoid problems of + # translation of directory name if native Windows gs gets invoked. + ($OUT, $tmp_filename) = tempfile(UNLINK => 1, DIR => '.'); + } else { + ($OUT, $tmp_filename) = tempfile(UNLINK => 1); + } debug "Using temporary file '$tmp_filename'"; } $outname = $GS; -- cgit v1.2.3