summaryrefslogtreecommitdiff
path: root/test/ruby/test_sprintf_comb.rb
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-01-25 04:42:36 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-01-25 04:42:36 +0000
commita470a2f1e184bf46642e54df093e32896dcf6e4e (patch)
treea88b22f68523768fc9cde71a65a33906aac8ae03 /test/ruby/test_sprintf_comb.rb
parent2fc0fe5332c45f7c0eea5ba4581a00dce10311fc (diff)
downloadruby-a470a2f1e184bf46642e54df093e32896dcf6e4e.tar.gz
combinational tests for printf.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15227 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/ruby/test_sprintf_comb.rb')
-rw-r--r--test/ruby/test_sprintf_comb.rb300
1 files changed, 300 insertions, 0 deletions
diff --git a/test/ruby/test_sprintf_comb.rb b/test/ruby/test_sprintf_comb.rb
new file mode 100644
index 0000000000..0c28ba7027
--- /dev/null
+++ b/test/ruby/test_sprintf_comb.rb
@@ -0,0 +1,300 @@
+require 'test/unit'
+
+class TestSprintfComb < Test::Unit::TestCase
+ VS = [
+ #-0x1000000000000000000000000000000000000000000000002,
+ #-0x1000000000000000000000000000000000000000000000001,
+ #-0x1000000000000000000000000000000000000000000000000,
+ #-0xffffffffffffffffffffffffffffffffffffffffffffffff,
+ #-0x1000000000000000000000002,
+ #-0x1000000000000000000000001,
+ #-0x1000000000000000000000000,
+ #-0xffffffffffffffffffffffff,
+ -0x10000000000000002,
+ -0x10000000000000001,
+ -0x10000000000000000,
+ -0xffffffffffffffff,
+ -0x4000000000000002,
+ -0x4000000000000001,
+ -0x4000000000000000,
+ -0x3fffffffffffffff,
+ -0x100000002,
+ -0x100000001,
+ -0x100000000,
+ -0xffffffff,
+ #-0xc717a08d, # 0xc717a08d * 0x524b2245 = 0x4000000000000001
+ -0x80000002,
+ -0x80000001,
+ -0x80000000,
+ -0x7fffffff,
+ #-0x524b2245,
+ -0x40000002,
+ -0x40000001,
+ -0x40000000,
+ -0x3fffffff,
+ #-0x10002,
+ #-0x10001,
+ #-0x10000,
+ #-0xffff,
+ #-0x8101, # 0x8101 * 0x7f01 = 0x40000001
+ #-0x8002,
+ #-0x8001,
+ #-0x8000,
+ #-0x7fff,
+ #-0x7f01,
+ #-65,
+ #-64,
+ #-63,
+ #-62,
+ #-33,
+ #-32,
+ #-31,
+ #-30,
+ -3,
+ -2,
+ -1,
+ 0,
+ 1,
+ 2,
+ 3,
+ #30,
+ #31,
+ #32,
+ #33,
+ #62,
+ #63,
+ #64,
+ #65,
+ #0x7f01,
+ #0x7ffe,
+ #0x7fff,
+ #0x8000,
+ #0x8001,
+ #0x8101,
+ #0xfffe,
+ #0xffff,
+ #0x10000,
+ #0x10001,
+ 0x3ffffffe,
+ 0x3fffffff,
+ 0x40000000,
+ 0x40000001,
+ #0x524b2245,
+ 0x7ffffffe,
+ 0x7fffffff,
+ 0x80000000,
+ 0x80000001,
+ #0xc717a08d,
+ 0xfffffffe,
+ 0xffffffff,
+ 0x100000000,
+ 0x100000001,
+ 0x3ffffffffffffffe,
+ 0x3fffffffffffffff,
+ 0x4000000000000000,
+ 0x4000000000000001,
+ 0xfffffffffffffffe,
+ 0xffffffffffffffff,
+ 0x10000000000000000,
+ 0x10000000000000001,
+ #0xffffffffffffffffffffffff,
+ #0x1000000000000000000000000,
+ #0x1000000000000000000000001,
+ #0xffffffffffffffffffffffffffffffffffffffffffffffff,
+ #0x1000000000000000000000000000000000000000000000000,
+ #0x1000000000000000000000000000000000000000000000001
+ ]
+ VS.reverse!
+
+ def combination(*args)
+ if args.empty?
+ yield []
+ else
+ arg = args.shift
+ arg.each {|v|
+ combination(*args) {|vs|
+ yield [v, *vs]
+ }
+ }
+ end
+ end
+
+ def emu(format, v)
+ /\A%( )?(\#)?(\+)?(-)?(0)?(\d+)?(?:\.(\d+))?(.)\z/ =~ format
+ sp = $1
+ hs = $2
+ pl = $3
+ mi = $4
+ zr = $5
+ width = $6
+ precision = $7
+ type = $8
+ width = width.to_i if width
+ precision = precision.to_i if precision
+ prefix = ''
+
+ zr = nil if precision
+
+ zr = nil if mi && zr
+
+ case type
+ when 'b'
+ radix = 2
+ digitmap = {0 => '0', 1 => '1'}
+ complement = !pl && !sp
+ prefix = '0b' if hs
+ when 'd'
+ radix = 10
+ digitmap = {}
+ 10.times {|i| digitmap[i] = i.to_s }
+ complement = false
+ when 'o'
+ radix = 8
+ digitmap = {}
+ 8.times {|i| digitmap[i] = i.to_s }
+ complement = !pl && !sp
+ when 'X'
+ radix = 16
+ digitmap = {}
+ 16.times {|i| digitmap[i] = i.to_s(16).upcase }
+ complement = !pl && !sp
+ prefix = '0X' if hs
+ when 'x'
+ radix = 16
+ digitmap = {}
+ 16.times {|i| digitmap[i] = i.to_s(16) }
+ complement = !pl && !sp
+ prefix = '0x' if hs
+ else
+ raise "unexpected type: #{type.inspect}"
+ end
+
+ digits = []
+ abs = v.abs
+ sign = ''
+ while 0 < abs
+ digits << (abs % radix)
+ abs /= radix
+ end
+
+ if v < 0
+ if complement
+ digits.map! {|d| radix-1 - d }
+ carry = 1
+ digits.each_index {|i|
+ digits[i] += carry
+ carry = 0
+ if radix <= digits[i]
+ digits[i] -= radix
+ carry = 1
+ end
+ }
+ if digits.last != radix-1
+ digits << (radix-1)
+ end
+ sign = '..'
+ else
+ sign = '-'
+ end
+ else
+ if pl
+ sign = '+'
+ elsif sp
+ sign = ' '
+ end
+ end
+
+ dlen = digits.length
+ dlen += 2 if sign == '..'
+
+ if v < 0 && complement
+ d = radix - 1
+ else
+ d = 0
+ end
+ if precision
+ if dlen < precision
+ (precision - dlen).times {
+ digits << d
+ }
+ end
+ else
+ if dlen == 0
+ digits << d
+ end
+ end
+ if type == 'o' && hs
+ if digits.empty? || digits.last != d
+ digits << d
+ end
+ end
+
+ digits.reverse!
+
+ str = digits.map {|d| digitmap[d] }.join
+
+ pad = ''
+ nlen = prefix.length + sign.length + str.length
+ if width && nlen < width
+ len = width - nlen
+ if zr
+ if complement && v < 0
+ pad = digitmap[radix-1] * len
+ else
+ pad = '0' * len
+ end
+ else
+ pad = ' ' * len
+ end
+ end
+
+ if / / =~ pad
+ if sign == '..'
+ str = prefix + sign + str
+ else
+ str = sign + prefix + str
+ end
+ if mi
+ str = str + pad
+ else
+ str = pad + str
+ end
+ else
+ if sign == '..'
+ str = prefix + sign + pad + str
+ else
+ str = sign + prefix + pad + str
+ end
+ end
+
+ str
+ end
+
+ def test_format
+ combination(
+ %w[b d o X x],
+ [nil, 0, 5, 20],
+ [nil, 0, 8, 20],
+ ['', ' '],
+ ['', '#'],
+ ['', '+'],
+ ['', '-'],
+ ['', '0']) {|type, width, precision, sp, hs, pl, mi, zr|
+ if precision
+ precision = ".#{precision}"
+ end
+ format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}"
+ VS.each {|v|
+ r = sprintf format, v
+ e = emu format, v
+ if true
+ assert_equal(e, r, "sprintf(#{format.dump}, #{v})")
+ else
+ if e != r
+ puts "#{e.dump}\t#{r.dump}\tsprintf(#{format.dump}, #{v})"
+ end
+ end
+ }
+ }
+ end
+end