#!/ms/dist/perl5/bin/perl
#
# $Id: flatten_macros,v 27.1 2007/01/11 20:24:34 molinam Exp $
#
# (c) 1999-2007 Morgan Stanley Dean Witter and Co.
# See ..../src/LICENSE for terms of distribution.
#
# NOTE: this file is just a tool to flatten all of the MQ* macros in
# the files in the pre.in directory.  Since some of them are only
# present in MQSeries 5.1, run this code on a 5.1 host, only when the
# file contents have been changed.
#
# It also greatly speeds up the loading of MQSeries::Command, too.
#
# To run this, from the top level source directory:
# ./util/flatten_macros

use File::Basename;
use Getopt::Long;

require "./util/parse_config";
require "./util/parse_headers";

GetOptions( \%Args, qw( force ) ) ||
  die "Error parsing \@ARGV\n";

die "This MUST be run on an MQSeries V5.1 box, fool!!\n"
  unless $mqversion == 5 && $mqsubversion >= 1;

unless ( @infiles = split(/\n+/,qx{find pre.in -type f -name '*.in' -print}) ) {
    die "Unable to find *.in files in pre.in\n";
}

foreach my $infile ( @infiles ) {
    $maxlen = length($infile) if length($infile) > $maxlen;
}

$thisyear = (localtime())[5] + 1900;

warn "Flattening MQSeries macros...\n";

foreach my $infile ( @infiles ) {

    my $outfile = $infile;
    $outfile =~ s:^pre\.in/::;
    $outfile =~ s/\.in$/.pl/;
    $tmpfile = "$outfile.$$";
    push(@tmpfiles,$tmpfile);

    if ( -f $outfile && ! $Args{force} ) {
	my (@outstat) = stat($outfile) or die "Unable to stat $outfile: $!\n";
	my (@instat) = stat($infile) or die "Unable to stat $infile: $!\n";
	next if $instat[9] < $outstat[9];
    }

    my $outdir = dirname($outfile);
    unless ( -d $outdir ) {
	warn "Creating directory $outdir\n";
	mkdir($outdir,0755) || die "Unable to mkdir $outdir: $!\n";
    }

    warn ($infile . " " x ($maxlen - length($infile)) . " => $outfile\n");

    open(IN,$infile) || die "Unable to open $infile: $!\n";
    open(OUT,">$tmpfile") || die "Unable to open $tmpfile: $!\n";

    #
    # Look for the first non-comment line, and dump the "edit this and
    # die" warning.
    #
    while ( <IN> ) {
	next if /^\#/;
	print OUT <<"EndOfWarning";
#
# WARNING: This file is automatically generated.
# Any changes made here will be mercilessly lost.
#
# You have been warned, infidel.
#
# P.S. For the real source to this file, see:
#
#    ..../src/$infile
#
# and for the evil hackery used to generate this, see:
#
#    ..../src/util/flatten_macros
#
# (c) 1999-2004 Morgan Stanley Dean Witter and Co.
# See ..../src/LICENSE for terms of distribution.
#
EndOfWarning
        last;
    }

    while ( <IN> ) {

	while ( /&(MQ[A-Z0-9_]+)(,)?/ ) {

	    my ($key,$comma) = ($1,$2);
	    my $value = "";

	    if ( exists $constant_numeric{$key} ) {
		$value = $constant_numeric{$key};
	    }
	    elsif ( exists $constant_hex{$key} ) {
		$value = $constant_hex{$key};
	    }
	    else {
		die "Unknown MQSeries macro: '$key'\n";
	    }

	    my $keylength = length($key) + 1; # Don't forget the &
	    my $valuelength = length($value) - 1; # But do forget the ,

	    #
	    # XXX -- this is really only relevant for the PCF/*.in
	    # files.  Not at all generic.
	    #
	    # I'm sick, I admit it -- I want the closing braces to
	    # lineup, too.  
	    #
	    if ( $key =~ /MQCFT_(STRING|INTEGER)/ ) {
		$value .= $comma;
	    }
	    else {
		$value .= $comma . " " x ($keylength - $valuelength);
	    }

	    s/&$key$comma/$value/;

	}

	#
	# Ugh - somewhere we're setting $* it appears....
	#
	s/\s+$/\n/;

	print OUT;

    }

    close(OUT) || die "Unable to close $tmpfile: $!\n";
    close(IN);

    rename($tmpfile,$outfile) || die "Unable to rename $tmpfile to $outfile: $!\n";

}

END {
    unlink @tmpfiles;
}
