{-# LANGUAGE DeriveDataTypeable #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Language.C.Data.Position
-- Copyright   :  (c) [1995..2000] Manuel M. T. Chakravarty
--                    [2008..2009] Benedikt Huber
-- License     :  BSD-style
-- Maintainer  :  benedikt.huber@gmail.com
-- Stability   :  experimental
-- Portability :  ghc
--
-- Source code position
-----------------------------------------------------------------------------
module Language.C.Data.Position (
  --
  -- source text positions
  --
  Position(),
  position,
  PosLength,
  posFile,posRow,posColumn,posOffset,posParent,
  initPos, isSourcePos,
  nopos, isNoPos,
  builtinPos, isBuiltinPos,
  internalPos, isInternalPos,
  incPos, retPos,
  incOffset,
  Pos(..),
) where
import Data.Data (Data)
import Data.Typeable (Typeable)
import GHC.Generics (Generic)
import Control.DeepSeq (NFData)

-- | file position information
data FilePosition = FilePosition { FilePosition -> String
posSrcFile    :: String,            -- ^ source file
                                   FilePosition -> Maybe Position
posParentFile :: (Maybe Position)   -- ^ including file, if any
                                 }
                    deriving (FilePosition -> FilePosition -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FilePosition -> FilePosition -> Bool
$c/= :: FilePosition -> FilePosition -> Bool
== :: FilePosition -> FilePosition -> Bool
$c== :: FilePosition -> FilePosition -> Bool
Eq, Eq FilePosition
FilePosition -> FilePosition -> Bool
FilePosition -> FilePosition -> Ordering
FilePosition -> FilePosition -> FilePosition
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 :: FilePosition -> FilePosition -> FilePosition
$cmin :: FilePosition -> FilePosition -> FilePosition
max :: FilePosition -> FilePosition -> FilePosition
$cmax :: FilePosition -> FilePosition -> FilePosition
>= :: FilePosition -> FilePosition -> Bool
$c>= :: FilePosition -> FilePosition -> Bool
> :: FilePosition -> FilePosition -> Bool
$c> :: FilePosition -> FilePosition -> Bool
<= :: FilePosition -> FilePosition -> Bool
$c<= :: FilePosition -> FilePosition -> Bool
< :: FilePosition -> FilePosition -> Bool
$c< :: FilePosition -> FilePosition -> Bool
compare :: FilePosition -> FilePosition -> Ordering
$ccompare :: FilePosition -> FilePosition -> Ordering
Ord, Typeable, Typeable FilePosition
FilePosition -> DataType
FilePosition -> Constr
(forall b. Data b => b -> b) -> FilePosition -> FilePosition
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> FilePosition -> u
forall u. (forall d. Data d => d -> u) -> FilePosition -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FilePosition -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FilePosition -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FilePosition -> m FilePosition
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FilePosition -> m FilePosition
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FilePosition
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FilePosition -> c FilePosition
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FilePosition)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c FilePosition)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FilePosition -> m FilePosition
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FilePosition -> m FilePosition
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FilePosition -> m FilePosition
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> FilePosition -> m FilePosition
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FilePosition -> m FilePosition
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> FilePosition -> m FilePosition
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> FilePosition -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> FilePosition -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> FilePosition -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> FilePosition -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FilePosition -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> FilePosition -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FilePosition -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> FilePosition -> r
gmapT :: (forall b. Data b => b -> b) -> FilePosition -> FilePosition
$cgmapT :: (forall b. Data b => b -> b) -> FilePosition -> FilePosition
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c FilePosition)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c FilePosition)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FilePosition)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c FilePosition)
dataTypeOf :: FilePosition -> DataType
$cdataTypeOf :: FilePosition -> DataType
toConstr :: FilePosition -> Constr
$ctoConstr :: FilePosition -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FilePosition
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c FilePosition
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FilePosition -> c FilePosition
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> FilePosition -> c FilePosition
Data, forall x. Rep FilePosition x -> FilePosition
forall x. FilePosition -> Rep FilePosition x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep FilePosition x -> FilePosition
$cfrom :: forall x. FilePosition -> Rep FilePosition x
Generic)

