line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
package Data::VString; |
3
|
|
|
|
|
|
|
|
4
|
4
|
|
|
4
|
|
105208
|
use 5.008; |
|
4
|
|
|
|
|
16
|
|
|
4
|
|
|
|
|
254
|
|
5
|
4
|
|
|
4
|
|
24
|
use strict; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
144
|
|
6
|
4
|
|
|
4
|
|
23
|
use warnings; |
|
4
|
|
|
|
|
14
|
|
|
4
|
|
|
|
|
408
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
require Exporter; |
9
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
10
|
|
|
|
|
|
|
our @EXPORT_OK = qw( |
11
|
|
|
|
|
|
|
parse_vstring |
12
|
|
|
|
|
|
|
format_vstring |
13
|
|
|
|
|
|
|
vstring_satisfy |
14
|
|
|
|
|
|
|
vstring_cmp |
15
|
|
|
|
|
|
|
); |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our $VERSION = '0.000004'; # '0.0.4' |
18
|
|
|
|
|
|
|
|
19
|
4
|
|
|
4
|
|
25
|
use Carp qw(carp); |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
6355
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
#use encoding 'utf8'; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 NAME |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
Data::VString - Perl extension to handle v-strings (often used as version strings) |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 SYNOPSIS |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
use Data::VString qw(parse_vstring format_vstring vstring_cmp vstring_satisfy); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# going from '0.0.1' to "\x{0}\x{0}\x{1}" and back |
32
|
|
|
|
|
|
|
$i_vstring = parse_vstring($vstring); |
33
|
|
|
|
|
|
|
$vstring = format_vstring($i_vstring); |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
print 'ok' if vstring_cmp($VERSION, '>=', '0.0.1'); |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
my $bool = vstring_satisfy($vstring, $predicate) |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=head1 DESCRIPTION |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
Most of the time, the so-called version numbers |
42
|
|
|
|
|
|
|
are not really numbers, but tuples of integers |
43
|
|
|
|
|
|
|
like C<'0.2.3'>. With this concept of version, |
44
|
|
|
|
|
|
|
C<'0.1'> is the same as C<'0.01'>. The ordering of |
45
|
|
|
|
|
|
|
such tuples is usually defined by comparing each |
46
|
|
|
|
|
|
|
part. And that makes |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
'0.1' < '0.2' |
49
|
|
|
|
|
|
|
'0.2.1' > '0.1.3' |
50
|
|
|
|
|
|
|
'0.11.10' > '0.10.10.10' |
51
|
|
|
|
|
|
|
'10.0.0' > '9.9.9' # notice that '10.0.0' gt '9.9.9' is false |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
and also C<'0.1'> < C<'0.1.0'> (because the first one is shorter). |
54
|
|
|
|
|
|
|
There is also no need to define how many integers to accept |
55
|
|
|
|
|
|
|
in the tuple, with C<'0.0.1.2.34.4.580.20'> being |
56
|
|
|
|
|
|
|
a nice version. |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
Perl had (and still has) this concept as v-strings. |
59
|
|
|
|
|
|
|
They had even deserved a syntax on their own: |
60
|
|
|
|
|
|
|
C or C<100.111.1111> (a literal |
61
|
|
|
|
|
|
|
with two or more dots). But their fate is sealed: |
62
|
|
|
|
|
|
|
in L of 5.8 we read: |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
Note: Version Strings (v-strings) have been deprecated. |
65
|
|
|
|
|
|
|
They will not be available after Perl 5.8. The marginal |
66
|
|
|
|
|
|
|
benefits of v-strings were greatly outweighed by the |
67
|
|
|
|
|
|
|
potential for Surprise and Confusion. |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
This module revives them as a simple module implementation. |
70
|
|
|
|
|
|
|
Version strings are well suited in many version "numbering" |
71
|
|
|
|
|
|
|
schemes and straightforward (if you always remember they |
72
|
|
|
|
|
|
|
are not numbers). In Perl, most of the confusion |
73
|
|
|
|
|
|
|
lies in that C<0.1> as a literal is a number and sorts |
74
|
|
|
|
|
|
|
like a number, while C<0.1.0> is a v-string and sorts |
75
|
|
|
|
|
|
|
like a v-string. Also from L: |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
A literal of the form "v1.20.300.4000" is parsed as a string composed |
78
|
|
|
|
|
|
|
of characters with the specified ordinals. This form, known as |
79
|
|
|
|
|
|
|
v-strings, provides an alternative, more readable way to construct |
80
|
|
|
|
|
|
|
strings, rather than use the somewhat less readable interpolation form |
81
|
|
|
|
|
|
|
"\x{1}\x{14}\x{12c}\x{fa0}". This is useful for representing Unicode |
82
|
|
|
|
|
|
|
strings, and for comparing version "numbers" using the string compari- |
83
|
|
|
|
|
|
|
son operators, "cmp", "gt", "lt" etc. If there are two or more dots in |
84
|
|
|
|
|
|
|
the literal, the leading "v" may be omitted. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
print v9786; # prints UTF-8 encoded SMILEY, "\x{263a}" |
87
|
|
|
|
|
|
|
print v102.111.111; # prints "foo" |
88
|
|
|
|
|
|
|
print 102.111.111; # same |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
This text reveals how this notion of version as tuple |
91
|
|
|
|
|
|
|
of integers can be represented efficiently if one |
92
|
|
|
|
|
|
|
agreeds that each part is limited to 16 bits (0-65565), |
93
|
|
|
|
|
|
|
which is more than enough for practical software |
94
|
|
|
|
|
|
|
versioning schemes. Converting each part to a Unicode |
95
|
|
|
|
|
|
|
character, the version string ends up like a Unicode |
96
|
|
|
|
|
|
|
string which can be compared with the usual string |
97
|
|
|
|
|
|
|
comparators. |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
Here, functions are provided for converting between v-strings |
100
|
|
|
|
|
|
|
(like C<'6.2.28'>) and their internal representation |
101
|
|
|
|
|
|
|
(C<"\x{6}\x{2}\x{1C}">) and to test them against other |
102
|
|
|
|
|
|
|
v-strings. |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=over 4 |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=item B |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
$i_vstring = parse_vstring($vstring); |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
parse_vstring('0.1.2') # return "\x{0}\x{1}\x{2}" |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
Converts a v-string into its internal representation |
114
|
|
|
|
|
|
|
(the string made up the Unicode characters given |
115
|
|
|
|
|
|
|
by the ordinals specified in v-string parts). |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
The syntax of a v-string can be defined by the |
118
|
|
|
|
|
|
|
following syntax rule (in C style) |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
: /\d+/ ( /[._]/ /\d+/ )* |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
For the reverse operation, see C. |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=cut |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub _is_vstring { |
127
|
40
|
|
|
40
|
|
269
|
return shift =~ /^\d+([._]\d+)*$/; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
sub parse_vstring { |
131
|
40
|
|
|
40
|
1
|
94
|
my $vs = shift; |
132
|
40
|
100
|
66
|
|
|
128
|
return undef unless defined $vs && _is_vstring($vs); |
133
|
|
|
|
|
|
|
#no warnings 'utf8'; # every 16-bit value is ok |
134
|
38
|
|
|
|
|
149
|
$vs =~ s/[._]?(\d+)/chr($1 & 0x0FFFF)/eg; |
|
62
|
|
|
|
|
178
|
|
135
|
38
|
|
|
|
|
109
|
return $vs |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=item B |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
$vstring = format_vstring($i_vstring) |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
Converts the internal representation of a v-string |
143
|
|
|
|
|
|
|
into a readable v-string. It does the reverse |
144
|
|
|
|
|
|
|
operation of C. |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=cut |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
sub format_vstring { |
149
|
3
|
|
|
3
|
1
|
11
|
my $vs = shift; |
150
|
3
|
50
|
|
|
|
10
|
return $vs unless $vs; # take care of '' |
151
|
|
|
|
|
|
|
#no warnings 'utf8'; # every 16-bit value is ok |
152
|
3
|
|
|
|
|
22
|
$vs =~ s/(.)/ord($1)."."/eg; |
|
7
|
|
|
|
|
31
|
|
153
|
3
|
|
|
|
|
8
|
chop $vs; |
154
|
3
|
|
|
|
|
16
|
return $vs |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=item B |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
vstring_satisfy($vstring, $predicate); |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
vstring_satisfy('0.1.1', '0.1.1'); # true |
162
|
|
|
|
|
|
|
vstring_satisfy('0.1.1', '> 0, < 0.2, != 0.1.0'); # true |
163
|
|
|
|
|
|
|
vstring_satisfy('0.2.4', '0.2.5..0.3.4'); # false |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
Determines if a v-string satisfy a predicate. |
166
|
|
|
|
|
|
|
The predicate is a list of simple predicates, |
167
|
|
|
|
|
|
|
each one must be satisfied (that is, an I). |
168
|
|
|
|
|
|
|
Simple predicates takes one of three forms: |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
'0.1.2' - exact match |
171
|
|
|
|
|
|
|
'>= 3.14.15' - (relational operator) (v-string) |
172
|
|
|
|
|
|
|
'5.6 .. 10.8' - meaning '>= 5.6, <= 10.8' |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
A grammar for predicates in L-like syntax |
175
|
|
|
|
|
|
|
is: |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
: (',' )* |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
: # the same as '==' |
180
|
|
|
|
|
|
|
| |
181
|
|
|
|
|
|
|
| '..' # the same as ">= , <= " |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
: '==' | '!=' | '<=' | '>=' | '<' | '>' |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
Spaces are irrelevant in predicates. |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=cut |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
sub vstring_satisfy { |
190
|
7
|
|
|
7
|
1
|
14
|
my $vs = shift; |
191
|
7
|
|
|
|
|
8
|
my $p = shift; |
192
|
7
|
|
|
|
|
24
|
$p =~ s/\s//g; # spaces are irrelevant |
193
|
7
|
|
|
|
|
21
|
my @p = split ',', $p; |
194
|
7
|
|
|
|
|
12
|
for (@p) { |
195
|
9
|
100
|
|
|
|
39
|
if (/^(\d+([._]\d+)*)$/) { |
196
|
3
|
100
|
|
|
|
7
|
next if _vstring_cmp($vs, '==', $1); |
197
|
1
|
|
|
|
|
17
|
return 0; |
198
|
|
|
|
|
|
|
} |
199
|
6
|
100
|
|
|
|
25
|
if (/^([=!<>]=|[<>])(\d+([._]\d+)*)$/) { |
200
|
4
|
50
|
|
|
|
9
|
next if _vstring_cmp($vs, $1, $2); |
201
|
0
|
|
|
|
|
0
|
return 0; |
202
|
|
|
|
|
|
|
} |
203
|
2
|
50
|
|
|
|
14
|
if (/^(\d+([._]\d+)*)\.\.(\d+([._]\d+)*)$/) { |
204
|
2
|
50
|
33
|
|
|
14
|
next if _vstring_cmp($1, '<=', $vs) && |
205
|
|
|
|
|
|
|
_vstring_cmp($vs, '<=', $3); # !!! |
206
|
0
|
|
|
|
|
0
|
return 0; |
207
|
|
|
|
|
|
|
} |
208
|
0
|
0
|
|
|
|
0
|
carp "bad predicate $_" |
209
|
|
|
|
|
|
|
and return undef; |
210
|
|
|
|
|
|
|
} |
211
|
6
|
|
|
|
|
27
|
return 1; |
212
|
|
|
|
|
|
|
} |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
my %cmp = ( |
215
|
|
|
|
|
|
|
'==' => sub { shift eq shift }, |
216
|
|
|
|
|
|
|
'!=' => sub { shift ne shift }, |
217
|
|
|
|
|
|
|
'<=' => sub { shift le shift }, |
218
|
|
|
|
|
|
|
'>=' => sub { shift ge shift }, |
219
|
|
|
|
|
|
|
'<' => sub { shift lt shift }, |
220
|
|
|
|
|
|
|
'>' => sub { shift gt shift } |
221
|
|
|
|
|
|
|
); |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
#sub Dump_literal { |
224
|
|
|
|
|
|
|
# my $lit = shift; |
225
|
|
|
|
|
|
|
# use YAML; |
226
|
|
|
|
|
|
|
# my $y = YAML::Dump $lit; |
227
|
|
|
|
|
|
|
# $y =~ s/--- //; |
228
|
|
|
|
|
|
|
# $y =~ s/\n//g; |
229
|
|
|
|
|
|
|
# return $y |
230
|
|
|
|
|
|
|
#} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub _vstring_cmp { |
233
|
14
|
|
|
14
|
|
32
|
my $v1 = parse_vstring shift; |
234
|
14
|
|
|
|
|
20
|
my $op = shift; # op is one of '==', '!=', '<=', '>=', '<', '>' |
235
|
14
|
|
|
|
|
24
|
my $v2 = parse_vstring shift; |
236
|
|
|
|
|
|
|
#print "v1: ", Dump_literal($v1), |
237
|
|
|
|
|
|
|
# " op: ", $op, |
238
|
|
|
|
|
|
|
# " v2: ", Dump_literal($v2), "\n"; |
239
|
14
|
|
|
|
|
17
|
return &{$cmp{$op}}($v1, $v2); |
|
14
|
|
|
|
|
38
|
|
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
=item B |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
$ans = vstring_cmp($vs1, $op, $vs2) |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
$eq = vstring_cmp('0.1.02', '==', '0.01.2'); # ok |
247
|
|
|
|
|
|
|
$le = vstring_cmp('1.2.3', '>=', '3.2.1'); # not ok |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
Makes a comparison between two v-strings. The supported operators |
250
|
|
|
|
|
|
|
are '==', '!=', '<=', '>=', '<', and '>'. |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
=cut |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
sub vstring_cmp { |
255
|
3
|
|
|
3
|
1
|
19
|
my $v1 = parse_vstring shift; |
256
|
3
|
50
|
|
|
|
12
|
return undef unless $v1; |
257
|
3
|
|
|
|
|
6
|
my $op = shift; |
258
|
3
|
50
|
|
|
|
12
|
unless (exists $cmp{$op}) { |
259
|
0
|
|
|
|
|
0
|
carp "vstring_cmp: unknown op '$op'"; |
260
|
|
|
|
|
|
|
return undef |
261
|
0
|
|
|
|
|
0
|
} |
262
|
3
|
|
|
|
|
6
|
my $v2 = parse_vstring shift; |
263
|
3
|
50
|
|
|
|
8
|
return undef unless $v2; |
264
|
3
|
|
|
|
|
6
|
return &{$cmp{$op}}($v1, $v2); |
|
3
|
|
|
|
|
111
|
|
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
=back |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=head2 EXPORT |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
None by default. C, C, |
273
|
|
|
|
|
|
|
C, and C can be exported on demand. |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=begin comment |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
Rewrite this section (DESCRIPTION) and move citations of |
278
|
|
|
|
|
|
|
perldata to a new section (HISTORY), making the documentation |
279
|
|
|
|
|
|
|
less centered in Perl documentation. |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
Document also the use of '_' as version part separator. |
282
|
|
|
|
|
|
|
(A usual convention used in CPAN is that when a version |
283
|
|
|
|
|
|
|
string contains '_', it is meant to be a developer's version). |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
Remember also the syntactical confusion that 'v65' is not |
286
|
|
|
|
|
|
|
a v-string in a the right hand of C<< '=>' >>. |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
Include a link to the JSAN library when it is released. |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
Document the behavior on error of the functions of the module. |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=end comment |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=cut |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=head1 SEE ALSO |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
L |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
L by John Peacock. That module is older and more famous. |
302
|
|
|
|
|
|
|
The main differences are: |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
=over 4 |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=item * |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
C is OO, this module is a bunch of functions |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=item * |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
C does not represents version as Unicode strings |
313
|
|
|
|
|
|
|
as we do (well, I think so after a quick glance of the code) |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=item * |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
C is much more tolerant with numeric versions. |
318
|
|
|
|
|
|
|
This module is not concerned with backward compatibility. |
319
|
|
|
|
|
|
|
Use it versions as strings from the beginning, |
320
|
|
|
|
|
|
|
stay out of trouble with numeric versions. |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=item * |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
C is also more tolerant with non-numeric versions. |
325
|
|
|
|
|
|
|
On the contrary, C is very strict about |
326
|
|
|
|
|
|
|
syntax. |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=item * |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
we don't dare to redefine C. |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=item * |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
v-strings are treated as data here and no attempt |
335
|
|
|
|
|
|
|
to force semantics as Perl module version was made. |
336
|
|
|
|
|
|
|
Indeed I started coding this module for |
337
|
|
|
|
|
|
|
handling JSAN distributions (which are data from |
338
|
|
|
|
|
|
|
the point of view of the Perl program). |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
=back |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
This module is a companion for the JSAN module |
343
|
|
|
|
|
|
|
C. This one implements the Perl side |
344
|
|
|
|
|
|
|
while the other will implement the JavaScript side. |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=head1 BUGS |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
There must be some. Because all trivial software |
349
|
|
|
|
|
|
|
must have at least one bug. This is the actual |
350
|
|
|
|
|
|
|
list of known bugs. |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=over 4 |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
=item * |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
There is a bug with certain version parts which are |
357
|
|
|
|
|
|
|
illegal Unicode characters. So the full range |
358
|
|
|
|
|
|
|
(0..65535) is not actually usable. |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
=back |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
Please report bugs via CPAN RT L. |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
=head1 AUTHOR |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
Adriano R. Ferreira, Eferreira@cpan.orgE |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
Copyright (C) 2005, 2007 by Adriano R. Ferreira |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
373
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=cut |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
1; |
379
|
|
|
|
|
|
|
|