add a formatContainsVar function
Also, the format function gets faster because it checks for "escaped_" at gen time instead of every time format is called.
This commit is contained in:
parent
224208a657
commit
30ac015b79
1 changed files with 27 additions and 9 deletions
|
@ -1,6 +1,6 @@
|
||||||
{- Formatted string handling.
|
{- Formatted string handling.
|
||||||
-
|
-
|
||||||
- Copyright 2010, 2011 Joey Hess <id@joeyh.name>
|
- Copyright 2010-2020 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- License: BSD-2-clause
|
- License: BSD-2-clause
|
||||||
-}
|
-}
|
||||||
|
@ -9,6 +9,7 @@ module Utility.Format (
|
||||||
Format,
|
Format,
|
||||||
gen,
|
gen,
|
||||||
format,
|
format,
|
||||||
|
formatContainsVar,
|
||||||
decode_c,
|
decode_c,
|
||||||
encode_c,
|
encode_c,
|
||||||
prop_encode_c_decode_c_roundtrip
|
prop_encode_c_decode_c_roundtrip
|
||||||
|
@ -29,9 +30,14 @@ type FormatString = String
|
||||||
{- A format consists of a list of fragments. -}
|
{- A format consists of a list of fragments. -}
|
||||||
type Format = [Frag]
|
type Format = [Frag]
|
||||||
|
|
||||||
{- A fragment is either a constant string,
|
{- A fragment is either a constant string, or a variable. -}
|
||||||
- or a variable, with a justification. -}
|
data Frag
|
||||||
data Frag = Const String | Var String Justify
|
= Const String
|
||||||
|
| Var
|
||||||
|
{ varName :: String
|
||||||
|
, varJustify :: Justify
|
||||||
|
, varEscaped :: Bool
|
||||||
|
}
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
data Justify = LeftJustified Int | RightJustified Int | UnJustified
|
data Justify = LeftJustified Int | RightJustified Int | UnJustified
|
||||||
|
@ -45,10 +51,8 @@ format :: Format -> Variables -> String
|
||||||
format f vars = concatMap expand f
|
format f vars = concatMap expand f
|
||||||
where
|
where
|
||||||
expand (Const s) = s
|
expand (Const s) = s
|
||||||
expand (Var name j)
|
expand (Var name j esc)
|
||||||
| "escaped_" `isPrefixOf` name =
|
| esc = justify j $ encode_c_strict $ getvar name
|
||||||
justify j $ encode_c_strict $
|
|
||||||
getvar $ drop (length "escaped_") name
|
|
||||||
| otherwise = justify j $ getvar name
|
| otherwise = justify j $ getvar name
|
||||||
getvar name = fromMaybe "" $ M.lookup name vars
|
getvar name = fromMaybe "" $ M.lookup name vars
|
||||||
justify UnJustified s = s
|
justify UnJustified s = s
|
||||||
|
@ -61,6 +65,8 @@ format f vars = concatMap expand f
|
||||||
- format string, such as "${foo} ${bar;10} ${baz;-10}\n"
|
- format string, such as "${foo} ${bar;10} ${baz;-10}\n"
|
||||||
-
|
-
|
||||||
- (This is the same type of format string used by dpkg-query.)
|
- (This is the same type of format string used by dpkg-query.)
|
||||||
|
-
|
||||||
|
- Also, "${escaped_foo}" will apply encode_c to the value of variable foo.
|
||||||
-}
|
-}
|
||||||
gen :: FormatString -> Format
|
gen :: FormatString -> Format
|
||||||
gen = filter (not . empty) . fuse [] . scan [] . decode_c
|
gen = filter (not . empty) . fuse [] . scan [] . decode_c
|
||||||
|
@ -94,12 +100,24 @@ gen = filter (not . empty) . fuse [] . scan [] . decode_c
|
||||||
| i < 0 = LeftJustified (-1 * i)
|
| i < 0 = LeftJustified (-1 * i)
|
||||||
| otherwise = RightJustified i
|
| otherwise = RightJustified i
|
||||||
novar v = "${" ++ reverse v
|
novar v = "${" ++ reverse v
|
||||||
foundvar f v p = scan (Var (reverse v) p : f)
|
foundvar f varname_r p =
|
||||||
|
let varname = reverse varname_r
|
||||||
|
var = if "escaped_" `isPrefixOf` varname
|
||||||
|
then Var (drop (length "escaped_") varname) p True
|
||||||
|
else Var varname p False
|
||||||
|
in scan (var : f)
|
||||||
|
|
||||||
empty :: Frag -> Bool
|
empty :: Frag -> Bool
|
||||||
empty (Const "") = True
|
empty (Const "") = True
|
||||||
empty _ = False
|
empty _ = False
|
||||||
|
|
||||||
|
{- Check if a Format contains a variable with a specified name. -}
|
||||||
|
formatContainsVar :: String -> Format -> Bool
|
||||||
|
formatContainsVar v = any go
|
||||||
|
where
|
||||||
|
go (Var v' _ _) | v' == v = True
|
||||||
|
go _ = False
|
||||||
|
|
||||||
{- Decodes a C-style encoding, where \n is a newline (etc),
|
{- Decodes a C-style encoding, where \n is a newline (etc),
|
||||||
- \NNN is an octal encoded character, and \xNN is a hex encoded character.
|
- \NNN is an octal encoded character, and \xNN is a hex encoded character.
|
||||||
-}
|
-}
|
||||||
|
|
Loading…
Reference in a new issue