* 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
This commit is contained in:
parent
1f40ee2366
commit
228c7aaaa0
5 changed files with 165 additions and 59 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
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
|
||||||
|
* fix a buffer overflow
|
||||||
|
|
||||||
26-04-2009
|
26-04-2009
|
||||||
* add support for comments inside xml-tags, e.g.: <test><!-- --></test>
|
* add support for comments inside xml-tags, e.g.: <test><!-- --></test>
|
||||||
|
|
||||||
|
|
|
@ -47,22 +47,23 @@ Overview of the available functions:
|
||||||
# id = xmlOpen("/tmp/file.xml");
|
# id = xmlOpen("/tmp/file.xml");
|
||||||
# xmlClose(id);
|
# xmlClose(id);
|
||||||
#
|
#
|
||||||
void *xmlOpen(const char *);
|
void *xmlOpen(const char *filename);
|
||||||
void xmlClose(const void *);
|
void *xmlInitBuffer(const char *buffer, size_t size);
|
||||||
|
void xmlClose(void *xid);
|
||||||
|
|
||||||
#
|
#
|
||||||
# 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 = xmlNodeGet(id, "/path/to/specified/node");
|
# xnid = xmlNodeGet(id, "/path/to/specified/node");
|
||||||
#
|
#
|
||||||
void *xmlNodeGet(const void *, const char *);
|
void *xmlNodeGet(const void *xid, const char *path);
|
||||||
void *xmlNodeCopy(void *, const char *);
|
void *xmlNodeCopy(const void *xid, const char *path);
|
||||||
|
|
||||||
#
|
#
|
||||||
# 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 = xmlNodeGetNum(xmid);
|
# num = xmlNodeGetNum(xmid, "node");
|
||||||
# for (i=0; i<num; i++) {
|
# for (i=0; i<num; i++) {
|
||||||
# if (xmlNodeGetPos(id, xmid, "element", i) != 0) {
|
# if (xmlNodeGetPos(id, xmid, "element", i) != 0) {
|
||||||
# if ((s = xmlGetString(xmid)) != 0) {
|
# if ((s = xmlGetString(xmid)) != 0) {
|
||||||
|
@ -73,15 +74,15 @@ void *xmlNodeCopy(void *, const char *);
|
||||||
# }
|
# }
|
||||||
# free(xmid);
|
# free(xmid);
|
||||||
#
|
#
|
||||||
void *xmlMarkId(void *);
|
void *xmlMarkId(const void *xid);
|
||||||
unsigned int xmlNodeGetNum(void *, const char *);
|
unsigned int xmlNodeGetNum(const void *xid, const char *path);
|
||||||
void *xmlNodeGetPos(const void *, void *, const char *, int);
|
void *xmlNodeGetPos(const void *pid, void *xid, const char *element, int pos);
|
||||||
|
|
||||||
#
|
#
|
||||||
# Get the name of the current node
|
# Get the name of the current node
|
||||||
#
|
#
|
||||||
char *xmlNodeGetName(void *);
|
char *xmlNodeGetName(const void *xid);
|
||||||
size_t xmlNodeCopyName(void *, const char *, size_t);
|
size_t xmlNodeCopyName(const void *xid, const char *buffer, size_t size);
|
||||||
|
|
||||||
#
|
#
|
||||||
# These functions work on the current node.
|
# These functions work on the current node.
|
||||||
|
@ -92,11 +93,11 @@ size_t xmlNodeCopyName(void *, const char *, size_t);
|
||||||
# xnid = xmlNodeGet(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(const void *xid);
|
||||||
double xmlGetDouble(void *);
|
double xmlGetDouble(const void *xid);
|
||||||
char *xmlGetString(void *);
|
char *xmlGetString(const void *xid);
|
||||||
size_t xmlCopyString(void *, char *, const size_t);
|
size_t xmlCopyString(const void *xid, char *buffer, const size_t size);
|
||||||
int xmlCompareString(const void *, const char *);
|
int xmlCompareString(const void *xid, const char *str);
|
||||||
|
|
||||||
#
|
#
|
||||||
# These functions work on a specified node path
|
# These functions work on a specified node path
|
||||||
|
@ -106,11 +107,12 @@ int xmlCompareString(const void *, const char *);
|
||||||
# xnid = xmlNodeGet(id, "/path/to");
|
# xnid = xmlNodeGet(id, "/path/to");
|
||||||
# i = xmlNodeGetInt(xnid, "node");
|
# i = xmlNodeGetInt(xnid, "node");
|
||||||
#
|
#
|
||||||
long int xmlNodeGetInt(void *, const char *);
|
long int xmlNodeGetInt(const void *xid, const char *path);
|
||||||
double xmlNodeGetDouble(void *, const char *);
|
double xmlNodeGetDouble(const void *xid, const char *path);
|
||||||
char *xmlNodeGetString(void *, const char *);
|
char *xmlNodeGetString(const void *xid, const char *path);
|
||||||
size_t xmlNodeCopyString(void *, const char *, char *, const size_t);
|
size_t xmlNodeCopyString(const void *xid, const char *path,
|
||||||
int xmlNodeCompareString(const void *, const char *, const char *);
|
char *buffer, const size_t size);
|
||||||
|
int xmlNodeCompareString(const void *xid, const char *path, const char *str);
|
||||||
|
|
||||||
#
|
#
|
||||||
# These functions work on a specified atribute
|
# These functions work on a specified atribute
|
||||||
|
@ -118,15 +120,17 @@ int xmlNodeCompareString(const void *, const char *, const char *);
|
||||||
# i = xmlAttributeGetInt(id, "n");
|
# i = xmlAttributeGetInt(id, "n");
|
||||||
#
|
#
|
||||||
# or
|
# or
|
||||||
# s = xmlNodeGetString(id, "type");
|
# s = xmlAttributeGetString(id, "type");
|
||||||
# if (s) printf("node is of type '%s'\n", s);
|
# if (s) printf("node is of type '%s'\n", s);
|
||||||
# free(s);
|
# free(s);
|
||||||
#
|
#
|
||||||
long int xmlAttributeGetInt(const void *, const char *);
|
long int xmlAttributeGetInt(const void *xid, const char *attr);
|
||||||
double xmlAttributeGetDouble(const void *, const char *);
|
double xmlAttributeGetDouble(const void *xid, const char *attr);
|
||||||
char *xmlAttributeGetString(const void *, const char *);
|
char *xmlAttributeGetString(const void *xid, const char *attr);
|
||||||
size_t xmlAttributeCopyString(const void *, const char *, const char *, size_t);
|
size_t xmlAttributeCopyString(const void *xid, const char *attr,
|
||||||
int xmlAttributeCompareString(const void *, const char *, const char *);
|
const char *buffer, size_t size);
|
||||||
|
int xmlAttributeCompareString(const void *xid, const char *attr,
|
||||||
|
const char *str);
|
||||||
|
|
||||||
#
|
#
|
||||||
# Error detection and reporting functions
|
# Error detection and reporting functions
|
||||||
|
@ -136,6 +140,7 @@ int xmlAttributeCompareString(const void *, const char *, const char *);
|
||||||
# int err = xmlErrorGetNo(id, 1); /* clear last error */
|
# int err = xmlErrorGetNo(id, 1); /* clear last error */
|
||||||
# if (err) printf("Error #%i at line %u: '%s'\n", err, err_lineno, err_str);
|
# if (err) printf("Error #%i at line %u: '%s'\n", err, err_lineno, err_str);
|
||||||
#
|
#
|
||||||
int xmlErrorGetNo(const void *, int);
|
int xmlErrorGetNo(const void *xid, int clear);
|
||||||
size_t xmlErrorGetLineNo(const void *, int);
|
size_t xmlErrorGetLineNo(const void *xid, int clear);
|
||||||
const char *xmlErrorGetString(const void *, int);
|
size_t xmlErrorGetColumnNo(const void *xid, int clear);
|
||||||
|
const char *xmlErrorGetString(const void *xid, int clear);
|
||||||
|
|
|
@ -46,16 +46,16 @@ typedef struct
|
||||||
#endif
|
#endif
|
||||||
#include <stdlib.h> /* free, malloc */
|
#include <stdlib.h> /* free, malloc */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#include <strings.h> /* strncasecmp */
|
||||||
|
#else
|
||||||
|
# define strncasecmp strnicmp
|
||||||
|
#endif
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#ifndef _MSC_VER
|
|
||||||
# include <strings.h> /* strncasecmp */
|
|
||||||
#else
|
|
||||||
# define strncasecmp strnicmp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef XML_NONVALIDATING
|
#ifndef XML_NONVALIDATING
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
|
@ -172,6 +172,25 @@ xmlOpen(const char *filename)
|
||||||
return (void *)rid;
|
return (void *)rid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
xmlInitBuffer(const char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
struct _root_id *rid = 0;
|
||||||
|
|
||||||
|
if (buffer && (size>0))
|
||||||
|
{
|
||||||
|
rid->fd = 0;
|
||||||
|
rid->start = (char *)buffer;
|
||||||
|
rid->len = size;
|
||||||
|
rid->name = 0;
|
||||||
|
#ifndef XML_NONVALIDATING
|
||||||
|
rid->info = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return (void *)rid;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xmlClose(void *id)
|
xmlClose(void *id)
|
||||||
{
|
{
|
||||||
|
@ -180,8 +199,11 @@ xmlClose(void *id)
|
||||||
assert(rid != 0);
|
assert(rid != 0);
|
||||||
assert(rid->name == 0);
|
assert(rid->name == 0);
|
||||||
|
|
||||||
munmap(rid->start, rid->len);
|
if (rid->fd)
|
||||||
close(rid->fd);
|
{
|
||||||
|
munmap(rid->start, rid->len);
|
||||||
|
close(rid->fd);
|
||||||
|
}
|
||||||
|
|
||||||
if (rid->info) free(rid->info);
|
if (rid->info) free(rid->info);
|
||||||
free(rid);
|
free(rid);
|
||||||
|
@ -1183,12 +1205,9 @@ xmlErrorGetLineNo(const void *id, int clear)
|
||||||
while (ps<pe)
|
while (ps<pe)
|
||||||
{
|
{
|
||||||
new = memchr(ps, '\n', pe-ps);
|
new = memchr(ps, '\n', pe-ps);
|
||||||
if (new)
|
if (new) ret++;
|
||||||
{
|
else break;
|
||||||
ps = new;
|
ps = new+1;
|
||||||
ret++;
|
|
||||||
}
|
|
||||||
ps++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clear) err->err_no = 0;
|
if (clear) err->err_no = 0;
|
||||||
|
@ -1198,6 +1217,45 @@ xmlErrorGetLineNo(const void *id, int clear)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
xmlErrorGetColumnNo(const void *id, int clear)
|
||||||
|
{
|
||||||
|
size_t ret = 0;
|
||||||
|
|
||||||
|
if (id)
|
||||||
|
{
|
||||||
|
struct _xml_id *xid = (struct _xml_id *)id;
|
||||||
|
struct _root_id *rid;
|
||||||
|
|
||||||
|
if (xid->name) rid = xid->root;
|
||||||
|
else rid = (struct _root_id *)xid;
|
||||||
|
|
||||||
|
assert(rid != 0);
|
||||||
|
|
||||||
|
if (rid->info)
|
||||||
|
{
|
||||||
|
struct _xml_error *err = rid->info;
|
||||||
|
char *ps = rid->start;
|
||||||
|
char *pe = err->pos;
|
||||||
|
char *new;
|
||||||
|
|
||||||
|
while (ps<pe)
|
||||||
|
{
|
||||||
|
new = memchr(ps, '\n', pe-ps);
|
||||||
|
new = memchr(ps, '\n', pe-ps);
|
||||||
|
if (new) ret++;
|
||||||
|
else break;
|
||||||
|
ps = new+1;
|
||||||
|
}
|
||||||
|
ret = pe-ps;
|
||||||
|
|
||||||
|
if (clear) err->err_no = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
xmlErrorGetString(const void *id, int clear)
|
xmlErrorGetString(const void *id, int clear)
|
||||||
{
|
{
|
||||||
|
@ -1334,8 +1392,8 @@ __xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *plen)
|
||||||
char *
|
char *
|
||||||
__xmlNodeGet(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 *element, *open, *start_tag=0;
|
||||||
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 return_len = 0;
|
size_t return_len = 0;
|
||||||
int found, num;
|
int found, num;
|
||||||
|
@ -1412,6 +1470,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
/*
|
/*
|
||||||
* get element name and a pointer to after the opening tag
|
* get element name and a pointer to after the opening tag
|
||||||
*/
|
*/
|
||||||
|
open = cur;
|
||||||
element = *name;
|
element = *name;
|
||||||
elementlen = *rlen;
|
elementlen = *rlen;
|
||||||
len_remaining = restlen;
|
len_remaining = restlen;
|
||||||
|
@ -1514,6 +1573,14 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
new = __xmlNodeGet(cur-1, &slen, &node, &nlen, &pos);
|
new = __xmlNodeGet(cur-1, &slen, &node, &nlen, &pos);
|
||||||
if (!new)
|
if (!new)
|
||||||
{
|
{
|
||||||
|
if (nlen == 0) /* error upstream */
|
||||||
|
{
|
||||||
|
*rlen = nlen;
|
||||||
|
*name = node;
|
||||||
|
*len = slen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (slen == restlen)
|
if (slen == restlen)
|
||||||
{
|
{
|
||||||
*rlen = 0;
|
*rlen = 0;
|
||||||
|
@ -1557,24 +1624,31 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
||||||
|
|
||||||
if (found == num)
|
if (found == num)
|
||||||
{
|
{
|
||||||
if (start_tag)
|
if (start_tag)
|
||||||
{
|
{
|
||||||
*len = new-ret-1;
|
*len = new-ret-1;
|
||||||
*name = start_tag;
|
*name = start_tag;
|
||||||
}
|
}
|
||||||
else /* report error */
|
else /* report error */
|
||||||
{
|
{
|
||||||
*rlen = 0;
|
*rlen = 0;
|
||||||
*name = new;
|
*name = new;
|
||||||
*len = XML_ELEMENT_NO_OPENING_TAG;
|
*len = XML_ELEMENT_NO_OPENING_TAG;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
/* else proper closing tag not yet found, continue. */
|
#ifndef XML_NONVALIDATING
|
||||||
/* TODO: could be a bad match to the opening tag though */
|
/* strcmp is a heavy operation when not required */
|
||||||
/* like: <test></teft> */
|
else if (strncmp(open, new+1, elementlen))
|
||||||
|
{
|
||||||
|
*rlen = 0;
|
||||||
|
*name = new+1;
|
||||||
|
*len = XML_ELEMENT_NO_CLOSING_TAG;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
new = memchr(cur, '>', restlen);
|
new = memchr(cur, '>', restlen);
|
||||||
if (!new)
|
if (!new)
|
||||||
|
|
|
@ -52,6 +52,16 @@ enum
|
||||||
*/
|
*/
|
||||||
void *xmlOpen(const char *);
|
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.
|
* Close the XML file after which no further processing is possible.
|
||||||
*
|
*
|
||||||
|
@ -329,6 +339,15 @@ int xmlErrorGetNo(const void *, int);
|
||||||
*/
|
*/
|
||||||
size_t xmlErrorGetLineNo(const void *, int);
|
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.
|
* Get a string that explains the last error.
|
||||||
*
|
*
|
||||||
|
|
|
@ -323,8 +323,9 @@ void grep_file(unsigned num)
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
size_t n = xmlErrorGetLineNo(xrid, 0);
|
size_t n = xmlErrorGetLineNo(xrid, 0);
|
||||||
|
size_t c = xmlErrorGetColumnNo(xrid, 0);
|
||||||
char *s = xmlErrorGetString(xrid, 1); /* clear the error */
|
char *s = xmlErrorGetString(xrid, 1); /* clear the error */
|
||||||
printf("%s: at line %u: '%s'\n",_filenames[num], n, s);
|
printf("%s: at line %u, column %u: '%s'\n",_filenames[num], n,c, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(xrid);
|
free(xrid);
|
||||||
|
|
Loading…
Reference in a new issue