File Coverage

blib/lib/MP3/Tag/ParseData.pm
Criterion Covered Total %
statement 75 79 94.9
branch 31 50 62.0
condition 17 33 51.5
subroutine 7 8 87.5
pod 0 3 0.0
total 130 173 75.1


line stmt bran cond sub pod time code
1             package MP3::Tag::ParseData;
2              
3 6     6   20 use strict;
  6         6  
  6         144  
4 6     6   18 use vars qw /$VERSION @ISA/;
  6         4  
  6         5512  
5              
6             $VERSION="1.00";
7             @ISA = 'MP3::Tag::__hasparent';
8              
9             =pod
10              
11             =head1 NAME
12              
13             MP3::Tag::ParseData - Module for parsing arbitrary data associated with music files.
14              
15             =head1 SYNOPSIS
16              
17             # parses the file name according to one of the patterns:
18             $mp3->config('parse_data', ['i', '%f', '%t - %n - %a.%e', '%t - %y.%e']);
19             $title = $mp3->title;
20              
21             see L
22              
23             =head1 DESCRIPTION
24              
25             MP3::Tag::ParseData is designed to be called from the MP3::Tag module.
26              
27             Each option of configuration item C should be of the form
28             C<[$flag, $string, $pattern1, ...]>. For each of the option, patterns of
29             the option are matched agains the $string of the option, until one of them
30             succeeds. The information obtained from later options takes precedence over
31             the information obtained from earlier ones.
32              
33             The meaning of the patterns is the same as for parse() or parse_rex() methods
34             of C. Since the default for C is empty, by default this
35             handler has no effect.
36              
37             $flag is split into 1-character-long flags (unknown flags are ignored):
38              
39             =over
40              
41             =item C
42              
43             the string-to-parse is interpolated first;
44              
45             =item C
46              
47             the string-to-parse is interpreted as the name of the file to read;
48              
49             =item C
50              
51             added to C, makes it non-fatal if the file does not exist;
52              
53             =item C
54              
55             the file should be read in C mode;
56              
57             =item C
58              
59             the string-to-parse is interpreted as collection of lines, one per track;
60              
61             =item C
62              
63             the string-to-parse is interpreted as collection of lines, and the first
64             matched is chosen;
65              
66             =item C
67              
68             the resulting string is interpolated before parsing.
69              
70             =item C
71              
72             Do not strip the leading and trailing blanks. (With output to file,
73             the output is performed in binary mode too.)
74              
75             =item C
76              
77             the patterns are considered as regular expressions.
78              
79             =item C
80              
81             one of the patterns must match.
82              
83             =item C, C, C
84              
85             With C or C interpret the pattern as a name of file to output
86             parse-data to. With C the name of output file is interpolated.
87             When C is present, intermediate directories are created.
88              
89             =item C
90              
91             Do not ignore a field even if the result is a 0-length string.
92              
93             =back
94              
95             Unless C option is given, the resulting values have starting and
96             trailing whitespace trimmed. (Actually, split()ing into lines is done
97             using the configuration item C; it defaults to C<"\n">.)
98              
99             If the configuration item C has multiple options, the $strings
100             which are interpolated will use information set by preceding options;
101             similarly, any interolated option may use information obtained by other
102             handlers - even if these handers are later in the pecking order than
103             C (which by default is the first handler). For
104             example, with
105              
106             ['i', '%t' => '%t (%y)'], ['i', '%t' => '%t - %c']
107              
108             and a local CDDB file which identifies title to C<'Merry old - another
109             interpretation (1905)'>, the first field will interpolate C<'%t'> into this
110             title, then will split it into the year and the rest. The second field will
111             split the rest into a title-proper and comment.
112              
113             Note that one can use fields of the form
114              
115             ['mz', 'This is a forced title' => '%t']
116              
117             to force particular values for parts of the MP3 tag.
118              
119             The usual methods C, C, C<album>, C<comment>, C<year>, C<track>, </td> </tr> <tr> <td class="h" > <a name="120">120</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> C<year> can be used to access the results of the parse. </td> </tr> <tr> <td class="h" > <a name="121">121</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="122">122</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> It is possible to set individual id3v2 frames; use %{TIT1} or </td> </tr> <tr> <td class="h" > <a name="123">123</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> some such. Setting to an empty string deletes the frame if config </td> </tr> <tr> <td class="h" > <a name="124">124</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> parameter C<id3v2_frame_empty_ok> is false (the default value). </td> </tr> <tr> <td class="h" > <a name="125">125</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> Setting ID3v2 frames uses the same translation rules as </td> </tr> <tr> <td class="h" > <a name="126">126</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> select_id3v2_frame_by_descr(). </td> </tr> <tr> <td class="h" > <a name="127">127</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="128">128</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head2 SEE ALSO </td> </tr> <tr> <td class="h" > <a name="129">129</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="130">130</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> The flags C<i f F B l m I b> are identical to flags of the method </td> </tr> <tr> <td class="h" > <a name="131">131</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> interpolate_with_flags() of MP3::Tag (see L<MP3::Tag/"interpolate_with_flags">). </td> </tr> <tr> <td class="h" > <a name="132">132</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> Essentially, the other flags (C<R m o O D z>) are applied to the result of </td> </tr> <tr> <td class="h" > <a name="133">133</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> calling the latter method. </td> </tr> <tr> <td class="h" > <a name="134">134</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="135">135</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="136">136</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="137">137</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="138">138</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # Constructor </td> </tr> <tr> <td class="h" > <a name="139">139</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="140">140</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub new_with_parent { </td> </tr> <tr> <td class="h" > <a name="141">141</a> </td> <td class="c3" > 86 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--subroutine.html#141-1"> 86 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--subroutine.html#141-1"> 0 </a> </td> <td > 109 </td> <td class="s"> my ($class, $filename, $parent) = @_; </td> </tr> <tr> <td class="h" > <a name="142">142</a> </td> <td class="c3" > 86 </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#142-1"> 100 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 270 </td> <td class="s"> $filename = $filename->filename if ref $filename; </td> </tr> <tr> <td class="h" > <a name="143">143</a> </td> <td class="c3" > 86 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 269 </td> <td class="s"> bless {filename => $filename, parent => $parent}, $class; </td> </tr> <tr> <td class="h" > <a name="144">144</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="145">145</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="146">146</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # Destructor </td> </tr> <tr> <td class="h" > <a name="147">147</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="148">148</a> </td> <td >   </td> <td >   </td> <td >   </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--subroutine.html#148-1"> 0 </a> </td> <td >   </td> <td >   </td> <td class="s"> sub DESTROY {} </td> </tr> <tr> <td class="h" > <a name="149">149</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="150">150</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub parse_one { </td> </tr> <tr> <td class="h" > <a name="151">151</a> </td> <td class="c3" > 31 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--subroutine.html#151-1"> 31 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--subroutine.html#151-1"> 0 </a> </td> <td > 31 </td> <td class="s"> my ($self, $in) = @_; </td> </tr> <tr> <td class="h" > <a name="152">152</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="153">153</a> </td> <td class="c3" > 31 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 48 </td> <td class="s"> my @patterns = @$in; # Apply shift to a copy, not original... </td> </tr> <tr> <td class="h" > <a name="154">154</a> </td> <td class="c3" > 31 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 30 </td> <td class="s"> my $flags = shift @patterns; </td> </tr> <tr> <td class="h" > <a name="155">155</a> </td> <td class="c3" > 31 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 29 </td> <td class="s"> my $data = shift @patterns; </td> </tr> <tr> <td class="h" > <a name="156">156</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="157">157</a> </td> <td class="c3" > 31 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 131 </td> <td class="s"> my @data = $self->{parent}->interpolate_with_flags($data, $flags); </td> </tr> <tr> <td class="h" > <a name="158">158</a> </td> <td class="c3" > 31 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 28 </td> <td class="s"> my $res; </td> </tr> <tr> <td class="h" > <a name="159">159</a> </td> <td class="c3" > 31 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 34 </td> <td class="s"> my @opatterns = @patterns; </td> </tr> <tr> <td class="h" > <a name="160">160</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="161">161</a> </td> <td class="c3" > 31 </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#161-1"> 100 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 58 </td> <td class="s"> if ($flags =~ /[oO]/) { </td> </tr> <tr> <td class="h" > <a name="162">162</a> </td> <td class="c3" > 1 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#162-1"> 50 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 20 </td> <td class="s"> @patterns = map $self->{parent}->interpolate($_), @patterns </td> </tr> <tr> <td class="h" > <a name="163">163</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> if $flags =~ /O/; </td> </tr> <tr> <td class="h" > <a name="164">164</a> </td> <td class="c3" > 1 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#164-1"> 50 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--condition.html#164-1"> 33 </a> </td> <td >   </td> <td >   </td> <td > 11 </td> <td class="s"> return unless length $data[0] or $flags =~ /z/; </td> </tr> <tr> <td class="h" > <a name="165">165</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 3 </td> <td class="s"> for my $file (@patterns) { </td> </tr> <tr> <td class="h" > <a name="166">166</a> </td> <td class="c3" > 1 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#166-1"> 50 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--condition.html#166-1"> 33 </a> </td> <td >   </td> <td >   </td> <td > 14 </td> <td class="s"> if ($flags =~ /D/ and $file =~ m,(.*)[/\\],s) { </td> </tr> <tr> <td class="h" > <a name="167">167</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 6 </td> <td class="s"> require File::Path; </td> </tr> <tr> <td class="h" > <a name="168">168</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 110 </td> <td class="s"> File::Path::mkpath($1); </td> </tr> <tr> <td class="h" > <a name="169">169</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="170">170</a> </td> <td class="c3" > 1 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#170-1"> 50 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 48 </td> <td class="s"> open OUT, "> $file" or die "open(`$file') for write: $!"; </td> </tr> <tr> <td class="h" > <a name="171">171</a> </td> <td class="c3" > 1 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#171-1"> 50 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 8 </td> <td class="s"> if ($flags =~ /b/) { </td> </tr> <tr> <td class="h" > <a name="172">172</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 2 </td> <td class="s"> binmode OUT; </td> </tr> <tr> <td class="h" > <a name="173">173</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } else { </td> </tr> <tr> <td class="h" > <a name="174">174</a> </td> <td class="c0" > <a href="#175"> 0 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 0 </td> <td class="s"> my $e; </td> </tr> <tr> <td class="h" > <a name="175">175</a> </td> <td class="c0" > <a href="#176"> 0 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#175-1"> 0 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--condition.html#175-1"> 0 </a> </td> <td >   </td> <td >   </td> <td > 0 </td> <td class="s"> if ($e = $self->get_config('encode_encoding_files') and $e->[0]) { </td> </tr> <tr> <td class="h" > <a name="176">176</a> </td> <td class="c0" > <a href="#241"> 0 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 0 </td> <td class="s"> eval "binmode OUT, ':encoding($e->[0])'"; # old binmode won't compile... </td> </tr> <tr> <td class="h" > <a name="177">177</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="178">178</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="179">179</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 5 </td> <td class="s"> local ($/, $,) = ('', ''); </td> </tr> <tr> <td class="h" > <a name="180">180</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 6 </td> <td class="s"> print OUT $data[0]; </td> </tr> <tr> <td class="h" > <a name="181">181</a> </td> <td class="c3" > 1 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#181-1"> 50 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 24 </td> <td class="s"> close OUT or die "close(`$file') for write: $!"; </td> </tr> <tr> <td class="h" > <a name="182">182</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="183">183</a> </td> <td class="c3" > 1 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 3 </td> <td class="s"> return; </td> </tr> <tr> <td class="h" > <a name="184">184</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="185">185</a> </td> <td class="c3" > 30 </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#185-1"> 100 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 42 </td> <td class="s"> if ($flags =~ /R/) { </td> </tr> <tr> <td class="h" > <a name="186">186</a> </td> <td class="c3" > 2 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 15 </td> <td class="s"> @patterns = map $self->{parent}->parse_rex_prepare($_), @patterns; </td> </tr> <tr> <td class="h" > <a name="187">187</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } else { </td> </tr> <tr> <td class="h" > <a name="188">188</a> </td> <td class="c3" > 28 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 111 </td> <td class="s"> @patterns = map $self->{parent}->parse_prepare($_), @patterns; </td> </tr> <tr> <td class="h" > <a name="189">189</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="190">190</a> </td> <td class="c3" > 30 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 45 </td> <td class="s"> for $data (@data) { </td> </tr> <tr> <td class="h" > <a name="191">191</a> </td> <td class="c3" > 30 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 19 </td> <td class="s"> my $pattern; </td> </tr> <tr> <td class="h" > <a name="192">192</a> </td> <td class="c3" > 30 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 30 </td> <td class="s"> for $pattern (@patterns) { </td> </tr> <tr> <td class="h" > <a name="193">193</a> </td> <td class="c3" > 30 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#193-1"> 50 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 121 </td> <td class="s"> last if $res = $self->{parent}->parse_rex_match($pattern, $data); </td> </tr> <tr> <td class="h" > <a name="194">194</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="195">195</a> </td> <td class="c3" > 30 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#195-1"> 50 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 52 </td> <td class="s"> last if $res; </td> </tr> <tr> <td class="h" > <a name="196">196</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="197">197</a> </td> <td class="c3" > 30 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 23 </td> <td class="s"> { local $" = "' `"; </td> </tr> <tr> <td class="h" > <a > </a> </td> <td class="c3" > 30 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 36 </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="198">198</a> </td> <td class="c3" > 30 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#198-1"> 50 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--condition.html#198-1"> 33 </a> </td> <td >   </td> <td >   </td> <td > 125 </td> <td class="s"> die "Pattern(s) `@opatterns' did not succeed vs `@data'" </td> </tr> <tr> <td class="h" > <a name="199">199</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> if $flags =~ /m/ and not $res; </td> </tr> <tr> <td class="h" > <a name="200">200</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="201">201</a> </td> <td class="c3" > 30 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 20 </td> <td class="s"> my $k; </td> </tr> <tr> <td class="h" > <a name="202">202</a> </td> <td class="c3" > 30 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 39 </td> <td class="s"> for $k (keys %$res) { </td> </tr> <tr> <td class="h" > <a name="203">203</a> </td> <td class="c3" > 34 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#203-1"> 50 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 60 </td> <td class="s"> unless ($flags =~ /b/) { </td> </tr> <tr> <td class="h" > <a name="204">204</a> </td> <td class="c3" > 34 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 45 </td> <td class="s"> $res->{$k} =~ s/^\s+//; </td> </tr> <tr> <td class="h" > <a name="205">205</a> </td> <td class="c3" > 34 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 49 </td> <td class="s"> $res->{$k} =~ s/\s+$//; </td> </tr> <tr> <td class="h" > <a name="206">206</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="207">207</a> </td> <td class="c3" > 34 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#207-1"> 50 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--condition.html#207-1"> 66 </a> </td> <td >   </td> <td >   </td> <td > 125 </td> <td class="s"> delete $res->{$k} unless length $res->{$k} or $flags =~ /z/; </td> </tr> <tr> <td class="h" > <a name="208">208</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="209">209</a> </td> <td class="c3" > 30 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#209-1"> 50 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--condition.html#209-1"> 33 </a> </td> <td >   </td> <td >   </td> <td > 105 </td> <td class="s"> return unless $res and keys %$res; </td> </tr> <tr> <td class="h" > <a name="210">210</a> </td> <td class="c3" > 30 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 72 </td> <td class="s"> return $res; </td> </tr> <tr> <td class="h" > <a name="211">211</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="212">212</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="213">213</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # XXX Two decisions: which entries can access results of which ones, </td> </tr> <tr> <td class="h" > <a name="214">214</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # and which entries overwrite which ones; the user can reverse one of them </td> </tr> <tr> <td class="h" > <a name="215">215</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # by sorting config('parse_data') in the opposite order; but not both. </td> </tr> <tr> <td class="h" > <a name="216">216</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # Only practice can show whether our choice is correct... How to customize? </td> </tr> <tr> <td class="h" > <a name="217">217</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="218">218</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub parse { # Later recipies can access results of earlier ones. </td> </tr> <tr> <td class="h" > <a name="219">219</a> </td> <td class="c3" > 282 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--subroutine.html#219-1"> 282 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--subroutine.html#219-1"> 0 </a> </td> <td > 254 </td> <td class="s"> my ($self,$what) = @_; </td> </tr> <tr> <td class="h" > <a name="220">220</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="221">221</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> return $self->{parsed}->{$what} # Recalculate during recursive calls </td> </tr> <tr> <td class="h" > <a name="222">222</a> </td> <td class="c3" > 282 </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#222-1"> 100 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--condition.html#222-1"> 66 </a> </td> <td >   </td> <td >   </td> <td > 857 </td> <td class="s"> if not $self->{parsing} and exists $self->{parsed}; # Do not recalc after finish </td> </tr> <tr> <td class="h" > <a name="223">223</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="224">224</a> </td> <td class="c3" > 234 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 401 </td> <td class="s"> my $data = $self->get_config('parse_data'); </td> </tr> <tr> <td class="h" > <a name="225">225</a> </td> <td class="c3" > 234 </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#225-1"> 100 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--condition.html#225-1"> 66 </a> </td> <td >   </td> <td >   </td> <td > 1252 </td> <td class="s"> return unless $data and @$data; </td> </tr> <tr> <td class="h" > <a name="226">226</a> </td> <td class="c3" > 24 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 27 </td> <td class="s"> my $parsing = $self->{parsing}; </td> </tr> <tr> <td class="h" > <a name="227">227</a> </td> <td class="c3" > 24 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 40 </td> <td class="s"> local $self->{parsing}; </td> </tr> <tr> <td class="h" > <a name="228">228</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="229">229</a> </td> <td class="c3" > 24 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 20 </td> <td class="s"> my (%res, $d, $c); </td> </tr> <tr> <td class="h" > <a name="230">230</a> </td> <td class="c3" > 24 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 35 </td> <td class="s"> for $d (@$data) { </td> </tr> <tr> <td class="h" > <a name="231">231</a> </td> <td class="c3" > 37 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 35 </td> <td class="s"> $c++; </td> </tr> <tr> <td class="h" > <a name="232">232</a> </td> <td class="c3" > 37 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 37 </td> <td class="s"> $self->{parsing} = $c; </td> </tr> <tr> <td class="h" > <a name="233">233</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # Protect against recursion: later $d can access results of earlier ones </td> </tr> <tr> <td class="h" > <a name="234">234</a> </td> <td class="c3" > 37 </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#234-1"> 100 </a> </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--condition.html#234-1"> 100 </a> </td> <td >   </td> <td >   </td> <td > 86 </td> <td class="s"> last if $parsing and $parsing <= $c; </td> </tr> <tr> <td class="h" > <a name="235">235</a> </td> <td class="c3" > 31 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 55 </td> <td class="s"> my $res = $self->parse_one($d); </td> </tr> <tr> <td class="h" > <a name="236">236</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # warn "Failure: [@$d]\n" unless $res; </td> </tr> <tr> <td class="h" > <a name="237">237</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # Set user-scratch space data immediately </td> </tr> <tr> <td class="h" > <a name="238">238</a> </td> <td class="c3" > 31 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 44 </td> <td class="s"> for my $k (keys %$res) { </td> </tr> <tr> <td class="h" > <a name="239">239</a> </td> <td class="c3" > 34 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#239-1"> 50 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 167 </td> <td class="s"> if ($k eq 'year') { # Do nothing </td> </tr> <tr> <td class="h" > <a > </a> </td> <td >   </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#-2"> 50 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a > </a> </td> <td >   </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#-3"> 100 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="240">240</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } elsif ($k =~ /^U(\d{1,2})$/) { </td> </tr> <tr> <td class="h" > <a name="241">241</a> </td> <td class="c0" > 0 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 0 </td> <td class="s"> $self->{parent}->set_user($1, delete $res->{$k}) </td> </tr> <tr> <td class="h" > <a name="242">242</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } elsif (0 and $k =~ /^\w{4}(\d{2,})?$/) { </td> </tr> <tr> <td class="h" > <a name="243">243</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> if (length $res->{$k} </td> </tr> <tr> <td class="h" > <a name="244">244</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> or $self->get_config('id3v2_frame_empty_ok')->[0]) { </td> </tr> <tr> <td class="h" > <a name="245">245</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> $self->{parent}->set_id3v2_frame($k, delete $res->{$k}) </td> </tr> <tr> <td class="h" > <a name="246">246</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } else { </td> </tr> <tr> <td class="h" > <a name="247">247</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> delete $res->{$k}; </td> </tr> <tr> <td class="h" > <a name="248">248</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> $self->{parent}->set_id3v2_frame($k); # delete </td> </tr> <tr> <td class="h" > <a name="249">249</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="250">250</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } elsif ($k =~ /^\w{4}(\d{2,}|(?:\(([^()]*(?:\([^()]+\)[^()]*)*)\))?(?:\[(\\.|[^]\\]*)\])?)$/) { </td> </tr> <tr> <td class="h" > <a name="251">251</a> </td> <td class="c3" > 20 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 27 </td> <td class="s"> my $r = delete $res->{$k}; </td> </tr> <tr> <td class="h" > <a name="252">252</a> </td> <td class="c3" > 20 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#252-1"> 50 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--condition.html#252-1"> 66 </a> </td> <td >   </td> <td >   </td> <td > 51 </td> <td class="s"> $r = undef unless length $r or $self->get_config('id3v2_frame_empty_ok')->[0]; </td> </tr> <tr> <td class="h" > <a name="253">253</a> </td> <td class="c3" > 20 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#253-1"> 50 </a> </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--condition.html#253-1"> 66 </a> </td> <td >   </td> <td >   </td> <td > 63 </td> <td class="s"> if (defined $r or $self->{parent}->_get_tag('ID3v2')) { </td> </tr> <tr> <td class="h" > <a name="254">254</a> </td> <td class="c3" > 20 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 72 </td> <td class="s"> $self->{parent}->select_id3v2_frame_by_descr($k, $r); </td> </tr> <tr> <td class="h" > <a name="255">255</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="256">256</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="257">257</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="258">258</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # later ones overwrite earlier </td> </tr> <tr> <td class="h" > <a name="259">259</a> </td> <td class="c3" > 31 </td> <td class="c0" > <a href="blib-lib-MP3-Tag-ParseData-pm--branch.html#259-1"> 50 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 119 </td> <td class="s"> %res = (%res, %$res) if $res; </td> </tr> <tr> <td class="h" > <a name="260">260</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="261">261</a> </td> <td class="c3" > 24 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 30 </td> <td class="s"> $self->{parsed} = \%res; </td> </tr> <tr> <td class="h" > <a name="262">262</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> # return unless keys %res; </td> </tr> <tr> <td class="h" > <a name="263">263</a> </td> <td class="c3" > 24 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 102 </td> <td class="s"> return $self->{parsed}->{$what}; </td> </tr> <tr> <td class="h" > <a name="264">264</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="265">265</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="266">266</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> for my $elt ( qw( title track artist album comment year genre ) ) { </td> </tr> <tr> <td class="h" > <a name="267">267</a> </td> <td class="c3" > 6 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--subroutine.html#267-1"> 6 </a> </td> <td >   </td> <td > 27 </td> <td class="s"> no strict 'refs'; </td> </tr> <tr> <td class="h" > <a > </a> </td> <td class="c3" > 6 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 6 </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a > </a> </td> <td class="c3" > 6 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 366 </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="268">268</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> *$elt = sub (;$) { </td> </tr> <tr> <td class="h" > <a name="269">269</a> </td> <td class="c3" > 282 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-MP3-Tag-ParseData-pm--subroutine.html#269-1"> 282 </a> </td> <td >   </td> <td > 230 </td> <td class="s"> my $self = shift; </td> </tr> <tr> <td class="h" > <a name="270">270</a> </td> <td class="c3" > 282 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 477 </td> <td class="s"> $self->parse($elt, @_); </td> </tr> <tr> <td class="h" > <a name="271">271</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="272">272</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="273">273</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="274">274</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> 1; </td> </tr> </table> </body> </html>