]> git.mxchange.org Git - flightgear.git/blobdiff - utils/xmlgrep/xml.c
Allow setting of NED velocities.
[flightgear.git] / utils / xmlgrep / xml.c
index 433828ce2c5111e570f1fc8b6c63a02901975ef8..5357ed81afd4d2706b9dffab66d81f3275dfac85 100644 (file)
  */
 
 #ifdef WIN32
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
 # include <io.h>
 
-typedef struct
-{
-    HANDLE m;
-    void *p;
-} SIMPLE_UNMMAP;
-
 #else  /* !WIN32 */
 # include <sys/mman.h>
 # include <unistd.h>
@@ -45,6 +37,7 @@ typedef struct
 # include <stdio.h>
 #endif
 #include <stdlib.h>     /* free, malloc */
+#include <malloc.h>
 #include <string.h>    /* memcmp */
 #ifndef _MSC_VER
 #include <strings.h>   /* strncasecmp */
@@ -57,17 +50,11 @@ typedef struct
 #include <assert.h>
 #include <ctype.h>
 
-#ifndef XML_NONVALIDATING
 #include "xml.h"
 
+#ifndef XML_NONVALIDATING
 static const char *__xml_error_str[XML_MAX_ERROR];
 
-struct _xml_error
-{
-    char *pos;
-    int err_no;
-};
-
 static void __xmlErrorSet(const void *, const char *, unsigned int);
 # define xmlErrorSet(a, b, c)  __xmlErrorSet(a, b, c)
 
@@ -87,39 +74,8 @@ static void __xmlErrorSet(const void *, const char *, unsigned int);
 # define SET_ERROR_AND_RETURN(a, b)    return 0;
 #endif
 
-/*
- * It is required for both the rood node and the normal xml nodes to both
- * have 'char *name' defined as the first entry. The code tests whether
- * name == 0 to detect the root node.
- */
-struct _root_id
-{
-    char *name;
-    char *start;
-    size_t len;
-    int fd;
-#ifndef XML_NONVALIDATING
-    struct _xml_error *info;
-#endif
-# ifdef WIN32
-    SIMPLE_UNMMAP un;
-# endif
-};
-
-struct _xml_id
-{
-    char *name;
-    char *start;
-    size_t len;
-    size_t name_len;
-#ifndef XML_NONVALIDATING
-    struct _root_id *root;
-#endif
-};
-
-static char *__xmlNodeCopy(const char *, size_t *, const char **);
-static char *__xmlNodeGetPath(const char *, size_t *, char **, size_t *);
-static char *__xmlNodeGet(const char *, size_t *, char **, size_t *, size_t *);
+static char *__xmlNodeGetPath(void **, const char *, size_t *, char **, size_t *);
+static char *__xmlNodeGet(void *, const char *, size_t *, char **, size_t *, size_t *);
 static char *__xmlProcessCDATA(char **, size_t *);
 static char *__xmlCommentSkip(const char *, size_t);
 static char *__xmlInfoProcess(const char *, size_t);
@@ -140,12 +96,14 @@ static void simple_unmmap(SIMPLE_UNMMAP *);
 
 #ifndef NDEBUG
 # define PRINT(a, b, c) { \
-   if (a) { \
-      size_t q, len = c; \
-      if (b < c) len = b; \
+   size_t l1 = (b), l2 = (c); \
+   char *s = (a); \
+   if (s) { \
+      size_t q, len = l2; \
+      if (l1 < l2) len = l1; \
       if (len < 50000) { \
          printf("(%i) '", len); \
-         for (q=0; q<len; q++) printf("%c", ((char *)(a))[q]); \
+         for (q=0; q<len; q++) printf("%c", s[q]); \
          printf("'\n"); \
       } else printf("Length (%u) seems too large at line %i\n",len, __LINE__); \
    } else printf("NULL pointer at line %i\n", __LINE__); \
@@ -169,16 +127,20 @@ xmlOpen(const char *filename)
             mm = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0L);
             if (mm != (void *)-1)
             {
-                rid = malloc(sizeof(struct _root_id));
+                rid = calloc(1, sizeof(struct _root_id));
                 if (rid)
                 {
+                    size_t blen = statbuf.st_size;
+#ifdef XML_USE_NODECACHE
+                    size_t num = 0, nlen = 1;
+                    char *n = "*";
+
+                    rid->node = cacheInit();
+                    __xmlNodeGet(rid->node, mm, &blen, &n, &nlen, &num);
+#endif
                     rid->fd = fd;
                     rid->start = mm;
-                    rid->len = statbuf.st_size;
-                    rid->name = 0;
-#ifndef XML_NONVALIDATING
-                    rid->info = 0;
-#endif
+                    rid->len = blen;
                 }
             }
         }
