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