* fix a problem where attributes or elements starting with the same letter
sequence could give a false negative result * Add a 'clear' attribute to the xmlErrorGet functions that indicates whether the error should be cleared or not * detect more xml syntax errors
This commit is contained in:
parent
7e3531ef5c
commit
8dec4a987f
5 changed files with 372 additions and 157 deletions
|
@ -1,3 +1,10 @@
|
|||
20-04-2008
|
||||
* fix a problem where attributes or elements starting with the same letter
|
||||
sequence could give a false negative result
|
||||
* Add a 'clear' attribute to the xmlErrorGet functions that indicates whether
|
||||
the error should be cleared or not
|
||||
* detect more xml syntax errors
|
||||
|
||||
18-04-2009
|
||||
* Make the code compiler correctly under windows
|
||||
* Introduce a root-node that can hold extra information which is necessary
|
||||
|
|
|
@ -131,11 +131,11 @@ 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);
|
||||
# char *err_str = xmlErrorGetString(id, 0);
|
||||
# size_t err_lineno = xmlErrorGetLineNo(id, 0);
|
||||
# int err = xmlErrorGetNo(id, 1); /* 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 *);
|
||||
int xmlErrorGetNo(const void *, int);
|
||||
size_t xmlErrorGetLineNo(const void *, int);
|
||||
const char *xmlErrorGetString(const void *, int);
|
||||
|
|
|
@ -57,21 +57,11 @@ typedef struct
|
|||
# define strncasecmp strnicmp
|
||||
#endif
|
||||
|
||||
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
|
||||
};
|
||||
#ifndef XML_NONVALIDATING
|
||||
#include "xml.h"
|
||||
|
||||
static const char *__xml_error_str[XML_MAX_ERROR];
|
||||
|
||||
#ifndef XML_NONVALIDATING
|
||||
struct _xml_error
|
||||
{
|
||||
char *pos;
|
||||
|
@ -114,7 +104,7 @@ struct _xml_id
|
|||
#endif
|
||||
};
|
||||
|
||||
static char *__xmlNodeCopy(const char *, size_t, const char *);
|
||||
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);
|
||||
|
@ -170,7 +160,6 @@ xmlOpen(const char *filename)
|
|||
rid->name = 0;
|
||||
#ifndef XML_NONVALIDATING
|
||||
rid->info = 0;
|
||||
__xmlErrorSet(rid, 0, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +178,9 @@ xmlClose(void *id)
|
|||
|
||||
munmap(rid->start, rid->len);
|
||||
close(rid->fd);
|
||||
free(id);
|
||||
|
||||
if (rid->info) free(rid->info);
|
||||
free(rid);
|
||||
id = 0;
|
||||
}
|
||||
|
||||
|
@ -225,8 +216,14 @@ xmlNodeGet(const void *id, const char *path)
|
|||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
else if (slen == 0)
|
||||
{
|
||||
xmlErrorSet(xid, node, len);
|
||||
}
|
||||
|
||||
return (void *)xsid;
|
||||
}
|
||||
|
@ -264,8 +261,14 @@ xmlNodeCopy(const void *id, const char *path)
|
|||
memcpy(xsid->start, ptr, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
else if (slen == 0)
|
||||
{
|
||||
xmlErrorSet(xid, node, len);
|
||||
}
|
||||
|
||||
return (void *)xsid;
|
||||
}
|
||||
|
@ -287,7 +290,9 @@ xmlNodeGetName(const void *id)
|
|||
*(ret + len) = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -342,6 +347,10 @@ xmlNodeGetNum(const void *id, const char *path)
|
|||
slen -= pathname-nodename;
|
||||
node = pathname;
|
||||
p = __xmlNodeGetPath(xid->start, &len, &node, &slen);
|
||||
if (p == 0 && slen == 0)
|
||||
{
|
||||
xmlErrorSet(xid, node, len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -351,8 +360,14 @@ xmlNodeGetNum(const void *id, const char *path)
|
|||
|
||||
if (p)
|
||||
{
|
||||
char *node = nodename;
|
||||
__xmlNodeGet(p, &len, &node, &slen, &num);
|
||||
char *ret, *node = nodename;
|
||||
|
||||
ret = __xmlNodeGet(p, &len, &node, &slen, &num);
|
||||
if (ret == 0 && slen == 0)
|
||||
{
|
||||
xmlErrorSet(xid, node, len);
|
||||
num = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,6 +399,10 @@ xmlNodeGetPos(const void *pid, void *id, const char *element, size_t num)
|
|||
xid->name_len = slen;
|
||||
ret = xid;
|
||||
}
|
||||
else if (slen == 0)
|
||||
{
|
||||
xmlErrorSet(xpid, node, len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -418,9 +437,11 @@ xmlGetString(const void *id)
|
|||
*(str+nlen) = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
@ -506,7 +527,10 @@ xmlNodeGetString(const void *id, const char *path)
|
|||
|
||||
if (xid->len)
|
||||
{
|
||||
str = __xmlNodeCopy(xid->start, xid->len, path);
|
||||
size_t len = xid->len;
|
||||
char *node = (char *)path;
|
||||
|
||||
str = __xmlNodeCopy(xid->start, &len, &path);
|
||||
if (str)
|
||||
{
|
||||
char *ps, *pe, *pend;
|
||||
|
@ -525,6 +549,10 @@ xmlNodeGetString(const void *id, const char *path)
|
|||
if (slen && (ps>str)) memmove(str, ps, slen);
|
||||
else if (!slen) *str = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(xid, node, len);
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
|
@ -572,6 +600,10 @@ xmlNodeCopyString(const void *id, const char *path, char *buffer, size_t buflen)
|
|||
*(buffer + nlen) = '\0';
|
||||
ret = nlen;
|
||||
}
|
||||
else if (slen == 0)
|
||||
{
|
||||
xmlErrorSet(xid, node, nlen);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -608,6 +640,10 @@ xmlNodeCompareString(const void *id, const char *path, const char *s)
|
|||
|
||||
ret = strncasecmp(ps, s, pe-ps);
|
||||
}
|
||||
else if (slen == 0)
|
||||
{
|
||||
xmlErrorSet(xid, node, len);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -653,6 +689,10 @@ xmlNodeGetInt(const void *id, const char *path)
|
|||
char *end = str+len;
|
||||
li = strtol(str, &end, 10);
|
||||
}
|
||||
else if (slen == 0)
|
||||
{
|
||||
xmlErrorSet(xid, node, len);
|
||||
}
|
||||
}
|
||||
|
||||
return li;
|
||||
|
@ -698,6 +738,10 @@ xmlNodeGetDouble(const void *id, const char *path)
|
|||
char *end = str+len;
|
||||
d = strtod(str, &end);
|
||||
}
|
||||
else if (slen == 0)
|
||||
{
|
||||
xmlErrorSet(xid, node, len);
|
||||
}
|
||||
}
|
||||
|
||||
return d;
|
||||
|
@ -726,19 +770,13 @@ xmlMarkId(const void *id)
|
|||
}
|
||||
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
|
||||
memcpy(xmid, id, sizeof(struct _xml_id));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(id, 0, XML_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return (void *)xmid;
|
||||
}
|
||||
|
@ -754,20 +792,17 @@ xmlAttributeGetDouble(const void *id, const char *name)
|
|||
|
||||
if (xid->len && xid->name_len)
|
||||
{
|
||||
size_t slen = strlen(name);
|
||||
char *ps, *pe;
|
||||
|
||||
assert(xid->start > xid->name);
|
||||
|
||||
ps = xid->name + xid->name_len + 1;
|
||||
pe = xid->start - 1;
|
||||
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
while (ps<pe)
|
||||
{
|
||||
size_t slen = strlen(name);
|
||||
size_t restlen = pe-ps;
|
||||
|
||||
if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
|
||||
{
|
||||
ps += slen;
|
||||
if ((ps<pe) && (*ps == '='))
|
||||
|
@ -785,19 +820,25 @@ xmlAttributeGetDouble(const void *id, const char *name)
|
|||
start = ps;
|
||||
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
|
||||
if (ps<pe)
|
||||
{
|
||||
ret = strtod(start, &ps);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((ps<pe) && !isspace(*ps)) ps++;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
while ((ps<pe) && !isspace(*ps)) ps++;
|
||||
if (ps<pe)
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -815,20 +856,17 @@ xmlAttributeGetInt(const void *id, const char *name)
|
|||
|
||||
if (xid->len && xid->name_len)
|
||||
{
|
||||
size_t slen = strlen(name);
|
||||
char *ps, *pe;
|
||||
|
||||
assert(xid->start > xid->name);
|
||||
|
||||
ps = xid->name + xid->name_len + 1;
|
||||
pe = xid->start - 1;
|
||||
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
while (ps<pe)
|
||||
{
|
||||
size_t slen = strlen(name);
|
||||
size_t restlen = pe-ps;
|
||||
|
||||
if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
|
||||
{
|
||||
ps += slen;
|
||||
if ((ps<pe) && (*ps == '='))
|
||||
|
@ -846,19 +884,25 @@ xmlAttributeGetInt(const void *id, const char *name)
|
|||
start = ps;
|
||||
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
|
||||
if (ps<pe)
|
||||
{
|
||||
ret = strtol(start, &ps, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
while ((ps<pe) && !isspace(*ps)) ps++;
|
||||
if (ps<pe)
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -876,20 +920,17 @@ xmlAttributeGetString(const void *id, const char *name)
|
|||
|
||||
if (xid->len && xid->name_len)
|
||||
{
|
||||
size_t slen = strlen(name);
|
||||
char *ps, *pe;
|
||||
|
||||
assert(xid->start > xid->name);
|
||||
|
||||
ps = xid->name + xid->name_len + 1;
|
||||
pe = xid->start - 1;
|
||||
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
while (ps<pe)
|
||||
{
|
||||
size_t slen = strlen(name);
|
||||
size_t restlen = pe-ps;
|
||||
|
||||
if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
|
||||
{
|
||||
ps += slen;
|
||||
if ((ps<pe) && (*ps == '='))
|
||||
|
@ -915,20 +956,27 @@ xmlAttributeGetString(const void *id, const char *name)
|
|||
*(ret+(ps-start)) = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((ps<pe) && !isspace(*ps)) ps++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
while ((ps<pe) && !isspace(*ps)) ps++;
|
||||
if (ps<pe)
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -949,6 +997,7 @@ xmlAttributeCopyString(const void *id, const char *name,
|
|||
|
||||
if (xid->len && xid->name_len)
|
||||
{
|
||||
size_t slen = strlen(name);
|
||||
char *ps, *pe;
|
||||
|
||||
assert(xid->start > xid->name);
|
||||
|
@ -956,14 +1005,10 @@ xmlAttributeCopyString(const void *id, const char *name,
|
|||
*buffer = '\0';
|
||||
ps = xid->name + xid->name_len + 1;
|
||||
pe = xid->start - 1;
|
||||
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
while (ps<pe)
|
||||
{
|
||||
size_t slen = strlen(name);
|
||||
size_t restlen = pe-ps;
|
||||
|
||||
if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
|
||||
{
|
||||
ps += slen;
|
||||
if ((ps<pe) && (*ps == '='))
|
||||
|
@ -982,7 +1027,7 @@ xmlAttributeCopyString(const void *id, const char *name,
|
|||
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
|
||||
if (ps<pe)
|
||||
{
|
||||
restlen = ps-start;
|
||||
size_t restlen = ps-start;
|
||||
if (restlen >= buflen)
|
||||
{
|
||||
restlen = buflen-1;
|
||||
|
@ -999,12 +1044,16 @@ xmlAttributeCopyString(const void *id, const char *name,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
while ((ps<pe) && !isspace(*ps)) ps++;
|
||||
if (ps<pe)
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1023,20 +1072,17 @@ xmlAttributeCompareString(const void *id, const char *name, const char *s)
|
|||
|
||||
if (xid->len && xid->name_len && strlen(s))
|
||||
{
|
||||
size_t slen = strlen(name);
|
||||
char *ps, *pe;
|
||||
|
||||
assert(xid->start > xid->name);
|
||||
|
||||
ps = xid->name + xid->name_len + 1;
|
||||
pe = xid->start - 1;
|
||||
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
while (ps<pe)
|
||||
{
|
||||
size_t slen = strlen(name);
|
||||
size_t restlen = pe-ps;
|
||||
|
||||
if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
|
||||
{
|
||||
ps += slen;
|
||||
if ((ps<pe) && (*ps == '='))
|
||||
|
@ -1054,19 +1100,25 @@ xmlAttributeCompareString(const void *id, const char *name, const char *s)
|
|||
start = ps;
|
||||
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
|
||||
if (ps<pe)
|
||||
{
|
||||
ret = strncasecmp(start, s, ps-start);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((ps<pe) && !isspace(*ps)) ps++;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
while ((ps<pe) && !isspace(*ps)) ps++;
|
||||
if (ps<pe)
|
||||
while ((ps<pe) && isspace(*ps)) ps++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1076,7 +1128,7 @@ xmlAttributeCompareString(const void *id, const char *name, const char *s)
|
|||
|
||||
#ifndef XML_NONVALIDATING
|
||||
int
|
||||
xmlErrorGetNo(const void *id)
|
||||
xmlErrorGetNo(const void *id, int clear)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -1095,7 +1147,7 @@ xmlErrorGetNo(const void *id)
|
|||
struct _xml_error *err = rid->info;
|
||||
|
||||
ret = err->err_no;
|
||||
err->err_no = 0;
|
||||
if (clear) err->err_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1103,7 +1155,7 @@ xmlErrorGetNo(const void *id)
|
|||
}
|
||||
|
||||
size_t
|
||||
xmlErrorGetLineNo(const void *id)
|
||||
xmlErrorGetLineNo(const void *id, int clear)
|
||||
{
|
||||
size_t ret = 0;
|
||||
|
||||
|
@ -1124,6 +1176,7 @@ xmlErrorGetLineNo(const void *id)
|
|||
char *pe = err->pos;
|
||||
char *new;
|
||||
|
||||
ret++;
|
||||
while (ps<pe)
|
||||
{
|
||||
new = memchr(ps, '\n', pe-ps);
|
||||
|
@ -1134,6 +1187,8 @@ xmlErrorGetLineNo(const void *id)
|
|||
}
|
||||
ps++;
|
||||
}
|
||||
|
||||
if (clear) err->err_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1141,7 +1196,7 @@ xmlErrorGetLineNo(const void *id)
|
|||
}
|
||||
|
||||
const char *
|
||||
xmlErrorGetString(const void *id)
|
||||
xmlErrorGetString(const void *id, int clear)
|
||||
{
|
||||
char *ret = 0;
|
||||
|
||||
|
@ -1159,10 +1214,16 @@ xmlErrorGetString(const void *id)
|
|||
{
|
||||
struct _xml_error *err = rid->info;
|
||||
if (XML_NO_ERROR <= err->err_no && err->err_no < XML_MAX_ERROR)
|
||||
{
|
||||
ret = (char *)__xml_error_str[err->err_no];
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = "incorrect error number.";
|
||||
}
|
||||
|
||||
if (clear) err->err_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -1171,27 +1232,33 @@ xmlErrorGetString(const void *id)
|
|||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef XML_NONVALIDATING
|
||||
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.",
|
||||
"buffer us too small to hold the result, truncating.",
|
||||
"incorrect comment section.",
|
||||
"bad information block.",
|
||||
"unexpected end of xml section (maybe a missing end tag?)",
|
||||
"element not found.",
|
||||
"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."
|
||||
};
|
||||
#endif
|
||||
|
||||
char *
|
||||
__xmlNodeCopy(const char *start, size_t len, const char *path)
|
||||
__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;
|
||||
rlen = *len;
|
||||
slen = strlen(*path);
|
||||
node = (char *)*path;
|
||||
p = __xmlNodeGetPath(start, &rlen, &node, &slen);
|
||||
if (p && rlen)
|
||||
{
|
||||
|
@ -1202,8 +1269,15 @@ __xmlNodeCopy(const char *start, size_t len, const char *path)
|
|||
*(ret+rlen+1) = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlErrorSet(0, 0, XML_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
else if (slen == 0)
|
||||
{
|
||||
*path = node;
|
||||
*len = rlen;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1214,11 +1288,12 @@ __xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *plen)
|
|||
char *node;
|
||||
char *ret = 0;
|
||||
|
||||
assert (start != 0);
|
||||
assert (len != 0);
|
||||
assert (name != 0);
|
||||
assert (*name != 0);
|
||||
assert (plen != 0);
|
||||
assert(start != 0);
|
||||
assert(len != 0);
|
||||
assert(name != 0);
|
||||
assert(*name != 0);
|
||||
assert(plen != 0);
|
||||
assert(*plen != 0);
|
||||
|
||||
if ((*len == 0) || (*plen == 0) || (*plen > *len))
|
||||
return 0;
|
||||
|
@ -1237,16 +1312,22 @@ __xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *plen)
|
|||
if (!path) plen = slen;
|
||||
else plen = path++ - node;
|
||||
|
||||
if (path)
|
||||
{
|
||||
num = 0;
|
||||
ret = __xmlNodeGet(start, len, &node, &plen, &num);
|
||||
if (ret && path)
|
||||
if (ret)
|
||||
{
|
||||
plen = slen - (path - *name);
|
||||
ret = __xmlNodeGetPath(ret, len, &path, &plen);
|
||||
}
|
||||
|
||||
*name = path;
|
||||
}
|
||||
else if (plen == 0)
|
||||
{
|
||||
*name = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1260,15 +1341,22 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
|||
size_t retlen = 0;
|
||||
int found, num;
|
||||
|
||||
assert (start != 0);
|
||||
assert (len != 0);
|
||||
assert (name != 0);
|
||||
assert (*name != 0);
|
||||
assert (rlen != 0);
|
||||
assert (nodenum != 0);
|
||||
assert(start != 0);
|
||||
assert(len != 0);
|
||||
assert(*len != 0);
|
||||
assert(name != 0);
|
||||
assert(*name != 0);
|
||||
assert(rlen != 0);
|
||||
assert(*rlen != 0);
|
||||
assert(nodenum != 0);
|
||||
|
||||
if ((*len == 0) || (*rlen == 0) || (*rlen > *len))
|
||||
if (*rlen > *len)
|
||||
{
|
||||
*rlen = 0;
|
||||
*name = start;
|
||||
*len = XML_UNEXPECTED_EOF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
found = 0;
|
||||
num = *nodenum;
|
||||
|
@ -1291,7 +1379,13 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
|||
if (*cur == '!')
|
||||
{
|
||||
new = __xmlCommentSkip(cur, restlen);
|
||||
if (!new) return 0;
|
||||
if (!new)
|
||||
{
|
||||
*rlen = 0;
|
||||
*name = cur;
|
||||
*len = XML_INVALID_COMMENT;
|
||||
return 0;
|
||||
}
|
||||
restlen -= new-cur;
|
||||
cur = new;
|
||||
continue;
|
||||
|
@ -1299,7 +1393,13 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
|||
else if (*cur == '?')
|
||||
{
|
||||
new = __xmlInfoProcess(cur, restlen);
|
||||
if (!new) return 0;
|
||||
if (!new)
|
||||
{
|
||||
*rlen = 0;
|
||||
*name = cur;
|
||||
*len = XML_INVALID_INFO_BLOCK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
restlen -= new-cur;
|
||||
cur = new;
|
||||
|
@ -1312,24 +1412,59 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
|||
if (new)
|
||||
{
|
||||
retlen = elementlen;
|
||||
if (found == num )
|
||||
if (found == num)
|
||||
{
|
||||
ret = new+1;
|
||||
start_tag = element;
|
||||
*rlen = elementlen;
|
||||
}
|
||||
else start_tag = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
new = cur+elementlen;
|
||||
if (new >= ne) return 0;
|
||||
if (new >= ne)
|
||||
{
|
||||
*rlen = 0;
|
||||
*name = cur;
|
||||
*len = XML_UNEXPECTED_EOF;
|
||||
return 0;
|
||||
}
|
||||
element = *name;
|
||||
}
|
||||
|
||||
if (*(new-1) == '/') /* e.g. <test/> */
|
||||
{
|
||||
if (found == num)
|
||||
{
|
||||
*len = 0;
|
||||
*name = start_tag;
|
||||
}
|
||||
found++;
|
||||
|
||||
if ((restlen < 1) || (*new != '>'))
|
||||
{
|
||||
*rlen = 0;
|
||||
*name = cur;
|
||||
*len = XML_ELEMENT_NO_CLOSING_TAG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
restlen -= new+1-cur;
|
||||
cur = new+1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* restlen -= new-cur; not necessary because of __xml_memncasecmp */
|
||||
cur = new;
|
||||
new = memchr(cur, '<', restlen);
|
||||
if (!new) return 0;
|
||||
if (!new)
|
||||
{
|
||||
*rlen = 0;
|
||||
*name = cur;
|
||||
*len = XML_ELEMENT_NO_CLOSING_TAG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
restlen -= new-cur;
|
||||
cur = new;
|
||||
|
@ -1343,7 +1478,13 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
|||
new = __xmlNodeGet(cur, &slen, &node, &nlen, &pos);
|
||||
if (!new)
|
||||
{
|
||||
if (slen == restlen) return 0;
|
||||
if (slen == restlen)
|
||||
{
|
||||
*rlen = 0;
|
||||
*name = cur;
|
||||
*len = XML_UNEXPECTED_EOF;
|
||||
return 0;
|
||||
}
|
||||
else new = cur + slen;
|
||||
}
|
||||
|
||||
|
@ -1351,7 +1492,13 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
|||
cur = new;
|
||||
|
||||
new = memchr(cur, '<', restlen);
|
||||
if (!new) return 0;
|
||||
if (!new)
|
||||
{
|
||||
*rlen = 0;
|
||||
*name = cur;
|
||||
*len = XML_ELEMENT_NO_CLOSING_TAG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
restlen -= new-cur;
|
||||
cur = new;
|
||||
|
@ -1363,24 +1510,54 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
|||
{
|
||||
if (found == num)
|
||||
{
|
||||
assert(start_tag != 0);
|
||||
if (start_tag)
|
||||
{
|
||||
*len = new-ret;
|
||||
*name = start_tag;
|
||||
}
|
||||
else /* report error */
|
||||
{
|
||||
*rlen = 0;
|
||||
*name = new;
|
||||
*len = XML_ELEMENT_NO_OPENING_TAG;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
found++;
|
||||
}
|
||||
|
||||
new = memchr(cur, '>', restlen);
|
||||
if (!new) return 0;
|
||||
if (!new)
|
||||
{
|
||||
*rlen = 0;
|
||||
*name = cur;
|
||||
*len = XML_ELEMENT_NO_CLOSING_TAG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
restlen -= new-cur;
|
||||
cur = new;
|
||||
}
|
||||
else return 0;
|
||||
else
|
||||
{
|
||||
*rlen = 0;
|
||||
*name = cur;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret == 0) && (start_tag == 0) && (*rlen > 1))
|
||||
{
|
||||
ret = 0;
|
||||
*rlen = 0;
|
||||
*name = start_tag;
|
||||
*len = XML_ELEMENT_NOT_FOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
*rlen = retlen;
|
||||
*nodenum = found;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1395,11 +1572,10 @@ __xmlCommentSkip(const char *start, size_t len)
|
|||
|
||||
if (memcmp(cur, "!--", 3) == 0)
|
||||
{
|
||||
if (len < 6) return 0;
|
||||
if (len < 6) return 0; /* <!-- --> */
|
||||
|
||||
cur += 3;
|
||||
len -= 3;
|
||||
|
||||
do
|
||||
{
|
||||
new = memchr(cur, '-', len);
|
||||
|
@ -1432,7 +1608,7 @@ __xmlInfoProcess(const char *start, size_t len)
|
|||
|
||||
if (*cur == '?')
|
||||
{
|
||||
if (len < 3) return 0;
|
||||
if (len < 3) return 0; /* <? ?> */
|
||||
|
||||
cur++;
|
||||
len--;
|
||||
|
@ -1467,7 +1643,7 @@ __xml_memncasecmp(const char *haystack, size_t *haystacklen,
|
|||
{
|
||||
char *he = hs + *haystacklen;
|
||||
|
||||
while ((hs < he) && (*hs != ' ') && (*hs != '>')) hs++;
|
||||
while ((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
|
||||
*needle = (char *)haystack;
|
||||
*needlelen = hs - haystack;
|
||||
while ((hs < he) && (*hs != '>')) hs++;
|
||||
|
@ -1481,23 +1657,28 @@ __xml_memncasecmp(const char *haystack, size_t *haystacklen,
|
|||
for (i=0; i<nlen; i++)
|
||||
{
|
||||
if (NOCASECMP(*hs,*ns) && (*ns != '?')) break;
|
||||
if ((*hs == ' ') || (*hs == '>')) break;
|
||||
if (isspace(*hs) || (*hs == '>')) break;
|
||||
hs++;
|
||||
ns++;
|
||||
}
|
||||
|
||||
if (i != nlen)
|
||||
{
|
||||
while((hs < he) && (*hs != ' ') && (*hs != '>')) hs++;
|
||||
while((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
|
||||
*needle = (char *)haystack;
|
||||
*needlelen = hs - haystack;
|
||||
}
|
||||
else
|
||||
{
|
||||
int found = (isspace(*hs) || (*hs == '>'));
|
||||
|
||||
*needle = (char *)haystack;
|
||||
*needlelen = hs - haystack;
|
||||
|
||||
while ((hs < he) && (*hs != '>')) hs++;
|
||||
rptr = hs;
|
||||
|
||||
if (!found) *needlelen = hs - haystack;
|
||||
else rptr = hs;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1520,9 +1701,10 @@ __xmlErrorSet(const void *id, const char *pos, unsigned int err_no)
|
|||
else rid = (struct _root_id *)xid;
|
||||
|
||||
assert(rid != 0);
|
||||
|
||||
if (rid->info == 0)
|
||||
{
|
||||
rid->info = malloc(sizeof(struct _xml_error));
|
||||
}
|
||||
|
||||
if (rid->info)
|
||||
{
|
||||
|
|
|
@ -28,6 +28,23 @@
|
|||
#ifndef __XML_CONFIG
|
||||
#define __XML_CONFIG 1
|
||||
|
||||
enum
|
||||
{
|
||||
XML_NO_ERROR = 0,
|
||||
XML_OUT_OF_MEMORY,
|
||||
XML_FILE_NOT_FOUND,
|
||||
XML_TRUNCATE_RESULT,
|
||||
XML_INVALID_COMMENT,
|
||||
XML_INVALID_INFO_BLOCK,
|
||||
XML_UNEXPECTED_EOF,
|
||||
XML_ELEMENT_NOT_FOUND,
|
||||
XML_ELEMENT_NO_OPENING_TAG,
|
||||
XML_ELEMENT_NO_CLOSING_TAG,
|
||||
XML_ATTRIB_NO_OPENING_QUOTE,
|
||||
XML_ATTRIB_NO_CLOSING_QUOTE,
|
||||
XML_MAX_ERROR
|
||||
};
|
||||
|
||||
/**
|
||||
* Open an XML file for processing.
|
||||
*
|
||||
|
@ -128,7 +145,7 @@ unsigned int xmlNodeGetNum(const void *, const char *);
|
|||
* @param num specify which occurence to return
|
||||
* @return XML-subsection-id for further processing or NULL if unsuccessful
|
||||
*/
|
||||
void *xmlNodeGetPos(const void *, void *, const char *, int);
|
||||
void *xmlNodeGetPos(const void *, void *, const char *, size_t);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -224,7 +241,7 @@ char *xmlAttributeGetString(const void *, const char *);
|
|||
* @param buflen length of the destination buffer
|
||||
* @return the length of the string
|
||||
*/
|
||||
size_t xmlAttributeCopyString(const void *, const char *, const char *, size_t);
|
||||
size_t xmlAttributeCopyString(const void *, const char *, char *, size_t);
|
||||
|
||||
/**
|
||||
* Compare the value of an attribute to a reference string.
|
||||
|
@ -299,25 +316,28 @@ double xmlAttributeGetDouble(const void *, const char *);
|
|||
* Get the error number of the last error and clear it.
|
||||
*
|
||||
* @param xid XML-id
|
||||
* @param clear clear the error state if non zero
|
||||
* @return the numer of the last error, 0 means no error detected.
|
||||
*/
|
||||
int xmlErrorGetNo(const void *);
|
||||
int xmlErrorGetNo(const void *, int);
|
||||
|
||||
/**
|
||||
* Get the line number of the last detected syntax error in the xml file.
|
||||
*
|
||||
* @param xid XML-id
|
||||
* @param clear clear the error state if non zero
|
||||
* @return the line number of the detected syntax error.
|
||||
*/
|
||||
size_t xmlErrorGetLineNo(const void *);
|
||||
size_t xmlErrorGetLineNo(const void *, int);
|
||||
|
||||
/**
|
||||
* Get a string that explains the last error.
|
||||
*
|
||||
* @param xid XML-id
|
||||
* @param clear clear the error state if non zero
|
||||
* @return a string that explains the last error.
|
||||
*/
|
||||
const char *xmlErrorGetString(const void *);
|
||||
const char *xmlErrorGetString(const void *, int);
|
||||
#endif
|
||||
|
||||
#endif /* __XML_CONFIG */
|
||||
|
|
|
@ -312,15 +312,21 @@ 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);
|
||||
r = xmlErrorGetNo(xrid, 0);
|
||||
if (r)
|
||||
{
|
||||
if (r == XML_ELEMENT_NOT_FOUND)
|
||||
{
|
||||
size_t n = xmlErrorGetLineNo(xrid, 0);
|
||||
char *s = xmlErrorGetString(xrid, 1); /* clear the error */
|
||||
printf("Error #%i at line %u: '%s'\n", r, n, s);
|
||||
}
|
||||
else printf("requested element was not found.\n");
|
||||
}
|
||||
|
||||
free(xrid);
|
||||
}
|
||||
|
@ -335,7 +341,7 @@ void grep_file(unsigned num)
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
unsigned int i;
|
||||
int i;
|
||||
|
||||
if (argc == 1)
|
||||
show_help();
|
||||
|
|
Loading…
Reference in a new issue