1{- Some git commands output encoded filenames, in a rather annoyingly complex 2 - C-style encoding. 3 - 4 - Copyright 2010, 2011 Joey Hess <id@joeyh.name> 5 - 6 - Licensed under the GNU AGPL version 3 or higher. 7 -} 8 9module Git.Filename where 10 11import Common 12import Utility.Format (decode_c, encode_c) 13import Utility.QuickCheck 14 15import Data.Char 16import Data.Word 17import qualified Data.ByteString as S 18 19-- encoded filenames will be inside double quotes 20decode :: S.ByteString -> RawFilePath 21decode b = case S.uncons b of 22 Nothing -> b 23 Just (h, t) 24 | h /= q -> b 25 | otherwise -> case S.unsnoc t of 26 Nothing -> b 27 Just (i, l) 28 | l /= q -> b 29 | otherwise -> 30 encodeBS $ decode_c $ decodeBS i 31 where 32 q :: Word8 33 q = fromIntegral (ord '"') 34 35{- Should not need to use this, except for testing decode. -} 36encode :: RawFilePath -> S.ByteString 37encode s = encodeBS $ "\"" ++ encode_c (decodeBS s) ++ "\"" 38 39-- Encoding and then decoding roundtrips only when the string does not 40-- contain high unicode, because eg, both "\12345" and "\227\128\185" 41-- are encoded to "\343\200\271". 42-- 43-- That is not a real-world problem, and using TestableFilePath 44-- limits what's tested to ascii, so avoids running into it. 45prop_encode_decode_roundtrip :: TestableFilePath -> Bool 46prop_encode_decode_roundtrip ts = 47 s == fromRawFilePath (decode (encode (toRawFilePath s))) 48 where 49 s = fromTestableFilePath ts 50