#!/usr/bin/env perl # $Id$ # Copyright 2007-2020 Karl Berry. # This file is licensed under the GNU General Public License version 2 # or any later version. # # Return all files for a given TeX Live package, or package name(s) for # a given set of files. our $mydir; BEGIN { $^W = 1; ($mydir = $0) =~ s,/[^/]*$,,; unshift (@INC, "$mydir/.."); } use strict; use TeXLive::TLConfig qw/$RelocPrefix $RelocTree/; use TeXLive::TLPDB; use Pod::Usage; use Getopt::Long; use TeXLive::TLUtils; our $FILE; our %DB_BY_FILE; # used privately below. our @opt_pkgof = (); my $opt_help = 0; my $opt_fullpath = 0; TeXLive::TLUtils::process_logging_options (); GetOptions ("pkgof=s" => \@opt_pkgof, "fullpath" => \$opt_fullpath, "help|?" => \$opt_help) or pod2usage (2); pod2usage ("-exitstatus" => 0, "-verbose" => 2) if $opt_help; exit (&main ()); sub main { my $Master = "$mydir/../.."; # xx TLPDB should default my $tlpdb_path = "$Master/$TeXLive::TLConfig::DatabaseLocation"; if (@opt_pkgof) { return &do_pkgof ($tlpdb_path, @opt_pkgof); } elsif (@ARGV != 1) { die "$0: expected exactly one package name; try --help if you need it.\n"; } # report files in given package. my $pkg = $ARGV[0]; my $tlpdb = TeXLive::TLPDB->new (root => $Master); if (! defined $tlpdb) { die "$0: no texlive.tlpdb under $Master, goodbye"; } my $obj = $tlpdb->get_package ($pkg); die "$0: no TeX Live package named $pkg in $Master.\n" if ! $obj; my @files = $obj->all_files; if ($obj->relocated) { for (@files) { s:^$RelocPrefix/:$RelocTree/:; } } print "$_\n" foreach @files; return 0; } # Report which package(s) the given files belong to. # sub do_pkgof { my ($tlpdb,@files) = @_; @files = split (/\s/, "@files"); for my $f (@files) { my $pkg = &find_pkg_of_file ($tlpdb, $f); printf "%s\t%s\n", $pkg || "-", $f; } return 0; } # return package to which FILE belongs, or undef. # # If $opt_fullpath is not set, any directory part of FILE is stripped. # If there are multiple packages holding files by the same name, all are # returned, space-separated. If $opt_fullpath is set, we compare the # whole path as given. # # We read the raw tlpdb file instead of using, e.g., TLPDB::find_file # which is slow, but it's probably still a mistake. # sub find_pkg_of_file { my ($tlpdb,$file) = @_; if (! keys %DB_BY_FILE) { local *FILE; open (FILE, $tlpdb) || die "open($tlpdb) failed: $!"; my $pkg; while () { chomp; if (/^name /) { (undef,$pkg) = split (/ /); } elsif (/^ /) { # we carefully designed the format so that the only lines with # leading spaces are the files. # By default we take only the basename, unless $opt_fullpath my $dbfile = $_; if ($opt_fullpath) { $dbfile =~ s,^ ,,; } else { $dbfile =~ s,^.*/,,; } $DB_BY_FILE{$dbfile} .= "$pkg "; } } close (FILE) || warn "close($tlpdb) failed: $!"; } if (!$opt_fullpath) { $file =~ s,^.*/,,; # take basename } # strict stupidity my $ret = exists $DB_BY_FILE{$file} ? substr ($DB_BY_FILE{$file}, 0, -1) : ""; return $ret; # omit final space, } __END__ =head1 NAME tlpfiles - list files contained in a TeX Live package, or vice versa =head1 SYNOPSIS tlpfiles [I