elua: slight optimization of format func

This commit is contained in:
Daniel Kolesa 2014-05-09 11:29:49 +01:00 committed by Daniel Kolesa
parent 006a49ddda
commit 8738ca957d
1 changed files with 40 additions and 24 deletions

View File

@ -1,6 +1,14 @@
-- elua core utilities used in other modules -- elua core utilities used in other modules
local ffi = require("ffi") local ffi = require("ffi")
local cast = ffi.cast
ffi.cdef [[
int isalnum(int c);
int isdigit(int c);
]]
local C = ffi.C
local M = {} local M = {}
@ -158,42 +166,48 @@ end
-- string fmt -- string fmt
local char = string.char
local tconc = table.concat local tconc = table.concat
local fmt = string.format local fmt = string.format
local pcall = pcall local pcall = pcall
local error = error local error = error
local type = type local type = type
getmetatable("").__mod = function(s, params) local bytes = { ("cdeEfgGiopuxXsq"):byte() }
for i, v in ipairs(bytes) do bytes[v] = true end
getmetatable("").__mod = function(fmts, params)
if not fmts then return nil end
if type(params) ~= "table" then params = { params } end if type(params) ~= "table" then params = { params } end
local iter = s:gmatch(".") local s = cast("const char*", fmts)
local buf = {} local buf = {}
local c = iter() local c
c, s = s[0], s + 1
local argn = 1 local argn = 1
while c do while c ~= 0 do
if c == "%" then if c == 37 then -- %
c = iter() c, s = s[0], s + 1
local nbuf = {} local nbuf = {}
while c and c:match("%w") do while c ~= 0 and C.isalnum(c) ~= 0 do
nbuf[#nbuf + 1] = c nbuf[#nbuf + 1] = c
c = iter() c, s = s[0], s + 1
end end
if c == "$" then if c == 36 then -- $
c = iter() c, s = s[0], s + 1
local n = tconc(nbuf) local n = char(unpack(nbuf))
nbuf = {} nbuf = {}
while c:match("[-0-9%.]") do while C.isdigit(c) ~= 0 or c == 45 or c == 46 do -- -, .
nbuf[#nbuf + 1] = c nbuf[#nbuf + 1] = c
c = iter() c, s = s[0], s + 1
end end
if not c:match("[cdeEfgGiopuxXsq]") then if bytes[c] then
buf[#buf + 1] = n buf[#buf + 1] = n
buf[#buf + 1] = "$" buf[#buf + 1] = "$"
buf[#buf + 1] = c buf[#buf + 1] = char(c)
else else
nbuf[#nbuf + 1] = c nbuf[#nbuf + 1] = c
local idx = tonumber(n) or n local idx = tonumber(n) or n
local stat, val = pcall(fmt, "%" .. tconc(nbuf), local stat, val = pcall(fmt, "%" .. char(unpack(nbuf)),
params[idx]) params[idx])
if stat then if stat then
buf[#buf + 1] = val buf[#buf + 1] = val
@ -206,24 +220,26 @@ getmetatable("").__mod = function(s, params)
end end
end end
else else
while c and c:match("[-0-9%.cdeEfgGiopuxXsq]") do while c ~= 0 and (bytes[c] or C.isdigit(c) ~= 0
or c == 45 or c == 46) do
nbuf[#nbuf + 1] = c nbuf[#nbuf + 1] = c
c = iter() c, s = s[0], s + 1
end end
local stat, val = pcall(fmt, "%" .. tconc(nbuf), params[argn]) local stat, val = pcall(fmt, "%" .. char(unpack(nbuf)),
params[argn])
if stat then if stat then
buf[#buf + 1] = val buf[#buf + 1] = val
else else
error("bad argument #" .. argn .. " to '%' " error("bad argument #" .. argn .. " to '%' "
.. val:match("%(.+%)"), 2) .. val:match("%(.+%)"), 2)
end end
if c then buf[#buf + 1] = c end if c then buf[#buf + 1] = char(c) end
argn = argn + 1 argn = argn + 1
end end
else else
buf[#buf + 1] = c buf[#buf + 1] = char(c)
end end
c = iter() c, s = s[0], s + 1
end end
return tconc(buf) return tconc(buf)
end end