aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndy Shevchenko <andy@smile.org.ua>2012-07-28 15:42:38 +0000
committerAndy Shevchenko <andy@smile.org.ua>2012-07-28 15:42:38 +0000
commit1950483d97958f219a5ab0dbf1cab147a59c92ac (patch)
tree3de5f2d7947d6d6a19e0944dc443614de729d7df /lib
parent4586f2d154dd4657072e4e025e45d822d95abf12 (diff)
downloadrenrot-1950483d97958f219a5ab0dbf1cab147a59c92ac.tar.gz
renrot-1950483d97958f219a5ab0dbf1cab147a59c92ac.tar.bz2
config: move configuration framework to Image::RenRot::Config
Split configuration framework to its own module. Additionally rename following functions: strToHash() -> str2hash() parseConfigFile() -> parsefile() update_config_option_value() -> update_cfg_value() parse_many_pairs() -> parse2hash() assign_hash_values() -> assign2hash() apply_config_values() -> apply() Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com> git-svn-id: file:///svnroot/renrot/trunk@610 fe2816f4-e837-0410-b10a-f608c9d244a1
Diffstat (limited to 'lib')
-rw-r--r--lib/Image/RenRot/Config.pm253
1 files changed, 253 insertions, 0 deletions
diff --git a/lib/Image/RenRot/Config.pm b/lib/Image/RenRot/Config.pm
new file mode 100644
index 0000000..943b8c0
--- /dev/null
+++ b/lib/Image/RenRot/Config.pm
@@ -0,0 +1,253 @@
+package Image::RenRot::Config;
+
+#
+# vim: ts=2 sw=2 et :
+#
+
+########################################################################################
+### CONFIGURATION FRAMEWORK ###
+########################################################################################
+
+use strict;
+use warnings;
+require 5.006;
+require Exporter;
+
+use Image::RenRot::Util;
+use Image::RenRot::Logging;
+
+use vars qw(@ISA @EXPORT);
+
+@ISA = qw(Exporter);
+@EXPORT = qw(str2hash update_cfg_value parse2hash assign2hash get_cfg_value);
+
+my %options = (
+ Sections => [],
+ MultiOptions => [],
+);
+
+sub init {
+ my $self = shift;
+
+ while (@_) {
+ my $option = shift;
+ my $value = shift;
+
+ map { push(@{$options{$option}}, $_) } @$value;
+ }
+}
+
+my %incFiles = (); # hash of included files while parsing configuration file
+
+########################################################################################
+# Usage : parsekv() gets (key, value) pair from the string like
+# : [multiword] key = "value"
+# Purpose : parses pairs of data
+# Returns : $key, $value string
+# Parameters : string like [multiword] key = "value"
+# Throws : no exceptions
+# Comments : none
+# See Also : N/A
+sub parsekv {
+ my $str = shift;
+ my $key = undef;
+ my $value = shift;
+
+ if ($str =~ m/^([^=]+)=(.+)/) {
+ ($key, $value) = (trim($1), trim($2));
+ $value =~ s/^[\'\"](.+)[\'\"]/$1/; # trim quotes
+ dbgmsg (4, "Parsed: '$key' <- '$value'\n");
+ } elsif ($str =~ m/^([^=]+)=$/) {
+ $key = trim($1);
+ dbgmsg (4, "Parsed empty '$key', applying default value: ", defined $value ? "'$value'" : "undef", "\n");
+ }
+
+ return ($key, $value);
+}
+
+########################################################################################
+#
+# str2hash() parses given string to a hash
+#
+sub str2hash {
+ my $str = shift;
+ my $default = shift;
+ my %hash = ();
+
+ $str =~ s/:/=/; # change first occurrence of ':' to '='
+ my ($key, $value) = parsekv($str, $default);
+ if (defined $key) {
+ $key =~ s/\s*[\(\[]([^\(\)\[\]]*)[\)\]]$//;
+ my $group = (defined $1 and $1 ne "") ? $1 : undef;
+ $hash{$key} = {value => $value, group => $group};
+
+ # Print debug message
+ $value = "" if (not defined $value);
+ $group = "" if (not defined $group);
+ dbgmsg (4, "Parsed: $key [$group] = '$value'\n");
+ } else {
+ warnmsg ("Invalid line format: $str\n");
+ }
+ return %hash;
+}
+
+########################################################################################
+#
+# parsefile() parses one file to a hash and merges it with already passed
+#
+sub parsefile {
+ my $self = shift;
+ my $file = shift;
+ my $hash = shift;
+ my $fc = @_ ? shift : 1;
+
+ return if (not -f $file);
+
+ my $tmphash = {};
+
+ if (open (CFGFILE, "<$file")) {
+ my @cfgfile = <CFGFILE>;
+ unless (close (CFGFILE)) { errmsg ("$file wasn't closed!\n"); }
+ $incFiles{$file} = $fc;
+ my $i = 0;
+ while ($i < scalar(@cfgfile)) {
+ my $line = $cfgfile[$i++];
+
+ # skip empty and comment lines
+ next if (($line =~ m/^\s*$/) or ($line =~ m/^\s*#/));
+
+ $line =~ s/#(.*)$//; # remove trailing comments
+
+ my ($key, $value) = parsekv($line);
+ if (defined $value) {
+ $key = lc($key);
+ if ($key eq "include" and not $incFiles{$value}) {
+ dbgmsg (2, "Parsing included file: '$value'\n");
+ $self->parsefile($value, $tmphash, $fc + 1);
+ }
+ $key .= sprintf("#%d#%d", $fc, $i) if (grep (/^$key$/, @{$options{MultiOptions}}));
+ $key .= ' ' . 'enabled' if (grep (/^$key$/, @{$options{Sections}}));
+ $tmphash->{$key} = str2bool($value);
+ dbgmsg (3, "Parsed line($i): '$key' <- '$tmphash->{$key}'\n");
+ } else {
+ warnmsg ("Unparsed line $i in configuration file.\n");
+ }
+ }
+ } else {
+ errmsg ("Can't open configuration file: $file\n");
+ }
+ map { $hash->{$_} = $tmphash->{$_} } keys %$tmphash;
+}
+
+########################################################################################
+#
+# update_cfg_value()
+#
+sub update_cfg_value {
+ my $hash = shift;
+ my $value = shift;
+ return if (not defined $value);
+ if (not defined $hash->{default}) {
+ $hash->{default} = $hash->{value};
+ }
+ $hash->{value} = $value;
+}
+
+########################################################################################
+# Usage : parse2hash() gets hash with (key, value) pairs from the string like
+# : key1="value1":key2="value2":...:keyM="valueN"
+# Purpose : parses pairs of data
+# Returns : filled hash %hash
+# Parameters : $str [str] string like key1="value1":key2="value2":...:keyM="valueN"
+# $hash [ref] reference to hash
+# $option [str] subtree in the hash
+# Throws : no exceptions
+# Comments : "value1", "value2", ..., "valueN" should not contain ':' symbol
+# See Also : parsekv()
+sub parse2hash {
+ my $str = shift;
+ my $hash = shift;
+ my $sect = shift;
+
+ return if (not defined $str);
+
+ my @k = keys %{$hash->{$sect}};
+ foreach my $pair (split(/:/, $str)) {
+ my ($key, $value) = parsekv($pair);
+ next if (not defined $key);
+ if (not grep (/^$key$/, @k)) {
+ warnmsg ("Invalid key '$key' in '$sect'. Skiping...\n");
+ next;
+ }
+ $value = str2bool($value) if ($hash->{$sect}{$key}{type} eq "!");
+ update_cfg_value($hash->{$sect}{$key}, $value);
+ dbgmsg (4, "Parsed: '$sect' -> '$key': '$value'\n");
+ }
+}
+
+########################################################################################
+#
+# assign2hash() assignes given values to a hash
+#
+sub assign2hash {
+ my $hash = shift;
+ my $sect = shift;
+ my $values = shift;
+ return if (not defined $values);
+ map { update_cfg_value($hash->{$sect}{$_}, $values->{$_}) } keys %$values;
+}
+
+########################################################################################
+#
+# apply() applies values by priority:
+# default -> config -> CLI new -> CLI old
+#
+sub apply {
+ my $self = shift;
+ my $hash = shift;
+ my $value;
+
+ foreach my $option (keys %$hash) {
+ next if (ref($hash->{$option}) ne ""); # Skip non-SCALAR
+ next if ($option =~ m/^[^#]+#\d+#\d+$/); # Skip multi-option
+
+ my ($sect, $key) = undef;
+ foreach my $s (@{${options}{Sections}}) {
+ if ($option =~ m/^$s(.*)/) {
+ ($sect, $key) = ($s, trim($1));
+ last;
+ }
+ }
+ ($sect, $key) = ('general', $option) if (not defined $sect);
+ next if (not defined $hash->{$sect}{$key});
+
+ dbgmsg (4, "Option '$option' will be put into '$sect'\n");
+
+ # Get default value
+ $value = $hash->{$sect}{$key}{default};
+ my $vdef = (defined $value) ? $value : "undef"; # For debug message
+
+ # Apply value from configuration file
+ $value = $hash->{$option} if (defined $hash->{$option});
+ my $vcfg = (defined $hash->{$option}) ? $value : "undef"; # For debug message
+
+ # Apply value from command line
+ $hash->{$sect}{$key}{value} = $value if (not defined $hash->{$sect}{$key}{value});
+
+ dbgmsg (4, "'$vdef' -> '$vcfg' -> '$hash->{$sect}{$key}{value}'\n");
+ }
+}
+
+########################################################################################
+#
+# get_cfg_value() returnes value of the given configuration option
+#
+sub get_cfg_value {
+ my $hash = shift;
+ my $key = shift;
+ return $hash->{$key}{value} if (defined $hash->{$key}{value});
+ return $hash->{$key}{default};
+}
+
+########################################################################################
+1; # end

Return to:

Send suggestions and report system problems to the System administrator.