1
0
Fork 0

* 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
This commit is contained in:
ehofman 2009-04-16 19:03:22 +00:00 committed by Tim Moore
parent 86b34010f3
commit 8943603ef1
5 changed files with 585 additions and 230 deletions

View file

@ -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

View file

@ -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<num; i++) {
# if (xmlGetNodeNum(id, xmid, "element", i) != 0) {
# if (xmlNodeGetPos(id, xmid, "element", i) != 0) {
# if ((s = xmlGetString(xmid)) != 0) {
# printf("%s\n", s);
# free(s);
@ -74,22 +74,22 @@ void *xmlCopyNode(void *, const char *);
# free(xmid);
#
void *xmlMarkId(void *);
unsigned int xmlGetNumNodes(void *, const char *);
void *xmlGetNodeNum(const void *, void *, const char *, int);
unsigned int xmlNodeGetNum(void *, const char *);
void *xmlNodeGetPos(const void *, void *, const char *, int);
#
# Get the name of the current node
#
char *xmlGetNodeName(void *);
size_t xmlCopyNodeName(void *, const char *, size_t);
char *xmlNodeGetName(void *);
size_t xmlNodeCopyName(void *, const char *, size_t);
#
# These functions work on the current node.
# e.g.
# xnid = xmlGetNode(id, "/path/to/last/node");
# xnid = xmlNodeGet(id, "/path/to/last/node");
# i = xmlGetInt(xnid);
# or
# xnid = xmlGetNode(id, "/path/to/specified/node");
# xnid = xmlNodeGet(id, "/path/to/specified/node");
# if (xmlCompareString(xnid, "value") == 0) printf("We have a match!\n");
#
long int xmlGetInt(void *);
@ -101,13 +101,29 @@ int xmlCompareString(const void *, const char *);
#
# These functions work on a specified node path
# e.g.
# d = xmlGetNodeDouble(id, "/path/to/node");
# d = xmlNodeGetDouble(id, "/path/to/node");
# or
# xnid = xmlGetNode(id, "/path/to");
# i = xmlGetNodeInt(xnid, "node");
# xnid = xmlNodeGet(id, "/path/to");
# i = xmlNodeGetInt(xnid, "node");
#
long int xmlGetNodeInt(void *, const char *);
double xmlGetNodeDouble(void *, const char *);
char *xmlGetNodeString(void *, const char *);
size_t xmlCopyNodeString(void *, const char *, char *, const size_t);
int xmlCompareNodeString(const void *, const char *, const char *);
long int xmlNodeGetInt(void *, const char *);
double xmlNodeGetDouble(void *, const char *);
char *xmlNodeGetString(void *, const char *);
size_t xmlNodeCopyString(void *, const char *, char *, const size_t);
int xmlNodeCompareString(const void *, const char *, const char *);
#
# These functions work on a specified atribute
# e.g.
# i = xmlAttributeGetInt(id, "n");
#
# or
# s = xmlNodeGetString(id, "type");
# if (s) printf("node is of type '%s'\n", s);
# free(s);
#
long int xmlAttributeGetInt(const void *, const char *);
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 *);

View file

