Search code examples
haskellnewlinebytestring

BS.getLine and CRLF endings


I'm trying to remove the \r from the end of lines when using BS.getLine. I've tried using hSetNewlineMode and it works with getLine but not with BS.getLine:

import qualified Data.ByteString.Char8 as BS
import Data.ByteString (ByteString)
import System.IO (hSetNewlineMode, universalNewlineMode, stdin)

main = do
  hSetNewlineMode stdin universalNewlineMode
  -- s <- BS.pack `fmap` getLine   -- \r removed
  s <- BS.getLine                  -- \r not removed
  putStrLn $ show s

-- to test: perl -e 'print "this\r\n"' | runhaskell program.hs

Is there something else I should be doing?


Solution

  • Looking at the source of BS.hGetLine, I see that '\n' is hardcoded:

    [...]
    -- find the end-of-line character, if there is one
    findEOL r w raw
        | r == w = return w
        | otherwise =  do
            (c,r') <- readCharFromBuffer raw r
            if c == '\n'
                then return r -- NB. not r': don't include the '\n'
                else findEOL r' w raw
    [...]
    

    This helper must be changed to use haInputNL from the provided Handle instead of the hardcoded value if we want it to take the newline mode into account. I suggest filing a bug report.