mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-23 18:02:54 -06:00
more the exception handling in a single place
This commit is contained in:
@@ -47,14 +47,13 @@ module PGF2 (-- * PGF
|
|||||||
PGFError(..)
|
PGFError(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Exception(Exception,throwIO,mask_,bracket)
|
import Control.Exception(mask_,bracket)
|
||||||
import System.IO.Unsafe(unsafePerformIO)
|
import System.IO.Unsafe(unsafePerformIO)
|
||||||
import PGF2.Expr
|
import PGF2.Expr
|
||||||
import PGF2.FFI
|
import PGF2.FFI
|
||||||
|
|
||||||
import Foreign
|
import Foreign
|
||||||
import Foreign.C
|
import Foreign.C
|
||||||
import Data.Typeable
|
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Data.IORef
|
import Data.IORef
|
||||||
|
|
||||||
@@ -67,20 +66,10 @@ type ConcName = String -- ^ Name of concrete syntax
|
|||||||
readPGF :: FilePath -> IO PGF
|
readPGF :: FilePath -> IO PGF
|
||||||
readPGF fpath =
|
readPGF fpath =
|
||||||
withCString fpath $ \c_fpath ->
|
withCString fpath $ \c_fpath ->
|
||||||
allocaBytes (#size PgfExn) $ \c_exn ->
|
|
||||||
mask_ $ do
|
mask_ $ do
|
||||||
c_pgf <- pgf_read_pgf c_fpath c_exn
|
c_pgf <- withPgfExn fpath (pgf_read_pgf c_fpath)
|
||||||
ex_type <- (#peek PgfExn, type) c_exn :: IO (#type PgfExnType)
|
fptr <- newForeignPtr pgf_free_fptr c_pgf
|
||||||
if ex_type == (#const PGF_EXN_NONE)
|
|
||||||
then do fptr <- newForeignPtr pgf_free_fptr c_pgf
|
|
||||||
return (PGF fptr Map.empty)
|
return (PGF fptr Map.empty)
|
||||||
else if ex_type == (#const PGF_EXN_SYSTEM_ERROR)
|
|
||||||
then do errno <- (#peek PgfExn, code) c_exn
|
|
||||||
ioError (errnoToIOError "readPGF" (Errno errno) Nothing (Just fpath))
|
|
||||||
else do c_msg <- (#peek PgfExn, msg) c_exn
|
|
||||||
msg <- peekCString c_msg
|
|
||||||
free c_msg
|
|
||||||
throwIO (PGFError msg)
|
|
||||||
|
|
||||||
-- | Reads a PGF file and stores the unpacked data in an NGF file
|
-- | Reads a PGF file and stores the unpacked data in an NGF file
|
||||||
-- ready to be shared with other process, or used for quick startup.
|
-- ready to be shared with other process, or used for quick startup.
|
||||||
@@ -90,20 +79,10 @@ bootNGF :: FilePath -> FilePath -> IO PGF
|
|||||||
bootNGF pgf_path ngf_path =
|
bootNGF pgf_path ngf_path =
|
||||||
withCString pgf_path $ \c_pgf_path ->
|
withCString pgf_path $ \c_pgf_path ->
|
||||||
withCString ngf_path $ \c_ngf_path ->
|
withCString ngf_path $ \c_ngf_path ->
|
||||||
allocaBytes (#size PgfExn) $ \c_exn ->
|
|
||||||
mask_ $ do
|
mask_ $ do
|
||||||
c_pgf <- pgf_boot_ngf c_pgf_path c_ngf_path c_exn
|
c_pgf <- withPgfExn pgf_path (pgf_boot_ngf c_pgf_path c_ngf_path)
|
||||||
ex_type <- (#peek PgfExn, type) c_exn :: IO (#type PgfExnType)
|
fptr <- newForeignPtr pgf_free_fptr c_pgf
|
||||||
if ex_type == (#const PGF_EXN_NONE)
|
|
||||||
then do fptr <- newForeignPtr pgf_free_fptr c_pgf
|
|
||||||
return (PGF fptr Map.empty)
|
return (PGF fptr Map.empty)
|
||||||
else if ex_type == (#const PGF_EXN_SYSTEM_ERROR)
|
|
||||||
then do errno <- (#peek PgfExn, code) c_exn
|
|
||||||
ioError (errnoToIOError "bootNGF" (Errno errno) Nothing (Just pgf_path))
|
|
||||||
else do c_msg <- (#peek PgfExn, msg) c_exn
|
|
||||||
msg <- peekCString c_msg
|
|
||||||
free c_msg
|
|
||||||
throwIO (PGFError msg)
|
|
||||||
|
|
||||||
-- | Tries to read the grammar from an already booted NGF file.
|
-- | Tries to read the grammar from an already booted NGF file.
|
||||||
-- If the file does not exist then a new one is created, and the
|
-- If the file does not exist then a new one is created, and the
|
||||||
@@ -112,20 +91,10 @@ bootNGF pgf_path ngf_path =
|
|||||||
readNGF :: FilePath -> IO PGF
|
readNGF :: FilePath -> IO PGF
|
||||||
readNGF fpath =
|
readNGF fpath =
|
||||||
withCString fpath $ \c_fpath ->
|
withCString fpath $ \c_fpath ->
|
||||||
allocaBytes (#size PgfExn) $ \c_exn ->
|
|
||||||
mask_ $ do
|
mask_ $ do
|
||||||
c_pgf <- pgf_read_ngf c_fpath c_exn
|
c_pgf <- withPgfExn fpath (pgf_read_ngf c_fpath)
|
||||||
ex_type <- (#peek PgfExn, type) c_exn :: IO (#type PgfExnType)
|
fptr <- newForeignPtr pgf_free_fptr c_pgf
|
||||||
if ex_type == (#const PGF_EXN_NONE)
|
|
||||||
then do fptr <- newForeignPtr pgf_free_fptr c_pgf
|
|
||||||
return (PGF fptr Map.empty)
|
return (PGF fptr Map.empty)
|
||||||
else if ex_type == (#const PGF_EXN_SYSTEM_ERROR)
|
|
||||||
then do errno <- (#peek PgfExn, code) c_exn
|
|
||||||
ioError (errnoToIOError "readPGF" (Errno errno) Nothing (Just fpath))
|
|
||||||
else do c_msg <- (#peek PgfExn, msg) c_exn
|
|
||||||
msg <- peekCString c_msg
|
|
||||||
free c_msg
|
|
||||||
throwIO (PGFError msg)
|
|
||||||
|
|
||||||
-- | The abstract language name is the name of the top-level
|
-- | The abstract language name is the name of the top-level
|
||||||
-- abstract module
|
-- abstract module
|
||||||
@@ -187,11 +156,10 @@ categories p =
|
|||||||
unsafePerformIO $ do
|
unsafePerformIO $ do
|
||||||
ref <- newIORef []
|
ref <- newIORef []
|
||||||
(allocaBytes (#size PgfItor) $ \itor ->
|
(allocaBytes (#size PgfItor) $ \itor ->
|
||||||
allocaBytes (#size PgfExn) $ \c_exn ->
|
|
||||||
bracket (wrapItorCallback (getCategories ref)) freeHaskellFunPtr $ \fptr ->
|
bracket (wrapItorCallback (getCategories ref)) freeHaskellFunPtr $ \fptr ->
|
||||||
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
||||||
(#poke PgfItor, fn) itor fptr
|
(#poke PgfItor, fn) itor fptr
|
||||||
pgf_iter_categories p_pgf itor c_exn
|
withPgfExn "" (pgf_iter_categories p_pgf itor)
|
||||||
cs <- readIORef ref
|
cs <- readIORef ref
|
||||||
return (reverse cs))
|
return (reverse cs))
|
||||||
where
|
where
|
||||||
@@ -244,11 +212,10 @@ functions p =
|
|||||||
unsafePerformIO $ do
|
unsafePerformIO $ do
|
||||||
ref <- newIORef []
|
ref <- newIORef []
|
||||||
(allocaBytes (#size PgfItor) $ \itor ->
|
(allocaBytes (#size PgfItor) $ \itor ->
|
||||||
allocaBytes (#size PgfExn) $ \c_exn ->
|
|
||||||
bracket (wrapItorCallback (getFunctions ref)) freeHaskellFunPtr $ \fptr ->
|
bracket (wrapItorCallback (getFunctions ref)) freeHaskellFunPtr $ \fptr ->
|
||||||
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
||||||
(#poke PgfItor, fn) itor fptr
|
(#poke PgfItor, fn) itor fptr
|
||||||
pgf_iter_functions p_pgf itor c_exn
|
withPgfExn "" (pgf_iter_functions p_pgf itor)
|
||||||
fs <- readIORef ref
|
fs <- readIORef ref
|
||||||
return (reverse fs))
|
return (reverse fs))
|
||||||
where
|
where
|
||||||
@@ -265,11 +232,10 @@ functionsByCat p cat =
|
|||||||
ref <- newIORef []
|
ref <- newIORef []
|
||||||
(withText cat $ \c_cat ->
|
(withText cat $ \c_cat ->
|
||||||
allocaBytes (#size PgfItor) $ \itor ->
|
allocaBytes (#size PgfItor) $ \itor ->
|
||||||
allocaBytes (#size PgfExn) $ \c_exn ->
|
|
||||||
bracket (wrapItorCallback (getFunctions ref)) freeHaskellFunPtr $ \fptr ->
|
bracket (wrapItorCallback (getFunctions ref)) freeHaskellFunPtr $ \fptr ->
|
||||||
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
||||||
(#poke PgfItor, fn) itor fptr
|
(#poke PgfItor, fn) itor fptr
|
||||||
pgf_iter_functions_by_cat p_pgf c_cat itor c_exn
|
withPgfExn "" (pgf_iter_functions_by_cat p_pgf c_cat itor)
|
||||||
fs <- readIORef ref
|
fs <- readIORef ref
|
||||||
return (reverse fs))
|
return (reverse fs))
|
||||||
where
|
where
|
||||||
@@ -348,11 +314,3 @@ readType str =
|
|||||||
freeStablePtr c_ty
|
freeStablePtr c_ty
|
||||||
return (Just ty)
|
return (Just ty)
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
-- Exceptions
|
|
||||||
|
|
||||||
newtype PGFError = PGFError String
|
|
||||||
deriving (Show, Typeable)
|
|
||||||
|
|
||||||
instance Exception PGFError
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ import GHC.Exts
|
|||||||
import GHC.Prim
|
import GHC.Prim
|
||||||
import GHC.Integer.Logarithms
|
import GHC.Integer.Logarithms
|
||||||
import Data.Word
|
import Data.Word
|
||||||
|
import Data.Typeable
|
||||||
import Foreign
|
import Foreign
|
||||||
import Foreign.C
|
import Foreign.C
|
||||||
import Foreign.Ptr
|
import Foreign.Ptr
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Control.Exception(bracket,mask_)
|
import Control.Exception(Exception,bracket,mask_,throwIO)
|
||||||
import System.IO.Unsafe(unsafePerformIO)
|
import System.IO.Unsafe(unsafePerformIO)
|
||||||
|
|
||||||
import PGF2.Expr
|
import PGF2.Expr
|
||||||
@@ -100,6 +101,9 @@ foreign import ccall "pgf/expr.h pgf_function_is_constructor"
|
|||||||
foreign import ccall "pgf/expr.h pgf_function_is_constructor"
|
foreign import ccall "pgf/expr.h pgf_function_is_constructor"
|
||||||
pgf_function_prob :: Ptr PgfPGF -> Ptr PgfText -> IO (#type prob_t)
|
pgf_function_prob :: Ptr PgfPGF -> Ptr PgfText -> IO (#type prob_t)
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- Texts
|
||||||
|
|
||||||
peekText :: Ptr PgfText -> IO String
|
peekText :: Ptr PgfText -> IO String
|
||||||
peekText ptr =
|
peekText ptr =
|
||||||
alloca $ \pptr -> do
|
alloca $ \pptr -> do
|
||||||
@@ -167,6 +171,32 @@ utf8Length s = count 0 s
|
|||||||
where
|
where
|
||||||
ucs = fromEnum x
|
ucs = fromEnum x
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- Exceptions
|
||||||
|
|
||||||
|
newtype PGFError = PGFError String
|
||||||
|
deriving (Show, Typeable)
|
||||||
|
|
||||||
|
instance Exception PGFError
|
||||||
|
|
||||||
|
withPgfExn fpath f =
|
||||||
|
allocaBytes (#size PgfExn) $ \c_exn -> do
|
||||||
|
res <- f c_exn
|
||||||
|
ex_type <- (#peek PgfExn, type) c_exn :: IO (#type PgfExnType)
|
||||||
|
case ex_type of
|
||||||
|
(#const PGF_EXN_NONE) -> return res
|
||||||
|
(#const PGF_EXN_SYSTEM_ERROR) -> do
|
||||||
|
errno <- (#peek PgfExn, code) c_exn
|
||||||
|
ioError (errnoToIOError "readPGF" (Errno errno) Nothing (Just fpath))
|
||||||
|
(#const PGF_EXN_PGF_ERROR) -> do
|
||||||
|
c_msg <- (#peek PgfExn, msg) c_exn
|
||||||
|
msg <- peekCString c_msg
|
||||||
|
free c_msg
|
||||||
|
throwIO (PGFError msg)
|
||||||
|
_ -> throwIO (PGFError "An unidentified error occurred")
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- Marshalling
|
||||||
|
|
||||||
type CBindType = (#type PgfBindType)
|
type CBindType = (#type PgfBindType)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user