diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-12-02 17:24:38 +0100 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-12-03 12:42:13 +0100 |
commit | ceb4bd03d48d161548e00f1db170b376583894a8 (patch) | |
tree | 86635a6469d44aff6aa443404363a355f5c0a394 | |
download | config-ast-ceb4bd03d48d161548e00f1db170b376583894a8.tar.gz config-ast-ceb4bd03d48d161548e00f1db170b376583894a8.tar.bz2 |
Initial commit
-rw-r--r-- | .gitignore | 11 | ||||
-rw-r--r-- | lib/Config/Tree.pm | 893 | ||||
-rw-r--r-- | lib/Config/Tree/Locus.pm | 288 | ||||
-rw-r--r-- | lib/Config/Tree/Node.pm | 161 | ||||
-rw-r--r-- | lib/Config/Tree/Node/Section.pm | 41 | ||||
-rw-r--r-- | lib/Config/Tree/Node/Value.pm | 34 | ||||
-rw-r--r-- | t/TestConfig.pm | 103 | ||||
-rw-r--r-- | t/conf01.t | 18 | ||||
-rw-r--r-- | t/conf02.t | 30 | ||||
-rw-r--r-- | t/conf03.t | 29 | ||||
-rw-r--r-- | t/conf04.t | 37 | ||||
-rw-r--r-- | t/conf05.t | 30 | ||||
-rw-r--r-- | t/conf06.t | 56 | ||||
-rw-r--r-- | t/conf07.t | 56 | ||||
-rw-r--r-- | t/conf08.t | 34 | ||||
-rw-r--r-- | t/conf09.t | 27 | ||||
-rw-r--r-- | t/conf10.t | 23 | ||||
-rw-r--r-- | t/conf11.t | 17 | ||||
-rw-r--r-- | t/locus.t | 50 |
19 files changed, 1938 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cd17285 --- /dev/null +++ b/.gitignore | |||
@@ -0,0 +1,11 @@ | |||
1 | .emacs* | ||
2 | *~ | ||
3 | *.bak | ||
4 | /MYMETA.json | ||
5 | /MYMETA.yml | ||
6 | Makefile | ||
7 | /*.tar.gz | ||
8 | /tmp | ||
9 | /blib | ||
10 | /pm_to_blib | ||
11 | /inc | ||
diff --git a/lib/Config/Tree.pm b/lib/Config/Tree.pm new file mode 100644 index 0000000..39e0de9 --- /dev/null +++ b/lib/Config/Tree.pm | |||
@@ -0,0 +1,893 @@ | |||
1 | # Configuration parser for Sourceyard -*- perl -*- | ||
2 | # Copyright (C) 2017 Sergey Poznyakoff <gray@gnu.org> | ||
3 | # | ||
4 | # This program is free software; you can redistribute it and/or modify | ||
5 | # it under the terms of the GNU General Public License as published by | ||
6 | # the Free Software Foundation; either version 3, or (at your option) | ||
7 | # any later version. | ||
8 | # | ||
9 | # This program is distributed in the hope that it will be useful, | ||
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | # GNU General Public License for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License | ||
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | package Config::Tree; | ||
18 | |||
19 | use strict; | ||
20 | use warnings; | ||
21 | use Carp; | ||
22 | use Config::Tree::Locus; | ||
23 | use Config::Tree::Node::Section; | ||
24 | use Config::Tree::Node::Value; | ||
25 | use Data::Dumper; | ||
26 | |||
27 | require Exporter; | ||
28 | our @ISA = qw(Exporter); | ||
29 | our %EXPORT_TAGS = ( 'sort' => [ qw(NO_SORT SORT_NATURAL SORT_PATH) ] ); | ||
30 | our @EXPORT_OK = qw(NO_SORT SORT_NATURAL SORT_PATH); | ||
31 | |||
32 | our $VERSION = "1.00"; | ||
33 | |||
34 | =head1 NAME | ||
35 | |||
36 | Config::Tree - generalized configuration file parser | ||
37 | |||
38 | =head1 SYNOPSIS | ||
39 | |||
40 | my $cfg = new Config::Tree($filename, %opts); | ||
41 | $cfg->parse() or die; | ||
42 | |||
43 | if ($cfg->is_set('core', 'variable')) { | ||
44 | ... | ||
45 | } | ||
46 | |||
47 | my $x = $cfg->get('file', 'locking'); | ||
48 | |||
49 | $cfg->set('file', 'locking', 'true'); | ||
50 | |||
51 | $cfg->unset('file', 'locking'); | ||
52 | |||
53 | =head1 DESCRIPTION | ||
54 | |||
55 | Configuration file handling. Features: | ||
56 | |||
57 | =over 4 | ||
58 | |||
59 | =item 1 | ||
60 | |||
61 | Handles I<git>-format configuration files. | ||
62 | |||
63 | =item 2 | ||
64 | |||
65 | Table-driven syntax checking and validation. | ||
66 | |||
67 | =item 3 | ||
68 | |||
69 | Optional caching facility allows for faster loading. This is especially | ||
70 | useful for big configurations. | ||
71 | |||
72 | =item 4 | ||
73 | |||
74 | Built-in B<lint> facility. | ||
75 | |||
76 | =item 5 | ||
77 | |||
78 | Location tracking. | ||
79 | |||
80 | =item 6 | ||
81 | |||
82 | Dump facility. The parsed configuration can be output to the given file | ||
83 | handler in a standardized form. | ||
84 | |||
85 | =item 7 | ||
86 | |||
87 | Both random access and iteration over all settings is possible. | ||
88 | |||
89 | =back | ||
90 | |||
91 | =head1 METHODS | ||
92 | |||
93 | =head2 $cfg = new Config::Tree($filename, %opts); | ||
94 | |||
95 | Creates new configuration object for file B<$filename>. Valid | ||
96 | options are: | ||
97 | |||
98 | =over 4 | ||
99 | |||
100 | =item B<debug> => I<NUM> | ||
101 | |||
102 | Sets debug verbosity level. | ||
103 | |||
104 | =item B<ci> => B<0> | B<1> | ||
105 | |||
106 | If B<1>, enables case-insensitive keyword matching. Default is B<0>, | ||
107 | i.e. the keywords are case-sensitive. | ||
108 | |||
109 | =item B<parameters> => \%hash | ||
110 | |||
111 | Defines the syntax table. See below for a description of B<%hash>. | ||
112 | |||
113 | =back | ||
114 | |||
115 | =head3 Syntax hash | ||
116 | |||
117 | The hash passed via the B<parameters> keyword defines the keywords and | ||
118 | sections allowed within a configuration file. In a simplest case, a | ||
119 | keyword is described as | ||
120 | |||
121 | name => 1 | ||
122 | |||
123 | This means that B<name> is a valid keyword, but does not imply anything | ||
124 | more about it or its value. A more complex declaration is possible, in | ||
125 | which the value is a hash reference, containing one or more of the following | ||
126 | keywords: | ||
127 | |||
128 | =over 4 | ||
129 | |||
130 | =item mandatory => 0 | 1 | ||
131 | |||
132 | Whether or not this setting is mandatory. | ||
133 | |||
134 | =item default => I<VALUE> | ||
135 | |||
136 | Default value for the setting. It is assigned when entire configuration file | ||
137 | has been parsed, if that particular setting did not occur in it. If I<VALUE> | ||
138 | is a code, it will be invoked as a method each time the value is accessed. | ||
139 | |||
140 | Default values must be pure Perl values (not the values that should appear | ||
141 | in the configuration file). They are not processed using the B<check> | ||
142 | callbacks. | ||
143 | |||
144 | =item array => 0 | 1 | ||
145 | |||
146 | If B<1>, the value of the setting is an array. Each subsequent occurrence | ||
147 | of the statement appends its value to the end of the array. | ||
148 | |||
149 | =item re => I<regexp> | ||
150 | |||
151 | Defines a regular expression to which must be matched by the value of the | ||
152 | setting, otherwise a syntax error will be reported. | ||
153 | |||
154 | =item select => I<coderef> | ||
155 | |||
156 | Points to a function to be called to decide whether to apply this hash to | ||
157 | a particular configuration setting. The function is called as | ||
158 | |||
159 | $self->$coderef($node, @path) | ||
160 | |||
161 | where $node is the B<Config::Tree::Node::Value> object (use | ||
162 | B<$vref-E<gt>value>, to obtain the actual value), and B<@path> is its patname. | ||
163 | |||
164 | =item check => I<coderef> | ||
165 | |||
166 | Defines a code which will be called after parsing the statement in order to | ||
167 | verify its value. The I<coderef> is called as | ||
168 | |||
169 | $self->$coderef($valref, $prev_value, $locus) | ||
170 | |||
171 | where B<$valref> is a reference to its value, and B<$prev_value> is the | ||
172 | value of the previous instance of this setting. The function must return non-0 | ||
173 | if the value is OK for that setting. In that case, it is allowed to modify | ||
174 | the value, referenced by B<$valref>. If the value is erroneous, the function | ||
175 | must issue an appropriate error message using B<$cfg-E<gt>error>, and return 0. | ||
176 | |||
177 | =back | ||
178 | |||
179 | To define a section, use the B<section> keyword, e.g.: | ||
180 | |||
181 | core => { | ||
182 | section => { | ||
183 | pidfile => { | ||
184 | mandatory => 1 | ||
185 | }, | ||
186 | verbose => { | ||
187 | re => qr/^(?:on|off)/i | ||
188 | } | ||
189 | } | ||
190 | } | ||
191 | |||
192 | This says that a section B<[core]> can have two variables: B<pidfile>, which | ||
193 | is mandatory, and B<verbose>, whose value must be B<on>, or B<off> (case- | ||
194 | insensitive). | ||
195 | |||
196 | To allow for arbitrary keywords, use B<*>. For example, the following | ||
197 | declares the B<[code]> section, which must have the B<pidfile> setting | ||