{-# LANGUAGE ExistentialQuantification, DeriveDataTypeable #-}
module Language.C.Data.Error (
ErrorLevel(..), isHardError,
Error(..), errorPos, errorLevel, errorMsgs,
CError(..),
ErrorInfo(..),showError,showErrorInfo,mkErrorInfo,
UnsupportedFeature, unsupportedFeature, unsupportedFeature_,
UserError, userErr,
internalErr,
)
where
import Data.Typeable
import Language.C.Data.Node
import Language.C.Data.Position
data ErrorLevel = LevelWarn
| LevelError
| LevelFatal
deriving (ErrorLevel -> ErrorLevel -> Bool
(ErrorLevel -> ErrorLevel -> Bool)
-> (ErrorLevel -> ErrorLevel -> Bool) -> Eq ErrorLevel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ErrorLevel -> ErrorLevel -> Bool
$c/= :: ErrorLevel -> ErrorLevel -> Bool
== :: ErrorLevel -> ErrorLevel -> Bool
$c== :: ErrorLevel -> ErrorLevel -> Bool
Eq, Eq ErrorLevel
Eq ErrorLevel =>
(ErrorLevel -> ErrorLevel -> Ordering)
-> (ErrorLevel -> ErrorLevel -> Bool)
-> (ErrorLevel -> ErrorLevel -> Bool)
-> (ErrorLevel -> ErrorLevel -> Bool)
-> (ErrorLevel -> ErrorLevel -> Bool)
-> (ErrorLevel -> ErrorLevel -> ErrorLevel)
-> (ErrorLevel -> ErrorLevel -> ErrorLevel)
-> Ord ErrorLevel
ErrorLevel -> ErrorLevel -> Bool
ErrorLevel -> ErrorLevel -> Ordering
ErrorLevel -> ErrorLevel -> ErrorLevel
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ErrorLevel -> ErrorLevel -> ErrorLevel
$cmin :: ErrorLevel -> ErrorLevel -> ErrorLevel
max :: ErrorLevel -> ErrorLevel -> ErrorLevel
$cmax :: ErrorLevel -> ErrorLevel -> ErrorLevel
>= :: ErrorLevel -> ErrorLevel -> Bool
$c>= :: ErrorLevel -> ErrorLevel -> Bool
> :: ErrorLevel -> ErrorLevel -> Bool
$c> :: ErrorLevel -> ErrorLevel -> Bool
<= :: ErrorLevel -> ErrorLevel -> Bool
$c<= :: ErrorLevel -> ErrorLevel -> Bool
< :: ErrorLevel -> ErrorLevel -> Bool
$c< :: ErrorLevel -> ErrorLevel -> Bool
compare :: ErrorLevel -> ErrorLevel -> Ordering
$ccompare :: ErrorLevel -> ErrorLevel -> Ordering
$cp1Ord :: Eq ErrorLevel
Ord)
instance Show ErrorLevel where
show :: ErrorLevel -> String
show LevelWarn = "WARNING"
show LevelError = "ERROR"
show LevelFatal = "FATAL ERROR"
isHardError :: (Error ex) => ex -> Bool
isHardError :: ex -> Bool
isHardError = ( ErrorLevel -> ErrorLevel -> Bool
forall a. Ord a => a -> a -> Bool
> ErrorLevel
LevelWarn) (ErrorLevel -> Bool) -> (ex -> ErrorLevel) -> ex -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ex -> ErrorLevel
forall e. Error e => e -> ErrorLevel
errorLevel
data ErrorInfo = ErrorInfo ErrorLevel Position [String] deriving Typeable
instance Show ErrorInfo where show :: ErrorInfo -> String
show = String -> ErrorInfo -> String
showErrorInfo "error"
instance Error ErrorInfo where
errorInfo :: ErrorInfo -> ErrorInfo
errorInfo = ErrorInfo -> ErrorInfo
forall a. a -> a
id
changeErrorLevel :: ErrorInfo -> ErrorLevel -> ErrorInfo
changeErrorLevel (ErrorInfo _ pos :: Position
pos msgs :: [String]
msgs) lvl' :: ErrorLevel
lvl' = ErrorLevel -> Position -> [String] -> ErrorInfo
ErrorInfo ErrorLevel
lvl' Position
pos [String]
msgs
mkErrorInfo :: ErrorLevel -> String -> NodeInfo -> ErrorInfo
mkErrorInfo :: ErrorLevel -> String -> NodeInfo -> ErrorInfo
mkErrorInfo lvl :: ErrorLevel
lvl msg :: String
msg node :: NodeInfo
node = ErrorLevel -> Position -> [String] -> ErrorInfo
ErrorInfo ErrorLevel
lvl (NodeInfo -> Position
posOfNode NodeInfo
node) (String -> [String]
lines String
msg)
data CError
= forall err. (Error err) => CError err
deriving Typeable
class (Typeable e, Show e) => Error e where
errorInfo :: e -> ErrorInfo
toError :: e -> CError
fromError :: CError -> (Maybe e)
changeErrorLevel :: e -> ErrorLevel -> e
fromError (CError e :: err
e) = err -> Maybe e
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast err
e
toError = e -> CError
forall err. Error err => err -> CError
CError
changeErrorLevel e :: e
e lvl :: ErrorLevel
lvl =
if e -> ErrorLevel
forall e. Error e => e -> ErrorLevel
errorLevel e
e ErrorLevel -> ErrorLevel -> Bool
forall a. Eq a => a -> a -> Bool
== ErrorLevel
lvl
then e
e
else String -> e
forall a. HasCallStack => String -> a
error (String -> e) -> String -> e
forall a b. (a -> b) -> a -> b
$ "changeErrorLevel: not possible for " String -> ShowS
forall a. [a] -> [a] -> [a]
++ e -> String
forall a. Show a => a -> String
show e
e
instance Show CError where
show :: CError -> String
show (CError e :: err
e) = err -> String
forall a. Show a => a -> String
show err
e
instance Error CError where
errorInfo :: CError -> ErrorInfo
errorInfo (CError err :: err
err) = err -> ErrorInfo
forall e. Error e => e -> ErrorInfo
errorInfo err
err
toError :: CError -> CError
toError = CError -> CError
forall a. a -> a
id
fromError :: CError -> Maybe CError
fromError = CError -> Maybe CError
forall a. a -> Maybe a
Just
changeErrorLevel :: CError -> ErrorLevel -> CError
changeErrorLevel (CError e :: err
e) = err -> CError
forall err. Error err => err -> CError
CError (err -> CError) -> (ErrorLevel -> err) -> ErrorLevel -> CError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. err -> ErrorLevel -> err
forall e. Error e => e -> ErrorLevel -> e
changeErrorLevel err
e
errorPos :: (Error e) => e -> Position
errorPos :: e -> Position
errorPos = ( \(ErrorInfo _ pos :: Position
pos _) -> Position
pos ) (ErrorInfo -> Position) -> (e -> ErrorInfo) -> e -> Position
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> ErrorInfo
forall e. Error e => e -> ErrorInfo
errorInfo
errorLevel :: (Error e) => e -> ErrorLevel
errorLevel :: e -> ErrorLevel
errorLevel = ( \(ErrorInfo lvl :: ErrorLevel
lvl _ _) -> ErrorLevel
lvl ) (ErrorInfo -> ErrorLevel) -> (e -> ErrorInfo) -> e -> ErrorLevel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> ErrorInfo
forall e. Error e => e -> ErrorInfo
errorInfo
errorMsgs :: (Error e) => e -> [String]
errorMsgs :: e -> [String]
errorMsgs = ( \(ErrorInfo _ _ msgs :: [String]
msgs) -> [String]
msgs ) (ErrorInfo -> [String]) -> (e -> ErrorInfo) -> e -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> ErrorInfo
forall e. Error e => e -> ErrorInfo
errorInfo
data UnsupportedFeature = UnsupportedFeature String Position deriving Typeable
instance Error UnsupportedFeature where
errorInfo :: UnsupportedFeature -> ErrorInfo
errorInfo (UnsupportedFeature msg :: String
msg pos :: Position
pos) = ErrorLevel -> Position -> [String] -> ErrorInfo
ErrorInfo ErrorLevel
LevelError Position
pos (String -> [String]
lines String
msg)
instance Show UnsupportedFeature where show :: UnsupportedFeature -> String
show = String -> UnsupportedFeature -> String
forall e. Error e => String -> e -> String
showError "Unsupported Feature"
unsupportedFeature :: (Pos a) => String -> a -> UnsupportedFeature
unsupportedFeature :: String -> a -> UnsupportedFeature
unsupportedFeature msg :: String
msg a :: a
a = String -> Position -> UnsupportedFeature
UnsupportedFeature String
msg (a -> Position
forall a. Pos a => a -> Position
posOf a
a)
unsupportedFeature_ :: String -> UnsupportedFeature
unsupportedFeature_ :: String -> UnsupportedFeature
unsupportedFeature_ msg :: String
msg = String -> Position -> UnsupportedFeature
UnsupportedFeature String
msg Position
internalPos
newtype UserError = UserError ErrorInfo deriving Typeable
instance Error UserError where
errorInfo :: UserError -> ErrorInfo
errorInfo (UserError info :: ErrorInfo
info) = ErrorInfo
info
instance Show UserError where show :: UserError -> String
show = String -> UserError -> String
forall e. Error e => String -> e -> String
showError "User Error"
userErr :: String -> UserError
userErr :: String -> UserError
userErr msg :: String
msg = ErrorInfo -> UserError
UserError (ErrorLevel -> Position -> [String] -> ErrorInfo
ErrorInfo ErrorLevel
LevelError Position
internalPos (String -> [String]
lines String
msg))
showError :: (Error e) => String -> e -> String
showError :: String -> e -> String
showError short_msg :: String
short_msg = String -> ErrorInfo -> String
showErrorInfo String
short_msg (ErrorInfo -> String) -> (e -> ErrorInfo) -> e -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> ErrorInfo
forall e. Error e => e -> ErrorInfo
errorInfo
showErrorInfo :: String -> ErrorInfo -> String
showErrorInfo :: String -> ErrorInfo -> String
showErrorInfo short_msg :: String
short_msg (ErrorInfo level :: ErrorLevel
level pos :: Position
pos msgs :: [String]
msgs) =
String
header String -> ShowS
forall a. [a] -> [a] -> [a]
++ [String] -> String
showMsgLines (if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
short_msg then [String]
msgs else String
short_msgString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
msgs)
where
header :: String
header = Position -> String
showPos Position
pos String -> ShowS
forall a. [a] -> [a] -> [a]
++ "[" String -> ShowS
forall a. [a] -> [a] -> [a]
++ ErrorLevel -> String
forall a. Show a => a -> String
show ErrorLevel
level String -> ShowS
forall a. [a] -> [a] -> [a]
++ "]"
showPos :: Position -> String
showPos p :: Position
p | Position -> Bool
isSourcePos Position
p = (Position -> String
posFile Position
p) String -> ShowS
forall a. [a] -> [a] -> [a]
++ ":" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Position -> Int
posRow Position
pos) String -> ShowS
forall a. [a] -> [a] -> [a]
++ ": " String -> ShowS
forall a. [a] -> [a] -> [a]
++
"(column " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Position -> Int
posColumn Position
pos) String -> ShowS
forall a. [a] -> [a] -> [a]
++ ") "
| Bool
otherwise = Position -> String
forall a. Show a => a -> String
show Position
p String -> ShowS
forall a. [a] -> [a] -> [a]
++ ":: "
showMsgLines :: [String] -> String
showMsgLines [] = ShowS
forall a. String -> a
internalErr "No short message or error message provided."
showMsgLines (x :: String
x:xs :: [String]
xs) = String
indent String -> ShowS
forall a. [a] -> [a] -> [a]
++ ">>> " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
x String -> ShowS
forall a. [a] -> [a] -> [a]
++ "\n" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [String] -> String
unlines (ShowS -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String
indentString -> ShowS
forall a. [a] -> [a] -> [a]
++) [String]
xs)
internalErrPrefix :: String
internalErrPrefix :: String
internalErrPrefix = [String] -> String
unlines [ "Language.C : Internal Error" ,
"This is propably a bug, and should be reported at "String -> ShowS
forall a. [a] -> [a] -> [a]
++
"http://www.sivity.net/projects/language.c/newticket"]
internalErr :: String -> a
internalErr :: String -> a
internalErr msg :: String
msg = String -> a
forall a. HasCallStack => String -> a
error (String
internalErrPrefix String -> ShowS
forall a. [a] -> [a] -> [a]
++ "\n"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
indentLines String
msg
String -> ShowS
forall a. [a] -> [a] -> [a]
++ "\n")
indent :: String
indent :: String
indent = " "
indentLines :: String -> String
indentLines :: ShowS
indentLines = [String] -> String
unlines ([String] -> String) -> (String -> [String]) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String
indentString -> ShowS
forall a. [a] -> [a] -> [a]
++) ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines