Handle tilde expansion in pattern matching (fixes #1769)
This commit is contained in:
parent
14e6806092
commit
34885142e7
|
@ -463,30 +463,35 @@ data PseudoGlob = PGAny | PGMany | PGChar Char
|
||||||
-- Turn a word into a PG pattern, replacing all unknown/runtime values with
|
-- Turn a word into a PG pattern, replacing all unknown/runtime values with
|
||||||
-- PGMany.
|
-- PGMany.
|
||||||
wordToPseudoGlob :: Token -> [PseudoGlob]
|
wordToPseudoGlob :: Token -> [PseudoGlob]
|
||||||
wordToPseudoGlob word =
|
wordToPseudoGlob = fromMaybe [PGMany] . wordToPseudoGlob' False
|
||||||
simplifyPseudoGlob . concatMap f $ getWordParts word
|
|
||||||
where
|
|
||||||
f x = case x of
|
|
||||||
T_Literal _ s -> map PGChar s
|
|
||||||
T_SingleQuoted _ s -> map PGChar s
|
|
||||||
|
|
||||||
T_Glob _ "?" -> [PGAny]
|
|
||||||
T_Glob _ ('[':_) -> [PGAny]
|
|
||||||
|
|
||||||
_ -> [PGMany]
|
|
||||||
|
|
||||||
-- Turn a word into a PG pattern, but only if we can preserve
|
-- Turn a word into a PG pattern, but only if we can preserve
|
||||||
-- exact semantics.
|
-- exact semantics.
|
||||||
wordToExactPseudoGlob :: Token -> Maybe [PseudoGlob]
|
wordToExactPseudoGlob :: Token -> Maybe [PseudoGlob]
|
||||||
wordToExactPseudoGlob word =
|
wordToExactPseudoGlob = wordToPseudoGlob' True
|
||||||
simplifyPseudoGlob . concat <$> mapM f (getWordParts word)
|
|
||||||
|
wordToPseudoGlob' :: Bool -> Token -> Maybe [PseudoGlob]
|
||||||
|
wordToPseudoGlob' exact word =
|
||||||
|
simplifyPseudoGlob <$> toGlob word
|
||||||
where
|
where
|
||||||
|
toGlob :: Token -> Maybe [PseudoGlob]
|
||||||
|
toGlob word =
|
||||||
|
case word of
|
||||||
|
T_NormalWord _ (T_Literal _ ('~':str):rest) -> do
|
||||||
|
guard $ not exact
|
||||||
|
let this = (PGMany : (map PGChar $ dropWhile (/= '/') str))
|
||||||
|
tail <- concat <$> (mapM f $ concatMap getWordParts rest)
|
||||||
|
return $ this ++ tail
|
||||||
|
_ -> concat <$> (mapM f $ getWordParts word)
|
||||||
|
|
||||||
f x = case x of
|
f x = case x of
|
||||||
T_Literal _ s -> return $ map PGChar s
|
T_Literal _ s -> return $ map PGChar s
|
||||||
T_SingleQuoted _ s -> return $ map PGChar s
|
T_SingleQuoted _ s -> return $ map PGChar s
|
||||||
T_Glob _ "?" -> return [PGAny]
|
T_Glob _ "?" -> return [PGAny]
|
||||||
T_Glob _ "*" -> return [PGMany]
|
T_Glob _ "*" -> return [PGMany]
|
||||||
_ -> fail "Unknown token type"
|
T_Glob _ ('[':_) | not exact -> return [PGAny]
|
||||||
|
_ -> if exact then fail "" else return [PGMany]
|
||||||
|
|
||||||
|
|
||||||
-- Reorder a PseudoGlob for more efficient matching, e.g.
|
-- Reorder a PseudoGlob for more efficient matching, e.g.
|
||||||
-- f?*?**g -> f??*g
|
-- f?*?**g -> f??*g
|
||||||
|
|
|
@ -1211,6 +1211,9 @@ prop_checkConstantIfs6 = verifyNot checkConstantIfs "[[ a -ot b ]]"
|
||||||
prop_checkConstantIfs7 = verifyNot checkConstantIfs "[ a -nt b ]"
|
prop_checkConstantIfs7 = verifyNot checkConstantIfs "[ a -nt b ]"
|
||||||
prop_checkConstantIfs8 = verifyNot checkConstantIfs "[[ ~foo == '~foo' ]]"
|
prop_checkConstantIfs8 = verifyNot checkConstantIfs "[[ ~foo == '~foo' ]]"
|
||||||
prop_checkConstantIfs9 = verify checkConstantIfs "[[ *.png == [a-z] ]]"
|
prop_checkConstantIfs9 = verify checkConstantIfs "[[ *.png == [a-z] ]]"
|
||||||
|
prop_checkConstantIfs10 = verifyNot checkConstantIfs "[[ ~me == ~+ ]]"
|
||||||
|
prop_checkConstantIfs11 = verifyNot checkConstantIfs "[[ ~ == ~+ ]]"
|
||||||
|
prop_checkConstantIfs12 = verify checkConstantIfs "[[ '~' == x ]]"
|
||||||
checkConstantIfs _ (TC_Binary id typ op lhs rhs) | not isDynamic =
|
checkConstantIfs _ (TC_Binary id typ op lhs rhs) | not isDynamic =
|
||||||
if isConstant lhs && isConstant rhs
|
if isConstant lhs && isConstant rhs
|
||||||
then warn id 2050 "This expression is constant. Did you forget the $ on a variable?"
|
then warn id 2050 "This expression is constant. Did you forget the $ on a variable?"
|
||||||
|
|
Loading…
Reference in New Issue