1 /*****************************************************************************/
2 /* Software Testing Automation Framework (STAF) */
3 /* (C) Copyright IBM Corp. 2001 */
4 /* */
5 /* This software is licensed under the Eclipse Public License (EPL) V1.0. */
6 /*****************************************************************************/
7
8 #ifndef STAF_Exception
9 #define STAF_Exception
10
11 #ifdef __cplusplus
12
13 #include <cstring>
14 #include <cstdio>
15 #include "STAF_iostream.h"
16 #include "STAFError.h"
17
18 /* The THROW_STAF_EXCEPTION macro is used to throw a STAFException or */
19 /* one of its derivatives. It also adds the location information to */
20 /* the exception. */
21
22 #define THROW_STAF_EXCEPTION(e)\
23 { e.setLocation(__FILE__, __LINE__); throw e; }
24
25 class STAFException
26 {
27 public:
28
29 STAFException(const char *text, unsigned int errorCode = 0,
30 const char *name = "STAFException")
fErrorCode(errorCode)31 : fErrorCode(errorCode)
32 {
33 // Using strncpy to make sure don't exceed the size of fName
34 strncpy(fName, name, sizeof(fName) - 1);
35 fName[sizeof(fName) - 1] = 0;
36
37 // Using strncpy to make sure don't exceed the size of fText
38 strncpy(fText, text, sizeof(fText) - 1);
39 fText[sizeof(fText) - 1] = 0;
40
41 fLocation[0] = 0;
42 }
43
setLocation(const char * filename,unsigned int lineNumber)44 void setLocation(const char *filename, unsigned int lineNumber)
45 {
46 // Make sure don't exceed the size of fLocation.
47 // Note: The 16 is based on the lineNumber length being at most 13,
48 // plus 2 for the size of "(" and ")" plus 1.
49 sprintf(fLocation, "%.*s(%u)",
50 static_cast<int>(sizeof(fLocation) - 16),
51 filename, lineNumber);
52 }
53
54 void trace(const char *caughtWhere = 0);
55 void trace(unsigned int tracePoint, const char *caughtWhere = 0);
56
57 static void checkRC(STAFRC_t rc, const char *errorMessage,
58 unsigned int osRC = 0);
59
60 inline void write(const char *caughtWhere = 0, ostream &os = cout)
61 {
62 if (caughtWhere) os << "In " << caughtWhere << ":" << endl;
63
64 os << "Caught STAFException" << endl
65 << "Name : " << getName() << endl
66 << "Location : " << getLocation() << endl
67 << "Text : " << getText() << endl
68 << "Error code: " << getErrorCode() << endl;
69 }
70
getName()71 const char *getName() { return fName; }
getText()72 const char *getText() { return fText; }
getLocation()73 const char *getLocation() { return fLocation; }
getErrorCode()74 unsigned int getErrorCode() { return fErrorCode; }
75
~STAFException()76 ~STAFException() { /* Do Nothing */ }
77
78 protected:
79
80 static void checkStandardExceptions(char *buffer, STAFRC_t rc,
81 const char *errorMessage,
82 unsigned int osRC);
83 private:
84
85 char fName[128];
86 /* Note: If change size of fText, must change size of buffer */
87 char fText[512];
88 char fLocation[384];
89 unsigned int fErrorCode;
90 };
91
92
93 /* The STAF_EXCEPTION_DEFINITION macro is used to create new types of */
94 /* STAF Exceptions. */
95
96 #define STAF_EXCEPTION_DEFINITION(className, baseName)\
97 class className : public baseName\
98 {\
99 public:\
100 className(const char *text, unsigned int errorCode = 0,\
101 const char *name = #className)\
102 : baseName(text, errorCode, name)\
103 { /* Do Nothing */ }\
104 \
105 static void checkRC(STAFRC_t rc, const char *errorMessage, unsigned int osRC = 0)\
106 {\
107 if (rc != kSTAFOk)\
108 {\
109 /* Note the buffer size must be same as the fText size */\
110 char buffer[512] = { 0 };\
111 checkStandardExceptions(buffer, rc, errorMessage, osRC);\
112 sprintf(buffer, "%.*s",\
113 static_cast<int>(sizeof(buffer) - 1), errorMessage);\
114 THROW_STAF_EXCEPTION(className(buffer, rc));\
115 }\
116 }\
117 \
118 ~className() { /* Do Nothing */ }\
119 };
120
121 STAF_EXCEPTION_DEFINITION(STAFOutOfBoundsException, STAFException);
122 STAF_EXCEPTION_DEFINITION(STAFInvalidObjectException, STAFException);
123 STAF_EXCEPTION_DEFINITION(STAFInvalidParmException, STAFException);
124 STAF_EXCEPTION_DEFINITION(STAFBaseOSErrorException, STAFException);
125
checkRC(STAFRC_t rc,const char * errorMessage,unsigned int osRC)126 inline void STAFException::checkRC(STAFRC_t rc, const char *errorMessage,
127 unsigned int osRC)
128 {
129 if (rc != kSTAFOk)
130 {
131 // Note the buffer size must be same as the fText size
132 char buffer[512] = { 0 };
133 checkStandardExceptions(buffer, rc, errorMessage, osRC);
134 // Makes sure no buffer overflow occurs if errorMessage
135 // exceeds size of buffer
136 sprintf(buffer, "%.*s", static_cast<int>(sizeof(buffer) - 1),
137 errorMessage);
138 THROW_STAF_EXCEPTION(STAFException(buffer, rc));
139 }
140 }
141
checkStandardExceptions(char * buffer,STAFRC_t rc,const char * errorMessage,unsigned int osRC)142 inline void STAFException::checkStandardExceptions(char *buffer, STAFRC_t rc,
143 const char *errorMessage,
144 unsigned int osRC)
145 {
146 switch (rc)
147 {
148 case kSTAFBaseOSError:
149 // Makes sure no buffer overflow occurs
150 // Note: The 16 is based on the osRC length being at most 13,
151 // plus 2 for the size of ": " plus 1.
152 sprintf(buffer, "%.*s: %u", static_cast<int>(sizeof(buffer) - 16),
153 errorMessage, osRC);
154 THROW_STAF_EXCEPTION(STAFBaseOSErrorException(buffer, rc));
155
156 case kSTAFInvalidObject:
157 // Makes sure no buffer overflow occurs if errorMessage
158 // exceeds size of buffer
159 sprintf(buffer, "%.*s", static_cast<int>(sizeof(buffer) - 1),
160 errorMessage);
161 THROW_STAF_EXCEPTION(STAFInvalidObjectException(buffer, rc));
162
163 case kSTAFInvalidParm:
164 // Makes sure no buffer overflow occurs if errorMessage
165 // exceeds size of buffer
166 sprintf(buffer, "%.*s", static_cast<int>(sizeof(buffer) - 1),
167 errorMessage);
168 THROW_STAF_EXCEPTION(STAFInvalidParmException(buffer, rc));
169
170 default:
171 break;
172 }
173 }
174
175 #endif
176
177 #endif
178