# # Author: John A. Turner # Los Alamos National Laboratory # Phone: 505-665-1303 # e-mail: turner@lanl.gov # $Id: memory.awk,v 1.7 1997/02/20 19:39:31 turner Exp $ # # GNU awk (gawk) script to read a file containing information about the arrays # in a routine and write out necessary header (.inc) files to be processed and # included by cpp. # # NOTE: This script requires GNU awk, which can be obtained for free from # prep.ai.mit.edu (and mirror sites) via anonymous ftp. # # USAGE: # # Assuming this file is named memory.awk, the input file is named # named arrays.inc, and you want the output filenames to have "-foo" # appended to them, the full command: # # [g|n]awk -f memory.awk \ # -v outfile=-foo \ # -v outdir=. \ # -v status=status \ # -v error=-1 \ # -v goto=9999 \ # -v int_kind=4 \ # -v real_kind=8 \ # arrays.inc # # would create the following three new .inc files: # # declare-foo.inc - declarations # allocate-foo.inc - statements to allocate memory # deallocate-foo.inc - statements to release memory # # VARIABLES: # # Note that the -v form for setting variables must be used so that # the variables will be available in the BEGIN block. (Actually # it's only really necessary for outdir and outfile, but just to # be consistent use it for all the variables.) # # Required: # # outfile - # Controls name used in generated files (e.g. foo in the example # above). # # Optional: # # outdir - # Controls where the generated files will reside. Can be # be a full path or a path relative to the directory in which # the script is invoked. Default is the directory in which # the script is invoked. # # status - # Name of integer Fortran variable to be set if allocation fails. # Default is "status". This variable must be declared (either # implicitly or explicitly) in the routine using the include # files generated by this script. # # error - # Sets the value to which to set variable "status" if allocation # fails. Defaults to -1. # # goto - # Statement label to which a goto should transfer control if # allocation fails. Default is 9999. # # int_kind, real_kind - # Kinds for integers and reals. They must be positive integer # constants or constant integer expressions which evaluate to # to positive values. No default (if they are not specified, # the KIND specifier is not used). # # A typical line of the input file might be: # #c* real ro (kd,ld) ! density in each cell # # NOTE: The 2nd field is assumed to contain the type of each array. The # name and size of each array are assumed to be in the 3rd and # 4th fields, respectively. The script could easily be modified # to accomodate other input file formats. # # The following would be written to declare-foo.inc: # # real, allocatable, dimension(:) :: ro # # and to allocate-foo.inc: # # allocate(ro(kd,ld), stat=status) # if (status /= 0) then # status = error # go to 9999 # end if # # and to deallocate-foo.inc: # # if (allocated(ro)) deallocate(ro) # # If the script had been invoked with real_kind=JT_real_type on the # command line, the following would have been written to declare-foo.inc # instead of the above: # # real(kind=JT_real_type), allocatable, dimension(:) :: ro # # A line to be processed is defined as one that has a type declaration in the # 2nd field. $2 ~ /integer|real/ { # Set outdir to "." if it wasn't defined on the command line. if ( outdir == "" ) outdir = "." # Set default value of status. if ( status == "" ) status = "istatus" # Set default value of error. if ( error == "" ) error = "-1" # Set default value of goto. if ( goto == "" ) goto = "9999" # Set kind if specified on the command line. if ( $2 == "integer" && int_kind != "" ) kind = "(kind="int_kind")" if ( $2 == "real" && real_kind != "" ) kind = "(kind="real_kind")" # Define the array name. name = $3 # Define the array shape (used in allocatable statement). split($4 , shape_array , "," ) shape = "(" for (i in shape_array) shape = shape":," shape = shape")" gsub( /,\)/ , ")" , shape) # Set dimension. dimension = $4 # Declaration. print " "$2 kind", allocatable, dimension"shape" :: "name > outdir"/declare"outfile".inc" # Allocation. print " allocate( "name $4", stat = "status" )" > outdir"/allocate"outfile".inc" print " if ("status" .ne. 0) then" > outdir"/allocate"outfile".inc" print " "status" = "error > outdir"/allocate"outfile".inc" print " go to "goto > outdir"/allocate"outfile".inc" print " end if" > outdir"/allocate"outfile".inc" # Deallocation. print " if (allocated("name")) deallocate( "name" )" > outdir"/deallocate"outfile".inc" }