#!/usr/bin/perl # $Id: search,v 1.10 2006/12/07 04:59:38 reed%reedloden.com Exp $ # search -- Freetext search # # Arne Georg Gleditsch # Per Kristian Gjermshus # # # 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 lib 'lib'; use Local; use LXR::Common; use LXR::Config; $maxhits = 1000; my ($openlist, $lastfilepath, $skip); my $styles=" "; sub toggle_style { my ($n, $m) = @_; my $s=0; my $t=10; my @inline = (), @none = (); push @none, ".$m$s"."_".(($n-1 % $t) % 10); push @inline, ".$m$s"."_".(($n % $t) % 10); if (($n % $t) == 0) { do { $n = ($n / 10) | 0; ++$s; if ($n % 10 == 0) { push @none, ".$m$s"."_9"; push @inline, ".$m$s"."_0"; } } while ($n>=10 && (($n % 10) == 0)); push @none, ".$m$s"."_".(($n -1) % 10); push @inline, ".$m$s"."_".($n % 10); } return join(',',@none)."{display:none;} ".join(',',@inline)."{display:inline;}"; } sub display_line { my ($glimpseline, $re) = @_; $sourceroot = $Conf->sourceroot; $glimpseline =~ s/$sourceroot//; ($file, $line, $text) = $glimpseline =~ /(.*?):\s*(\d+)\s*:(.*)/; if (length($text) > 160) { # the string is way too long # "hello cruel world what time is it this day. We are here to \ # celebrate the beginning of things which no one cares about \ # because it is so very important. When for other reasons it \ # becomes clear that no one really cares. We should stop it." my $context = '.{0,20}'; $text =~ s/.*?($context$re$context)/..$1../g; $text =~ s/($re$context)((?!$re).)*$/$1.../; $text = '.' . $text; } my $path=''; my $filename; my $skip = $lastfilepath eq $file; #$skip = 0; $lastfilepath = $file; if ($openlist && !$skip) { $openlist = 0; print (''); } ($file,$filename)=split m|/(?!.*/)|, $file; foreach my $filepart ($file =~ m{^/?$} ? ('') : split m|/|, $file) { $path .= "$filepart/"; unless ($skip) { print(&fileref($filepart ? $filepart : '/', "$path"), $filepart && '/'); } } my $filepath = $path ? $path . $filename : "/$filename"; my @frargs = (); if ($filename =~ /\.html?$/) { @frargs = ("force=1"); } unless ($skip) { print(&fileref("$filename", "$filepath")); print(&blamerefs($file.'/'.$filename)); } unless ($skip) { print ('') if $openlist; print "

"; if ($numlines < 5) { close(GLIMPSE); $retval = $? >> 8; } else { kill 15, $glimpsepid; $retval = 0; } # The manpage for glimpse says that it returns 2 on syntax errors or # inaccessible files. It seems this is not the case. # We will have to work around it for the time being. if ($retval == 0) { if ($numlines == 0) { print "No matching files
"; } else { if ($numlines > $maxhits) { print "Too many hits, displaying the first $maxhits
"; } else { if ($numlines == 1) { print "Found one matching line
"; } else { my $match_count = $hitlimit != 1 ? " $numlines" : ''; my $in_files = $hit_file_count > 1 ? " in $hit_file_count files" : ''; print "Found$match_count matching lines$in_files
"; } } } } elsif ($retval == 1) { print "No results found
"; } elsif ($retval == 2) { # searching for '-' triggers this. } else { print "Unexpected return value $retval from Glimpse. Please file a bug "; } } } ($Conf, $HTTP, $Path, $head) = &glimpse_init; $searchtext = $HTTP->{'param'}->{'string'}; $regexp = $HTTP->{'param'}->{'regexp'} || $Conf->{'regexp'}; $regexp = $regexp =~ /1|on|yes/ ? 1 : ''; $find = $HTTP->{'param'}->{'find'}; $findi = $HTTP->{'param'}->{'findi'}; $search_sensitive = defined $HTTP->{'param'}->{'case'} ? $HTTP->{'param'}->{'case'} =~ /1|on|yes/ : ''; $filter = $HTTP->{'param'}->{'filter'} || # '^[^\\0]*$' '%5E%5B%5E\\0%5D%2A%24'; $hitlimit = cleanHitlimit($HTTP->{'param'}->{'hitlimit'}) || undef; $filter =~ tr/+/ /; $filter =~ s/%(\w\w)/chr(hex $1)/ge; sub cleanHitlimit { my $hitLimit = shift; $hitLimit =~ s/\D//gs; return $hitLimit; } $find_warning = 0; if (defined $findi && $findi ne '') { if (defined $find && $find ne '') { $find_warning = $find ne $findi; } else { #$find = $findi; } } sub cleanFind { my $find = shift; $find =~ s/["`'<>|()]+//g; $find =~ s|%2f|/|gi; $find =~ s|%24|\$|g; $find =~ s|%5c|\\|gi; $find =~ s|%2a|*|gi; return $find; } $find = cleanFind($find); $searchtext =~ tr/+/ /; $searchtext =~ s/%([0-9a-f]{2})/chr(hex $1)/gie; my $refresh; my $tree = $HTTP->{'param'}->{'tree'}; if ($tree && ($tree ne $Conf->{'treename'})) { my @treelist = @{$Conf->{'trees'}}; foreach my $othertree (@treelist) { next unless $othertree eq $tree; push @tail, "string=" . url_quote($searchtext) if $searchtext ne ''; push @tail, "regexp=" . url_quote($regexp) if $regexp ne ''; push @tail, "case=" . url_quote($search_sensitive) if $search_sensitive ne ''; push @tail, "find=" . url_quote($find) if $find ne ''; push @tail, "findi=" . url_quote($findi) if $findi ne ''; push @tail, "filter=" . url_quote($filter) if $filter ne ''; push @tail, "hitlimit=" . url_quote($hitlimit) if $hitlimit ne ''; my $tail = $#tail >= 0 ? '?' . join "&", @tail : ''; $refresh .= "Refresh: 0; url=../$tree/search$tail "; } } print "$head$refresh "; exit if $refresh ne ''; &makeheader('search'); &search; &makefooter('search'); 1;