packages feed

hexml 0.2 → 0.3

raw patch · 5 files changed

+68/−64 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGES.txt view
@@ -1,5 +1,9 @@ Changelog for Hexml +0.3+    #8, Mac compatibility+    Fix a bug when parsing closing comments+    #7, prefix all the C functions with hexml_ 0.2     #6, remove buffer overruns     #5, add lower bounds
cbits/hexml.c view
@@ -1,5 +1,5 @@ #include "hexml.h"-#include <malloc.h>+#include <stdlib.h> #include <string.h> #include <assert.h> #include <ctype.h>@@ -97,16 +97,16 @@     bound(end(s), mn, mx); } -void render_str(render* r, str s)+static void render_str(render* r, str s) {     bound_str(s, 0, doc_length(r->d));     for (int i = 0; i < s.length; i++)         render_char(r, r->d->body[s.start + i]); } -void render_tag(render* r, const node* n);+static void render_tag(render* r, const node* n); -void render_content(render* r, const node* n)+static void render_content(render* r, const node* n) {     bound_str(n->inner, 0, doc_length(r->d));     bound_str(n->nodes, 0, r->d->nodes.used_front);@@ -123,7 +123,7 @@     render_str(r, start_end(done, end(n->inner))); } -void render_tag(render* r, const node* n)+static void render_tag(render* r, const node* n) {     render_char(r, '<');     render_str(r, n->name);@@ -145,7 +145,7 @@     render_char(r, '>'); } -int node_render(const document* d, const node* n, char* buffer, int length)+int hexml_node_render(const document* d, const node* n, char* buffer, int length) {     render r;     r.d = d;@@ -164,10 +164,10 @@ ///////////////////////////////////////////////////////////////////// // NOT THE PARSER -char* document_error(const document* d){return d->error_message;}-node* document_node(const document* d){return &d->nodes.nodes[0];}+char* hexml_document_error(const document* d){return d->error_message;}+node* hexml_document_node(const document* d){return &d->nodes.nodes[0];} -void document_free(document* d)+void hexml_document_free(document* d) {     free(d->error_message);     free(d->nodes.alloc);@@ -175,20 +175,20 @@     free(d); } -node* node_children(const document* d, const node* n, int* res)+node* hexml_node_children(const document* d, const node* n, int* res) {     *res = n->nodes.length;     return &d->nodes.nodes[n->nodes.start]; } -attr* node_attributes(const document* d, const node* n, int* res)+attr* hexml_node_attributes(const document* d, const node* n, int* res) {     *res = n->attrs.length;     return &d->attrs.attrs[n->attrs.start]; }  -attr* node_attributeBy(const document* d, const node* n, const char* s, int slen)+attr* hexml_node_attribute(const document* d, const node* n, const char* s, int slen) {     if (slen == -1) slen = (int) strlen(s);     const int limit = end(n->attrs);@@ -202,7 +202,7 @@ }  // Search for given strings within a node-node* node_childBy(const document* d, const node* parent, const node* prev, const char* s, int slen)+node* hexml_node_child(const document* d, const node* parent, const node* prev, const char* s, int slen) {     if (slen == -1) slen = (int) strlen(s);     int i = prev == NULL ? parent->nodes.start : (int) (prev + 1 - d->nodes.nodes);@@ -220,13 +220,13 @@ ///////////////////////////////////////////////////////////////////// // PARSE TABLE -const char tag_name1 = 0x1;-const char tag_name = 0x2;-const char tag_space = 0x4;+static const char tag_name1 = 0x1;+static const char tag_name = 0x2;+static const char tag_space = 0x4; -char parse_table[256];+static char parse_table[256]; -void init_parse_table()+static void init_parse_table() {     static bool done = 0;     if (done) return;@@ -249,8 +249,8 @@ ///////////////////////////////////////////////////////////////////// // PARSER COMBINATORS -static inline char peekAt(const document* d, int i) { return d->cursor[i]; }-static inline char peek(const document* d) { return peekAt(d, 0); }+static inline char peek_at(const document* d, int i) { return d->cursor[i]; }+static inline char peek(const document* d) { return peek_at(d, 0); } static inline void skip(document* d, int i) { d->cursor += i; } static inline char get(document* d) { char c = peek(d); skip(d, 1); return c; } @@ -262,7 +262,7 @@ }  // Find this character form the cursor onwards, if true adjust the cursor to that char, otherwise leave it at the end-bool find(document* d, char c)+static bool find(document* d, char c) {     char* x = memchr(d->cursor, c, d->end - d->cursor);     if (x == NULL)@@ -310,7 +310,7 @@     b->alloc = buf2; } -void set_error(document* d, const char* msg)+static void set_error(document* d, const char* msg) {     if (d->error_message != NULL) return; // keep the first error message     d->error_message = malloc(strlen(msg)+1);@@ -381,7 +381,7 @@     return start_end(start, d->attrs.used); } -str parse_content(document* d);+static str parse_content(document* d);   // Add a new entry into tag, am at a '<'@@ -405,7 +405,7 @@     if (d->error_message != NULL) return;      c = peek(d);-    if ((c == '/' || c == '?') && peekAt(d, 1) == '>')+    if ((c == '/' || c == '?') && peek_at(d, 1) == '>')     {         skip(d, 2);         me->nodes = start_length(0, 0);@@ -429,7 +429,7 @@     me->inner.length = start_end(me->inner.start, doc_position(d)).length;      if (d->error_message != NULL) return;-    if (peek(d) == '<' && peekAt(d, 1) == '/')+    if (peek(d) == '<' && peek_at(d, 1) == '/')     {         skip(d, 2);         if (d->end - d->cursor >= me->name.length &&@@ -451,7 +451,7 @@  // Parser until </, return the index of your node children // Not inline as it is recursive-str parse_content(document* d)+static str parse_content(document* d) {     int before = d->nodes.used_back;     while (d->error_message == NULL)@@ -461,16 +461,16 @@         {             break;         }-        else if (peekAt(d, 1) == '/')+        else if (peek_at(d, 1) == '/')         {             // have found a </             break;         }-        else if (peekAt(d, 1) == '!' && peekAt(d, 2) == '-' && peekAt(d, 3) == '-')+        else if (peek_at(d, 1) == '!' && peek_at(d, 2) == '-' && peek_at(d, 3) == '-')         {             skip(d, 3);             // you can't reuse the two '-' characters for the closing as well-            if (peekAt(d, 0) == '\0' || peekAt(d, 1) == '\0')+            if (peek_at(d, 0) == '\0' || peek_at(d, 1) == '\0')             {                 set_error(d, "Didn't get a closing comment");                 return start_end(0, 0);@@ -484,7 +484,7 @@                     return start_end(0, 0);                 }                 skip(d, 1);-                if (peekAt(d, -3) == '-' && peekAt(d, -2))+                if (peek_at(d, -3) == '-' && peek_at(d, -2) == '-')                     break;             }         }@@ -512,7 +512,7 @@     node nodes[500]; } buffer; -document* document_parse(const char* s, int slen)+document* hexml_document_parse(const char* s, int slen) {     if (slen == -1) slen = (int) strlen(s);     assert(s[slen] == 0);
cbits/hexml.h view
@@ -30,27 +30,27 @@ // Parse a document, returns a potentially invalid document - use document_error to check // Must use document_free to release the memory (even if invalid). // The string must be nul terminated, e.g. slen != -1 ==> slen[0]-document* document_parse(const char* s, int slen);+document* hexml_document_parse(const char* s, int slen);  // Free the memory returned from document_parse.-void document_free(document* d);+void hexml_document_free(document* d);  // Generate a fresh string with the same semantics as the node. // Requires an input buffer, returns the size of the rendered document. // Requires the string passed to document_parse to be valid.-int node_render(const document* d, const node* n, char* buffer, int length);+int hexml_node_render(const document* d, const node* n, char* buffer, int length);  // Return either NULL (successful parse) or the error message.-char* document_error(const document* d);+char* hexml_document_error(const document* d);  // Return the root node of the document - imagine the document is wrapped in <>$DOC</> tags.-node* document_node(const document* d);+node* hexml_document_node(const document* d);  // List all items within a node-node* node_children(const document* d, const node* n, int* res);-attr* node_attributes(const document* d, const node* n, int* res);+node* hexml_node_children(const document* d, const node* n, int* res);+attr* hexml_node_attributes(const document* d, const node* n, int* res);  // Search for given strings within a node, note that prev may be NULL // Requires the string passed to document_parse to be valid.-node* node_childBy(const document* d, const node* parent, const node* prev, const char* s, int slen);-attr* node_attributeBy(const document* d, const node* n, const char* s, int slen);+node* hexml_node_child(const document* d, const node* parent, const node* prev, const char* s, int slen);+attr* hexml_node_attribute(const document* d, const node* n, const char* s, int slen);
hexml.cabal view
@@ -1,10 +1,10 @@ cabal-version:      >= 1.18 build-type:         Simple name:               hexml-version:            0.2+version:            0.3 license:            BSD3 license-file:       LICENSE-category:           Development+category:           XML author:             Neil Mitchell <ndmitchell@gmail.com> maintainer:         Neil Mitchell <ndmitchell@gmail.com> copyright:          Neil Mitchell 2016
src/Text/XML/Hexml.hs view
@@ -45,18 +45,18 @@     peek p = Str <$> peekByteOff p 0 <*> peekByteOff p 4     poke p Str{..} = pokeByteOff p 0 strStart >> pokeByteOff p 4 strLength -foreign import ccall document_parse :: CString -> CInt -> IO (Ptr CDocument)-foreign import ccall document_free :: Ptr CDocument -> IO ()-foreign import ccall "&document_free" document_free_funptr :: FunPtr (Ptr CDocument -> IO ())-foreign import ccall node_render :: Ptr CDocument -> Ptr CNode -> CString -> CInt -> IO CInt-foreign import ccall document_error :: Ptr CDocument -> IO CString-foreign import ccall document_node :: Ptr CDocument -> IO (Ptr CNode)+foreign import ccall hexml_document_parse :: CString -> CInt -> IO (Ptr CDocument)+foreign import ccall hexml_document_free :: Ptr CDocument -> IO ()+foreign import ccall "&hexml_document_free" hexml_document_free_funptr :: FunPtr (Ptr CDocument -> IO ())+foreign import ccall hexml_node_render :: Ptr CDocument -> Ptr CNode -> CString -> CInt -> IO CInt+foreign import ccall hexml_document_error :: Ptr CDocument -> IO CString+foreign import ccall hexml_document_node :: Ptr CDocument -> IO (Ptr CNode) -foreign import ccall node_children :: Ptr CDocument -> Ptr CNode -> Ptr CInt -> IO (Ptr CNode)-foreign import ccall node_attributes :: Ptr CDocument -> Ptr CNode -> Ptr CInt -> IO (Ptr CAttr)+foreign import ccall hexml_node_children :: Ptr CDocument -> Ptr CNode -> Ptr CInt -> IO (Ptr CNode)+foreign import ccall hexml_node_attributes :: Ptr CDocument -> Ptr CNode -> Ptr CInt -> IO (Ptr CAttr) -foreign import ccall node_childBy :: Ptr CDocument -> Ptr CNode -> Ptr CNode -> CString -> CInt -> IO (Ptr CNode)-foreign import ccall node_attributeBy :: Ptr CDocument -> Ptr CNode -> CString -> CInt -> IO (Ptr CAttr)+foreign import ccall hexml_node_child :: Ptr CDocument -> Ptr CNode -> Ptr CNode -> CString -> CInt -> IO (Ptr CNode)+foreign import ccall hexml_node_attribute :: Ptr CDocument -> Ptr CNode -> CString -> CInt -> IO (Ptr CAttr)  -- | A node in an XML document, created by 'parse', then calling functions such --   as 'children' on that initial 'Node'.@@ -85,23 +85,23 @@ parse src = do     let src0 = src <> BS.singleton '\0'     unsafePerformIO $ BS.unsafeUseAsCStringLen src0 $ \(str, len) -> do-        doc <- document_parse str (fromIntegral len - 1)-        err <- document_error doc+        doc <- hexml_document_parse str (fromIntegral len - 1)+        err <- hexml_document_error doc         if err /= nullPtr then do-            bs <- BS.packCString =<< document_error doc-            document_free doc+            bs <- BS.packCString =<< hexml_document_error doc+            hexml_document_free doc             return $ Left bs          else do-            node <- document_node doc-            doc <- newForeignPtr document_free_funptr doc+            node <- hexml_document_node doc+            doc <- newForeignPtr hexml_document_free_funptr doc             return $ Right $ Node src0 doc node  -- | Given a node, rerender it to something with an equivalent parse tree. --   Mostly useful for debugging - if you want the real source document use 'outer' instead. render :: Node -> BS.ByteString render (Node src doc n) = unsafePerformIO $ withForeignPtr doc $ \d -> do-    i <- node_render d n nullPtr 0-    res <- BS.create (fromIntegral i) $ \ptr -> void $ node_render d n (castPtr ptr) i+    i <- hexml_node_render d n nullPtr 0+    res <- BS.create (fromIntegral i) $ \ptr -> void $ hexml_node_render d n (castPtr ptr) i     touchBS src     return res @@ -154,7 +154,7 @@ children :: Node -> [Node] children (Node src doc n) = unsafePerformIO $ withForeignPtr doc $ \d -> do     alloca $ \count -> do-        res <- node_children d n count+        res <- hexml_node_children d n count         count <- fromIntegral <$> peek count         return [Node src doc $ plusPtr res $ i*szNode | i <- [0..count-1]] @@ -162,7 +162,7 @@ attributes :: Node -> [Attribute] attributes (Node src doc n) = unsafePerformIO $ withForeignPtr doc $ \d -> do     alloca $ \count -> do-        res <- node_attributes d n count+        res <- hexml_node_attributes d n count         count <- fromIntegral <$> peek count         return [attrPeek src doc $ plusPtr res $ i*szAttr | i <- [0..count-1]] @@ -175,7 +175,7 @@     where         go old = unsafePerformIO $ withForeignPtr doc $ \d ->             BS.unsafeUseAsCStringLen str $ \(bs, len) -> do-                r <- node_childBy d n old bs $ fromIntegral len+                r <- hexml_node_child d n old bs $ fromIntegral len                 touchBS src                 return $ if r == nullPtr then [] else Node src doc r : go r @@ -186,7 +186,7 @@ attributeBy :: Node -> BS.ByteString -> Maybe Attribute attributeBy (Node src doc n) str = unsafePerformIO $ withForeignPtr doc $ \d ->     BS.unsafeUseAsCStringLen str $ \(bs, len) -> do-        r <- node_attributeBy d n bs $ fromIntegral len+        r <- hexml_node_attribute d n bs $ fromIntegral len         touchBS src         return $ if r == nullPtr then Nothing else Just $ attrPeek src doc r