@@ -20,6 +20,9 @@ import Foreign.Ptr
20import Foreign.ForeignPtr
20import Foreign.ForeignPtr
21import Foreign.Marshal.Alloc
21import Foreign.Marshal.Alloc
24+import Control.Monad.Attempt.Class
23data ParserStruct
26data ParserStruct
24type Parser = Ptr ParserStruct
27type Parser = Ptr ParserStruct
25parserSize :: Int
28parserSize :: Int
@@ -70,13 +73,13 @@ foreign import ccall unsafe "yaml_event_delete"
70foreign import ccall "print_parser_error"
73foreign import ccall "print_parser_error"
71 c_print_parser_error :: Parser -> IO ()
74 c_print_parser_error :: Parser -> IO ()
73−-- FIXME more grace error handling
74−parserParseOne :: Parser -> IO Event
76+parserParseOne :: Parser -> IO (Attempt Event)
75parserParseOne parser = withEventRaw $ \er -> do
77parserParseOne parser = withEventRaw $ \er -> do
76 res <- c_yaml_parser_parse parser er
78 res <- c_yaml_parser_parse parser er
77− when (res == 0) $
80+ if res == 0
78− c_print_parser_error parser >> fail "yaml_parser_parse failed"
81+ then c_print_parser_error parser >> return (failureString "yaml_parser_parse failed") -- FIXME get the actual error message
79− event <- getEvent er
82+ else return `fmap` getEvent er
80 c_yaml_event_delete er
83 c_yaml_event_delete er
81 return event
84 return event
@@ -139,14 +142,19 @@ getEvent er = do
139 YamlMappingStartEvent -> return EventMappingStart
142 YamlMappingStartEvent -> return EventMappingStart
140 YamlMappingEndEvent -> return EventMappingEnd
143 YamlMappingEndEvent -> return EventMappingEnd
142−parserParse :: Parser -> IO [Event]
145+parserParse :: Parser -> IO (Attempt [Event])
143parserParse parser = do
146parserParse parser = do
144− event <- parserParseOne parser
147+ event' <- parserParseOne parser
145− case event of
148+ case event' of
149+ Failure e -> return $ Failure e
146− EventStreamEnd -> return [event]
152+ EventStreamEnd -> return $ Success [event]
148− rest <- parserParse parser
154+ rest <- parserParse parser
156+ Failure e -> return $ Failure e
149− return $! event : rest
157+ Success rest' -> return $ Success $ event : rest'
151-- Emitter
159-- Emitter
@@ -175,20 +183,23 @@ foreign import ccall unsafe "get_buffer_buff"
175foreign import ccall unsafe "get_buffer_used"
183foreign import ccall unsafe "get_buffer_used"
176 c_get_buffer_used :: Buffer -> IO CULong
184 c_get_buffer_used :: Buffer -> IO CULong
178−withBuffer :: (Buffer -> IO ()) -> IO B.ByteString
186+withBuffer :: (Buffer -> IO (Attempt ())) -> IO (Attempt B.ByteString)
179withBuffer f = do
187withBuffer f = do
180 allocaBytes bufferSize $ \b -> do
188 allocaBytes bufferSize $ \b -> do
181 c_buffer_init b
189 c_buffer_init b
192+ Failure e -> return $ Failure e
183− ptr' <- c_get_buffer_buff b
194+ ptr' <- c_get_buffer_buff b
184− len <- c_get_buffer_used b
195+ len <- c_get_buffer_used b
185− fptr <- newForeignPtr_ $ castPtr ptr'
196+ fptr <- newForeignPtr_ $ castPtr ptr'
186− return $! B.fromForeignPtr fptr 0 $ fromIntegral len
197+ return $ Success $ B.fromForeignPtr fptr 0 $ fromIntegral len
188foreign import ccall unsafe "my_emitter_set_output"
199foreign import ccall unsafe "my_emitter_set_output"
189 c_my_emitter_set_output :: Emitter -> Buffer -> IO ()
200 c_my_emitter_set_output :: Emitter -> Buffer -> IO ()
191−withEmitter :: (Emitter -> IO ()) -> IO B.ByteString
202+withEmitter :: (Emitter -> IO (Attempt ())) -> IO (Attempt B.ByteString)
192withEmitter f = do
203withEmitter f = do
193 allocaBytes emitterSize $ \e -> do
204 allocaBytes emitterSize $ \e -> do
194 _res <- c_yaml_emitter_initialize e
205 _res <- c_yaml_emitter_initialize e
@@ -205,14 +216,13 @@ foreign import ccall unsafe "yaml_emitter_emit"
205foreign import ccall unsafe "print_emitter_error"
216foreign import ccall unsafe "print_emitter_error"
206 c_print_emitter_error :: Emitter -> IO ()
217 c_print_emitter_error :: Emitter -> IO ()
208−-- FIXME more graceful error handling
209−emitEvents :: Emitter -> [Event] -> IO ()
219+emitEvents :: Emitter -> [Event] -> IO (Attempt ())
210−emitEvents _ [] = return ()
220+emitEvents _ [] = return $ Success ()
211emitEvents emitter (e:rest) = do
221emitEvents emitter (e:rest) = do
212 res <- toEventRaw e $ c_yaml_emitter_emit emitter
222 res <- toEventRaw e $ c_yaml_emitter_emit emitter
213− when (res == 0) $
223+ if res == 0
214− c_print_emitter_error emitter >> fail "yaml_emitter_emit failed"
224+ then c_print_emitter_error emitter >> return (failureString "yaml_emitter_emit failed") -- FIXME get the actual error message
215− emitEvents emitter rest
225+ else emitEvents emitter rest
217foreign import ccall unsafe "yaml_stream_start_event_initialize"
227foreign import ccall unsafe "yaml_stream_start_event_initialize"
218 c_yaml_stream_start_event_initialize :: EventRaw -> CInt -> IO CInt
228 c_yaml_stream_start_event_initialize :: EventRaw -> CInt -> IO CInt