File Coverage

blib/lib/AppConfig/State.pm
Criterion Covered Total %
statement 202 250 80.8
branch 115 154 74.6
condition 8 13 61.5
subroutine 18 20 90.0
pod 0 5 0.0
total 343 442 77.6


line stmt bran cond sub pod time code
1             #============================================================================
2             #
3             # AppConfig::State.pm
4             #
5             # Perl5 module in which configuration information for an application can
6             # be stored and manipulated. AppConfig::State objects maintain knowledge
7             # about variables; their identities, options, aliases, targets, callbacks
8             # and so on. This module is used by a number of other AppConfig::* modules.
9             #
10             # Written by Andy Wardley
11             #
12             # Copyright (C) 1997-2007 Andy Wardley. All Rights Reserved.
13             # Copyright (C) 1997,1998 Canon Research Centre Europe Ltd.
14             #
15             #----------------------------------------------------------------------------
16             #
17             # TODO
18             #
19             # * Change varlist() to varhash() and provide another varlist() method
20             # which returns a list. Multiple parameters passed implies a hash
21             # slice/list grep, a single parameter should indicate a regex.
22             #
23             # * Perhaps allow a callback to be installed which is called *instead* of
24             # the get() and set() methods (or rather, is called by them).
25             #
26             # * Maybe CMDARG should be in there to specify extra command-line only
27             # options that get added to the AppConfig::GetOpt alias construction,
28             # but not applied in config files, general usage, etc. The GLOBAL
29             # CMDARG might be specified as a format, e.g. "-%c" where %s = name,
30             # %c = first character, %u - first unique sequence(?). Will
31             # GetOpt::Long handle --long to -l application automagically?
32             #
33             # * ..and an added thought is that CASE sensitivity may be required for the
34             # command line (-v vs -V, -r vs -R, for example), but not for parsing
35             # config files where you may wish to treat "Name", "NAME" and "name" alike.
36             #
37             #============================================================================
38              
39             package AppConfig::State;
40 13     13   209 use 5.006;
  13         32  
  13         514  
41 13     13   58 use strict;
  13         16  
  13         394  
42 13     13   58 use warnings;
  13         13  
  13         747  
43              
44             our $VERSION = '1.71';
45             our $DEBUG = 0;
46             our $AUTOLOAD;
47              
48             # need access to AppConfig::ARGCOUNT_*
49 13     13   62 use AppConfig ':argcount';
  13         16  
  13         44231  
