* add support for self-contained tags like <test/>
* fix a problem if a file could not be mmaped * add a few comments which hopefully makes the code easier to understand * code cleanups
This commit is contained in:
parent
1ce2924c28
commit
8862b3e2b3
3 changed files with 86 additions and 61 deletions
|
@ -1,4 +1,10 @@
|
||||||
20-04-2008
|
25-04-2009
|
||||||
|
* add support for self-contained tags like <test/>
|
||||||
|
* fix a problem if a file could not be mmaped
|
||||||
|
* add a few comments which hopefully makes the code easier to understand
|
||||||
|
* code cleanups
|
||||||
|
|
||||||
|
20-04-2009
|
||||||
* fix a case where a single-element root path (e.g. "/printer") would not
|
* fix a case where a single-element root path (e.g. "/printer") would not
|
||||||
pass xmlNodeGetPath
|
pass xmlNodeGetPath
|
||||||
* fix a problem where attributes or elements starting with the same letter
|
* fix a problem where attributes or elements starting with the same letter
|
||||||
|
@ -14,7 +20,7 @@
|
||||||
* Add xmlErrorGetString, xmlErrorGetLineNo for syntax error detetction
|
* Add xmlErrorGetString, xmlErrorGetLineNo for syntax error detetction
|
||||||
* Add xmlErrGetNo for detection of, and clearing the last error
|
* Add xmlErrGetNo for detection of, and clearing the last error
|
||||||
|
|
||||||
16-04-2008
|
16-04-2009
|
||||||
* Rename xmlGetNode functions to xmlNodeGet for better consistancy
|
* Rename xmlGetNode functions to xmlNodeGet for better consistancy
|
||||||
* likewise for xmlCopyNode en xmlCompareNode
|
* likewise for xmlCopyNode en xmlCompareNode
|
||||||
* add xmlAttributeGetDouble, xmlAttributeGetInt, xmlAttributeGetString
|
* add xmlAttributeGetDouble, xmlAttributeGetInt, xmlAttributeGetString
|
||||||
|
|
|
@ -151,16 +151,20 @@ xmlOpen(const char *filename)
|
||||||
if (rid)
|
if (rid)
|
||||||
{
|
{
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
void *mm;
|
||||||
|
|
||||||
fstat(fd, &statbuf);
|
fstat(fd, &statbuf);
|
||||||
|
mm = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0L);
|
||||||
rid->fd = fd;
|
if (mm != (void *)-1)
|
||||||
rid->len = statbuf.st_size;
|
{
|
||||||
rid->start = mmap(0, rid->len, PROT_READ, MAP_PRIVATE, fd, 0L);
|
rid->fd = fd;
|
||||||
rid->name = 0;
|
rid->start = mm;
|
||||||
|
rid->len = statbuf.st_size;
|
||||||
|
rid->name = 0;
|
||||||
#ifndef XML_NONVALIDATING
|
#ifndef XML_NONVALIDATING
|
||||||
rid->info = 0;
|
rid->info = 0;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,7 +365,6 @@ xmlNodeGetNum(const void *id, const char *path)
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
char *ret, *node = nodename;
|
char *ret, *node = nodename;
|
||||||
|
|
||||||
ret = __xmlNodeGet(p, &len, &node, &slen, &num);
|
ret = __xmlNodeGet(p, &len, &node, &slen, &num);
|
||||||
if (ret == 0 && slen == 0)
|
if (ret == 0 && slen == 0)
|
||||||
{
|
{
|
||||||
|
@ -790,7 +793,7 @@ xmlAttributeGetDouble(const void *id, const char *name)
|
||||||
assert(xid != 0);
|
assert(xid != 0);
|
||||||
assert(name != 0);
|
assert(name != 0);
|
||||||
|
|
||||||
if (xid->len && xid->name_len)
|
if (xid->name_len)
|
||||||
{
|
{
|
||||||
size_t slen = strlen(name);
|
size_t slen = strlen(name);
|
||||||
char *ps, *pe;
|
char *ps, *pe;
|
||||||
|
@ -854,7 +857,7 @@ xmlAttributeGetInt(const void *id, const char *name)
|
||||||
assert(xid != 0);
|
assert(xid != 0);
|
||||||
assert(name != 0);
|
assert(name != 0);
|
||||||
|
|
||||||
if (xid->len && xid->name_len)
|
if (xid->name_len)
|
||||||
{
|
{
|
||||||
size_t slen = strlen(name);
|
size_t slen = strlen(name);
|
||||||
char *ps, *pe;
|
char *ps, *pe;
|
||||||
|
@ -918,7 +921,7 @@ xmlAttributeGetString(const void *id, const char *name)
|
||||||
assert(xid != 0);
|
assert(xid != 0);
|
||||||
assert(name != 0);
|
assert(name != 0);
|
||||||
|
|
||||||
if (xid->len && xid->name_len)
|
if (xid->name_len)
|
||||||
{
|
{
|
||||||
size_t slen = strlen(name);
|
size_t slen = strlen(name);
|
||||||
char *ps, *pe;
|
char *ps, *pe;
|
||||||
|
@ -995,7 +998,7 @@ xmlAttributeCopyString(const void *id, const char *name,
|
||||||
assert(buffer != 0);
|
assert(buffer != 0);
|
||||||
assert(buflen > 0);
|
assert(buflen > 0);
|
||||||
|
|
||||||
if (xid->len && xid->name_len)
|
if (xid->name_len)
|
||||||
{
|
{
|
||||||
size_t slen = strlen(name);
|
size_t slen = strlen(name);
|
||||||
char *ps, *pe;
|
char *ps, *pe;
|
||||||
|
@ -1070,7 +1073,7 @@ xmlAttributeCompareString(const void *id, const char *name, const char *s)
|
||||||
assert(name != 0);
|
assert(name != 0);
|
||||||
assert(s != 0);
|
assert(s != 0);
|
||||||
|
|
||||||
if (xid->len && xid->name_len && strlen(s))
|
if (xid->name_len && strlen(s))
|
||||||
{
|
{
|
||||||
size_t slen = strlen(name);
|
size_t slen = strlen(name);
|
||||||
char *ps, *pe;
|
char *ps, *pe;
|
||||||
|
@ -1334,7 +1337,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
char *new, *cur, *ne, *ret = 0;
|
char *new, *cur, *ne, *ret = 0;
|
||||||
char *element, *start_tag=0;
|
char *element, *start_tag=0;
|
||||||
size_t restlen, elementlen;
|
size_t restlen, elementlen;
|
||||||
size_t retlen = 0;
|
size_t return_len = 0;
|
||||||
int found, num;
|
int found, num;
|
||||||
|
|
||||||
assert(start != 0);
|
assert(start != 0);
|
||||||
|
@ -1360,11 +1363,15 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
cur = (char *)start;
|
cur = (char *)start;
|
||||||
ne = cur + restlen;
|
ne = cur + restlen;
|
||||||
|
|
||||||
|
/* search for an opening tag */
|
||||||
while ((new = memchr(cur, '<', restlen)) != 0)
|
while ((new = memchr(cur, '<', restlen)) != 0)
|
||||||
{
|
{
|
||||||
if (*(new+1) == '/') /* cascading closing tag found */
|
size_t len_remaining;
|
||||||
|
char *rptr;
|
||||||
|
|
||||||
|
if (*(new+1) == '/') /* end of section */
|
||||||
{
|
{
|
||||||
*len -= restlen;
|
*len -= restlen-1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1372,7 +1379,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
restlen -= new-cur;
|
restlen -= new-cur;
|
||||||
cur = new;
|
cur = new;
|
||||||
|
|
||||||
if (*cur == '!')
|
if (*cur == '!') /* comment */
|
||||||
{
|
{
|
||||||
new = __xmlCommentSkip(cur, restlen);
|
new = __xmlCommentSkip(cur, restlen);
|
||||||
if (!new)
|
if (!new)
|
||||||
|
@ -1386,7 +1393,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
cur = new;
|
cur = new;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (*cur == '?')
|
else if (*cur == '?') /* info block */
|
||||||
{
|
{
|
||||||
new = __xmlInfoProcess(cur, restlen);
|
new = __xmlInfoProcess(cur, restlen);
|
||||||
if (!new)
|
if (!new)
|
||||||
|
@ -1402,23 +1409,27 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get element name and a pointer to after the opening tag
|
||||||
|
*/
|
||||||
element = *name;
|
element = *name;
|
||||||
elementlen = *rlen;
|
elementlen = *rlen;
|
||||||
new = __xml_memncasecmp(cur, &restlen, &element, &elementlen);
|
len_remaining = restlen;
|
||||||
if (new)
|
new = rptr = __xml_memncasecmp(cur, &restlen, &element, &elementlen);
|
||||||
|
if (rptr) /* requested element was found */
|
||||||
{
|
{
|
||||||
retlen = elementlen;
|
return_len = elementlen;
|
||||||
if (found == num)
|
if (found == num)
|
||||||
{
|
{
|
||||||
ret = new+1;
|
ret = new;
|
||||||
start_tag = element;
|
start_tag = element;
|
||||||
*rlen = elementlen;
|
*rlen = elementlen;
|
||||||
}
|
}
|
||||||
else start_tag = 0;
|
else start_tag = 0;
|
||||||
}
|
}
|
||||||
else
|
else /* different element name was foud */
|
||||||
{
|
{
|
||||||
new = cur+elementlen;
|
new = cur + (len_remaining - restlen);
|
||||||
if (new >= ne)
|
if (new >= ne)
|
||||||
{
|
{
|
||||||
*rlen = 0;
|
*rlen = 0;
|
||||||
|
@ -1429,28 +1440,24 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
element = *name;
|
element = *name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*(new-1) == '/') /* e.g. <test/> */
|
if (*(new-2) == '/') /* e.g. <test/> */
|
||||||
{
|
{
|
||||||
if (found == num)
|
cur = new;
|
||||||
|
if (rptr)
|
||||||
{
|
{
|
||||||
*len = 0;
|
if (found == num)
|
||||||
*name = start_tag;
|
{
|
||||||
|
*name = start_tag;
|
||||||
|
*len = 0;
|
||||||
|
}
|
||||||
|
found++;
|
||||||
}
|
}
|
||||||
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get the next xml tag
|
||||||
|
*/
|
||||||
/* restlen -= new-cur; not necessary because of __xml_memncasecmp */
|
/* restlen -= new-cur; not necessary because of __xml_memncasecmp */
|
||||||
cur = new;
|
cur = new;
|
||||||
new = memchr(cur, '<', restlen);
|
new = memchr(cur, '<', restlen);
|
||||||
|
@ -1464,13 +1471,16 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
|
|
||||||
restlen -= new-cur;
|
restlen -= new-cur;
|
||||||
cur = new;
|
cur = new;
|
||||||
if (*(cur+1) != '/') /* new node found */
|
if (*(cur+1) != '/') /* cascading tag found */
|
||||||
{
|
{
|
||||||
char *node = "*";
|
char *node = "*";
|
||||||
size_t slen = restlen;
|
size_t slen = restlen;
|
||||||
size_t nlen = 1;
|
size_t nlen = 1;
|
||||||
size_t pos = -1;
|
size_t pos = -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* recursively walk the xml tree from here
|
||||||
|
*/
|
||||||
new = __xmlNodeGet(cur, &slen, &node, &nlen, &pos);
|
new = __xmlNodeGet(cur, &slen, &node, &nlen, &pos);
|
||||||
if (!new)
|
if (!new)
|
||||||
{
|
{
|
||||||
|
@ -1487,6 +1497,9 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
restlen -= slen;
|
restlen -= slen;
|
||||||
cur = new;
|
cur = new;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* look for the closing tag of the cascading block
|
||||||
|
*/
|
||||||
new = memchr(cur, '<', restlen);
|
new = memchr(cur, '<', restlen);
|
||||||
if (!new)
|
if (!new)
|
||||||
{
|
{
|
||||||
|
@ -1521,6 +1534,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
}
|
}
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
|
/* else proper closing tag not yet found, continue */
|
||||||
|
|
||||||
new = memchr(cur, '>', restlen);
|
new = memchr(cur, '>', restlen);
|
||||||
if (!new)
|
if (!new)
|
||||||
|
@ -1538,20 +1552,21 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
{
|
{
|
||||||
*rlen = 0;
|
*rlen = 0;
|
||||||
*name = cur;
|
*name = cur;
|
||||||
|
*len = XML_ELEMENT_NO_CLOSING_TAG;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret == 0) && (start_tag == 0) && (*rlen > 1))
|
if (found == 0)
|
||||||
{
|
{
|
||||||
ret = 0;
|
ret = 0;
|
||||||
*rlen = 0;
|
*rlen = 0;
|
||||||
*name = start_tag;
|
*name = start_tag;
|
||||||
*len = XML_NO_ERROR; /* element not found */
|
*len = XML_NO_ERROR; /* element not found, no real error */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*rlen = retlen;
|
*rlen = return_len;
|
||||||
*nodenum = found;
|
*nodenum = found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1623,7 +1638,7 @@ void *
|
||||||
__xml_memncasecmp(const char *haystack, size_t *haystacklen,
|
__xml_memncasecmp(const char *haystack, size_t *haystacklen,
|
||||||
char **needle, size_t *needlelen)
|
char **needle, size_t *needlelen)
|
||||||
{
|
{
|
||||||
void *rptr = 0;
|
char *rptr = 0;
|
||||||
|
|
||||||
if (haystack && needle && needlelen && (*needlelen > 0)
|
if (haystack && needle && needlelen && (*needlelen > 0)
|
||||||
&& (*haystacklen >= *needlelen))
|
&& (*haystacklen >= *needlelen))
|
||||||
|
@ -1640,9 +1655,14 @@ __xml_memncasecmp(const char *haystack, size_t *haystacklen,
|
||||||
char *he = hs + *haystacklen;
|
char *he = hs + *haystacklen;
|
||||||
|
|
||||||
while ((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
|
while ((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
|
||||||
|
if (*(hs-1) == '/') hs--;
|
||||||
|
|
||||||
*needle = (char *)haystack;
|
*needle = (char *)haystack;
|
||||||
*needlelen = hs - haystack;
|
*needlelen = hs - haystack;
|
||||||
|
|
||||||
while ((hs < he) && (*hs != '>')) hs++;
|
while ((hs < he) && (*hs != '>')) hs++;
|
||||||
|
hs++;
|
||||||
|
|
||||||
rptr = hs;
|
rptr = hs;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1653,28 +1673,31 @@ __xml_memncasecmp(const char *haystack, size_t *haystacklen,
|
||||||
for (i=0; i<nlen; i++)
|
for (i=0; i<nlen; i++)
|
||||||
{
|
{
|
||||||
if (NOCASECMP(*hs,*ns) && (*ns != '?')) break;
|
if (NOCASECMP(*hs,*ns) && (*ns != '?')) break;
|
||||||
if (isspace(*hs) || (*hs == '>')) break;
|
if (isspace(*hs) || (*hs == '/') || (*hs == '>')) break;
|
||||||
hs++;
|
hs++;
|
||||||
ns++;
|
ns++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != nlen)
|
if (i == nlen)
|
||||||
{
|
{
|
||||||
while((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
|
|
||||||
*needle = (char *)haystack;
|
*needle = (char *)haystack;
|
||||||
*needlelen = hs - haystack;
|
*needlelen = hs - haystack;
|
||||||
|
|
||||||
|
while ((hs < he) && (*hs != '>')) hs++;
|
||||||
|
hs++;
|
||||||
|
|
||||||
|
rptr = hs;
|
||||||
}
|
}
|
||||||
else
|
else /* not found */
|
||||||
{
|
{
|
||||||
int found = (isspace(*hs) || (*hs == '>'));
|
while((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
|
||||||
|
if (*(hs-1) == '/') hs--;
|
||||||
|
|
||||||
*needle = (char *)haystack;
|
*needle = (char *)haystack;
|
||||||
*needlelen = hs - haystack;
|
*needlelen = hs - haystack;
|
||||||
|
|
||||||
while ((hs < he) && (*hs != '>')) hs++;
|
while ((hs < he) && (*hs != '>')) hs++;
|
||||||
|
hs++;
|
||||||
if (!found) *needlelen = hs - haystack;
|
|
||||||
else rptr = hs;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -322,13 +322,9 @@ void grep_file(unsigned num)
|
||||||
r = xmlErrorGetNo(xrid, 0);
|
r = xmlErrorGetNo(xrid, 0);
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
if (r)
|
size_t n = xmlErrorGetLineNo(xrid, 0);
|
||||||
{
|
char *s = xmlErrorGetString(xrid, 1); /* clear the error */
|
||||||
size_t n = xmlErrorGetLineNo(xrid, 0);
|
printf("Error #%i at line %u: '%s'\n", r, n, s);
|
||||||
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);
|
free(xrid);
|
||||||
|
|
Loading…
Add table
Reference in a new issue