diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -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
diff --git a/cbits/hexml.c b/cbits/hexml.c
--- a/cbits/hexml.c
+++ b/cbits/hexml.c
@@ -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);
diff --git a/cbits/hexml.h b/cbits/hexml.h
--- a/cbits/hexml.h
+++ b/cbits/hexml.h
@@ -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);
diff --git a/hexml.cabal b/hexml.cabal
--- a/hexml.cabal
+++ b/hexml.cabal
@@ -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
diff --git a/src/Text/XML/Hexml.hs b/src/Text/XML/Hexml.hs
--- a/src/Text/XML/Hexml.hs
+++ b/src/Text/XML/Hexml.hs
@@ -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
 
