diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/Makefile.am | 3 | ||||
-rw-r--r-- | src/include/abrtlib.h | 3 | ||||
-rw-r--r-- | src/include/report/event_xml_parser.h | 41 | ||||
-rw-r--r-- | src/lib/Makefile.am | 3 | ||||
-rw-r--r-- | src/lib/event_xml_parser.c | 186 |
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); +} |