Branch data Line data Source code
1 : : /* GLIB - Library of useful routines for C programming
2 : : * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 : : *
4 : : * SPDX-License-Identifier: LGPL-2.1-or-later
5 : : *
6 : : * This library is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU Lesser General Public
8 : : * License as published by the Free Software Foundation; either
9 : : * version 2.1 of the License, or (at your option) any later version.
10 : : *
11 : : * This library is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * Lesser General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General Public
17 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : */
19 : :
20 : : /*
21 : : * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 : : * file for a list of people on the GLib Team. See the ChangeLog
23 : : * files for a list of changes. These files are distributed with
24 : : * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 : : */
26 : :
27 : : #include "config.h"
28 : :
29 : : #include "gvalgrind.h"
30 : : #include <string.h>
31 : :
32 : : #include "gerror.h"
33 : :
34 : : #include "ghash.h"
35 : : #include "glib-init.h"
36 : : #include "gslice.h"
37 : : #include "gstrfuncs.h"
38 : : #include "gtestutils.h"
39 : : #include "gthread.h"
40 : :
41 : : static GRWLock error_domain_global;
42 : : /* error_domain_ht must be accessed with error_domain_global
43 : : * locked.
44 : : */
45 : : static GHashTable *error_domain_ht = NULL;
46 : :
47 : : void
48 : 1090 : g_error_init (void)
49 : : {
50 : 1090 : error_domain_ht = g_hash_table_new (NULL, NULL);
51 : 1090 : }
52 : :
53 : : typedef struct
54 : : {
55 : : /* private_size is already aligned. */
56 : : gsize private_size;
57 : : GErrorInitFunc init;
58 : : GErrorCopyFunc copy;
59 : : GErrorClearFunc clear;
60 : : } ErrorDomainInfo;
61 : :
62 : : /* Must be called with error_domain_global locked.
63 : : */
64 : : static inline ErrorDomainInfo *
65 : 237398 : error_domain_lookup (GQuark domain)
66 : : {
67 : 474796 : return g_hash_table_lookup (error_domain_ht,
68 : 237398 : GUINT_TO_POINTER (domain));
69 : : }
70 : :
71 : : /* Copied from gtype.c. */
72 : : #define STRUCT_ALIGNMENT (2 * sizeof (gsize))
73 : : #define ALIGN_STRUCT(offset) \
74 : : ((offset + (STRUCT_ALIGNMENT - 1)) & -STRUCT_ALIGNMENT)
75 : :
76 : : static void
77 : 2 : error_domain_register (GQuark error_quark,
78 : : gsize error_type_private_size,
79 : : GErrorInitFunc error_type_init,
80 : : GErrorCopyFunc error_type_copy,
81 : : GErrorClearFunc error_type_clear)
82 : : {
83 : 2 : g_rw_lock_writer_lock (&error_domain_global);
84 : 2 : if (error_domain_lookup (error_quark) == NULL)
85 : : {
86 : 2 : ErrorDomainInfo *info = g_new (ErrorDomainInfo, 1);
87 : 2 : info->private_size = ALIGN_STRUCT (error_type_private_size);
88 : 2 : info->init = error_type_init;
89 : 2 : info->copy = error_type_copy;
90 : 2 : info->clear = error_type_clear;
91 : :
92 : 2 : g_hash_table_insert (error_domain_ht,
93 : 2 : GUINT_TO_POINTER (error_quark),
94 : : info);
95 : : }
96 : : else
97 : : {
98 : 0 : const char *name = g_quark_to_string (error_quark);
99 : :
100 : 0 : g_critical ("Attempted to register an extended error domain for %s more than once", name);
101 : : }
102 : 2 : g_rw_lock_writer_unlock (&error_domain_global);
103 : 2 : }
104 : :
105 : : /**
106 : : * g_error_domain_register_static:
107 : : * @error_type_name: static string to create a #GQuark from
108 : : * @error_type_private_size: size of the private error data in bytes
109 : : * @error_type_init: (scope forever): function initializing fields of the private error data
110 : : * @error_type_copy: (scope forever): function copying fields of the private error data
111 : : * @error_type_clear: (scope forever): function freeing fields of the private error data
112 : : *
113 : : * This function registers an extended #GError domain.
114 : : *
115 : : * @error_type_name should not be freed. @error_type_private_size must
116 : : * be greater than 0.
117 : : *
118 : : * @error_type_init receives an initialized #GError and should then initialize
119 : : * the private data.
120 : : *
121 : : * @error_type_copy is a function that receives both original and a copy
122 : : * #GError and should copy the fields of the private error data. The standard
123 : : * #GError fields are already handled.
124 : : *
125 : : * @error_type_clear receives the pointer to the error, and it should free the
126 : : * fields of the private error data. It should not free the struct itself though.
127 : : *
128 : : * Normally, it is better to use G_DEFINE_EXTENDED_ERROR(), as it
129 : : * already takes care of passing valid information to this function.
130 : : *
131 : : * Returns: #GQuark representing the error domain
132 : : * Since: 2.68
133 : : */
134 : : GQuark
135 : 1 : g_error_domain_register_static (const char *error_type_name,
136 : : gsize error_type_private_size,
137 : : GErrorInitFunc error_type_init,
138 : : GErrorCopyFunc error_type_copy,
139 : : GErrorClearFunc error_type_clear)
140 : : {
141 : : GQuark error_quark;
142 : :
143 : 1 : g_return_val_if_fail (error_type_name != NULL, 0);
144 : 1 : g_return_val_if_fail (error_type_private_size > 0, 0);
145 : 1 : g_return_val_if_fail (error_type_init != NULL, 0);
146 : 1 : g_return_val_if_fail (error_type_copy != NULL, 0);
147 : 1 : g_return_val_if_fail (error_type_clear != NULL, 0);
148 : :
149 : 1 : error_quark = g_quark_from_static_string (error_type_name);
150 : 1 : error_domain_register (error_quark,
151 : : error_type_private_size,
152 : : error_type_init,
153 : : error_type_copy,
154 : : error_type_clear);
155 : 1 : return error_quark;
156 : : }
157 : :
158 : : /**
159 : : * g_error_domain_register:
160 : : * @error_type_name: string to create a #GQuark from
161 : : * @error_type_private_size: size of the private error data in bytes
162 : : * @error_type_init: (scope forever): function initializing fields of the private error data
163 : : * @error_type_copy: (scope forever): function copying fields of the private error data
164 : : * @error_type_clear: (scope forever): function freeing fields of the private error data
165 : : *
166 : : * This function registers an extended #GError domain.
167 : : * @error_type_name will be duplicated. Otherwise does the same as
168 : : * g_error_domain_register_static().
169 : : *
170 : : * Returns: #GQuark representing the error domain
171 : : * Since: 2.68
172 : : */
173 : : GQuark
174 : 1 : g_error_domain_register (const char *error_type_name,
175 : : gsize error_type_private_size,
176 : : GErrorInitFunc error_type_init,
177 : : GErrorCopyFunc error_type_copy,
178 : : GErrorClearFunc error_type_clear)
179 : : {
180 : : GQuark error_quark;
181 : :
182 : 1 : g_return_val_if_fail (error_type_name != NULL, 0);
183 : 1 : g_return_val_if_fail (error_type_private_size > 0, 0);
184 : 1 : g_return_val_if_fail (error_type_init != NULL, 0);
185 : 1 : g_return_val_if_fail (error_type_copy != NULL, 0);
186 : 1 : g_return_val_if_fail (error_type_clear != NULL, 0);
187 : :
188 : 1 : error_quark = g_quark_from_string (error_type_name);
189 : 1 : error_domain_register (error_quark,
190 : : error_type_private_size,
191 : : error_type_init,
192 : : error_type_copy,
193 : : error_type_clear);
194 : 1 : return error_quark;
195 : : }
196 : :
197 : : static GError *
198 : 118734 : g_error_allocate (GQuark domain, ErrorDomainInfo *out_info)
199 : : {
200 : : guint8 *allocated;
201 : : GError *error;
202 : : ErrorDomainInfo *info;
203 : : gsize private_size;
204 : :
205 : 118734 : g_rw_lock_reader_lock (&error_domain_global);
206 : 118734 : info = error_domain_lookup (domain);
207 : 118734 : if (info != NULL)
208 : : {
209 : 3 : if (out_info != NULL)
210 : 3 : *out_info = *info;
211 : 3 : private_size = info->private_size;
212 : 3 : g_rw_lock_reader_unlock (&error_domain_global);
213 : : }
214 : : else
215 : : {
216 : 118731 : g_rw_lock_reader_unlock (&error_domain_global);
217 : 118731 : if (out_info != NULL)
218 : 118731 : memset (out_info, 0, sizeof (*out_info));
219 : 118731 : private_size = 0;
220 : : }
221 : : /* See comments in g_type_create_instance in gtype.c to see what
222 : : * this magic is about.
223 : : */
224 : : #ifdef ENABLE_VALGRIND
225 : 118734 : if (private_size > 0 && RUNNING_ON_VALGRIND)
226 : : {
227 : 0 : private_size += ALIGN_STRUCT (1);
228 : 0 : allocated = g_slice_alloc0 (private_size + sizeof (GError) + sizeof (gpointer));
229 : 0 : *(gpointer *) (allocated + private_size + sizeof (GError)) = allocated + ALIGN_STRUCT (1);
230 : 0 : VALGRIND_MALLOCLIKE_BLOCK (allocated + private_size, sizeof (GError) + sizeof (gpointer), 0, TRUE);
231 : 0 : VALGRIND_MALLOCLIKE_BLOCK (allocated + ALIGN_STRUCT (1), private_size - ALIGN_STRUCT (1), 0, TRUE);
232 : : }
233 : : else
234 : : #endif
235 : 118734 : allocated = g_slice_alloc0 (private_size + sizeof (GError));
236 : :
237 : 118734 : error = (GError *) (allocated + private_size);
238 : 118734 : return error;
239 : : }
240 : :
241 : : /* This function takes ownership of @message. */
242 : : static GError *
243 : 118734 : g_error_new_steal (GQuark domain,
244 : : gint code,
245 : : gchar *message,
246 : : ErrorDomainInfo *out_info)
247 : : {
248 : : ErrorDomainInfo info;
249 : 118734 : GError *error = g_error_allocate (domain, &info);
250 : :
251 : 118734 : error->domain = domain;
252 : 118734 : error->code = code;
253 : 118734 : error->message = message;
254 : :
255 : 118734 : if (info.init != NULL)
256 : 3 : info.init (error);
257 : 118734 : if (out_info != NULL)
258 : 923 : *out_info = info;
259 : :
260 : 118734 : return error;
261 : : }
262 : :
263 : : /**
264 : : * g_error_new_valist:
265 : : * @domain: error domain
266 : : * @code: error code
267 : : * @format: printf()-style format for error message
268 : : * @args: #va_list of parameters for the message format
269 : : *
270 : : * Creates a new #GError with the given @domain and @code,
271 : : * and a message formatted with @format.
272 : : *
273 : : * Returns: a new #GError
274 : : *
275 : : * Since: 2.22
276 : : */
277 : : GError*
278 : 20705 : g_error_new_valist (GQuark domain,
279 : : gint code,
280 : : const gchar *format,
281 : : va_list args)
282 : : {
283 : 20705 : g_return_val_if_fail (format != NULL, NULL);
284 : :
285 : : /* Historically, GError allowed this (although it was never meant to work),
286 : : * and it has significant use in the wild, which g_return_val_if_fail
287 : : * would break. It should maybe g_return_val_if_fail in GLib 4.
288 : : * (GNOME#660371, GNOME#560482)
289 : : */
290 : 20704 : g_warn_if_fail (domain != 0);
291 : :
292 : 20704 : return g_error_new_steal (domain, code, g_strdup_vprintf (format, args), NULL);
293 : : }
294 : :
295 : : /**
296 : : * g_error_new:
297 : : * @domain: error domain
298 : : * @code: error code
299 : : * @format: printf()-style format for error message
300 : : * @...: parameters for message format
301 : : *
302 : : * Creates a new #GError with the given @domain and @code,
303 : : * and a message formatted with @format.
304 : : *
305 : : * Returns: a new #GError
306 : : */
307 : : GError*
308 : 3361 : g_error_new (GQuark domain,
309 : : gint code,
310 : : const gchar *format,
311 : : ...)
312 : : {
313 : : GError* error;
314 : : va_list args;
315 : :
316 : 3361 : g_return_val_if_fail (format != NULL, NULL);
317 : 3361 : g_return_val_if_fail (domain != 0, NULL);
318 : :
319 : 3361 : va_start (args, format);
320 : 3361 : error = g_error_new_valist (domain, code, format, args);
321 : 3361 : va_end (args);
322 : :
323 : 3361 : return error;
324 : : }
325 : :
326 : : /**
327 : : * g_error_new_literal:
328 : : * @domain: error domain
329 : : * @code: error code
330 : : * @message: error message
331 : : *
332 : : * Creates a new #GError; unlike g_error_new(), @message is
333 : : * not a printf()-style format string. Use this function if
334 : : * @message contains text you don't have control over,
335 : : * that could include printf() escape sequences.
336 : : *
337 : : * Returns: a new #GError
338 : : **/
339 : : GError*
340 : 97107 : g_error_new_literal (GQuark domain,
341 : : gint code,
342 : : const gchar *message)
343 : : {
344 : 97107 : g_return_val_if_fail (message != NULL, NULL);
345 : 97107 : g_return_val_if_fail (domain != 0, NULL);
346 : :
347 : 97107 : return g_error_new_steal (domain, code, g_strdup (message), NULL);
348 : : }
349 : :
350 : : /**
351 : : * g_error_free:
352 : : * @error: a #GError
353 : : *
354 : : * Frees a #GError and associated resources.
355 : : */
356 : : void
357 : 118662 : g_error_free (GError *error)
358 : : {
359 : : gsize private_size;
360 : : ErrorDomainInfo *info;
361 : : guint8 *allocated;
362 : :
363 : 118662 : g_return_if_fail (error != NULL);
364 : :
365 : 118662 : g_rw_lock_reader_lock (&error_domain_global);
366 : 118662 : info = error_domain_lookup (error->domain);
367 : 118662 : if (info != NULL)
368 : : {
369 : 3 : GErrorClearFunc clear = info->clear;
370 : :
371 : 3 : private_size = info->private_size;
372 : 3 : g_rw_lock_reader_unlock (&error_domain_global);
373 : 3 : clear (error);
374 : : }
375 : : else
376 : : {
377 : 118659 : g_rw_lock_reader_unlock (&error_domain_global);
378 : 118659 : private_size = 0;
379 : : }
380 : :
381 : 118662 : g_free (error->message);
382 : 118662 : allocated = ((guint8 *) error) - private_size;
383 : : /* See comments in g_type_free_instance in gtype.c to see what this
384 : : * magic is about.
385 : : */
386 : : #ifdef ENABLE_VALGRIND
387 : 118662 : if (private_size > 0 && RUNNING_ON_VALGRIND)
388 : : {
389 : 0 : private_size += ALIGN_STRUCT (1);
390 : 0 : allocated -= ALIGN_STRUCT (1);
391 : 0 : *(gpointer *) (allocated + private_size + sizeof (GError)) = NULL;
392 : 0 : g_slice_free1 (private_size + sizeof (GError) + sizeof (gpointer), allocated);
393 : 0 : VALGRIND_FREELIKE_BLOCK (allocated + ALIGN_STRUCT (1), 0);
394 : 0 : VALGRIND_FREELIKE_BLOCK (error, 0);
395 : : }
396 : : else
397 : : #endif
398 : 118662 : g_slice_free1 (private_size + sizeof (GError), allocated);
399 : : }
400 : :
401 : : /**
402 : : * g_error_copy:
403 : : * @error: a #GError
404 : : *
405 : : * Makes a copy of @error.
406 : : *
407 : : * Returns: a new #GError
408 : : */
409 : : GError*
410 : 923 : g_error_copy (const GError *error)
411 : : {
412 : : GError *copy;
413 : : ErrorDomainInfo info;
414 : :
415 : 923 : g_return_val_if_fail (error != NULL, NULL);
416 : 923 : g_return_val_if_fail (error->message != NULL, NULL);
417 : :
418 : : /* See g_error_new_valist for why this doesn’t return */
419 : 923 : g_warn_if_fail (error->domain != 0);
420 : :
421 : 923 : copy = g_error_new_steal (error->domain,
422 : 923 : error->code,
423 : 1846 : g_strdup (error->message),
424 : : &info);
425 : 923 : if (info.copy != NULL)
426 : 1 : info.copy (error, copy);
427 : :
428 : 923 : return copy;
429 : : }
430 : :
431 : : /**
432 : : * g_error_matches:
433 : : * @error: (nullable): a #GError
434 : : * @domain: an error domain
435 : : * @code: an error code
436 : : *
437 : : * Returns %TRUE if @error matches @domain and @code, %FALSE
438 : : * otherwise. In particular, when @error is %NULL, %FALSE will
439 : : * be returned.
440 : : *
441 : : * If @domain contains a `FAILED` (or otherwise generic) error code,
442 : : * you should generally not check for it explicitly, but should
443 : : * instead treat any not-explicitly-recognized error code as being
444 : : * equivalent to the `FAILED` code. This way, if the domain is
445 : : * extended in the future to provide a more specific error code for
446 : : * a certain case, your code will still work.
447 : : *
448 : : * Returns: whether @error has @domain and @code
449 : : */
450 : : gboolean
451 : 278838 : g_error_matches (const GError *error,
452 : : GQuark domain,
453 : : gint code)
454 : : {
455 : 175284 : return error &&
456 : 454120 : error->domain == domain &&
457 : 175282 : error->code == code;
458 : : }
459 : :
460 : : #define ERROR_OVERWRITTEN_WARNING "GError set over the top of a previous GError or uninitialized memory.\n" \
461 : : "This indicates a bug in someone's code. You must ensure an error is NULL before it's set.\n" \
462 : : "The overwriting error message was: %s"
463 : :
464 : : /**
465 : : * g_set_error:
466 : : * @err: (out callee-allocates) (optional): a return location for a #GError
467 : : * @domain: error domain
468 : : * @code: error code
469 : : * @format: printf()-style format
470 : : * @...: args for @format
471 : : *
472 : : * Does nothing if @err is %NULL; if @err is non-%NULL, then *@err
473 : : * must be %NULL. A new #GError is created and assigned to *@err.
474 : : */
475 : : void
476 : 18245 : g_set_error (GError **err,
477 : : GQuark domain,
478 : : gint code,
479 : : const gchar *format,
480 : : ...)
481 : : {
482 : : GError *new;
483 : :
484 : : va_list args;
485 : :
486 : 18245 : if (err == NULL)
487 : 923 : return;
488 : :
489 : 17322 : va_start (args, format);
490 : 17322 : new = g_error_new_valist (domain, code, format, args);
491 : 17322 : va_end (args);
492 : :
493 : 17322 : if (*err == NULL)
494 : 17321 : *err = new;
495 : : else
496 : : {
497 : 1 : g_warning (ERROR_OVERWRITTEN_WARNING, new->message);
498 : 1 : g_error_free (new);
499 : : }
500 : : }
501 : :
502 : : /**
503 : : * g_set_error_literal:
504 : : * @err: (out callee-allocates) (optional): a return location for a #GError
505 : : * @domain: error domain
506 : : * @code: error code
507 : : * @message: error message
508 : : *
509 : : * Does nothing if @err is %NULL; if @err is non-%NULL, then *@err
510 : : * must be %NULL. A new #GError is created and assigned to *@err.
511 : : * Unlike g_set_error(), @message is not a printf()-style format string.
512 : : * Use this function if @message contains text you don't have control over,
513 : : * that could include printf() escape sequences.
514 : : *
515 : : * Since: 2.18
516 : : */
517 : : void
518 : 99729 : g_set_error_literal (GError **err,
519 : : GQuark domain,
520 : : gint code,
521 : : const gchar *message)
522 : : {
523 : 99729 : if (err == NULL)
524 : 3203 : return;
525 : :
526 : 96526 : if (*err == NULL)
527 : 96525 : *err = g_error_new_literal (domain, code, message);
528 : : else
529 : 1 : g_warning (ERROR_OVERWRITTEN_WARNING, message);
530 : : }
531 : :
532 : : /**
533 : : * g_propagate_error:
534 : : * @dest: (out callee-allocates) (optional) (nullable): error return location
535 : : * @src: (transfer full): error to move into the return location
536 : : *
537 : : * If @dest is %NULL, free @src; otherwise, moves @src into *@dest.
538 : : * The error variable @dest points to must be %NULL.
539 : : *
540 : : * @src must be non-%NULL.
541 : : *
542 : : * Note that @src is no longer valid after this call. If you want
543 : : * to keep using the same GError*, you need to set it to %NULL
544 : : * after calling this function on it.
545 : : */
546 : : void
547 : 21540 : g_propagate_error (GError **dest,
548 : : GError *src)
549 : : {
550 : 21540 : g_return_if_fail (src != NULL);
551 : :
552 : 21540 : if (dest == NULL)
553 : : {
554 : 16420 : g_error_free (src);
555 : 16420 : return;
556 : : }
557 : : else
558 : : {
559 : 5120 : if (*dest != NULL)
560 : : {
561 : 1 : g_warning (ERROR_OVERWRITTEN_WARNING, src->message);
562 : 1 : g_error_free (src);
563 : : }
564 : : else
565 : 5119 : *dest = src;
566 : : }
567 : : }
568 : :
569 : : /**
570 : : * g_clear_error:
571 : : * @err: a #GError return location
572 : : *
573 : : * If @err or *@err is %NULL, does nothing. Otherwise,
574 : : * calls g_error_free() on *@err and sets *@err to %NULL.
575 : : */
576 : : void
577 : 16362 : g_clear_error (GError **err)
578 : : {
579 : 16362 : if (err && *err)
580 : : {
581 : 5654 : g_error_free (*err);
582 : 5654 : *err = NULL;
583 : : }
584 : 16362 : }
585 : :
586 : : G_GNUC_PRINTF(2, 0)
587 : : static void
588 : 499 : g_error_add_prefix (gchar **string,
589 : : const gchar *format,
590 : : va_list ap)
591 : : {
592 : : gchar *oldstring;
593 : : gchar *prefix;
594 : :
595 : 499 : prefix = g_strdup_vprintf (format, ap);
596 : 499 : oldstring = *string;
597 : 499 : *string = g_strconcat (prefix, oldstring, NULL);
598 : 499 : g_free (oldstring);
599 : 499 : g_free (prefix);
600 : 499 : }
601 : :
602 : : /**
603 : : * g_prefix_error:
604 : : * @err: (inout) (optional) (nullable): a return location for a #GError
605 : : * @format: printf()-style format string
606 : : * @...: arguments to @format
607 : : *
608 : : * Formats a string according to @format and prefix it to an existing
609 : : * error message. If @err is %NULL (ie: no error variable) then do
610 : : * nothing.
611 : : *
612 : : * If *@err is %NULL (ie: an error variable is present but there is no
613 : : * error condition) then also do nothing.
614 : : *
615 : : * Since: 2.16
616 : : */
617 : : void
618 : 495 : g_prefix_error (GError **err,
619 : : const gchar *format,
620 : : ...)
621 : : {
622 : 495 : if (err && *err)
623 : : {
624 : : va_list ap;
625 : :
626 : 486 : va_start (ap, format);
627 : 486 : g_error_add_prefix (&(*err)->message, format, ap);
628 : 486 : va_end (ap);
629 : : }
630 : 495 : }
631 : :
632 : : /**
633 : : * g_prefix_error_literal:
634 : : * @err: (inout) (nullable) (optional): a return location for a #GError, or %NULL
635 : : * @prefix: string to prefix @err with
636 : : *
637 : : * Prefixes @prefix to an existing error message. If @err or *@err is
638 : : * %NULL (i.e.: no error variable) then do nothing.
639 : : *
640 : : * Since: 2.70
641 : : */
642 : : void
643 : 5 : g_prefix_error_literal (GError **err,
644 : : const gchar *prefix)
645 : : {
646 : 5 : if (err && *err)
647 : : {
648 : : gchar *oldstring;
649 : :
650 : 2 : oldstring = (*err)->message;
651 : 2 : (*err)->message = g_strconcat (prefix, oldstring, NULL);
652 : 2 : g_free (oldstring);
653 : : }
654 : 5 : }
655 : :
656 : : /**
657 : : * g_propagate_prefixed_error:
658 : : * @dest: error return location
659 : : * @src: error to move into the return location
660 : : * @format: printf()-style format string
661 : : * @...: arguments to @format
662 : : *
663 : : * If @dest is %NULL, free @src; otherwise, moves @src into *@dest.
664 : : * *@dest must be %NULL. After the move, add a prefix as with
665 : : * g_prefix_error().
666 : : *
667 : : * Since: 2.16
668 : : **/
669 : : void
670 : 14 : g_propagate_prefixed_error (GError **dest,
671 : : GError *src,
672 : : const gchar *format,
673 : : ...)
674 : : {
675 : 14 : g_propagate_error (dest, src);
676 : :
677 : 14 : if (dest)
678 : : {
679 : : va_list ap;
680 : :
681 : 13 : g_assert (*dest != NULL);
682 : 13 : va_start (ap, format);
683 : 13 : g_error_add_prefix (&(*dest)->message, format, ap);
684 : 13 : va_end (ap);
685 : : }
686 : 14 : }
|