summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorJiri Moskovcak <jmoskovc@redhat.com>2011-03-07 15:36:07 +0100
committerJiri Moskovcak <jmoskovc@redhat.com>2011-03-07 15:36:07 +0100
commitf2e2bba844ed36ab3b9ce0c936dad673cfc865b9 (patch)
tree108183211df07ed372b16916fa7dfdbc23070f36 /src/lib
parentc9ab6a163d96771d9a731ba93ec500c40683c923 (diff)
downloadabrt-f2e2bba844ed36ab3b9ce0c936dad673cfc865b9.tar.gz
abrt-f2e2bba844ed36ab3b9ce0c936dad673cfc865b9.tar.xz
abrt-f2e2bba844ed36ab3b9ce0c936dad673cfc865b9.zip
added function to parse event description from xml file
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Makefile.am3
-rw-r--r--src/lib/event_xml_parser.c186
2 files changed, 188 insertions, 1 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index bad3e63a..9e9a7324 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -43,7 +43,8 @@ libreport_la_SOURCES = \
hooklib.c hooklib.h \
parse_release.c \
parse_options.c parse_options.h \
- steal_directory.c
+ steal_directory.c \
+ event_xml_parser.c
libreport_la_CPPFLAGS = \
-Wall -Werror \
-I$(srcdir)/../include/report -I$(srcdir)/../include \
diff --git a/src/lib/event_xml_parser.c b/src/lib/event_xml_parser.c
new file mode 100644
index 00000000..6b562957
--- /dev/null
+++ b/src/lib/event_xml_parser.c
@@ -0,0 +1,186 @@
+//#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "event_xml_parser.h"
+
+#define EVENT_ELEMENT "event"
+#define LABEL_ELEMENT "label"
+#define DESCRIPTION_ELEMENT "description"
+#define ALLOW_EMPTY_ELEMENT "allow-empty"
+#define OPTION_ELEMENT "option"
+#define ACTION_ELEMENT "action"
+#define NAME_ELEMENT "name"
+
+int in_option = 0;
+
+static const char *option_types[] =
+{
+ "text",
+ "bool",
+ "password",
+ "number",
+ NULL
+};
+
+// Called for open tags <foo bar="baz">
+void start_element(GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ //g_print("start: %s\n", element_name);
+
+ event_obj_t *ui = (event_obj_t *)user_data;
+
+ if(strcmp(element_name, OPTION_ELEMENT) == 0)
+ {
+ if(in_option == 0)
+ {
+ in_option = 1;
+ event_option_obj_t *option = (event_option_obj_t *)malloc(sizeof(event_option_obj_t));
+ //we need to prepend, so ui->options always points to the last created option
+ ui->options = g_list_prepend(ui->options, option);
+
+ int i;
+ for(i = 0; attribute_names[i] != NULL; ++i)
+ {
+ //g_print("attr: %s:%s\n", attribute_names[i], attribute_values[i]);
+ if(strcmp(attribute_names[i], "name") == 0)
+ option->name = strdup(attribute_values[i]);
+ if(strcmp(attribute_names[i], "type") == 0)
+ {
+ option_type_t type = 0;
+ for(type = OPTION_TYPE_TEXT; type < OPTION_TYPE_INVALID; ++type)
+ {
+ if(strcmp(option_types[type], attribute_values[i]) == 0)
+ option->type = type;
+ }
+ }
+ }
+ }
+ else
+ {
+ g_print("error, option nested in option!\n");
+ exit(-127);
+ }
+ }
+
+}
+
+ // Called for close tags </foo>
+void end_element(GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ event_obj_t *ui = (event_obj_t *)user_data;
+ if(strcmp(element_name, OPTION_ELEMENT) == 0)
+ {
+ in_option = 0;
+ }
+ if(strcmp(element_name, EVENT_ELEMENT) == 0)
+ {
+ //we need to revers the list, because we we're prepending
+ ui->options = g_list_reverse(ui->options);
+ in_option = 0;
+ }
+}
+
+ // Called for character data
+ // text is not nul-terminated
+void text(GMarkupParseContext *context,
+ const gchar *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+ event_obj_t *ui = (event_obj_t *)user_data;
+ const gchar * inner_element = g_markup_parse_context_get_element(context);
+ char *_text = (char *)malloc(text_len+1);
+ strncpy(_text, text, text_len);
+ _text[text_len] = '\0';
+ if(in_option == 1)
+ {
+ event_option_obj_t *option = (event_option_obj_t *)((ui->options)->data);
+ if(strcmp(inner_element, LABEL_ELEMENT) == 0)
+ {
+ //g_print("\tnew label: \t\t%s\n", _text);
+ option->label = _text;
+ }
+ if(strcmp(inner_element, DESCRIPTION_ELEMENT) == 0)
+ {
+ //g_print("\ttooltip: \t\t%s\n", _text);
+ option->description = _text;
+ }
+ }
+ else
+ {
+ /* we're not in option, so the description is for the event */
+ if(strcmp(inner_element, ACTION_ELEMENT) == 0)
+ {
+ //g_print("\taction description: \t%s\n", _text);
+ ui->action = _text;
+ }
+ if(strcmp(inner_element, NAME_ELEMENT) == 0)
+ {
+ //g_print("\tevent name: \t\t%s\n", _text);
+ ui->name = _text;
+ }
+ }
+ //will be freed when the event_option is freed
+ //free(_text);
+}
+
+ // Called for strings that should be re-saved verbatim in this same
+ // position, but are not otherwise interpretable. At the moment
+ // this includes comments and processing instructions.
+ // text is not nul-terminated
+void passthrough(GMarkupParseContext *context,
+ const gchar *passthrough_text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+ g_print("passthrough\n");
+}
+
+// Called on error, including one set by other
+// methods in the vtable. The GError should not be freed.
+void error(GMarkupParseContext *context,
+ GError *error,
+ gpointer user_data)
+{
+ g_print("error\n");
+}
+
+/* this function takes 2 parameters
+ * ui -> pointer to event_obj_t
+ * filename -> filename to read
+ * event_obj_t contains list of options, which is malloced by hits function
+ * and must be freed by the caller
+ */
+
+void load_event_from_file(event_obj_t *ui, const char* filename)
+{
+ GMarkupParser parser;
+ parser.start_element = &start_element;
+ parser.end_element = &end_element;
+ parser.text = &text;
+ parser.passthrough = &passthrough;
+ parser.error = &error;
+ GMarkupParseContext *context = g_markup_parse_context_new(
+ &parser, G_MARKUP_TREAT_CDATA_AS_TEXT,
+ ui, NULL);
+ FILE* fin = fopen(filename, "r");
+ size_t read_bytes = 0;
+ char buff[1024] = {'\0'};
+ while((read_bytes = fread(buff, 1, 1024, fin)))
+ {
+ g_markup_parse_context_parse(context, buff, read_bytes, NULL);
+ }
+ fclose(fin);
+ free(context);
+}