aboutsummaryrefslogtreecommitdiffstats
path: root/lxr-genxref
diff options
context:
space:
mode:
Diffstat (limited to 'lxr-genxref')
-rwxr-xr-xlxr-genxref122
1 files changed, 87 insertions, 35 deletions
diff --git a/lxr-genxref b/lxr-genxref
index d61526f..f64fe78 100755
--- a/lxr-genxref
+++ b/lxr-genxref
@@ -37,6 +37,7 @@ use IO::Handle;
use Fcntl;
use Term::ProgressBar;
use Devel::Size qw(size total_size);
+use Encode;
$SIG{'INT'} = sub { die "\nSIGINT: $$: please wait, flushing caches...\n"; };
$SIG{'QUIT'} = sub { die "\nSIGQUIT: $$: please wait, flushing caches...\n"; };
@@ -51,6 +52,7 @@ my $tree = shift(@ARGV);
my @versions = @ARGV;
my $context = LXRng::Context->new('tree' => $tree);
+die "Usage: $0 <tree-id>\n" unless $context and $context->tree;
LXRng::Lang->init($context);
my $index = $context->config->{'index'};
@@ -58,6 +60,10 @@ my $usage = $context->config->{'usage'};
my $hash = $context->config->{'search'};
my $rep = $context->config->{'repository'};
my $progress;
+my $progress_ident;
+my $progress_count;
+my $progress_next;
+my $progress_target;
$SIG{'__WARN__'} = sub { $progress ? $progress->message(shift) : warn(@_) };
@@ -73,6 +79,50 @@ sub memory_status {
}
}
+sub progress_init {
+ my ($ident, $total) = @_;
+
+ if (-t STDOUT) {
+ $progress = Term::ProgressBar->new({name => $ident,
+ count => $total,
+ ETA => 'linear'});
+ $progress->max_update_rate(0.25);
+ }
+ else {
+ $progress_ident = $ident;
+ $progress_target = $total;
+ $progress_next = int($progress_target/10);
+ $progress_count = 0;
+ }
+}
+
+sub progress_update {
+ my ($count) = @_;
+
+ return $progress->update($count) if $progress;
+
+ if (defined($count)) {
+ $progress_count = $count;
+ }
+ else {
+ $progress_count++;
+ }
+ if ($progress_count > $progress_next or
+ $progress_count >= $progress_target)
+ {
+ print("$progress_ident: $progress_count/$progress_target done...\n");
+ $progress_next = $progress_count + int($progress_target/10);
+ }
+}
+
+sub progress_target {
+ my ($target) = @_;
+
+ return $progress->target($target) if $progress;
+
+ $progress_target = $target;
+}
+
sub make_add_ident($) {
my ($fileid) = @_;
@@ -87,7 +137,8 @@ sub make_add_ident($) {
$last_func = $symbol;
}
if ($$info{'kind'} eq 'l') {
- $$info{'context'} = $identcache{$last_func};
+ $$info{'context'} = $identcache{$last_func} if
+ defined($last_func);
}
if (exists $$info{'class'}) {
$$info{'context'} = $identcache{$$info{'class'}};
@@ -123,10 +174,14 @@ sub index_file($$) {
return 0 unless $index->to_index($fileid);
return 1 unless $lang->doindex();
- my $add_ident = make_add_ident($fileid);
-
warn("--- indexing ".$file->name." [".$file->revision."]\n");
- my @extra_flags = ('-IEXPORT_SYMBOL+', '-I__initcall+');
+
+ my $add_ident = make_add_ident($fileid);
+ return $lang->index_file($context, $file, $add_ident)
+ if $lang->can('index_file');
+ return 1 unless $lang->ctagslangname();
+
+ my $extra_flags = $context->config->{'ctags_flags'} || [];
my $ctags;
my $pid = open($ctags, '-|');
@@ -134,7 +189,7 @@ sub index_file($$) {
if ($pid == 0) {
exec('ctags-exuberant',
- @extra_flags,
+ @$extra_flags,
'--fields=+aifmknsSz', '--sort=no',
'--excmd=number', '-f', '-',
'--language-force='.$lang->ctagslangname,
@@ -149,6 +204,7 @@ sub index_file($$) {
while (<$ctags>) {
chomp;
my ($symbol, $file, $excmd, @info) = split(/\t/);
+ $symbol = $lang->mangle_sym($symbol);
my %info = map { split(/:/, $_, 2) } @info;
$add_ident->($symbol, \%info);
@@ -167,9 +223,8 @@ sub index_file($$) {
sub reference_file($$$) {
my ($file, $fileid, $doc) = @_;
- my $lang = LXRng::Lang->new($file);
-
return 0 unless $index->to_reference($fileid);
+ my $lang = LXRng::Lang->new($file);
return 1 unless $lang->doindex();
my $handle;
@@ -181,12 +236,7 @@ sub reference_file($$$) {
warn("--- referencing ".$file->name." [".$file->revision."]\n");
my $reserved = $lang->reserved();
-
- my $re = qr(
- (?m:^|[^a-zA-Z0-9_]) # Non-symbol chars.
- (_*[a-zA-Z][a-zA-Z0-9_]*) # The symbol.
- \b
- )x;
+ my $re = $lang->identifier_re();
my %refs;
my $line = 1;
@@ -199,7 +249,7 @@ sub reference_file($$$) {
while ($frag =~ /\G.*?(?:(\n)|$re)/gc) {
$line++ && next if defined $1;
- my $sym = $2;
+ my $sym = $lang->mangle_sym($2);
next if $$reserved{$sym};
push(@{$refs{$sym} ||= []}, $line);
@@ -244,20 +294,28 @@ sub hash_file($$$) {
warn("--- hashing ".$file->name." [".$file->revision."]\n");
my $doc = $hash->new_document($file->name);
+ my $charset = $context->config->{'content_charset'} || [];
+ $charset = [ref($charset) eq 'ARRAY' ? @$charset : $charset];
+ push(@$charset, 'iso-8859-1'); # Fall back
+ my $add_line = $hash->make_add_text($doc);
+
while (<$handle>) {
my $pos = 0;
- # Latin-1 word characters.
- foreach my $term (/([0-9a-zA-Z\300-\326\330-\366\370-\377]+)/g) {
- $term = lc($term);
- next if length($term) > 128;
- $doc->add_posting($term, $.*100 + $pos++);
+ my $text;
+ while (@$charset) {
+ $text = eval { decode($$charset[0], $_, Encode::FB_CROAK); };
+ last unless $@;
+ shift(@$charset);
}
+
+ $add_line->($.*100, $text);
}
reference_file($file, $fileid, $doc);
$docid = $hash->add_document($doc, [map {
$index->release_id($tree, $_) } @$rels]);
$index->add_hashed_document($fileid, $docid);
+ $index->set_rfile_charset($fileid, $$charset[0] || 'ascii');
$handle->close();
return 1;
}
@@ -301,10 +359,7 @@ sub index_pending() {
my $count = 0;
print("\n");
- $progress = Term::ProgressBar->new({name => 'Indexing',
- count => $total,
- ETA => 'linear'});
- $progress->max_update_rate(0.25);
+ progress_init('Indexing', $total);
warn("--- indexing/updating $total files...\n");
foreach my $p (@$pending) {
@@ -321,7 +376,7 @@ sub index_pending() {
index_file($node, $fileid))
{
$count++;
- $progress->update($count);
+ progress_update($count);
}
else {
$total--;
@@ -329,11 +384,11 @@ sub index_pending() {
if ($skip % 100 == 0) {
warn("--- skipped/refreshed $skip files...\n");
}
- $progress->target($total);
+ progress_target($total);
}
} $index;
}
- $progress->update($total);
+ progress_update($total);
my $done = $index->update_indexed_releases($tree);
@@ -344,32 +399,29 @@ sub index_pending() {
-$progress = Term::ProgressBar->new({name => 'Recording',
- count => 1,
- ETA => 'linear'});
-$progress->max_update_rate(0.25);
+progress_init('Recording', 1);
if (@versions) {
- $progress->target(1+@versions);
+ progress_target(1+@versions);
foreach my $version (@versions) {
inventory_release($version);
- $progress->update();
+ progress_update();
}
}
else {
@versions = grep { ! $index->_get_release($index->tree_id($tree), $_);
} @{$context->all_releases};
- $progress->target(1+@versions);
+ progress_target(1+@versions);
LXRng::Index::transaction {
foreach my $version (reverse @versions) {
# TODO: Breaking during the inventory process renders
# version half-recorded.
inventory_release($version);
- $progress->update();
+ progress_update();
}
} $index;
}
-$progress->update();
+progress_update();
LXRng::Index::transaction {
index_pending();