Changeset 9005
- Timestamp:
- 02/15/06 14:13:33 (3 years ago)
- Location:
- src
- Files:
-
- 2 modified
-
Data/Yaml/Syck.hsc (modified) (9 diffs)
-
Pugs/Prim/Yaml.hs (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Data/Yaml/Syck.hsc
r8999 r9005 5 5 module Data.Yaml.Syck ( 6 6 parseYaml, emitYaml, 7 YamlNode(..), YamlElem(..), tagNode, nilNode, mkNode, mkTagNode, SYMID,7 YamlNode(..), YamlElem(..), YamlAnchor(..), tagNode, nilNode, mkNode, mkTagNode, SYMID, 8 8 ) where 9 9 … … 21 21 import Foreign.Storable 22 22 import Data.Generics 23 import qualified Data.HashTable as Hash 23 24 24 25 type YamlTag = Maybe String 25 type YamlAnchor = Maybe String 26 data YamlAnchor 27 = MkYamlAnchor Int 28 | MkYamlReference Int 29 deriving (Show, Ord, Eq, Typeable, Data) 26 30 type SYMID = CULong 27 31 28 cuLongType = mkIntType "Foreign.C.Types.CULong"29 30 32 instance Data SYMID where 31 toConstr x = mkIntConstr cuLongType(fromIntegral x)33 toConstr x = mkIntConstr (mkIntType "Foreign.C.Types.CULong") (fromIntegral x) 32 34 gunfold k z c = case constrRep c of 33 35 (IntConstr x) -> z (fromIntegral x) 34 36 _ -> error "gunfold" 35 dataTypeOf _ = cuLongType37 dataTypeOf _ = mkIntType "Foreign.C.Types.CULong" 36 38 37 39 data YamlNode = MkYamlNode … … 39 41 , el :: YamlElem 40 42 , tag :: YamlTag 41 , anchor :: YamlAnchor 42 , shortcut :: (Maybe YamlNode) 43 , anchor :: Maybe YamlAnchor 43 44 } 44 45 deriving (Show, Ord, Eq, Typeable, Data) … … 64 65 65 66 nilNode :: YamlNode 66 nilNode = MkYamlNode 0 YamlNil Nothing Nothing Nothing67 nilNode = MkYamlNode 0 YamlNil Nothing Nothing 67 68 68 69 tagNode :: YamlTag -> YamlNode -> YamlNode 69 tagNode _ MkYamlNode{tag=Just x} = error ("can't add tag: already tagged with" ++ x)70 tagNode tag node = node{tag = tag}70 tagNode _ MkYamlNode{tag=Just x} = error ("can't add tag: already tagged with" ++ x) 71 tagNode tag node = node{tag = tag} 71 72 72 73 mkNode :: YamlElem -> YamlNode 73 mkNode x = MkYamlNode 0 x Nothing Nothing Nothing74 mkNode x = MkYamlNode 0 x Nothing Nothing 74 75 75 76 mkTagNode :: String -> YamlElem -> YamlNode 76 mkTagNode s x = MkYamlNode 0 x (Just s) Nothing Nothing77 mkTagNode s x = MkYamlNode 0 x (Just s) Nothing 77 78 78 79 -- the extra commas here are not a bug … … 94 95 #{poke SyckEmitter, bonus} emitter outPtr 95 96 #{poke SyckEmitter, style} emitter scalarFold 97 #{poke SyckEmitter, sort_keys} emitter (1 :: CInt) 98 withCString "%d" $ #{poke SyckEmitter, anchor_format} emitter 99 100 -- nodes <- Hash.new (==) (Hash.hashInt) 101 marks <- Hash.new (==) (Hash.hashInt) 102 103 let freeze = freezeNode marks 104 syck_emitter_handler emitter =<< mkEmitterCallback (emitterCallback freeze) 96 105 syck_output_handler emitter =<< mkOutputCallback outputCallback 97 syck_emitter_handler emitter =<< mkEmitterCallback emitterCallback 98 markYamlNode emitter node 99 nodePtr <- freezeNode node 106 107 markYamlNode marks emitter node 108 109 nodePtr <- freeze node 100 110 let nodePtr' = fromIntegral $ nodePtr `minusPtr` nullPtr 101 111 syck_emit emitter nodePtr' … … 103 113 fmap Right $ readIORef out 104 114 105 markYamlNode :: SyckEmitter -> YamlNode -> IO () 106 markYamlNode emitter node = do 107 nodePtr <- writeNode node 115 markYamlNode :: Hash.HashTable Int SyckNodePtr -> SyckEmitter -> YamlNode -> IO () 116 markYamlNode marks emitter node@MkYamlNode{ anchor = Just (MkYamlReference n) } = do 117 Just nodePtr <- Hash.lookup marks n 118 syck_emitter_mark_node emitter nodePtr 119 return () 120 markYamlNode marks emitter node = do 121 nodePtr <- freezeNode marks node 108 122 rv <- syck_emitter_mark_node emitter nodePtr 109 if rv == 0 then return () else case el node of 123 if rv == 0 then return () else do 124 case anchor node of 125 Just (MkYamlAnchor n) -> Hash.insert marks n nodePtr 126 _ -> return () 127 case el node of 110 128 YamlMap xs -> sequence_ [ mark x >> mark y | (x, y) <- xs ] 111 129 YamlSeq xs -> mapM_ mark xs 112 130 _ -> return () 113 131 where 114 mark = markYamlNode emitter132 mark = markYamlNode marks emitter 115 133 116 134 outputCallback :: SyckEmitter -> CString -> CLong -> IO () … … 119 137 out <- deRefStablePtr (castPtrToStablePtr outPtr) 120 138 str <- peekCStringLen (buf, fromIntegral len) 121 #{poke SyckEmitter, headless} emitter (1 :: CInt)122 139 modifyIORef out (++ str) 123 140 … … 132 149 deRefStablePtr (castPtrToStablePtr ptr) 133 150 134 emitterCallback :: SyckEmitter -> Ptr () -> IO () 135 emitterCallback e vp = emitNode e =<< thawNode vp 151 152 emitterCallback :: (YamlNode -> IO SyckNodePtr) -> SyckEmitter -> Ptr () -> IO () 153 emitterCallback f e vp = emitNode f e =<< thawNode vp 136 154 137 emitNode :: SyckEmitter -> YamlNode -> IO ()138 emitNode e n@(MkYamlNode{el = YamlNil}) = do155 emitNode :: (YamlNode -> IO SyckNodePtr) -> SyckEmitter -> YamlNode -> IO () 156 emitNode _ e n@(MkYamlNode{el = YamlNil}) = do 139 157 withTag n "string" $ \tag -> 140 158 withCString "~" $ \cs -> 141 159 syck_emit_scalar e tag scalarNone 0 0 0 cs 1 142 160 143 emitNode e n@(MkYamlNode{el = YamlStr "~"}) = do161 emitNode _ e n@(MkYamlNode{el = YamlStr "~"}) = do 144 162 withTag n "string" $ \tag -> 145 163 withCString "~" $ \cs -> 146 164 syck_emit_scalar e tag scalar1quote 0 0 0 cs 1 147 165 148 emitNode e n@(MkYamlNode{el = YamlStr str}) = do166 emitNode _ e n@(MkYamlNode{el = YamlStr str}) = do 149 167 withTag n "string" $ \tag -> 150 168 withCString str $ \cs -> 151 169 syck_emit_scalar e tag scalarNone 0 0 0 cs (toEnum $ length str) 152 170 153 emitNode e n@(MkYamlNode{el = YamlSeq seq}) = do171 emitNode freeze e n@(MkYamlNode{el = YamlSeq seq}) = do 154 172 withTag n "array" $ \tag -> 155 173 syck_emit_seq e tag seqNone 156 mapM_ (syck_emit_item e) =<< (mapM freezeNode seq)174 mapM_ (syck_emit_item e) =<< mapM freeze seq 157 175 syck_emit_end e 158 176 159 emitNode e n@(MkYamlNode{el = YamlMap m}) = do177 emitNode freeze e n@(MkYamlNode{el = YamlMap m}) = do 160 178 withTag n "hash" $ \tag -> 161 179 syck_emit_map e tag mapNone 162 180 flip mapM_ m (\(k,v) -> do 163 syck_emit_item e =<< freeze Nodek164 syck_emit_item e =<< freeze Nodev)181 syck_emit_item e =<< freeze k 182 syck_emit_item e =<< freeze v) 165 183 syck_emit_end e 166 184 … … 205 223 ] 206 224 207 freezeNode :: YamlNode -> IO (Ptr a) 208 freezeNode node = do 225 freezeNode :: Hash.HashTable Int (Ptr a) -> YamlNode -> IO (Ptr a) 226 freezeNode nodes node@MkYamlNode{ anchor = Just (MkYamlReference n) } = do 227 Just ptr <- Hash.lookup nodes n 228 return ptr 229 freezeNode nodes node = do 209 230 ptr <- newStablePtr node 210 return (castPtr $ castStablePtrToPtr ptr) 231 let ptr' = castPtr $ castStablePtrToPtr ptr 232 case anchor node of 233 Just (MkYamlAnchor n) -> Hash.insert nodes n ptr' >> return ptr' 234 _ -> return ptr' 211 235 212 236 thawNode :: Ptr () -> IO YamlNode -
src/Pugs/Prim/Yaml.hs
r8999 r9005 67 67 dumpYaml :: Int -> Val -> Eval Val 68 68 dumpYaml limit v = do 69 done <- liftSTM $ newTVar IntMap.empty70 69 let ?seen = IntSet.empty 71 ?done = done 72 obj <- toYaml v 73 nodeMap <- liftSTM . readTVar $ done 74 let replaceNode node@MkYamlNode{ nid = n } 75 | n == 0 = node 76 | otherwise = (IntMap.!) nodeMap (fromEnum n) 77 rv <- liftIO . emitYaml $ everywhere (mkT replaceNode) obj 70 obj <- toYaml v 71 rv <- liftIO . emitYaml $ obj 78 72 either (fail . ("YAML Emit Error: "++)) 79 73 (return . VStr . decodeUTF8) rv … … 87 81 return (castStablePtrToPtr ptr `minusPtr` (nullPtr :: Ptr ())) 88 82 89 toYaml :: (?seen :: IntSet.IntSet , ?done :: TVar (IntMap.IntMap YamlNode)) => Val -> Eval YamlNode83 toYaml :: (?seen :: IntSet.IntSet) => Val -> Eval YamlNode 90 84 toYaml VUndef = return $ mkNode YamlNil 91 85 toYaml (VBool x) = return $ boolToYaml x … … 93 87 toYaml v@(VRef r) = do 94 88 ptr <- liftIO $ addressOf r 95 if IntSet.member ptr ?seen then return nilNode{ nid = toEnum ptr} else do89 if IntSet.member ptr ?seen then return nilNode{ anchor = Just (MkYamlReference ptr) } else do 96 90 let ?seen = IntSet.insert ptr ?seen 97 91 node <- ifValTypeIsa v "Hash" (hashToYaml r) $ do … … 101 95 VObject _ -> nodes 102 96 _ -> mkNode $ YamlMap [(strNode "<ref>", nodes)] 103 liftSTM $ modifyTVar ?done (IntMap.insert ptr node) 104 return node 97 return node{ anchor = Just (MkYamlAnchor ptr) } 105 98 toYaml (VList nodes) = do 106 99 n <- mapM toYaml nodes … … 125 118 toYaml v = return $ strNode $ (encodeUTF8 . pretty) v 126 119 127 hashToYaml :: (?seen :: IntSet.IntSet , ?done :: TVar (IntMap.IntMap YamlNode)) => VRef -> Eval YamlNode120 hashToYaml :: (?seen :: IntSet.IntSet) => VRef -> Eval YamlNode 128 121 hashToYaml (MkRef (IHash hv)) = do 129 122 h <- hash_fetch hv
