diff options
Diffstat (limited to 'storage/ndb/tools/rgrep')
-rwxr-xr-x | storage/ndb/tools/rgrep | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/storage/ndb/tools/rgrep b/storage/ndb/tools/rgrep new file mode 100755 index 00000000000..212b068639d --- /dev/null +++ b/storage/ndb/tools/rgrep @@ -0,0 +1,194 @@ +#!/vobs/wds/swt/bin/perl + +die "Usage: rgrep [-iredblLn] regexp filepat ...\n rgrep -h for help\n" + if $#ARGV < $[; + +# Written by Piet van Oostrum <piet@cs.ruu.nl> +# This is really free software + +# Mats Lidell added support for gzip. +# Mats Lidell added support for skipping line numbers. + +$nextopt = 1; +$igncase = ''; +$regpat = 0; +$links = 0; +$error = 0; +$skipbin = 1; +$havenl = 1; +$debug = 0; + +do { $regexp = shift (@ARGV); } while &checkopt ($regexp); +$icreg = $igncase; +$igncase = ''; + +eval 'sub grep_file { + while (<F>) { + $ln++; + if (/$regexp/o' . $icreg .') { + print "$file:$ln:" if $havenl; + print "$_"; + print "\n" if substr($_, -1, 1) ne "\n"; + } + } +}'; + +for (@ARGV) { + if (! &checkopt ($_)) { + if ($igncase || $regpat || /[?*[]/ || ! -e) { + if ($regpat) { + s/#/\\#/g; + $_ = "#$_#"; + } else { # translate File pattern into regexp + $re = '#($|/)'; $save = $_; + while (/[[*?+()|.^$#]/) { + $re .= $`; + $c = $&; + $_ = $'; + if ($c eq '*') { $c = '[^/]*'; } + elsif ($c eq '?') { $c = '[^/]'; } + elsif ($c eq '[') { + if (/.\]/) { $c = "[$`$&"; $_ = $'; } + else { + $error++; + printf stderr "Illegal filepattern %s\n", $save; + } + } else { $c = "\\$c"; } + $re .= $c; + } + $_ = "$re$_\$#$igncase"; + } + print "filepat: $_\n" if $debug; + push (@filepat, $_); + } + else { push (@files, $_); print "file: $_\n" if $debug; } + } +} + +exit 1 if $errors ; + +if ($#filepat < $[) { + eval "sub in_pat {1;}" ; +} +else { + $subtxt = 'sub in_pat { local ($f) = @_;'; + $or = ""; + for (@filepat) { + $subtxt .= $or . '$f =~ m' . $_; + $or = " || "; + } + $subtxt .= ';};1'; + + if (! eval $subtxt) { + print $@; + exit 1; + } +} + +@files = (".") if $#files < $[; + +for $file (@files) { + &do_grep ($file); +} + +sub do_grep { + local ($file) = @_; + local (*F, $ln, $f, $g, @dirfiles); + if (-f $file) { + if (open (F, $file)) { + if (-B F) { # binary file -- may be compressed/compacted/gziped + if (($cx1 = getc(F)) eq "\377" && (getc(F) eq "\037")) { + open (F, "uncompact < $file|"); + if ($skipbin && -B F) { close (F); return; } + } + elsif ($cx1 eq "\037" && (($cx2 = getc(F)) eq "\235")) { + open (F, "uncompress < $file|"); + if ($skipbin && -B F) { close (F); return; } + } + elsif ($cx1 eq "\037" && $cx2 eq "\213") { + open (F, "gzip -d < $file|"); + if ($skipbin && -B F) { close (F); return; } + } + elsif ($skipbin) { + close (F); return; + } + } + print "Reading $file\n" if $debug; + &grep_file; + } else { + print stderr "Cannot open $file\n"; + } + } + elsif (-d $file) { + print "Entering $file\n" if $debug; + if (opendir (F, $file)) { + @dirfiles = readdir (F); + closedir (F); + for $f (@dirfiles) { + next if ($f eq '.' || $f eq '..'); + $g = "$file/$f"; + next if (-l $g && ($links < 1 || $links == 1 && -d $g)); + if (-f $g && &in_pat ($g) || -d _) { + &do_grep ($g); + } + } + } else { + print stderr "Can't open $file\n"; + } + } +} + +sub checkopt { + local ($_) = $_[0]; + if (/^-/ && $nextopt) { + $nextopt = 1; + @opt = split (/-*/,$_); shift (@opt); + for $opt (@opt) { + if ($opt eq 'i') { $igncase = 'i'; } + elsif ($opt eq 'd') { $debug = 1; } + elsif ($opt eq 'l') { $links = 1; } + elsif ($opt eq 'L') { $links = 2; } + elsif ($opt eq 'b') { $skipbin = 0; } + elsif ($opt eq 'r') { $regpat = 1; } + elsif ($opt eq 'e') { $nextopt = 0; } + elsif ($opt eq 'n') { $havenl = 0; } + elsif ($opt eq 'h' || $opt eq 'H') { & help; } + else { $error++; printf stderr "Unknown option -%s\n", $opt; } + } + return 1; + } + $nextopt = 1; + return 0; +} + +sub help { + print <<'HELP'; exit 0; +Usage: rgrep [-iredblL] regexp filepat ... + regexp = perl regular expression to search + filepat ... = a list of files and directories to be searched or + file patterns to match filenames. + filepat will be interpreted as file or directory name if it exists + as such, and does not contain the metacharacters [ ] ? or *. After + the options -i and -r all filepats will be considered patterns. + rgrep will search all files in any of the directories given (and its + subdirectories) that match any of the filepats, except binary files. + Compressed files will be searched in uncompressed form. + Note: filepats may contain / contrary to find usage. + -b Don't skip binary files. + -i Ignore case, either in the regexp or in filename matching (depending + on the location). Before the regexp only applies to the regexp, + otherwise to the filepats following it. + -r The following filepats are treated as real perl regexps rather than + shell style filename patterns. In this case / is not a special + character, i.e. it is matched by . and matching is not anchored (you + must supply ^ and $ yourself). E.g. a.b matches the file /xa/by/zz. + -l Do follow symbolic links only for files (default is do not follow). + -L Do follow symbolic links for files and directories. + -e Do not interpret following argument as option. Useful if regexp or + filepat starts with a -. + -d Debugging: Give a lot of output on what happens. + -n Don't precede each line by its relative line number in the file. + -h print this message and exit. +Piet van Oostrum <piet@cs.ruu.nl> +HELP +} |