| Filename | C:/tmp64ng/perl/lib/Text/ParseWords.pm | 
| Statements | Executed 999 statements in 15.6ms | 
| Calls | P | F | Exclusive Time  | 
        Inclusive Time  | 
        Subroutine | 
|---|---|---|---|---|---|
| 144 | 2 | 1 | 15.6ms | 15.6ms | Text::ParseWords::CORE:subst (opcode) | 
| 1 | 1 | 1 | 0s | 0s | Text::ParseWords::BEGIN@133 | 
| 1 | 1 | 1 | 0s | 0s | Text::ParseWords::BEGIN@3 | 
| 1 | 1 | 1 | 0s | 0s | Text::ParseWords::BEGIN@62 | 
| 1 | 1 | 1 | 0s | 0s | Text::ParseWords::BEGIN@8 | 
| 72 | 1 | 1 | 0s | 0s | Text::ParseWords::CORE:regcomp (opcode) | 
| 0 | 0 | 0 | 0s | 0s | Text::ParseWords::nested_quotewords | 
| 0 | 0 | 0 | 0s | 0s | Text::ParseWords::old_shellwords | 
| 6 | 1 | 1 | 0s | 15.6ms | Text::ParseWords::parse_line | 
| 6 | 2 | 1 | 0s | 15.6ms | Text::ParseWords::quotewords | 
| 0 | 0 | 0 | 0s | 0s | Text::ParseWords::shellwords | 
| Line | State ments  | 
      Time on line  | 
      Calls | Time in subs  | 
      Code | 
|---|---|---|---|---|---|
| 1 | package Text::ParseWords; | ||||
| 2 | |||||
| 3 | 2 | 0s | 2 | 0s | # spent 0s within Text::ParseWords::BEGIN@3 which was called:
#    once (0s+0s) by ExtUtils::Liblist::Kid::_win32_ext at line 3 # spent     0s making 1 call to Text::ParseWords::BEGIN@3
# spent     0s making 1 call to strict::import  | 
| 4 | 1 | 0s | require 5.006; | ||
| 5 | 1 | 0s | our $VERSION = "3.29"; | ||
| 6 | |||||
| 7 | |||||
| 8 | 2 | 0s | 2 | 0s | # spent 0s within Text::ParseWords::BEGIN@8 which was called:
#    once (0s+0s) by ExtUtils::Liblist::Kid::_win32_ext at line 8 # spent     0s making 1 call to Exporter::import
# spent     0s making 1 call to Text::ParseWords::BEGIN@8  | 
| 9 | 1 | 0s | our @ISA = qw(Exporter); | ||
| 10 | 1 | 0s | our @EXPORT = qw(shellwords quotewords nested_quotewords parse_line); | ||
| 11 | 1 | 0s | our @EXPORT_OK = qw(old_shellwords); | ||
| 12 | 1 | 0s | our $PERL_SINGLE_QUOTE; | ||
| 13 | |||||
| 14 | |||||
| 15 | sub shellwords { | ||||
| 16 | my (@lines) = @_; | ||||
| 17 | my @allwords; | ||||
| 18 | |||||
| 19 | foreach my $line (@lines) { | ||||
| 20 | $line =~ s/^\s+//; | ||||
| 21 | my @words = parse_line('\s+', 0, $line); | ||||
| 22 | pop @words if (@words and !defined $words[-1]); | ||||
| 23 | return() unless (@words || !length($line)); | ||||
| 24 | push(@allwords, @words); | ||||
| 25 | } | ||||
| 26 | return(@allwords); | ||||
| 27 | } | ||||
| 28 | |||||
| - - | |||||
| 31 | # spent 15.6ms (0s+15.6) within Text::ParseWords::quotewords which was called 6 times, avg 2.60ms/call:
# 3 times (0s+15.6ms) by ExtUtils::Liblist::Kid::_win32_default_search_paths at line 382 of ExtUtils/Liblist/Kid.pm, avg 5.20ms/call
# 3 times (0s+0s) by ExtUtils::Liblist::Kid::_win32_make_lib_search_list at line 371 of ExtUtils/Liblist/Kid.pm, avg 0s/call  | ||||
| 32 | 6 | 0s | my($delim, $keep, @lines) = @_; | ||
| 33 | 6 | 0s | my($line, @words, @allwords); | ||
| 34 | |||||
| 35 | 6 | 0s | foreach $line (@lines) { | ||
| 36 | 6 | 0s | 6 | 15.6ms |         @words = parse_line($delim, $keep, $line);         # spent  15.6ms making 6 calls to Text::ParseWords::parse_line, avg 2.60ms/call  | 
| 37 | 6 | 0s | return() unless (@words || !length($line)); | ||
| 38 | 6 | 0s | push(@allwords, @words); | ||
| 39 | } | ||||
| 40 | 6 | 0s | 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 15.6ms (0s+15.6) within Text::ParseWords::parse_line which was called 6 times, avg 2.60ms/call:
# 6 times (0s+15.6ms) by Text::ParseWords::quotewords at line 36, avg 2.60ms/call  | ||||
| 59 | 6 | 0s | my($delimiter, $keep, $line) = @_; | ||
| 60 | 6 | 0s | my($word, @pieces); | ||
| 61 | |||||
| 62 | 2 | 0s | 2 | 0s | # spent 0s within Text::ParseWords::BEGIN@62 which was called:
#    once (0s+0s) by ExtUtils::Liblist::Kid::_win32_ext at line 62     # spent     0s making 1 call to Text::ParseWords::BEGIN@62
    # spent     0s making 1 call to warnings::unimport  | 
