mirror of
https://codeberg.org/scip/Config-General.git
synced 2025-12-16 20:21:01 +01:00
i 1.24: - AllowMultiOptions printed out the value and not the
option itself, if more than one of this particular
option occured.
- added -UseApacheInclude feature, contributed by
Thomas Klausner <domm@zsi.at>
- fixed bug with multiple options stuff, which did not
work with blocks or named blocks. Pointed out by
Thomas Klausner <domm@zsi.at>, who meant it being
feature request, but in fact it was a bug (IMHO).
- Config::General does now contain also it's OO-sister
Config::General::Extended, which is from now on
no more available as an extra module, because it
lived a shadowy existence.
- finally(!) created a Changelog file (this one, yes).
git-svn-id: http://dev.catalyst.perl.org/repos/Config-General/trunk@12 be1acefe-a474-0410-9a34-9b3221f2030f
This commit is contained in:
35
Changelog
Normal file
35
Changelog
Normal file
@@ -0,0 +1,35 @@
|
||||
1.24: - AllowMultiOptions printed out the value and not the
|
||||
option itself, if more than one of this particular
|
||||
option occured.
|
||||
- added -UseApacheInclude feature, contributed by
|
||||
Thomas Klausner <domm@zsi.at>
|
||||
- fixed bug with multiple options stuff, which did not
|
||||
work with blocks or named blocks. Pointed out by
|
||||
Thomas Klausner <domm@zsi.at>, who meant it being
|
||||
feature request, but in fact it was a bug (IMHO).
|
||||
- Config::General does now contain also it's OO-sister
|
||||
Config::General::Extended, which is from now on
|
||||
no more available as an extra module, because it
|
||||
lived a shadowy existence.
|
||||
- finally(!) created a Changelog file (this one, yes).
|
||||
|
||||
1.23: - fixed bug, which removed trailing or leading " even
|
||||
no matching " was there.
|
||||
|
||||
1.22: - added a new option to new(): -LowerCaseNames, which
|
||||
lowercases all option-names (feature request)
|
||||
|
||||
1.21: - lines with just one "#" became an option array named
|
||||
"#" with empty entries, very weird, fixed
|
||||
|
||||
1.20: - added an if(exists... to new() for checking of the
|
||||
existence of -AllowMultiOptions.
|
||||
- use now "local $_" because it caused weird results
|
||||
if a user used $_ with the module.
|
||||
|
||||
1.19: - you can escape "#" characters using a backslash: "\#"
|
||||
which will now no more treated as a comment.
|
||||
- comments inside here-documents will now remain in the
|
||||
here-doc value.
|
||||
|
||||
previous history logs are lost in space :-(
|
||||
206
General.pm
206
General.pm
@@ -10,21 +10,6 @@
|
||||
# All Rights Reserved. Std. disclaimer applies.
|
||||
# Artificial License, same as perl itself. Have fun.
|
||||
#
|
||||
# 1.23: - fixed bug, which removed trailing or leading " even
|
||||
# no matching " was there.
|
||||
# 1.22: - added a new option to new(): -LowerCaseNames, which
|
||||
# lowercases all option-names (feature request)
|
||||
# 1.21: - lines with just one "#" became an option array named
|
||||
# "#" with empty entries, very weird, fixed
|
||||
# 1.20: - added an if(exists... to new() for checking of the
|
||||
# existence of -AllowMultiOptions.
|
||||
# - use now "local $_" because it caused weird results
|
||||
# if a user used $_ with the module.
|
||||
# 1.19: - you can escape "#" characters using a backslash: "\#"
|
||||
# which will now no more treated as a comment.
|
||||
# - comments inside here-documents will now remain in the
|
||||
# here-doc value.
|
||||
|
||||
# namespace
|
||||
package Config::General;
|
||||
|
||||
@@ -32,7 +17,7 @@ use FileHandle;
|
||||
use strict;
|
||||
use Carp;
|
||||
|
||||
$Config::General::VERSION = "1.23";
|
||||
$Config::General::VERSION = "1.24";
|
||||
|
||||
sub new {
|
||||
#
|
||||
@@ -61,6 +46,12 @@ sub new {
|
||||
$self->{LowerCaseNames} = 1;
|
||||
}
|
||||
}
|
||||
# contributed by Thomas Klausner <domm@zsi.at>
|
||||
if (exists $conf{-UseApacheInclude}) {
|
||||
if ($conf{-UseApacheInclude}) {
|
||||
$self->{UseApacheInclude} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ($#param == 0) {
|
||||
# use of the old style
|
||||
@@ -178,6 +169,12 @@ sub _open {
|
||||
if (/^<<include (.+?)>>$/) { # include external config file
|
||||
$this->_open($1) if(!$c_comment); # call _open with the argument to include assuming it is a filename
|
||||
}
|
||||
elsif ((/^[Ii]nclude (.+?)$/) && ($this->{UseApacheInclude})) {
|
||||
# contributed by Thomas Klausner <domm@zsi.at>
|
||||
# include external config file, Apache Style
|
||||
# call _open with the argument to include assuming it is a filename
|
||||
$this->_open($1) if(!$c_comment);
|
||||
}
|
||||
else { # standard config line, push it onto the content stack
|
||||
push @{$this->{content}}, $_ if(!$c_comment);
|
||||
}
|
||||
@@ -195,6 +192,8 @@ sub _open {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
sub _parse {
|
||||
#
|
||||
# parse the contents of the file
|
||||
@@ -234,7 +233,7 @@ sub _parse {
|
||||
$option = lc($option) if $this->{LowerCaseNames};
|
||||
if ($this->{NoMultiOptions}) { # configurable via special method ::NoMultiOptions()
|
||||
if (exists $config->{$option}) {
|
||||
croak "Option $config->{$option} occurs more than once (level: $this->{level}, chunk $chunk)!\n";
|
||||
croak "Option \"$option\" occurs more than once (level: $this->{level}, chunk $chunk)!\n";
|
||||
}
|
||||
$config->{$option} = $value;
|
||||
}
|
||||
@@ -245,7 +244,7 @@ sub _parse {
|
||||
delete $config->{$option};
|
||||
push @{$config->{$option}}, $savevalue;
|
||||
}
|
||||
push @{$config->{$option}}, $value; # it's still an array, just push
|
||||
push @{$config->{$option}}, $value; # it's already an array, just push
|
||||
}
|
||||
else {
|
||||
$config->{$option} = $value; # standard config option, insert key/value pair into node
|
||||
@@ -263,12 +262,52 @@ sub _parse {
|
||||
push @newcontent, $_; # push onto new content stack
|
||||
}
|
||||
else { # calling myself recursively, end of $block reached, $block_level is 0
|
||||
if ($blockname) {
|
||||
$config->{$block}->{$blockname} = # a named block, make it a hashref inside a hash within the current node
|
||||
$this->_parse($config->{$block}->{$blockname}, \@newcontent);
|
||||
if ($blockname) { # a named block, make it a hashref inside a hash within the current node
|
||||
if (exists $config->{$block}->{$blockname}) { # the named block already exists, make it an array
|
||||
if ($this->{NoMultiOptions}) {
|
||||
croak "Named block \"<$block $blockname>\" occurs more than once (level: $this->{level}, chunk $chunk)!\n";
|
||||
}
|
||||
else { # preserve existing data
|
||||
my $savevalue = $config->{$block}->{$blockname};
|
||||
delete $config->{$block}->{$blockname};
|
||||
my @ar;
|
||||
if (ref $savevalue eq "ARRAY") {
|
||||
push @ar, @{$savevalue}; # preserve array if any
|
||||
}
|
||||
else {
|
||||
push @ar, $savevalue;
|
||||
}
|
||||
push @ar, $this->_parse( {}, \@newcontent); # append it
|
||||
$config->{$block}->{$blockname} = \@ar;
|
||||
}
|
||||
}
|
||||
else { # the first occurence of this particular named block
|
||||
$config->{$block}->{$blockname} = $this->_parse($config->{$block}->{$blockname}, \@newcontent);
|
||||
}
|
||||
}
|
||||
else { # standard block
|
||||
$config->{$block} = $this->_parse($config->{$block}, \@newcontent);
|
||||
if (exists $config->{$block}) { # the block already exists, make it an array
|
||||
if ($this->{NoMultiOptions}) {
|
||||
croak "Block \"<$block>\" occurs more than once (level: $this->{level}, chunk $chunk)!\n";
|
||||
}
|
||||
else {
|
||||
my $savevalue = $config->{$block};
|
||||
delete $config->{$block};
|
||||
my @ar;
|
||||
if (ref $savevalue eq "ARRAY") {
|
||||
push @ar, @{$savevalue};
|
||||
}
|
||||
else {
|
||||
push @ar, $savevalue;
|
||||
}
|
||||
push @ar, $this->_parse( {}, \@newcontent);
|
||||
$config->{$block} = \@ar;
|
||||
}
|
||||
}
|
||||
else {
|
||||
# the first occurence of this particular block
|
||||
$config->{$block} = $this->_parse($config->{$block}, \@newcontent);
|
||||
}
|
||||
}
|
||||
undef $blockname;
|
||||
undef $block;
|
||||
@@ -289,6 +328,12 @@ sub _parse {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
sub NoMultiOptions {
|
||||
#
|
||||
# turn NoMultiOptions off, still exists for backward compatibility.
|
||||
@@ -376,7 +421,7 @@ Config::General - Generic Config Module
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This small module opens a config file and parses it's contents for you. The B<new> method
|
||||
This module opens a config file and parses it's contents for you. The B<new> method
|
||||
requires one parameter which needs to be a filename. The method B<getall> returns a hash
|
||||
which contains all options and it's associated values of your config file.
|
||||
|
||||
@@ -402,8 +447,9 @@ Possible ways to call B<new()>:
|
||||
|
||||
$conf = new Config::General(
|
||||
-file => "rcfile",
|
||||
-AllowMultiOptions => "no"
|
||||
-LowerCaseNames => "yes"
|
||||
-AllowMultiOptions => "no",
|
||||
-LowerCaseNames => "yes",
|
||||
-UseApacheInclude => 1
|
||||
);
|
||||
|
||||
$conf = new Config::General(
|
||||
@@ -429,6 +475,8 @@ still supported. Possible parameters are:
|
||||
-LowerCaseNames - if true (1 or "yes") then all options found
|
||||
in the config will be converted to lowercase.
|
||||
This allows you to provide case-in-sensitive configs
|
||||
-UseApacheInclude - consider "include ..." as valid include statement (just
|
||||
like the well known apache include statement).
|
||||
|
||||
|
||||
=item NoMultiOptions()
|
||||
@@ -591,31 +639,6 @@ state counter, which indicates a block end.
|
||||
If the module cannot find an end-block statement, then this block will be ignored.
|
||||
|
||||
|
||||
=head1 IDENTICAL OPTIONS
|
||||
|
||||
You may have more than one line of the same option with different values.
|
||||
|
||||
Example:
|
||||
log log1
|
||||
log log2
|
||||
log log2
|
||||
|
||||
You will get a scalar if the option occured only once or an array if it occured
|
||||
more than once. If you expect multiple identical options, then you may need to
|
||||
check if an option occured more than once:
|
||||
|
||||
$allowed = $hash{jonas}->{tablestructure}->{allowed};
|
||||
if(ref($allowed) eq "ARRAY") {
|
||||
@ALLOWED = @{$allowed};
|
||||
else {
|
||||
@ALLOWED = ($allowed);
|
||||
}
|
||||
|
||||
If you don't want to allow more than one identical options, you may turn it off
|
||||
by setting the flag I<AllowMutliOptions> in the B<new()> method to "no".
|
||||
If turned off, Config::General will complain about multiple occuring options
|
||||
whit identical names!
|
||||
|
||||
|
||||
=head1 NAMED BLOCKS
|
||||
|
||||
@@ -653,6 +676,62 @@ You cannot have more than one named block with the same name because it will
|
||||
be stored in a hashref and therefore be overwritten if a block occurs once more.
|
||||
|
||||
|
||||
|
||||
=head1 IDENTICAL OPTIONS
|
||||
|
||||
You may have more than one line of the same option with different values.
|
||||
|
||||
Example:
|
||||
log log1
|
||||
log log2
|
||||
log log2
|
||||
|
||||
You will get a scalar if the option occured only once or an array if it occured
|
||||
more than once. If you expect multiple identical options, then you may need to
|
||||
check if an option occured more than once:
|
||||
|
||||
$allowed = $hash{jonas}->{tablestructure}->{allowed};
|
||||
if(ref($allowed) eq "ARRAY") {
|
||||
@ALLOWED = @{$allowed};
|
||||
else {
|
||||
@ALLOWED = ($allowed);
|
||||
}
|
||||
|
||||
The same applies to blocks and named blocks too (they are described in more detail
|
||||
below). For example, if you have the following config:
|
||||
|
||||
<dir blah>
|
||||
user max
|
||||
</dir>
|
||||
<dir blah>
|
||||
user hannes
|
||||
</dir>
|
||||
|
||||
then you would end up with a data structure like this:
|
||||
|
||||
$VAR1 = {
|
||||
'dir' => {
|
||||
'blah' => [
|
||||
{
|
||||
'user' => 'max'
|
||||
},
|
||||
{
|
||||
'user' => 'hannes'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
As you can see, the two identical blocks are stored in a hash which contains
|
||||
an array(-reference) of hashes.
|
||||
|
||||
If you don't want to allow more than one identical options, you may turn it off
|
||||
by setting the flag I<AllowMutliOptions> in the B<new()> method to "no".
|
||||
If turned off, Config::General will complain about multiple occuring options
|
||||
whit identical names!
|
||||
|
||||
|
||||
|
||||
=head1 LONG LINES
|
||||
|
||||
If you have a config value, which is too long and would take more than one line,
|
||||
@@ -714,11 +793,16 @@ line inside the here-document.
|
||||
|
||||
=head1 INCLUDES
|
||||
|
||||
You can include an external file at any posision in you config file using the following statement
|
||||
You can include an external file at any posision in your config file using the following statement
|
||||
in your config file:
|
||||
|
||||
<<include externalconfig.rc>>
|
||||
|
||||
If you turned on B<-UseApacheInclude> (see B<new()>), then you can also use the following
|
||||
statement to include an external file:
|
||||
|
||||
include externalconfig.rc
|
||||
|
||||
This file will be inserted at the position where it was found as if the contents of this file
|
||||
were directly at this position.
|
||||
|
||||
@@ -765,6 +849,24 @@ the number sign as the begin of a comment because of the leading backslash.
|
||||
Inside here-documents escaping of number signs is NOT required!
|
||||
|
||||
|
||||
=head1 OBJECT ORIENTED INTERFACE
|
||||
|
||||
There is a way to access a parsed config the OO-way.
|
||||
Use the module B<Config::General::Extended>, which is
|
||||
supplied with the Config::General distribution.
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
I recommend you to read the following documentations, which are supplied with perl:
|
||||
|
||||
perlreftut Perl references short introduction
|
||||
perlref Perl references, the rest of the story
|
||||
perldsc Perl data structures intro
|
||||
perllol Perl data structures: arrays of arrays
|
||||
|
||||
Config::General::Extended Object oriented interface to parsed configs
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (c) 2000-2001 Thomas Linden
|
||||
@@ -785,7 +887,7 @@ Thomas Linden <tom@daemon.de>
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
1.22
|
||||
1.24
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
498
General/Extended.pm
Normal file
498
General/Extended.pm
Normal file
@@ -0,0 +1,498 @@
|
||||
#
|
||||
# Config::General::Extended - special Class based on Config::General
|
||||
#
|
||||
# Copyright (c) 2000-2001 Thomas Linden <tom@daemon.de>.
|
||||
# All Rights Reserved. Std. disclaimer applies.
|
||||
# Artificial License, same as perl itself. Have fun.
|
||||
#
|
||||
|
||||
# namespace
|
||||
package Config::General::Extended;
|
||||
|
||||
# yes we need the hash support of new() in 1.18 or higher!
|
||||
use Config::General 1.18;
|
||||
|
||||
use FileHandle;
|
||||
use Carp;
|
||||
use vars qw(@ISA);
|
||||
|
||||
# inherit new() and so on from Config::General
|
||||
@ISA = qw(Config::General);
|
||||
|
||||
use strict;
|
||||
|
||||
|
||||
$Config::General::Extended::VERSION = "1.2";
|
||||
|
||||
|
||||
sub obj {
|
||||
#
|
||||
# returns a config object from a given key
|
||||
# or from the current config hash if the $key does not exist
|
||||
# or an empty object if the content of $key is empty.
|
||||
#
|
||||
my($this, $key) = @_;
|
||||
if (exists $this->{config}->{$key}) {
|
||||
if (!$this->{config}->{$key}) {
|
||||
return $this->new( () ); # empty object!
|
||||
}
|
||||
else {
|
||||
return $this->new( $this->{config}->{$key} );
|
||||
}
|
||||
}
|
||||
else {
|
||||
return $this->new( $this->{config} );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub value {
|
||||
#
|
||||
# returns a value of the config hash from a given key
|
||||
# this can be a hashref or a scalar
|
||||
#
|
||||
my($this, $key, $value) = @_;
|
||||
if ($value) {
|
||||
$this->{config}->{$key} = $value;
|
||||
}
|
||||
else {
|
||||
return $this->{config}->{$key} if(exists $this->{config}->{$key});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub hash {
|
||||
#
|
||||
# returns a value of the config hash from a given key
|
||||
# as hash
|
||||
#
|
||||
my($this, $key) = @_;
|
||||
return %{$this->{config}->{$key}} if(exists $this->{config}->{$key});
|
||||
}
|
||||
|
||||
|
||||
sub array {
|
||||
#
|
||||
# returns a value of the config hash from a given key
|
||||
# as array
|
||||
#
|
||||
my($this, $key) = @_;
|
||||
return @{$this->{config}->{$key}} if(exists $this->{config}->{$key});
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub is_hash {
|
||||
#
|
||||
# return true if the given key contains a hashref
|
||||
#
|
||||
my($this, $key) = @_;
|
||||
if (exists $this->{config}->{$key}) {
|
||||
if (ref($this->{config}->{$key}) eq "HASH") {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub is_array {
|
||||
#
|
||||
# return true if the given key contains an arrayref
|
||||
#
|
||||
my($this, $key) = @_;
|
||||
if (exists $this->{config}->{$key}) {
|
||||
if (ref($this->{config}->{$key}) eq "ARRAY") {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub is_scalar {
|
||||
#
|
||||
# returns true if the given key contains a scalar(or number)
|
||||
#
|
||||
my($this, $key) = @_;
|
||||
if (exists $this->{config}->{$key} && !ref(exists $this->{config}->{$key})) {
|
||||
return 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub exists {
|
||||
#
|
||||
# returns true if the key exists
|
||||
#
|
||||
my($this, $key) = @_;
|
||||
if (exists $this->{config}->{$key}) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub keys {
|
||||
#
|
||||
# returns all keys under in the hash of the specified key, if
|
||||
# it contains keys (so it must be a hash!)
|
||||
#
|
||||
my($this, $key) = @_;
|
||||
if (exists $this->{config}->{$key} && ref($this->{config}->{$key}) eq "HASH") {
|
||||
return map { $_ } keys %{$this->{config}->{$key}};
|
||||
}
|
||||
else {
|
||||
return ();
|
||||
}
|
||||
}
|
||||
|
||||
sub save {
|
||||
#
|
||||
# save the config back to disk
|
||||
#
|
||||
my($this,$file) = @_;
|
||||
my $fh = new FileHandle;
|
||||
|
||||
if (!$file) {
|
||||
$file = $this->{configfile};
|
||||
}
|
||||
open $fh, ">$file" or croak "Could not open $file!($!)\n";
|
||||
$this->_store($fh, 0,%{$this->{config}});
|
||||
}
|
||||
|
||||
|
||||
sub configfile {
|
||||
#
|
||||
# sets or returns the config filename
|
||||
#
|
||||
my($this,$file) = @_;
|
||||
if ($file) {
|
||||
$this->{configfile} = $file;
|
||||
}
|
||||
return $this->{configfile};
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub AUTOLOAD {
|
||||
#
|
||||
# returns the representing value, if it is a scalar.
|
||||
#
|
||||
my($this, $value) = @_;
|
||||
my $key = $Config::General::Extended::AUTOLOAD; # get to know how we were called
|
||||
$key =~ s/.*:://; # remove package name!
|
||||
|
||||
if ($value) {
|
||||
# just set $key to $value!
|
||||
$this->{config}->{$key} = $value;
|
||||
}
|
||||
elsif (exists $this->{config}->{$key}) {
|
||||
if ($this->is_hash($key)) {
|
||||
croak "\"$key\" points to a hash and cannot be automatically accessed\n";
|
||||
}
|
||||
elsif ($this->is_array($key)) {
|
||||
croak "\"$key\" points to an array and cannot be automatically accessed\n";
|
||||
}
|
||||
else {
|
||||
return $this->{config}->{$key};
|
||||
}
|
||||
}
|
||||
else {
|
||||
croak "\"$key\" does not exist within current object\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub DESTROY {
|
||||
my $this = shift;
|
||||
$this = ();
|
||||
}
|
||||
|
||||
# keep this one
|
||||
1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Config::General::Extended - Extended access to Config files
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Config::General::Extended;
|
||||
$conf = new Config::General::Extended("rcfile");
|
||||
# or
|
||||
$conf = new Config::General::Extended(\%somehash);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module is a subclass of B<Config::General>. You can use it if
|
||||
you want OO access to parts of your config file. The following methods
|
||||
are directly inherited from Config::General: B<new() getall()>.
|
||||
|
||||
Please refer to the L<Config::General>, if you want to learn about the usage
|
||||
of the two methods mentioned above. The possible format of config files supported
|
||||
by this module is also well described in L<Config::General>.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=over
|
||||
|
||||
=item new(filename) or new(\%somehash)
|
||||
|
||||
This method returns a B<Config::General> object (a hash blessed into "Config::General::Extended"
|
||||
namespace. All further methods must be used from that returned object. see below.
|
||||
|
||||
Read a more detailed discussion on how to use the new() method in L<Config::General>.
|
||||
|
||||
|
||||
=item NoMultiOptions()
|
||||
|
||||
This method only exists for compatibility reasons.
|
||||
Now you should set the new() flag B<-AllowMultiOptions>
|
||||
to "no".
|
||||
|
||||
Refer to L<Config::General> for details about this method.
|
||||
|
||||
=item getall()
|
||||
|
||||
Returns a hash structure which represents the whole config.
|
||||
|
||||
If you use this method, then it would be probably
|
||||
better to use the simpler module B<Config::General>. It is just mentioned here
|
||||
for completeness.
|
||||
|
||||
|
||||
=item save()
|
||||
|
||||
|
||||
Writes the current config hash back to the harddisk.
|
||||
It takes an optional argument: B<filename>. If you omit a filename, save() will
|
||||
use the filename configured by the method B<configfile()> or B<new()> (see below).
|
||||
|
||||
|
||||
|
||||
=item configfile('filename')
|
||||
|
||||
Set the filename to be used by B<save> to "filename". It returns the current
|
||||
configured filename if called without arguments.
|
||||
|
||||
|
||||
=item obj('key')
|
||||
|
||||
Returns a new object (of Config::General::Extended Class) from the given key.
|
||||
Short example:
|
||||
Assume you have the following config:
|
||||
|
||||
<individual>
|
||||
<martin>
|
||||
age 23
|
||||
</martin>
|
||||
<joseph>
|
||||
age 56
|
||||
</joseph>
|
||||
</individual>
|
||||
<other>
|
||||
blah blubber
|
||||
blah gobble
|
||||
leer
|
||||
</other>
|
||||
|
||||
and already read it in using B<Config::General::Extended::new()>, then you can get a
|
||||
new object from the "individual" block this way:
|
||||
|
||||
$individual = $conf->obj("individual");
|
||||
|
||||
Now if you call B<getall> on I<$individual> (just for reference) you would get:
|
||||
|
||||
$VAR1 = (
|
||||
martin => { age => 13 }
|
||||
);
|
||||
|
||||
Or, here is another use:
|
||||
|
||||
my $individual = $conf->obj("individual");
|
||||
foreach my $person ($conf->keys("individual")) {
|
||||
$man = $individual->obj($person);
|
||||
print "$person is " . $man->value("age") . " years old\n";
|
||||
}
|
||||
|
||||
See the discussion on B<hash()> and B<value()> below.
|
||||
|
||||
If the key from which you want to create a new object is empty, an empty
|
||||
object will be returned. If you run the following on the above config:
|
||||
|
||||
$obj = $conf->obj("other")->obj("leer");
|
||||
|
||||
Then $obj will be empty, just like if you have had run this:
|
||||
|
||||
$obj = new Config::General::Extended( () );
|
||||
|
||||
Read operations on this empty object will return nothing or even fail.
|
||||
But you can use an empty object for I<creating> a new config using write
|
||||
operations, i.e.:
|
||||
|
||||
$obj->someoption("value");
|
||||
|
||||
See the discussion on B<AUTOLOAD METHODS> below.
|
||||
|
||||
=item hash('key')
|
||||
|
||||
This method returns a hash(if it B<is> one!) from the config which is referenced by
|
||||
"key". Given the sample config above you would get:
|
||||
|
||||
my %sub_hash = $conf->hash("individual");
|
||||
print Dumper(\%sub_hash);
|
||||
$VAR1 = {
|
||||
martin => { age => 13 }
|
||||
};
|
||||
|
||||
=item array('key')
|
||||
|
||||
This the equivalent of B<hash()> mentioned above, except that it returns an array.
|
||||
Again, we use the sample config mentioned above:
|
||||
|
||||
$other = $conf->obj("other");
|
||||
my @blahs = $other->array("blah");
|
||||
print Dumper(\@blahs);
|
||||
$VAR1 = [ "blubber", "gobble" ];
|
||||
|
||||
|
||||
=item value('key')
|
||||
|
||||
This method returns the scalar value of a given key. Given the following sample
|
||||
config:
|
||||
|
||||
name = arthur
|
||||
age = 23
|
||||
|
||||
you could do something like that:
|
||||
|
||||
print $conf->value("name") . " is " . $conf->value("age") . " years old\n";
|
||||
|
||||
|
||||
|
||||
You can use this method also to set the value of "key" to something if you give over
|
||||
a hash reference, array reference or a scalar in addition to the key. An example:
|
||||
|
||||
$conf->value("key", \%somehash);
|
||||
# or
|
||||
$conf->value("key", \@somearray);
|
||||
# or
|
||||
$conf->value("key", $somescalar);
|
||||
|
||||
Please note, that this method does not complain about existing values within "key"!
|
||||
|
||||
=item is_hash('key') is_array('key') is_scalar('key')
|
||||
|
||||
As seen above, you can access parts of your current config using hash, array or scalar
|
||||
methods. But you are right if you guess, that this might become problematic, if
|
||||
for example you call B<hash()> on a key which is in real not a hash but a scalar. Under
|
||||
normal circumstances perl would refuse this and die.
|
||||
|
||||
To avoid such behavior you can use one of the methods is_hash() is_array() is_scalar() to
|
||||
check if the value of "key" is really what you expect it to be.
|
||||
|
||||
An example(based on the config example from above):
|
||||
|
||||
if($conf->is_hash("individual") {
|
||||
$individual = $conf->obj("individual");
|
||||
}
|
||||
else {
|
||||
die "You need to configure a "individual" block!\n";
|
||||
}
|
||||
|
||||
|
||||
=item exists('key')
|
||||
|
||||
This method returns just true if the given key exists in the config.
|
||||
|
||||
|
||||
=item keys('key')
|
||||
|
||||
Returns an array of the keys under the specified "key". If you use the example
|
||||
config above you yould do that:
|
||||
|
||||
print Dumper($conf->keys("individual");
|
||||
$VAR1 = [ "martin", "joseph" ];
|
||||
|
||||
You can use this method in B<foreach> loops as seen in an example above(obj() ).
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 AUTOLOAD METHODS
|
||||
|
||||
Another usefull feature is implemented in this class using the B<AUTOLOAD> feature
|
||||
of perl. If you know the keynames of a block within your config, you can access to
|
||||
the values of each individual key using the method notation. See the following example
|
||||
and you will get it:
|
||||
|
||||
We assume the following config:
|
||||
|
||||
<person>
|
||||
name = Moser
|
||||
prename = Peter
|
||||
birth = 12.10.1972
|
||||
</person>
|
||||
|
||||
Now we read it in and process it:
|
||||
|
||||
my $conf = new Config::General::Extended("configfile");
|
||||
my $person = $conf->obj("person");
|
||||
print $person->prename . " " . $person->name . " is " . $person->age . " years old\n";
|
||||
|
||||
This notation supports only scalar values! You need to make sure, that the block
|
||||
<person> does not contain any subblock or multiple identical options(which will become
|
||||
an array after parsing)!
|
||||
|
||||
Of course you can use this kind of methods for writing data too:
|
||||
|
||||
$person->name("Neustein");
|
||||
|
||||
This changes the value of the "name" key to "Neustein". This feature behaves exactly like
|
||||
B<value()>, which means you can assign hash or array references as well and that existing
|
||||
values under the given key will be overwritten.
|
||||
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (c) 2000-2001 Thomas Linden
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the same terms as Perl itself.
|
||||
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
none known yet.
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Thomas Linden <tom@daemon.de>
|
||||
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
1.1
|
||||
|
||||
=cut
|
||||
|
||||
4
README
4
README
@@ -1,7 +1,6 @@
|
||||
NAME
|
||||
Config::General - Generic Config Module
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
use Config::General;
|
||||
$conf = new Config::General("rcfile");
|
||||
@@ -37,6 +36,7 @@ INSTALLATION
|
||||
|
||||
to read the complete documentation, type:
|
||||
perldoc Config::General
|
||||
perldoc Config::General::Extended
|
||||
|
||||
see some example config files which can
|
||||
be parsed with Config::Genreal in the subdirectory
|
||||
@@ -59,4 +59,4 @@ AUTHOR
|
||||
|
||||
|
||||
VERSION
|
||||
1.23
|
||||
1.24
|
||||
|
||||
83
t/run.t
83
t/run.t
@@ -1,15 +1,18 @@
|
||||
#
|
||||
# testscript for Conf.pm by Thomas Linden
|
||||
# testscript for Config::General Classes by Thomas Linden
|
||||
#
|
||||
# needs to be invoked using the command "make test" from
|
||||
# the Conf.pm source directory.
|
||||
# Under normal circumstances every test should run.
|
||||
# the Config::General source directory.
|
||||
#
|
||||
# Under normal circumstances every test should succeed.
|
||||
|
||||
BEGIN { $| = 1; print "1..8\n";}
|
||||
BEGIN { $| = 1; print "1..15\n";}
|
||||
use lib "blib/lib";
|
||||
use Config::General;
|
||||
use Config::General::Extended;
|
||||
use Data::Dumper;
|
||||
print "ok\n";
|
||||
print STDERR "\n1 .. ok # loading Config::General\n";
|
||||
print STDERR "\n1 .. ok # loading Config::General and Config::General::Extended\n";
|
||||
|
||||
foreach (2..7) {
|
||||
&p("t/cfg." . $_, $_);
|
||||
@@ -37,6 +40,76 @@ else {
|
||||
}
|
||||
|
||||
|
||||
############## Extended Tests #################
|
||||
|
||||
$conf = new Config::General::Extended("t/test.rc");
|
||||
print "ok\n";
|
||||
print STDERR "9 .. ok # Creating a new object from config file\n";
|
||||
|
||||
|
||||
|
||||
|
||||
# now test the new notation of new()
|
||||
my $conf2 = new Config::General::Extended(
|
||||
-file => "t/test.rc",
|
||||
-AllowMultiOptions => "yes"
|
||||
);
|
||||
print "ok\n";
|
||||
print STDERR "10 .. ok # Creating a new object using the hash parameter way\n";
|
||||
|
||||
|
||||
|
||||
|
||||
my $domain = $conf->obj("domain");
|
||||
print "ok\n";
|
||||
print STDERR "11 .. ok # Creating a new object from a block\n";
|
||||
|
||||
|
||||
|
||||
|
||||
my $addr = $domain->obj("bar.de");
|
||||
print "ok\n";
|
||||
print STDERR "12 .. ok # Creating a new object from a sub block\n";
|
||||
|
||||
|
||||
|
||||
|
||||
my @keys = $conf->keys("domain");
|
||||
print "ok\n";
|
||||
print STDERR "13 .. ok # Getting values from the object\n";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# test various OO methods
|
||||
if ($conf->is_hash("domain")) {
|
||||
my $domains = $conf->obj("domain");
|
||||
foreach my $domain ($conf->keys("domain")) {
|
||||
my $domain_obj = $domains->obj($domain);
|
||||
foreach my $address ($domains->keys($domain)) {
|
||||
my $blah = $domain_obj->value($address);
|
||||
}
|
||||
}
|
||||
}
|
||||
print "ok\n";
|
||||
print STDERR "14 .. ok # Using keys() and values() \n";
|
||||
|
||||
# test AUTOLOAD methods
|
||||
my $conf3 = new Config::General::Extended( { name => "Moser", prename => "Hannes"}
|
||||
);
|
||||
my $n = $conf3->name;
|
||||
my $p = $conf3->prename;
|
||||
$conf3->name("Meier");
|
||||
$conf3->prename("Max");
|
||||
$conf3->save("t/test.cfg");
|
||||
|
||||
print "ok\n";
|
||||
print STDERR "15 .. ok # Using AUTOLOAD methods\n";
|
||||
|
||||
|
||||
|
||||
|
||||
sub p {
|
||||
my($cfg, $t) = @_;
|
||||
open T, "<$cfg";
|
||||
|
||||
90
t/test.rc
Normal file
90
t/test.rc
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Beispiel .redirect Datei.
|
||||
*
|
||||
* Wenn diese Datei nicht im $HOME des
|
||||
* jeweiligen Benutzers vorhanden ist,
|
||||
* oder wenn die vorhandene Datei aus
|
||||
* irgendeinem Grund ung<6E>ltig ist(Syntax)
|
||||
* dann wird per Default alles an @domain
|
||||
* zum Benutzer weitergeleitet.
|
||||
*
|
||||
* Syntax:
|
||||
* Domain Bl<42>cke beginnen mit <domain name> und enden
|
||||
* mit </domain> (equivalent zu apache config).
|
||||
* Als Kommentare sind # sowie C-Style erlaubt(so
|
||||
* wie dieser hier).
|
||||
* N<>heres zum <domain ...> Block siehe unten.
|
||||
*
|
||||
* Im <var> Block kann man Variablen definieren, auf
|
||||
* die man dann innerhalb der <domain...> Bl<42>cke zu-
|
||||
* greifen kann (siehe <var> sample!)
|
||||
*
|
||||
*
|
||||
* Im <list name> Block kann man Mailinglisten einrichten
|
||||
* allerdings rudiment<6E>r, d.h. es sind eigentlich nur
|
||||
* Verteiler, aber immerhin. Die entsprechende Adresse
|
||||
* muss im dazugeh<65>rigen <domain..> Block definiert sein.
|
||||
*
|
||||
* Angegebene Emailadressen werden (zumindest im Moment)
|
||||
* nicht <20>berpr<70>ft, also 1:1 <20>bernommen, also Sorgfalt
|
||||
* walten lassen.
|
||||
*
|
||||
* Fragen/Kommentare/Kritik/Flames/Mecker an:
|
||||
* Thomas Linden <tom@daemon.de>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Hier kann man Variablen definieren und sp<73>ter mittels
|
||||
* $variablenname verwenden.
|
||||
*********************************************************************
|
||||
*/
|
||||
<var>
|
||||
USER scip # via $USER verwendbar
|
||||
</var>
|
||||
|
||||
host manna
|
||||
host gorky
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* F<>r jede Domain muss ein <domain name> Block vorhanden sein
|
||||
*********************************************************************
|
||||
*/
|
||||
<domain bar.de>
|
||||
foo max@nasa.gov # foo@bar.de nach max@nasa.gov
|
||||
|
||||
coderz %coderz # coderz@bar.de ist ein Verteiler, der
|
||||
# in <list coderz> definiert ist.
|
||||
|
||||
@ $USER # alles andere an "scip" schicken.
|
||||
# Wenn nicht angegeben, kommen unbekannte
|
||||
# Adressen an den Absender zur<75>ck, z.B.
|
||||
# gibtsnet@bar.de w<>rde "Unknown User" ver-
|
||||
# ursachen!
|
||||
</domain>
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Definition einer "Mailingliste", g<>ltige Empf<70>nger m<>ssen mit
|
||||
* dem Parameter "rcpt" definiert werden. <list> Bl<42>cke sind Domain-
|
||||
* unabh<62>ngig, d.h. sie m<>ssen einen eindeutigen Namen haben.
|
||||
*********************************************************************
|
||||
*/
|
||||
<list coderz>
|
||||
rcpt solaar.designer@packetstorm.org
|
||||
rcpt $USER
|
||||
rcpt machine@star.wars.de
|
||||
</list>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user