Sergey,


On 21.08.2024 11:58, Sergey Kaplun wrote:
This patch moves the aforementioned test from the <misc> to the
<lib/base> directory, includes it in <index>, and names the subtest.

Also, the NaN checks are skipped for parsing via `strtod()`, since
LuaJIT uses canonicalized NaNs, which are equal to -NaN
(0xfff8000000000000).

Part of tarantool/tarantool#9398
---
thanks for the patch! LGTM
 test/LuaJIT-tests/lib/base/index              |  1 +
 .../{misc => lib/base}/tonumber_scan.lua      | 58 ++++++++++++-------
 2 files changed, 37 insertions(+), 22 deletions(-)
 rename test/LuaJIT-tests/{misc => lib/base}/tonumber_scan.lua (93%)

diff --git a/test/LuaJIT-tests/lib/base/index b/test/LuaJIT-tests/lib/base/index
index 942c53c0..bef5dcb4 100644
--- a/test/LuaJIT-tests/lib/base/index
+++ b/test/LuaJIT-tests/lib/base/index
@@ -8,4 +8,5 @@ pairs.lua
 pcall_jit.lua
 select.lua
 tonumber_tostring.lua
+tonumber_scan.lua +ffi
 xpcall_jit.lua +compat5.2
diff --git a/test/LuaJIT-tests/misc/tonumber_scan.lua b/test/LuaJIT-tests/lib/base/tonumber_scan.lua
similarity index 93%
rename from test/LuaJIT-tests/misc/tonumber_scan.lua
rename to test/LuaJIT-tests/lib/base/tonumber_scan.lua
index 78e1ca3e..e2dcd4d0 100644
--- a/test/LuaJIT-tests/misc/tonumber_scan.lua
+++ b/test/LuaJIT-tests/lib/base/tonumber_scan.lua
@@ -150,31 +150,45 @@ local function tohex64(x)
   return "0x"..bit.tohex(tonumber(x/2LL^32))..bit.tohex(tonumber(x%2LL^32)).."ULL"
 end
 
-local conv = tonumber
+local e = ffi.new("char *[1]")
+local u = ffi.new("union { double d; uint64_t x; }")
 
-if arg and arg[1] == "strtod" then
-  local e = ffi.new("char *[1]")
-  function conv(s)
-    local d = ffi.C.strtod(s, e)
-    return (e[0][0] == 0 and #s ~= 0) and d or nil
+local function test_conv(conv, skip_nan)
+  for i = 1, #t, 2 do
+    local y, s = t[i], t[i + 1]
+    if s:lower():match('nan') and skip_nan then
+      -- LuaJIT uses canonicalized NaNs.
+      -- -NaN = 0xfff8000000000000.
+      -- Hence, `strtod()` yields a different value here.
+      goto continue
+    end
+    local d = conv(s)
+    local ok
+    if d == nil then
+      ok = (y == false)
+    else
+      u.d = d
+      ok = (y == u.x)
+    end
+    if not ok then
+      error(string.format(
+        "FAIL: '%s'\n\tGOT: %s\n\tOK:  %s",
+        s,
+        d and tohex64(u.x) or "nil",
+        y and tohex64(y) or "nil", "\n\n"
+      ))
+    end
+    ::continue::
   end
 end
 
-local u = ffi.new("union { double d; uint64_t x; }")
-
-for i=1,#t,2 do
-  local y, s = t[i], t[i+1]
-  local d = conv(s)
-  local ok
-  if d == nil then
-    ok = (y == false)
-  else
-    u.d = d
-    ok = (y == u.x)
-  end
-  if not ok then
-    io.write('FAIL: "', s, '"\n GOT: ', d and tohex64(u.x) or "nil", "   OK: ", y and tohex64(y) or "nil", "\n\n")
---      print("  "..tohex64(u.x)..", \""..s.."\",")
-  end
+do --- tonumber parsing
+  test_conv(tonumber)
 end
 
+do --- strtod parsing
+  test_conv(function(s)
+    local d = ffi.C.strtod(s, e)
+    return (e[0][0] == 0 and #s ~= 0) and d or nil
+  end, true)
+end