int len;
int read_index;
int eof;
+ int error;
} XMLBUF;
}
+static void xml_end_file(XMLBUF *xml)
+{
+ xml->len = 0;
+ xml->eof = 1;
+ xml->read_index = 0 ;
+ xml->error = 1;
+}
+
/* All reading of the XML buffer done through these two functions */
/*** read a byte without advancing the offset */
static char xml_peek(XMLBUF *xml)
int offset = xml->read_index;
int delta;
char *ret = NULL;
+ char *tmp = NULL;
int size = 0;
/* perform first and N middle realloc()'s */
if(offset >= xml->len)
{
delta = offset - xml->read_index;
- ret = realloc(ret, size + delta + 1);
+ tmp = realloc(ret, size + delta + 1);
+ if(!tmp)goto xml_feed_malloc;
+ ret = tmp;
memcpy(ret+size, xml->buf + xml->read_index, delta);
size += delta;
ret[size]=0;
if(offset > xml->read_index)
{
delta = offset - xml->read_index;
- ret = realloc(ret, size + delta + 1);
+ tmp = realloc(ret, size + delta + 1);
+ if(!tmp)goto xml_feed_malloc;
+ ret = tmp;
memcpy(ret+size, xml->buf + xml->read_index, delta);
xml->read_index = offset;
size += delta;
ret[size]=0;
}
return ret;
+xml_feed_malloc:
+ free(ret);
+ xml_end_file(xml);
+ return 0;
}
/* this reads attributes from tags, of the form...
static void xml_read_attr(struct XMLBUF *xml, XmlNode *node)
{
int n=0;
+ char **tmp;
// how does this tag finish?
while(xml->len)
return;
n = ++node->nattrib;
- node->attrib = realloc(node->attrib, n * 2 * sizeof(char*) );
+ tmp = realloc(node->attrib, n * 2 * sizeof(char*) );
+ if(!tmp)goto xml_read_attr_malloc;
+ node->attrib = tmp;
node->attrib[--n*2+1] = 0;
feed_mask = XML_EQUALS | XML_SPACE | XML_CLOSE | XML_SLASH;
}
xml_skip(xml, XML_SPACE);
}
+ return;
+xml_read_attr_malloc:
+ xml_end_file(xml);
}
/* The big decision maker, is it a regular node, or a text node.
*/
static XmlNode* xml_parse(struct XMLBUF *xml)
{
- int offset;
int toff;
- char *tmp;
+ char **tmp;
+ char *stmp;
XmlNode **this, *ret = NULL;
-
+
this = &ret;
xml_skip(xml, XML_SPACE); // skip whitespace
- offset=0;
while( (xml->read_index < xml->len) || !xml->eof )
{
switch(is_special(xml_peek(xml)))
// read the tag name
feed_mask = XML_SPACE | XML_SLASH | XML_CLOSE;
*this = xml_new( xml_feed(xml, test_mask));
+ if(xml->error)goto xml_parse_malloc;
xml_skip(xml, XML_SPACE); // skip any whitespace
xml_read_attr(xml, *this); // read attributes
xml_skip(xml, XML_SPACE); // skip any whitespace
feed_mask = XML_OPEN;
(*this)->nattrib=1;
- (*this)->attrib = malloc(sizeof(char*)*2);
+ tmp = malloc(sizeof(char*)*2);
+ if(!tmp)goto xml_parse_malloc;
+ (*this)->attrib = tmp;
(*this)->attrib[1] = NULL;
- tmp = (*this)->attrib[0] = xml_feed(xml, test_mask);
+ stmp = (*this)->attrib[0] = xml_feed(xml, test_mask);
/* trim the whitespace off the end of text nodes,
* by overwriting the spaces will null termination. */
- toff = strlen(tmp)-1;
- while( ( is_special(tmp[toff]) & XML_SPACE ) )
+ toff = strlen(stmp)-1;
+ while( ( is_special(stmp[toff]) & XML_SPACE ) )
{
- tmp[toff] = 0;
+ stmp[toff] = 0;
toff --;
}
break;
}
- this = &(*this)->next;
+ this = &(*this)->next;
xml_skip(xml, XML_SPACE); // skip whitespace
- }
+ }
return ret;
+xml_parse_malloc:
+ xml_end_file(xml);
+ if(ret)xml_free(ret);
+ return 0;
}
// printf("xml_load(\"%s\");\n", filename);
+ xml.error = 0;
xml.eof = 0;
xml.read_index = 0;
xml.fptr = fopen(filename, "rb");
ret = xml_parse(&xml);
+ if(xml.error)
+ {
+ xml_free(ret);
+ ret = NULL;
+ }
+
free(xml.buf);
xml_load_fail_malloc_buf:
fclose(xml.fptr);