From dff657f1c1fdb2f91e606ba02ae94ed439e3af78 Mon Sep 17 00:00:00 2001 From: Jens Nolte <git@queezle.net> Date: Thu, 9 Sep 2021 18:06:54 +0200 Subject: [PATCH] Parse arguments from xml specification --- src/Quasar/Wayland/Protocol/Core.hs | 1 - src/Quasar/Wayland/Protocol/TH.hs | 67 +++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/Quasar/Wayland/Protocol/Core.hs b/src/Quasar/Wayland/Protocol/Core.hs index 2b5a0df..0222b96 100644 --- a/src/Quasar/Wayland/Protocol/Core.hs +++ b/src/Quasar/Wayland/Protocol/Core.hs @@ -213,7 +213,6 @@ invalidOpcode object opcode = fail $ "Invalid opcode " <> show opcode <> " on " <> objectInterfaceName object <> "@" <> show (objectId object) - -- TODO remove data DynamicArgument = DynamicIntArgument Int32 diff --git a/src/Quasar/Wayland/Protocol/TH.hs b/src/Quasar/Wayland/Protocol/TH.hs index 6066fe2..a313fe0 100644 --- a/src/Quasar/Wayland/Protocol/TH.hs +++ b/src/Quasar/Wayland/Protocol/TH.hs @@ -31,7 +31,28 @@ newtype EventSpec = EventSpec MessageSpec data MessageSpec = MessageSpec { name :: String, - opcode :: Opcode + opcode :: Opcode, + arguments :: [ArgumentSpec] +} + deriving stock Show + + +data ArgumentType + = IntArgument + | UIntArgument + | FixedArgument + | StringArgument + | ArrayArgument + | ObjectArgument String + | UnknownObjectArgument + | NewIdArgument String + | UnknownNewIdArgument + | FdArgument + deriving stock Show + +data ArgumentSpec = ArgumentSpec { + name :: String, + argType :: ArgumentType } deriving stock Show @@ -155,20 +176,47 @@ parseInterface element = do } parseRequest :: MonadFail m => (Opcode, Element) -> m RequestSpec -parseRequest (opcode, element) = do +parseRequest x = RequestSpec <$> parseMessage x + +parseEvent :: MonadFail m => (Opcode, Element) -> m EventSpec +parseEvent x = EventSpec <$> parseMessage x + +parseMessage :: MonadFail m => (Opcode, Element) -> m MessageSpec +parseMessage (opcode, element) = do name <- getAttr "name" element - pure $ RequestSpec MessageSpec { + arguments <- mapM parseArgument $ findChildren (qname "arg") element + pure MessageSpec { name, - opcode + opcode, + arguments } -parseEvent :: MonadFail m => (Opcode, Element) -> m EventSpec -parseEvent (opcode, element) = do + +parseArgument :: forall m. MonadFail m => Element -> m ArgumentSpec +parseArgument element = do name <- getAttr "name" element - pure $ EventSpec MessageSpec { + argTypeStr <- getAttr "type" element + interface <- peekAttr "interface" element + argType <- parseArgumentType argTypeStr interface + pure ArgumentSpec { name, - opcode + argType } + where + parseArgumentType :: String -> Maybe String -> m ArgumentType + parseArgumentType "int" Nothing = pure IntArgument + parseArgumentType "uint" Nothing = pure UIntArgument + parseArgumentType "fixed" Nothing = pure FixedArgument + parseArgumentType "string" Nothing = pure StringArgument + parseArgumentType "array" Nothing = pure ArrayArgument + parseArgumentType "object" (Just interface) = pure (ObjectArgument interface) + parseArgumentType "object" Nothing = pure UnknownObjectArgument + parseArgumentType "new_id" (Just interface) = pure (NewIdArgument interface) + parseArgumentType "new_id" Nothing = pure UnknownNewIdArgument + parseArgumentType "fd" Nothing = pure FdArgument + parseArgumentType x Nothing = fail $ "Unknown argument type \"" <> x <> "\" encountered" + parseArgumentType x _ = fail $ "Argument type \"" <> x <> "\" should not have \"interface\" attribute" + qname :: String -> QName qname name = blank_name { qName = name } @@ -177,3 +225,6 @@ getAttr :: MonadFail m => String -> Element -> m String getAttr name element = do (Just value) <- pure $ findAttr (qname name) element pure value + +peekAttr :: Applicative m => String -> Element -> m (Maybe String) +peekAttr name element = pure $ findAttr (qname name) element -- GitLab