#****************************************************************************
#  ##   ##         #####   #####  ##     **        NoSQL RDBMS - uniq       *
#  ###  ##        ####### ####### ##     **        $Revision: 2.1 $			*
#  #### ##        ###     ##   ## ##     ************************************
#  #######  ####  #####   ##   ## ##     **      Carlo Strozzi (c) 1998     *
#  ####### ######   ##### ## # ## ##     ************************************
#  ## #### ##  ##     ### ##  ### ##     **           Adapted by            *
#  ##  ### ###### ####### ######  ###### **          Carlo Strozzi          *
#  ##   ##  ####   #####   #### # ###### **     e-mail: carlos@linux.it     *
#****************************************************************************
#   NoSQL RDBMS, Copyright (C) 1998 Carlo Strozzi.                          *
#   This program comes with ABSOLUTELY NO WARRANTY; for details             *
#   refer to the GNU General Public License.                                *
#****************************************************************************
# Original code: uniqtbl,v 2.4 1993/03/29 13:34:46 hobbs
#****************************************************************************

$0 =~ s-.*/-- ;
while ( ($_ = $ARGV[0]) =~ /^-/ ) {			# Get args
    if( /^-D.*/ || /^--count$/ ){ $DIG++ ; shift ; $remov = 0 ; next ; }
    if( /^-g.*/ || /^--groups$/ ){ $GRP++ ; shift ; next ; }
    if( /^-v.*/ || /^--revert$/ ){ $INV++ ; shift ; next ; }
    die "\n$0: unknown option: $_\n" ; 
}
while(<STDIN>){					# read header + 1 or 2 rows
    push( @f3, $_ ) ;
    next if /^\s*#/ ;	# comment
    chop ;
    if( ++$lln == 1 ){
	@H = split( /\t/, $_ ) ; # column names
	$nrf = @H ; }		 # nr of fields 
    elsif( $GRP && $lln == 2 ){
	last ; }
    elsif( $lln == 3 ){
	@P = split( /\t/, $_ ) ; # 1st data line
	last ; } }
&get_col_x ;
print @f3 ;
unless( $GRP ){ &do_reg ; }	# read data, regular case
else{ &do_grp ; }		# read data, group   case

sub do_reg {						# regular case
    while(<STDIN>){			# read the data 
	chop ;
	@D = split( /\t/, $_, $nrf );
	if( &chksame ){
	    $remov++ ;
	    next ; }
	print $_, "\n" ;
    }
    print STDERR "Rows Removed: $remov\n" if $DIG ;
}
sub do_grp {						# group case
    chop( $_sav = <STDIN> ) ;
    @p = split( /\t/, $_sav, $nrf );
    while(<STDIN>){			# read the data 
	chop ;
	@D = split( /\t/, $_, $nrf );
	if( &chksame ){
	    if( ! $ingrp ){
		$remov++ ;
		$x = @D -1 ;
		print "\t" x $x, "\n" ; # blank row
		print $_sav, "\n" ; }
	    $ingrp++ ;
	    print $_, "\n" ; }
	else{
	    $_sav = $_ ;
	    $ingrp = 0 ; }
    }
    print STDERR "Nr Groups: $remov\n" if $DIG ;
}
sub chksame {	# return 1 if @D and @P are same on spec cols, else 0.
    $val = 1 ;
    for $x (@n) {
	if( $D[$x] ne $P[$x] ){
	    $val = 0 ;
	    last ; }
    }
    @P = @D ;
    $val ;
}
sub get_col_x {		# get, chk column indexes, inc -v, die if bad column
			# uses @H, $INV, put indexes in @n.
    local( $f, $ok, @nn ) ;
    for $arg (@ARGV){
	for( $ok=$f=0 ; $f < @H ; $f++ ){
	    if( $arg eq $H[$f] ){	# match existing column
		$ok++ ;
		push( @n, $f );
		last ; }
	}
	die "\n$0: bad column name: $arg\n" if ! $ok ;
    }
    if( $INV ){					# inverse option
	loop: for( $f=0 ; $f < @H ; $f++ ){
	    for $i (@n){
		next loop if $i eq $f ; }
	    push( @nn, $f ); }
	@n = @nn ;
    }
}
