@@ -27,6 +27,10 @@ import Control.Monad.Failure
27import Data.Typeable (Typeable)
27import Data.Typeable (Typeable)
28import Control.Exception (Exception)
28import Control.Exception (Exception)
30+import Data.Convertible
31+import Data.Text.Lazy (Text)
32+import Data.Object.Text ()
30data ParserStruct
34data ParserStruct
31type Parser = Ptr ParserStruct
35type Parser = Ptr ParserStruct
32parserSize :: Int
36parserSize :: Int
@@ -73,15 +77,32 @@ foreign import ccall unsafe "yaml_parser_parse"
73foreign import ccall unsafe "yaml_event_delete"
77foreign import ccall unsafe "yaml_event_delete"
74 c_yaml_event_delete :: EventRaw -> IO ()
78 c_yaml_event_delete :: EventRaw -> IO ()
76−foreign import ccall "print_parser_error"
80+foreign import ccall "get_parser_error_problem"
77− c_print_parser_error :: Parser -> IO ()
81+ c_get_parser_error_problem :: Parser -> IO (Ptr CUChar)
83+foreign import ccall "get_parser_error_context"
84+ c_get_parser_error_context :: Parser -> IO (Ptr CUChar)
86+foreign import ccall unsafe "get_parser_error_offset"
87+ c_get_parser_error_offset :: Parser -> IO CULong
79data YamlException =
89data YamlException =
80− YamlParserException String
90+ YamlParserException
91+ { parserProblem :: String
92+ , parserContext :: String
93+ , parserOffset :: Int
81− | YamlEmitterException String
95+ | YamlEmitterException { emitterProblem :: String }
82 deriving (Show, Typeable)
96 deriving (Show, Typeable)
83instance Exception YamlException
97instance Exception YamlException
99+makeString :: (a -> IO (Ptr CUChar)) -> a -> IO String
101+ cchar <- castPtr `fmap` f a
102+ len <- fromIntegral `fmap` B.c_strlen cchar
103+ bs <- B.create len $ \dest -> B.memcpy dest (castPtr cchar) (fromIntegral len)
104+ return $ (convertSuccess :: Text -> String) $ convertSuccess bs
85parserParseOne :: MonadFailure YamlException m
106parserParseOne :: MonadFailure YamlException m
86 => Parser
107 => Parser
87 -> IO (m Event)
108 -> IO (m Event)
@@ -89,8 +110,13 @@ parserParseOne parser = withEventRaw $ \er -> do
89 res <- c_yaml_parser_parse parser er
110 res <- c_yaml_parser_parse parser er
91 if res == 0
112 if res == 0
92− then c_print_parser_error parser
113+ then do
114+ problem <- makeString c_get_parser_error_problem parser
115+ context <- makeString c_get_parser_error_context parser
116+ offset <- fromIntegral `fmap`
117+ c_get_parser_error_offset parser
93− >> return (failure $ YamlParserException "FIXME")
118+ return $ failure $
119+ YamlParserException problem context offset
94 else return `fmap` getEvent er
120 else return `fmap` getEvent er
95 c_yaml_event_delete er
121 c_yaml_event_delete er
96 return event
122 return event
@@ -154,7 +180,7 @@ getEvent er = do
154 YamlMappingStartEvent -> return EventMappingStart
180 YamlMappingStartEvent -> return EventMappingStart
155 YamlMappingEndEvent -> return EventMappingEnd
181 YamlMappingEndEvent -> return EventMappingEnd
157−data YAttempt v = YSuccess v | YFailure YamlException -- FIXME use c-m-e?
183+data YAttempt v = YSuccess v | YFailure YamlException
158instance Monad YAttempt where
184instance Monad YAttempt where
159 return = YSuccess
185 return = YSuccess
160 YSuccess v >>= f = f v
186 YSuccess v >>= f = f v
@@ -237,8 +263,8 @@ withEmitter f = allocaBytes emitterSize $ \e -> do
237foreign import ccall unsafe "yaml_emitter_emit"
263foreign import ccall unsafe "yaml_emitter_emit"
238 c_yaml_emitter_emit :: Emitter -> EventRaw -> IO CInt
264 c_yaml_emitter_emit :: Emitter -> EventRaw -> IO CInt
240−foreign import ccall unsafe "print_emitter_error"
266+foreign import ccall unsafe "get_emitter_error"
241− c_print_emitter_error :: Emitter -> IO ()
267+ c_get_emitter_error :: Emitter -> IO (Ptr CUChar)
243emitEvents :: MonadFailure YamlException m
269emitEvents :: MonadFailure YamlException m
244 => Emitter
270 => Emitter
@@ -248,8 +274,9 @@ emitEvents _ [] = return $ return ()
248emitEvents emitter (e:rest) = do
274emitEvents emitter (e:rest) = do
249 res <- toEventRaw e $ c_yaml_emitter_emit emitter
275 res <- toEventRaw e $ c_yaml_emitter_emit emitter
250 if res == 0
276 if res == 0
251− then c_print_emitter_error emitter
277+ then do
278+ problem <- makeString c_get_emitter_error emitter
252− >> return (failure $ YamlEmitterException "FIXME")
279+ return $ failure $ YamlEmitterException problem
253 else emitEvents emitter rest
280 else emitEvents emitter rest
255foreign import ccall unsafe "yaml_stream_start_event_initialize"
282foreign import ccall unsafe "yaml_stream_start_event_initialize"