123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- // $XConsortium: Exceptions.cc /main/3 1996/06/11 16:51:03 cde-hal $
- #ifndef NATIVE_EXCEPTIONS
- #include "Exceptions.hh"
- //#include <new.h>
- #include <memory.h>
- #include <string.h>
- #ifdef C_API
- char* Exceptions::f_msg_internal_error = 0;
- char* Exceptions::f_msg_application_error = 0;
- char* Exceptions::f_msg_throw_message = 0;
- char* Exceptions::f_msg_not_initialized = 0;
- char* Exceptions::f_msg_initialized_twice = 0;
- char* Exceptions::f_msg_not_caught = 0;
- char* Exceptions::f_msg_no_current_exception = 0;
- char* Exceptions::f_msg_throw_from_terminate = 0;
- char* Exceptions::f_msg_throw_from_error_handler = 0;
- char* Exceptions::f_msg_throw_from_destructor = 0;
- char* Exceptions::f_msg_throw_ptr_to_stack = 0;
- char* Exceptions::f_msg_out_of_exception_memory = 0;
- char* Exceptions::f_msg_out_of_obj_stack_memory = 0;
- char* Exceptions::f_msg_memory_already_freed = 0;
- #else
- char *Exceptions::f_msg_internal_error =
- (char*)"Internal exceptions error:";
- char *Exceptions::f_msg_application_error =
- (char*)"Application exceptions error:";
- char *Exceptions::f_msg_throw_message =
- (char*)"Application threw exception:";
- char *Exceptions::f_msg_not_initialized =
- (char*)"Exceptions library not initialized with INIT_EXCEPTIONS().";
- char *Exceptions::f_msg_initialized_twice =
- (char*)"Attept to call INIT_EXCEPTIONS() more than once.";
-
- char *Exceptions::f_msg_not_caught =
- (char*)"Exception not caught.";
- char *Exceptions::f_msg_no_current_exception =
- (char*)"There is no current exception (for catch or rethrow).";
- char *Exceptions::f_msg_throw_from_terminate =
- (char*)"Exceptions may not be thrown from terminate.";
- char *Exceptions::f_msg_throw_from_error_handler =
- (char*)"Exceptions may not be thrown from error handler.";
- char *Exceptions::f_msg_throw_from_destructor =
- (char*)"Exited destructor with throw while handling an exception.";
- char *Exceptions::f_msg_throw_ptr_to_stack =
- (char*)"Threw a pointer to an automatic (stack-based) exceptions object.";
- char *Exceptions::f_msg_out_of_exception_memory =
- (char*)"Not enough memory to allocate an exception object.";
- char *Exceptions::f_msg_out_of_obj_stack_memory =
- (char*)"Not enough memory to allocate object stack.";
- char *Exceptions::f_msg_memory_already_freed =
- (char*)"Tried to alloc or realloc pool memory that was previously freed.";
- #endif
- // /////////////////////////////////////////////////////////////////
- // initialize - initialize the exceptions library
- // /////////////////////////////////////////////////////////////////
- void
- Exceptions::initialize (void *ptr)
- {
- PRINTF (("Initializing exceptions library\n"));
- if (Destructable::g_stack_start != NULL)
- {
- error (f_msg_initialized_twice, APPLICATION_ERROR);
- terminate();
- }
- else
- {
- // These two values MUST be initialized before the static
- // Jump_Environment below, or the its Destructable base class
- // constructor will fail because it won't think the library
- // is initialized or it may think the Jump Environment is on
- // the stack because f_stack_start is 0.
- Destructable::g_stack_start = ptr;
- // The following is the global jump environment. According to ARM
- // (6.7) this isn't initialized until the first call to this function,
- // NOT at a global level before main() is called. This is important
- // because Jump_Environment is subclassed of Destructable, whose
- // constructor expects g_stack_start to be non-zero.
- static Jump_Environment __jump_env;
- if (setjmp (__jump_env.f_env) != 0)
- {
- // Re-set base environment to allow for the creation of
- // Destructable objects in error handler and terminate
- // terminate function.
- Jump_Environment::g_jump_env_stack = &__jump_env;
- error (f_msg_not_caught, APPLICATION_ERROR);
- terminate();
- }
- }
- }
- // Static variable declarations
- Exceptions::error_handler_t Exceptions::g_error_handler;
- // Error message declarations
- // The error messages are stored here because many appear in the
- // header files and we don't want to duplicate them in every app
- // that uses the header files.
-
- // /////////////////////////////////////////////////////////////////
- // set_error_handler
- // /////////////////////////////////////////////////////////////////
- Exceptions::error_handler_t
- Exceptions::set_error_handler (error_handler_t error_handler)
- {
- error_handler_t previous = g_error_handler;
- g_error_handler = error_handler;
- return (previous);
- }
- // /////////////////////////////////////////////////////////////////
- // error - print a useful error message
- // /////////////////////////////////////////////////////////////////
- void
- Exceptions::error (const char *message, error_type_t error_type)
- {
- const unsigned int bufferlen = 100;
- char buffer[3][bufferlen];
- static char *lines[3] = { buffer[0], buffer[1], buffer[2] };
- int len, count = 0;
- if (error_type == INTERNAL_ERROR) {
- len = MIN(strlen(f_msg_internal_error), bufferlen - 1);
- *((char *) memcpy(buffer[count++], f_msg_internal_error, len) + len) = '\0';
- }
- else if (error_type == APPLICATION_ERROR) {
- len = MIN(strlen(f_msg_application_error), bufferlen - 1);
- *((char *) memcpy(buffer[count++], f_msg_application_error,len)+len) = '\0';
- }
- else {
- len = MIN(strlen(f_msg_throw_message), bufferlen - 1);
- *((char *) memcpy(buffer[count++], f_msg_throw_message, len) + len) = '\0';
- }
-
- // Don't use fprintf because it may try to allocate memory.
- if (Exception::g_current_exception != NULL)
- {
- snprintf (buffer[count++], bufferlen,
- " In exception thrown in file \"%s\", line %d,",
- Exception::g_current_exception->f_file,
- Exception::g_current_exception->f_line);
- }
- if (message != NULL)
- snprintf (buffer[count++], bufferlen, " %s", message);
- // Call user print function if set, otherwise just dump lines.
- if (g_error_handler != NULL)
- {
- mtry
- {
- // Reset global variable to NULL before calling to prevent
- // the possibility of recursive calls.
- Exceptions::error_handler_t current = set_error_handler (NULL);
- (*current) ((const char**)lines, count);
- set_error_handler (current);
- }
- mcatch_any()
- {
- // Error handler will be NULL at this point.
- Exceptions::error (Exceptions::f_msg_throw_from_error_handler,
- Exceptions::APPLICATION_ERROR);
- terminate();
- }
- end_try;
- }
- else
- {
- for (int i = 0; i < count; i++)
- {
- fputs (buffer[i], stderr);
- fputc ('\n', stderr);
- }
- }
- }
- // /////////////////////////////////////////////////////////////////
- // check_initialized - exit with error if not initialized
- // /////////////////////////////////////////////////////////////////
- void
- Exceptions::check_initialized()
- {
- void terminate();
- if (Destructable::g_stack_start == NULL)
- {
- // Can't call user defined error handler unless we're initialized.
- // Also can't do lazy initialization because we need the stack
- // pointer from the start of main, not here. From here is good
- // enough for terminating, however.
- INIT_EXCEPTIONS();
- error (f_msg_not_initialized, APPLICATION_ERROR);
- terminate();
- }
- }
- #endif /* NATIVE_EXCEPTIONS */
|