#!/usr/bin/perl # ipp: a preprocessor script # author : Reese Jones rjones@sandia.gov (based on dprepro [Sandia]) # to do : # priority (overide file defaults e.g. a=1 pfile a=2 -> a=2) # also order precedence: a=10 -p p.file b=12 # nested if/else/endif blocks # Regular expressions for numeric fields $e = "-?(?:\\d+\\.?\\d*|\\.\\d+)[eEdD](?:\\+|-)?\\d+"; # exponential notation $f = "-?\\d+\\.\\d*|-?\\.\\d+"; # floating point $i = "-?\\d+"; # integer $ui = "\\d+"; # unsigned integer $n = "$e|$f|$i"; # numeric field # Read command line arguments while (scalar(@ARGV)) { $arg = shift(@ARGV); if ($arg =~ /-p/) { $parameter_file = shift(@ARGV); parse_parameter_file($parameter_file); } elsif ($arg =~ /-o/) { $new_file = shift(@ARGV); } elsif ($arg =~ /=/) { ($tag,$value) = split(/=/,$arg); $values_p1{$tag} = $value; } else { $template_file = $arg; } } # Check for correct command line arguments if( ! defined($template_file) ) { print STDERR "Usage: ipp <-p parameters_file> template_file <-o new_file>\n"; print STDERR " note: \"value\" must be numeric (not a character string)\n"; print STDERR " parameter file format : name = value\n"; print STDERR " or : value name\n"; print STDERR " template file example: modulus is {10.0*name +3.2}\n"; exit(-1); } # output $output_fh = \*STDOUT; if( defined($new_file) ) { open(NEW,">$new_file"); $output_fh = \*NEW; } output($template_file,$output_fh); if( defined($new_file) ) { close(NEW); } # debug : print key--> value #foreach $key (sort keys %values_p1) { # print "# $key ---> ",$values_p1{$key},"\n"; #} ########################################################################### # parse parameter file ########################################################################### # Read parameters file, extract tags and corresponding values in either aprepro # "{ tag = value }" format or standard "value tag" format, and store the # tag/value pairs in %values_p1. # NOTE : compound expressions are not currently allowed. sub parse_parameter_file { my $pfile = shift(@_); # (1) parse numerical values open (PARAMETERS, "<$pfile") || die "Can't open parameters file: $pfile: $!"; while () { # read each line of file, one at a time # extract tag/value fields allowing multiple matches per line in either format foreach $field (m/(?:$n)\s+\w+|\s*\w+\s*=\s*(?:$n)\s*/go) { # extract tag/value pair from each field NOTE () are memory if ( ( ($value, $tag) = ($field =~ m/^($n)\s+(\w+)$/o) ) || # Standard ( ($tag, $value) = ($field =~ m/^\s*(\w+)\s*=\s*($n)\s*$/o))){# Apr $value =~ s/[dD]/e/o; # convert any F77 dbl prec exponents $values_p1{$tag} = $value; # store in hash } } } close (PARAMETERS); # (2) parse string values in dbl quotes open (PARAMETERS, "<$pfile") || die "Can't open parameters file: $pfile: $!"; while () { # read each line of file, one at a time # extract tag/value fields allowing multiple matches per line in either format #if ( m/=/ && m/\"/ ){ if ( ($tag, $value) = ($_ =~ m/^\s*(\w+)\s*=\s*\"(.*)\"\s*$/o)){ $values_p1{$tag} = $value; # store in hash } } close (PARAMETERS); } ################################################################# # Process template simulation file and create new simulation file ################################################################# # Read each line of template_file, find the {} fields, process any # assignments or expressions, and substitute the corresponding values. # Print each line with substitution to new_file. The parameters # file assignments (%values_p1 = precedence 1) take precedence over any # duplicate template file assignments (%values_p2 = precedence 2) in # order to allow the flexibility to define defaults in the template # file which can then be overridden by a particular parameters file. sub output{ my $tfile = shift (@_); # Open the template simulation file for input. open (TEMPLATE, "<$tfile") || die "Can't open template file $tfile: $!"; # Open the new simulation file for output. #$print_to_file = 0; #if (defined($new_file)) { #open (NEW, ">$new_file") || die "Can't create instance file $new_file: $!"; #$print_to_file = 1; #} $print_to_file = 1; $fh = shift (@_); $print = 1; # print line flag while (