summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2018-07-10 11:55:54 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2018-07-10 11:55:54 +0200
commitcc81fa13ff5a8402457a860a0e64d76d3d89b8d9 (patch)
treee287607491077d0946868ec26a7d236a9a56ec1d
parent90d7ba0cd178ca223355c8bcb1cf6c1174bee794 (diff)
downloadconfig-ast-cc81fa13ff5a8402457a860a0e64d76d3d89b8d9.tar.gz
config-ast-cc81fa13ff5a8402457a860a0e64d76d3d89b8d9.tar.bz2
Rename to Config::AST
-rw-r--r--Makefile.PL6
-rw-r--r--lib/Config/AST.pm (renamed from lib/Config/Tree.pm)248
-rw-r--r--lib/Config/AST/Node.pm (renamed from lib/Config/Tree/Node.pm)14
-rw-r--r--lib/Config/AST/Node/Null.pm (renamed from lib/Config/Tree/Node/Null.pm)4
-rw-r--r--lib/Config/AST/Node/Section.pm (renamed from lib/Config/Tree/Node/Section.pm)8
-rw-r--r--lib/Config/AST/Node/Value.pm (renamed from lib/Config/Tree/Node/Value.pm)4
-rw-r--r--t/01conf03.t2
-rw-r--r--t/01conf04.t2
-rw-r--r--t/01conf05.t2
-rw-r--r--t/01conf06.t2
-rw-r--r--t/01conf07.t2
-rw-r--r--t/01conf08.t2
-rw-r--r--t/01conf09.t2
-rw-r--r--t/01conf10.t2
-rw-r--r--t/01conf13.t4
-rw-r--r--t/01conf14.t4
-rw-r--r--t/01conf15.t4
-rw-r--r--t/02merge.t18
-rw-r--r--t/TestConfig.pm6
19 files changed, 219 insertions, 117 deletions
diff --git a/Makefile.PL b/Makefile.PL
index cedef68..80b1928 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -1,15 +1,15 @@
# -*- perl -*-
use strict;
use warnings;
use ExtUtils::MakeMaker;
use Module::Metadata;
-WriteMakefile(NAME => 'Config::Tree',
- ABSTRACT_FROM => 'lib/Config/Tree.pm',
- VERSION_FROM => 'lib/Config/Tree.pm',
+WriteMakefile(NAME => 'Config::AST',
+ ABSTRACT_FROM => 'lib/Config/AST.pm',
+ VERSION_FROM => 'lib/Config/AST.pm',
AUTHOR => 'Sergey Poznyakoff <gray@gnu.org>',
LICENSE => 'gpl_3',
MIN_PERL_VERSION => 5.016001,
PREREQ_PM => {
'Carp' => 0,
'Clone' => 0,
diff --git a/lib/Config/Tree.pm b/lib/Config/AST.pm
index b4d2728..5774865 100644
--- a/lib/Config/Tree.pm
+++ b/lib/Config/AST.pm
@@ -11,37 +11,37 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-package Config::Tree;
+package Config::AST;
use strict;
use warnings;
use Carp;
use Text::Locus;
-use Config::Tree::Node qw(:sort);
-use Config::Tree::Node::Section;
-use Config::Tree::Node::Value;
+use Config::AST::Node qw(:sort);
+use Config::AST::Node::Section;
+use Config::AST::Node::Value;
use Data::Dumper;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'sort' => [ qw(NO_SORT SORT_NATURAL SORT_PATH) ] );
our @EXPORT_OK = qw(NO_SORT SORT_NATURAL SORT_PATH);
our $VERSION = "1.00";
=head1 NAME
-Config::Tree - generalized configuration file parser
+Config::AST - abstract syntax tree for configuration files
=head1 SYNOPSIS
- my $cfg = new Config::Tree($filename, %opts);
+ my $cfg = new Config::AST($filename, %opts);
$cfg->parse() or die;
if ($cfg->is_set('core', 'variable')) {
...
}
@@ -50,51 +50,103 @@ Config::Tree - generalized configuration file parser
$cfg->set('file', 'locking', 'true');
$cfg->unset('file', 'locking');
=head1 DESCRIPTION
-Configuration file handling. Features:
+This module aims to provide a generalized implementation of parse tree
+for various configuration files. It does not implement parser for any existing
+configuration file format. Instead, it provides an API that can be used by
+parsers to build internal representation for the particular configuration file
+format.
+
+A configuration file in general is supposed to consist of statements of two
+kinds: simple statements, and sections. A simple statement declares or sets
+a configuration parameter. Examples of simple statements are:
+
+ # Bind configuration file:
+ file "cache/named.root";
+
+ # Apache configuration file:
+ ServerName example.com
+
+ # Git configuration file:
+ logallrefupdates = true
+
+A section statement groups together a number of another statements. These
+can be simple statements, as well as another sections. Examples of sections
+are (with subordinate statements replaced with ellipsis):
+
+ # Bind configuration file:
+ zone "." {
+ ...
+ };
+
+ # Apache configuration file:
+ <VirtualHost *:80>
+ ...
+ </VirtualHost>
+
+ # Git configuration file:
+ [core]
+ ...
+
+Syntax of Git configuration file being one of the simplest, we will use
+it in the discussion below to illustrate various concepts.
+
+The abstract syntax tree (AST) for configuration file consists of nodes.
+Each node represents a single statement and carries detailed information
+about that statement, in particular:
=over 4
-=item 1
-
-Handles I<git>-format configuration files.
+=item B<locus>
-=item 2
+Location of the statement in the configuration. It is represented by an
+object of class B<Text::Locus>.
-Table-driven syntax checking and validation.
+=item order
-=item 3
+0-based number reflecting position of this node in the parent section
+node.
-Optional caching facility allows for faster loading. This is especially
-useful for big configurations.
+=item value
-=item 4
+For simple statements - the value of this statement.
-Built-in B<lint> facility.
+=item subtree
-=item 5
+For sections - the subtree below this section.
-Location tracking.
+=back
-=item 6
+The type of each node can be determined using the following node attributes:
-Dump facility. The parsed configuration can be output to the given file
-handler in a standardized form.
+=over 4
+
+=item is_section
-=item 7
+True if node is a section node.
-Both random access and iteration over all settings is possible.
+=item is_value
+
+True if node is a simple statement.
=back
-=head1 METHODS
+To retrieve a node, address it using its I<full path>, i.e. list of statement
+names that lead to this node. For example, in this simple configuration file:
+
+ [core]
+ filemode = true
+
+the path of the C<filemode> statement is C<qw(core filemode)>.
+
+=head1 CONSTRUCTOR
-=head2 $cfg = new Config::Tree($filename, %opts);
+ $cfg = new Config::AST($filename, %opts);
Creates new configuration object for file B<$filename>. Valid
options are:
=over 4
@@ -104,21 +156,21 @@ Sets debug verbosity level.
=item B<ci> => B<0> | B<1>
If B<1>, enables case-insensitive keyword matching. Default is B<0>,
i.e. the keywords are case-sensitive.
-=item B<parameters> => \%hash
+=item B<lexicon> => \%hash
-Defines the syntax table. See below for a description of B<%hash>.
+Defines the keywords lexicon. See below for a description of B<%hash>.
=back
-=head3 Syntax hash
+=head3 Keywords lexicon
-The hash reference passed via the B<parameters> keyword defines the keywords
+The hash reference passed via the B<lexicon> keyword defines the keywords
and sections allowed within a configuration file. In a simplest case, a
keyword is described as
name => 1
This means that B<name> is a valid keyword, but does not imply anything
@@ -132,19 +184,19 @@ keywords:
Whether or not this setting is mandatory.
=item default => I<VALUE>
Default value for the setting. This value will be assigned if that particular
-variable is not explicilty assigned in the configuration file. If I<VALUE>
+statement is not explicilty used in the configuration file. If I<VALUE>
is a CODE reference, it will be invoked as a method each time the value is
accessed.
Default values must be pure Perl values (not the values that should appear
in the configuration file). They are not processed using the B<check>
-callbacks.
+callbacks (see below).
=item array => 0 | 1
If B<1>, the value of the setting is an array. Each subsequent occurrence
of the statement appends its value to the end of the array.
@@ -158,13 +210,13 @@ a syntax error will be reported.
Reference to a method which will be called in order to decide whether to
apply this hash to a particular configuration setting. The method is
called as
$self->$coderef($node, @path)
-where $node is the B<Config::Tree::Node::Value> object (use
+where $node is the B<Config::AST::Node::Value> object (use
B<$vref-E<gt>value>, to obtain the actual value), and B<@path> is its patname.
=item check => I<coderef>
Defines a method which will be called after parsing the statement in order to
verify its value. The I<coderef> is called as
@@ -193,29 +245,33 @@ To define a section, use the B<section> keyword, e.g.:
verbose => {
re => qr/^(?:on|off)/i
}
}
}
-This says that the section B<[core]> can have two variables: B<pidfile>, which
-is mandatory, and B<verbose>, whose value must be B<on>, or B<off> (case-
-insensitive).
+This says that the section named B<core> can have two variables: B<pidfile>,
+which is mandatory, and B<verbose>, whose value must be B<on>, or B<off>
+(case-insensitive). E.g.:
+
+ [core]
+ pidfile = /run/ast.pid
+ verbose = off
To accept arbitrary keywords, use B<*>. For example, the following
-declares the B<[code]> section, which must have the B<pidfile> setting
+declares B<code> section, which must have the B<pidfile> setting
and is allowed to have any other settings as well.
code => {
section => {
pidfile => { mandatory => 1 },
'*' => 1
}
}
Everything said above applies to the B<'*'> as well. E.g. the following
-example declares the B<[code]> section, which must have the B<pidfile>
+example declares the B<code> section, which must have the B<pidfile>
setting and is allowed to have I<subsections> with arbitrary settings.
code => {
section => {
pidfile = { mandatory => 1 },
'*' => {
@@ -227,13 +283,13 @@ setting and is allowed to have I<subsections> with arbitrary settings.
}
The special entry
'*' => '*'
-means "any settings and any subsections".
+means "any settings and any subsections are allowed".
=cut
sub new {
my $class = shift;
local %_ = @_;
@@ -241,17 +297,17 @@ sub new {
my $v;
my $err;
$self->{_debug} = delete $_{debug} || 0;
$self->{_ci} = delete $_{ci} || 0;
- if (defined($v = delete $_{parameters})) {
+ if (defined($v = delete $_{lexicon})) {
if (ref($v) eq 'HASH') {
- $self->{_parameters} = $v;
+ $self->{_lexicon} = $v;
} else {
- carp "parameters must refer to a HASH";
+ carp "lexicon must refer to a HASH";
++$err;
}
}
if (keys(%_)) {
foreach my $k (keys %_) {
@@ -261,12 +317,20 @@ sub new {
}
croak "can't create configuration instance" if $err;
$self->reset;
return $self;
}
+=head1 METHODS
+
+=head2 $cfg->reset;
+
+Resets the parse tree.
+
+=cut
+
sub reset {
my $self = shift;
$self->{_error_count} = 0;
delete $self->{_tree};
}
@@ -315,18 +379,18 @@ sub _fixup {
if (exists($d->{default}) && !$section->has_key($k)) {
my $n;
my $dfl = ref($d->{default}) eq 'CODE'
? sub { $self->${ \ $d->{default} } }
: $d->{default};
if (exists($d->{section})) {
- $n = new Config::Tree::Node::Section(
+ $n = new Config::AST::Node::Section(
default => 1,
subtree => $dfl
);
} else {
- $n = new Config::Tree::Node::Value(
+ $n = new Config::AST::Node::Value(
default => 1,
value => $dfl
);
}
$section->subtree($k => $n);
}
@@ -341,13 +405,13 @@ sub _fixup {
}
} elsif ($vref->is_section) {
$self->_fixup($vref, $d->{section}, @path, $name);
}
}
} else {
- my $node = new Config::Tree::Node::Section;
+ my $node = new Config::AST::Node::Section;
$self->_fixup($node, $d->{section}, @path, $k);
if ($node->keys > 0) {
# If the newly created node contains any subnodes
# after fixup, they were created because syntax
# contained mandatory variables with default values.
# Treat sections containing such variables as
@@ -366,13 +430,13 @@ sub _fixup {
}
}
} else {
my $node;
unless ($node = $section->subtree($k)) {
- $node = new Config::Tree::Node::Section;
+ $node = new Config::AST::Node::Section;
}
if ((!exists($d->{select})
|| $self->${ \ $d->{select} }($node, @path, $k))) {
$self->_fixup($node, $d->{section}, @path, $k);
}
if ($node->keys > 0) {
@@ -394,37 +458,57 @@ sub _fixup {
}
}
}
=head2 $cfg->parse(...)
-Parses the configuration file and stores the data in the object. Returns
-true on success and false on failure. Eventual errors in the configuration
-are reported using B<error>.
+Abstract method that is supposed to actually parse the configuration file
+and build the parse tree from it. Derived classes must overload it.
+
+The must return true on success and false on failure. Eventual errors in
+the configuration should be reported using B<error>.
=cut
sub parse {
my ($self) = @_;
croak "call to abstract method"
}
+=head2 $cfg->commit
+
+Must be called after B<parse> to finalize the parse tree. This function
+does the actual syntax checking and applied default values to the statements
+where such are defined. Returns true on success.
+
+=cut
+
+sub commit {
+ my ($self) = @_;
+ # FIXME
+ $self->_fixup($self->tree, $self->{_lexicon})
+ if exists $self->{_lexicon};
+ return $self->{_error_count} == 0;
+}
+
sub getnode {
my $self = shift;
my $node = $self->{_tree} or return undef;
for (@_) {
$node = $node->subtree($self->{_ci} ? lc($_) : $_)
or return undef;
}
return $node;
}
+=head1 NODE RETRIEVAL
+
=head2 $var = $cfg->get(@path);
-Returns the B<Config::Tree::Node::Value>(3) corresponding to the
+Returns the B<Config::AST::Node::Value>(3) corresponding to the
configuration variable represented by its I<path>, or B<undef> if the
variable is not set. The path is a list of configuration variables leading
to the value in question. For example, the following statement:
pidfile = /var/run/x.pid
@@ -472,46 +556,59 @@ sub is_set {
return defined $self->getnode(@_);
}
=head2 $cfg->is_section(@path)
Returns true if the configuration section addressed by B<@path> is
-set.
+defined.
=cut
sub is_section {
my $self = shift;
my $node = $self->getnode(@_);
return defined($node) && $node->is_section;
}
=head2 $cfg->is_variable(@path)
Returns true if the configuration setting addressed by B<@path>
-is set and is a variable.
+is set and is a simple statement.
=cut
sub is_variable {
my $self = shift;
my $node = $self->getnode(@_);
return defined($node) && $node->is_value;
}
+=head2 $cfg->tree
+
+ Returns the parse tree.
+
+=cut
+
sub tree {
my $self = shift;
- return $self->{_tree} //= new Config::Tree::Node::Section(locus => new Text::Locus);
+ return $self->{_tree} //= new Config::AST::Node::Section(locus => new Text::Locus);
}
+=head2 $cfg->subtree(@path)
+
+Returns the configuration subtree associated with the statement indicated by
+B<@path>.
+
+=cut
+
sub subtree {
my $self = shift;
return $self->tree->subtree(@_);
}
-sub _get_section_synt {
+sub _section_lexicon {
my ($self, $kw, $name) = @_;
if (defined($kw)) {
if (ref($kw) eq 'HASH') {
my $synt;
if (exists($kw->{$name})) {
@@ -532,26 +629,32 @@ sub _get_section_synt {
return
}
use constant TAINT => eval '${^TAINT}';
use constant TESTS => TAINT && defined eval 'require Taint::Util';
-=head2 add_node($path, $node)
+=head2 $cfg->add_node($path, $node)
+
+Adds the node in the node corresponding to B<$path>. B<$path> can be
+either a list of keyword names, or its string representation, where
+names are separated by dots. I.e., the following two calls are equivalent:
- FIXME
+ $cfg->add_node(qw(core pidfile), $node)
+
+ $cfg->add_node('core.pidfile', $node)
=cut
sub add_node {
my ($self, $path, $node) = @_;
unless (ref($path) eq 'ARRAY') {
$path = [ split(/\./, $path) ]
}
- my $kw = $self->{_parameters} // { '*' => '*' };
+ my $kw = $self->{_lexicon} // { '*' => '*' };
my $tree = $self->tree;
my $pn = $#{$path};
my $name;
my $locus = $node->locus;
for (my $i = 0; $i < $pn; $i++) {
$name = ${$path}[$i];
@@ -559,24 +662,24 @@ sub add_node {
unless ($tree->is_section) {
$self->error(join('.', @{$path}[0..$i]) . ": not a section");
$self->{_error_count}++;
return;
}
- $kw = $self->_get_section_synt($kw, $name);
+ $kw = $self->_section_lexicon($kw, $name);
unless ($kw) {
$self->error(join('.', @{$path}[0..$i]) . ": unknown section");
$self->{_error_count}++;
return;
}
if (my $subtree = $tree->subtree($name)) {
$tree = $subtree;
} else {
$tree = $tree->subtree(
- $name => new Config::Tree::Node::Section(
+ $name => new Config::AST::Node::Section(
order => $self->{_order}++,
locus => $locus->clone)
);
}
}
@@ -656,26 +759,25 @@ sub add_node {
}
$newnode->order($self->{order}++);
$newnode->value($v);
return $newnode;
}
+=head2 $cfg->add_value($path, $value, $locus)
+
+Adds a statement node with the given B<$value> and B<$locus> in position,
+indicated by $path.
+
+=cut
+
sub add_value {
my ($self, $path, $value, $locus) = @_;
- $self->add_node($path, new Config::Tree::Node::Value(value => $value,
+ $self->add_node($path, new Config::AST::Node::Value(value => $value,
locus => $locus));
}
-sub commit {
- my ($self) = @_;
- # FIXME
- $self->_fixup($self->tree, $self->{_parameters})
- if exists $self->{_parameters};
- return $self->{_error_count} == 0;
-}
-
=head2 $cfg->set(@path, $value)
Sets the configuration variable B<@path> to B<$value>.
=cut
@@ -687,19 +789,19 @@ sub set {
croak "not a section" unless $node->is_section;
my $arg = shift;
if (my $n = $node->subtree($arg)) {
$node = $n;
} else {
$node = $node->subtree(
- $arg => new Config::Tree::Node::Section
+ $arg => new Config::AST::Node::Section
);
}
}
my $v = $node->subtree($_[0]) ||
- $node->subtree($_[0] => new Config::Tree::Node::Value(
+ $node->subtree($_[0] => new Config::AST::Node::Value(
order => $self->{_order}++
));
$v->value($_[1]);
$v->default(0);
return $v;
@@ -764,13 +866,13 @@ sub names_of {
=head2 @array = $cfg->flatten(sort => $sort)
Returns a I<flattened> representation of the configuration, as a
list of pairs B<[ $path, $value ]>, where B<$path> is a reference
to the variable pathname, and B<$value> is a
-B<Config::Tree::Node::Value> object.
+B<Config::AST::Node::Value> object.
The I<$sort> argument controls the ordering of the entries in the returned
B<@array>. It is either a code reference suitable to pass to the Perl B<sort>
function, or one of the following constants:
=over 4
@@ -792,13 +894,13 @@ Sort by pathname.
=back
These constants are not exported by default. You can either import the
ones you need, or use the B<:sort> keyword to import them all, e.g.:
- use Config::Tree qw(:sort);
+ use Config::AST qw(:sort);
@array = $cfg->flatten(sort => SORT_PATH);
=cut
sub flatten {
my $self = shift;
@@ -843,13 +945,13 @@ sub as_hash {
}
=head2 $cfg->canonical(%args)
Returns the canonical string representation of the configuration tree.
For details, please refer to the documentation of the eponymous method
-in class B<Config::Tree::Node>.
+in class B<Config::AST::Node>.
=cut
sub canonical {
my $self = shift;
$self->tree->canonical(@_);
diff --git a/lib/Config/Tree/Node.pm b/lib/Config/AST/Node.pm
index 24fca30..ba0d279 100644
--- a/lib/Config/Tree/Node.pm
+++ b/lib/Config/AST/Node.pm
@@ -1,7 +1,7 @@
-package Config::Tree::Node;
+package Config::AST::Node;
use strict;
use warnings;
use parent 'Exporter';
use Text::Locus;
use Clone 'clone';
@@ -10,17 +10,17 @@ use Carp;
our %EXPORT_TAGS = ( 'sort' => [ qw(NO_SORT SORT_NATURAL SORT_PATH) ] );
our @EXPORT_OK = qw(NO_SORT SORT_NATURAL SORT_PATH);
=head1 NAME
-Config::Tree::Node - generic configuration node
+Config::AST::Node - generic configuration node
=head1 SYNOPSIS
-use parent 'Config::Tree::Node';
+use parent 'Config::AST::Node';
=head1 DESCRIPTION
This is an abstract class representing a node in the configuration parse
tree. A node can be either a non-leaf node, representing a I<section>, or
a leaf node, representing configuration I<statement>.
@@ -32,13 +32,13 @@ a leaf node, representing configuration I<statement>.
Creates new object. Recognized arguments are:
=over 4
=item B<clone =E<gt>> I<OBJ>
-Clone object I<OBJ>, which must be an instance of B<Config::Tree::Node>
+Clone object I<OBJ>, which must be an instance of B<Config::AST::Node>
or its derived class.
=item B<default =E<gt>> I<VAL>
Sets default value.
@@ -182,13 +182,13 @@ use constant {
=head2 @array = $cfg->flatten(sort => $sort)
Returns a I<flattened> representation of the configuration, as a
list of pairs B<[ $path, $value ]>, where B<$path> is a reference
to the variable pathname, and B<$value> is a
-B<Config::Tree::Node::Value> object.
+B<Config::AST::Node::Value> object.
The I<$sort> argument controls the ordering of the entries in the returned
B<@array>. It is either a code reference suitable to pass to the Perl B<sort>
function, or one of the following constants:
=over 4
@@ -210,13 +210,13 @@ Sort by pathname.
=back
These constants are not exported by default. You can either import the
ones you need, or use the B<:sort> keyword to import them all, e.g.:
- use Config::Tree::Node qw(:sort);
+ use Config::AST::Node qw(:sort);
@array = $node->flatten(sort => SORT_PATH);
=cut
sub flatten {
my $self = shift;
@@ -279,13 +279,13 @@ sub canonical {
local %_ = @_;
my $delim;
unless (defined($delim = delete $_{delim})) {
$delim = "\n";
}
my $prloc = delete $_{locus};
- carp "unknown parameters: " . join(', ', keys(%_)) if (keys(%_));
+ carp "unrecognized parameters: " . join(', ', keys(%_)) if (keys(%_));
return join $delim, map {
($prloc ? '[' . $_->[1]->locus . ']: ' : '')
. join('.', map {
if (/[\.="]/) {
s/\"/\\"/;
diff --git a/lib/Config/Tree/Node/Null.pm b/lib/Config/AST/Node/Null.pm
index edf3aad..66986d2 100644
--- a/lib/Config/Tree/Node/Null.pm
+++ b/lib/Config/AST/Node/Null.pm
@@ -1,8 +1,8 @@
-package Config::Tree::Node::Null;
-use parent 'Config::Tree::Node';
+package Config::AST::Node::Null;
+use parent 'Config::AST::Node';
use strict;
use warnings;
use Carp;
sub is_null { 1 }
diff --git a/lib/Config/Tree/Node/Section.pm b/lib/Config/AST/Node/Section.pm
index 340bdee..47668fc 100644
--- a/lib/Config/Tree/Node/Section.pm
+++ b/lib/Config/AST/Node/Section.pm
@@ -1,12 +1,12 @@
-package Config::Tree::Node::Section;
-use parent 'Config::Tree::Node';
+package Config::AST::Node::Section;
+use parent 'Config::AST::Node';
use strict;
use warnings;
use Carp;
-use Config::Tree::Node::Null;
+use Config::AST::Node::Null;
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
$self->{_subtree} = {};
return $self;
@@ -120,12 +120,12 @@ sub AUTOLOAD {
my $self = shift;
my $key = $AUTOLOAD;
$key =~ s/.*:://;
if ($key =~ s/^([A-Z])(.*)/\l$1$2/) {
$key =~ s/__/-/g;
return $self->subtree($self->{_ci} ? lc($key) : $key)
- // new Config::Tree::Node::Null;
+ // new Config::AST::Node::Null;
}
confess "Can't locate method $AUTOLOAD";
}
1;
diff --git a/lib/Config/Tree/Node/Value.pm b/lib/Config/AST/Node/Value.pm
index d9961c0..24dd18d 100644
--- a/lib/Config/Tree/Node/Value.pm
+++ b/lib/Config/AST/Node/Value.pm
@@ -1,8 +1,8 @@
-package Config::Tree::Node::Value;
-use parent 'Config::Tree::Node';
+package Config::AST::Node::Value;
+use parent 'Config::AST::Node';
use strict;
use warnings;
sub new {
my $class = shift;
local %_ = @_;
diff --git a/t/01conf03.t b/t/01conf03.t
index b887995..87444d8 100644
--- a/t/01conf03.t
+++ b/t/01conf03.t
@@ -21,9 +21,9 @@ my %keywords = (
);
my $cfg = new TestConfig(
config => [
'core.tempdir' => '/tmp',
'core.output' => 'file'
],
- parameters => \%keywords,
+ lexicon => \%keywords,
expect => [ 'keyword "output" is unknown' ]);
ok($cfg->errors() == 1);
diff --git a/t/01conf04.t b/t/01conf04.t
index 0ad4b64..dcce2a4 100644
--- a/t/01conf04.t
+++ b/t/01conf04.t
@@ -28,10 +28,10 @@ my %keywords = (
my $cfg = new TestConfig(
config => [
'core.tempdir' => '/tmp',
'backend.file.local' => 1
],
- parameters => \%keywords,
+ lexicon => \%keywords,
expect => [ 'mandatory variable "core.retain-interval" not set',
'mandatory variable "backend.file.name" not set' ]);
ok($cfg->errors()==2);
diff --git a/t/01conf05.t b/t/01conf05.t
index 4cb7942..6b03cf8 100644
--- a/t/01conf05.t
+++ b/t/01conf05.t
@@ -23,8 +23,8 @@ my $cfg = new TestConfig(
'core.list' => 'to',
'core.list' => '5',
'core.pidfile' => 'file1',
'core.pidfile' => 'file2'
],
- parameters => \%keywords);
+ lexicon => \%keywords);
ok($cfg->canonical(),'core.list=["en","to",5] core.pidfile="file2"');
diff --git a/t/01conf06.t b/t/01conf06.t
index 1d04c8e..b3f58ca 100644
--- a/t/01conf06.t
+++ b/t/01conf06.t
@@ -22,13 +22,13 @@ my $cfg = new TestConfig(
config => [
'core.retain-interval' => 10,
'core.tempdir' => '/tmp',
'backend.file.local' => 1,
'backend.file.level' => 3
],
- parameters => \%keywords);
+ lexicon => \%keywords);
ok($cfg->canonical, 'backend.file.level=3 backend.file.local=1 core.retain-interval=10 core.tempdir="/tmp"');
ok($cfg->lint(\%keywords));
my %subkw = (
diff --git a/t/01conf07.t b/t/01conf07.t
index ba28872..8e6b62d 100644
--- a/t/01conf07.t
+++ b/t/01conf07.t
@@ -23,13 +23,13 @@ my $cfg = new TestConfig(
'core.retain-interval' => 10,
'item.foo.backend' => 'tar',
'item.foo.directory' => 'baz',
'item.bar.backend' => 'mysql',
'item.bar.database' => 'quux'
],
- parameters => \%keywords
+ lexicon => \%keywords
);
ok($cfg->canonical, 'core.retain-interval=10 item.bar.backend="mysql" item.bar.database="quux" item.foo.backend="tar" item.foo.directory="baz"');
my %subkw = (
item => {
diff --git a/t/01conf08.t b/t/01conf08.t
index 8068de2..8e36a1d 100644
--- a/t/01conf08.t
+++ b/t/01conf08.t
@@ -25,10 +25,10 @@ my %keywords = (
);
ok(new TestConfig(
config => [
'core.name' => 'foo'
],
- parameters => \%keywords,
+ lexicon => \%keywords,
expect => [ "must start with a capital letter" ]));
diff --git a/t/01conf09.t b/t/01conf09.t
index cbe5536..b188617 100644
--- a/t/01conf09.t
+++ b/t/01conf09.t
@@ -17,11 +17,11 @@ my %keywords = (
section => {
name => 1
}
}
);
-my $cfg = new TestConfig(parameters => \%keywords);
+my $cfg = new TestConfig(lexicon => \%keywords);
ok($cfg);
ok($cfg->canonical, q{core.backend="file"});
diff --git a/t/01conf10.t b/t/01conf10.t
index 91fcb25..a30f784 100644
--- a/t/01conf10.t
+++ b/t/01conf10.t
@@ -19,10 +19,10 @@ my %keywords = (
);
my $t = new TestConfig(
config =>