@@ -194,16 +156,20 @@ xmlInitBuffer(const char *buffer, size_t size)
 
     if (buffer && (size > 0))
     {
-        rid = malloc(sizeof(struct _root_id));
+        rid = calloc(1, sizeof(struct _root_id));
         if (rid)
         {
-            rid->fd = -1;
+#ifdef XML_USE_NODECACHE
+            size_t num = 0, nlen = 1;
+            size_t blen = size;
+            char *n = "*";
+
+            rid->node = cacheInit();
+            __xmlNodeGet(rid->node, buffer, &blen, &n, &nlen, &num);
+#endif
+           rid->fd = -1;
             rid->start = (char *)buffer;
             rid->len = size;
-            rid->name = 0;
-#ifndef XML_NONVALIDATING
-            rid->info = 0;
-#endif
         }
     }
 
@@ -224,7 +190,12 @@ xmlClose(void *id)
          close(rid->fd);
      }
 
+#ifdef XML_USE_NODECACHE
+     if (rid->node) cacheFree(rid->node);
+#endif
+#ifndef XML_NONVALIDATING
      if (rid->info) free(rid->info);
+#endif
      free(rid);
      id = 0;
 }
@@ -236,6 +207,7 @@ xmlNodeGet(const void *id, const char *path)
     struct _xml_id *xsid = 0;
     size_t len, slen;
     char *ptr, *node;
+    void *nc, *nnc;
 
     assert(id != 0);
     assert(path != 0);
@@ -243,16 +215,21 @@ xmlNodeGet(const void *id, const char *path)
     node = (char *)path;
     len = xid->len;
     slen = strlen(path);
