|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #!perl  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Config::Perl;  | 
| 
3
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
109932
 | 
 use warnings;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
157
 | 
    | 
| 
4
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
20
 | 
 use strict;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
367
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '0.02';  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 Name  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Config::Perl - Perl extension to parse configuration files written in a subset of Perl  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 and (limited) undumping of data structures (safer than eval thanks to parsing via PPI)  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 Synopsis  | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =for comment  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Remember to test this by copy/pasting to/from 91_author_pod.t  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  use Config::Perl;  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $parser = Config::Perl->new;  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $data = $parser->parse_or_die( \<<' END_CONFIG_FILE' );  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    # This is the example configuration file  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    $foo = "bar";  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    %text = ( test => ["Hello", "World!"] );  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    @vals = qw/ x y a /;  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  END_CONFIG_FILE  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  print $data->{'$foo'}, "\n";   # prints "bar\n"  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # Resulting $data: {  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  #   '$foo'  => "bar",  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  #   '%text' => { test => ["Hello", "World!"] },  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  #   '@vals' => ["x", "y", "a"],  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # };  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 Description  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The goal of this module is to support the parsing of a small subset of Perl,  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 primarily in order to parse configuration files written in that subset of Perl.  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 As a side effect, this module can "undump" some data structures written by  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L and L - see L.  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The code is parsed via L, eliminating the need for Perl's C.  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This should provide a higher level of safety* compared to C  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 (even when making use of a module like L).  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 * B A "higher level of safety" does not mean "perfect safety".  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This software is distributed B; without even the implied  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 warranty of B or B.  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See also the licence for this software.  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This module attempts to provide 100% compatibility with Perl over the subset of Perl it supports.  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 When a Perl feature is not supported by this module, it should complain   | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 that the feature is not supported, instead of silently giving a wrong result.  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If the output of a parse is different from how Perl would evaluate the same string,  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 then that is a bug in this module that should be fixed by correcting the output  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 or adding an error message that the particular feature is unsupported.  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 However, the result of using this module to parse something that is not valid Perl is undefined;  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 it may cause an error, or may fail in some other silent way.  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This document describes version 0.02 of the module.  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Although this module is well-tested and working, it still lacks some  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 features to make it I useful (see list below).  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Contributions are welcome!  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Interface  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This module has a simple OO interface. A new parser is created  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 with C<< Config::Perl->new >>, which currently does not take any arguments,  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 and documents are parsed with either the method C or C.  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $parser = Config::Perl->new;  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $out1 = $parser->parse_or_undef(\' $foo = "bar"; ');  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  warn "parse failed: ".$parser->errstr unless defined $out1;  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $out2 = $parser->parse_or_die('filename.pl');  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The arguments and return values of these two methods are (almost) the same:  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 They each take exactly one argument, which is either a filename,  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 or a reference to a string containing the code to be parsed  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 (this is the same as L's C method).  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The methods differ in that, as the names imply, C  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 will C on errors, while C will return C;  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the error message is then accessible via the C method.  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 For a successful parse, the return value of each function is a hashref  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 representing the "symbol table" of the parsed document.  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This "symbol table" hash is similar to, but not the same as, Perl's symbol table.  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The hash includes a key for every variable declared or assigned to in the document,  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the key is the name of the variable including its sigil.  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If the document ends with a plain value or list that is not part of an assignment,  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 that value is saved in the "symbol table" hash with the key "C<_>" (a single underscore).  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 For example, the string C<"$foo=123; $bar=456;"> will return the data structure  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C<< { '$foo'=>123, '$bar'=>456 } >>, and the string C<"('foo','bar')"> will return the data  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 structure C<< { _=>["foo","bar"] } >>.  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Note that documents are currently always parsed in list context.  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 For example, this means that a document like "C<@foo = ("a","b","c"); @foo>"  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 will return the array's elements (C<"a","b","c">) instead of the item count (C<3>).  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This also means that the special hash element "C<_>" will currently always be an arrayref.  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 What is currently supported  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 plain scalars, arrays, hashes, lists  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 arrayrefs and hashrefs constructed via C<[]> and C<{}> resp.  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 declarations - only C, also C on the outermost level (document)  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 where it is treated exactly like C;  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 not supported are lexical C inside blocks, C or C  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 assignments (except the return value of assignments is not yet implemented)  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 simple array and hash subscripts (e.g. C<$x[1]>, C<$x[$y]>, C<$x{z}>, C<$x{"$y"}>)  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 very simple variable interpolations in strings (currently only C<"hello$world"> or C<"foo${bar}quz">)  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 and some escape sequences (e.g. C<"\x00">)  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C blocks (contents limited to the supported features listed here)  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 What is not supported (yet)  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 I hope to achieve a balance where this module is useful, without becoming too much of a re-implementation of Perl.  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 I've labeled these items with "wishlist", "maybe", and "no", depending on whether I currently feel that  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 I'd like to support this feature in a later version, I'd consider supporting this feature if the need arises,  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 or I currently don't think the feature should be implemented.  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 lexical variables (C) (wishlist)  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 taking references via C<\> and dereferencing (C<@{...}>, C<%{...}>, etc.) (wishlist)  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 return values of assignments (e.g. C<$foo = do { $bar = "quz" }>) (maybe)  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 operators other than assignment (maybe; supporting a subset, like concatenation, is wishlist)  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 conditionals, like for example a very simple C (maybe)  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 any functions (mostly this is "no"; supporting a very small subset of functions, e.g. C, is "maybe")  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 anything that can't be resolved via a static parse (including Cs, many regexps, etc.) (no)  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Note this list is not complete.  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 Author, Copyright, and License  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Copyright (c) 2015 Hauke Daempfling (haukex@zero-g.net).  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This library is free software; you can redistribute it and/or modify  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 it under the same terms as Perl 5 itself.  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 For more information see the L,  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 which should have been distributed with your copy of Perl.  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Try the command "C" or see  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L.  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
195
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
22
 | 
 use Carp;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
