Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Extend the 1.9 Sprinter to handle negative numbers in hex, octal, binary

Correctly append ".." in front of negative integers when they are
formatted into hex, octal or binary (%x, %X, %o, %b).

Also remove dead code and pointless predicate methods that simply
delegate to ivars.
  • Loading branch information...
commit 157860a738b29dec2b8512cdb0d3727b86ee2b45 1 parent 39c8659
@leocassarani leocassarani authored
View
84 kernel/common/sprinter.rb
@@ -440,7 +440,6 @@ def push_width_value
end
def push_width(adjust=true)
- yield if block_given?
if @width_static
raise ArgumentError, "width too big" unless @width_static.class == Fixnum
if adjust && @full_leader_size > 0
@@ -449,14 +448,6 @@ def push_width(adjust=true)
@g.push @width_static
end
- if block_given?
- @g.swap
- @b.if_true do
- @g.meta_push_1
- @b.meta_op_minus
- end
- end
-
elsif @width_index
@g.push_local @width_index
@@ -473,30 +464,6 @@ def push_width(adjust=true)
end
end
- n = adjust ? @full_leader_size : 0
- if block_given?
- adjusted = @g.new_label
-
- @g.swap
- @b.if_true do
- @g.push n + 1
- @b.meta_op_minus
- if n > 0
- @g.goto adjusted
- end
- end
-
- if n > 0
- @g.push n
- @b.meta_op_minus
- adjusted.set!
- end
-
- elsif n > 0
- @g.push n
- @b.meta_op_minus
- end
-
else
raise "push without a width"
@@ -512,7 +479,6 @@ def push_precision_value
end
def push_precision
- yield if block_given?
if @prec_static
raise ArgumentError, "precision too big" unless @prec_static.class == Fixnum
@g.push @prec_static
@@ -537,14 +503,6 @@ def push_precision
raise "push without a precision"
end
-
- if block_given?
- @g.swap
- @b.if_true do
- @g.meta_push_1
- @b.meta_op_minus
- end
- end
end
def push_format_string
@@ -607,32 +565,24 @@ def justify_width(adjust=true)
end
end
- def zero_pad?
- @has_precision || (@has_width && @f_zero)
- end
-
- def zero_pad(pad="0", &readjust)
+ def zero_pad(pad="0")
if @has_precision
- push_precision(&readjust)
+ push_precision
+
+ # let the caller adjust the width if needed
+ yield if block_given?
+
@g.push_literal pad
@g.send :rjust, 2
elsif @has_width && @f_zero
- push_width true, &readjust
+ push_width true
@g.push_literal pad
@g.send :rjust, 2
end
end
- def width?
- @has_width
- end
-
attr_reader :width_static
- def precision?
- @has_precision
- end
-
def leader?
@full_leader_size > 0
end
@@ -650,7 +600,7 @@ def string_justify
justify_width
- if precision?
+ if @has_precision
@g.meta_push_0
push_precision
@g.send :[], 2
@@ -761,7 +711,7 @@ def bytecode
@b.append_str
end
- if precision?
+ if @has_precision
@g.push :self
@g.push_stack_local val_idx
@@ -769,7 +719,7 @@ def bytecode
@g.send :digit_expand_precision, 2
- if width?
+ if @has_width
@g.push :self
@g.swap
push_width_value
@@ -783,7 +733,7 @@ def bytecode
@b.append_str
- elsif width?
+ elsif @has_width
@g.push :self
@g.push_stack_local val_idx
@@ -857,15 +807,7 @@ def bytecode
end
padding = format_negative_int(radix)
-
- if zero_pad?
- zero_pad padding
-
- elsif !precision? && !@f_zero
- @g.push_literal ".."
- @g.string_dup
- @g.string_append
- end
+ pad_negative_int(padding)
have_formatted.set!
end
@@ -901,7 +843,7 @@ def bytecode
end
- if precision? || !@f_zero
+ if @has_precision || !@f_zero
justify_width false
end
View
17 kernel/common/sprinter18.rb
@@ -8,6 +8,12 @@ class Builder
def encode_result
end
+ class Atom
+ def zero_pad?
+ @has_precision || (@has_width && @f_zero)
+ end
+ end
+
class CharAtom < Atom
def bytecode
push_value
@@ -70,6 +76,17 @@ def expand_with_width
end
class ExtIntegerAtom < Atom
+ def pad_negative_int(padding)
+ if zero_pad?
+ zero_pad(padding)
+
+ elsif !@has_precision && !@f_zero
+ @g.push_literal ".."
+ @g.string_dup
+ @g.string_append
+ end
+ end
+
def prepend_prefix_bytecode
prepend_prefix
end
View
12 kernel/common/sprinter19.rb
@@ -86,6 +86,18 @@ def expand_with_width
end
class ExtIntegerAtom < Atom
+ def pad_negative_int(padding)
+ zero_pad(padding) do
+ # decrease the width by 2 to account for the ".." below
+ @g.meta_push_2
+ @b.meta_op_minus
+ end
+
+ @g.push_literal ".."
+ @g.string_dup
+ @g.string_append
+ end
+
def prepend_prefix_bytecode
skip_prefix = @g.new_label
View
4 spec/tags/19/ruby/core/string/modulo_tags.txt
@@ -1,5 +1 @@
-fails:String#% supports binary formats using %b for negative numbers
-fails:String#% supports octal formats using %o for negative numbers
fails:String#% supports negative bignums with %u or %d
-fails:String#% supports hex formats using %x for negative numbers
-fails:String#% supports hex formats using %X for negative numbers
View
4 spec/tags/20/ruby/core/string/modulo_tags.txt
@@ -1,5 +1 @@
-fails:String#% supports binary formats using %b for negative numbers
-fails:String#% supports octal formats using %o for negative numbers
fails:String#% supports negative bignums with %u or %d
-fails:String#% supports hex formats using %x for negative numbers
-fails:String#% supports hex formats using %X for negative numbers
Please sign in to comment.
Something went wrong with that request. Please try again.