-    ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
+
+    nnc = nc = cacheNodeGet(xid);
+    ptr = __xmlNodeGetPath(&nnc, xid->start, &len, &node, &slen);
     if (ptr)
     {
         xsid = malloc(sizeof(struct _xml_id));
         if (xsid)
         {
-             xsid->len = len;
-             xsid->start = ptr;
-             xsid->name_len = slen;
              xsid->name = node;
+             xsid->name_len = slen;
+             xsid->start = ptr;
+             xsid->len = len;
+#ifdef XML_USE_NODECACHE
+             xsid->node = nnc;
+#endif
 #ifndef XML_NONVALIDATING
              if (xid->name)
                 xsid->root = xid->root;
@@ -280,11 +257,14 @@ xmlNodeCopy(const void *id, const char *path)
     struct _xml_id *xsid = 0;
     char *ptr, *node, *p;
     size_t slen, len;
+    void *nc, *nnc;
 
     node = (char *)path;
     len = xid->len;
     slen = strlen(path);
-    ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
+
+    nnc = nc = cacheNodeGet(xid);
+    ptr = __xmlNodeGetPath(&nnc, xid->start, &len, &node, &slen);
     if (ptr)
     {
         xsid = malloc(sizeof(struct _xml_id) + len);
@@ -296,6 +276,9 @@ xmlNodeCopy(const void *id, const char *path)
             xsid->start = p;
             xsid->name_len = slen;
             xsid->name = node;
+#ifdef XML_USE_NODECACHE
+                 xsid->node = nc;
+#endif
 #ifndef XML_NONVALIDATING
             if (xid->name)
                 xsid->root = xid->root;
@@ -376,12 +359,14 @@ xmlNodeGetNum(const void *id, const char *path)
     {
         char *nodename, *pathname;
         size_t len, slen;
+        void *nc;
         char *p;
 
         nodename = (char *)path;
         if (*path == '/') nodename++;
         slen = strlen(nodename);
 
+        nc = cacheNodeGet(xid);
         pathname = strchr(nodename, '/');
         if (pathname)
         {
@@ -391,7 +376,7 @@ xmlNodeGetNum(const void *id, const char *path)
            pathname++;
            slen -= pathname-nodename;
            node = pathname;
-           p = __xmlNodeGetPath(xid->start, &len, &node, &slen);
+           p = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
            if (p == 0 && slen == 0)
            {
                xmlErrorSet(xid, node, len);
@@ -406,7 +391,11 @@ xmlNodeGetNum(const void *id, const char *path)
         if (p)
         {
             char *ret, *node = nodename;
-            ret = __xmlNodeGet(p, &len, &node, &slen, &num);
+#ifndef XML_USE_NODECACHE
+            ret = __xmlNodeGet(nc, p, &len, &node, &slen, &num);
+#else
+            ret = __xmlNodeGetFromCache(&nc, p, &len, &node, &slen, &num);
+#endif
             if (ret == 0 && slen == 0)
             {
                 xmlErrorSet(xid, node, len);
@@ -426,6 +415,7 @@ xmlNodeGetPos(const void *pid, void *id, const char *element, size_t num)
     size_t len, slen;
     char *ptr, *node;
     void *ret = 0;
+    void *nc;
 
     assert(xpid != 0);
     assert(xid != 0);
@@ -434,13 +424,23 @@ xmlNodeGetPos(const void *pid, void *id, const char *element, size_t num)
     len = xpid->len;
     slen = strlen(element);
     node = (char *)element;
-    ptr = __xmlNodeGet(xpid->start, &len, &node, &slen, &num);
+    nc = cacheNodeGet(xpid);
+#ifndef XML_USE_NODECACHE
+    ptr = __xmlNodeGet(nc, xpid->start, &len, &node, &slen, &num);
+#else
+    ptr = __xmlNodeGetFromCache(&nc, xpid->start, &len, &node, &slen, &num);
+#endif
     if (ptr)
     {
          xid->len = len;
          xid->start = ptr;
          xid->name = node;
          xid->name_len = slen;
+#ifdef XML_USE_NODECACHE
+         /* unused for the cache but tested at the start of this function */
+         if (len == 0) xid->len = 1;
+         xid->node = nc;
+#endif
          ret = xid;
     }
     else if (slen == 0)
@@ -465,11 +465,11 @@ xmlGetString(const void *id)
         char *ps;
 
         ps = xid->start;
-        len = xid->len;
+        len = xid->len-1;
         __xmlPrepareData(&ps, &len);
-
         if (len)
         {
+            len++;
             str = malloc(len+1);
             if (str)
             {
@@ -496,16 +496,15 @@ xmlCopyString(const void *id, char *buffer, size_t buflen)
     assert(buffer != 0);
     assert(buflen > 0);
 
+    *buffer = '\0';
     if (xid->len)
     {
         size_t len;
-        char *ps,
+        char *ps;
 
-        *buffer = '\0';
         ps = xid->start;
         len = xid->len;
         __xmlPrepareData(&ps, &len);
-
         if (len)
         {
             if (len >= buflen)
@@ -515,8 +514,8 @@ xmlCopyString(const void *id, char *buffer, size_t buflen)
             }
             memcpy(buffer, ps, len);
             *(buffer+len) = 0;
-            ret = len;
         }
+        ret = len;
     }
 
     return ret;
@@ -537,7 +536,7 @@ xmlCompareString(const void *id, const char *s)
         char *ps;
 
         ps = xid->start;
-        len = xid->len-1;
+        len = xid->len;
         __xmlPrepareData(&ps, &len);
         ret = strncasecmp(ps, s, len);
     }
@@ -556,23 +555,26 @@ xmlNodeGetString(const void *id, const char *path)
 
     if (xid->len)
     {
+        char *ptr, *node = (char *)path;
+        size_t slen = strlen(node);
         size_t len = xid->len;
-        char *node = (char *)path;
+        void *nc;
 
-        str = __xmlNodeCopy(xid->start, &len, &path);
-        if (str)
+        nc = cacheNodeGet(xid);
+        ptr = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
+        if (ptr && len)
         {
-            size_t len;
-            char *ps, *pe;
-
-            ps = str;
-            len = strlen(str);
-            __xmlPrepareData(&ps, &len);
-            pe = ps + len;
-
-            *++pe = 0;
-            if (len && (ps>str)) memmove(str, ps, len);
-            else if (!len) *str = 0;
+            __xmlPrepareData(&ptr, &len);
+            str = malloc(len+1);
+            if (str)
+            {
+               memcpy(str, ptr, len);
+               *(str+len) = '\0';
+            }
+            else
+            {
+                xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
+            }
         }
         else
         {
@@ -594,29 +596,30 @@ xmlNodeCopyString(const void *id, const char *path, char *buffer, size_t buflen)
     assert(buffer != 0);
     assert(buflen > 0);
 
+    *buffer = '\0';
     if (xid->len)
     {
-        char *str, *node;
-        size_t slen, len;
+        char *p, *node = (char *)path;
+        size_t slen = strlen(node);
+        size_t len = xid->len;
+        void *nc;
 
-        *buffer = '\0';
-        len = xid->len;
-        slen = strlen(path);
-        node = (char *)path;
-        str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
-        if (str)
+        nc = cacheNodeGet(xid);
+        p = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
+        if (p)
         {
-            char *ps = str;
-            __xmlPrepareData(&ps, &len);
-
-            if (len >= buflen)
+            __xmlPrepareData(&p, &len);
+            if (len)
             {
-                len = buflen-1;
-                xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
-            }
+                if (len >= buflen)
+                {
+                    len = buflen-1;
+                    xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
+                }
 
-            memcpy(buffer, ps, len);
-            *(buffer + len) = '\0';
+                memcpy(buffer, p, len);
+                *(buffer+len) = '\0';
+            }
             ret = len;
         }
         else if (slen == 0)
@@ -642,11 +645,13 @@ xmlNodeCompareString(const void *id, const char *path, const char *s)
     {
         char *node, *str, *ps, *pe;
         size_t len, slen;
+        void *nc;
 
         len = xid->len;
         slen = strlen(path);
         node = (char *)path;
-        str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
+        nc = cacheNodeGet(xid);
+        str = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
         if (str)
         {
             ps = str;
@@ -692,11 +697,13 @@ xmlNodeGetInt(const void *id, const char *path)
     {
         size_t len, slen;
         char *str, *node;
+        void *nc;
 
         len = xid->len;
         slen = strlen(path);
         node = (char *)path;
-        str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
+        nc = cacheNodeGet(xid);
+        str = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
         if (str)
         {
             char *end = str+len;
@@ -741,11 +748,13 @@ xmlNodeGetDouble(const void *id, const char *path)
     {
         size_t len, slen;
         char *str, *node;
+        void *nc;
 
         len = xid->len;
         slen = strlen(path);
         node = (char *)path;
-        str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
+        nc = cacheNodeGet(xid);
+        str = __xmlNodeGetPath(&nc, xid->start, &len, &node, &slen);
         if (str)
         {
             char *end = str+len;
@@ -774,9 +783,12 @@ xmlMarkId(const void *id)
         if (xrid->name == 0)
         {
             xmid->name = "";
+            xmid->name_len = 0;
             xmid->start = xrid->start;
             xmid->len = xrid->len;
-            xmid->name_len = 0;
+#ifdef XML_USE_NODECACHE
+            xmid->node = xrid->node;
+#endif
 #ifndef XML_NONVALIDATING
             xmid->root = xrid;
 #endif
@@ -1277,6 +1289,33 @@ xmlErrorGetString(const void *id, int clear)
 
     return ret;
 }
+
+#else
+
+int
+xmlErrorGetNo(const void *id, int clear)
+{
+    return XML_NO_ERROR;
+}
+
+size_t
+xmlErrorGetLineNo(const void *id, int clear)
+{
+    return 0;
+}
+
+size_t
+xmlErrorGetColumnNo(const void *id, int clear)
+{
+    return 0;
+}
+
+const char *
+xmlErrorGetString(const void *id, int clear)
+{
+   return "error detection was not enabled at compile time: no error.";
+}
+
 #endif
 
 /* -------------------------------------------------------------------------- */
@@ -1300,83 +1339,53 @@ static const char *__xml_error_str[XML_MAX_ERROR] =
 #endif
 
 char *
-__xmlNodeCopy(const char *start, size_t *len, const char **path)
-{
-    char *node, *p, *ret = 0;
-    size_t rlen, slen;
-
-    rlen = *len;
-    slen = strlen(*path);
-    node = (char *)*path;
-    p = __xmlNodeGetPath(start, &rlen, &node, &slen);
-    if (p && rlen)
-    {
-        ret = malloc(rlen+1);
-        if (ret)
-        {
-            memcpy(ret, p, rlen);
-            *(ret+rlen) = '\0';
-        }
-        else
-        {
-            xmlErrorSet(0, 0, XML_OUT_OF_MEMORY);
-        }
-    }
-    else if (slen == 0)
-    {
-        *path = node;
-        *len = rlen;
-    }
-
-    return ret;
-}
-
-char *
-__xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *nlen)
+__xmlNodeGetPath(void **nc, const char *start, size_t *len, char **name, size_t *nlen)
 {
-    char *node;
+    char *path;
     char *ret = 0;
 
     assert(start != 0);
     assert(len != 0);
-    assert(*len != 0);
     assert(name != 0);
     assert(*name != 0);
     assert(nlen != 0);
-    assert(*nlen != 0);
 
-    if (*nlen > *len) return 0;
-
-    node = *name;
-    if (*node == '/') node++;
-    if (*node != 0)
+    path = *name;
+    if (*path == '/') path++;
+    if (*path != '\0')
     {
-        size_t blen, plen, slen;
-        char *path;
-        size_t num;
+        size_t num, blocklen, pathlen, nodelen;
+        char *node;
 
-        slen = strlen(node);
+        node = path;
+        pathlen = strlen(path);
         path = strchr(node, '/');
 
-        if (!path) plen = slen;
-        else plen = path++ - node;
+        if (!path) nodelen = pathlen;
+        else nodelen = path++ - node;
 
         num = 0;
-        blen = *len;
-        ret = __xmlNodeGet(start, &blen, &node, &plen, &num);
+        blocklen = *len;
+
+#ifndef XML_USE_NODECACHE
+        ret = __xmlNodeGet(nc, start, &blocklen, &node, &nodelen, &num);
+#else
+        ret = __xmlNodeGetFromCache(nc, start, &blocklen, &node, &nodelen, &num);
+#endif
         if (ret)
         {
             if (path)
             {
-                plen = slen - (path - *name);
-                ret = __xmlNodeGetPath(ret, &blen, &path, &plen);
+                ret = __xmlNodeGetPath(nc, ret, &blocklen, &path, &pathlen);
                 *name = path;
+                *len = blocklen;
+                *nlen = pathlen;
             }
             else
             {
                *name = node;
-               *nlen = plen;
-               *len = blen;
+               *nlen = nodelen;
+               *len = blocklen;
             }
         }
         else
@@ -1390,7 +1399,7 @@ __xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *nlen)
 }
 
 char *
-__xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *nodenum)
+__xmlNodeGet(void *nc, const char *start, size_t *len, char **name, size_t *rlen, size_t *nodenum)
 {
     char *cdata, *open_element = *name;
     char *element, *start_tag=0;
@@ -1399,6 +1408,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
     size_t open_len = *rlen;
     size_t return_len = 0;
     int found, num;
+    void *nnc = 0;
 
     assert(start != 0);
     assert(len != 0);
@@ -1419,6 +1429,10 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
     cur = (char *)start;
     ne = cur + restlen;
 
+#ifdef XML_USE_NODECACHE
+    cacheInitLevel(nc);
+#endif
+
     /* search for an opening tag */
     while ((new = memchr(cur, '<', restlen)) != 0)
     {
@@ -1464,9 +1478,10 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
         element = *name;
         elementlen = *rlen;
         len_remaining = restlen;
-        new = rptr = __xml_memncasecmp(cur, &restlen, &element, &elementlen);
+        rptr = __xml_memncasecmp(cur, &restlen, &element, &elementlen);
         if (rptr)                      /* requested element was found */
         {
+            new = rptr;
             return_len = elementlen;
             if (found == num)
             {
@@ -1485,11 +1500,18 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
             element = *name;
         }
 
+#ifdef XML_USE_NODECACHE
+        nnc = cacheNodeNew(nc);
+#endif
+
         if (*(new-2) == '/')                           /* e.g. <test/> */
         {
             cur = new;
             if (rptr)
             {
+#ifdef XML_USE_NODECACHE
+                cacheDataSet(nnc, element, elementlen, rptr, 0);
+#endif
                 if (found == num)
                 {
                     open_element = start_tag;
@@ -1539,6 +1561,41 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
             cur = new;
         }
 
+        if (*cur == '/')               /* closing tag of leaf node found */
+        {
+            if (!strncasecmp(new+1, element, elementlen))
+            {
+#ifdef XML_USE_NODECACHE
+                cacheDataSet(nnc, element, elementlen, rptr, new-rptr-1);
+#endif
+                if (*(new+elementlen+1) != '>')
+                    SET_ERROR_AND_RETURN(new+1, XML_ELEMENT_NO_CLOSING_TAG);
+
+                if (found == num)
+                {
+                    if (start_tag)
+                    {
+                        *len = new-ret-1;
+                        open_element = start_tag;
+                        cdata = (char *)start;
+                        start_tag = 0;
+                    }
+                    else /* report error */
+                        SET_ERROR_AND_RETURN(new, XML_ELEMENT_NO_OPENING_TAG);
+                }
+                found++;
+            }
+
+            new = memchr(cur, '>', restlen);
+            if (!new)
+                SET_ERROR_AND_RETURN(cur, XML_ELEMENT_NO_CLOSING_TAG);
+
+            restlen -= new-cur;
+            cur = new;
+            continue;
+        }
+
+        /* no leaf node, continue */
         if (*cur != '/')                       /* cascading tag found */
         {
             char *node = "*";
@@ -1549,7 +1606,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
             /*
              * recursively walk the xml tree from here
              */
-            new = __xmlNodeGet(cur-1, &slen, &node, &nlen, &pos);
+            new = __xmlNodeGet(nnc, cur-1, &slen, &node, &nlen, &pos);
             if (!new)
             {
                 if (nlen == 0)         /* error upstream */
@@ -1589,18 +1646,14 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
                 if (*(new+elementlen+1) != '>')
                     SET_ERROR_AND_RETURN(new+1, XML_ELEMENT_NO_CLOSING_TAG);
 
+#ifdef XML_USE_NODECACHE
+                cacheDataSet(nnc, element, elementlen, rptr, new-rptr-1);
+#endif
                 if (found == num)
                 {
                     if (start_tag)
                     {
                         *len = new-ret-1;
-#if 0
-                        if (cdata == ret)
-                        {
-                            ret += 9;          /* ![CDATA[[     */
-                            *len -= 12;                /* ![CDATA[[ ]]> */
-                        }
-#endif
                         open_element = start_tag;
                         cdata = (char *)start;
                         start_tag = 0;
@@ -1652,8 +1705,8 @@ __xmlProcessCDATA(char **start, size_t *len)
         new = __xmlCommentSkip(cur, restlen);
         if (new)
         {
-            *start += 3;                               /* !-- */
-            *len = (*start-cur)-3;                     /* --> */
+            *start = new;
+            *len = 0;
         }
         return new;
     }
@@ -1675,7 +1728,7 @@ __xmlProcessCDATA(char **start, size_t *len)
             {
                 if ((restlen > 3) && (memcmp(new, "]]>", 3) == 0))
                 {
-                    *len = new-*start;
+                    *len = new-1 - *start;
                     restlen -= 3;
                     new += 3;
                     break;
@@ -1713,14 +1766,15 @@ __xmlCommentSkip(const char *start, size_t len)
             new = memchr(cur, '-', len);
             if (new)
             {
-                len -= new - cur;
+                len -= new-cur;
                 if ((len >= 3) && (memcmp(new, "-->", 3) == 0))
                 {
                     new += 3;
-                    len -= 3;
+                    /* len -= 3; */
                     break;
                 }
                 cur = new+1;
+                len -= cur-new;
             }
             else break;
         }
@@ -1754,15 +1808,20 @@ __xmlInfoProcess(const char *start, size_t len)
 }
 
 
-static void __xmlPrepareData(char **start, size_t *blocklen)
+static void
+__xmlPrepareData(char **start, size_t *blocklen)
 {
     size_t len = *blocklen;
     char *pe, *ps = *start;
 
-    pe = ps + len;
-    while ((ps<pe) && isspace(*ps)) ps++;
-    while ((pe>ps) && isspace(*pe)) pe--;
-    len = (pe-ps);
+    if (len > 1)
+    {
+        pe = ps + len-1;
+        while ((ps<pe) && isspace(*ps)) ps++;
+        while ((pe>ps) && isspace(*pe)) pe--;
+        len = (pe-ps)+1;
+    }
+    else if (isspace(*(ps+1))) len--;
 
     /* CDATA or comment */
     if ((len >= 2) && !strncmp(ps, "<!", 2))
@@ -1771,11 +1830,10 @@ static void __xmlPrepareData(char **start, size_t *blocklen)
         size_t blocklen = len-1;
         if (blocklen >= 6)                  /* !-- --> */
         {
-            char *new = __xmlProcessCDATA(&start, &blocklen);
+            char *new = __xmlProcessCDATA(&start, &len);
             if (new)
             {
                 ps = start;
-                len = blocklen;
                 pe = ps + len;
 
                 while ((ps<pe) && isspace(*ps)) ps++;