Menu

[34a99d]: / genxref  Maximize  Restore  History

Download this file

204 lines (167 with data), 6.1 kB

#!/usr/bin/perl
# -*- tab-width: 4 -*-"

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

use strict;
use lib 'lib';
use Fcntl;
use Getopt::Long;
use IO::Handle;
use File::MMagic;

use LXR::Files;
use LXR::Index;
use LXR::Config;
use LXR::Tagger;
use LXR::Common;

my %option;
GetOptions(\%option, "help!", "url=s", "version=s", "allurls!", "allversions!", "reindexall!");

if ($option{'help'}) {

	# this may not be the best way to implement this, but at least it's something
	print <<END_HELP;
Usage: genxref [option ...]

The genxref program automatically generates LXR database cross-reference
tokens for a set of URL configuration blocks and source code versions.  These
are both defined in the lxr.conf configuration file.  Each "URL" is a separate
source tree; LXR separates and identifies these by their URL.  Each "version" is
a different version of the source tree being indexed.  See lxr.conf or
lxr.conf.template for configuring URLs and versions.

Valid options are:
  --help             Print a summary of the options.
  --url=URL          Generate tokens for the given URL configuration block.
  --allurls          Generate tokens for all URL configuration blocks.
  --version=VERSION  Generate tokens for the given version of the code.
  --allversions      Generate tokens for all versions of the code (default).
  --reindexall       Purges existing index data
  
Report bugs at http://sourceforge.net/projects/lxr/.
END_HELP
	exit 0;
}

# TODO: implement --allurls
die("Option --allurls not implemented.  Use --url instead.\n")
  if $option{'allurls'};

die("URL must be specified. Try \"genxref --help\".\n")
  unless $option{'url'};

$config = new LXR::Config($option{'url'});

die("No matching configuration") unless $config->sourceroot;

$files = new LXR::Files($config->sourceroot, $config->sourceparams);
die "Can't create file access object " . $config->sourceroot
  if !defined($files);
$index = new LXR::Index($config->dbname, O_RDWR | O_CREAT);
die "Can't create Index " . $config->dbname if !defined($index);

our $filetype = new File::MMagic();
our %binaryfiles;

my @versions;

if ($option{'allversions'} || !$option{'version'}) {
	@versions = $config->varrange('v');
	die
	  "Option --allversions cannot be used because no versions found automatically.  Use --version=VERSION or fix lxr.conf.\n"
	  if scalar @versions <= 0;
} else {
	@versions = $option{'version'};
}

foreach my $version (@versions) {
	$index->purge($version) if $option{'reindexall'};
	gensearch($version);
	genindex('/', $version);
	genrefs('/', $version);
}

sub genindex {
	my ($pathname, $release) = @_;

	print(STDERR "*** $pathname $release \n");

	if ($pathname =~ m|/$|) {
		map { genindex($pathname . $_, $release) } $files->getdir($pathname, $release);
	} else {
		&LXR::Tagger::processfile($pathname, $release, $config, $files, $index)
		  unless exists $binaryfiles{$pathname};
	}
}

sub genrefs {
	my ($pathname, $release) = @_;

	print(STDERR "### $pathname $release \n");

	if ($pathname =~ m|/$|) {
		map { genrefs($pathname . $_, $release) } $files->getdir($pathname, $release);
	} else {
		&LXR::Tagger::processrefs($pathname, $release, $config, $files, $index)
		  unless exists $binaryfiles{$pathname};
	}
}

sub feedswish {
	my ($pathname, $release, $swish, $filelist) = @_;

	print(STDERR "&&& $pathname $release \n");

	if ($pathname =~ m|/$|) {
		map { feedswish($pathname . $_, $release, $swish, $filelist) }
		  $files->getdir($pathname, $release);
	} else {
		print $filelist "$pathname\n";
		my $contents = $files->getfile($pathname, $release);
		if ($filetype->checktype_contents($contents) =~ m%(text|message)/%
			and length($contents) > 0)
		{
			$swish->print(
				"Path-Name: $pathname\n",
				"Content-Length: " . length($contents) . "\n",
				"Document-Type: TXT\n",
				"\n", $contents
			);
		} else {
			$binaryfiles{$pathname} = 1;
		}
	}
}

sub gensearch {
	my ($release) = @_;
	my $string;

	if ($config->glimpsedir and $config->glimpseindex) {

		# Make sure the directory that the glimpse results go into
		# already exists as glimpse won't work if the directory does
		# not exist
		die $config->glimpsedir . " does not exist"
		  unless -d $config->glimpsedir;
		$string = $config->glimpsedir . "/" . $release;
		mkdir $string;
		system("chmod 755 $string");
		my $glimpse = new IO::Handle;
		my $pid = open($glimpse, "|-");
		if ($pid == 0) {
			exec($config->glimpseindex, "-n", "-o", "-H",
				$config->glimpsedir . "/$release",
				$config->sourceroot . "/" . $release
			);
			print(STDERR "Couldn't exec " . $config->glimpseindex . ": $!\n");
			kill(9, $$);
		}
		$glimpse->close();

		# Need to chmod the glimpse files so everybody can read them.
		$string = $config->glimpsedir . "/" . $release . "/.glimpse\*";
		system("chmod 644 $string");
	}

	if ($config->swishdir and $config->swishbin) {
		my $swish = new IO::Handle;
		die $config->swishdir . " does not exist" unless -d $config->swishdir;
		my $filelist = new IO::File $config->swishdir . "/$release.filenames", "w"
		  or die "can't open $release.filenames for writing";

		# execute swish, as a pipe we can write to

		open($swish,
			    "| "
			  . $config->swishbin
			  . " -S prog -i stdin -v 1 -c swish-e.conf -f "
			  . $config->swishdir . "/"
			  . $release
			  . ".index")
		  or die "Couldn't exec " . $config->swishbin . ": $!\n";

		feedswish("/", $release, $swish, $filelist);

		$swish->close();
		$filelist->close();
	}
}
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.