Skip to content

Commit

Permalink
ffiUtil: Don't branch on ffi.os at runtime (#1583)
Browse files Browse the repository at this point in the history
We're unlikely to change OS at runtime ;o).

Includes a few drive-by simplifications (no need to cast a char[] to char*, that's only needed for Lua strings; no need for ffi.copy for a Lua -> C string conversion, ffi.new handles constructors).
  • Loading branch information
NiLuJe committed Feb 17, 2023
1 parent cea0a73 commit 96b2a16
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 30 deletions.
6 changes: 2 additions & 4 deletions ffi/koptcontext.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ function KOPTContext_mt.__index:setLineSpacing(line_spacing) self.line_spacing =
function KOPTContext_mt.__index:setWordSpacing(word_spacing) self.word_spacing = word_spacing end
--- @fixme: Update the APIs to make KOPTContext's language field a const char*, so that we can just pass it a Lua string.
function KOPTContext_mt.__index:setLanguage(language)
self.language = ffi.new("char[?]", #language + 1)
ffi.copy(self.language, language)
self.language = ffi.new("char[?]", #language + 1, language)
end

function KOPTContext_mt.__index:setDebug() self.debug = 1 end
Expand Down Expand Up @@ -732,8 +731,7 @@ function KOPTContext.fromtable(context)
context.nnai.array), context.nnai.n, C.L_COPY)
end
if context.language then
kc.language = ffi.new("char[?]", #context.language + 1)
ffi.copy(kc.language, context.language)
kc.language = ffi.new("char[?]", #context.language + 1, context.language)
end

k2pdfopt.bmp_init(kc.src)
Expand Down
67 changes: 41 additions & 26 deletions ffi/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ function util.strcoll(str1, str2)
local strcoll_func = strcoll

-- Some devices lack compiled locales (Hi, Kobo!), preventing strcoll from behaving sanely. See issue koreader/koreader#686
if jit.os == "Linux" and C.access("/usr/lib/locale/locale-archive", C.F_OK) ~= 0 then
if ffi.os == "Linux" and C.access("/usr/lib/locale/locale-archive", C.F_OK) ~= 0 then
strcoll_func = function(a, b)
return a < b
end
Expand All @@ -152,46 +152,55 @@ function util.strcoll(str1, str2)
end

--- Wrapper for C.realpath.
function util.realpath(path)
local buffer = ffi.new("char[?]", C.PATH_MAX)
if ffi.os == "Windows" then
if ffi.os == "Windows" then
function util.realpath(path)
local buffer = ffi.new("char[?]", C.PATH_MAX)
if C.GetFullPathNameA(path, C.PATH_MAX, buffer, nil) ~= 0 then
return ffi.string(buffer)
end
else
end
else
function util.realpath(path)
local buffer = ffi.new("char[?]", C.PATH_MAX)
if C.realpath(path, buffer) ~= nil then
return ffi.string(buffer)
end
end
end

--- Wrapper for C.basename.
function util.basename(path)
local ptr = ffi.cast("uint8_t *", path)
if ffi.os == "Windows" then
if ffi.os == "Windows" then
function util.basename(path)
local ptr = ffi.cast("uint8_t *", path)
return ffi.string(C.PathFindFileNameA(ptr))
else
return ffi.string(C.basename(ptr))
end
else
function util.basename(in_path)
-- We have no guarantee of getting a GNU implementation of basename;
-- POSIX compliant implementations *will* modify input, so, always make a copy.
local path = ffi.new("char[?]", #in_path + 1, in_path)
return ffi.string(C.basename(path))
end
end

--- Wrapper for C.dirname.
function util.dirname(in_path)
--[[
Both PathRemoveFileSpec and dirname will change original input string, so
we need to make a copy.
--]]
local path = ffi.new("char[?]", #in_path + 1)
ffi.copy(path, in_path)
local ptr = ffi.cast("uint8_t *", path)
if ffi.os == "Windows" then
if C.PathRemoveFileSpec(ptr) then
return ffi.string(ptr)
if ffi.os == "Windows" then
function util.dirname(in_path)
--[[
Both PathRemoveFileSpec and dirname will change original input string,
so we need to make a copy.
--]]
local path = ffi.new("char[?]", #in_path + 1, in_path)
if C.PathRemoveFileSpec(path) then
return ffi.string(path)
else
return path
end
else
return ffi.string(C.dirname(ptr))
end
else
function util.dirname(in_path)
local path = ffi.new("char[?]", #in_path + 1, in_path)
return ffi.string(C.dirname(path))
end
end

Expand Down Expand Up @@ -593,8 +602,14 @@ function util.ffiLoadCandidates(candidates)
end

--- Returns true if isWindows…
function util.isWindows()
return ffi.os == "Windows"
if ffi.os == "Windows" then
function util.isWindows()
return true
end
else
function util.isWindows()
return false
end
end

local isAndroid = nil
Expand All @@ -618,7 +633,7 @@ function util.haveSDL2()

if haveSDL2 == nil then
local candidates
if jit.os == "OSX" then
if ffi.os == "OSX" then
candidates = {"libs/libSDL2.dylib", "SDL2"}
else
candidates = {"SDL2", "libSDL2-2.0.so", "libSDL2-2.0.so.0"}
Expand Down

0 comments on commit 96b2a16

Please sign in to comment.