* 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
|
||||
* 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");
|
||||
# xmlClose(id);
|
||||
#
|
||||
void *xmlOpen(const char *);
|
||||
void xmlClose(const void *);
|
||||
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 *, const char *);
|
||||
void *xmlNodeCopy(void *, const char *);
|
||||
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);
|
||||
# num = xmlNodeGetNum(xmid, "node");
|
||||
# for (i=0; i<num; i++) {
|
||||
# if (xmlNodeGetPos(id, xmid, "element", i) != 0) {
|
||||
# if ((s = xmlGetString(xmid)) != 0) {
|
||||
|
@ -73,15 +74,15 @@ void *xmlNodeCopy(void *, const char *);
|
|||
# }
|
||||
# free(xmid);
|
||||
#
|
||||
void *xmlMarkId(void *);
|
||||
unsigned int xmlNodeGetNum(void *, const char *);
|
||||
void *xmlNodeGetPos(const void *, void *, const char *, int);
|
||||
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(void *);
|
||||
size_t xmlNodeCopyName(void *, const char *, size_t);
|
||||
char *xmlNodeGetName(const void *xid);
|
||||
size_t xmlNodeCopyName(const void *xid, const char *buffer, size_t size);
|
||||
|
||||
#
|
||||
# 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");
|
||||
# if (xmlCompareString(xnid, "value") == 0) printf("We have a match!\n");
|
||||
#
|
||||
long int xmlGetInt(void *);
|
||||
double xmlGetDouble(void *);
|
||||
char *xmlGetString(void *);
|
||||
size_t xmlCopyString(void *, char *, const size_t);
|
||||
int xmlCompareString(const void *, const char *);
|
||||
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
|
||||
|
@ -106,11 +107,12 @@ int xmlCompareString(const void *, const char *);
|
|||
# xnid = xmlNodeGet(id, "/path/to");
|
||||
# i = xmlNodeGetInt(xnid, "node");
|
||||
#
|
||||
long int xmlNodeGetInt(void *, const char *);
|
||||
double xmlNodeGetDouble(void *, const char *);
|
||||
char *xmlNodeGetString(void *, const char *);
|
||||
size_t xmlNodeCopyString(void *, const char *, char *, const size_t);
|
||||
int xmlNodeCompareString(const void *, const char *, const char *);
|
||||
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
|
||||
|
@ -118,15 +120,17 @@ int xmlNodeCompareString(const void *, const char *, const char *);
|
|||
# i = xmlAttributeGetInt(id, "n");
|
||||
#
|
||||
# or
|
||||
# s = xmlNodeGetString(id, "type");
|
||||
# s = xmlAttributeGetString(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 *);
|
||||
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
|
||||
|
@ -136,6 +140,7 @@ int xmlAttributeCompareString(const void *, const char *, const char *);
|
|||
# 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 *, int);
|
||||
size_t xmlErrorGetLineNo(const void *, int);
|
||||
const char *xmlErrorGetString(const void *, int);
|
||||
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);
|
||||
|
|
|
@ -46,16 +46,16 @@ typedef struct
|
|||
#endif
|
||||
#include <stdlib.h> /* free, malloc */
|
||||
#include <string.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <strings.h> /* strncasecmp */
|
||||
#else
|
||||
# define strncasecmp strnicmp
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#ifndef _MSC_VER
|
||||
# include <strings.h> /* strncasecmp */
|
||||
#else
|
||||
# define strncasecmp strnicmp
|
||||
#endif
|
||||
|
||||
#ifndef XML_NONVALIDATING
|
||||
#include "xml.h"
|
||||
|
@ -172,6 +172,25 @@ xmlOpen(const char *filename)
|
|||
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
|
||||
xmlClose(void *id)
|
||||
{
|
||||
|
@ -180,8 +199,11 @@ xmlClose(void *id)
|
|||
assert(rid != 0);
|
||||
assert(rid->name == 0);
|
||||
|
||||
if (rid->fd)
|
||||
{
|
||||
munmap(rid->start, rid->len);
|
||||
close(rid->fd);
|
||||
}
|
||||
|
||||
if (rid->info) free(rid->info);
|
||||
free(rid);
|
||||
|
@ -1183,13 +1205,49 @@ xmlErrorGetLineNo(const void *id, int clear)
|
|||
while (ps<pe)
|
||||
{
|
||||
new = memchr(ps, '\n', pe-ps);
|
||||
if (new)
|
||||
if (new) ret++;
|
||||
else break;
|
||||
ps = new+1;
|
||||
}
|
||||
|
||||
if (clear) err->err_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
xmlErrorGetColumnNo(const void *id, int clear)
|
||||
{
|
||||
size_t ret = 0;
|
||||
|
||||
if (id)
|
||||
{
|
||||
ps = new;
|
||||
ret++;
|
||||
}
|
||||
ps++;
|
||||
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;
|
||||
}
|
||||
|
@ -1334,8 +1392,8 @@ __xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *plen)
|
|||
char *
|
||||
__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 *element, *start_tag=0;
|
||||
size_t restlen, elementlen;
|
||||
size_t return_len = 0;
|
||||
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
|
||||
*/
|
||||
open = cur;
|
||||
element = *name;
|
||||
elementlen = *rlen;
|
||||
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);
|
||||
if (!new)
|
||||
{
|
||||
if (nlen == 0) /* error upstream */
|
||||
{
|
||||
*rlen = nlen;
|
||||
*name = node;
|
||||
*len = slen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (slen == restlen)
|
||||
{
|
||||
*rlen = 0;
|
||||
|
@ -1572,9 +1639,16 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
|
|||
}
|
||||
found++;
|
||||
}
|
||||
/* else proper closing tag not yet found, continue. */
|
||||
/* TODO: could be a bad match to the opening tag though */
|
||||
/* like: <test></teft> */
|
||||
#ifndef XML_NONVALIDATING
|
||||
/* strcmp is a heavy operation when not required */
|
||||
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);
|
||||
if (!new)
|
||||
|
|
|
@ -52,6 +52,16 @@ enum
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -329,6 +339,15 @@ int xmlErrorGetNo(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.
|
||||
*
|
||||
|
|
|
@ -323,8 +323,9 @@ void grep_file(unsigned num)
|
|||
if (r)
|
||||
{
|
||||
size_t n = xmlErrorGetLineNo(xrid, 0);
|
||||
size_t c = xmlErrorGetColumnNo(xrid, 0);
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue