From cd91f72843359c5305842fa8afbec4a2d72629fa Mon Sep 17 00:00:00 2001 From: Albert Krewinkel Date: Wed, 17 Nov 2021 08:47:30 +0100 Subject: Lua: set `lpeg`, `re` as globals; allow shared lib access via require The `lpeg` and `re` modules are loaded into globals of the respective name, but they are not necessarily registered as loaded packages. This ensures that - the built-in library versions are preferred when setting the globals, - a shared library is used if pandoc has been compiled without `lpeg`, and - the `require` mechanism can be used to load the shared library if available, falling back to the internal version if possible and necessary. --- src/Text/Pandoc/Lua/Init.hs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/Text/Pandoc/Lua/Init.hs b/src/Text/Pandoc/Lua/Init.hs index bf87f0a41..72a06f556 100644 --- a/src/Text/Pandoc/Lua/Init.hs +++ b/src/Text/Pandoc/Lua/Init.hs @@ -47,7 +47,8 @@ initLuaState = do liftPandocLua Lua.openlibs installPandocPackageSearcher initPandocModule - requireGlobalModules + installLpegSearcher + setGlobalModules loadInitScript "init.lua" where initPandocModule :: PandocLua () @@ -76,33 +77,32 @@ initLuaState = do PandocLuaError msg -> msg _ -> T.pack $ show err - requireGlobalModules :: PandocLua () - requireGlobalModules = liftPandocLua $ + setGlobalModules :: PandocLua () + setGlobalModules = liftPandocLua $ forM_ [ ("lpeg", LPeg.luaopen_lpeg_ptr) , ("re", LPeg.luaopen_re_ptr) ] $ \(pkgname, luaopen) -> do - -- Try loading via the normal package loading mechanism, and - -- fall back to manual module loading if the normal mechanism - -- fails. This means the system installation of the package, - -- should it be available, is preferred. - Lua.getglobal "require" - Lua.pushName pkgname - Lua.pcall 1 1 Nothing >>= \case + Lua.pushcfunction luaopen + Lua.pcall 0 1 Nothing >>= \case OK -> pure () -- all good, loading succeeded - _ -> do -- default mechanism failed, load included lib + _ -> do -- built-in library failed, load system lib Lua.pop 1 -- ignore error message - Lua.pushcfunction luaopen - Lua.call 0 1 -- Throws an exception if loading failed again! - -- Success. Add module to table @_LOADED@ in the registry - _ <- Lua.getfield Lua.registryindex Lua.loaded - Lua.pushvalue (Lua.nth 2) -- push module to top - Lua.setfield (Lua.nth 2) pkgname - Lua.pop 1 -- pop _LOADED + -- Try loading via the normal package loading mechanism. + Lua.getglobal "require" + Lua.pushName pkgname + Lua.call 1 1 -- Throws an exception if loading failed again! -- Module on top of stack. Register as global Lua.setglobal pkgname + installLpegSearcher :: PandocLua () + installLpegSearcher = liftPandocLua $ do + Lua.getglobal' "package.searchers" + Lua.pushHaskellFunction $ Lua.state >>= liftIO . LPeg.lpeg_searcher + Lua.rawseti (Lua.nth 2) . (+1) . fromIntegral =<< Lua.rawlen (Lua.nth 2) + Lua.pop 1 -- remove 'package.searchers' from stack + -- | AST elements are marshaled via normal constructor functions in the -- @pandoc@ module. However, accessing Lua globals from Haskell is -- expensive (due to error handling). Accessing the Lua registry is much -- cgit v1.2.3