#include <stdio.h>
+#include <stdlib.h>
#include <glib.h>
#include "xmlparser.h"
@@ -19,8 +20,8 @@ XmlTag xml_tag_new(XmlTag parent) {
tag->children = g_array_new(FALSE, FALSE, sizeof(XmlTag));
tag->parent = parent;
tag->value = g_string_new(NULL);
- tag->attributes = g_malloc(sizeof(GData *));
- g_datalist_init(tag->attributes);
+ //tag->attributes = g_malloc(sizeof(GData *));
+ //g_datalist_init(tag->attributes);
return tag;
}
@@ -32,8 +33,22 @@ void xml_tag_free(XmlTag tag) {
g_string_free(tag->name, TRUE);
g_array_free(tag->children, TRUE);
g_string_free(tag->value, TRUE);
- g_dataset_destroy(tag->attributes);
+ //g_dataset_destroy(tag->attributes);
+ //g_free(tag->attributes);
g_free(tag);
+ return;
+}
+
+// Frees an entire tree of XmlTags
+// Arguments:
+// * root: the root of the tree you wish to free
+void xml_tree_free(XmlTag root) {
+ int i;
+ for (i = 0; i < root->children->len; i++) {
+ xml_tree_free(g_array_index(root->children, XmlTag, i));
+ }
+ xml_tag_free(root);
+ return;
}
void xml_print_tree_helper(XmlTag tag) {
@@ -52,16 +67,18 @@ void xml_print_tree_helper(XmlTag tag) {
xml_print_tree_helper(g_array_index(tag->children, XmlTag, i));
}
depth--;
+ return;
}
// Prints the tag tree
// Arguments:
// * tag: This should be the root of the tree, and it won't be printed.
-void xml_print_tree(XmlTag tag) {
+void xml_tree_print(XmlTag tag) {
int i;
for (i = 0; i < tag->children->len; i++) {
xml_print_tree_helper(g_array_index(tag->children, XmlTag, i));
}
+ return;
}
// Strips whitespace from a GString
@@ -72,7 +89,7 @@ void xml_print_tree(XmlTag tag) {
// or if string was NULL, the amount of whitespace stripped off the
// beginning of the last stripped string.
int g_string_strip(GString *string) {
- static int i;
+ static int i = 0;
if (string == NULL) {
return i;
}
@@ -100,8 +117,9 @@ int g_string_strip(GString *string) {
// * message: the error message to print
// * line: the line at which the error occurred
// * col: the column at which the error occurred
-void xml_error(const char *message, int line, int col) {
- printf("ERROR (%d,%d): %s\n", line, col + g_string_strip(NULL) + 1, message);
+void xml_error(const char *message, unsigned int line, int col) {
+ printf("ERROR (%u,%d): %s\n", line, col + g_string_strip(NULL) + 1, message);
+ return;
}
// Checks a tag for validity
@@ -112,7 +130,7 @@ void xml_error(const char *message, int line, int col) {
// Returns:
// TRUE if the tag has a nonzero length name
// FALSE if the tag has a zero length name
-gboolean check_tag(XmlTag tag, int line, int col) {
+gboolean xml_tag_check(XmlTag tag, int line, int col) {
if (tag->name->len == 0) {
XML_STATUS = XML_UNNAMED_TAG;
xml_error(XML_E_UNNAMED_TAG, line, col);
@@ -123,6 +141,7 @@ gboolean check_tag(XmlTag tag, int line, int col) {
// This will parse the tagname to extract attributes from it
void xml_tag_parse_attributes(XmlTag tag) {
+ return;
}
// Parses an XML file
@@ -150,7 +169,7 @@ XmlTag xml_parse(char *path_to_file) {
gboolean escape = FALSE;
int i;
- int line = 1;
+ unsigned int line = 1;
char c;
while (g_io_channel_read_line_string(input, buffer, NULL, NULL) == G_IO_STATUS_NORMAL) {
g_string_strip(buffer);
@@ -164,26 +183,40 @@ XmlTag xml_parse(char *path_to_file) {
break;
}
case '<':
- if (opentag) {
- XML_STATUS = XML_INVALID_CHAR;
- xml_error(XML_E_INVALID_CHAR, line, i);
- return NULL;
+ if (!escape) {
+ if (opentag) {
+ XML_STATUS = XML_INVALID_CHAR;
+ xml_error(XML_E_INVALID_CHAR, line, i);
+ g_string_free(buffer, TRUE);
+ g_io_channel_shutdown(input, TRUE, NULL);
+ g_io_channel_unref(input);
+ xml_tree_free(head);
+ return NULL;
+ }
+ opentag = TRUE;
+ currenttag = xml_tag_new(currenttag);
+ g_array_append_val(currenttag->parent->children, currenttag);
+ break;
}
- opentag = TRUE;
- currenttag = xml_tag_new(currenttag);
- g_array_append_val(currenttag->parent->children, currenttag);
- break;
case '>':
if (opentag) opentag = FALSE;
else {
XML_STATUS = XML_INVALID_CLOSING;
xml_error(XML_E_INVALID_CLOSING, line, i);
+ g_string_free(buffer, TRUE);
+ g_io_channel_shutdown(input, TRUE, NULL);
+ g_io_channel_unref(input);
+ xml_tree_free(head);
return NULL;
}
if (g_str_has_prefix(currenttag->name->str, "/")) {
if (g_strcmp0(currenttag->name->str + 1, currenttag->parent->name->str)) {
XML_STATUS = XML_INVALID_CLOSING;
xml_error(XML_E_INVALID_CLOSING, line, i-currenttag->name->len - 1);
+ g_string_free(buffer, TRUE);
+ g_io_channel_shutdown(input, TRUE, NULL);
+ g_io_channel_unref(input);
+ xml_tree_free(head);
return NULL;
}
g_array_remove_index(currenttag->parent->children, currenttag->parent->children->len-1);
@@ -192,12 +225,20 @@ XmlTag xml_parse(char *path_to_file) {
xml_tag_free(temp);
} else if (g_str_has_suffix(currenttag->name->str, " /")) {
g_string_truncate(currenttag->name, currenttag->name->len - 2);
- if (!check_tag(currenttag, line, i)) {
+ if (!xml_tag_check(currenttag, line, i)) {
+ g_string_free(buffer, TRUE);
+ g_io_channel_shutdown(input, TRUE, NULL);
+ g_io_channel_unref(input);
+ xml_tree_free(head);
return NULL;
}
currenttag = currenttag->parent;
} else {
- if (!check_tag(currenttag, line, i)) {
+ if (!xml_tag_check(currenttag, line, i)) {
+ g_string_free(buffer, TRUE);
+ g_io_channel_shutdown(input, TRUE, NULL);
+ g_io_channel_unref(input);
+ xml_tree_free(head);
return NULL;
}
}
@@ -206,6 +247,10 @@ XmlTag xml_parse(char *path_to_file) {
if (currenttag == head) {
XML_STATUS = XML_VALUE_NO_PARENT;
xml_error(XML_E_VALUE_NO_PARENT, line, i);
+ g_string_free(buffer, TRUE);
+ g_io_channel_shutdown(input, TRUE, NULL);
+ g_io_channel_unref(input);
+ xml_tree_free(head);
return NULL;
}
if (opentag) {
@@ -221,8 +266,15 @@ XmlTag xml_parse(char *path_to_file) {
if (currenttag != head) {
XML_STATUS = XML_UNCLOSED_TAGS;
xml_error(XML_E_UNCLOSED_TAGS, 0, 0);
+ g_string_free(buffer, TRUE);
+ g_io_channel_shutdown(input, TRUE, NULL);
+ g_io_channel_unref(input);
+ xml_tree_free(head);
return NULL;
}
+ g_string_free(buffer, TRUE);
+ g_io_channel_shutdown(input, TRUE, NULL);
+ g_io_channel_unref(input);
return head;
}