aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cgi-bin/css/lxrng.css6
-rw-r--r--cgi-bin/js/lxrng-funcs.js47
-rwxr-xr-xcgi-bin/lxr66
-rw-r--r--lib/LXRng/Context.pm16
-rw-r--r--lib/LXRng/Index/DBI.pm117
-rw-r--r--lib/LXRng/Index/Pg.pm3
-rw-r--r--lib/LXRng/Index/PgBatch.pm2
-rw-r--r--lib/LXRng/Lang/C.pm3
-rw-r--r--lib/LXRng/Markup/File.pm2
-rw-r--r--lib/LXRng/Repo/Git.pm17
-rw-r--r--lib/LXRng/Search/Xapian.pm29
-rwxr-xr-xlxr-genxref127
-rw-r--r--lxrng.conf-dist2
-rw-r--r--tmpl/header.tt218
-rw-r--r--tmpl/prefs.tt213
-rw-r--r--tmpl/search_result.tt26
16 files changed, 335 insertions, 139 deletions
diff --git a/cgi-bin/css/lxrng.css b/cgi-bin/css/lxrng.css
index 9a47d80..637c774 100644
--- a/cgi-bin/css/lxrng.css
+++ b/cgi-bin/css/lxrng.css
@@ -273,6 +273,12 @@ div.progress {
font-style: italic;
}
+div.error {
+ font-weight: bold;
+ font-style: italic;
+ color: #E04040;
+}
+
form {
display: inline;
}
diff --git a/cgi-bin/js/lxrng-funcs.js b/cgi-bin/js/lxrng-funcs.js
index d7c9be8..614879e 100644
--- a/cgi-bin/js/lxrng-funcs.js
+++ b/cgi-bin/js/lxrng-funcs.js
@@ -74,12 +74,18 @@ var pending_ver;
var pending_line;
function ajax_nav() {
- var file = this.href.replace(/^(http:.*?lxr\/[+]ajax\/|)/, '');
- // alert(loaded_file + ' - ' + file);
+ var file = this.href.replace(/^(http:.*?\/.*?[+][*]\/|)/, '');
load_file(loaded_tree, file, loaded_ver, '');
return false;
}
+function ajax_jumpto_line() {
+ location.hash = location.hash.replace(/\#L\d+$/, '') +
+ this.href.replace(/.*(\#L\d+)$/, '$1');
+ check_hash_navigation();
+ return false;
+}
+
function ajax_prefs() {
if (use_ajax_navigation) {
var full_path = location.href.split(/#/)[0];
@@ -102,12 +108,14 @@ function check_hash_navigation() {
if (location.hash.replace(/\#L\d+$/, '') ==
loaded_hash.replace(/\#L\d+$/, ''))
{
- var l = location.hash.replace(/.*(\#L\d+)$/, '$1');
+ var l = location.hash.replace(/.*#(L\d+)$/, '$1');
var a = document.getElementById(l);
if (l && a) {
- a.name = location.hash;
+ a.name = location.hash.replace(/^\#/, '');
location.hash = a.name;
+ loaded_hash = location.hash;
}
+ hash_check = setTimeout('check_hash_navigation()', 50);
}
else {
// alert(location.hash + ' / ' + loaded_hash);
@@ -150,6 +158,7 @@ function load_file(tree, file, ver, line) {
function load_file_finalize(content) {
var res = document.getElementById('content');
+ res.innerHTML = 'Done';
res.innerHTML = content;
var head = document.getElementById('current_path');
head.innerHTML = '<a class=\"fref\" href=\".\">' + pending_tree + '</a>';
@@ -165,11 +174,11 @@ function load_file_finalize(content) {
}
document.title = 'LXR ' + pending_tree + '/' + pending_file;
- var full_path = pending_tree;
+ var full_tree = pending_tree;
if (pending_ver) {
- full_path = full_path + '+' + pending_ver;
+ full_tree = full_tree + '+' + pending_ver;
}
- full_path = full_path + '/' + pending_file.replace(/^\/?/, '');
+ var full_path = full_tree + '/' + pending_file.replace(/^\/?/, '');
var pre = document.getElementById('file_contents');
if (pre && pre.className == 'partial') {
@@ -178,6 +187,9 @@ function load_file_finalize(content) {
[load_file_finalize]);
}
+ if (hash_check) {
+ clearTimeout(hash_check);
+ }
if (pending_line) {
var anchor = document.getElementById('L' + pending_line);
if (anchor) {
@@ -197,18 +209,18 @@ function load_file_finalize(content) {
loaded_tree = pending_tree;
loaded_file = pending_file;
loaded_ver = pending_ver;
- if (hash_check) {
- clearTimeout(hash_check);
- }
hash_check = setTimeout('check_hash_navigation()', 50);
+// return;
+// TODO: This really takes oodles of time. Consider coding into html.
var i;
for (i = 0; i < document.links.length; i++) {
- if (document.links[i].className == 'fref' ||
- document.links[i].className == 'line')
- {
+ if (document.links[i].className == 'fref') {
document.links[i].onclick = ajax_nav;
}
+ else if (document.links[i].className == 'line') {
+ document.links[i].onclick = ajax_jumpto_line;
+ }
else if (document.links[i].className == 'sref' ||
document.links[i].className == 'falt')
{
@@ -243,8 +255,10 @@ function load_content_finalize(content) {
function update_version(verlist, base_url, tree, defversion, path) {
if (use_ajax_navigation) {
var file = location.hash.replace(/^[^\/]*\//, '');
+ var line = file.replace(/.*\#L(\d+)/, '$1');
+ file = file.replace(/\#L\d+$/, '');
- load_file(loaded_tree, file, verlist.value, '');
+ load_file(loaded_tree, file, verlist.value, line);
return false;
}
else {
@@ -279,7 +293,10 @@ function ajax_lookup_anchor(event, anchor) {
if (!anchor)
anchor = this;
- lookup = anchor.href.replace(/^(http:.*?lxr\/[+]ajax\/|)/, '');
+ // TODO: Fix
+// lookup = anchor.href.replace(/^(http:.*?lxr\/[+]ajax\/|)/, '');
+ lookup = anchor.href.replace(/^(http:.*?\/.*?[+][*]\/|)/, '');
+
var lvar = document.getElementById('ajax_lookup');
lvar.value = lookup;
diff --git a/cgi-bin/lxr b/cgi-bin/lxr
index cda9179..a0c0f6e 100755
--- a/cgi-bin/lxr
+++ b/cgi-bin/lxr
@@ -4,7 +4,6 @@ use strict;
use FindBin;
use lib "$FindBin::Bin/../lib";
-use lib '/home/argggh/www/lxrng/_deps/share/perl/5.8.4';
use CGI::Carp qw(fatalsToBrowser);
use IO::Handle;
@@ -51,6 +50,11 @@ sub print_markedup_file {
autoflush STDOUT 1;
+ unless ($node) {
+ print('<div class="error">File not found.</div>');
+ return;
+ }
+
if ($node->isa('LXRng::Repo::Directory')) {
my $markup = LXRng::Markup::Dir->new('context' => $context,
'node' => $node);
@@ -126,29 +130,29 @@ sub print_release_list {
}
sub source {
- my ($context, $template, $query) = @_;
+ my ($context, $template, $query, $template_extra_args) = @_;
- my $pjx = CGI::Ajax->new('pjx_search' => 'lxr',
- 'pjx_load_file' => 'lxr',
- 'pjx_releases' => 'lxr');
+ my $pjx = CGI::Ajax->new('pjx_search' => '',
+ 'pjx_load_file' => '',
+ 'pjx_releases' => '');
$pjx->js_encode_function('escape');
-
+
if ($context->prefs and $context->prefs->{'navmethod'} eq 'ajax') {
- my $path = $query->path_info;
- $path =~ s,^/[+ ],,;
- if ($path ne '') {
- $path =~ s,^/+,,;
- print($query->redirect($query->url(-full => 1).
- '#'.$path));
+ if ($context->tree ne '') {
+ my $base = $context->base_url(1);
+ my $path = $context->vtree.'/'.$context->path;
+ print($query->redirect($base.'#'.$path));
}
else {
print($query->header(-type => 'text/html',
-charset => 'utf-8'));
- my $base = $query->url(-full => 1);
+ my $base = $context->base_url(1);
+ $base =~ s,/*$,/ajax+*/,;
+
$template->process('main.tt2',
{'context' => $context,
- 'base_url' => $base.'/+ajax/',
+ 'base_url' => $base,
'javascript' => $pjx->show_javascript(),
'is_ajax' => 1})
or die $template->error();
@@ -168,11 +172,13 @@ sub source {
my $ver = $context->release;
my $rep = $context->config->{'repository'};
- my $node = $rep->node($context->path, $ver);
+ die "No tree given" unless $rep;
+ my $node = $rep->node($context->path, $ver);
die "Node not found: ".$context->path." ($ver)" unless $node;
- my %template_args = ('context' => $context,
+ my %template_args = (%{$template_extra_args || {}},
+ 'context' => $context,
'tree' => $context->tree,
'node' => $node,
'base_url' => $context->base_url,
@@ -288,7 +294,7 @@ sub search {
$$ident[5] &&= $LXRng::Lang::deftypes{$$ident[5]};
use Data::Dumper;
- warn Dumper($symname, $symid, $ident, $refs);
+ # warn Dumper($symname, $symid, $ident, $refs);
$template_args{'ident_res'} = {'query' => $symname,
'ident' => $ident,
'refs' => $refs};
@@ -326,26 +332,23 @@ sub search_result {
'search_res' => $result,
'base_url' => $context->base_url);
- my $gzip = do_compress_response($query);
+ if ($context->prefs and $context->prefs->{'navmethod'} eq 'popup') {
+ my $gzip = do_compress_response($query);
- print($query->header(-type => 'text/html',
- -charset => 'utf-8',
- $gzip ? (-content_encoding => 'gzip') : ()));
+ print($query->header(-type => 'text/html',
+ -charset => 'utf-8',
+ $gzip ? (-content_encoding => 'gzip') : ()));
- binmode(\*STDOUT, ":gzip") if $gzip;
+ binmode(\*STDOUT, ":gzip") if $gzip;
- if ($context->prefs and $context->prefs->{'navmethod'} eq 'popup') {
$template->process('popup_main.tt2',
{%template_args,
'is_popup' => 1})
or die $template->error();
}
else {
- $template->process('main.tt2',
- {%template_args,
- 'file_content' => '',
- 'is_dir' => 0})
- or die $template->error();
+ $context->path('');
+ source($context, $template, $query, \%template_args);
}
}
@@ -423,8 +426,13 @@ sub handle_preferences {
print($query->header(-type => 'text/html',
-charset => 'utf-8'));
+ my $nav = 'is_replace';
+ $nav = 'is_'.$context->prefs->{'navmethod'} if
+ $context->prefs and $context->prefs->{'navmethod'} ne '';
+
$template->process('prefs.tt2',
- {'return' => $query->param('return')})
+ {'return' => $query->param('return'),
+ $nav => 1})
or die $template->error();
}
}
diff --git a/lib/LXRng/Context.pm b/lib/LXRng/Context.pm
index 46faa21..caaa473 100644
--- a/lib/LXRng/Context.pm
+++ b/lib/LXRng/Context.pm
@@ -9,7 +9,10 @@ sub new {
$self = bless({}, $self);
if ($args{'query'}) {
- $$self{'req_url'} = $args{'query'}->url();
+ # CGI::Simple appears to confuse '' with undef for SCRIPT_NAME.
+ # $$self{'req_url'} = $args{'query'}->url();
+ $$self{'req_url'} =
+ $args{'query'}->url(-base => 1).'/'.$ENV{'SCRIPT_NAME'};
foreach my $p ($args{'query'}->param) {
$$self{'params'}{$p} = [$args{'query'}->param($p)];
@@ -28,7 +31,7 @@ sub new {
}
if ($$self{'tree'} =~ s/[+](.*)$//) {
- $$self{'release'} = $1;
+ $$self{'release'} = $1 if $1 ne '*';
}
if ($$self{'tree'}) {
@@ -137,7 +140,7 @@ sub path_elements {
sub config {
my ($self) = @_;
- return $$self{'config'};
+ return $$self{'config'} || {};
}
sub prefs {
@@ -147,7 +150,7 @@ sub prefs {
}
sub base_url {
- my ($self) = @_;
+ my ($self, $notree) = @_;
my $base = $self->config->{'base_url'};
unless ($base) {
@@ -156,7 +159,10 @@ sub base_url {
}
$base =~ s,/+$,,;
- $base .= '/lxr/'.$self->vtree.'/';
+
+ return $base if $notree;
+
+ $base .= '/'.$self->vtree.'/';
$base =~ s,//+$,/,;
return $base;
diff --git a/lib/LXRng/Index/DBI.pm b/lib/LXRng/Index/DBI.pm
index 602eac8..932202c 100644
--- a/lib/LXRng/Index/DBI.pm
+++ b/lib/LXRng/Index/DBI.pm
@@ -73,6 +73,110 @@ sub _get_tree {
return $id;
}
+sub pending_files {
+ my ($self, $tree) = @_;
+
+ my $tree_id = $self->_get_tree($tree);
+ return [] unless $tree_id;
+
+ my $dbh = $self->dbh;
+ my $pre = $self->prefix;
+
+ # Can be made more fine grained by consulting filestatus, but all
+ # hashed documents need to have their termlist updated... Just
+ # include all files participating in releases not yet fully
+ # indexed.
+ my $sth = $$self{'sth'}{'pending_files'} ||=
+ $dbh->prepare(qq{
+ select rv.id, f.path, rv.revision
+ from ${pre}revisions rv, ${pre}files f
+ where rv.id_file = f.id
+ and rv.id in (select fr.id_rfile
+ from ${pre}releases r, ${pre}filereleases fr
+ where r.id = fr.id_release
+ and r.id_tree = ?
+ and r.is_indexed = 'f')});
+
+# $dbh->prepare(qq{
+# select rv.id, f.path, rv.revision
+# from ${pre}files f, ${pre}revisions rv
+# where rv.id_file = f.id
+# and not exists(select 1 from ${pre}filestatus fs
+# where fs.id_rfile = rv.id
+# and fs.indexed = 't'
+# and fs.hashed = 't'
+# and fs.referenced = 't')
+# and exists(select 1 from ${pre}filereleases fr, ${pre}releases r
+# where fr.id_rfile = rv.id
+# and fr.id_release = r.id
+# and r.id_tree = ?)});
+ if ($sth->execute($tree_id) > 0) {
+ return $sth->fetchall_arrayref();
+ }
+ else {
+ $sth->finish();
+ return [];
+ }
+}
+
+sub new_releases_by_file {
+ my ($self, $file_id) = @_;
+
+ my $dbh = $self->dbh;
+ my $pre = $self->prefix;
+ my $sth = $$self{'sth'}{'releases_by_file'} ||=
+ $dbh->prepare(qq{
+ select r.release_tag from ${pre}releases r, ${pre}filereleases f
+ where r.id = f.id_release and f.id_rfile = ? and r.is_indexed = 'f'});
+ if ($sth->execute($file_id) > 0) {
+ return [map { $$_[0] } @{$sth->fetchall_arrayref()}];
+ }
+ else {
+ $sth->finish();
+ return [];
+ }
+}
+
+sub update_indexed_releases {
+ my ($self, $tree) = @_;
+
+ my $tree_id = $self->_get_tree($tree);
+ return [] unless $tree_id;
+
+ my $dbh = $self->dbh;
+ my $pre = $self->prefix;
+ my $sth = $$self{'sth'}{'update_indexed_releases_find'} ||=
+ $dbh->prepare(qq{
+ select r.id, r.release_tag
+ from ${pre}releases r
+ where is_indexed = 'f'
+ and not exists (select 1
+ from ${pre}filereleases fr
+ left outer join ${pre}filestatus fs
+ on (fr.id_rfile = fs.id_rfile)
+ where fr.id_release = r.id
+ and (fs.id_rfile is null
+ or fs.indexed = 'f'
+ or fs.hashed = 'f'
+ or fs.referenced = 'f'))});
+
+ if ($sth->execute() > 0) {
+ my $rels = $sth->fetchall_arrayref();
+ $sth->finish();
+ $sth = $$self{'sth'}{'update_indexed_releases_set'} ||=
+ $dbh->prepare(qq{
+ update ${pre}releases set is_indexed = 't' where id = ?});
+ foreach my $r (@$rels) {
+ $sth->execute($$r[0]);
+ }
+ $sth->finish();
+ return [map { $$_[1] } @$rels];
+ }
+ else {
+ return [];
+ }
+}
+
sub _get_release {
my ($self, $tree_id, $release) = @_;
@@ -345,14 +449,19 @@ sub get_symbol_usage {
my $dbh = $self->dbh;
my $pre = $self->prefix;
- my $sth = $$self{'sth'}{'get_symbol_usage'} ||=
+
+ # Postgres' query optimizer deals badly with placeholders and
+ # prepared statements in this case.
+ return undef unless $symid =~ /^\d+$/s;
+ my $sth =
$dbh->prepare(qq{
select u.id_rfile, u.line
from ${pre}usage u, ${pre}filereleases fr
- where u.id_symbol = ?
- and u.id_rfile = fr.id_rfile and fr.id_release = ?});
+ where u.id_symbol = $symid
+ and u.id_rfile = fr.id_rfile and fr.id_release = ?
+ limit 1000});
- $sth->execute($symid, $rel_id);
+ $sth->execute($rel_id);
my $res = $sth->fetchall_arrayref();
$sth->finish();
diff --git a/lib/LXRng/Index/Pg.pm b/lib/LXRng/Index/Pg.pm
index 05fe3a0..1b905c0 100644
--- a/lib/LXRng/Index/Pg.pm
+++ b/lib/LXRng/Index/Pg.pm
@@ -179,6 +179,8 @@ sub init_db {
or die($dbh->errstr);
$dbh->do(qq{create index ${pre}file_idx1 on ${pre}files using btree (path)})
or die($dbh->errstr);
+ $dbh->do(qq{create index ${pre}filerel_idx1 on ${pre}filereleases using btree (id_release)})
+ or die($dbh->errstr);
$dbh->do(qq{grant select on ${pre}charsets to public}) or die($dbh->errstr);
$dbh->do(qq{grant select on ${pre}trees to public}) or die($dbh->errstr);
@@ -212,6 +214,7 @@ sub drop_db {
$dbh->do(qq{drop index ${pre}usage_idx2});
$dbh->do(qq{drop index ${pre}include_idx1});
$dbh->do(qq{drop index ${pre}file_idx1});
+ $dbh->do(qq{drop index ${pre}filerel_idx1});
$dbh->do(qq{drop table ${pre}usage});
$dbh->do(qq{drop table ${pre}identifiers});
diff --git a/lib/LXRng/Index/PgBatch.pm b/lib/LXRng/Index/PgBatch.pm
index 8f8844c..19c9fa9 100644
--- a/lib/LXRng/Index/PgBatch.pm
+++ b/lib/LXRng/Index/PgBatch.pm
@@ -77,7 +77,7 @@ sub flush {
}
}
$self->dbh->commit() unless $self->dbh->{AutoCommit};
- $self->dbh->do(q(analyze)) if $i > 100000;
+ $self->dbh->do(q(analyze)) if $i > 500000;
$self->dbh->disconnect();
warn "\n*** index: flushed $i rows\n";
kill(9, $$);
diff --git a/lib/LXRng/Lang/C.pm b/lib/LXRng/Lang/C.pm
index c88f424..1a826bd 100644
--- a/lib/LXRng/Lang/C.pm
+++ b/lib/LXRng/Lang/C.pm
@@ -51,7 +51,8 @@ sub parsespec {
'comment', '//', "\$",
'string', '"', '"',
'string', "'", "'",
- 'include', '#\s*include', "\$"];
+ 'include', '#\s*include\s+"', '"',
+ 'include', '#\s*include\s+<', '>'];
}
sub typemap {
diff --git a/lib/LXRng/Markup/File.pm b/lib/LXRng/Markup/File.pm
index 406737c..abb763c 100644
--- a/lib/LXRng/Markup/File.pm
+++ b/lib/LXRng/Markup/File.pm
@@ -16,7 +16,7 @@ sub context {
sub safe_html {
my ($str) = @_;
- return encode_entities($str, '^\n\r\t !\#\$\(-;=?-~');
+ return encode_entities($str, '^\n\r\t !\#\$\(-;=?-~\200-\377');
}
sub make_format_newline {
diff --git a/lib/LXRng/Repo/Git.pm b/lib/LXRng/Repo/Git.pm
index 2d6ea33..757da26 100644
--- a/lib/LXRng/Repo/Git.pm
+++ b/lib/LXRng/Repo/Git.pm
@@ -74,7 +74,7 @@ sub allversions {
}
sub node {
- my ($self, $path, $release) = @_;
+ my ($self, $path, $release, $rev) = @_;
$path =~ s,^/+,,;
$path =~ s,/+$,,;
@@ -88,14 +88,21 @@ sub node {
return LXRng::Repo::Git::Directory->new($self, '', $ref);
}
- my $git = $self->_git_cmd('ls-tree', $release, $path);
- my ($mode, $type, $ref, $gitpath) = split(" ", <$git>);
+ my $type;
+ if ($rev) {
+ $type = 'blob';
+ }
+ else {
+ my $git = $self->_git_cmd('ls-tree', $release, $path);
+ my ($mode, $gitpath);
+ ($mode, $type, $rev, $gitpath) = split(" ", <$git>);
+ }
if ($type eq 'tree') {
- return LXRng::Repo::Git::Directory->new($self, $path, $ref, $release);
+ return LXRng::Repo::Git::Directory->new($self, $path, $rev, $release);
}
elsif ($type eq 'blob') {
- return LXRng::Repo::Git::File->new($self, $path, $ref, $release);
+ return LXRng::Repo::Git::File->new($self, $path, $rev, $release);
}
else {
return undef;
diff --git a/lib/LXRng/Search/Xapian.pm b/lib/LXRng/Search/Xapian.pm
index 42c7580..b6e28a0 100644
--- a/lib/LXRng/Search/Xapian.pm
+++ b/lib/LXRng/Search/Xapian.pm
@@ -32,9 +32,11 @@ sub new_document {
}
sub add_document {
- my ($self, $doc, $rel_id) = @_;
+ my ($self, $doc, $rel_ids) = @_;
- $doc->add_term('__@@LXRREL_'.$rel_id);
+ foreach my $r (@$rel_ids) {
+ $doc->add_term('__@@LXRREL_'.$r);
+ }
my $doc_id = $self->wrdb->add_document($doc);
$self->{'writes'}++;
$self->flush() if $self->{'writes'} % 499 == 0;
@@ -42,20 +44,25 @@ sub add_document {
}
sub add_release {
- my ($self, $doc_id, $rel_id) = @_;
+ my ($self, $doc_id, $rel_ids) = @_;
- my $reltag = '__@@LXRREL_'.$rel_id;
my $doc = $self->wrdb->get_document($doc_id);
- my $term = $doc->termlist_begin;
my $termend = $doc->termlist_end;
- $term->skip_to($reltag);
- if ($term ne $termend) {
- return 0 if $term->get_termname eq $reltag;
+ my $changes = 0;
+ foreach my $r (@$rel_ids) {
+ my $reltag = '__@@LXRREL_'.$r;
+ my $term = $doc->termlist_begin;
+ $term->skip_to($reltag);
+ if ($term ne $termend) {
+ next if $term->get_termname eq $reltag;
+ }
+ $doc->add_term($reltag);
+ $changes++;
}
- $doc->add_term($reltag);
- $self->wrdb->replace_document($doc_id, $doc);
- return 1;
+
+ $self->wrdb->replace_document($doc_id, $doc) if $changes;
+ return $changes;
}
sub flush {
diff --git a/lxr-genxref b/lxr-genxref
index 79e98f5..9f055ae 100755
--- a/lxr-genxref
+++ b/lxr-genxref
@@ -86,15 +86,15 @@ sub make_add_ident {
}
sub index_file {
- my ($context, $index, $tree, $rel, $file, $fileid) = @_;
+ my ($context, $index, $tree, $file, $fileid) = @_;
my $lang = LXRng::Lang->new($file);
- return unless $lang->doindex();
unless ($index->to_index($fileid)) {
progress_mark("*");
return;
}
+ return unless $lang->doindex();
my $add_ident = make_add_ident($index, $fileid);
@@ -137,20 +137,18 @@ sub index_file {
}
sub reference_file {
- my ($context, $index, $tree, $rel, $file, $fileid) = @_;
+ my ($context, $index, $tree, $file, $fileid) = @_;
my $lang = LXRng::Lang->new($file);
- return unless $lang->doindex();
-
unless ($index->to_reference($fileid)) {
progress_mark(".");
return;
}
+ return unless $lang->doindex();
-# sysopen(my $handle, $file->phys_path, O_RDONLY) or die($!);
-# my $parse = new LXRng::Parse::Simple($handle, 8, @{$lang->parsespec});
- my $parse = new LXRng::Parse::Simple($file->handle, 8, @{$lang->parsespec});
+ my $parse = new LXRng::Parse::Simple($file->handle, 8,
+ @{$lang->parsespec});
progress_info("referencing ".$file->name.", ".
$file->size." bytes ($lang)...");
@@ -196,7 +194,7 @@ sub reference_file {
}
sub hash_file {
- my ($context, $index, $hash, $tree, $rel, $file, $fileid) = @_;
+ my ($context, $index, $hash, $tree, $file, $fileid, $rels) = @_;
my $docid;
if ($index->to_hash($fileid)) {
@@ -218,47 +216,19 @@ sub hash_file {
$doc->add_posting($term, $.*100 + $pos++);
}
}
- $docid = $hash->add_document($doc, $index->release_id($tree, $rel));
+
+ $docid = $hash->add_document($doc, [map {
+ $index->release_id($tree, $_) } @$rels]);
$index->add_hashed_document($fileid, $docid);
}
else {
$docid = $index->get_hashed_document($fileid);
- if ($hash->add_release($docid, $index->release_id($tree, $rel))) {
- progress_mark("+");
- }
- else {
- progress_mark("-");
- }
+ my $changed = $hash->add_release($docid, [map {
+ $index->release_id($tree, $_) } @$rels]);
+ progress_mark($changed ? "+" : "-");
}
- # for all releases this fileid belongs to (that are not is_indexed)
- # add_release to $docid.
}
-sub do_index {
- my ($context, $index, $hash, $tree, $rel, $iter) = @_;
-
- my $node;
- while (defined($node = $iter->next)) {
- next if $node->name =~ /\.o$/;
- my $fileid = $index->rfile_id($node, 1);
- $index->add_filerelease($tree, $rel, $fileid);
- index_file($context, $index, $tree, $rel, $node, $fileid);
- hash_file($context, $index, $hash, $tree, $rel, $node, $fileid);
- }
-}
-
-sub do_reference {
- my ($context, $index, $hash, $tree, $rel, $iter) = @_;
-
- my $node;
- while (defined($node = $iter->next)) {
- next if $node->name =~ /\.o$/;
- my $fileid = $index->rfile_id($node, 1);
- LXRng::Index::transaction {
- reference_file($context, $index, $tree, $rel, $node, $fileid);
- } $index;
- }
-}
my $tree = shift(@ARGV);
my @versions = @ARGV;
@@ -269,33 +239,76 @@ my $index = $context->config->{'index'};
my $hash = $context->config->{'search'};
my $rep = $context->config->{'repository'};
-sub do_genxref {
+
+sub inventory_release {
my ($tree, $version) = @_;
- print("\nindexing release $version...\n");
- my $root = $rep->node('/', $version) or die "bad root";
- $context->release($version);
-
+ print("\nrecording all files for $version...\n");
+
+ my $iter = $rep->iterator($version);
+ LXRng::Index::transaction {
+ my $root = $rep->node('/', $version) or die "bad root";
+
+ my $node;
+ while (defined($node = $iter->next)) {
+ next if $node->name =~ /\.o$/;
+ my $fileid = $index->rfile_id($node, 1);
+ $index->add_filerelease($tree, $version, $fileid);
+ }
+ } $index;
+}
+
+sub index_pending {
+ my ($tree) = @_;
+ my $pending = $index->pending_files($tree);
+
+ print("\nindexing ".(0+@$pending)." outstanding files...\n");
LXRng::Index::transaction {
- do_index($context, $index, $hash, $tree, $version, $rep->iterator($version));
- do_reference($context, $index, $hash, $tree, $version, $rep->iterator($version));
+ foreach my $p (@$pending) {
+ my ($fileid, $path, $rev) = @$p;
+ my $rels = $index->new_releases_by_file($fileid);
+ next unless @$rels;
+ my $node = $rep->node($path, $$rels[0], $rev);
+ next unless $node;
+
+ hash_file($context, $index, $hash, $tree, $node, $fileid, $rels);
+ index_file($context, $index, $tree, $node, $fileid);
+ }
} $index;
- $hash->flush();
- # Mark release as is_indexed
- progress_info("release $version done");
+ print("\nreferencing ".(0+@$pending)." outstanding files...\n");
+ LXRng::Index::transaction {
+ foreach my $p (@$pending) {
+ my ($fileid, $path, $rev) = @$p;
+ my $rels = $index->new_releases_by_file($fileid);
+ next unless @$rels;
+ $context->release($$rels[0]); # Needed for include resolution.
+ my $node = $rep->node($path, $$rels[0], $rev);
+ next unless $node;
+
+ LXRng::Index::transaction {
+ reference_file($context, $index, $tree, $node, $fileid, $rels);
+ } $index;
+ }
+ } $index;
+
+ my $done = $index->update_indexed_releases($tree);
+
+ progress_info("releases ".join(", ", @$done)." done") if
+ @$done;
}
if (@versions) {
foreach my $version (@versions) {
- do_genxref($tree, $version);
+ inventory_release($tree, $version);
}
}
else {
- # Run pass over all un-indexed releases, record all files.
-
foreach my $version (reverse @{$context->all_releases}) {
next if $index->_get_release($index->tree_id($tree), $version);
- system($0, $tree, $version);
+ inventory_release($tree, $version);
}
}
+
+index_pending($tree);
+$hash->flush();
diff --git a/lxrng.conf-dist b/lxrng.conf-dist
index 80c35f5..27abb1b 100644
--- a/lxrng.conf-dist
+++ b/lxrng.conf-dist
@@ -24,7 +24,7 @@ return {
'index' => $index,
'search' => $search,
- 'base_url' => 'http://lxr-test.linpro.no/',
+ 'base_url' => 'http://lxr-test.linpro.no/lxr',
# Must be writable by httpd user:
'cache' => '/var/lib/lxrng/cache',
diff --git a/tmpl/header.tt2 b/tmpl/header.tt2
index 0c5b6f6..0b07111 100644
--- a/tmpl/header.tt2
+++ b/tmpl/header.tt2
@@ -2,9 +2,22 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
- <base href="[% base_url %]" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-
+ [% IF is_ajax %]
+ <script type="text/javascript">
+ var tree = location.hash.match(/^#([^/+]+)([+][^/]*|)/);
+ if (tree) {
+ var base = '[% base_url %]';
+ base = base.replace(/\/ajax[+][*]/, '/' + tree[1] + '+*');
+ document.write('<base href="' + base + '" />');
+ }
+ else {
+ document.write('<base href="[% base_url %]" />');
+ }
+ </script>
+ [% ELSE %]
+ <base href="[% base_url %]" />
+ [% END %]
<script type="text/javascript" src="../../js/lxrng-funcs.js"></script>
<link rel="stylesheet" href="../../css/lxrng.css" type="text/css" title="LXRng" />
@@ -36,6 +49,7 @@
END %]
</span>
<img src="../../gfx/rolldown.png" />
+ <!-- TODO: appears to break w. ajax nav. -->
[% IF node.name.match('[^/]$') %]
<form action="+print=[% node.name %]" method="post">
<button type="submit" class="print"><img src="../../gfx/print.png"></button>
diff --git a/tmpl/prefs.tt2 b/tmpl/prefs.tt2
index c7f6a6d..6246ac6 100644
--- a/tmpl/prefs.tt2
+++ b/tmpl/prefs.tt2
@@ -18,7 +18,7 @@
</span>
<div class="lxr_menu">
- <span class="lxr_prefs"><a href="[% return || '.' %]">Back</a></span>
+ <span class="lxr_prefs"><a href="./[% return %]">Back</a></span>
</div>
<div class="headingbottom"></div>
</div>
@@ -30,10 +30,12 @@
<input type="hidden" name="return" value="[% return %]" />
Where do you want your search results to be displayed?
<ol>
- <li><input type="radio" name="resultloc" value="replace" />
+ <li><input type="radio" name="resultloc" value="replace"
+ [% IF is_replace %]checked[% END %]/>
Replace the active source browsing window</li>
- <li><input type="radio" name="resultloc" value="popup" />
+ <li><input type="radio" name="resultloc" value="popup"
+ [% IF is_popup %]checked[% END %]/>
Show them in a popup window (requires JavaScript enabled)<br>
<font size="-1"><em>If your browser limits the ability to
@@ -41,9 +43,10 @@
Preferences -> Content -> Enable JavaScript -> Advanced ->
Allow scripts to: Raise or lower windows), make sure you
either close your search result windows or avoid hiding them
- behing other windows after use.</em></font></li>
+ behind other windows after use.</em></font></li>
- <li><input type="radio" name="resultloc" value="ajax" />
+ <li><input type="radio" name="resultloc" value="ajax"
+ [% IF is_ajax %]checked[% END %]/>
Show them inside the active source browsing window
(requires JavaScript enabled)
</li>
diff --git a/tmpl/search_result.tt2 b/tmpl/search_result.tt2
index 639e951..1a38e22 100644
--- a/tmpl/search_result.tt2
+++ b/tmpl/search_result.tt2
@@ -56,7 +56,8 @@ at [% INCLUDE line_reference.tt2, file = file.1, line = file.2 %]
<ul>
[% FOREACH file = file_res.files %]
<li><a href="[% file %]" onclick="return load_file('[% context.tree %]',
- '[% file %][% context.args_url %]', '', '');" [% navtarget %]>[% file %]</a>
+ '[% file %][% context.args_url %]', '[% context.release %]', '');"
+ [% navtarget %]>[% file %]</a>
</li>
[% END %]
</ul>
@@ -67,7 +68,8 @@ at [% INCLUDE line_reference.tt2, file = file.1, line = file.2 %]
<ul>
[% FOREACH file = ambig_res.files %]
<li><a href="[% file %]" onclick="return load_file('[% context.tree %]',
- '[% file %][% context.args_url %]', '', '');" [% navtarget %]>[% file %]</a>
+ '[% file %][% context.args_url %]', '[% context.release %]', '');"
+ [% navtarget %]>[% file %]</a>
</li>
[% END %]
</ul>