diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2019-08-23 14:43:52 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2019-08-23 14:45:35 +0300 |
commit | d69ba51bb8498146d07a08031de3685e6cda0768 (patch) | |
tree | e67c2e6903544dc007422fa616481c8984446da0 | |
parent | 21cbaaf979d12447c56382d353d7f03853f49907 (diff) | |
download | config-parser-d69ba51bb8498146d07a08031de3685e6cda0768.tar.gz config-parser-d69ba51bb8498146d07a08031de3685e6cda0768.tar.bz2 |
Implement BOOLEAN data type.v1.03
-rw-r--r-- | Changes | 3 | ||||
-rw-r--r-- | lib/Config/Parser.pm | 58 | ||||
-rw-r--r-- | t/ConfigSpec.pm | 1 | ||||
-rw-r--r-- | t/conf00.t | 3 | ||||
-rw-r--r-- | t/conf09.t | 8 |
5 files changed, 63 insertions, 10 deletions
@@ -1,5 +1,8 @@ Revision history for Perl extension Config::Parser +1.03 Fri Aug 23 14:44:18 2019 + - implement the BOOLEAN data type + 1.02 Thu Aug 22 09:47:42 2019 - use mro to track descendant classes diff --git a/lib/Config/Parser.pm b/lib/Config/Parser.pm index 0c771ed..bd230b5 100644 --- a/lib/Config/Parser.pm +++ b/lib/Config/Parser.pm @@ -7,7 +7,7 @@ use Cwd qw(abs_path); use Text::ParseWords; use mro; -our $VERSION = "1.02"; +our $VERSION = "1.03"; sub new { my $class = shift; @@ -112,6 +112,8 @@ sub loadsynt { $ret->{re} = '^[0-7]+$'; } elsif ($val eq 'HEX') { $ret->{re} = '^([0-9][A-Fa-f])+$'; + } elsif ($val =~ /^BOOL(EAN)?$/) { + $ret->{check} = \&check_bool; } else { unshift @words, $val; } @@ -142,6 +144,29 @@ sub loadsynt { return $lex; } +sub check_bool { + my ($self, $valref, undef, $locus) = @_; + my %bv = ( + yes => 1, + no => 0, + true => 1, + false => 0, + on => 1, + off => 0, + t => 1, + nil => 0, + 1 => 1, + 0 => 0 + ); + + if (exists($bv{$$valref})) { + $$valref = $bv{$$valref}; + return 1; + } + $self->error("$$valref is not a valid boolean value", locus => $locus); + return 0; +} + 1; =head1 NAME @@ -202,7 +227,7 @@ This call first parses the B<__DATA__> section and builds validation rules, then it parses the actual configuration from B<$filename>. Finally, it applies the validation rules to the created syntax tree. If all rules pass, the configuration is correct and the constructor returns a valid object. -Otherwise, it issues proper diagnostics and returns B<undef>. +Otherwise, it issues proper diagnostics and croaks. Upon successful return, the B<$cf> object is used to obtain the actual configuration values as needed. @@ -229,9 +254,12 @@ Creates a new parser object. Keyword arguments are: =item B<filename> -Name of the file to parse. If not supplied, you will have to -call the B<$cfg-E<gt>parse> method explicitly after you are returned a -valid B<$cfg>. +Name of the file to parse. If supplied, the constructor will call +the B<parse> and B<commit> methods automatically and will croak if +the latter returns false. The B<parse> method is given B<filename>, +B<line> and B<fh> keyword-value pairs (if present) as its arguments. + +If not supplied, the caller is supposed to call both methods later. =item B<line> @@ -239,11 +267,15 @@ Optional line where the configuration starts in B<filename>. It is used to keep track of statement location in the file for correct diagnostics. If not supplied, B<1> is assumed. +Valid only together with B<filename>. + =item B<fh> File handle to read from. If it is not supplied, new handle will be created by using B<open> on the supplied filename. +Valid only together with B<filename>. + =item B<lexicon> Dictionary of allowed configuration statements in the file. You will not @@ -329,6 +361,12 @@ Octal number. Hex number. +=item B<BOOL> or B<BOOLEAN> + +Boolean value. Allowed values are: +B<yes>, B<true>, B<on>, B<t>, B<1>, for C<true> and +B<no>, B<false>, B<off>, B<nil>, B<0>, for C<false>. + =back If the data type is omitted, no checking is performed unless specified @@ -404,6 +442,16 @@ To specify options for a section, use the reserved keyword B<__options__>. Its value is the list of options as described above. After processing, the keyword itself is removed from the lexicon. +=head1 OTHER METHODS + +=head2 $cfg->check($valref, $prev, $locus) + +This method implements syntax checking and translation for C<BOOLEAN> data +types. If B<$$valref> is one of the valid boolean values (as described +above), it translates it to B<1> or B<0>, stores that value in B<$valref>, +and returns 1. Otherwise, it emits error message using B<$cfg->error> and +returns 0. + =head1 SEE ALSO B<Config::AST>(3). diff --git a/t/ConfigSpec.pm b/t/ConfigSpec.pm index 30812ed..b94c1df 100644 --- a/t/ConfigSpec.pm +++ b/t/ConfigSpec.pm @@ -16,6 +16,7 @@ __DATA__ base = STRING :mandatory null number = NUMBER :array size = STRING :re='\d+(?:(?i) *[kmg])' + enable = BOOL [load] file = STRING :check=_check_abs_name :mandatory ANY = STRING @@ -8,7 +8,7 @@ plan(tests => 1); my $c = new ConfigSpec; ok($c->canonical, - q{core.base=4 core.number=[5,10] core.size="10 k" load.file="/etc/passwd" load.foobar="baz"}); + q{core.base=4 core.enable=1 core.number=[5,10] core.size="10 k" load.file="/etc/passwd" load.foobar="baz"}); __DATA__ [core] @@ -16,6 +16,7 @@ __DATA__ base = 4 size = 10 k number = 10 + enable = true [load] file = /etc/passwd foobar = baz @@ -2,16 +2,16 @@ use lib qw(t lib); use strict; use Test; -use ConfigSpec; +use ConfigSpec2; use ConfigSpec3; plan(tests => 2); -my $c = new ConfigSpec; +my $c2 = new ConfigSpec2; my $c3 = new ConfigSpec3; -ok($c->canonical_lexicon, - q{{"core" => {"section" => {"base" => {"default" => "null","mandatory" => 1},"number" => {"array" => 1,"re" => "^\\\\d+\\$"},"size" => {"re" => "\\\\d+(?:(?i) *[kmg])"}}},"load" => {"section" => {"*" => {},"file" => {"check" => "_check_abs_name","mandatory" => 1}}}}}); +ok($c2->canonical_lexicon, + q{{"core" => {"section" => {"base" => {"default" => "null","mandatory" => 1}}},"load" => {"section" => {"*" => {"section" => {"param" => {"mandatory" => 1,"section" => {"mode" => {"re" => "^[0-7]+\$"},"owner" => {}}}}}}}}}); ok($c3->canonical_lexicon, q{{"core" => {"section" => {"root" => {"mandatory" => 1}}},"dir" => {"section" => {"diag" => {},"store" => {},"temp" => {}}}}}); |