Point to the new location of the ZeroXML library that contains xmlgrep
This commit is contained in:
parent
2d267a5782
commit
ecccfeb18a
11 changed files with 3 additions and 3872 deletions
|
@ -1,111 +0,0 @@
|
||||||
24-05-2009
|
|
||||||
* Add a node cache that can be enabled at compile time.
|
|
||||||
the node cache prevents recursively walking the xml tree over and over
|
|
||||||
again to find the specified nodes.
|
|
||||||
|
|
||||||
05-05-2009
|
|
||||||
* Various bugfixes, required to get fgrun working
|
|
||||||
* add testxml as sort of a stress test application
|
|
||||||
|
|
||||||
30-04-2009
|
|
||||||
* Add support for CDATA
|
|
||||||
* Fix an off by one problem.
|
|
||||||
|
|
||||||
28-04-2009
|
|
||||||
* changes to the code to allow walking the xml-tree using "*" as a node name
|
|
||||||
* add printxml, an example utility that walks an xml-tree and prints it
|
|
||||||
contenst
|
|
||||||
|
|
||||||
27-04-2009
|
|
||||||
* add xmlInitBuffer() for processing of a preallocated buffer
|
|
||||||
* add xmlErrorGetColumnNo to get the column number of the syntax error
|
|
||||||
* pass an error at a higher level to lower levels
|
|
||||||
* detect a number of extra syntax errors
|
|
||||||
|
|
||||||
26-04-2009
|
|
||||||
* add support for comments inside xml-tags, e.g.: <test><!-- --></test>
|
|
||||||
|
|
||||||
25-04-2009
|
|
||||||
* add support for self-contained tags like <test/>
|
|
||||||
* fix a problem if a file could not be mmaped
|
|
||||||
* add a few comments which hopefully makes the code easier to understand
|
|
||||||
* code cleanups
|
|
||||||
|
|
||||||
20-04-2009
|
|
||||||
* fix a case where a single-element root path (e.g. "/printer") would not
|
|
||||||
pass xmlNodeGetPath
|
|
||||||
* fix a problem where attributes or elements starting with the same letter
|
|
||||||
sequence could give a false negative result
|
|
||||||
* Add a 'clear' attribute to the xmlErrorGet functions that indicates whether
|
|
||||||
the error should be cleared or not
|
|
||||||
* detect more xml syntax errors
|
|
||||||
|
|
||||||
18-04-2009
|
|
||||||
* Make the code compiler correctly under windows
|
|
||||||
* Introduce a root-node that can hold extra information which is necessary
|
|
||||||
for thread safety under windows
|
|
||||||
* Add xmlErrorGetString, xmlErrorGetLineNo for syntax error detetction
|
|
||||||
* Add xmlErrGetNo for detection of, and clearing the last error
|
|
||||||
|
|
||||||
16-04-2009
|
|
||||||
* 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
|
|
||||||
* xmlgrep now also works when only the -e options is specified
|
|
||||||
* fix xmlgrep to show the correct node-name (it reported the parent
|
|
||||||
node-name in the previous version)
|
|
||||||
|
|
||||||
20-07-2008
|
|
||||||
* fix __xmlSkipComment to properly find the end of comment tag.
|
|
||||||
* add the xmlGetNodeName and xmlCopyNodeName functions
|
|
||||||
* add the xmlCopyString function
|
|
||||||
* clean up some code
|
|
||||||
|
|
||||||
19-07-2008
|
|
||||||
* rewrite the code to always recursively walk the node tree when searching
|
|
||||||
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 verion
|
|
||||||
* rename xmlGetElement to xmlGetNodeNum and add the possibility to request
|
|
||||||
the nth node with this name
|
|
||||||
* rename xmlGetNumElements to xmlGetNumNodes
|
|
||||||
|
|
||||||
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 furute use
|
|
||||||
* add preliminary support for wildcards in the search path ('*' and '?')
|
|
||||||
|
|
||||||
01-07-2008
|
|
||||||
* fix a problem caused by removing the last unnecessary alloc
|
|
||||||
* strip leading-, and trailing spaces from the string before comparing
|
|
||||||
* fix a problem where trailing spaces weren't removed
|
|
||||||
|
|
||||||
30-06-2008:
|
|
||||||
* some small changes; fix some typo's and fix a small memory leak
|
|
||||||
* update the documentation in README
|
|
||||||
* remove the last unnecessary alloc
|
|
||||||
|
|
||||||
29-06-2008:
|
|
||||||
* rename xmlGet(Int/Double/String) to xmlGetNode(Int/Double/String)
|
|
||||||
* add new xmlGet(Int/Double/String) functions
|
|
||||||
* rename xmlCompareString to xmlCompareNodeString for consistency
|
|
||||||
* rename xmlCompareElement to xmlCompareString for consistency
|
|
||||||
* add a README file with short examples of various functions
|
|
||||||
|
|
||||||
27-06-2008:
|
|
||||||
* removed some memory allocation in xmlGetNode and XMLGetNextElement
|
|
||||||
* use the file-size for mmap and remove the root node from the xml-id
|
|
||||||
* rearrange xmlGetNode to work with complicated xml files
|
|
||||||
* add the xmlMarkId function to save the id before using xmlGetNextElement
|
|
||||||
* speed up xmlGetNextId
|
|
||||||
|
|
||||||
23-06-2008: Initial release
|
|
|
@ -1,146 +1,6 @@
|
||||||
This library is specially designed for reading xml configuration files and
|
|
||||||
to be as low on memory management as possible. Modifying or writing xml files
|
|
||||||
is not planned for the future. In most situations being able to gather data
|
|
||||||
by reading an xml file is more than enough and the read-only decision
|
|
||||||
provides a number of advantages over a one-size fits all approach. For isntance
|
|
||||||
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
|
The xmlgrep utility is part op the ZeroXML package which is now hosted at:
|
||||||
to a memory region. The only places where memory is allocated is when creating
|
http://www.adalin.com
|
||||||
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,
|
Any further development will take place there.
|
||||||
read every parameter one by one and close the id again.
|
|
||||||
{
|
|
||||||
void *xid;
|
|
||||||
|
|
||||||
xid = xmlOpen("/tmp/file.xml");
|
|
||||||
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
|
|
||||||
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.
|
|
||||||
{
|
|
||||||
void *xnid;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
xnid = xmlNodeGet(id, "/configuration/setup/");
|
|
||||||
version = xmlNodeGetDouble(xnid, "version");
|
|
||||||
s = xmlNodeGetString(xnid, "author");
|
|
||||||
if (s) author = s;
|
|
||||||
free(s);
|
|
||||||
free(xnid);
|
|
||||||
}
|
|
||||||
|
|
||||||
Overview of the available functions:
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Functions to Open and Close the XML file
|
|
||||||
# e.g.
|
|
||||||
# id = xmlOpen("/tmp/file.xml");
|
|
||||||
# xmlClose(id);
|
|
||||||
#
|
|
||||||
void *xmlOpen(const char *filename);
|
|
||||||
void *xmlInitBuffer(const char *buffer, size_t size);
|
|
||||||
void xmlClose(void *xid);
|
|
||||||
|
|
||||||
#
|
|
||||||
# Get the Id of a node at the specified path
|
|
||||||
# e.g.
|
|
||||||
# xnid = xmlNodeGet(id, "/path/to/specified/node");
|
|
||||||
#
|
|
||||||
void *xmlNodeGet(const void *xid, const char *path);
|
|
||||||
void *xmlNodeCopy(const void *xid, const char *path);
|
|
||||||
|
|
||||||
#
|
|
||||||
# Functions to walk the node tree and process them one by one.
|
|
||||||
# e.g.
|
|
||||||
# xmid = xmlMarkId(id);
|
|
||||||
# num = xmlNodeGetNum(xmid, "node");
|
|
||||||
# for (i=0; i<num; i++) {
|
|
||||||
# if (xmlNodeGetPos(id, xmid, "element", i) != 0) {
|
|
||||||
# if ((s = xmlGetString(xmid)) != 0) {
|
|
||||||
# printf("%s\n", s);
|
|
||||||
# free(s);
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# free(xmid);
|
|
||||||
#
|
|
||||||
void *xmlMarkId(const void *xid);
|
|
||||||
unsigned int xmlNodeGetNum(const void *xid, const char *path);
|
|
||||||
void *xmlNodeGetPos(const void *pid, void *xid, const char *element, int pos);
|
|
||||||
|
|
||||||
#
|
|
||||||
# Get the name of the current node
|
|
||||||
#
|
|
||||||
char *xmlNodeGetName(const void *xid);
|
|
||||||
size_t xmlNodeCopyName(const void *xid, const char *buffer, size_t size);
|
|
||||||
|
|
||||||
#
|
|
||||||
# These functions work on the current node.
|
|
||||||
# e.g.
|
|
||||||
# xnid = xmlNodeGet(id, "/path/to/last/node");
|
|
||||||
# i = xmlGetInt(xnid);
|
|
||||||
# or
|
|
||||||
# xnid = xmlNodeGet(id, "/path/to/specified/node");
|
|
||||||
# if (xmlCompareString(xnid, "value") == 0) printf("We have a match!\n");
|
|
||||||
#
|
|
||||||
long int xmlGetInt(const void *xid);
|
|
||||||
double xmlGetDouble(const void *xid);
|
|
||||||
char *xmlGetString(const void *xid);
|
|
||||||
size_t xmlCopyString(const void *xid, char *buffer, const size_t size);
|
|
||||||
int xmlCompareString(const void *xid, const char *str);
|
|
||||||
|
|
||||||
#
|
|
||||||
# These functions work on a specified node path
|
|
||||||
# e.g.
|
|
||||||
# d = xmlNodeGetDouble(id, "/path/to/node");
|
|
||||||
# or
|
|
||||||
# xnid = xmlNodeGet(id, "/path/to");
|
|
||||||
# i = xmlNodeGetInt(xnid, "node");
|
|
||||||
#
|
|
||||||
long int xmlNodeGetInt(const void *xid, const char *path);
|
|
||||||
double xmlNodeGetDouble(const void *xid, const char *path);
|
|
||||||
char *xmlNodeGetString(const void *xid, const char *path);
|
|
||||||
size_t xmlNodeCopyString(const void *xid, const char *path,
|
|
||||||
char *buffer, const size_t size);
|
|
||||||
int xmlNodeCompareString(const void *xid, const char *path, const char *str);
|
|
||||||
|
|
||||||
#
|
|
||||||
# These functions work on a specified atribute
|
|
||||||
# e.g.
|
|
||||||
# i = xmlAttributeGetInt(id, "n");
|
|
||||||
#
|
|
||||||
# or
|
|
||||||
# s = xmlAttributeGetString(id, "type");
|
|
||||||
# if (s) printf("node is of type '%s'\n", s);
|
|
||||||
# free(s);
|
|
||||||
#
|
|
||||||
long int xmlAttributeGetInt(const void *xid, const char *attr);
|
|
||||||
double xmlAttributeGetDouble(const void *xid, const char *attr);
|
|
||||||
char *xmlAttributeGetString(const void *xid, const char *attr);
|
|
||||||
size_t xmlAttributeCopyString(const void *xid, const char *attr,
|
|
||||||
const char *buffer, size_t size);
|
|
||||||
int xmlAttributeCompareString(const void *xid, const char *attr,
|
|
||||||
const char *str);
|
|
||||||
|
|
||||||
#
|
|
||||||
# Error detection and reporting functions
|
|
||||||
#
|
|
||||||
# char *err_str = xmlErrorGetString(id, 0);
|
|
||||||
# size_t err_lineno = xmlErrorGetLineNo(id, 0);
|
|
||||||
# int err = xmlErrorGetNo(id, 1); /* clear last error */
|
|
||||||
# if (err) printf("Error #%i at line %u: '%s'\n", err, err_lineno, err_str);
|
|
||||||
#
|
|
||||||
int xmlErrorGetNo(const void *xid, int clear);
|
|
||||||
size_t xmlErrorGetLineNo(const void *xid, int clear);
|
|
||||||
size_t xmlErrorGetColumnNo(const void *xid, int clear);
|
|
||||||
const char *xmlErrorGetString(const void *xid, int clear);
|
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
#include "xml.h"
|
|
||||||
|
|
||||||
void print_xml(void *, char *, unsigned int);
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc < 1)
|
|
||||||
{
|
|
||||||
printf("usage: printtree <filename>\n\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
void *rid;
|
|
||||||
|
|
||||||
rid = xmlOpen(argv[1]);
|
|
||||||
if (xmlErrorGetNo(rid, 0) != XML_NO_ERROR)
|
|
||||||
{
|
|
||||||
printf("%s\n", xmlErrorGetString(rid, 1));
|
|
||||||
}
|
|
||||||
else if (rid)
|
|
||||||
{
|
|
||||||
unsigned int i, num;
|
|
||||||
void *xid;
|
|
||||||
|
|
||||||
xid = xmlMarkId(rid);
|
|
||||||
num = xmlNodeGetNum(xid, "*");
|
|
||||||
for (i=0; i<num; i++)
|
|
||||||
{
|
|
||||||
if (xmlNodeGetPos(rid, xid, "*", i) != 0)
|
|
||||||
{
|
|
||||||
char name[4096] = "";
|
|
||||||
print_xml(xid, (char *)&name, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(xid);
|
|
||||||
|
|
||||||
xmlClose(rid);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Error while opening file for reading: '%s'\n", argv[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_xml(void *id, char *name, unsigned int len)
|
|
||||||
{
|
|
||||||
void *xid = xmlMarkId(id);
|
|
||||||
unsigned int i, num;
|
|
||||||
|
|
||||||
num = xmlNodeGetNum(xid, "*");
|
|
||||||
if (num == 0)
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
s = xmlGetString(xid);
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
name[len] = 0;
|
|
||||||
printf("%s = %s\n", name, s);
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned int i, q;
|
|
||||||
|
|
||||||
name[len++] = '/';
|
|
||||||
for (i=0; i<num; i++)
|
|
||||||
{
|
|
||||||
if (xmlNodeGetPos(id, xid, "*", i) != 0)
|
|
||||||
{
|
|
||||||
unsigned int res, i = 4096 - len;
|
|
||||||
res = xmlNodeCopyName(xid, (char *)&name[len], i);
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
unsigned int index = xmlAttributeGetInt(xid, "n");
|
|
||||||
if (index)
|
|
||||||
{
|
|
||||||
unsigned int pos = len+res;
|
|
||||||
|
|
||||||
name[pos++] = '[';
|
|
||||||
i = snprintf((char *)&name[pos], 4096-pos, "%i", index);
|
|
||||||
name[pos+i] = ']';
|
|
||||||
res += i+2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print_xml(xid, name, len+res);
|
|
||||||
}
|
|
||||||
else printf("error\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
#include "xml.h"
|
|
||||||
|
|
||||||
void print_xml(void *);
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc < 1)
|
|
||||||
{
|
|
||||||
printf("usage: printxml <filename>\n\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
void *rid;
|
|
||||||
|
|
||||||
rid = xmlOpen(argv[1]);
|
|
||||||
if (xmlErrorGetNo(rid, 0) != XML_NO_ERROR)
|
|
||||||
{
|
|
||||||
printf("%s\n", xmlErrorGetString(rid, 1));
|
|
||||||
}
|
|
||||||
else if (rid)
|
|
||||||
{
|
|
||||||
unsigned int i, num;
|
|
||||||
void *xid;
|
|
||||||
|
|
||||||
xid = xmlMarkId(rid);
|
|
||||||
num = xmlNodeGetNum(xid, "*");
|
|
||||||
for (i=0; i<num; i++)
|
|
||||||
{
|
|
||||||
if (xmlNodeGetPos(rid, xid, "*", i) != 0)
|
|
||||||
{
|
|
||||||
char name[256];
|
|
||||||
xmlNodeCopyName(xid, (char *)&name, 256);
|
|
||||||
printf("<%s>\n", name);
|
|
||||||
print_xml(xid);
|
|
||||||
printf("\n</%s>\n", name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(xid);
|
|
||||||
|
|
||||||
xmlClose(rid);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Error while opening file for reading: '%s'\n", argv[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_xml(void *id)
|
|
||||||
{
|
|
||||||
static int level = 1;
|
|
||||||
void *xid = xmlMarkId(id);
|
|
||||||
unsigned int i, num;
|
|
||||||
|
|
||||||
num = xmlNodeGetNum(xid, "*");
|
|
||||||
if (num == 0)
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
s = xmlGetString(xid);
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
printf("%s", s);
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned int i, q;
|
|
||||||
for (i=0; i<num; i++)
|
|
||||||
{
|
|
||||||
if (xmlNodeGetPos(id, xid, "*", i) != 0)
|
|
||||||
{
|
|
||||||
char name[256];
|
|
||||||
int r;
|
|
||||||
|
|
||||||
xmlNodeCopyName(xid, (char *)&name, 256);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
for(q=0; q<level; q++) printf(" ");
|
|
||||||
printf("<%s>", name);
|
|
||||||
level++;
|
|
||||||
print_xml(xid);
|
|
||||||
level--;
|
|
||||||
printf("</%s>", name);
|
|
||||||
}
|
|
||||||
else printf("error\n");
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
for(q=1; q<level; q++) printf(" ");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<Configuration>
|
|
||||||
|
|
||||||
<output>
|
|
||||||
<frequency-hz>48000</frequency-hz>
|
|
||||||
<interval-hz>20</interval-hz>
|
|
||||||
<num-speakers>2</num-speakers>
|
|
||||||
|
|
||||||
<tmp><!-- --></tmp>
|
|
||||||
<test n="0" ëlémènt="bjôrn"/>
|
|
||||||
<test n="1"/>
|
|
||||||
<test n="2"/>
|
|
||||||
|
|
||||||
<menu><name>* Traffic, # taxiing to runway (.</name></menu>
|
|
||||||
<sample><test> * Traffic, # taxiing to runway (. </test></sample>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
- x is positive to the right
|
|
||||||
- y is positive upwards
|
|
||||||
- z is positive backwards
|
|
||||||
-->
|
|
||||||
<speaker n="0">
|
|
||||||
<channel>0</channel>
|
|
||||||
<volume-norm>1.0</volume-norm>
|
|
||||||
<desc><!-- empty --></desc>
|
|
||||||
</speaker>
|
|
||||||
|
|
||||||
<speaker n="1">
|
|
||||||
<channel>1</channel>
|
|
||||||
<volume-norm>1.0</volume-norm>
|
|
||||||
<desc>
|
|
||||||
<!--
|
|
||||||
empty --></desc>
|
|
||||||
</speaker>
|
|
||||||
|
|
||||||
<script><![CDATA[
|
|
||||||
getprop(call(sprintf, size(arg));
|
|
||||||
c--; x >>= 33;
|
|
||||||
// --> comment ]>
|
|
||||||
;]]></script>
|
|
||||||
</output>
|
|
||||||
|
|
||||||
<backend>
|
|
||||||
<name type="stereo">ALSA Hardware</name>
|
|
||||||
<Output>
|
|
||||||
<renderer>hw:0</renderer>
|
|
||||||
<channels>2</channels>
|
|
||||||
<!-- periods>16</periods -->
|
|
||||||
<frequency-hz>44100</frequency-hz>
|
|
||||||
<bits-per-sample>16</bits-per-sample>
|
|
||||||
</Output>
|
|
||||||
<Input>
|
|
||||||
<renderer>default</renderer>
|
|
||||||
<frequency-hz>44100</frequency-hz>
|
|
||||||
</Input>
|
|
||||||
</backend>
|
|
||||||
|
|
||||||
<nasal>
|
|
||||||
<YF23>
|
|
||||||
<script><![CDATA[
|
|
||||||
# If the ground-roll-heading-hold has been reset (<-999) set:
|
|
||||||
if(agl > 50) {};
|
|
||||||
]]></script>
|
|
||||||
</YF23>
|
|
||||||
</nasal>
|
|
||||||
|
|
||||||
</Configuration>
|
|
|
@ -1,188 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "xml.h"
|
|
||||||
|
|
||||||
#define ROOTNODE "/Configuration/output/menu"
|
|
||||||
#define LEAFNODE "name"
|
|
||||||
#define PATH ROOTNODE"/"LEAFNODE
|
|
||||||
#define BUFLEN 4096
|
|
||||||
|
|
||||||
#define PRINT_ERROR_AND_EXIT(id) \
|
|
||||||
if (xmlErrorGetNo(id, 0) != XML_NO_ERROR) { \
|
|
||||||
const char *errstr = xmlErrorGetString(id, 0); \
|
|
||||||
size_t column = xmlErrorGetColumnNo(id, 0); \
|
|
||||||
size_t lineno = xmlErrorGetLineNo(id, 1); \
|
|
||||||
printf("Error at line %i, column %i: %s\n", lineno, column, errstr); \
|
|
||||||
exit(-1); \
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
void *root_id;
|
|
||||||
|
|
||||||
root_id = xmlOpen("sample.xml");
|
|
||||||
if (root_id)
|
|
||||||
{
|
|
||||||
void *path_id, *node_id;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
printf("\nTesting xmlNodeGetString for /*/*/test:\t\t\t\t\t");
|
|
||||||
s = xmlNodeGetString(root_id , "/*/*/test");
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
printf("failed.\n\t'%s' should be empty\n", s);
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
|
|
||||||
printf("Testing xmlGetString for /Configuration/output/test:\t\t\t");
|
|
||||||
path_id = xmlNodeGet(root_id, "/Configuration/output/test");
|
|
||||||
if (path_id)
|
|
||||||
{
|
|
||||||
s = xmlGetString(path_id);
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
printf("failed.\n\t'%s' should be empty\n", s);
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
PRINT_ERROR_AND_EXIT(root_id);
|
|
||||||
|
|
||||||
path_id = xmlNodeGet(root_id, PATH);
|
|
||||||
node_id = xmlNodeGet(root_id, ROOTNODE);
|
|
||||||
|
|
||||||
if (path_id && node_id)
|
|
||||||
{
|
|
||||||
char buf[BUFLEN];
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
xmlCopyString(path_id, buf, BUFLEN);
|
|
||||||
printf("Testing xmlNodeCopyString against xmlGetString:\t\t\t\t");
|
|
||||||
if ((s = xmlGetString(path_id)) != 0)
|
|
||||||
{
|
|
||||||
if (strcmp(s, buf)) /* not the same */
|
|
||||||
printf("failed.\n\t'%s' differs from '%s'\n", s, buf);
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
|
|
||||||
printf("Testing xmlCopyString against xmlGetString:\t\t\t\t");
|
|
||||||
xmlCopyString(path_id, buf, BUFLEN);
|
|
||||||
if (strcmp(s, buf)) /* not the same */
|
|
||||||
printf("failed.\n\t'%s' differs from\n\t'%s'\n", s, buf);
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
PRINT_ERROR_AND_EXIT(path_id);
|
|
||||||
|
|
||||||
printf("Testing xmlCopyString against xmlCompareString:\t\t\t\t");
|
|
||||||
if (xmlCompareString(path_id, buf)) /* not the same */
|
|
||||||
printf ("failed.\n\t'%s' differs from\n\t'%s'\n", s, buf);
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
|
|
||||||
printf("Testing xmlCopyString against xmlNodeCompareString:\t\t\t");
|
|
||||||
if (xmlNodeCompareString(node_id, LEAFNODE, buf)) /* not the same */
|
|
||||||
printf("failed.\n\t'%s' differs from\n\t'%s'\n", s, buf);
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
|
|
||||||
if (s) free(s);
|
|
||||||
|
|
||||||
printf("Testing xmlCopyString against xmlNodeGetString:\t\t\t\t");
|
|
||||||
if ((s = xmlNodeGetString(node_id, LEAFNODE)) != 0)
|
|
||||||
{
|
|
||||||
if (strcmp(s, buf)) /* not the same */
|
|
||||||
printf("failed.\n\t'%s' differs from\n\t'%s'\n", s, buf);
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
PRINT_ERROR_AND_EXIT(node_id);
|
|
||||||
|
|
||||||
free(path_id);
|
|
||||||
path_id = xmlNodeGet(root_id, "/Configuration/backend/name");
|
|
||||||
if (path_id)
|
|
||||||
{
|
|
||||||
printf("Testing xmlAttributeCopyString against xmlAttributeCompareString:\t");
|
|
||||||
xmlAttributeCopyString(path_id, "type", buf, BUFLEN);
|
|
||||||
if (xmlAttributeCompareString(path_id, "type", buf)) /* no match */
|
|
||||||
printf("failed.\n\t'%s' differs\n", buf);
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
|
|
||||||
printf("Testing xmlAttributeCopyString against xmlAttributeGetString:\t\t");
|
|
||||||
if ((s = xmlAttributeGetString(path_id, "type")) != 0)
|
|
||||||
{
|
|
||||||
if (strcmp(s, buf)) /* not the same */
|
|
||||||
printf("failed.\n\t'%s' differs from '%s'\n", s, buf);
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
PRINT_ERROR_AND_EXIT(path_id);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
PRINT_ERROR_AND_EXIT(root_id);
|
|
||||||
|
|
||||||
free(node_id);
|
|
||||||
free(path_id);
|
|
||||||
|
|
||||||
path_id = xmlNodeGet(root_id, "Configuration/output/sample/test");
|
|
||||||
if (path_id)
|
|
||||||
{
|
|
||||||
xmlNodeCopyString(root_id ,"Configuration/output/menu/name", buf, BUFLEN);
|
|
||||||
printf("Testing xmlCompareString against a fixed string: \t\t\t");
|
|
||||||
if (xmlCompareString(path_id, buf)) /* no match */
|
|
||||||
printf("failed.\n\t'%s' differs\n", buf);
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
|
|
||||||
s = xmlGetString(path_id);
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
printf("Testing xmlGetString against a fixed string: \t\t\t\t");
|
|
||||||
if (strcmp(s, buf)) /* mismatch */
|
|
||||||
printf("failed.\n\t'%s' differs from\n\t'%s'\n", s, buf);
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
|
|
||||||
printf("Testing xmlCopyString gainst a fixed string: \t\t\t\t");
|
|
||||||
xmlCopyString(path_id, buf, BUFLEN);
|
|
||||||
if (strcmp(s, buf)) /* mismatch */
|
|
||||||
printf("failed.\n\t'%s' differs from\n\t'%s'\n", s, buf);
|
|
||||||
else
|
|
||||||
printf("succes.\n");
|
|
||||||
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
PRINT_ERROR_AND_EXIT(path_id);
|
|
||||||
|
|
||||||
free(path_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlErrorGetNo(root_id, 0) != XML_NO_ERROR)
|
|
||||||
{
|
|
||||||
const char *errstr = xmlErrorGetString(root_id, 0);
|
|
||||||
size_t column = xmlErrorGetColumnNo(root_id, 0);
|
|
||||||
size_t lineno = xmlErrorGetLineNo(root_id, 1);
|
|
||||||
|
|
||||||
printf("Error at line %i, column %i: %s\n", lineno, column, errstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlClose(root_id);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
1995
utils/xmlgrep/xml.c
1995
utils/xmlgrep/xml.c
File diff suppressed because it is too large
Load diff
|
@ -1,434 +0,0 @@
|
||||||
/* Copyright (c) 2007-2009 by Adalin B.V.
|
|
||||||
* Copyright (c) 2007-2009 by Erik Hofman
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of (any of) the copyrightholder(s) nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
||||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
* THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XML_CONFIG
|
|
||||||
#define __XML_CONFIG 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef XML_NONVALIDATING
|
|
||||||
|
|
||||||
#ifdef XML_USE_NODECACHE
|
|
||||||
#include "xml_cache.h"
|
|
||||||
#else
|
|
||||||
void *cacheGet(void *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
XML_NO_ERROR = 0,
|
|
||||||
XML_OUT_OF_MEMORY,
|
|
||||||
XML_FILE_NOT_FOUND,
|
|
||||||
XML_INVALID_NODE_NAME,
|
|
||||||
XML_UNEXPECTED_EOF,
|
|
||||||
XML_TRUNCATE_RESULT,
|
|
||||||
XML_INVALID_COMMENT,
|
|
||||||
XML_INVALID_INFO_BLOCK,
|
|
||||||
XML_ELEMENT_NO_OPENING_TAG,
|
|
||||||
XML_ELEMENT_NO_CLOSING_TAG,
|
|
||||||
XML_ATTRIB_NO_OPENING_QUOTE,
|
|
||||||
XML_ATTRIB_NO_CLOSING_QUOTE,
|
|
||||||
XML_MAX_ERROR
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
# define WIN32_LEAN_AND_MEAN
|
|
||||||
# include <windows.h>
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
HANDLE m;
|
|
||||||
void *p;
|
|
||||||
} SIMPLE_UNMMAP;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef XML_NONVALIDATING
|
|
||||||
struct _xml_error
|
|
||||||
{
|
|
||||||
char *pos;
|
|
||||||
int err_no;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* It is required for both the rood node and the normal xml nodes to both
|
|
||||||
* have 'char *name' defined as the first entry. The code tests whether
|
|
||||||
* name == 0 to detect the root node.
|
|
||||||
*/
|
|
||||||
struct _root_id
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
char *start;
|
|
||||||
size_t len;
|
|
||||||
int fd;
|
|
||||||
#ifdef XML_USE_NODECACHE
|
|
||||||
void *node;
|
|
||||||
#endif
|
|
||||||
#ifndef XML_NONVALIDATING
|
|
||||||
struct _xml_error *info;
|
|
||||||
#endif
|
|
||||||
#ifdef WIN32
|
|
||||||
SIMPLE_UNMMAP un;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _xml_id
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
char *start;
|
|
||||||
size_t len;
|
|
||||||
size_t name_len;
|
|
||||||
#ifndef XML_NONVALIDATING
|
|
||||||
struct _root_id *root;
|
|
||||||
#endif
|
|
||||||
#ifdef XML_USE_NODECACHE
|
|
||||||
void *node;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open an XML file for processing.
|
|
||||||
*
|
|
||||||
* @param fname path to the file
|
|
||||||
* @return XML-id which is used for further processing
|
|
||||||
*/
|
|
||||||
void *xmlOpen(const char *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a section of XML code in a preallocated buffer.
|
|
||||||
* The buffer may not be free'd until xmlClose has been called.
|
|
||||||
*
|
|
||||||
* @param buffer pointer to the buffer
|
|
||||||
* @param size size of the buffer
|
|
||||||
* @return XML-id which is used for further processing
|
|
||||||
*/
|
|
||||||
void *xmlInitBuffer(const char *, size_t);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the XML file after which no further processing is possible.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
*/
|
|
||||||
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 *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.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @return a newly alocated string containing the node name
|
|
||||||
*/
|
|
||||||
char *xmlNodeGetName(const void *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 xmlNodeCopyName(const void *, char *, size_t);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a marker XML-id that starts out with the same settings as the
|
|
||||||
* refference XML-id.
|
|
||||||
*
|
|
||||||
* Marker id's are required when xmlNodeGetNum() and xmlNodeGetPos() are used
|
|
||||||
* to walk a number of nodes. The xmlNodeGetPos function adjusts the contents
|
|
||||||
* of the provided XML-id to keep track of it's position within the xml section.
|
|
||||||
* The returned XML-id is limited to the boundaries of the requested XML tag
|
|
||||||
* and has to be freed by the calling process.
|
|
||||||
*
|
|
||||||
* @param xid reference XML-id
|
|
||||||
* @return a copy of the reference XML-id
|
|
||||||
*/
|
|
||||||
void *xmlMarkId(const void *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of nodes with the same name from a specified xml path.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @param path path to the xml node
|
|
||||||
* @return the number count of the nodename
|
|
||||||
*/
|
|
||||||
unsigned int xmlNodeGetNum(const void *, const char *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the nth occurrence of node in the parent node.
|
|
||||||
* 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
|
|
||||||
* @param node name of the node to search for
|
|
||||||
* @param num specify which occurence to return
|
|
||||||
* @return XML-subsection-id for further processing or NULL if unsuccessful
|
|
||||||
*/
|
|
||||||
void *xmlNodeGetPos(const void *, void *, const char *, size_t);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a string of characters from the current node.
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*
|
|
||||||
* @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 string
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @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 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.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @param path path to the xml node
|
|
||||||
* @return a newly alocated string containing the contents of the node
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @param path path to the xml node
|
|
||||||
* @param buffer the buffer to copy the string to
|
|
||||||
* @param buflen length of the destination buffer
|
|
||||||
* @return the length of the string
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @param path path to the xml node to compare to
|
|
||||||
* @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 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 *, char *, size_t);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare the value of an attribute to a reference string.
|
|
||||||
* Comparing is done in a case insensitive way.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @param name name of the attribute to acquire.
|
|
||||||
* @param str the string to compare to
|
|
||||||
* @return an integer less than, equal to, ro greater than zero if the value
|
|
||||||
* of the node is found, respectively, to be less than, to match, or be greater
|
|
||||||
* than str
|
|
||||||
*/
|
|
||||||
int xmlAttributeCompareString(const void *, const char *, const char *);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the integer value from the current node/
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @return the contents of the node converted to an integer value
|
|
||||||
*/
|
|
||||||
long int xmlGetInt(const void *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 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/
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @return the contents of the node converted to a double value
|
|
||||||
*/
|
|
||||||
double xmlGetDouble(const void *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 xmlNodeGetDouble(const void *, const char *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the double 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
|
|
||||||
*/
|
|
||||||
double xmlAttributeGetDouble(const void *, const char *);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the error number of the last error and clear it.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @param clear clear the error state if non zero
|
|
||||||
* @return the numer of the last error, 0 means no error detected.
|
|
||||||
*/
|
|
||||||
int xmlErrorGetNo(const void *, int);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the line number of the last detected syntax error in the xml file.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @param clear clear the error state if non zero
|
|
||||||
* @return the line number of the detected syntax error.
|
|
||||||
*/
|
|
||||||
size_t xmlErrorGetLineNo(const void *, int);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the column number of the last detected syntax error in the xml file.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @param clear clear the error state if non zero
|
|
||||||
* @return the line number of the detected syntax error.
|
|
||||||
*/
|
|
||||||
size_t xmlErrorGetColumnNo(const void *, int);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a string that explains the last error.
|
|
||||||
*
|
|
||||||
* @param xid XML-id
|
|
||||||
* @param clear clear the error state if non zero
|
|
||||||
* @return a string that explains the last error.
|
|
||||||
*/
|
|
||||||
const char *xmlErrorGetString(const void *, int);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __XML_CONFIG */
|
|
||||||
|
|
|
@ -1,250 +0,0 @@
|
||||||
/* Copyright (c) 2007-2009 by Adalin B.V.
|
|
||||||
* Copyright (c) 2007-2009 by Erik Hofman
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of (any of) the copyrightholder(s) nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
||||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
* THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "xml.h"
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
# define PRINT(a, b, c) { \
|
|
||||||
size_t l1 = (b), l2 = (c); \
|
|
||||||
char *s = (a); \
|
|
||||||
if (s) { \
|
|
||||||
size_t q, len = l2; \
|
|
||||||
if (l1 < l2) len = l1; \
|
|
||||||
if (len < 50000) { \
|
|
||||||
printf("(%i) '", len); \
|
|
||||||
for (q=0; q<len; q++) printf("%c", s[q]); \
|
|
||||||
printf("'\n"); \
|
|
||||||
} else printf("Length (%u) seems too large at line %i\n",len, __LINE__); \
|
|
||||||
} else printf("NULL pointer at line %i\n", __LINE__); \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(XML_USE_NODECACHE)
|
|
||||||
void *
|
|
||||||
cacheNodeGet(void *id, const char *node)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define NODE_BLOCKSIZE 16
|
|
||||||
|
|
||||||
struct _xml_node
|
|
||||||
{
|
|
||||||
void *parent;
|
|
||||||
char *name;
|
|
||||||
size_t name_len;
|
|
||||||
char *data;
|
|
||||||
size_t data_len;
|
|
||||||
void **node;
|
|
||||||
size_t no_nodes;
|
|
||||||
size_t first_free;
|
|
||||||
};
|
|
||||||
|
|
||||||
char *
|
|
||||||
__xmlNodeGetFromCache(void **nc, const char *start, size_t *len,
|
|
||||||
char **element, size_t *elementlen , size_t *nodenum)
|
|
||||||
{
|
|
||||||
struct _xml_node *cache;
|
|
||||||
size_t num = *nodenum;
|
|
||||||
char *name = *element;
|
|
||||||
void *rv = 0;
|
|
||||||
|
|
||||||
assert(nc != 0);
|
|
||||||
|
|
||||||
cache = (struct _xml_node *)*nc;
|
|
||||||
assert(cache != 0);
|
|
||||||
|
|
||||||
assert((cache->first_free > num) || (cache->first_free == 0));
|
|
||||||
|
|
||||||
if (cache->first_free == 0) /* leaf node */
|
|
||||||
{
|
|
||||||
rv = cache->data;
|
|
||||||
*len = cache->data_len;
|
|
||||||
*element = cache->name;
|
|
||||||
*elementlen = cache->name_len;
|
|
||||||
*nodenum = 0;
|
|
||||||
}
|
|
||||||
else if (*name == '*')
|
|
||||||
{
|
|
||||||
struct _xml_node *node = cache->node[num];
|
|
||||||
*nc = node;
|
|
||||||
rv = node->data;
|
|
||||||
*len = node->data_len;
|
|
||||||
*element = node->name;
|
|
||||||
*elementlen = node->name_len;
|
|
||||||
*nodenum = cache->first_free;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t namelen = *elementlen;
|
|
||||||
size_t i, pos = 0;
|
|
||||||
|
|
||||||
for (i=0; i<cache->first_free; i++)
|
|
||||||
{
|
|
||||||
struct _xml_node *node = cache->node[i];
|
|
||||||
|
|
||||||
assert(node);
|
|
||||||
|
|
||||||
if ((node->name_len == namelen) &&
|
|
||||||
(!strncasecmp(node->name, name, namelen)))
|
|
||||||
{
|
|
||||||
if (pos == num)
|
|
||||||
{
|
|
||||||
*nc = node;
|
|
||||||
rv = node->data;
|
|
||||||
*element = node->name;
|
|
||||||
*elementlen = node->name_len;
|
|
||||||
*len = node->data_len;
|
|
||||||
*nodenum = cache->first_free;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *
|
|
||||||
cacheInit()
|
|
||||||
{
|
|
||||||
return calloc(1, sizeof(struct _xml_node));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cacheInitLevel(void *nc)
|
|
||||||
{
|
|
||||||
struct _xml_node *cache = (struct _xml_node *)nc;
|
|
||||||
|
|
||||||
assert(cache != 0);
|
|
||||||
|
|
||||||
cache->node = calloc(NODE_BLOCKSIZE, sizeof(struct _xml_node *));
|
|
||||||
cache->no_nodes = NODE_BLOCKSIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cacheFree(void *nc)
|
|
||||||
{
|
|
||||||
struct _xml_node *cache = (struct _xml_node *)nc;
|
|
||||||
|
|
||||||
assert(nc != 0);
|
|
||||||
|
|
||||||
if (cache->first_free)
|
|
||||||
{
|
|
||||||
struct _xml_node **node = (struct _xml_node **)cache->node;
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
while(i < cache->first_free)
|
|
||||||
{
|
|
||||||
cacheFree(node[i++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(node);
|
|
||||||
}
|
|
||||||
free(cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
cacheNodeGet(void *id)
|
|
||||||
{
|
|
||||||
struct _xml_id *xid = (struct _xml_id *)id;
|
|
||||||
struct _xml_node *cache = 0;
|
|
||||||
|
|
||||||
assert(xid != 0);
|
|
||||||
|
|
||||||
if (xid->name)
|
|
||||||
{
|
|
||||||
cache = xid->node;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct _root_id *rid = (struct _root_id *)xid;
|
|
||||||
cache = rid->node;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
cacheNodeNew(void *nc)
|
|
||||||
{
|
|
||||||
struct _xml_node *cache = (struct _xml_node *)nc;
|
|
||||||
struct _xml_node *rv = 0;
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
assert(nc != 0);
|
|
||||||
|
|
||||||
i = cache->first_free;
|
|
||||||
if (i == cache->no_nodes)
|
|
||||||
{
|
|
||||||
size_t size, no_nodes;
|
|
||||||
void *p;
|
|
||||||
|
|
||||||
no_nodes = cache->no_nodes + NODE_BLOCKSIZE;
|
|
||||||
size = no_nodes * sizeof(struct _xml_node *);
|
|
||||||
p = realloc(cache->node, size);
|
|
||||||
if (!p) return 0;
|
|
||||||
|
|
||||||
cache->node = p;
|
|
||||||
cache->no_nodes = no_nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = calloc(1, sizeof(struct _xml_node));
|
|
||||||
if (rv) rv->parent = cache;
|
|
||||||
cache->node[i] = rv;
|
|
||||||
cache->first_free++;
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cacheDataSet(void *n, char *name, size_t namelen, char *data, size_t datalen)
|
|
||||||
{
|
|
||||||
struct _xml_node *node = (struct _xml_node *)n;
|
|
||||||
|
|
||||||
assert(node != 0);
|
|
||||||
assert(name != 0);
|
|
||||||
assert(namelen != 0);
|
|
||||||
assert(data != 0);
|
|
||||||
|
|
||||||
node->name = name;
|
|
||||||
node->name_len = namelen;
|
|
||||||
node->data = data;
|
|
||||||
node->data_len = datalen;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
/* Copyright (c) 2007-2009 by Adalin B.V.
|
|
||||||
* Copyright (c) 2007-2009 by Erik Hofman
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of (any of) the copyrightholder(s) nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
||||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
* THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XML_NODECACHE
|
|
||||||
#define __XML_NODECACHE 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *cacheInit();
|
|
||||||
void cacheInitLevel(void *);
|
|
||||||
void cacheFree(void *);
|
|
||||||
void *cacheNodeNew(void *);
|
|
||||||
|
|
||||||
void *cacheNodeGet(void *);
|
|
||||||
void cacheDataSet(void *, char *, size_t, char *, size_t);
|
|
||||||
|
|
||||||
char *__xmlNodeGetFromCache(void **, const char *, size_t *, char **, size_t *, size_t *);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __XML_NODECACHE */
|
|
||||||
|
|
|
@ -1,442 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#ifndef _MSC_VER
|
|
||||||
# include <strings.h>
|
|
||||||
# include <unistd.h> /* read */
|
|
||||||
#else
|
|
||||||
# define strncasecmp strnicmp
|
|
||||||
# include <stdlib.h>
|
|
||||||
# include <io.h>
|
|
||||||
#endif
|
|
||||||
#include <assert.h>
|
|
||||||
#include <sys/stat.h> /* fstat */
|
|
||||||
#include <fcntl.h> /* open */
|
|
||||||
|
|
||||||
#include "xml.h"
|
|
||||||
|
|
||||||
static const char *_static_root = "/";
|
|
||||||
static const char *_static_element = "*";
|
|
||||||
static unsigned int _fcount = 0;
|
|
||||||
static char **_filenames = 0;
|
|
||||||
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);
|
|
||||||
|
|
||||||
#define USE_BUFFER 0
|
|
||||||
#define NODE_NAME_LEN 256
|
|
||||||
#define STRING_LEN 2048
|
|
||||||
|
|
||||||
#define SHOW_NOVAL(opt) \
|
|
||||||
{ \
|
|
||||||
printf("option '%s' requires a value\n\n", (opt)); \
|
|
||||||
free_and_exit(-1); \
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
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>\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' 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 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 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])
|
|
||||||
{
|
|
||||||
if (print_filenames) printf("%s\n", _filenames[i]);
|
|
||||||
free(_filenames[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(_filenames);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
parse_option(char **args, int n, int max)
|
|
||||||
{
|
|
||||||
char *opt, *arg = 0;
|
|
||||||
unsigned int alen = 0;
|
|
||||||
unsigned int olen;
|
|
||||||
|
|
||||||
opt = args[n];
|
|
||||||
if (strncmp(opt, "--", 2) == 0)
|
|
||||||
opt++;
|
|
||||||
|
|
||||||
if ((arg = strchr(opt, '=')) != NULL)
|
|
||||||
{
|
|
||||||
*arg++ = 0;
|
|
||||||
}
|
|
||||||
else if (++n < max)
|
|
||||||
{
|
|
||||||
arg = args[n];
|
|
||||||
#if 0
|
|
||||||
if (arg && arg[0] == '-')
|
|
||||||
arg = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
olen = strlen(opt);
|
|
||||||
if (strncmp(opt, "-help", olen) == 0)
|
|
||||||
{
|
|
||||||
show_help();
|
|
||||||
}
|
|
||||||
else if (strncmp(opt, "-root", olen) == 0)
|
|
||||||
{
|
|
||||||
if (arg == 0) SHOW_NOVAL(opt);
|
|
||||||
alen = strlen(arg)+1;
|
|
||||||
if (_root) free(_root);
|
|
||||||
_root = malloc(alen);
|
|
||||||
memcpy(_root, arg, alen);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
else if (strncmp(opt, "-element", olen) == 0)
|
|
||||||
{
|
|
||||||
if (arg == 0) SHOW_NOVAL(opt);
|
|
||||||
alen = strlen(arg)+1;
|
|
||||||
if (_element) free(_element);
|
|
||||||
_element = malloc(alen);
|
|
||||||
memcpy(_element, arg, alen);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
else if (strncmp(opt, "-value", olen) == 0)
|
|
||||||
{
|
|
||||||
if (arg == 0) SHOW_NOVAL(opt);
|
|
||||||
alen = strlen(arg)+1;
|
|
||||||
if (_value) free(_value);
|
|
||||||
_value = malloc(alen);
|
|
||||||
memcpy(_value, arg, alen);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
else if (strncmp(opt, "-print", olen) == 0)
|
|
||||||
{
|
|
||||||
if (arg == 0) SHOW_NOVAL(opt);
|
|
||||||
alen = strlen(arg)+1;
|
|
||||||
if (_print) free(_print);
|
|
||||||
_print = malloc(alen);
|
|
||||||
memcpy(_print, arg, alen);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
else if (strncmp(opt, "-attribute", olen) == 0)
|
|
||||||
{
|
|
||||||
if (arg == 0) SHOW_NOVAL(opt);
|
|
||||||
alen = strlen(arg)+1;
|
|
||||||
if (_attribute) free(_attribute);
|
|
||||||
_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;
|
|
||||||
}
|
|
||||||
else if (opt[0] == '-')
|
|
||||||
{
|
|
||||||
printf("Unknown option %s\n", opt);
|
|
||||||
free_and_exit(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int pos = _fcount++;
|
|
||||||
if (_filenames == 0)
|
|
||||||
{
|
|
||||||
_filenames = (char **)malloc(sizeof(char*));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char **ptr = (char **)realloc(_filenames, _fcount*sizeof(char*));
|
|
||||||
if (ptr == 0)
|
|
||||||
{
|
|
||||||
printf("Out of memory.\n\n");
|
|
||||||
free_and_exit(-1);
|
|
||||||
}
|
|
||||||
_filenames = ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
alen = strlen(opt)+1;
|
|
||||||
_filenames[pos] = malloc(alen);
|
|
||||||
memcpy(_filenames[pos], opt, alen);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void walk_the_tree(size_t num, void *xid, char *tree)
|
|
||||||
{
|
|
||||||
unsigned int i, no_elements;
|
|
||||||
|
|
||||||
if (!tree) /* last node from the tree */
|
|
||||||
{
|
|
||||||
void *xmid = xmlMarkId(xid);
|
|
||||||
if (xmid && _print)
|
|
||||||
{
|
|
||||||
no_elements = xmlNodeGetNum(xid, _print);
|
|
||||||
for (i=0; i<no_elements; i++)
|
|
||||||
{
|
|
||||||
if (xmlNodeGetPos(xid, xmid, _print, i) != 0)
|
|
||||||
{
|
|
||||||
char *value;
|
|
||||||
|
|
||||||
value = xmlGetString(xmid);
|
|
||||||
if (_value && _attribute && value)
|
|
||||||
{
|
|
||||||
#if 1
|
|
||||||
char *a = xmlAttributeGetString(xmid, _attribute);
|
|
||||||
if (a && !strcmp(a, _value))
|
|
||||||
#else
|
|
||||||
if (!xmlAttributeCompareString(xmid, _attribute, _value))
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
printf("%s: <%s %s=\"%s\">%s</%s>\n",
|
|
||||||
_filenames[num], _print, _attribute, _value,
|
|
||||||
value, _print);
|
|
||||||
}
|
|
||||||
if (value) free(value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("%s: <%s>%s</%s>\n",
|
|
||||||
_filenames[num], _print, value, _print);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(xmid);
|
|
||||||
}
|
|
||||||
else if (xmid && _value)
|
|
||||||
{
|
|
||||||
no_elements = xmlNodeGetNum(xmid, _element);
|
|
||||||
for (i=0; i<no_elements; i++)
|
|
||||||
{
|
|
||||||
if (xmlNodeGetPos(xid, xmid, _element, i) != 0)
|
|
||||||
{
|
|
||||||
char nodename[NODE_NAME_LEN];
|
|
||||||
|
|
||||||
xmlNodeCopyName(xmid, (char *)&nodename, NODE_NAME_LEN);
|
|
||||||
if (xmlCompareString(xmid, _value) == 0)
|
|
||||||
{
|
|
||||||
printf("%s: <%s>%s</%s>\n",
|
|
||||||
_filenames[num], nodename, _value, nodename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(xmid);
|
|
||||||
}
|
|
||||||
else if (xmid && _element)
|
|
||||||
{
|
|
||||||
char parentname[NODE_NAME_LEN];
|
|
||||||
|
|
||||||
xmlNodeCopyName(xid, (char *)&parentname, NODE_NAME_LEN);
|
|
||||||
|
|
||||||
no_elements = xmlNodeGetNum(xmid, _element);
|
|
||||||
for (i=0; i<no_elements; i++)
|
|
||||||
{
|
|
||||||
if (xmlNodeGetPos(xid, xmid, _element, i) != 0)
|
|
||||||
{
|
|
||||||
char nodename[NODE_NAME_LEN];
|
|
||||||
|
|
||||||
xmlNodeCopyName(xmid, (char *)&nodename, NODE_NAME_LEN);
|
|
||||||
if (!strncasecmp((char*)&nodename, _element, NODE_NAME_LEN))
|
|
||||||
{
|
|
||||||
char value[NODE_NAME_LEN];
|
|
||||||
xmlCopyString(xmid, (char *)&value, NODE_NAME_LEN);
|
|
||||||
printf("%s: <%s> <%s>%s</%s> </%s>\n",
|
|
||||||
_filenames[num], parentname, nodename, value,
|
|
||||||
nodename, parentname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else printf("Error executing xmlMarkId\n");
|
|
||||||
}
|
|
||||||
else if (xid) /* walk the rest of the tree */
|
|
||||||
{
|
|
||||||
char *elem, *next;
|
|
||||||
void *xmid;
|
|
||||||
|
|
||||||
elem = tree;
|
|
||||||
if (*elem == '/') elem++;
|
|
||||||
|
|
||||||
next = strchr(elem, '/');
|
|
||||||
|
|
||||||
xmid = xmlMarkId(xid);
|
|
||||||
if (xmid)
|
|
||||||
{
|
|
||||||
if (next)
|
|
||||||
{
|
|
||||||
*next++ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
no_elements = xmlNodeGetNum(xid, elem);
|
|
||||||
for (i=0; i<no_elements; i++)
|
|
||||||
{
|
|
||||||
if (xmlNodeGetPos(xid, xmid, elem, i) != 0)
|
|
||||||
walk_the_tree(num, xmid, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (next)
|
|
||||||
{
|
|
||||||
*--next = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
free(xmid);
|
|
||||||
}
|
|
||||||
else printf("Error executing xmlMarkId\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void grep_file(unsigned num)
|
|
||||||
{
|
|
||||||
void *xid;
|
|
||||||
|
|
||||||
xid = xmlOpen(_filenames[num]);
|
|
||||||
if (xid)
|
|
||||||
{
|
|
||||||
void *xrid = xmlMarkId(xid);
|
|
||||||
int r = 0;
|
|
||||||
|
|
||||||
walk_the_tree(num, xrid, _root);
|
|
||||||
|
|
||||||
r = xmlErrorGetNo(xrid, 0);
|
|
||||||
if (r)
|
|
||||||
{
|
|
||||||
size_t n = xmlErrorGetLineNo(xrid, 0);
|
|
||||||
size_t c = xmlErrorGetColumnNo(xrid, 0);
|
|
||||||
const char *s = xmlErrorGetString(xrid, 1); /* clear the error */
|
|
||||||
printf("%s: at line %u, column %u: '%s'\n",_filenames[num], n,c, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(xrid);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error reading file '%s'\n", _filenames[num]);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlClose(xid);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void grep_file_buffer(unsigned num)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
void *xid, *buf;
|
|
||||||
int fd, res;
|
|
||||||
|
|
||||||
fd = open(_filenames[num], O_RDONLY);
|
|
||||||
if (fd == -1)
|
|
||||||
{
|
|
||||||
printf("read error opening file '%s'\n", _filenames[num]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fstat(fd, &st);
|
|
||||||
buf = malloc(st.st_size);
|
|
||||||
if (!buf)
|
|
||||||
{
|
|
||||||
printf("unable to allocate enough memory for reading.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = read(fd, buf, st.st_size);
|
|
||||||
if (res == -1)
|
|
||||||
{
|
|
||||||
printf("unable to read from file '%s'.\n", _filenames[num]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
xid = xmlInitBuffer(buf, st.st_size);
|
|
||||||
if (xid)
|
|
||||||
{
|
|
||||||
void *xrid = xmlMarkId(xid);
|
|
||||||
int r = 0;
|
|
||||||
|
|
||||||
walk_the_tree(num, xrid, _root);
|
|
||||||
|
|
||||||
r = xmlErrorGetNo(xrid, 0);
|
|
||||||
if (r)
|
|
||||||
{
|
|
||||||
size_t n = xmlErrorGetLineNo(xrid, 0);
|
|
||||||
size_t c = xmlErrorGetColumnNo(xrid, 0);
|
|
||||||
const char *s = xmlErrorGetString(xrid, 1); /* clear the error */
|
|
||||||
printf("%s: at line %u, column %u: '%s'\n",_filenames[num], n,c, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(xrid);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error reading file '%s'\n", _filenames[num]);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlClose(xid);
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
unsigned int u;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (argc == 1)
|
|
||||||
show_help();
|
|
||||||
|
|
||||||
for (i=1; i<argc;)
|
|
||||||
{
|
|
||||||
int ret = parse_option(argv, i, argc);
|
|
||||||
i += ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_root == 0) _root = (char *)_static_root;
|
|
||||||
if (_element == 0) _element = (char *)_static_element;
|
|
||||||
|
|
||||||
for (u=0; u<_fcount; u++)
|
|
||||||
#if USE_BUFFER
|
|
||||||
grep_file_buffer(u);
|
|
||||||
#else
|
|
||||||
grep_file(u);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
free_and_exit(0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in a new issue