#!/usr/bin/perl
# Original code: compute,v 2.6 1994/11/09 10:43:59 hobbs
#
$RCS_ID = '$Id: nsq-compute,v 1.0 1998/05/14 11:07:04 carlos Exp $' ;
$0 =~ s-.*/-- ;
$HelpInfo = <<EOH ;

	    NoSQL operator: $0

Usage:  $0  [options]  [statements]

Options:
    -fXXX    The statements are in the file 'XXX', instead of on the 
             command line. The advantage in this case is that no quoting
             of chars that might be special to the UNIX shell is necessary.
    -help    Print this help info.
    -x       Debug option.

Computes values for data fields based on arbitrary statements using
column names. Chars that are special to the UNIX shell must be quoted.

Comparsion operators may be of the form: gt, ge, lt, le, eq, ne.  E.g
'column eq Hobbs'.  Logical constructors 'or' and 'and' may be used; as
well as 'null' to indicate an empty data value.

This operator reads an rdbtable via STDIN and writes a rdbtable via STDOUT.
Options may be abbreviated.

$RCS_ID

			----------------------
NoSQL RDBMS, Copyright (C) 1998 Carlo Strozzi.
This program comes with ABSOLUTELY NO WARRANTY; for details
refer to the GNU General Public License.

You should have received a copy of the GNU General Public License
along with this program;  if not, write to the Free Software
Foundation, Inc., 59 Temple Place Suite 330, Boston, MA 02111-1307
USA.
			----------------------

EOH
%cmpop = ( "lt", "<", "le", "<=", "gt", ">", "ge", ">=", # cmp opers
	   "eq", "==", "ne", "!="  ) ;
%resw  = ( "or", "||", "and", "&&", "null", "\"\"" ) ;# reserved words
while ( $ARGV[0] =~ /^-/ ) {				# Get args
    $_ = shift ;
    if( /-f(\S+)/ ) { $FEXP = $1 ; next ; }
    if( /^-h.*/ ){ print $HelpInfo ; exit 1 ; }
    if( /-x.*/ ){ $XBUG++ ; next ; }
    die "\nBad arg: $_\n", "For help type \"$0 -help\".\n" ; 
}
while(<STDIN>){
    print ;
    next if /^\s*#/ ;			# comment
    chop ;
    @F = split( /\t/, $_ );
    if( ++$lln == 1 ){					# col name line
	@H = @F ; # save headers
	$nrf = @H ;	# nr of fields
	next ; }
    if( $lln == 2 ){					# col define line
	if( $FEXP ){			# exp from file
	    open( FEXP ) || die "\nCan't open input: $FEXP\n" ;
	    while( <FEXP> ){
		s/(^|\s+)#.*$// ;	# skip comments
		$x .= $_ ; }
	    @ARGV = split( ' ', $x ) ; }
	for $arg ( @ARGV ){
	    &convert ; }
	push( @ARGV, ";" ) if $ARGV[$#ARGV] ne ';' ;
	$exp = join( ' ', @ARGV ) ;
	$prog = <<EOP ;
	while(<STDIN>){
	    chop ;
	    \@F = split( /\\t/, \$_, $nrf );
	    $exp 
	    print join( "\\t", \@F ), "\\n" ;
	}
EOP
	last ;
    }
}
# print STDERR $prog, "\n" if $XBUG ;
print STDERR $prog if $XBUG ;	# chg for perl5 
eval( $prog ) ;
print STDERR $@ if $@ ;

sub convert {				# chk and convert $arg if necessary
    for( $f=0 ; $f <= $#H ; $f++ ){
	if( $arg eq $H[$f] ){		# col name trans
	    $arg = '$F[' . $f . ']' ;	# defn line
	    if( $F[$f] =~ /(\S+)/ && $1 =~ /N/i ){
		$numf++ ; # num data flag
	    }
	    return ;
	}
    }
    if( $numf && $cmpop{$arg} ){ # numeric op trans
	$arg = $cmpop{$arg} ;
    }
    else{				# quote leading zeros
	$arg = '"' . $arg . '"' if $arg =~ /^0/ ;
    }
    $numf = "" ;
    if( $resw{$arg} ){	# reserved word chk
	$arg = $resw{$arg} ;
    }
}
