LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/langtag/liblangtag - lt-error.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 36 64 56.2 %
Date: 2012-12-17 Functions: 5 7 71.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
       2             : /* 
       3             :  * lt-error.c
       4             :  * Copyright (C) 2011-2012 Akira TAGOH
       5             :  * 
       6             :  * Authors:
       7             :  *   Akira TAGOH  <akira@tagoh.org>
       8             :  * 
       9             :  * You may distribute under the terms of either the GNU
      10             :  * Lesser General Public License or the Mozilla Public
      11             :  * License, as specified in the README file.
      12             :  */
      13             : #ifdef HAVE_CONFIG_H
      14             : #include "config.h"
      15             : #endif
      16             : 
      17             : #ifndef _WIN32
      18             : #include <execinfo.h>
      19             : #endif
      20             : #include <stdlib.h>
      21             : #include "lt-list.h"
      22             : #include "lt-mem.h"
      23             : #include "lt-messages.h"
      24             : #include "lt-utils.h"
      25             : #include "lt-error.h"
      26             : 
      27             : struct _lt_error_t {
      28             :         lt_mem_t   parent;
      29             :         lt_list_t *data;
      30             : };
      31             : typedef struct _lt_error_data_t {
      32             :         lt_mem_t          parent;
      33             :         lt_error_type_t   type;
      34             :         char             *message;
      35             :         char            **traces;
      36             :         size_t            stack_size;
      37             : } lt_error_data_t;
      38             : 
      39             : /**
      40             :  * SECTION:lt-error
      41             :  * @Short_Description: Error handling
      42             :  * @Title: Error
      43             :  *
      44             :  * This section describes the error handling in this library.
      45             :  */
      46             : /*< private >*/
      47             : lt_error_t *
      48          14 : lt_error_new(void)
      49             : {
      50          14 :         return lt_mem_alloc_object(sizeof (lt_error_t));
      51             : }
      52             : 
      53             : /*< public >*/
      54             : 
      55             : /**
      56             :  * lt_error_ref:
      57             :  * @error: a #lt_error_t
      58             :  *
      59             :  * Inscreases the reference count of @error.
      60             :  *
      61             :  * Returns: (transfer none): the same @error object.
      62             :  */
      63             : lt_error_t *
      64          14 : lt_error_ref(lt_error_t *error)
      65             : {
      66          14 :         lt_return_val_if_fail (error != NULL, NULL);
      67             : 
      68          14 :         return lt_mem_ref(&error->parent);
      69             : }
      70             : 
      71             : /**
      72             :  * lt_error_unref:
      73             :  * @error: a #lt_error_t
      74             :  *
      75             :  * Decreases the reference count of @error. when its reference count
      76             :  * drops to 0, the object is finalized (i.e. its memory is freed).
      77             :  */
      78             : void
      79          28 : lt_error_unref(lt_error_t *error)
      80             : {
      81          28 :         if (error)
      82          28 :                 lt_mem_unref(&error->parent);
      83          28 : }
      84             : 
      85             : /**
      86             :  * lt_error_set:
      87             :  * @error: a return location for a #lt_error_t
      88             :  * @type: a #lt_error_type_t
      89             :  * @message: the string format to output the error messages
      90             :  * @...: the parameters to insert into the format string
      91             :  *
      92             :  * Sets the error into @error according to the given parameters.
      93             :  *
      94             :  * Returns: an instance of #lt_error_t
      95             :  */
      96             : lt_error_t *
      97          14 : lt_error_set(lt_error_t      **error,
      98             :              lt_error_type_t   type,
      99             :              const char       *message,
     100             :              ...)
     101             : {
     102             :         va_list ap;
     103             :         void *traces[1024];
     104          14 :         lt_error_data_t *d = lt_mem_alloc_object(sizeof (lt_error_data_t));
     105             :         int size;
     106             :         lt_bool_t allocated;
     107             : 
     108          14 :         lt_return_val_if_fail (error != NULL, NULL);
     109             : 
     110          14 :         if (!d)
     111           0 :                 goto bail0;
     112          14 :         if (!*error)
     113          14 :                 *error = lt_error_new();
     114          14 :         if (!*error)
     115           0 :                 goto bail0;
     116             : 
     117          14 :         d->type = type;
     118          14 :         va_start(ap, message);
     119          14 :         d->message = lt_strdup_vprintf(message, ap);
     120          14 :         va_end(ap);
     121             : 
     122             : #ifdef _WIN32
     123             :         size = 0;
     124             : #else
     125          14 :         size = backtrace(traces, 1024);
     126          14 :         if (size > 0)
     127          14 :                 d->traces = backtrace_symbols(traces, size);
     128             : #endif
     129          14 :         d->stack_size = size;
     130             : 
     131          14 :         lt_mem_add_ref(&d->parent, d->message, free);
     132          14 :         if (d->traces != NULL)
     133          14 :                 lt_mem_add_ref(&d->parent, d->traces, free);
     134             : 
     135          14 :         allocated = (*error)->data == NULL;
     136          14 :         (*error)->data = lt_list_append((*error)->data, d, (lt_destroy_func_t)lt_mem_unref);
     137          14 :         if (allocated)
     138          14 :                 lt_mem_add_ref(&(*error)->parent,
     139          14 :                                (*error)->data,
     140             :                                (lt_destroy_func_t)lt_list_free);
     141             : 
     142          14 :         return *error;
     143             :   bail0:
     144           0 :         lt_critical("Out of memory");
     145             : 
     146           0 :         return *error;
     147             : }
     148             : 
     149             : /**
     150             :  * lt_error_clear:
     151             :  * @error: a #lt_error_t
     152             :  *
     153             :  * Clean up all of the errors in @error.
     154             :  */
     155             : void
     156           0 : lt_error_clear(lt_error_t *error)
     157             : {
     158           0 :         if (error) {
     159           0 :                 lt_mem_delete_ref(&error->parent, error->data);
     160           0 :                 error->data = NULL;
     161             :         }
     162           0 : }
     163             : 
     164             : /**
     165             :  * lt_error_is_set:
     166             :  * @error: a #lt_error_t
     167             :  * @type: a #lt_error_type_t
     168             :  *
     169             :  * Checks if @error contains @type of errors. if #LT_ERR_ANY is set to @type,
     170             :  * all the types of the errors are targeted. otherwise the result is filtered
     171             :  * out by @type.
     172             :  *
     173             :  * Returns: %TRUE if any, otherwise %FALSE
     174             :  */
     175             : lt_bool_t
     176         232 : lt_error_is_set(lt_error_t      *error,
     177             :                 lt_error_type_t  type)
     178             : {
     179         232 :         if (type == LT_ERR_ANY) {
     180         232 :                 return error && error->data;
     181             :         } else {
     182           0 :                 if (error && error->data) {
     183             :                         lt_list_t *l;
     184             : 
     185           0 :                         for (l = error->data; l != NULL; l = lt_list_next(l)) {
     186           0 :                                 lt_error_data_t *d = lt_list_value(l);
     187             : 
     188           0 :                                 if (d->type == type)
     189           0 :                                         return TRUE;
     190             :                         }
     191             :                 }
     192             :         }
     193             : 
     194           0 :         return FALSE;
     195             : }
     196             : 
     197             : /**
     198             :  * lt_error_print:
     199             :  * @error: a #lt_error_t
     200             :  * @type: a #lt_error_type_t
     201             :  *
     202             :  * Output the error messages in @error according to @type.
     203             :  */
     204             : void
     205           0 : lt_error_print(lt_error_t      *error,
     206             :                lt_error_type_t  type)
     207             : {
     208             :         lt_list_t *l;
     209             : 
     210           0 :         if (lt_error_is_set(error, type)) {
     211           0 :                 lt_warning("Error raised:");
     212           0 :                 for (l = error->data; l != NULL; l = lt_list_next(l)) {
     213           0 :                         lt_error_data_t *d = lt_list_value(l);
     214             :                         int i;
     215             : 
     216           0 :                         if (type == LT_ERR_ANY || type == d->type) {
     217           0 :                                 lt_warning("  %s", d->message);
     218           0 :                                 if (d->stack_size > 0) {
     219           0 :                                         lt_warning("  Backtraces:");
     220             :                                 } else {
     221           0 :                                         lt_warning("  No backtraces");
     222             :                                 }
     223           0 :                                 for (i = 1; i < d->stack_size; i++) {
     224           0 :                                         lt_warning("    %d. %s", i - 1, d->traces[i]);
     225             :                                 }
     226             :                         }
     227             :                 }
     228             :         }
     229           0 : }

Generated by: LCOV version 1.10