#! /bin/sh
perl -x -S $0 "$@"
exit

#! perl
require 5.003;
use strict;

# Copyright by The HDF Group.
# Copyright by the Board of Trustees of the University of Illinois.
# All rights reserved.
#
# This file is part of HDF5.  The full HDF5 copyright notice, including
# terms governing use, modification, and redistribution, is contained in
# the files COPYING and Copyright.html.  COPYING can be found at the root
# of the source code distribution tree; Copyright.html can be found at the
# root level of an installed copy of the electronic HDF5 document set and
# is linked from the top-level documents page.  It can also be found at
# http://hdfgroup.org/HDF5/doc/Copyright.html.  If you do not have
# access to either file, you may request a copy from help@hdfgroup.org.
#
# Robb Matzke <matzke@llnl.gov>
# 17 July 1998
# Modified 4 September 2009
# M. Scot Breitenfeld

### Purpose
# Increments the hdf5 HL library version number by changing the value of
# constants in the VERSION file.  The new version number is
# printed on the standard output. An alternate source file name can be
# specified as an argument.  In any case, the original file is saved
# by appending a tilde `~' to the name.

### Usage:
# h5vers [OPTIONS] [FILE]

# Without options this program only displays the current version and
# doesn't modify any files or create backups.  The default is to print
# the version number like X.Y.Z-A where X is the major version number,
# Y is the minor version number, Z is the release number, and A is
# a short annotation string (the `-' is printed only if A is not empty).
# If the `-v' switch is given the version will be printed like:
#
#    version X.Y release Z (A)
#
# The space and parentheses around A are only printed if A is not empty.
#
# The `-s VERSION' switch will set the version as specified.  If the
# string contains a dotted triple then it will be used as the version
# number, otherwise up to three numbers will be read from the end of
# the string and used as the major version, minor version, and release
# number.  If any numbers are missing then zero is assumed.  This
# allows versions to be specified like `-s "version 2.1 release 8"' or
# `-s hdf5-2.1.8.tar.bz2'.  If the new version is less than the old
# version then a warning message is generated on standard error. The
# annotation string, A, is set only if it appears immediately after the
# third number, separated by a dash (e.g., `1.2.3-pre1') or in parentheses
# (e.g., `version 1.2 release 3 (pre1)').
#
# The `-i [major|minor|release|annot|last]' option increments the major
# number, minor number, release number, or annotation string. The `last'
# switch increments the annotation string if present, otherwise the
# release number. If the release number is incremented then the annotation
# string is cleared.  If the minor number is incremented then the release
# number is set to zero and the annotation string is cleared; if the major
# number is incremented then the minor and release numbers are set to zero
# and the annotation string is cleared.
#
# If a file is specified then that file is used instead of
# VERSION.
#
# If the version number is changed (either `-s' or `-i' was used on
# the command line) then the first line of the README.txt and RELEASE.txt files
# in the main directory. The version number is also added to all the Makefiles.
#
##############################################################################

sub getvers {
  local ($_) = @_;
  my (@vers);

  ($vers[0]) = /^\#\s*define\s+H5_VERS_MAJOR\s+(\d+)/m;
  ($vers[1]) = /^\#\s*define\s+H5_VERS_MINOR\s+(\d+)/m;
  ($vers[2]) = /^\#\s*define\s+H5_VERS_RELEASE\s+(\d+)/m;
  ($vers[3]) = /^\#\s*define\s+H5_VERS_SUBRELEASE\s+\"([^\"]*)\"/m;
  return @vers;
}

