Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / dti_excs / Jump_Environment.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: Jump_Environment.C /main/6 1996/10/04 09:37:00 drk $
24 #ifndef NATIVE_EXCEPTIONS
25 #include "Exceptions.hh"
26
27 Jump_Environment *Jump_Environment::g_jump_env_stack;
28
29 #ifdef EXC_DEBUG
30 int Jump_Environment::g_level;
31 #endif
32
33 unsigned short Unwind_Stack::g_top ;
34
35 #ifdef C_API
36 Unwind_Record* Unwind_Stack::g_stack = 0; // inited in init.C
37 #else
38 Unwind_Record Unwind_Stack::g_stack[UNWIND_STACK_SIZE];
39 #endif
40
41
42 // /////////////////////////////////////////////////////////////////
43 // Jump_Environment - class constructor
44 // /////////////////////////////////////////////////////////////////
45
46 Jump_Environment::Jump_Environment()
47 : f_active_exception (NULL), f_unwinding (0)
48 {
49   PRINTF (("<%d> New Jump_Environment @ %p\n", ++g_level, this));
50   // Push this on to the top of the jump env stack. 
51   f_next = g_jump_env_stack;
52   g_jump_env_stack = this;
53 }
54
55 // /////////////////////////////////////////////////////////////////
56 // class destructor
57 // /////////////////////////////////////////////////////////////////
58
59 Jump_Environment::~Jump_Environment()
60 {
61   // If g_jump_env_stack == this an exception wasn't thrown.
62   // (Because at throw time we set g_jump_env_stack to f_next.) 
63   if (g_jump_env_stack == this)
64     {
65       g_jump_env_stack = f_next;
66     }
67   // An exception was thrown in our try block.
68   // An exception may have been thrown in our catch block.
69   // If one was, g_jump_env_stack->f_active_exception != NULL. 
70   if (f_active_exception != NULL)
71     {
72       delete_active();
73     }
74   PRINTF (("<%d> Done with Jump_Environment @ %p\n",
75            g_level--, this));
76 }
77
78
79 // /////////////////////////////////////////////////////////////////
80 // unwind - call destructors for stack based objects
81 // /////////////////////////////////////////////////////////////////
82
83 void
84 Jump_Environment::do_unwind_and_jump (Exception *exception, int debugging)
85 {
86   PRINTF (("----- <%d> Unwinding stack -----\n", g_level));
87
88   // Remember the current exception so we can delete it later.
89   f_active_exception = exception;
90
91   // Check for a throw out of a destructor. 
92   if (f_unwinding)
93     {
94       Exceptions::error (Exceptions::f_msg_throw_from_destructor,
95                          Exceptions::APPLICATION_ERROR);
96       terminate();
97     }
98
99   f_unwinding = 1;
100
101   // Call the destructor of each objet on the stack in reverse.
102   // Length is automatically decremented as each object unregisters itself.
103   while (!f_unwind_stack.empty())
104     {
105       PRINTF (("* Calling dtor of %p\n", f_unwind_stack.top().f_object));
106 #if CC_VERSION < 30
107       f_unwind_stack.top().f_object->destruct();
108 #else
109       f_unwind_stack.top().f_object->~Destructable();
110 #endif
111     }
112
113   // This Jump Environment is no longer needed, so we need to pull it off
114   // the global jump env stack.  Any new stack objects from this point
115   // on must be registed in the enclosing Jump Environment scope for the
116   // purposes of exceptions or otherwise.  The memory associated with the
117   // unwind_stack is freed when we exit the scope or throw an exception. 
118   g_jump_env_stack = f_next;
119   PRINTF (("----- <%d> Unwind complete -----\n", g_level));
120
121   // Make the current exception official (it may move in the process).
122   f_active_exception->make_current();
123
124   // Print a message about the throw point if debugging is on. 
125   if (debugging)
126     {
127       Exceptions::error_handler_t saved = Exceptions::set_error_handler (NULL);
128       Exceptions::error (NULL, Exceptions::THROW_MESSAGE);
129       Exceptions::set_error_handler (saved);
130     }
131
132   // And away we go... 
133   longjmp();
134 }
135
136
137 // /////////////////////////////////////////////////////////////////
138 // delete_active - delete active exception, maybe move pending
139 // /////////////////////////////////////////////////////////////////
140
141 void
142 Jump_Environment::delete_active()
143 {
144   // For starters, it's no longer the current exception.
145   f_active_exception->unmake_current();
146
147   // We normally delete the current exception when it's enclosing
148   // environment is destructed, UNLESS the same exception is being
149   // rethrown to the handler above.  g_jump_env_stack points to
150   // the Jump_Environment that is unwinding.
151
152   if (f_active_exception->f_temporary &&
153       (g_jump_env_stack == NULL || f_active_exception != pending_exception()))
154     {
155       // If there's one pending we created and a current one, we are going
156       // to have to move the pending one down on our stack after
157       // deleting the current one, so we need to remember where it ends.
158       // If the pending exception == the current one, then we're just
159       // returning to the scope of a previous exception. 
160       
161       if (g_jump_env_stack != NULL &&
162           pending_exception() != NULL &&
163           pending_exception()->f_temporary &&
164           pending_exception() != Exception::g_current_exception)
165         {
166           // The length() method is only valid here! 
167           int length = pending_exception()->length();
168           delete f_active_exception;
169           Exception::relocate (&g_jump_env_stack->f_active_exception,
170                                length);
171         }
172       else  // Just delete it -- no move necessary. 
173         {
174           delete f_active_exception;
175         }
176     }
177 }
178 #endif /* NATIVE_EXCEPTIONS */