The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl
#
# $Id: flatten_macros,v 33.1 2009/07/10 17:33:44 biersma Exp $
#
# (c) 1999-2009 Morgan Stanley & Co. Incorporated
# 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.
#
# 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";

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-2009 Morgan Stanley & Co. Incorporated
# 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;
}