#!/afs/athena/contrib/perl/perl
$RCS_ID = '$Id: dataent,v 2.1 1992/06/16 09:26:34 hobbs Exp $' ;
$0 =~ s-.*/-- ;
$HelpInfo = <<EOH ;

	    RDB utility: $0

Usage:  $0  [options]  rdbtable
   or:  $0  [options]  -init  template

Options:
    -help    Print this help info.
    -init    Initiate a new rdbtable.
    -nbr     Do NOT remove leading and trailing blank space from data values.
    -prev    Use data values from previous row as defaults for current row.

This utility provides an interactive capability for entering data into an
rdbtable. The user is prompted by column name for data values.  Options may
be abbreviated.

In the first case of usage above, new rows of data are added at the end of an
existing rdbtable. In the second case, a template file is used to generate a
new rdbtable and add rows of data to it.

At each column name prompt the user may enter data followed by a <RET> or
just a <RET> to retain the current value, which is initially null.  Normally
leading and trailing blank space is removed from data values.  If it is desired
to prevent this enter a backslash (\\) as the first character (the backslash
will be removed) or use the '-nbr' option.  In order to replace an existing data
value with a null value enter a backslash (\\) and a <RET>.

At any column name prompt, if a single space character is entered, followed by
a <RET>, control is transferred to the end of row action prompt.  This is
useful if not all data values need to be entered on all rows.  If two space
characters followed by a <RET> is entered control is transferred to the
previous column name prompt. This is useful if an error was made entering data;
it can be corrected immediately.

After all the column name prompts for a row have been responded to, the user is
asked for the next action. The default is to save the current row of data to
the rdbtable and go on to enter data for the next row. Other options available
are to go back and check each value of the current row; to quit, saving or not
saving the current row; to list the data values for the entire row; to delete
the current row and start a new one; to jump back to a specified column name
prompt for the current row and continue from there; or to produce a help
listing.  Also the setting of the '-nbr' and '-prev' options may be toggled on
or off.

At any time an INTERRUPT signal (^C or DEL) may be entered to abort the
program.  In this case all rows of data except the current one will be saved.

Uses RDB operator: headchg.

$RCS_ID
EOH

$SIG{'INT'} = 'catch' ;
while ( $ARGV[0] =~ /^-/ ){				# Get args
    $_ = shift ;
    if( /-h.*/ ){ print $HelpInfo ; exit; }
    if( /-i.*/ ){ $INIT++ ; next ; }
    if( /-n.*/ ){ $NBRM++ ; next ; }
    if( /-p.*/ ){ $PREV++ ; next ; }
    if( /-x.*/ ){ $XBUG++ ; next ; }
    die "Bad arg: $_\n", $HelpInfo ; }
