forked from enlightenment/efl
Fix and improvement for stringshare and array, thanks to the tests suite.
SVN revision: 35288
This commit is contained in:
parent
254ce073a8
commit
67d2b46784
|
@ -1,6 +1,8 @@
|
|||
#ifndef EINA_ARRAY_H_
|
||||
#define EINA_ARRAY_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "eina_types.h"
|
||||
|
||||
typedef struct _Eina_Array Eina_Array; /**< A generic vector */
|
||||
|
@ -21,4 +23,8 @@ EAPI void eina_array_clean (Eina_Array *array);
|
|||
EAPI void eina_array_flush (Eina_Array *array);
|
||||
EAPI void eina_array_remove (Eina_Array *array, Eina_Bool (*keep)(void *data, void *gdata), void *gdata);
|
||||
|
||||
#define EINA_ARRAY_ITER_NEXT(array, index, item) for ((index) = 0, (item) = _eina_array_get((array), (index)); (index) < (array)->count; ++(index), (item) = _eina_array_get((array), (index)))
|
||||
|
||||
#include "eina_inline_array.x"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,15 +11,15 @@ static inline Eina_Bool
|
|||
_eina_array_grow(Eina_Array *array)
|
||||
{
|
||||
void **tmp;
|
||||
size_t total;
|
||||
|
||||
unsigned int total;
|
||||
|
||||
total = array->total + array->step;
|
||||
tmp = realloc(array->data, sizeof (void*) * total);
|
||||
if (!tmp) return 0;
|
||||
|
||||
if (UNLIKELY(!tmp)) return 0;
|
||||
|
||||
array->total = total;
|
||||
array->data = tmp;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ _eina_array_append(Eina_Array *array, void *data)
|
|||
{
|
||||
if (UNLIKELY((array->count + array->step) > array->total))
|
||||
if (!_eina_array_grow(array)) return ;
|
||||
|
||||
|
||||
array->data[array->count++] = data;
|
||||
}
|
||||
|
||||
|
@ -38,4 +38,10 @@ _eina_array_get(Eina_Array *array, unsigned int index)
|
|||
return array->data[index];
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
eina_array_count(Eina_Array *array)
|
||||
{
|
||||
return array->count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "eina_array.h"
|
||||
#include "eina_inline_array.x"
|
||||
|
@ -68,19 +70,58 @@ eina_array_free(Eina_Array *array)
|
|||
free(array);
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
EAPI void
|
||||
eina_array_remove(Eina_Array *array, Eina_Bool (*keep)(void *data, void *gdata), void *gdata)
|
||||
{
|
||||
void **tmp;
|
||||
unsigned int total = 0;
|
||||
unsigned int limit;
|
||||
unsigned int i;
|
||||
|
||||
if (array->total == 0) return ;
|
||||
|
||||
for (i = 0; i < array->count; ++i)
|
||||
{
|
||||
void *data;
|
||||
|
||||
data = _eina_array_get(array, i);
|
||||
|
||||
if (keep(data, gdata) == EINA_FALSE)
|
||||
break;
|
||||
}
|
||||
limit = i;
|
||||
for (; i < array->count; ++i)
|
||||
{
|
||||
void *data;
|
||||
|
||||
data = _eina_array_get(array, i);
|
||||
|
||||
if (keep(data, gdata) == EINA_TRUE)
|
||||
break;
|
||||
}
|
||||
/* Special case all objects that need to stay are at the beginning of the array. */
|
||||
if (i == array->count)
|
||||
{
|
||||
array->count = limit;
|
||||
if (array->count == 0)
|
||||
{
|
||||
free(array->data);
|
||||
array->total = 0;
|
||||
array->data = NULL;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
tmp = malloc(sizeof (void*) * array->total);
|
||||
if (!tmp) return ;
|
||||
|
||||
for (i = 0; i < array->count; i++)
|
||||
memcpy(tmp, array->data, limit * sizeof(void*));
|
||||
total = limit;
|
||||
|
||||
for (; i < array->count; ++i)
|
||||
{
|
||||
void *data;
|
||||
|
||||
|
@ -95,16 +136,10 @@ eina_array_remove(Eina_Array *array, Eina_Bool (*keep)(void *data, void *gdata),
|
|||
|
||||
free(array->data);
|
||||
|
||||
if (total == 0)
|
||||
{
|
||||
array->total = 0;
|
||||
array->data = NULL;
|
||||
free(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
array->data = tmp;
|
||||
}
|
||||
/* If we do not keep any object in the array, we should have exited
|
||||
earlier in test (i == array->count). */
|
||||
assert(total != 0);
|
||||
|
||||
array->data = tmp;
|
||||
array->count = total;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "eina_stringshare.h"
|
||||
#include "eina_error.h"
|
||||
|
||||
typedef struct _Eina_Stringshare Eina_Stringshare;
|
||||
typedef struct _Eina_Stringshare_Node Eina_Stringshare_Node;
|
||||
|
@ -69,7 +70,7 @@ _eina_stringshare_hash_gen(const char *str, int *len)
|
|||
* Initialize the eina stringshare internal structure.
|
||||
* @return Zero on failure, non-zero on successful initialization.
|
||||
*/
|
||||
EAPI int
|
||||
EAPI int
|
||||
eina_stringshare_init()
|
||||
{
|
||||
/*
|
||||
|
@ -82,7 +83,6 @@ eina_stringshare_init()
|
|||
if (!share)
|
||||
return 0;
|
||||
}
|
||||
|
||||
eina_stringshare_init_count++;
|
||||
|
||||
return 1;
|
||||
|
@ -169,14 +169,14 @@ eina_stringshare_del(const char *str)
|
|||
return;
|
||||
}
|
||||
}
|
||||
printf("EEEK trying to del non-shared stringshare \"%s\"\n", str);
|
||||
abort();
|
||||
EINA_ERROR_PWARN("EEEK trying to del non-shared stringshare \"%s\"\n", str);
|
||||
if (getenv("EINA_ERROR_ABORT")) abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the eina string internal structures
|
||||
*/
|
||||
EAPI void
|
||||
EAPI void
|
||||
eina_stringshare_shutdown()
|
||||
{
|
||||
--eina_stringshare_init_count;
|
||||
|
|
Loading…
Reference in New Issue