$OpenBSD: patch-src_Actions_hs,v 1.1 2013/07/12 13:48:39 dcoppa Exp $

Due to our regex(3) library not supporting GNU extensions, xmobar
immediately fails at startup:

xmobar: user error (Text.Regex.Posix.String died: (ReturnCode 13,"repetition-operator operand invalid"))

when using the StdinReader plugin.

So do what's required with Text.Regex.PCRE instead of Text.Regex.Posix.

Code contributed by Alexander Polakov, thanks!

--- src/Actions.hs.orig	Wed Jun  5 00:37:16 2013
+++ src/Actions.hs	Fri Jul 12 14:47:17 2013
@@ -14,7 +14,8 @@ module Actions (Action(..), runAction, stripActions) w
 
 import System.Process (system)
 import Control.Monad (void)
-import Text.Regex (subRegex, mkRegex)
+import Text.Regex.PCRE
+import Data.Array ((!))
 
 data Action = Spawn String
                 deriving (Eq)
@@ -23,5 +24,41 @@ runAction :: Action -> IO ()
 runAction (Spawn s) = void $ system (s ++ "&")
 
 stripActions :: String -> String
-stripActions s = subRegex actionRegex s "[action=\1]\2[action]"
-  where actionRegex = mkRegex "<action=([^>])*>(.+?)</action>"
+stripActions s = subRegex actionRegex s "[action=\\1]\\2[action]"
+  where actionRegex = makeRegex "<action=([^>]*)>(.+?)</action>"
+
+-- copy-pasted from regex-compat
+subRegex :: Regex                          -- ^ Search pattern
+         -> String                         -- ^ Input string
+         -> String                         -- ^ Replacement text
+         -> String                         -- ^ Output string
+subRegex _ "" _ = ""
+subRegex regexp inp repl =
+  let compile _i str [] = \ _m ->  (str++)
+      compile i str (("\\",(off,len)):rest) =
+        let i' = off+len
+            pre = take (off-i) str
+            str' = drop (i'-i) str
+        in if null str' then \ _m -> (pre ++) . ('\\':)
+             else \  m -> (pre ++) . ('\\' :) . compile i' str' rest m
+      compile i str ((xstr,(off,len)):rest) =
+        let i' = off+len
+            pre = take (off-i) str
+            str' = drop (i'-i) str
+            x = read xstr
+        in if null str' then \ m -> (pre++) . ((fst (m!x))++)
+             else \ m -> (pre++) . ((fst (m!x))++) . compile i' str' rest m
+      compiled :: MatchText String -> String -> String
+      compiled = compile 0 repl findrefs where
+        -- bre matches a backslash then capture either a backslash or some digits
+        bre = makeRegex "\\\\(\\\\|[0-9]+)" :: Regex
+        findrefs = map (\m -> (fst (m!1),snd (m!0))) (matchAllText bre repl)
+      go _i str [] = str
+      go i str (m:ms) =
+        let (_,(off,len)) = m!0
+            i' = off+len
+            pre = take (off-i) str
+            str' = drop (i'-i) str
+        in if null str' then pre ++ (compiled m "")
+             else pre ++ (compiled m (go i' str' ms))
+  in go 0 inp (matchAllText regexp inp)   
