vim_str2nr_spec.lua 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. local t = require('test.unit.testutil')
  2. local bit = require('bit')
  3. local itp = t.gen_itp(it)
  4. local child_call_once = t.child_call_once
  5. local cimport = t.cimport
  6. local ffi = t.ffi
  7. local lib = cimport('./src/nvim/charset.h')
  8. local ARGTYPES
  9. child_call_once(function()
  10. ARGTYPES = {
  11. num = ffi.typeof('varnumber_T[1]'),
  12. unum = ffi.typeof('uvarnumber_T[1]'),
  13. pre = ffi.typeof('int[1]'),
  14. len = ffi.typeof('int[1]'),
  15. }
  16. end)
  17. local icnt = -42
  18. local ucnt = 4242
  19. local function arginit(arg)
  20. if arg == 'unum' then
  21. ucnt = ucnt + 1
  22. return ARGTYPES[arg]({ ucnt })
  23. else
  24. icnt = icnt - 1
  25. return ARGTYPES[arg]({ icnt })
  26. end
  27. end
  28. local function argreset(arg, args)
  29. if arg == 'unum' then
  30. ucnt = ucnt + 1
  31. args[arg][0] = ucnt
  32. else
  33. icnt = icnt - 1
  34. args[arg][0] = icnt
  35. end
  36. end
  37. local function test_vim_str2nr(s, what, exp, maxlen, strict)
  38. if strict == nil then
  39. strict = true
  40. end
  41. local bits = {}
  42. for k, _ in pairs(exp) do
  43. bits[#bits + 1] = k
  44. end
  45. maxlen = maxlen or #s
  46. local args = {}
  47. for k, _ in pairs(ARGTYPES) do
  48. args[k] = arginit(k)
  49. end
  50. for case = 0, ((2 ^ #bits) - 1) do
  51. local cv = {}
  52. for b = 0, (#bits - 1) do
  53. if bit.band(case, (2 ^ b)) == 0 then
  54. local k = bits[b + 1]
  55. argreset(k, args)
  56. cv[k] = args[k]
  57. end
  58. end
  59. lib.vim_str2nr(s, cv.pre, cv.len, what, cv.num, cv.unum, maxlen, strict, nil)
  60. for cck, ccv in pairs(cv) do
  61. if exp[cck] ~= tonumber(ccv[0]) then
  62. error(
  63. ('Failed check (%s = %d) in test (s=%s, w=%u, m=%d, strict=%s): %d'):format(
  64. cck,
  65. exp[cck],
  66. s,
  67. tonumber(what),
  68. maxlen,
  69. tostring(strict),
  70. tonumber(ccv[0])
  71. )
  72. )
  73. end
  74. end
  75. end
  76. end
  77. local _itp = itp
  78. itp = function(...)
  79. collectgarbage('restart')
  80. _itp(...)
  81. end
  82. describe('vim_str2nr()', function()
  83. itp('works fine when it has nothing to do', function()
  84. test_vim_str2nr('', 0, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
  85. test_vim_str2nr('', lib.STR2NR_ALL, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
  86. test_vim_str2nr('', lib.STR2NR_BIN, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
  87. test_vim_str2nr('', lib.STR2NR_OCT, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
  88. test_vim_str2nr('', lib.STR2NR_OOCT, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
  89. test_vim_str2nr('', lib.STR2NR_HEX, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
  90. test_vim_str2nr(
  91. '',
  92. lib.STR2NR_FORCE + lib.STR2NR_DEC,
  93. { len = 0, num = 0, unum = 0, pre = 0 },
  94. 0
  95. )
  96. test_vim_str2nr(
  97. '',
  98. lib.STR2NR_FORCE + lib.STR2NR_BIN,
  99. { len = 0, num = 0, unum = 0, pre = 0 },
  100. 0
  101. )
  102. test_vim_str2nr(
  103. '',
  104. lib.STR2NR_FORCE + lib.STR2NR_OCT,
  105. { len = 0, num = 0, unum = 0, pre = 0 },
  106. 0
  107. )
  108. test_vim_str2nr(
  109. '',
  110. lib.STR2NR_FORCE + lib.STR2NR_OOCT,
  111. { len = 0, num = 0, unum = 0, pre = 0 },
  112. 0
  113. )
  114. test_vim_str2nr(
  115. '',
  116. lib.STR2NR_FORCE + lib.STR2NR_OCT + lib.STR2NR_OOCT,
  117. { len = 0, num = 0, unum = 0, pre = 0 },
  118. 0
  119. )
  120. test_vim_str2nr(
  121. '',
  122. lib.STR2NR_FORCE + lib.STR2NR_HEX,
  123. { len = 0, num = 0, unum = 0, pre = 0 },
  124. 0
  125. )
  126. end)
  127. itp('works with decimal numbers', function()
  128. for _, flags in ipairs({
  129. 0,
  130. lib.STR2NR_BIN,
  131. lib.STR2NR_OCT,
  132. lib.STR2NR_HEX,
  133. lib.STR2NR_OOCT,
  134. lib.STR2NR_BIN + lib.STR2NR_OCT,
  135. lib.STR2NR_BIN + lib.STR2NR_HEX,
  136. lib.STR2NR_OCT + lib.STR2NR_HEX,
  137. lib.STR2NR_OOCT + lib.STR2NR_HEX,
  138. lib.STR2NR_ALL,
  139. lib.STR2NR_FORCE + lib.STR2NR_DEC,
  140. }) do
  141. -- Check that all digits are recognized
  142. test_vim_str2nr('12345', flags, { len = 5, num = 12345, unum = 12345, pre = 0 }, 0)
  143. test_vim_str2nr('67890', flags, { len = 5, num = 67890, unum = 67890, pre = 0 }, 0)
  144. test_vim_str2nr('12345A', flags, { len = 0 }, 0)
  145. test_vim_str2nr('67890A', flags, { len = 0 }, 0)
  146. test_vim_str2nr('12345A', flags, { len = 5, num = 12345, unum = 12345, pre = 0 }, 0, false)
  147. test_vim_str2nr('67890A', flags, { len = 5, num = 67890, unum = 67890, pre = 0 }, 0, false)
  148. test_vim_str2nr('42', flags, { len = 2, num = 42, unum = 42, pre = 0 }, 0)
  149. test_vim_str2nr('42', flags, { len = 1, num = 4, unum = 4, pre = 0 }, 1)
  150. test_vim_str2nr('42', flags, { len = 2, num = 42, unum = 42, pre = 0 }, 2)
  151. test_vim_str2nr('42', flags, { len = 2, num = 42, unum = 42, pre = 0 }, 3) -- includes NUL byte in maxlen
  152. test_vim_str2nr('42x', flags, { len = 0 }, 0)
  153. test_vim_str2nr('42x', flags, { len = 0 }, 3)
  154. test_vim_str2nr('42x', flags, { len = 2, num = 42, unum = 42, pre = 0 }, 0, false)
  155. test_vim_str2nr('42x', flags, { len = 2, num = 42, unum = 42, pre = 0 }, 3, false)
  156. test_vim_str2nr('-42', flags, { len = 3, num = -42, unum = 42, pre = 0 }, 3)
  157. test_vim_str2nr('-42', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  158. test_vim_str2nr('-42x', flags, { len = 0 }, 0)
  159. test_vim_str2nr('-42x', flags, { len = 0 }, 4)
  160. test_vim_str2nr('-42x', flags, { len = 3, num = -42, unum = 42, pre = 0 }, 0, false)
  161. test_vim_str2nr('-42x', flags, { len = 3, num = -42, unum = 42, pre = 0 }, 4, false)
  162. end
  163. end)
  164. itp('works with binary numbers', function()
  165. for _, flags in ipairs({
  166. lib.STR2NR_BIN,
  167. lib.STR2NR_BIN + lib.STR2NR_OCT,
  168. lib.STR2NR_BIN + lib.STR2NR_HEX,
  169. lib.STR2NR_ALL,
  170. lib.STR2NR_FORCE + lib.STR2NR_BIN,
  171. }) do
  172. local bin
  173. local BIN
  174. if flags > lib.STR2NR_FORCE then
  175. bin = 0
  176. BIN = 0
  177. else
  178. bin = ('b'):byte()
  179. BIN = ('B'):byte()
  180. end
  181. test_vim_str2nr('0b101', flags, { len = 5, num = 5, unum = 5, pre = bin }, 0)
  182. test_vim_str2nr('0b101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  183. test_vim_str2nr('0b101', flags, { len = 0 }, 2)
  184. test_vim_str2nr('0b101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 2, false)
  185. test_vim_str2nr('0b101', flags, { len = 3, num = 1, unum = 1, pre = bin }, 3)
  186. test_vim_str2nr('0b101', flags, { len = 4, num = 2, unum = 2, pre = bin }, 4)
  187. test_vim_str2nr('0b101', flags, { len = 5, num = 5, unum = 5, pre = bin }, 5)
  188. test_vim_str2nr('0b101', flags, { len = 5, num = 5, unum = 5, pre = bin }, 6)
  189. test_vim_str2nr('0b1012', flags, { len = 0 }, 0)
  190. test_vim_str2nr('0b1012', flags, { len = 0 }, 6)
  191. test_vim_str2nr('0b1012', flags, { len = 5, num = 5, unum = 5, pre = bin }, 0, false)
  192. test_vim_str2nr('0b1012', flags, { len = 5, num = 5, unum = 5, pre = bin }, 6, false)
  193. test_vim_str2nr('-0b101', flags, { len = 6, num = -5, unum = 5, pre = bin }, 0)
  194. test_vim_str2nr('-0b101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  195. test_vim_str2nr('-0b101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
  196. test_vim_str2nr('-0b101', flags, { len = 0 }, 3)
  197. test_vim_str2nr('-0b101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 3, false)
  198. test_vim_str2nr('-0b101', flags, { len = 4, num = -1, unum = 1, pre = bin }, 4)
  199. test_vim_str2nr('-0b101', flags, { len = 5, num = -2, unum = 2, pre = bin }, 5)
  200. test_vim_str2nr('-0b101', flags, { len = 6, num = -5, unum = 5, pre = bin }, 6)
  201. test_vim_str2nr('-0b101', flags, { len = 6, num = -5, unum = 5, pre = bin }, 7)
  202. test_vim_str2nr('-0b1012', flags, { len = 0 }, 0)
  203. test_vim_str2nr('-0b1012', flags, { len = 0 }, 7)
  204. test_vim_str2nr('-0b1012', flags, { len = 6, num = -5, unum = 5, pre = bin }, 0, false)
  205. test_vim_str2nr('-0b1012', flags, { len = 6, num = -5, unum = 5, pre = bin }, 7, false)
  206. test_vim_str2nr('0B101', flags, { len = 5, num = 5, unum = 5, pre = BIN }, 0)
  207. test_vim_str2nr('0B101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  208. test_vim_str2nr('0B101', flags, { len = 0 }, 2)
  209. test_vim_str2nr('0B101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 2, false)
  210. test_vim_str2nr('0B101', flags, { len = 3, num = 1, unum = 1, pre = BIN }, 3)
  211. test_vim_str2nr('0B101', flags, { len = 4, num = 2, unum = 2, pre = BIN }, 4)
  212. test_vim_str2nr('0B101', flags, { len = 5, num = 5, unum = 5, pre = BIN }, 5)
  213. test_vim_str2nr('0B101', flags, { len = 5, num = 5, unum = 5, pre = BIN }, 6)
  214. test_vim_str2nr('0B1012', flags, { len = 0 }, 0)
  215. test_vim_str2nr('0B1012', flags, { len = 0 }, 6)
  216. test_vim_str2nr('0B1012', flags, { len = 5, num = 5, unum = 5, pre = BIN }, 0, false)
  217. test_vim_str2nr('0B1012', flags, { len = 5, num = 5, unum = 5, pre = BIN }, 6, false)
  218. test_vim_str2nr('-0B101', flags, { len = 6, num = -5, unum = 5, pre = BIN }, 0)
  219. test_vim_str2nr('-0B101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  220. test_vim_str2nr('-0B101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
  221. test_vim_str2nr('-0B101', flags, { len = 0 }, 3)
  222. test_vim_str2nr('-0B101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 3, false)
  223. test_vim_str2nr('-0B101', flags, { len = 4, num = -1, unum = 1, pre = BIN }, 4)
  224. test_vim_str2nr('-0B101', flags, { len = 5, num = -2, unum = 2, pre = BIN }, 5)
  225. test_vim_str2nr('-0B101', flags, { len = 6, num = -5, unum = 5, pre = BIN }, 6)
  226. test_vim_str2nr('-0B101', flags, { len = 6, num = -5, unum = 5, pre = BIN }, 7)
  227. test_vim_str2nr('-0B1012', flags, { len = 0 }, 0)
  228. test_vim_str2nr('-0B1012', flags, { len = 0 }, 7)
  229. test_vim_str2nr('-0B1012', flags, { len = 6, num = -5, unum = 5, pre = BIN }, 0, false)
  230. test_vim_str2nr('-0B1012', flags, { len = 6, num = -5, unum = 5, pre = BIN }, 7, false)
  231. if flags > lib.STR2NR_FORCE then
  232. test_vim_str2nr('-101', flags, { len = 4, num = -5, unum = 5, pre = 0 }, 0)
  233. end
  234. end
  235. end)
  236. itp('works with octal numbers (0 prefix)', function()
  237. for _, flags in ipairs({
  238. lib.STR2NR_OCT,
  239. lib.STR2NR_OCT + lib.STR2NR_BIN,
  240. lib.STR2NR_OCT + lib.STR2NR_HEX,
  241. lib.STR2NR_OCT + lib.STR2NR_OOCT,
  242. lib.STR2NR_ALL,
  243. lib.STR2NR_FORCE + lib.STR2NR_OCT,
  244. lib.STR2NR_FORCE + lib.STR2NR_OOCT,
  245. lib.STR2NR_FORCE + lib.STR2NR_OCT + lib.STR2NR_OOCT,
  246. }) do
  247. local oct
  248. if flags > lib.STR2NR_FORCE then
  249. oct = 0
  250. else
  251. oct = ('0'):byte()
  252. end
  253. -- Check that all digits are recognized
  254. test_vim_str2nr('012345670', flags, { len = 9, num = 2739128, unum = 2739128, pre = oct }, 0)
  255. test_vim_str2nr('054', flags, { len = 3, num = 44, unum = 44, pre = oct }, 0)
  256. test_vim_str2nr('054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  257. test_vim_str2nr('054', flags, { len = 2, num = 5, unum = 5, pre = oct }, 2)
  258. test_vim_str2nr('054', flags, { len = 3, num = 44, unum = 44, pre = oct }, 3)
  259. test_vim_str2nr('0548', flags, { len = 3, num = 44, unum = 44, pre = oct }, 3)
  260. test_vim_str2nr('054', flags, { len = 3, num = 44, unum = 44, pre = oct }, 4)
  261. test_vim_str2nr('054x', flags, { len = 0 }, 4)
  262. test_vim_str2nr('054x', flags, { len = 0 }, 0)
  263. test_vim_str2nr('054x', flags, { len = 3, num = 44, unum = 44, pre = oct }, 4, false)
  264. test_vim_str2nr('054x', flags, { len = 3, num = 44, unum = 44, pre = oct }, 0, false)
  265. test_vim_str2nr('-054', flags, { len = 4, num = -44, unum = 44, pre = oct }, 0)
  266. test_vim_str2nr('-054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  267. test_vim_str2nr('-054', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
  268. test_vim_str2nr('-054', flags, { len = 3, num = -5, unum = 5, pre = oct }, 3)
  269. test_vim_str2nr('-054', flags, { len = 4, num = -44, unum = 44, pre = oct }, 4)
  270. test_vim_str2nr('-0548', flags, { len = 4, num = -44, unum = 44, pre = oct }, 4)
  271. test_vim_str2nr('-054', flags, { len = 4, num = -44, unum = 44, pre = oct }, 5)
  272. test_vim_str2nr('-054x', flags, { len = 0 }, 5)
  273. test_vim_str2nr('-054x', flags, { len = 0 }, 0)
  274. test_vim_str2nr('-054x', flags, { len = 4, num = -44, unum = 44, pre = oct }, 5, false)
  275. test_vim_str2nr('-054x', flags, { len = 4, num = -44, unum = 44, pre = oct }, 0, false)
  276. if flags > lib.STR2NR_FORCE then
  277. test_vim_str2nr('-54', flags, { len = 3, num = -44, unum = 44, pre = 0 }, 0)
  278. test_vim_str2nr('-0548', flags, { len = 0 }, 5)
  279. test_vim_str2nr('-0548', flags, { len = 0 }, 0)
  280. test_vim_str2nr('-0548', flags, { len = 4, num = -44, unum = 44, pre = 0 }, 5, false)
  281. test_vim_str2nr('-0548', flags, { len = 4, num = -44, unum = 44, pre = 0 }, 0, false)
  282. else
  283. test_vim_str2nr('-0548', flags, { len = 5, num = -548, unum = 548, pre = 0 }, 5)
  284. test_vim_str2nr('-0548', flags, { len = 5, num = -548, unum = 548, pre = 0 }, 0)
  285. end
  286. end
  287. end)
  288. itp('works with octal numbers (0o or 0O prefix)', function()
  289. for _, flags in ipairs({
  290. lib.STR2NR_OOCT,
  291. lib.STR2NR_OOCT + lib.STR2NR_BIN,
  292. lib.STR2NR_OOCT + lib.STR2NR_HEX,
  293. lib.STR2NR_OCT + lib.STR2NR_OOCT,
  294. lib.STR2NR_OCT + lib.STR2NR_OOCT + lib.STR2NR_BIN,
  295. lib.STR2NR_OCT + lib.STR2NR_OOCT + lib.STR2NR_HEX,
  296. lib.STR2NR_ALL,
  297. lib.STR2NR_FORCE + lib.STR2NR_OCT,
  298. lib.STR2NR_FORCE + lib.STR2NR_OOCT,
  299. lib.STR2NR_FORCE + lib.STR2NR_OCT + lib.STR2NR_OOCT,
  300. }) do
  301. local oct
  302. local OCT
  303. if flags > lib.STR2NR_FORCE then
  304. oct = 0
  305. OCT = 0
  306. else
  307. oct = ('o'):byte()
  308. OCT = ('O'):byte()
  309. end
  310. test_vim_str2nr('0o054', flags, { len = 5, num = 44, unum = 44, pre = oct }, 0)
  311. test_vim_str2nr('0o054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  312. test_vim_str2nr('0o054', flags, { len = 0 }, 2)
  313. test_vim_str2nr('0o054', flags, { len = 3, num = 0, unum = 0, pre = oct }, 3)
  314. test_vim_str2nr('0o054', flags, { len = 4, num = 5, unum = 5, pre = oct }, 4)
  315. test_vim_str2nr('0o054', flags, { len = 5, num = 44, unum = 44, pre = oct }, 5)
  316. test_vim_str2nr('0o0548', flags, { len = 5, num = 44, unum = 44, pre = oct }, 5)
  317. test_vim_str2nr('0o054', flags, { len = 5, num = 44, unum = 44, pre = oct }, 6)
  318. test_vim_str2nr('0o054x', flags, { len = 0 }, 6)
  319. test_vim_str2nr('0o054x', flags, { len = 0 }, 0)
  320. test_vim_str2nr('0o054x', flags, { len = 5, num = 44, unum = 44, pre = oct }, 6, false)
  321. test_vim_str2nr('0o054x', flags, { len = 5, num = 44, unum = 44, pre = oct }, 0, false)
  322. test_vim_str2nr('-0o054', flags, { len = 6, num = -44, unum = 44, pre = oct }, 0)
  323. test_vim_str2nr('-0o054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  324. test_vim_str2nr('-0o054', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
  325. test_vim_str2nr('-0o054', flags, { len = 0 }, 3)
  326. test_vim_str2nr('-0o054', flags, { len = 4, num = 0, unum = 0, pre = oct }, 4)
  327. test_vim_str2nr('-0o054', flags, { len = 5, num = -5, unum = 5, pre = oct }, 5)
  328. test_vim_str2nr('-0o054', flags, { len = 6, num = -44, unum = 44, pre = oct }, 6)
  329. test_vim_str2nr('-0o0548', flags, { len = 6, num = -44, unum = 44, pre = oct }, 6)
  330. test_vim_str2nr('-0o054', flags, { len = 6, num = -44, unum = 44, pre = oct }, 7)
  331. test_vim_str2nr('-0o054x', flags, { len = 0 }, 7)
  332. test_vim_str2nr('-0o054x', flags, { len = 0 }, 0)
  333. test_vim_str2nr('-0o054x', flags, { len = 6, num = -44, unum = 44, pre = oct }, 7, false)
  334. test_vim_str2nr('-0o054x', flags, { len = 6, num = -44, unum = 44, pre = oct }, 0, false)
  335. test_vim_str2nr('0O054', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 0)
  336. test_vim_str2nr('0O054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  337. test_vim_str2nr('0O054', flags, { len = 0 }, 2)
  338. test_vim_str2nr('0O054', flags, { len = 3, num = 0, unum = 0, pre = OCT }, 3)
  339. test_vim_str2nr('0O054', flags, { len = 4, num = 5, unum = 5, pre = OCT }, 4)
  340. test_vim_str2nr('0O054', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 5)
  341. test_vim_str2nr('0O0548', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 5)
  342. test_vim_str2nr('0O054', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 6)
  343. test_vim_str2nr('0O054x', flags, { len = 0 }, 6)
  344. test_vim_str2nr('0O054x', flags, { len = 0 }, 0)
  345. test_vim_str2nr('0O054x', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 6, false)
  346. test_vim_str2nr('0O054x', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 0, false)
  347. test_vim_str2nr('-0O054', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 0)
  348. test_vim_str2nr('-0O054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  349. test_vim_str2nr('-0O054', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
  350. test_vim_str2nr('-0O054', flags, { len = 0 }, 3)
  351. test_vim_str2nr('-0O054', flags, { len = 4, num = 0, unum = 0, pre = OCT }, 4)
  352. test_vim_str2nr('-0O054', flags, { len = 5, num = -5, unum = 5, pre = OCT }, 5)
  353. test_vim_str2nr('-0O054', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 6)
  354. test_vim_str2nr('-0O0548', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 6)
  355. test_vim_str2nr('-0O054', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 7)
  356. test_vim_str2nr('-0O054x', flags, { len = 0 }, 7)
  357. test_vim_str2nr('-0O054x', flags, { len = 0 }, 0)
  358. test_vim_str2nr('-0O054x', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 7, false)
  359. test_vim_str2nr('-0O054x', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 0, false)
  360. if flags > lib.STR2NR_FORCE then
  361. test_vim_str2nr('-0548', flags, { len = 0 }, 5)
  362. test_vim_str2nr('-0548', flags, { len = 0 }, 0)
  363. test_vim_str2nr('-0548', flags, { len = 4, num = -44, unum = 44, pre = 0 }, 5, false)
  364. test_vim_str2nr('-0548', flags, { len = 4, num = -44, unum = 44, pre = 0 }, 0, false)
  365. test_vim_str2nr('-055', flags, { len = 4, num = -45, unum = 45, pre = 0 }, 0)
  366. else
  367. test_vim_str2nr('-0548', flags, { len = 5, num = -548, unum = 548, pre = 0 }, 5)
  368. test_vim_str2nr('-0548', flags, { len = 5, num = -548, unum = 548, pre = 0 }, 0)
  369. end
  370. end
  371. end)
  372. itp('works with hexadecimal numbers', function()
  373. for _, flags in ipairs({
  374. lib.STR2NR_HEX,
  375. lib.STR2NR_HEX + lib.STR2NR_BIN,
  376. lib.STR2NR_HEX + lib.STR2NR_OCT,
  377. lib.STR2NR_ALL,
  378. lib.STR2NR_FORCE + lib.STR2NR_HEX,
  379. }) do
  380. local hex
  381. local HEX
  382. if flags > lib.STR2NR_FORCE then
  383. hex = 0
  384. HEX = 0
  385. else
  386. hex = ('x'):byte()
  387. HEX = ('X'):byte()
  388. end
  389. -- Check that all digits are recognized
  390. test_vim_str2nr('0x12345', flags, { len = 7, num = 74565, unum = 74565, pre = hex }, 0)
  391. test_vim_str2nr('0x67890', flags, { len = 7, num = 424080, unum = 424080, pre = hex }, 0)
  392. test_vim_str2nr('0xABCDEF', flags, { len = 8, num = 11259375, unum = 11259375, pre = hex }, 0)
  393. test_vim_str2nr('0xabcdef', flags, { len = 8, num = 11259375, unum = 11259375, pre = hex }, 0)
  394. test_vim_str2nr('0x101', flags, { len = 5, num = 257, unum = 257, pre = hex }, 0)
  395. test_vim_str2nr('0x101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  396. test_vim_str2nr('0x101', flags, { len = 0 }, 2)
  397. test_vim_str2nr('0x101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 2, false)
  398. test_vim_str2nr('0x101', flags, { len = 3, num = 1, unum = 1, pre = hex }, 3)
  399. test_vim_str2nr('0x101', flags, { len = 4, num = 16, unum = 16, pre = hex }, 4)
  400. test_vim_str2nr('0x101', flags, { len = 5, num = 257, unum = 257, pre = hex }, 5)
  401. test_vim_str2nr('0x101', flags, { len = 5, num = 257, unum = 257, pre = hex }, 6)
  402. test_vim_str2nr('0x101G', flags, { len = 0 }, 0)
  403. test_vim_str2nr('0x101G', flags, { len = 0 }, 6)
  404. test_vim_str2nr('0x101G', flags, { len = 5, num = 257, unum = 257, pre = hex }, 0, false)
  405. test_vim_str2nr('0x101G', flags, { len = 5, num = 257, unum = 257, pre = hex }, 6, false)
  406. test_vim_str2nr('-0x101', flags, { len = 6, num = -257, unum = 257, pre = hex }, 0)
  407. test_vim_str2nr('-0x101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  408. test_vim_str2nr('-0x101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
  409. test_vim_str2nr('-0x101', flags, { len = 0 }, 3)
  410. test_vim_str2nr('-0x101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 3, false)
  411. test_vim_str2nr('-0x101', flags, { len = 4, num = -1, unum = 1, pre = hex }, 4)
  412. test_vim_str2nr('-0x101', flags, { len = 5, num = -16, unum = 16, pre = hex }, 5)
  413. test_vim_str2nr('-0x101', flags, { len = 6, num = -257, unum = 257, pre = hex }, 6)
  414. test_vim_str2nr('-0x101', flags, { len = 6, num = -257, unum = 257, pre = hex }, 7)
  415. test_vim_str2nr('-0x101G', flags, { len = 0 }, 0)
  416. test_vim_str2nr('-0x101G', flags, { len = 0 }, 7)
  417. test_vim_str2nr('-0x101G', flags, { len = 6, num = -257, unum = 257, pre = hex }, 0, false)
  418. test_vim_str2nr('-0x101G', flags, { len = 6, num = -257, unum = 257, pre = hex }, 7, false)
  419. test_vim_str2nr('0X101', flags, { len = 5, num = 257, unum = 257, pre = HEX }, 0)
  420. test_vim_str2nr('0X101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  421. test_vim_str2nr('0X101', flags, { len = 0 }, 2)
  422. test_vim_str2nr('0X101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 2, false)
  423. test_vim_str2nr('0X101', flags, { len = 3, num = 1, unum = 1, pre = HEX }, 3)
  424. test_vim_str2nr('0X101', flags, { len = 4, num = 16, unum = 16, pre = HEX }, 4)
  425. test_vim_str2nr('0X101', flags, { len = 5, num = 257, unum = 257, pre = HEX }, 5)
  426. test_vim_str2nr('0X101', flags, { len = 5, num = 257, unum = 257, pre = HEX }, 6)
  427. test_vim_str2nr('0X101G', flags, { len = 0 }, 0)
  428. test_vim_str2nr('0X101G', flags, { len = 0 }, 6)
  429. test_vim_str2nr('0X101G', flags, { len = 5, num = 257, unum = 257, pre = HEX }, 0, false)
  430. test_vim_str2nr('0X101G', flags, { len = 5, num = 257, unum = 257, pre = HEX }, 6, false)
  431. test_vim_str2nr('-0X101', flags, { len = 6, num = -257, unum = 257, pre = HEX }, 0)
  432. test_vim_str2nr('-0X101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
  433. test_vim_str2nr('-0X101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
  434. test_vim_str2nr('-0X101', flags, { len = 0 }, 3)
  435. test_vim_str2nr('-0X101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 3, false)
  436. test_vim_str2nr('-0X101', flags, { len = 4, num = -1, unum = 1, pre = HEX }, 4)
  437. test_vim_str2nr('-0X101', flags, { len = 5, num = -16, unum = 16, pre = HEX }, 5)
  438. test_vim_str2nr('-0X101', flags, { len = 6, num = -257, unum = 257, pre = HEX }, 6)
  439. test_vim_str2nr('-0X101', flags, { len = 6, num = -257, unum = 257, pre = HEX }, 7)
  440. test_vim_str2nr('-0X101G', flags, { len = 0 }, 0)
  441. test_vim_str2nr('-0X101G', flags, { len = 0 }, 7)
  442. test_vim_str2nr('-0X101G', flags, { len = 6, num = -257, unum = 257, pre = HEX }, 0, false)
  443. test_vim_str2nr('-0X101G', flags, { len = 6, num = -257, unum = 257, pre = HEX }, 7, false)
  444. if flags > lib.STR2NR_FORCE then
  445. test_vim_str2nr('-101', flags, { len = 4, num = -257, unum = 257, pre = 0 }, 0)
  446. end
  447. end
  448. end)
  449. -- Test_str2nr() in test_functions.vim already tests normal usage
  450. itp('works with weirdly quoted numbers', function()
  451. local flags = lib.STR2NR_DEC + lib.STR2NR_QUOTE
  452. test_vim_str2nr("'027", flags, { len = 0 }, 0)
  453. test_vim_str2nr("'027", flags, { len = 0 }, 0, false)
  454. test_vim_str2nr("1'2'3'4", flags, { len = 7, num = 1234, unum = 1234, pre = 0 }, 0)
  455. -- counter-intuitive, but like Vim, strict=true should partially accept
  456. -- these: (' and - are not alphanumeric)
  457. test_vim_str2nr("7''331", flags, { len = 1, num = 7, unum = 7, pre = 0 }, 0)
  458. test_vim_str2nr("123'x4", flags, { len = 3, num = 123, unum = 123, pre = 0 }, 0)
  459. test_vim_str2nr("1337'", flags, { len = 4, num = 1337, unum = 1337, pre = 0 }, 0)
  460. test_vim_str2nr("-'", flags, { len = 1, num = 0, unum = 0, pre = 0 }, 0)
  461. flags = lib.STR2NR_HEX + lib.STR2NR_QUOTE
  462. local hex = ('x'):byte()
  463. test_vim_str2nr("0x'abcd", flags, { len = 0 }, 0)
  464. test_vim_str2nr("0x'abcd", flags, { len = 1, num = 0, unum = 0, pre = 0 }, 0, false)
  465. test_vim_str2nr("0xab''cd", flags, { len = 4, num = 171, unum = 171, pre = hex }, 0)
  466. end)
  467. end)