-- | -- Module : EndOfExe2 -- Copyright : (c) Oleksandr Zhabenko 2019-2024 -- License : MIT -- Maintainer : oleksandr.zhabenko@yahoo.com -- -- A small library to deal with executable endings. Uses a Maybe data representation inside an IO monad. -- -- It is a fork of now deprecated library [mmsyn3](https://hackage.haskell.org/package/mmsyn3). {-# LANGUAGE NoImplicitPrelude #-} {-# OPTIONS_HADDOCK -show-extensions #-} module EndOfExe2 where import GHC.Base import GHC.List import qualified System.Directory as D (findExecutable) import Data.Maybe (isJust,isNothing,fromJust) import System.IO.Unsafe (unsafePerformIO,unsafeDupablePerformIO) -- | Can be used instead of 'System.Info.os' to check whether the executable ends in \".exe\". The function returns 'IO' 'Nothing' if there is neither -- @ys@ nor @(ys ++ ".exe")@ names for executables in the search path. It can also search in other locations and its behaviour is OS dependent. For more information, please, refer to the link: -- For more information, how the executable is searched, see also the following address: maybeEndOfExecutable :: String -> IO (Maybe String) maybeEndOfExecutable ys = do xs <- D.findExecutable ys if isJust xs then return xs else do zs <- D.findExecutable (ys ++ ".exe") if isJust zs then return zs else return Nothing -- | The function 'endOfExe' returns 'IO' \"\" if no executable found by 'D.findExecutable'. Otherwise, it returns its path in the 'IO' monad. endOfExe :: String -> IO String endOfExe ys = do xs <- D.findExecutable ys if isJust xs then return . fromJust $ xs else do zs <- D.findExecutable (ys ++ ".exe") if isJust zs then return . fromJust $ zs else return "" -- | Gets the proper name of the executable in the system (it must be seen in the directories in the @PATH@ variable). -- Further you can adopt it to be used -- inside the 'System.Process.callCommand' as the name of the executable showE :: String -> Maybe String showE xs | null xs = Nothing | otherwise = unsafePerformIO . maybeEndOfExecutable $ xs {-# INLINE showE #-} -- | Similar to 'showE' but uses 'unsafeDupablePerformIO', which is more efficient, but for the multiprocessor can lead to executing the IO action multiple times. showEDup :: String -> Maybe String showEDup xs | null xs = Nothing | otherwise = unsafeDupablePerformIO . maybeEndOfExecutable $ xs {-# INLINE showEDup #-} -- | If executable not found, then returns empty 'String'. showE0 :: String -> String showE0 xs | null xs = "" | otherwise = unsafePerformIO . endOfExe $ xs {-# INLINE showE0 #-} -- | If executable not found, then returns empty 'String'. Uses 'unsafeDupablePerformIO'. showE0Dup :: String -> String showE0Dup xs | null xs = "" | otherwise = unsafeDupablePerformIO . endOfExe $ xs {-# INLINE showE0Dup #-}