1 /* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric Bail
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.
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.
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/>.
30 #include "eina_config.h"
31 #include "eina_private.h"
32 #include "eina_error.h"
35 /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
36 #include "eina_safety_checks.h"
37 #include "eina_magic.h"
39 /*============================================================================*
41 *============================================================================*/
47 typedef struct _Eina_Magic_String Eina_Magic_String;
48 struct _Eina_Magic_String
51 Eina_Bool string_allocated;
55 static int _eina_magic_string_log_dom = -1;
60 #define ERR(...) EINA_LOG_DOM_ERR(_eina_magic_string_log_dom, __VA_ARGS__)
65 #define DBG(...) EINA_LOG_DOM_DBG(_eina_magic_string_log_dom, __VA_ARGS__)
67 static Eina_Magic_String *_eina_magic_strings = NULL;
68 static size_t _eina_magic_strings_count = 0;
69 static size_t _eina_magic_strings_allocated = 0;
70 static Eina_Bool _eina_magic_strings_dirty = 0;
73 _eina_magic_strings_sort_cmp(const void *p1, const void *p2)
75 const Eina_Magic_String *a = p1, *b = p2;
76 return a->magic - b->magic;
80 _eina_magic_strings_find_cmp(const void *p1, const void *p2)
82 Eina_Magic a = (Eina_Magic)(size_t)p1;
83 const Eina_Magic_String *b = p2;
87 static Eina_Magic_String *
88 _eina_magic_strings_alloc(void)
92 if (_eina_magic_strings_count == _eina_magic_strings_allocated)
97 if (EINA_UNLIKELY(_eina_magic_strings_allocated == 0))
100 size = _eina_magic_strings_allocated + 16;
102 tmp = realloc(_eina_magic_strings, sizeof(Eina_Magic_String) * size);
105 ERR("could not realloc magic_strings from %zu to %zu buckets.",
106 _eina_magic_strings_allocated, size);
110 _eina_magic_strings = tmp;
111 _eina_magic_strings_allocated = size;
114 idx = _eina_magic_strings_count;
115 _eina_magic_strings_count++;
116 return _eina_magic_strings + idx;
123 /*============================================================================*
125 *============================================================================*/
127 EAPI Eina_Error EINA_ERROR_MAGIC_FAILED = 0;
129 static const char EINA_ERROR_MAGIC_FAILED_STR[] = "Magic check failed.";
133 * @brief Initialize the magic string module.
135 * @return #EINA_TRUE on success, #EINA_FALSE on failure.
137 * This function sets up the magic string module of Eina. It is called by
143 eina_magic_string_init(void)
145 _eina_magic_string_log_dom = eina_log_domain_register
146 ("eina_magic_string", EINA_LOG_COLOR_DEFAULT);
147 if (_eina_magic_string_log_dom < 0)
149 EINA_LOG_ERR("Could not register log domain: eina_magic_string");
152 EINA_ERROR_MAGIC_FAILED = eina_error_msg_static_register(
153 EINA_ERROR_MAGIC_FAILED_STR);
160 * @brief Shut down the magic string module.
162 * @return #EINA_TRUE on success, #EINA_FALSE on failure.
164 * This function shuts down the magic string module set up by
165 * eina_magic string_init(). It is called by eina_shutdown().
167 * @see eina_shutdown()
170 eina_magic_string_shutdown(void)
172 Eina_Magic_String *ems, *ems_end;
174 ems = _eina_magic_strings;
175 ems_end = ems + _eina_magic_strings_count;
177 for (; ems < ems_end; ems++)
178 if (ems->string_allocated)
179 free((char *)ems->string);
181 free(_eina_magic_strings);
182 _eina_magic_strings = NULL;
183 _eina_magic_strings_count = 0;
184 _eina_magic_strings_allocated = 0;
186 eina_log_domain_unregister(_eina_magic_string_log_dom);
187 _eina_magic_string_log_dom = -1;
192 /*============================================================================*
194 *============================================================================*/
196 eina_magic_string_get(Eina_Magic magic)
198 Eina_Magic_String *ems;
200 if (!_eina_magic_strings)
203 if (_eina_magic_strings_dirty)
205 qsort(_eina_magic_strings, _eina_magic_strings_count,
206 sizeof(Eina_Magic_String), _eina_magic_strings_sort_cmp);
207 _eina_magic_strings_dirty = 0;
210 ems = bsearch((void *)(size_t)magic, _eina_magic_strings,
211 _eina_magic_strings_count, sizeof(Eina_Magic_String),
212 _eina_magic_strings_find_cmp);
214 return ems->string ? ems->string : "(undefined)";
220 eina_magic_string_set(Eina_Magic magic, const char *magic_name)
222 Eina_Magic_String *ems;
224 EINA_SAFETY_ON_NULL_RETURN_VAL(magic_name, EINA_FALSE);
226 ems = _eina_magic_strings_alloc();
231 ems->string_allocated = EINA_TRUE;
232 ems->string = strdup(magic_name);
235 ERR("could not allocate string '%s'", magic_name);
236 _eina_magic_strings_count--;
240 _eina_magic_strings_dirty = 1;
245 eina_magic_string_static_set(Eina_Magic magic, const char *magic_name)
247 Eina_Magic_String *ems;
249 EINA_SAFETY_ON_NULL_RETURN_VAL(magic_name, EINA_FALSE);
251 ems = _eina_magic_strings_alloc();
256 ems->string_allocated = EINA_FALSE;
257 ems->string = magic_name;
259 _eina_magic_strings_dirty = 1;
263 #ifdef eina_magic_fail
264 # undef eina_magic_fail
268 eina_magic_fail(void *d,
275 eina_error_set(EINA_ERROR_MAGIC_FAILED);
277 eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL,
279 "*** Eina Magic Check Failed !!!\n"
280 " Input handle pointer is NULL !\n"
281 "*** NAUGHTY PROGRAMMER!!!\n"
282 "*** SPANK SPANK SPANK!!!\n"
283 "*** Now go fix your code. Tut tut tut!\n"
286 if (m == EINA_MAGIC_NONE)
287 eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL,
289 "*** Eina Magic Check Failed !!!\n"
290 " Input handle has already been freed!\n"
291 "*** NAUGHTY PROGRAMMER!!!\n"
292 "*** SPANK SPANK SPANK!!!\n"
293 "*** Now go fix your code. Tut tut tut!\n"
297 eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL,
299 "*** Eina Magic Check Failed !!!\n"
300 " Input handle is wrong type\n"
301 " Expected: %08x - %s\n"
302 " Supplied: %08x - %s\n"
303 "*** NAUGHTY PROGRAMMER!!!\n"
304 "*** SPANK SPANK SPANK!!!\n"
305 "*** Now go fix your code. Tut tut tut!\n"
307 req_m, eina_magic_string_get(req_m),
308 m, eina_magic_string_get(m));
310 eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL,
312 "*** Eina Magic Check Failed !!!\n"
313 " Why did you call me !\n"
314 "*** NAUGHTY PROGRAMMER!!!\n"
315 "*** SPANK SPANK SPANK!!!\n"
316 "*** Now go fix your code. Tut tut tut!\n"