File Coverage

blib/lib/AppConfig/State.pm
Criterion Covered Total %
statement 199 247 80.5
branch 115 154 74.6
condition 8 13 61.5
subroutine 17 19 89.4
pod 0 5 0.0
total 339 438 77.4


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