home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume20 / cgrep / part01 / cgrep
Encoding:
Text File  |  1991-07-02  |  4.7 KB  |  188 lines

  1. #!/bin/perl
  2. #
  3. #    Copyright (C) 1991 by Lutz Prechelt, Karlsruhe
  4. #
  5. #    This program is free software; you can redistribute it and/or modify
  6. #    it under the terms of the GNU General Public License as published by
  7. #    the Free Software Foundation; either version 1, or (at your option)
  8. #    any later version.
  9. #    This program is distributed in the hope that it will be useful,
  10. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. #    GNU General Public License for more details.
  13. #    If you don't have a copy of the GNU General Public License write to
  14. #    Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15.  
  16. # Author: Lutz Prechelt (prechelt@ira.uka.de),
  17. #         23.03.91
  18. # Change: Lutz Prechelt, 02.07.91
  19. #
  20. # Usage: see message at "die" below.
  21.  
  22. $infinity = 10000;
  23.  
  24. $precontext  = 2;
  25. $postcontext = 2;
  26. $paragraphmode    = 0;
  27. $withlinenumber   = 0;
  28. $withfilename     = 0;
  29. $wrong_option     = 0;
  30. $reversemode      = 0;
  31. $delimiterstring  = "-----------\n";
  32. # $endpara = '\S.*\n';
  33.  
  34. sub showline {
  35.   if ($withfilename != 0) {
  36.     printf ("\"%s\"", $ARGV);
  37.   }
  38.   if ($withfilename != 0 && $withlinenumber != 0) {
  39.     print ",";
  40.   }
  41.   if ($withlinenumber != 0) {
  42.     printf ("%4d", $.);
  43.   }
  44.   if ($withfilename != 0 || $withlinenumber != 0) {
  45.     print ": ";
  46.   }
  47.   print ($_[0]);
  48. }
  49.  
  50.  
  51. # Process the Options:
  52. do {
  53.   $something_done = 1;
  54.   if ($ARGV[0] =~ /^-(\d+)$/) {
  55.     $precontext = $postcontext = $1;
  56.     shift;
  57.   }
  58.   elsif ($ARGV[0] =~ /^-(\d+)[\,\+\/\;](\d+)$/) {
  59.     $precontext  = $1;
  60.     $postcontext = $2;
  61.     shift;
  62.   }
  63.   elsif ($ARGV[0] =~ /^-d$/ && $#ARGV > 0) {
  64.     $delimiterstring = $ARGV[1];
  65.     $delimiterstring =~ s/\\n/\n/o;
  66.     shift; shift;
  67.   }
  68.   elsif ($ARGV[0] =~ /^-d(.*)$/) {
  69.     $delimiterstring = $1;
  70.     $delimiterstring =~ s/\\n/\n/o;
  71.     shift;
  72.   }
  73.   elsif ($ARGV[0] =~ /^-p$/) {
  74.     $paragraphmode = 1;
  75.     shift;
  76.   }
  77.   elsif ($ARGV[0] =~ /^-n$/) {
  78.     $withlinenumber = 1;
  79.     shift;
  80.   }
  81.   elsif ($ARGV[0] =~ /^-h$/) {
  82.     $withfilename = 1;
  83.     shift;
  84.   }
  85.   elsif ($ARGV[0] =~ /^-v$/) {
  86.     $reversemode = 1;
  87.     shift;
  88.   }
  89.   elsif ($ARGV[0] =~ /^-e$/) { # end options (for expressions starting with - )
  90.     $something_done = 0;
  91.     shift;
  92.   }
  93.   elsif ($ARGV[0] =~ /^-/) {
  94.     printf ("don't know option '%s'\n", $ARGV[0]);
  95.     $wrong_option = 1;
  96.     $something_done = 0;
  97.     shift;
  98.   }
  99.   else {
  100.     $something_done = 0;
  101.   }
  102. } while ($something_done);
  103.  
  104.  
  105. # Usage message:
  106. if ($#ARGV == -1 || $wrong_option) {
  107.   die "
  108.    Usage: cgrep [-pre[,post]] [-p] [-v] [-h] [-n] [-d string] pattern
  109. [file...]
  110.  
  111.    cgrep is a context grep. It displays more than the one matching line for
  112.    every match (2 before and 2 after as default).
  113.  
  114.    -3  means display 3 lines before and 3 lines after the match
  115.    -5,12  means display 5 lines before the match and 12 lines after
  116.    -p  means display only as much of the context as belongs to the
  117.        current paragraph. (paragraphs bounded by empty lines)
  118.    -v  means invert search (display nomatches)
  119.    -h  means toggle display filename before every line
  120.    -n  means display line number before every line
  121.    -d string  means use string as the output delimiter string
  122.    pattern  is a Perl regular expression (you better quote it !)
  123. Exiting";
  124. }
  125.  
  126.  
  127. if (length (@ARGV) > 1) {
  128.   $withfilename = !$withfilename;
  129. }
  130.  
  131.  
  132. # Get the pattern and protect the delimiter.
  133. $pat = shift;
  134. $pat =~ s#/#\\/#g;
  135.  
  136.  
  137. # current line will always be at end of array, i.e. $ary[$currentpre]
  138. $_ = <>;
  139. push(@ary,$_);
  140. $currentpre = 0;
  141.  
  142.  
  143. # now use @ary as a silo, shifting and pushing.
  144. # the length of the @ary at any time is $currentpre + 1
  145. # the current line is @ary[$currentpre], the postcontext is not held in @ary.
  146. $seq = 0;
  147. $lastoutput = $infinity;  #last output is infinitely many lines ago
  148. $cur = @ary[0];       #current line
  149. while ($cur) {  #as long as there is something to look at
  150.   if ($reversemode == 1 ? $cur !~ /$pat/o : $cur =~ /$pat/o) {   #match found
  151.     if ($lastoutput <= $postcontext) {
  152.       &showline ($cur);
  153.     }
  154.     else {
  155.       print $delimiterstring if ($seq++ && $precontext + $postcontext > 0);
  156.       foreach $line (@ary) {
  157.         &showline ($line);
  158.       }
  159.     }
  160.     $lastoutput = 0;
  161.   }
  162.   elsif (($cur !~ /\S.*\n/o && $paragraphmode == 1) || eof) {
  163. #paragraph/file end
  164.     for (; $currentpre >= 0; $currentpre--) {
  165.       shift (@ary);
  166.     }
  167.     $lastoutput = $infinity;
  168.     close (ARGV) if (eof);
  169.   }
  170.   elsif ($lastoutput <= $postcontext) {     #another line of postcontext
  171.     &showline ($cur);
  172.   }
  173.   #goto next line of input:
  174.   $lastoutput++;
  175.   $_ = <> if $_;
  176.   push(@ary,$_); 
  177.   if ($currentpre < $precontext) {
  178.     $currentpre++;
  179.   }
  180.   else {
  181.     shift(@ary);
  182.   }
  183.   $cur = $ary[$currentpre];
  184. }
  185.  
  186.  
  187.  
  188.