#!/usr/bin/perl my $arch = `uname -p`; chomp $arch; my @texdistlocations = ( "/Library/TeX/Distributions"); my $defaultname = '.DefaultTeX'; my $texdistversion = '1.5'; use Getopt::Long; my $verbose = 0; my $list = 0; my $all = 0; my $usage = 0; my $dir = 0; my $version = 0; my $unique = 0; my $current = 0; my $setcurrent = ''; my $showpath = ''; my $expand = 0; my $texdist = "$defaultname"; my $basepath = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"; $result = GetOptions( "verbose+" => \$verbose, "list" => \$list, "usage" => \$usage, "all" => \$all, "version" => \$version, "dir" => \$dir, "unique" => \$unique, "current" => \$current, "setcurrent=s" => \$setcurrent, "showpath" => \$showpath, "basepath=s" => \$basepath, "texdist=s" => \$texdist, "expand" => \$expand); my %alldist = locate_alldist(); my %unique; if ($version) { print "${texdistversion}\n"; exit 0; } if ($usage) { print <<__EOF_USAGE This is TeXDist, (C) Gerben Wierda, 2006 TeXDist is an interface to multiple TeX distributions on your system, using the TeXDist description structure. TeXDist is free software under the BSD License (see below) Usage: texdist [--verbose+] [--usage] [--version] [--list] [--all] [--dir] [--unique] [--current] [--expand] [--texdist=s] [--basepath=s] [--showpath] [--setcurrent=s] [command] --verbose increases the verbosity of the program. Multiple --verbose flags increase the verbosity even more. There is one help mode: --usage gives this message and exits There is one identification mode: --version gives the texdist version nuber and exits There are two listing modes: --list lists all available TeX Dstributions on your system and exits --current only shows the current distribution and exits. If the current TeX Distribution is not usable (no binaries that are usable on your system), this command displays nothing. The listing modes can be modified: --all modifies --list to display all known distributions instead --dir modifies --list and --current to show not only names of the TeX Distributions but also where the TeX Distribution descriptions are kept. --expand modifies --list and --current to show not the TeX Distribution description but the root directory of that TeX Distribution. --unique modifies --list to show any unique output only once. There may be multiple TeX Distribution descriptions on your system that point to the same actual distribution There is one mode for setting the system default TeX: --setcurrent=s looks in /Library/TeX/Distributions for s.texdist and then sets the current system-wide TeX Distribution to s. It will only do this when it is running with administrator privileges and of course if s.texdist exists. The default is set in /Library/TeX/Distributions/.DefaultTeX After setting the default, the command exits. Then there is the command mode: If neither --usage, --list or --current is given, TeXDist executes command after having adapted the PATH to reflect the location of the TeX Distribution to use. The default TeX Distribution used is .DefaultTex. The standard PATH to which the TeX binaries directory is appended is /bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin The command mode can be modified: --texdist=s changes the TeX Distribution to use to the string s before executing command --basepath=s changes the standard PATH to which the TeX binaries drectory is appended to s before executing command --showpath changes command mode such that the PATH for the command is displayed but the command is not executed. Examples: \$ texdist --list --all TeXLive-2004.texdist TeXLive-2005.texdist TeXLive-2006.texdist gwTeX-2003-2005.texdist gwTeX.texdist \$ texdist --list TeXLive-2005.texdist gwTeX-2003-2005.texdist gwTeX.texdist \$ texdist --list --dir /Library/TeX/Distributions/TeXLive-2005.texdist /Library/TeX/Distributions/gwTeX-2003-2005.texdist /Library/TeX/Distributions/gwTeX.texdist \$ texdist --list --expand /usr/local/texlive/2005 /usr/local/teTeX /usr/local/gwTeX \$ texdist --current gwTeX \$ texdist --current -dir /Library/TeX/Distributions/gwTeX.texdist \$ texdist --current --expand /usr/local/gwTeX \$ texdist --verbose "kpsewhich fmtutil.cnf" /usr/local/gwTeX/texmf/web2c/fmtutil.cnf \$ texdist --verbose --texdist=TeXLive-2005 "kpsewhich fmtutil.cnf" /usr/local/texlive/2005/texmf/web2c/fmtutil.cnf \$ texdist --setcurrent=gwTeX --verbose \$ sudo ./texdist --setcurrent=gwTeX Password: Default TeX set to "gwTeX" \$ sudo ./texdist --setcurrent=gwTeX --dir Password: Default TeX set to /Library/TeX/Distributions/gwTeX.texdist \$ sudo ./texdist --setcurrent=gwTeX --expand Password: Default TeX set to /usr/local/gwTeX __EOF_USAGE ;exit 0; } if ($setcurrent ne '') { if ($> != 0) { die "The --setcurrent option requires administrator privileges. Bailing out...\n"; } for my $distdir (@texdistlocations) { if (-e "${distdir}/${setcurrent}.texdist") { my $linkdistdir = $distdir; if (${distdir} eq '/Library/TeX/Distributions') { $linkdistdir = '..'; } system( "/bin/rm -f /Library/TeX/Distributions/.DefaultTeX/Contents"); system( "/bin/ln -s \"${linkdistdir}/${setcurrent}.texdist/Contents\" /Library/TeX/Distributions/.DefaultTeX/Contents"); my $rapport = "\"$setcurrent\""; $rapport = "$distdir/$setcurrent.texdist" if $dir; $rapport = expand( "$distdir/$setcurrent.texdist/Contents/Root") if $expand; print "Default TeX set to $rapport\n"; exit 0; } } die "$0: No TeX distributions \"$setcurrent\" found.\n"; } if ($current) { if ($alldist{"$defaultname"}{'usable'} eq 'no') { warn "$0: No usable current TeX defined (no binaries in an architecture we can run)\n" if $verbose; } elsif ($alldist{"$defaultname"}{'usable'} eq 'rosetta') { warn "$0: Your current default will be run via Rosetta emulation (slow)\n" if $verbose; } # First: try to find which .texdist is pointing to us. This is done by # using readlink my $defaultcontents = $alldist{"$defaultname"}{'location'} . '/Contents'; my $contentslink = readlink( $defaultcontents); my $location = $alldist{"$defaultname"}{'location'}; $location =~ s/$/\/$contentslink/; $location =~ s/\/Contents//; $location =~ s/$defaultname\/\.\.\///; my ($dirname,$distname) = $location =~ m|(.+)/([^/]+)\.texdist$|; if (-e $alldist{"$defaultname"}{'root'}) { my $rapport; if ($expand) { $rapport = expand( $alldist{"$defaultname"}{'root'}); } elsif ($dir) { $rapport = "$dirname/$distname.texdist"; } else { $rapport = $distname; } print( "$rapport\n"); } else { warn "$0: No locatable current TeX defined\n" if $verbose; } exit 0; } if ($list) { foreach my $dist (sort keys %alldist) { next if $dist eq "$defaultname"; if ($all or $alldist{$dist}{'usable'} ne 'no') { my $rapport; if ($expand) { if (not -e $alldist{$dist}{'root'}) { $rapport = "$alldist{$dist}{'root'} (unresolved)"; } else { $rapport = expand( $alldist{$dist}{'root'}); } } elsif ($dir) { $rapport = $alldist{$dist}{'location'}; } else { $rapport = $dist; } if (not $unique or not exists $unique{$rapport}) { print( "$rapport\n"); } $unique{$rapport} = 1; } } exit 0; } warn "$0: Using TeX distribution ${texdist}\n" if ($verbose > 1); my $truepath = undef; if (not exists $alldist{$texdist}{'path'}) { if (not exists $alldist{"$texdist.texdist"}{'path'}) { die "Distribution $texdist does not poin to a usable binaries location.\n"; } $truepath = $alldist{"$texdist.texdist"}{'path'}; } else { $truepath = $alldist{$texdist}{'path'}; } warn "Adding $truepath to PATH\n" if $verbose > 3; $ENV{'PATH'} = "$basepath:$truepath"; if ($showpath) { print "Will execute \"$ARGV[0]\" with PATH=\"$basepath:$truepath\"\n"; exit 0; } else { exit system( "$ARGV[0]"); } sub locate_alldist { my %resultdirs; for my $dir (@texdistlocations) { if (opendir( DIRHANDLE, $dir)) { while (my $potentialtexdir = readdir( DIRHANDLE)) { warn "$0: Testing for TeX distribution \"$dir/$potentialtexdir\"\n" if ($verbose > 3); if (-e "$dir/$potentialtexdir/Contents/TeXDistVersion") { warn "$0: Possible TeX distribution \"$dir/$potentialtexdir\" found.\n" if ($verbose > 2); $resultdirs{$potentialtexdir}{'location'} = "$dir/$potentialtexdir"; $resultdirs{$potentialtexdir}{'shortname'} = "$potentialtexdir"; if (-e "$dir/$potentialtexdir/Contents/Programs/$arch/tex") { warn "$0: Usable TeX distribution \"$dir/$potentialtexdir\" found.\n" if ($verbose > 2); $resultdirs{$potentialtexdir}{'usable'} = 'native'; $resultdirs{$potentialtexdir}{'path'} = "$dir/$potentialtexdir/Contents/Programs/$arch"; $resultdirs{$potentialtexdir}{'root'} = "$dir/$potentialtexdir/Contents/Root"; } elsif ($arch eq 'i386' and -e "$dir/$potentialtexdir/Contents/Programs/powerpc/tex") { warn "$0: Usable (Rosetta) TeX distribution \"$dir/$potentialtexdir\" found.\n" if ($verbose > 1); $resultdirs{$potentialtexdir}{'usable'} = 'rosetta'; $resultdirs{$potentialtexdir}{'path'} = "$dir/$potentialtexdir/Contents/Programs/powerpc"; $resultdirs{$potentialtexdir}{'root'} = "$dir/$potentialtexdir/Contents/Root"; } else { warn "$0: Unavailable TeX distribution \"$dir/$potentialtexdir\" found.\n" if ($verbose > 1); $resultdirs{$potentialtexdir}{'usable'} = 'no'; $resultdirs{$potentialtexdir}{'root'} = "$dir/$potentialtexdir/Contents/Root"; $resultdirs{$potentialtexdir}{'path'} = undef; } } } closedir( DIRHANDLE); } } return %resultdirs; } sub expand { my $try = shift; my $tryparent = $try; $tryparent =~ s|/[^/]+$||; my $result = `{ cd \"$try\" || cd \"$tryparent\" ; } >/dev/null 2>&1 && /bin/pwd -P`; chomp $result; return $result; }