-/* Copyright (c) 2007, 2008 by Adalin B.V.
- * Copyright (c) 2007, 2008 by Erik Hofman
+/* 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
*/
#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <io.h>
typedef struct
{
- HANDLE m;
- void *p;
+ HANDLE m;
+ void *p;
} SIMPLE_UNMMAP;
-static SIMPLE_UNMMAP un;
-
-/*
- * map 'filename' and return a pointer to it.
- */
-static void *simple_mmap(int, size_t, SIMPLE_UNMMAP *);
-static void simple_unmmap(SIMPLE_UNMMAP *);
-
-# define mmap(a,b,c,d,e,f) simple_mmap((e), (b), &un)
-# define munmap(a,b) simple_unmmap(&un)
-
-# include <io.h>
-# include <stdlib.h>
-
#else /* !WIN32 */
# include <sys/mman.h>
# include <unistd.h>
#endif
-# include <fcntl.h>
+#ifndef NDEBUG
+# include <stdio.h>
+#endif
+#include <fcntl.h>
+#include <stdlib.h> /* free, malloc */
+#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
-#include <string.h>
#ifndef _MSC_VER
-# include <strings.h> /* strncasecmp */
+# include <strings.h> /* strncasecmp */
#else
# define strncasecmp strnicmp
#endif
-#ifndef NDEBUG
-#include <stdio.h>
+
+enum
+{
+ XML_NO_ERROR = 0,
+ XML_OUT_OF_MEMORY,
+ XML_FILE_NOT_FOUND,
+ XML_TRUNCATE_RESULT,
+ XML_ELEMENT_NO_OPENING_TAG,
+ XML_ELEMENT_NO_CLOSING_TAG,
+ XML_ATTRIB_NO_OPENING_QUOTE,
+ XML_ATTRIB_NO_CLOSING_QUOTE,
+ XML_MAX_ERROR
+};
+static const char *__xml_error_str[XML_MAX_ERROR];
+
+#ifndef XML_NONVALIDATING
+struct _xml_error
+{
+ char *pos;
+ int errno;
+};
+
+static void __xmlErrorSet(const void *, const char *, unsigned int);
+# define xmlErrorSet(a, b, c) __xmlErrorSet(a, b, c)
+#else /* !XML_NONVALIDATING */
+# define xmlErrorSet(a, b, c)
#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;
+#ifndef XML_NONVALIDATING
+ struct _xml_error *info;
+#endif
+# ifdef WIN32
+ SIMPLE_UNMMAP un;
+# endif
+};
struct _xml_id
{
- size_t len;
- char *start;
char *name;
- union {
- size_t name_len;
- int fd;
- } node;
+ char *start;
+ size_t len;
+ size_t name_len;
+#ifndef XML_NONVALIDATING
+ struct _root_id *root;
+#endif
};
static char *__xmlNodeCopy(const char *, size_t, const char *);
static char *__xmlNodeGetPath(const char *, size_t *, char **, size_t *);
static char *__xmlNodeGet(const char *, size_t *, char **, size_t *, size_t *);
static char *__xmlCommentSkip(const char *, size_t);
-static char *__xmlInfoSkip(const char *, size_t);
+static char *__xmlInfoProcess(const char *, size_t);
static void *__xml_memncasecmp(const char *, size_t *, char **, size_t *);
-#define PRINT(a, b, c) { \
+#ifdef WIN32
+/*
+ * map 'filename' and return a pointer to it.
+ */
+static void *simple_mmap(int, size_t, SIMPLE_UNMMAP *);
+static void simple_unmmap(SIMPLE_UNMMAP *);
+
+# define mmap(a,b,c,d,e,f) simple_mmap((e), (b), &rid->un)
+# define munmap(a,b) simple_unmmap(&rid->un)
+#endif
+
+#ifndef NDEBUG
+# define PRINT(a, b, c) { \
if (a) { \
size_t q, len = c; \
if (b < c) len = b; \
} else printf("Length (%u) seems too large at line %i\n",len, __LINE__); \
} else printf("NULL pointer at line %i\n", __LINE__); \
}
+#endif
void *
xmlOpen(const char *filename)
{
- struct _xml_id *id = 0;
+ struct _root_id *rid = 0;
if (filename)
{
int fd = open(filename, O_RDONLY);
if (fd > 0)
{
- id = malloc(sizeof(struct _xml_id));
- if (id)
+ rid = malloc(sizeof(struct _root_id));
+ if (rid)
{
struct stat statbuf;
fstat(fd, &statbuf);
- id->node.fd = fd;
- id->len = statbuf.st_size;
- id->start = mmap(0, id->len, PROT_READ, MAP_PRIVATE, fd, 0L);
- id->name = 0;
+ rid->fd = fd;
+ rid->len = statbuf.st_size;
+ rid->start = mmap(0, rid->len, PROT_READ, MAP_PRIVATE, fd, 0L);
+ rid->name = 0;
+#ifndef XML_NONVALIDATING
+ rid->info = 0;
+ __xmlErrorSet(rid, 0, 0);
+#endif
}
}
}
- return (void *)id;
+ return (void *)rid;
}
void
xmlClose(void *id)
{
- if (id)
- {
- struct _xml_id *xid = (struct _xml_id *)id;
- assert(xid->name == 0);
+ struct _root_id *rid = (struct _root_id *)id;
- munmap(xid->start, xid->len);
- close(xid->node.fd);
- free(id);
- id = 0;
- }
+ assert(rid != 0);
+ assert(rid->name == 0);
+
+ munmap(rid->start, rid->len);
+ close(rid->fd);
+ free(id);
+ id = 0;
}
void *
xmlNodeGet(const void *id, const char *path)
{
- struct _xml_id *xsid = 0;
+ struct _xml_id *xid = (struct _xml_id *)id;
+ struct _xml_id *xsid = 0;
+ size_t len, slen;
+ char *ptr, *node;
- if (id && path)
- {
- struct _xml_id *xid = (struct _xml_id *)id;
- size_t len, slen;
- char *ptr, *node;
-
- node = (char *)path;
- len = xid->len;
- slen = strlen(path);
- ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
- if (ptr)
- {
- xsid = malloc(sizeof(struct _xml_id));
- if (xsid)
- {
+ assert(id != 0);
+ assert(path != 0);
+
+ node = (char *)path;
+ len = xid->len;
+ slen = strlen(path);
+ ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
+ if (ptr)
+ {
+ xsid = malloc(sizeof(struct _xml_id));
+ if (xsid)
+ {
xsid->len = len;
xsid->start = ptr;
- xsid->node.name_len = slen;
+ xsid->name_len = slen;
xsid->name = node;
- }
- }
- }
+#ifndef XML_NONVALIDATING
+ if (xid->name)
+ xsid->root = xid->root;
+ else
+ xsid->root = (struct _root_id *)xid;
+#endif
+ }
+ else
+ xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
+ }
- return (void *)xsid;
+ return (void *)xsid;
}
void *
xmlNodeCopy(const void *id, const char *path)
{
+ struct _xml_id *xid = (struct _xml_id *)id;
struct _xml_id *xsid = 0;
-
- if (id && path)
+ char *ptr, *node, *p;
+ size_t slen, len;
+
+ node = (char *)path;
+ len = xid->len;
+ slen = strlen(path);
+ ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
+ if (ptr)
{
- struct _xml_id *xid = (struct _xml_id *)id;
- char *ptr, *node, *p;
- size_t slen, len;
-
- node = (char *)path;
- len = xid->len;
- slen = strlen(path);
- ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
- if (ptr)
+ xsid = malloc(sizeof(struct _xml_id) + len);
+ if (xsid)
{
- xsid = malloc(sizeof(struct _xml_id) + len);
- if (xsid)
- {
- p = (char *)xsid + sizeof(struct _xml_id);
-
- xsid->len = len;
- xsid->start = p;
- xsid->node.name_len = slen;
- xsid->name = node;
+ p = (char *)xsid + sizeof(struct _xml_id);
+
+ xsid->len = len;
+ xsid->start = p;
+ xsid->name_len = slen;
+ xsid->name = node;
+#ifndef XML_NONVALIDATING
+ if (xid->name)
+ xsid->root = xid->root;
+ else
+ xsid->root = (struct _root_id *)xid;
+#endif
- memcpy(xsid->start, ptr, len);
- }
- }
+ memcpy(xsid->start, ptr, len);
+ }
+ else
+ xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
}
return (void *)xsid;
size_t len;
char *ret;
- len = xid->node.name_len;
+ assert(xid != 0);
+
+ len = xid->name_len;
ret = malloc(len+1);
if (ret)
{
memcpy(ret, xid->name, len);
*(ret + len) = 0;
}
+ else
+ xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
return ret;
}
size_t
-xmlNodeCopyName(const void *id, char *buf, size_t len)
+xmlNodeCopyName(const void *id, char *buf, size_t buflen)
{
struct _xml_id *xid = (struct _xml_id *)id;
size_t slen = 0;
- if (buf)
+ assert(buf != 0);
+ assert(buflen > 0);
+
+ slen = buflen-1;
+ if (slen > xid->name_len)
{
- slen = len-1;
- if (slen > xid->node.name_len) slen = xid->node.name_len;
- memcpy(buf, xid->name, slen);
- *(buf + slen) = 0;
+ slen = xid->name_len;
+ xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
}
+ memcpy(buf, xid->name, slen);
+ *(buf + slen) = 0;
return slen;
}
struct _xml_id *xid = (struct _xml_id *)id;
size_t num = 0;
- if (xid && xid->len && path)
+ assert(xid != 0);
+ assert(path != 0);
+
+ if (xid->len)
{
char *nodename, *pathname;
size_t len, slen;
void *
xmlNodeGetPos(const void *pid, void *id, const char *element, size_t num)
{
+ struct _xml_id *xpid = (struct _xml_id *)pid;
+ struct _xml_id *xid = (struct _xml_id *)id;
+ size_t len, slen;
+ char *ptr, *node;
void *ret = 0;
- if (pid && element)
- {
- struct _xml_id *xpid = (struct _xml_id *)pid;
- struct _xml_id *xid = (struct _xml_id *)id;
- size_t len, slen;
- char *ptr, *node;
+ assert(xpid != 0);
+ assert(xid != 0);
+ assert(element != 0);
- len = xpid->len;
- slen = strlen(element);
- node = (char *)element;
- ptr = __xmlNodeGet(xpid->start, &len, &node, &slen, &num);
- if (ptr)
- {
- xid->len = len;
- xid->start = ptr;
- xid->name = node;
- xid->node.name_len = slen;
- ret = xid;
- }
+ len = xpid->len;
+ slen = strlen(element);
+ node = (char *)element;
+ ptr = __xmlNodeGet(xpid->start, &len, &node, &slen, &num);
+ if (ptr)
+ {
+ xid->len = len;
+ xid->start = ptr;
+ xid->name = node;
+ xid->name_len = slen;
+ ret = xid;
}
return ret;
struct _xml_id *xid = (struct _xml_id *)id;
char *str = 0;
- if (xid && xid->len)
+ assert(xid != 0);
+
+ if (xid->len)
{
char *ps, *pe, *pend;
int nlen;
memcpy(str, ps, nlen);
*(str+nlen) = 0;
}
+ else
+ xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
}
}
{
struct _xml_id *xid = (struct _xml_id *)id;
size_t ret = 0;
+
+ assert(xid != 0);
+ assert(buffer != 0);
+ assert(buflen > 0);
- if (xid && xid->len && buffer && buflen)
+ if (xid->len)
{
char *ps, *pe, *pend;
size_t slen, nlen;
if (nlen)
{
- if (nlen >= buflen) nlen = buflen-1;
+ if (nlen >= buflen)
+ {
+ nlen = buflen-1;
+ xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
+ }
memcpy(buffer, ps, nlen);
*(buffer+nlen) = 0;
ret = nlen;
struct _xml_id *xid = (struct _xml_id *)id;
int ret = -1;
- if (xid && xid->len && s && (strlen(s) > 0))
+ assert(xid != 0);
+ assert(s != 0);
+
+ if (xid->len && (strlen(s) > 0))
{
char *ps, *pe;
struct _xml_id *xid = (struct _xml_id *)id;
char *str = 0;
- if (xid && xid->len && path)
+ assert(xid != 0);
+ assert(path != 0);
+
+ if (xid->len)
{
str = __xmlNodeCopy(xid->start, xid->len, path);
if (str)
struct _xml_id *xid = (struct _xml_id *)id;
size_t ret = 0;
- if (xid && xid->len && path && buffer && buflen)
+ assert(xid != 0);
+ assert(path != 0);
+ assert(buffer != 0);
+ assert(buflen > 0);
+
+ if (xid->len)
{
char *str, *node;
size_t slen, nlen;
while ((pe>ps) && isspace(*pe)) pe--;
nlen = (pe-ps)+1;
- if (nlen >= buflen) nlen = buflen-1;
+ if (nlen >= buflen)
+ {
+ nlen = buflen-1;
+ xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
+ }
memcpy(buffer, ps, nlen);
*(buffer + nlen) = '\0';
struct _xml_id *xid = (struct _xml_id *)id;
int ret = -1;
- if (xid && xid->len && path && s && (strlen(s) > 0))
+ assert(xid != 0);
+ assert(path != 0);
+ assert(s != 0);
+
+ if (xid->len && (strlen(s) > 0))
{
char *node, *str, *ps, *pe;
size_t len, slen;
struct _xml_id *xid = (struct _xml_id *)id;
long int li = 0;
- if (xid && xid->len)
+ assert(xid != 0);
+
+ if (xid->len)
{
char *end = xid->start + xid->len;
li = strtol(xid->start, &end, 10);
struct _xml_id *xid = (struct _xml_id *)id;
long int li = 0;
- if (path && xid && xid->len)
+ assert(xid != 0);
+ assert(path != 0);
+
+ if (xid->len)
{
size_t len, slen;
char *str, *node;
struct _xml_id *xid = (struct _xml_id *)id;
double d = 0.0;
- if (xid && xid->len)
+ assert(xid != 0);
+
+ if (xid->len)
{
char *end = xid->start + xid->len;
d = strtod(xid->start, &end);
struct _xml_id *xid = (struct _xml_id *)id;
double d = 0.0;
- if (path && xid && xid->len)
+ assert(xid != 0);
+ assert(path != 0);
+
+ if (xid->len)
{
size_t len, slen;
char *str, *node;
void *
xmlMarkId(const void *id)
{
- struct _xml_id *xmid = 0;
+ struct _xml_id *xmid = 0;
- if (id)
- {
- xmid = malloc(sizeof(struct _xml_id));
- if (xmid)
- {
- memcpy(xmid, id, sizeof(struct _xml_id));
- }
- }
+ assert(id != 0);
+
+ xmid = malloc(sizeof(struct _xml_id));
+ if (xmid)
+ {
+ struct _root_id *xrid = (struct _root_id *)id;
+ if (xrid->name == 0)
+ {
+ xmid->name = "";
+ xmid->start = xrid->start;
+ xmid->len = xrid->len;
+ xmid->name_len = 0;
+#ifndef XML_NONVALIDATING
+ xmid->root = xrid;
+#endif
+ }
+ else
+ {
+ struct _xml_id *xid = (struct _xml_id *)id;
+
+ xmid->name = xid->name;
+ xmid->start = xid->start;
+ xmid->len = xid->len;
+ xmid->name_len = xid->name_len;
+#ifndef XML_NONVALIDATING
+ xmid->root = xid->root;
+#endif
+ }
+ }
+ else
+ xmlErrorSet(id, 0, XML_OUT_OF_MEMORY);
- return (void *)xmid;
+ return (void *)xmid;
}
double
xmlAttributeGetDouble(const void *id, const char *name)
{
- struct _xml_id *xid = (struct _xml_id *)id;
- double ret = 0.0;
+ struct _xml_id *xid = (struct _xml_id *)id;
+ double ret = 0.0;
- if (xid && xid->start && xid->len && xid->node.name_len)
- {
- char *p, *end, *new = 0;
-
- assert(xid->start > xid->name);
-
- p = xid->name + xid->node.name_len;
- end = xid->start-1;
-
- while ((p<end) && isspace(*p)) p++;
- while (p<end)
- {
- size_t elementlen = strlen(name);
- size_t restlen = end-p;
- char *element = (char *)name;
-
- new = __xml_memncasecmp(p, &restlen, &element, &elementlen);
- if (new)
- {
- restlen = end-p;
- new = memchr(p, '=', restlen);
- if (new)
- {
- new++;
- if (*new == '"') new++;
- restlen -= (new-p);
- end = new+restlen;
- ret = strtod(new, &end);
- }
- break;
- }
+ assert(xid != 0);
+ assert(name != 0);
- while ((p<end) && !isspace(*p)) p++;
- if (p<end)
- while ((p<end) && isspace(*p)) p++;
- }
- }
+ if (xid->len && xid->name_len)
+ {
+ char *ps, *pe;
+
+ assert(xid->start > xid->name);
+
+ ps = xid->name + xid->name_len + 1;
+ pe = xid->start - 1;
- return ret;
+ while ((ps<pe) && isspace(*ps)) ps++;
+ while (ps<pe)
+ {
+ size_t slen = strlen(name);
+ size_t restlen = pe-ps;
+
+ if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
+ {
+ ps += slen;
+ if ((ps<pe) && (*ps == '='))
+ {
+ char *start;
+
+ ps++;
+ if (*ps == '"' || *ps == '\'') ps++;
+ else
+ {
+ xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
+ return 0;
+ }
+
+ start = ps;
+ while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
+ if (ps<pe)
+ ret = strtod(start, &ps);
+ else
+ {
+ xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
+ return 0;
+ }
+ }
+ break;
+ }
+
+ while ((ps<pe) && !isspace(*ps)) ps++;
+ if (ps<pe)
+ while ((ps<pe) && isspace(*ps)) ps++;
+ }
+ }
+
+ return ret;
}
long int
xmlAttributeGetInt(const void *id, const char *name)
{
- struct _xml_id *xid = (struct _xml_id *)id;
- long int ret = 0;
+ struct _xml_id *xid = (struct _xml_id *)id;
+ long int ret = 0;
- if (xid && xid->start && xid->len && xid->node.name_len)
- {
- char *p, *end, *new = 0;
-
- assert(xid->start > xid->name);
-
- p = xid->name + xid->node.name_len;
- end = xid->start-1;
-
- while ((p<end) && isspace(*p)) p++;
- while (p<end)
- {
- size_t elementlen = strlen(name);
- size_t restlen = end-p;
- char *element = (char *)name;
-
- new = __xml_memncasecmp(p, &restlen, &element, &elementlen);
- if (new)
- {
- restlen = end-p;
- new = memchr(p, '=', restlen);
- if (new)
- {
- new++;
- if (*new == '"') new++;
- restlen -= (new-p);
- end = new+restlen;
- ret = strtol(new, &end, 10);
- }
- break;
- }
+ assert(xid != 0);
+ assert(name != 0);
- while ((p<end) && !isspace(*p)) p++;
- if (p<end)
- while ((p<end) && isspace(*p)) p++;
- }
- }
+ if (xid->len && xid->name_len)
+ {
+ char *ps, *pe;
+
+ assert(xid->start > xid->name);
+
+ ps = xid->name + xid->name_len + 1;
+ pe = xid->start - 1;
- return ret;
+ while ((ps<pe) && isspace(*ps)) ps++;
+ while (ps<pe)
+ {
+ size_t slen = strlen(name);
+ size_t restlen = pe-ps;
+
+ if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
+ {
+ ps += slen;
+ if ((ps<pe) && (*ps == '='))
+ {
+ char *start;
+
+ ps++;
+ if (*ps == '"' || *ps == '\'') ps++;
+ else
+ {
+ xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
+ return 0;
+ }
+
+ start = ps;
+ while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
+ if (ps<pe)
+ ret = strtol(start, &ps, 10);
+ else
+ {
+ xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
+ return 0;
+ }
+ }
+ break;
+ }
+
+ while ((ps<pe) && !isspace(*ps)) ps++;
+ if (ps<pe)
+ while ((ps<pe) && isspace(*ps)) ps++;
+ }
+ }
+
+ return ret;
}
char *
xmlAttributeGetString(const void *id, const char *name)
{
- struct _xml_id *xid = (struct _xml_id *)id;
- char *ret = 0;
+ struct _xml_id *xid = (struct _xml_id *)id;
+ char *ret = 0;
- if (xid && xid->start && xid->len && xid->node.name_len)
- {
- char *p, *end, *new = 0;
-
- assert(xid->start > xid->name);
-
- p = xid->name + xid->node.name_len;
- end = xid->start-1;
-
- while ((p<end) && isspace(*p)) p++;
- while (p<end)
- {
- size_t elementlen = strlen(name);
- size_t restlen = end-p;
- char *element = (char *)name;
-
- new = __xml_memncasecmp(p, &restlen, &element, &elementlen);
- if (new)
- {
- restlen = end-p;
- new = memchr(p, '=', restlen);
- if (new)
+ assert(xid != 0);
+ assert(name != 0);
+
+ if (xid->len && xid->name_len)
+ {
+ char *ps, *pe;
+
+ assert(xid->start > xid->name);
+
+ ps = xid->name + xid->name_len + 1;
+ pe = xid->start - 1;
+
+ while ((ps<pe) && isspace(*ps)) ps++;
+ while (ps<pe)
+ {
+ size_t slen = strlen(name);
+ size_t restlen = pe-ps;
+
+ if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
{
- new++;
- if (*new == '"') new++;
- p = new;
- while ((p<end) && (*p != '"') && (*p != ' ')) p++;
- if (p<end)
- {
- ret = calloc(1, p-new);
- memcpy(ret, new, (p-new));
- }
+ ps += slen;
+ if ((ps<pe) && (*ps == '='))
+ {
+ char *start;
+
+ ps++;
+ if (*ps == '"' || *ps == '\'') ps++;
+ else
+ {
+ xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
+ return 0;
+ }
+
+ start = ps;
+ while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
+ if (ps<pe)
+ {
+ ret = malloc(ps-start);
+ if (ret)
+ {
+ memcpy(ret, start, (ps-start));
+ *(ret+(ps-start)) = '\0';
+ }
+ else
+ xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
+ }
+ else
+ {
+ xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
+ return 0;
+ }
+ }
+ break;
}
- break;
- }
- while ((p<end) && !isspace(*p)) p++;
- if (p<end)
- while ((p<end) && isspace(*p)) p++;
- }
- }
+ while ((ps<pe) && !isspace(*ps)) ps++;
+ if (ps<pe)
+ while ((ps<pe) && isspace(*ps)) ps++;
+ }
+ }
- return ret;
+ return ret;
}
size_t
xmlAttributeCopyString(const void *id, const char *name,
char *buffer, size_t buflen)
{
- struct _xml_id *xid = (struct _xml_id *)id;
- size_t ret = 0;
+ struct _xml_id *xid = (struct _xml_id *)id;
+ size_t ret = 0;
- if (xid && xid->start && xid->len && xid->node.name_len
- && buffer && buflen)
- {
- char *ps, *pe;
+ assert(xid != 0);
+ assert(name != 0);
+ assert(buffer != 0);
+ assert(buflen > 0);
- *buffer = '\0';
- ps = xid->name + xid->node.name_len + 1;
- pe = xid->start - 1;
+ if (xid->len && xid->name_len)
+ {
+ char *ps, *pe;
- assert((int)(pe-ps) > 0);
+ assert(xid->start > xid->name);
- while ((ps<pe) && isspace(*ps)) ps++;
- while (ps<pe)
- {
- size_t slen = strlen(name);
- size_t restlen = pe-ps;
+ *buffer = '\0';
+ ps = xid->name + xid->name_len + 1;
+ pe = xid->start - 1;
- if ((restlen >= slen) && (strncasecmp(ps, name, slen) == 0))
- {
- char *new;
+ while ((ps<pe) && isspace(*ps)) ps++;
+ while (ps<pe)
+ {
+ size_t slen = strlen(name);
+ size_t restlen = pe-ps;
- restlen = pe-ps;
- new = memchr(ps, '=', restlen);
- if (new)
- {
- new++;
- if (*new == '"') new++;
- ps = new;
- while ((ps<pe) && (*ps != '"') && (*ps != ' ')) ps++;
- if (ps<pe)
+ if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
+ {
+ ps += slen;
+ if ((ps<pe) && (*ps == '='))
{
- restlen = ps-new;
- if (restlen >= buflen) restlen = buflen-1;
- memcpy(buffer, new, restlen);
- *(buffer+restlen) = 0;
- ret = restlen;
+ char *start;
+
+ ps++;
+ if (*ps == '"' || *ps == '\'') ps++;
+ else
+ {
+ xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
+ return 0;
+ }
+
+ start = ps;
+ while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
+ if (ps<pe)
+ {
+ restlen = ps-start;
+ if (restlen >= buflen)
+ {
+ restlen = buflen-1;
+ xmlErrorSet(xid, ps, XML_TRUNCATE_RESULT);
+ }
+
+ memcpy(buffer, start, restlen);
+ *(buffer+restlen) = 0;
+ ret = restlen;
+ }
+ else
+ {
+ xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
+ return 0;
+ }
}
- }
- break;
- }
+ break;
+ }
- while ((ps<pe) && !isspace(*ps)) ps++;
- if (ps<pe)
- while ((ps<pe) && isspace(*ps)) ps++;
- }
- }
+ while ((ps<pe) && !isspace(*ps)) ps++;
+ if (ps<pe)
+ while ((ps<pe) && isspace(*ps)) ps++;
+ }
+ }
- return ret;
+ return ret;
}
int
xmlAttributeCompareString(const void *id, const char *name, const char *s)
{
- struct _xml_id *xid = (struct _xml_id *)id;
- int ret = -1;
-
- if (xid && xid->start && xid->len && xid->node.name_len
- && s && strlen(s))
- {
- char *ps, *pe;
+ struct _xml_id *xid = (struct _xml_id *)id;
+ int ret = -1;
+
+ assert(xid != 0);
+ assert(name != 0);
+ assert(s != 0);
- ps = xid->name + xid->node.name_len + 1;
- pe = xid->start - 1;
+ if (xid->len && xid->name_len && strlen(s))
+ {
+ char *ps, *pe;
- assert((int)(pe-ps) > 0);
+ assert(xid->start > xid->name);
- while ((ps<pe) && isspace(*ps)) ps++;
- while (ps<pe)
- {
- size_t slen = strlen(name);
- size_t restlen = pe-ps;
+ ps = xid->name + xid->name_len + 1;
+ pe = xid->start - 1;
- if ((restlen >= slen) && (strncasecmp(ps, name, slen) == 0))
- {
- char *new;
+ while ((ps<pe) && isspace(*ps)) ps++;
+ while (ps<pe)
+ {
+ size_t slen = strlen(name);
+ size_t restlen = pe-ps;
- restlen = pe-ps;
- new = memchr(ps, '=', restlen);
- if (new)
- {
- new++;
- if (*new == '"') new++;
- ps = new;
- while ((ps<pe) && (*ps != '"') && (*ps != ' ')) ps++;
- if (ps<pe)
+ if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
+ {
+ ps += slen;
+ if ((ps<pe) && (*ps == '='))
{
- int alen = ps-new;
- ret = strncasecmp(new, s, alen);
+ char *start;
+
+ ps++;
+ if (*ps == '"' || *ps == '\'') ps++;
+ else
+ {
+ xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
+ return 0;
+ }
+
+ start = ps;
+ while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
+ if (ps<pe)
+ ret = strncasecmp(start, s, ps-start);
+ else
+ {
+ xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
+ return 0;
+ }
}
- }
- break;
- }
+ break;
+ }
- while ((ps<pe) && !isspace(*ps)) ps++;
- if (ps<pe)
- while ((ps<pe) && isspace(*ps)) ps++;
- }
- }
+ while ((ps<pe) && !isspace(*ps)) ps++;
+ if (ps<pe)
+ while ((ps<pe) && isspace(*ps)) ps++;
+ }
+ }
- return ret;
+ return ret;
}
+#ifndef XML_NONVALIDATING
+int
+xmlErrorGetNo(const void *id)
+{
+ int 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;
+
+ ret = err->errno;
+ err->errno = 0;
+ }
+ }
+
+ return ret;
+}
+
+size_t
+xmlErrorGetLineNo(const void *id)
+{
+ 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);
+ if (new)
+ {
+ ps = new;
+ ret++;
+ }
+ ps++;
+ }
+ }
+ }
+
+ return ret;
+}
+
+const char *
+xmlErrorGetString(const void *id)
+{
+ char *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;
+ if (XML_NO_ERROR <= err->errno && err->errno < XML_MAX_ERROR)
+ ret = (char *)__xml_error_str[err->errno];
+ else
+ ret = "incorrect error number.";
+ }
+ }
+
+ return ret;
+}
+#endif
+
/* -------------------------------------------------------------------------- */
-static char *
+static const char *__xml_error_str[XML_MAX_ERROR] =
+{
+ "no error.",
+ "unable to allocate enough memory.",
+ "unable to open file for reading.",
+ "provided buffer us too small to hold the result, truncating.",
+ "incompatible opening tag for element.",
+ "missing or invalid closing tag for element.",
+ "missing or invalid opening quote for attribute.",
+ "missing or invalid closing quote for attribute."
+};
+
+char *
__xmlNodeCopy(const char *start, size_t len, const char *path)
{
- char *node, *p, *ret = 0;
- size_t rlen, slen;
-
- rlen = len;
- slen = strlen(path);
- node = (char *)path;
- p = __xmlNodeGetPath(start, &rlen, &node, &slen);
- if (p && rlen)
- {
- ret = calloc(1, rlen+1);
- memcpy(ret, p, rlen);
- }
+ char *node, *p, *ret = 0;
+ size_t rlen, slen;
+
+ rlen = len;
+ slen = strlen(path);
+ node = (char *)path;
+ p = __xmlNodeGetPath(start, &rlen, &node, &slen);
+ if (p && rlen)
+ {
+ ret = malloc(rlen+1);
+ if (ret)
+ {
+ memcpy(ret, p, rlen);
+ *(ret+rlen+1) = '\0';
+ }
+ else
+ xmlErrorSet(0, 0, XML_OUT_OF_MEMORY);
+ }
- return ret;
+ return ret;
}
char *
ret = __xmlNodeGet(start, len, &node, &plen, &num);
if (ret && path)
{
- plen = slen - (path - *name);
- ret = __xmlNodeGetPath(ret, len, &path, &plen);
+ plen = slen - (path - *name);
+ ret = __xmlNodeGetPath(ret, len, &path, &plen);
}
*name = path;
}
else if (*cur == '?')
{
- new = __xmlInfoSkip(cur, restlen);
+ new = __xmlInfoProcess(cur, restlen);
if (!new) return 0;
restlen -= new-cur;
}
char *
-__xmlInfoSkip(const char *start, size_t len)
+__xmlInfoProcess(const char *start, size_t len)
{
char *cur, *new;
return rptr;
}
+#ifndef XML_NONVALIDATING
+void
+__xmlErrorSet(const void *id, const char *pos, unsigned int errno)
+{
+ struct _xml_id *xid = (struct _xml_id *)id;
+ struct _root_id *rid;
+
+ assert(xid != 0);
+
+ if (xid->name) rid = xid->root;
+ else rid = (struct _root_id *)xid;
+
+ assert(rid != 0);
+
+ if (rid->info == 0)
+ rid->info = malloc(sizeof(struct _xml_error));
+
+ if (rid->info)
+ {
+ struct _xml_error *err = rid->info;
+
+ err->pos = (char *)pos;
+ err->errno = errno;
+ }
+}
+#endif
+
#ifdef WIN32
/* Source:
* https://mollyrocket.com/forums/viewtopic.php?p=2529
void
simple_unmmap(SIMPLE_UNMMAP *un)
{
- UnmapViewOfFile(un->p);
- CloseHandle(un->m);
+ UnmapViewOfFile(un->p);
+ CloseHandle(un->m);
}
#endif