LCOV - code coverage report
Current view: top level - src/base - pdf-error.c (source / functions) Hit Total Coverage
Test: libgnupdf.info Lines: 89 99 89.9 %
Date: 2011-12-09 Functions: 14 14 100.0 %
Branches: 36 58 62.1 %

           Branch data     Line data    Source code
       1                 :            : /* -*- mode: C -*-
       2                 :            :  *
       3                 :            :  *       File:         pdf-error.c
       4                 :            :  *       Date:         Sun Feb  24 20:22:05 2008
       5                 :            :  *
       6                 :            :  *       GNU PDF Library - Implementation for the Error module
       7                 :            :  *
       8                 :            :  */
       9                 :            : 
      10                 :            : /* Copyright (C) 2008-2011 Free Software Foundation, Inc. */
      11                 :            : 
      12                 :            : /* This program is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU General Public License as published by
      14                 :            :  * the Free Software Foundation, either version 3 of the License, or
      15                 :            :  * (at your option) any later version.
      16                 :            :  *
      17                 :            :  * This program is distributed in the hope that it will be useful,
      18                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      19                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20                 :            :  * GNU General Public License for more details.
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU General Public License
      23                 :            :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24                 :            :  */
      25                 :            : 
      26                 :            : #include <config.h>
      27                 :            : 
      28                 :            : #include <stdio.h>
      29                 :            : #include <stdlib.h>
      30                 :            : #include <stdarg.h>
      31                 :            : #include <string.h>
      32                 :            : 
      33                 :            : /* From gnulib */
      34                 :            : #include "vasnprintf.h"
      35                 :            : 
      36                 :            : #include <pdf-alloc.h>
      37                 :            : #include <pdf-global.h>
      38                 :            : #include <pdf-error.h>
      39                 :            : 
      40                 :            : extern pdf_char_t *pdf_library_name;
      41                 :            : 
      42                 :            : /* Update this list according to pdf_status_t. */
      43                 :            : #define ERROR_ENTRY(id, string) string
      44                 :            : const pdf_char_t * pdf_error_stlist [] =
      45                 :            :   {
      46                 :            :     PDF_ERROR_LIST
      47                 :            :   };
      48                 :            : #undef ERROR_ENTRY
      49                 :            : 
      50                 :            : /* Update this list according to pdf_error_domain_t. */
      51                 :            : #define ERROR_ENTRY(id, string) string
      52                 :            : const pdf_char_t * pdf_error_domain_stlist [] =
      53                 :            :   {
      54                 :            :     PDF_ERROR_DOMAIN_LIST
      55                 :            :   };
      56                 :            : #undef ERROR_ENTRY
      57                 :            : 
      58                 :            : /* Structure of the PDF error object */
      59                 :            : struct pdf_error_s {
      60                 :            :   pdf_error_domain_t domain;
      61                 :            :   pdf_status_t status;
      62                 :            :   pdf_char_t *message;
      63                 :            : };
      64                 :            : 
      65                 :            : /* This static constant structure is used as backup when setting a new error and
      66                 :            :  * memory allocation of the new error fails. */
      67                 :            : static const pdf_error_t static_enomem_error = {
      68                 :            :   .domain = PDF_EDOMAIN_UNDEFINED,
      69                 :            :   .status = PDF_ENOMEM,
      70                 :            :   .message = "memory allocation failed"
      71                 :            : };
      72                 :            : 
      73                 :            : void
      74                 :          2 : pdf_perror (const pdf_status_t  status,
      75                 :            :             const pdf_char_t   *str)
      76                 :            : {
      77                 :          2 :   pdf_error ((int) status, stderr, str);
      78                 :          2 : }
      79                 :            : 
      80                 :            : void
      81                 :         20 : pdf_error (const pdf_status_t  status,
      82                 :            :            FILE               *fd,
      83                 :            :            const pdf_char_t   *format,
      84                 :            :            ...)
      85                 :            : {
      86                 :            :   va_list args;
      87                 :            :   int errnum;
      88                 :            : 
      89                 :         20 :   errnum = (int) status;
      90                 :            : 
      91         [ +  + ]:         20 :   if (fd == NULL)
      92                 :          1 :     fd = stderr;
      93                 :            : 
      94                 :         20 :   fprintf (fd, "%s", pdf_library_name);
      95                 :            : 
      96         [ +  + ]:         20 :   if (format != NULL)
      97                 :            :     {
      98                 :         18 :       fprintf (fd, ": ");
      99                 :         18 :       va_start (args, format);
     100                 :         18 :       vfprintf (fd, format, args);
     101                 :         18 :       va_end (args);
     102                 :            :     }
     103                 :            : 
     104         [ +  + ]:         20 :   if (errnum >  0 && errnum < PDF_STATUS_ITEMS)
     105                 :         14 :     fprintf (fd, ": %s", pdf_error_stlist[errnum-1]);
     106                 :            : 
     107                 :         20 :   fprintf (fd, ".\n");
     108                 :         20 :   fflush (fd);
     109                 :         20 : }
     110                 :            : 
     111                 :            : static pdf_error_t *
     112                 :       8699 : error_new_valist (pdf_error_domain_t  domain,
     113                 :            :                   pdf_status_t        status,
     114                 :            :                   const pdf_char_t   *format,
     115                 :            :                   va_list             args)
     116                 :            : {
     117                 :            :   pdf_error_t *error;
     118                 :            : 
     119                 :       8699 :   error = pdf_alloc (sizeof (struct pdf_error_s));
     120 [ +  -  +  -  + :      17398 :   if ((error != NULL) &&
                      - ]
     121                 :       8699 :       (vasprintf (&(error->message), format, args) >= 0) &&
     122                 :       8699 :       (error->message != NULL))
     123                 :            :     {
     124                 :       8699 :       error->status = status;
     125                 :       8699 :       error->domain = domain;
     126                 :            :     }
     127                 :            :   else
     128                 :            :     {
     129         [ #  # ]:          0 :       if (error)
     130                 :          0 :         pdf_dealloc (error);
     131                 :            :       /* Set backup enomem error */
     132                 :          0 :       error = (pdf_error_t *)&static_enomem_error;
     133                 :            :     }
     134                 :       8699 :   return error;
     135                 :            : }
     136                 :            : 
     137                 :            : pdf_error_t *
     138                 :        217 : pdf_error_new (pdf_error_domain_t  domain,
     139                 :            :                pdf_status_t        status,
     140                 :            :                const pdf_char_t   *format,
     141                 :            :                ...)
     142                 :            : {
     143                 :            :   va_list args;
     144                 :            :   pdf_error_t *error;
     145                 :            : 
     146                 :        217 :   va_start (args, format);
     147                 :        217 :   error = error_new_valist (domain,
     148                 :            :                             status,
     149                 :            :                             format,
     150                 :            :                             args);
     151                 :        217 :   va_end (args);
     152                 :        217 :   return error;
     153                 :            : }
     154                 :            : 
     155                 :            : pdf_error_t *
     156                 :        210 : pdf_error_dup (const pdf_error_t *error)
     157                 :            : {
     158         [ -  + ]:        210 :   PDF_ASSERT_RETURN_VAL (error != NULL, NULL);
     159                 :            : 
     160                 :        210 :   return pdf_error_new (error->domain,
     161                 :            :                         error->status,
     162                 :        210 :                         error->message);
     163                 :            : }
     164                 :            : 
     165                 :            : pdf_status_t
     166                 :         26 : pdf_error_get_status (const pdf_error_t *error)
     167                 :            : {
     168         [ -  + ]:         26 :   PDF_ASSERT_RETURN_VAL (error != NULL, PDF_EBADDATA);
     169                 :            : 
     170                 :         26 :   return error->status;
     171                 :            : }
     172                 :            : 
     173                 :            : pdf_error_domain_t
     174                 :          7 : pdf_error_get_domain (const pdf_error_t *error)
     175                 :            : {
     176         [ -  + ]:          7 :   PDF_ASSERT_RETURN_VAL (error != NULL, PDF_EDOMAIN_UNDEFINED);
     177                 :            : 
     178                 :          7 :   return error->domain;
     179                 :            : }
     180                 :            : 
     181                 :            : const pdf_char_t *
     182                 :          7 : pdf_error_get_message (const pdf_error_t *error)
     183                 :            : {
     184         [ -  + ]:          7 :   PDF_ASSERT_RETURN_VAL (error != NULL, NULL);
     185                 :            : 
     186                 :          7 :   return error->message;
     187                 :            : }
     188                 :            : 
     189                 :            : void
     190                 :       8537 : pdf_error_destroy (pdf_error_t *error)
     191                 :            : {
     192 [ +  - ][ +  - ]:       8537 :   if (error != NULL &&
     193                 :            :       error != &static_enomem_error)
     194                 :            :     {
     195                 :       8537 :       pdf_dealloc (error->message);
     196                 :       8537 :       pdf_dealloc (error);
     197                 :            :     }
     198                 :       8537 : }
     199                 :            : 
     200                 :            : void
     201                 :       8484 : pdf_set_error (pdf_error_t        **err,
     202                 :            :                pdf_error_domain_t   domain,
     203                 :            :                pdf_status_t         status,
     204                 :            :                const pdf_char_t    *format,
     205                 :            :                ...)
     206                 :            : {
     207         [ +  + ]:       8484 :   if (err != NULL)
     208                 :            :     {
     209                 :            :       va_list args;
     210                 :            : 
     211         [ -  + ]:       8482 :       PDF_ASSERT (*err == NULL);
     212                 :            : 
     213                 :            : #ifdef PDF_HAVE_DEBUG_BASE
     214                 :            :       if (*err != NULL)
     215                 :            :         PDF_DEBUG_BASE ("  Previous error contents: %s",
     216                 :            :                         (*err)->message);
     217                 :            : #endif /* PDF_HAVE_DEBUG_BASE */
     218                 :            : 
     219                 :       8482 :       va_start (args, format);
     220                 :       8482 :       *err = error_new_valist (domain,
     221                 :            :                                status,
     222                 :            :                                format,
     223                 :            :                                args);
     224                 :       8482 :       va_end (args);
     225                 :            :     }
     226                 :       8484 : }
     227                 :            : 
     228                 :            : void
     229                 :       7923 : pdf_prefix_error (pdf_error_t        **err,
     230                 :            :                   const pdf_char_t    *format,
     231                 :            :                   ...)
     232                 :            : {
     233 [ +  + ][ +  + ]:       7923 :   if ((err != NULL) &&
                 [ +  - ]
     234                 :       7921 :       (*err != NULL) &&
     235                 :       7919 :       (*err != &static_enomem_error))
     236                 :            :     {
     237                 :       7919 :       pdf_char_t *new_message = NULL;
     238                 :            :       va_list args;
     239                 :       7919 :       pdf_bool_t enomem = PDF_FALSE;
     240                 :            : 
     241                 :       7919 :       va_start (args, format);
     242   [ +  -  +  - ]:       7919 :       if ((vasprintf (&new_message, format, args) >= 0) &&
     243                 :       7919 :           (new_message != NULL))
     244                 :            :         {
     245                 :            :           pdf_char_t *prefixed;
     246                 :            :           pdf_size_t new_message_len;
     247                 :            : 
     248                 :       7919 :           new_message_len = (strlen (new_message) + strlen ((*err)->message) + 1);
     249                 :       7919 :           prefixed = pdf_realloc (new_message, new_message_len);
     250         [ -  + ]:       7919 :           if (!prefixed)
     251                 :            :             {
     252                 :          0 :               pdf_dealloc (new_message);
     253                 :          0 :               enomem = PDF_TRUE;
     254                 :            :             }
     255                 :            :           else
     256                 :            :             {
     257                 :       7919 :               strcat (prefixed, (*err)->message);
     258                 :       7919 :               prefixed[new_message_len - 1] = '\0';
     259                 :       7919 :               pdf_dealloc ((*err)->message);
     260                 :       7919 :               (*err)->message = prefixed;
     261                 :            :             }
     262                 :            :         }
     263                 :            :       else
     264                 :          0 :         enomem = PDF_TRUE;
     265                 :            : 
     266         [ -  + ]:       7919 :       if (enomem)
     267                 :            :         {
     268                 :            :           /* Oops, ENOMEM */
     269         [ #  # ]:          0 :           if (new_message)
     270                 :          0 :             pdf_dealloc (new_message);
     271                 :          0 :           pdf_error_destroy (*err);
     272                 :            :           /* Set backup enomem error */
     273                 :          0 :           *err = (pdf_error_t *)&static_enomem_error;
     274                 :            :         }
     275                 :       7919 :       va_end (args);
     276                 :            :     }
     277                 :       7923 : }
     278                 :            : 
     279                 :            : void
     280                 :       8090 : pdf_clear_error (pdf_error_t **err)
     281                 :            : {
     282 [ +  + ][ +  + ]:       8090 :   if ((err == NULL) ||
     283                 :       8089 :       (*err == NULL))
     284                 :            :     return;
     285                 :            : 
     286                 :       7822 :   pdf_error_destroy (*err);
     287                 :       8090 :   *err = NULL;
     288                 :            : }
     289                 :            : 
     290                 :            : void
     291                 :        212 : pdf_propagate_error (pdf_error_t **dest,
     292                 :            :                      pdf_error_t  *src)
     293                 :            : {
     294         [ -  + ]:        212 :   PDF_ASSERT_RETURN (src != NULL);
     295                 :            : 
     296         [ +  + ]:        212 :   if (dest == NULL)
     297                 :         71 :     pdf_error_destroy (src);
     298                 :            :   else
     299                 :        212 :     *dest = src;
     300                 :            : }
     301                 :            : 
     302                 :            : void
     303                 :        210 : pdf_propagate_error_dup (pdf_error_t       **dest,
     304                 :            :                          const pdf_error_t  *src)
     305                 :            : {
     306         [ -  + ]:        210 :   PDF_ASSERT_RETURN (src != NULL);
     307                 :            : 
     308         [ +  - ]:        210 :   if (dest)
     309                 :        210 :     *dest = pdf_error_dup (src);
     310                 :            : }
     311                 :            : 
     312                 :            : /* End of pdf-error.c */

Generated by: LCOV version 1.8