JWS C Library
C language utility library
error.c
Go to the documentation of this file.
00001 /*
00002  * This work is licensed under a Creative Commons 
00003  * Attribution-Noncommercial-Share Alike 3.0 United States License.
00004  * 
00005  *    http://creativecommons.org/licenses/by-nc-sa/3.0/us/
00006  * 
00007  * You are free:
00008  * 
00009  *    to Share - to copy, distribute, display, and perform the work
00010  *    to Remix - to make derivative works
00011  * 
00012  * Under the following conditions:
00013  * 
00014  *    Attribution. You must attribute the work in the manner specified by the
00015  *    author or licensor (but not in any way that suggests that they endorse you
00016  *    or your use of the work).
00017  * 
00018  *    Noncommercial. You may not use this work for commercial purposes.
00019  * 
00020  *    Share Alike. If you alter, transform, or build upon this work, you may
00021  *    distribute the resulting work only under the same or similar license to
00022  *    this one.
00023  * 
00024  * For any reuse or distribution, you must make clear to others the license
00025  * terms of this work. The best way to do this is by including this header.
00026  * 
00027  * Any of the above conditions can be waived if you get permission from the
00028  * copyright holder.
00029  * 
00030  * Apart from the remix rights granted under this license, nothing in this
00031  * license impairs or restricts the author's moral rights.
00032  */
00033 
00034 
00046 #include <jwsc/config.h>
00047 
00048 #include <stdlib.h>
00049 #include <stdio.h>
00050 #include <errno.h>
00051 #include <string.h>
00052 #include <assert.h>
00053 #include <inttypes.h>
00054 
00055 #include "jwsc/base/error.h"
00056 
00057 #ifdef JWSC_HAVE_DMALLOC
00058 #include <dmalloc.h>
00059 #endif
00060 
00061 
00062 extern int errno;
00063 
00064 
00066 static uint32_t num_unhandled_errors = 0;
00067 
00068 
00070 static Error no_memory = 
00071 { 
00072     ERROR_NO_MEMORY, 
00073     "No memory available.",
00074     NULL,
00075     0,
00076     0
00077 };
00078 
00079 
00081 Error* error_no_memory = &no_memory;
00082 
00083 
00096 Error* create_error
00097 (
00098     Error_type   type, 
00099     const char*  file,
00100     unsigned int line,
00101     const char*  msg
00102 )
00103 {
00104     size_t len;
00105     const char* ptr;
00106     Error* e;
00107 
00108     if ((e = malloc(sizeof(Error))) == NULL)
00109     {
00110         return error_no_memory;
00111     }
00112 
00113     num_unhandled_errors++;
00114 
00115     e->type = type;
00116     e->file = NULL;
00117     e->line = line;
00118     e->msg  = NULL;
00119     e->code = 0;
00120 
00121     if (file != NULL)
00122     {
00123         len = strlen(file);
00124         ptr = file + len;
00125         while (ptr != file && *ptr != '/') ptr--;
00126         if (ptr != file) ptr++;
00127         len = strlen(ptr);
00128 
00129         if ((e->file = malloc((len+1)*sizeof(char))) == NULL)
00130         {
00131             free_error(e);
00132             return error_no_memory;
00133         }
00134         strcpy(e->file, ptr);
00135     }
00136     if (msg != NULL)
00137     {
00138         if ((e->msg = malloc((strlen(msg)+1)*sizeof(char))) == NULL)
00139         {
00140             free_error(e);
00141             return error_no_memory;
00142         }
00143         strcpy(e->msg, msg);
00144     }
00145 
00146     return e;
00147 }
00148 
00149 
00151 void free_error(Error* e)
00152 {
00153     if (e == NULL || e == error_no_memory) return;
00154 
00155     num_unhandled_errors--;
00156 
00157     if (e->file != NULL)
00158     {
00159         free(e->file);
00160     }
00161     if (e->msg != NULL)
00162     {
00163         free(e->msg);
00164     }
00165 
00166     free(e);
00167 }
00168 
00169 
00181 void print_error(const char* prefix, const Error* e)
00182 {
00183     int had_prefix;
00184 
00185     assert(e != NULL);
00186     had_prefix = 0;
00187 
00188     if (prefix != NULL)
00189     {
00190         fprintf(stderr, "%s", prefix);
00191         had_prefix = 1;
00192     }
00193     if (e->file != NULL)
00194     {
00195         if (had_prefix)
00196         {
00197             fprintf(stderr, ": %s", e->file);
00198         }
00199         else
00200         {
00201             fprintf(stderr, "%s", e->file);
00202             had_prefix = 1;
00203         }
00204     }
00205     if (had_prefix)
00206     {
00207         fprintf(stderr, ": line %u", e->line);
00208     }
00209     else
00210     {
00211         fprintf(stderr, "line %u", e->line);
00212         had_prefix = 1;
00213     }
00214     if (e->msg != NULL)
00215     {
00216         if (had_prefix)
00217         {
00218             fprintf(stderr, ": %s", e->msg);
00219         }
00220         else
00221         {
00222             fprintf(stderr, "%s", e->msg);
00223         }
00224     }
00225     fprintf(stderr, "\n");
00226 }
00227 
00228 
00229 void print_error_exit(const char* prefix, const Error* e)
00230 {
00231     print_error(prefix, e);
00232     exit(EXIT_FAILURE);
00233 }
00234 
00235 
00248 void print_error_msg(const char* prefix, const char* msg)
00249 {
00250     if (prefix != NULL)
00251     {
00252         fprintf(stderr, "%s: ", prefix);
00253     }
00254 
00255     if (msg != NULL)
00256     {
00257         fprintf(stderr, "%s\n", msg);
00258     }
00259 }
00260 
00261 
00276 void print_error_msg_exit(const char* prefix, const char* msg)
00277 {
00278     print_error_msg(prefix, msg);
00279     exit(EXIT_FAILURE);
00280 }
00281 
00282 
00294 void print_errno(const char* prefix)
00295 {
00296     if (prefix != NULL)
00297     {
00298         fprintf(stderr, "%s: ", prefix);
00299     }
00300 
00301     fprintf(stderr, "%s\n", strerror(errno));
00302 }
00303 
00304 
00318 void print_errno_exit(const char* prefix)
00319 {
00320     print_errno(prefix);
00321     exit(EXIT_FAILURE);
00322 }
00323 
00324 
00326 uint32_t get_num_unhandled_errors()
00327 {
00328     return num_unhandled_errors;
00329 }