Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / dti_excs / Exception.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: Exception.C /main/4 1996/10/04 09:40:25 drk $
24 #ifndef NATIVE_EXCEPTIONS
25 #include "Exceptions.hh"
26 #include <memory.h>
27
28 Exception *Exception::g_current_exception;
29
30 #ifdef C_API
31 char*  Exception::g_temp_space = 0;
32 char *Exception::g_next_avail = 0;
33 #else
34 char  Exception::g_temp_space[G_TEMP_SPACE_SIZE];
35 char *Exception::g_next_avail = Exception::g_temp_space;
36 #endif
37
38 // /////////////////////////////////////////////////////////////////
39 // class constructor
40 // /////////////////////////////////////////////////////////////////
41
42 Exception::Exception()
43 : f_thrown(0), f_thrown_as_pointer(1), f_temporary(0), f_line(0)
44 {
45   PRINTF (("Constructed Exception obj @ %p\n", this));
46 }
47
48
49 // /////////////////////////////////////////////////////////////////
50 // operator delete
51 // /////////////////////////////////////////////////////////////////
52
53 void
54 Exception::operator delete (void *place)
55 {
56   // Move pointer back if it's in our temp space, else just free it. 
57   if (place >= g_temp_space && place < g_temp_space + G_TEMP_SPACE_SIZE)
58     {
59       g_next_avail = (char *) place;
60       PRINTF (("De-alloc EXC @ %p\n", place));
61     }
62   else
63     {
64       free ((char *) place);
65     }
66 }
67
68
69 // /////////////////////////////////////////////////////////////////
70 // operator new
71 // /////////////////////////////////////////////////////////////////
72
73 // int arg is only used for type matching to insure that our version
74 //  of new gets called to make temporaries. 
75
76 void *
77 Exception::operator new (size_t size, int)
78 {
79   if (g_next_avail + size > g_temp_space + G_TEMP_SPACE_SIZE)
80     {
81       Exceptions::error (Exceptions::f_msg_out_of_exception_memory,
82                          Exceptions::INTERNAL_ERROR);
83       terminate();
84     }
85
86   void *p = g_next_avail;
87   g_next_avail += size;
88   PRINTF (("Allocate EXC @ %p, size = %ld\n", p, (long)size));
89   return (p);
90 }
91
92
93 // /////////////////////////////////////////////////////////////////
94 // throw_it
95 // /////////////////////////////////////////////////////////////////
96
97 // According to ARM, 15.2c temporary object thrown is of the static
98 // type of the operand to throw, so this method must be non-virtual.
99 // A non-virtual version of this function is created with macros in
100 // each subclass of the Exception object.  See Exception.hh. 
101
102 void
103 Exception::throw_it (unsigned int line, const char *file, int dbg)
104 {
105   // NOTE: This is the only place we can detect a throw of a pointer
106   // to a stack based object.
107
108   Exception *temp;
109   PRINTF (("Preparing to throw Exception object at %p:\n", this));
110
111   // Only make a temporary if the exception object is on the stack.
112   if (in_stack())
113     {
114       PRINTF (("  Exception is on the stack - copying it\n"));
115       // Use the special new operator which allocates the exception
116       // in reserved storage if there's no memory available.
117       temp = new (0) Exception (*this);
118       // We created it, so we should delete it. 
119       temp->f_temporary = 1;
120     }
121   else
122     {
123       PRINTF (("  Exception is on the heap\n"));
124       temp = this;
125     }
126
127   temp->do_throw (line, file, dbg);
128 }
129
130
131 // /////////////////////////////////////////////////////////////////
132 // throw - throw the current exception
133 // /////////////////////////////////////////////////////////////////
134
135 void
136 Exception::do_throw (unsigned int line, const char *file, int debugging)
137 {
138 #ifdef EXC_DEBUG
139   if (f_line == 0)
140     {
141       PRINTF (("========== Throwing exception ==========\n"));
142     }
143   else // must be a rethrow 
144     {
145       PRINTF (("========== Re-throwing exception ==========\n"));
146     }
147 #endif
148   
149   // Save line and file if we don't already have it.
150   if (f_line == 0)
151     {
152       f_line = line;
153       f_file = file;
154     }
155
156   f_thrown = 1;
157   Jump_Environment::unwind_and_jump (this, debugging);
158 }
159
160
161 // /////////////////////////////////////////////////////////////////
162 // current_exception - return the current exception
163 // /////////////////////////////////////////////////////////////////
164
165 Exception &
166 Exception::current_exception()
167 {
168   if (g_current_exception == NULL)
169     {
170       Exceptions::error (Exceptions::f_msg_no_current_exception,
171                          Exceptions::APPLICATION_ERROR);
172       terminate();
173     }
174
175   return (*g_current_exception);
176 }
177
178
179 // /////////////////////////////////////////////////////////////////
180 // (un)make_current - (un)make this exception the current one
181 // /////////////////////////////////////////////////////////////////
182
183 void
184 Exception::unmake_current()
185 {
186   PRINTF (("Current Exc POP %p <-- %p\n",
187            g_current_exception, f_previous_exception));
188   if (this != g_current_exception)
189     {
190       Exceptions::error ("Popped exception is the current one!",
191                          Exceptions::INTERNAL_ERROR);
192       terminate();
193     }
194
195   // Called when a catch clause is exited. 
196   g_current_exception = f_previous_exception;
197 }
198
199
200 void
201 Exception::make_current()
202 {
203   PRINTF (("Current Exc PUSH --> %p\n", this));
204   f_previous_exception = g_current_exception;
205   g_current_exception = this;
206 }
207
208
209 // /////////////////////////////////////////////////////////////////
210 // relocate - move this exception to the current top of stack
211 // /////////////////////////////////////////////////////////////////
212
213 void
214 Exception::relocate (Exception **exception, int length)
215 {
216   PRINTF (("Moving %p --> %p (%d bytes)\n",
217            *exception, g_next_avail, length));
218   // Slide the specified exception down to fill the hole below it.
219   if (g_next_avail >= (char *) *exception)
220     abort();
221   memcpy (g_next_avail, (void*)*exception, length);
222   *exception = (Exception *) g_next_avail;
223   g_next_avail = ((char *) *exception) + length;
224 }
225
226
227 // /////////////////////////////////////////////////////////////////
228 // is - return true this class is of type TYPE
229 // /////////////////////////////////////////////////////////////////
230
231 int
232 Exception::is (const char *type, const char *this_class)
233 {
234   PRINTF (("Type specified is <%s>\n", type));
235   
236   while (isalnum ((unsigned char) *type) &&
237          isalnum ((unsigned char) *this_class) &&
238          *type++ == *this_class++);
239   if (isalnum ((unsigned char) *type) ||
240       isalnum ((unsigned char) *this_class))
241     return (0);
242
243   // Check for pointer types
244   while (isspace ((unsigned char) *type))
245     {
246       type++;
247     }
248   PRINTF (("  var part is <%s>\n", type));
249
250   // See if one's a pointer and the other isn't. 
251   if ((*type == '*' && !f_thrown_as_pointer) ||
252       (*type != '*' &&  f_thrown_as_pointer))
253     return (0);
254   // Otherwise they are either both pointers or both objects/references.
255   return (1);
256 }
257 #endif /* NATIVE_EXCEPTIONS */