libreport  2.7.2
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  - problem directory element names prefixed by "-",
103  which excludes given element from all wildcards
104 
105  - Nonexistent elements are silently ignored.
106 
107  You can add your own section:
108 
109  problem_formatter_t *formatter = problem_formatter_new();
110  problem_formatter_add_section(formatter, "additional_info", PFFF_REQUIRED);
111 
112  and then you can use the section in the formatting string:
113 
114  problem_formatter_load_string(formatter,
115  "::comment\n"
116  "%additional_info:: maps");
117  problem_formatter_generate_report(formatter, data, &report);
118 
119  printf("Problem: %s\n", problem_report_get_summary());
120  printf("%s\n", problem_report_get_description());
121  printf("Additional info: %s\n", problem_report_get_section(report, "additiona_info"));
122 
123  The lines above are equivalent to the following lines:
124 
125  printf("Problem: %s\n", problem_data_get_content_or_NULL(data, "reason"));
126  printf("%s\n", problem_data_get_content_or_NULL(data, "comment"));
127  printf("Additional info: %s\n", problem_data_get_content_or_NULL(data, "maps"));
128 */
129 #ifndef LIBREPORT_PROBLEM_REPORT_H
130 #define LIBREPORT_PROBLEM_REPORT_H
131 
132 #include <glib.h>
133 #include <stdio.h>
134 #include "problem_data.h"
135 
136 #ifdef __cplusplus
137 extern "C" {
138 #endif
139 
140 #define PR_SEC_SUMMARY "summary"
141 #define PR_SEC_DESCRIPTION "description"
142 
143 /*
144  * The problem report structure represents a problem data formatted according
145  * to a format string.
146  *
147  * A problem report is composed of well-known sections:
148  * - summary
149  * - descritpion
150  * - attach
151  *
152  * and custom sections accessed by:
153  * problem_report_get_section();
154  */
155 struct problem_report;
156 typedef struct problem_report problem_report_t;
157 
158 /*
159  * Helpers for easily switching between FILE and struct strbuf
160  */
161 
162 /*
163  * Type of buffer used by Problem report
164  */
165 typedef FILE problem_report_buffer;
166 
167 /*
168  * Wrapper for the proble buffer's formated output function.
169  */
170 #define problem_report_buffer_printf(buf, fmt, ...)\
171  fprintf((buf), (fmt), ##__VA_ARGS__)
172 
173 
174 /*
175  * Get a section buffer
176  *
177  * Use this function if you need to amend something to a formatted section.
178  *
179  * @param self Problem report
180  * @param section_name Name of required section
181  * @return Always valid pointer to a section buffer
182  */
183 problem_report_buffer *problem_report_get_buffer(const problem_report_t *self,
184  const char *section_name);
185 
186 /*
187  * Get Summary string
188  *
189  * The returned pointer is valid as long as you perform no further output to
190  * the summary buffer.
191  *
192  * @param self Problem report
193  * @return Non-NULL pointer to summary data
194  */
195 const char *problem_report_get_summary(const problem_report_t *self);
196 
197 /*
198  * Get Description string
199  *
200  * The returned pointer is valid as long as you perform no further output to
201  * the description buffer.
202  *
203  * @param self Problem report
204  * @return Non-NULL pointer to description data
205  */
206 const char *problem_report_get_description(const problem_report_t *self);
207 
208 /*
209  * Get Section's string
210  *
211  * The returned pointer is valid as long as you perform no further output to
212  * the section's buffer.
213  *
214  * @param self Problem report
215  * @param section_name Name of the required section
216  * @return Non-NULL pointer to description data
217  */
218 const char *problem_report_get_section(const problem_report_t *self,
219  const char *section_name);
220 
221 /*
222  * Get GList of the problem data items that are to be attached
223  *
224  * @param self Problem report
225  * @return A pointer to GList (NULL means empty list)
226  */
227 GList *problem_report_get_attachments(const problem_report_t *self);
228 
229 /*
230  * Releases all resources allocated by a problem report
231  *
232  * @param self Problem report
233  */
234 void problem_report_free(problem_report_t *self);
235 
236 
237 /*
238  * An enum of Extra section flags
239  */
240 enum problem_formatter_section_flags {
241  PFFF_REQUIRED = 1 << 0,
242 };
243 
244 /*
245  * The problem formatter structure formats a problem data according to a format
246  * string and stores result a problem report.
247  *
248  * The problem formatter uses '%reason%' as %summary section format string, if
249  * %summary is not provided by a format string.
250  */
251 struct problem_formatter;
252 typedef struct problem_formatter problem_formatter_t;
253 
254 /*
255  * Constructs a new problem formatter.
256  *
257  * @return Non-NULL pointer to the new problem formatter
258  */
259 problem_formatter_t *problem_formatter_new(void);
260 
261 /*
262  * Releases all resources allocated by a problem formatter
263  *
264  * @param self Problem formatter
265  */
266 void problem_formatter_free(problem_formatter_t *self);
267 
268 /*
269  * Adds a new recognized section
270  *
271  * The problem formatter ignores a section in the format spec if the section is
272  * not one of the default nor added by this function.
273  *
274  * How the problem formatter handles these extra sections:
275  *
276  * A custom section is something like %description section. %description is the
277  * default section where all text (sub)sections are stored. If the formatter
278  * finds the custom section in format string, then starts storing text
279  * (sub)sections in the custom section.
280  *
281  * (%description) |:: comment
282  * (%description) |
283  * (%description) |Package:: package
284  * (%description) |
285  * (%additiona_info) |%additional_info::
286  * (%additiona_info) |%reporter%
287  * (%additiona_info) |User:: user_name,uid
288  * (%additiona_info) |
289  * (%additiona_info) |Directories:: root,cwd
290  *
291  *
292  * @param self Problem formatter
293  * @param name Name of the added section
294  * @param flags Info about the added section
295  * @return Zero on success. -EEXIST if the name is already known by the formatter
296  */
297 int problem_formatter_add_section(problem_formatter_t *self, const char *name, int flags);
298 
299 /*
300  * Loads a problem format from a string.
301  *
302  * @param self Problem formatter
303  * @param fmt Format
304  * @return Zero on success or number of warnings (e.g. missing section,
305  * unrecognized section).
306  */
307 int problem_formatter_load_string(problem_formatter_t* self, const char *fmt);
308 
309 /*
310  * Loads a problem format from a file.
311  *
312  * @param self Problem formatter
313  * @param pat Path to the format file
314  * @return Zero on success or number of warnings (e.g. missing section,
315  * unrecognized section).
316  */
317 int problem_formatter_load_file(problem_formatter_t* self, const char *path);
318 
319 /*
320  * Creates a new problem report, formats the data according to the loaded
321  * format string and stores output in the report.
322  *
323  * @param self Problem formatter
324  * @param data Problem data to format
325  * @param report Pointer where the created problem report is to be stored
326  * @return Zero on success, otherwise non-zero value.
327  */
328 int problem_formatter_generate_report(const problem_formatter_t *self, problem_data_t *data, problem_report_t **report);
329 
330 #ifdef __cplusplus
331 }
332 #endif
333 
334 #endif // LIBREPORT_PROBLEM_REPORT_H