By | ~fr33domlover |
At | 2019-10-31 |
Title | Finish implementing patch parser |
Description |
Edit file src/Development/Darcs/Internal/Patch/Parser.hs 0 → 0
- 3 - Written in 2018 by fr33domlover <fr33domlover@riseup.net>.
+ 3 - Written in 2018, 2019 by fr33domlover <fr33domlover@riseup.net>.
… … … … + 20 , Change (..)
- 25 import Control.Applicative (many)
+ 26 import Control.Applicative
+ 28 import Data.Bifunctor
+ 31 import Data.Char (chr)
+ 35 import qualified Data.ByteString as B
+ 36 import qualified Data.ByteString.Base16 as B16
+ 37 import qualified Data.ByteString.Char8 as BC
… … … … - 46 hunk :: Parser Hunk
- 47 hunk = Hunk
- 48 <$> (string "hunk ./" *> takeWhile1 (/= ' ')) <* char ' '
- 49 <*> decimal
- 50 <*> many (char '\n' *> char '-' *> A.takeWhile (/= '\n'))
- 51 <*> many (char '\n' *> char '+' *> A.takeWhile (/= '\n'))
- 52 - 53 patch :: Parser (PatchInfoRaw, [Hunk])
- 54 patch = (,) <$> patchInfoRawP' <*> many hunk
+ 52 data Change
+ 53 = EditFile Hunk
+ 54 | AddFile ByteString
+ 55 | AddDir ByteString
+ 56 | Move ByteString ByteString
+ 57 | RemoveFile ByteString
+ 58 | RemoveDir ByteString
+ 59 | Replace ByteString ByteString ByteString ByteString
+ 60 | Binary ByteString ByteString ByteString
+ 61 | Pref ByteString ByteString ByteString
+ 62 + 63 patch :: Parser (PatchInfoRaw, [Change])
+ 64 patch = (,) <$> patchInfoRawP' <*> change `sepBy` char '\n'
+ 65 where
+ 66 change =
+ 67 EditFile <$> hunk <|> addFile <|> addDir <|> move <|> removeFile <|>
+ 68 removeDir <|> replace <|> binary <|> pref
+ 69 where
+ 70 filename = unescape <$> (string "./" *> takeWhile1 (not . isSpace))
+ 71 where
+ 72 unescape b =
+ 73 case BC.uncons b of
+ 74 Nothing -> b
+ 75 Just (c, r) ->
+ 76 if c == '\\'
+ 77 then case second BC.uncons $ BC.break (== '\\') r of
+ 78 (num, Just ('\\', rest)) ->
+ 79 chr (read $ BC.unpack num) `BC.cons`
+ 80 unescape rest
+ 81 _ -> error "No closing backslash"
+ 82 else c `BC.cons` unescape r
+ 83 hunk = Hunk
+ 84 <$> (string "hunk " *> filename) <* char ' '
+ 85 <*> decimal
+ 86 <*> many (string "\n-" *> A.takeWhile (/= '\n'))
+ 87 <*> many (string "\n+" *> A.takeWhile (/= '\n'))
+ 88 addFile = AddFile <$> (string "addfile " *> filename)
+ 89 addDir = AddDir <$> (string "adddir " *> filename)
+ 90 move = Move <$> (string "move " *> filename) <* char ' ' <*> filename
+ 91 removeFile = RemoveFile <$> (string "rmfile " *> filename)
+ 92 removeDir = RemoveDir <$> (string "rmdir " *> filename)
+ 93 replace =
+ 94 Replace
+ 95 <$> (string "replace " *> filename)
+ 96 <* char ' ' <*> takeWhile1 (not . isSpace)
+ 97 <* char ' ' <*> takeWhile1 (not . isSpace)
+ 98 <* char ' ' <*> takeWhile1 (not . isSpace)
+ 99 binary =
+ 100 Binary
+ 101 <$> (string "binary " *> filename)
+ 102 <* string "\noldhex" <*> hex
+ 103 <* string "\nnewhex" <*> hex
+ 104 where
+ 105 hex = do
+ 106 bs <- some $ string "\n*" *> A.takeWhile (/= '\n')
+ 107 let (b, r) = B16.decode $ B.concat bs
+ 108 if B.null r
+ 109 then return b
+ 110 else fail "Non hex characters"
+ 111 pref =
+ 112 Pref
+ 113 <$> (string "changepref " *> takeWhile1 (not . isSpace))
+ 114 <* char '\n' <*> A.takeWhile (/= '\n')
+ 115 <* char '\n' <*> A.takeWhile (/= '\n')
… … … …