summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/Makefile.am3
-rw-r--r--src/include/abrtlib.h3
-rw-r--r--src/include/report/event_xml_parser.h41
-rw-r--r--src/lib/Makefile.am3
-rw-r--r--src/lib/event_xml_parser.c186
5 files changed, 234 insertions, 2 deletions
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index 477963c3..e21b043b 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -2,7 +2,8 @@ libreport_includedir = $(includedir)/report
libreport_include_HEADERS = \
report/crash_data.h \
report/dump_dir.h \
- report/run_event.h
+ report/run_event.h \
+ report/event_xml_parser.h
libabrt_includedir = $(includedir)/abrt
libabrt_include_HEADERS = \
diff --git a/src/include/abrtlib.h b/src/include/abrtlib.h
index 116f4b36..1b2f6bbc 100644
--- a/src/include/abrtlib.h
+++ b/src/include/abrtlib.h
@@ -82,6 +82,7 @@ int vdprintf(int d, const char *format, va_list ap);
#include "abrt_types.h"
#include "dump_dir.h"
#include "run_event.h"
+#include "event_xml_parser.h"
#ifdef __cplusplus
@@ -256,6 +257,8 @@ void parse_release_for_rhts(const char *pRelease, char **product, char **version
#define load_conf_file abrt_load_conf_file
bool load_conf_file(const char *pPath, map_string_h *settings, bool skipKeysWithoutValue);
+void load_event_description_from_file(event_obj_t *event_desc, const char* filename);
+
/* Tries to create a copy of dump_dir_name in base_dir, with same or similar basename.
* Returns NULL if copying failed. In this case, logs a message before returning. */
#define steal_directory abrt_steal_directory
diff --git a/src/include/report/event_xml_parser.h b/src/include/report/event_xml_parser.h
new file mode 100644
index 00000000..caf81506
--- /dev/null
+++ b/src/include/report/event_xml_parser.h
@@ -0,0 +1,41 @@
+#include <glib.h>
+
+typedef enum
+{
+ OPTION_TYPE_TEXT,
+ OPTION_TYPE_BOOL,
+ OPTION_TYPE_PASSWORD,
+ OPTION_TYPE_NUMBER,
+ OPTION_TYPE_INVALID,
+} option_type_t;
+
+/*
+ * struct to hold information about config options
+ * it's supposed to hold information about:
+ * type -> which designates the widget used to display it and we can do some test based on the type
+ * label
+ * allowed value(s) -> regexp?
+ * name -> env variable name
+ * value -> value retrieved from the gui, so when we want to set the env
+ * evn variables, we can just traverse the list of the options
+ * and set the env variables according to name:value in this structure
+ */
+typedef struct
+{
+ const char* label;
+ const char* name; //name of the value which should be used for env variable
+ char *value;
+ option_type_t type;
+ const char* description; //can be used as tooltip in gtk app
+ const char* allowed_value;
+ int required;
+} event_option_obj_t;
+
+//structure to hold the option data
+typedef struct
+{
+ const char *name; //name of the event "Bugzilla" "RedHat Support Uploader"
+ const char *title; //window title - not used right now, maybe the "name" is enough?
+ const char *action;//action description to show in gui like: Upload report to the Red Hat bugzilla"
+ GList *options;
+} event_obj_t;
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);
+}