Filename | /usr/local/perls/perl-5.26.1/lib/5.26.1/Text/ParseWords.pm |
Statements | Executed 108 statements in 508µs |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
3 | 1 | 1 | 210µs | 419µs | parse_line | Text::ParseWords::
6 | 1 | 1 | 147µs | 147µs | CORE:regcomp (opcode) | Text::ParseWords::
3 | 1 | 1 | 94µs | 522µs | shellwords | Text::ParseWords::
15 | 3 | 1 | 71µs | 71µs | CORE:subst (opcode) | Text::ParseWords::
0 | 0 | 0 | 0s | 0s | BEGIN | Text::ParseWords::
0 | 0 | 0 | 0s | 0s | nested_quotewords | Text::ParseWords::
0 | 0 | 0 | 0s | 0s | old_shellwords | Text::ParseWords::
0 | 0 | 0 | 0s | 0s | quotewords | Text::ParseWords::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Text::ParseWords; | ||||
2 | |||||
3 | use strict; | ||||
4 | require 5.006; | ||||
5 | our $VERSION = "3.30"; | ||||
6 | |||||
7 | |||||
8 | use Exporter; | ||||
9 | our @ISA = qw(Exporter); | ||||
10 | our @EXPORT = qw(shellwords quotewords nested_quotewords parse_line); | ||||
11 | our @EXPORT_OK = qw(old_shellwords); | ||||
12 | our $PERL_SINGLE_QUOTE; | ||||
13 | |||||
14 | |||||
15 | # spent 522µs (94+428) within Text::ParseWords::shellwords which was called 3 times, avg 174µs/call:
# 3 times (94µs+428µs) by CPAN::shell at line 367 of CPAN.pm, avg 174µs/call | ||||
16 | 3 | 9µs | my (@lines) = @_; | ||
17 | 3 | 1µs | my @allwords; | ||
18 | |||||
19 | 3 | 8µs | foreach my $line (@lines) { | ||
20 | 3 | 32µs | 3 | 9µs | $line =~ s/^\s+//; # spent 9µs making 3 calls to Text::ParseWords::CORE:subst, avg 3µs/call |
21 | 3 | 18µs | 3 | 419µs | my @words = parse_line('\s+', 0, $line); # spent 419µs making 3 calls to Text::ParseWords::parse_line, avg 140µs/call |
22 | 3 | 5µs | pop @words if (@words and !defined $words[-1]); | ||
23 | 3 | 1µs | return() unless (@words || !length($line)); | ||
24 | 3 | 7µs | push(@allwords, @words); | ||
25 | } | ||||
26 | 3 | 11µs | return(@allwords); | ||
27 | } | ||||
28 | |||||
- - | |||||
31 | sub quotewords { | ||||
32 | my($delim, $keep, @lines) = @_; | ||||
33 | my($line, @words, @allwords); | ||||
34 | |||||
35 | foreach $line (@lines) { | ||||
36 | @words = parse_line($delim, $keep, $line); | ||||
37 | return() unless (@words || !length($line)); | ||||
38 | push(@allwords, @words); | ||||
39 | } | ||||
40 | return(@allwords); | ||||
41 | } | ||||
42 | |||||
- - | |||||
45 | sub nested_quotewords { | ||||
46 | my($delim, $keep, @lines) = @_; | ||||
47 | my($i, @allwords); | ||||
48 | |||||
49 | for ($i = 0; $i < @lines; $i++) { | ||||
50 | @{$allwords[$i]} = parse_line($delim, $keep, $lines[$i]); | ||||
51 | return() unless (@{$allwords[$i]} || !length($lines[$i])); | ||||
52 | } | ||||
53 | return(@allwords); | ||||
54 | } | ||||
55 | |||||
- - | |||||
58 | # spent 419µs (210+209) within Text::ParseWords::parse_line which was called 3 times, avg 140µs/call:
# 3 times (210µs+209µs) by Text::ParseWords::shellwords at line 21, avg 140µs/call | ||||
59 | 3 | 7µs | my($delimiter, $keep, $line) = @_; | ||
60 | 3 | 2µs | my($word, @pieces); | ||
61 | |||||
62 | no warnings 'uninitialized'; # we will be testing undef strings | ||||
63 | |||||
64 | 3 | 3µs | while (length($line)) { | ||
65 | # This pattern is optimised to be stack conservative on older perls. | ||||
66 | # Do not refactor without being careful and testing it on very long strings. | ||||
67 | # See Perl bug #42980 for an example of a stack busting input. | ||||
68 | 6 | 254µs | 12 | 202µs | $line =~ s/^ # spent 147µs making 6 calls to Text::ParseWords::CORE:regcomp, avg 24µs/call
# spent 55µs making 6 calls to Text::ParseWords::CORE:subst, avg 9µs/call |
69 | (?: | ||||
70 | # double quoted string | ||||
71 | (") # $quote | ||||
72 | ((?>[^\\"]*(?:\\.[^\\"]*)*))" # $quoted | ||||
73 | | # --OR-- | ||||
74 | # singe quoted string | ||||
75 | (') # $quote | ||||
76 | ((?>[^\\']*(?:\\.[^\\']*)*))' # $quoted | ||||
77 | | # --OR-- | ||||
78 | # unquoted string | ||||
79 | ( # $unquoted | ||||
80 | (?:\\.|[^\\"'])*? | ||||
81 | ) | ||||
82 | # followed by | ||||
83 | ( # $delim | ||||
84 | \Z(?!\n) # EOL | ||||
85 | | # --OR-- | ||||
86 | (?-x:$delimiter) # delimiter | ||||
87 | | # --OR-- | ||||
88 | (?!^)(?=["']) # a quote | ||||
89 | ) | ||||
90 | )//xs or return; # extended layout | ||||
91 | 6 | 38µs | my ($quote, $quoted, $unquoted, $delim) = (($1 ? ($1,$2) : ($3,$4)), $5, $6); | ||
92 | |||||
93 | |||||
94 | 6 | 6µs | return() unless( defined($quote) || length($unquoted) || length($delim)); | ||
95 | |||||
96 | 6 | 2µs | if ($keep) { | ||
97 | $quoted = "$quote$quoted$quote"; | ||||
98 | } | ||||
99 | else { | ||||
100 | 6 | 22µs | 6 | 7µs | $unquoted =~ s/\\(.)/$1/sg; # spent 7µs making 6 calls to Text::ParseWords::CORE:subst, avg 1µs/call |
101 | 6 | 3µs | if (defined $quote) { | ||
102 | $quoted =~ s/\\(.)/$1/sg if ($quote eq '"'); | ||||
103 | $quoted =~ s/\\([\\'])/$1/g if ( $PERL_SINGLE_QUOTE && $quote eq "'"); | ||||
104 | } | ||||
105 | } | ||||
106 | 6 | 12µs | $word .= substr($line, 0, 0); # leave results tainted | ||
107 | 6 | 6µs | $word .= defined $quote ? $quoted : $unquoted; | ||
108 | |||||
109 | 6 | 3µs | if (length($delim)) { | ||
110 | 3 | 6µs | push(@pieces, $word); | ||
111 | 3 | 5µs | push(@pieces, $delim) if ($keep eq 'delimiters'); | ||
112 | 3 | 2µs | undef $word; | ||
113 | } | ||||
114 | 6 | 28µs | if (!length($line)) { | ||
115 | push(@pieces, $word); | ||||
116 | } | ||||
117 | } | ||||
118 | 3 | 17µs | return(@pieces); | ||
119 | } | ||||
120 | |||||
- - | |||||
123 | sub old_shellwords { | ||||
124 | |||||
125 | # Usage: | ||||
126 | # use ParseWords; | ||||
127 | # @words = old_shellwords($line); | ||||
128 | # or | ||||
129 | # @words = old_shellwords(@lines); | ||||
130 | # or | ||||
131 | # @words = old_shellwords(); # defaults to $_ (and clobbers it) | ||||
132 | |||||
133 | no warnings 'uninitialized'; # we will be testing undef strings | ||||
134 | local *_ = \join('', @_) if @_; | ||||
135 | my (@words, $snippet); | ||||
136 | |||||
137 | s/\A\s+//; | ||||
138 | while ($_ ne '') { | ||||
139 | my $field = substr($_, 0, 0); # leave results tainted | ||||
140 | for (;;) { | ||||
141 | if (s/\A"(([^"\\]|\\.)*)"//s) { | ||||
142 | ($snippet = $1) =~ s#\\(.)#$1#sg; | ||||
143 | } | ||||
144 | elsif (/\A"/) { | ||||
145 | require Carp; | ||||
146 | Carp::carp("Unmatched double quote: $_"); | ||||
147 | return(); | ||||
148 | } | ||||
149 | elsif (s/\A'(([^'\\]|\\.)*)'//s) { | ||||
150 | ($snippet = $1) =~ s#\\(.)#$1#sg; | ||||
151 | } | ||||
152 | elsif (/\A'/) { | ||||
153 | require Carp; | ||||
154 | Carp::carp("Unmatched single quote: $_"); | ||||
155 | return(); | ||||
156 | } | ||||
157 | elsif (s/\A\\(.?)//s) { | ||||
158 | $snippet = $1; | ||||
159 | } | ||||
160 | elsif (s/\A([^\s\\'"]+)//) { | ||||
161 | $snippet = $1; | ||||
162 | } | ||||
163 | else { | ||||
164 | s/\A\s+//; | ||||
165 | last; | ||||
166 | } | ||||
167 | $field .= $snippet; | ||||
168 | } | ||||
169 | push(@words, $field); | ||||
170 | } | ||||
171 | return @words; | ||||
172 | } | ||||
173 | |||||
174 | 1; | ||||
175 | |||||
176 | __END__ | ||||
# spent 147µs within Text::ParseWords::CORE:regcomp which was called 6 times, avg 24µs/call:
# 6 times (147µs+0s) by Text::ParseWords::parse_line at line 68, avg 24µs/call | |||||
# spent 71µs within Text::ParseWords::CORE:subst which was called 15 times, avg 5µs/call:
# 6 times (55µs+0s) by Text::ParseWords::parse_line at line 68, avg 9µs/call
# 6 times (7µs+0s) by Text::ParseWords::parse_line at line 100, avg 1µs/call
# 3 times (9µs+0s) by Text::ParseWords::shellwords at line 20, avg 3µs/call |