I'm sure this isn't the cleanest but this is the function I've been using reliably for several years now without a problem against VAR=$VALUE files. In effect I load the vars that will require interpolation into the enviornment, then parse the config file, then add the new values to the environment.
The first function function (readDat) just gets the info from another file. The second code snippet (unpackDatArray) does the actual value setting ( including $VARS as long as they are in the environment. ) The third snippet (getEnvValue) substitutes the $VAR for it's value.
There are a few functions in these snippets like 'debug' that you'll have to comment out or add similar functionality for them ( i.e. setEnv ).
# Reads a text file with var=values pairs line delimited
# Storing the values into a hash filled array.
sub readDat {
# Grab the passed parameter
my $filename = $_[0];
my $state = $_[1];
# Establish the array to hold the aquired Data
# and pass back to calling Function
my @Data;
# The ubiquitous $i counter
my $i = 0;
debug( "Reading dat file - $filename\n", 5 );
# Register a filehandle
local (*DATFILE);
# Open the file for read
open (DATFILE, $filename) or debug( "Can't open $filename: $1", 10
+0);
# Read through the file one line at a time
FORA:while (<DATFILE>) {
debug("Proccessing Line = \n$_\n", 0);
# Skip over any comments
if ( /#.*/ ) {
next FORA;
}
# Clean up any extraneous garbage
chomp; # no newline
s/^\s+//; # no leading white
s/\s+$//; # no trailing white
# If clean up eliminated any data worth reading
# lets skip to the next line
next unless length;
debug( "Loading Line = \n$_\n", 0 );
# We can't load the lines with $VARS as we will
# loose any values so we'll make sure to escape them
# (the $'s that is)
s/\$/\\\$/g;
# localizing $var and $value to make sure
# they are clean out on every read.
my ($var, $value) = split(/=/,$_);
if ( $var && $value ) {
debug( "\$var = $var \$value = $value\n", 0 );
}
# Stuff those puppies into a hash and store
# the hash into our @Data array
# (See Camel 3rd ed pgs 278 - 279)
$Data[$i]{$var} = $value;
# Increment and get the next
$i++;
}
# Send the info back to the caller
return @Data;
}
--------------------
# Used to unpack data read from .dat files (excluding modify.dat)
sub unpackDatArray {
my @dat = @_;
# Unpack the data
# (See Camel 3rd ed pgs 278 - 279)
my ( $i, $var, $value);
for $i ( 0 .. $#dat ) {
for $var ( keys %{ $dat[$i] } ) {
$value = $dat[$i]{$var};
if ( $var && $value ) {
debug("\$var = $var \$value = $value\n", 0);
# set our workspace
$_ = $value;
# If the values have a $ in them we must get
# the environmental Var value and substitue it
# into our value.
/(\\\$)(\w+)(.*)/ ;
if ( $2 ) {
$value = getEnvValue($value);
}
# Set the Environment
$_ = $value;
# eliminate surrounding quoutes from string
s/^\"//g;
s/$\"//g;
$value = "$_";
my %newHashValue;
$newHashValue{$var} = $value;
setEnv(%newHashValue);
}
}
}
}
--------------------
# This is a nasty little sub that parses out what Environmental
# Var to retrieve and then inserts it into the string
sub getEnvValue {
my $envValue = "";
# set the workspace
$_ = $_[0];
# As long as a question mark exists keep working
# on it (Bad place for a possible 'hang' or looping
# problem.)
while ( /\$/ ) {
# Seperate out the VarName and the remaining string
/(\\\$)(\w+)(.*)/ ;
# eliminate surrounding quoutes from string
# get that freakin delimeter
my $delimeter = $`;
my $envVarString = $2;
my $workString = $3;
debug( "\$delimeter = $delimeter\n
\$envVarString = $envVarString\n
\$workString = $workString\n", 0 );
# Get the environments value and substitute it into the
# current line if it exists
if ( $ENV{$envVarString} ) {
$envValue = $delimeter . $ENV{$envVarString} . $workString
+;
s/$envVarString/$ENV{$envVarString}/g;
} else {
$envValue = $delimeter . "NA" . $workString;
s/$envVarString/NA/g
}
debug( "Harvest::FileFuc::getEnvValue\n
\$Workpace = $_\n
\$workString = $workString\n
So far returning $envValue\n",1);
# If theres no more $'s in the string pop it back on
# the return value
$_ = $envValue;
}
# Return the work
return $envValue;
}
coreolyn |