packages feed

yaml (empty) → 0.0.0

raw patch · 7 files changed

+730/−0 lines, 7 filesdep +basedep +bytestringdep +bytestring-classsetup-changed

Dependencies added: base, bytestring, bytestring-class, data-object, haskell98

Files

+ C2HS.hs view
@@ -0,0 +1,220 @@+--  C->Haskell Compiler: Marshalling library+--+--  Copyright (c) [1999...2005] Manuel M T Chakravarty+--+--  Redistribution and use in source and binary forms, with or without+--  modification, are permitted provided that the following conditions are met:+-- +--  1. Redistributions of source code must retain the above copyright notice,+--     this list of conditions and the following disclaimer. +--  2. Redistributions in binary form must reproduce the above copyright+--     notice, this list of conditions and the following disclaimer in the+--     documentation and/or other materials provided with the distribution. +--  3. The name of the author may not be used to endorse or promote products+--     derived from this software without specific prior written permission. +--+--  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+--  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+--  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN+--  NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +--  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED+--  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR+--  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+--  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+--  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+--  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+--+--- Description ---------------------------------------------------------------+--+--  Language: Haskell 98+--+--  This module provides the marshaling routines for Haskell files produced by +--  C->Haskell for binding to C library interfaces.  It exports all of the+--  low-level FFI (language-independent plus the C-specific parts) together+--  with the C->HS-specific higher-level marshalling routines.+--++module C2HS (++  -- * Re-export the language-independent component of the FFI +  module Foreign,++  -- * Re-export the C language component of the FFI+  module CForeign,++  -- * Composite marshalling functions+  withCStringLenIntConv, peekCStringLenIntConv, withIntConv, withFloatConv,+  peekIntConv, peekFloatConv, withBool, peekBool, withEnum, peekEnum,++  -- * Conditional results using 'Maybe'+  nothingIf, nothingIfNull,++  -- * Bit masks+  combineBitMasks, containsBitMask, extractBitMasks,++  -- * Conversion between C and Haskell types+  cIntConv, cFloatConv, cToBool, cFromBool, cToEnum, cFromEnum+) where +++import Foreign+       hiding       (Word)+		    -- Should also hide the Foreign.Marshal.Pool exports in+		    -- compilers that export them+import CForeign++import Monad        (when, liftM)+++-- Composite marshalling functions+-- -------------------------------++-- Strings with explicit length+--+withCStringLenIntConv s f    = withCStringLen s $ \(p, n) -> f (p, cIntConv n)+peekCStringLenIntConv (s, n) = peekCStringLen (s, cIntConv n)++-- Marshalling of numerals+--++withIntConv   :: (Storable b, Integral a, Integral b) +	      => a -> (Ptr b -> IO c) -> IO c+withIntConv    = with . cIntConv++withFloatConv :: (Storable b, RealFloat a, RealFloat b) +	      => a -> (Ptr b -> IO c) -> IO c+withFloatConv  = with . cFloatConv++peekIntConv   :: (Storable a, Integral a, Integral b) +	      => Ptr a -> IO b+peekIntConv    = liftM cIntConv . peek++peekFloatConv :: (Storable a, RealFloat a, RealFloat b) +	      => Ptr a -> IO b+peekFloatConv  = liftM cFloatConv . peek++-- Passing Booleans by reference+--++withBool :: (Integral a, Storable a) => Bool -> (Ptr a -> IO b) -> IO b+withBool  = with . fromBool++peekBool :: (Integral a, Storable a) => Ptr a -> IO Bool+peekBool  = liftM toBool . peek+++-- Passing enums by reference+--++withEnum :: (Enum a, Integral b, Storable b) => a -> (Ptr b -> IO c) -> IO c+withEnum  = with . cFromEnum++peekEnum :: (Enum a, Integral b, Storable b) => Ptr b -> IO a+peekEnum  = liftM cToEnum . peek+++-- Storing of 'Maybe' values+-- -------------------------++instance Storable a => Storable (Maybe a) where+  sizeOf    _ = sizeOf    (undefined :: Ptr ())+  alignment _ = alignment (undefined :: Ptr ())++  peek p = do+	     ptr <- peek (castPtr p)+	     if ptr == nullPtr+	       then return Nothing+	       else liftM Just $ peek ptr++  poke p v = do+	       ptr <- case v of+		        Nothing -> return nullPtr+			Just v' -> new v'+               poke (castPtr p) ptr+++-- Conditional results using 'Maybe'+-- ---------------------------------++-- Wrap the result into a 'Maybe' type.+--+-- * the predicate determines when the result is considered to be non-existing,+--   ie, it is represented by `Nothing'+--+-- * the second argument allows to map a result wrapped into `Just' to some+--   other domain+--+nothingIf       :: (a -> Bool) -> (a -> b) -> a -> Maybe b+nothingIf p f x  = if p x then Nothing else Just $ f x++-- |Instance for special casing null pointers.+--+nothingIfNull :: (Ptr a -> b) -> Ptr a -> Maybe b+nothingIfNull  = nothingIf (== nullPtr)+++-- Support for bit masks+-- ---------------------++-- Given a list of enumeration values that represent bit masks, combine these+-- masks using bitwise disjunction.+--+combineBitMasks :: (Enum a, Bits b) => [a] -> b+combineBitMasks = foldl (.|.) 0 . map (fromIntegral . fromEnum)++-- Tests whether the given bit mask is contained in the given bit pattern+-- (i.e., all bits set in the mask are also set in the pattern).+--+containsBitMask :: (Bits a, Enum b) => a -> b -> Bool+bits `containsBitMask` bm = let bm' = fromIntegral . fromEnum $ bm+			    in+			    bm' .&. bits == bm'++-- |Given a bit pattern, yield all bit masks that it contains.+--+-- * This does *not* attempt to compute a minimal set of bit masks that when+--   combined yield the bit pattern, instead all contained bit masks are+--   produced.+--+extractBitMasks :: (Bits a, Enum b, Bounded b) => a -> [b]+extractBitMasks bits = +  [bm | bm <- [minBound..maxBound], bits `containsBitMask` bm]+++-- Conversion routines+-- -------------------++-- |Integral conversion+--+cIntConv :: (Integral a, Integral b) => a -> b+cIntConv  = fromIntegral++-- |Floating conversion+--+cFloatConv :: (RealFloat a, RealFloat b) => a -> b+cFloatConv  = realToFrac+-- As this conversion by default goes via `Rational', it can be very slow...+{-# RULES +  "cFloatConv/Float->Float"   forall (x::Float).  cFloatConv x = x;+  "cFloatConv/Double->Double" forall (x::Double). cFloatConv x = x+ #-}++-- |Obtain C value from Haskell 'Bool'.+--+cFromBool :: Num a => Bool -> a+cFromBool  = fromBool++-- |Obtain Haskell 'Bool' from C value.+--+cToBool :: Num a => a -> Bool+cToBool  = toBool++-- |Convert a C enumeration to Haskell.+--+cToEnum :: (Integral i, Enum e) => i -> e+cToEnum  = toEnum . cIntConv++-- |Convert a Haskell enumeration to C.+--+cFromEnum :: (Enum e, Integral i) => e -> i+cFromEnum  = cIntConv . fromEnum
+ LICENSE view
@@ -0,0 +1,25 @@+The following license covers this documentation, and the source code, except+where otherwise indicated.++Copyright 2008, Michael Snoyman. All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+  list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright notice,+  this list of conditions and the following disclaimer in the documentation+  and/or other materials provided with the distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO+EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.lhs view
@@ -0,0 +1,7 @@+#!/usr/bin/env runhaskell++> module Main where+> import Distribution.Simple++> main :: IO ()+> main = defaultMain
+ Text/Libyaml.chs view
@@ -0,0 +1,299 @@+{-# LANGUAGE ForeignFunctionInterface #-}+module Text.Libyaml+    ( Event (..)+    , parserParse+    , withParser+    , emitEvents+    , withEmitter+    ) where++#include <yaml.h>+#include "../../../c/helper.h"++import C2HS+import qualified Data.ByteString.Internal as B+import Control.Monad++{#context lib="yaml" #}++{#pointer *yaml_parser_t as Parser newtype#}+parserSize :: Int+parserSize = {#sizeof yaml_parser_t#}++{#pointer *yaml_event_t as EventRaw newtype#}+eventSize :: Int+eventSize = {#sizeof yaml_event_t#}++{#fun unsafe yaml_parser_initialize+    { id `Parser'+    } -> `Int' #}++{#fun unsafe yaml_parser_delete+    { id `Parser'+    } -> `()' #}++withParser :: B.ByteString -> (Parser -> IO a) -> IO a+withParser bs f = do+    allocaBytes parserSize $ \p ->+      do+        let p' = Parser p+        _res <- yaml_parser_initialize p'+        -- FIXME check res+        let (fptr, offset, len) = B.toForeignPtr bs+        ret <- withForeignPtr fptr $ \ptr ->+                do+                    let ptr' = castPtr ptr `plusPtr` offset+                    yaml_parser_set_input_string p' ptr' len+                    f p'+        yaml_parser_delete p'+        return ret++withEventRaw :: (EventRaw -> IO a) -> IO a+withEventRaw f = allocaBytes eventSize $ f . EventRaw++{#fun unsafe yaml_parser_set_input_string+    { id `Parser'+    , id `Ptr CUChar'+    , `Int'+    } -> `()' #}++{#fun unsafe yaml_parser_parse+    { id `Parser'+    , id `EventRaw'+    } -> `Int' #}++{#fun unsafe yaml_event_delete+    { id `EventRaw'+    } -> `()' #}++parserParse :: Parser -> IO [Event]+parserParse parser = do+    event <- parserParseOne parser+    case event of+		EventStreamEnd -> return [event]+		_ -> do+			rest <- parserParse parser+			return $! event : rest++{#fun unsafe print_parser_error+    { id `Parser'+    } -> `()' #}++parserParseOne :: Parser -> IO Event+parserParseOne parser = withEventRaw $ \er -> do+    res <- yaml_parser_parse parser er+    when (res == 0) $+        print_parser_error parser >> fail "yaml_parser_parse failed"+    event <- getEvent er+    yaml_event_delete er+    return event++data Event =+    EventNone+    | EventStreamStart+    | EventStreamEnd+    | EventDocumentStart+    | EventDocumentEnd+    | EventAlias+    | EventScalar B.ByteString+    | EventSequenceStart+    | EventSequenceEnd+    | EventMappingStart+    | EventMappingEnd+    deriving (Show)++{#enum yaml_event_type_e as EventType {underscoreToCase} deriving (Show) #}+getEvent :: EventRaw -> IO Event+getEvent (EventRaw ptr') = do+    et <- {#get yaml_event_t.type#} ptr'+    case toEnum $ fromEnum et of+		YamlNoEvent -> return EventNone+		YamlStreamStartEvent -> return EventStreamStart+		YamlStreamEndEvent -> return EventStreamEnd+		YamlDocumentStartEvent -> return EventDocumentStart+		YamlDocumentEndEvent -> return EventDocumentEnd+		YamlAliasEvent -> return EventAlias+		YamlScalarEvent -> do+			yvalue <- {#get yaml_event_t.data.scalar.value#} ptr'+			ylen <- {#get yaml_event_t.data.scalar.length#} ptr'+			let yvalue' = castPtr yvalue+			let ylen' = fromEnum ylen+			let ylen'' = toEnum $ fromEnum ylen+			bs <- B.create ylen' $ \dest -> B.memcpy dest yvalue' ylen''+			return $ EventScalar bs+		YamlSequenceStartEvent -> return EventSequenceStart+		YamlSequenceEndEvent -> return EventSequenceEnd+		YamlMappingStartEvent -> return EventMappingStart+		YamlMappingEndEvent -> return EventMappingEnd++-- Emitter+{#pointer *yaml_emitter_t as Emitter newtype#}+emitterSize :: Int+emitterSize = {#sizeof yaml_emitter_t#}++{#fun unsafe yaml_emitter_initialize+    { id `Emitter'+    } -> `Int' #}++{#fun unsafe yaml_emitter_delete+    { id `Emitter'+    } -> `()' #}++{#pointer *buffer_t as Buffer newtype#}+bufferSize :: Int+bufferSize = {#sizeof buffer_t#}++{#fun unsafe buffer_init+    { id `Buffer'+    } -> `()' #}++withBuffer :: (Buffer -> IO ()) -> IO B.ByteString+withBuffer f = do+    allocaBytes bufferSize $ \b -> do+        let b' = Buffer b+        buffer_init b'+        f b'+        ptr' <- {#get buffer_t.buff#} b+        len <- {#get buffer_t.used#} b+        fptr <- newForeignPtr_ $ castPtr ptr'+        return $! B.fromForeignPtr fptr 0 $ fromIntegral len++{#fun unsafe yaml_emitter_set_output+    { id `Emitter'+    , id `FunPtr (Ptr () -> Ptr CUChar -> CULong -> IO CInt)'+    , id `Ptr ()'+    } -> `()' #}++foreign import ccall "buffer.h &buffer_append"+    buffer_append :: FunPtr (Ptr () -> Ptr CUChar -> CULong -> IO CInt)++withEmitter :: (Emitter -> IO ()) -> IO B.ByteString+withEmitter f = do+    allocaBytes emitterSize $ \e -> do+        let e' = Emitter e+        _res <- yaml_emitter_initialize e'+        -- FIXME check res+        bs <- withBuffer $ \(Buffer b) -> do+                let fun = buffer_append+                yaml_emitter_set_output e' buffer_append $ castPtr b+                f e'+        yaml_emitter_delete e'+        return bs++{#fun unsafe yaml_emitter_emit+    { id `Emitter'+    , id `EventRaw'+    } -> `Int' #}++{#fun unsafe print_emitter_error+    { id `Emitter'+    } -> `()' #}++emitEvents :: Emitter -> [Event] -> IO ()+emitEvents _ [] = return ()+emitEvents emitter (e:rest) = do+    res <- toEventRaw e $ yaml_emitter_emit emitter+    when (res == 0) $+        print_emitter_error emitter >> fail "yaml_emitter_emit failed"+    emitEvents emitter rest++{#fun unsafe yaml_stream_start_event_initialize+    { id `EventRaw'+    , `Int'+    } -> `Int' #}++{#fun unsafe yaml_stream_end_event_initialize+    { id `EventRaw'+    } -> `Int' #}++{#fun unsafe yaml_scalar_event_initialize+    { id `EventRaw'+    , id `Ptr CUChar' -- anchor+    , id `Ptr CUChar' -- tag+    , id `Ptr CUChar' -- value+    , `Int'+    , `Int'+    , `Int'+    , `Int'+    } -> `Int' #}++{#fun unsafe simple_document_start+    { id `EventRaw'+    } -> `Int' #}++{#fun unsafe yaml_document_end_event_initialize+    { id `EventRaw'+    , `Int'+    } -> `Int' #}++{#fun unsafe yaml_sequence_start_event_initialize+    { id `EventRaw'+    , id `Ptr CUChar'+    , id `Ptr CUChar'+    , `Int'+    , `Int'+    } -> `Int' #}++{#fun unsafe yaml_sequence_end_event_initialize+    { id `EventRaw'+    } -> `Int' #}++{#fun unsafe yaml_mapping_start_event_initialize+    { id `EventRaw'+    , id `Ptr CUChar'+    , id `Ptr CUChar'+    , `Int'+    , `Int'+    } -> `Int' #}++{#fun unsafe yaml_mapping_end_event_initialize+    { id `EventRaw'+    } -> `Int' #}++toEventRaw :: Event -> (EventRaw -> IO a) -> IO a+toEventRaw e f = withEventRaw $ \er -> do+    case e of+        EventStreamStart ->+            yaml_stream_start_event_initialize+                er+                0 -- YAML_ANY_ENCODING+        EventStreamEnd ->+            yaml_stream_end_event_initialize er+        EventDocumentStart ->+            simple_document_start er+        EventDocumentEnd ->+            yaml_document_end_event_initialize er 1+        EventScalar bs -> do+            let (fvalue, offset, len) = B.toForeignPtr bs+            withForeignPtr fvalue $ \value -> do+                let value' = value `plusPtr` offset+                yaml_scalar_event_initialize+                    er+                    nullPtr+                    nullPtr+                    value'+                    len+                    0+                    1+                    0 -- YAML_ANY_SCALAR_STYLE+        EventSequenceStart ->+            yaml_sequence_start_event_initialize+                er+                nullPtr+                nullPtr+                1+                0 -- YAML_ANY_SEQUENCE_STYLE+        EventSequenceEnd ->+            yaml_sequence_end_event_initialize er+        EventMappingStart ->+            yaml_mapping_start_event_initialize+                er+                nullPtr+                nullPtr+                1+                0 -- YAML_ANY_SEQUENCE_STYLE+        EventMappingEnd ->+            yaml_mapping_end_event_initialize er+        EventAlias -> error "toEventRaw: EventAlias not supported"+        EventNone -> error "toEventRaw: EventNone not supported"+    f er
+ Text/Yaml.hs view
@@ -0,0 +1,98 @@+---------------------------------------------------------+--+-- Module        : Text.Yaml+-- Copyright     : Michael Snoyman+-- License       : BSD3+--+-- Maintainer    : Michael Snoyman <michael@snoyman.com>+-- Stability     : Stable+-- Portability   : portable+--+-- Provides a user friendly interface for serializing Yaml data.+--+---------------------------------------------------------++module Text.Yaml+    ( module Data.Object+    , encode+    , encodeFile+    , decode+    , decodeFile+    ) where++import Prelude hiding (readList)+import Text.Libyaml+import qualified Data.ByteString as B+import Data.ByteString.Class+import Data.Object+import System.IO.Unsafe++encode :: (StrictByteString bs, ToObject o) => o -> bs+encode = unsafePerformIO . encode'++decode :: (Monad m, StrictByteString bs, FromObject o) => bs -> m o+decode = unsafePerformIO . decode'++encodeFile :: ToObject o => FilePath -> o -> IO ()+encodeFile path o = encode' o >>= B.writeFile path++decodeFile :: (Monad m, FromObject o) => FilePath -> IO (m o)+decodeFile path = do+    c <- B.readFile path+    decode' c++encode' :: (StrictByteString bs, ToObject o) => o -> IO bs+encode' o =+    let events = objectToEvents $ toObject o+        result = withEmitter $ flip emitEvents $ events+     in fromStrictByteString `fmap` result++decode' :: (Monad m, StrictByteString bs, FromObject o) => bs -> IO (m o)+decode' bs = do+    let bs' = toStrictByteString bs+        events = withParser bs' parserParse+    (fromObject . eventsToObject) `fmap` events++objectToEvents :: Object -> [Event]+objectToEvents y = concat+                    [ [EventStreamStart, EventDocumentStart]+                    , writeSingle y+                    , [EventDocumentEnd, EventStreamEnd]] where+    writeSingle :: Object -> [Event]+    writeSingle (Scalar bs) = [EventScalar bs]+    writeSingle (Sequence ys) =+        (EventSequenceStart : concatMap writeSingle ys)+        ++ [EventSequenceEnd]+    writeSingle (Mapping pairs) =+        EventMappingStart : concatMap writePair pairs ++ [EventMappingEnd]+    writePair :: (B.ByteString, Object) -> [Event]+    writePair (k, v) = EventScalar k : writeSingle v++eventsToObject :: [Event] -> Object+eventsToObject = fst . readSingle . dropWhile isIgnored where+    isIgnored EventAlias = False+    isIgnored (EventScalar _) = False+    isIgnored EventSequenceStart = False+    isIgnored EventSequenceEnd = False+    isIgnored EventMappingStart = False+    isIgnored EventMappingEnd = False+    isIgnored _ = True+    readSingle :: [Event] -> (Object, [Event])+    readSingle [] = error "readSingle: no more events"+    readSingle (EventScalar bs:rest) = (Scalar bs, rest)+    readSingle (EventSequenceStart:rest) = readList [] rest+    readSingle (EventMappingStart:rest) = readMap [] rest+    readSingle (x:_) = error $ "readSingle: " ++ show x+    readList :: [Object] -> [Event] -> (Object, [Event])+    readList nodes (EventSequenceEnd:rest) =+        (Sequence $ reverse nodes, rest)+    readList nodes events =+        let (next, rest) = readSingle events+         in readList (next : nodes) rest+    readMap :: [(B.ByteString, Object)] -> [Event] -> (Object, [Event])+    readMap pairs (EventMappingEnd:rest) = (Mapping $ reverse pairs, rest)+    readMap pairs (EventScalar bs:events) =+        let (next, rest) = readSingle events+         in readMap ((fromStrictByteString bs, next) : pairs) rest+    readMap _ (e:_) = error $ "Unexpected event in readMap: " ++ show e+    readMap _ [] = error "Unexpected empty event list in readMap"
+ c/helper.c view
@@ -0,0 +1,55 @@+#include <stdlib.h>+#include <string.h>+#include <stdio.h>+#include "helper.h"++void buffer_init(buffer_t *buffer)+{+	buffer->buff = 0;+	buffer->size = buffer->used = 0;+}++int buffer_append(void *ext, unsigned char *str, size_t size)+{+	buffer_t *b = ext;+	int new_size, new_used;+	char *tmp;++	new_used = b->used + size;+	for (new_size = b->size || 8; new_size < new_used; new_size *= 2);++	if (new_size != b->size) {+		tmp = realloc(b->buff, new_size);+		if (!tmp) return 0;+		b->buff = tmp;+		b->size = new_size;+	}++	memcpy(b->buff + b->used, str, size);+	b->used = new_used;++	return 1;+}++void print_parser_error(yaml_parser_t *p)+{+	fprintf(stderr, "Problem: %s\nContext: %s\nOffset: %u\n",+		p->problem,+		p->context,+		(unsigned int) p->problem_offset);+}++void print_emitter_error(yaml_emitter_t *e)+{+	fprintf(stderr, "%s\n", e->problem);+}++int simple_document_start(yaml_event_t *e)+{+	return yaml_document_start_event_initialize+		(e,+		 0,+		 0,+		 0,+		 1);+}
+ yaml.cabal view
@@ -0,0 +1,26 @@+name:            yaml+version:         0.0.0+license:         BSD3+license-file:    LICENSE+author:          Michael Snoyman <michael@snoyman.com>+maintainer:      Michael Snoyman <michael@snoyman.com>+synopsis:        Support for serialising Haskell to and from Yaml.+description:     Binds to the libyaml library+category:        Web+stability:       unstable+cabal-version:   >= 1.2+build-type:      Simple+homepage:        http://github.com/snoyberg/yaml/tree/master++library+    build-depends:   base >= 4 && < 5,+                     bytestring-class,+                     data-object,+                     bytestring >= 0.9.1.4 && < 1,+                     haskell98+    exposed-modules: Text.Yaml+    other-modules:   Text.Libyaml,+                     C2HS+    ghc-options:     -Wall+    c-sources:       c/helper.c+    extra-libraries: yaml