* Added the new Words->string() method to insert variables, data and other strings into the requested 'key'. This is a condensed and cleaned up version of v2's String->get() method.
* Added the new $an->_get_hash_reference() method that takes a key in the format "foo::bar" and returns the contents of $an->data->{foo}{bar}.
* Added the new Words->clean_spaces() method that removes leading and trailing spaces from a string, and condenses multiple spaces into single ones to simplify string parsing.
Signed-off-by: Digimer <digimer@alteeve.ca>
die"$THIS_FILE ".__LINE__."; The hash key string: [$parameter->{key}] doesn't seem to be valid. It should be a string in the format 'foo::bar::baz'.\n"if$parameter->{key}!~/::/;
# Split up the keys.
my$key=$parameter->{key}?$parameter->{key}:"";
my$value=undef;# We return 'undef' so that the caller can tell the difference between an empty string versus nothing found.
Thismethidtakesastringviaa'C<< line >>'parameterandstripsleadingandtrailingspaces,pluscompressesmultiplespacesintosinglespaces.Itisdesignedprimarilyforusebycodeparsingtextcominginfromashellcommand.
Thefilecanbethefilename,orapath.Thespecifiedfileissearchforbymatchingthethepassedinstringagainsttheendofthefilepath.Forexample,'C<< file => 'AN/an-tools.xml' >> will match the file 'c<< /usr/share/perl5/AN/an-tools.xml>>'.
=head3key(required)
Thisisthekeytoreturnthestringfor.
@ -111,12 +147,6 @@ This is the key to return the string for.
Thefilecanbethefilename,orapath.Thespecifiedfileissearchforbymatchingthethepassedinstringagainsttheendofthefilepath.Forexample,'C<< file => 'AN/an-tools.xml' >> will match the file 'c<< /usr/share/perl5/AN/an-tools.xml>>'.
# We set the 'loop' variable to '1' and check it at the end of each pass. This is done
# because we might inject a string near the end that adds a replacement key to an
# otherwise-processed string and we don't want to miss that.
my$loop=1;
while($loop)
{
# First, look for any '#!...!#' keys that we don't recognize and protect them. We'll
# restore them once we're out of this loop.
foreachmy$check($string=~ /#!([^\s]+?)!#/)
{
if(($check!~/^replace/)&&
($check!~/^data/)&&
($check!~/^string/)&&
($check!~/^variable/))
{
# Simply invert the '#!...!#' to '!#...#!'.
$string=~s/#!($check)!#/!#$1#!/g;
}
# Die if I've looped too many times.
$loops++;
die"$THIS_FILE ".__LINE__."; Infinite loop detected while processing the string: [".$string."] from the key: [$key] in language: [$language], exiting.\n"if$loops>$limit;
}
# Now, look for any '#!string!x!#' embedded strings.
while($string=~ /#!string!(.+?)!#/)
{
my$key=$1;
my$this_string=$an->Words->key({
key=>$key,
language=>$language,
file=>$file,
});
if($this_stringeq"#!not_found!#")
{
# The key was bad...
$string=~s/#!string!$key!#/!!e[$key]!!/;
}
else
{
$string=~s/#!string!$key!#/$this_string/;
}
# Die if I've looped too many times.
$loops++;
die"$THIS_FILE ".__LINE__."; Infinite loop detected while processing the string: [".$string."] from the key: [$key] in language: [$language], exiting.\n"if$loops>$limit;
}
# Now insert variables in the strings.
while($string=~ /#!variable!(.+?)!#/s)
{
my$variable=$1;
# Sometimes, #!variable!*!# is used in explaining things to users. So we need
# to escape it. It will be restored later in '_restore_protected()'.
if($variableeq"*")
{
$string=~s/#!variable!\*!#/!#variable!*#!/;
next;
}
if(notdefined$variables->{$variable})
{
# I can't expect there to always be a defined value in the variables
# array at any given position so if it is blank qw blank the key.
$string=~s/#!variable!$variable!#//;
}
else
{
my$value=$variables->{$variable};
chomp$value;
$string=~s/#!variable!$variable!#/$value/;
}
# Die if I've looped too many times.
$loops++;
die"$THIS_FILE ".__LINE__."; Infinite loop detected while processing the string: [".$string."] from the key: [$key] in language: [$language], exiting.\n"if$loops>$limit;
}
# Next, convert '#!data!x!#' to the value in '$an->data->{x}'.
while($string=~ /#!data!(.+?)!#/)
{
my$id=$1;
if($id=~ /::/)
{
# Multi-dimensional hash.
my$value=$an->_get_hash_reference({key=>$id});
if(notdefined$value)
{
$string=~s/#!data!$id!#/!!a[$id]!!/;
}
else
{
$string=~s/#!data!$id!#/$value/;
}
}
else
{
# One dimension
if(notdefined$an->data->{$id})
{
$string=~s/#!data!$id!#/!!b[$id]!!/;
}
else
{
my$value=$an->data->{$id};
$string=~s/#!data!$id!#/$value/;
}
}
# Die if I've looped too many times.
$loops++;
die"$THIS_FILE ".__LINE__."; Infinite loop detected while processing the string: [".$string."] from the key: [$key] in language: [$language], exiting.\n"if$loops>$limit;
}
$loops++;
die"$THIS_FILE ".__LINE__."; Infinite loop detected while processing the string: [".$string."] from the key: [$key] in language: [$language], exiting.\n"if$loops>$limit;
# If there are no replacement keys left, exit the loop.
if($string!~/#!([^\s]+?)!#/)
{
$loop=0;
}
}
# Restore any protected keys. Reset the loop counter, too.
$loops=0;
$loop=1;
while($loop)
{
$string=~s/!#([^\s]+?)#!/#!$1!#/g;
$loops++;
die"$THIS_FILE ".__LINE__."; Infinite loop detected while processing the string: [".$string."] from the key: [$key] in language: [$language], exiting.\n"if$loops>$limit;