Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
libreport.spec.in | 1 +
po/POTFILES.in | 1 +
src/include/Makefile.am | 3 +-
src/include/event_usability.h | 59 ++++++++++++
src/lib/Makefile.am | 4 +-
src/lib/event_usability.c | 201 +++++++++++++++++++++++++++++++++++++++++
6 files changed, 267 insertions(+), 2 deletions(-)
create mode 100644 src/include/event_usability.h
create mode 100644 src/lib/event_usability.c
diff --git a/libreport.spec.in b/libreport.spec.in
index 6f6da01..3f730e3 100644
--- a/libreport.spec.in
+++ b/libreport.spec.in
@@ -296,6 +296,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null ||
:
%{_includedir}/libreport/problem_data.h
%{_includedir}/libreport/report.h
%{_includedir}/libreport/run_event.h
+%{_includedir}/libreport/event_usability.h
# Private api headers:
%{_includedir}/libreport/internal_abrt_dbus.h
%{_includedir}/libreport/internal_libreport.h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3203183..88c15f5 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -14,6 +14,7 @@ src/lib/parse_options.c
src/lib/curl.c
src/lib/client.c
src/lib/run_event.c
+src/lib/event_usability.c
src/lib/problem_data.c
src/plugins/abrt_rh_support.c
src/plugins/report.c
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index 61b49a3..7aa5f78 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -9,4 +9,5 @@ libreport_include_HEADERS = \
libreport_curl.h \
\
internal_libreport.h \
- internal_abrt_dbus.h
+ internal_abrt_dbus.h \
+ event_usability.h
diff --git a/src/include/event_usability.h b/src/include/event_usability.h
new file mode 100644
index 0000000..342c125
--- /dev/null
+++ b/src/include/event_usability.h
@@ -0,0 +1,59 @@
+/*
+ Copyright (C) 2009 Abrt team.
+ Copyright (C) 2009 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#ifndef LIBREPORT_EVENT_USABILITY_CHECK_H_
+#define LIBREPORT_EVENT_USABILITY_CHECK_H_
+
+#include <glib.h>
+#include "problem_data.h"
+#include "event_config.h"
+
+/*
+ * Event usability levels
+ */
+enum event_usability_status
+{
+ EUS_GOOD, ///< event is usuable
+ EUS_LOW, ///< event is possibly unusable
+ EUS_UNUSABLE, ///< event is not usable
+};
+
+/*
+ * Selects the forst usability
+ *
+ * @param f an event usability level
+ * @param s an event usability level
+ * @return returns the worst usability from the two passed
+ */
+enum event_usability_status worst_usability(enum event_usability_status f, enum
event_usability_status s);
+
+/*
+ * Cechcks event config agains problem items an returns event usability level.
+ *
+ * @param ec a checked event config
+ * @param pd a checked problem data
+ * @param not_loaded_items a items not in problem data, thier values are unknown
+ * @param issues a list of found issues
+ * @param min_level a minimal checked level, issues above this level are not reported
+ * @return returns the worst found usability
+ */
+enum event_usability_status check_event_usability(const event_config_t *ec, const
problem_data_t *pd,
+ const GList *not_loaded_items, GList
**issues,
+ enum event_usability_status
min_level);
+
+#endif /* LIBREPORT_EVENT_USABILITY_CHECK_H_ */
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index d2282db..cd1f164 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -47,7 +47,9 @@ libreport_la_SOURCES = \
report.c \
user_settings.c \
client.c \
- utf8.c
+ utf8.c \
+ event_usability.c
+
libreport_la_CPPFLAGS = \
-Wall -Wwrite-strings -Werror \
-I$(srcdir)/../include \
diff --git a/src/lib/event_usability.c b/src/lib/event_usability.c
new file mode 100644
index 0000000..f53168d
--- /dev/null
+++ b/src/lib/event_usability.c
@@ -0,0 +1,201 @@
+/*
+ Copyright (C) 2012 ABRT Team
+ Copyright (C) 2012 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <errno.h>
+#include <stdlib.h>
+#include "internal_libreport.h"
+#include "event_usability.h"
+
+enum event_usability_status worst_usability(enum event_usability_status f, enum
event_usability_status s)
+{
+ return f > s ? f : s;
+}
+
+static enum event_usability_status check_btrating_usability(const event_config_t *cfg,
const char *rating_str, char **message)
+{
+ enum event_usability_status ret = EUS_GOOD;
+
+ if (rating_str)
+ {
+ char *endptr;
+ errno = 0;
+ long rating = strtol(rating_str, &endptr, 10);
+ char *issue = NULL;
+ if (errno != 0 || endptr == rating_str || *endptr != '\0')
+ {
+ issue = xasprintf("%s '%s'.", _("Reporting disabled
because the rating does not contain a number"), rating_str);
+ ret = EUS_UNUSABLE;
+ }
+ else if (rating == cfg->ec_minimal_rating) /* bt is usable, but not complete,
so show a warning */
+ {
+ issue = xstrdup(_("The backtrace is incomplete, please make sure you
provide the steps to reproduce."));
+ ret = EUS_LOW;
+ }
+ else if (rating < cfg->ec_minimal_rating)
+ {
+ issue = xstrdup(_("Reporting disabled because the backtrace is
unusable."));
+ ret = EUS_UNUSABLE;
+ }
+
+ if (message)
+ *message = issue;
+ else
+ free(issue);
+ }
+
+ return ret;
+}
+
+struct problem_item_source
+{
+ bool (* contain_item)(void *, const char *);
+ void *source;
+};
+
+static char *get_complement_as_comma_list(const struct problem_item_source *source, const
char *input_item_list)
+{
+ if (!input_item_list)
+ return NULL;
+
+ char *item_list = xstrdup(input_item_list);
+ char *result = item_list;
+ char *dst = item_list;
+
+ while (item_list[0])
+ {
+ char *end = strchr(item_list, ',');
+ if (end) *end = '\0';
+ if (!source->contain_item(source->source, item_list))
+ {
+ if (dst != result)
+ *dst++ = ',';
+ dst = stpcpy(dst, item_list);
+ }
+ if (!end)
+ break;
+ *end = ',';
+ item_list = end + 1;
+ }
+ if (result == dst)
+ {
+ free(result);
+ result = NULL;
+ }
+ return result;
+}
+
+static bool contain_item_in_problem_data(void *source, const char *item_name)
+{
+ problem_data_t *pd = (problem_data_t *)source;
+ return !!get_problem_item_content_or_NULL(pd, item_name);
+}
+
+static bool contain_item_in_glist(void *source, const char *item_name)
+{
+ GList *list = (GList *)source;
+ return !!g_list_find_custom(list, (gpointer)item_name, (GCompareFunc)strcmp);
+}
+
+enum event_usability_status check_event_usability(const event_config_t *cfg,
+ const problem_data_t *pd,
+ const GList *not_loaded_items,
+ GList **issues,
+ enum event_usability_status min_level
+ )
+{
+ enum event_usability_status ret = EUS_GOOD;
+
+ if (!cfg)
+ return ret;
+
+ GList* work_issues = NULL;
+
+ struct problem_item_source pd_source;
+ pd_source.contain_item = contain_item_in_problem_data;
+ pd_source.source = (void *)pd;
+
+ struct problem_item_source list_source;
+ list_source.contain_item = contain_item_in_glist;
+ list_source.source = (void *)not_loaded_items;
+
+ /* find missing items */
+ char *existing_missing = get_complement_as_comma_list(&pd_source,
cfg->ec_requires_items);
+ char *created_missing = get_complement_as_comma_list(&list_source,
existing_missing);
+ if (created_missing)
+ {
+ if (worst_usability(EUS_UNUSABLE, min_level) == EUS_UNUSABLE)
+ {
+ ret = EUS_UNUSABLE;
+ work_issues = g_list_prepend(work_issues, xasprintf("%s : %s.",
_("Missing items "), created_missing));
+ }
+ }
+ free(existing_missing);
+ free(created_missing);
+
+#if 0
+ /* find already existing items */
+ if (cfg->ec_creates_items)
+ {
+ existing_missing = get_complement_as_comma_list(&pd_source,
cfg->ec_creates_items);
+ created_missing = get_complement_as_comma_list(&list_source,
existing_missing);
+ if (!created_missing)
+ {
+ if (worst_usability(EUS_LOW, min_level) == EUS_LOW)
+ {
+ ret = worst_usability(EUS_LOW, ret);
+ work_issues = g_list_prepend(work_issues, xasprintf("%s :
%s.", _("Items already exist "), cfg->ec_creates_items));
+ }
+ }
+ free(existing_missing);
+ free(created_missing);
+ }
+#endif
+
+ /* if a rating is in not loaded items we cannot assure */
+ /* that a rating is OK at a moment of event run */
+ const char *rating_str = get_problem_item_content_or_NULL((problem_data_t *)pd,
FILENAME_RATING);
+ if ((!rating_str || g_list_find_custom((GList *)not_loaded_items,
FILENAME_RATING, (GCompareFunc)strcmp)))
+ {
+ if (worst_usability(EUS_LOW, min_level) == EUS_LOW)
+ {
+ ret = worst_usability(EUS_LOW, ret);
+ work_issues = g_list_prepend(work_issues, xstrdup(_("Backtrace
rating can't be checked now and can be possibly low at a moment of event
run")));
+ }
+ }
+ else // btrating is in existing items
+ {
+ char *message = NULL;
+ enum event_usability_status bt = check_btrating_usability(cfg, rating_str,
&message);
+ if (worst_usability(bt, min_level) == bt)
+ {
+ ret = worst_usability(bt, ret);
+ if (message)
+ work_issues = g_list_prepend(work_issues, message);
+ }
+ else
+ free(message);
+ }
+
+ if (issues)
+ *issues = work_issues;
+ else
+ g_list_free(work_issues);
+
+ return ret;
+}
+
--
1.7.10.2