packages feed

hexpat (empty) → 0.1

raw patch · 8 files changed

+643/−0 lines, 8 filesdep +basedep +haskell98setup-changed

Dependencies added: base, 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,26 @@+Copyright (c) 2008 Evan Martin <martine@danga.com>+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.+* Neither the name of the author nor the names of contributors may be+  used to endorse or promote products derived from this software without+  specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 OWNER+OR CONTRIBUTORS 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,4 @@+#! /usr/bin/env runhaskell++> import Distribution.Simple+> main = defaultMain
+ Text/XML/Expat/IO.chs view
@@ -0,0 +1,133 @@+-- hexpat, a Haskell wrapper for expat+-- Copyright (C) 2008 Evan Martin <martine@danga.com>++-- |This module wraps the Expat API directly, with IO.++module Text.XML.Expat.IO (+  -- ** Parser Setup+  Parser, newParser,++  -- ** Parsing+  parse,++  -- ** Parser Callbacks+  StartElementHandler, EndElementHandler, CharacterDataHandler,+  setStartElementHandler, setEndElementHandler, setCharacterDataHandler+) where++import C2HS++#include <expat.h>++-- Expat functions start with "XML", but C2HS appears to ignore our "as"+-- definitions if they only differ from the symbol in case.  So we write out+-- XML_* in most cases anyway...  :(+{#context lib = "expat" prefix = "XML"#}++-- |Opaque parser type.+type ParserPtr = Ptr ()+newtype Parser = Parser (ForeignPtr ())++withParser :: Parser -> (ParserPtr -> IO a) -> IO a+withParser (Parser fp) = withForeignPtr fp++withOptCString :: Maybe String -> (CString -> IO a) -> IO a+withOptCString Nothing    f = f nullPtr+withOptCString (Just str) f = withCString str f++{#fun unsafe XML_ParserCreate as parserCreate+    {withOptCString* `Maybe String'} -> `ParserPtr' id#}+foreign import ccall "&XML_ParserFree" parserFree :: FunPtr (ParserPtr -> IO ())++-- |Create a 'Parser'.  The optional parameter is the default character+-- encoding, and can be one of+--+-- - \"US-ASCII\"+--+-- - \"UTF-8\"+--+-- - \"UTF-16\"+--+-- - \"ISO-8859-1\"+newParser :: Maybe String -> IO Parser+newParser enc = do+  ptr <- parserCreate enc+  fptr <- newForeignPtr parserFree ptr+  return $ Parser fptr++unStatus :: CInt -> Bool+unStatus 0 = False+unStatus 1 = True+-- |@parse data False@ feeds mode data into a 'Parser'.  The end of the data+-- is indicated by passing True for the final parameter.  @parse@ returns+-- False on a parse error.+{#fun XML_Parse as parse+    {withParser* `Parser', `String' &, `Bool'} -> `Bool' unStatus#}++-- |The type of the \"element started\" callback.  The first parameter is+-- the element name; the second are the (attribute, value) pairs.+type StartElementHandler  = String -> [(String,String)] -> IO ()+-- |The type of the \"element ended\" callback.  The parameter is+-- the element name.+type EndElementHandler    = String -> IO ()+-- |The type of the \"character data\" callback.  The parameter is+-- the character data processed.  This callback may be called more than once+-- while processing a single conceptual block of text.+type CharacterDataHandler = String -> IO ()++type CStartElementHandler = Ptr () -> CString -> Ptr CString -> IO ()+foreign import ccall "wrapper"+  mkCStartElementHandler :: CStartElementHandler+                         -> IO (FunPtr CStartElementHandler)+wrapStartElementHandler :: StartElementHandler+                        -> IO (FunPtr CStartElementHandler)+wrapStartElementHandler handler = mkCStartElementHandler h where+  h ptr cname cattrs = do+    name <- peekCString cname+    cattrlist <- peekArray0 nullPtr cattrs+    attrlist <- mapM peekCString cattrlist+    handler name (pairwise attrlist)+-- |Attach a StartElementHandler to a Parser.+setStartElementHandler :: Parser -> StartElementHandler -> IO ()+setStartElementHandler parser handler = do+  withParser parser $ \p -> do+  handler' <- wrapStartElementHandler handler+  {#call unsafe XML_SetStartElementHandler as ^#} p handler'+++type CEndElementHandler = Ptr () -> CString -> IO ()+foreign import ccall "wrapper"+  mkCEndElementHandler :: CEndElementHandler+                       -> IO (FunPtr CEndElementHandler)+wrapEndElementHandler :: EndElementHandler+                      -> IO (FunPtr CEndElementHandler)+wrapEndElementHandler handler = mkCEndElementHandler h where+  h ptr cname = do+    name <- peekCString cname+    handler name+-- |Attach an EndElementHandler to a Parser.+setEndElementHandler :: Parser -> EndElementHandler -> IO ()+setEndElementHandler parser handler = do+  withParser parser $ \p -> do+  handler' <- wrapEndElementHandler handler+  {#call unsafe XML_SetEndElementHandler as ^#} p handler'++type CCharacterDataHandler = Ptr () -> CString -> CInt -> IO ()+foreign import ccall "wrapper"+  mkCCharacterDataHandler :: CCharacterDataHandler+                          -> IO (FunPtr CCharacterDataHandler)+wrapCharacterDataHandler :: CharacterDataHandler+                      -> IO (FunPtr CCharacterDataHandler)+wrapCharacterDataHandler handler = mkCCharacterDataHandler h where+  h ptr cdata len = do+    data_ <- peekCStringLen (cdata, fromIntegral len)+    handler data_+-- |Attach an CharacterDataHandler to a Parser.+setCharacterDataHandler :: Parser -> CharacterDataHandler -> IO ()+setCharacterDataHandler parser handler = do+  withParser parser $ \p -> do+  handler' <- wrapCharacterDataHandler handler+  {#call unsafe XML_SetCharacterDataHandler as ^#} p handler'++pairwise (x1:x2:xs) = (x1,x2) : pairwise xs+pairwise []         = []
+ Text/XML/Expat/IO.hs view
@@ -0,0 +1,164 @@+-- GENERATED by C->Haskell Compiler, version 0.15.1 Rainy Days, 31 Aug 2007 (Haskell)+-- Edit the ORIGNAL .chs file instead!+++{-# LINE 1 "IO.chs" #-}-- hexpat, a Haskell wrapper for expat+-- Copyright (C) 2008 Evan Martin <martine@danga.com>++-- |This module wraps the Expat API directly, with IO.++module Text.XML.Expat.IO (+  -- ** Parser Setup+  Parser, newParser,++  -- ** Parsing+  parse,++  -- ** Parser Callbacks+  StartElementHandler, EndElementHandler, CharacterDataHandler,+  setStartElementHandler, setEndElementHandler, setCharacterDataHandler+) where++import C2HS+++-- Expat functions start with "XML", but C2HS appears to ignore our "as"+-- definitions if they only differ from the symbol in case.  So we write out+-- XML_* in most cases anyway...  :(++{-# LINE 25 "IO.chs" #-}++-- |Opaque parser type.+type ParserPtr = Ptr ()+newtype Parser = Parser (ForeignPtr ())++withParser :: Parser -> (ParserPtr -> IO a) -> IO a+withParser (Parser fp) = withForeignPtr fp++withOptCString :: Maybe String -> (CString -> IO a) -> IO a+withOptCString Nothing    f = f nullPtr+withOptCString (Just str) f = withCString str f++parserCreate :: Maybe String -> IO (ParserPtr)+parserCreate a1 =+  withOptCString a1 $ \a1' -> +  parserCreate'_ a1' >>= \res ->+  let {res' = id res} in+  return (res')+{-# LINE 39 "IO.chs" #-}+foreign import ccall "&XML_ParserFree" parserFree :: FunPtr (ParserPtr -> IO ())++-- |Create a 'Parser'.  The optional parameter is the default character+-- encoding, and can be one of+--+-- - \"US-ASCII\"+--+-- - \"UTF-8\"+--+-- - \"UTF-16\"+--+-- - \"ISO-8859-1\"+newParser :: Maybe String -> IO Parser+newParser enc = do+  ptr <- parserCreate enc+  fptr <- newForeignPtr parserFree ptr+  return $ Parser fptr++unStatus :: CInt -> Bool+unStatus 0 = False+unStatus 1 = True+-- |@parse data False@ feeds mode data into a 'Parser'.  The end of the data+-- is indicated by passing True for the final parameter.  @parse@ returns+-- False on a parse error.+parse :: Parser -> String -> Bool -> IO (Bool)+parse a1 a2 a3 =+  withParser a1 $ \a1' -> +  withCStringLenIntConv a2 $ \(a2'1, a2'2) -> +  let {a3' = cFromBool a3} in +  parse'_ a1' a2'1  a2'2 a3' >>= \res ->+  let {res' = unStatus res} in+  return (res')+{-# LINE 65 "IO.chs" #-}++-- |The type of the \"element started\" callback.  The first parameter is+-- the element name; the second are the (attribute, value) pairs.+type StartElementHandler  = String -> [(String,String)] -> IO ()+-- |The type of the \"element ended\" callback.  The parameter is+-- the element name.+type EndElementHandler    = String -> IO ()+-- |The type of the \"character data\" callback.  The parameter is+-- the character data processed.  This callback may be called more than once+-- while processing a single conceptual block of text.+type CharacterDataHandler = String -> IO ()++type CStartElementHandler = Ptr () -> CString -> Ptr CString -> IO ()+foreign import ccall "wrapper"+  mkCStartElementHandler :: CStartElementHandler+                         -> IO (FunPtr CStartElementHandler)+wrapStartElementHandler :: StartElementHandler+                        -> IO (FunPtr CStartElementHandler)+wrapStartElementHandler handler = mkCStartElementHandler h where+  h ptr cname cattrs = do+    name <- peekCString cname+    cattrlist <- peekArray0 nullPtr cattrs+    attrlist <- mapM peekCString cattrlist+    handler name (pairwise attrlist)+-- |Attach a StartElementHandler to a Parser.+setStartElementHandler :: Parser -> StartElementHandler -> IO ()+setStartElementHandler parser handler = do+  withParser parser $ \p -> do+  handler' <- wrapStartElementHandler handler+  xmlSetstartelementhandler p handler'+++type CEndElementHandler = Ptr () -> CString -> IO ()+foreign import ccall "wrapper"+  mkCEndElementHandler :: CEndElementHandler+                       -> IO (FunPtr CEndElementHandler)+wrapEndElementHandler :: EndElementHandler+                      -> IO (FunPtr CEndElementHandler)+wrapEndElementHandler handler = mkCEndElementHandler h where+  h ptr cname = do+    name <- peekCString cname+    handler name+-- |Attach an EndElementHandler to a Parser.+setEndElementHandler :: Parser -> EndElementHandler -> IO ()+setEndElementHandler parser handler = do+  withParser parser $ \p -> do+  handler' <- wrapEndElementHandler handler+  xmlSetendelementhandler p handler'++type CCharacterDataHandler = Ptr () -> CString -> CInt -> IO ()+foreign import ccall "wrapper"+  mkCCharacterDataHandler :: CCharacterDataHandler+                          -> IO (FunPtr CCharacterDataHandler)+wrapCharacterDataHandler :: CharacterDataHandler+                      -> IO (FunPtr CCharacterDataHandler)+wrapCharacterDataHandler handler = mkCCharacterDataHandler h where+  h ptr cdata len = do+    data_ <- peekCStringLen (cdata, fromIntegral len)+    handler data_+-- |Attach an CharacterDataHandler to a Parser.+setCharacterDataHandler :: Parser -> CharacterDataHandler -> IO ()+setCharacterDataHandler parser handler = do+  withParser parser $ \p -> do+  handler' <- wrapCharacterDataHandler handler+  xmlSetcharacterdatahandler p handler'++pairwise (x1:x2:xs) = (x1,x2) : pairwise xs+pairwise []         = []++foreign import ccall unsafe "IO.chs.h XML_ParserCreate"+  parserCreate'_ :: ((Ptr CChar) -> (IO (Ptr ())))++foreign import ccall safe "IO.chs.h XML_Parse"+  parse'_ :: ((Ptr ()) -> ((Ptr CChar) -> (CInt -> (CInt -> (IO CInt)))))++foreign import ccall unsafe "IO.chs.h XML_SetStartElementHandler"+  xmlSetstartelementhandler :: ((Ptr ()) -> ((FunPtr ((Ptr ()) -> ((Ptr CChar) -> ((Ptr (Ptr CChar)) -> (IO ()))))) -> (IO ())))++foreign import ccall unsafe "IO.chs.h XML_SetEndElementHandler"+  xmlSetendelementhandler :: ((Ptr ()) -> ((FunPtr ((Ptr ()) -> ((Ptr CChar) -> (IO ())))) -> (IO ())))++foreign import ccall unsafe "IO.chs.h XML_SetCharacterDataHandler"+  xmlSetcharacterdatahandler :: ((Ptr ()) -> ((FunPtr ((Ptr ()) -> ((Ptr CChar) -> (CInt -> (IO ()))))) -> (IO ())))
+ Text/XML/Expat/Tree.hs view
@@ -0,0 +1,50 @@+-- hexpat, a Haskell wrapper for expat+-- Copyright (C) 2008 Evan Martin <martine@danga.com>++-- |The Expat.Tree module provides a simplified interface to parsing, that+-- returns a tree of the XML structure.  (Note that this is not a lazy parse+-- of the document: as soon as the root node is accessed, the entire document+-- is parsed.)++module Text.XML.Expat.Tree (+  Text.XML.Expat.Tree.parse, Node(..)+) where++import Text.XML.Expat.IO as EIO+import Data.IORef+import System.IO.Unsafe (unsafePerformIO)++-- |Simplistic XML tree representation.+data Node = Element { eName :: String, eAttrs :: [(String,String)],+                      eChildren :: [Node] }+          | Text String+          deriving Show++modifyChildren :: ([Node] -> [Node]) -> Node -> Node+modifyChildren f node = node { eChildren = f (eChildren node) }++-- |@parse enc doc@ parses XML content @doc@ with optional encoding @enc@,+-- and returns the root 'Node' of the document if there were no parsing errors.+parse :: Maybe String -> String -> Maybe Node+parse enc doc = unsafePerformIO $ runParse where+  runParse = do+    parser <- EIO.newParser enc+    -- We maintain the invariant that the stack always has one element,+    -- whose only child at the end of parsing is the root of the actual tree.+    stack <- newIORef [Element "" [] []]+    EIO.setStartElementHandler  parser (\n a -> modifyIORef stack (start n a))+    EIO.setEndElementHandler    parser (\n -> modifyIORef stack (end n))+    EIO.setCharacterDataHandler parser (\s -> modifyIORef stack (text s))+    ok <- EIO.parse parser doc True+    if ok+      then do+        [Element _ _ [root]] <- readIORef stack+        return $ Just $ modifyChildren reverse root+      else return Nothing+  start name attrs stack = Element name attrs [] : stack+  text str (cur:rest) = modifyChildren (Text str:) cur : rest+  end name (cur:parent:rest) =+    if eName cur /= name then error "name mismatch" else+    let node = modifyChildren reverse cur in+    modifyChildren (node:) parent : rest+
+ hexpat.cabal view
@@ -0,0 +1,20 @@+Cabal-Version: >= 1.2+Name: hexpat+Version: 0.1+Synopsis: wrapper for expat, the fast XML parser+Category: XML+License: BSD3+License-File: LICENSE+Author: Evan Martin+Maintainer: martine@danga.com+Copyright: (c) 2008 Evan Martin <martine@danga.com>+Homepage: http://neugierig.org/software/darcs/browse/?r=hexpat;a=summary+Extra-Source-Files: C2HS.hs test.hs+Build-Type: Simple++Library+  Build-Depends: base, haskell98+  Exposed-Modules: Text.XML.Expat.IO, Text.XML.Expat.Tree+  Extensions: ForeignFunctionInterface+  Extra-Libraries: expat+
+ test.hs view
@@ -0,0 +1,26 @@+import qualified Text.XML.Expat.IO as EIO+import qualified Text.XML.Expat.Tree as ETree+import Data.Tree++main_eio doc = do+  parser <- EIO.newParser Nothing+  EIO.setStartElementHandler parser startElement+  EIO.parse parser doc True+  putStrLn "ok"+  where+  startElement name attrs = putStrLn $ show name ++ " " ++ show attrs++main_tree doc = do+  let etree = ETree.parse Nothing doc+  --let dtree = toDTree etree+  --putStrLn (drawTree dtree)+  etree `seq` putStrLn "ok"+  where+  toDTree (ETree.Element name attrs kids) =+    Node ("<" ++ name ++ " " ++ show attrs ++ ">") (map toDTree kids)+  toDTree (ETree.Text str) = Node (show str) []++main = do+  let doc = "<foo baz='bah'><bar/><text>some &amp; text</text></foo>"+  xml <- readFile "test.xml"+  main_eio xml