sub setvers {
  my ($contents, @vers) = @_;
  $_[0] =~ s/^(\#\s*define\s+H5_VERS_MAJOR\s+)\d+/$1$vers[0]/m;
  $_[0] =~ s/^(\#\s*define\s+H5_VERS_MINOR\s+)\d+/$1$vers[1]/m;
  $_[0] =~ s/^(\#\s*define\s+H5_VERS_RELEASE\s+)\d+/$1$vers[2]/m;
  $_[0] =~ s/^(\#\s*define\s+H5_VERS_SUBRELEASE\s+\")[^\"]*/$1$vers[3]/m;
  $_[0] =~ s/^(\#\s*define\s+H5_VERS_INFO\s+\")[^\"]*/
    sprintf("%sHDF5_HL_REGION library version: %d.%d.%d%s%s", $1, @vers[0,1,2],
	    $vers[3]?"-":"", $vers[3])/me;
}

sub usage {
  my ($prog) = $0 =~ /([^\/]+)$/;
  print STDERR <<EOF;
Usage: $prog [OPTS] [FILE]
    -i major|minor|release|annot
        Increment specified version component and set following components
        to zero.
    -s VERSION
        Set the version as specified. The version number can be embedded in
        some other string such as \"hdf5-1.1.0-pre1.tar.bz2\" or even
        \"this is HDF5 library version 1.1 release 0 (pre1)\" for convenience.
    -v
        Instead of displaying only a dotted triple version number a line such
        as \"version 1.1 release 0 (pre1)\" will be printed.
    FILE
        The name of the file that contains version information.  This is
        seldom necessary since files H5public.h, src/H5public.h and
        ../src/H5public.h are automatically checked.
EOF
  exit 1;
}

# Parse arguments
my ($verbose, $set, $inc, $file, $rc);
my (@files) = ("VERSION");
while ($_ = shift) {
  $_ eq "-s" && do {
    die "-s switch needs a version number\n" unless @ARGV;
    $set = shift;
    next;
  };

  $_ eq "-i" && do {
    if (@ARGV && $ARGV[0]=~/^(major|minor|release|annot)$/) {
      $inc = shift;
    } else {
      $inc = "last";
    }
    next;
  };

  $_ eq "-v" && do {
    $verbose = 1;
    next;
  };

  /^-(h|\?|-?help)$/ && usage;
  /^-/ && die "unrecognized option: $_\n";
  die "only one file name can be specified\n" if $file;
  $file = $_;
}
die "mutually exclusive options given\n" if $set && $inc;

# Determine file to use as H5public.h, README.txt,
# release_docs/RELEASE.txt, configure.in, windows/src/H5pubconf.h,
# vms/src/h5pubcof.h and config/lt_vers.am. 
# The README.txt, release_docs/RELEASE.txt, configure.in, 
# windows/src/H5pubconf.h, vms/src/h5pubconf.h and config/lt_vers.am 
# files are always in the directory above H5public.h
unless ($file) {
  for (@files) {
    ($file=$_,last) if -f $_;
  }
}
die "unable to find source files\n" unless defined $file;
die "unable to read file: $file\n" unless -r $file;
# Makefile
my $MAKEFILE_MAIN = $file;
$MAKEFILE_MAIN =~ s/[^\/]*$/.\/Makefile/;
die "unable to read file: $MAKEFILE_MAIN\n" unless -r $file;
# README.txt
my $README = $file;
$README =~ s/[^\/]*$/.\/README.txt/;
die "unable to read file: $README\n" unless -r $file;
# doc/RELEASE.txt
my $RELEASE = $file;
$RELEASE =~ s/[^\/]*$/.\/doc\/RELEASE.txt/;
die "unable to read file: $RELEASE\n" unless -r $file;
# src/Makefile
my $MAKEFILE_SRC = $file;
$MAKEFILE_SRC =~ s/[^\/]*$/.\/src\/Makefile/;
die "unable to read file: $MAKEFILE_SRC\n" unless -r $file;
# test/Makefile
my $MAKEFILE_TEST = $file;
$MAKEFILE_TEST =~ s/[^\/]*$/.\/test\/Makefile/;
die "unable to read file: $MAKEFILE_TEST\n" unless -r $file;
# examples/Makefile
my $MAKEFILE_EXAMPLES = $file;
$MAKEFILE_EXAMPLES =~ s/[^\/]*$/.\/examples\/Makefile/;
die "unable to read file: $MAKEFILE_EXAMPLES\n" unless -r $file;

# Get the current version number.
open FILE, $file or die "unable to open $file: $!\n";
my ($contents) = join "", <FILE>;
close FILE;
my (@curver) = getvers $contents;



# Determine the new version number.
my @newver; #new version
if ($set) {
  if ($set =~ /(\d+)\.(\d+)\.(\d+)(-([a-zA-Z]\w*))?/) {
    @newver = ($1, $2, $3, $5);
  } elsif ($set =~ /(\d+)\D+(\d+)\D+(\d+)(\s*\(([a-zA-Z]\w*)\))?\D*$/) {
    @newver = ($1, $2, $3, $5);
  } elsif ($set =~ /(\d+)\D+(\d+)\D*$/) {
    @newver = ($1, $2, 0, "");
  } elsif ($set =~ /(\d+)\D*$/) {
    @newver = ($1, 0, 0, "");
  } else {
    die "illegal version number specified: $set\n";
  }
} elsif ($inc) {
  $inc = $curver[3] eq "" ? 'release' : 'annot' if $inc eq 'last';
  if ($inc eq "major") {
    $newver[0] = $curver[0]+1;
    @newver[1,2,3] = (0,0,"");
  } elsif ($inc eq "minor") {
    $newver[0] = $curver[0];
    $newver[1] = $curver[1]+1;
    @newver[2,3] = (0,"");
  } elsif ($inc eq "release") {
    @newver[0,1] = @curver[0,1];
    $newver[2] = $curver[2]+1;
    $newver[3] = "";
  } elsif ($inc eq "annot") {
    @newver[0,1,2] = @curver[0,1,2];
    $newver[3] = $curver[3];
    $newver[3] =~ s/(\d+)\D*$/$1+1/e or
      die "Annotation \"".$newver[3]."\" cannot be incremented.\n";
  } else {
    die "unknown increment field: $inc\n";
  }
} else {
# Update the README.txt file
  # Nothing to do but print result
  $README = "";
  $RELEASE = "";
  $MAKEFILE_SRC = "";
  $MAKEFILE_TEST = "";
  $MAKEFILE_EXAMPLES = "";
  $MAKEFILE_MAIN = "";
  @newver = @curver;
}

# Note if the version increased or decreased
my $version_increased="";
# Print a warning if the version got smaller (don't check annot field)
if ($newver[0]*1000000 + $newver[1]*1000 + $newver[2] <
    $curver[0]*1000000 + $curver[1]*1000 + $curver[2]) {
  printf STDERR "Warning: version decreased from %d.%d.%d to %d.%d.%d\n",
    @curver[0,1,2], @newver[0,1,2];
}
if ($newver[0]*1000000 + $newver[1]*1000 + $newver[2] >
    $curver[0]*1000000 + $curver[1]*1000 + $curver[2]) {
  $version_increased="true";
}

# Update the version number if it changed.
if ($newver[0]!=$curver[0] ||
    $newver[1]!=$curver[1] ||
    $newver[2]!=$curver[2] ||
    $newver[3]ne$curver[3]) {
  setvers $contents, @newver or die "unable to set version\n";
  rename $file, "$file~" or die "unable to save backup file\n";
  open FILE, ">$file" or die "unable to open $file but backup saved!\n";
  print FILE $contents;
  close FILE;
}
# Update the libtool shared library version in src/Makefile.am if
# the version number has increased.
# if ($MAKEFILE_MAIN && $version_increased) {
#   open FILE, $MAKEFILE_MAIN or die "$MAKEFILE_MAIN: $!\n";
#   my ($contentsy) = join "", <FILE>;
#   close FILE;

#   local($_) = $contentsy;

#   my ($lt_revision) = /^MAKEFILE_MAIN_REVISION\s*=\s*(\d+)/m;
#   my $new_lt_revision = $lt_revision+1;
#   ($contentsy) =~ s/^(MAKEFILE_MAIN_REVISION\s*=\s*)\d+/$1$new_lt_revision/m;

#   open FILE, ">$MAKEFILE_MAIN" or die "$MAKEFILE_MAIN: $!\n";
#   print FILE $contentsy;
#   close FILE;
# }


if ($README) {
  open FILE, $README or die "$README: $!\n";
  my @contents = <FILE>;
  close FILE;
  $contents[0] = sprintf(" HDF5 HL_REGION version %d.%d.%d%s %s",
			 @newver[0,1,2],
			 $newver[3] eq "" ? "" : "-".$newver[3],
			 "currently under development\n");
  open FILE, ">$README" or die "$README: $!\n";
  print FILE @contents;
  close FILE;
}

# Update the release_docs/RELEASE.txt file
if ($RELEASE) {
  open FILE, $RELEASE or die "$RELEASE: $!\n";
  my @contents = <FILE>;
  close FILE;
  $contents[0] = sprintf("HDF5 HL_REGION version %d.%d.%d%s %s",
			 @newver[0,1,2],
			 $newver[3] eq "" ? "" : "-".$newver[3],
			 "currently under development\n");
  open FILE, ">$RELEASE" or die "$RELEASE: $!\n";
  print FILE @contents;
  close FILE;
}

# Update the ./Makefile file
if ($MAKEFILE_MAIN) {
  open FILE, $MAKEFILE_MAIN or die "$MAKEFILE_MAIN: $!\n";
  my @contents = <FILE>;
  close FILE;
  $contents[0] = sprintf("# HDF5 HL_REGION version %d.%d.%d%s %s",
			 @newver[0,1,2],
			 $newver[3] eq "" ? "" : "-".$newver[3],
			 "currently under development\n");
  open FILE, ">$MAKEFILE_MAIN" or die "$MAKEFILE_MAIN: $!\n";
  print FILE @contents;
  close FILE;
}

# Update the ./src/Makefile file
if ($MAKEFILE_SRC) {
  open FILE, $MAKEFILE_SRC or die "$MAKEFILE_SRC: $!\n";
  my @contents = <FILE>;
  close FILE;
  $contents[0] = sprintf("# HDF5 HL_REGION version %d.%d.%d%s %s",
			 @newver[0,1,2],
			 $newver[3] eq "" ? "" : "-".$newver[3],
			 "currently under development\n");
  open FILE, ">$MAKEFILE_SRC" or die "$MAKEFILE_SRC: $!\n";
  print FILE @contents;
  close FILE;
}

# Update the ./examples/Makefile file
if ($MAKEFILE_EXAMPLES) {
  open FILE, $MAKEFILE_EXAMPLES or die "$MAKEFILE_EXAMPLES: $!\n";
  my @contents = <FILE>;
  close FILE;
  $contents[0] = sprintf("# HDF5 HL_REGION version %d.%d.%d%s %s",
			 @newver[0,1,2],
			 $newver[3] eq "" ? "" : "-".$newver[3],
			 "currently under development\n");
  open FILE, ">$MAKEFILE_EXAMPLES" or die "$MAKEFILE_EXAMPLES: $!\n";
  print FILE @contents;
  close FILE;
}


# Update the ./test/Makefile file
if ($MAKEFILE_TEST) {
  open FILE, $MAKEFILE_TEST or die "$MAKEFILE_TEST: $!\n";
  my @contents = <FILE>;
  close FILE;
  $contents[0] = sprintf("# HDF5 HL_REGION version %d.%d.%d%s %s",
			 @newver[0,1,2],
			 $newver[3] eq "" ? "" : "-".$newver[3],
			 "currently under development\n");
  open FILE, ">$MAKEFILE_TEST" or die "$MAKEFILE_TEST: $!\n";
  print FILE @contents;
  close FILE;
}


# # Update the configure.in files and regenerate them
# gen_configure("HDF5", $MAKEFILE_SRC) if $MAKEFILE_SRC;

# sub gen_h5pubconf {
#     my ($name, $pubconf, @vers) = @_;

#     my $namelc = lc($name);
#     my $nameuc = uc($name);

#     open FILE, $pubconf or die "$pubconf: $!\n";
#     my @contents = <FILE>;
#     close FILE;

#     for (my $i = 0; $i < $#contents; ++$i) {
# 	if ($contents[$i] =~ /\#\s*define\s+H5_PACKAGE\s+/) {
# 	    $contents[$i] = "\#define H5_PACKAGE \"$namelc\"\n";
# 	} elsif ($contents[$i] =~ /\#\s*define\s+H5_PACKAGE_NAME\s+/) {
# 	    $contents[$i] = "\#define H5_PACKAGE_NAME \"$nameuc\"\n";
# 	} elsif ($contents[$i] =~ /\#\s*define\s+H5_PACKAGE_STRING\s+/) {
# 	    $contents[$i] = sprintf("\#define H5_PACKAGE_STRING \"$nameuc %d.%d.%d%s\"\n",
# 				    @vers[0,1,2],
# 				    $newver[3] eq "" ? "" : "-".$newver[3]);
# 	} elsif ($contents[$i] =~ /\#\s*define\s+H5_PACKAGE_TARNAME\s+/) {
# 	    $contents[$i] = "\#define H5_PACKAGE_TARNAME \"$namelc\"\n";
# 	} elsif ($contents[$i] =~ /\#\s*define\s+H5_PACKAGE_VERSION\s+/) {
# 	    $contents[$i] = sprintf("\#define H5_PACKAGE_VERSION \"%d.%d.%d%s\"\n",
# 				    @vers[0,1,2],
# 				    $newver[3] eq "" ? "" : "-".$newver[3]);
# 	} elsif ($contents[$i] =~ /\#\s*define\s+H5_VERSION\s+/) {
# 	    $contents[$i] = sprintf("\#define H5_VERSION \"%d.%d.%d%s\"\n",
# 				    @vers[0,1,2],
# 				    $newver[3] eq "" ? "" : "-".$newver[3]);
# 	}
#     }

#     open FILE, ">$pubconf" or die "$pubconf: $!\n";
#     print FILE @contents;
#     close FILE;
# }

# Update the Windows-maintained H5pubconf.h file
# gen_h5pubconf("HDF5", $MAKEFILE_TEST, @newver) if $MAKEFILE_TEST;
    
# # Update the VMS-maintained h5pubconf.h file
# gen_h5pubconf("HDF5", $MAKEFILE_EXAMPLES, @newver) if $MAKEFILE_EXAMPLES;
    
# # Print the new version number
 if ($verbose) {
   printf("version %d.%d release %d%s\n", @newver[0,1,2],
 	 $newver[3] eq "" ? "" : " (".$newver[3].")");
 } else {
   printf("%d.%d.%d%s\n", @newver[0,1,2],
 	 $newver[3] eq "" ? "" : "-".$newver[3]);
 }

exit 0;

# Because the first line of this file looks like a Bourne shell script, we
# must tell XEmacs explicitly that this is really a perl script.
#
# Local Variables:
# mode:perl
# End:
