mirror of
https://codeberg.org/scip/Config-General.git
synced 2025-12-16 20:21:01 +01:00
2.12 - fixed cpan bugid #1768, stuff inside a hash given
by the -DefaultConfig parameter was ignored by the new interpolation code, this has been fixed. - fixed another bug in the new interpolation code, which made variable global, the variable scope were ignored. Now a special constructed hash exists, which makes sure, that variables only valid within its correct scope. git-svn-id: http://dev.catalyst.perl.org/repos/Config-General/trunk@38 be1acefe-a474-0410-9a34-9b3221f2030f
This commit is contained in:
10
Changelog
10
Changelog
@@ -1,3 +1,13 @@
|
|||||||
|
2.12 - fixed cpan bugid #1768, stuff inside a hash given
|
||||||
|
by the -DefaultConfig parameter was ignored by
|
||||||
|
the new interpolation code, this has been fixed.
|
||||||
|
|
||||||
|
- fixed another bug in the new interpolation code,
|
||||||
|
which made variable global, the variable scope
|
||||||
|
were ignored. Now a special constructed hash
|
||||||
|
exists, which makes sure, that variables only
|
||||||
|
valid within its correct scope.
|
||||||
|
|
||||||
2.11 - heavy change in the variable interpolation code.
|
2.11 - heavy change in the variable interpolation code.
|
||||||
Peter Sergeant <pete@clueball.com> reported this
|
Peter Sergeant <pete@clueball.com> reported this
|
||||||
mis-behavior. The problem was that the whole hash
|
mis-behavior. The problem was that the whole hash
|
||||||
|
|||||||
31
General.pm
31
General.pm
@@ -17,7 +17,7 @@ use strict;
|
|||||||
use Carp;
|
use Carp;
|
||||||
use Exporter;
|
use Exporter;
|
||||||
|
|
||||||
$Config::General::VERSION = "2.11";
|
$Config::General::VERSION = "2.12";
|
||||||
|
|
||||||
use vars qw(@ISA @EXPORT);
|
use vars qw(@ISA @EXPORT);
|
||||||
@ISA = qw(Exporter);
|
@ISA = qw(Exporter);
|
||||||
@@ -69,7 +69,10 @@ sub new {
|
|||||||
|
|
||||||
StrictVars => 1, # be strict on undefined variables in Interpolate mode
|
StrictVars => 1, # be strict on undefined variables in Interpolate mode
|
||||||
|
|
||||||
parsed => 0
|
parsed => 0,
|
||||||
|
upperkey => "",
|
||||||
|
lastkey => "",
|
||||||
|
prevkey => " ",
|
||||||
};
|
};
|
||||||
|
|
||||||
# create the class instance
|
# create the class instance
|
||||||
@@ -197,6 +200,9 @@ sub new {
|
|||||||
|
|
||||||
# process as usual
|
# process as usual
|
||||||
if (!$self->{parsed}) {
|
if (!$self->{parsed}) {
|
||||||
|
if ($self->{DefaultConfig} && $self->{InterPolateVars}) {
|
||||||
|
$self->{DefaultConfig} = $self->_interpolate_hash($self->{DefaultConfig});
|
||||||
|
}
|
||||||
if (exists $self->{StringContent}) {
|
if (exists $self->{StringContent}) {
|
||||||
# consider the supplied string as config file
|
# consider the supplied string as config file
|
||||||
$self->_read($self->{StringContent}, "SCALAR");
|
$self->_read($self->{StringContent}, "SCALAR");
|
||||||
@@ -408,8 +414,6 @@ sub _parse {
|
|||||||
local $_;
|
local $_;
|
||||||
my $indichar = chr(182); # <20>, inserted by _open, our here-doc indicator
|
my $indichar = chr(182); # <20>, inserted by _open, our here-doc indicator
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
foreach (@{$content}) { # loop over content stack
|
foreach (@{$content}) { # loop over content stack
|
||||||
chomp;
|
chomp;
|
||||||
$chunk++;
|
$chunk++;
|
||||||
@@ -436,7 +440,6 @@ sub _parse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($value && $value =~ /^"/ && $value =~ /"$/) {
|
if ($value && $value =~ /^"/ && $value =~ /"$/) {
|
||||||
$value =~ s/^"//; # remove leading and trailing "
|
$value =~ s/^"//; # remove leading and trailing "
|
||||||
$value =~ s/"$//;
|
$value =~ s/"$//;
|
||||||
@@ -503,6 +506,7 @@ sub _parse {
|
|||||||
}
|
}
|
||||||
else { # calling myself recursively, end of $block reached, $block_level is 0
|
else { # calling myself recursively, end of $block reached, $block_level is 0
|
||||||
if ($blockname) { # a named block, make it a hashref inside a hash within the current node
|
if ($blockname) { # a named block, make it a hashref inside a hash within the current node
|
||||||
|
$this->_savelast($blockname);
|
||||||
if (exists $config->{$block}->{$blockname}) { # the named block already exists, make it an array
|
if (exists $config->{$block}->{$blockname}) { # the named block already exists, make it an array
|
||||||
if ($this->{MergeDuplicateBlocks}) {
|
if ($this->{MergeDuplicateBlocks}) {
|
||||||
# just merge the new block with the same name as an existing one into
|
# just merge the new block with the same name as an existing one into
|
||||||
@@ -531,8 +535,10 @@ sub _parse {
|
|||||||
else { # the first occurence of this particular named block
|
else { # the first occurence of this particular named block
|
||||||
$config->{$block}->{$blockname} = $this->_parse($config->{$block}->{$blockname}, \@newcontent);
|
$config->{$block}->{$blockname} = $this->_parse($config->{$block}->{$blockname}, \@newcontent);
|
||||||
}
|
}
|
||||||
|
$this->_backlast($blockname);
|
||||||
}
|
}
|
||||||
else { # standard block
|
else { # standard block
|
||||||
|
$this->_savelast($block);
|
||||||
if (exists $config->{$block}) { # the block already exists, make it an array
|
if (exists $config->{$block}) { # the block already exists, make it an array
|
||||||
if ($this->{MergeDuplicateBlocks}) {
|
if ($this->{MergeDuplicateBlocks}) {
|
||||||
# just merge the new block with the same name as an existing one into
|
# just merge the new block with the same name as an existing one into
|
||||||
@@ -562,6 +568,7 @@ sub _parse {
|
|||||||
# the first occurence of this particular block
|
# the first occurence of this particular block
|
||||||
$config->{$block} = $this->_parse($config->{$block}, \@newcontent);
|
$config->{$block} = $this->_parse($config->{$block}, \@newcontent);
|
||||||
}
|
}
|
||||||
|
$this->_backlast($block);
|
||||||
}
|
}
|
||||||
undef $blockname;
|
undef $blockname;
|
||||||
undef $block;
|
undef $block;
|
||||||
@@ -582,8 +589,18 @@ sub _parse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub _savelast {
|
||||||
|
my($this, $key) = @_;
|
||||||
|
$this->{upperkey} = $this->{lastkey};
|
||||||
|
$this->{lastkey} = $this->{prevkey};
|
||||||
|
$this->{prevkey} = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _backlast {
|
||||||
|
my($this, $key) = @_;
|
||||||
|
$this->{prevkey} = $this->{lastkey};
|
||||||
|
$this->{lastkey} = $this->{upperkey};
|
||||||
|
}
|
||||||
|
|
||||||
sub _parse_value {
|
sub _parse_value {
|
||||||
#
|
#
|
||||||
@@ -1724,7 +1741,7 @@ Thomas Linden <tom@daemon.de>
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
2.11
|
2.12
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
package Config::General::Interpolated;
|
package Config::General::Interpolated;
|
||||||
$Config::General::Interpolated::VERSION = "2.0";
|
$Config::General::Interpolated::VERSION = "2.01";
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Carp;
|
use Carp;
|
||||||
@@ -56,11 +56,27 @@ sub _interpolate {
|
|||||||
#
|
#
|
||||||
my ($this, $key, $value) = @_;
|
my ($this, $key, $value) = @_;
|
||||||
|
|
||||||
|
my $prevkey;
|
||||||
|
|
||||||
|
if ($this->{level} == 1) {
|
||||||
|
# top level
|
||||||
|
$prevkey = " ";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# incorporate variables outside current scope(block) into
|
||||||
|
# our scope to make them visible to _interpolate()
|
||||||
|
foreach my $key (keys %{$this->{stack}->{ $this->{level} - 1}->{ $this->{lastkey} }}) {
|
||||||
|
$this->{stack}->{ $this->{level} }->{ $this->{prevkey} }->{$key} =
|
||||||
|
$this->{stack}->{ $this->{level} - 1}->{ $this->{lastkey} }->{$key};
|
||||||
|
}
|
||||||
|
$prevkey = $this->{prevkey};
|
||||||
|
}
|
||||||
|
|
||||||
$value =~ s{$this->{regex}}{
|
$value =~ s{$this->{regex}}{
|
||||||
my $con = $1;
|
my $con = $1;
|
||||||
my $var = $3;
|
my $var = $3;
|
||||||
if (exists $this->{varstack}->{$var}) {
|
if (exists $this->{stack}->{ $this->{level} }->{ $prevkey }->{$var}) {
|
||||||
$con . $this->{varstack}->{$var};
|
$con . $this->{stack}->{ $this->{level} }->{ $prevkey }->{$var};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ($this->{StrictVars}) {
|
if ($this->{StrictVars}) {
|
||||||
@@ -73,12 +89,98 @@ sub _interpolate {
|
|||||||
}
|
}
|
||||||
}egx;
|
}egx;
|
||||||
|
|
||||||
$this->{varstack}->{$key} = $value;
|
$this->{stack}->{ $this->{level} }->{ $prevkey }->{$key} = $value;
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
sub _interpolate_hash {
|
||||||
|
#
|
||||||
|
# interpolate a complete hash and keep the results
|
||||||
|
# on the varstack.
|
||||||
|
#
|
||||||
|
# called directly by Config::General::new()
|
||||||
|
#
|
||||||
|
my ($this, $config) = @_;
|
||||||
|
|
||||||
|
$this->{level} = 1;
|
||||||
|
$this->{upperkey} = "";
|
||||||
|
$this->{lastkey} = "";
|
||||||
|
$this->{prevkey} = " ";
|
||||||
|
|
||||||
|
$config = $this->_var_hash_stacker($config);
|
||||||
|
|
||||||
|
$this->{level} = 1;
|
||||||
|
$this->{upperkey} = "";
|
||||||
|
$this->{lastkey} = "";
|
||||||
|
$this->{prevkey} = " ";
|
||||||
|
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _var_hash_stacker {
|
||||||
|
#
|
||||||
|
# build a varstack of a given hash ref
|
||||||
|
#
|
||||||
|
my ($this, $config) = @_;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
foreach my $key (keys %{$config}) {
|
||||||
|
if (ref($config->{$key}) eq "ARRAY" ) {
|
||||||
|
$this->{level}++;
|
||||||
|
$this->_savelast($key);
|
||||||
|
$config->{$key} = $this->_var_array_stacker($config->{$key}, $key);
|
||||||
|
$this->_backlast($key);
|
||||||
|
$this->{level}--;
|
||||||
|
}
|
||||||
|
elsif (ref($config->{$key}) eq "HASH") {
|
||||||
|
$this->{level}++;
|
||||||
|
$this->_savelast($key);
|
||||||
|
$config->{$key} = $this->_var_hash_stacker($config->{$key});
|
||||||
|
$this->_backlast($key);
|
||||||
|
$this->{level}--;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# SCALAR
|
||||||
|
$config->{$key} = $this->_interpolate($key, $config->{$key});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#$this->{level}--;
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub _var_array_stacker {
|
||||||
|
#
|
||||||
|
# same as _var_hash_stacker but for arrayrefs
|
||||||
|
#
|
||||||
|
my ($this, $config, $key) = @_;
|
||||||
|
|
||||||
|
my @new;
|
||||||
|
#$this->{level}++;
|
||||||
|
|
||||||
|
foreach my $entry (@{$config}) {
|
||||||
|
if (ref($entry) eq "HASH") {
|
||||||
|
$entry = $this->_var_hash_stacker($entry);
|
||||||
|
}
|
||||||
|
elsif (ref($entry) eq "ARRAY") {
|
||||||
|
# ignore this. Arrays of Arrays cannot be created/supported
|
||||||
|
# with Config::General, because they are not accessible by
|
||||||
|
# any key (anonymous array-ref)
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$entry = $this->_interpolate($key, $entry);
|
||||||
|
}
|
||||||
|
push @new, $entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return \@new;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
@@ -184,7 +286,7 @@ See L<http://www.perl.com/perl/misc/Artistic.html>
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
2.0
|
2.01
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
|||||||
2
t/run.t
2
t/run.t
@@ -120,7 +120,7 @@ print STDERR " .. ok # Using AUTOLOAD methods\n";
|
|||||||
|
|
||||||
|
|
||||||
# testing variable interpolation
|
# testing variable interpolation
|
||||||
my $conf16 = new Config::General(-ConfigFile => "t/cfg.16", -InterPolateVars => 1);
|
my $conf16 = new Config::General(-ConfigFile => "t/cfg.16", -InterPolateVars => 1, -StrictVars => 0);
|
||||||
my %h16 = $conf16->getall();
|
my %h16 = $conf16->getall();
|
||||||
if($h16{etc}->{log} eq "/usr/local/log/logfile") {
|
if($h16{etc}->{log} eq "/usr/local/log/logfile") {
|
||||||
print "ok\n";
|
print "ok\n";
|
||||||
|
|||||||
Reference in New Issue
Block a user