libreport  2.8.0
A tool to inform users about various problems on the running system
problem_report.h
1 /*
2  Copyright (C) 2014 ABRT team
3  Copyright (C) 2014 RedHat Inc
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 
19  @brief API for formating of problem data
20 
21  These functions can be used to convert a problem data to its string
22  representation.
23 
24  The output format can be parsed from a string:
25 
26  problem_formatter_t *formatter = problem_formatter_new();
27  problem_formatter_load_string(formatter, MY_FORMAT_STRING);
28 
29  or loaded from a file:
30 
31  problem_formatter_t *formatter = problem_formatter_new();
32  problem_formatter_load_file(formatter, MY_FORMAT_FILE);
33 
34  Once you have configured your formatter you can convert problem_data to
35  problem_report by calling:
36 
37  problem_report_t *report;
38  if (problem_formatter_generate_report(formatter, data, &report) != 0)
39  errx(EXIT_FAILURE, "Problem data cannot be converted to problem report.");
40 
41  Now you can print the report:
42 
43  printf("Problem: %s\n", problem_report_get_summary());
44  printf("%s\n", problem_report_get_description());
45 
46  puts("Problem attachments:");
47  for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a))
48  printf(" %s\n", a->data);
49 
50  Format description:
51 
52  ----
53  %summary:: summary format
54  %attach:: elemnt1[,element2]...
55  section:: element1[,element2]...
56  The literal text line to be added to report.
57  ----
58 
59  Summary format is a line of text, where %element% is replaced by
60  text element's content, and [[...%element%...]] block is used only if
61  %element% exists. [[...]] blocks can nest.
62 
63  Sections can be:
64  - %summary: bug summary format string.
65 
66  - %attach: a list of elements to attach.
67 
68  - text, double colon (::) and the list of comma-separated elements.
69  Text can be empty (":: elem1, elem2, elem3" works),
70  in this case "Text:" header line will be omitted.
71 
72  - %description: this section is implicit and contains all text
73  sections unless another section was specified (%summary and %attach
74  are ignored when determining text section's placement)
75 
76  - every text element belongs to the last specified section (%summary
77  and %attach sections are ignored). If no section was specified,
78  the text element belogns to %description.
79 
80  - If none of elements exists, the section will not be created.
81 
82  - Empty lines are NOT ignored.
83 
84  Elements can be:
85  - problem directory element names, which get formatted as
86  <element_name>: <contents>
87  or
88  <element_name>:
89  :<contents>
90  :<contents>
91  :<contents>
92 
93  - problem directory element names prefixed by "%bare_",
94  which is formatted as-is, without "<element_name>:" and colons
95 
96  - %oneline, %multiline, %text wildcards, which select all corresponding
97  elements for output or attachment
98 
99  - %binary wildcard, valid only for %attach section, instructs to attach
100  binary elements
101 
102  - %short_backtrace is a reserved element that is replaced with contents
103  of backtrace file truncated to optimal number of frames
104 
105  - %reporter is a reserved element that is replaced by name and version
106  of the software that created the report
107 
108  - problem directory element names prefixed by "-",
109  which excludes given element from all wildcards
110 
111  - Nonexistent elements are silently ignored.
112 
113  You can add your own section:
114 
115  problem_formatter_t *formatter = problem_formatter_new();
116  problem_formatter_add_section(formatter, "additional_info", PFFF_REQUIRED);
117 
118  and then you can use the section in the formatting string:
119 
120  problem_formatter_load_string(formatter,
121  "::comment\n"
122  "%additional_info:: maps");
123  problem_formatter_generate_report(formatter, data, &report);
124 
125  printf("Problem: %s\n", problem_report_get_summary());
126  printf("%s\n", problem_report_get_description());
127  printf("Additional info: %s\n", problem_report_get_section(report, "additiona_info"));
128 
129  The lines above are equivalent to the following lines:
130 
131  printf("Problem: %s\n", problem_data_get_content_or_NULL(data, "reason"));
132  printf("%s\n", problem_data_get_content_or_NULL(data, "comment"));
133  printf("Additional info: %s\n", problem_data_get_content_or_NULL(data, "maps"));
134 */
135 #ifndef LIBREPORT_PROBLEM_REPORT_H
136 #define LIBREPORT_PROBLEM_REPORT_H
137 
138 #include <glib.h>
139 #include <stdio.h>
140 #include "problem_data.h"
141 
142 #ifdef __cplusplus
143 extern "C" {
144 #endif
145 
146 #define PR_SEC_SUMMARY "summary"
147 #define PR_SEC_DESCRIPTION "description"
148 
149 /*
150  * The problem report structure represents a problem data formatted according
151  * to a format string.
152  *
153  * A problem report is composed of well-known sections:
154  * - summary
155  * - descritpion
156  * - attach
157  *
158  * and custom sections accessed by:
159  * problem_report_get_section();
160  */
161 struct problem_report;
162 typedef struct problem_report problem_report_t;
163 
164 /*
165  * Helpers for easily switching between FILE and struct strbuf
166  */
167 
168 /*
169  * Type of buffer used by Problem report
170  */
171 typedef FILE problem_report_buffer;
172 
173 /*
174  * Wrapper for the proble buffer's formated output function.
175  */
176 #define problem_report_buffer_printf(buf, fmt, ...)\
177  fprintf((buf), (fmt), ##__VA_ARGS__)
178 
179 
180 /*
181  * Get a section buffer
182  *
183  * Use this function if you need to amend something to a formatted section.
184  *
185  * @param self Problem report
186  * @param section_name Name of required section
187  * @return Always valid pointer to a section buffer
188  */
189 problem_report_buffer *problem_report_get_buffer(const problem_report_t *self,
190  const char *section_name);
191 
192 /*
193  * Get Summary string
194  *
195  * The returned pointer is valid as long as you perform no further output to
196  * the summary buffer.
197  *
198  * @param self Problem report
199  * @return Non-NULL pointer to summary data
200  */
201 const char *problem_report_get_summary(const problem_report_t *self);
202 
203 /*
204  * Get Description string
205  *
206  * The returned pointer is valid as long as you perform no further output to
207  * the description buffer.
208  *
209  * @param self Problem report
210  * @return Non-NULL pointer to description data
211  */
212 const char *problem_report_get_description(const problem_report_t *self);
213 
214 /*
215  * Get Section's string
216  *
217  * The returned pointer is valid as long as you perform no further output to
218  * the section's buffer.
219  *
220  * @param self Problem report
221  * @param section_name Name of the required section
222  * @return Non-NULL pointer to description data
223  */
224 const char *problem_report_get_section(const problem_report_t *self,
225  const char *section_name);
226 
227 /*
228  * Get GList of the problem data items that are to be attached
229  *
230  * @param self Problem report
231  * @return A pointer to GList (NULL means empty list)
232  */
233 GList *problem_report_get_attachments(const problem_report_t *self);
234 
235 /*
236  * Releases all resources allocated by a problem report
237  *
238  * @param self Problem report
239  */
240 void problem_report_free(problem_report_t *self);
241 
242 
243 /*
244  * An enum of Extra section flags
245  */
246 enum problem_formatter_section_flags {
247  PFFF_REQUIRED = 1 << 0,
248 };
249 
250 /*
251  * The problem formatter structure formats a problem data according to a format
252  * string and stores result a problem report.
253  *
254  * The problem formatter uses '%reason%' as %summary section format string, if
255  * %summary is not provided by a format string.
256  */
257 struct problem_formatter;
258 typedef struct problem_formatter problem_formatter_t;
259 
260 /*
261  * Constructs a new problem formatter.
262  *
263  * @return Non-NULL pointer to the new problem formatter
264  */
265 problem_formatter_t *problem_formatter_new(void);
266 
267 /*
268  * Releases all resources allocated by a problem formatter
269  *
270  * @param self Problem formatter
271  */
272 void problem_formatter_free(problem_formatter_t *self);
273 
274 /*
275  * Adds a new recognized section
276  *
277  * The problem formatter ignores a section in the format spec if the section is
278  * not one of the default nor added by this function.
279  *
280  * How the problem formatter handles these extra sections:
281  *
282  * A custom section is something like %description section. %description is the
283  * default section where all text (sub)sections are stored. If the formatter
284  * finds the custom section in format string, then starts storing text
285  * (sub)sections in the custom section.
286  *
287  * (%description) |:: comment
288  * (%description) |
289  * (%description) |Package:: package
290  * (%description) |
291  * (%additiona_info) |%additional_info::
292  * (%additiona_info) |%reporter%
293  * (%additiona_info) |User:: user_name,uid
294  * (%additiona_info) |
295  * (%additiona_info) |Directories:: root,cwd
296  *
297  *
298  * @param self Problem formatter
299  * @param name Name of the added section
300  * @param flags Info about the added section
301  * @return Zero on success. -EEXIST if the name is already known by the formatter
302  */
303 int problem_formatter_add_section(problem_formatter_t *self, const char *name, int flags);
304 
305 /*
306  * Loads a problem format from a string.
307  *
308  * @param self Problem formatter
309  * @param fmt Format
310  * @return Zero on success or number of warnings (e.g. missing section,
311  * unrecognized section).
312  */
313 int problem_formatter_load_string(problem_formatter_t* self, const char *fmt);
314 
315 /*
316  * Loads a problem format from a file.
317  *
318  * @param self Problem formatter
319  * @param pat Path to the format file
320  * @return Zero on success or number of warnings (e.g. missing section,
321  * unrecognized section).
322  */
323 int problem_formatter_load_file(problem_formatter_t* self, const char *path);
324 
325 /*
326  * Creates a new problem report, formats the data according to the loaded
327  * format string and stores output in the report.
328  *
329  * @param self Problem formatter
330  * @param data Problem data to format
331  * @param report Pointer where the created problem report is to be stored
332  * @return Zero on success, otherwise non-zero value.
333  */
334 int problem_formatter_generate_report(const problem_formatter_t *self, problem_data_t *data, problem_report_t **report);
335 
336 #ifdef __cplusplus
337 }
338 #endif
339 
340 #endif // LIBREPORT_PROBLEM_REPORT_H