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 21-07-2008
* change a number of function parameters to const where appropriate * change a number of function parameters to const where appropriate
* fix a problem where the wrong node-name length was returned * 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 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; particular name is located deeper in a node with the same name;
for example -r /configuration/device/reference/device would fail in the 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 * rename xmlGetElement to xmlGetNodeNum and add the possibility to request
the nth node with this name the nth node with this name
* rename xmlGetNumElements to xmlGetNumNodes * rename xmlGetNumElements to xmlGetNumNodes
@ -24,7 +32,7 @@
06-07-2008 06-07-2008
* reorganize the code to be able to skip comment sections * reorganize the code to be able to skip comment sections
* depreciate __xmlFindNextElement and use __xmlGetNode instead * 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 '?') * add preliminary support for wildcards in the search path ('*' and '?')
01-07-2008 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 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 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. 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, 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; void *xid;
xid = xmlOpen("/tmp/file.xml"); xid = xmlOpen("/tmp/file.xml");
xpos = xmlGetNodeDouble(xid, "/configuration/x-pos"); xpos = xmlNodeGetDouble(xid, "/configuration/x-pos");
ypos = xmlGetNodeDouble(xid, "/configuration/y-pos"); ypos = xmlNodeGetDouble(xid, "/configuration/y-pos");
zpos = xmlGetNodeDouble(xid, "/configuration/z-pos"); zpos = xmlNodeGetDouble(xid, "/configuration/z-pos");
xmlClose(xid); xmlClose(xid);
} }
While it is certainly possible to access every node directly by calling the 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 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 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. 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; void *xnid;
char *s; char *s;
xnid = xmlGetNode(id, "/configuration/setup/"); xnid = xmlNodeGet(id, "/configuration/setup/");
version = xmlGetNodeDouble(xnid, "version"); version = xmlNodeGetDouble(xnid, "version");
s = xmlGetNodeString(xnid, "author"); s = xmlNodeGetString(xnid, "author");
if (s) author = s; if (s) author = s;
free(s); free(s);
free(xnid); free(xnid);
@ -53,18 +53,18 @@ void xmlClose(const void *);
# #
# Get the Id of a node at the specified path # Get the Id of a node at the specified path
# e.g. # e.g.
# xnid = xmlGetNode(id, "/path/to/specified/node"); # xnid = xmlNodeGet(id, "/path/to/specified/node");
# #
void *xmlGetNode(const void *, const char *); void *xmlNodeGet(const void *, const char *);
void *xmlCopyNode(void *, const char *); void *xmlNodeCopy(void *, const char *);
# #
# Functions to walk the node tree and process them one by one. # Functions to walk the node tree and process them one by one.
# e.g. # e.g.
# xmid = xmlMarkId(id); # xmid = xmlMarkId(id);
# num = xmlGetNumNodes(xmid); # num = xmlNodeGetNum(xmid);
# for (i=0; i<num; i++) { # 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) { # if ((s = xmlGetString(xmid)) != 0) {
# printf("%s\n", s); # printf("%s\n", s);
# free(s); # free(s);
@ -74,22 +74,22 @@ void *xmlCopyNode(void *, const char *);
# free(xmid); # free(xmid);
# #
void *xmlMarkId(void *); void *xmlMarkId(void *);
unsigned int xmlGetNumNodes(void *, const char *); unsigned int xmlNodeGetNum(void *, const char *);
void *xmlGetNodeNum(const void *, void *, const char *, int); void *xmlNodeGetPos(const void *, void *, const char *, int);
# #
# Get the name of the current node # Get the name of the current node
# #
char *xmlGetNodeName(void *); char *xmlNodeGetName(void *);
size_t xmlCopyNodeName(void *, const char *, size_t); size_t xmlNodeCopyName(void *, const char *, size_t);
# #
# These functions work on the current node. # These functions work on the current node.
# e.g. # e.g.
# xnid = xmlGetNode(id, "/path/to/last/node"); # xnid = xmlNodeGet(id, "/path/to/last/node");
# i = xmlGetInt(xnid); # i = xmlGetInt(xnid);
# or # 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"); # if (xmlCompareString(xnid, "value") == 0) printf("We have a match!\n");
# #
long int xmlGetInt(void *); long int xmlGetInt(void *);
@ -101,13 +101,29 @@ int xmlCompareString(const void *, const char *);
# #
# These functions work on a specified node path # These functions work on a specified node path
# e.g. # e.g.
# d = xmlGetNodeDouble(id, "/path/to/node"); # d = xmlNodeGetDouble(id, "/path/to/node");
# or # or
# xnid = xmlGetNode(id, "/path/to"); # xnid = xmlNodeGet(id, "/path/to");
# i = xmlGetNodeInt(xnid, "node"); # i = xmlNodeGetInt(xnid, "node");
# #
long int xmlGetNodeInt(void *, const char *); long int xmlNodeGetInt(void *, const char *);
double xmlGetNodeDouble(void *, const char *); double xmlNodeGetDouble(void *, const char *);
char *xmlGetNodeString(void *, const char *); char *xmlNodeGetString(void *, const char *);
size_t xmlCopyNodeString(void *, const char *, char *, const size_t); size_t xmlNodeCopyString(void *, const char *, char *, const size_t);
int xmlCompareNodeString(const void *, const char *, const char *); 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. * map 'filename' and return a pointer to it.
*/ */
void *simple_mmap(int, unsigned int, SIMPLE_UNMMAP *); static void *simple_mmap(int, size_t, SIMPLE_UNMMAP *);
void simple_unmmap(SIMPLE_UNMMAP *); static void simple_unmmap(SIMPLE_UNMMAP *);
#define mmap(a,b,c,d,e,f) simple_mmap((e), (b), &un) #define mmap(a,b,c,d,e,f) simple_mmap((e), (b), &un)
#define munmap(a,b) simple_unmmap(&un) #define munmap(a,b) simple_unmmap(&un)
@ -58,28 +58,28 @@ void simple_unmmap(SIMPLE_UNMMAP *);
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <strings.h> /* strncasecmp */ #include <strings.h> /* strncasecmp */
#ifndef NDEBUG
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #endif
struct _xml_id struct _xml_id
{ {
char *name;
char *start;
size_t len; size_t len;
char *start;
char *name;
union { union {
size_t name_len;
int fd; int fd;
size_t len;
} node; } node;
}; };
static char *__xmlCopyNode(const char *, size_t, const char *); static char *__xmlNodeCopy(const char *, size_t, const char *);
static char *__xmlGetNodePath(const char *, size_t *, char **, size_t *); static char *__xmlNodeGetPath(const char *, size_t *, char **, size_t *);
static char *__xmlGetNode(const char *, size_t *, char **, size_t *, size_t *); static char *__xmlNodeGet(const char *, size_t *, char **, size_t *, size_t *);
static char *__xmlSkipComment(const char *, size_t); static char *__xmlCommentSkip(const char *, size_t);
static char *__xmlSkipInfo(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 *); static void *__xml_memncasecmp(const char *, size_t *, char **, size_t *);
#define PRINT(a, b, c) { \ #define PRINT(a, b, c) { \
@ -138,7 +138,7 @@ xmlClose(void *id)
} }
void * void *
xmlGetNode(const void *id, const char *path) xmlNodeGet(const void *id, const char *path)
{ {
struct _xml_id *xsid = 0; struct _xml_id *xsid = 0;
@ -151,7 +151,7 @@ xmlGetNode(const void *id, const char *path)
node = (char *)path; node = (char *)path;
len = xid->len; len = xid->len;
slen = strlen(path); slen = strlen(path);
ptr = __xmlGetNodePath(xid->start, &len, &node, &slen); ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
if (ptr) if (ptr)
{ {
xsid = malloc(sizeof(struct _xml_id)); xsid = malloc(sizeof(struct _xml_id));
@ -159,7 +159,7 @@ xmlGetNode(const void *id, const char *path)
{ {
xsid->len = len; xsid->len = len;
xsid->start = ptr; xsid->start = ptr;
xsid->node.len = slen; xsid->node.name_len = slen;
xsid->name = node; xsid->name = node;
} }
} }
@ -169,7 +169,7 @@ xmlGetNode(const void *id, const char *path)
} }
void * void *
xmlCopyNode(const void *id, const char *path) xmlNodeCopy(const void *id, const char *path)
{ {
struct _xml_id *xsid = 0; struct _xml_id *xsid = 0;
@ -182,7 +182,7 @@ xmlCopyNode(const void *id, const char *path)
node = (char *)path; node = (char *)path;
len = xid->len; len = xid->len;
slen = strlen(path); slen = strlen(path);
ptr = __xmlGetNodePath(xid->start, &len, &node, &slen); ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
if (ptr) if (ptr)
{ {
xsid = malloc(sizeof(struct _xml_id) + len); xsid = malloc(sizeof(struct _xml_id) + len);
@ -192,7 +192,7 @@ xmlCopyNode(const void *id, const char *path)
xsid->len = len; xsid->len = len;
xsid->start = p; xsid->start = p;
xsid->node.len = slen; xsid->node.name_len = slen;
xsid->name = node; xsid->name = node;
memcpy(xsid->start, ptr, len); memcpy(xsid->start, ptr, len);
@ -204,13 +204,13 @@ xmlCopyNode(const void *id, const char *path)
} }
char * char *
xmlGetNodeName(const void *id) xmlNodeGetName(const void *id)
{ {
struct _xml_id *xid = (struct _xml_id *)id; struct _xml_id *xid = (struct _xml_id *)id;
size_t len; size_t len;
char *ret; char *ret;
len = xid->node.len; len = xid->node.name_len;
ret = malloc(len+1); ret = malloc(len+1);
if (ret) if (ret)
{ {
@ -222,7 +222,7 @@ xmlGetNodeName(const void *id)
} }
size_t 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; struct _xml_id *xid = (struct _xml_id *)id;
size_t slen = 0; size_t slen = 0;
@ -230,7 +230,7 @@ xmlCopyNodeName(const void *id, char *buf, size_t len)
if (buf) if (buf)
{ {
slen = len-1; 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); memcpy(buf, xid->name, slen);
*(buf + slen) = 0; *(buf + slen) = 0;
} }
@ -239,7 +239,7 @@ xmlCopyNodeName(const void *id, char *buf, size_t len)
} }
unsigned int unsigned int
xmlGetNumNodes(const void *id, const char *path) xmlNodeGetNum(const void *id, const char *path)
{ {
struct _xml_id *xid = (struct _xml_id *)id; struct _xml_id *xid = (struct _xml_id *)id;
size_t num = 0; size_t num = 0;
@ -263,7 +263,7 @@ xmlGetNumNodes(const void *id, const char *path)
pathname++; pathname++;
slen -= pathname-nodename; slen -= pathname-nodename;
node = pathname; node = pathname;
p = __xmlGetNodePath(xid->start, &len, &node, &slen); p = __xmlNodeGetPath(xid->start, &len, &node, &slen);
} }
else else
{ {
@ -274,7 +274,7 @@ xmlGetNumNodes(const void *id, const char *path)
if (p) if (p)
{ {
char *node = nodename; 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 * 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; void *ret = 0;
@ -296,13 +296,13 @@ xmlGetNodeNum(const void *pid, void *id, const char *element, size_t num)
len = xpid->len; len = xpid->len;
slen = strlen(element); slen = strlen(element);
node = (char *)element; node = (char *)element;
ptr = __xmlGetNode(xpid->start, &len, &node, &slen, &num); ptr = __xmlNodeGet(xpid->start, &len, &node, &slen, &num);
if (ptr) if (ptr)
{ {
xid->len = len; xid->len = len;
xid->start = ptr; xid->start = ptr;
xid->name = node; xid->name = node;
xid->node.len = slen; xid->node.name_len = slen;
ret = xid; ret = xid;
} }
} }
@ -344,17 +344,18 @@ xmlGetString(const void *id)
} }
size_t 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; 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; char *ps, *pe, *pend;
int slen; size_t slen, nlen;
nlen = len-1; *buffer = '\0';
nlen = buflen-1;
ps = xid->start; ps = xid->start;
slen = xid->len; slen = xid->len;
pend = ps+slen; pend = ps+slen;
@ -367,12 +368,14 @@ xmlCopyString(const void *id, char *buf, size_t len)
if (nlen) if (nlen)
{ {
memcpy(buf, ps, nlen); if (nlen >= buflen) nlen = buflen-1;
*(buf+nlen) = 0; memcpy(buffer, ps, nlen);
*(buffer+nlen) = 0;
ret = nlen;
} }
} }
return nlen; return ret;
} }
int int
@ -400,14 +403,14 @@ xmlCompareString(const void *id, const char *s)
} }
char * char *
xmlGetNodeString(const void *id, const char *path) xmlNodeGetString(const void *id, const char *path)
{ {
struct _xml_id *xid = (struct _xml_id *)id; struct _xml_id *xid = (struct _xml_id *)id;
char *str = 0; char *str = 0;
if (xid && xid->len && path) if (xid && xid->len && path)
{ {
str = __xmlCopyNode(xid->start, xid->len, path); str = __xmlNodeCopy(xid->start, xid->len, path);
if (str) if (str)
{ {
char *ps, *pe, *pend; char *ps, *pe, *pend;
@ -432,45 +435,45 @@ xmlGetNodeString(const void *id, const char *path)
} }
size_t 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; struct _xml_id *xid = (struct _xml_id *)id;
size_t len = 0; size_t ret = 0;
if (xid && xid->len && path && buffer && buflen) if (xid && xid->len && path && buffer && buflen)
{ {
char *str, *node; char *str, *node;
size_t slen; size_t slen, nlen;
*buffer = '\0'; *buffer = '\0';
len = xid->len; nlen = xid->len;
slen = strlen(path); slen = strlen(path);
node = (char *)path; node = (char *)path;
str = __xmlGetNodePath(xid->start, &len, &node, &slen); str = __xmlNodeGetPath(xid->start, &nlen, &node, &slen);
if (str) if (str)
{ {
char *ps, *pe; char *ps, *pe;
ps = str; ps = str;
pe = ps+len-1; pe = ps+nlen-1;
while ((ps<pe) && isspace(*ps)) ps++; while ((ps<pe) && isspace(*ps)) ps++;
while ((pe>ps) && isspace(*pe)) pe--; while ((pe>ps) && isspace(*pe)) pe--;
len = (pe-ps)+1; nlen = (pe-ps)+1;
if (len >= buflen) len = buflen-1; if (nlen >= buflen) nlen = buflen-1;
memcpy(buffer, ps, len); memcpy(buffer, ps, nlen);
str = buffer + len; *(buffer + nlen) = '\0';
*str = '\0'; ret = nlen;
} }
} }
return len; return ret;
} }
int 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; struct _xml_id *xid = (struct _xml_id *)id;
int ret = -1; 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)) if (xid && xid->len && path && s && (strlen(s) > 0))
{ {
char *node, *str, *ps, *pe; char *node, *str, *ps, *pe;
size_t len, slen, i; size_t len, slen;
len = xid->len; len = xid->len;
slen = strlen(path); slen = strlen(path);
node = (char *)path; node = (char *)path;
str = __xmlGetNodePath(xid->start, &len, &node, &slen); str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
if (str) if (str)
{ {
ps = str; ps = str;
@ -517,7 +520,7 @@ xmlGetInt(const void *id)
} }
long int long int
xmlGetNodeInt(const void *id, const char *path) xmlNodeGetInt(const void *id, const char *path)
{ {
struct _xml_id *xid = (struct _xml_id *)id; struct _xml_id *xid = (struct _xml_id *)id;
long int li = 0; long int li = 0;
@ -530,7 +533,7 @@ xmlGetNodeInt(const void *id, const char *path)
len = xid->len; len = xid->len;
slen = strlen(path); slen = strlen(path);
node = (char *)path; node = (char *)path;
str = __xmlGetNodePath(xid->start, &len, &node, &slen); str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
if (str) if (str)
{ {
char *end = str+len; char *end = str+len;
@ -557,7 +560,7 @@ xmlGetDouble(const void *id)
} }
double double
xmlGetNodeDouble(const void *id, const char *path) xmlNodeGetDouble(const void *id, const char *path)
{ {
struct _xml_id *xid = (struct _xml_id *)id; struct _xml_id *xid = (struct _xml_id *)id;
double d = 0.0; double d = 0.0;
@ -570,7 +573,7 @@ xmlGetNodeDouble(const void *id, const char *path)
len = xid->len; len = xid->len;
slen = strlen(path); slen = strlen(path);
node = (char *)path; node = (char *)path;
str = __xmlGetNodePath(xid->start, &len, &node, &slen); str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
if (str) if (str)
{ {
char *end = str+len; char *end = str+len;
@ -598,10 +601,265 @@ xmlMarkId(const void *id)
return (void *)xmid; 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 * 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; char *node, *p, *ret = 0;
size_t rlen, slen; size_t rlen, slen;
@ -609,7 +867,7 @@ __xmlCopyNode(const char *start, size_t len, const char *path)
rlen = len; rlen = len;
slen = strlen(path); slen = strlen(path);
node = (char *)path; node = (char *)path;
p = __xmlGetNodePath(start, &rlen, &node, &slen); p = __xmlNodeGetPath(start, &rlen, &node, &slen);
if (p && rlen) if (p && rlen)
{ {
ret = calloc(1, rlen+1); ret = calloc(1, rlen+1);
@ -620,7 +878,7 @@ __xmlCopyNode(const char *start, size_t len, const char *path)
} }
char * 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 *node;
char *ret = 0; char *ret = 0;
@ -649,11 +907,11 @@ __xmlGetNodePath(const char *start, size_t *len, char **name, size_t *plen)
else plen = path++ - node; else plen = path++ - node;
num = 0; num = 0;
ret = __xmlGetNode(start, len, &node, &plen, &num); ret = __xmlNodeGet(start, len, &node, &plen, &num);
if (ret && path) if (ret && path)
{ {
plen = slen - (path - *name); plen = slen - (path - *name);
ret = __xmlGetNodePath(ret, len, &path, &plen); ret = __xmlNodeGetPath(ret, len, &path, &plen);
} }
*name = path; *name = path;
@ -663,13 +921,13 @@ __xmlGetNodePath(const char *start, size_t *len, char **name, size_t *plen)
} }
char * 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 *new, *cur, *ne, *ret = 0;
char *element, *start_tag=0;
size_t restlen, elementlen; size_t restlen, elementlen;
size_t retlen = 0; size_t retlen = 0;
int found, num; int found, num;
char *element;
assert (start != 0); assert (start != 0);
assert (len != 0); assert (len != 0);
@ -701,7 +959,7 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
if (*cur == '!') if (*cur == '!')
{ {
new = __xmlSkipComment(cur, restlen); new = __xmlCommentSkip(cur, restlen);
if (!new) return 0; if (!new) return 0;
restlen -= new-cur; restlen -= new-cur;
cur = new; cur = new;
@ -709,7 +967,7 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
} }
else if (*cur == '?') else if (*cur == '?')
{ {
new = __xmlSkipInfo(cur, restlen); new = __xmlInfoSkip(cur, restlen);
if (!new) return 0; if (!new) return 0;
restlen -= new-cur; restlen -= new-cur;
@ -723,7 +981,12 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
if (new) if (new)
{ {
retlen = elementlen; retlen = elementlen;
if (found == num ) ret = new+1; if (found == num )
{
ret = new+1;
start_tag = element;
}
else start_tag = 0;
} }
else 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 nlen = 1;
size_t pos = -1; size_t pos = -1;
new = __xmlGetNode(cur, &slen, &node, &nlen, &pos); new = __xmlNodeGet(cur, &slen, &node, &nlen, &pos);
if (!new) if (!new)
{ {
if (slen == restlen) return 0; 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 (!strncasecmp(new+2, element, elementlen))
{ {
if (found == num) *len = new-ret; if (found == num)
*name = element; {
assert(start_tag != 0);
*len = new-ret;
*name = start_tag;
}
found++; found++;
} }
@ -788,7 +1055,7 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
} }
char * char *
__xmlSkipComment(const char *start, size_t len) __xmlCommentSkip(const char *start, size_t len)
{ {
char *cur, *new; char *cur, *new;
@ -825,7 +1092,7 @@ __xmlSkipComment(const char *start, size_t len)
} }
char * char *
__xmlSkipInfo(const char *start, size_t len) __xmlInfoSkip(const char *start, size_t len)
{ {
char *cur, *new; 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 ) #define NOCASECMP(a,b) ( ((a)^(b)) & 0xdf )
void * void *
__xml_memncasecmp(const char *haystack, size_t *haystacklen, __xml_memncasecmp(const char *haystack, size_t *haystacklen,
@ -952,7 +1182,7 @@ __xml_memncasecmp(const char *haystack, size_t *haystacklen,
*/ */
void * void *
simple_mmap(int fd, unsigned int length, SIMPLE_UNMMAP *un) simple_mmap(int fd, size_t length, SIMPLE_UNMMAP *un)
{ {
HANDLE f; HANDLE f;
HANDLE m; HANDLE m;
@ -971,8 +1201,6 @@ simple_mmap(int fd, unsigned int length, SIMPLE_UNMMAP *un)
return NULL; return NULL;
} }
if (n) *n = GetFileSize(f, NULL);
if (un) if (un)
{ {
un->m = m; un->m = m;

View file

@ -29,7 +29,7 @@
#define __XML_CONFIG 1 #define __XML_CONFIG 1
/** /**
* Open an XML file for processing * Open an XML file for processing.
* *
* @param fname path to the file * @param fname path to the file
* @return XML-id which is used for further processing * @return XML-id which is used for further processing
@ -37,7 +37,7 @@
void *xmlOpen(const char *); 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 * @param xid XML-id
*/ */
@ -47,22 +47,7 @@ void xmlClose(void *);
/** /**
* Locate a subsection of the xml tree for further processing. * Locate a subsection of the xml tree for further processing.
* This adds processing speed since the reuired nodes will only be searched * 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
*
* @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
* *
* The memory allocated for the XML-subsection-id has to be freed by the * The memory allocated for the XML-subsection-id has to be freed by the
* calling process. * calling process.
@ -71,41 +56,71 @@ void *xmlGetNode(const void *, const char *);
* @param node path to the node containing the subsection * @param node path to the node containing the subsection
* @return XML-subsection-id for further processing * @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. * 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 * @param xid XML-id
* @return a newly alocated string containing the node name * @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 xid XML-id
* @param buffer the buffer to copy the string to * @param buffer the buffer to copy the string to
* @param buflen length of the destination buffer * @param buflen length of the destination buffer
* @return the length of the node name * @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 xid XML-id
* @param path path to the xml node * @param path path to the xml node
* @return the number count of the nodename * @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. * 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 pid XML-id of the parent node of this node
* @param xid XML-id * @param xid XML-id
@ -113,12 +128,12 @@ unsigned int xmlGetNumNodes(const void *, const char *);
* @param num specify which occurence to return * @param num specify which occurence to return
* @return XML-subsection-id for further processing or NULL if unsuccessful * @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. * 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 * @param xid XML-id
* @return a newly alocated string containing the contents of the node * @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. * Get a string of characters from the current node.
* This function has the advantage of not allocating its own return buffer, * This function has the advantage of not allocating its own return buffer,
* keeping the memory management to an absolute minimum but the disadvantage * 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 xid XML-id
* @param buffer the buffer to copy the string to * @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. * 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 xid XML-id
* @param str the string to compare to * @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. * 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 xid XML-id
* @param path path to the xml node * @param path path to the xml node
* @return a newly alocated string containing the contents of the 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. * Get a string of characters from a specified xml path.
* This function has the advantage of not allocating its own return buffer, * This function has the advantage of not allocating its own return buffer,
* keeping the memory management to an absolute minimum but the disadvantage * 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 xid XML-id
* @param path path to the xml node * @param path path to the xml node
@ -172,11 +187,11 @@ char *xmlGetNodeString(const void *, const char *);
* @param buflen length of the destination buffer * @param buflen length of the destination buffer
* @return the length of the string * @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. * 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 xid XML-id
* @param path path to the xml node to compare to * @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 * of the node is found, respectively, to be less than, to match, or be greater
* than str * 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 * @param xid XML-id
* @return the contents of the node converted to an integer value * @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 *); 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 xid XML-id
* @param path path to the xml node * @param path path to the xml node
* @return the contents of the node converted to an integer value * @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 * @param xid XML-id
* @return the contents of the node converted to a double value * @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 *); 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 xid XML-id
* @param path path to the xml node * @param path path to the xml node
* @return the contents of the node converted to a double value * @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 * Get the double value from the named attribute.
* refference XML-id.
* The returned XML-id has to be freed by the calling process
* *
* @param xid reference XML-id * @param xid XML-id
* @return a copy of the reference 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 */ #endif /* __XML_CONFIG */

View file

@ -1,7 +1,9 @@
#include <stdio.h> #include <stdio.h>
#include <strings.h>
#include <stdlib.h> #define _GNU_SOURCE
#include <string.h> #include <string.h>
#include <strings.h>
#include <assert.h>
#include "xml.h" #include "xml.h"
@ -13,6 +15,7 @@ static char *_element = 0;
static char *_value = 0; static char *_value = 0;
static char *_root = 0; static char *_root = 0;
static char *_print = 0; static char *_print = 0;
static char *_attribute = 0;
static int print_filenames = 0; static int print_filenames = 0;
static void free_and_exit(int i); static void free_and_exit(int i);
@ -29,30 +32,35 @@ show_help ()
printf("usage: xmlgrep [options] [file ...]\n\n"); printf("usage: xmlgrep [options] [file ...]\n\n");
printf("Options:\n"); printf("Options:\n");
printf("\t-h\t\tshow this help message\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-e <id>\t\tshow sections that contain this element\n");
printf("\t-p <id>\t\tprint this element as the output\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-r <path>\tspecify the XML search root\n");
printf("\t-v <string>\tshow sections where one of the elements has this "); printf("\t-v <string>\tfilter sections that contain this vale\n\n");
printf("value\n\n");
printf(" To print the contents of the 'type' element of the XML section "); 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("that begins\n at '/printer/output' use the following command:\n\n");
printf("syntax:\n\n\txmlgrep -r /printer/output -p type sample.xml\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(" 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\txmlgrep -r /printer/output -e driver -v generic sample.xml");
printf("\n\n"); printf("\n\n");
free_and_exit(0); free_and_exit(0);
} }
void void
free_and_exit(int i) free_and_exit(int ret)
{ {
if (_root && _root != _static_root) free(_root); if (_root && _root != _static_root) free(_root);
if (_element && _element != _static_element) free(_element); if (_element && _element != _static_element) free(_element);
if (_value) free(_value); if (_value) free(_value);
if (_print) free(_print); if (_print) free(_print);
if (_attribute) free(_attribute);
if (_filenames) if (_filenames)
{ {
unsigned int i;
for (i=0; i < _fcount; i++) for (i=0; i < _fcount; i++)
{ {
if (_filenames[i]) if (_filenames[i])
@ -64,17 +72,18 @@ free_and_exit(int i)
free(_filenames); free(_filenames);
} }
exit(i); exit(ret);
} }
int int
parse_option(char **args, int n, int max) parse_option(char **args, int n, int max)
{ {
char *opt, *arg = 0; char *opt, *arg = 0;
int sz; unsigned int alen = 0;
unsigned int olen;
opt = args[n]; opt = args[n];
if (opt[0] == '-' && opt[1] == '-') if (strncmp(opt, "--", 2) == 0)
opt++; opt++;
if ((arg = strchr(opt, '=')) != NULL) if ((arg = strchr(opt, '=')) != NULL)
@ -90,36 +99,52 @@ parse_option(char **args, int n, int max)
#endif #endif
} }
sz = strlen(opt); olen = strlen(opt);
if (strncmp(opt, "-help", sz) == 0) if (strncmp(opt, "-help", olen) == 0)
{ {
show_help(); show_help();
} }
else if (strncmp(opt, "-root", sz) == 0) else if (strncmp(opt, "-root", olen) == 0)
{ {
if (arg == 0) SHOW_NOVAL(opt); if (arg == 0) SHOW_NOVAL(opt);
_root = strdup(arg); alen = strlen(arg)+1;
_root = malloc(alen);
memcpy(_root, arg, alen);
return 2; return 2;
} }
else if (strncmp(opt, "-element", sz) == 0) else if (strncmp(opt, "-element", olen) == 0)
{ {
if (arg == 0) SHOW_NOVAL(opt); if (arg == 0) SHOW_NOVAL(opt);
_element = strdup(arg); alen = strlen(arg)+1;
_element = malloc(alen);
memcpy(_element, arg, alen);
return 2; return 2;
} }
else if (strncmp(opt, "-value", sz) == 0) else if (strncmp(opt, "-value", olen) == 0)
{ {
if (arg == 0) SHOW_NOVAL(opt); if (arg == 0) SHOW_NOVAL(opt);
_value = strdup(arg); alen = strlen(arg)+1;
_value = malloc(alen);
memcpy(_value, arg, alen);
return 2; return 2;
} }
else if (strncmp(opt, "-print", sz) == 0) else if (strncmp(opt, "-print", olen) == 0)
{ {
if (arg == 0) SHOW_NOVAL(opt); if (arg == 0) SHOW_NOVAL(opt);
_print = strdup(arg); alen = strlen(arg)+1;
_print = malloc(alen);
memcpy(_print, arg, alen);
return 2; 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 */ { /* undocumented test argument */
print_filenames = 1; print_filenames = 1;
return 1; return 1;
@ -147,7 +172,9 @@ parse_option(char **args, int n, int max)
_filenames = ptr; _filenames = ptr;
} }
_filenames[pos] = strdup(opt); alen = strlen(opt)+1;
_filenames[pos] = malloc(alen);
memcpy(_filenames[pos], opt, alen);
} }
return 1; return 1;
@ -162,30 +189,42 @@ void walk_the_tree(size_t num, void *xid, char *tree)
void *xmid = xmlMarkId(xid); void *xmid = xmlMarkId(xid);
if (xmid && _print) if (xmid && _print)
{ {
no_elements = xmlGetNumNodes(xid, _print); no_elements = xmlNodeGetNum(xid, _print);
for (i=0; i<no_elements; i++) 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); xmlCopyString(xmid, (char *)&value, 1024);
printf("%s: <%s>%s</%s>\n", if (_value && _attribute)
_filenames[num], _print, value, _print); {
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); free(xmid);
} }
else if (xmid && _value) else if (xmid && _value)
{ {
no_elements = xmlGetNumNodes(xmid, _element); no_elements = xmlNodeGetNum(xmid, _element);
for (i=0; i<no_elements; i++) for (i=0; i<no_elements; i++)
{ {
if (xmlGetNodeNum(xid, xmid, _element, i) != 0) if (xmlNodeGetPos(xid, xmid, _element, i) != 0)
{ {
char nodename[64]; char nodename[64];
xmlCopyNodeName(xmid, (char *)&nodename, 64); xmlNodeCopyName(xmid, (char *)&nodename, 64);
if (xmlCompareString(xmid, _value) == 0) if (xmlCompareString(xmid, _value) == 0)
{ {
printf("%s: <%s>%s</%s>\n", printf("%s: <%s>%s</%s>\n",
@ -199,16 +238,16 @@ void walk_the_tree(size_t num, void *xid, char *tree)
{ {
char parentname[64]; 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++) for (i=0; i<no_elements; i++)
{ {
if (xmlGetNodeNum(xid, xmid, _element, i) != 0) if (xmlNodeGetPos(xid, xmid, _element, i) != 0)
{ {
char nodename[64]; char nodename[64];
xmlCopyNodeName(xmid, (char *)&nodename, 64); xmlNodeCopyName(xmid, (char *)&nodename, 64);
if (strncasecmp((char *)&nodename, _element, 64) == 0) if (strncasecmp((char *)&nodename, _element, 64) == 0)
{ {
char value[64]; char value[64];
@ -235,16 +274,22 @@ void walk_the_tree(size_t num, void *xid, char *tree)
xmid = xmlMarkId(xid); xmid = xmlMarkId(xid);
if (xmid) 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++) 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); walk_the_tree(num, xmid, next);
} }
if (next) *--next = '/'; if (next)
{
*--next = '/';
}
free(xmid); free(xmid);
} }
@ -275,7 +320,7 @@ void grep_file(unsigned num)
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
int i; unsigned int i;
if (argc == 1) if (argc == 1)
show_help(); show_help();