{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE Safe #-}
module Data.YAML.Pos
( Pos(..)
, prettyPosWithSource
) where
import qualified Data.ByteString.Lazy as BL
import qualified Data.YAML.Token.Encoding as Enc
import Util
data Pos = Pos
{ Pos -> Int
posByteOffset :: !Int
, Pos -> Int
posCharOffset :: !Int
, Pos -> Int
posLine :: !Int
, Pos -> Int
posColumn :: !Int
} deriving (Pos -> Pos -> Bool
(Pos -> Pos -> Bool) -> (Pos -> Pos -> Bool) -> Eq Pos
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Pos -> Pos -> Bool
$c/= :: Pos -> Pos -> Bool
== :: Pos -> Pos -> Bool
$c== :: Pos -> Pos -> Bool
Eq, Int -> Pos -> ShowS
[Pos] -> ShowS
Pos -> String
(Int -> Pos -> ShowS)
-> (Pos -> String) -> ([Pos] -> ShowS) -> Show Pos
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Pos] -> ShowS
$cshowList :: [Pos] -> ShowS
show :: Pos -> String
$cshow :: Pos -> String
showsPrec :: Int -> Pos -> ShowS
$cshowsPrec :: Int -> Pos -> ShowS
Show, (forall x. Pos -> Rep Pos x)
-> (forall x. Rep Pos x -> Pos) -> Generic Pos
forall x. Rep Pos x -> Pos
forall x. Pos -> Rep Pos x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Pos x -> Pos
$cfrom :: forall x. Pos -> Rep Pos x
Generic)
instance NFData Pos where rnf :: Pos -> ()
rnf !Pos
_ = ()
prettyPosWithSource :: Pos -> BL.ByteString -> String -> String
prettyPosWithSource :: Pos -> ByteString -> ShowS
prettyPosWithSource Pos{..} source :: ByteString
source msg :: String
msg
| Int
posCharOffset Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 Bool -> Bool -> Bool
|| Int
posByteOffset Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = "0:0:" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg String -> ShowS
forall a. [a] -> [a] -> [a]
++ "\n"
| Bool
otherwise = [String] -> String
unlines
[ Int -> String
forall a. Show a => a -> String
show Int
posLine String -> ShowS
forall a. [a] -> [a] -> [a]
++ ":" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
posColumn String -> ShowS
forall a. [a] -> [a] -> [a]
++ ":" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg
, String
lpfx
, String
lnostr String -> ShowS
forall a. [a] -> [a] -> [a]
++ "| " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
line
, String
lpfx String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
posColumn ' ' String -> ShowS
forall a. [a] -> [a] -> [a]
++ "^"
]
where
lnostr :: String
lnostr = " " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
posLine String -> ShowS
forall a. [a] -> [a] -> [a]
++ " "
lpfx :: String
lpfx = (' ' Char -> ShowS
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String
lnostr) String -> ShowS
forall a. [a] -> [a] -> [a]
++ "| "
(_,lstart :: [(Int, Char)]
lstart) = Int -> ByteString -> (Int, [(Int, Char)])
findLineStartByByteOffset Int
posByteOffset ByteString
source
line :: String
line = ((Int, Char) -> Char) -> [(Int, Char)] -> String
forall a b. (a -> b) -> [a] -> [b]
map (Int, Char) -> Char
forall a b. (a, b) -> b
snd ([(Int, Char)] -> String) -> [(Int, Char)] -> String
forall a b. (a -> b) -> a -> b
$ ((Int, Char) -> Bool) -> [(Int, Char)] -> [(Int, Char)]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not (Bool -> Bool) -> ((Int, Char) -> Bool) -> (Int, Char) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isNL (Char -> Bool) -> ((Int, Char) -> Char) -> (Int, Char) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Char) -> Char
forall a b. (a, b) -> b
snd) [(Int, Char)]
lstart
isNL :: Char -> Bool
isNL c :: Char
c = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '\r' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '\n'
findLineStartByByteOffset :: Int -> BL.ByteString -> (Int,[(Int,Char)])
findLineStartByByteOffset :: Int -> ByteString -> (Int, [(Int, Char)])
findLineStartByByteOffset bofs0 :: Int
bofs0 input :: ByteString
input = Int -> [(Int, Char)] -> [(Int, Char)] -> (Int, [(Int, Char)])
go 0 [(Int, Char)]
inputChars [(Int, Char)]
inputChars
where
(_,inputChars :: [(Int, Char)]
inputChars) = ByteString -> (Encoding, [(Int, Char)])
Enc.decode ByteString
input
go :: Int -> [(Int, Char)] -> [(Int, Char)] -> (Int, [(Int, Char)])
go lsOfs :: Int
lsOfs lsChars :: [(Int, Char)]
lsChars [] = (Int
lsOfs,[(Int, Char)]
lsChars)
go lsOfs :: Int
lsOfs lsChars :: [(Int, Char)]
lsChars ((ofs' :: Int
ofs',_):_)
| Int
bofs0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
ofs' = (Int
lsOfs,[(Int, Char)]
lsChars)
go _ _ ((_,'\r'):(ofs' :: Int
ofs','\n'):rest :: [(Int, Char)]
rest) = Int -> [(Int, Char)] -> [(Int, Char)] -> (Int, [(Int, Char)])
go Int
ofs' [(Int, Char)]
rest [(Int, Char)]
rest
go _ _ ((ofs' :: Int
ofs','\r'):rest :: [(Int, Char)]
rest) = Int -> [(Int, Char)] -> [(Int, Char)] -> (Int, [(Int, Char)])
go Int
ofs' [(Int, Char)]
rest [(Int, Char)]
rest
go _ _ ((ofs' :: Int
ofs','\n'):rest :: [(Int, Char)]
rest) = Int -> [(Int, Char)] -> [(Int, Char)] -> (Int, [(Int, Char)])
go Int
ofs' [(Int, Char)]
rest [(Int, Char)]
rest
go lsOfs :: Int
lsOfs lsChars :: [(Int, Char)]
lsChars (_:rest :: [(Int, Char)]
rest) = Int -> [(Int, Char)] -> [(Int, Char)] -> (Int, [(Int, Char)])
go Int
lsOfs [(Int, Char)]
lsChars [(Int, Char)]
rest