Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / dti_excs / Exceptions.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 // $XConsortium: Exceptions.cc /main/3 1996/06/11 16:51:03 cde-hal $
24 #ifndef NATIVE_EXCEPTIONS
25 #include "Exceptions.hh"
26 //#include <new.h>
27 #include <memory.h>
28 #include <string.h>
29
30 #ifdef C_API
31 char* Exceptions::f_msg_internal_error =   0;
32 char* Exceptions::f_msg_application_error = 0;
33 char* Exceptions::f_msg_throw_message =  0;
34 char* Exceptions::f_msg_not_initialized = 0;
35 char* Exceptions::f_msg_initialized_twice = 0;
36 char* Exceptions::f_msg_not_caught = 0;
37 char* Exceptions::f_msg_no_current_exception = 0;
38 char* Exceptions::f_msg_throw_from_terminate = 0;
39 char* Exceptions::f_msg_throw_from_error_handler = 0;
40 char* Exceptions::f_msg_throw_from_destructor = 0;
41 char* Exceptions::f_msg_throw_ptr_to_stack = 0;
42 char* Exceptions::f_msg_out_of_exception_memory = 0;
43 char* Exceptions::f_msg_out_of_obj_stack_memory = 0;
44 char* Exceptions::f_msg_memory_already_freed = 0;
45 #else
46 char *Exceptions::f_msg_internal_error =
47   (char*)"Internal exceptions error:";
48
49 char *Exceptions::f_msg_application_error =
50   (char*)"Application exceptions error:";
51
52 char *Exceptions::f_msg_throw_message =
53   (char*)"Application threw exception:";
54
55 char *Exceptions::f_msg_not_initialized =
56   (char*)"Exceptions library not initialized with INIT_EXCEPTIONS().";
57
58 char *Exceptions::f_msg_initialized_twice =
59   (char*)"Attept to call INIT_EXCEPTIONS() more than once.";
60   
61 char *Exceptions::f_msg_not_caught =
62   (char*)"Exception not caught.";
63
64 char *Exceptions::f_msg_no_current_exception =
65   (char*)"There is no current exception (for catch or rethrow).";
66
67 char *Exceptions::f_msg_throw_from_terminate =
68   (char*)"Exceptions may not be thrown from terminate.";
69
70 char *Exceptions::f_msg_throw_from_error_handler =
71   (char*)"Exceptions may not be thrown from error handler.";
72
73 char *Exceptions::f_msg_throw_from_destructor =
74   (char*)"Exited destructor with throw while handling an exception.";
75
76 char *Exceptions::f_msg_throw_ptr_to_stack =
77   (char*)"Threw a pointer to an automatic (stack-based) exceptions object.";
78
79 char *Exceptions::f_msg_out_of_exception_memory =
80   (char*)"Not enough memory to allocate an exception object.";
81
82 char *Exceptions::f_msg_out_of_obj_stack_memory =
83   (char*)"Not enough memory to allocate object stack.";
84
85 char *Exceptions::f_msg_memory_already_freed =
86   (char*)"Tried to alloc or realloc pool memory that was previously freed.";
87
88 #endif
89
90 // /////////////////////////////////////////////////////////////////
91 // initialize - initialize the exceptions library
92 // /////////////////////////////////////////////////////////////////
93
94 void
95 Exceptions::initialize (void *ptr)
96 {
97   PRINTF (("Initializing exceptions library\n"));
98
99   if (Destructable::g_stack_start != NULL)
100     {
101       error (f_msg_initialized_twice, APPLICATION_ERROR);
102       terminate();
103     }
104   else
105     {
106       // These two values MUST be initialized before the static
107       // Jump_Environment below, or the its Destructable base class
108       // constructor will fail because it won't think the library
109       // is initialized or it may think the Jump Environment is on
110       // the stack because f_stack_start is 0.
111       Destructable::g_stack_start = ptr;
112
113       // The following is the global jump environment.  According to ARM
114       // (6.7) this isn't initialized until the first call to this function,
115       // NOT at a global level before main() is called.  This is important
116       // because Jump_Environment is subclassed of Destructable, whose
117       // constructor expects g_stack_start to be non-zero.
118       static Jump_Environment __jump_env;
119
120       if (setjmp (__jump_env.f_env) != 0)
121         {
122           // Re-set base environment to allow for the creation of
123           // Destructable objects in error handler and terminate
124           // terminate function.
125           Jump_Environment::g_jump_env_stack = &__jump_env;
126
127           error (f_msg_not_caught, APPLICATION_ERROR);
128           terminate();
129         }
130     }
131 }
132
133
134 // Static variable declarations 
135
136 Exceptions::error_handler_t Exceptions::g_error_handler;
137
138 // Error message declarations
139 // The error messages are stored here because many appear in the
140 // header files and we don't want to duplicate them in every app
141 // that uses the header files. 
142
143
144   
145 // /////////////////////////////////////////////////////////////////
146 // set_error_handler
147 // /////////////////////////////////////////////////////////////////
148
149 Exceptions::error_handler_t
150 Exceptions::set_error_handler (error_handler_t error_handler)
151 {
152   error_handler_t previous = g_error_handler;
153   g_error_handler = error_handler;
154   return (previous);
155 }
156
157
158 // /////////////////////////////////////////////////////////////////
159 // error - print a useful error message
160 // /////////////////////////////////////////////////////////////////
161
162 void
163 Exceptions::error (const char *message, error_type_t error_type)
164 {
165   const unsigned int bufferlen = 100;
166   char buffer[3][bufferlen];
167   static char *lines[3] = { buffer[0], buffer[1], buffer[2] };
168   int len, count = 0;
169
170   if (error_type == INTERNAL_ERROR) {
171     len = MIN(strlen(f_msg_internal_error), bufferlen - 1);
172     *((char *) memcpy(buffer[count++], f_msg_internal_error, len) + len) = '\0';
173   }
174   else if (error_type == APPLICATION_ERROR) {
175     len = MIN(strlen(f_msg_application_error), bufferlen - 1);
176     *((char *) memcpy(buffer[count++], f_msg_application_error,len)+len) = '\0';
177   }
178   else {
179     len = MIN(strlen(f_msg_throw_message), bufferlen - 1);
180     *((char *) memcpy(buffer[count++], f_msg_throw_message, len) + len) = '\0';
181   }
182       
183   // Don't use fprintf because it may try to allocate memory.
184   if (Exception::g_current_exception != NULL)
185     {
186       snprintf (buffer[count++], bufferlen,
187                "   In exception thrown in file \"%s\", line %d,",
188                Exception::g_current_exception->f_file,
189                Exception::g_current_exception->f_line);
190     }
191
192   if (message != NULL)
193     snprintf (buffer[count++], bufferlen, "   %s", message);
194
195   // Call user print function if set, otherwise just dump lines.
196   if (g_error_handler != NULL)
197     {
198       mtry
199         {
200           // Reset global variable to NULL before calling to prevent
201           // the possibility of recursive calls. 
202           Exceptions::error_handler_t current = set_error_handler (NULL);
203           (*current) ((const char**)lines, count);
204           set_error_handler (current);
205         }
206       mcatch_any()
207         {
208           // Error handler will be NULL at this point. 
209           Exceptions::error (Exceptions::f_msg_throw_from_error_handler,
210                              Exceptions::APPLICATION_ERROR);
211           terminate();
212
213         }
214       end_try;
215     }
216   else
217     {
218       for (int i = 0; i < count; i++)
219         {
220           fputs (buffer[i], stderr);
221           fputc ('\n', stderr);
222         }
223     }
224 }
225
226
227 // /////////////////////////////////////////////////////////////////
228 // check_initialized - exit with error if not initialized
229 // /////////////////////////////////////////////////////////////////
230
231 void
232 Exceptions::check_initialized()
233 {
234   void terminate();
235   if (Destructable::g_stack_start == NULL)
236     {
237       // Can't call user defined error handler unless we're initialized.
238       // Also can't do lazy initialization because we need the stack
239       // pointer from the start of main, not here.  From here is good
240       // enough for terminating, however.
241       INIT_EXCEPTIONS();
242       error (f_msg_not_initialized, APPLICATION_ERROR);
243       terminate();
244     }
245 }
246
247 #endif /* NATIVE_EXCEPTIONS */