diff options
author | Satoshi Asami <asami@FreeBSD.org> | 1998-12-12 07:41:49 +0000 |
---|---|---|
committer | Satoshi Asami <asami@FreeBSD.org> | 1998-12-12 07:41:49 +0000 |
commit | df0519ed9306e1922fe08591dbbdeab3d5efe70a (patch) | |
tree | 8bdf5c8c5849d732c857779216154053b783c341 /Tools/make_index | |
parent | (0) Fast INDEX generation. Only print out the directory name and (diff) |
Fast INDEX generation. See bsd.port.mk rev. 1.300 for details.
Submitted by: steve
Notes
Notes:
svn path=/head/; revision=15302
Diffstat (limited to 'Tools/make_index')
-rw-r--r-- | Tools/make_index | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/Tools/make_index b/Tools/make_index new file mode 100644 index 000000000000..aa465b820e8a --- /dev/null +++ b/Tools/make_index @@ -0,0 +1,117 @@ +#!/usr/bin/perl +# +# $Id$ +# +# Written to speed-up INDEX file generation. The new scheme +# basically visits each port once and writes out each port's +# build-depends and run-depends as a list of directories. This +# script goes back in and maps the directories back to pkgnames, +# fixes up the build-depends and run-depends list, and writes +# out the new INDEX file. + +# Helper function to map a directory to a pkgname. +sub by_path { + my $name = shift; + + # If a direct mapping exists, then use it. + return $by_path{$name} if (defined $by_path{$name}); + + # Make sure we have /usr/ports at the beginning. + $name =~ s!^$pwd!/usr/ports!o; + return $by_path{$name} if (defined $by_path{$name}); + + # Collapse all the '..' sequences. + my @f = split('/', $name), @p = (); + foreach (@f) { (/\.\./) ? pop(@p) : push(@p, $_); } + return $by_path{join('/', @p)}; +} + +# This routine replaces what used to be the time-consuming +# recursive 'depends-list' and 'package-depends' targets. +sub recurse { + my $pkg = shift(@_); + return if $pkg->{checked}; + + # build-depends = build-depends + recursive list of run-depends + # for each build-depends + my @deps = (); + foreach $name (@{$pkg->{bdep}}) { + recurse($index{$name}); + push(@deps, @{$index{$name}->{rdep}}); + } + $pkg->{bdep} = uniqify(@{$pkg->{bdep}}, @deps); + + # same as above except for run-depends this time + @deps = (); + foreach $name (@{$pkg->{rdep}}) { + recurse($index{$name}); + push(@deps, @{$index{$name}->{rdep}}); + } + $pkg->{rdep} = uniqify(@{$pkg->{rdep}}, @deps); + $pkg->{checked} = 1; +} + +# Given one or more lists as arguments return the set +# of unique elements among them. +sub uniqify { + my %seen = (); + my @unique = grep {! $seen{$_}++} (@_); + return \@unique; +} + +# Save where we are so that we can map all directories formed +# from ${PORTSDIR} to their canonical location '/usr/ports/...'. +chomp($pwd = `pwd`); + +# Read each line of output generated by the 'index' target. +while (<>) { + chomp; + my @f = split(/\|/); + + # Force to canonical form. + $f[1] =~ s!^$pwd!/usr/ports!o; + $f[4] =~ s!^$pwd!/usr/ports!o; + + # Save directory -> pkgname relationship. + # Note: $f[0] gets clobbered by the splice below so we'll save + # it to a new $name first. + $by_path{$f[1]} = $name = $f[0]; + + # Create a hash table of the infomation we need about this port. + my $pkg = { + 'bdep' => [split(/ /, $f[7])], + 'rdep' => [split(/ /, $f[8])], + 'text' => join('|', splice(@f, 0, 7)) + }; + $index{$name} = $pkg; + + # This is a cheap way of preserving the order of the entries. + push(@names, $name); +} + +# For each port perform the mapping between directory and pkgnames. +foreach $name (keys %index) { + my $pkg = $index{$name}; + # first the build dependencies + if (@{$pkg->{bdep}}) { + my @bdep = map { by_path($_) } @{$pkg->{bdep}}; + $pkg->{bdep} = \@bdep; + } + # and now the run dependencies + if (@{$pkg->{rdep}}) { + my @rdep = map { by_path($_) } @{$pkg->{rdep}}; + $pkg->{rdep} = \@rdep; + } +} + +# With all that done we're finally ready to write out the new +# INDEX file one port at a time. +foreach $name (@names) { + my $pkg = $index{$name}; + recurse($pkg); + print "$pkg->{text}|"; + print join(' ', sort(@{$pkg->{bdep}})) if @{$pkg->{bdep}}; + print "|"; + print join(' ', sort(@{$pkg->{rdep}})) if @{$pkg->{rdep}}; + print "\n"; +} |