#!/qds/opt/tools/bin/perl

#
# This PERL script updates the src/ directory (which is where this
# script assumes it lives) with files from the "vc" directories.  Only
# files that are different are updated.  The files processed in this
# update are *.C, *.h and *.table files. This script also updates the
# "vc" directory version of the store_module files from their home, in
# the src/ directory.  This update will only be done if the
# store_module files are different and the version in src/ is more
# recent than the version in the "vc" directory.  
#
# Usage:
#
#   This script has no arguments.  The script assumes that it is in the
#   src/ directory and will now work properly if it is executed from outside.
#   To execute the script enter
#
#     perl <script_name>
#
# Ian Kaplan 12/96
#


  &main();

sub main {
  local($root) = "/vobs/quest/Import";
  local($path) = "$root/vc";
  local( $i, $test );

  &get_dirs( $path );

  $index = 0;
  for ($i = 0; $dirlist[ $i ]; ++$i) {
      # don't want to do the src directory and the store directory is special
      if ($dirlist[ $i ] ne "store" && $dirlist[ $i ] ne "src") {
	  &get_files( $path, $dirlist[ $i ] );
      }
  }

  &get_diff_files();

  if (@diff_file) {
      print "Preparing to update these files in the source directory:\n";
      for ($i = 0; $diff_full_path[ $i ]; ++$i) {
	  print "$diff_full_path[ $i ]\n";
      }
      print "Ok? (y/n, default y) ";
      $test = <STDIN>;
      if ($test ne "n\n") {
	  &check_out_files_in_src();
	  ©_files();
	  &check_in_files_in_src();
      }
  }
  else {
      print "No differences found\n";
  }

  &do_store_module( $path );

  print "\nFiles in src/ that are not checked into clearcase:\n";
  system("cleartool ls | fgrep -v Rule");
} # main


#
# do_store_module
#
# The store_module files that build net lists from information
# supplied by "vc" are special, in that their home directory is
# src/.  Updates are done from src/ to vc/store.  This PERL subroutine
# makes this update.  Note that the update is not done if the files
# are not different, or if the time stamp of the file in vc/store
# is newer than the file in src/
#
# As new files are added for store_module, add their names to
# the @store_module_file list.
#

sub do_store_module {
    (local $path ) = @_;
    (local $store_module_dir ) = "$path/store";
    (local @store_module_files) = ("store_module.C", "store_local.h");
    (local $time_src, $time_vc);
    (local $i, $tmp, $different);

    # yet another variation on list iteration
    for ($i = 0; @store_module_files; ++$i) {
	$tmp = pop( @store_module_files );
	$time_src = -M $tmp;
	$time_vc = -M "$path/store/$tmp";
	$different = system("diff $tmp $path/store/$tmp > /dev/null");
	if ($time_vc < $time_src && $different) {
	    print "Warning: the version of $tmp in $path/store\n";
	    print "         is newer than the version in src/ and the files differ.\n";
	    print "         No update of $path/store will be done.\n";
	}
	elsif ($different) {
	    print "Updating the copy of $tmp in $path/store\n";
	    system("cleartool co -nc $path/store/$tmp");
	    print "copying $tmp to $path/store/$tmp\n";
	    system("cp $tmp $path/store/$tmp");
	    system("cleartool ci -nc $path/store/$tmp");
	}
    }
} # do_store_module



#
# check_out_files_in_src
#
# Check out files in the src/ directory (the assumed home
# of this script).
# 

sub check_out_files_in_src()
{
    local( $i );

    if (@diff_file) {
	print "In src/ directory\n";
    }
    for ($i = 0; $diff_file[ $i ]; ++$i) {
	system("cleartool co -nc $diff_file[ $i ]");
    }
} # check_out_files_in_src



#
# check_in_files_in_src
#
# Check in files in the src/ directory (the assumed home
# of this script).
# 

sub check_in_files_in_src()
{
    local( $i );

    if (@diff_file) {
	print "In src/ directory\n";
    }
    for ($i = 0; $diff_file[ $i ]; ++$i) {
	system("cleartool ci -nc $diff_file[ $i ]");
    }
} # check_in_files_in_src



#
# copy_files
#
# Copy files from the "vc" directories into the src/ directories
# (note that src/ is the assumed home of this script).
#

sub copy_files {
    local( $i );

    for ($i = 0; $diff_full_path[ $i ]; ++$i) {
	print "copying $diff_full_path[ $i ] to $diff_file[ $i ]\n";
	system("cp $diff_full_path[ $i ] $diff_file[ $i ]");
    }    
} # copy_files




#
# get_diff_files
#
# This function iterates through the global list $full_path_list and
# find files that differ when compared to the same file in the src/
# directory.  It returns two global lists, $diff_file, which contains
# the file name (without the path) and $diff_full_path, which contains
# the full file name in the "vc" directory.
#

sub get_diff_files {
    local( $result, $i, $cnt );

    $cnt = 0;
    print "\nLooking for files to update....\n";
    for ($i = 0; $full_path_list[ $i ]; ++$i) {
	$result = system("diff $file_list[ $i ] $full_path_list[ $i ] > /dev/null");
	if ($result) {
	    $diff_file[ $cnt ] = $file_list[ $i ];
	    $diff_full_path[ $cnt ] = $full_path_list[ $i ];
	    ++$cnt;
	}
    }
} # get_diff_files



#
# get_files
#
# This function is passed a root path (e.g., the path for the "vc" directory)
# and a directory name.  This function returns two global lists - $file_list
# and $full_path_list that contain the *.C, *.h and *.table files from
# the directory argument.
#

sub get_files {
    local( $path, $filename ) = @_;
    local( $full_filename ) = "$path/$filename";
    local( $i );
    
    opendir(FILEPTR, $full_filename) || die "error opening ", $full_filename, "\n";
    local(@local_files) = readdir(FILEPTR);
    closedir( FILEPTR );

    for ($i = 0; $local_files[ $i ]; ++$i) {
        # file all the files that end with .C
	if ($local_files[ $i ] =~ /.C$/) {
	    $file_list[ $index ] = $local_files[ $i ];
	    $full_path_list[ $index ] = "$full_filename/$local_files[ $i ]";
	    ++$index;
	}
	if ($local_files[ $i ] =~ /.h$/) {
	    $file_list[ $index ] = $local_files[ $i ];
	    $full_path_list[ $index ] = "$full_filename/$local_files[ $i ]";
	    ++$index;
	}
	if ($local_files[ $i ] =~ /.table$/) {
	    $file_list[ $index ] = $local_files[ $i ];
	    $full_path_list[ $index ] = "$full_filename/$local_files[ $i ]";
	    ++$index;
	}
    } # for

} # get_files



#
# get_dirs
#
# This function is passed a the path to the "vc" directory.  It returns
# the global list @dirlist, containing all the files that are directories
# in this list.
#

sub get_dirs {
    local( $path ) = @_;
    local( $filecnt ) = 0;
    local( $dircnt ) = 0;

    opendir(TOPDIR, $path) || die "error opening ", $path;
      local(@topfiles) = readdir(TOPDIR);
    closedir(TOPDIR);

    while ($topfiles[ $filecnt] ) {
	if ( $topfiles[ $filecnt ] ne "." && $topfiles[ $filecnt ] ne "..") {

	    local($filename) = "$path/$topfiles[ $filecnt ]";
            # -d operator checks to see if filename is a directory
	    if ( -d $filename) {
		# dirlist is a return value - global
		$dirlist[ $dircnt ] = $topfiles[ $filecnt ];
		++$dircnt;
	    }

	}
	++$filecnt;
    } # for
} # get_dirs