@ -40,8 +40,8 @@ static SIMPLE_UNMMAP un;
/*
* map 'filename' and return a pointer to it.
*/
void *simple_mmap(int, unsigned int, SIMPLE_UNMMAP *);
void simple_unmmap(SIMPLE_UNMMAP *);
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)
@ -58,28 +58,28 @@ void simple_unmmap(SIMPLE_UNMMAP *);
#include <ctype.h>
#include <string.h>
#include <strings.h> /* strncasecmp */
#ifndef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#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 ((ps<pe) && isspace(*ps)) ps++;
while ((pe>ps) && 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 ((p<end) && isspace(*p)) p++;
while (p<end)
{
size_t elementlen = strlen(name);
size_t restlen = end-p;
char *element = (char *)name;
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 ((p<end) && !isspace(*p)) p++;
if (p<end)
while ((p<end) && isspace(*p)) p++;
}
}
return ret;
}
long int
xmlAttributeGetInt(const void *id, const char *name)
{
struct _xml_id *xid = (struct _xml_id *)id;
long int ret = 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 ((p<end) && isspace(*p)) p++;
while (p<end)
{
size_t elementlen = strlen(name);
size_t restlen = end-p;
char *element = (char *)name;
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 ((p<end) && !isspace(*p)) p++;
if (p<end)
while ((p<end) && isspace(*p)) p++;
}
}
return ret;
}
char *
xmlAttributeGetString(const void *id, const char *name)
{
struct _xml_id *xid = (struct _xml_id *)id;
char *ret = 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 ((p<end) && isspace(*p)) p++;
while (p<end)
{
size_t elementlen = strlen(name);
size_t restlen = end-p;
char *element = (char *)name;
new = __xml_memncasecmp(p, &restlen, &element, &elementlen);
if (new)
{
restlen = end-p;
new = memchr(p, '=', restlen);
if (new)
{
new++;
if (*new == '"') new++;
p = new;
while ((p<end) && (*p != '"') && (*p != ' ')) p++;
if (p<end)
{
ret = calloc(1, p-new);
memcpy(ret, new, (p-new));
}
}
break;
}
while ((p<end) && !isspace(*p)) p++;
if (p<end)
while ((p<end) && isspace(*p)) p++;
}
}
return ret;
}
size_t
xmlAttributeCopyString(const void *id, const char *name,
char *buffer, size_t buflen)
{
struct _xml_id *xid = (struct _xml_id *)id;
size_t ret = 0;
if (xid && xid->start && 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<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))
{
char *new;
restlen = pe-ps;
new = memchr(ps, '=', restlen);
if (new)
{
new++;
if (*new == '"') new++;
ps = new;
while ((ps<pe) && (*ps != '"') && (*ps != ' ')) ps++;
if (ps<pe)
{
restlen = ps-new;
if (restlen >= buflen) restlen = buflen-1;
memcpy(buffer, new, restlen);
*(buffer+restlen) = 0;
ret = restlen;
}
}
break;
}
while ((ps<pe) && !isspace(*ps)) ps++;
if (ps<pe)
while ((ps<pe) && isspace(*ps)) ps++;
}
}
return ret;
}
int
xmlAttributeCompareString(const void *id, const char *name, const char *s)
{
struct _xml_id *xid = (struct _xml_id *)id;
int ret = -1;
if (xid && xid->start && 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<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))
{
char *new;
restlen = pe-ps;
new = memchr(ps, '=', restlen);
if (new)
{
new++;
if (*new == '"') new++;
ps = new;
while ((ps<pe) && (*ps != '"') && (*ps != ' ')) ps++;
if (ps<pe)
{
int alen = ps-new;
ret = strncasecmp(new, s, alen);
}
}
break;
}
while ((ps<pe) && !isspace(*ps)) ps++;
if (ps<pe)
while ((ps<pe) && isspace(*ps)) ps++;
}
}
return ret;
}
/* -------------------------------------------------------------------------- */
static char *
__xmlCopyNode(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;
@ -609,7 +867,7 @@ __xmlCopyNode(const char *start, size_t len, const char *path)
rlen = len;
slen = strlen(path);
node = (char *)path;
p = __xmlGetNodePath(start, &rlen, &node, &slen);
p = __xmlNodeGetPath(start, &rlen, &node, &slen);
if (p && rlen)
{
ret = calloc(1, rlen+1);
@ -620,7 +878,7 @@ __xmlCopyNode(const char *start, size_t len, const char *path)
}
char *
__xmlGetNodePath(const char *start, size_t *len, char **name, size_t *plen)
__xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *plen)
{
char *node;
char *ret = 0;
@ -649,11 +907,11 @@ __xmlGetNodePath(const char *start, size_t *len, char **name, size_t *plen)
else plen = path++ - node;
num = 0;
ret = __xmlGetNode(start, len, &node, &plen, &num);
ret = __xmlNodeGet(start, len, &node, &plen, &num);
if (ret && path)
{
plen = slen - (path - *name);
ret = __xmlGetNodePath(ret, len, &path, &plen);
ret = __xmlNodeGetPath(ret, len, &path, &plen);
}
*name = path;
@ -663,13 +921,13 @@ __xmlGetNodePath(const char *start, size_t *len, char **name, size_t *plen)
}
char *
__xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *nodenum)
__xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *nodenum)
{
char *new, *cur, *ne, *ret = 0;
char *element, *start_tag=0;
size_t restlen, elementlen;
size_t retlen = 0;
int found, num;
char *element;
assert (start != 0);
assert (len != 0);
@ -701,7 +959,7 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
if (*cur == '!')
{
new = __xmlSkipComment(cur, restlen);
new = __xmlCommentSkip(cur, restlen);
if (!new) return 0;
restlen -= new-cur;
cur = new;
@ -709,7 +967,7 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
}
else if (*cur == '?')
{
new = __xmlSkipInfo(cur, restlen);
new = __xmlInfoSkip(cur, restlen);
if (!new) return 0;
restlen -= new-cur;
@ -723,7 +981,12 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
if (new)
{
retlen = elementlen;
if (found == num ) ret = new+1;
if (found == num )
{
ret = new+1;
start_tag = element;
}
else start_tag = 0;
}
else
{
@ -746,7 +1009,7 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
size_t nlen = 1;
size_t pos = -1;
new = __xmlGetNode(cur, &slen, &node, &nlen, &pos);
new = __xmlNodeGet(cur, &slen, &node, &nlen, &pos);
if (!new)
{
if (slen == restlen) return 0;
@ -767,8 +1030,12 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
{
if (!strncasecmp(new+2, element, elementlen))
{
if (found == num) *len = new-ret;
*name = element;
if (found == num)
{
assert(start_tag != 0);
*len = new-ret;
*name = start_tag;
}
found++;
}
@ -788,7 +1055,7 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
}
char *
__xmlSkipComment(const char *start, size_t len)
__xmlCommentSkip(const char *start, size_t len)
{
char *cur, *new;
@ -825,7 +1092,7 @@ __xmlSkipComment(const char *start, size_t len)
}
char *
__xmlSkipInfo(const char *start, size_t len)
__xmlInfoSkip(const char *start, size_t len)
{
char *cur, *new;
@ -848,43 +1115,6 @@ __xmlSkipInfo(const char *start, size_t len)
}
void *
__xml_memmem(const char *haystack, size_t haystacklen,
const char *needle, size_t needlelen)
{
void *rptr = 0;
if (haystack && needle && (needlelen > 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;

View file

@ -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,7 @@ 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
*
* The memory allocated for the XML-subsection-id has to be freed by the
* 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 *);
/**
* 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
* in the subsection.
*
* The memory allocated for the XML-subsection-id has to be freed by the
* calling process.
@ -71,41 +56,71 @@ 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 *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.
*
* The memory allocated for the XML-subsection-id has to be freed by the
* calling process.
*
* @param xid XML-id
* @param node path to the node containing the subsection
* @return XML-subsection-id for further processing
*/
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);
/**
* Get the number of nodes with the same name from a specified xml path
* 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.
*
* @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 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
* 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 */

View file

@ -1,7 +1,9 @@
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#define _GNU_SOURCE
#include <string.h>
#include <strings.h>
#include <assert.h>
#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 <string>\tprint this attribute as the output\n");
printf("\t-e <id>\t\tshow sections that contain this element\n");
printf("\t-p <id>\t\tprint this element as the output\n");
printf("\t-r <path>\tspecify the XML search root\n");
printf("\t-v <string>\tshow sections where one of the elements has this ");
printf("value\n\n");
printf("\t-v <string>\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);
_root = strdup(arg);
alen = strlen(arg)+1;
_root = malloc(alen);
memcpy(_root, arg, alen);
return 2;
}
else if (strncmp(opt, "-element", sz) == 0)
else if (strncmp(opt, "-element", olen) == 0)
{
if (arg == 0) SHOW_NOVAL(opt);
_element = strdup(arg);
alen = strlen(arg)+1;
_element = malloc(alen);
memcpy(_element, arg, alen);
return 2;
}
else if (strncmp(opt, "-value", sz) == 0)
else if (strncmp(opt, "-value", olen) == 0)
{
if (arg == 0) SHOW_NOVAL(opt);
_value = strdup(arg);
alen = strlen(arg)+1;
_value = malloc(alen);
memcpy(_value, arg, alen);
return 2;
}
else if (strncmp(opt, "-print", sz) == 0)
else if (strncmp(opt, "-print", olen) == 0)
{
if (arg == 0) SHOW_NOVAL(opt);
_print = strdup(arg);
alen = strlen(arg)+1;
_print = malloc(alen);
memcpy(_print, arg, alen);
return 2;
}
else if (strncmp(opt, "-list-filenames", sz) == 0)
else if (strncmp(opt, "-attribute", olen) == 0)
{
if (arg == 0) SHOW_NOVAL(opt);
alen = strlen(arg)+1;
_attribute = malloc(alen);
memcpy(_attribute, arg, alen);
return 2;
}
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<no_elements; i++)
{
if (xmlGetNodeNum(xid, xmid, _print, i) != 0)
if (xmlNodeGetPos(xid, xmid, _print, i) != 0)
{
char value[64];
char value[1024];
xmlCopyString(xmid, (char *)&value, 64);
printf("%s: <%s>%s</%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</%s>\n",
_filenames[num], _print, _attribute, _value,
value, _print);
}
}
else
{
printf("%s: <%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<no_elements; i++)
{
if (xmlGetNodeNum(xid, xmid, _element, i) != 0)
if (xmlNodeGetPos(xid, xmid, _element, i) != 0)
{
char nodename[64];
xmlCopyNodeName(xmid, (char *)&nodename, 64);
xmlNodeCopyName(xmid, (char *)&nodename, 64);
if (xmlCompareString(xmid, _value) == 0)
{
printf("%s: <%s>%s</%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<no_elements; i++)
{
if (xmlGetNodeNum(xid, xmid, _element, i) != 0)
if (xmlNodeGetPos(xid, xmid, _element, i) != 0)
{
char nodename[64];
xmlCopyNodeName(xmid, (char *)&nodename, 64);
xmlNodeCopyName(xmid, (char *)&nodename, 64);
if (strncasecmp((char *)&nodename, _element, 64) == 0)
{
char value[64];
@ -235,16 +274,22 @@ void walk_the_tree(size_t num, void *xid, char *tree)
xmid = xmlMarkId(xid);
if (xmid)
{
if (next) *next++ = 0;
if (next)
{
*next++ = 0;
}
no_elements = xmlGetNumNodes(xid, elem);
no_elements = xmlNodeGetNum(xid, elem);
for (i=0; i<no_elements; i++)
{
if (xmlGetNodeNum(xid, xmid, elem, i) != 0)
if (xmlNodeGetPos(xid, xmid, elem, i) != 0)
walk_the_tree(num, xmid, next);
}
if (next) *--next = '/';
if (next)
{
*--next = '/';
}
free(xmid);
}
@ -275,7 +320,7 @@ void grep_file(unsigned num)
int
main (int argc, char **argv)
{
int i;
unsigned int i;
if (argc == 1)
show_help();