diff options
Diffstat (limited to 'lib/utils/make_descr.cpp')
-rw-r--r-- | lib/utils/make_descr.cpp | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/lib/utils/make_descr.cpp b/lib/utils/make_descr.cpp new file mode 100644 index 00000000..46d9644d --- /dev/null +++ b/lib/utils/make_descr.cpp @@ -0,0 +1,236 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 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 "abrtlib.h" +#include "crash_types.h" +#include "debug_dump.h" /* FILENAME_ARCHITECTURE etc */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#if ENABLE_NLS +# include <libintl.h> +# define _(S) gettext(S) +#else +# define _(S) (S) +#endif + +using namespace std; + +static void add_content(bool &was_multiline, string& description, const char *header, const char *content) +{ + /* We separate multiline contents with emply line */ + if (was_multiline) + description += '\n'; + + while (content[0] == '\n') + content++; + + if (strchr(content, '\n') == NULL) + { + if (skip_whitespace(content)[0] == '\0') + { + /* empty, dont report at all */ + return; + } + /* one string value, like OS release */ + description += header; + description += ": "; + description += content; + description += '\n'; + was_multiline = 0; + } + else + { + /* multi-string value, like backtrace */ + if (!was_multiline && description.size() != 0) /* if wasn't yet separated */ + description += '\n'; /* do it now */ + description += header; + description += "\n-----\n"; + description += content; + if (content[strlen(content) - 1] != '\n') + description += '\n'; + was_multiline = 1; + } +} + +/* Items we don't want to include */ +static const char *const blacklisted_items[] = { + FILENAME_ANALYZER , + FILENAME_COREDUMP , + FILENAME_DESCRIPTION, /* package description - basically useless */ + FILENAME_HOSTNAME , + FILENAME_GLOBAL_UUID, + CD_UUID , + CD_INFORMALL , + CD_DUPHASH , + CD_DUMPDIR , + CD_COUNT , + CD_REPORTED , + CD_MESSAGE , + NULL +}; + +string make_description_bz(const map_crash_data_t& pCrashData) +{ + string description; + string long_description; + + map_crash_data_t::const_iterator it = pCrashData.begin(); + for (; it != pCrashData.end(); it++) + { + const string& itemname = it->first; + const string& type = it->second[CD_TYPE]; + const string& content = it->second[CD_CONTENT]; + if (type == CD_TXT) + { + /* Skip items we are not interested in */ + const char *const *bl = blacklisted_items; + while (*bl) + { + if (itemname == *bl) + break; + bl++; + } + if (*bl) + continue; /* blacklisted */ + if (content == "1.\n2.\n3.\n") + continue; /* user did not change default "How to reproduce" */ + + if (content.size() <= CD_TEXT_ATT_SIZE) + { + /* Add small (less than few kb) text items inline */ + bool was_multiline = 0; + string tmp; + add_content(was_multiline, + tmp, + /* "reproduce: blah" looks ugly, fixing: */ + itemname == FILENAME_REPRODUCE ? "How to reproduce" : itemname.c_str(), + content.c_str() + ); + + if (was_multiline) + { + /* Not one-liner */ + if (long_description.size() != 0) + long_description += '\n'; + long_description += tmp; + } + else + { + description += tmp; + } + } else { + bool was_multiline = 0; + add_content(was_multiline, description, "Attached file", itemname.c_str()); + } + } + } + + /* One-liners go first, then multi-line items */ + if (description.size() != 0 && long_description.size() != 0) + { + description += '\n'; + } + description += long_description; + + return description; +} + +string make_description_logger(const map_crash_data_t& pCrashData) +{ + string description; + string long_description; + + map_crash_data_t::const_iterator it = pCrashData.begin(); + for (; it != pCrashData.end(); it++) + { + const string &filename = it->first; + const string &type = it->second[CD_TYPE]; + const string &content = it->second[CD_CONTENT]; + if (type == CD_TXT + || type == CD_BIN + ) { + /* Skip items we are not interested in */ + const char *const *bl = blacklisted_items; + while (*bl) + { + if (filename == *bl) + break; + bl++; + } + if (*bl) + continue; /* blacklisted */ + if (content == "1.\n2.\n3.\n") + continue; /* user did not change default "How to reproduce" */ + + bool was_multiline = 0; + string tmp; + add_content(was_multiline, tmp, filename.c_str(), content.c_str()); + + if (was_multiline) + { + if (long_description.size() != 0) + long_description += '\n'; + long_description += tmp; + } + else + { + description += tmp; + } + } + } + + if (description.size() != 0 && long_description.size() != 0) + { + description += '\n'; + } + description += long_description; + + return description; +} + +string make_description_reproduce_comment(const map_crash_data_t& pCrashData) +{ + map_crash_data_t::const_iterator end = pCrashData.end(); + map_crash_data_t::const_iterator it; + + string howToReproduce; + it = pCrashData.find(FILENAME_REPRODUCE); + if (it != end) + { + if ((it->second[CD_CONTENT].size() > 0) + && (it->second[CD_CONTENT] != "1.\n2.\n3.\n")) + { + howToReproduce = "\n\nHow to reproduce\n" + "-----\n"; + howToReproduce += it->second[CD_CONTENT]; + } + } + string comment; + it = pCrashData.find(FILENAME_COMMENT); + if (it != end) + { + if (it->second[CD_CONTENT].size() > 0) + { + comment = "\n\nComment\n" + "-----\n"; + comment += it->second[CD_CONTENT]; + } + } + return howToReproduce + comment; +} |