aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib/eina_magic.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/lib/eina_magic.c')
-rw-r--r--libraries/eina/src/lib/eina_magic.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/libraries/eina/src/lib/eina_magic.c b/libraries/eina/src/lib/eina_magic.c
new file mode 100644
index 0000000..1adde92
--- /dev/null
+++ b/libraries/eina/src/lib/eina_magic.c
@@ -0,0 +1,320 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2008 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 <stdlib.h>
24#include <string.h>
25
26#ifdef HAVE_EVIL
27# include <Evil.h>
28#endif
29
30#include "eina_config.h"
31#include "eina_private.h"
32#include "eina_error.h"
33#include "eina_log.h"
34
35/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
36#include "eina_safety_checks.h"
37#include "eina_magic.h"
38
39/*============================================================================*
40* Local *
41*============================================================================*/
42
43/**
44 * @cond LOCAL
45 */
46
47typedef struct _Eina_Magic_String Eina_Magic_String;
48struct _Eina_Magic_String
49{
50 Eina_Magic magic;
51 Eina_Bool string_allocated;
52 const char *string;
53};
54
55static int _eina_magic_string_log_dom = -1;
56
57#ifdef ERR
58#undef ERR
59#endif
60#define ERR(...) EINA_LOG_DOM_ERR(_eina_magic_string_log_dom, __VA_ARGS__)
61
62#ifdef DBG
63#undef DBG
64#endif
65#define DBG(...) EINA_LOG_DOM_DBG(_eina_magic_string_log_dom, __VA_ARGS__)
66
67static Eina_Magic_String *_eina_magic_strings = NULL;
68static size_t _eina_magic_strings_count = 0;
69static size_t _eina_magic_strings_allocated = 0;
70static Eina_Bool _eina_magic_strings_dirty = 0;
71
72static int
73_eina_magic_strings_sort_cmp(const void *p1, const void *p2)
74{
75 const Eina_Magic_String *a = p1, *b = p2;
76 return a->magic - b->magic;
77}
78
79static int
80_eina_magic_strings_find_cmp(const void *p1, const void *p2)
81{
82 Eina_Magic a = (Eina_Magic)p1;
83 const Eina_Magic_String *b = p2;
84 return a - b->magic;
85}
86
87static Eina_Magic_String *
88_eina_magic_strings_alloc(void)
89{
90 size_t idx;
91
92 if (_eina_magic_strings_count == _eina_magic_strings_allocated)
93 {
94 void *tmp;
95 size_t size;
96
97 if (EINA_UNLIKELY(_eina_magic_strings_allocated == 0))
98 size = 48;
99 else
100 size = _eina_magic_strings_allocated + 16;
101
102 tmp = realloc(_eina_magic_strings, sizeof(Eina_Magic_String) * size);
103 if (!tmp)
104 {
105#ifdef _WIN32
106 ERR("could not realloc magic_strings from %Iu to %Iu buckets.",
107 _eina_magic_strings_allocated, size);
108#else
109 ERR("could not realloc magic_strings from %zu to %zu buckets.",
110 _eina_magic_strings_allocated, size);
111#endif
112 return NULL;
113 }
114
115 _eina_magic_strings = tmp;
116 _eina_magic_strings_allocated = size;
117 }
118
119 idx = _eina_magic_strings_count;
120 _eina_magic_strings_count++;
121 return _eina_magic_strings + idx;
122}
123
124/**
125 * @endcond
126 */
127
128/*============================================================================*
129* Global *
130*============================================================================*/
131
132/**
133 * @internal
134 * @brief Initialize the magic string module.
135 *
136 * @return #EINA_TRUE on success, #EINA_FALSE on failure.
137 *
138 * This function sets up the magic string module of Eina. It is called by
139 * eina_init().
140 *
141 * @see eina_init()
142 */
143Eina_Bool
144eina_magic_string_init(void)
145{
146 _eina_magic_string_log_dom = eina_log_domain_register
147 ("eina_magic_string", EINA_LOG_COLOR_DEFAULT);
148 if (_eina_magic_string_log_dom < 0)
149 {
150 EINA_LOG_ERR("Could not register log domain: eina_magic_string");
151 return EINA_FALSE;
152 }
153
154 return EINA_TRUE;
155}
156
157/**
158 * @internal
159 * @brief Shut down the magic string module.
160 *
161 * @return #EINA_TRUE on success, #EINA_FALSE on failure.
162 *
163 * This function shuts down the magic string module set up by
164 * eina_magic string_init(). It is called by eina_shutdown().
165 *
166 * @see eina_shutdown()
167 */
168Eina_Bool
169eina_magic_string_shutdown(void)
170{
171 Eina_Magic_String *ems, *ems_end;
172
173 ems = _eina_magic_strings;
174 ems_end = ems + _eina_magic_strings_count;
175
176 for (; ems < ems_end; ems++)
177 if (ems->string_allocated)
178 free((char *)ems->string);
179
180 free(_eina_magic_strings);
181 _eina_magic_strings = NULL;
182 _eina_magic_strings_count = 0;
183 _eina_magic_strings_allocated = 0;
184
185 eina_log_domain_unregister(_eina_magic_string_log_dom);
186 _eina_magic_string_log_dom = -1;
187
188 return EINA_TRUE;
189}
190
191/*============================================================================*
192* API *
193*============================================================================*/
194EAPI const char *
195eina_magic_string_get(Eina_Magic magic)
196{
197 Eina_Magic_String *ems;
198
199 if (!_eina_magic_strings)
200 return "(none)";
201
202 if (_eina_magic_strings_dirty)
203 {
204 qsort(_eina_magic_strings, _eina_magic_strings_count,
205 sizeof(Eina_Magic_String), _eina_magic_strings_sort_cmp);
206 _eina_magic_strings_dirty = 0;
207 }
208
209 ems = bsearch((void *)magic, _eina_magic_strings,
210 _eina_magic_strings_count, sizeof(Eina_Magic_String),
211 _eina_magic_strings_find_cmp);
212 if (ems)
213 return ems->string ? ems->string : "(undefined)";
214
215 return "(unknown)";
216}
217
218EAPI Eina_Bool
219eina_magic_string_set(Eina_Magic magic, const char *magic_name)
220{
221 Eina_Magic_String *ems;
222
223 EINA_SAFETY_ON_NULL_RETURN_VAL(magic_name, EINA_FALSE);
224
225 ems = _eina_magic_strings_alloc();
226 if (!ems)
227 return EINA_FALSE;
228
229 ems->magic = magic;
230 ems->string_allocated = EINA_TRUE;
231 ems->string = strdup(magic_name);
232 if (!ems->string)
233 {
234 ERR("could not allocate string '%s'", magic_name);
235 _eina_magic_strings_count--;
236 return EINA_FALSE;
237 }
238
239 _eina_magic_strings_dirty = 1;
240 return EINA_TRUE;
241}
242
243EAPI Eina_Bool
244eina_magic_string_static_set(Eina_Magic magic, const char *magic_name)
245{
246 Eina_Magic_String *ems;
247
248 EINA_SAFETY_ON_NULL_RETURN_VAL(magic_name, EINA_FALSE);
249
250 ems = _eina_magic_strings_alloc();
251 if (!ems)
252 return EINA_FALSE;
253
254 ems->magic = magic;
255 ems->string_allocated = EINA_FALSE;
256 ems->string = magic_name;
257
258 _eina_magic_strings_dirty = 1;
259 return EINA_TRUE;
260}
261
262#ifdef eina_magic_fail
263# undef eina_magic_fail
264#endif
265
266EAPI void
267eina_magic_fail(void *d,
268 Eina_Magic m,
269 Eina_Magic req_m,
270 const char *file,
271 const char *fnc,
272 int line)
273{
274 if (!d)
275 eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL,
276 file, fnc, line,
277 "*** Eina Magic Check Failed !!!\n"
278 " Input handle pointer is NULL !\n"
279 "*** NAUGHTY PROGRAMMER!!!\n"
280 "*** SPANK SPANK SPANK!!!\n"
281 "*** Now go fix your code. Tut tut tut!\n"
282 "\n");
283 else
284 if (m == EINA_MAGIC_NONE)
285 eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL,
286 file, fnc, line,
287 "*** Eina Magic Check Failed !!!\n"
288 " Input handle has already been freed!\n"
289 "*** NAUGHTY PROGRAMMER!!!\n"
290 "*** SPANK SPANK SPANK!!!\n"
291 "*** Now go fix your code. Tut tut tut!\n"
292 "\n");
293 else
294 if (m != req_m)
295 eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL,
296 file, fnc, line,
297 "*** Eina Magic Check Failed !!!\n"
298 " Input handle is wrong type\n"
299 " Expected: %08x - %s\n"
300 " Supplied: %08x - %s\n"
301 "*** NAUGHTY PROGRAMMER!!!\n"
302 "*** SPANK SPANK SPANK!!!\n"
303 "*** Now go fix your code. Tut tut tut!\n"
304 "\n",
305 req_m, eina_magic_string_get(req_m),
306 m, eina_magic_string_get(m));
307 else
308 eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL,
309 file, fnc, line,
310 "*** Eina Magic Check Failed !!!\n"
311 " Why did you call me !\n"
312 "*** NAUGHTY PROGRAMMER!!!\n"
313 "*** SPANK SPANK SPANK!!!\n"
314 "*** Now go fix your code. Tut tut tut!\n"
315 "\n");
316}
317
318/**
319 * @}
320 */