From 8943603ef15519c92fa24cafdb49e21e59e1b8a6 Mon Sep 17 00:00:00 2001 From: ehofman Date: Thu, 16 Apr 2009 19:03:22 +0000 Subject: [PATCH] * Rename xmlGetNode functions to xmlNodeGet for better consistancy * likewise for xmlCopyNode en xmlCompareNode * add xmlAttributeGetDouble, xmlAttributeGetInt, xmlAttributeGetString xmlAttributeCopyString and xmlAttributeCompareString functions * fix some small bugs and problems along the way * add support for filtering on attribute value in xmlgrep --- utils/xmlgrep/ChangeLog | 12 +- utils/xmlgrep/README | 70 ++++--- utils/xmlgrep/xml.c | 452 ++++++++++++++++++++++++++++++---------- utils/xmlgrep/xml.h | 130 ++++++++---- utils/xmlgrep/xmlgrep.c | 127 +++++++---- 5 files changed, 573 insertions(+), 218 deletions(-) diff --git a/utils/xmlgrep/ChangeLog b/utils/xmlgrep/ChangeLog index 73b6864ec..f4dd02d6a 100644 --- a/utils/xmlgrep/ChangeLog +++ b/utils/xmlgrep/ChangeLog @@ -1,3 +1,11 @@ +16-04-2008 + * Rename xmlGetNode functions to xmlNodeGet for better consistancy + * likewise for xmlCopyNode en xmlCompareNode + * add xmlAttributeGetDouble, xmlAttributeGetInt, xmlAttributeGetString + xmlAttributeCopyString and xmlAttributeCompareString functions + * fix some small bugs and problems along the way + * add support for filtering on attribute value in xmlgrep + 21-07-2008 * change a number of function parameters to const where appropriate * fix a problem where the wrong node-name length was returned @@ -16,7 +24,7 @@ for a particular node. this is required for cases where a node with a particular name is located deeper in a node with the same name; for example -r /configuration/device/reference/device would fail in the - previous version + previous verion * rename xmlGetElement to xmlGetNodeNum and add the possibility to request the nth node with this name * rename xmlGetNumElements to xmlGetNumNodes @@ -24,7 +32,7 @@ 06-07-2008 * reorganize the code to be able to skip comment sections * depreciate __xmlFindNextElement and use __xmlGetNode instead - * xmlGetNextElement now returns char* instead of void* for future use + * xmlGetNextElement now returns char* instead of void* for furute use * add preliminary support for wildcards in the search path ('*' and '?') 01-07-2008 diff --git a/utils/xmlgrep/README b/utils/xmlgrep/README index a23050bcc..74cb6afd9 100644 --- a/utils/xmlgrep/README +++ b/utils/xmlgrep/README @@ -7,7 +7,7 @@ the memory footprint can be kept low and the library can be kept simple. To achieve these goals the mmap function is used to map the configuration file to a memory region. The only places where memory is allocated is when creating -a new XML-id, when requesting a string from a node, when requesting the node +a new XML-id, when requesting a string from a node, when requestiong the node name or when a request is made to copy a node into a new memory region. Using this library should be pretty simple for most tasks; just open a file, @@ -16,14 +16,14 @@ read every parameter one by one and close the id again. void *xid; xid = xmlOpen("/tmp/file.xml"); - xpos = xmlGetNodeDouble(xid, "/configuration/x-pos"); - ypos = xmlGetNodeDouble(xid, "/configuration/y-pos"); - zpos = xmlGetNodeDouble(xid, "/configuration/z-pos"); + xpos = xmlNodeGetDouble(xid, "/configuration/x-pos"); + ypos = xmlNodeGetDouble(xid, "/configuration/y-pos"); + zpos = xmlNodeGetDouble(xid, "/configuration/z-pos"); xmlClose(xid); } While it is certainly possible to access every node directly by calling the -xmlGetNode(Int/Double/String) functions, when more than one node need to be +xmlNodeGet(Int/Double/String) functions, when more than one node need to be gathered from a parent node it is advised to get the id of the parent node and work from there since the XML-id holds the boundaries of the (parent)node which limits the searching area resulting in improved searching speed. @@ -31,9 +31,9 @@ which limits the searching area resulting in improved searching speed. void *xnid; char *s; - xnid = xmlGetNode(id, "/configuration/setup/"); - version = xmlGetNodeDouble(xnid, "version"); - s = xmlGetNodeString(xnid, "author"); + xnid = xmlNodeGet(id, "/configuration/setup/"); + version = xmlNodeGetDouble(xnid, "version"); + s = xmlNodeGetString(xnid, "author"); if (s) author = s; free(s); free(xnid); @@ -53,18 +53,18 @@ void xmlClose(const void *); # # Get the Id of a node at the specified path # e.g. -# xnid = xmlGetNode(id, "/path/to/specified/node"); +# xnid = xmlNodeGet(id, "/path/to/specified/node"); # -void *xmlGetNode(const void *, const char *); -void *xmlCopyNode(void *, const char *); +void *xmlNodeGet(const void *, const char *); +void *xmlNodeCopy(void *, const char *); # # Functions to walk the node tree and process them one by one. # e.g. # xmid = xmlMarkId(id); -# num = xmlGetNumNodes(xmid); +# num = xmlNodeGetNum(xmid); # for (i=0; i #include #include /* strncasecmp */ +#ifndef NDEBUG #include -#include +#endif struct _xml_id { - char *name; - char *start; size_t len; + char *start; + char *name; union { + size_t name_len; int fd; - size_t len; } node; }; -static char *__xmlCopyNode(const char *, size_t, const char *); -static char *__xmlGetNodePath(const char *, size_t *, char **, size_t *); -static char *__xmlGetNode(const char *, size_t *, char **, size_t *, size_t *); -static char *__xmlSkipComment(const char *, size_t); -static char *__xmlSkipInfo(const char *, size_t); +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 void *__xml_memmem(const char *, size_t, const char *, size_t); static void *__xml_memncasecmp(const char *, size_t *, char **, size_t *); #define PRINT(a, b, c) { \ @@ -138,7 +138,7 @@ xmlClose(void *id) } void * -xmlGetNode(const void *id, const char *path) +xmlNodeGet(const void *id, const char *path) { struct _xml_id *xsid = 0; @@ -151,7 +151,7 @@ xmlGetNode(const void *id, const char *path) node = (char *)path; len = xid->len; slen = strlen(path); - ptr = __xmlGetNodePath(xid->start, &len, &node, &slen); + ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen); if (ptr) { xsid = malloc(sizeof(struct _xml_id)); @@ -159,7 +159,7 @@ xmlGetNode(const void *id, const char *path) { xsid->len = len; xsid->start = ptr; - xsid->node.len = slen; + xsid->node.name_len = slen; xsid->name = node; } } @@ -169,7 +169,7 @@ xmlGetNode(const void *id, const char *path) } void * -xmlCopyNode(const void *id, const char *path) +xmlNodeCopy(const void *id, const char *path) { struct _xml_id *xsid = 0; @@ -182,7 +182,7 @@ xmlCopyNode(const void *id, const char *path) node = (char *)path; len = xid->len; slen = strlen(path); - ptr = __xmlGetNodePath(xid->start, &len, &node, &slen); + ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen); if (ptr) { xsid = malloc(sizeof(struct _xml_id) + len); @@ -192,7 +192,7 @@ xmlCopyNode(const void *id, const char *path) xsid->len = len; xsid->start = p; - xsid->node.len = slen; + xsid->node.name_len = slen; xsid->name = node; memcpy(xsid->start, ptr, len); @@ -204,13 +204,13 @@ xmlCopyNode(const void *id, const char *path) } char * -xmlGetNodeName(const void *id) +xmlNodeGetName(const void *id) { struct _xml_id *xid = (struct _xml_id *)id; size_t len; char *ret; - len = xid->node.len; + len = xid->node.name_len; ret = malloc(len+1); if (ret) { @@ -222,7 +222,7 @@ xmlGetNodeName(const void *id) } size_t -xmlCopyNodeName(const void *id, char *buf, size_t len) +xmlNodeCopyName(const void *id, char *buf, size_t len) { struct _xml_id *xid = (struct _xml_id *)id; size_t slen = 0; @@ -230,7 +230,7 @@ xmlCopyNodeName(const void *id, char *buf, size_t len) if (buf) { slen = len-1; - if (slen > xid->node.len) slen = xid->node.len; + if (slen > xid->node.name_len) slen = xid->node.name_len; memcpy(buf, xid->name, slen); *(buf + slen) = 0; } @@ -239,7 +239,7 @@ xmlCopyNodeName(const void *id, char *buf, size_t len) } unsigned int -xmlGetNumNodes(const void *id, const char *path) +xmlNodeGetNum(const void *id, const char *path) { struct _xml_id *xid = (struct _xml_id *)id; size_t num = 0; @@ -263,7 +263,7 @@ xmlGetNumNodes(const void *id, const char *path) pathname++; slen -= pathname-nodename; node = pathname; - p = __xmlGetNodePath(xid->start, &len, &node, &slen); + p = __xmlNodeGetPath(xid->start, &len, &node, &slen); } else { @@ -274,7 +274,7 @@ xmlGetNumNodes(const void *id, const char *path) if (p) { char *node = nodename; - __xmlGetNode(p, &len, &node, &slen, &num); + __xmlNodeGet(p, &len, &node, &slen, &num); } } @@ -282,7 +282,7 @@ xmlGetNumNodes(const void *id, const char *path) } void * -xmlGetNodeNum(const void *pid, void *id, const char *element, size_t num) +xmlNodeGetPos(const void *pid, void *id, const char *element, size_t num) { void *ret = 0; @@ -296,13 +296,13 @@ xmlGetNodeNum(const void *pid, void *id, const char *element, size_t num) len = xpid->len; slen = strlen(element); node = (char *)element; - ptr = __xmlGetNode(xpid->start, &len, &node, &slen, &num); + ptr = __xmlNodeGet(xpid->start, &len, &node, &slen, &num); if (ptr) { xid->len = len; xid->start = ptr; xid->name = node; - xid->node.len = slen; + xid->node.name_len = slen; ret = xid; } } @@ -344,17 +344,18 @@ xmlGetString(const void *id) } size_t -xmlCopyString(const void *id, char *buf, size_t len) +xmlCopyString(const void *id, char *buffer, size_t buflen) { struct _xml_id *xid = (struct _xml_id *)id; - size_t nlen = 0; + size_t ret = 0; - if (xid && xid->len && buf && len) + if (xid && xid->len && buffer && buflen) { char *ps, *pe, *pend; - int slen; + size_t slen, nlen; - nlen = len-1; + *buffer = '\0'; + nlen = buflen-1; ps = xid->start; slen = xid->len; pend = ps+slen; @@ -367,12 +368,14 @@ xmlCopyString(const void *id, char *buf, size_t len) if (nlen) { - memcpy(buf, ps, nlen); - *(buf+nlen) = 0; + if (nlen >= buflen) nlen = buflen-1; + memcpy(buffer, ps, nlen); + *(buffer+nlen) = 0; + ret = nlen; } } - return nlen; + return ret; } int @@ -400,14 +403,14 @@ xmlCompareString(const void *id, const char *s) } char * -xmlGetNodeString(const void *id, const char *path) +xmlNodeGetString(const void *id, const char *path) { struct _xml_id *xid = (struct _xml_id *)id; char *str = 0; if (xid && xid->len && path) { - str = __xmlCopyNode(xid->start, xid->len, path); + str = __xmlNodeCopy(xid->start, xid->len, path); if (str) { char *ps, *pe, *pend; @@ -432,45 +435,45 @@ xmlGetNodeString(const void *id, const char *path) } size_t -xmlCopyNodeString(const void *id, const char *path, char *buffer, size_t buflen) +xmlNodeCopyString(const void *id, const char *path, char *buffer, size_t buflen) { struct _xml_id *xid = (struct _xml_id *)id; - size_t len = 0; + size_t ret = 0; if (xid && xid->len && path && buffer && buflen) { char *str, *node; - size_t slen; + size_t slen, nlen; *buffer = '\0'; - len = xid->len; + nlen = xid->len; slen = strlen(path); node = (char *)path; - str = __xmlGetNodePath(xid->start, &len, &node, &slen); + str = __xmlNodeGetPath(xid->start, &nlen, &node, &slen); if (str) { char *ps, *pe; ps = str; - pe = ps+len-1; + pe = ps+nlen-1; while ((psps) && isspace(*pe)) pe--; - len = (pe-ps)+1; - if (len >= buflen) len = buflen-1; + nlen = (pe-ps)+1; + if (nlen >= buflen) nlen = buflen-1; - memcpy(buffer, ps, len); - str = buffer + len; - *str = '\0'; + memcpy(buffer, ps, nlen); + *(buffer + nlen) = '\0'; + ret = nlen; } } - return len; + return ret; } int -xmlCompareNodeString(const void *id, const char *path, const char *s) +xmlNodeCompareString(const void *id, const char *path, const char *s) { struct _xml_id *xid = (struct _xml_id *)id; int ret = -1; @@ -478,12 +481,12 @@ xmlCompareNodeString(const void *id, const char *path, const char *s) if (xid && xid->len && path && s && (strlen(s) > 0)) { char *node, *str, *ps, *pe; - size_t len, slen, i; + size_t len, slen; len = xid->len; slen = strlen(path); node = (char *)path; - str = __xmlGetNodePath(xid->start, &len, &node, &slen); + str = __xmlNodeGetPath(xid->start, &len, &node, &slen); if (str) { ps = str; @@ -517,7 +520,7 @@ xmlGetInt(const void *id) } long int -xmlGetNodeInt(const void *id, const char *path) +xmlNodeGetInt(const void *id, const char *path) { struct _xml_id *xid = (struct _xml_id *)id; long int li = 0; @@ -530,7 +533,7 @@ xmlGetNodeInt(const void *id, const char *path) len = xid->len; slen = strlen(path); node = (char *)path; - str = __xmlGetNodePath(xid->start, &len, &node, &slen); + str = __xmlNodeGetPath(xid->start, &len, &node, &slen); if (str) { char *end = str+len; @@ -557,7 +560,7 @@ xmlGetDouble(const void *id) } double -xmlGetNodeDouble(const void *id, const char *path) +xmlNodeGetDouble(const void *id, const char *path) { struct _xml_id *xid = (struct _xml_id *)id; double d = 0.0; @@ -570,7 +573,7 @@ xmlGetNodeDouble(const void *id, const char *path) len = xid->len; slen = strlen(path); node = (char *)path; - str = __xmlGetNodePath(xid->start, &len, &node, &slen); + str = __xmlNodeGetPath(xid->start, &len, &node, &slen); if (str) { char *end = str+len; @@ -598,10 +601,265 @@ xmlMarkId(const void *id) return (void *)xmid; } +double +xmlAttributeGetDouble(const void *id, const char *name) +{ + 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->start > xid->name); + + p = xid->name + xid->node.name_len; + end = xid->start-1; + + while ((pstart && xid->len && xid->node.name_len) + { + char *p, *end, *new = 0; + + assert(xid->start > xid->name); + + p = xid->name + xid->node.name_len; + end = xid->start-1; + + while ((pstart && xid->len && xid->node.name_len) + { + char *p, *end, *new = 0; + + assert(xid->start > xid->name); + + p = xid->name + xid->node.name_len; + end = xid->start-1; + + while ((pstart && xid->len && xid->node.name_len + && buffer && buflen) + { + char *ps, *pe; + + *buffer = '\0'; + ps = xid->name + xid->node.name_len + 1; + pe = xid->start - 1; + + assert((int)(pe-ps) > 0); + + 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= buflen) restlen = buflen-1; + memcpy(buffer, new, restlen); + *(buffer+restlen) = 0; + ret = restlen; + } + } + break; + } + + while ((psstart && xid->len && xid->node.name_len + && s && strlen(s)) + { + char *ps, *pe; + + ps = xid->name + xid->node.name_len + 1; + pe = xid->start - 1; + + assert((int)(pe-ps) > 0); + + 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 0) && (haystacklen >= needlelen)) - { - char *ns, *hs, *ptr; - - hs = (char *)haystack; - ns = (char *)needle; - do - { - ptr = memchr(hs, *ns, haystacklen); - if (ptr) - { - haystacklen -= (ptr - hs); - - if (haystacklen < needlelen) break; - if (memcmp(ptr, needle, needlelen) == 0) - { - rptr = ptr; - break; - } - - hs = ptr+1; - } - else break; - } - while (haystacklen > needlelen); - } - - return rptr; -} - - #define NOCASECMP(a,b) ( ((a)^(b)) & 0xdf ) void * __xml_memncasecmp(const char *haystack, size_t *haystacklen, @@ -952,7 +1182,7 @@ __xml_memncasecmp(const char *haystack, size_t *haystacklen, */ void * -simple_mmap(int fd, unsigned int length, SIMPLE_UNMMAP *un) +simple_mmap(int fd, size_t length, SIMPLE_UNMMAP *un) { HANDLE f; HANDLE m; @@ -971,8 +1201,6 @@ simple_mmap(int fd, unsigned int length, SIMPLE_UNMMAP *un) return NULL; } - if (n) *n = GetFileSize(f, NULL); - if (un) { un->m = m; diff --git a/utils/xmlgrep/xml.h b/utils/xmlgrep/xml.h index 874fc659b..b02296554 100644 --- a/utils/xmlgrep/xml.h +++ b/utils/xmlgrep/xml.h @@ -29,7 +29,7 @@ #define __XML_CONFIG 1 /** - * Open an XML file for processing + * Open an XML file for processing. * * @param fname path to the file * @return XML-id which is used for further processing @@ -37,7 +37,7 @@ void *xmlOpen(const char *); /** - * Close the XML file after which no further processing is possible + * Close the XML file after which no further processing is possible. * * @param xid XML-id */ @@ -47,22 +47,22 @@ void xmlClose(void *); /** * Locate a subsection of the xml tree for further processing. * This adds processing speed since the reuired nodes will only be searched - * in the subsection + * in the subsection. * * The memory allocated for the XML-subsection-id has to be freed by the - * calling process + * calling process. * * @param xid XML-id * @param node path to the node containing the subsection * @return XML-subsection-id for further processing */ -void *xmlGetNode(const void *, const char *); +void *xmlNodeGet(const void *, const char *); /** * Copy a subsection of the xml tree for further processing. * This is useful when it's required to process a section of the XML code * after the file has been closed. The drawback is the added memory - * requirements + * requirements. * * The memory allocated for the XML-subsection-id has to be freed by the * calling process. @@ -71,41 +71,56 @@ void *xmlGetNode(const void *, const char *); * @param node path to the node containing the subsection * @return XML-subsection-id for further processing */ -void *xmlCopyNode(const void *, const char *); +void *xmlNodeCopy(const void *, const char *); /** * Return the name of this node. - * The returned string has to be freed by the calling process + * The returned string has to be freed by the calling process. * * @param xid XML-id * @return a newly alocated string containing the node name */ -char *xmlGetNodeName(const void *); +char *xmlNodeGetName(const void *); /** - * Copy the name of this node in a pre-allocated buffer + * Copy the name of this node in a pre-allocated buffer. * * @param xid XML-id * @param buffer the buffer to copy the string to * @param buflen length of the destination buffer * @return the length of the node name */ -size_t xmlCopyNodeName(const void *, char *, size_t); +size_t xmlNodeCopyName(const void *, char *, size_t); + +/** + * Create a marker XML-id that starts out with the same settings as the + * refference XML-id. + * + * Marker id's are required when xmlNodeGetNum() and xmlNodeGetPos() are used + * to walk a number of nodes. The xmlNodeGetPos function adjusts the contents + * of the provided XML-id to keep track of it's position within the xml section. + * The returned XML-id is limited to the boundaries of the requested XML tag + * and has to be freed by the calling process. + * + * @param xid reference XML-id + * @return a copy of the reference XML-id + */ +void *xmlMarkId(const void *); /** - * Get the number of nodes with the same name from a specified xml path + * Get the number of nodes with the same name from a specified xml path. * * @param xid XML-id * @param path path to the xml node * @return the number count of the nodename */ -unsigned int xmlGetNumNodes(const void *, const char *); +unsigned int xmlNodeGetNum(const void *, const char *); /** * Get the nth occurrence of node in the parent node. - * The return value should neevr be altered or freed by the caller + * The return value should never be altered or freed by the caller. * * @param pid XML-id of the parent node of this node * @param xid XML-id @@ -113,12 +128,12 @@ unsigned int xmlGetNumNodes(const void *, const char *); * @param num specify which occurence to return * @return XML-subsection-id for further processing or NULL if unsuccessful */ -void *xmlGetNodeNum(const void *, void *, const char *, int); +void *xmlNodeGetPos(const void *, void *, const char *, int); /** * Get a string of characters from the current node. - * The returned string has to be freed by the calling process + * The returned string has to be freed by the calling process. * * @param xid XML-id * @return a newly alocated string containing the contents of the node @@ -129,7 +144,7 @@ char *xmlGetString(const void *); * Get a string of characters from the current node. * This function has the advantage of not allocating its own return buffer, * keeping the memory management to an absolute minimum but the disadvantage - * is that it's unreliable in multithread environments + * is that it's unreliable in multithread environments. * * @param xid XML-id * @param buffer the buffer to copy the string to @@ -140,7 +155,7 @@ size_t xmlCopyString(const void *, char *, size_t); /** * Compare the value of this node to a reference string. - * Comparing is done in a case insensitive way + * Comparing is done in a case insensitive way. * * @param xid XML-id * @param str the string to compare to @@ -152,19 +167,19 @@ int xmlCompareString(const void *, const char *); /** * Get a string of characters from a specified xml path. - * The returned string has to be freed by the calling process + * The returned string has to be freed by the calling process. * * @param xid XML-id * @param path path to the xml node * @return a newly alocated string containing the contents of the node */ -char *xmlGetNodeString(const void *, const char *); +char *xmlNodeGetString(const void *, const char *); /** * Get a string of characters from a specified xml path. * This function has the advantage of not allocating its own return buffer, * keeping the memory management to an absolute minimum but the disadvantage - * is that it's unreliable in multithread environments + * is that it's unreliable in multithread environments. * * @param xid XML-id * @param path path to the xml node @@ -172,11 +187,11 @@ char *xmlGetNodeString(const void *, const char *); * @param buflen length of the destination buffer * @return the length of the string */ -size_t xmlCopyNodeString(const void *, const char *, char *, size_t); +size_t xmlNodeCopyString(const void *, const char *, char *, size_t); /** * Compare the value of a node to a reference string. - * Comparing is done in a case insensitive way + * Comparing is done in a case insensitive way. * * @param xid XML-id * @param path path to the xml node to compare to @@ -185,11 +200,46 @@ size_t xmlCopyNodeString(const void *, const char *, char *, size_t); * of the node is found, respectively, to be less than, to match, or be greater * than str */ -int xmlCompareNodeString(const void *, const char *, const char *); +int xmlNodeCompareString(const void *, const char *, const char *); +/** + * Get a string of characters from a named attribute. + * The returned string has to be freed by the calling process. + * + * @param xid XML-id + * @param name name of the attribute to acquire + * @return the contents of the node converted to an integer value + */ +char *xmlAttributeGetString(const void *, const char *); /** - * Get the integer value from the current node + * Get a string of characters from a named attribute. + * This function has the advantage of not allocating its own return buffer, + * keeping the memory management to an absolute minimum but the disadvantage + * is that it's unreliable in multithread environments. + * + * @param xid XML-id + * @param name name of the attribute to acquire. + * @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); + +/** + * Compare the value of an attribute to a reference string. + * Comparing is done in a case insensitive way. + * + * @param xid XML-id + * @param name name of the attribute to acquire. + * @param str the string to compare to + * @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 *); + + +/** + * Get the integer value from the current node/ * * @param xid XML-id * @return the contents of the node converted to an integer value @@ -197,17 +247,26 @@ int xmlCompareNodeString(const void *, const char *, const char *); long int xmlGetInt(const void *); /** - * Get an integer value from a specified xml path + * Get an integer value from a specified xml path. * * @param xid XML-id * @param path path to the xml node * @return the contents of the node converted to an integer value */ -long int xmlGetNodeInt(const void *, const char *); +long int xmlNodeGetInt(const void *, const char *); + +/** + * Get the integer value from the named attribute. + * + * @param xid XML-id + * @param name name of the attribute to acquire + * @return the contents of the node converted to an integer value + */ +long int xmlAttributeGetInt(const void *, const char *); /** - * Get the double value from the curent node + * Get the double value from the curent node/ * * @param xid XML-id * @return the contents of the node converted to a double value @@ -215,24 +274,23 @@ long int xmlGetNodeInt(const void *, const char *); double xmlGetDouble(const void *); /** - * Get a double value from a specified xml path + * Get a double value from a specified xml path/ * * @param xid XML-id * @param path path to the xml node * @return the contents of the node converted to a double value */ -double xmlGetNodeDouble(const void *, const char *); +double xmlNodeGetDouble(const void *, const char *); /** - * Create a marker XML-id that starts out with the same settings as the - * refference XML-id. - * The returned XML-id has to be freed by the calling process + * Get the double value from the named attribute. * - * @param xid reference XML-id - * @return a copy of the reference XML-id + * @param xid XML-id + * @param name name of the attribute to acquire + * @return the contents of the node converted to an integer value */ -void *xmlMarkId(const void *); +double xmlAttributeGetDouble(const void *, const char *); #endif /* __XML_CONFIG */ diff --git a/utils/xmlgrep/xmlgrep.c b/utils/xmlgrep/xmlgrep.c index 90a55e439..fe4782e0f 100644 --- a/utils/xmlgrep/xmlgrep.c +++ b/utils/xmlgrep/xmlgrep.c @@ -1,7 +1,9 @@ #include -#include -#include + +#define _GNU_SOURCE #include +#include +#include #include "xml.h" @@ -13,6 +15,7 @@ static char *_element = 0; static char *_value = 0; static char *_root = 0; static char *_print = 0; +static char *_attribute = 0; static int print_filenames = 0; static void free_and_exit(int i); @@ -29,30 +32,35 @@ show_help () printf("usage: xmlgrep [options] [file ...]\n\n"); printf("Options:\n"); printf("\t-h\t\tshow this help message\n"); + printf("\t-a \tprint this attribute as the output\n"); printf("\t-e \t\tshow sections that contain this element\n"); printf("\t-p \t\tprint this element as the output\n"); printf("\t-r \tspecify the XML search root\n"); - printf("\t-v \tshow sections where one of the elements has this "); - printf("value\n\n"); + printf("\t-v \tfilter sections that contain this vale\n\n"); printf(" To print the contents of the 'type' element of the XML section "); - printf("that begins\n at '/printer/output' one would use the following "); - printf("syntax:\n\n\txmlgrep -r /printer/output -p type sample.xml\n\n"); + printf("that begins\n at '/printer/output' use the following command:\n\n"); + printf("\txmlgrep -r /printer/output -p type sample.xml\n\n"); + printf(" To filter 'output' elements under '/printer' that have attribute"); + printf(" 'n' set to '1'\n use the following command:\n\n"); + printf("\txmlgrep -r /printer -p output -a n -v 1 sample.xml\n\n"); printf(" To filter out sections that contain the 'driver' element with "); - printf("'generic' as\n it's value one would issue the following command:"); + printf("'generic' as\n it's value use the following command:"); printf("\n\n\txmlgrep -r /printer/output -e driver -v generic sample.xml"); printf("\n\n"); free_and_exit(0); } void -free_and_exit(int i) +free_and_exit(int ret) { if (_root && _root != _static_root) free(_root); if (_element && _element != _static_element) free(_element); if (_value) free(_value); if (_print) free(_print); + if (_attribute) free(_attribute); if (_filenames) { + unsigned int i; for (i=0; i < _fcount; i++) { if (_filenames[i]) @@ -64,17 +72,18 @@ free_and_exit(int i) free(_filenames); } - exit(i); + exit(ret); } int parse_option(char **args, int n, int max) { char *opt, *arg = 0; - int sz; + unsigned int alen = 0; + unsigned int olen; opt = args[n]; - if (opt[0] == '-' && opt[1] == '-') + if (strncmp(opt, "--", 2) == 0) opt++; if ((arg = strchr(opt, '=')) != NULL) @@ -90,36 +99,52 @@ parse_option(char **args, int n, int max) #endif } - sz = strlen(opt); - if (strncmp(opt, "-help", sz) == 0) + olen = strlen(opt); + if (strncmp(opt, "-help", olen) == 0) { show_help(); } - else if (strncmp(opt, "-root", sz) == 0) + else if (strncmp(opt, "-root", olen) == 0) + { + if (arg == 0) SHOW_NOVAL(opt); + alen = strlen(arg)+1; + _root = malloc(alen); + memcpy(_root, arg, alen); + return 2; + } + else if (strncmp(opt, "-element", olen) == 0) { if (arg == 0) SHOW_NOVAL(opt); - _root = strdup(arg); + alen = strlen(arg)+1; + _element = malloc(alen); + memcpy(_element, arg, alen); return 2; } - else if (strncmp(opt, "-element", sz) == 0) + else if (strncmp(opt, "-value", olen) == 0) { if (arg == 0) SHOW_NOVAL(opt); - _element = strdup(arg); + alen = strlen(arg)+1; + _value = malloc(alen); + memcpy(_value, arg, alen); return 2; } - else if (strncmp(opt, "-value", sz) == 0) + else if (strncmp(opt, "-print", olen) == 0) { if (arg == 0) SHOW_NOVAL(opt); - _value = strdup(arg); + alen = strlen(arg)+1; + _print = malloc(alen); + memcpy(_print, arg, alen); return 2; } - else if (strncmp(opt, "-print", sz) == 0) + else if (strncmp(opt, "-attribute", olen) == 0) { if (arg == 0) SHOW_NOVAL(opt); - _print = strdup(arg); + alen = strlen(arg)+1; + _attribute = malloc(alen); + memcpy(_attribute, arg, alen); return 2; } - else if (strncmp(opt, "-list-filenames", sz) == 0) + else if (strncmp(opt, "-list-filenames", olen) == 0) { /* undocumented test argument */ print_filenames = 1; return 1; @@ -147,7 +172,9 @@ parse_option(char **args, int n, int max) _filenames = ptr; } - _filenames[pos] = strdup(opt); + alen = strlen(opt)+1; + _filenames[pos] = malloc(alen); + memcpy(_filenames[pos], opt, alen); } return 1; @@ -162,30 +189,42 @@ void walk_the_tree(size_t num, void *xid, char *tree) void *xmid = xmlMarkId(xid); if (xmid && _print) { - no_elements = xmlGetNumNodes(xid, _print); + no_elements = xmlNodeGetNum(xid, _print); for (i=0; i%s\n", - _filenames[num], _print, value, _print); + xmlCopyString(xmid, (char *)&value, 1024); + if (_value && _attribute) + { + if (!xmlAttributeCompareString(xmid, _attribute, _value)) + { + printf("%s: <%s %s=\"%s\">%s\n", + _filenames[num], _print, _attribute, _value, + value, _print); + } + } + else + { + printf("%s: <%s>%s\n", + _filenames[num], _print, value, _print); + } } } free(xmid); } else if (xmid && _value) { - no_elements = xmlGetNumNodes(xmid, _element); + no_elements = xmlNodeGetNum(xmid, _element); for (i=0; i%s\n", @@ -199,16 +238,16 @@ void walk_the_tree(size_t num, void *xid, char *tree) { char parentname[64]; - xmlCopyNodeName(xid, (char *)&parentname, 64); + xmlNodeCopyName(xid, (char *)&parentname, 64); - no_elements = xmlGetNumNodes(xmid, _element); + no_elements = xmlNodeGetNum(xmid, _element); for (i=0; i