Bug Summary

File:tests/suite/ecore/src/lib/eina_rectangle.c
Location:line 569, column 4
Description:Dereference of null pointer

Annotated Source Code

1/* EINA - EFL data type library
2 * Copyright (C) 2007-2008 Cedric BAIL, Carsten Haitzler
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_H1
20# include "config.h"
21#endif
22
23#include <stdio.h>
24#include <stdlib.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_magic.h"
33#include "eina_inlist.h"
34#include "eina_mempool.h"
35#include "eina_list.h"
36#include "eina_trash.h"
37#include "eina_log.h"
38
39/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
40#include "eina_safety_checks.h"
41#include "eina_rectangle.h"
42
43/*============================================================================*
44* Local *
45*============================================================================*/
46
47/**
48 * @cond LOCAL
49 */
50
51#define EINA_RECTANGLE_POOL_MAGIC0x1578FCB0 0x1578FCB0
52#define EINA_RECTANGLE_ALLOC_MAGIC0x1578FCB1 0x1578FCB1
53
54#define BUCKET_THRESHOLD110 110
55
56typedef struct _Eina_Rectangle_Alloc Eina_Rectangle_Alloc;
57
58struct _Eina_Rectangle_Pool
59{
60 Eina_Inlist *head;
61 Eina_List *empty;
62 void *data;
63
64 Eina_Trash *bucket;
65 unsigned int bucket_count;
66
67 unsigned int references;
68 int w;
69 int h;
70
71 Eina_Bool sorted;
72 EINA_MAGICEina_Magic __magic;
73};
74
75struct _Eina_Rectangle_Alloc
76{
77 EINA_INLISTEina_Inlist __in_list;
78 Eina_Rectangle_Pool *pool;
79 EINA_MAGICEina_Magic __magic;
80};
81
82#define EINA_MAGIC_CHECK_RECTANGLE_POOL(d)do { if (!(((d)) && (((d))->__magic == (0x1578FCB0
)))) { eina_magic_fail((void *)((d)), ((d)) ? ((d))->__magic
: 0, (0x1578FCB0), "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 82);; } } while (0)
\
83 do { \
84 if (!EINA_MAGIC_CHECK((d), EINA_RECTANGLE_POOL_MAGIC)(((d)) && (((d))->__magic == (0x1578FCB0)))) { \
85 EINA_MAGIC_FAIL((d), EINA_RECTANGLE_POOL_MAGIC)eina_magic_fail((void *)((d)), ((d)) ? ((d))->__magic : 0,
(0x1578FCB0), "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 85);
; } \
86 } while (0)
87
88#define EINA_MAGIC_CHECK_RECTANGLE_ALLOC(d)do { if (!(((d)) && (((d))->__magic == (0x1578FCB1
)))) { eina_magic_fail((void *)((d)), ((d)) ? ((d))->__magic
: 0, (0x1578FCB1), "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 88);; } } while (0)
\
89 do { \
90 if (!EINA_MAGIC_CHECK((d), EINA_RECTANGLE_ALLOC_MAGIC)(((d)) && (((d))->__magic == (0x1578FCB1)))) { \
91 EINA_MAGIC_FAIL((d), EINA_RECTANGLE_ALLOC_MAGIC)eina_magic_fail((void *)((d)), ((d)) ? ((d))->__magic : 0,
(0x1578FCB1), "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 91);
; } \
92 } while (0)
93
94static Eina_Mempool *_eina_rectangle_alloc_mp = NULL((void*)0);
95static Eina_Mempool *_eina_rectangle_mp = NULL((void*)0);
96
97static Eina_Trash *_eina_rectangles = NULL((void*)0);
98static unsigned int _eina_rectangles_count = 0;
99static int _eina_rectangle_log_dom = -1;
100
101#ifdef ERR
102#undef ERR
103#endif
104#define ERR(...)eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 104, ...)
EINA_LOG_DOM_ERR(_eina_rectangle_log_dom, __VA_ARGS__)eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 104, __VA_ARGS__)
105
106#ifdef DBG
107#undef DBG
108#endif
109#define DBG(...)eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 109, ...)
EINA_LOG_DOM_DBG(_eina_rectangle_log_dom, __VA_ARGS__)eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 109, __VA_ARGS__)
110
111static int
112_eina_rectangle_cmp(const Eina_Rectangle *r1, const Eina_Rectangle *r2)
113{
114 return (r2->w * r2->h) - (r1->w * r1->h);
115}
116
117static Eina_List *
118_eina_rectangle_merge_list(Eina_List *empty, Eina_Rectangle *r)
119{
120 Eina_Rectangle *match;
121 Eina_List *l;
122 int xw;
123 int yh;
124
125 if (r->w == 0 || r->h == 0)
126 {
127 eina_rectangle_free(r);
128 return empty;
129 }
130
131start_again:
132 xw = r->x + r->w;
133 yh = r->y + r->h;
134
135 EINA_LIST_FOREACH(empty, l, match)for (l = empty, match = eina_list_data_get(l); l; l = eina_list_next
(l), match = eina_list_data_get(l))
136 {
137 if (match->x == r->x && match->w == r->w
138 && (match->y == yh || r->y == match->y + match->h))
139 {
140 if (match->y > r->y)
141 match->y = r->y;
142
143 match->h += r->h;
144
145 eina_rectangle_free(r);
146
147 empty = eina_list_remove_list(empty, l);
148
149 r = match;
150
151 goto start_again;
152 }
153 else if (match->y == r->y && match->h == r->h
154 && (match->x == xw || r->x == match->x + match->w))
155 {
156 if (match->x > r->x)
157 match->x = r->x;
158
159 match->w += r->w;
160
161 eina_rectangle_free(r);
162
163 empty = eina_list_remove_list(empty, l);
164
165 r = match;
166
167 goto start_again;
168 }
169 }
170
171 return eina_list_append(empty, r);
172}
173
174static Eina_List *
175_eina_rectangle_empty_space_find(Eina_List *empty, int w, int h, int *x, int *y)
176{
177 Eina_Rectangle *r;
178 Eina_List *l;
179
180 EINA_LIST_FOREACH(empty, l, r)for (l = empty, r = eina_list_data_get(l); l; l = eina_list_next
(l), r = eina_list_data_get(l))
181 {
182 if (r->w >= w && r->h >= h)
183 {
184 /* Remove l from empty */
185 empty = eina_list_remove_list(empty, l);
186 /* Remember x and y */
187 *x = r->x;
188 *y = r->y;
189 /* Split r in 2 rectangle if needed (only the empty one) and insert them */
190 if (r->w == w)
191 {
192 r->y += h;
193 r->h -= h;
194 }
195 else if (r->h == h)
196 {
197 r->x += w;
198 r->w -= w;
199 }
200 else
201 {
202 int rx1, ry1, rw1, rh1;
203 int x2, y2, w2, h2;
204
205 rx1 = r->x + w;
206 ry1 = r->y;
207 rw1 = r->w - w;
208 /* h1 could be h or r->h */
209 x2 = r->x;
210 y2 = r->y + h;
211 /* w2 could be w or r->w */
212 h2 = r->h - h;
213
214 if (rw1 * r->h > h2 * r->w)
215 {
216 rh1 = r->h;
217 w2 = w;
218 }
219 else
220 {
221 rh1 = h;
222 w2 = r->w;
223 }
224
225 EINA_RECTANGLE_SET(r, rx1, ry1, rw1, rh1)(r)->x = rx1; (r)->y = ry1; (r)->w = rw1; (r)->h =
rh1;
;
226 empty = _eina_rectangle_merge_list(empty, r);
227
228 r = eina_rectangle_new(x2, y2, w2, h2);
229 }
230
231 if (r)
232 {
233 empty = _eina_rectangle_merge_list(empty, r); /* Return empty */
234
235 }
236
237 return empty;
238 }
239 }
240
241 *x = -1;
242 *y = -1;
243 return empty;
244}
245
246/**
247 * @endcond
248 */
249
250/*============================================================================*
251* Global *
252*============================================================================*/
253
254Eina_Bool
255eina_rectangle_init(void)
256{
257 const char *choice, *tmp;
258
259 _eina_rectangle_log_dom = eina_log_domain_register("eina_rectangle",
260 EINA_LOG_COLOR_DEFAULT"\033[36m");
261 if (_eina_rectangle_log_dom < 0)
262 {
263 EINA_LOG_ERR("Could not register log domain: eina_rectangle")eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 263, "Could not register log domain: eina_rectangle"
)
;
264 return EINA_FALSE((Eina_Bool)0);
265 }
266
267#ifdef EINA_DEFAULT_MEMPOOL
268 choice = "pass_through";
269#else
270 choice = "chained_mempool";
271#endif
272 tmp = getenv("EINA_MEMPOOL");
273 if (tmp && tmp[0])
274 choice = tmp;
275
276 _eina_rectangle_alloc_mp = eina_mempool_add
277 (choice, "rectangle-alloc", NULL((void*)0),
278 sizeof(Eina_Rectangle_Alloc) + sizeof(Eina_Rectangle), 1024);
279 if (!_eina_rectangle_alloc_mp)
280 {
281 ERR("Mempool for rectangle cannot be allocated in rectangle init.")eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 281, "Mempool for rectangle cannot be allocated in rectangle init."
)
;
282 goto init_error;
283 }
284
285 _eina_rectangle_mp = eina_mempool_add
286 (choice, "rectangle", NULL((void*)0), sizeof(Eina_Rectangle), 256);
287 if (!_eina_rectangle_mp)
288 {
289 ERR("Mempool for rectangle cannot be allocated in rectangle init.")eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 289, "Mempool for rectangle cannot be allocated in rectangle init."
)
;
290 goto init_error;
291 }
292
293 return EINA_TRUE((Eina_Bool)1);
294
295init_error:
296 eina_log_domain_unregister(_eina_rectangle_log_dom);
297 _eina_rectangle_log_dom = -1;
298
299 return EINA_FALSE((Eina_Bool)0);
300}
301
302Eina_Bool
303eina_rectangle_shutdown(void)
304{
305 Eina_Rectangle *del;
306
307 while ((del = eina_trash_pop(&_eina_rectangles)))
308 eina_mempool_free(_eina_rectangle_mp, del);
309 _eina_rectangles_count = 0;
310
311 eina_mempool_del(_eina_rectangle_alloc_mp);
312 eina_mempool_del(_eina_rectangle_mp);
313
314 eina_log_domain_unregister(_eina_rectangle_log_dom);
315 _eina_rectangle_log_dom = -1;
316
317 return EINA_TRUE((Eina_Bool)1);
318}
319
320/*============================================================================*
321* API *
322*============================================================================*/
323
324/**
325 * @addtogroup Eina_Rectangle_Group Rectangle
326 *
327 * @brief These functions provide rectangle management.
328 *
329 * @{
330 */
331
332/**
333 * @brief Create a new rectangle.
334 *
335 * @param x The X coordinate of the top left corner of the rectangle.
336 * @param y The Y coordinate of the top left corner of the rectangle.
337 * @param w The width of the rectangle.
338 * @param h The height of the rectangle.
339 * @return The new rectangle on success, @ NULL otherwise.
340 *
341 * This function creates a rectangle which top left corner has the
342 * coordinates (@p x, @p y), with height @p w and height @p h and adds
343 * it to the rectangles pool. No check is done on @p w and @p h. This
344 * function returns a new rectangle on success, @c NULL otherwhise.
345 */
346EAPI__attribute__ ((visibility("default"))) Eina_Rectangle *
347eina_rectangle_new(int x, int y, int w, int h)
348{
349 Eina_Rectangle *rect;
350
351 if (_eina_rectangles)
352 {
353 rect = eina_trash_pop(&_eina_rectangles);
354 _eina_rectangles_count--;
355 }
356 else
357 rect = eina_mempool_malloc(_eina_rectangle_mp, sizeof (Eina_Rectangle));
358
359 if (!rect)
360 return NULL((void*)0);
361
362 EINA_RECTANGLE_SET(rect, x, y, w, h)(rect)->x = x; (rect)->y = y; (rect)->w = w; (rect)->
h = h;
;
363
364 return rect;
365}
366
367/**
368 * @brief Free the given rectangle.
369 *
370 * @param rect The rectangle to free.
371 *
372 * This function removes @p rect from the rectangles pool.
373 */
374EAPI__attribute__ ((visibility("default"))) void
375eina_rectangle_free(Eina_Rectangle *rect)
376{
377 EINA_SAFETY_ON_NULL_RETURN(rect)do { if (__builtin_expect(((rect) == ((void*)0)), 0)) { eina_error_set
(EINA_ERROR_SAFETY_FAILED); eina_log_print(EINA_LOG_DOMAIN_GLOBAL
, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 377, "%s", "safety check failed: " "rect" " == NULL"); return
; } } while (0)
;
378
379 if (_eina_rectangles_count > BUCKET_THRESHOLD110)
380 eina_mempool_free(_eina_rectangle_mp, rect);
381 else
382 {
383 eina_trash_push(&_eina_rectangles, rect);
384 _eina_rectangles_count++;
385 }
386}
387
388/**
389 * @brief Add a rectangle in a new pool.
390 *
391 * @param w The width of the rectangle.
392 * @param h The height of the rectangle.
393 * @return A newly allocated pool on success, @c NULL otherwise.
394 *
395 * This function adds the rectangle of size (@p width, @p height) to a
396 * new pool. If the pool can not be created, @c NULL is
397 * returned. Otherwise the newly allocated pool is returned.
398 */
399EAPI__attribute__ ((visibility("default"))) Eina_Rectangle_Pool *
400eina_rectangle_pool_new(int w, int h)
401{
402 Eina_Rectangle_Pool *new;
403
404 new = malloc(sizeof (Eina_Rectangle_Pool));
405 if (!new)
406 return NULL((void*)0);
407
408 new->head = NULL((void*)0);
409 new->empty = eina_list_append(NULL((void*)0), eina_rectangle_new(0, 0, w, h));
410 new->references = 0;
411 new->sorted = EINA_FALSE((Eina_Bool)0);
412 new->w = w;
413 new->h = h;
414 new->bucket = NULL((void*)0);
415 new->bucket_count = 0;
416
417 EINA_MAGIC_SET(new, EINA_RECTANGLE_POOL_MAGIC)(new)->__magic = (0x1578FCB0);
418 DBG("pool=%p, size=(%d, %d)", new, w, h)eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 418, "pool=%p, size=(%d, %d)", new, w, h)
;
419
420 return new;
421}
422
423/**
424 * @brief Free the given pool.
425 *
426 * @param pool The pool to free.
427 *
428 * This function frees the allocated data of @p pool. If @p pool is
429 * @c NULL, ths function returned immediately.
430 */
431EAPI__attribute__ ((visibility("default"))) void
432eina_rectangle_pool_free(Eina_Rectangle_Pool *pool)
433{
434 Eina_Rectangle_Alloc *del;
435
436 EINA_SAFETY_ON_NULL_RETURN(pool)do { if (__builtin_expect(((pool) == ((void*)0)), 0)) { eina_error_set
(EINA_ERROR_SAFETY_FAILED); eina_log_print(EINA_LOG_DOMAIN_GLOBAL
, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 436, "%s", "safety check failed: " "pool" " == NULL"); return
; } } while (0)
;
437 DBG("pool=%p, size=(%d, %d), references=%u",eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 438, "pool=%p, size=(%d, %d), references=%u",
pool, pool->w, pool->h, pool->references)
438 pool, pool->w, pool->h, pool->references)eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 438, "pool=%p, size=(%d, %d), references=%u",
pool, pool->w, pool->h, pool->references)
;
439 while (pool->head)
440 {
441 del = (Eina_Rectangle_Alloc *)pool->head;
442
443 pool->head = (EINA_INLIST_GET(del)(& ((del)->__in_list)))->next;
444
445 EINA_MAGIC_SET(del, EINA_MAGIC_NONE)(del)->__magic = (0x1234fedc);
446 eina_mempool_free(_eina_rectangle_alloc_mp, del);
447 }
448
449 while (pool->bucket)
450 {
451 del = eina_trash_pop(&pool->bucket);
452 eina_mempool_free(_eina_rectangle_alloc_mp, del);
453 }
454
455 MAGIC_FREE(pool)do { if (pool) { (pool)->__magic = (0x1234fedc); do { free
(pool); pool = ((void*)0); } while(0);; } } while(0);
;
456}
457
458/**
459 * @brief Return the number of rectangles in the given pool.
460 *
461 * @param pool The pool.
462 * @return The number of rectangles in the pool.
463 *
464 * This function returns the number of rectangles in @p pool.
465 */
466EAPI__attribute__ ((visibility("default"))) int
467eina_rectangle_pool_count(Eina_Rectangle_Pool *pool)
468{
469 EINA_SAFETY_ON_NULL_RETURN_VAL(pool, 0)do { if (__builtin_expect(((pool) == ((void*)0)), 0)) { eina_error_set
(EINA_ERROR_SAFETY_FAILED); eina_log_print(EINA_LOG_DOMAIN_GLOBAL
, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 469, "%s", "safety check failed: " "pool" " == NULL"); return
(0); } } while (0)
;
470 return pool->references;
471}
472
473/**
474 * @brief Request a rectangle of given size in the given pool.
475 *
476 * @param pool The pool.
477 * @param w The width of the rectangle to request.
478 * @param h The height of the rectangle to request.
479 * @return The requested rectangle on success, @c NULL otherwise.
480 *
481 * This function retrieve from @p pool the rectangle of width @p w and
482 * height @p h. If @p pool is @c NULL, or @p w or @p h are non-positive,
483 * the function returns @c NULL. If @p w or @p h are greater than the
484 * pool size, the function returns @c NULL. On success, the function
485 * returns the rectangle which matches the size (@p w, @p h).
486 * Otherwise it returns @c NULL.
487 */
488EAPI__attribute__ ((visibility("default"))) Eina_Rectangle *
489eina_rectangle_pool_request(Eina_Rectangle_Pool *pool, int w, int h)
490{
491 Eina_Rectangle_Alloc *new;
492 Eina_Rectangle *rect;
493 int x;
494 int y;
495
496 EINA_SAFETY_ON_NULL_RETURN_VAL(pool, NULL)do { if (__builtin_expect(((pool) == ((void*)0)), 0)) { eina_error_set
(EINA_ERROR_SAFETY_FAILED); eina_log_print(EINA_LOG_DOMAIN_GLOBAL
, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 496, "%s", "safety check failed: " "pool" " == NULL"); return
(((void*)0)); } } while (0)
;
497
498 DBG("pool=%p, size=(%d, %d), references=%u",eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 499, "pool=%p, size=(%d, %d), references=%u",
pool, pool->w, pool->h, pool->references)
499 pool, pool->w, pool->h, pool->references)eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 499, "pool=%p, size=(%d, %d), references=%u",
pool, pool->w, pool->h, pool->references)
;
500
501 if (w <= 0 || h <= 0)
502 return NULL((void*)0);
503
504 if (w > pool->w || h > pool->h)
505 return NULL((void*)0);
506
507 /* Sort empty if dirty */
508 if (pool->sorted)
509 {
510 pool->empty =
511 eina_list_sort(pool->empty, 0, EINA_COMPARE_CB(_eina_rectangle_cmp)((Eina_Compare_Cb)_eina_rectangle_cmp));
512 pool->sorted = EINA_TRUE((Eina_Bool)1);
513 }
514
515 pool->empty = _eina_rectangle_empty_space_find(pool->empty, w, h, &x, &y);
516 if (x == -1)
517 return NULL((void*)0);
518
519 pool->sorted = EINA_FALSE((Eina_Bool)0);
520
521 if (pool->bucket_count > 0)
522 {
523 new = eina_trash_pop(&pool->bucket);
524 pool->bucket_count--;
525 }
526 else
527 new = eina_mempool_malloc(_eina_rectangle_alloc_mp,
528 sizeof (Eina_Rectangle_Alloc) +
529 sizeof (Eina_Rectangle));
530
531 if (!new)
532 return NULL((void*)0);
533
534 rect = (Eina_Rectangle *)(new + 1);
535 eina_rectangle_coords_from(rect, x, y, w, h);
536
537 pool->head = eina_inlist_prepend(pool->head, EINA_INLIST_GET(new)(& ((new)->__in_list)));
538 pool->references++;
539
540 new->pool = pool;
541
542 EINA_MAGIC_SET(new, EINA_RECTANGLE_ALLOC_MAGIC)(new)->__magic = (0x1578FCB1);
543 DBG("rect=%p pool=%p, size=(%d, %d), references=%u",eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 544, "rect=%p pool=%p, size=(%d, %d), references=%u"
, rect, pool, pool->w, pool->h, pool->references)
544 rect, pool, pool->w, pool->h, pool->references)eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 544, "rect=%p pool=%p, size=(%d, %d), references=%u"
, rect, pool, pool->w, pool->h, pool->references)
;
545
546 return rect;
547}
548
549/**
550 * @brief Remove the given rectangle from the pool.
551 *
552 * @param rect The rectangle to remove from the pool.
553 *
554 * This function removes @p rect from the pool. If @p rect is
555 * @c NULL, the function returns immediately. Otherwise it remoes @p
556 * rect from the pool.
557 */
558EAPI__attribute__ ((visibility("default"))) void
559eina_rectangle_pool_release(Eina_Rectangle *rect)
560{
561 Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *)rect) - 1;
562 Eina_Rectangle *r;
563
564 EINA_SAFETY_ON_NULL_RETURN(rect)do { if (__builtin_expect(((rect) == ((void*)0)), 0)) { eina_error_set
(EINA_ERROR_SAFETY_FAILED); eina_log_print(EINA_LOG_DOMAIN_GLOBAL
, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 564, "%s", "safety check failed: " "rect" " == NULL"); return
; } } while (0)
;
565
566 EINA_MAGIC_CHECK_RECTANGLE_ALLOC(era)do { if (!(((era)) && (((era))->__magic == (0x1578FCB1
)))) { eina_magic_fail((void *)((era)), ((era)) ? ((era))->
__magic : 0, (0x1578FCB1), "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 566);; } } while (0)
;
567 EINA_MAGIC_CHECK_RECTANGLE_POOL(era->pool)do { if (!(((era->pool)) && (((era->pool))->
__magic == (0x1578FCB0)))) { eina_magic_fail((void *)((era->
pool)), ((era->pool)) ? ((era->pool))->__magic : 0, (
0x1578FCB0), "ecore/src/lib/eina_rectangle.c", __FUNCTION__, 567
);; } } while (0)
;
1
Within the expansion of the macro 'EINA_MAGIC_CHECK_RECTANGLE_POOL':
a
Assuming pointer value is null
568
569 DBG("rect=%p pool=%p, size=(%d, %d), references=%u",eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 570, "rect=%p pool=%p, size=(%d, %d), references=%u"
, rect, era->pool, era->pool->w, era->pool->h,
era->pool->references)
2
Within the expansion of the macro 'DBG':
a
Dereference of null pointer
570 rect, era->pool, era->pool->w, era->pool->h, era->pool->references)eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 570, "rect=%p pool=%p, size=(%d, %d), references=%u"
, rect, era->pool, era->pool->w, era->pool->h,
era->pool->references)
;
571
572 era->pool->references--;
573 era->pool->head = eina_inlist_remove(era->pool->head, EINA_INLIST_GET(era)(& ((era)->__in_list)));
574
575 r = eina_rectangle_new(rect->x, rect->y, rect->w, rect->h);
576 if (r)
577 {
578 era->pool->empty = _eina_rectangle_merge_list(era->pool->empty, r);
579 era->pool->sorted = EINA_FALSE((Eina_Bool)0);
580 }
581
582 if (era->pool->bucket_count < BUCKET_THRESHOLD110)
583 {
584 Eina_Rectangle_Pool *pool;
585
586 pool = era->pool;
587
588 pool->bucket_count++;
589 eina_trash_push(&pool->bucket, era);
590 }
591 else
592 {
593 EINA_MAGIC_SET(era, EINA_MAGIC_NONE)(era)->__magic = (0x1234fedc);
594 eina_mempool_free(_eina_rectangle_alloc_mp, era);
595 }
596}
597
598/**
599 * @brief Return the pool of the given rectangle.
600 *
601 * @param rect The rectangle.
602 * @return The pool of the given rectangle.
603 *
604 * This function returns the pool in which @p rect is. If @p rect is
605 * @c NULL, @c NULL is returned.
606 */
607EAPI__attribute__ ((visibility("default"))) Eina_Rectangle_Pool *
608eina_rectangle_pool_get(Eina_Rectangle *rect)
609{
610 Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *)rect) - 1;
611
612 EINA_SAFETY_ON_NULL_RETURN_VAL(rect, NULL)do { if (__builtin_expect(((rect) == ((void*)0)), 0)) { eina_error_set
(EINA_ERROR_SAFETY_FAILED); eina_log_print(EINA_LOG_DOMAIN_GLOBAL
, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 612, "%s", "safety check failed: " "rect" " == NULL"); return
(((void*)0)); } } while (0)
;
613
614 EINA_MAGIC_CHECK_RECTANGLE_ALLOC(era)do { if (!(((era)) && (((era))->__magic == (0x1578FCB1
)))) { eina_magic_fail((void *)((era)), ((era)) ? ((era))->
__magic : 0, (0x1578FCB1), "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 614);; } } while (0)
;
615 EINA_MAGIC_CHECK_RECTANGLE_POOL(era->pool)do { if (!(((era->pool)) && (((era->pool))->
__magic == (0x1578FCB0)))) { eina_magic_fail((void *)((era->
pool)), ((era->pool)) ? ((era->pool))->__magic : 0, (
0x1578FCB0), "ecore/src/lib/eina_rectangle.c", __FUNCTION__, 615
);; } } while (0)
;
616
617 return era->pool;
618}
619
620/**
621 * @brief Set the data to the given pool.
622 *
623 * @param pool The pool.
624 * @param data The data to set.
625 *
626 * This function sets @p data to @p pool. If @p pool is @c NULL, this
627 * function does nothing.
628 */
629EAPI__attribute__ ((visibility("default"))) void
630eina_rectangle_pool_data_set(Eina_Rectangle_Pool *pool, const void *data)
631{
632 EINA_MAGIC_CHECK_RECTANGLE_POOL(pool)do { if (!(((pool)) && (((pool))->__magic == (0x1578FCB0
)))) { eina_magic_fail((void *)((pool)), ((pool)) ? ((pool))->
__magic : 0, (0x1578FCB0), "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 632);; } } while (0)
;
633 EINA_SAFETY_ON_NULL_RETURN(pool)do { if (__builtin_expect(((pool) == ((void*)0)), 0)) { eina_error_set
(EINA_ERROR_SAFETY_FAILED); eina_log_print(EINA_LOG_DOMAIN_GLOBAL
, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 633, "%s", "safety check failed: " "pool" " == NULL"); return
; } } while (0)
;
634
635 DBG("data=%p pool=%p, size=(%d, %d), references=%u",eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 636, "data=%p pool=%p, size=(%d, %d), references=%u"
, data, pool, pool->w, pool->h, pool->references)
636 data, pool, pool->w, pool->h, pool->references)eina_log_print(_eina_rectangle_log_dom, EINA_LOG_LEVEL_DBG, "ecore/src/lib/eina_rectangle.c"
, __FUNCTION__, 636, "data=%p pool=%p, size=(%d, %d), references=%u"
, data, pool, pool->w, pool->h, pool->references)
;
637
638 pool->data = (void *)data;
639}
640
641/**
642 * @brief Get the data from the given pool.
643 *
644 * @param pool The pool.
645 * @return The returned data.
646 *
647 * This function gets the data from @p pool set by
648 * eina_rectangle_pool_data_set(). If @p pool is @c NULL, this
649 * function returns @c NULL.
650 */
651EAPI__attribute__ ((visibility("default"))) void *
652eina_rectangle_pool_data_get(Eina_Rectangle_Pool *pool)
653{
654 EINA_MAGIC_CHECK_RECTANGLE_POOL(pool)do { if (!(((pool)) && (((pool))->__magic == (0x1578FCB0
)))) { eina_magic_fail((void *)((pool)), ((pool)) ? ((pool))->
__magic : 0, (0x1578FCB0), "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 654);; } } while (0)
;
655 EINA_SAFETY_ON_NULL_RETURN_VAL(pool, NULL)do { if (__builtin_expect(((pool) == ((void*)0)), 0)) { eina_error_set
(EINA_ERROR_SAFETY_FAILED); eina_log_print(EINA_LOG_DOMAIN_GLOBAL
, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 655, "%s", "safety check failed: " "pool" " == NULL"); return
(((void*)0)); } } while (0)
;
656
657 return pool->data;
658}
659
660/**
661 * @brief Return the width and height of the given pool.
662 *
663 * @param pool The pool.
664 * @param w The returned width.
665 * @param h The returned height.
666 * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
667 *
668 * This function returns the width and height of @p pool and store
669 * them in respectively @p w and @p h if they are not @c NULL. If
670 * @p pool is @c NULL, #EINA_FALSE is returned. Otherwise #EINA_TRUE is
671 * returned.
672 */
673EAPI__attribute__ ((visibility("default"))) Eina_Bool
674eina_rectangle_pool_geometry_get(Eina_Rectangle_Pool *pool, int *w, int *h)
675{
676 if (!pool)
677 return EINA_FALSE((Eina_Bool)0);
678
679 EINA_MAGIC_CHECK_RECTANGLE_POOL(pool)do { if (!(((pool)) && (((pool))->__magic == (0x1578FCB0
)))) { eina_magic_fail((void *)((pool)), ((pool)) ? ((pool))->
__magic : 0, (0x1578FCB0), "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 679);; } } while (0)
;
680 EINA_SAFETY_ON_NULL_RETURN_VAL(pool, EINA_FALSE)do { if (__builtin_expect(((pool) == ((void*)0)), 0)) { eina_error_set
(EINA_ERROR_SAFETY_FAILED); eina_log_print(EINA_LOG_DOMAIN_GLOBAL
, EINA_LOG_LEVEL_ERR, "ecore/src/lib/eina_rectangle.c", __FUNCTION__
, 680, "%s", "safety check failed: " "pool" " == NULL"); return
(((Eina_Bool)0)); } } while (0)
;
681
682 if (w)
683 *w = pool->w;
684
685 if (h)
686 *h = pool->h;
687
688 return EINA_TRUE((Eina_Bool)1);
689}
690
691/**
692 * @}
693 */