0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / Standard / Standard_Failure.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <Standard_ErrorHandler.hxx>
17 #include <Standard_Failure.hxx>
18 #include <Standard_Macro.hxx>
19 #include <Standard_NoSuchObject.hxx>
20 #include <Standard_PCharacter.hxx>
21 #include <Standard_Type.hxx>
22 #include <Standard_TypeMismatch.hxx>
23
24 #include <string.h>
25 IMPLEMENT_STANDARD_RTTIEXT(Standard_Failure,Standard_Transient)
26
27 static Standard_CString allocate_message(const Standard_CString AString)
28 {
29   Standard_CString aStr = 0;
30   if(AString) {
31     const Standard_Size aLen = strlen(AString);
32     aStr = (Standard_CString) malloc(aLen+sizeof(Standard_Integer)+1);
33     if (aStr) {
34       Standard_PCharacter pStr=(Standard_PCharacter)aStr;
35       strcpy(pStr+sizeof(Standard_Integer),AString);
36       *((Standard_Integer*)aStr) = 1;
37     }
38   }
39   return aStr;
40 }
41
42 static Standard_CString copy_message(Standard_CString aMessage)
43 {
44   Standard_CString aStr = 0;
45   if(aMessage) {
46     aStr = aMessage;
47     (*((Standard_Integer*)aStr))++;
48   }
49   return aStr;
50 }
51
52 static void deallocate_message(Standard_CString aMessage)
53 {
54   if(aMessage) {
55     (*((Standard_Integer*)aMessage))--;
56     if(*((Standard_Integer*)aMessage)==0)
57       free((void*)aMessage);
58   }
59 }
60
61 // Define Standard_THREADLOCAL modifier as C++11 thread_local keyword
62 // where it is available.
63 #if (defined(__INTEL_COMPILER) && __INTEL_COMPILER > 1400) || \
64     (defined(__clang__)) /* assume standard CLang > 3.3 or XCode >= 8 */ || \
65     (defined(_MSC_VER) && _MSC_VER >= 1900) /* MSVC++ >= 14 */ || \
66     (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) /* GCC >= 4.8 */
67   #define Standard_THREADLOCAL thread_local
68 #else
69   #define Standard_THREADLOCAL
70 #endif
71
72 // ******************************************************************
73 //                           Standard_Failure                       *
74 // ******************************************************************
75 static Standard_THREADLOCAL Handle(Standard_Failure) RaisedError;
76
77 // ------------------------------------------------------------------
78 //
79 // ------------------------------------------------------------------
80 Standard_Failure::Standard_Failure ()
81 : myMessage(NULL) 
82 {
83 }
84
85 // ------------------------------------------------------------------
86 // Create returns mutable Failure;
87 // ------------------------------------------------------------------
88 Standard_Failure::Standard_Failure (const Standard_CString AString) 
89 :  myMessage(NULL)
90 {
91   myMessage = allocate_message(AString);
92 }
93
94 Standard_Failure::Standard_Failure (const Standard_Failure& theFailure) 
95 : Standard_Transient(theFailure)
96 {
97   myMessage = copy_message(theFailure.myMessage);
98 }
99
100 Standard_Failure::~Standard_Failure()
101 {
102   deallocate_message(myMessage);
103 }
104
105 void Standard_Failure::SetMessageString(const Standard_CString AString)
106 {
107   if ( AString == GetMessageString() ) return;
108   deallocate_message(myMessage);
109   myMessage = allocate_message(AString);
110 }
111
112 // ------------------------------------------------------------------
113 // Caught (myclass) returns mutable Failure raises NoSuchObject ;
114 // ------------------------------------------------------------------
115 Handle(Standard_Failure) Standard_Failure::Caught() 
116 {
117   return RaisedError ;
118 }
119
120 // ------------------------------------------------------------------
121 // Raise (myclass; aMessage: CString = "") ;
122 // ------------------------------------------------------------------
123 void Standard_Failure::Raise (const Standard_CString AString) 
124
125   Handle(Standard_Failure) E = new Standard_Failure()  ;
126   E->Reraise (AString) ;
127 }
128
129 // ------------------------------------------------------------------
130 // Raise(myclass; aReason: in out SStream) ;
131 // ------------------------------------------------------------------
132 void Standard_Failure::Raise (const Standard_SStream& AReason) 
133
134   Handle(Standard_Failure) E = new Standard_Failure();
135   E->Reraise (AReason);
136 }
137
138 // ------------------------------------------------------------------
139 // Reraise (me: mutable; aMessage: CString) ;
140 // ------------------------------------------------------------------
141 void Standard_Failure::Reraise (const Standard_CString AString) 
142 {
143   SetMessageString(AString);
144   Reraise();
145 }
146
147 void Standard_Failure::Reraise (const Standard_SStream& AReason) 
148 {
149   SetMessageString(AReason.str().c_str());
150   Reraise();
151 }
152
153 void Standard_Failure::Reraise () 
154 {
155   RaisedError = this;
156   Throw();
157 }
158
159 void Standard_Failure::Jump()
160 {
161 #if defined (OCC_CONVERT_SIGNALS)
162   Standard_ErrorHandler::Error (this);
163   Standard_ErrorHandler::Abort (this);
164 #else
165   RaisedError = this;
166   Throw();
167 #endif
168 }
169
170
171 // ------------------------------------------------------------------
172 // Throw (me) is virtual ;
173 // ------------------------------------------------------------------
174 void Standard_Failure::Throw() const
175 {
176   throw *this;
177 }
178
179 // ------------------------------------------------------------------
180 // Print (me; s: in out OStream) returns OStream;
181 // ------------------------------------------------------------------
182 void Standard_Failure::Print (Standard_OStream& AStream) const
183 {
184 if(myMessage){ 
185     AStream << DynamicType() << ": " << GetMessageString(); 
186  } 
187  else { 
188     AStream << DynamicType();
189  }
190 }
191
192 Handle(Standard_Failure) Standard_Failure::NewInstance(const Standard_CString AString)
193 {
194   return new Standard_Failure(AString)  ;
195 }
196
197 //=======================================================================
198 //function : GetMessageString
199 //purpose  : Returns error message
200 //=======================================================================
201 Standard_CString Standard_Failure::GetMessageString () const
202 {
203   return (myMessage ? myMessage+sizeof(Standard_Integer) : "");
204 }
205