#! /usr/bin/perl -wT # rouilj@ieee.org # a wrapper to make twiki and bool work better together. # this detects when it is not a boolean string and turns it into an # and boolean string respecting phrases surrounded by " or '. # So typing: # "this phrase" twiki nothing else # gets converted into: # "this phrase" and twiki and nothing and else # rather than returing a syntax error. use strict; $ENV{'PATH'} = "/usr/bin"; sub boolwrap { my $bool = "/tools/bool-0.2.1/bin/bool"; my $fgrep = "/bin/fgrep"; my $debug = 0; print STDERR join(" | ", @_) . "\n" if $debug; my ($argument, $files, $searchstring); while ($_ = shift @_) { last if m/^--$/; $debug = 1, next if m/^-Dhelper/; $argument .= " $_", next if m/^-/; unshift @_, $_; last; } $argument .= " --"; $searchstring = shift @_; $files = join(" ", @_); # strip fore and aft whitespace $searchstring =~ s/\s*$//; $searchstring =~ s/^\s*//; MODIFY: { # see if there are boolean commands in string. Pass through # unmolested. Bool will complain if its not well formed though 8-(. $searchstring = qq($searchstring), last MODIFY if $searchstring =~ /\s(and|or|near|not)\s/i; # put 'and' between every whitespace delimited word or quoted # phrase. Walk through string locating quoted strings. my ($searchPart, $searchRest, $inQuote, @searchParts); $inQuote = 0; $searchRest = $searchstring; while ($searchRest) { ($searchPart, $searchRest) = split(/\"/, $searchRest, 2); $inQuote = 1 if !defined($searchPart) || $searchPart =~ /^\s*$/; # had a quote at the beginning of searchRest. if ($inQuote) { if (defined($searchPart) && $searchPart !~ /^\s*$/) { # put back quotes around phrase push @searchParts, qq["$searchPart"]; $inQuote = 0; } } else { push @searchParts, join(" and ", split(' ', $searchPart)) if defined($searchPart) && $searchPart !~ /^\s*$/; $inQuote = 1; } } # recreate a new search string $searchstring = join(" and ", @searchParts); # escape characters special to bool $searchstring =~ s/([()])/\\$1/g; } # parse out a line assume that we have syntax of: # phrase := word op phrase | word # op := and, or, near, not # detaint. Replace $searchstring =~ s/\"/"'/g; $searchstring = $1 if $searchstring =~ m/(.*)/; $argument = $1 if $argument =~ m/ (.*)/; $files = $1 if $files =~ m/(.*)/; print STDERR "$0: args: '$argument'\n" if $debug; print STDERR "$0: search: '$searchstring'\n" if $debug; print STDERR "$0: files: '$files'\n" if $debug; if ( $files ne "" ) { # that is we are searching files if ( $searchstring !~ m/^['"]*$/ ){ # look for stupid search # like for ' or " print STDERR "$0: $bool $argument \"$searchstring\" $files\n" if $debug; exec "$bool $argument \"$searchstring\" $files"; } else { print STDERR "$0: meaningless query\n" if $debug; } } else { # bool is great, but it doesn't work for grepping matching patterns # from stdin 8-(. print STDERR "$0: $fgrep $argument \"$searchstring\"\n" if $debug; exec "$fgrep $argument \"$searchstring\""; } } boolwrap(@ARGV);