#!/usr/bin/perl

#
# dbrow
# Copyright (C) 1991-1998 by John Heidemann <johnh@isi.edu>
# $Id: dbrow,v 1.19 2002/10/25 21:45:20 johnh Exp $
#
# This program is distributed under terms of the GNU general
# public license, version 2.  See the file COPYING
# in $dblibdir for details.
#
sub usage {
    print <<END;
usage: $0 condition [condition...]
    Select rows for which all conditions are true.
    Conditions are specified as Perl code.
    Column names can be embedded in the code if preceeded by underscores.

Options:   
    -v  select rows where the condition does NOT match
    -d  debug mode

Sample input:
#h account passwd uid gid fullname homedir shell
johnh * 2274 134 John_Heidemann /home/johnh /bin/bash
greg * 2275 134 Greg_Johnson /home/greg /bin/bash
root * 0 0 Root /root /bin/bash
# this is a simple database

Sample command:
cat DATA/passwd.jdb | dbrow '_fullname =~ /John/'

Sample output:
#h      account passwd  uid     gid     fullname        homedir shell
johnh   *       2274    134     John_Heidemann  /home/johnh     /bin/bash
greg    *       2275    134     Greg_Johnson    /home/greg      /bin/bash
# this is a simple database
#  | /home/johnh/BIN/DB/dbrow 

Bugs:
Doesn't detect references to unknown columns in conditions.
END
    #' for font-lock mode.
    exit 1;
}

require 5.000;
BEGIN {
    $dblibdir = "/usr/local/lib/jdb";
    push(@INC, $dblibdir);
}
require "$dblibdir/dblib.pl";
use DbGetopt;

my(@orig_argv) = @ARGV;
my($prog) = &progname;
my($debug) = 0;
my($negate) = 0;
my($dbopts) = new DbGetopt("dv?", \@ARGV);
my($ch);
while ($dbopts->getopt) {
    $ch = $dbopts->opt;
    if ($ch eq 'd') {
	$debug++;
    } elsif ($ch eq 'v') {
	$negate++;
    } else {
	&usage;
    };
};
&usage if ($#ARGV == -1 || $ARGV[0] =~ /^-/);

&readprocess_header;

$code = join(") && (", @ARGV);

$code = &codify($code);

&write_header();

my($negate_code) = $negate ? "!" : "";

my($loop) = q[
    while (<STDIN>) {
	&pass_comments && next;
	&split_cols;
	$result = ] . $negate_code . q[(] . $code . q[);
	&write_cols if ($result);
    };
];
if ($debug) {
    print STDERR "DEBUG:\n$loop\n";
    exit 1;
};
eval $loop;
$@ && die "$prog: error in eval code: $@\n";

$code =~ s/\n/ /g;   # otherwise comments break
print "#  | $prog ", join(" ", @orig_argv), "\n";
exit 0;
