#!/usr/bonsaitools/bin/perl
# $Id: search,v 1.9 2003/07/28 21:24:42 leaf%mozilla.org Exp $

# search --	Freetext search
#
#	Arne Georg Gleditsch <argggh@ifi.uio.no>
#	Per Kristian Gjermshus <pergj@ifi.uio.no>
#
#
# 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 LXR::Common;
use LXR::Config;

$maxhits = 1000;

sub search {
    print("<P ALIGN=CENTER>\n",
	  "Free-text search through the source code, including comments.\n",
          "<BR>By default, this form treats all characters as literals. \n",
          "<BR>Search strings can have a maximum of 29 characters.\n",
	  "<BR>Read the <A HREF=\"search-help.html\">documentation</A>",
	  " for help with glimpse's regular expression syntax,\n");

    print("<TABLE><TR><TD>");
    print("<form method=get action=\"search\">\n");

    foreach ($Conf->allvariables) {
	if ($Conf->variable($_) ne $Conf->vardefault($_)) {
	    print("<input type=hidden name=\"",$_, "\" ",
		  "value=\"", $Conf->variable($_), "\">\n");
	}
    }

    $s = $searchtext;
    $s =~ s/"/\&quot;/g;
    print("<B>Search for: </B></TD><TD><input type=text name=\"string\" ",
	  "value=\"",$s,"\" maxlength=29 size=30>\n",
	  "<input type=submit value=\"search\"><BR>\n",
          "</TD></TR><TR><TD></TD><TD>\n",
	  "<input type=\"checkbox\" name=\"regexp\"");
          if ($Conf->{'regexp'} eq 'on') {
              print (" CHECKED");
              print (" value=\"on\">Regular Expression Search\n");
          } else {
              print (">Regular Expression Search\n");
          }
          print ("</TD></TR>\n</form>\n </TABLE>\n");
    
    $| = 1; print('');
   
    if ($searchtext ne "") {
	print("<hr>\n");
	unless (open(GLIMPSE, "-|")) {
	    open(STDERR, ">&STDOUT");
	    $!='';
            if ($Conf->{'regexp'} eq 'off') {
                $searchtext =~ s/([;,#><\-\$.^*[^|()\!])/\\$1/g;
            }
	    exec($Conf->glimpsebin,"-i","-H".$Conf->dbdir,'-y','-n','-e',$searchtext);
	    print("Glimpse subprocess died unexpectedly: $!\n");
	    exit;
	}

	$numlines = 0;
	while (<GLIMPSE>) {
	    $numlines++;
	    push(@glimpselines,$_);
	    if ($numlines > $maxhits) {
		last;
	    }
	}

	close(GLIMPSE);

	$retval = $? >> 8;

	# 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 (@glimpselines == 0) {
		print("No matching files<br>\n");
	    } elsif (@glimpselines[0] =~ /pattern too long/) {
                print ("Pattern too long. Use a maximum 29 characters.\n");
	    } else {
		if ($numlines > $maxhits) {
		    print("<b> Too many hits, displaying first $maxhits</b><br>\n");
		}
                $searchtext =~ s/&/&amp;/g;
                $searchtext =~ s/</&lt;/g;
                $searchtext =~ s/>/&gt;/g;

		print("<h1>$searchtext</h1>\n");
		$sourceroot = $Conf->sourceroot;
		foreach $glimpseline (@glimpselines) {
		    
		    $glimpseline =~ s/$sourceroot//;
		    ($file, $line, $text) = 
			$glimpseline =~ /(.*?):\s*(\d+)\s*:(.*)/;
		    $text =~ s/&/&amp;/g;
		    $text =~ s/</&lt;/g;
		    $text =~ s/>/&gt;/g;

		    print(&fileref("$file, line $line", "$file", $line),
			  " -- $text<br>\n");
		}
	    }
	} elsif ($retval == 1) {
	    $glimpsebin = $Conf->glimpsebin;
	    $glimpseresponse = join("<br>",@glimpselines);
	    $glimpseresponse =~ s/$glimpsebin/Reason/;
	    $glimpseresponse =~ s/glimpse: error in searching index//;
	    print("<b>Search failed</b><br>\n$glimpseresponse");
	} else {
	    print("Unexpected returnvalue $retval from Glimpse\n");
	}
    }
}

($Conf, $HTTP, $Path) = &glimpse_init;
$searchtext = $HTTP->{'param'}->{'string'};
$regexp = $HTTP->{'param'}->{'regexp'};
$searchtext =~ tr/+/ /;
$searchtext =~ s/%(\w\w)/chr(hex $1)/ge;


&makeheader('search');
&search;
&makefooter('search');
