Changeset 8566
- Timestamp:
- 01/03/06 23:03:30 (3 years ago)
- Location:
- src
- Files:
-
- 3 modified
-
Data/Yaml/Syck.hsc (modified) (7 diffs)
-
Pugs/Prim.hs (modified) (2 diffs)
-
Pugs/Prim/Yaml.hs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Data/Yaml/Syck.hsc
r7579 r8566 1 1 {-# OPTIONS_GHC -fglasgow-exts -fvia-C #-} 2 2 #include "../../syck/syck.h" 3 #include "../../cbits/fpstring.h" 3 4 4 5 module Data.Yaml.Syck ( 5 parseYaml, 6 parseYaml, emitYaml, 6 7 YamlNode(..), 7 8 ) where … … 9 10 import Control.Exception (bracket) 10 11 import Data.IORef 12 import Data.Word (Word8) 13 import qualified Data.FastPackedString as P 11 14 import Foreign.Ptr 12 15 import Foreign.StablePtr 16 import Foreign.ForeignPtr 13 17 import Foreign.C.Types 14 18 import Foreign.C.String … … 17 21 import Foreign.Storable 18 22 23 import Debug.Trace 24 import Control.Monad.Trans 25 19 26 data YamlNode 20 27 = YamlMap [(YamlNode, YamlNode)] 21 28 | YamlSeq [YamlNode] 22 29 | YamlStr String 30 | YamlNil 23 31 deriving (Show, Ord, Eq) 24 32 … … 29 37 type SyckErrorHandler = SyckParser -> CString -> IO () 30 38 type SyckNodePtr = Ptr CString 31 data SyckKind = SyckMap | SyckSeq | SyckStr 39 type FSPtr = Ptr CString 40 type SyckEmitter = Ptr () 41 type SyckEmitterHandler = SyckEmitter -> Ptr () -> IO () 42 type SyckOutputHandler = SyckEmitter -> CString -> CLong -> IO () 43 data SyckKind = SyckMap | SyckSeq | SyckStr | SyckNil 32 44 deriving (Show, Ord, Eq, Enum) 45 46 -- the extra comma here is not a bug 47 #enum CInt, , scalar_none, scalar_1quote, scalar_2quote, scalar_fold, scalar_literal, scalar_plain 48 49 #def typedef struct _EmitterExtras { char * ps; int l; } EmitterExtras; 50 type EmitterExtras = Ptr () 51 52 emitYaml :: YamlNode -> IO (Either String String) 53 emitYaml node = do 54 alloca $ \(emitterExtras :: Ptr EmitterExtras) -> do 55 bracket syck_new_emitter syck_free_emitter $ \emitter -> do 56 -- set up output port 57 let out = P.empty 58 (outps, _, l) = P.toForeignPtr out 59 outpsF <- freezeFS outps 60 #{poke EmitterExtras, ps} emitterExtras outpsF 61 #{poke EmitterExtras, l} emitterExtras l 62 #{poke SyckEmitter, bonus} emitter emitterExtras 63 syck_output_handler emitter =<< mkOutputCallback outputCallback 64 syck_emitter_handler emitter =<< mkEmitterCallback emitterCallback 65 nodePtr <- freezeNode node 66 let nodePtr' = fromIntegral $ nodePtr `minusPtr` nullPtr 67 trace ("node: " ++ (show node) ++ " nodePtr': " ++ (show nodePtr')) $ return () 68 syck_emit emitter nodePtr' 69 syck_emitter_flush emitter 0 70 return . Right $ P.unpack out -- TODO: handle Left 71 72 outputCallback :: SyckEmitter -> CString -> CLong -> IO () 73 outputCallback emitter buf len = do 74 bonus <- #{peek SyckEmitter, bonus} emitter 75 fp <- readFS =<< #{peek EmitterExtras, ps} bonus 76 l <- #{peek EmitterExtras, l} bonus 77 let fps = P.fromForeignPtr fp l 78 let new = P.packCStringLen (buf, fromIntegral len) 79 let (catPS, _, catL) = P.toForeignPtr $ P.append fps new 80 catPSF <- freezeFS catPS 81 #{poke EmitterExtras, ps} bonus catPSF 82 #{poke EmitterExtras, l} bonus catL 83 return () 84 85 freezeFS :: ForeignPtr Word8 -> IO FSPtr 86 freezeFS ps = do 87 ptr <- newStablePtr ps 88 new (castPtr $ castStablePtrToPtr ptr) 89 90 readFS :: FSPtr -> IO (ForeignPtr Word8) 91 readFS fs = do 92 ptr <- peek . castPtr =<< peek fs 93 deRefStablePtr (castPtrToStablePtr ptr) 94 95 emitterCallback :: SyckEmitter -> Ptr () -> IO () 96 emitterCallback e vp = do 97 node <- thawNode vp 98 case node of 99 (YamlStr str) -> do 100 -- return syck_emit_scalar(e, "string", scalar_none, 0, 0, 0, SvPVX(sv), SvCUR(sv)); 101 withCString "string" $ \string_literal -> 102 withCString str $ \cs -> 103 syck_emit_scalar e string_literal scalarNone 0 0 0 cs (toEnum $ length str) 33 104 34 105 parseYaml :: String -> IO (Either String (Maybe YamlNode)) … … 69 140 ] 70 141 71 freezeNode :: YamlNode -> IO SyckNodePtr142 --freezeNode :: YamlNode -> IO SyckNodePtr 72 143 freezeNode node = do 73 144 ptr <- newStablePtr node 74 145 new (castPtr $ castStablePtrToPtr ptr) 146 147 thawNode :: Ptr () -> IO YamlNode 148 thawNode nodePtr = do 149 trace ("thawNode: nodePtr=" ++ show nodePtr) $ return () 150 --let ptr = castPtr nodePtr 151 --trace ("thawNode: ptr=" ++ show ptr) $ return () 152 -- deRefStablePtr (castPtrToStablePtr ptr) 153 rv <- deRefStablePtr (castPtrToStablePtr nodePtr) 154 rv' <- rv 155 trace ("thawNode: rv=" ++ show rv') $ return () 156 rv 157 75 158 76 159 readNode :: SyckParser -> SYMID -> IO YamlNode … … 115 198 mkErrorCallback :: SyckErrorHandler -> IO (FunPtr SyckErrorHandler) 116 199 200 foreign import ccall "wrapper" 201 mkOutputCallback :: SyckOutputHandler -> IO (FunPtr SyckOutputHandler) 202 203 foreign import ccall "wrapper" 204 mkEmitterCallback :: SyckEmitterHandler -> IO (FunPtr SyckEmitterHandler) 205 117 206 foreign import ccall 118 207 syck_new_parser :: IO SyckParser … … 153 242 foreign import ccall 154 243 syck_map_read :: SyckNode -> CInt -> CLong -> IO SYMID 244 245 foreign import ccall 246 syck_new_emitter :: IO SyckEmitter 247 248 foreign import ccall 249 syck_free_emitter :: SyckEmitter -> IO () 250 251 foreign import ccall 252 syck_emitter_handler :: SyckEmitter -> FunPtr SyckEmitterHandler -> IO () 253 254 foreign import ccall 255 syck_output_handler :: SyckEmitter -> FunPtr SyckOutputHandler -> IO () 256 257 foreign import ccall 258 syck_emit :: SyckEmitter -> CLong -> IO () 259 260 foreign import ccall 261 syck_emitter_flush :: SyckEmitter -> CLong -> IO () 262 263 foreign import ccall 264 syck_emit_scalar :: SyckEmitter -> CString -> CInt -> CInt -> CInt -> CInt -> CString -> CInt -> IO () 265 -
src/Pugs/Prim.hs
r8518 r8566 223 223 op1 "none" = op1Cast opJuncNone 224 224 op1 "perl" = fmap VStr . prettyVal 0 225 op1 "yaml" = dumpYaml 225 226 op1 "require_haskell" = \v -> do 226 227 name <- fromVal v … … 1559 1560 \\n Any pre Pugs::Internals::eval_haskell unsafe (Str)\ 1560 1561 \\n Any pre Pugs::Internals::eval_yaml safe (Str)\ 1562 \\n Any pre yaml safe (Any)\ 1561 1563 \\n Any pre require unsafe (?Str=$_)\ 1562 1564 \\n Any pre use unsafe (?Str=$_)\ -
src/Pugs/Prim/Yaml.hs
r7826 r8566 3 3 4 4 module Pugs.Prim.Yaml ( 5 evalYaml 5 evalYaml, dumpYaml 6 6 ) where 7 7 import Pugs.Internals … … 34 34 hv <- liftSTM $ (newTVar (Map.fromList vals) :: STM IHash) 35 35 return $ VRef (hashRef hv) 36 37 dumpYaml :: Val -> Eval Val 38 dumpYaml v = do 39 obj <- toYaml =<< fromVal v 40 rv <- liftIO (emitYaml obj) 41 case rv of 42 Left err -> fail $ "YAML Emit Error: " ++ err 43 Right str -> return $ VStr str 44 45 toYaml :: Val -> Eval YamlNode 46 toYaml VUndef = return YamlNil 47 toYaml (VStr str) = return $ YamlStr (encodeUTF8 str) 48 toYaml (VList nodes) = do 49 fmap YamlSeq $ mapM toYaml nodes 50 --toYaml (VHash hash) = do 51 -- fmap YamlMap $ Map.toList hash 52 53 54
