summaryrefslogtreecommitdiff
path: root/Master/tlpkg/etc
diff options
context:
space:
mode:
authorNorbert Preining <preining@logic.at>2008-10-26 22:25:58 +0000
committerNorbert Preining <preining@logic.at>2008-10-26 22:25:58 +0000
commite529fec5f79d90dd50669f1a5b47a4f061cdaf52 (patch)
tree3e69933ab8c79c33b8b98a6773c81570cc57c052 /Master/tlpkg/etc
parent79efd4658611e6110d8d4ab3ee435d7667c3d828 (diff)
add two patches, see separate email and header of the patches
git-svn-id: svn://tug.org/texlive/trunk@11072 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/etc')
-rw-r--r--Master/tlpkg/etc/auto-backup-feature.patch276
-rw-r--r--Master/tlpkg/etc/use-autopatterns-from-dedicated-tlpsrc-files.patch362
2 files changed, 638 insertions, 0 deletions
diff --git a/Master/tlpkg/etc/auto-backup-feature.patch b/Master/tlpkg/etc/auto-backup-feature.patch
new file mode 100644
index 00000000000..51493fd227b
--- /dev/null
+++ b/Master/tlpkg/etc/auto-backup-feature.patch
@@ -0,0 +1,276 @@
+Implement automatic backups
+Current status:
+ tlmgr option backupdir .....
+sets the defalt backup dir. Now tlmgr update can take another argument
+ tlmgr update --backup ....
+which creates backups in the default backupdir as specified in the TLPDB.
+
+Furthermore, if the tlpdb opion autobackup is set to a integer >= -1 the
+following happens (all of them need the option backupdir set to an
+existing directory)
+ tlmgr option autobackup -1
+ always make backups, keep infinitely many
+ tlmgr option autobackup 0
+ disable automatic backups
+ tlmgr option autobackup N
+ for N > 0 keep N backups
+
+
+So if you want to set up automatic backups, do:
+ mkdir /var/cache/texlive-backups
+ tlmgr option backupdir /var/cache/texlive-backups/
+ tlmgr option autobackup 5
+
+TODO:
+- tlmgr backup clean
+ necessary? can be done by hand. But since the code is here ...
+- testing on windows
+- documentation in POD format
+- testing with .doc/.src args, and with .ARCH packages, no idea
+ what is going on there
+
+
+Index: texmf/scripts/texlive/tlmgr.pl
+===================================================================
+--- texmf/scripts/texlive/tlmgr.pl (revision 11059)
++++ texmf/scripts/texlive/tlmgr.pl (working copy)
+@@ -34,6 +34,16 @@
+ # - always do backups, let the user clean them up manually
+ # Possibly, an operation like 'tlmgr clean' for cleaning old backup could
+ # be great.
++# format for the options:
++# option backupdir
++# option autobackup/TIME
++# where TIME = natural number N -> keep N backups per package
++# or = 0 -> don't do auto backups
++# or = -1 (= +\infty) keep backup indefinitely
++# or = Nd | Nw | Nm -> keeping backups younger then
++# Nd N days
++# Nw N weeks
++# Nm N months
+ # - ordering or collections removal (see below for details)
+ # - (?) removal does not remove created format files from TEXMFSYSVAR
+ # - after install/update show the number of bytes transfered
+@@ -112,7 +122,7 @@
+ "gui-lang=s" => \$opt_gui_lang,
+ "package-logfile=s" => \$opt_packagelogfile,
+ "version" => \$opt_version,
+- "pause" => \$opt_pause,
++ "pause" => \$opt_pause,
+ "h|help|?" => \$opt_help) or pod2usage(2);
+
+ my $action = shift;
+@@ -909,6 +919,7 @@
+ my $opt_list = 0;
+ my $opt_noremove = 0;
+ my $opt_backupdir;
++ my $opt_backup = 0;
+ Getopt::Long::Configure(@getopt_configure_subopts);
+ GetOptions("no-depends" => \$opt_nodepends,
+ "no-depends-at-all" => \$opt_reallynodepends,
+@@ -916,6 +927,7 @@
+ "list" => \$opt_list,
+ "no-remove" => \$opt_noremove,
+ "backupdir=s" => \$opt_backupdir,
++ "backup" => \$opt_backup,
+ "n|dry-run" => \$opt_dry) or pod2usage(2);
+ $opt_nodepends = 1 if $opt_reallynodepends;
+ my $nrupdated = 0;
+@@ -925,6 +937,70 @@
+ my $mediatlpdb = $tlmediasrc->tlpdb;
+ info("update: dry run, no changes will be made\n") if $opt_dry;
+
++ # do backup dir checking now so that we don't run into troubles
++ # later, and exit if that doesn't work
++ if ($opt_backupdir) {
++ $opt_backupdir = abs_path($opt_backupdir);
++ if (! -d $opt_backupdir) {
++ tlwarn("Argument for --backupdir must be an existing directory. Terminating.\n");
++ exit 1;
++ }
++ }
++
++ my $autobackup = 0;
++ # check for the tlpdb option autobackup, and if present and true (!= 0)
++ # assume we are doing backups
++ if (!$opt_backup) {
++ $autobackup = $localtlpdb->option("autobackup");
++ if ($autobackup) {
++ # check the format, we currently allow only natural numbers, and -1
++ if ($autobackup eq "-1") {
++ debug ("Automatic backups activated, keeping \\infty backups.\n");
++ $opt_backup = 1;
++ } elsif ($autobackup eq "0") {
++ debug ("Automatic backups disabled.\n");
++ } elsif ($autobackup =~ m/^[0-9]+$/) {
++ debug ("Automatic backups activated, keeping $autobackup backups.\n");
++ $opt_backup = 1;
++ } else {
++ tlwarn ("Option autobackup can only be an integer >= -1.\n");
++ tlwarn ("Disabling auto backups.\n");
++ $localtlpdb->option("autobackup", 0);
++ $autobackup = 0;
++ }
++ }
++ }
++
++ # cmd line --backup, we check for --backupdir, and if that is not given
++ # we try to get the default from the tlpdb. If that doesn't work, exit.
++ if ($opt_backup) {
++ my $diebackupdir = 0;
++ if (!$opt_backupdir) {
++ $opt_backupdir = $localtlpdb->option("backupdir");
++ if ($opt_backupdir) {
++ # check again:
++ $opt_backupdir = abs_path($opt_backupdir);
++ $diebackupdir = 1 if (! -d $opt_backupdir);
++ } else {
++ # not set in the tlpdb, and not set on cmd line, but asked for
++ # --backup
++ $diebackupdir = 1;
++ }
++ }
++ # no else branch necessary, we already checked that --backupdir if
++ # given is ok, see above
++ if ($diebackupdir) {
++ tlwarn("You have asked for backups, but the backup directory as specified\n");
++ tlwarn("in the local TLPDB or the cmd line does not exists, exiting.\n");
++ exit 1;
++ }
++ }
++
++ # finally, if we have --backupdir, but no --backup, just enable it
++ $opt_backup = 1 if $opt_backupdir;
++
++ debug("Doing backups to $opt_backupdir\n") if $opt_backup;
++
+ # these two variables are used throughout this function
+ my $root = $localtlpdb->root;
+ my $temp = "$root/temp";
+@@ -1103,19 +1179,18 @@
+ if ($opt_list) {
+ info("$pkg: local: $rev, source: $mediarev\n");
+ } else {
+- # first remove the package, then reinstall it
+- # this way we get rid of useless files
+- # force the deinstallation since we will reinstall it
+- if ($opt_backupdir && !$opt_dry) {
+- $opt_backupdir = abs_path($opt_backupdir);
+- if (! -d $opt_backupdir) {
+- tlwarn("backupdir argument must be an existing directory!\n");
+- } else {
+- $tlp->make_container("lzma", $root,
+- $opt_backupdir, "${pkg}.r" . $tlp->revision);
+- $unwind_package = "$opt_backupdir/${pkg}.r" . $tlp->revision . ".tar.lzma";
++ if ($opt_backup && !$opt_dry) {
++ $tlp->make_container("lzma", $root,
++ $opt_backupdir, "${pkg}.r" . $tlp->revision);
++ $unwind_package =
++ "$opt_backupdir/${pkg}.r" . $tlp->revision . ".tar.lzma";
++
++ if ($autobackup) {
++ # in case we do auto backups we remove older backups
++ clear_old_backups($pkg, $opt_backupdir, $autobackup);
+ }
+ }
++
+ if (win32() && ($pkg =~ m/$WinSpecialUpdatePackagesRegexp/)) {
+ add_win32_updater($mediatlp, $opt_dry);
+ } else {
+@@ -1142,6 +1217,10 @@
+ $remove_unwind_container = 1;
+ $unwind_package = "$fullname";
+ }
++ # first remove the package, then reinstall it
++ # this way we get rid of useless files
++ # force the deinstallation since we will reinstall it
++ #
+ # the remove_package should also remove empty dirs in case
+ # a dir is changed into a file
+ merge_into(\%ret, &remove_package($pkg, $localtlpdb, 1));
+@@ -1157,7 +1236,7 @@
+ # dirs from the new package before re-installing the old one.
+ # TODO
+ logpackage("failed update: $pkg ($rev -> $mediarev)");
+- tlwarn("\n\nInstallation of new version of $pkg did fail, trying to unwind!\n");
++ tlwarn("\n\nInstallation of new version of $pkg did fail, trying to unwind.\n");
+ if (win32()) {
+ # win32 is notorious for not releasing a file immediately
+ # we experienced permission denied errors
+@@ -1383,7 +1462,15 @@
+ print "Install documentation files: ", ($localtlpdb->option_install_docfiles ? "yes": "no"), "\n";
+ print "Install source files: ", ($localtlpdb->option_install_srcfiles ? "yes": "no"), "\n";
+ } else {
+- warn "Setting other options currently not supported, please edit texlive.tlpdb!";
++ my $val = shift @ARGV;
++ if (defined($val)) {
++ print "Setting option $what to $val.\n";
++ $localtlpdb->option($what,$val);
++ $localtlpdb->save;
++ } else {
++ print "Option $what = ", $localtlpdb->option($what), "\n";;
++ }
++ #warn "Setting other options currently not supported, please edit texlive.tlpdb!";
+ }
+ return;
+ }
+@@ -1937,6 +2024,32 @@
+ }
+
+
++# clear the backup dir for $pkg and keep only $autobackup packages
++sub clear_old_backups
++{
++ my ($pkg, $opt_backupdir, $autobackup) = @_;
++ # keep arbitrary many backups
++ return if ($autobackup == -1);
++
++ opendir (DIR, $opt_backupdir) || die "opendir($opt_backupdir) failed: $!";
++ my @dirents = readdir (DIR);
++ closedir (DIR) || warn "closedir($opt_backupdir) failed: $!";
++ my @backups;
++ for my $dirent (@dirents) {
++ next if (-d $dirent);
++ next if ($dirent !~ m/^$pkg\.r([0-9]+)\.tar\.lzma$/);
++ push @backups, $1;
++ }
++ my $i = 1;
++ for my $e (reverse sort {$a <=> $b} @backups) {
++ if ($i > $autobackup) {
++ unlink("$opt_backupdir/$pkg.r$e.tar.lzma");
++ }
++ $i++;
++ }
++}
++
++
+ #
+ # return all the directories from which all content will be removed
+ #
+Index: tlpkg/TeXLive/TLPDB.pm
+===================================================================
+--- tlpkg/TeXLive/TLPDB.pm (revision 11059)
++++ tlpkg/TeXLive/TLPDB.pm (working copy)
+@@ -49,6 +49,7 @@
+ $tlpdb->config_container_format;
+ $tlpdb->config_release;
+ $tlpdb->config_revision;
++ $tlpdb->option($key, [$value]);
+
+ TeXLive::TLPDB->listdir([$dir]);
+ $tlpdb->generate_listfiles([$destdir]);
+@@ -955,6 +956,14 @@
+ return;
+ }
+
++sub option {
++ my $self = shift;
++ my $key = shift;
++ if (@_) { $self->_set_option_value($key, shift); }
++ return $self->_option_value($key);
++}
++# TODO the above function should be used in the functions below as
++# far as possible ...
+ sub option_available_architectures {
+ my $self = shift;
+ if (@_) { $self->_set_option_value("available_architectures","@_"); }
diff --git a/Master/tlpkg/etc/use-autopatterns-from-dedicated-tlpsrc-files.patch b/Master/tlpkg/etc/use-autopatterns-from-dedicated-tlpsrc-files.patch
new file mode 100644
index 00000000000..f29aa49b158
--- /dev/null
+++ b/Master/tlpkg/etc/use-autopatterns-from-dedicated-tlpsrc-files.patch
@@ -0,0 +1,362 @@
+
+This patch adds the ability to change the auto generated patterns by
+adding tlpsrc files named
+ 00texlive.autopatterns.<CATEGORY>.tlpsrc
+and within these files the relevant src/bin/doc/run patterns.
+
+This patch adds in addition the tlpsrc autopattern files
+ 00texlive.autopatterns.Package.tlpsrc
+ 00texlive.autopatterns.Documentation.tlpsrc
+to get the exact same behaviour as before.
+
+Warning: This change will make the description for maintaining separate
+repositories a bit outdated, since now also these autopattern files
+have to be added, or patterns themselves have to be specified.
+
+
+Index: tlpkg/bin/tlpsrc2tlpdb
+===================================================================
+--- tlpkg/bin/tlpsrc2tlpdb (revision 11059)
++++ tlpkg/bin/tlpsrc2tlpdb (working copy)
+@@ -63,9 +63,43 @@
+ $tlc = TeXLive::TeXCatalogue->new ("location" => $opt_catalogue);
+ }
+
++ # get the default patterns
++ my $tlpsrc_dir = "$opt_master/tlpkg/tlpsrc";
++ chdir ($tlpsrc_dir) || die "chdir($tlpsrc_dir) failed: $!";
++ my @autopatternfiles = glob ("00texlive.autopatterns.*.tlpsrc");
++ my %autopatterns;
++ for my $ap (@autopatternfiles) {
++ (my $cat = $ap) =~ s/^00texlive\.autopatterns\.(.*)\.tlpsrc$/$1/;
++ my $tlsrc = new TeXLive::TLPSRC;
++ $tlsrc->from_file ($ap);
++ push @{$autopatterns{$cat}{"bin"}}, $tlsrc->binpatterns
++ if $tlsrc->binpatterns;
++ push @{$autopatterns{$cat}{"src"}}, $tlsrc->srcpatterns
++ if $tlsrc->srcpatterns;
++ push @{$autopatterns{$cat}{"doc"}}, $tlsrc->docpatterns
++ if $tlsrc->docpatterns;
++ push @{$autopatterns{$cat}{"run"}}, $tlsrc->runpatterns
++ if $tlsrc->runpatterns;
++ }
++
++ for my $cat (keys %autopatterns) {
++ debug ("Category $cat\n");
++ for my $d (@{$autopatterns{$cat}{"bin"}}) {
++ debug ("Found auto bin pattern $d\n");
++ }
++ for my $d (@{$autopatterns{$cat}{"src"}}) {
++ debug ("Found auto src pattern $d\n");
++ }
++ for my $d (@{$autopatterns{$cat}{"doc"}}) {
++ debug ("Found auto doc pattern $d\n");
++ }
++ for my $d (@{$autopatterns{$cat}{"run"}}) {
++ debug ("Found auto run pattern $d\n");
++ }
++ }
++
+ # if we're regenerating the whole thing, get all our tlpsrc files.
+ if ($opt_all) {
+- my $tlpsrc_dir = "$opt_master/tlpkg/tlpsrc";
+ chdir ($tlpsrc_dir) || die "chdir($tlpsrc_dir) failed: $!";
+ @ARGV = glob ("*.tlpsrc");
+ }
+@@ -82,11 +116,16 @@
+ my $tldb = TeXLive::TLPDB->new;
+ my $src_count = 0;
+ foreach my $f (@ARGV) {
++ next if ($f =~ m/^00texlive\.autopatterns/);
+ $src_count++ if $opt_all;
+
+ my $tlsrc = new TeXLive::TLPSRC;
+ $tlsrc->from_file ($f);
+- my $tlp = $tlsrc->make_tlpobj ($tltree);
++ my $patternref;
++ if (defined($autopatterns{$tlsrc->category})) {
++ $patternref = $autopatterns{$tlsrc->category};
++ }
++ my $tlp = $tlsrc->make_tlpobj ($tltree, $autopatterns{$tlsrc->category});
+
+ (my $base_f = $f) =~ s/\.tlpsrc$//;
+ warn "$f: package name " . $tlp->name . " does not match filename\n"
+Index: tlpkg/tlpsrc/00texlive.autopatterns.Package.tlpsrc
+===================================================================
+--- tlpkg/tlpsrc/00texlive.autopatterns.Package.tlpsrc (revision 0)
++++ tlpkg/tlpsrc/00texlive.autopatterns.Package.tlpsrc (revision 0)
+@@ -0,0 +1,17 @@
++name 00texlive.autopatterns.package
++category Package
++shortdesc Defines the automatically generated patterns for category Package
++runpattern t texmf-dist bibtex %NAME%
++runpattern t texmf-dist context %NAME%
++runpattern t texmf-dist dvips %NAME%
++runpattern t texmf-dist fonts %NAME%
++runpattern t texmf-dist makeindex %NAME%
++runpattern t texmf-dist metafont %NAME%
++runpattern t texmf-dist metapost %NAME%
++runpattern t texmf-dist mft %NAME%
++runpattern t texmf-dist omega %NAME%
++runpattern t texmf-dist scripts %NAME%
++runpattern t texmf-dist tex %NAME%
++runpattern t texmf-dist vtex %NAME%
++srcpattern t texmf-dist source %NAME%
++docpattern t texmf-dist doc %NAME%
+Index: tlpkg/tlpsrc/00texlive.autopatterns.Documentation.tlpsrc
+===================================================================
+--- tlpkg/tlpsrc/00texlive.autopatterns.Documentation.tlpsrc (revision 0)
++++ tlpkg/tlpsrc/00texlive.autopatterns.Documentation.tlpsrc (revision 0)
+@@ -0,0 +1,5 @@
++name 00texlive.autopatterns.documentation
++category Documentation
++shortdesc Defines the automatically generated patterns for category Documentation
++srcpattern t texmf-doc source %NAME%
++docpattern t texmf-doc doc %NAME%
+Index: tlpkg/TeXLive/TLPSRC.pm
+===================================================================
+--- tlpkg/TeXLive/TLPSRC.pm (revision 11059)
++++ tlpkg/TeXLive/TLPSRC.pm (working copy)
+@@ -201,7 +201,11 @@
+ #
+ sub make_tlpobj
+ {
+- my ($self,$tltree) = @_;
++ my ($self,$tltree,$defaultpatterns) = @_;
++ my %patterns;
++ if (defined($defaultpatterns)) {
++ %patterns = %{$defaultpatterns};
++ }
+ my $tlp = TeXLive::TLPOBJ->new;
+ $tlp->name($self->name);
+ $tlp->category($self->category);
+@@ -212,124 +216,67 @@
+ $tlp->depends(@{$self->{'depends'}}) if (defined($self->{'depends'}));
+ $tlp->revision(0);
+ my $filemax;
+- my $usedefault = 1;
++ my $usedefault;
+ my @allpospats;
+ my @allnegpats;
++ my $pkgname = $self->name;
+ #
+- # runpatterns
++ # src/run/doc patterns
+ #
+- foreach my $p (@{$self->{'runpatterns'}}) {
+- if ($p =~ m/^\+!(.*)$/) {
+- push @allnegpats, $1;
+- } elsif ($p =~ m/^\+(.*)$/) {
+- push @allpospats, $1;
+- } elsif ($p =~ m/^!(.*)$/) {
+- push @allnegpats, $1;
+- $usedefault = 0;
+- } else {
+- push @allpospats, $p;
+- $usedefault = 0;
++ # WARNING WARNING WARNING
++ # the "bin" must be last since we drop through for further dealing
++ # with specialities of the bin patterns!!!!
++ for my $pattype (qw/src run doc bin/) {
++ @allpospats = ();
++ @allnegpats = ();
++ $usedefault = 1;
++ foreach my $p (@{$self->{${pattype} . 'patterns'}}) {
++ if ($p =~ m/^\+!(.*)$/) {
++ push @allnegpats, $1;
++ } elsif ($p =~ m/^\+(.*)$/) {
++ push @allpospats, $1;
++ } elsif ($p =~ m/^!(.*)$/) {
++ push @allnegpats, $1;
++ $usedefault = 0;
++ } else {
++ push @allpospats, $p;
++ $usedefault = 0;
++ }
+ }
+- }
+- if ($usedefault) {
+- if ($self->category eq "Package") {
+- foreach my $md (qw/bibtex context dvips fonts makeindex metafont
+- metapost mft omega scripts tex vtex/) {
+- # mark the default pattern with a leading * so that
+- # we do not warn a missing hit on a default pattern
+- push @allpospats, "*t texmf-dist $md $self->{'name'}";
++ if ($usedefault && defined($patterns{$pattype})) {
++ for my $p (@{$patterns{$pattype}}) {
++ # replace the string %NAME% with the actual package name
++ # we have to make a copy of $p otherwise we change it in the
++ # hash once and for all
++ (my $pp = $p) =~ s/%NAME%/$pkgname/g;
++ # sort through the patterns, and make sure that * are added to
++ # tag the default patterns
++ if ($pp =~ m/^!(.*)$/) {
++ push @allnegpats, "*$1";
++ } else {
++ push @allpospats, "*$pp";
++ }
+ }
+ }
+- }
+- foreach my $p (@allpospats) {
+- $self->_do_normal_pattern($p,$tlp,$tltree,'run');
+- }
+- foreach my $p (@allnegpats) {
+- $self->_do_normal_pattern($p,$tlp,$tltree,'run',1);
+- }
+- #
+- # srcpatterns
+- #
+- @allpospats = ();
+- @allnegpats = ();
+- $usedefault = 1;
+- foreach my $p (@{$self->{'srcpatterns'}}) {
+- if ($p =~ m/^\+!(.*)$/) {
+- push @allnegpats, $1;
+- } elsif ($p =~ m/^\+(.*)$/) {
+- push @allpospats, $1;
+- } elsif ($p =~ m/^!(.*)$/) {
+- push @allnegpats, $1;
+- $usedefault = 0;
+- } else {
+- push @allpospats, $p;
+- $usedefault = 0;
++ # at this point we do NOT do the actual pattern matching for
++ # bin patterns, since we have some specialities to do
++ last if ($pattype eq "bin");
++ # for all other patterns we create the list and add the files
++ foreach my $p (@allpospats) {
++ ddebug("pos pattern $p\n");
++ $self->_do_normal_pattern($p,$tlp,$tltree,$pattype);
+ }
+- }
+- if ($usedefault) {
+- # default patterns for srcfiles
+- if ($self->category eq "Package") {
+- push @allpospats, "*t texmf-dist source $self->{'name'}";
+- } elsif ($self->category eq "Documentation") {
+- push @allpospats, "*t texmf-doc source $self->{'name'}";
++ foreach my $p (@allnegpats) {
++ ddebug("neg pattern $p\n");
++ $self->_do_normal_pattern($p,$tlp,$tltree,$pattype,1);
+ }
+ }
+- foreach my $p (@allpospats) {
+- $self->_do_normal_pattern($p,$tlp,$tltree,'src');
+- }
+- foreach my $p (@allnegpats) {
+- $self->_do_normal_pattern($p,$tlp,$tltree,'src',1);
+- }
+ #
+- # docpatterns
+- #
+- @allpospats = ();
+- @allnegpats = ();
+- $usedefault = 1;
+- foreach my $p (@{$self->{'docpatterns'}}) {
+- if ($p =~ m/^\+!(.*)$/) {
+- push @allnegpats, $1;
+- } elsif ($p =~ m/^\+(.*)$/) {
+- push @allpospats, $1;
+- } elsif ($p =~ m/^!(.*)$/) {
+- push @allnegpats, $1;
+- $usedefault = 0;
+- } else {
+- push @allpospats, $p;
+- $usedefault = 0;
+- }
+- }
+- if ($usedefault) {
+- # default patterns for docfiles
+- if ($self->category eq "Package") {
+- push @allpospats, "*t texmf-dist doc $self->{'name'}";
+- } elsif ($self->category eq "Documentation") {
+- push @allpospats, "*t texmf-doc doc $self->{'name'}";
+- }
+- }
+- foreach my $p (@allpospats) {
+- $self->_do_normal_pattern($p,$tlp,$tltree,'doc');
+- }
+- foreach my $p (@allnegpats) {
+- $self->_do_normal_pattern($p,$tlp,$tltree,'doc',1);
+- }
+- #
+ # binpatterns
+ #
+- # no default patterns for binfiles
+- @allpospats = ();
+- @allnegpats = ();
+- foreach my $p (@{$self->{'binpatterns'}}) {
+- if ($p =~ m/^\+!(.*)$/) {
+- push @allnegpats, $1;
+- } elsif ($p =~ m/^\+(.*)$/) {
+- push @allpospats, $1;
+- } elsif ($p =~ m/^!(.*)$/) {
+- push @allnegpats, $1;
+- } else {
+- push @allpospats, $p;
+- }
+- }
++ # mind that @allpospats and @allnegpats have already been set up
++ # in the above loop. We only have to deal with the specialities of
++ # the bin patterns
+ foreach my $p (@allpospats) {
+ my @todoarchs = $tltree->architectures;
+ my $finalp = $p;
+@@ -472,17 +419,29 @@
+ sub srcpatterns {
+ my $self = shift;
+ if (@_) { @{ $self->{'srcpatterns'} } = @_ }
+- return @{ $self->{'srcpatterns'} };
++ if (defined($self->{'srcpatterns'})) {
++ return @{ $self->{'srcpatterns'} };
++ } else {
++ return;
++ }
+ }
+ sub docpatterns {
+ my $self = shift;
+ if (@_) { @{ $self->{'docpatterns'} } = @_ }
+- return @{ $self->{'docpatterns'} };
++ if (defined($self->{'docpatterns'})) {
++ return @{ $self->{'docpatterns'} };
++ } else {
++ return;
++ }
+ }
+ sub binpatterns {
+ my $self = shift;
+ if (@_) { @{ $self->{'binpatterns'} } = @_ }
+- return @{ $self->{'binpatterns'} };
++ if (defined($self->{'binpatterns'})) {
++ return @{ $self->{'binpatterns'} };
++ } else {
++ return;
++ }
+ }
+ sub depends {
+ my $self = shift;
+@@ -492,7 +451,11 @@
+ sub runpatterns {
+ my $self = shift;
+ if (@_) { @{ $self->{'runpatterns'} } = @_ }
+- return @{ $self->{'runpatterns'} };
++ if (defined($self->{'runpatterns'})) {
++ return @{ $self->{'runpatterns'} };
++ } else {
++ return;
++ }
+ }
+ sub executes {
+ my $self = shift;
+@@ -746,7 +709,9 @@
+
+ If a given pattern section is empty or B<all> the provided patterns have
+ the prefix C<+> (e.g., C<+f ...>), then the following patterns, listed
+-by type are I<automatically> added at expansion time:
++by type are I<automatically> added at expansion time. Note that this list
++is not definitive, but is taken from the patterns of tlpsrc files
++named C<00texlive.autopatterns.>I<Category>C<.tlpsrc>.
+
+ =over 4
+