instance NFData FilePosition

-- | uniform representation of source file positions
data Position = Position { Position -> Int
posOffset :: {-# UNPACK #-} !Int  -- ^ absolute offset in the preprocessed file
                         , Position -> Int
posRow :: {-# UNPACK #-} !Int     -- ^ row (line)  in the original file. Affected by #LINE pragmas.
                         , Position -> Int
posColumn :: {-# UNPACK #-} !Int  -- ^ column in the preprocessed file. Inaccurate w.r.t. to the original
                                                             --   file in the presence of preprocessor macros.
                         , Position -> FilePosition
posFileInfo :: FilePosition       -- ^ position in source file, including files
                         }
              | NoPosition
              | BuiltinPosition
              | InternalPosition
                deriving (Position -> Position -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Position -> Position -> Bool
$c/= :: Position -> Position -> Bool
== :: Position -> Position -> Bool
$c== :: Position -> Position -> Bool
Eq, Eq Position
Position -> Position -> Bool
Position -> Position -> Ordering
Position -> Position -> Position
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 :: Position -> Position -> Position
$cmin :: Position -> Position -> Position
max :: Position -> Position -> Position
$cmax :: Position -> Position -> Position
>= :: Position -> Position -> Bool
$c>= :: Position -> Position -> Bool
> :: Position -> Position -> Bool
$c> :: Position -> Position -> Bool
<= :: Position -> Position -> Bool
$c<= :: Position -> Position -> Bool
< :: Position -> Position -> Bool
$c< :: Position -> Position -> Bool
compare :: Position -> Position -> Ordering
$ccompare :: Position -> Position -> Ordering
Ord, Typeable, Typeable Position
Position -> DataType
Position -> Constr
(forall b. Data b => b -> b) -> Position -> Position
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Position -> u
forall u. (forall d. Data d => d -> u) -> Position -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Position -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Position -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Position -> m Position
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Position -> m Position
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Position
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Position -> c Position
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Position)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Position)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Position -> m Position
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Position -> m Position
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Position -> m Position
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Position -> m Position
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Position -> m Position
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Position -> m Position
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Position -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Position -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> Position -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Position -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Position -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Position -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Position -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Position -> r
gmapT :: (forall b. Data b => b -> b) -> Position -> Position
$cgmapT :: (forall b. Data b => b -> b) -> Position -> Position
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Position)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Position)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Position)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Position)
dataTypeOf :: Position -> DataType
$cdataTypeOf :: Position -> DataType
toConstr :: Position -> Constr
$ctoConstr :: Position -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Position
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Position
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Position -> c Position
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Position -> c Position
Data, forall x. Rep Position x -> Position
forall x. Position -> Rep Position x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Position x -> Position
$cfrom :: forall x. Position -> Rep Position x
Generic)

instance NFData Position

posFile :: Position -> String
posFile :: Position -> String
posFile = FilePosition -> String
posSrcFile forall b c a. (b -> c) -> (a -> b) -> a -> c
. Position -> FilePosition
posFileInfo

posParent :: Position -> (Maybe Position)
posParent :: Position -> Maybe Position
posParent = FilePosition -> Maybe Position
posParentFile forall b c a. (b -> c) -> (a -> b) -> a -> c
. Position -> FilePosition
posFileInfo

-- | Position and length of a token
type PosLength = (Position,Int)

instance Show Position where
  showsPrec :: Int -> Position -> ShowS
showsPrec Int
_ (Position Int
_ Int
row Int
_ (FilePosition String
fname Maybe Position
mparent)) =
    String -> ShowS
showString String
"(" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
0 String
fname forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
": line " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
0 Int
row forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. a -> a
id (\Position
p -> String -> ShowS
showString String
", in file included from " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
0 Position
p) Maybe Position
mparent forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    String -> ShowS
showString String
")"
  showsPrec Int
