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-09-05 00:58:38 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @page tutorial_error_page Error Tutorial
|
|
|
|
*
|
|
|
|
* @section tutorial_error_introduction Introduction
|
|
|
|
*
|
|
|
|
* The Eina error module provides a way to manage errors in a simple
|
|
|
|
* but powerful way in libraries and modules. It is also used in Eina
|
|
|
|
* itself. It provides facilities for displaying different kind of
|
|
|
|
* messages (warning, informations, errors, or debug), which can be
|
|
|
|
* tuned by the user, or for registering new errors messages.
|
|
|
|
*
|
|
|
|
* @section tutorial_error_basic_usage Basic Usage
|
|
|
|
*
|
|
|
|
* The first thing to do when using the error module is to initialize
|
|
|
|
* it with eina_error_init() and, when the error module is not used
|
|
|
|
* anymore, to shut down it with eina_error_shutdown(). So a basic
|
|
|
|
* program would look like that:
|
|
|
|
*
|
|
|
|
* @code
|
|
|
|
* #include <stdlib.h>
|
|
|
|
* #include <stdio.h>
|
|
|
|
*
|
|
|
|
* #include <eina_error.h>
|
|
|
|
*
|
|
|
|
* int main(void)
|
|
|
|
* {
|
|
|
|
* if (!eina_error_init())
|
|
|
|
* {
|
|
|
|
* printf ("Error during the initialization of eina_error module\n");
|
|
|
|
* return EXIT_FAILURE;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* eina_error_shutdown();
|
|
|
|
*
|
|
|
|
* return EXIT_SUCCESS;
|
|
|
|
* }
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* All program using any module of eina must be compiled with the
|
|
|
|
* following command:
|
|
|
|
*
|
|
|
|
* @code
|
|
|
|
* gcc -Wall -o my_exe my_source.c `pkg-config --cflags --libs eina`
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* Now that the error module is initialized, error messages can
|
|
|
|
* be displayed. Helper macros are already defined for such purpose:
|
|
|
|
*
|
|
|
|
* @li EINA_ERROR_PERR(),
|
|
|
|
* @li EINA_ERROR_PINFO(),
|
|
|
|
* @li EINA_ERROR_PWARN(),
|
|
|
|
* @li EINA_ERROR_PDBG().
|
|
|
|
*
|
|
|
|
* Here is an example:
|
|
|
|
*
|
|
|
|
* @code
|
|
|
|
* #include <stdlib.h>
|
|
|
|
* #include <stdio.h>
|
|
|
|
*
|
|
|
|
* #include <eina_error.h>
|
|
|
|
*
|
|
|
|
* void test(int i)
|
|
|
|
* {
|
|
|
|
* EINA_ERROR_PDBG("Entering test\n");
|
|
|
|
*
|
|
|
|
* if (i < 0)
|
|
|
|
* {
|
|
|
|
* EINA_ERROR_PERR("argument is negative\n");
|
|
|
|
* return;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* EINA_ERROR_PINFO("argument non negative\n");
|
|
|
|
*
|
|
|
|
* EINA_ERROR_PDBG("Exiting test\n");
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* int main(void)
|
|
|
|
* {
|
|
|
|
* if (!eina_error_init())
|
|
|
|
* {
|
|
|
|
* printf ("Error during the initialization of eina_error module\n");
|
|
|
|
* return EXIT_FAILURE;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* test(-1);
|
|
|
|
* test(0);
|
|
|
|
*
|
|
|
|
* eina_error_shutdown();
|
|
|
|
*
|
|
|
|
* return EXIT_SUCCESS;
|
|
|
|
* }
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* If you compiled Eina without debug mode, after executing that
|
|
|
|
* program, you will see only 1 message (the argument being
|
|
|
|
* negative). Why ? These macros are just wrappers around
|
|
|
|
* eina_error_print(). This function only dysplays messages if the
|
|
|
|
* current error level is lesser or equal than the one used by
|
|
|
|
* eina_error_print(). By default, the current error level is
|
|
|
|
* #EINA_ERROR_LEVEL_ERR (in non debug mode), and the macro uses
|
|
|
|
* the error values defines by #Eina_Error_Level. So as
|
|
|
|
* #EINA_ERROR_LEVEL_ERR is the smallest value, only
|
|
|
|
* EINA_ERROR_PERR() will display the message.
|
|
|
|
*
|
|
|
|
* To modify this behavior, you have two solutions:
|
|
|
|
*
|
|
|
|
* @li Using the environment variable EINA_ERROR_LEVEL. In that case,
|
|
|
|
* just set the environment variable to a integer number between 0
|
|
|
|
* (#EINA_ERROR_LEVEL_ERR) and 3 (#EINA_ERROR_LEVEL_DBG)
|
|
|
|
* before executing the program. That environment variable will be
|
|
|
|
* read during the first call of eina_error_init().
|
|
|
|
* @li Using the function eina_error_log_level_set().
|
|
|
|
*
|
|
|
|
* So try using the environment variable like this:
|
|
|
|
*
|
|
|
|
* @code
|
|
|
|
* EINA_ERROR_LEVEL=2 ./my_app
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* To do the same with eina_error_log_level_set(), just add
|
|
|
|
*
|
|
|
|
* @code
|
|
|
|
* eina_error_log_level_set(EINA_ERROR_LEVEL_INFO);
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* before the calls of the tests in the above example.
|
|
|
|
*
|
2008-09-06 01:54:22 -07:00
|
|
|
* @section tutorial_error_advanced_display Advanced usage of print callbacks
|
2008-09-06 01:48:36 -07:00
|
|
|
*
|
|
|
|
* The error module allows the user to change the way
|
|
|
|
* eina_error_print() displays the messages. It suffices to pass to
|
|
|
|
* eina_error_print_cb_set() the function used to display the
|
|
|
|
* message. That function must be of type #Eina_Error_Print_Cb. As a
|
|
|
|
* custom data can be passed to that callback, powerful display
|
|
|
|
* messages can be displayed.
|
|
|
|
*
|
|
|
|
* It is suggested to not use __FILE__, __FUNCTION__ or __LINE__ when
|
|
|
|
* writing that callback, but when defining macros (like
|
|
|
|
* EINA_ERROR_PERR() and other macros).
|
|
|
|
*
|
|
|
|
* Here is an example of custom callback, whose behavior can be
|
|
|
|
* changed at runtime:
|
|
|
|
*
|
|
|
|
* @code
|
|
|
|
* #include <stdlib.h>
|
|
|
|
* #include <stdio.h>
|
|
|
|
*
|
|
|
|
* #include <eina_error.h>
|
|
|
|
*
|
|
|
|
* #define ERROR(fmt, ...) \
|
|
|
|
* eina_error_print(EINA_ERROR_LEVEL_ERR, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
|
|
|
*
|
|
|
|
* typedef struct _Data Data;
|
|
|
|
*
|
|
|
|
* struct _Data
|
|
|
|
* {
|
|
|
|
* int to_stderr;
|
|
|
|
* };
|
|
|
|
*
|
|
|
|
* void print_cb(Eina_Error_Level level,
|
|
|
|
* const char *file,
|
|
|
|
* const char *fnc,
|
|
|
|
* int line,
|
|
|
|
* const char *fmt,
|
|
|
|
* void *data,
|
|
|
|
* va_list args)
|
|
|
|
* {
|
|
|
|
* Data *d;
|
|
|
|
* FILE *output;
|
|
|
|
* char *str;
|
|
|
|
*
|
|
|
|
* d = (Data *)data;
|
|
|
|
* if (d->to_stderr)
|
|
|
|
* {
|
|
|
|
* output = stderr;
|
|
|
|
* str = "stderr";
|
|
|
|
* }
|
|
|
|
* else
|
|
|
|
* {
|
|
|
|
* output = stdout;
|
|
|
|
* str = "stdout";
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* fprintf(output, "%s:%s (%d) %s: ", file, fnc, line, str);
|
|
|
|
* vfprintf(output, fmt, args);
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* void test(Data *data, int i)
|
|
|
|
* {
|
|
|
|
* if (i < 0)
|
|
|
|
* data->to_stderr = 0;
|
|
|
|
* else
|
|
|
|
* data->to_stderr = 1;
|
|
|
|
*
|
|
|
|
* ERROR("error message...\n");
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* int main(void)
|
|
|
|
* {
|
|
|
|
* Data *data;
|
|
|
|
*
|
|
|
|
* if (!eina_error_init())
|
|
|
|
* {
|
|
|
|
* printf ("Error during the initialization of eina_error module\n");
|
|
|
|
* return EXIT_FAILURE;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* data = (Data *)malloc(sizeof(Data));
|
|
|
|
* if (!data)
|
|
|
|
* {
|
|
|
|
* printf ("Error during memory allocation\n");
|
|
|
|
* eina_error_shutdown();
|
|
|
|
* return EXIT_FAILURE;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* eina_error_print_cb_set(print_cb, data);
|
|
|
|
*
|
|
|
|
* test(data, -1);
|
|
|
|
* test(data, 0);
|
|
|
|
*
|
|
|
|
* eina_error_shutdown();
|
|
|
|
*
|
|
|
|
* return EXIT_SUCCESS;
|
|
|
|
* }
|
|
|
|
* @endcode
|
|
|
|
*
|
2008-09-05 00:58:38 -07:00
|
|
|
* @section tutorial_error_registering_msg Registering messages
|
|
|
|
*
|
2008-09-06 01:48:36 -07:00
|
|
|
* The error module can provide a system that mimic the errno system
|
|
|
|
* of the C standard library. It consists in 2 parts:
|
|
|
|
*
|
|
|
|
* @li a way of registering new messages with
|
|
|
|
* eina_error_msg_register() and eina_error_msg_get(),
|
|
|
|
* @li a way of setting / getting last error message with
|
|
|
|
* eina_error_set() / eina_error_get().
|
|
|
|
*
|
|
|
|
* So one has to fisrt register all the error messages that a program
|
|
|
|
* or a lib should manage. Then, when an error can occur, use
|
2008-09-06 02:14:54 -07:00
|
|
|
* eina_error_set(), and when errors are managed, use
|
|
|
|
* eina_error_get(). If eina_error_set() is used to set an error, do
|
|
|
|
* not forget to call before eina_error_set0), to remove previous set
|
|
|
|
* errors.
|
2008-09-06 01:48:36 -07:00
|
|
|
*
|
2008-09-06 01:54:22 -07:00
|
|
|
* Here is an example of use:
|
|
|
|
*
|
2008-09-06 01:48:36 -07:00
|
|
|
* @code
|
|
|
|
* #include <stdlib.h>
|
|
|
|
* #include <stdio.h>
|
|
|
|
*
|
|
|
|
* #include <eina_error.h>
|
|
|
|
*
|
|
|
|
* Eina_Error MY_ERROR_NEGATIVE;
|
|
|
|
* Eina_Error MY_ERROR_NULL;
|
|
|
|
*
|
|
|
|
* voi *data_new()
|
|
|
|
* {
|
2008-09-06 02:14:54 -07:00
|
|
|
* eina_error_set(0);
|
|
|
|
*
|
2008-09-06 01:48:36 -07:00
|
|
|
* eina_error_set(MY_ERROR_NULL);
|
|
|
|
* return NULL;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* int test(int n)
|
|
|
|
* {
|
2008-09-06 02:14:54 -07:00
|
|
|
* eina_error_set(0);
|
|
|
|
*
|
2008-09-06 01:48:36 -07:00
|
|
|
* if (n < 0)
|
|
|
|
* {
|
|
|
|
* eina_error_set(MY_ERROR_NEGATIVE);
|
|
|
|
* return 0;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* return 1;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* int main(void)
|
|
|
|
* {
|
|
|
|
* void *data;
|
2008-09-05 00:58:38 -07:00
|
|
|
*
|
2008-09-06 01:48:36 -07:00
|
|
|
* if (!eina_error_init())
|
|
|
|
* {
|
|
|
|
* printf ("Error during the initialization of eina_error module\n");
|
|
|
|
* return EXIT_FAILURE;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* MY_ERROR_NEGATIVE = eina_error_msg_register("Negative number");
|
|
|
|
* MY_ERROR_NULL = eina_error_msg_register("NULL pointer");
|
|
|
|
|
|
|
|
* data = data_new();
|
|
|
|
* if (!data)
|
|
|
|
* {
|
|
|
|
* Eina_Error err;
|
|
|
|
*
|
|
|
|
* err = eina_error_get();
|
|
|
|
* if (err)
|
|
|
|
* printf("Error during memory allocation: %s\n",
|
|
|
|
* eina_error_msg_get(err));
|
|
|
|
* }
|
|
|
|
*
|
2008-09-06 02:14:54 -07:00
|
|
|
* if (!test(0))
|
|
|
|
* {
|
|
|
|
* Eina_Error err;
|
|
|
|
*
|
|
|
|
* err = eina_error_get();
|
|
|
|
* if (err)
|
|
|
|
* printf("Error during test function: %s\n",
|
|
|
|
* eina_error_msg_get(err));
|
|
|
|
* }
|
|
|
|
*
|
2008-09-06 01:48:36 -07:00
|
|
|
* if (!test(-1))
|
|
|
|
* {
|
|
|
|
* Eina_Error err;
|
|
|
|
*
|
|
|
|
* err = eina_error_get();
|
|
|
|
* if (err)
|
|
|
|
* printf("Error during test function: %s\n",
|
|
|
|
* eina_error_msg_get(err));
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* eina_error_shutdown();
|
|
|
|
*
|
|
|
|
* return EXIT_SUCCESS;
|
|
|
|
* }
|
|
|
|
* @endcode
|
2008-09-06 01:54:22 -07:00
|
|
|
*
|
|
|
|
* Of course, instead of printf(), eina_error_print() can be used to
|
|
|
|
* have beautiful error messages.
|
2008-09-05 00:58:38 -07:00
|
|
|
*/
|
|
|
|
|
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-07-30 06:35:49 -07:00
|
|
|
#include "eina_error.h"
|
|
|
|
#include "eina_list.h"
|
2008-07-30 05:46:55 -07:00
|
|
|
#include "eina_private.h"
|
2008-08-28 00:46:42 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/* TODO
|
|
|
|
* + printing errors to stdout or stderr can be implemented
|
2008-08-28 00:46:42 -07:00
|
|
|
* using a queue, useful for multiple threads printing
|
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
|
|
|
/*============================================================================*
|
2008-08-28 00:46:42 -07:00
|
|
|
* Local *
|
2008-07-30 05:46:55 -07:00
|
|
|
*============================================================================*/
|
2008-08-28 00:46:42 -07:00
|
|
|
|
2008-09-05 00:58:38 -07:00
|
|
|
/**
|
|
|
|
* @cond LOCAL
|
|
|
|
*/
|
|
|
|
|
2008-09-25 07:46:16 -07:00
|
|
|
static int _eina_error_init_count = 0;
|
2008-07-30 05:46:55 -07:00
|
|
|
static Eina_List *_error_list;
|
2008-08-04 10:00:30 -07:00
|
|
|
static Eina_Error _err;
|
2008-08-08 03:39:47 -07:00
|
|
|
static Eina_Error_Print_Cb _print_cb = eina_error_print_cb_stdout;
|
|
|
|
static void *_print_cb_data = NULL;
|
2008-07-30 05:46:55 -07:00
|
|
|
|
|
|
|
#define RED "\033[31;1m"
|
|
|
|
#define GREEN "\033[32;1m"
|
|
|
|
#define YELLOW "\033[33;1m"
|
|
|
|
#define WHITE "\033[37;1m"
|
|
|
|
#define NOTHING "\033[0m"
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
2008-07-30 06:35:49 -07:00
|
|
|
static Eina_Error_Level _error_level = EINA_ERROR_LEVEL_DBG;
|
2008-07-30 05:46:55 -07:00
|
|
|
#else
|
2008-07-30 06:35:49 -07:00
|
|
|
static Eina_Error_Level _error_level = EINA_ERROR_LEVEL_ERR;
|
2008-07-30 05:46:55 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static char *_colors[EINA_ERROR_LEVELS] = {
|
|
|
|
[EINA_ERROR_LEVEL_ERR] = RED,
|
|
|
|
[EINA_ERROR_LEVEL_WARN] = YELLOW,
|
|
|
|
[EINA_ERROR_LEVEL_INFO] = NOTHING,
|
|
|
|
[EINA_ERROR_LEVEL_DBG] = GREEN,
|
|
|
|
};
|
|
|
|
|
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
|
|
|
/*============================================================================*
|
2008-08-28 00:46:42 -07:00
|
|
|
* Global *
|
|
|
|
*============================================================================*/
|
|
|
|
|
|
|
|
/*============================================================================*
|
|
|
|
* API *
|
2008-07-30 05:46:55 -07:00
|
|
|
*============================================================================*/
|
2008-08-28 00:46:42 -07:00
|
|
|
|
2008-09-17 11:55:54 -07:00
|
|
|
/**
|
2008-09-18 22:22:43 -07:00
|
|
|
* @addtogroup Eina_Tools_Group Tools
|
2008-09-17 11:55:54 -07:00
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2008-09-05 00:58:38 -07:00
|
|
|
/**
|
2008-09-18 22:22:43 -07:00
|
|
|
* @addtogroup Eina_Error_Group Error
|
2008-09-05 00:58:38 -07:00
|
|
|
*
|
2008-09-07 12:12:49 -07:00
|
|
|
* @brief These functions provide error management for projects.
|
2008-09-05 00:58:38 -07:00
|
|
|
*
|
|
|
|
* The error system must be initialized with eina_error_init() and
|
|
|
|
* shut down with eina_error_shutdown(). The most generic way to print
|
|
|
|
* errors is to use eina_error_print() but the helper macros
|
|
|
|
* EINA_ERROR_PERR(), EINA_ERROR_PINFO(), EINA_ERROR_PWARN() and
|
|
|
|
* EINA_ERROR_PDBG() should be used instead.
|
|
|
|
*
|
|
|
|
* Here is a straightforward example:
|
|
|
|
*
|
|
|
|
* @code
|
|
|
|
* #include <stdlib.h>
|
|
|
|
* #include <stdio.h>
|
|
|
|
*
|
|
|
|
* #include <eina_error.h>
|
|
|
|
*
|
|
|
|
* void test_warn(void)
|
|
|
|
* {
|
|
|
|
* EINA_ERROR_PWARN("Here is a warning message\n");
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* int main(void)
|
|
|
|
* {
|
|
|
|
* if (!eina_error_init())
|
|
|
|
* {
|
|
|
|
* printf ("Error during the initialization of eina_error module\n");
|
|
|
|
* return EXIT_FAILURE;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* test_warn();
|
|
|
|
*
|
|
|
|
* eina_error_shutdown();
|
|
|
|
*
|
|
|
|
* return EXIT_SUCCESS;
|
|
|
|
* }
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* Compile this code with the following commant:
|
|
|
|
*
|
|
|
|
* @code
|
|
|
|
* gcc -Wall -o test_eina_error test_eina.c `pkg-config --cflags --libs eina`
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* If Eina is compiled without debug mode, then executing the
|
|
|
|
* resulting program displays nothing because the default error level
|
|
|
|
* is #EINA_ERROR_LEVEL_ERR and we want to display a warning
|
|
|
|
* message, which level is strictly greater than the error level (see
|
|
|
|
* eina_error_print() for more informations). Now execute the program
|
|
|
|
* with:
|
|
|
|
*
|
|
|
|
* @code
|
|
|
|
* EINA_ERROR_LEVEL=2 ./test_eina_error
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* You should see a message displayed in the terminal.
|
|
|
|
*
|
|
|
|
* For more information, you can look at the @ref tutorial_error_page.
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @cond LOCAL
|
|
|
|
*/
|
|
|
|
|
2008-08-28 05:41:58 -07:00
|
|
|
EAPI Eina_Error EINA_ERROR_OUT_OF_MEMORY = 0;
|
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/**
|
2008-09-05 00:58:38 -07:00
|
|
|
* @endcond
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize the error system.
|
|
|
|
*
|
|
|
|
* @return 1 or greater on success, 0 on error.
|
2008-08-28 00:46:42 -07:00
|
|
|
*
|
2008-09-05 00:58:38 -07:00
|
|
|
* This function sets up the error system or Eina. It is called by
|
|
|
|
* eina_init() and by all subsystems initialization functions. It
|
|
|
|
* returns 0 on failure, otherwise it returns the number of times it
|
|
|
|
* is called.
|
|
|
|
*
|
|
|
|
* The default error level value is set by default to
|
|
|
|
* #EINA_ERROR_LEVEL_DBG if Eina is compiled with debug mode, or to
|
|
|
|
* #EINA_ERROR_LEVEL_ERR otherwise. That value can be overwritten by
|
|
|
|
* setting the environment variable EINA_ERROR_LEVEL. This function
|
|
|
|
* checks the value of that environment variable in the first
|
|
|
|
* call. Its value must be a number between 0 and 3, to match the
|
|
|
|
* error levels #EINA_ERROR_LEVEL_ERR, #EINA_ERROR_LEVEL_WARN,
|
|
|
|
* #EINA_ERROR_LEVEL_INFO and #EINA_ERROR_LEVEL_DBG. That value can
|
|
|
|
* also be set later with eina_error_log_level_set().
|
|
|
|
*
|
2008-09-06 01:48:36 -07:00
|
|
|
* If you call explicitely this function and once the error subsystem
|
|
|
|
* is not used anymore, then eina_error_shutdown() must be called to
|
2008-09-05 00:58:38 -07:00
|
|
|
* shut down the error system.
|
2008-07-30 05:46:55 -07:00
|
|
|
*/
|
|
|
|
EAPI int eina_error_init(void)
|
|
|
|
{
|
2008-09-25 07:46:16 -07:00
|
|
|
if (!_eina_error_init_count)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
|
|
|
char *level;
|
|
|
|
/* TODO register the eina's basic errors */
|
|
|
|
/* TODO load the environment variable for getting the log level */
|
2008-07-30 06:35:49 -07:00
|
|
|
if ((level = getenv("EINA_ERROR_LEVEL")))
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
|
|
|
_error_level = atoi(level);
|
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
EINA_ERROR_OUT_OF_MEMORY = eina_error_msg_register("Out of memory");
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
|
|
|
/* get all the modules */
|
2008-09-25 07:46:16 -07:00
|
|
|
return ++_eina_error_init_count;
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/**
|
2008-09-05 00:58:38 -07:00
|
|
|
* @brief Shut down the error system.
|
2008-08-28 00:46:42 -07:00
|
|
|
*
|
2008-09-05 00:58:38 -07:00
|
|
|
* @return 0 when the error system is completely shut down, 1 or
|
|
|
|
* greater otherwise.
|
|
|
|
*
|
|
|
|
* This function shut down the error system set up by
|
|
|
|
* eina_error_init(). It is called by eina_shutdown() and by all
|
|
|
|
* subsystems shutdown functions. It returns 0 when it is called the
|
2008-09-06 01:48:36 -07:00
|
|
|
* same number of times than eina_error_init() and it clears the error
|
2008-09-05 00:58:38 -07:00
|
|
|
* list.
|
2008-07-30 05:46:55 -07:00
|
|
|
*/
|
|
|
|
EAPI int eina_error_shutdown(void)
|
|
|
|
{
|
2008-09-25 07:46:16 -07:00
|
|
|
_eina_error_init_count--;
|
|
|
|
if (!_eina_error_init_count)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
|
|
|
/* remove the error strings */
|
|
|
|
while (_error_list)
|
|
|
|
{
|
2008-09-25 07:46:16 -07:00
|
|
|
free(eina_list_data_get(_error_list));
|
2008-07-30 05:46:55 -07:00
|
|
|
_error_list = eina_list_free(_error_list);
|
|
|
|
}
|
|
|
|
}
|
2008-09-25 07:46:16 -07:00
|
|
|
return _eina_error_init_count;
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-09-05 00:58:38 -07:00
|
|
|
* @brief Register a new error type.
|
|
|
|
*
|
|
|
|
* @param msg The description of the 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 retrive later by passing to
|
|
|
|
* eina_error_msg_get() the returned value.
|
2008-07-30 05:46:55 -07:00
|
|
|
*/
|
2008-09-05 00:58:38 -07:00
|
|
|
EAPI Eina_Error eina_error_msg_register(const char *msg)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
2008-08-01 07:26:13 -07:00
|
|
|
_error_list = eina_list_append(_error_list, strdup(msg));
|
|
|
|
|
|
|
|
return eina_list_count(_error_list);
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/**
|
2008-09-05 00:58:38 -07:00
|
|
|
* @brief Return the description of the given an error number.
|
2008-08-28 00:46:42 -07:00
|
|
|
*
|
2008-09-05 00:58:38 -07:00
|
|
|
* @param error The error number.
|
|
|
|
* @return The description of the error.
|
|
|
|
*
|
|
|
|
* This function returns the description of an error that has been
|
|
|
|
* registered with eina_error_msg_register(). If an incorrect error is
|
|
|
|
* given, then @c NULL is returned.
|
2008-07-30 05:46:55 -07:00
|
|
|
*/
|
2008-09-05 00:58:38 -07:00
|
|
|
EAPI const char * eina_error_msg_get(Eina_Error error)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
2008-09-05 00:58:38 -07:00
|
|
|
return eina_list_nth(_error_list, error - 1);
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/**
|
2008-09-05 00:58:38 -07:00
|
|
|
* @brief Return the last set error.
|
2008-08-28 00:46:42 -07:00
|
|
|
*
|
2008-09-05 00:58:38 -07:00
|
|
|
* @return The last error.
|
|
|
|
*
|
2008-09-07 12:12:49 -07:00
|
|
|
* This function returns the last error set by eina_error_set(). The
|
|
|
|
* description of the message is returned by eina_error_msg_get().
|
2008-07-30 05:46:55 -07:00
|
|
|
*/
|
2008-09-05 00:58:38 -07:00
|
|
|
EAPI Eina_Error eina_error_get(void)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
2008-09-05 00:58:38 -07:00
|
|
|
return _err;
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/**
|
2008-09-05 00:58:38 -07:00
|
|
|
* @brief Set the last error.
|
|
|
|
*
|
|
|
|
* @param err The error identifier.
|
|
|
|
*
|
|
|
|
* This function sets the last error identifier. The last error can be
|
|
|
|
* retrieved with eina_error_get().
|
2008-07-30 05:46:55 -07:00
|
|
|
*/
|
2008-09-05 00:58:38 -07:00
|
|
|
EAPI void eina_error_set(Eina_Error err)
|
2008-07-30 05:46:55 -07:00
|
|
|
{
|
2008-09-05 00:58:38 -07:00
|
|
|
_err = err;
|
2008-07-30 05:46:55 -07:00
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/**
|
2008-09-05 00:58:38 -07:00
|
|
|
* @brief Print the error to a file.
|
2008-08-08 03:39:47 -07:00
|
|
|
*
|
2008-09-05 00:58:38 -07:00
|
|
|
* @param level The error level.
|
|
|
|
* @param file The name of the file where the error occurred.
|
|
|
|
* @param fnc The name of the function where the error occurred.
|
|
|
|
* @param line The number of the line where the error occurred.
|
|
|
|
* @param fmt The format to use.
|
|
|
|
*
|
|
|
|
* This function sends to a stream (like stdout or stderr) a formatted
|
|
|
|
* string that describes the error. The error level is set by
|
|
|
|
* @p level, the name of the file, of the function and the number of the
|
|
|
|
* line where the error occurred are respectively set by @p file,
|
|
|
|
* @p fnc and @p line. A description of the error message is given by
|
|
|
|
* @p fmt, which is a formatted string, followed by optional arguments
|
|
|
|
* that can be converted (like with printf). If @p level is strictly
|
|
|
|
* larger than the current error level, that function returns
|
|
|
|
* immediatly, otherwise it prints all the errors up to the current
|
|
|
|
* error level. The current error level can be changed with
|
|
|
|
* eina_error_log_level_set(). See also eina_error_init() for more
|
|
|
|
* informations.
|
|
|
|
*
|
|
|
|
* By default, that formatted message is send to stdout and is
|
|
|
|
* formatted by eina_error_print_cb_stdout(). The destination of the
|
|
|
|
* formatted message is send and the way it is formatted can be
|
|
|
|
* changed by setting a print callback with
|
|
|
|
* eina_error_print_cb_set(). Some print callbacks are already
|
|
|
|
* defined: eina_error_print_cb_stdout() that send the message to
|
|
|
|
* stdout and eina_error_print_cb_file() that sends it to a file, but
|
|
|
|
* custom print callbacks can be used. They must be of type
|
|
|
|
* #Eina_Error_Print_Cb.
|
2008-07-30 05:46:55 -07:00
|
|
|
*/
|
2008-08-08 03:39:47 -07:00
|
|
|
EAPI void eina_error_print(Eina_Error_Level level, const char *file,
|
2008-07-30 05:46:55 -07:00
|
|
|
const char *fnc, int line, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
|
2008-08-23 12:50:21 -07:00
|
|
|
if (level > _error_level)
|
|
|
|
return;
|
2008-08-28 00:46:42 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
va_start(args, fmt);
|
2008-08-23 12:50:21 -07:00
|
|
|
_print_cb(level, file, fnc, line, fmt, _print_cb_data, args);
|
2008-07-30 05:46:55 -07:00
|
|
|
va_end(args);
|
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2008-08-08 03:39:47 -07:00
|
|
|
/**
|
2008-09-06 01:48:36 -07:00
|
|
|
* @brief Print callback that sends the error message to stdout.
|
2008-09-05 00:58:38 -07:00
|
|
|
*
|
|
|
|
* @param level The error level.
|
|
|
|
* @param file The name of the file where the error occurred.
|
|
|
|
* @param fnc The name of the function where the error occurred.
|
|
|
|
* @param line The number of the line where the error occurred.
|
|
|
|
* @param fmt The format to use.
|
|
|
|
* @param data Unused.
|
|
|
|
* @param args The arguments that will be converted.
|
2008-08-08 03:39:47 -07:00
|
|
|
*
|
2008-09-05 00:58:38 -07:00
|
|
|
* This function is used to send a formatted error message to standard
|
2008-09-06 01:48:36 -07:00
|
|
|
* output and is used as a print callback, with
|
|
|
|
* eina_error_print(). This is the default print callback.
|
2008-08-08 03:39:47 -07:00
|
|
|
*/
|
|
|
|
EAPI void eina_error_print_cb_stdout(Eina_Error_Level level, const char *file,
|
2008-08-08 05:29:13 -07:00
|
|
|
const char *fnc, int line, const char *fmt, __UNUSED__ void *data,
|
2008-08-08 03:39:47 -07:00
|
|
|
va_list args)
|
|
|
|
{
|
|
|
|
printf("%s", _colors[level]);
|
|
|
|
printf("[%s:%d] %s() ", file, line, fnc);
|
|
|
|
printf("%s", _colors[EINA_ERROR_LEVEL_INFO]);
|
|
|
|
vprintf(fmt, args);
|
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2008-08-08 03:39:47 -07:00
|
|
|
/**
|
2008-09-06 01:48:36 -07:00
|
|
|
* @brief Print callback that sends the error message to a specified stream.
|
2008-09-05 00:58:38 -07:00
|
|
|
*
|
|
|
|
* @param level Unused.
|
|
|
|
* @param file The name of the file where the error occurred.
|
|
|
|
* @param fnc The name of the function where the error occurred.
|
|
|
|
* @param line The number of the line where the error occurred.
|
|
|
|
* @param fmt The format to use.
|
|
|
|
* @param data The file stream.
|
|
|
|
* @param args The arguments that will be converted.
|
2008-08-08 03:39:47 -07:00
|
|
|
*
|
2008-09-05 00:58:38 -07:00
|
|
|
* This function is used to send a formatted error message to the
|
|
|
|
* stream specified by @p data. That stream must be of type FILE *. Look
|
|
|
|
* at eina_error_print_cb_stdout() for the description of the other
|
|
|
|
* parameters. Use eina_error_print_cb_set() to set it as default
|
|
|
|
* print callback in eina_error_print().
|
2008-08-08 03:39:47 -07:00
|
|
|
*/
|
2008-08-08 05:29:13 -07:00
|
|
|
EAPI void eina_error_print_cb_file(__UNUSED__ Eina_Error_Level level, const char *file,
|
2008-08-08 03:39:47 -07:00
|
|
|
const char *fnc, int line, const char *fmt, void *data,
|
|
|
|
va_list args)
|
|
|
|
{
|
|
|
|
FILE *f = data;
|
|
|
|
|
|
|
|
fprintf(f, "[%s:%d] %s() ", file, line, fnc);
|
|
|
|
vfprintf(f, fmt, args);
|
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2008-08-08 03:39:47 -07:00
|
|
|
/**
|
2008-09-05 00:58:38 -07:00
|
|
|
* @brief Set the default print callback.
|
2008-08-08 03:39:47 -07:00
|
|
|
*
|
2008-09-05 00:58:38 -07:00
|
|
|
* @param cb The print callback.
|
|
|
|
* @param data The data to pass to the callback
|
|
|
|
*
|
2008-09-06 01:48:36 -07:00
|
|
|
* This function sets the default print callback @p cb used by
|
|
|
|
* eina_error_print(). A data can be passed to that callback with
|
2008-09-05 00:58:38 -07:00
|
|
|
* @p data.
|
2008-08-08 03:39:47 -07:00
|
|
|
*/
|
|
|
|
EAPI void eina_error_print_cb_set(Eina_Error_Print_Cb cb, void *data)
|
|
|
|
{
|
|
|
|
_print_cb = cb;
|
|
|
|
_print_cb_data = data;
|
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
2008-07-30 05:46:55 -07:00
|
|
|
/**
|
2008-09-05 00:58:38 -07:00
|
|
|
* @brief Set the default error log level.
|
|
|
|
*
|
|
|
|
* @param level The error level.
|
2008-08-01 07:26:13 -07:00
|
|
|
*
|
2008-09-06 01:48:36 -07:00
|
|
|
* This function sets the error log level @p level. It is used in
|
2008-09-05 00:58:38 -07:00
|
|
|
* eina_error_print().
|
2008-07-30 05:46:55 -07:00
|
|
|
*/
|
|
|
|
EAPI void eina_error_log_level_set(Eina_Error_Level level)
|
|
|
|
{
|
|
|
|
_error_level = level;
|
|
|
|
}
|
2008-09-05 00:58:38 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
2008-09-17 11:55:54 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|