diff --git a/utils/xmlgrep/ChangeLog b/utils/xmlgrep/ChangeLog index f4dd02d6a..0b24f5ee5 100644 --- a/utils/xmlgrep/ChangeLog +++ b/utils/xmlgrep/ChangeLog @@ -1,3 +1,10 @@ +18-04-2009 + * Make the code compiler correctly under windows + * Introduce a root-node that can hold extra information which is necessary + for thread safety under windows + * Add xmlErrorGetString, xmlErrorGetLineNo for syntax error detetction + * Add xmlErrGetNo for detection of, and clearing the last error + 16-04-2008 * Rename xmlGetNode functions to xmlNodeGet for better consistancy * likewise for xmlCopyNode en xmlCompareNode diff --git a/utils/xmlgrep/README b/utils/xmlgrep/README index 74cb6afd9..f2027636a 100644 --- a/utils/xmlgrep/README +++ b/utils/xmlgrep/README @@ -127,3 +127,15 @@ double xmlAttributeGetDouble(const void *, const char *); char *xmlAttributeGetString(const void *, const char *); size_t xmlAttributeCopyString(const void *, const char *, const char *, size_t); int xmlAttributeCompareString(const void *, const char *, const char *); + +# +# Error detection and reporting functions +# +# char *err_str = xmlErrorGetString(id); +# size_t err_lineno = xmlErrorGetLineNo(id); +# int err = xmlErrorGetNo(id); /* clear last error */ +# if (err) printf("Error #%i at line #%u: '%s'\n", err, err_lineno, err_str); +# +int xmlErrorGetNo(const void *); +size_t xmlErrorGetLineNo(const void *); +const char *xmlErrorGetString(const void *); diff --git a/utils/xmlgrep/xml.c b/utils/xmlgrep/xml.c index 760952e8a..7c3386d06 100644 --- a/utils/xmlgrep/xml.c +++ b/utils/xmlgrep/xml.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2007, 2008 by Adalin B.V. - * Copyright (c) 2007, 2008 by Erik Hofman +/* Copyright (c) 2007-2009 by Adalin B.V. + * Copyright (c) 2007-2009 by Erik Hofman * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,70 +26,115 @@ */ #ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include +# define WIN32_LEAN_AND_MEAN +# include +# include typedef struct { - HANDLE m; - void *p; + HANDLE m; + void *p; } SIMPLE_UNMMAP; -static SIMPLE_UNMMAP un; - -/* - * map 'filename' and return a pointer to it. - */ -static void *simple_mmap(int, size_t, SIMPLE_UNMMAP *); -static void simple_unmmap(SIMPLE_UNMMAP *); - -# define mmap(a,b,c,d,e,f) simple_mmap((e), (b), &un) -# define munmap(a,b) simple_unmmap(&un) - -# include -# include - #else /* !WIN32 */ # include # include #endif -# include +#ifndef NDEBUG +# include +#endif +#include +#include /* free, malloc */ +#include #include #include #include #include -#include #ifndef _MSC_VER -# include /* strncasecmp */ +# include /* strncasecmp */ #else # define strncasecmp strnicmp #endif -#ifndef NDEBUG -#include + +enum +{ + XML_NO_ERROR = 0, + XML_OUT_OF_MEMORY, + XML_FILE_NOT_FOUND, + XML_TRUNCATE_RESULT, + XML_ELEMENT_NO_OPENING_TAG, + XML_ELEMENT_NO_CLOSING_TAG, + XML_ATTRIB_NO_OPENING_QUOTE, + XML_ATTRIB_NO_CLOSING_QUOTE, + XML_MAX_ERROR +}; +static const char *__xml_error_str[XML_MAX_ERROR]; + +#ifndef XML_NONVALIDATING +struct _xml_error +{ + char *pos; + int errno; +}; + +static void __xmlErrorSet(const void *, const char *, unsigned int); +# define xmlErrorSet(a, b, c) __xmlErrorSet(a, b, c) +#else /* !XML_NONVALIDATING */ +# define xmlErrorSet(a, b, c) #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 { - size_t len; - char *start; char *name; - union { - size_t name_len; - int fd; - } node; + 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 *__xmlCommentSkip(const char *, size_t); -static char *__xmlInfoSkip(const char *, size_t); +static char *__xmlInfoProcess(const char *, size_t); static void *__xml_memncasecmp(const char *, size_t *, char **, size_t *); -#define PRINT(a, b, c) { \ +#ifdef WIN32 +/* + * map 'filename' and return a pointer to it. + */ +static void *simple_mmap(int, size_t, SIMPLE_UNMMAP *); +static void simple_unmmap(SIMPLE_UNMMAP *); + +# define mmap(a,b,c,d,e,f) simple_mmap((e), (b), &rid->un) +# define munmap(a,b) simple_unmmap(&rid->un) +#endif + +#ifndef NDEBUG +# define PRINT(a, b, c) { \ if (a) { \ size_t q, len = c; \ if (b < c) len = b; \ @@ -100,111 +145,126 @@ static void *__xml_memncasecmp(const char *, size_t *, char **, size_t *); } else printf("Length (%u) seems too large at line %i\n",len, __LINE__); \ } else printf("NULL pointer at line %i\n", __LINE__); \ } +#endif void * xmlOpen(const char *filename) { - struct _xml_id *id = 0; + struct _root_id *rid = 0; if (filename) { int fd = open(filename, O_RDONLY); if (fd > 0) { - id = malloc(sizeof(struct _xml_id)); - if (id) + rid = malloc(sizeof(struct _root_id)); + if (rid) { struct stat statbuf; fstat(fd, &statbuf); - id->node.fd = fd; - id->len = statbuf.st_size; - id->start = mmap(0, id->len, PROT_READ, MAP_PRIVATE, fd, 0L); - id->name = 0; + rid->fd = fd; + rid->len = statbuf.st_size; + rid->start = mmap(0, rid->len, PROT_READ, MAP_PRIVATE, fd, 0L); + rid->name = 0; +#ifndef XML_NONVALIDATING + rid->info = 0; + __xmlErrorSet(rid, 0, 0); +#endif } } } - return (void *)id; + return (void *)rid; } void xmlClose(void *id) { - if (id) - { - struct _xml_id *xid = (struct _xml_id *)id; - assert(xid->name == 0); + struct _root_id *rid = (struct _root_id *)id; - munmap(xid->start, xid->len); - close(xid->node.fd); - free(id); - id = 0; - } + assert(rid != 0); + assert(rid->name == 0); + + munmap(rid->start, rid->len); + close(rid->fd); + free(id); + id = 0; } void * xmlNodeGet(const void *id, const char *path) { - struct _xml_id *xsid = 0; + struct _xml_id *xid = (struct _xml_id *)id; + struct _xml_id *xsid = 0; + size_t len, slen; + char *ptr, *node; - if (id && path) - { - struct _xml_id *xid = (struct _xml_id *)id; - size_t len, slen; - char *ptr, *node; + assert(id != 0); + assert(path != 0); - node = (char *)path; - len = xid->len; - slen = strlen(path); - ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen); - if (ptr) - { - xsid = malloc(sizeof(struct _xml_id)); - if (xsid) - { + node = (char *)path; + len = xid->len; + slen = strlen(path); + ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen); + if (ptr) + { + xsid = malloc(sizeof(struct _xml_id)); + if (xsid) + { xsid->len = len; xsid->start = ptr; - xsid->node.name_len = slen; + xsid->name_len = slen; xsid->name = node; - } - } - } +#ifndef XML_NONVALIDATING + if (xid->name) + xsid->root = xid->root; + else + xsid->root = (struct _root_id *)xid; +#endif + } + else + xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY); + } - return (void *)xsid; + return (void *)xsid; } void * xmlNodeCopy(const void *id, const char *path) { + struct _xml_id *xid = (struct _xml_id *)id; struct _xml_id *xsid = 0; + char *ptr, *node, *p; + size_t slen, len; - if (id && path) + node = (char *)path; + len = xid->len; + slen = strlen(path); + ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen); + if (ptr) { - struct _xml_id *xid = (struct _xml_id *)id; - char *ptr, *node, *p; - size_t slen, len; - - node = (char *)path; - len = xid->len; - slen = strlen(path); - ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen); - if (ptr) + xsid = malloc(sizeof(struct _xml_id) + len); + if (xsid) { - xsid = malloc(sizeof(struct _xml_id) + len); - if (xsid) - { - p = (char *)xsid + sizeof(struct _xml_id); + p = (char *)xsid + sizeof(struct _xml_id); - xsid->len = len; - xsid->start = p; - xsid->node.name_len = slen; - xsid->name = node; + xsid->len = len; + xsid->start = p; + xsid->name_len = slen; + xsid->name = node; +#ifndef XML_NONVALIDATING + if (xid->name) + xsid->root = xid->root; + else + xsid->root = (struct _root_id *)xid; +#endif - memcpy(xsid->start, ptr, len); - } - } + memcpy(xsid->start, ptr, len); + } + else + xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY); } return (void *)xsid; @@ -217,30 +277,38 @@ xmlNodeGetName(const void *id) size_t len; char *ret; - len = xid->node.name_len; + assert(xid != 0); + + len = xid->name_len; ret = malloc(len+1); if (ret) { memcpy(ret, xid->name, len); *(ret + len) = 0; } + else + xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY); return ret; } size_t -xmlNodeCopyName(const void *id, char *buf, size_t len) +xmlNodeCopyName(const void *id, char *buf, size_t buflen) { struct _xml_id *xid = (struct _xml_id *)id; size_t slen = 0; - if (buf) + assert(buf != 0); + assert(buflen > 0); + + slen = buflen-1; + if (slen > xid->name_len) { - slen = len-1; - if (slen > xid->node.name_len) slen = xid->node.name_len; - memcpy(buf, xid->name, slen); - *(buf + slen) = 0; + slen = xid->name_len; + xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT); } + memcpy(buf, xid->name, slen); + *(buf + slen) = 0; return slen; } @@ -251,7 +319,10 @@ xmlNodeGetNum(const void *id, const char *path) struct _xml_id *xid = (struct _xml_id *)id; size_t num = 0; - if (xid && xid->len && path) + assert(xid != 0); + assert(path != 0); + + if (xid->len) { char *nodename, *pathname; size_t len, slen; @@ -291,27 +362,27 @@ xmlNodeGetNum(const void *id, const char *path) void * xmlNodeGetPos(const void *pid, void *id, const char *element, size_t num) { + struct _xml_id *xpid = (struct _xml_id *)pid; + struct _xml_id *xid = (struct _xml_id *)id; + size_t len, slen; + char *ptr, *node; void *ret = 0; - if (pid && element) - { - struct _xml_id *xpid = (struct _xml_id *)pid; - struct _xml_id *xid = (struct _xml_id *)id; - size_t len, slen; - char *ptr, *node; + assert(xpid != 0); + assert(xid != 0); + assert(element != 0); - len = xpid->len; - slen = strlen(element); - node = (char *)element; - ptr = __xmlNodeGet(xpid->start, &len, &node, &slen, &num); - if (ptr) - { - xid->len = len; - xid->start = ptr; - xid->name = node; - xid->node.name_len = slen; - ret = xid; - } + len = xpid->len; + slen = strlen(element); + node = (char *)element; + ptr = __xmlNodeGet(xpid->start, &len, &node, &slen, &num); + if (ptr) + { + xid->len = len; + xid->start = ptr; + xid->name = node; + xid->name_len = slen; + ret = xid; } return ret; @@ -323,7 +394,9 @@ xmlGetString(const void *id) struct _xml_id *xid = (struct _xml_id *)id; char *str = 0; - if (xid && xid->len) + assert(xid != 0); + + if (xid->len) { char *ps, *pe, *pend; int nlen; @@ -344,6 +417,8 @@ xmlGetString(const void *id) memcpy(str, ps, nlen); *(str+nlen) = 0; } + else + xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY); } } @@ -355,8 +430,12 @@ xmlCopyString(const void *id, char *buffer, size_t buflen) { struct _xml_id *xid = (struct _xml_id *)id; size_t ret = 0; + + assert(xid != 0); + assert(buffer != 0); + assert(buflen > 0); - if (xid && xid->len && buffer && buflen) + if (xid->len) { char *ps, *pe, *pend; size_t slen, nlen; @@ -375,7 +454,11 @@ xmlCopyString(const void *id, char *buffer, size_t buflen) if (nlen) { - if (nlen >= buflen) nlen = buflen-1; + if (nlen >= buflen) + { + nlen = buflen-1; + xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT); + } memcpy(buffer, ps, nlen); *(buffer+nlen) = 0; ret = nlen; @@ -391,7 +474,10 @@ xmlCompareString(const void *id, const char *s) struct _xml_id *xid = (struct _xml_id *)id; int ret = -1; - if (xid && xid->len && s && (strlen(s) > 0)) + assert(xid != 0); + assert(s != 0); + + if (xid->len && (strlen(s) > 0)) { char *ps, *pe; @@ -415,7 +501,10 @@ xmlNodeGetString(const void *id, const char *path) struct _xml_id *xid = (struct _xml_id *)id; char *str = 0; - if (xid && xid->len && path) + assert(xid != 0); + assert(path != 0); + + if (xid->len) { str = __xmlNodeCopy(xid->start, xid->len, path); if (str) @@ -447,7 +536,12 @@ xmlNodeCopyString(const void *id, const char *path, char *buffer, size_t buflen) struct _xml_id *xid = (struct _xml_id *)id; size_t ret = 0; - if (xid && xid->len && path && buffer && buflen) + assert(xid != 0); + assert(path != 0); + assert(buffer != 0); + assert(buflen > 0); + + if (xid->len) { char *str, *node; size_t slen, nlen; @@ -468,7 +562,11 @@ xmlNodeCopyString(const void *id, const char *path, char *buffer, size_t buflen) while ((pe>ps) && isspace(*pe)) pe--; nlen = (pe-ps)+1; - if (nlen >= buflen) nlen = buflen-1; + if (nlen >= buflen) + { + nlen = buflen-1; + xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT); + } memcpy(buffer, ps, nlen); *(buffer + nlen) = '\0'; @@ -485,7 +583,11 @@ xmlNodeCompareString(const void *id, const char *path, const char *s) struct _xml_id *xid = (struct _xml_id *)id; int ret = -1; - if (xid && xid->len && path && s && (strlen(s) > 0)) + assert(xid != 0); + assert(path != 0); + assert(s != 0); + + if (xid->len && (strlen(s) > 0)) { char *node, *str, *ps, *pe; size_t len, slen; @@ -517,7 +619,9 @@ xmlGetInt(const void *id) struct _xml_id *xid = (struct _xml_id *)id; long int li = 0; - if (xid && xid->len) + assert(xid != 0); + + if (xid->len) { char *end = xid->start + xid->len; li = strtol(xid->start, &end, 10); @@ -532,7 +636,10 @@ xmlNodeGetInt(const void *id, const char *path) struct _xml_id *xid = (struct _xml_id *)id; long int li = 0; - if (path && xid && xid->len) + assert(xid != 0); + assert(path != 0); + + if (xid->len) { size_t len, slen; char *str, *node; @@ -557,7 +664,9 @@ xmlGetDouble(const void *id) struct _xml_id *xid = (struct _xml_id *)id; double d = 0.0; - if (xid && xid->len) + assert(xid != 0); + + if (xid->len) { char *end = xid->start + xid->len; d = strtod(xid->start, &end); @@ -572,7 +681,10 @@ xmlNodeGetDouble(const void *id, const char *path) struct _xml_id *xid = (struct _xml_id *)id; double d = 0.0; - if (path && xid && xid->len) + assert(xid != 0); + assert(path != 0); + + if (xid->len) { size_t len, slen; char *str, *node; @@ -594,294 +706,506 @@ xmlNodeGetDouble(const void *id, const char *path) void * xmlMarkId(const void *id) { - struct _xml_id *xmid = 0; + struct _xml_id *xmid = 0; - if (id) - { - xmid = malloc(sizeof(struct _xml_id)); - if (xmid) - { - memcpy(xmid, id, sizeof(struct _xml_id)); - } - } + assert(id != 0); - return (void *)xmid; + xmid = malloc(sizeof(struct _xml_id)); + if (xmid) + { + struct _root_id *xrid = (struct _root_id *)id; + if (xrid->name == 0) + { + xmid->name = ""; + xmid->start = xrid->start; + xmid->len = xrid->len; + xmid->name_len = 0; +#ifndef XML_NONVALIDATING + xmid->root = xrid; +#endif + } + else + { + struct _xml_id *xid = (struct _xml_id *)id; + + xmid->name = xid->name; + xmid->start = xid->start; + xmid->len = xid->len; + xmid->name_len = xid->name_len; +#ifndef XML_NONVALIDATING + xmid->root = xid->root; +#endif + } + } + else + xmlErrorSet(id, 0, XML_OUT_OF_MEMORY); + + return (void *)xmid; } double xmlAttributeGetDouble(const void *id, const char *name) { - struct _xml_id *xid = (struct _xml_id *)id; - double ret = 0.0; + struct _xml_id *xid = (struct _xml_id *)id; + double ret = 0.0; - if (xid && xid->start && xid->len && xid->node.name_len) - { - char *p, *end, *new = 0; + assert(xid != 0); + assert(name != 0); - assert(xid->start > xid->name); + if (xid->len && xid->name_len) + { + char *ps, *pe; - p = xid->name + xid->node.name_len; - end = xid->start-1; + assert(xid->start > xid->name); - while ((pname + xid->name_len + 1; + pe = xid->start - 1; - new = __xml_memncasecmp(p, &restlen, &element, &elementlen); - if (new) - { - restlen = end-p; - new = memchr(p, '=', restlen); - if (new) - { - new++; - if (*new == '"') new++; - restlen -= (new-p); - end = new+restlen; - ret = strtod(new, &end); - } - break; - } + while ((ps slen) && (strncasecmp(ps, name, slen) == 0)) + { + ps += slen; + if ((psstart && xid->len && xid->node.name_len) - { - char *p, *end, *new = 0; + assert(xid != 0); + assert(name != 0); - assert(xid->start > xid->name); + if (xid->len && xid->name_len) + { + char *ps, *pe; - p = xid->name + xid->node.name_len; - end = xid->start-1; + assert(xid->start > xid->name); - while ((pname + xid->name_len + 1; + pe = xid->start - 1; - new = __xml_memncasecmp(p, &restlen, &element, &elementlen); - if (new) - { - restlen = end-p; - new = memchr(p, '=', restlen); - if (new) - { - new++; - if (*new == '"') new++; - restlen -= (new-p); - end = new+restlen; - ret = strtol(new, &end, 10); - } - break; - } + while ((ps slen) && (strncasecmp(ps, name, slen) == 0)) + { + ps += slen; + if ((psstart && xid->len && xid->node.name_len) - { - char *p, *end, *new = 0; + assert(xid != 0); + assert(name != 0); - assert(xid->start > xid->name); + if (xid->len && xid->name_len) + { + char *ps, *pe; - p = xid->name + xid->node.name_len; - end = xid->start-1; + assert(xid->start > xid->name); - while ((pname + xid->name_len + 1; + pe = xid->start - 1; - new = __xml_memncasecmp(p, &restlen, &element, &elementlen); - if (new) - { - restlen = end-p; - new = memchr(p, '=', restlen); - if (new) + while ((ps slen) && (strncasecmp(ps, name, slen) == 0)) { - new++; - if (*new == '"') new++; - p = new; - while ((pstart && xid->len && xid->node.name_len - && buffer && buflen) - { - char *ps, *pe; + assert(xid != 0); + assert(name != 0); + assert(buffer != 0); + assert(buflen > 0); - *buffer = '\0'; - ps = xid->name + xid->node.name_len + 1; - pe = xid->start - 1; + if (xid->len && xid->name_len) + { + char *ps, *pe; - assert((int)(pe-ps) > 0); + assert(xid->start > xid->name); - while ((psname + xid->name_len + 1; + pe = xid->start - 1; - if ((restlen >= slen) && (strncasecmp(ps, name, slen) == 0)) - { - char *new; + while ((ps slen) && (strncasecmp(ps, name, slen) == 0)) + { + ps += slen; + if ((ps= buflen) + { + restlen = buflen-1; + xmlErrorSet(xid, ps, XML_TRUNCATE_RESULT); + } + + memcpy(buffer, start, restlen); + *(buffer+restlen) = 0; + ret = restlen; + } + else + { + xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE); + return 0; + } } - } - break; - } + break; + } - while ((psstart && xid->len && xid->node.name_len - && s && strlen(s)) - { - char *ps, *pe; + if (xid->len && xid->name_len && strlen(s)) + { + char *ps, *pe; - ps = xid->name + xid->node.name_len + 1; - pe = xid->start - 1; + assert(xid->start > xid->name); - assert((int)(pe-ps) > 0); + ps = xid->name + xid->name_len + 1; + pe = xid->start - 1; - while ((ps= slen) && (strncasecmp(ps, name, slen) == 0)) - { - char *new; - - restlen = pe-ps; - new = memchr(ps, '=', restlen); - if (new) - { - new++; - if (*new == '"') new++; - ps = new; - while ((ps slen) && (strncasecmp(ps, name, slen) == 0)) + { + ps += slen; + if ((psname) rid = xid->root; + else rid = (struct _root_id *)xid; + + assert(rid != 0); + + if (rid->info) + { + struct _xml_error *err = rid->info; + + ret = err->errno; + err->errno = 0; + } + } + + return ret; +} + +size_t +xmlErrorGetLineNo(const void *id) +{ + size_t ret = 0; + + if (id) + { + struct _xml_id *xid = (struct _xml_id *)id; + struct _root_id *rid; + + if (xid->name) rid = xid->root; + else rid = (struct _root_id *)xid; + + assert(rid != 0); + + if (rid->info) + { + struct _xml_error *err = rid->info; + char *ps = rid->start; + char *pe = err->pos; + char *new; + + while (psname) rid = xid->root; + else rid = (struct _root_id *)xid; + + assert(rid != 0); + + if (rid->info) + { + struct _xml_error *err = rid->info; + if (XML_NO_ERROR <= err->errno && err->errno < XML_MAX_ERROR) + ret = (char *)__xml_error_str[err->errno]; + else + ret = "incorrect error number."; + } + } + + return ret; +} +#endif + /* -------------------------------------------------------------------------- */ -static char * +static const char *__xml_error_str[XML_MAX_ERROR] = +{ + "no error.", + "unable to allocate enough memory.", + "unable to open file for reading.", + "provided buffer us too small to hold the result, truncating.", + "incompatible opening tag for element.", + "missing or invalid closing tag for element.", + "missing or invalid opening quote for attribute.", + "missing or invalid closing quote for attribute." +}; + +char * __xmlNodeCopy(const char *start, size_t len, const char *path) { - char *node, *p, *ret = 0; - size_t rlen, slen; + 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 = calloc(1, rlen+1); - memcpy(ret, p, rlen); - } + 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+1) = '\0'; + } + else + xmlErrorSet(0, 0, XML_OUT_OF_MEMORY); + } - return ret; + return ret; } char * @@ -917,8 +1241,8 @@ __xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *plen) ret = __xmlNodeGet(start, len, &node, &plen, &num); if (ret && path) { - plen = slen - (path - *name); - ret = __xmlNodeGetPath(ret, len, &path, &plen); + plen = slen - (path - *name); + ret = __xmlNodeGetPath(ret, len, &path, &plen); } *name = path; @@ -974,7 +1298,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t * } else if (*cur == '?') { - new = __xmlInfoSkip(cur, restlen); + new = __xmlInfoProcess(cur, restlen); if (!new) return 0; restlen -= new-cur; @@ -1099,7 +1423,7 @@ __xmlCommentSkip(const char *start, size_t len) } char * -__xmlInfoSkip(const char *start, size_t len) +__xmlInfoProcess(const char *start, size_t len) { char *cur, *new; @@ -1183,6 +1507,33 @@ __xml_memncasecmp(const char *haystack, size_t *haystacklen, return rptr; } +#ifndef XML_NONVALIDATING +void +__xmlErrorSet(const void *id, const char *pos, unsigned int errno) +{ + struct _xml_id *xid = (struct _xml_id *)id; + struct _root_id *rid; + + assert(xid != 0); + + if (xid->name) rid = xid->root; + else rid = (struct _root_id *)xid; + + assert(rid != 0); + + if (rid->info == 0) + rid->info = malloc(sizeof(struct _xml_error)); + + if (rid->info) + { + struct _xml_error *err = rid->info; + + err->pos = (char *)pos; + err->errno = errno; + } +} +#endif + #ifdef WIN32 /* Source: * https://mollyrocket.com/forums/viewtopic.php?p=2529 @@ -1220,7 +1571,7 @@ simple_mmap(int fd, size_t length, SIMPLE_UNMMAP *un) void simple_unmmap(SIMPLE_UNMMAP *un) { - UnmapViewOfFile(un->p); - CloseHandle(un->m); + UnmapViewOfFile(un->p); + CloseHandle(un->m); } #endif diff --git a/utils/xmlgrep/xml.h b/utils/xmlgrep/xml.h index d9829d83a..06f073a45 100644 --- a/utils/xmlgrep/xml.h +++ b/utils/xmlgrep/xml.h @@ -223,6 +223,7 @@ char *xmlAttributeGetString(const void *, const char *); * @param buffer the buffer to copy the string to * @param buflen length of the destination buffer * @return the length of the string + */ size_t xmlAttributeCopyString(const void *, const char *, const char *, size_t); /** @@ -235,7 +236,6 @@ size_t xmlAttributeCopyString(const void *, const char *, const char *, size_t); * @return an integer less than, equal to, ro greater than zero if the value * of the node is found, respectively, to be less than, to match, or be greater * than str - */ int xmlAttributeCompareString(const void *, const char *, const char *); @@ -283,7 +283,6 @@ double xmlGetDouble(const void *); */ double xmlNodeGetDouble(const void *, const char *); - /** * Get the double value from the named attribute. * @@ -293,5 +292,32 @@ double xmlNodeGetDouble(const void *, const char *); */ double xmlAttributeGetDouble(const void *, const char *); + +#ifndef XML_NONVALIDATING +/** + * Get the error number of the last error and clear it. + * + * @param xid XML-id + * @return the numer of the last error, 0 means no error detected. + */ +int xmlErrorGetNo(const void *); + +/** + * Get the line number of the last detected syntax error in the xml file. + * + * @param xid XML-id + * @return the line number of the detected syntax error. + */ +size_t xmlErrorGetLineNo(const void *); + +/** + * Get a string that explains the last error. + * + * @param xid XML-id + * @return a string that explains the last error. + */ +const char *xmlErrorGetString(const void *); +#endif + #endif /* __XML_CONFIG */ diff --git a/utils/xmlgrep/xmlgrep.c b/utils/xmlgrep/xmlgrep.c index 532db40dd..074d4cc72 100644 --- a/utils/xmlgrep/xmlgrep.c +++ b/utils/xmlgrep/xmlgrep.c @@ -1,6 +1,7 @@ #include #define _GNU_SOURCE +#include #include #ifndef _MSC_VER # include @@ -311,7 +312,16 @@ void grep_file(unsigned num) if (xid) { void *xrid = xmlMarkId(xid); + size_t n = 0; + char *s = 0; + int r = 0; walk_the_tree(num, xrid, _root); + + s = xmlErrorGetString(xrid); + n = xmlErrorGetLineNo(xrid); + r = xmlErrorGetNo(xrid); + if (r) printf("Error #%i at line #%u: '%s'\n", r, n, s); + free(xrid); } else