Don't encode/decode file paths if base >= 4.5.

Prior to base 4.5 (and perhaps earlier - check), filepaths and command
line arguments were treated as unencoded lists of bytes, not unicode
strings, so we had to work around that by encoding and decoding
them.  This commit adds CPP checks for base 4.5 that disable the
encoding/decoding.

Fixes a bug with multilingual filenames when pandoc was compiled
with ghc 7.4. Closes #540.
This commit is contained in:
John MacFarlane 2012-06-22 21:24:02 +02:00
parent c24b7991aa
commit cc39c313c5
2 changed files with 33 additions and 9 deletions

View file

@ -39,21 +39,25 @@ module Text.Pandoc.UTF8 ( readFile
where
#if MIN_VERSION_base(4,5,0)
#else
import Codec.Binary.UTF8.String (encodeString)
#endif
#if MIN_VERSION_base(4,2,0)
import System.IO hiding (readFile, writeFile, getContents,
putStr, putStrLn, hPutStr, hPutStrLn, hGetContents)
import Prelude hiding (readFile, writeFile, getContents, putStr, putStrLn )
import Codec.Binary.UTF8.String (encodeString)
import qualified System.IO as IO
readFile :: FilePath -> IO String
readFile f = do
h <- openFile (encodeString f) ReadMode
h <- openFile (encodePath f) ReadMode
hGetContents h
writeFile :: FilePath -> String -> IO ()
writeFile f s = withFile (encodeString f) WriteMode $ \h -> hPutStr h s
writeFile f s = withFile (encodePath f) WriteMode $ \h -> hPutStr h s
getContents :: IO String
getContents = hGetContents stdin
@ -76,7 +80,6 @@ hGetContents h = hSetEncoding h utf8_bom >> IO.hGetContents h
#else
import qualified Data.ByteString as B
import Codec.Binary.UTF8.String (encodeString)
import Data.ByteString.UTF8 (toString, fromString)
import Prelude hiding (readFile, writeFile, getContents, putStr, putStrLn)
import System.IO (Handle)
@ -91,10 +94,10 @@ stripBOM s | bom `B.isPrefixOf` s = B.drop 3 s
stripBOM s = s
readFile :: FilePath -> IO String
readFile = liftM (toString . stripBOM) . B.readFile . encodeString
readFile = liftM (toString . stripBOM) . B.readFile . encodePath
writeFile :: FilePath -> String -> IO ()
writeFile f = B.writeFile (encodeString f) . fromString
writeFile f = B.writeFile (encodePath f) . fromString
getContents :: IO String
getContents = liftM (toString . stripBOM) B.getContents
@ -115,3 +118,10 @@ hPutStrLn :: Handle -> String -> IO ()
hPutStrLn h s = hPutStr h (s ++ "\n")
#endif
encodePath :: FilePath -> FilePath
#if MIN_VERSION_base(4,5,0)
encodePath = id
#else
encodePath = encodeString
#endif

View file

@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-
Copyright (C) 2006-2012 John MacFarlane <jgm@berkeley.edu>
@ -56,8 +57,21 @@ import Network.HTTP (simpleHTTP, mkRequest, getResponseBody, RequestMethod(..))
import Network.URI (parseURI, isURI, URI(..))
import qualified Data.ByteString.Lazy as B
import Data.ByteString.Lazy.UTF8 (toString )
import Codec.Binary.UTF8.String (decodeString, encodeString)
import Text.CSL.Reference (Reference(..))
#if MIN_VERSION_base(4,5,0)
#else
import Codec.Binary.UTF8.String (decodeString, encodeString)
#endif
encodePath, decodeArg :: FilePath -> FilePath
#if MIN_VERSION_base(4,5,0)
encodePath = id
decodeArg = id
#else
encodePath = encodeString
decodeArg = decodeString
#endif
copyrightMessage :: String
copyrightMessage = "\nCopyright (C) 2006-2012 John MacFarlane\n" ++
@ -745,7 +759,7 @@ defaultWriterName x =
main :: IO ()
main = do
rawArgs <- liftM (map decodeString) getArgs
rawArgs <- liftM (map decodeArg) getArgs
prg <- getProgName
let compatMode = (prg == "hsmarkdown")
@ -1023,7 +1037,7 @@ main = do
else return doc1
let writeBinary :: B.ByteString -> IO ()
writeBinary = B.writeFile (encodeString outputFile)
writeBinary = B.writeFile (encodePath outputFile)
let writerFn :: FilePath -> String -> IO ()
writerFn "-" = UTF8.putStr