#!perl -w
# $Id: insert.pl,v 1.3 2004/09/30 07:34:13 jlinoff Exp $
#
# This perl script inserts text fragments at specified points in
# source files. The insertion points are specified by tags in
# the source files. To insert the copyright notice, the user
# inserts tags in the source files. The tags are arbitrary and
# are specified on the insert.pl command line.
#
# To insert the arbitrary information automatically the user would
# create a text document that contains the copyright notice, insert
# tags into the text and then run this tool to automatically insert
# the text.
#
# The best way to understand this is to present an example. For
# the copyright notice a text file called copyright.txt was created
# and the tags //@copyright_begin and //@copyright_end were defined
# and inserted in the code. To do the insertion, this script is run
# as follows:
#
#   perl insert.pl -c -i copyright.txt -b @copyright_begin -e @copyright_end *.cc *.h
#
# It is used to insert the copyright notice and help text.
#
use strict;
&Main;

# ================================================
# Main
# ================================================
sub Main {
  # ================================================
  # Initialize variables.
  # ================================================
  my $verbose = 0;
  my $ifile = "";
  my $cflag = 0;
  my $sflag = 0;
  my $btag = "";
  my $etag = "";
  my @files = ();

  # ================================================
  # Parse switches.
  # ================================================
  while ( $#ARGV >= 0 ) {
    my $arg = shift @ARGV;
    if( $arg eq "-c" ) {
      $cflag = 1;
    }
    elsif( $arg eq "-s" ) {
      $sflag = 1;
    }
    elsif( $arg eq "-b" ) {
      $arg = shift @ARGV;
      $btag = $arg;
    }
    elsif( $arg eq "-e" ) {
      $arg = shift @ARGV;
      $etag = $arg;
    }
    elsif( $arg eq "-i" ) {
      $arg = shift @ARGV;
      $ifile = $arg;
    }
    elsif( $arg eq "-h" || $arg eq "-help" ) {
      &Usage;
      exit 0;
    }
    elsif( $arg eq "-v" ) {
      $verbose = 1;
    }
    else {
      push @files,$arg;
    }
  }

  # ================================================
  # Check for switch errors.
  # ================================================
  if( $cflag && $sflag ) {
    print STDERR "ERROR: -c and -s switches are mutually exclusive\n";
    exit 1;
  }
  if( $btag eq "" ) {
    print STDERR "ERROR: -b <tag> not specified.\n";
    exit 1;
  }
  if( $etag eq "" ) {
    print STDERR "ERROR: -e <tag> not specified.\n";
    exit 1;
  }

  # ================================================
  # Process each file.
  # ================================================
  my $file;
  foreach $file ( @files ) {
    &Process($ifile,
	     $btag,
	     $etag,
	     $verbose,
	     $cflag,
	     $sflag,
	     $file);
  }
}

# ================================================
# Process
# ================================================
sub Process {
  my $ifile = shift;
  my $btag = shift;
  my $etag = shift;
  my $verbose = shift;
  my $cflag = shift;
  my $sflag = shift;
  my $file = shift;

  print "processing $file: " if( $verbose );

  if( ! -w $file ) {
    print STDERR "\nERROR: File '$file' is not writeable.\n";
    return;
  }
  if( ! -r $ifile ) {
    print STDERR "\nERROR: Copyright file '$file' is not readable.\n";
    return;
  }

  my $cnt = 0;
  open IFP,"$file" || die "\nERROR: Can't read '$file'.\n";
  open OFP,">$file.tmp" || die "\nERROR: Can't read '$file.tmp'.\n";
  while( <IFP> ) {
    chop;
    my $line = $_;
    if( $line =~ /${btag}/ ) {
      $cnt++;
      print OFP "$line\n";
      open CFP,"$ifile" || die "\nERROR: Can't read '$ifile'.\n";
      while( <CFP> ) {
	chop;
	$line = $_;
	if( $cflag ) {
	  print OFP "// $line\n";
	}
	elsif( $sflag ) {
	  chop;
	  print OFP "    << \"${line}\\n\"\n";
	}
	else {
	  print OFP "$line\n";
	}
      }
      close CFP;
      while( <IFP> ) {
	chop;
	$line = $_;
	if( $line =~ /${etag}/ ) {
	  print OFP "$line\n";
	  last;
	}
      }
    }
    else {
      print OFP "$line\n";
    }
  }
  close OFP;
  close IFP;
  rename "$file.tmp","$file";
  print "replaced $cnt occurences of $btag and $etag.\n" if( $verbose );
}
# ================================================
# Usage
# ================================================
sub Usage {
  my $X = "\$";
  print <<END

\$Id: insert.pl,v 1.3 2004/09/30 07:34:13 jlinoff Exp $X

usage: perl insert.pl [-c] [-i <file>] [-h] [-help] <files>

  -b <tag>   The name of the tag that marks the start of insertion.

  -c         Convert the text to comments. If this switch is
             not specified, the text is inserted verbatim.

  -e <tag>   The name of the tag that marks the end of insertion.
             Old data between the beginning and ending points is
             replaced.

  -h,-help   This help message.

  -i <file>  The insertion text.

  -s         Output data as stream strings.

  -v         Verbose mode. Report each file that is being processed.

  <files>    The files to substitute.

example:

  % perl copyright.pl -c copyright.txt *.c *.h

END
}