| 63 | |||||
| 64 | 6 | 0s | 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 | 72 | 15.6ms | 144 | 15.6ms |         $line =~ s/^         # spent  15.6ms making 72 calls to Text::ParseWords::CORE:subst, avg 217µs/call
        # spent     0s making 72 calls to Text::ParseWords::CORE:regcomp, avg 0s/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 | 72 | 0s | my ($quote, $quoted, $unquoted, $delim) = (($1 ? ($1,$2) : ($3,$4)), $5, $6); | ||
| 92 | |||||
| 93 | |||||
| 94 | 72 | 0s | return() unless( defined($quote) || length($unquoted) || length($delim)); | ||
| 95 | |||||
| 96 | 72 | 0s | if ($keep) { | ||
| 97 | $quoted = "$quote$quoted$quote"; | ||||
| 98 | } | ||||
| 99 | else { | ||||
| 100 | 72 | 0s | 72 | 0s |             $unquoted =~ s/\\(.)/$1/sg;             # spent     0s making 72 calls to Text::ParseWords::CORE:subst, avg 0s/call  | 
| 101 | 72 | 0s | 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 | 72 | 0s | $word .= substr($line, 0, 0); # leave results tainted | ||
| 107 | 72 | 0s | $word .= defined $quote ? $quoted : $unquoted; | ||
| 108 | |||||
| 109 | 72 | 0s | if (length($delim)) { | ||
| 110 | 66 | 0s | push(@pieces, $word); | ||
| 111 | 66 | 0s | push(@pieces, $delim) if ($keep eq 'delimiters'); | ||
| 112 | 66 | 0s | undef $word; | ||
| 113 | } | ||||
| 114 | 72 | 0s | if (!length($line)) { | ||
| 115 | push(@pieces, $word); | ||||
| 116 | } | ||||
| 117 | } | ||||
| 118 | 6 | 0s | 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 | 2 | 0s | 2 | 0s | # spent 0s within Text::ParseWords::BEGIN@133 which was called:
#    once (0s+0s) by ExtUtils::Liblist::Kid::_win32_ext at line 133     # spent     0s making 1 call to Text::ParseWords::BEGIN@133
    # spent     0s making 1 call to warnings::unimport  | 
| 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 | 0s | 1; | ||
| 175 | |||||
| 176 | __END__ | ||||
# spent 0s within Text::ParseWords::CORE:regcomp which was called 72 times, avg 0s/call:
# 72 times (0s+0s) by Text::ParseWords::parse_line at line 68, avg 0s/call  | |||||
sub Text::ParseWords::CORE:subst; # opcode  |