A haskell IRC bot because who doesn't need one
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

56 satır
1.7KB

  1. {-# LANGUAGE MagicHash #-}
  2. {-# LANGUAGE UnboxedTuples #-}
  3. module IRC.Plugins.Loader ( load ) where
  4. import qualified Data.HashMap.Lazy as M
  5. import Control.Exception ( catch, ErrorCall )
  6. import GHC.Exts ( addrToAny# )
  7. import GHC.Ptr ( Ptr(..) )
  8. import System.Info ( os, arch )
  9. import GHCi.ObjLink
  10. import Encoding
  11. type PluginSet = M.HashMap String Plugin
  12. data Plugin = Plugin { pluginEvent :: String, -- e.g. PRIVMSG
  13. pluginEntry :: Int }
  14. load :: PluginSet -> String -> IO (Either String PluginSet)
  15. load set path = do
  16. initObjLinker RetainCAFs
  17. loadObj "Plugin.o"
  18. _ret <- resolveObjs
  19. ptr <- lookupSymbol (mangleSymbol Nothing "Plugin" "f")
  20. case ptr of
  21. Nothing -> return $ Left "Couldn’t load symbol"
  22. Just (Ptr addr) -> case addrToAny# addr of
  23. (# f #) -> return $ Right f
  24. unload :: PluginSet -> String -> IO PluginSet
  25. unload set plugin = catch unloadPlugin exceptionHandler
  26. where exceptionHandler :: ErrorCall -> IO PluginSet
  27. exceptionHandler _ = return set
  28. unloadPlugin :: IO PluginSet
  29. unloadPlugin = do
  30. unloadObj $ plugin <> ".o"
  31. return $ M.delete plugin set
  32. mangleSymbol :: Maybe String -> String -> String -> String
  33. mangleSymbol pkg module' valsym =
  34. prefixUnderscore <>
  35. maybe "" (\p -> zEncodeString p <> "_") pkg <>
  36. zEncodeString module' <> "_" <> zEncodeString valsym <> "_closure"
  37. prefixUnderscore :: String
  38. prefixUnderscore =
  39. case (os,arch) of
  40. ("mingw32","x86_64") -> ""
  41. ("cygwin","x86_64") -> ""
  42. ("mingw32",_) -> "_"
  43. ("darwin",_) -> "_"
  44. ("cygwin",_) -> "_"
  45. _ -> ""