#! /usr/bin/env perl
#
# (C) 2014 by Argonne National Laboratory.
# See COPYRIGHT in top-level directory.
#
use warnings;
use strict;
# Check to make sure the file was passed in as a parameter
if ($#ARGV != 0) {
print "Usage: buildiface <filename>\n";
exit 1;
}
open(FD, $ARGV[0]) || die "Could not open file " . $ARGV[0];
while (<FD>) {
if (/\/\*\s*Begin Prototypes/) { last; }
}
my $eol = 1;
my $fullline = "";
my $tab = " ";
my $retarg;
my $routine;
my $args;
my @arglist;
my $fname;
my $cdesc_routine;
my $x;
my $y;
my @argbits;
my $num_dtypes;
my @dtype_bind;
my $io_header;
my $make_exists = 0;
open(OUTFD, ">all_romio_symbols.c") || die "Could not open file all_romio_symbols.c";
print OUTFD <<EOT;
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* (C) 2014 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*
* This file is automatically generated by buildiface
* DO NOT EDIT
*/
/*
* This file is created for the sole purpose of referencing all the symbols
* in ROMIO.
*
* All ROMIO public symbols are being added into the libromio convenience
* library, which is LIBADD'ed into libmpi. The correct behavior would
* be for libtool to add -Wl,--whole-archive to the link line, thus
* forcing all symbols in libromio to end up in libmpi. However, in some
* cases, this is not working out correctly. For example, with the
* Absoft compiler, the linker flags were being reordered thus causing
* the -Wl,--whole-archive flag to not correspond to libromio.
* Consequently, only symbols that were used from within the other
* functions of libmpi were being included.
*
* In the past, we got lucky in two ways:
*
* 1. We were including all the Fortran 77 symbols into libmpi. Since
* the Fortran symbols were calling the C ROMIO symbols, those ROMIO
* symbols were pulled in even without -Wl,--whole-archive.
*
* 2. The problem only showed up with absoft and nag, both of which are
* Fortran-only compilers. If a C compiler has this issue, it should
* have shown up when Fortran support is disabled.
*/
#include "mpiimpl.h"
#include <stdio.h>
void MPIR_All_romio_symbols(void);
void MPIR_All_romio_symbols(void)
{
#ifdef MPI_MODE_RDONLY
EOT
while (<FD>) {
if (/\/\*\s*End Prototypes/) { last; }
if (/\/\*\s*Begin Skip Prototypes/) {
while (<FD>) {
if (/\/\*\s*End Skip Prototypes/) { last; }
}
}
# If we found a semi-colon at the end, that's the end of the line.
# This is not perfect (e.g., does not work when a single line has
# multiple semi-colon separated statements), but should be good
# enough for the MPICH mpi.h file
if (/.*;/) { $eol = 1; }
else { $eol = 0; }
chomp($_);
$fullline .= "$_";
if ($eol == 0) { next; }
# We got the entire prototype in a single line
# parse out comments
$fullline =~ s+/\*.*\*/++g;
# parse out attributes
$fullline =~ s/MPICH_ATTR_POINTER_WITH_TYPE_TAG\(.*\)//g;
# cleanup pointer format
$fullline =~ s/\s*\*/* /g;
# parse out unnecessary spaces
$fullline =~ s/^\s*//g;
$fullline =~ s/\s*$//g;
$fullline =~ s/\s*;/;/g;
$fullline =~ s/\s\s*/ /g;
# split the line into the return type, routine name, and arguments
$fullline =~ m/([^ ]*) ([^(]*)\((.*)\)/;
$retarg = $1;
$routine = $2;
$args = $3;
# cleanup args
$args =~ s/^\s*//g;
$args =~ s/\s*$//g;
@arglist = split(/,/, $args);
for ($x = 0; $x <= $#arglist; $x++) {
$arglist[$x] =~ s/^\s*//g;
$arglist[$x] =~ s/\s*$//g;
}
print OUTFD "${tab}{\n";
for ($x = 0; $x <= $#arglist; $x++) {
print OUTFD "${tab}${tab}$arglist[$x]";
if ($arglist[$x] =~ /\*/) {
print OUTFD " = NULL;\n";
}
elsif ($arglist[$x] =~ /MPI_Comm/) {
print OUTFD " = MPI_COMM_NULL;\n";
}
elsif ($arglist[$x] =~ /MPI_Info/) {
print OUTFD " = MPI_INFO_NULL;\n";
}
elsif ($arglist[$x] =~ /MPI_File/) {
print OUTFD " = MPI_FILE_NULL;\n";
}
elsif ($arglist[$x] =~ /MPI_Datatype/) {
print OUTFD " = MPI_DATATYPE_NULL;\n";
}
elsif ($arglist[$x] =~ /MPI_Errhandler/) {
print OUTFD " = MPI_ERRHANDLER_NULL;\n";
}
elsif ($arglist[$x] =~ /MPI_Offset/) {
print OUTFD " = 0;\n";
}
elsif ($arglist[$x] =~ /int/) {
print OUTFD " = 0;\n";
}
else {
print "$arglist[$x]\n";
print OUTFD ";\n";
}
}
print OUTFD "\n${tab}${tab}$routine(";
for ($x = 0; $x <= $#arglist; $x++) {
@argbits = split(/ /, $arglist[$x]);
if ($x < $#arglist) {
print OUTFD "$argbits[$#argbits], ";
}
else {
print OUTFD "$argbits[$#argbits]);\n";
}
}
print OUTFD "${tab}}\n\n";
$fullline = "";
}
# A few symbols are not in mpio.h
print OUTFD <<EOT;
{
MPI_Fint fh = 0;
MPI_File_f2c(fh);
}
{
MPI_File fh = MPI_FILE_NULL;
MPI_File_c2f(fh);
}
MPIR_Comm_split_filesystem(MPI_COMM_NULL, 0, NULL, NULL);
#endif /* MPI_MODE_RDONLY */
}
EOT
close FD;
close OUTFD;