*/
EAPI extern Eina_Error EINA_ERROR_OUT_OF_MEMORY;
-EAPI Eina_Error eina_error_msg_register(const char *msg) EINA_ARG_NONNULL(1);
+EAPI Eina_Error eina_error_msg_register(const char *msg) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+EAPI Eina_Error eina_error_msg_static_register(const char *msg) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
EAPI Eina_Error eina_error_get(void);
EAPI void eina_error_set(Eina_Error err);
EAPI const char * eina_error_msg_get(Eina_Error error) EINA_PURE;
*/
EAPI const char* eina_magic_string_get(Eina_Magic magic) EINA_PURE EINA_WARN_UNUSED_RESULT;
EAPI Eina_Bool eina_magic_string_set(Eina_Magic magic, const char *magic_name) EINA_ARG_NONNULL(2);
+EAPI Eina_Bool eina_magic_string_static_set(Eina_Magic magic, const char *magic_name) EINA_ARG_NONNULL(2);
/**
* @def EINA_MAGIC_NONE
* @cond LOCAL
*/
+static const char EINA_MAGIC_ACCESSOR_STR[] = "Eina Accessor";
+
#define EINA_MAGIC_CHECK_ACCESSOR(d) \
do { \
if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ACCESSOR)) \
Eina_Bool
eina_accessor_init(void)
{
- return eina_magic_string_set(EINA_MAGIC_ACCESSOR, "Eina Accessor");
+ return eina_magic_string_set(EINA_MAGIC_ACCESSOR, EINA_MAGIC_ACCESSOR_STR);
}
/**
* @cond LOCAL
*/
+static const char EINA_MAGIC_ARRAY_STR[] = "Eina Array";
+static const char EINA_MAGIC_ARRAY_ITERATOR_STR[] = "Eina Array Iterator";
+static const char EINA_MAGIC_ARRAY_ACCESSOR_STR[] = "Eina Array Accessor";
+
#define EINA_MAGIC_CHECK_ARRAY(d) \
do { \
if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ARRAY)) \
return EINA_FALSE;
}
- eina_magic_string_set(EINA_MAGIC_ARRAY, "Eina Array");
- eina_magic_string_set(EINA_MAGIC_ARRAY_ITERATOR, "Eina Array Iterator");
- eina_magic_string_set(EINA_MAGIC_ARRAY_ACCESSOR, "Eina Array Accessor");
+#define EMS(n) eina_magic_string_static_set(n, n##_STR)
+ EMS(EINA_MAGIC_ARRAY);
+ EMS(EINA_MAGIC_ARRAY_ITERATOR);
+ EMS(EINA_MAGIC_ARRAY_ACCESSOR);
+#undef EMS
return EINA_TRUE;
}
EAPI Eina_Error EINA_ERROR_CONVERT_0X_NOT_FOUND = 0;
EAPI Eina_Error EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH = 0;
+static const char EINA_ERROR_CONVERT_0X_NOT_FOUND_STR[] = "Error during string convertion to float, First '0x' was not found.";
+static const char EINA_ERROR_CONVERT_P_NOT_FOUND_STR[] = "Error during string convertion to float, First 'p' was not found.";
+static const char EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH_STR[] = "Error outrun string limit during convertion string convertion to float.";
+
/**
* @endcond
*/
return EINA_FALSE;
}
- EINA_ERROR_CONVERT_0X_NOT_FOUND = eina_error_msg_register("Error during string convertion to float, First '0x' was not found.");
- EINA_ERROR_CONVERT_P_NOT_FOUND = eina_error_msg_register("Error during string convertion to float, First 'p' was not found.");
- EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH = eina_error_msg_register("Error outrun string limit during convertion string convertion to float.");
+#define EEMR(n) n = eina_error_msg_static_register(n##_STR)
+ EEMR(EINA_ERROR_CONVERT_0X_NOT_FOUND);
+ EEMR(EINA_ERROR_CONVERT_P_NOT_FOUND);
+ EEMR(EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH);
+#undef EEMR
return EINA_TRUE;
}
# endif
}
#else
+static const char EINA_ERROR_COUNTER_WINDOWS_STR[] = "Change your OS, you moron !";
static int EINA_ERROR_COUNTER_WINDOWS = 0;
static LARGE_INTEGER _eina_counter_frequency;
eina_counter_init(void)
{
#ifdef _WIN32
- EINA_ERROR_COUNTER_WINDOWS = eina_error_msg_register("Change your OS, you moron !");
+ EINA_ERROR_COUNTER_WINDOWS = eina_error_msg_static_register(EINA_ERROR_COUNTER_WINDOWS_STR);
if (!QueryPerformanceFrequency(&_eina_counter_frequency))
{
eina_error_set(EINA_ERROR_COUNTER_WINDOWS);
* @cond LOCAL
*/
-static const char **_eina_errors = NULL;
+typedef struct _Eina_Error_Message Eina_Error_Message;
+struct _Eina_Error_Message
+{
+ Eina_Bool string_allocated;
+ const char *string;
+};
+
+static Eina_Error_Message *_eina_errors = NULL;
static size_t _eina_errors_count = 0;
static size_t _eina_errors_allocated = 0;
static Eina_Error _eina_last_error;
+static Eina_Error_Message *
+_eina_error_msg_alloc(void)
+{
+ size_t idx;
+
+ if (_eina_errors_count == _eina_errors_allocated)
+ {
+ void *tmp;
+ size_t size;
+
+ if (EINA_UNLIKELY(_eina_errors_allocated == 0))
+ size = 24;
+ else
+ size = _eina_errors_allocated + 8;
+
+ tmp = realloc(_eina_errors, sizeof(Eina_Error_Message) * size);
+ if (!tmp)
+ return NULL;
+ _eina_errors = tmp;
+ _eina_errors_allocated = size;
+ }
+
+ idx = _eina_errors_count;
+ _eina_errors_count++;
+ return _eina_errors + idx;
+}
+
/**
* @endcond
*/
EAPI Eina_Error EINA_ERROR_OUT_OF_MEMORY = 0;
+static const char EINA_ERROR_OUT_OF_MEMORY_STR[] = "Out of memory";
+
/**
* @endcond
*/
eina_error_init(void)
{
/* TODO register the eina's basic errors */
- EINA_ERROR_OUT_OF_MEMORY = eina_error_msg_register("Out of memory");
+ EINA_ERROR_OUT_OF_MEMORY = eina_error_msg_static_register(EINA_ERROR_OUT_OF_MEMORY_STR);
return EINA_TRUE;
}
Eina_Bool
eina_error_shutdown(void)
{
- size_t i;
+ Eina_Error_Message *eem, *eem_end;
+
+ eem = _eina_errors;
+ eem_end = eem + _eina_errors_count;
- for (i = 0; i < _eina_errors_count; i++)
- free((char *)_eina_errors[i]);
+ for (; eem < eem_end; eem++)
+ if (eem->string_allocated)
+ free((char *)eem->string);
free(_eina_errors);
_eina_errors = NULL;
/**
* @brief Register a new error type.
*
- * @param msg The description of the error.
+ * @param msg The description of the error. It will be duplicated using
+ * strdup().
* @return The unique number identifier for this error.
*
* This function stores in a list the error message described by
* @p msg. The returned value is a unique identifier greater or equal
* than 1. The description can be retrieve later by passing to
* eina_error_msg_get() the returned value.
+ *
+ * @see eina_error_msg_static_register()
*/
EAPI Eina_Error
eina_error_msg_register(const char *msg)
{
+ Eina_Error_Message *eem;
+
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0);
- if (_eina_errors_count == _eina_errors_allocated)
+ eem = _eina_error_msg_alloc();
+ if (!eem)
+ return 0;
+
+ eem->string_allocated = EINA_TRUE;
+ eem->string = strdup(msg);
+ if (!eem->string)
{
- void *tmp;
- size_t size;
+ _eina_errors_count--;
+ return 0;
+ }
- if (EINA_UNLIKELY(_eina_errors_allocated == 0))
- size = 24;
- else
- size = _eina_errors_allocated + 8;
+ return _eina_errors_count; /* identifier = index + 1 (== _count). */
+}
- tmp = realloc(_eina_errors, sizeof(char *) * size);
- if (!tmp)
- return 0;
- _eina_errors = tmp;
- _eina_errors_allocated = size;
- }
+/**
+ * @brief Register a new error type, statically allocated message.
+ *
+ * @param msg The description of the error. This string will not be
+ * duplicated and thus the given pointer should live during
+ * usage of eina_error.
+ * @return The unique number identifier for this error.
+ *
+ * This function stores in a list the error message described by
+ * @p msg. The returned value is a unique identifier greater or equal
+ * than 1. The description can be retrieve later by passing to
+ * eina_error_msg_get() the returned value.
+ *
+ * @see eina_error_msg_register()
+ */
+EAPI Eina_Error
+eina_error_msg_static_register(const char *msg)
+{
+ Eina_Error_Message *eem;
- _eina_errors[_eina_errors_count] = strdup(msg);
- if (!_eina_errors[_eina_errors_count])
+ EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0);
+
+ eem = _eina_error_msg_alloc();
+ if (!eem)
return 0;
- return ++_eina_errors_count; /* identifier = index + 1 */
+
+ eem->string_allocated = EINA_FALSE;
+ eem->string = msg;
+ return _eina_errors_count; /* identifier = index + 1 (== _count). */
}
/**
return NULL;
if ((size_t)error > _eina_errors_count)
return NULL;
- return _eina_errors[error - 1];
+ return _eina_errors[error - 1].string;
}
/**
* @cond LOCAL
*/
+static const char EINA_MAGIC_ITERATOR_STR[] = "Eina Iterator";
+
#define EINA_MAGIC_CHECK_ITERATOR(d) \
do { \
if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ITERATOR)) \
Eina_Bool
eina_iterator_init(void)
{
- return eina_magic_string_set(EINA_MAGIC_ITERATOR, "Eina Iterator");
+ return eina_magic_string_set(EINA_MAGIC_ITERATOR, EINA_MAGIC_ITERATOR_STR);
}
/**
* @cond LOCAL
*/
+static const char EINA_MAGIC_LIST_STR[] = "Eina List";
+static const char EINA_MAGIC_LIST_ITERATOR_STR[] = "Eina List Iterator";
+static const char EINA_MAGIC_LIST_ACCESSOR_STR[] = "Eina List Accessor";
+static const char EINA_MAGIC_LIST_ACCOUNTING_STR[] = "Eina List Accounting";
+
+
#define EINA_MAGIC_CHECK_LIST(d, ...) \
do { \
if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_LIST)) \
goto on_init_fail;
}
- eina_magic_string_set(EINA_MAGIC_LIST, "Eina List");
- eina_magic_string_set(EINA_MAGIC_LIST_ITERATOR, "Eina List Iterator");
- eina_magic_string_set(EINA_MAGIC_LIST_ACCESSOR, "Eina List Accessor");
- eina_magic_string_set(EINA_MAGIC_LIST_ACCOUNTING, "Eina List Accounting");
+#define EMS(n) eina_magic_string_static_set(n, n##_STR)
+ EMS(EINA_MAGIC_LIST);
+ EMS(EINA_MAGIC_LIST_ITERATOR);
+ EMS(EINA_MAGIC_LIST_ACCESSOR);
+ EMS(EINA_MAGIC_LIST_ACCOUNTING);
+#undef EMS
return EINA_TRUE;
struct _Eina_Magic_String
{
Eina_Magic magic;
- char *string;
+ Eina_Bool string_allocated;
+ const char *string;
};
static int _eina_magic_string_log_dom = -1;
return a - b->magic;
}
+static Eina_Magic_String *
+_eina_magic_strings_alloc(void)
+{
+ size_t idx;
+
+ if (_eina_magic_strings_count == _eina_magic_strings_allocated)
+ {
+ void *tmp;
+ size_t size;
+
+ if (EINA_UNLIKELY(_eina_magic_strings_allocated == 0))
+ size = 48;
+ else
+ size = _eina_magic_strings_allocated + 16;
+
+ tmp = realloc(_eina_magic_strings, sizeof(Eina_Magic_String) * size);
+ if (!tmp)
+ {
+ ERR("could not realloc magic_strings from %zu to %zu buckets.",
+ _eina_magic_strings_allocated, size);
+ return NULL;
+ }
+ _eina_magic_strings = tmp;
+ _eina_magic_strings_allocated = size;
+ }
+
+ idx = _eina_magic_strings_count;
+ _eina_magic_strings_count++;
+ return _eina_magic_strings + idx;
+}
+
/**
* @endcond
*/
Eina_Bool
eina_magic_string_shutdown(void)
{
- size_t i;
+ Eina_Magic_String *ems, *ems_end;
- for (i = 0; i < _eina_magic_strings_count; i++)
- free(_eina_magic_strings[i].string);
+ ems = _eina_magic_strings;
+ ems_end = ems + _eina_magic_strings_count;
+
+ for (; ems < ems_end; ems++)
+ if (ems->string_allocated)
+ free((char *)ems->string);
free(_eina_magic_strings);
_eina_magic_strings = NULL;
* This function sets the string @p magic_name to @p magic. It is not
* checked if number or string are already set, then you might end
* with duplicates in that case.
+ *
+ * @see eina_magic_string_static_set()
*/
EAPI Eina_Bool
eina_magic_string_set(Eina_Magic magic, const char *magic_name)
EINA_SAFETY_ON_NULL_RETURN_VAL(magic_name, EINA_FALSE);
- if (_eina_magic_strings_count == _eina_magic_strings_allocated)
- {
- void *tmp;
- size_t size;
-
- if (EINA_UNLIKELY(_eina_magic_strings_allocated == 0))
- size = 48;
- else
- size = _eina_magic_strings_allocated + 16;
-
- tmp = realloc(_eina_magic_strings, sizeof(Eina_Magic_String) * size);
- if (!tmp)
- {
- ERR("could not realloc magic_strings from %zu to %zu buckets.",
- _eina_magic_strings_allocated, size);
- return EINA_FALSE;
- }
- _eina_magic_strings = tmp;
- _eina_magic_strings_allocated = size;
- }
+ ems = _eina_magic_strings_alloc();
+ if (!ems)
+ return EINA_FALSE;
- ems = _eina_magic_strings + _eina_magic_strings_count;
ems->magic = magic;
+ ems->string_allocated = EINA_TRUE;
ems->string = strdup(magic_name);
if (!ems->string)
{
ERR("could not allocate string '%s'", magic_name);
+ _eina_magic_strings_count--;
return EINA_FALSE;
}
- _eina_magic_strings_count++;
+ _eina_magic_strings_dirty = 1;
+ return EINA_TRUE;
+}
+
+/**
+ * @brief Set the string associated to the given magic identifier.
+ *
+ * @param magic The magic identifier.
+ * @param The string associated to the identifier, must not be @c NULL,
+ * it will not be duplcated, just referenced thus it must be live
+ * during magic number usage.
+ *
+ * @return #EINA_TRUE on success, #EINA_FALSE on failure.
+ *
+ * This function sets the string @p magic_name to @p magic. It is not
+ * checked if number or string are already set, then you might end
+ * with duplicates in that case.
+ *
+ * @see eina_magic_string_set()
+ */
+EAPI Eina_Bool
+eina_magic_string_static_set(Eina_Magic magic, const char *magic_name)
+{
+ Eina_Magic_String *ems;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(magic_name, EINA_FALSE);
+
+ ems = _eina_magic_strings_alloc();
+ if (!ems)
+ return EINA_FALSE;
+
+ ems->magic = magic;
+ ems->string_allocated = EINA_FALSE;
+ ems->string = magic_name;
+
_eina_magic_strings_dirty = 1;
return EINA_TRUE;
}
/**
* @cond LOCAL
*/
+
+static const char EINA_MAGIC_MATRIXSPARSE_STR[] = "Eina Matrixsparse";
+static const char EINA_MAGIC_MATRIXSPARSE_ROW_STR[] = "Eina Matrixsparse Row";
+static const char EINA_MAGIC_MATRIXSPARSE_CELL_STR[] = "Eina Matrixsparse Cell";
+static const char EINA_MAGIC_MATRIXSPARSE_ITERATOR_STR[] = "Eina Matrixsparse Iterator";
+static const char EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR_STR[] = "Eina Matrixsparse Row Accessor";
+static const char EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR_STR[] = "Eina Matrixsparse Row Iterator";
+static const char EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR_STR[] = "Eina Matrixsparse Cell Accessor";
+static const char EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR_STR[] = "Eina Matrixsparse Cell Iterator";
+
+
#define EINA_MAGIC_CHECK_MATRIXSPARSE(d, ...) \
do { \
if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE)) \
goto on_init_fail;
}
- eina_magic_string_set(EINA_MAGIC_MATRIXSPARSE, "Eina Matrixsparse");
- eina_magic_string_set(EINA_MAGIC_MATRIXSPARSE_ROW, "Eina Matrixsparse Row");
- eina_magic_string_set(EINA_MAGIC_MATRIXSPARSE_CELL, "Eina Matrixsparse Cell");
- eina_magic_string_set(EINA_MAGIC_MATRIXSPARSE_ITERATOR, "Eina Matrixsparse Iterator");
- eina_magic_string_set(EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR, "Eina Matrixsparse Row Accessor");
- eina_magic_string_set(EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR, "Eina Matrixsparse Row Iterator");
- eina_magic_string_set(EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR, "Eina Matrixsparse Cell Accessor");
- eina_magic_string_set(EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR, "Eina Matrixsparse Cell Iterator");
+#define EMS(n) eina_magic_string_static_set(n, n##_STR)
+ EMS(EINA_MAGIC_MATRIXSPARSE);
+ EMS(EINA_MAGIC_MATRIXSPARSE_ROW);
+ EMS(EINA_MAGIC_MATRIXSPARSE_CELL);
+ EMS(EINA_MAGIC_MATRIXSPARSE_ITERATOR);
+ EMS(EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR);
+ EMS(EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR);
+ EMS(EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR);
+ EMS(EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR);
+#undef EMS
return EINA_TRUE;
EAPI Eina_Error EINA_ERROR_NOT_MEMPOOL_MODULE = 0;
+static const char EINA_ERROR_NOT_MEMPOOL_MODULE_STR[] = "Not a memory pool module.";
+
Eina_Bool
eina_mempool_init(void)
{
return 0;
}
- EINA_ERROR_NOT_MEMPOOL_MODULE = eina_error_msg_register("Not a memory pool module.");
+ EINA_ERROR_NOT_MEMPOOL_MODULE = eina_error_msg_static_register(EINA_ERROR_NOT_MEMPOOL_MODULE_STR);
_backends = eina_hash_string_superfast_new(NULL);
/* dynamic backends */
* @cond LOCAL
*/
+static const char EINA_ERROR_WRONG_MODULE_STR[] = "Wrong file format or no file module found";
+static const char EINA_ERROR_MODULE_INIT_FAILED_STR[] = "Module initialisation function failed";
+
EAPI Eina_Error EINA_ERROR_WRONG_MODULE = 0;
EAPI Eina_Error EINA_ERROR_MODULE_INIT_FAILED = 0;
return EINA_FALSE;
}
- EINA_ERROR_WRONG_MODULE = eina_error_msg_register("Wrong file format or no file module found");
- EINA_ERROR_MODULE_INIT_FAILED = eina_error_msg_register("Module initialisation function failed");
+#define EEMR(n) n = eina_error_msg_static_register(n##_STR)
+ EEMR(EINA_ERROR_WRONG_MODULE);
+ EEMR(EINA_ERROR_MODULE_INIT_FAILED);
+#undef EEMR
return EINA_TRUE;
}
EAPI Eina_Error EINA_ERROR_SAFETY_FAILED = 0;
+static const char EINA_ERROR_SAFETY_FAILED_STR[] = "Safety check failed.";
+
/**
* @endcond
*/
Eina_Bool
eina_safety_checks_init(void)
{
- EINA_ERROR_SAFETY_FAILED = eina_error_msg_register("Safety check failed.");
+ EINA_ERROR_SAFETY_FAILED = eina_error_msg_static_register(EINA_ERROR_SAFETY_FAILED_STR);
return EINA_TRUE;
}
#define EINA_STRINGSHARE_BUCKETS 256
#define EINA_STRINGSHARE_MASK 0xFF
+static const char EINA_MAGIC_STRINGSHARE_STR[] = "Eina Stringshare";
+static const char EINA_MAGIC_STRINGSHARE_HEAD_STR[] = "Eina Stringshare Head";
+static const char EINA_MAGIC_STRINGSHARE_NODE_STR[] = "Eina Stringshare Node";
+
+
#define EINA_MAGIC_CHECK_STRINGSHARE_HEAD(d, ...) \
do { \
if (!EINA_MAGIC_CHECK((d), EINA_MAGIC_STRINGSHARE_HEAD)) \
return EINA_FALSE;
}
- eina_magic_string_set(EINA_MAGIC_STRINGSHARE, "Eina Stringshare");
- eina_magic_string_set(EINA_MAGIC_STRINGSHARE_HEAD, "Eina Stringshare Head");
- eina_magic_string_set(EINA_MAGIC_STRINGSHARE_NODE, "Eina Stringshare Node");
+#define EMS(n) eina_magic_string_static_set(n, n##_STR)
+ EMS(EINA_MAGIC_STRINGSHARE);
+ EMS(EINA_MAGIC_STRINGSHARE_HEAD);
+ EMS(EINA_MAGIC_STRINGSHARE_NODE);
+#undef EMS
EINA_MAGIC_SET(share, EINA_MAGIC_STRINGSHARE);
_eina_stringshare_small_init();