/
githubmirror
/
libreport
Обзор
Документация
Войти
/
githubmirror
/
libreport
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/include/problem_report.h
365 строк
12 KB
Matěj Grabovský
lib: Auto-cleanup for problem structs
27 авг 2020, 22:51
27 авг 2020, 22:51
2821eda
Код
Авторство
О чём код?
/* Copyright (C) 2014 ABRT team Copyright (C) 2014 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. @brief API for formating of problem data These functions can be used to convert a problem data to its string representation. The output format can be parsed from a string: problem_formatter_t *formatter = problem_formatter_new(); problem_formatter_load_string(formatter, MY_FORMAT_STRING); or loaded from a file: problem_formatter_t *formatter = problem_formatter_new(); problem_formatter_load_file(formatter, MY_FORMAT_FILE); Once you have configured your formatter you can convert problem_data to problem_report by calling: problem_report_t *report; if (problem_formatter_generate_report(formatter, data, &report) != 0) errx(EXIT_FAILURE, "Problem data cannot be converted to problem report."); Now you can print the report: printf("Problem: %s\n", problem_report_get_summary()); printf("%s\n", problem_report_get_description()); puts("Problem attachments:"); for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a)) printf(" %s\n", a->data); Format description: ---- %summary:: summary format %attach:: elemnt1[,element2]... section:: element1[,element2]... The literal text line to be added to report. ---- Summary format is a line of text, where %element% is replaced by text element's content, and [[...%element%...]] block is used only if %element% exists. [[...]] blocks can nest. Sections can be: - %summary: bug summary format string. - %attach: a list of elements to attach. - text, double colon (::) and the list of comma-separated elements. Text can be empty (":: elem1, elem2, elem3" works), in this case "Text:" header line will be omitted. - %description: this section is implicit and contains all text sections unless another section was specified (%summary and %attach are ignored when determining text section's placement) - every text element belongs to the last specified section (%summary and %attach sections are ignored). If no section was specified, the text element belogns to %description. - If none of elements exists, the section will not be created. - Empty lines are NOT ignored. Elements can be: - problem directory element names, which get formatted as <element_name>: <contents> or <element_name>: :<contents> :<contents> :<contents> - problem directory element names prefixed by "%bare_", which is formatted as-is, without "<element_name>:" and colons - %oneline, %multiline, %text wildcards, which select all corresponding elements for output or attachment - %binary wildcard, valid only for %attach section, instructs to attach binary elements - %short_backtrace is a reserved element that is replaced with contents of backtrace file truncated to optimal number of frames - %reporter is a reserved element that is replaced by name and version of the software that created the report - problem directory element names prefixed by "-", which excludes given element from all wildcards - Nonexistent elements are silently ignored. You can add your own section: problem_formatter_t *formatter = problem_formatter_new(); problem_formatter_add_section(formatter, "additional_info", PFFF_REQUIRED); and then you can use the section in the formatting string: problem_formatter_load_string(formatter, "::comment\n" "%additional_info:: maps"); problem_formatter_generate_report(formatter, data, &report); printf("Problem: %s\n", problem_report_get_summary()); printf("%s\n", problem_report_get_description()); printf("Additional info: %s\n", problem_report_get_section(report, "additiona_info")); The lines above are equivalent to the following lines: printf("Problem: %s\n", problem_data_get_content_or_NULL(data, "reason")); printf("%s\n", problem_data_get_content_or_NULL(data, "comment")); printf("Additional info: %s\n", problem_data_get_content_or_NULL(data, "maps")); */ #pragma once #include <glib.h> #include <stdio.h> #include "problem_data.h" G_BEGIN_DECLS #define PR_SEC_SUMMARY "summary" #define PR_SEC_DESCRIPTION "description" /* * The problem report structure represents a problem data formatted according * to a format string. * * A problem report is composed of well-known sections: * - summary * - descritpion * - attach * * and custom sections accessed by: * problem_report_get_section(); */ struct problem_report; typedef struct problem_report problem_report_t; /* * The problem report settings structure contains advance settings * for report generating */ struct problem_report_settings { int prs_shortbt_max_frames; ///< generate only max top frames in %short_backtrace size_t prs_shortbt_max_text_size; ///< short bt only if it is bigger then this }; typedef struct problem_report_settings problem_report_settings_t; /* * Helpers for easily switching between FILE and GString */ /* * Type of buffer used by Problem report */ typedef FILE problem_report_buffer; /* * Wrapper for the proble buffer's formated output function. */ #define problem_report_buffer_printf(buf, fmt, ...)\ fprintf((buf), (fmt), ##__VA_ARGS__) /* * Get a section buffer * * Use this function if you need to amend something to a formatted section. * * @param self Problem report * @param section_name Name of required section * @return Always valid pointer to a section buffer */ problem_report_buffer *problem_report_get_buffer(const problem_report_t *self, const char *section_name); /* * Get Summary string * * The returned pointer is valid as long as you perform no further output to * the summary buffer. * * @param self Problem report * @return Non-NULL pointer to summary data */ const char *problem_report_get_summary(const problem_report_t *self); /* * Get Description string * * The returned pointer is valid as long as you perform no further output to * the description buffer. * * @param self Problem report * @return Non-NULL pointer to description data */ const char *problem_report_get_description(const problem_report_t *self); /* * Get Section's string * * The returned pointer is valid as long as you perform no further output to * the section's buffer. * * @param self Problem report * @param section_name Name of the required section * @return Non-NULL pointer to description data */ const char *problem_report_get_section(const problem_report_t *self, const char *section_name); /* * Get GList of the problem data items that are to be attached * * @param self Problem report * @return A pointer to GList (NULL means empty list) */ GList *problem_report_get_attachments(const problem_report_t *self); /* * Releases all resources allocated by a problem report * * @param self Problem report */ void problem_report_free(problem_report_t *self); G_DEFINE_AUTOPTR_CLEANUP_FUNC(problem_report_t, problem_report_free) /* * An enum of Extra section flags */ enum problem_formatter_section_flags { PFFF_REQUIRED = 1 << 0, ///< section must be present in the format spec }; /* * The problem formatter structure formats a problem data according to a format * string and stores result a problem report. * * The problem formatter uses '%reason%' as %summary section format string, if * %summary is not provided by a format string. */ struct problem_formatter; typedef struct problem_formatter problem_formatter_t; /* * Constructs a new problem formatter. * * @return Non-NULL pointer to the new problem formatter */ problem_formatter_t *problem_formatter_new(void); /* * Releases all resources allocated by a problem formatter * * @param self Problem formatter */ void problem_formatter_free(problem_formatter_t *self); G_DEFINE_AUTOPTR_CLEANUP_FUNC(problem_formatter_t, problem_formatter_free) /* * Adds a new recognized section * * The problem formatter ignores a section in the format spec if the section is * not one of the default nor added by this function. * * How the problem formatter handles these extra sections: * * A custom section is something like %description section. %description is the * default section where all text (sub)sections are stored. If the formatter * finds the custom section in format string, then starts storing text * (sub)sections in the custom section. * * (%description) |:: comment * (%description) | * (%description) |Package:: package * (%description) | * (%additiona_info) |%additional_info:: * (%additiona_info) |%reporter% * (%additiona_info) |User:: user_name,uid * (%additiona_info) | * (%additiona_info) |Directories:: root,cwd * * * @param self Problem formatter * @param name Name of the added section * @param flags Info about the added section * @return Zero on success. -EEXIST if the name is already known by the formatter */ int problem_formatter_add_section(problem_formatter_t *self, const char *name, int flags); /* * Loads a problem format from a string. * * @param self Problem formatter * @param fmt Format * @return Zero on success or number of warnings (e.g. missing section, * unrecognized section). */ int problem_formatter_load_string(problem_formatter_t* self, const char *fmt); /* * Loads a problem format from a file. * * @param self Problem formatter * @param pat Path to the format file * @return Zero on success or number of warnings (e.g. missing section, * unrecognized section). */ int problem_formatter_load_file(problem_formatter_t* self, const char *path); /* * Creates a new problem report, formats the data according to the loaded * format string and stores output in the report. * * @param self Problem formatter * @param data Problem data to format * @param report Pointer where the created problem report is to be stored * @return Zero on success, otherwise non-zero value. */ int problem_formatter_generate_report(const problem_formatter_t *self, problem_data_t *data, problem_report_t **report); /* * Returns problem report settings from given formatter * * @param self Problem formatter * @return problem report settings */ problem_report_settings_t problem_formatter_get_settings(const problem_formatter_t *self); /* * Sets problem report settings to given formatter * * @param self Problem formatter * @param settings Problem report settings */ void problem_formatter_set_settings(problem_formatter_t *self, problem_report_settings_t settings); G_END_DECLS