File Coverage

blib/lib/AppConfig/CGI.pm
Criterion Covered Total %
statement 40 52 76.9
branch 10 20 50.0
condition n/a
subroutine 7 8 87.5
pod 0 2 0.0
total 57 82 69.5


line stmt bran cond sub pod time code
1             #============================================================================
2             #
3             # AppConfig::CGI.pm
4             #
5             # Perl5 module to provide a CGI interface to AppConfig. Internal variables
6             # may be set through the CGI "arguments" appended to a URL.
7             #
8             # Written by Andy Wardley
9             #
10             # Copyright (C) 1997-2003 Andy Wardley. All Rights Reserved.
11             # Copyright (C) 1997,1998 Canon Research Centre Europe Ltd.
12             #
13             #============================================================================
14              
15             package AppConfig::CGI;
16 1     1   433 use 5.006;
  1         2  
  1         33  
17 1     1   4 use strict;
  1         1  
  1         22  
18 1     1   3 use warnings;
  1         2  
  1         19  
19 1     1   4 use AppConfig::State;
  1         1  
  1         373  
20             our $VERSION = '1.71';
21              
22              
23             #------------------------------------------------------------------------
24             # new($state, $query)
25             #
26             # Module constructor. The first, mandatory parameter should be a
27             # reference to an AppConfig::State object to which all actions should
28             # be applied. The second parameter may be a string containing a CGI
29             # QUERY_STRING which is then passed to parse() to process. If no second
30             # parameter is specifiied then the parse() process is skipped.
31             #
32             # Returns a reference to a newly created AppConfig::CGI object.
33             #------------------------------------------------------------------------
34              
35             sub new {
36 1     1 0 9 my $class = shift;
37 1         2 my $state = shift;
38 1         4 my $self = {
39             STATE => $state, # AppConfig::State ref
40             DEBUG => $state->_debug(), # store local copy of debug
41             PEDANTIC => $state->_pedantic, # and pedantic flags
42             };
43 1         3 bless $self, $class;
44              
45             # call parse(@_) to parse any arg list passed
46 1 50       2 $self->parse(@_)
47             if @_;
48              
49 1         2 return $self;
50             }
51              
52              
53             #------------------------------------------------------------------------
54             # parse($query)
55             #
56             # Method used to parse a CGI QUERY_STRING and set internal variable
57             # values accordingly. If a query is not passed as the first parameter,
58             # then _get_cgi_query() is called to try to determine the query by
59             # examing the environment as per CGI protocol.
60             #
61             # Returns 0 if one or more errors or warnings were raised or 1 if the
62             # string parsed successfully.
63             #------------------------------------------------------------------------
64              
65             sub parse {
66 2     2 0 254 my $self = shift;
67 2         2 my $query = shift;
68 2         2 my $warnings = 0;
69 2         2 my ($variable, $value, $nargs);
70              
71              
72             # take a local copy of the state to avoid much hash dereferencing
73 2         9 my ($state, $debug, $pedantic) = @$self{ qw( STATE DEBUG PEDANTIC ) };
74              
75             # get the cgi query if not defined
76             $query = $ENV{ QUERY_STRING }
77 2 100       5 unless defined $query;
78              
79             # no query to process
80 2 50       5 return 1 unless defined $query;
81              
82             # we want to install a custom error handler into the AppConfig::State
83             # which appends filename and line info to error messages and then
84             # calls the previous handler; we start by taking a copy of the
85             # current handler..
86 2         7 my $errhandler = $state->_ehandler();
87              
88             # install a closure as a new error handler
89             $state->_ehandler(
90             sub {
91             # modify the error message
92 0     0   0 my $format = shift;
93 0         0 $format =~ s/
94 0         0 $format =~ s/>/>/g;
95 0         0 $format = "

\n[ AppConfig::CGI error: $format ] \n

\n";

96             # send error to stdout for delivery to web client
97 0         0 printf($format, @_);
98             }
99 2         13 );
100              
101              
102 2         29 PARAM: foreach (split('&', $query)) {
103              
104             # extract parameter and value from query token
105 6         10 ($variable, $value) = map { _unescape($_) } split('=');
  11         13  
106              
107             # check an argument was provided if one was expected
108 6 100       27 if ($nargs = $state->_argcount($variable)) {
109 4 50       5 unless (defined $value) {
110 0         0 $state->_error("$variable expects an argument");
111 0         0 $warnings++;
112 0 0       0 last PARAM if $pedantic;
113 0         0 next;
114             }
115             }
116             # default an undefined value to 1 if ARGCOUNT_NONE
117             else {
118 2 50       5 $value = 1 unless defined $value;
119             }
120              
121             # set the variable, noting any error
122 6 50       13 unless ($state->set($variable, $value)) {
123 0         0 $warnings++;
124 0 0       0 last PARAM if $pedantic;
125             }
126             }
127              
128             # restore original error handler
129 2         5 $state->_ehandler($errhandler);
130              
131             # return $warnings => 0, $success => 1
132 2 50       8 return $warnings ? 0 : 1;
133             }
134              
135              
136              
137             # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
138             # The following sub-routine was lifted from Lincoln Stein's CGI.pm
139             # module, version 2.36. Name has been prefixed by a '_'.
140              
141             # unescape URL-encoded data
142             sub _unescape {
143 11     11   9 my($todecode) = @_;
144 11         9 $todecode =~ tr/+/ /; # pluses become spaces
145 11         15 $todecode =~ s/%([0-9a-fA-F]{2})/pack("c",hex($1))/ge;
  0         0  
146 11         16 return $todecode;
147             }
148              
149             #
150             # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
151              
152              
153              
154              
155             1;
156              
157             __END__