Blame maint/parse.sub

Packit 0848f5
#! /usr/bin/env perl
Packit 0848f5
#
Packit 0848f5
# File of useful routines use to process the MPI source files.  This is 
Packit 0848f5
# included by routines that process parameters and error messages, along with
Packit 0848f5
# tools to check for proper usage (such as system routines and preprocessor
Packit 0848f5
# tests).
Packit 0848f5
Packit 0848f5
#
Packit 0848f5
# GetBalancedParen( FD, curline )
Packit 0848f5
# Returns a balanced parenthesis string, starting at curline.  Reads from FD
Packit 0848f5
# if necessary.  Skips any comments.
Packit 0848f5
# Returns the pair (leading, result, remainder)
Packit 0848f5
# Leading is anything before the opening paren.  If no opening paren in the
Packit 0848f5
# line, returns the current line as "leading"
Packit 0848f5
# Newlines are removed.
Packit 0848f5
sub GetBalancedParen {
Packit 0848f5
    my $paren_count = 1;
Packit 0848f5
    my $result = "";
Packit 0848f5
    my $count = 0;
Packit 0848f5
    my $leading = "";
Packit 0848f5
    my $maxcount = 200;
Packit 0848f5
    $FD = $_[0];
Packit 0848f5
    $curline = $_[1];
Packit 0848f5
    # Remove escaped newlines
Packit 0848f5
    $curline =~ s/\\$//;
Packit 0848f5
    
Packit 0848f5
    if ($curline =~ /^([^\(]*)\((.*)$/) {
Packit 0848f5
	$leading = $1;
Packit 0848f5
	$curline = $2;
Packit 0848f5
	$result  = "(";
Packit 0848f5
	print "Found open paren\n" if $debug;
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	$leading = $curline;
Packit 0848f5
	return ($leading, "", "" );
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    while ($count < $maxcount && $paren_count > 0) {
Packit 0848f5
	if ($curline =~ /^([^\(\)]*\()(.*$)/) {
Packit 0848f5
	    # Found an opening paren
Packit 0848f5
	    $result .= $1;
Packit 0848f5
	    $curline = $2;
Packit 0848f5
	    $paren_count++;
Packit 0848f5
	    print "Found open paren\n" if $debug;
Packit 0848f5
	}
Packit 0848f5
        elsif ($curline =~ /^([^\(\)]*\))(.*$)/) {
Packit 0848f5
	    # Found a closing paren
Packit 0848f5
	    $result .= $1;
Packit 0848f5
	    $curline = $2;
Packit 0848f5
	    $paren_count--;
Packit 0848f5
	    print "Found close paren\n" if $debug;
Packit 0848f5
	}
Packit 0848f5
	else {
Packit 0848f5
	    # Need to read a new line
Packit 0848f5
	    $result .= $curline;
Packit 0848f5
	    $curline = <$FD>;
Packit 0848f5
	    $curline =~ s/[\r]*\n//;
Packit 0848f5
	    # Remove escaped newlines
Packit 0848f5
	    $curline =~ s/\\$//;
Packit 0848f5
	}
Packit 0848f5
	$count ++;
Packit 0848f5
    }
Packit 0848f5
    return ($leading, $result, $curline);
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
# Like get balanced paren, but for a string.  Simpler because it does not need
Packit 0848f5
# to handle balanced text.  
Packit 0848f5
sub GetString {
Packit 0848f5
    my $result = "";
Packit 0848f5
    my $count = 0;
Packit 0848f5
    my $leading = "";
Packit 0848f5
    my $maxcount = 200;
Packit 0848f5
    $FD = $_[0];
Packit 0848f5
    $curline = $_[1];
Packit 0848f5
    
Packit 0848f5
    if ($curline =~ /^([^\"]*)\"(.*)$/) {
Packit 0848f5
	$leading = $1;
Packit 0848f5
	$curline = $2;
Packit 0848f5
	$result  = "\"";
Packit 0848f5
	print "Found quote\n" if $debug;
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	$leading = $curline;
Packit 0848f5
	return ($leading, "", "" );
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    while ($count < $maxcount) {
Packit 0848f5
	if ($curline =~ /^([^\"]*\\\")(.*$)/) {
Packit 0848f5
	    # Found an escaped quote
Packit 0848f5
	    $result .= $1;
Packit 0848f5
	    $curline = $2;
Packit 0848f5
	    print "Found escaped quote\n" if $debug;
Packit 0848f5
	}
Packit 0848f5
        elsif ($curline =~ /^([^\"]*\")(.*$)/) {
Packit 0848f5
	    # Found the closing quote
Packit 0848f5
	    $result .= $1;
Packit 0848f5
	    $curline = $2;
Packit 0848f5
	    print "Found closing quote\n" if $debug;
Packit 0848f5
	    last;
Packit 0848f5
	}
Packit 0848f5
	else {
Packit 0848f5
	    # Need to read a new line
Packit 0848f5
	    $result .= $curline;
Packit 0848f5
	    $curline = <$FD>;
Packit 0848f5
	    $curline =~ s/[\r]*\n//;
Packit 0848f5
	}
Packit 0848f5
	$count ++;
Packit 0848f5
    }
Packit 0848f5
    return ($leading, $result, $curline);
Packit 0848f5
}
Packit 0848f5
#
Packit 0848f5
# GetSubArgs( FD, curline ) returns an array of the arguments of a routine.
Packit 0848f5
# Specifically, it converts (a,b,c) into an array containing "a", "b", and "c".
Packit 0848f5
# The special feature of this is that any commas that are within balanced
Packit 0848f5
# parenthesis are included within their argument.
Packit 0848f5
# Actually returns
Packit 0848f5
#  (leader, remainder, (@args) )
Packit 0848f5
# in this order so the last values are always all of the args
Packit 0848f5
# so you don't need to know
Packit 0848f5
sub GetSubArgs {
Packit 0848f5
    my @args = ();
Packit 0848f5
    my $curline;
Packit 0848f5
    my ($outer, $leader, $remainder, $arg);
Packit 0848f5
Packit 0848f5
    $FD = $_[0];
Packit 0848f5
    $curline = $_[1];
Packit 0848f5
    # Remove any embedded newlines
Packit 0848f5
    $curline =~ s/[\r\n]//g;
Packit 0848f5
Packit 0848f5
    $curline =~ /^\(/ || die "No initial paren";
Packit 0848f5
    ($leader, $outer, $remainder ) = &GetBalancedParen( $FD, $curline );
Packit 0848f5
Packit 0848f5
Packit 0848f5
    # Strip off the first and last parens
Packit 0848f5
    # Because of the greedy algorithm, the \s before the closing paren
Packit 0848f5
    # won't be used.  To avoid problems with empty arguments, we remove
Packit 0848f5
    # those blanks separately
Packit 0848f5
    $outer =~ /^\s*\(\s*(.*)\s*\)\s*$/;
Packit 0848f5
    $outer = $1;
Packit 0848f5
    if ($outer =~ /(.*)\s+$/) { $outer = $1; }
Packit 0848f5
    print "Line to tokenize is $outer\n" if $debug;
Packit 0848f5
    $arg   = "";
Packit 0848f5
    while ($outer ne "") {
Packit 0848f5
	if ($outer =~ /^([^,\(\"]*)\s*,\s*(.*$)/) {
Packit 0848f5
	    # simple arg
Packit 0848f5
	    $arg .= $1;
Packit 0848f5
	    $args[$#args+1] = $arg;
Packit 0848f5
	    print "Found simple arg $arg (remainder $2)\n" if $debug;
Packit 0848f5
	    $outer = $2;
Packit 0848f5
	    $arg   = "";
Packit 0848f5
	}
Packit 0848f5
	elsif ($outer =~ /^([^,\"]*)\((.*$)/) { 
Packit 0848f5
	    # arg with ()
Packit 0848f5
	    ($startarg,$bal,$outer) = &GetBalancedParen( $FD, $outer );
Packit 0848f5
	    $arg = $arg . $startarg . $bal;
Packit 0848f5
	    # Rest of code will catch the rest
Packit 0848f5
	}
Packit 0848f5
        elsif ($outer =~ /^([^,\(]*)\"(.*$)/) {
Packit 0848f5
	    # arg with ""
Packit 0848f5
	    ($startarg,$string,$outer) = &GetString( $FD, $outer );
Packit 0848f5
	    print "string is $string\n" if $debug;
Packit 0848f5
	    $arg = $arg . $startarg . $string;
Packit 0848f5
	    # Rest of code will catch the rest
Packit 0848f5
	}
Packit 0848f5
	else {
Packit 0848f5
	    # no comma
Packit 0848f5
	    print "Adding |$outer| to arg $arg\n" if $debug;
Packit 0848f5
	    $arg .= $outer;
Packit 0848f5
	    $outer = "";
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
    if ($arg ne "") {
Packit 0848f5
	$args[$#args+1] = $arg;
Packit 0848f5
    }
Packit 0848f5
    print "Number of args is 1+$#args\n" if $debug;
Packit 0848f5
    return ($leader, $remainder, @args );
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
# remainder = StripComments( FD, inputline )
Packit 0848f5
# removes comments from a line and returns the line.  Read more if necessary
Packit 0848f5
# Places the comment into $comment_line;
Packit 0848f5
# The external "cxx_header" adds // to the comments stripped
Packit 0848f5
Packit 0848f5
# Set a default value for cxx_header
Packit 0848f5
if (!defined($cxx_header)) {
Packit 0848f5
    $cxx_header = 0;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
sub StripComments {
Packit 0848f5
    my $FD = $_[0];
Packit 0848f5
    my $curline = $_[1];
Packit 0848f5
    my $remainder = "";
Packit 0848f5
    $comment_line = "";
Packit 0848f5
    if ($cxx_header == 1 && $curline =~ /(\/\/.*)/) {
Packit 0848f5
	$comment_line = $1;
Packit 0848f5
	$curline =~ s/\/\/.*//;
Packit 0848f5
	print "Removed C++ comment, now is $curline\n" if $debug;
Packit 0848f5
	return $curline;
Packit 0848f5
    }
Packit 0848f5
    while ($curline =~ /\/\*/) {
Packit 0848f5
	print "Curline = $curline\n" if $debug;
Packit 0848f5
	if ($curline =~ /(\/\*.*?\*\/)/s) {
Packit 0848f5
	    $comment_line = $1;
Packit 0848f5
	    $curline =~ s/\/\*.*?\*\///s;
Packit 0848f5
	    print "Removed comment, now is $curline\n" if $debug;
Packit 0848f5
	    # Keep looking for comments incase the line has multiple 
Packit 0848f5
	    # comments
Packit 0848f5
	}
Packit 0848f5
	else {
Packit 0848f5
	    # Keep collecting until we find the end of the comment
Packit 0848f5
	    if (eof($FD)) {
Packit 0848f5
		print STDOUT "Unterminated comment found$errsrc!\n";
Packit 0848f5
		my $line = $curline;
Packit 0848f5
		if ($line =~ /(.*)\n/) { $line = "$1"; }
Packit 0848f5
		print STDOUT "Comment begins with $line\n";
Packit 0848f5
		return $curline;
Packit 0848f5
	    }
Packit 0848f5
	    $curline .= <$FD>;
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
    return $curline;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
# Since this is a required package, indicate that we are successful.
Packit 0848f5
return 1;