272
 | 
    | 
| 
196
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
22
 | 
 use warnings::register;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
614
 | 
    | 
| 
197
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
2656
 | 
 use PPI ();  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
862132
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
136
 | 
    | 
| 
198
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
2180
 | 
 use PPI::Dumper ();  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4074
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14015
 | 
    | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
201
 | 
140
 | 
 
 | 
 
 | 
  
140
  
 | 
  
0
  
 | 
135549
 | 
 	my $class = shift;  | 
| 
202
 | 
140
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
603
 | 
 	croak "new currently takes no arguments" if @_;  | 
| 
203
 | 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
414
 | 
 	my $self = {  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		errstr => undef,  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		out => undef,  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		ctx => undef, # Note: valid values for ctx currently "list", "scalar", "scalar-void"  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	};  | 
| 
208
 | 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
505
 | 
 	return bless $self, $class;  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
210
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
0
  
 | 
12
 | 
 sub errstr { return shift->{errstr} }  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #TODO: make _errmsg a little prettier?  | 
| 
213
 | 
15
 | 
 
 | 
 
 | 
  
15
  
 | 
 
 | 
66
 | 
 sub _dump { return PPI::Dumper->new(shift,whitespace=>0,comments=>0,locations=>0)->string }  | 
| 
214
 | 
15
 | 
 
 | 
 
 | 
  
15
  
 | 
 
 | 
87
 | 
 sub _errmsg { chomp(my $e=_dump(shift)); $e=~s/^/\t/mg; return "<<< $e >>>" }  | 
| 
 
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2798
 | 
    | 
| 
 
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1642
 | 
    | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub parse_or_undef {  ## no critic (RequireArgUnpacking)  | 
| 
217
 | 
87
 | 
 
 | 
 
 | 
  
87
  
 | 
  
0
  
 | 
1358
 | 
 	my $self = shift;  | 
| 
218
 | 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
 	my $out = eval { $self->parse_or_die(@_) };  | 
| 
 
 | 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
169
 | 
    | 
| 
219
 | 
87
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
536
 | 
 	my $errmsg = $@||"Unknown error";  | 
| 
220
 | 
87
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
163
 | 
 	$self->{errstr} = defined $out ? undef : $errmsg;  | 
| 
221
 | 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
193
 | 
 	return $out;  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub parse_or_die {  | 
| 
225
 | 
147
 | 
 
 | 
 
 | 
  
147
  
 | 
  
0
  
 | 
3197
 | 
 	my ($self,$input) = @_;  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# PPI::Documents are not "complete" if they don't have a final semicolon, so tack on on there if it's missing  | 
| 
227
 | 
147
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1143
 | 
 	$input = \"$$input;" if ref $input eq 'SCALAR' && $$input!~/;\s*$/;  | 
| 
228
 | 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
550
 | 
 	$self->{doc} = my $doc = PPI::Document->new($input);  | 
| 
229
 | 
147
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
313301
 | 
 	my $errmsg = PPI::Document->errstr||"Unknown error";  | 
| 
230
 | 
147
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1495
 | 
 	$doc or croak "Parse failed: $errmsg";  | 
| 
231
 | 
146
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
359
 | 
 	$doc->complete or croak "Document incomplete (missing final semicolon?)";  | 
| 
232
 | 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37187
 | 
 	$self->{ctx} = 'list';  | 
| 
233
 | 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
219
 | 
 	$self->{out} = {};  | 
| 
234
 | 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
341
 | 
 	my @rv = $self->_handle_block($doc, outer=>1);  | 
| 
235
 | 
126
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
280
 | 
 	$self->{out}{_} = \@rv if @rv;  | 
| 
236
 | 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
319
 | 
 	return $self->{out};  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _handle_block {  ## no critic (ProhibitExcessComplexity)  | 
| 
240
 | 
151
 | 
 
 | 
 
 | 
  
151
  
 | 
 
 | 
359
 | 
 	my ($self,$block,%param) = @_;  | 
| 
241
 | 
151
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
1104
 | 
 	confess "invalid \$block class"  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		unless $block->isa('PPI::Structure::Block') || $block->isa('PPI::Document');  | 
| 
243
 | 
151
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
344
 | 
 	return unless $block->schildren;  | 
| 
244
 | 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1847
 | 
 	my @rv;  | 
| 
245
 | 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
309
 | 
 	my $el = $block->schild(0);  | 
| 
246
 | 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1485
 | 
 	ELEMENT: while ($el) {  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		# uncoverable branch true  | 
| 
248
 | 
295
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
3230
 | 
 		$el->isa('PPI::Statement') or croak "Unsupported element\n"._errmsg($el);  | 
| 
249
 | 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
568
 | 
 		my @sc = $el->schildren;  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		# remove semicolons from statements  | 
| 
251
 | 
295
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
4019
 | 
 		if ( @sc && $sc[-1]->isa('PPI::Token::Structure') && $sc[-1]->content eq ';' )  | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
252
 | 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1522
 | 
 			{ pop(@sc)->delete }  | 
| 
253
 | 
295
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
8753
 | 
 		next ELEMENT unless @sc; # empty statement?  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		# last statement in block gets its context, otherwise void context  | 
| 
255
 | 
295
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1564
 | 
 		local $self->{ctx} = $el->snext_sibling ? 'scalar-void' : $self->{ctx};  | 
| 
256
 | 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4963
 | 
 		my $is_assign; # remove this once _handle_assign return values implemented  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		# variable declaration  | 
| 
258
 | 
295
 | 
  
100
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
614
 | 
 		if ($el->class eq 'PPI::Statement::Variable') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# note that Perl does not allow array or hash elements in declarations  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# so we don't have to worry about subscripts here  | 
| 
261
 | 
65
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
287
 | 
 			croak "Unsupported declaration type \"".$el->type."\""  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				unless $el->type eq 'our' || $el->type eq 'my';  | 
| 
263
 | 
64
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
1947
 | 
 			croak "Lexical variables (\"my\") not supported" # I'd like to support "my" soon  | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				unless $el->type eq 'our' || ($el->type eq 'my' && $param{outer});  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# Note: Don't use $el->symbols, as that omits undefs on LHS!  | 
| 
266
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1406
 | 
 			$self->_handle_assign($el,$sc[1],$sc[3]);  | 
| 
267
 | 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
 			$is_assign=1;  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		elsif ($el->class eq 'PPI::Statement') {  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# assignment, possibly with symbol+subscript on the RHS  | 
| 
271
 | 
226
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
3071
 | 
 			if ( (@sc==3||@sc==4) && $sc[1]->isa('PPI::Token::Operator') && $sc[1]->content eq '=' ) {  ## no critic (ProhibitCascadingIfElse)  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
272
 | 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
809
 | 
 				$self->_handle_assign($el,$sc[0],$sc[2]);  | 
| 
273
 | 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
203
 | 
 				$is_assign=1;  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# assignment assumed to have a symbol+subscript on the LHS  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			elsif ( (@sc==4||@sc==5) && $sc[2]->isa('PPI::Token::Operator') && $sc[2]->content eq '=' ) {  | 
| 
277
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
 				$self->_handle_assign($el,$sc[0],$sc[3]);  | 
| 
278
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 				$is_assign=1;  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# do-BLOCK  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			elsif ( @sc==2 && $sc[0]->isa('PPI::Token::Word') && $sc[0]->literal eq 'do'  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				&& $sc[1]->isa('PPI::Structure::Block') ) {  | 
| 
283
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
98
 | 
 				my @tmprv = $self->_handle_block($sc[1]);  | 
| 
284
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
 				@rv = @tmprv unless $self->{ctx} eq 'scalar-void';  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# single statements  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			elsif ( @sc==1 || (@sc==2 && $sc[0]->isa('PPI::Token::Symbol') && $sc[1]->isa('PPI::Structure::Subscript')) ) {  | 
| 
288
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
92
 | 
 				my @tmprv = $self->_handle_value($sc[0]);  | 
| 
289
 | 
24
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
124
 | 
 				@rv = @tmprv unless $self->{ctx} eq 'scalar-void';  | 
| 
290
 | 
24
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
545
 | 
 				warnings::warnif("value in void context") if $self->{ctx} eq 'scalar-void';  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# push  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			elsif ( @sc>2 && $sc[0]->isa('PPI::Token::Word') && $sc[0]->literal eq 'push') {  | 
| 
294
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
 				croak "don't support push\n"._errmsg($el); # I'm considering supporting push  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
296
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 			else { croak "Unsupported element\n"._errmsg($el) }  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		elsif ( $el->isa('PPI::Statement::Compound') && @sc==1 && $sc[0]->isa('PPI::Token::Label') ) {  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# ignore labels  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
301
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		else { croak "Unsupported element ".$el->class." in\n"._errmsg($el) }  | 
| 
302
 | 
276
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1325
 | 
 		if ($is_assign && $self->{ctx} ne 'scalar-void') {  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# special case: the last statement of the outermost block  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			#TODO: Would it make sense to not error out on *any* assignment at the end of a block, not just the outermost one?  | 
| 
305
 | 
104
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
335
 | 
 			if ($param{outer} && !$el->snext_sibling)  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				{} # currently nothing; could warn here?  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			else  | 
| 
308
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				{ croak "Assignment return values not implemented (current context is $$self{ctx}) in\n"._errmsg($el) }  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
310
 | 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2071
 | 
 	} continue { $el = $el->snext_sibling }  | 
| 
311
 | 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1800
 | 
 	return @rv;  | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # returns nothing (yet)  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _handle_assign {  | 
| 
316
 | 
250
 | 
 
 | 
 
 | 
  
250
  
 | 
 
 | 
306
 | 
 	my ($self,$as,$lhs,$rhs) = @_;  | 
| 
317
 | 
250
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
410
 | 
 	confess "invalid \$as class"  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		unless $as->class eq 'PPI::Statement' || $as->class eq 'PPI::Statement::Variable';  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# Note we expect our caller to pick the correct $lhs and $rhs children from $as,  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# and at the moment *some* call sites also already check the number of children.  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# Possible To-Do for Later: Clean up the _handle_assign calling  | 
| 
322
 | 
250
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
1249
 | 
 	croak "bad assignment statement length in:\n"._errmsg($as)  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		if $as->schildren<3 || $as->schildren>5;  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
325
 | 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5711
 | 
 	my $lhs_scalar;  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	my @lhs;  | 
| 
327
 | 
249
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
569
 | 
 	if ($lhs->isa('PPI::Token::Symbol')) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
328
 | 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
423
 | 
 		@lhs = ($self->_handle_symbol($lhs));  | 
| 
329
 | 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
401
 | 
 		$lhs_scalar = $lhs[0]->{atype} eq '$';  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif ($lhs->isa('PPI::Structure::List')) {  | 
| 
332
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
102
 | 
 		local $self->{ctx} = 'list';  | 
| 
333
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
 		@lhs = $self->_handle_list($lhs,is_lhs=>1);  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
335
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	else { confess "invalid assignment LHS "._errmsg($lhs) }  # uncoverable statement  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
337
 | 
245
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
518
 | 
 	local $self->{ctx} = $lhs_scalar ? 'scalar' : 'list';  | 
| 
338
 | 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
427
 | 
 	my @rhs = $self->_handle_value($rhs);  | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  | 
| 
340
 | 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1391
 | 
 	for my $l (@lhs) {  | 
| 
341
 | 
250
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
604
 | 
 		if (!defined($l))  ## no critic (ProhibitCascadingIfElse)  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
342
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 			{ shift @rhs }  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		elsif ($l->{atype} eq '$')  | 
| 
344
 | 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
211
 | 
 			{ ${ $l->{ref} } = shift @rhs }  | 
| 
 
 | 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
451
 | 
    | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		elsif ($l->{atype} eq '@') {  | 
| 
346
 | 
20
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
 			if (!defined ${$l->{ref}})  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
    | 
| 
347
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
 				{ ${ $l->{ref} } = [@rhs] }  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			else  | 
| 
349
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 				{ @{ ${ $l->{ref} } } = @rhs }  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
    | 
| 
350
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
 			last; # slurp  | 
| 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		elsif ($l->{atype} eq '%') {  | 
| 
353
 | 
14
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
15
 | 
 			if (!defined ${$l->{ref}})  | 
| 
 
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
    | 
| 
354
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
 				{ ${ $l->{ref} } = {@rhs} }  | 
| 
 
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			else  | 
| 
356
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 				{ %{ ${ $l->{ref} } } = @rhs }  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    | 
| 
357
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
 			last; # slurp  | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
359
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		else { confess "Possible internal error: can't assign to "._errmsg($l)." in\n"._errmsg($as) }  # uncoverable statement  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
361
 | 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
561
 | 
 	return;  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # returns a list (if param is_lhs is true, list will consist of only _handle_symbol return values)  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _handle_list {  ## no critic (ProhibitExcessComplexity)  | 
| 
366
 | 
110
 | 
 
 | 
 
 | 
  
110
  
 | 
 
 | 
168
 | 
 	my ($self,$outerlist,%param) = @_;  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# NOTE this handles both () lists as well as the *contents* of {} and [] constructors  | 
| 
368
 | 
110
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
234
 | 
 	confess "outerlist is undef?" unless $outerlist;  | 
| 
369
 | 
110
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
554
 | 
 	confess "bad list class ".$outerlist->class  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		unless $outerlist->isa('PPI::Structure::List') || $outerlist->isa('PPI::Structure::Constructor');  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# We should already have been placed in list context  | 
| 
372
 | 
110
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
614
 | 
 	confess "Internal error: Context is not list? Is \"$$self{ctx} \"at:\n"._errmsg($outerlist)  | 
| 
373
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		unless $self->{ctx}=~/^list\b/;  | 
| 
374
 | 
110
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
243
 | 
 	croak "can only handle a plain list on LHS"  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		if $param{is_lhs} && !$outerlist->isa('PPI::Structure::List');  | 
| 
376
 | 
110
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
297
 | 
 	return unless $outerlist->schildren; # empty list  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# the first & only child of the outer list structure is a statement / expression  | 
| 
378
 | 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1320
 | 
 	my $act_list = $outerlist->schild(0);  | 
| 
379
 | 
110
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
1071
 | 
 	croak "Unsupported list\n"._errmsg($outerlist)  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		unless $outerlist->schildren==1 && ($act_list->isa('PPI::Statement::Expression') || $act_list->class eq 'PPI::Statement');  | 
| 
381
 | 
110
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1837
 | 
 	return unless $act_list->schildren; # empty list?  | 
| 
382
 | 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1415
 | 
 	my @thelist;  | 
| 
383
 | 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
115
 | 
 	my $expect = 'item';  | 
| 
384
 | 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
219
 | 
 	my $el = $act_list->schild(0);  | 
| 
385
 | 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
897
 | 
 	ELEMENT: while ($el) {  | 
| 
386
 | 
482
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
5483
 | 
 		if ($expect eq 'item') {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
387
 | 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
600
 | 
 			my $peek_next = $el->snext_sibling;  | 
| 
388
 | 
295
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
4556
 | 
 			my $fat_comma_next = $peek_next && $peek_next->isa('PPI::Token::Operator') && $peek_next->content eq '=>';  | 
| 
389
 | 
295
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
896
 | 
 			if ($param{is_lhs}) {  | 
| 
390
 | 
15
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
50
 | 
 				if ($el->isa('PPI::Token::Symbol'))  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
391
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
 					{ push @thelist, $self->_handle_symbol($el) }  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				elsif (!$fat_comma_next && $el->isa('PPI::Token::Word') && $el->literal eq 'undef')  | 
| 
393
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 					{ push @thelist, undef }  | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				else  | 
| 
395
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 					{ croak "Don't support this on LHS: "._errmsg($el) }  | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			else {  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				# handle fat comma autoquoting words  | 
| 
399
 | 
280
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1819
 | 
 				if ($fat_comma_next && $el->isa('PPI::Token::Word') && $el->literal=~/^\w+$/ )  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
400
 | 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
349
 | 
 					{ push @thelist, $el->literal }  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				elsif ($el->isa('PPI::Token::QuoteLike::Words')) # qw// in a list  | 
| 
402
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 					{ push @thelist, $el->literal } # here "literal" returns a list of words  | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				else {  | 
| 
404
 | 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
400
 | 
 					push @thelist, $self->_handle_value($el);  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					# special case of do followed by BLOCKs  | 
| 
406
 | 
249
 | 
  
 50
  
 | 
  
100
  
 | 
 
 | 
 
 | 
2180
 | 
 					if ($el->isa('PPI::Token::Word') && $el->literal eq 'do'  | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 						&& $peek_next && $peek_next->isa('PPI::Structure::Block'))  | 
| 
408
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
 						{ $el = $el->snext_sibling } # this will have been handled by _handle_value  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				}  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# special case of symbols followed by subscripts  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			# Possible To-Do for Later: More generalized handling of multi-element list items?  | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			#   Right now we have special handling of Symbol-Subscript and do-BLOCK pairs, if more special cases appear,  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			#   we should figure out a more generalized way of advancing our list pointer over the handled elements.  | 
| 
415
 | 
294
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1326
 | 
 			if ($el->isa('PPI::Token::Symbol') && $peek_next && $peek_next->isa('PPI::Structure::Subscript'))  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
416
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 				{ $el = $el->snext_sibling } # this will have been handled by _handle_symbol, called from _handle_value  | 
| 
417
 | 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
424
 | 
 			$expect = 'separator';  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		elsif ($expect eq 'separator') {  | 
| 
420
 | 
187
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
691
 | 
 			croak "Expected list separator, got "._errmsg($el)  | 
| 
 
 | 
 
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
421
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				unless $el->isa('PPI::Token::Operator')  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				&& ($el->content eq ',' || $el->content eq '=>');  | 
| 
423
 | 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1007
 | 
 			$expect = 'item';  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
425
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		else { confess "really shouldn't happen, bad state $expect" }  # uncoverable statement  | 
| 
426
 | 
481
 | 
 
 | 
 
 | 
 
 | 
 
 | 
818
 | 
 	} continue { $el = $el->snext_sibling }  | 
| 
427
 | 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1783
 | 
 	return @thelist;  | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # respects context and returns either a single value, or list if applicable  | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _handle_value {  ## no critic (ProhibitExcessComplexity)  | 
| 
432
 | 
538
 | 
 
 | 
 
 | 
  
538
  
 | 
 
 | 
566
 | 
 	my ($self,$val) = @_;  | 
| 
433
 | 
538
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1169
 | 
 	confess "\$val is false" unless $val;  | 
| 
434
 | 
538
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
2883
 | 
 	if ($val->isa('PPI::Token::Number'))  ## no critic (ProhibitCascadingIfElse)  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
435
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
357
 | 
 		{ return 0+$val->literal }  | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif ($val->isa('PPI::Token::Quote'))  | 
| 
437
 | 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
371
 | 
 		{ return $self->_handle_quote($val) }  | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif ($val->isa('PPI::Structure::Constructor'))  | 
| 
439
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
151
 | 
 		{ return $self->_handle_struct($val) }  | 
| 
440
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif ($val->isa('PPI::Token::Word') && $val->literal eq 'undef')  | 
| 
441
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 		{ return undef }  ## no critic (ProhibitExplicitReturnUndef)  | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif ($val->isa('PPI::Token::Word') && $val->literal=~/^-\w+$/)  | 
| 
443
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
80
 | 
 		{ return $val->literal }  | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif ($val->isa('PPI::Token::Symbol')) {  | 
| 
445
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
80
 | 
 		my $sym = $self->_handle_symbol($val);  | 
| 
446
 | 
18
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
58
 | 
 		if ($sym->{atype} eq '$') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
447
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 			return ${ $sym->{ref} };  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
    | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		elsif ($sym->{atype} eq '@') {  | 
| 
450
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 			return $self->{ctx}=~/^scalar\b/  | 
| 
451
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 				? scalar(@{ ${ $sym->{ref} } })  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
    | 
| 
452
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 				: @{ ${ $sym->{ref} } };  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		elsif ($sym->{atype} eq '%') {  | 
| 
455
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 			return $self->{ctx}=~/^scalar\b/  | 
| 
456
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
 				? scalar(%{ ${ $sym->{ref} } })  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
457
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
 				: %{ ${ $sym->{ref} } };  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
459
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
144
 | 
 		else { confess "bad symbol $sym" }  | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif ($val->isa('PPI::Token::Word') && $val->literal eq 'do'  | 
| 
462
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		&& $val->snext_sibling && $val->snext_sibling->isa('PPI::Structure::Block'))  | 
| 
463
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
121
 | 
 		{ return $self->_handle_block($val->snext_sibling) }  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif ($val->isa('PPI::Structure::List')) {  | 
| 
465
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1056
 | 
 		my @l = do {  | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				# temporarily force list context to make _handle_list happy  | 
| 
467
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
 				local $self->{ctx} = 'list';  | 
| 
468
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
 				$self->_handle_list($val);  | 
| 
469
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			};  | 
| 
470
 | 
24
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
94
 | 
 		return $self->{ctx}=~/^scalar\b/ ? $l[-1] : @l;  | 
| 
471
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif ($val->isa('PPI::Token::QuoteLike::Words')) { # qw//  | 
| 
473
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
 		my @l = $val->literal; # returns a list of words  | 
| 
474
 | 
20
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
209
 | 
 		return $self->{ctx}=~/^scalar\b/ ? $l[-1] : @l;  | 
| 
475
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
476
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
 	croak "Can't handle value "._errmsg($val);  | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # returns a hashref representing the symbol (see code below for details)  | 
| 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _handle_symbol {  | 
| 
481
 | 
274
 | 
 
 | 
 
 | 
  
274
  
 | 
 
 | 
338
 | 
 	my ($self,$sym) = @_;  | 
| 
482
 | 
274
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
595
 | 
 	confess "bad symbol" unless $sym->isa('PPI::Token::Symbol');  | 
| 
483
 | 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
501
 | 
 	my $peek_next = $sym->snext_sibling;  | 
| 
484
 | 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3718
 | 
 	my %rsym = ( name => $sym->symbol, atype => $sym->raw_type );  | 
| 
485
 | 
274
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
10482
 | 
 	if ($peek_next && $peek_next->isa('PPI::Structure::Subscript')) {  | 
| 
486
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
 		my $sub = $self->_handle_subscript($peek_next);  | 
| 
487
 | 
14
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
153
 | 
 		if ($sym->raw_type eq '$' && $sym->symbol_type eq '@' && $peek_next->braces eq '[]') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
488
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
655
 | 
 			$rsym{ref} = \( $self->{out}{$sym->symbol}[$sub] );  | 
| 
489
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
467
 | 
 			$rsym{sub} = "[$sub]";  | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
491
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		elsif ($sym->raw_type eq '$' && $sym->symbol_type eq '%' && $peek_next->braces eq '{}') {  | 
| 
492
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
273
 | 
 			$rsym{ref} = \( $self->{out}{$sym->symbol}{$sub} );  | 
| 
493
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
93
 | 
 			$rsym{sub} = "{$sub}";  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
495
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
 		else { croak "Can't handle this subscript on this variable: "._errmsg($sym)._errmsg($peek_next) }  | 
| 
496
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
497
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	else {  | 
| 
498
 | 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
579
 | 
 		$rsym{ref} = \( $self->{out}{$sym->symbol} );  | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
500
 | 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6681
 | 
 	return \%rsym;  | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
502
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # returns a single value  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _handle_subscript {  | 
| 
505
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
26
 | 
 	my ($self,$sub) = @_;  | 
| 
506
 | 
18
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
49
 | 
 	confess "bad subscript" unless $sub->isa('PPI::Structure::Subscript');  | 
| 
507
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
 	my @sub_ch = $sub->schildren;  | 
| 
508
 | 
18
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
208
 | 
 	croak "Expected subscript to contain a single expression\n"._errmsg($sub)  | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		unless @sub_ch==1 && $sub_ch[0]->isa('PPI::Statement::Expression');  | 
| 
510
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
 	my @subs = $sub_ch[0]->schildren;  | 
| 
511
 | 
18
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
102
 | 
 	croak "Expected subscript to contain a single value\n"._errmsg($sub)  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		unless @subs==1;  | 
| 
513
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# autoquoting in hash braces  | 
| 
514
 | 
15
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
28
 | 
 	if ($sub->braces eq '{}' && $subs[0]->isa('PPI::Token::Word'))  | 
| 
515
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
 		{ return $subs[0]->literal }  | 
| 
516
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	else {  | 
| 
517
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
 		local $self->{ctx} = 'scalar';  | 
| 
518
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
 		return $self->_handle_value($subs[0]);  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # returns arrayref or hashref  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _handle_struct {  | 
| 
524
 | 
77
 | 
 
 | 
 
 | 
  
77
  
 | 
 
 | 
85
 | 
 	my ($self,$constr) = @_;  | 
| 
525
 | 
77
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
200
 | 
 	confess "bad struct class ".$constr->class  | 
| 
526
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		unless $constr->isa('PPI::Structure::Constructor');  | 
| 
527
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
123
 | 
 	local $self->{ctx} = 'list';  | 
| 
528
 | 
77
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
192
 | 
 	if ($constr->braces eq '[]')  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
529
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
237
 | 
 		{ return [$self->_handle_list($constr)] }  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif ($constr->braces eq '{}')  | 
| 
531
 | 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
700
 | 
 		{ return {$self->_handle_list($constr)} }  | 
| 
532
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	croak "Unsupported constructor\n"._errmsg($constr);  # uncoverable statement  | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # handles the known PPI::Token::Quote subclasses  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # returns a single value  | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _handle_quote {  | 
| 
538
 | 
233
 | 
 
 | 
 
 | 
  
233
  
 | 
 
 | 
210
 | 
 	my ($self,$q) = @_;  | 
| 
539
 | 
233
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1358
 | 
 	if ( $q->isa('PPI::Token::Quote::Single') || $q->isa('PPI::Token::Quote::Literal') )  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
540
 | 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
331
 | 
 		{ return $q->literal }  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	elsif ( $q->isa('PPI::Token::Quote::Double') || $q->isa('PPI::Token::Quote::Interpolate') )  | 
| 
542
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
185
 | 
 		{ return $self->_handle_interpolate($q) }  | 
| 
543
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	confess "unknown PPI::Token::Quote subclass ".$q->class;  # uncoverable statement  | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # for use in _handle_quote; does very limited string interpolation  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # returns a single value  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _handle_interpolate {  | 
| 
548
 | 
100
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
109
 | 
 	my ($self,$q) = @_;  | 
| 
549
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
268
 | 
 	my $str = $q->string;  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# Perl (at least v5.20) doesn't allow trailing $, it does allow trailing @  | 
| 
551
 | 
100
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
789
 | 
 	croak "Final \$ should be \\\$ or \$name" if $str=~/\$$/;  | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# Variables  | 
| 
553
 | 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
181
 | 
 	$str=~s{(?_fetch_interp_var($2)}eg;  | 
| 
 
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
    | 
| 
554
 | 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
110
 | 
 	$str=~s{(?_fetch_interp_var($2.$3)}eg;  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
    | 
| 
555
 | 
99
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
263
 | 
 	croak "Don't support string interpolation of '$1' in '$str' at "._errmsg($q)  | 
| 
556
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		if $str=~/(?
 | 
| 
557
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# Backslash escape sequences  | 
| 
558
 | 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
127
 | 
 	$str=~s{\\([0-7]{1,3}|x[0-9A-Fa-f]{2}|.)}{$self->_backsl($1)}eg;  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
    | 
| 
559
 | 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
250
 | 
 	return $str;  | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %_backsl_tbl = ( '\\'=>'\\', '$'=>'$', '"'=>'"', "'"=>"'", 'n'=>"\n", 'r'=>"\r", 't'=>"\t" );  | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _backsl { # for use in _handle_interpolate ONLY  | 
| 
563
 | 
16
 | 
 
 | 
 
 | 
  
16
  
 | 
 
 | 
28
 | 
 	my ($self,$what) = @_;  | 
| 
564
 | 
16
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
56
 | 
 	return chr(oct($what)) if $what=~/^[0-7]+$/;  | 
| 
565
 | 
13
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
22
 | 
 	return chr(hex($1)) if $what=~/^x([0-9A-Fa-f]+)$/;  ## no critic (ProhibitCaptureWithoutTest)  | 
| 
566
 | 
13
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
 	return $_backsl_tbl{$what} if exists $_backsl_tbl{$what};  | 
| 
567
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
103
 | 
 	croak "Don't support escape sequence \"\\$what\"";  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _fetch_interp_var { # for use in _handle_interpolate ONLY  | 
| 
570
 | 
11
 | 
 
 | 
 
 | 
  
11
  
 | 
 
 | 
19
 | 
 	my ($self,$var) = @_;  | 
| 
571
 | 
11
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
79
 | 
 	return $self->{out}{$var}  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		if exists $self->{out}{$var} && defined $self->{out}{$var};  | 
| 
573
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
500
 | 
 	warnings::warnif("Use of uninitialized value $var in interpolation");  | 
| 
574
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
141
 | 
 	return "";  | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  |