$file = shift ;
if( ! $file ){ die "No file given\n", $HelpInfo ; }
if( $INIT ){					# init a new rdbtable
    @F = `headchg -gen -q $file` ;
    for $_ (@F){
	next if /^#\s|^\s+#/ ;	# comment
	chop( $y = $_ ) ;	# col name line
	last ; }
    @H = split( "\t", $y ) ;
    if( $file =~ /\.[^.]*$/ && $& ne '.rdb' ){	# get new filename
	$new = "$`.rdb" ; }		# form:  xxx.rdb
    else{
	$new = "$file.rdb" ; }	# safety valve
    if( -f $new ){				# chk if $new exists 
	print STDERR "\nFile $new exists, Add new data to end? " ;
	$a = <STDIN> ;
	die "Aborting\n" if $a !~ /^y/i ;
	open( UT, ">>$new" ) || die "Can't open output: $new\n" ; }
    else{
	open( UT, ">$new" ) || die "Can't open output: $new\n" ;
	print UT @F ; }		# header of new rdbtable 
}
else{						# add to existing rdbtable
    open( FI, $file ) || die "Can't open input: $file\n" ;
    while(<FI>){
	next if /^#\s|^\s+#/ ;	# comment
	chop ;			# col name line of header
	last ; }
    @H = split( "\t", $_ ) ;
    close FI ;
    open( UT, ">>$file" ) || die "Can't open output: $file\n" ;
}
for( $i=0 ; $i < @H ; $i++ ){ $dat[$i] = "" ; }
main: while( 1 ){					# main loop
    unless( $do_over ){			# clear row
	print "New Row ...\n" ;
	if( ! $PREV ){
	    for( $i=0 ; $i < @H ; $i++ ){ $dat[$i] = "" ; } }
	$#dat = $#H ; }
    for( $i=$ii ; $i < @H ; $i++ ){	# print values, if any, prompts
	if( $dat[$i] ){
	    printf( "%12s: (%s) ", $H[$i], $dat[$i] ) ; }
	else{
	    printf( "%12s: ", $H[$i] ) ; }
	chop( $v = <STDIN> ) ;
	if( $v eq ' ' ){		# go to end of row action prompt
	    last ; }
	if( $v eq '  ' ){		# back up a column
	    $i--  if $i > 0 ;
	    print "\n" ;
	    redo ; }
	if( $v ){			# save data value
	    unless( ($v =~ s/^\\// ) || $NBRM ){
		$v =~ s/^\s+// ;
		$v =~ s/\s+$// ;
	    }
	    if( $v =~ s/\t/ /g ){
		warn "TAB chars removed\n" ; }
	    $dat[$i] = $v ;
	}
    }
    while( 1 ){						# ACTION prompt
	$do_over = $ii = 0 ;
        print "ACTION? (save, check, quit, list, del, jump NAME, help) [save] ";
	chop( $a = <STDIN> ) ;
	if( $a =~ /^s/ || $a eq "" ){		# new row in rdbtable
	    print UT join( "\t", @dat ), "\n" ;
	    last ; }
	elsif( $a =~ /^c/ || $a =~ /^ / ){	# check row again
	    print "\n" ;
	    $do_over++ ;
	    last ; }
	elsif( $a =~ /^l/ ){			# list entire row
	    print "\n" ;
	    for( $i=0 ; $i < @H ; $i++ ){
		if( $dat[$i] ){
		    printf( "%12s: (%s)\n", $H[$i], $dat[$i] ) ; }
		else{
		    printf( "%12s:\n", $H[$i] ) ; } } }
	elsif( $a =~ /^q/ ){			# quit
	    if( $a =~ /^q\S*\s+\S/ ){			# del row
		last main ; }
	    print UT join( "\t", @dat ), "\n" ;		# save row
	    last main ; }
	elsif( $a =~ /^d/ ){			# del this row, continue
	    last ; }
	elsif( $a =~ /^j\S*\s+(\S+)/ ){		# jump to column, do over
	    $x = $1 ;
	    for( $i=0 ; $i < @H ; $i++ ){
		if( $H[$i] =~ /^$x/ ){
		    $ii = $i ;
		    last ; }
	    }
	    $do_over++ ;
	    last ; }
	elsif( $a =~ /^-/ ){			# toggle option
	    if( $a =~ /^-p/ ){
		if( $PREV ){ $PREV = 0 ; print "\n\t>>> -prev OFF\n\n" ; }
		else{ $PREV++ ; print "\n\t>>> -prev ON\n\n" ; } }
	    if( $a =~ /^-n/ ){
		if( $NBRM ){ $NBRM = 0 ; print "\n\t>>> -nbr OFF\n\n" ; }
		else{ $NBRM++ ; print "\n\t>>> -nbr ON\n\n" ; } }
	}
	elsif( $a =~ /^h/ ){			# help listing
	    print <<EOP ;

save    - save row, continue.
check   - check each data value for this row again.
quit    - save row, quit program.
quit no - do NOT save row, quit program.
list    - List data values for entire row.
del     - delete this row, start new row.
jump NAME - jump back to column NAME, check rest of row.
INTERRUPT (^C or DEL) - abort the program, discarding the current row.

At any column name prompt:
a space char & <RET>    - jump to the end of row action prompt.
two space chars & <RET> - jump back to the previous column name prompt.

Options and column names may be abbreviated.

EOP
	}
	else{ print "What ?\n" ; }
    }
}
sub catch {			# catch INTs, save data to rdbtable
    close UT ;
    exit ;
}
