diff --git a/utils/xmlgrep/ChangeLog b/utils/xmlgrep/ChangeLog index f935845aa..76fd8fdf0 100644 --- a/utils/xmlgrep/ChangeLog +++ b/utils/xmlgrep/ChangeLog @@ -1,4 +1,10 @@ -20-04-2008 +25-04-2009 + * add support for self-contained tags like + * 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 pass xmlNodeGetPath * fix a problem where attributes or elements starting with the same letter @@ -14,7 +20,7 @@ * Add xmlErrorGetString, xmlErrorGetLineNo for syntax error detetction * Add xmlErrGetNo for detection of, and clearing the last error -16-04-2008 +16-04-2009 * Rename xmlGetNode functions to xmlNodeGet for better consistancy * likewise for xmlCopyNode en xmlCompareNode * add xmlAttributeGetDouble, xmlAttributeGetInt, xmlAttributeGetString diff --git a/utils/xmlgrep/xml.c b/utils/xmlgrep/xml.c index 05e220f48..dee507003 100644 --- a/utils/xmlgrep/xml.c +++ b/utils/xmlgrep/xml.c @@ -151,16 +151,20 @@ xmlOpen(const char *filename) if (rid) { struct stat statbuf; + void *mm; fstat(fd, &statbuf); - - rid->fd = fd; - rid->len = statbuf.st_size; - rid->start = mmap(0, rid->len, PROT_READ, MAP_PRIVATE, fd, 0L); - rid->name = 0; + mm = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0L); + if (mm != (void *)-1) + { + rid->fd = fd; + rid->start = mm; + rid->len = statbuf.st_size; + rid->name = 0; #ifndef XML_NONVALIDATING - rid->info = 0; + rid->info = 0; #endif + } } } } @@ -361,7 +365,6 @@ xmlNodeGetNum(const void *id, const char *path) if (p) { char *ret, *node = nodename; - ret = __xmlNodeGet(p, &len, &node, &slen, &num); if (ret == 0 && slen == 0) { @@ -790,7 +793,7 @@ xmlAttributeGetDouble(const void *id, const char *name) assert(xid != 0); assert(name != 0); - if (xid->len && xid->name_len) + if (xid->name_len) { size_t slen = strlen(name); char *ps, *pe; @@ -854,7 +857,7 @@ xmlAttributeGetInt(const void *id, const char *name) assert(xid != 0); assert(name != 0); - if (xid->len && xid->name_len) + if (xid->name_len) { size_t slen = strlen(name); char *ps, *pe; @@ -918,7 +921,7 @@ xmlAttributeGetString(const void *id, const char *name) assert(xid != 0); assert(name != 0); - if (xid->len && xid->name_len) + if (xid->name_len) { size_t slen = strlen(name); char *ps, *pe; @@ -995,7 +998,7 @@ xmlAttributeCopyString(const void *id, const char *name, assert(buffer != 0); assert(buflen > 0); - if (xid->len && xid->name_len) + if (xid->name_len) { size_t slen = strlen(name); char *ps, *pe; @@ -1070,7 +1073,7 @@ xmlAttributeCompareString(const void *id, const char *name, const char *s) assert(name != 0); assert(s != 0); - if (xid->len && xid->name_len && strlen(s)) + if (xid->name_len && strlen(s)) { size_t slen = strlen(name); 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 *element, *start_tag=0; size_t restlen, elementlen; - size_t retlen = 0; + size_t return_len = 0; int found, num; assert(start != 0); @@ -1360,11 +1363,15 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t * cur = (char *)start; ne = cur + restlen; + /* search for an opening tag */ 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; } @@ -1372,7 +1379,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t * restlen -= new-cur; cur = new; - if (*cur == '!') + if (*cur == '!') /* comment */ { new = __xmlCommentSkip(cur, restlen); if (!new) @@ -1386,7 +1393,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t * cur = new; continue; } - else if (*cur == '?') + else if (*cur == '?') /* info block */ { new = __xmlInfoProcess(cur, restlen); if (!new) @@ -1402,23 +1409,27 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t * continue; } + /* + * get element name and a pointer to after the opening tag + */ element = *name; elementlen = *rlen; - new = __xml_memncasecmp(cur, &restlen, &element, &elementlen); - if (new) + len_remaining = restlen; + new = rptr = __xml_memncasecmp(cur, &restlen, &element, &elementlen); + if (rptr) /* requested element was found */ { - retlen = elementlen; + return_len = elementlen; if (found == num) { - ret = new+1; + ret = new; start_tag = element; *rlen = elementlen; } else start_tag = 0; } - else + else /* different element name was foud */ { - new = cur+elementlen; + new = cur + (len_remaining - restlen); if (new >= ne) { *rlen = 0; @@ -1429,28 +1440,24 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t * element = *name; } - if (*(new-1) == '/') /* e.g. */ + if (*(new-2) == '/') /* e.g. */ { - if (found == num) + cur = new; + if (rptr) { - *len = 0; - *name = start_tag; + if (found == num) + { + *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; } + /* + * get the next xml tag + */ /* restlen -= new-cur; not necessary because of __xml_memncasecmp */ cur = new; 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; cur = new; - if (*(cur+1) != '/') /* new node found */ + if (*(cur+1) != '/') /* cascading tag found */ { char *node = "*"; size_t slen = restlen; size_t nlen = 1; size_t pos = -1; + /* + * recursively walk the xml tree from here + */ new = __xmlNodeGet(cur, &slen, &node, &nlen, &pos); if (!new) { @@ -1487,6 +1497,9 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t * restlen -= slen; cur = new; + /* + * look for the closing tag of the cascading block + */ new = memchr(cur, '<', restlen); if (!new) { @@ -1521,6 +1534,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t * } found++; } + /* else proper closing tag not yet found, continue */ new = memchr(cur, '>', restlen); if (!new) @@ -1538,20 +1552,21 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t * { *rlen = 0; *name = cur; + *len = XML_ELEMENT_NO_CLOSING_TAG; return 0; } } - if ((ret == 0) && (start_tag == 0) && (*rlen > 1)) + if (found == 0) { ret = 0; *rlen = 0; *name = start_tag; - *len = XML_NO_ERROR; /* element not found */ + *len = XML_NO_ERROR; /* element not found, no real error */ } else { - *rlen = retlen; + *rlen = return_len; *nodenum = found; } @@ -1623,7 +1638,7 @@ void * __xml_memncasecmp(const char *haystack, size_t *haystacklen, char **needle, size_t *needlelen) { - void *rptr = 0; + char *rptr = 0; if (haystack && needle && needlelen && (*needlelen > 0) && (*haystacklen >= *needlelen)) @@ -1640,9 +1655,14 @@ __xml_memncasecmp(const char *haystack, size_t *haystacklen, char *he = hs + *haystacklen; while ((hs < he) && !isspace(*hs) && (*hs != '>')) hs++; + if (*(hs-1) == '/') hs--; + *needle = (char *)haystack; *needlelen = hs - haystack; + while ((hs < he) && (*hs != '>')) hs++; + hs++; + rptr = hs; } else @@ -1653,28 +1673,31 @@ __xml_memncasecmp(const char *haystack, size_t *haystacklen, for (i=0; i')) break; + if (isspace(*hs) || (*hs == '/') || (*hs == '>')) break; hs++; ns++; } - if (i != nlen) + if (i == nlen) { - while((hs < he) && !isspace(*hs) && (*hs != '>')) hs++; *needle = (char *)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; *needlelen = hs - haystack; while ((hs < he) && (*hs != '>')) hs++; - - if (!found) *needlelen = hs - haystack; - else rptr = hs; + hs++; } } diff --git a/utils/xmlgrep/xmlgrep.c b/utils/xmlgrep/xmlgrep.c index c541b80ce..8db5bead3 100644 --- a/utils/xmlgrep/xmlgrep.c +++ b/utils/xmlgrep/xmlgrep.c @@ -322,13 +322,9 @@ void grep_file(unsigned num) r = xmlErrorGetNo(xrid, 0); if (r) { - if (r) - { - 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"); + 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); } free(xrid);