Blame maint/genstates

Packit 0848f5
#! /usr/bin/env perl
Packit 0848f5
use File::Find;
Packit 0848f5
Packit 0848f5
%states = ();
Packit 0848f5
Packit 0848f5
# Find all the source and header files and parse the states.
Packit 0848f5
find sub
Packit 0848f5
{
Packit 0848f5
	if ($File::Find::name =~ /\.[ich]$/)
Packit 0848f5
	{
Packit 0848f5
		%local_states = ();
Packit 0848f5
		$line_no = 1;
Packit 0848f5
		$previous_line_no = 1;
Packit 0848f5
		$filename = $File::Find::name;
Packit 0848f5
		#printf("opening $_\n");
Packit 0848f5
		open (F, "$_") or die "unable to open $_";
Packit 0848f5
		while (<F>)
Packit 0848f5
		{
Packit 0848f5
			chomp;
Packit 0848f5
			if (/STATE_DECL\((.+)\)/)
Packit 0848f5
			{
Packit 0848f5
				if (!/^#\s*define/)
Packit 0848f5
				{
Packit 0848f5
					if ($local_states{$1} eq "declared")
Packit 0848f5
					{
Packit 0848f5
						printf("$filename:$previous_line_no:$line_no\n");
Packit 0848f5
						printf("ERROR: no FUNC_ENTER/EXIT for declared state '$1'\n");
Packit 0848f5
					}
Packit 0848f5
#					if ($local_states{$1} eq "entered")
Packit 0848f5
#					{
Packit 0848f5
#						# This actually could be a nested state declaration of the same name.
Packit 0848f5
#						printf("$filename:$line_no\n");
Packit 0848f5
#						printf("ERROR: no FUNC_EXIT for state '$1'\n");
Packit 0848f5
#					}
Packit 0848f5
					#printf("state declared: $1\n");
Packit 0848f5
					if (/\s+\\\s*/)
Packit 0848f5
					{
Packit 0848f5
						# Assume that if the declared state is in a macro then it will be correctly entered and exited.
Packit 0848f5
						# Otherwise it is too hard to parse the file.
Packit 0848f5
						$local_states{$1} = "exited";
Packit 0848f5
					}
Packit 0848f5
					else
Packit 0848f5
					{
Packit 0848f5
						$local_states{$1} = "declared";
Packit 0848f5
					}
Packit 0848f5
					$previous_line_no = $line_no;
Packit 0848f5
				}
Packit 0848f5
			}
Packit 0848f5
			if (/FUNC_ENTER.*\((.+)\)/)
Packit 0848f5
			{
Packit 0848f5
				if ( (!/^#\s*define/) && (!/\s+\\\s*/) )
Packit 0848f5
				{
Packit 0848f5
					if ($local_states{$1} eq "declared")
Packit 0848f5
					{
Packit 0848f5
						#printf("state entered: '$1'\n");
Packit 0848f5
						$local_states{$1} = "entered";
Packit 0848f5
					}
Packit 0848f5
					else
Packit 0848f5
					{
Packit 0848f5
						if (!defined($local_states{$1}))
Packit 0848f5
						{
Packit 0848f5
							printf("$filename:$line_no\n");
Packit 0848f5
							printf("ERROR: FUNC_ENTER for undefined state '$1'\n");
Packit 0848f5
						}
Packit 0848f5
						if ($local_states{$1} eq "entered")
Packit 0848f5
						{
Packit 0848f5
							printf("$filename:$line_no\n");
Packit 0848f5
							printf("ERROR: FUNC_ENTER repeated for state '$1'\n");
Packit 0848f5
						}
Packit 0848f5
#						if ($local_states{$1} eq "exited")
Packit 0848f5
#						{
Packit 0848f5
#							printf("$filename:$line_no\n");
Packit 0848f5
#							printf("Warning: FUNC_ENTER after FUNC_EXIT for state '$1'\n");
Packit 0848f5
#						}
Packit 0848f5
					}
Packit 0848f5
				}
Packit 0848f5
			}
Packit 0848f5
			if (/FUNC_EXIT.*\((.+)\)/)
Packit 0848f5
			{
Packit 0848f5
				if ( (!/^#\s*define/) && (!/\s+\\\s*/) )
Packit 0848f5
				{
Packit 0848f5
					if (($local_states{$1} eq "entered") || ($local_states{$1} eq "exited"))
Packit 0848f5
					{
Packit 0848f5
						#printf("state exited: $1\n");
Packit 0848f5
						$local_states{$1} = "exited";
Packit 0848f5
					}
Packit 0848f5
					else
Packit 0848f5
					{
Packit 0848f5
						if (!defined($local_states{$1}))
Packit 0848f5
						{
Packit 0848f5
							printf("$filename:$line_no\n");
Packit 0848f5
							printf("ERROR: FUNC_EXIT for undefined state '$1'\n");
Packit 0848f5
						}
Packit 0848f5
						if ($local_states{$1} eq "declared")
Packit 0848f5
						{
Packit 0848f5
							printf("$filename:$line_no\n");
Packit 0848f5
							printf("ERROR: FUNC_EXIT without FUNC_ENTER for state '$1'\n");
Packit 0848f5
						}
Packit 0848f5
					}
Packit 0848f5
				}
Packit 0848f5
			}
Packit 0848f5
			$line_no = $line_no + 1;
Packit 0848f5
		}
Packit 0848f5
		close F;
Packit 0848f5
		foreach (keys(%local_states))
Packit 0848f5
		{
Packit 0848f5
			if ($local_states{$_} eq "declared")
Packit 0848f5
			{
Packit 0848f5
				printf("$filename:\n");
Packit 0848f5
				printf("ERROR: no FUNC_ENTER/EXIT for declared state $_\n");
Packit 0848f5
			}
Packit 0848f5
			else
Packit 0848f5
			{
Packit 0848f5
				if ($local_states{$_} eq "entered")
Packit 0848f5
				{
Packit 0848f5
					printf("$filename:\n");
Packit 0848f5
					printf("ERROR: FUNC_ENTER without FUNC_EXIT for state $_\n");
Packit 0848f5
				}
Packit 0848f5
				else
Packit 0848f5
				{
Packit 0848f5
					if (!($_ eq ""))
Packit 0848f5
					{
Packit 0848f5
						$states{$_} = "NULL";
Packit 0848f5
					}
Packit 0848f5
				}
Packit 0848f5
			}
Packit 0848f5
		}
Packit 0848f5
	}
Packit 0848f5
}, "src";
Packit 0848f5
Packit 0848f5
@states = sort keys(%states);
Packit 0848f5
Packit 0848f5
# Remove the MPID_STATE_ prefix
Packit 0848f5
foreach (@states)
Packit 0848f5
{
Packit 0848f5
	if ( !($_ eq "") )
Packit 0848f5
	{
Packit 0848f5
		/(MPID_STATE_)(.+)/;
Packit 0848f5
		$display_names{"$1$2"} = "$2";
Packit 0848f5
	}
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
# Find all the describe_states.txt files and parse them
Packit 0848f5
find sub
Packit 0848f5
{
Packit 0848f5
	if ($_ eq "describe_states.txt")
Packit 0848f5
	{
Packit 0848f5
		open F, $_;
Packit 0848f5
		$line_no = 1;
Packit 0848f5
		while (<F>)
Packit 0848f5
		{
Packit 0848f5
			chomp;
Packit 0848f5
			# Check for a line with a display name and a color
Packit 0848f5
			/\s*(\S+)(\s+)(\S+)(\s+)(\d+)(\s+)(\d+)(\s+)(\d+).*/;
Packit 0848f5
			if (defined($1) && defined($2) && defined($3) && defined($4) && defined($5) && defined($6) && defined($7) && defined($8) && defined($9))
Packit 0848f5
			{
Packit 0848f5
				if (!defined($states{$1}))
Packit 0848f5
				{
Packit 0848f5
					printf("Warning1: described state '$1' not used, consider removing it from $File::Find::name:$line_no\n");
Packit 0848f5
				}
Packit 0848f5
				$display_names{$1} = "$3";
Packit 0848f5
				$states{$1} = "\"$5 $7 $9\"";
Packit 0848f5
			}
Packit 0848f5
			else
Packit 0848f5
			{
Packit 0848f5
				# Check for a line with just a color
Packit 0848f5
				/\s*(\S+)(\s+)(\d+)(\s+)(\d+)(\s+)(\d+).*/;
Packit 0848f5
				if (defined($1) && defined($2) && defined($3) && defined($4) && defined($5) && defined($6) && defined($7))
Packit 0848f5
				{
Packit 0848f5
					if (!defined($states{$1}))
Packit 0848f5
					{
Packit 0848f5
						printf("Warning2: described state '$1' not used, consider removing it from $File::Find::name:$line_no\n");
Packit 0848f5
					}
Packit 0848f5
					$states{$1} = "\"$3 $5 $7\"";
Packit 0848f5
				}
Packit 0848f5
				else
Packit 0848f5
				{
Packit 0848f5
					# Check for a line with just a display name
Packit 0848f5
					/\s*(\S+)(\s+)(\S+).*/;
Packit 0848f5
					if (defined($1) && defined($2) && defined($3))
Packit 0848f5
					{
Packit 0848f5
						if (!defined($states{$1}))
Packit 0848f5
						{
Packit 0848f5
							printf("Warning3: described state '$1' not used, consider removing it from $File::Find::name:$line_no\n");
Packit 0848f5
						}
Packit 0848f5
						$display_names{$1} = "$3";
Packit 0848f5
					}
Packit 0848f5
				}
Packit 0848f5
			}
Packit 0848f5
			$line_no = $line_no + 1;
Packit 0848f5
		}
Packit 0848f5
		close F;
Packit 0848f5
	}
Packit 0848f5
}, "src";
Packit 0848f5
Packit 0848f5
# FIXME: It would be better to assemble this from just the relevant 
Packit 0848f5
# modules, rather than all files.  A directory-based approach, such as
Packit 0848f5
# that from extractstrings, could be used.
Packit 0848f5
#
Packit 0848f5
open HFILE, ">src/include/mpiallstates.h"
Packit 0848f5
	or die "Unable to open src/include/mpiallstates.h";
Packit 0848f5
print HFILE "/* -*- Mode: C; c-basic-offset:4 ; -*- */\n";
Packit 0848f5
print HFILE "/*\n";
Packit 0848f5
print HFILE " *  (C) 2001 by Argonne National Laboratory.\n";
Packit 0848f5
print HFILE " *      See COPYRIGHT in top-level directory.\n";
Packit 0848f5
print HFILE " */\n";
Packit 0848f5
print HFILE "\n";
Packit 0848f5
print HFILE "/* automatically generated by maint/genstates */\n";
Packit 0848f5
print HFILE "\n";
Packit 0848f5
print HFILE "#ifndef MPIALLSTATES_H_INCLUDED\n";
Packit 0848f5
print HFILE "#define MPIALLSTATES_H_INCLUDED\n";
Packit 0848f5
print HFILE "\n";
Packit 0848f5
print HFILE "/* Insert all the states to be logged here */\n";
Packit 0848f5
print HFILE "\n";
Packit 0848f5
print HFILE "enum MPID_TIMER_STATE\n";
Packit 0848f5
print HFILE "{\n";
Packit 0848f5
foreach (@states)
Packit 0848f5
{
Packit 0848f5
	if ( !($_ eq "") )
Packit 0848f5
	{
Packit 0848f5
		print HFILE "$_,\n";
Packit 0848f5
	}
Packit 0848f5
}
Packit 0848f5
print HFILE "MPID_NUM_TIMER_STATES\n";
Packit 0848f5
print HFILE "};\n";
Packit 0848f5
print HFILE "\n";
Packit 0848f5
print HFILE "#endif\n";
Packit 0848f5
close HFILE;
Packit 0848f5
Packit 0848f5
# FIXME: This is RLOG specific and should be placed in the appropriate 
Packit 0848f5
# RLOG directory, not common.  
Packit 0848f5
# FIXME: It would also make more sense for the RLOG_Describe_state routine
Packit 0848f5
# to perform the random color assignement when provided with an empty
Packit 0848f5
# or null color string, rather than including all of this code in what is
Packit 0848f5
# otherwise an RLOG-specific file.
Packit 0848f5
Packit 0848f5
open F, ">src/util/logging/common/describe_states.c"
Packit 0848f5
	or die "Unable to open src/util/logging/common/describe_states.c";
Packit 0848f5
print F "/* -*- Mode: C; c-basic-offset:4 ; -*- */\n";
Packit 0848f5
print F "/*\n";
Packit 0848f5
print F " *  (C) 2001 by Argonne National Laboratory.\n";
Packit 0848f5
print F " *      See COPYRIGHT in top-level directory.\n";
Packit 0848f5
print F " */\n";
Packit 0848f5
print F "\n";
Packit 0848f5
print F "/* automatically generated by maint/genstates */\n";
Packit 0848f5
print F "\n";
Packit 0848f5
print F "#include \"mpiimpl.h\"\n";
Packit 0848f5
print F "\n";
Packit 0848f5
print F "/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build\n";
Packit 0848f5
print F "   the MPI routines */\n";
Packit 0848f5
print F "#ifndef MPICH_MPI_FROM_PMPI\n";
Packit 0848f5
print F "\n";
Packit 0848f5
print F "#ifdef HAVE_TIMING\n";
Packit 0848f5
print F "\n";
Packit 0848f5
print F "#if (USE_LOGGING == MPID_LOGGING_RLOG)\n";
Packit 0848f5
print F "\n";
Packit 0848f5
print F "int MPIR_Describe_timer_states()\n";
Packit 0848f5
print F "{\n";
Packit 0848f5
print F "\n";
Packit 0848f5
foreach (@states)
Packit 0848f5
{
Packit 0848f5
	if ( !($_ eq "") )
Packit 0848f5
	{
Packit 0848f5
		print F "    RLOG_DescribeState(g_pRLOG, $_, \"$display_names{$_}\", $states{$_});\n";
Packit 0848f5
	}
Packit 0848f5
}
Packit 0848f5
print F "    return 0;\n";
Packit 0848f5
print F "}\n";
Packit 0848f5
print F "\n";
Packit 0848f5
print F "#endif /* USE_LOGGING == MPID_LOGGING_RLOG */\n";
Packit 0848f5
print F "#endif /* HAVE_TIMING */\n";
Packit 0848f5
print F "#endif /* MPICH_MPI_FROM_PMPI */\n";