@@ -26,7 +26,9 @@ module Text.Libyaml
2626 , emitStream
2727 , emitDocument
2828 , emitSequence
29+ , emitSequenceWithAnchor
2930 , emitMapping
31+ , emitMappingWithAnchor
3032 -- * Higher level functions
3133 , encode
3234 , decode
@@ -57,11 +59,11 @@ data Event =
5759 | EventStreamEnd
5860 | EventDocumentStart
5961 | EventDocumentEnd
60− | EventAlias
61− | EventScalar !ByteString !Tag !Style
62− | EventSequenceStart
62+ | EventAlias !AnchorName
63+ | EventScalar !ByteString !Tag !Style !Anchor
64+ | EventSequenceStart !Anchor
6365 | EventSequenceEnd
64− | EventMappingStart
66+ | EventMappingStart !Anchor
6567 | EventMappingEnd
6668 deriving (Show, Eq)
6769
@@ -85,6 +87,9 @@ data Tag = StrTag
8587 | NoTag
8688 deriving (Show, Eq)
8789
90+type AnchorName = String
91+type Anchor = Maybe AnchorName
92+
8893tagToString :: Tag -> String
8994tagToString StrTag = "tag:yaml.org,2002:str"
9095tagToString FloatTag = "tag:yaml.org,2002:float"
@@ -296,6 +301,18 @@ foreign import ccall unsafe "get_scalar_tag_len"
296301foreign import ccall unsafe "get_scalar_style"
297302 c_get_scalar_style :: EventRaw -> IO CInt
298303
304+foreign import ccall unsafe "get_scalar_anchor"
305+ c_get_scalar_anchor :: EventRaw -> IO CString
306+
307+foreign import ccall unsafe "get_sequence_start_anchor"
308+ c_get_sequence_start_anchor :: EventRaw -> IO CString
309+
310+foreign import ccall unsafe "get_mapping_start_anchor"
311+ c_get_mapping_start_anchor :: EventRaw -> IO CString
312+
313+foreign import ccall unsafe "get_alias_anchor"
314+ c_get_alias_anchor :: EventRaw -> IO CString
315+
299316getEvent :: EventRaw -> IO Event
300317getEvent er = do
301318 et <- c_get_event_type er
@@ -305,7 +322,12 @@ getEvent er = do
305322 YamlStreamEndEvent -> return EventStreamEnd
306323 YamlDocumentStartEvent -> return EventDocumentStart
307324 YamlDocumentEndEvent -> return EventDocumentEnd
308− YamlAliasEvent -> return EventAlias
325+ YamlAliasEvent -> do
326+ yanchor <- c_get_alias_anchor er
327+ anchor <- if yanchor == nullPtr
328+ then error "got YamlAliasEvent with empty anchor"
329+ else peekCString yanchor
330+ return $ EventAlias anchor
309331 YamlScalarEvent -> do
310332 yvalue <- c_get_scalar_value er
311333 ylen <- c_get_scalar_length er
@@ -324,10 +346,24 @@ getEvent er = do
324346 else B.create ytag_len'
325347 $ \dest -> B.memcpy dest ytag' (toEnum ytag_len')
326348 let style = toEnum $ fromEnum ystyle
327− return $ EventScalar bs (bsToTag tagbs) style
328− YamlSequenceStartEvent -> return EventSequenceStart
349+ yanchor <- c_get_scalar_anchor er
350+ anchor <- if yanchor == nullPtr
351+ then return Nothing
352+ else fmap Just $ peekCString yanchor
353+ return $ EventScalar bs (bsToTag tagbs) style anchor
354+ YamlSequenceStartEvent -> do
355+ yanchor <- c_get_sequence_start_anchor er
356+ anchor <- if yanchor == nullPtr
357+ then return Nothing
358+ else fmap Just $ peekCString yanchor
359+ return $ EventSequenceStart anchor
329360 YamlSequenceEndEvent -> return EventSequenceEnd
330− YamlMappingStartEvent -> return EventMappingStart
361+ YamlMappingStartEvent -> do
362+ yanchor <- c_get_mapping_start_anchor er
363+ anchor <- if yanchor == nullPtr
364+ then return Nothing
365+ else fmap Just $ peekCString yanchor
366+ return $ EventMappingStart anchor
331367 YamlMappingEndEvent -> return EventMappingEnd
332368
333369-- Emitter
@@ -429,10 +465,19 @@ emitStream, emitDocument, emitSequence, emitMapping
429465emitStream e = emitEvent EventStreamStart >> e >> emitEvent EventStreamEnd
430466emitDocument e = emitEvent EventDocumentStart >> e
431467 >> emitEvent EventDocumentEnd
432−emitSequence e = emitEvent EventSequenceStart >> e
433− >> emitEvent EventSequenceEnd
434−emitMapping e = emitEvent EventMappingStart >> e
435− >> emitEvent EventMappingEnd
468+emitSequence e = emitSequenceWithAnchor e Nothing
469+emitMapping e = emitMappingWithAnchor e Nothing
470+
471+emitSequenceWithAnchor, emitMappingWithAnchor
472+ :: (MonadIO m, MonadFailure YamlException m)
473+ => YamlEncoder m ()
474+ -> Anchor
475+ -> YamlEncoder m ()
476+emitSequenceWithAnchor e a = emitEvent (EventSequenceStart a) >> e
477+ >> emitEvent EventSequenceEnd
478+emitMappingWithAnchor e a = emitEvent (EventMappingStart a) >> e
479+ >> emitEvent EventMappingEnd
480+
436481
437482parseEvent :: (With m, MonadFailure YamlException m)
438483 => YamlDecoder m Event
@@ -489,6 +534,12 @@ foreign import ccall unsafe "yaml_mapping_start_event_initialize"
489534foreign import ccall unsafe "yaml_mapping_end_event_initialize"
490535 c_yaml_mapping_end_event_initialize :: EventRaw -> IO CInt
491536
537+foreign import ccall unsafe "yaml_alias_event_initialize"
538+ c_yaml_alias_event_initialize
539+ :: EventRaw
540+ -> Ptr CUChar
541+ -> IO CInt
542+
492543toEventRaw :: Event -> (EventRaw -> IO a) -> IO a
493544toEventRaw e f = allocaBytesR eventSize $ \er -> do
494545 ret <- case e of
@@ -502,7 +553,7 @@ toEventRaw e f = allocaBytesR eventSize $ \er -> do
502553 c_simple_document_start er
503554 EventDocumentEnd ->
504555 c_yaml_document_end_event_initialize er 1
505− EventScalar bs thetag style -> do
556+ EventScalar bs thetag style anchor -> do
506557 let (fvalue, offset, len) = B.toForeignPtr bs
507558 withForeignPtr fvalue $ \value -> do
508559 let value' = value `plusPtr` offset
@@ -515,34 +566,71 @@ toEventRaw e f = allocaBytesR eventSize $ \er -> do
515566 let style' = toEnum $ fromEnum style
516567 tagP = castPtr tag'
517568 qi = if null thetag' then 1 else 0
518− c_yaml_scalar_event_initialize
519− er
520− nullPtr -- anchor
521− tagP -- tag
522− value'' -- value
523− len' -- length
524− 0 -- plain_implicit
525− qi -- quoted_implicit
526− style' -- style
527− EventSequenceStart ->
569+ case anchor of
570+ Nothing ->
571+ c_yaml_scalar_event_initialize
572+ er
573+ nullPtr -- anchor
574+ tagP -- tag
575+ value'' -- value
576+ len' -- length
577+ 0 -- plain_implicit
578+ qi -- quoted_implicit
579+ style' -- style
580+ Just anchor' ->
581+ withCString anchor' $ \anchorP' -> do
582+ let anchorP = castPtr anchorP'
583+ c_yaml_scalar_event_initialize
584+ er
585+ anchorP -- anchor
586+ tagP -- tag
587+ value'' -- value
588+ len' -- length
589+ 0 -- plain_implicit
590+ qi -- quoted_implicit
591+ style' -- style
592+ EventSequenceStart Nothing ->
528593 c_yaml_sequence_start_event_initialize
529594 er
530595 nullPtr
531596 nullPtr
532597 1
533598 0 -- YAML_ANY_SEQUENCE_STYLE
599+ EventSequenceStart (Just anchor) ->
600+ withCString anchor $ \anchor' -> do
601+ let anchorP = castPtr anchor'
602+ c_yaml_sequence_start_event_initialize
603+ er
604+ anchorP
605+ nullPtr
606+ 1
607+ 0 -- YAML_ANY_SEQUENCE_STYLE
534608 EventSequenceEnd ->
535609 c_yaml_sequence_end_event_initialize er
536− EventMappingStart ->
610+ EventMappingStart Nothing ->
537611 c_yaml_mapping_start_event_initialize
538612 er
539613 nullPtr
540614 nullPtr
541615 1
542616 0 -- YAML_ANY_SEQUENCE_STYLE
617+ EventMappingStart (Just anchor) ->
618+ withCString anchor $ \anchor' -> do
619+ let anchorP = castPtr anchor'
620+ c_yaml_mapping_start_event_initialize
621+ er
622+ anchorP
623+ nullPtr
624+ 1
625+ 0 -- YAML_ANY_SEQUENCE_STYLE
543626 EventMappingEnd ->
544627 c_yaml_mapping_end_event_initialize er
545− EventAlias -> error "toEventRaw: EventAlias not supported"
628+ EventAlias anchor ->
629+ withCString anchor $ \anchorP' -> do
630+ let anchorP = castPtr anchorP'
631+ c_yaml_alias_event_initialize
632+ er
633+ anchorP
546634 EventNone -> error "toEventRaw: EventNone not supported"
547635 unless (ret == 1) $ throwIO $ ToEventRawException ret
548636 f er