vim-patch:9.0.1704: Cannot use positional arguments for printf() (#24719)

Problem: Cannot use positional arguments for printf()
Solution: Support positional arguments in string formatting

closes: vim/vim#12140

0c6181fec4

Co-authored-by: Christ van Willegen <cvwillegen@gmail.com>
This commit is contained in:
zeertzjq
2023-08-15 19:16:19 +08:00
committed by GitHub
parent 7aad4643f9
commit 842a47d6a4
9 changed files with 1529 additions and 77 deletions

View File

@@ -140,37 +140,83 @@ describe('vim_strchr()', function()
end)
describe('vim_snprintf()', function()
itp('truncation', function()
local function check(expected, buf, bsize, fmt, ...)
eq(#expected, strings.vim_snprintf(buf, bsize, fmt, ...))
if bsize > 0 then
local actual = ffi.string(buf, math.min(#expected + 1, bsize))
eq(expected:sub(1, bsize - 1) .. '\0', actual)
end
local function a(expected, buf, bsize, fmt, ...)
eq(#expected, strings.vim_snprintf(buf, bsize, fmt, ...))
if bsize > 0 then
local actual = ffi.string(buf, math.min(#expected + 1, bsize))
eq(expected:sub(1, bsize - 1) .. '\0', actual)
end
end
local function i(n) return ffi.cast('int', n) end
local function l(n) return ffi.cast('long', n) end
local function u(n) return ffi.cast('unsigned', n) end
local function ll(n) return ffi.cast('long long', n) end
local function ul(n) return ffi.cast('unsigned long', n) end
local function ull(n) return ffi.cast('unsigned long long', n) end
itp('truncation', function()
for bsize = 0, 14 do
local buf = ffi.gc(strings.xmalloc(bsize), strings.xfree)
check('1234567', buf, bsize, '%d', ffi.cast('int', 1234567))
check('1234567', buf, bsize, '%ld', ffi.cast('long', 1234567))
check(' 1234567', buf, bsize, '%9ld', ffi.cast('long', 1234567))
check('1234567 ', buf, bsize, '%-9ld', ffi.cast('long', 1234567))
check('deadbeef', buf, bsize, '%x', ffi.cast('unsigned', 0xdeadbeef))
check('001100', buf, bsize, '%06b', ffi.cast('int', 12))
check('1.234000', buf, bsize, '%f', ffi.cast('double', 1.234))
check('1.234000e+00', buf, bsize, '%e', ffi.cast('double', 1.234))
check('nan', buf, bsize, '%f', ffi.cast('double', 0.0 / 0.0))
check('inf', buf, bsize, '%f', ffi.cast('double', 1.0 / 0.0))
check('-inf', buf, bsize, '%f', ffi.cast('double', -1.0 / 0.0))
check('-0.000000', buf, bsize, '%f', ffi.cast('double', -0.0))
check('漢語', buf, bsize, '%s', '漢語')
check(' 漢語', buf, bsize, '%8s', '漢語')
check('漢語 ', buf, bsize, '%-8s', '漢語')
check('', buf, bsize, '%.3s', '漢語')
check(' foo', buf, bsize, '%5S', 'foo')
check('%%%', buf, bsize, '%%%%%%')
check('0x87654321', buf, bsize, '%p', ffi.cast('char *', 0x87654321))
check('0x0087654321', buf, bsize, '%012p', ffi.cast('char *', 0x87654321))
a('1.00000001e7', buf, bsize, '%.8g', 10000000.1)
a('1234567', buf, bsize, '%d', i(1234567))
a('1234567', buf, bsize, '%ld', l(1234567))
a(' 1234567', buf, bsize, '%9ld', l(1234567))
a('1234567 ', buf, bsize, '%-9ld', l(1234567))
a('deadbeef', buf, bsize, '%x', u(0xdeadbeef))
a('001100', buf, bsize, '%06b', u(12))
a('one two', buf, bsize, '%s %s', 'one', 'two')
a('1.234000', buf, bsize, '%f', 1.234)
a('1.234000e+00', buf, bsize, '%e', 1.234)
a('nan', buf, bsize, '%f', 0.0 / 0.0)
a('inf', buf, bsize, '%f', 1.0 / 0.0)
a('-inf', buf, bsize, '%f', -1.0 / 0.0)
a('-0.000000', buf, bsize, '%f', -0.0)
a('漢語', buf, bsize, '%s', '漢語')
a(' 漢語', buf, bsize, '%8s', '漢語')
a('漢語 ', buf, bsize, '%-8s', '漢語')
a('', buf, bsize, '%.3s', '漢語')
a(' foo', buf, bsize, '%5S', 'foo')
a('%%%', buf, bsize, '%%%%%%')
a('0x87654321', buf, bsize, '%p', ffi.cast('char *', 0x87654321))
a('0x0087654321', buf, bsize, '%012p', ffi.cast('char *', 0x87654321))
end
end)
itp('positional arguments', function()
for bsize = 0, 24 do
local buf = ffi.gc(strings.xmalloc(bsize), strings.xfree)
a('1234567 ', buf, bsize, '%1$*2$ld', l(1234567), i(-9))
a('1234567 ', buf, bsize, '%1$*2$.*3$ld', l(1234567), i(-9), i(5))
a('1234567 ', buf, bsize, '%1$*3$.*2$ld', l(1234567), i(5), i(-9))
a('1234567 ', buf, bsize, '%3$*1$.*2$ld', i(-9), i(5), l(1234567))
a('1234567', buf, bsize, '%1$ld', l(1234567))
a(' 1234567', buf, bsize, '%1$*2$ld', l(1234567), i(9))
a('9 12345 7654321', buf, bsize, '%2$ld %1$d %3$lu', i(12345), l(9), ul(7654321))
a('9 1234567 7654321', buf, bsize, '%2$d %1$ld %3$lu', l(1234567), i(9), ul(7654321))
a('9 1234567 7654321', buf, bsize, '%2$d %1$lld %3$lu', ll(1234567), i(9), ul(7654321))
a('9 12345 7654321', buf, bsize, '%2$ld %1$u %3$lu', u(12345), l(9), ul(7654321))
a('9 1234567 7654321', buf, bsize, '%2$d %1$lu %3$lu', ul(1234567), i(9), ul(7654321))
a('9 1234567 7654321', buf, bsize, '%2$d %1$llu %3$lu', ull(1234567), i(9), ul(7654321))
a('9 1234567 7654321', buf, bsize, '%2$d %1$llu %3$lu', ull(1234567), i(9), ul(7654321))
a('9 deadbeef 7654321', buf, bsize, '%2$d %1$x %3$lu', u(0xdeadbeef), i(9), ul(7654321))
a('9 c 7654321', buf, bsize, '%2$ld %1$c %3$lu', i(('c'):byte()), l(9), ul(7654321))
a('9 hi 7654321', buf, bsize, '%2$ld %1$s %3$lu', 'hi', l(9), ul(7654321))
a('9 0.000000e+00 7654321', buf, bsize, '%2$ld %1$e %3$lu', 0.0, l(9), ul(7654321))
a('two one two', buf, bsize, '%2$s %1$s %2$s', 'one', 'two', 'three')
a('three one two', buf, bsize, '%3$s %1$s %2$s', 'one', 'two', 'three')
a('1234567', buf, bsize, '%1$d', i(1234567))
a('deadbeef', buf, bsize, '%1$x', u(0xdeadbeef))
a('001100', buf, bsize, '%1$0.*2$b', u(12), i(6))
a('one two', buf, bsize, '%1$s %2$s', 'one', 'two')
a('001100', buf, bsize, '%06b', u(12))
a('two one', buf, bsize, '%2$s %1$s', 'one', 'two')
a('1.234000', buf, bsize, '%1$f', 1.234)
a('1.234000e+00', buf, bsize, '%1$e', 1.234)
a('nan', buf, bsize, '%1$f', 0.0 / 0.0)
a('inf', buf, bsize, '%1$f', 1.0 / 0.0)
a('-inf', buf, bsize, '%1$f', -1.0 / 0.0)
a('-0.000000', buf, bsize, '%1$f', -0.0)
end
end)
end)