JWS C Library
C language utility library
|
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 }