2 ======================================================================
4 CREATOR: eric 16 May 1999
6 $Id: icalerror.c,v 1.22 2008-01-15 23:17:40 dothebart Exp $
10 (C) COPYRIGHT 2000, Eric Busboom <eric@softwarestudio.org>
11 http://www.softwarestudio.org
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of either:
16 The LGPL as published by the Free Software Foundation, version
17 2.1, available at: http://www.fsf.org/copyleft/lesser.html
21 The Mozilla Public License Version 1.0. You may obtain a copy of
22 the License at http://www.mozilla.org/MPL/
24 The original code is icalerror.c
26 ======================================================================*/
37 #include <stdlib.h> /* for malloc() */
38 #include <string.h> /* for strcmp */
39 #include "icalerror.h"
44 static pthread_key_t icalerrno_key;
45 static pthread_once_t icalerrno_key_once = PTHREAD_ONCE_INIT;
47 static void icalerrno_destroy(void* buf) {
49 pthread_setspecific(icalerrno_key, NULL);
52 static void icalerrno_key_alloc(void) {
53 pthread_key_create(&icalerrno_key, icalerrno_destroy);
56 icalerrorenum *icalerrno_return(void) {
57 icalerrorenum *_errno;
59 pthread_once(&icalerrno_key_once, icalerrno_key_alloc);
61 _errno = (icalerrorenum*) pthread_getspecific(icalerrno_key);
64 _errno = malloc(sizeof(icalerrorenum));
65 *_errno = ICAL_NO_ERROR;
66 pthread_setspecific(icalerrno_key, _errno);
73 static icalerrorenum icalerrno_storage = ICAL_NO_ERROR;
75 icalerrorenum *icalerrno_return(void) {
76 return &icalerrno_storage;
84 void icalerror_stop_here(void)
86 foo++; /* Keep optimizers from removing routine */
89 void icalerror_crash_here(void)
97 #ifdef ICAL_SETERROR_ISFUNC
98 void icalerror_set_errno(icalerrorenum x)
101 if(icalerror_get_error_state(x)==ICAL_ERROR_FATAL ||
102 (icalerror_get_error_state(x)==ICAL_ERROR_DEFAULT &&
103 icalerror_errors_are_fatal == 1 )){
104 icalerror_warn(icalerror_strerror(x));
112 void icalerror_clear_errno() {
114 icalerrno = ICAL_NO_ERROR;
117 #if ICAL_ERRORS_ARE_FATAL == 1
118 int icalerror_errors_are_fatal = 1;
120 int icalerror_errors_are_fatal = 0;
123 struct icalerror_state {
125 icalerrorstate state;
128 static struct icalerror_state error_state_map[] =
130 { ICAL_BADARG_ERROR,ICAL_ERROR_DEFAULT},
131 { ICAL_NEWFAILED_ERROR,ICAL_ERROR_DEFAULT},
132 { ICAL_ALLOCATION_ERROR,ICAL_ERROR_DEFAULT},
133 { ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_DEFAULT},
134 { ICAL_PARSE_ERROR,ICAL_ERROR_DEFAULT},
135 { ICAL_INTERNAL_ERROR,ICAL_ERROR_DEFAULT},
136 { ICAL_FILE_ERROR,ICAL_ERROR_DEFAULT},
137 { ICAL_USAGE_ERROR,ICAL_ERROR_DEFAULT},
138 { ICAL_UNIMPLEMENTED_ERROR,ICAL_ERROR_DEFAULT},
139 { ICAL_UNKNOWN_ERROR,ICAL_ERROR_DEFAULT},
140 { ICAL_NO_ERROR,ICAL_ERROR_DEFAULT}
144 struct icalerror_string_map {
150 static const struct icalerror_string_map string_map[] =
152 {"BADARG",ICAL_BADARG_ERROR,"BADARG: Bad argument to function"},
153 { "NEWFAILED",ICAL_NEWFAILED_ERROR,"NEWFAILED: Failed to create a new object via a *_new() routine"},
154 { "ALLOCATION",ICAL_ALLOCATION_ERROR,"ALLOCATION: Failed to allocate new memory"},
155 {"MALFORMEDDATA",ICAL_MALFORMEDDATA_ERROR,"MALFORMEDDATA: An input string was not correctly formed or a component has missing or extra properties"},
156 { "PARSE",ICAL_PARSE_ERROR,"PARSE: Failed to parse a part of an iCal component"},
157 {"INTERNAL",ICAL_INTERNAL_ERROR,"INTERNAL: Random internal error. This indicates an error in the library code, not an error in use"},
158 { "FILE",ICAL_FILE_ERROR,"FILE: An operation on a file failed. Check errno for more detail."},
159 { "USAGE",ICAL_USAGE_ERROR,"USAGE: Failed to propertyl sequence calls to a set of interfaces"},
160 { "UNIMPLEMENTED",ICAL_UNIMPLEMENTED_ERROR,"UNIMPLEMENTED: This feature has not been implemented"},
161 { "NO",ICAL_NO_ERROR,"NO: No error"},
162 {"UNKNOWN",ICAL_UNKNOWN_ERROR,"UNKNOWN: Unknown error type -- icalerror_strerror() was probably given bad input"}
166 icalerrorenum icalerror_error_from_string(const char* str){
169 for( i = 0; string_map[i].error != ICAL_UNKNOWN_ERROR; i++)
170 if (strcmp(string_map[i].str,str) == 0)
173 return string_map[i].error;
176 icalerrorstate icalerror_supress(const char* error){
178 icalerrorenum e = icalerror_error_from_string(error);
181 if (e == ICAL_NO_ERROR){
182 return ICAL_ERROR_UNKNOWN;
186 es = icalerror_get_error_state(e);
187 icalerror_set_error_state(e,ICAL_ERROR_NONFATAL);
192 const char* icalerror_perror(void)
194 return icalerror_strerror(icalerrno);
197 void icalerror_restore(const char* error, icalerrorstate es){
200 icalerrorenum e = icalerror_error_from_string(error);
202 if (e != ICAL_NO_ERROR){
203 icalerror_set_error_state(e,es);
210 void icalerror_set_error_state( icalerrorenum error,
211 icalerrorstate state)
215 for(i = 0; error_state_map[i].error!= ICAL_NO_ERROR;i++){
216 if(error_state_map[i].error == error){
217 error_state_map[i].state = state;
222 icalerrorstate icalerror_get_error_state( icalerrorenum error)
226 for(i = 0; error_state_map[i].error!= ICAL_NO_ERROR;i++){
227 if(error_state_map[i].error == error){
228 return error_state_map[i].state;
232 return ICAL_ERROR_UNKNOWN;
238 const char* icalerror_strerror(icalerrorenum e) {
242 for (i=0; string_map[i].error != ICAL_UNKNOWN_ERROR; i++) {
243 if (string_map[i].error == e) {
244 return string_map[i].name;
248 return string_map[i].name; /* Return string for ICAL_UNKNOWN_ERROR*/
255 #ifdef HAVE_BACKTRACE
256 void *stack_frames[50];
260 size = backtrace(stack_frames, sizeof(stack_frames) / sizeof(void*));
261 strings = backtrace_symbols(stack_frames, size);
262 for (i = 0; i < size; i++) {
264 fprintf(stderr, "%s\n", strings[i]);
266 fprintf(stderr, "%p\n", stack_frames[i]);