module Darcs.Patch.TokenReplace
(
tryTokInternal
, forceTokReplace
, breakOutToken
, breakToTokens
, defaultToks
) where
import Prelude ()
import Darcs.Prelude
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import Data.Maybe ( isNothing )
import Darcs.Util.ByteString ( substrPS, linesPS, unlinesPS )
import Darcs.Patch.RegChars ( regChars )
breakOutToken :: String -> BC.ByteString
-> (BC.ByteString, BC.ByteString, BC.ByteString)
breakOutToken tokChars input =
let isTokChar = regChars tokChars
(before, tokAndRest) = BC.break isTokChar input
(tok, remaining) = BC.break (not . isTokChar) tokAndRest in
(before, tok, remaining)
tryTokInternal :: String -> B.ByteString -> B.ByteString -> B.ByteString
-> Maybe [B.ByteString]
tryTokInternal _ oldToken newToken input
| isNothing (substrPS oldToken input) &&
isNothing (substrPS newToken input) = Just [ input ]
tryTokInternal tokChars oldToken newToken input =
let (before, tok, remaining) = breakOutToken tokChars input in
case tryTokInternal tokChars oldToken newToken remaining of
Nothing -> Nothing
Just rest | tok == oldToken -> Just $ before : newToken : rest
| tok == newToken -> Nothing
| otherwise -> Just $ before : tok : rest
forceTokReplace :: String -> B.ByteString -> B.ByteString -> B.ByteString
-> B.ByteString
forceTokReplace tokChars oldToken newToken = forceReplaceLines
where
forceReplaceLines = unlinesPS . map forceReplace . linesPS
breakOutAllTokens input | B.null input = []
breakOutAllTokens input =
let (before, tok, remaining) = breakOutToken tokChars input in
before : tok : breakOutAllTokens remaining
forceReplace = B.concat . map replaceMatchingToken . breakOutAllTokens
replaceMatchingToken input | input == oldToken = newToken
| otherwise = input
breakToTokens :: BC.ByteString -> [BC.ByteString]
breakToTokens input | B.null input = []
breakToTokens input =
let (_, tok, remaining) = breakOutToken defaultToks input in
tok : breakToTokens remaining
defaultToks :: String
defaultToks = "A-Za-z_0-9"