aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib/eina_error.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/lib/eina_error.c')
-rw-r--r--libraries/eina/src/lib/eina_error.c279
1 files changed, 279 insertions, 0 deletions
diff --git a/libraries/eina/src/lib/eina_error.c b/libraries/eina/src/lib/eina_error.c
new file mode 100644
index 0000000..428c414
--- /dev/null
+++ b/libraries/eina/src/lib/eina_error.c
@@ -0,0 +1,279 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2007-2008 Jorge Luis Zapata Muga, Cedric Bail
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26
27#ifdef HAVE_EVIL
28# include <Evil.h>
29#endif
30
31#include "eina_config.h"
32#include "eina_private.h"
33
34
35/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
36#include "eina_safety_checks.h"
37#include "eina_error.h"
38#include "eina_stringshare.h"
39
40/* TODO
41 * + add a wrapper for assert?
42 * + add common error numbers, messages
43 * + add a calltrace of errors, not only store the last error but a list of them
44 * and also store the function that set it
45 */
46
47/*============================================================================*
48* Local *
49*============================================================================*/
50
51/**
52 * @cond LOCAL
53 */
54
55typedef struct _Eina_Error_Message Eina_Error_Message;
56struct _Eina_Error_Message
57{
58 Eina_Bool string_allocated;
59 const char *string;
60};
61
62static Eina_Error_Message *_eina_errors = NULL;
63static size_t _eina_errors_count = 0;
64static size_t _eina_errors_allocated = 0;
65static Eina_Error _eina_last_error;
66
67static Eina_Error_Message *
68_eina_error_msg_alloc(void)
69{
70 size_t idx;
71
72 if (_eina_errors_count == _eina_errors_allocated)
73 {
74 void *tmp;
75 size_t size;
76
77 if (EINA_UNLIKELY(_eina_errors_allocated == 0))
78 size = 24;
79 else
80 size = _eina_errors_allocated + 8;
81
82 tmp = realloc(_eina_errors, sizeof(Eina_Error_Message) * size);
83 if (!tmp)
84 return NULL;
85
86 _eina_errors = tmp;
87 _eina_errors_allocated = size;
88 }
89
90 idx = _eina_errors_count;
91 _eina_errors_count++;
92 return _eina_errors + idx;
93}
94
95/**
96 * @endcond
97 */
98
99
100/*============================================================================*
101* Global *
102*============================================================================*/
103
104/**
105 * @cond LOCAL
106 */
107
108EAPI Eina_Error EINA_ERROR_OUT_OF_MEMORY = 0;
109
110static const char EINA_ERROR_OUT_OF_MEMORY_STR[] = "Out of memory";
111
112/**
113 * @endcond
114 */
115
116/**
117 * @internal
118 * @brief Initialize the error module.
119 *
120 * @return #EINA_TRUE on success, #EINA_FALSE on failure.
121 *
122 * This function sets up the error module of Eina. It is called by
123 * eina_init().
124 *
125 * This function registers the error #EINA_ERROR_OUT_OF_MEMORY.
126 *
127 * @see eina_init()
128 */
129Eina_Bool
130eina_error_init(void)
131{
132 /* TODO register the eina's basic errors */
133 EINA_ERROR_OUT_OF_MEMORY = eina_error_msg_static_register(
134 EINA_ERROR_OUT_OF_MEMORY_STR);
135 return EINA_TRUE;
136}
137
138/**
139 * @internal
140 * @brief Shut down the error module.
141 *
142 * @return #EINA_TRUE on success, #EINA_FALSE on failure.
143 *
144 * This function shuts down the error module set up by
145 * eina_error_init(). It is called by eina_shutdown().
146 *
147 * @see eina_shutdown()
148 */
149Eina_Bool
150eina_error_shutdown(void)
151{
152 Eina_Error_Message *eem, *eem_end;
153
154 eem = _eina_errors;
155 eem_end = eem + _eina_errors_count;
156
157 for (; eem < eem_end; eem++)
158 if (eem->string_allocated)
159 eina_stringshare_del(eem->string);
160
161 free(_eina_errors);
162 _eina_errors = NULL;
163 _eina_errors_count = 0;
164 _eina_errors_allocated = 0;
165
166 return EINA_TRUE;
167}
168
169/*============================================================================*
170* API *
171*============================================================================*/
172
173EAPI Eina_Error
174eina_error_msg_register(const char *msg)
175{
176 Eina_Error_Message *eem;
177
178 EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0);
179
180 eem = _eina_error_msg_alloc();
181 if (!eem)
182 return 0;
183
184 eem->string_allocated = EINA_TRUE;
185 eem->string = eina_stringshare_add(msg);
186 if (!eem->string)
187 {
188 _eina_errors_count--;
189 return 0;
190 }
191
192 return _eina_errors_count; /* identifier = index + 1 (== _count). */
193}
194
195EAPI Eina_Error
196eina_error_msg_static_register(const char *msg)
197{
198 Eina_Error_Message *eem;
199
200 EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0);
201
202 eem = _eina_error_msg_alloc();
203 if (!eem)
204 return 0;
205
206 eem->string_allocated = EINA_FALSE;
207 eem->string = msg;
208 return _eina_errors_count; /* identifier = index + 1 (== _count). */
209}
210
211EAPI Eina_Bool
212eina_error_msg_modify(Eina_Error error, const char *msg)
213{
214 EINA_SAFETY_ON_NULL_RETURN_VAL(msg, EINA_FALSE);
215 if (error < 1)
216 return EINA_FALSE;
217
218 if ((size_t)error > _eina_errors_count)
219 return EINA_FALSE;
220
221 if (_eina_errors[error - 1].string_allocated)
222 {
223 const char *tmp;
224
225 if (!(tmp = eina_stringshare_add(msg)))
226 return EINA_FALSE;
227
228 eina_stringshare_del(_eina_errors[error - 1].string);
229 _eina_errors[error - 1].string = tmp;
230 return EINA_TRUE;
231 }
232
233 _eina_errors[error - 1].string = msg;
234 return EINA_TRUE;
235}
236
237EAPI const char *
238eina_error_msg_get(Eina_Error error)
239{
240 if (error < 1)
241 return NULL;
242
243 if ((size_t)error > _eina_errors_count)
244 return NULL;
245
246 return _eina_errors[error - 1].string;
247}
248
249EAPI Eina_Error
250eina_error_get(void)
251{
252 return _eina_last_error;
253}
254
255EAPI void
256eina_error_set(Eina_Error err)
257{
258 _eina_last_error = err;
259}
260
261EAPI Eina_Error
262eina_error_find(const char *msg)
263{
264 size_t i;
265
266 EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0);
267
268 for (i = 0; i < _eina_errors_count; i++)
269 {
270 if (_eina_errors[i].string_allocated)
271 {
272 if (_eina_errors[i].string == msg)
273 return i + 1;
274 }
275 if (!strcmp(_eina_errors[i].string, msg))
276 return i + 1;
277 }
278 return 0;
279}