File Coverage

blib/lib/WWW/Chat/Processor.pm
Criterion Covered Total %
statement 72 126 57.1
branch 10 38 26.3
condition 2 12 16.6
subroutine 7 7 100.0
pod 0 4 0.0
total 91 187 48.6


line stmt bran cond sub pod time code
1             package WWW::Chat::Processor;
2             $VERSION = '0.62';
3 1     1   1546 use strict;
  1         2  
  1         152  
4 1     1   6 use Config qw(%Config);
  1         2  
  1         310  
5              
6              
7              
8             sub parse
9             {
10 1     1 0 581 my ($script, $file) = @_; # get the script as a single $calar
11             # plus the file name (optional)
12 1   50     5 $file ||= '[unknown]'; # set the default filename
13 1         3 my $output = ''; # initialise the output
14 1         6 my @LINES = split /\n/, $script; # split the script up into lines
15 1         2 undef $script; # and undef the script to save memory
16              
17 1         3 my $progname = $0; # get the progname name for diagnostics
18 1         6 $progname =~ s,.*[\\/],,; # and loose the path
19              
20 1         1202 $output .= "$Config{'startperl'} -w\n"; # get the shebang line
21              
22 1         32592 $output .= "# !!! DO NOT EDIT !!!\n"; # add some cruft
23 1         5 $output .= "# This program was automatically generated from '$file' by $progname\n";
24              
25             # .... and awwaaaaaay we go
26 1         5 $output .= <<'EOT';
27              
28             use strict;
29              
30             use URI ();
31             use HTTP::Request ();
32             use LWP::UserAgent ();
33             #use LWP::Debug qw(+);
34              
35             use HTML::Form ();
36             use WWW::Chat;
37              
38             use vars qw($ua $uri $base $req $res $status $ct @forms $form @links $TRACE);
39              
40             $base ||= "http://localhost";
41             unless ($ua) {
42             $ua = LWP::UserAgent->new;
43             $ua->agent("webchat/0.61 " . $ua->agent);
44             $ua->env_proxy;
45             }
46              
47             $TRACE = $ENV{WEBCHAT_TRACE};
48              
49             EOT
50              
51 1         4 $output .= "#line 1 \"$file\"\n";
52              
53 1     1   1376 use Data::Dump qw(dump);
  1         14461  
  1         2551  
54              
55 1         3 my $seen_end;
56 1         2 my $level = 0;
57 1         3 my $line = 2;
58 1         6 for ($line=0; $line < scalar @LINES; $line++)
59             {
60 2         5 $_ = $LINES[$line];
61 2 50       9 if ($seen_end)
62             {
63 0         0 $output .= $_."\n";
64 0         0 next;
65             }
66              
67 2 100       29 if (/^(\s*)GET\s+(\S+)\s*$/) {
    50          
    50          
    50          
    0          
    0          
    0          
    0          
68 1         2 my $indent = $1;
69 1         4 my $uri = $2;
70 1 50       12 $uri = dump($uri) unless $uri =~ /^\$/;
71 1         340 $output .= "$indent#GET $uri\n";
72 1         2 $output .= "${indent}eval {\n";
73 1         2 $level++;
74 1         4 $output .= "$indent local \$uri = URI->new_abs($uri, \$base);\n";
75 1         3 $output .= "$indent local \$req = HTTP::Request->new(GET => \$uri);\n";
76 1         6 $output .= request("$indent ");
77 1         7 $output .= line($line, $file);
78              
79             } elsif (/^(\s*)FOLLOW\s(.*)/) {
80 0         0 my $indent = $1;
81 0         0 my $what = $2;
82 0         0 $what =~ s/\s+$//;
83 0         0 $output .= "${indent}# FOLLOW $what\n";
84 0         0 $output .= "${indent}eval {\n";
85 0         0 $level++;
86 0 0       0 if ($what =~ m,^/,) {
87 0         0 $output .= "$indent local \$uri;\n";
88 0         0 $output .= "$indent for (\@links) { \$uri = \$_->[0], last if \$_->[1] =~ $what }\n";
89 0         0 my $text = dump("FOLLOW $what");
90 0         0 $output .= "$indent WWW::Chat::fail($text, \$res, \$ct) unless defined \$uri;\n";
91 0         0 $output .= "$indent \$uri = URI->new_abs(\$uri, \$base);\n";
92             } else {
93 0         0 $what = dump($what);
94 0         0 $output .= "$indent local \$uri = WWW::Chat::locate_link($what, \\\@links, \$base);\n";
95             }
96 0         0 $output .= "$indent local \$req = HTTP::Request->new(GET => \$uri);\n";
97 0         0 $output .= request("$indent ");
98 0         0 $output .= line($line, $file);
99              
100             } elsif (/^(\s*)FORM:?(\d+)?(?:\s+(\S+))?\s*$/) {
101 0         0 my $indent = $1;
102 0   0     0 my $form_no = $2 || 1;
103 0         0 my $uri = $3;
104 0 0 0     0 $uri = dump($uri) if !defined($uri) || $uri !~ /^\$/;
105 0         0 $output .= $indent. "\$form = WWW::Chat::findform(\\\@forms, $form_no, $uri);\n";
106              
107             } elsif (/^(\s*)EXPECT\s+(.*)$/) {
108 1         99 my $indent = $1;
109 1         3 my $what = $2;
110 1         3 $what =~ s/;$//;
111             # $output .= "$indent#EXPECT $what\n";
112 1         4 my $text = dump($what);
113 1         294 $what =~ s/(OK|ERROR)/WWW::Chat::$1(\$status)/g;
114 1         12 $output .= $indent. "WWW::Chat::fail($text, \$res, \$ct) unless $what;\n";
115              
116             } elsif (/^(\s*)BACK(?:\s+(ALL|\d+))?\s*$/) {
117 0         0 my $indent = $1;
118 0   0     0 my $done = $2 || "1";
119 0         0 $output .= done($indent, $done, $line, $file, \$level);
120            
121             } elsif (/^(\s*)F\s+([\w.:\-*\#]+)\s*=\s*(.*)/) {
122 0         0 my $indent = $1;
123 0         0 my $name = $2;
124 0         0 my $val = dump ("$3");
125              
126 0         0 my $no = 1;
127 0 0       0 $no = $1 if $name =~ s/:(\d+)$//;
128 0         0 $name = dump($name);
129              
130 0 0       0 if ($no == 1) {
131 0         0 $output .= "$indent\$form->value($name => $val);\n";
132             } else {
133 0         0 $output .= "$indent\$form->find_input($name, $no)->value($val);\n";
134             }
135              
136             } elsif (/^(\s*)(?:CLICK|SUBMIT)(?:\s+(\w+))?\s+(?:(\d+)\s+(\d+))?/) {
137 0         0 my $indent = $1;
138 0         0 my $name = $2;
139 0         0 $name = dump($name);
140 0         0 my $x = $3;
141 0         0 my $y = $4;
142 0 0       0 for ($x, $y) { $_ = 1 unless defined; }
  0         0  
143 0         0 $output .= "$indent#CLICK $name $x $y\n";
144 0         0 $output .= $indent. "eval {\n";
145 0         0 $level++;
146 0         0 $output .= $indent. " local \$uri = \$form->uri;\n";
147 0         0 $output .= $indent. " local \$req = \$form->click($name, $x, $y);\n";
148 0         0 $output .= request("$indent ");
149 0         0 $output .= line($line, $file);
150              
151             } elsif (/^__END__$/) {
152 0 0       0 $output .= done("", "ALL", $line, $file, \$level) if $level;
153 0         0 $output .= $_."\n";
154 0         0 $seen_end++;
155              
156             } else {
157 0         0 $output .= $_."\n";
158             }
159             }
160 1 50       9 $output .= done("", "ALL", $line, $file, \$level) if $level;
161 1         9 return $output;
162             }
163              
164              
165             sub done
166             {
167 1     1 0 3 my($indent, $done, $line, $file, $rlevel) = @_;
168 1 50 33     7 $done = $$rlevel if $done eq "ALL" || $done > $$rlevel;
169 1         2 $$rlevel -= $done;
170 1         2 my $output = '';
171 1         5 for (1 .. $done) {
172 1         4 $output .= $indent. "}; WWW::Chat::check_eval(\$@);\n";
173             }
174 1 50       6 $output .= line($line, $file) if ($done > 1);
175 1         3 return $output;
176             }
177              
178             sub request
179             {
180 1     1 0 3 my ($indent) = @_;
181 1         2 my $output = '';
182 1         3 $output .= $indent. "local \$res = WWW::Chat::request(\$req, \$ua, \$TRACE);\n";
183 1         5 $output .= $indent. "#print STDERR \$res->as_string;\n";
184 1         2 $output .= $indent. "local \$status = \$res->code;\n";
185 1         5 $output .= $indent. "local \$base = \$res->base;\n";
186 1         4 $output .= $indent. "local \$ct = \$res->content_type || \"\";\n";
187 1         3 $output .= $indent. "local \$_ = \$res->content;\n";
188 1         3 $output .= $indent. "local(\@forms, \$form, \@links);\n";
189 1         4 $output .= $indent. "if (\$ct eq 'text/html') {\n";
190 1         3 $output .= $indent. " \@forms = HTML::Form->parse(\$_, \$res->base);\n";
191 1         3 $output .= $indent. " \$form = \$forms[0] if \@forms;\n";
192 1         3 $output .= $indent. " \@links = WWW::Chat::extract_links(\$_);\n";
193 1         3 $output .= $indent. "}\n";
194 1         5 return $output;
195             }
196              
197             sub line
198             {
199 1     1 0 3 my ($line, $file) = @_;
200 1         3 $line+=2;
201 1         8 return qq(#line $line "$file"\n);
202             }
203              
204             1;
205             __END__