implement massReplace

This looks at the string one char at a time, which is hardly efficient..
but more than good enough for expanding variables in
relatively short command lines.
This commit is contained in:
Joey Hess 2013-04-08 23:56:37 -04:00
parent 6523b8a476
commit 4f5ceffead
2 changed files with 23 additions and 5 deletions

View file

@ -447,12 +447,12 @@ downloadUrl urls file = go =<< annexWebDownloadCommand <$> Annex.getGitConfig
liftIO $ anyM (\u -> Url.download u headers opts file) urls
go (Just basecmd) = liftIO $ anyM (downloadcmd basecmd) urls
downloadcmd basecmd url =
boolSystem "sh" [Param "-c", Param $ gencmd basecmd url]
boolSystem "sh" [Param "-c", Param $ gencmd url basecmd]
<&&> doesFileExist file
gencmd basecmd url =
replace "%file" (shellEscape file) $
replace "%url" (shellEscape url)
basecmd
gencmd url = massReplace
[ ("%file", shellEscape file)
, ("%url", shellEscape url)
]
{- Copies a key's content, when present, to a temp file.
- This is used to speed up some rsyncs. -}

View file

@ -11,6 +11,7 @@ import System.IO
import Control.Monad
import Foreign
import Data.Char
import Data.List
import Control.Applicative
import System.Posix.Process (getAnyProcessStatus)
@ -70,6 +71,23 @@ segmentDelim p l = map reverse $ go [] [] l
| p i = go [] ([i]:c:r) is
| otherwise = go (i:c) r is
{- Replaces multiple values in a string.
-
- Takes care to skip over just-replaced values, so that they are not
- mangled. For example, massReplace [("foo", "new foo")] does not
- replace the "new foo" with "new new foo".
-}
massReplace :: [(String, String)] -> String -> String
massReplace vs = go [] vs
where
go acc _ [] = concat $ reverse acc
go acc [] (c:cs) = go ([c]:acc) vs cs
go acc ((val, replacement):rest) s
| val `isPrefixOf` s =
go (replacement:acc) vs (drop (length val) s)
| otherwise = go acc rest s
{- Given two orderings, returns the second if the first is EQ and returns
- the first otherwise.
-