diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-04-01 04:32:22 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-04-01 04:32:22 +0000 |
commit | 2067e4eb30eb78b36c252baff319c6d581700460 (patch) | |
tree | fb7bcef35cfac3925163973fe683dfd3ea4aac0a /lib/scanf.rb | |
parent | 7b93993b20f1e1c045aa6f687ea56ae9d4ac01f7 (diff) |
* lib/scanf.rb: support %a format. [ruby-dev:40650]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27139 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/scanf.rb')
-rw-r--r-- | lib/scanf.rb | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/lib/scanf.rb b/lib/scanf.rb index ffc0d90f49..dd6ba6c9d0 100644 --- a/lib/scanf.rb +++ b/lib/scanf.rb @@ -112,7 +112,7 @@ and <tt>tests/scanftests.rb</tt> for examples.) [x,X] Matches an optionally signed hexadecimal integer, -[f,g,e,E] +[a,e,f,g,A,E,F,G] Matches an optionally signed floating-point number. [s] @@ -309,7 +309,22 @@ module Scanf def skip; /^\s*%\*/.match(@spec_string); end - def extract_float(s); s.to_f if s &&! skip; end + def extract_float(s) + return nil unless s &&! skip + if /\A(?<sign>[-+]?)0[xX](?<frac>\.\h+|\h+(?:\.\h*)?)[pP](?<exp>[-+]\d+)/ =~ s + f1, f2 = frac.split('.') + f = f1.hex + if f2 + len = f2.length + if len > 0 + f += f2.hex / (16.0 ** len) + end + end + (sign == ?- ? -1 : 1) * Math.ldexp(f, exp.to_i) + else + s.to_f + end + end def extract_decimal(s); s.to_i if s &&! skip; end def extract_hex(s); s.hex if s &&! skip; end def extract_octal(s); s.oct if s &&! skip; end @@ -409,12 +424,12 @@ module Scanf [ "([-+][0-7]{1,#{$1.to_i-1}}|[0-7]{1,#{$1}})", :extract_octal ] # %f - when /%\*?[efgEFG]/ - [ '([-+]?(?:\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))', :extract_float ] + when /%\*?[aefgAEFG]/ + [ '([-+]?(?:0[xX](?:\.\h+|\h+(?:\.\h*)?)[pP][-+]\d+|\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))', :extract_float ] # %5f - when /%\*?(\d+)[efgEFG]/ - [ '(?=[-+]?(?:\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))' + + when /%\*?(\d+)[aefgAEFG]/ + [ '(?=[-+]?(?:0[xX](?:\.\h+|\h+(?:\.\h*)?)[pP][-+]\d+|\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))' + "(\\S{1,#{$1}})", :extract_float ] # %5s @@ -491,7 +506,7 @@ module Scanf attr_reader :string_left, :last_spec_tried, :last_match_tried, :matched_count, :space - SPECIFIERS = 'diuXxofFeEgGsc' + SPECIFIERS = 'diuXxofFeEgGscaA' REGEX = / # possible space, followed by... (?:\s* |