diff options
Diffstat (limited to 'src/libical/icalerror.c')
-rw-r--r-- | src/libical/icalerror.c | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/src/libical/icalerror.c b/src/libical/icalerror.c new file mode 100644 index 0000000..4cff753 --- /dev/null +++ b/src/libical/icalerror.c @@ -0,0 +1,271 @@ +/* -*- Mode: C -*- + ====================================================================== + FILE: icalerror.c + CREATOR: eric 16 May 1999 + + $Id: icalerror.c,v 1.22 2008-01-15 23:17:40 dothebart Exp $ + $Locker: $ + + + (C) COPYRIGHT 2000, Eric Busboom <eric@softwarestudio.org> + http://www.softwarestudio.org + + This program is free software; you can redistribute it and/or modify + it under the terms of either: + + The LGPL as published by the Free Software Foundation, version + 2.1, available at: http://www.fsf.org/copyleft/lesser.html + + Or: + + The Mozilla Public License Version 1.0. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + The original code is icalerror.c + + ======================================================================*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_BACKTRACE +#include <execinfo.h> +#endif + +#include <stdlib.h> /* for malloc() */ +#include <string.h> /* for strcmp */ +#include "icalerror.h" + +#ifdef HAVE_PTHREAD +#include <pthread.h> + +static pthread_key_t icalerrno_key; +static pthread_once_t icalerrno_key_once = PTHREAD_ONCE_INIT; + +static void icalerrno_destroy(void* buf) { + free(buf); + pthread_setspecific(icalerrno_key, NULL); +} + +static void icalerrno_key_alloc(void) { + pthread_key_create(&icalerrno_key, icalerrno_destroy); +} + +icalerrorenum *icalerrno_return(void) { + icalerrorenum *_errno; + + pthread_once(&icalerrno_key_once, icalerrno_key_alloc); + + _errno = (icalerrorenum*) pthread_getspecific(icalerrno_key); + + if (!_errno) { + _errno = malloc(sizeof(icalerrorenum)); + *_errno = ICAL_NO_ERROR; + pthread_setspecific(icalerrno_key, _errno); + } + return _errno; +} + +#else + +static icalerrorenum icalerrno_storage = ICAL_NO_ERROR; + +icalerrorenum *icalerrno_return(void) { + return &icalerrno_storage; +} + +#endif + + +static int foo; + +void icalerror_stop_here(void) +{ + foo++; /* Keep optimizers from removing routine */ +} + +void icalerror_crash_here(void) +{ + int *p=0; + *p = 1; + + assert( *p); +} + +#ifdef ICAL_SETERROR_ISFUNC +void icalerror_set_errno(icalerrorenum x) +{ + icalerrno = x; + if(icalerror_get_error_state(x)==ICAL_ERROR_FATAL || + (icalerror_get_error_state(x)==ICAL_ERROR_DEFAULT && + icalerror_errors_are_fatal == 1 )){ + icalerror_warn(icalerror_strerror(x)); + ical_bt(); + assert(0); + } + +} +#endif + +void icalerror_clear_errno() { + + icalerrno = ICAL_NO_ERROR; +} + +#if ICAL_ERRORS_ARE_FATAL == 1 +int icalerror_errors_are_fatal = 1; +#else +int icalerror_errors_are_fatal = 0; +#endif + +struct icalerror_state { + icalerrorenum error; + icalerrorstate state; +}; + +static struct icalerror_state error_state_map[] = +{ + { ICAL_BADARG_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_NEWFAILED_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_ALLOCATION_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_PARSE_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_INTERNAL_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_FILE_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_USAGE_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_UNIMPLEMENTED_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_UNKNOWN_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_NO_ERROR,ICAL_ERROR_DEFAULT} + +}; + +struct icalerror_string_map { + const char* str; + icalerrorenum error; + char name[160]; +}; + +static const struct icalerror_string_map string_map[] = +{ + {"BADARG",ICAL_BADARG_ERROR,"BADARG: Bad argument to function"}, + { "NEWFAILED",ICAL_NEWFAILED_ERROR,"NEWFAILED: Failed to create a new object via a *_new() routine"}, + { "ALLOCATION",ICAL_ALLOCATION_ERROR,"ALLOCATION: Failed to allocate new memory"}, + {"MALFORMEDDATA",ICAL_MALFORMEDDATA_ERROR,"MALFORMEDDATA: An input string was not correctly formed or a component has missing or extra properties"}, + { "PARSE",ICAL_PARSE_ERROR,"PARSE: Failed to parse a part of an iCal component"}, + {"INTERNAL",ICAL_INTERNAL_ERROR,"INTERNAL: Random internal error. This indicates an error in the library code, not an error in use"}, + { "FILE",ICAL_FILE_ERROR,"FILE: An operation on a file failed. Check errno for more detail."}, + { "USAGE",ICAL_USAGE_ERROR,"USAGE: Failed to propertyl sequence calls to a set of interfaces"}, + { "UNIMPLEMENTED",ICAL_UNIMPLEMENTED_ERROR,"UNIMPLEMENTED: This feature has not been implemented"}, + { "NO",ICAL_NO_ERROR,"NO: No error"}, + {"UNKNOWN",ICAL_UNKNOWN_ERROR,"UNKNOWN: Unknown error type -- icalerror_strerror() was probably given bad input"} +}; + + +icalerrorenum icalerror_error_from_string(const char* str){ + int i; + + for( i = 0; string_map[i].error != ICAL_UNKNOWN_ERROR; i++) + if (strcmp(string_map[i].str,str) == 0) + break; + + return string_map[i].error; +} + +icalerrorstate icalerror_supress(const char* error){ + + icalerrorenum e = icalerror_error_from_string(error); + icalerrorstate es; + + if (e == ICAL_NO_ERROR){ + return ICAL_ERROR_UNKNOWN; + } + + + es = icalerror_get_error_state(e); + icalerror_set_error_state(e,ICAL_ERROR_NONFATAL); + + return es; +} + +const char* icalerror_perror() +{ + return icalerror_strerror(icalerrno); +} + +void icalerror_restore(const char* error, icalerrorstate es){ + + + icalerrorenum e = icalerror_error_from_string(error); + + if (e != ICAL_NO_ERROR){ + icalerror_set_error_state(e,es); + } + +} + + + +void icalerror_set_error_state( icalerrorenum error, + icalerrorstate state) +{ + int i; + + for(i = 0; error_state_map[i].error!= ICAL_NO_ERROR;i++){ + if(error_state_map[i].error == error){ + error_state_map[i].state = state; + } + } +} + +icalerrorstate icalerror_get_error_state( icalerrorenum error) +{ + int i; + + for(i = 0; error_state_map[i].error!= ICAL_NO_ERROR;i++){ + if(error_state_map[i].error == error){ + return error_state_map[i].state; + } + } + + return ICAL_ERROR_UNKNOWN; +} + + + + +const char* icalerror_strerror(icalerrorenum e) { + + int i; + + for (i=0; string_map[i].error != ICAL_UNKNOWN_ERROR; i++) { + if (string_map[i].error == e) { + return string_map[i].name; + } + } + + return string_map[i].name; /* Return string for ICAL_UNKNOWN_ERROR*/ + +} + + +void ical_bt(void) +{ +#ifdef HAVE_BACKTRACE + void *stack_frames[50]; + size_t size, i; + char **strings; + + size = backtrace(stack_frames, sizeof(stack_frames) / sizeof(void*)); + strings = backtrace_symbols(stack_frames, size); + for (i = 0; i < size; i++) { + if (strings != NULL) + fprintf(stderr, "%s\n", strings[i]); + else + fprintf(stderr, "%p\n", stack_frames[i]); + } + free(strings); +#endif +} + |