_  Position
NoPosition                     = String -> ShowS
showString String
"<no file>"
  showsPrec Int
_  Position
BuiltinPosition                = String -> ShowS
showString String
"<builtin>"
  showsPrec Int
_ Position
InternalPosition                = String -> ShowS
showString String
"<internal>"

-- | @position absoluteOffset fileName lineNumber columnNumber@ initializes a @Position@ using the given arguments
position :: Int -> String -> Int -> Int -> Maybe Position -> Position
position :: Int -> String -> Int -> Int -> Maybe Position -> Position
position Int
offset String
fname Int
row Int
col Maybe Position
mparent = Int -> Int -> Int -> FilePosition -> Position
Position Int
offset Int
row Int
col (String -> Maybe Position -> FilePosition
FilePosition String
fname Maybe Position
mparent)

-- | class of type which aggregate a source code location
class Pos a where
    posOf :: a -> Position

-- | initialize a Position to the start of the translation unit starting in the given file
initPos :: FilePath -> Position
initPos :: String -> Position
initPos String
file = Int -> Int -> Int -> FilePosition -> Position
Position Int
0 Int
1 Int
1 (String -> Maybe Position -> FilePosition
FilePosition String
file forall a. Maybe a
Nothing)

-- | returns @True@ if the given position refers to an actual source file
isSourcePos :: Position -> Bool
isSourcePos :: Position -> Bool
isSourcePos (Position Int
_ Int
_ Int
_ FilePosition
_) = Bool
True
isSourcePos Position
_                  = Bool
False

-- | no position (for unknown position information)
nopos :: Position
nopos :: Position
nopos  = Position
NoPosition

-- | returns @True@ if the there is no position information available
isNoPos :: Position -> Bool
isNoPos :: Position -> Bool
isNoPos Position
NoPosition = Bool
True
isNoPos Position
_          = Bool
False

-- | position attached to built-in objects
--
builtinPos :: Position
builtinPos :: Position
builtinPos  = Position
BuiltinPosition

-- | returns @True@ if the given position refers to a builtin definition
isBuiltinPos :: Position -> Bool
isBuiltinPos :: Position -> Bool
isBuiltinPos Position
BuiltinPosition = Bool
True
isBuiltinPos Position
_               = Bool
False

-- | position used for internal errors
internalPos :: Position
internalPos :: Position
internalPos = Position
InternalPosition

-- | returns @True@ if the given position is internal
isInternalPos :: Position -> Bool
isInternalPos :: Position -> Bool
isInternalPos Position
InternalPosition = Bool
True
isInternalPos Position
_                = Bool
False

{-# INLINE incPos #-}
-- | advance column
incPos :: Position -> Int -> Position
incPos :: Position -> Int -> Position
incPos (Position Int
offs Int
row Int
col FilePosition
fpos) Int
n = Int -> Int -> Int -> FilePosition -> Position
Position (Int
offs forall a. Num a => a -> a -> a
+ Int
n) Int
row (Int
col forall a. Num a => a -> a -> a
+ Int
n) FilePosition
fpos
incPos Position
p Int
_                             = Position
p

{-# INLINE retPos #-}
-- | advance to next line
retPos :: Position -> Position
retPos :: Position -> Position
retPos (Position Int
offs Int
row Int
_ FilePosition
fpos) = Int -> Int -> Int -> FilePosition -> Position
Position (Int
offsforall a. Num a => a -> a -> a
+Int
1) (Int
row forall a. Num a => a -> a -> a
+ Int
1) Int
1 FilePosition
fpos
retPos Position
p                           = Position
p

{-# INLINE incOffset #-}
-- | advance just the offset
incOffset :: Position -> Int -> Position
incOffset :: Position -> Int -> Position
incOffset (Position Int
o Int
r Int
c FilePosition
f) Int
n = Int -> Int -> Int -> FilePosition -> Position
Position (Int
o forall a. Num a => a -> a -> a
+ Int
n) Int
r Int
c FilePosition
f
incOffset Position
pos Int
_             = Position
pos