#!/usr/bin/perl
#
# fu: finduses replacement, with the ability to specify the pattern
#     for an identifier on the command line.
#
# Usage: fu [pattern] [-noquote]
#
#   pattern is a Perl regexp for matching an identifier.
#   If you put parentheses in there, use (?: ... ) so that they
#   won't match outside the pattern!  If pattern is not given,
#   uses \w[\w\d]*, which matches C/C++ identifiers.
#
#   -noquote says not to look inside quoted code.
#
# Version 0.2 of 26 May 1997
#
# Author: Dan Schmidt <dfan@alum.mit.edu>
# Public domain.            

while ($opt = shift) {
  $noquote = 1, next if ($opt =~ /-noquote/);
  $pat = $opt;
}
$pat = "\\w[\\w\\d]*" if (! $pat);

# Ensure STDIN is seekable
$TMPFILE = "fu.tmp";
if (! -f STDIN) {
  open TMPFILE, "> $TMPFILE"
    or die "Couldn't open `$TMPFILE' for writing: $!; aborting";
  print TMPFILE while <STDIN>;
  close TMPFILE;
  open STDIN, "< $TMPFILE"
    or die "Couldn't open `$TMPFILE' for reading: $!; aborting";
  unlink $TMPFILE;
}

while (<>) {
  if (/^\@index defn (.*)$/) {
    foreach $defn (split " ", $1) {
      $is_defn{$defn} = 1;
    }
  }
}

seek (STDIN, 0, 0);

while (<>) {
  if ($incode) {
    if (/\@text (.*)/) {
      next if (length $1 == 0);
      $text = $1; $pretext = "";
      while ($text =~ /^(.*?)($pat)(.*)$/o) {
        if (defined $is_defn{$2}) {
          print "\@text $pretext$1\n\@index use $2\n\@text $2\n";
          $pretext = "";
        } else { $pretext .= $1 . $2; }
        $text = $3;
      }
      print "\@text $pretext$text\n" if (length $pretext || length $text);
      next;
    } elsif (/\@end/) { $incode = 0; }
  } elsif (/^\@begin code/ || ((! $noquote) && /^\@quote/)) { $incode = 1; }

  print;
}
