File Coverage

blib/lib/PPI/Token/Number/Version.pm
Criterion Covered Total %
statement 38 38 100.0
branch 16 18 88.8
condition 3 3 100.0
subroutine 5 5 100.0
pod 1 1 100.0
total 63 65 96.9


line stmt bran cond sub pod time code
1             package PPI::Token::Number::Version;
2              
3             =pod
4              
5             =head1 NAME
6              
7             PPI::Token::Number::Version - Token class for a byte-packed number
8              
9             =head1 SYNOPSIS
10              
11             $n = 1.1.0;
12             $n = 127.0.0.1;
13             $n = 10_000.10_000.10_000;
14             $n = v1.2.3.4
15              
16             =head1 INHERITANCE
17              
18             PPI::Token::Number::Version
19             isa PPI::Token::Number
20             isa PPI::Token
21             isa PPI::Element
22              
23             =head1 DESCRIPTION
24              
25             The C class is used for tokens that have
26             multiple decimal points. In truth, these aren't treated like numbers
27             at all by Perl, but they look like numbers to a parser.
28              
29             =head1 METHODS
30              
31             =cut
32              
33 65     65   365 use strict;
  65         122  
  65         1513  
34 65     65   270 use PPI::Token::Number ();
  65         129  
  65         33942  
35              
36             our $VERSION = '1.276';
37              
38             our @ISA = "PPI::Token::Number";
39              
40             =pod
41              
42             =head2 base
43              
44             Returns the base for the number: 256.
45              
46             =cut
47              
48             sub base() { 256 }
49              
50             =pod
51              
52             =head2 literal
53              
54             Return the numeric value of this token.
55              
56             =cut
57              
58             sub literal {
59 8     8 1 11 my $self = shift;
60 8         16 my $content = $self->{content};
61 8         19 $content =~ s/^v//;
62 8         26 return join '', map { chr $_ } ( split /\./, $content );
  26         88  
63             }
64              
65              
66              
67              
68              
69             #####################################################################
70             # Tokenizer Methods
71              
72             sub __TOKENIZER__on_char {
73 3099     3099   4159 my $class = shift;
74 3099         3420 my $t = shift;
75 3099         4915 my $char = substr( $t->{line}, $t->{line_cursor}, 1 );
76              
77             # Allow digits
78 3099 100       8315 return 1 if $char =~ /\d/o;
79              
80 1339 100       2435 if( $char eq '_' ) {
81 191 100       663 return 1 if $t->{token}{content} !~ /\.$/;
82              
83 8         32 chop $t->{token}->{content};
84             $t->{class} = $t->{token}->set_class( 'Number::Float' )
85 8 50       97 if $t->{token}{content} !~ /\..+\./;
86 8         54 $t->_new_token('Operator', '.');
87 8         24 $t->_new_token('Word', '_');
88 8         49 return 0;
89             }
90              
91             # Is this a second decimal point in a row? Then the '..' operator
92 1148 100       1755 if ( $char eq '.' ) {
93 8 100       27 if ( $t->{token}->{content} =~ /\.$/ ) {
94             # We have a .., which is an operator.
95             # Take the . off the end of the token..
96             # and finish it, then make the .. operator.
97 2         6 chop $t->{token}->{content};
98             $t->{class} = $t->{token}->set_class( 'Number::Float' )
99 2 50       19 if $t->{token}{content} !~ /\..+\./;
100 2         19 $t->_new_token('Operator', '..');
101 2         6 return 0;
102             } else {
103 6         15 return 1;
104             }
105             }
106              
107             # Doesn't fit a special case, or is after the end of the token
108             # End of token.
109 1140         2097 $t->_finalize_token->__TOKENIZER__on_char( $t );
110             }
111              
112             sub __TOKENIZER__commit {
113 2983     2983   4048 my $t = $_[1];
114              
115             # Capture the rest of the token
116 2983         6476 pos $t->{line} = $t->{line_cursor};
117             # This was not a v-string after all (it's a word);
118             return PPI::Token::Word->__TOKENIZER__commit($t)
119 2983 100       16516 if $t->{line} !~ m/\G(v\d[_\d]*(?:\.\d[_\d]*)+|v\d[_\d]*\b)/gc;
120              
121 2553         5420 my $content = $1;
122              
123             # If there are no periods this could be a word starting with v\d
124             # Forced to be a word. Done.
125 2553 100 100     7849 return PPI::Token::Word->__TOKENIZER__commit($t)
126             if $content !~ /\./ and $t->__current_token_is_forced_word($content);
127              
128             # This is a v-string
129 2539         3757 $t->{line_cursor} += length $content;
130 2539         5964 $t->_new_token( 'Number::Version', $content );
131 2539         4274 $t->_finalize_token->__TOKENIZER__on_char($t);
132             }
133              
134             1;
135              
136             =pod
137              
138             =head1 BUGS
139              
140             - Does not handle leading minus sign correctly. Should translate to a DashedWord.
141             See L
142              
143             -95.0.1.0 --> "-_\000\cA\000"
144             -96.0.1.0 --> Argument "`\0^A\0" isn't numeric in negation (-)
145              
146             =head1 SUPPORT
147              
148             See the L in the main module.
149              
150             =head1 AUTHOR
151              
152             Chris Dolan Ecdolan@cpan.orgE
153              
154             =head1 COPYRIGHT
155              
156             Copyright 2006 Chris Dolan.
157              
158             This program is free software; you can redistribute
159             it and/or modify it under the same terms as Perl itself.
160              
161             The full text of the license can be found in the
162             LICENSE file included with this module.
163              
164             =cut