package Zen::Configo; use strict; use base qw/II720d6e18aa34327713eb014408fc9144/; use Zen; our $Data = {}; our $LoadedFiles = {}; sub get { my $class = shift; my ($name) = @_; $name ||= $class; $name .= '.' . Zen->getLanguage; my $cache = $class->cache; $cache->fetch($name) || $cache->store($name, $class->new(@_)); } sub new { my ($class, $scope) = @_; die 'call get() instead of new()' unless (caller(1))[3] =~ /::get$/; $class->loadFile($_) for $class, $scope; my $lang = Zen->getLanguage; $Data->{$lang}{$scope} ||= {}; $class->SUPER::assume($Data->{$lang}{$scope}); } sub scope { $_[0]->{_scope} } sub enum { my $this = shift; my $sec = shift; return $this->{_keys}{$sec} ? @{$this->{_keys}{$sec}} : (); } sub enumSecs { my $this = shift; $this->{_keys} ? keys %{ $this->{_keys} } : (); } sub getSet { my ($this, $sec, $key) = @_; grep {length $_} split(/[^\w\.]+/, $this->{$sec}{$key}); } sub scope2file { my ($this, $scope) = @_; my $fore; if ($scope eq 'FORE') { $scope = $this->scope; $fore = 1; } Zen->configFILE($scope, $fore); } sub loadFile { my ($class, $scope, $defaultSection) = @_; my $file = $class->scope2file($scope); return if $LoadedFiles->{$file} || ! $file || ! -f $file; my $fh; open $fh, $file or die "failed to open file [$file]: $!"; $LoadedFiles->{$file} = 1; my $lang = Zen->getLanguage; my $sec = $defaultSection || 'main'; $Data->{$lang}{$scope} ||= {}; my ($key, $val, $str); while (my $line = <$fh>) { $line =~ s/[\r\n]//g; if (($str) = $line =~ /^#include\s+(.*)/i) { die "invalid config directive: $line\n" unless $str =~ /([\w:]+)(?:\s+under\s+(\w+))?/; my ($incScope, $defSec) = ($1, $2); $class->loadFile($incScope, $defSec); my $incCfg = $Data->{$lang}{$incScope}; for my $s (keys %{ $incCfg->{_keys} }) { for my $k (@{ $incCfg->{_keys}{$s} }) { push @{$Data->{$lang}{$scope}{_keys}{$s}}, $k unless exists $Data->{$lang}{$scope}{$s}{$k}; $Data->{$lang}{$scope}{$s}{$k} = $incCfg->{$s}{$k}; } } } elsif ($line =~ /^#alias\s+(\w+)\.(\w+)\s+(\w+)\.(\w+)/) { push @{$Data->{$lang}{$scope}{_keys}{$1}}, $2 unless exists $Data->{$lang}{$scope}{$1}{$2}; $Data->{$lang}{$scope}{$1}{$2} = $Data->{$lang}{$scope}{$3}{$4}; } elsif ($line =~ /^[#;]/) { } elsif ($line =~ /^\[(.+?)\]/) { $sec = $1; } elsif ($line =~ /^@([\w\:]+)/) { $scope = $1; $Data->{$lang}{$scope} ||= {}; $class->loadFile($scope); $sec = 'main'; } elsif (($key, $val) = $line =~ /^([^=]*?)=(.*)$/) { if ($val =~ /^\s*<<(\w+)/) { my $ender = $1; $val = ''; while (my $subline = <$fh>) { last if $subline =~ /^$ender/; $val .= $subline; } } push @{$Data->{$lang}{$scope}{_keys}{$sec}}, $key unless exists $Data->{$lang}{$scope}{$sec}{$key}; $Data->{$lang}{$scope}{$sec}{$key} = $val; } } close $fh; return; } 1; 