module Kparams.Internal where

-- word extracts the first "word" from the input,
-- returning the word itself and what's left.
-- We split on unquoted, unescaped spaces.
word :: String -> Maybe Char -> (String, String)
word :: String -> Maybe Char -> (String, String)
word []        Maybe Char
_       = ([], [])

word (Char
' ':String
xs)  Maybe Char
Nothing = ([], String
xs)
word (Char
'\t':String
xs) Maybe Char
Nothing = ([], String
xs)
word (Char
'\n':String
xs) Maybe Char
Nothing = ([], String
xs)
word (Char
x:[])    Maybe Char
Nothing = ([Char
x], [])
word (Char
x:String
xs)    Maybe Char
Nothing = (String
progress, String
rem)
  where special :: Bool
special = Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'"' Bool -> Bool -> Bool
|| Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\'' Bool -> Bool -> Bool
|| Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\\'
        (String
wurd, String
rem) = String -> Maybe Char -> (String, String)
word String
xs (if Bool
special then Char -> Maybe Char
forall a. a -> Maybe a
Just Char
x else Maybe Char
forall a. Maybe a
Nothing)
        progress :: String
progress = if Bool
special then String
wurd else Char
xChar -> String -> String
forall a. a -> [a] -> [a]
:String
wurd

word (Char
'\'':String
xs) (Just Char
'\'') = String -> Maybe Char -> (String, String)
word String
xs Maybe Char
forall a. Maybe a
Nothing
word (Char
'"':String
xs)  (Just Char
'"')  = String -> Maybe Char -> (String, String)
word String
xs Maybe Char
forall a. Maybe a
Nothing
word (Char
x:String
xs)    (Just Char
'\\') = (Char
xChar -> String -> String
forall a. a -> [a] -> [a]
:String
wurd, String
rem)
  where (String
wurd, String
rem) = String -> Maybe Char -> (String, String)
word String
xs Maybe Char
forall a. Maybe a
Nothing
word (Char
x:String
xs)    Maybe Char
q           = (Char
xChar -> String -> String
forall a. a -> [a] -> [a]
:String
wurd, String
rem)
  where (String
wurd, String
rem) = String -> Maybe Char -> (String, String)
word String
xs Maybe Char
q


-- wordsplit splits a string into words, using `word`.
wordsplit :: String -> [String]
wordsplit :: String -> [String]
wordsplit String
"" = []
wordsplit String
s = String
wurdString -> [String] -> [String]
forall a. a -> [a] -> [a]
:(String -> [String]
wordsplit String
rem)
  where (String
wurd, String
rem) = String -> Maybe Char -> (String, String)
word String
s Maybe Char
forall a. Maybe a
Nothing

-- var splits a string into a name-value pait at the first =.
var :: String -> (String, String)
var :: String -> (String, String)
var []       = ([], [])
var (Char
'=':String
xs) = ([], String
xs)
var (Char
x:String
xs)   = (Char
xChar -> String -> String
forall a. a -> [a] -> [a]
:String
vname, String
val)
  where (String
vname, String
val) = String -> (String, String)
var String
xs


-- find takes a /proc/cmdline string and Maybe finds the desired param.
find :: String -> String -> Maybe String
find :: String -> String -> Maybe String
find String
"" String
_      = Maybe String
forall a. Maybe a
Nothing
find String
_  String
""     = Maybe String
forall a. Maybe a
Nothing
find String
want String
have = if [(String, String)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(String, String)]
matching Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
                 then (String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String)
-> ((String, String) -> String) -> (String, String) -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, String) -> String
forall a b. (a, b) -> b
snd) ((String, String) -> Maybe String)
-> (String, String) -> Maybe String
forall a b. (a -> b) -> a -> b
$ [(String, String)] -> (String, String)
forall a. [a] -> a
last [(String, String)]
matching
                 else Maybe String
forall a. Maybe a
Nothing
  where varpairs :: [(String, String)]
varpairs = (String -> (String, String)) -> [String] -> [(String, String)]
forall a b. (a -> b) -> [a] -> [b]
map String -> (String, String)
var (String -> [String]
wordsplit String
have)
        isOurParam :: (String, b) -> Bool
isOurParam (String, b)
vp = String
want String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== (String, b) -> String
forall a b. (a, b) -> a
fst (String, b)
vp
        matching :: [(String, String)]
matching = ((String, String) -> Bool)
-> [(String, String)] -> [(String, String)]
forall a. (a -> Bool) -> [a] -> [a]
filter (String, String) -> Bool
forall b. (String, b) -> Bool
isOurParam [(String, String)]
varpairs