timeplot-1.0.18: Tools/TimePlot/Source.hs
module Tools.TimePlot.Source (
readSource
) where
import qualified Data.ByteString.Char8 as S
import qualified Data.ByteString.Lazy.Char8 as B
import Data.ByteString.Lex.Lazy.Double
import Tools.TimePlot.Types
readSource :: (Show t) => (B.ByteString -> Maybe (t,B.ByteString)) -> FilePath -> IO [(t, InEvent)]
readSource readTime f = (map parseLine . filter (not . B.null) . blines) `fmap` (if f == "-" then B.getContents else B.readFile f)
where
blines = map pruneLF . B.split '\n'
pruneLF b | not (B.null b) && (B.last b == '\r') = B.init b
| otherwise = b
strict = S.concat . B.toChunks
parseLine s = (\x -> case x of { Just e -> e; Nothing -> error $ "Unparseable input line: " ++ B.unpack s }) $ do
(t, s') <- readTime s
(_, s'') <- B.uncons s'
(c,rest) <- B.uncons s''
case c of
'>' -> return (t, InEdge (strict rest) Rise )
'<' -> return (t, InEdge (strict rest) Fall )
'!' -> do
let (track, val') = B.break (==' ') rest
if B.null val'
then return (t, InEdge (strict track) (Pulse (Status "" "")))
else do
(_,val) <- B.uncons val'
return (t, InEdge (strict track) $ Pulse (Status "" (B.unpack val)))
'@' -> do
let (track, val') = B.break (==' ') rest
(_,val) <- B.uncons val'
return (t, InEdge (strict track) $ SetTo (Status {statusColor = B.unpack $ val, statusLabel = ""}))
'=' -> do
let (track, val') = B.break (==' ') rest
(_,val) <- B.uncons val'
if B.null val
then Nothing
else do
case B.head val of
'`' -> do
return (t, InAtom (strict track) (strict $ B.tail val))
_ -> do
(v,_ ) <- readDouble val
return (t, InValue (strict track) v)
_ -> Nothing