2008-08-06 11:15:24 -07:00
|
|
|
/* EINA - EFL data type library
|
|
|
|
* Copyright (C) 2007-2008 Jorge Luis Zapata Muga, Cedric Bail
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library;
|
|
|
|
* if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2008-08-08 05:29:13 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2008-08-28 00:46:42 -07:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2008-09-30 09:25:11 -07:00
|
|
|
#include <stdlib.h>
|
2014-03-05 21:26:30 -08:00
|
|
|
#include <stdint.h>
|
2008-08-28 00:46:42 -07:00
|
|
|
|
2008-10-16 14:31:51 -07:00
|
|
|
#ifdef HAVE_EVIL
|
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
|
|
|
|
2009-08-28 05:03:34 -07:00
|
|
|
#include "eina_config.h"
|
2008-07-30 05:46:55 -07:00
|
|
|
#include "eina_private.h"
|
2008-08-28 00:46:42 -07:00
|
|
|
|
2009-09-06 15:21:56 -07:00
|
|
|
|
|
|
|
/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
|
|
|
|
#include "eina_safety_checks.h"
|
|
|
|
#include "eina_error.h"
|
2011-03-18 15:02:03 -07:00
|
|
|
#include "eina_stringshare.h"
|
2014-03-05 21:26:30 -08:00
|
|
|
#include "eina_lock.h"
|
2016-08-18 09:36:05 -07:00
|
|
|
#ifdef EINA_HAVE_THREADS
|
|
|
|
#include "eina_hash.h"
|
|
|
|
#endif
|
2009-09-06 15:21:56 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/* TODO
|
2008-09-06 01:48:36 -07:00
|
|
|
* + add a wrapper for assert?
|
2008-07-30 05:46:55 -07:00
|
|
|
* + add common error numbers, messages
|
2008-09-06 01:48:36 -07:00
|
|
|
* + add a calltrace of errors, not only store the last error but a list of them
|
2008-07-30 05:46:55 -07:00
|
|
|
* and also store the function that set it
|
|
|
|
*/
|
2008-08-28 00:46:42 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/*============================================================================*
|
2010-07-27 19:37:05 -07:00
|
|
|
* Local *
|
|
|
|
*============================================================================*/
|
2008-08-28 00:46:42 -07:00
|
|
|
|
2008-09-05 00:58:38 -07:00
|
|
|
/**
|
|
|
|
* @cond LOCAL
|
|
|
|
*/
|
|
|
|
|
2009-09-06 20:32:22 -07:00
|
|
|
typedef struct _Eina_Error_Message Eina_Error_Message;
|
|
|
|
struct _Eina_Error_Message
|
|
|
|
{
|
|
|
|
Eina_Bool string_allocated;
|
|
|
|
const char *string;
|
|
|
|
};
|
|
|
|
|
2016-08-18 09:36:05 -07:00
|
|
|
#ifdef EINA_HAVE_THREADS
|
|
|
|
static Eina_Spinlock _eina_errno_msgs_lock;
|
|
|
|
static Eina_Hash *_eina_errno_msgs = NULL;
|
|
|
|
#endif
|
2009-09-06 20:32:22 -07:00
|
|
|
static Eina_Error_Message *_eina_errors = NULL;
|
2009-09-06 15:54:49 -07:00
|
|
|
static size_t _eina_errors_count = 0;
|
|
|
|
static size_t _eina_errors_allocated = 0;
|
2014-03-05 21:26:30 -08:00
|
|
|
|
2016-08-18 09:36:05 -07:00
|
|
|
/* used to differentiate registered errors from errno.h */
|
|
|
|
#define EINA_ERROR_REGISTERED_BIT (1 << 30)
|
|
|
|
#define EINA_ERROR_REGISTERED_CHECK(err) ((err) & EINA_ERROR_REGISTERED_BIT)
|
|
|
|
|
|
|
|
#define EINA_ERROR_FROM_INDEX(idx) ((idx) | EINA_ERROR_REGISTERED_BIT)
|
|
|
|
#define EINA_ERROR_TO_INDEX(err) ((err) & (~EINA_ERROR_REGISTERED_BIT))
|
|
|
|
|
2009-09-06 15:54:49 -07:00
|
|
|
static Eina_Error _eina_last_error;
|
2014-03-05 21:26:30 -08:00
|
|
|
static Eina_TLS _eina_last_key;
|
2008-07-30 05:46:55 -07:00
|
|
|
|
2009-09-06 20:32:22 -07:00
|
|
|
static Eina_Error_Message *
|
|
|
|
_eina_error_msg_alloc(void)
|
|
|
|
{
|
|
|
|
size_t idx;
|
|
|
|
|
|
|
|
if (_eina_errors_count == _eina_errors_allocated)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
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;
|
2009-09-06 20:32:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
idx = _eina_errors_count;
|
|
|
|
_eina_errors_count++;
|
|
|
|
return _eina_errors + idx;
|
|
|
|
}
|
|
|
|
|
2008-09-05 00:58:38 -07:00
|
|
|
/**
|
|
|
|
* @endcond
|
|
|
|
*/
|
|
|
|
|
2008-08-08 03:39:47 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/*============================================================================*
|
2010-07-27 19:37:05 -07:00
|
|
|
* Global *
|
|
|
|
*============================================================================*/
|
2008-08-28 00:46:42 -07:00
|
|
|
|
2008-09-05 00:58:38 -07:00
|
|
|
/**
|
|
|
|
* @cond LOCAL
|
|
|
|
*/
|
|
|
|
|
2016-08-18 09:36:05 -07:00
|
|
|
EAPI Eina_Error EINA_ERROR_OUT_OF_MEMORY = ENOMEM;
|
2009-09-06 20:32:22 -07:00
|
|
|
|
2016-08-18 09:36:05 -07:00
|
|
|
EWAPI Eina_Error EINA_ERROR_TIMEOUT = ETIMEDOUT;
|
2016-08-01 01:38:05 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/**
|
2008-09-05 00:58:38 -07:00
|
|
|
* @endcond
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2009-09-06 15:21:56 -07:00
|
|
|
* @internal
|
2009-06-22 13:03:58 -07:00
|
|
|
* @brief Initialize the error module.
|
2008-09-05 00:58:38 -07:00
|
|
|
*
|
2009-09-06 15:21:56 -07:00
|
|
|
* @return #EINA_TRUE on success, #EINA_FALSE on failure.
|
2008-08-28 00:46:42 -07:00
|
|
|
*
|
2009-06-22 13:03:58 -07:00
|
|
|
* This function sets up the error module of Eina. It is called by
|
2009-09-06 15:21:56 -07:00
|
|
|
* eina_init().
|
2008-09-05 00:58:38 -07:00
|
|
|
*
|
2009-06-22 13:03:58 -07:00
|
|
|
* This function registers the error #EINA_ERROR_OUT_OF_MEMORY.
|
|
|
|
*
|
|
|
|
* @see eina_init()
|
2008-07-30 05:46:55 -07:00
|
|
|
*/
|
2009-09-06 15:21:56 -07:00
|
|
|
Eina_Bool
|
|
|
|
eina_error_init(void)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
2014-10-21 23:48:11 -07:00
|
|
|
if (!eina_tls_new(&_eina_last_key))
|
|
|
|
return EINA_FALSE;
|
2016-08-18 09:36:05 -07:00
|
|
|
|
|
|
|
#ifdef EINA_HAVE_THREADS
|
|
|
|
if (!eina_spinlock_new(&_eina_errno_msgs_lock)) goto failed_lock;
|
|
|
|
_eina_errno_msgs = eina_hash_int32_new(EINA_FREE_CB(eina_stringshare_del));
|
|
|
|
if (!_eina_errno_msgs) goto failed_hash;
|
|
|
|
#endif
|
|
|
|
|
2009-09-06 15:21:56 -07:00
|
|
|
return EINA_TRUE;
|
2016-08-18 09:36:05 -07:00
|
|
|
|
|
|
|
#ifdef EINA_HAVE_THREADS
|
|
|
|
failed_hash:
|
|
|
|
eina_spinlock_free(&_eina_errno_msgs_lock);
|
|
|
|
failed_lock:
|
|
|
|
eina_tls_free(_eina_last_key);
|
|
|
|
_eina_last_error = 0;
|
|
|
|
return EINA_FALSE;
|
|
|
|
#endif
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/**
|
2009-09-06 15:21:56 -07:00
|
|
|
* @internal
|
2009-06-22 13:03:58 -07:00
|
|
|
* @brief Shut down the error module.
|
2008-08-28 00:46:42 -07:00
|
|
|
*
|
2009-09-06 15:21:56 -07:00
|
|
|
* @return #EINA_TRUE on success, #EINA_FALSE on failure.
|
2008-09-05 00:58:38 -07:00
|
|
|
*
|
2009-06-22 13:03:58 -07:00
|
|
|
* This function shuts down the error module set up by
|
2009-09-06 15:21:56 -07:00
|
|
|
* eina_error_init(). It is called by eina_shutdown().
|
2009-06-22 13:03:58 -07:00
|
|
|
*
|
|
|
|
* @see eina_shutdown()
|
2008-07-30 05:46:55 -07:00
|
|
|
*/
|
2009-09-06 15:21:56 -07:00
|
|
|
Eina_Bool
|
|
|
|
eina_error_shutdown(void)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
2009-09-06 20:32:22 -07:00
|
|
|
Eina_Error_Message *eem, *eem_end;
|
|
|
|
|
|
|
|
eem = _eina_errors;
|
|
|
|
eem_end = eem + _eina_errors_count;
|
2009-09-06 15:54:49 -07:00
|
|
|
|
2009-09-06 20:32:22 -07:00
|
|
|
for (; eem < eem_end; eem++)
|
2010-07-27 19:37:05 -07:00
|
|
|
if (eem->string_allocated)
|
2011-03-18 15:02:03 -07:00
|
|
|
eina_stringshare_del(eem->string);
|
2009-09-06 15:54:49 -07:00
|
|
|
|
2014-03-05 21:26:30 -08:00
|
|
|
free(_eina_errors);
|
2009-09-06 15:54:49 -07:00
|
|
|
_eina_errors = NULL;
|
|
|
|
_eina_errors_count = 0;
|
|
|
|
_eina_errors_allocated = 0;
|
|
|
|
|
2016-08-18 09:36:05 -07:00
|
|
|
#ifdef EINA_HAVE_THREADS
|
|
|
|
eina_hash_free(_eina_errno_msgs);
|
|
|
|
_eina_errno_msgs = NULL;
|
|
|
|
eina_spinlock_free(&_eina_errno_msgs_lock);
|
|
|
|
#endif
|
|
|
|
|
2014-03-05 21:26:30 -08:00
|
|
|
eina_tls_free(_eina_last_key);
|
|
|
|
_eina_last_error = 0;
|
|
|
|
|
2009-09-06 15:21:56 -07:00
|
|
|
return EINA_TRUE;
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
|
|
|
|
2009-12-27 00:45:30 -08:00
|
|
|
/*============================================================================*
|
2010-07-27 19:37:05 -07:00
|
|
|
* API *
|
|
|
|
*============================================================================*/
|
2009-12-27 00:45:30 -08:00
|
|
|
|
2009-09-06 15:54:49 -07:00
|
|
|
EAPI Eina_Error
|
|
|
|
eina_error_msg_register(const char *msg)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
2009-09-06 20:32:22 -07:00
|
|
|
Eina_Error_Message *eem;
|
|
|
|
|
2009-09-06 15:54:49 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0);
|
2008-12-26 10:31:14 -08:00
|
|
|
|
2009-09-06 20:32:22 -07:00
|
|
|
eem = _eina_error_msg_alloc();
|
|
|
|
if (!eem)
|
2010-07-27 19:37:05 -07:00
|
|
|
return 0;
|
2009-09-06 20:32:22 -07:00
|
|
|
|
|
|
|
eem->string_allocated = EINA_TRUE;
|
2011-03-18 15:02:03 -07:00
|
|
|
eem->string = eina_stringshare_add(msg);
|
2009-09-06 20:32:22 -07:00
|
|
|
if (!eem->string)
|
2009-09-06 15:54:49 -07:00
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
_eina_errors_count--;
|
|
|
|
return 0;
|
2009-09-06 20:32:22 -07:00
|
|
|
}
|
2009-09-06 15:54:49 -07:00
|
|
|
|
2016-08-18 09:36:05 -07:00
|
|
|
return EINA_ERROR_FROM_INDEX(_eina_errors_count); /* identifier = index + 1 (== _count). */
|
2009-09-06 20:32:22 -07:00
|
|
|
}
|
2009-09-06 15:54:49 -07:00
|
|
|
|
2009-09-06 20:32:22 -07:00
|
|
|
EAPI Eina_Error
|
|
|
|
eina_error_msg_static_register(const char *msg)
|
|
|
|
{
|
|
|
|
Eina_Error_Message *eem;
|
2008-09-30 09:25:11 -07:00
|
|
|
|
2009-09-06 20:32:22 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0);
|
|
|
|
|
|
|
|
eem = _eina_error_msg_alloc();
|
|
|
|
if (!eem)
|
2010-07-27 19:37:05 -07:00
|
|
|
return 0;
|
2009-09-06 20:32:22 -07:00
|
|
|
|
|
|
|
eem->string_allocated = EINA_FALSE;
|
|
|
|
eem->string = msg;
|
2016-08-18 09:36:05 -07:00
|
|
|
return EINA_ERROR_FROM_INDEX(_eina_errors_count); /* identifier = index + 1 (== _count). */
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2010-07-24 23:25:06 -07:00
|
|
|
EAPI Eina_Bool
|
|
|
|
eina_error_msg_modify(Eina_Error error, const char *msg)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, EINA_FALSE);
|
2016-08-18 09:36:05 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL(EINA_ERROR_REGISTERED_CHECK(error), EINA_FALSE);
|
|
|
|
error = EINA_ERROR_TO_INDEX(error);
|
2010-07-24 23:25:06 -07:00
|
|
|
if (error < 1)
|
2010-07-27 19:37:05 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
|
2010-07-24 23:25:06 -07:00
|
|
|
if ((size_t)error > _eina_errors_count)
|
2010-07-27 19:37:05 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
|
2010-07-24 23:25:06 -07:00
|
|
|
if (_eina_errors[error - 1].string_allocated)
|
|
|
|
{
|
|
|
|
const char *tmp;
|
|
|
|
|
2011-03-18 15:02:03 -07:00
|
|
|
if (!(tmp = eina_stringshare_add(msg)))
|
2010-07-27 19:37:05 -07:00
|
|
|
return EINA_FALSE;
|
2010-07-24 23:25:06 -07:00
|
|
|
|
2011-03-18 15:02:03 -07:00
|
|
|
eina_stringshare_del(_eina_errors[error - 1].string);
|
2010-07-24 23:25:06 -07:00
|
|
|
_eina_errors[error - 1].string = tmp;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
_eina_errors[error - 1].string = msg;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2009-09-06 15:54:49 -07:00
|
|
|
EAPI const char *
|
|
|
|
eina_error_msg_get(Eina_Error error)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
2016-08-18 09:36:05 -07:00
|
|
|
if (!EINA_ERROR_REGISTERED_CHECK(error))
|
|
|
|
{
|
|
|
|
const char unknown_prefix[] = "Unknown error ";
|
|
|
|
const char *msg;
|
|
|
|
|
|
|
|
/* original behavior of this function did not return strings
|
|
|
|
* for unknown errors, so skip 0 ("Success") and
|
|
|
|
* "Unknown error $N".
|
|
|
|
*/
|
|
|
|
if (error == 0) return NULL;
|
|
|
|
|
|
|
|
#ifndef EINA_HAVE_THREADS
|
|
|
|
msg = strerror(error);
|
|
|
|
if (strncmp(msg, unknown_prefix, sizeof(unknown_prefix) -1) == 0)
|
|
|
|
msg = NULL;
|
|
|
|
#else /* EINA_HAVE_THREADS */
|
|
|
|
/* strerror() is not thread safe, so use a local buffer with
|
|
|
|
* strerror_r() and cache resolved strings in a hash so we can
|
|
|
|
* return the stringshared refernece.
|
|
|
|
*/
|
|
|
|
if (eina_spinlock_take(&_eina_errno_msgs_lock) != EINA_LOCK_SUCCEED)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ERROR("could not take spinlock for errno messages hash!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
msg = eina_hash_find(_eina_errno_msgs, &error);
|
|
|
|
eina_spinlock_release(&_eina_errno_msgs_lock);
|
|
|
|
|
|
|
|
if (!msg)
|
|
|
|
{
|
|
|
|
char buf[256] = "";
|
|
|
|
const char *str;
|
|
|
|
|
|
|
|
#if (_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE
|
|
|
|
if (strerror_r(error, buf, sizeof(buf)) == 0) /* XSI */
|
|
|
|
str = buf;
|
|
|
|
else
|
|
|
|
str = NULL;
|
|
|
|
#else
|
|
|
|
str = strerror_r(error, buf, sizeof(buf)); /* GNU */
|
|
|
|
#endif
|
|
|
|
if (!str)
|
|
|
|
EINA_SAFETY_ERROR("strerror_r() failed");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (strncmp(str, unknown_prefix, sizeof(unknown_prefix) -1) == 0)
|
|
|
|
msg = NULL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
msg = eina_stringshare_add(str);
|
|
|
|
if (eina_spinlock_take(&_eina_errno_msgs_lock) != EINA_LOCK_SUCCEED)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ERROR("could not take spinlock for errno messages hash!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
eina_hash_add(_eina_errno_msgs, &error, msg);
|
|
|
|
eina_spinlock_release(&_eina_errno_msgs_lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = EINA_ERROR_TO_INDEX(error);
|
|
|
|
|
2009-09-06 15:54:49 -07:00
|
|
|
if (error < 1)
|
2010-07-27 19:37:05 -07:00
|
|
|
return NULL;
|
|
|
|
|
2009-09-06 15:54:49 -07:00
|
|
|
if ((size_t)error > _eina_errors_count)
|
2010-07-27 19:37:05 -07:00
|
|
|
return NULL;
|
|
|
|
|
2009-09-06 20:32:22 -07:00
|
|
|
return _eina_errors[error - 1].string;
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2009-09-06 15:54:49 -07:00
|
|
|
EAPI Eina_Error
|
|
|
|
eina_error_get(void)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
2014-03-05 21:26:30 -08:00
|
|
|
if (eina_main_loop_is())
|
|
|
|
return _eina_last_error;
|
|
|
|
|
|
|
|
return (Eina_Error)(uintptr_t) eina_tls_get(_eina_last_key);
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2009-09-06 15:54:49 -07:00
|
|
|
EAPI void
|
|
|
|
eina_error_set(Eina_Error err)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
2014-03-05 21:26:30 -08:00
|
|
|
if (eina_main_loop_is())
|
|
|
|
_eina_last_error = err;
|
|
|
|
else
|
|
|
|
eina_tls_set(_eina_last_key, (void*)(uintptr_t) err);
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2011-03-18 17:07:23 -07:00
|
|
|
EAPI Eina_Error
|
|
|
|
eina_error_find(const char *msg)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0);
|
|
|
|
|
|
|
|
for (i = 0; i < _eina_errors_count; i++)
|
|
|
|
{
|
|
|
|
if (_eina_errors[i].string_allocated)
|
|
|
|
{
|
|
|
|
if (_eina_errors[i].string == msg)
|
2016-08-18 09:36:05 -07:00
|
|
|
return EINA_ERROR_FROM_INDEX(i + 1);
|
2011-03-18 17:07:23 -07:00
|
|
|
}
|
2011-03-18 17:15:42 -07:00
|
|
|
if (!strcmp(_eina_errors[i].string, msg))
|
2016-08-18 09:36:05 -07:00
|
|
|
return EINA_ERROR_FROM_INDEX(i + 1);
|
2011-03-18 17:07:23 -07:00
|
|
|
}
|
2016-08-18 09:36:05 -07:00
|
|
|
|
|
|
|
/* not bothering to lookup errno.h as we don't have a "maximum
|
|
|
|
* error", thus we'd need to loop up to some arbitrary constant and
|
|
|
|
* keep comparing if strerror() returns something meaningful.
|
|
|
|
*/
|
|
|
|
|
2011-03-18 17:07:23 -07:00
|
|
|
return 0;
|
|
|
|
}
|