50              
51             # internal per-variable hashes that AUTOLOAD should provide access to
52             my %METHVARS;
53             @METHVARS{ qw( EXPAND ARGS ARGCOUNT ) } = ();
54              
55             # internal values that AUTOLOAD should provide access to
56             my %METHFLAGS;
57             @METHFLAGS{ qw( PEDANTIC ) } = ();
58              
59             # variable attributes that may be specified in GLOBAL;
60             my @GLOBAL_OK = qw( DEFAULT EXPAND VALIDATE ACTION ARGS ARGCOUNT );
61              
62              
63             #------------------------------------------------------------------------
64             # new(\%config, @vars)
65             #
66             # Module constructor. A reference to a hash array containing
67             # configuration options may be passed as the first parameter. This is
68             # passed off to _configure() for processing. See _configure() for
69             # information about configurarion options. The remaining parameters
70             # may be variable definitions and are passed en masse to define() for
71             # processing.
72             #
73             # Returns a reference to a newly created AppConfig::State object.
74             #------------------------------------------------------------------------
75              
76             sub new {
77 14     14 0 2011 my $class = shift;
78              
79 14         166 my $self = {
80             # internal hash arrays to store variable specification information
81             VARIABLE => { }, # variable values
82             DEFAULT => { }, # default values
83             ALIAS => { }, # known aliases ALIAS => VARIABLE
84             ALIASES => { }, # reverse alias lookup VARIABLE => ALIASES
85             ARGCOUNT => { }, # arguments expected
86             ARGS => { }, # specific argument pattern (AppConfig::Getopt)
87             EXPAND => { }, # variable expansion (AppConfig::File)
88             VALIDATE => { }, # validation regexen or functions
89             ACTION => { }, # callback functions for when variable is set
90             GLOBAL => { }, # default global settings for new variables
91              
92             # other internal data
93             CREATE => 0, # auto-create variables when set
94             CASE => 0, # case sensitivity flag (1 = sensitive)
95             PEDANTIC => 0, # return immediately on parse warnings
96             EHANDLER => undef, # error handler (let's hope we don't need it!)
97             ERROR => '', # error message
98             };
99              
100 14         39 bless $self, $class;
101              
102             # configure if first param is a config hash ref
103 14 100       101 $self->_configure(shift)
104             if ref($_[0]) eq 'HASH';
105              
106             # call define(@_) to handle any variables definitions
107 14 100       97 $self->define(@_)
108             if @_;
109              
110 14         45 return $self;
111             }
112              
113              
114             #------------------------------------------------------------------------
115             # define($variable, \%cfg, [$variable, \%cfg, ...])
116             #
117             # Defines one or more variables. The first parameter specifies the
118             # variable name. The following parameter may reference a hash of
119             # configuration options for the variable. Further variables and
120             # configuration hashes may follow and are processed in turn. If the
121             # parameter immediately following a variable name isn't a hash reference
122             # then it is ignored and the variable is defined without a specific
123             # configuration, although any default parameters as specified in the
124             # GLOBAL option will apply.
125             #
126             # The $variable value may contain an alias/args definition in compact
127             # format, such as "Foo|Bar=1".
128             #
129             # A warning is issued (via _error()) if an invalid option is specified.
130             #------------------------------------------------------------------------
131              
132             sub define {
133 26     26 0 52 my $self = shift;
134 26         34 my ($var, $args, $count, $opt, $val, $cfg, @names);
135              
136 26         73 while (@_) {
137 68         83 $var = shift;
138 68 100       189 $cfg = ref($_[0]) eq 'HASH' ? shift : { };
139              
140             # variable may be specified in compact format, 'foo|bar=i@'
141 68 100       419 if ($var =~ s/(.+?)([!+=:].*)/$1/) {
142              
143             # anything coming after the name|alias list is the ARGS
144 6 50       22 $cfg->{ ARGS } = $2
145             if length $2;
146             }
147              
148             # examine any ARGS option
149 68 100       151 if (defined ($args = $cfg->{ ARGS })) {
150 8 100       23 ARGGCOUNT: {
151 8         8 $count = ARGCOUNT_NONE, last if $args =~ /^!/;
152 7 100       22 $count = ARGCOUNT_LIST, last if $args =~ /@/;
153 5 100       14 $count = ARGCOUNT_HASH, last if $args =~ /%/;
154 4         8 $count = ARGCOUNT_ONE;
155             }
156 8         11 $cfg->{ ARGCOUNT } = $count;
157             }
158              
159             # split aliases out
160 68         183 @names = split(/\|/, $var);
161 68         93 $var = shift @names;
162 68 100       140 $cfg->{ ALIAS } = [ @names ] if @names;
163              
164             # variable name gets folded to lower unless CASE sensitive
165 68 100       189 $var = lc $var unless $self->{ CASE };
166              
167             # activate $variable (so it does 'exist()')
168 68         120 $self->{ VARIABLE }->{ $var } = undef;
169              
170             # merge GLOBAL and variable-specific configurations
171 68         73 $cfg = { %{ $self->{ GLOBAL } }, %$cfg };
  68         256  
172              
173             # examine each variable configuration parameter
174 68         237 while (($opt, $val) = each %$cfg) {
175 162         219 $opt = uc $opt;
176              
177             # DEFAULT, VALIDATE, EXPAND, ARGS and ARGCOUNT are stored as
178             # they are;
179 162 100       482 $opt =~ /^DEFAULT|VALIDATE|EXPAND|ARGS|ARGCOUNT$/ && do {
180 138         209 $self->{ $opt }->{ $var } = $val;
181 138         287 next;
182             };
183              
184             # CMDARG has been deprecated
185 24 50       57 $opt eq 'CMDARG' && do {
186 0         0 $self->_error("CMDARG has been deprecated. "
187             . "Please use an ALIAS if required.");
188 0         0 next;
189             };
190              
191             # ACTION should be a code ref
192 24 100       55 $opt eq 'ACTION' && do {
193 2 50       16 unless (ref($val) eq 'CODE') {
194 0         0 $self->_error("'$opt' value is not a code reference");
195 0         0 next;
196             };
197              
198             # store code ref, forcing keyword to upper case
199 2         32 $self->{ ACTION }->{ $var } = $val;
200              
201 2         8 next;
202             };
203              
204             # ALIAS creates alias links to the variable name
205 22 50       49 $opt eq 'ALIAS' && do {
206              
207             # coerce $val to an array if not already so
208 22 100       97 $val = [ split(/\|/, $val) ]
209             unless ref($val) eq 'ARRAY';
210              
211             # fold to lower case unless CASE sensitivity set
212 22 50       52 unless ($self->{ CASE }) {
213 22         35 @$val = map { lc } @$val;
  37         89  
214             }
215              
216             # store list of aliases...
217 22         38 $self->{ ALIASES }->{ $var } = $val;
218              
219             # ...and create ALIAS => VARIABLE lookup hash entries
220 22         38 foreach my $a (@$val) {
221 37         72 $self->{ ALIAS }->{ $a } = $var;
222             }
223              
224 22         57 next;
225             };
226              
227             # default
228 0         0 $self->_error("$opt is not a valid configuration item");
229             }
230              
231             # set variable to default value
232 68         154 $self->_default($var);
233              
234             # DEBUG: dump new variable definition
235 68 50       222 if ($DEBUG) {
236 0         0 print STDERR "Variable defined:\n";
237 0         0 $self->_dump_var($var);
238             }
239             }
240             }
241              
242              
243             #------------------------------------------------------------------------
244             # get($variable)
245             #
246             # Returns the value of the variable specified, $variable. Returns undef
247             # if the variable does not exists or is undefined and send a warning
248             # message to the _error() function.
249             #------------------------------------------------------------------------
250              
251             sub get {
252 116     116 0 155 my $self = shift;
253 116         129 my $variable = shift;
254 116         107 my $negate = 0;
255 116         96 my $value;
256              
257             # _varname returns variable name after aliasing and case conversion
258             # $negate indicates if the name got converted from "no" to ""
259 116         208 $variable = $self->_varname($variable, \$negate);
260              
261             # check the variable has been defined
262 116 100       243 unless (exists($self->{ VARIABLE }->{ $variable })) {
263 1         3 $self->_error("$variable: no such variable");
264 1         5 return undef;
265             }
266              
267             # DEBUG
268             print STDERR "$self->get($variable) => ",
269             defined $self->{ VARIABLE }->{ $variable }
270 115 0       184 ? $self->{ VARIABLE }->{ $variable }
    50          
271             : "",
272             "\n"
273             if $DEBUG;
274              
275             # return variable value, possibly negated if the name was "no"
276 115         152 $value = $self->{ VARIABLE }->{ $variable };
277              
278 115 100       482 return $negate ? !$value : $value;
279             }
280              
281              
282             #------------------------------------------------------------------------
283             # set($variable, $value)
284             #
285             # Assigns the value, $value, to the variable specified.
286             #
287             # Returns 1 if the variable is successfully updated or 0 if the variable
288             # does not exist. If an ACTION sub-routine exists for the variable, it
289             # will be executed and its return value passed back.
290             #------------------------------------------------------------------------
291              
292             sub set {
293 123     123 0 125 my $self = shift;
294 123         112 my $variable = shift;
295 123         114 my $value = shift;
296 123         154 my $negate = 0;
297 123         132 my $create;
298              
299             # _varname returns variable name after aliasing and case conversion
300             # $negate indicates if the name got converted from "no" to ""
301 123         211 $variable = $self->_varname($variable, \$negate);
302              
303             # check the variable exists
304 123 100       231 if (exists($self->{ VARIABLE }->{ $variable })) {
305             # variable found, so apply any value negation
306 112 100       186 $value = $value ? 0 : 1 if $negate;
    100          
307             }
308             else {
309             # auto-create variable if CREATE is 1 or a pattern matching
310             # the variable name (real name, not an alias)
311 11         19 $create = $self->{ CREATE };
312 11 100 66     142 if (defined $create
      33        
313             && ($create eq '1' || $variable =~ /$create/)) {
314 10         17 $self->define($variable);
315              
316 10 50       16 print STDERR "Auto-created $variable\n" if $DEBUG;
317             }
318             else {
319 1         7 $self->_error("$variable: no such variable");
320 1         8 return 0;
321             }
322             }
323              
324             # call the validate($variable, $value) method to perform any validation
325 122 100       226 unless ($self->_validate($variable, $value)) {
326 2         9 $self->_error("$variable: invalid value: $value");
327 2         16 return 0;
328             }
329              
330             # DEBUG
331 120 0       196 print STDERR "$self->set($variable, ",
    50          
332             defined $value
333             ? $value
334             : "",
335             ")\n"
336             if $DEBUG;
337              
338              
339             # set the variable value depending on its ARGCOUNT
340 120         152 my $argcount = $self->{ ARGCOUNT }->{ $variable };
341 120 100       186 $argcount = AppConfig::ARGCOUNT_ONE unless defined $argcount;
342              
343 120 100       278 if ($argcount eq AppConfig::ARGCOUNT_LIST) {
    100          
344             # push value onto the end of the list
345 11         15 push(@{ $self->{ VARIABLE }->{ $variable } }, $value);
  11         18  
346             }
347             elsif ($argcount eq AppConfig::ARGCOUNT_HASH) {
348             # insert "=" data into hash
349 13         49 my ($k, $v) = split(/\s*=\s*/, $value, 2);
350             # strip quoting
351 13 100       31 $v =~ s/^(['"])(.*)\1$/$2/ if defined $v;
352 13         46 $self->{ VARIABLE }->{ $variable }->{ $k } = $v;
353             }
354             else {
355             # set simple variable
356 96         146 $self->{ VARIABLE }->{ $variable } = $value;
357             }
358              
359              
360             # call any ACTION function bound to this variable
361 18         43 return &{ $self->{ ACTION }->{ $variable } }($self, $variable, $value)
362 120 100       235 if (exists($self->{ ACTION }->{ $variable }));
363              
364             # ...or just return 1 (ok)
365 102         837 return 1;
366             }
367              
368              
369             #------------------------------------------------------------------------
370             # varlist($criteria, $filter)
371             #
372             # Returns a hash array of all variables and values whose real names
373             # match the $criteria regex pattern passed as the first parameter.
374             # If $filter is set to any true value, the keys of the hash array
375             # (variable names) will have the $criteria part removed. This allows
376             # the caller to specify the variables from one particular [block] and
377             # have the "block_" prefix removed, for example.
378             #
379             # TODO: This should be changed to varhash(). varlist() should return a
380             # list. Also need to consider specification by list rather than regex.
381             #
382             #------------------------------------------------------------------------
383              
384             sub varlist {
385 2     2 0 825 my $self = shift;
386 2         4 my $criteria = shift;
387 2         3 my $strip = shift;
388              
389 2 50       6 $criteria = "" unless defined $criteria;
390              
391             # extract relevant keys and slice out corresponding values
392 2         3 my @keys = grep(/$criteria/, keys %{ $self->{ VARIABLE } });
  2         61  
393 2         6 my @vals = @{ $self->{ VARIABLE } }{ @keys };
  2         8  
394 2         2 my %set;
395              
396             # clean off the $criteria part if $strip is set
397 2 100       5 @keys = map { s/$criteria//; $_ } @keys if $strip;
  6         16  
  6         10  
398              
399             # slice values into the target hash
400 2         9 @set{ @keys } = @vals;
401 2         14 return %set;
402             }
403              
404              
405             #------------------------------------------------------------------------
406             # AUTOLOAD
407             #
408             # Autoload function called whenever an unresolved object method is
409             # called. If the method name relates to a defined VARIABLE, we patch
410             # in $self->get() and $self->set() to magically update the varaiable
411             # (if a parameter is supplied) and return the previous value.
412             #
413             # Thus the function can be used in the folowing ways:
414             # $state->variable(123); # set a new value
415             # $foo = $state->variable(); # get the current value
416             #
417             # Returns the current value of the variable, taken before any new value
418             # is set. Prints a warning if the variable isn't defined (i.e. doesn't
419             # exist rather than exists with an undef value) and returns undef.
420             #------------------------------------------------------------------------
421              
422             sub AUTOLOAD {
423 258     258   4268 my $self = shift;
424 258         622 my ($variable, $attrib);
425              
426              
427             # splat the leading package name
428 258         1523 ($variable = $AUTOLOAD) =~ s/.*:://;
429              
430             # ignore destructor
431 258 50       526 $variable eq 'DESTROY' && return;
432              
433              
434             # per-variable attributes and internal flags listed as keys in
435             # %METHFLAGS and %METHVARS respectively can be accessed by a
436             # method matching the attribute or flag name in lower case with
437             # a leading underscore_
438 258 100       633 if (($attrib = $variable) =~ s/_//g) {
439 141         148 $attrib = uc $attrib;
440              
441 141 100       747 if (exists $METHFLAGS{ $attrib }) {
442 9         49 return $self->{ $attrib };
443             }
444              
445 132 100       232 if (exists $METHVARS{ $attrib }) {
446             # next parameter should be variable name
447 115         144 $variable = shift;
448 115         160 $variable = $self->_varname($variable);
449              
450             # check we've got a valid variable
451             # $self->_error("$variable: no such variable or method"),
452             # return undef
453             # unless exists($self->{ VARIABLE }->{ $variable });
454              
455             # return attribute
456 115         814 return $self->{ $attrib }->{ $variable };
457             }
458             }
459              
460             # set a new value if a parameter was supplied or return the old one
461 134 100       368 return defined($_[0])
462             ? $self->set($variable, shift)
463             : $self->get($variable);
464             }
465              
466              
467              
468             #========================================================================
469             # ----- PRIVATE METHODS -----
470             #========================================================================
471              
472             #------------------------------------------------------------------------
473             # _configure(\%cfg)
474             #
475             # Sets the various configuration options using the values passed in the
476             # hash array referenced by $cfg.
477             #------------------------------------------------------------------------
478              
479             sub _configure {
480 11     11   22 my $self = shift;
481 11   50     45 my $cfg = shift || return;
482              
483             # construct a regex to match values which are ok to be found in GLOBAL
484 11         55 my $global_ok = join('|', @GLOBAL_OK);
485              
486 11         42 foreach my $opt (keys %$cfg) {
487              
488             # GLOBAL must be a hash ref
489 18 100       126 $opt =~ /^GLOBALS?$/i && do {
490 10 50       50 unless (ref($cfg->{ $opt }) eq 'HASH') {
491 0         0 $self->_error("\U$opt\E parameter is not a hash ref");
492 0         0 next;
493             }
494              
495             # we check each option is ok to be in GLOBAL, but we don't do
496             # any error checking on the values they contain (but should?).
497 10         23 foreach my $global ( keys %{ $cfg->{ $opt } } ) {
  10         50  
498              
499             # continue if the attribute is ok to be GLOBAL
500 18 50       745 next if ($global =~ /(^$global_ok$)/io);
501              
502 0         0 $self->_error( "\U$global\E parameter cannot be GLOBAL");
503             }
504 10         72 $self->{ GLOBAL } = $cfg->{ $opt };
505 10         36 next;
506             };
507              
508             # CASE, CREATE and PEDANTIC are stored as they are
509 8 100       60 $opt =~ /^CASE|CREATE|PEDANTIC$/i && do {
510 4         12 $self->{ uc $opt } = $cfg->{ $opt };
511 4         5 next;
512             };
513              
514             # ERROR triggers $self->_ehandler()
515 4 50       17 $opt =~ /^ERROR$/i && do {
516 4         23 $self->_ehandler($cfg->{ $opt });
517 4         11 next;
518             };
519              
520             # DEBUG triggers $self->_debug()
521 0 0       0 $opt =~ /^DEBUG$/i && do {
522 0         0 $self->_debug($cfg->{ $opt });
523 0         0 next;
524             };
525              
526             # warn about invalid options
527 0         0 $self->_error("\U$opt\E is not a valid configuration option");
528             }
529             }
530              
531              
532             #------------------------------------------------------------------------
533             # _varname($variable, \$negated)
534             #
535             # Variable names are treated case-sensitively or insensitively, depending
536             # on the value of $self->{ CASE }. When case-insensitive ($self->{ CASE }
537             # != 0), all variable names are converted to lower case. Variable values
538             # are not converted. This function simply converts the parameter
539             # (variable) to lower case if $self->{ CASE } isn't set. _varname() also
540             # expands a variable alias to the name of the target variable.
541             #
542             # Variables with an ARGCOUNT of ARGCOUNT_ZERO may be specified as
543             # "no" in which case, the intended value should be negated. The
544             # leading "no" part is stripped from the variable name. A reference to
545             # a scalar value can be passed as the second parameter and if the
546             # _varname() method identified such a variable, it will negate the value.
547             # This allows the intended value or a simple negate flag to be passed by
548             # reference and be updated to indicate any negation activity taking place.
549             #
550             # The (possibly modified) variable name is returned.
551             #------------------------------------------------------------------------
552              
553             sub _varname {
554 644     644   561 my $self = shift;
555 644         541 my $variable = shift;
556 644         483 my $negated = shift;
557              
558             # convert to lower case if case insensitive
559 644 100       1180 $variable = $self->{ CASE } ? $variable : lc $variable;
560              
561             # get the actual name if this is an alias
562             $variable = $self->{ ALIAS }->{ $variable }
563 644 100       1170 if (exists($self->{ ALIAS }->{ $variable }));
564              
565             # if the variable doesn't exist, we can try to chop off a leading
566             # "no" and see if the remainder matches an ARGCOUNT_ZERO variable
567 644 100       1089 unless (exists($self->{ VARIABLE }->{ $variable })) {
568             # see if the variable is specified as "no"
569 41 100       100 if ($variable =~ /^no(.*)/) {
570             # see if the real variable (minus "no") exists and it
571             # has an ARGOUNT of ARGCOUNT_NONE (or no ARGCOUNT at all)
572 20         39 my $novar = $self->_varname($1);
573 20 100 66     108 if (exists($self->{ VARIABLE }->{ $novar })
574             && ! $self->{ ARGCOUNT }->{ $novar }) {
575             # set variable name and negate value
576 19         18 $variable = $novar;
577 19 100       70 $$negated = ! $$negated if defined $negated;
578             }
579             }
580             }
581              
582             # return the variable name
583 644         1030 $variable;
584             }
585              
586              
587             #------------------------------------------------------------------------
588             # _default($variable)
589             #
590             # Sets the variable specified to the default value or undef if it doesn't
591             # have a default. The default value is returned.
592             #------------------------------------------------------------------------
593              
594             sub _default {
595 73     73   94 my $self = shift;
596 73         79 my $variable = shift;
597              
598             # _varname returns variable name after aliasing and case conversion
599 73         126 $variable = $self->_varname($variable);
600              
601             # check the variable exists
602 73 50       149 if (exists($self->{ VARIABLE }->{ $variable })) {
603             # set variable value to the default scalar, an empty list or empty
604             # hash array, depending on its ARGCOUNT value
605 73         97 my $argcount = $self->{ ARGCOUNT }->{ $variable };
606 73 100       117 $argcount = AppConfig::ARGCOUNT_ONE unless defined $argcount;
607              
608 73 100       197 if ($argcount == AppConfig::ARGCOUNT_NONE) {
    100          
    100          
609             return $self->{ VARIABLE }->{ $variable }
610 18   100     124 = $self->{ DEFAULT }->{ $variable } || 0;
611             }
612             elsif ($argcount == AppConfig::ARGCOUNT_LIST) {
613 7         18 my $deflist = $self->{ DEFAULT }->{ $variable };
614 7 100       46 return $self->{ VARIABLE }->{ $variable } =
615             [ ref $deflist eq 'ARRAY' ? @$deflist : ( ) ];
616              
617             }
618             elsif ($argcount == AppConfig::ARGCOUNT_HASH) {
619 6         21 my $defhash = $self->{ DEFAULT }->{ $variable };
620 6 100       29 return $self->{ VARIABLE }->{ $variable } =
621             { ref $defhash eq 'HASH' ? %$defhash : () };
622             }
623             else {
624             return $self->{ VARIABLE }->{ $variable }
625 42         89 = $self->{ DEFAULT }->{ $variable };
626             }
627             }
628             else {
629 0         0 $self->_error("$variable: no such variable");
630 0         0 return 0;
631             }
632             }
633              
634              
635             #------------------------------------------------------------------------
636             # _exists($variable)
637             #
638             # Returns 1 if the variable specified exists or 0 if not.
639             #------------------------------------------------------------------------
640              
641             sub _exists {
642 75     75   71 my $self = shift;
643 75         67 my $variable = shift;
644              
645              
646             # _varname returns variable name after aliasing and case conversion
647 75         103 $variable = $self->_varname($variable);
648              
649             # check the variable has been defined
650 75         251 return exists($self->{ VARIABLE }->{ $variable });
651             }
652              
653              
654             #------------------------------------------------------------------------
655             # _validate($variable, $value)
656             #
657             # Uses any validation rules or code defined for the variable to test if
658             # the specified value is acceptable.
659             #
660             # Returns 1 if the value passed validation checks, 0 if not.
661             #------------------------------------------------------------------------
662              
663             sub _validate {
664 122     122   106 my $self = shift;
665 122         109 my $variable = shift;
666 122         115 my $value = shift;
667 122         95 my $validator;
668              
669              
670             # _varname returns variable name after aliasing and case conversion
671 122         190 $variable = $self->_varname($variable);
672              
673             # return OK unless there is a validation function
674 122 100       407 return 1 unless defined($validator = $self->{ VALIDATE }->{ $variable });
675              
676             #
677             # the validation performed is based on the validator type;
678             #
679             # CODE ref: code executed, returning 1 (ok) or 0 (failed)
680             # SCALAR : a regex which should match the value
681             #
682              
683             # CODE ref
684 15 100       33 ref($validator) eq 'CODE' && do {
685             # run the validation function and return the result
686 2         4 return &$validator($variable, $value);
687             };
688              
689             # non-ref (i.e. scalar)
690 13 50       29 ref($validator) || do {
691             # not a ref - assume it's a regex
692 13         114 return $value =~ /$validator/;
693             };
694              
695             # validation failed
696 0         0 return 0;
697             }
698              
699              
700             #------------------------------------------------------------------------
701             # _error($format, @params)
702             #
703             # Checks for the existence of a user defined error handling routine and
704             # if defined, passes all variable straight through to that. The routine
705             # is expected to handle a string format and optional parameters as per
706             # printf(3C). If no error handler is defined, the message is formatted
707             # and passed to warn() which prints it to STDERR.
708             #------------------------------------------------------------------------
709              
710             sub _error {
711 4     4   5 my $self = shift;
712 4         3 my $format = shift;
713              
714             # user defined error handler?
715 4 50       16 if (ref($self->{ EHANDLER }) eq 'CODE') {
716 4         5 &{ $self->{ EHANDLER } }($format, @_);
  4         11  
717             }
718             else {
719 0         0 warn(sprintf("$format\n", @_));
720             }
721             }
722              
723              
724             #------------------------------------------------------------------------
725             # _ehandler($handler)
726             #
727             # Allows a new error handler to be installed. The current value of
728             # the error handler is returned.
729             #
730             # This is something of a kludge to allow other AppConfig::* modules to
731             # install their own error handlers to format error messages appropriately.
732             # For example, AppConfig::File appends a message of the form
733             # "at $file line $line" to each error message generated while parsing
734             # configuration files. The previous handler is returned (and presumably
735             # stored by the caller) to allow new error handlers to chain control back
736             # to any user-defined handler, and also restore the original handler when
737             # done.
738             #------------------------------------------------------------------------
739              
740             sub _ehandler {
741 26     26   36 my $self = shift;
742 26         30 my $handler = shift;
743              
744             # save previous value
745 26         51 my $previous = $self->{ EHANDLER };
746              
747             # update internal reference if a new handler vas provide
748 26 100       67 if (defined $handler) {
749             # check this is a code reference
750 18 50       82 if (ref($handler) eq 'CODE') {
751 18         32 $self->{ EHANDLER } = $handler;
752              
753             # DEBUG
754 18 50       49 print STDERR "installed new ERROR handler: $handler\n" if $DEBUG;
755             }
756             else {
757 0         0 $self->_error("ERROR handler parameter is not a code ref");
758             }
759             }
760              
761 26         71 return $previous;
762             }
763              
764              
765             #------------------------------------------------------------------------
766             # _debug($debug)
767             #
768             # Sets the package debugging variable, $AppConfig::State::DEBUG depending
769             # on the value of the $debug parameter. 1 turns debugging on, 0 turns
770             # debugging off.
771             #
772             # May be called as an object method, $state->_debug(1), or as a package
773             # function, AppConfig::State::_debug(1). Returns the previous value of
774             # $DEBUG, before any new value was applied.
775             #------------------------------------------------------------------------
776              
777             sub _debug {
778             # object reference may not be present if called as a package function
779 11 50   11   71 my $self = shift if ref($_[0]);
780 11         20 my $newval = shift;
781              
782             # save previous value
783 11         19 my $oldval = $DEBUG;
784              
785             # update $DEBUG if a new value was provided
786 11 50       31 $DEBUG = $newval if defined $newval;
787              
788             # return previous value
789 11         92 $oldval;
790             }
791              
792              
793             #------------------------------------------------------------------------
794             # _dump_var($var)
795             #
796             # Displays the content of the specified variable, $var.
797             #------------------------------------------------------------------------
798              
799             sub _dump_var {
800 0     0     my $self = shift;
801 0           my $var = shift;
802              
803 0 0         return unless defined $var;
804              
805             # $var may be an alias, so we resolve the real variable name
806 0           my $real = $self->_varname($var);
807 0 0         if ($var eq $real) {
808 0           print STDERR "$var\n";
809             }
810             else {
811 0           print STDERR "$real ('$var' is an alias)\n";
812 0           $var = $real;
813             }
814              
815             # for some bizarre reason, the variable VALUE is stored in VARIABLE
816             # (it made sense at some point in time)
817             printf STDERR " VALUE => %s\n",
818             defined($self->{ VARIABLE }->{ $var })
819 0 0         ? $self->{ VARIABLE }->{ $var }
820             : "";
821              
822             # the rest of the values can be read straight out of their hashes
823 0           foreach my $param (qw( DEFAULT ARGCOUNT VALIDATE ACTION EXPAND )) {
824 0 0         printf STDERR " %-12s => %s\n", $param,
825             defined($self->{ $param }->{ $var })
826             ? $self->{ $param }->{ $var }
827             : "";
828             }
829              
830             # summarise all known aliases for this variable
831             print STDERR " ALIASES => ",
832 0           join(", ", @{ $self->{ ALIASES }->{ $var } }), "\n"
833 0 0         if defined $self->{ ALIASES }->{ $var };
834             }
835              
836              
837             #------------------------------------------------------------------------
838             # _dump()
839             #
840             # Dumps the contents of the Config object and all stored variables.
841             #------------------------------------------------------------------------
842              
843             sub _dump {
844 0     0     my $self = shift;
845 0           my $var;
846              
847 0           print STDERR "=" x 71, "\n";
848 0           print STDERR
849             "Status of AppConfig::State (version $VERSION) object:\n\t$self\n";
850              
851              
852 0           print STDERR "- " x 36, "\nINTERNAL STATE:\n";
853 0           foreach (qw( CREATE CASE PEDANTIC EHANDLER ERROR )) {
854 0 0         printf STDERR " %-12s => %s\n", $_,
855             defined($self->{ $_ }) ? $self->{ $_ } : "";
856             }
857              
858 0           print STDERR "- " x 36, "\nVARIABLES:\n";
859 0           foreach $var (keys %{ $self->{ VARIABLE } }) {
  0            
860 0           $self->_dump_var($var);
861             }
862              
863 0           print STDERR "- " x 36, "\n", "ALIASES:\n";
864 0           foreach $var (keys %{ $self->{ ALIAS } }) {
  0            
865 0           printf(" %-12s => %s\n", $var, $self->{ ALIAS }->{ $var });
866             }
867 0           print STDERR "=" x 72, "\n";
868             }
869              
870              
871              
872             1;
873              
874             __END__