1 | /*␊ |
2 | * contains some ideas from the Mark VanderVoord's CException project␊ |
3 | *␊ |
4 | * Copyright (c) 2012-2013 Cadet-Petit Armel␊ |
5 | * All rights reserved.␊ |
6 | *␊ |
7 | * Redistribution and use in source and binary forms, with or without␊ |
8 | * modification, are permitted provided that the following conditions are␊ |
9 | * met:␊ |
10 | *␊ |
11 | * * Redistributions of source code must retain the above copyright␊ |
12 | * notice, this list of conditions and the following disclaimer.␊ |
13 | *␊ |
14 | * * Redistributions in binary form must reproduce the above copyright␊ |
15 | * notice, this list of conditions and the following disclaimer in the␊ |
16 | * documentation and/or other materials provided with the␊ |
17 | * distribution.␊ |
18 | *␊ |
19 | * * Neither the name of Cadet-Petit Armel nor the names of the␊ |
20 | * contributors may be used to endorse or promote products derived␊ |
21 | * from this software without specific prior written permission.␊ |
22 | *␊ |
23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS␊ |
24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT␊ |
25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR␊ |
26 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT␊ |
27 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,␊ |
28 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT␊ |
29 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,␊ |
30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY␊ |
31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT␊ |
32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE␊ |
33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.␊ |
34 | */␊ |
35 | #ifndef _CEXCEPTION_H␊ |
36 | #define _CEXCEPTION_H␊ |
37 | ␊ |
38 | #include <setjmp.h>␊ |
39 | ␊ |
40 | #ifdef __cplusplus␊ |
41 | extern "C"␊ |
42 | {␊ |
43 | #endif␊ |
44 | ␉␊ |
45 | #define CEXCEPTION_USE_CONFIG_FILE␊ |
46 | ␉//#define DEBUG_EXCEPTION␊ |
47 | ␉␊ |
48 | ␉//To Use CException, you have a number of options:␊ |
49 | ␉//1. Just include it and run with the defaults␊ |
50 | ␉//2. Define any of the following symbols at the command line to override them␊ |
51 | ␉//3. Include a header file before CException.h everywhere which defines any of these␊ |
52 | ␉//4. Create an Exception.h in your path, and just define EXCEPTION_USE_CONFIG_FILE first␊ |
53 | ␉␊ |
54 | #ifdef CEXCEPTION_USE_CONFIG_FILE␊ |
55 | #include "CExceptionConfig.h"␊ |
56 | #endif␊ |
57 | ␉␊ |
58 | ␉//This is the value to assign when there isn't an exception␊ |
59 | #ifndef CEXCEPTION_NONE␊ |
60 | #define CEXCEPTION_NONE (0x5A5A5A5A)␊ |
61 | #endif␊ |
62 | ␊ |
63 | #ifndef EXIT_SUCCESS␊ |
64 | #define EXIT_SUCCESS (1)␊ |
65 | #endif␊ |
66 | ␉␊ |
67 | #ifndef EXIT_FAILURE␊ |
68 | #define EXIT_FAILURE (-1)␊ |
69 | #endif␊ |
70 | ␉␊ |
71 | #ifndef SIGABRT␊ |
72 | #define SIGABRT (-2)␊ |
73 | #endif␊ |
74 | ␊ |
75 | ␉//This is number of exception stacks to keep track of (one per task)␊ |
76 | #ifndef CEXCEPTION_NUM_ID␊ |
77 | #define CEXCEPTION_NUM_ID (1) //there is only the one stack by default␊ |
78 | #endif␊ |
79 | ␉␊ |
80 | ␉//This is the method of getting the current exception stack index (0 if only one stack)␊ |
81 | #ifndef CEXCEPTION_GET_ID␊ |
82 | #define CEXCEPTION_GET_ID (0) //use the first index always because there is only one anyway␊ |
83 | #endif␊ |
84 | ␉␊ |
85 | ␉//The type to use to store the exception values.␊ |
86 | #ifndef CEXCEPTION_T␊ |
87 | #define CEXCEPTION_T unsigned int␊ |
88 | #endif␊ |
89 | ␉␊ |
90 | ␉//This is an optional special handler for when there is no global Catch␊ |
91 | #ifndef CEXCEPTION_NO_CATCH_HANDLER␊ |
92 | #define CEXCEPTION_NO_CATCH_HANDLER(id)␊ |
93 | #endif␊ |
94 | ␉␊ |
95 | ␉//exception frame structures␊ |
96 | ␉typedef struct CEXCEPTION_FRAME {␊ |
97 | ␉␉jmp_buf cx;␊ |
98 | ␉␉struct CEXCEPTION_FRAME *pFrame; ␊ |
99 | ␉␉void *zone; ␊ |
100 | ␉␉void *atexit;␊ |
101 | ␉␉int new_registration;␊ |
102 | ␉␉int err_no;␊ |
103 | ␉} CEXCEPTION_FRAME_T;␊ |
104 | ␉␊ |
105 | void pushFrame(void);␊ |
106 | void popFrame(void);␊ |
107 | unsigned long getFramesCount(void);␊ |
108 | ␉CEXCEPTION_FRAME_T * getcurrentFrame(void);␊ |
109 | ␉CEXCEPTION_FRAME_T * getMainFrames(void);␊ |
110 | ␉␊ |
111 | ␉//Try (see C file for explanation)␊ |
112 | #define Try␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
113 | {␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
114 | pushFrame(); \␊ |
115 | if ((e = setjmp(getcurrentFrame()->cx)) == 0) { \␊ |
116 | e = CEXCEPTION_NONE; \␊ |
117 | if (1)␊ |
118 | ␉␊ |
119 | ␉//Catch (see C file for explanation)␊ |
120 | #define Catch(e)␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
121 | else { } \␊ |
122 | } \␊ |
123 | popFrame();\␊ |
124 | }␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
125 | if (e != CEXCEPTION_NONE)␊ |
126 | ␉␊ |
127 | ␊ |
128 | ␉//Throw an Error␊ |
129 | ␉void Throw(CEXCEPTION_T ExceptionID);␊ |
130 | ␉int Install_Default_Handler(void);␊ |
131 | ␉␊ |
132 | ␉␊ |
133 | #ifdef DEBUG_ALL_EXIT␊ |
134 | #define exit(e) \␊ |
135 | ((void) (__exit (#e,e, __FILE__, __LINE__)))␊ |
136 | #define __exit(estr, e, file, line) \␊ |
137 | ((void)printf ("%s:%u: exit status `%s'\n", file, line, estr), Throw(e))␊ |
138 | #else␊ |
139 | #define exit(e) \␊ |
140 | ((void) ((e == 0) ? Throw(EXIT_SUCCESS) : __exit (#e, e, __FILE__, __LINE__)))␊ |
141 | #define __exit(estr, e, file, line) \␊ |
142 | ((void)printf ("%s:%u: exit status `%s'\n", file, line, estr), Throw(e))␊ |
143 | #endif␉␊ |
144 | ␉␊ |
145 | #ifdef __cplusplus␊ |
146 | } // extern "C"␊ |
147 | #endif␊ |
148 | ␊ |
149 | ␊ |
150 | #endif // _CEXCEPTION_H␊ |
151 | |