Signed-off-by: Jakub Filak <[email protected]>
---
 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

Reply via email to