forked from enlightenment/efl
Initial import of the new eina logging API.
* eina_error might be kept for error messages and codes, but it's logging API will be deprecated. For now, it's been kept for not breaking others code and for a smoother transition. * Added test for new logging API, also demonstrates usage. SVN revision: 41960
This commit is contained in:
parent
85ba9823e7
commit
d7bbc05b12
|
@ -3,6 +3,7 @@ MAINTAINERCLEANFILES = Makefile.in
|
|||
EINAHEADERS = \
|
||||
eina_safety_checks.h \
|
||||
eina_error.h \
|
||||
eina_log.h \
|
||||
eina_f16p16.h \
|
||||
eina_hash.h \
|
||||
eina_inline_hash.x \
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
/* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef EINA_LOG_H_
|
||||
#define EINA_LOG_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "eina_types.h"
|
||||
|
||||
#define EINA_COLOR_LIGHTRED "\033[31;1m"
|
||||
#define EINA_COLOR_RED "\033[31m"
|
||||
#define EINA_COLOR_BLUE "\033[34;1m"
|
||||
#define EINA_COLOR_GREEN "\033[32;1m"
|
||||
#define EINA_COLOR_YELLOW "\033[33;1m"
|
||||
#define EINA_COLOR_WHITE "\033[37;1m"
|
||||
#define EINA_COLOR_LIGHTBLUE "\033[36;1m"
|
||||
#define EINA_COLOR_RESET "\033[0m"
|
||||
|
||||
/**
|
||||
* @addtogroup Eina_Tools_Group Tools
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup Eina_Log_Group Log
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
EAPI extern int EINA_LOG_DOMAIN_GLOBAL;
|
||||
|
||||
|
||||
/**
|
||||
* @def EINA_LOG(DOM, LEVEL, fmt, ...)
|
||||
* Logs a message on the specified domain, level and format.
|
||||
*/
|
||||
#define EINA_LOG(DOM, LEVEL, fmt, ...) \
|
||||
eina_log_print(DOM, LEVEL, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @def EINA_LOG_DOM_CRIT(DOM, fmt, ...)
|
||||
* Logs a message with level CRITICAL on the specified domain and format.
|
||||
*/
|
||||
#define EINA_LOG_DOM_CRIT(DOM, fmt, ...) \
|
||||
EINA_LOG(DOM, EINA_LOG_LEVEL_CRITICAL, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @def EINA_LOG_DOM_ERR(DOM, fmt, ...)
|
||||
* Logs a message with level ERROR on the specified domain and format.
|
||||
*/
|
||||
#define EINA_LOG_DOM_ERR(DOM, fmt, ...) \
|
||||
EINA_LOG(DOM, EINA_LOG_LEVEL_ERR, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @def EINA_LOG_DOM_INFO(DOM, fmt, ...)
|
||||
* Logs a message with level INFO on the specified domain and format.
|
||||
*/
|
||||
#define EINA_LOG_DOM_INFO(DOM, fmt, ...) \
|
||||
EINA_LOG(DOM, EINA_LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @def EINA_LOG_DOM_DBG(DOM, fmt, ...)
|
||||
* Logs a message with level DEBUG on the specified domain and format.
|
||||
*/
|
||||
#define EINA_LOG_DOM_DBG(DOM, fmt, ...) \
|
||||
EINA_LOG(DOM, EINA_LOG_LEVEL_DBG, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @def EINA_LOG_DOM_WARN(DOM, fmt, ...)
|
||||
* Logs a message with level WARN on the specified domain and format.
|
||||
*/
|
||||
#define EINA_LOG_DOM_WARN(DOM, fmt, ...) \
|
||||
EINA_LOG(DOM, EINA_LOG_LEVEL_WARN, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @def EINA_LOG_CRIT(fmt, ...)
|
||||
* Logs a message with level CRITICAL on the global domain with the specified
|
||||
* format.
|
||||
*/
|
||||
#define EINA_LOG_CRIT(fmt, ...) \
|
||||
EINA_LOG(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @def EINA_LOG_ERR(fmt, ...)
|
||||
* Logs a message with level ERROR on the global domain with the specified
|
||||
* format.
|
||||
*/
|
||||
#define EINA_LOG_ERR(fmt, ...) \
|
||||
EINA_LOG(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_ERR, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @def EINA_LOG_INFO(fmt, ...)
|
||||
* Logs a message with level INFO on the global domain with the specified
|
||||
* format.
|
||||
*/
|
||||
#define EINA_LOG_INFO(fmt, ...) \
|
||||
EINA_LOG(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @def EINA_LOG_WARN(fmt, ...)
|
||||
* Logs a message with level WARN on the global domain with the specified
|
||||
* format.
|
||||
*/
|
||||
#define EINA_LOG_WARN(fmt, ...) \
|
||||
EINA_LOG(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_WARN, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @def EINA_LOG_DBG(fmt, ...)
|
||||
* Logs a message with level DEBUG on the global domain with the specified
|
||||
* format.
|
||||
*/
|
||||
#define EINA_LOG_DBG(fmt, ...) \
|
||||
EINA_LOG(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_DBG, fmt, ##__VA_ARGS__)
|
||||
|
||||
typedef struct _Eina_Log_Domain Eina_Log_Domain;
|
||||
|
||||
struct _Eina_Log_Domain
|
||||
{
|
||||
int level; /**< Max level to log */
|
||||
const char *domain_str; /**< Formatted string with color to print */
|
||||
const char *name; /**< Domain name */
|
||||
|
||||
/* Private */
|
||||
Eina_Bool deleted:1; /**< Flags deletion of domain, a free slot */
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef Eina_Log_Level
|
||||
* List of available logging levels.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @enum _Eina_Log_Level
|
||||
* List of available logging levels.
|
||||
*/
|
||||
typedef enum _Eina_Log_Level
|
||||
{
|
||||
EINA_LOG_LEVEL_CRITICAL, /**< Critical log level */
|
||||
EINA_LOG_LEVEL_ERR, /**< Error log level */
|
||||
EINA_LOG_LEVEL_WARN, /**< Warning log level */
|
||||
EINA_LOG_LEVEL_INFO, /**< Information log level */
|
||||
EINA_LOG_LEVEL_DBG, /**< Debug log level */
|
||||
EINA_LOG_LEVELS, /**< Count of default log levels */
|
||||
EINA_LOG_LEVEL_UNKNOWN = INT32_MIN /**< Unknown level */
|
||||
} Eina_Log_Level;
|
||||
|
||||
/**
|
||||
* @typedef Eina_Log_Print_Cb
|
||||
* Type for print callbacks.
|
||||
*/
|
||||
typedef void (*Eina_Log_Print_Cb)(const Eina_Log_Domain *d, Eina_Log_Level level,
|
||||
const char *file, const char *fnc, int line,
|
||||
const char *fmt, void *data, va_list args);
|
||||
|
||||
/**
|
||||
* @var EINA_LOG_OUT_OF_MEMORY
|
||||
* Log identifier corresponding to a lack of memory.
|
||||
*/
|
||||
EAPI extern int EINA_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
EAPI int eina_log_init(void);
|
||||
EAPI int eina_log_shutdown(void);
|
||||
|
||||
/*
|
||||
* Customization
|
||||
*/
|
||||
EAPI void eina_log_print_cb_set(Eina_Log_Print_Cb cb, void *data) EINA_ARG_NONNULL(1);
|
||||
EAPI void eina_log_level_set(Eina_Log_Level level);
|
||||
|
||||
/*
|
||||
* Logging domains
|
||||
*/
|
||||
EAPI int eina_log_domain_register(const char *name, const char *color) EINA_ARG_NONNULL(1);
|
||||
EAPI void eina_log_domain_unregister(int domain);
|
||||
|
||||
EAPI void eina_log_print(int domain, Eina_Log_Level level, const char *file, const char *function, int line, const char *fmt, ...) EINA_ARG_NONNULL(2, 3, 5);
|
||||
EAPI void eina_log_print_cb_stdout(const Eina_Log_Domain *d, Eina_Log_Level level, const char *file, const char *fnc, int line, const char *fmt, void *data, va_list args);
|
||||
EAPI void eina_log_print_cb_file(const Eina_Log_Domain *d, Eina_Log_Level level, const char *file, const char *fnc, int line, const char *fmt, void *data, va_list args);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* EINA_LOG_H_ */
|
|
@ -12,6 +12,7 @@ lib_LTLIBRARIES = libeina.la
|
|||
|
||||
libeina_la_SOURCES = \
|
||||
eina_error.c \
|
||||
eina_log.c \
|
||||
eina_hash.c \
|
||||
eina_lalloc.c \
|
||||
eina_inlist.c \
|
||||
|
|
|
@ -0,0 +1,820 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2007-2009 Jorge Luis Zapata Muga, Cedric Bail, Andre Dieb
|
||||
* Martins
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @page tutorial_log_page log Tutorial
|
||||
*
|
||||
* @section tutorial_log_introduction Introduction
|
||||
*
|
||||
* The Eina Log module provides logging facilities for libraries and
|
||||
* applications. It provides colored logging, basic logging levels (error,
|
||||
* warning, debug, info, critical) and loggers - called logging domains -
|
||||
* which will be covered on next sections.
|
||||
*
|
||||
* @section tutorial_log_basic_usage Basic Usage
|
||||
*
|
||||
* The first thing to do when using the log module is to initialize
|
||||
* it with eina_log_init() and when the log module is not used
|
||||
* anymore, shut it down with eina_log_shutdown(). Here's a basic example:
|
||||
*
|
||||
* @code
|
||||
* #include <stdlib.h>
|
||||
* #include <stdio.h>
|
||||
*
|
||||
* #include <eina_log.h>
|
||||
*
|
||||
* int main(void)
|
||||
* {
|
||||
* if (!eina_log_init())
|
||||
* {
|
||||
* printf ("Error initializing Eina Log module\n");
|
||||
* return EXIT_FAILURE;
|
||||
* }
|
||||
*
|
||||
* eina_log_shutdown();
|
||||
*
|
||||
* return EXIT_SUCCESS;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* Every 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
|
||||
*
|
||||
* After the module has been initialized, log messages can be displayed using
|
||||
* the following macros:
|
||||
*
|
||||
* @li EINA_LOG_ERR(),
|
||||
* @li EINA_LOG_INFO(),
|
||||
* @li EINA_LOG_WARN(),
|
||||
* @li EINA_LOG_DBG().
|
||||
*
|
||||
* Here is an example:
|
||||
*
|
||||
* @code
|
||||
* #include <stdlib.h>
|
||||
* #include <stdio.h>
|
||||
*
|
||||
* #include <eina_log.h>
|
||||
*
|
||||
* void test(int i)
|
||||
* {
|
||||
* EINA_LOG_DBG("Entering test\n");
|
||||
*
|
||||
* if (i < 0)
|
||||
* {
|
||||
* EINA_LOG_ERR("Argument is negative\n");
|
||||
* return;
|
||||
* }
|
||||
*
|
||||
* EINA_LOG_INFO("argument non negative\n");
|
||||
*
|
||||
* EINA_LOG_DBG("Exiting test\n");
|
||||
* }
|
||||
*
|
||||
* int main(void)
|
||||
* {
|
||||
* if (!eina_log_init())
|
||||
* {
|
||||
* printf ("log during the initialization of Eina_Log module\n");
|
||||
* return EXIT_FAILURE;
|
||||
* }
|
||||
*
|
||||
* test(-1);
|
||||
* test(0);
|
||||
*
|
||||
* eina_log_shutdown();
|
||||
*
|
||||
* return EXIT_SUCCESS;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* If you compiled Eina without debug mode, execution will yield only one log
|
||||
* message, which is "argument is negative".
|
||||
*
|
||||
* Here we introduce the concept of logging domains (or loggers), which might
|
||||
* already be familiar to readers. It is basically a way to separate a set of
|
||||
* log messages into a context (e.g. a module) and provide a way of controlling
|
||||
* this set as a whole.
|
||||
*
|
||||
* For example, suppose you have 3 different modules on your application and you
|
||||
* want to get logging only from one of them (e.g. create some sort of filter).
|
||||
* For achieving that, all you need to do is create a logging domain for each
|
||||
* module so that all logging inside a module can be considered as a whole.
|
||||
*
|
||||
* Logging domains are specified by a name, color applied to the name and the
|
||||
* level. The first two (name and color) are set through code, that is, inside
|
||||
* your application/module/library.
|
||||
*
|
||||
* The level is used for controlling which messages should appear. It
|
||||
* specifies the lowest level that should be displayed (e.g. a message
|
||||
* with level 11 being logged on a domain with level set to 10 would be
|
||||
* displayed, while a message with level 9 wouldn't).
|
||||
*
|
||||
* The domain level is set during runtime (in contrast with the name and
|
||||
* color) through the environment variable EINA_LOG_LEVELS. This variable
|
||||
* expects a list in the form domain_name1:level1,domain_name2:level2,... . For
|
||||
* example:
|
||||
*
|
||||
* @code
|
||||
*
|
||||
* EINA_LOG_LEVELS=mymodule1:5,mymodule2:2,mymodule3:0 ./myapp
|
||||
*
|
||||
* @encode
|
||||
*
|
||||
* This line would set mymodule1 level to 5, mymodule2 level to 2 and mymodule3
|
||||
* level to 0.
|
||||
*
|
||||
*
|
||||
* There's also a global logger to which EINA_LOG_(ERR, DBG, INFO, CRIT, WARN)
|
||||
* macros do log on. It is a logger that is created internally by Eina Log with
|
||||
* an empty name and can be used for general logging (where logging domains do
|
||||
* not apply).
|
||||
*
|
||||
* Since this global logger doesn't have a name, you can't set its level through
|
||||
* EINA_LOG_LEVELS variable. Here we introduce a second environment variable
|
||||
* that is a bit more special: EINA_LOG_LEVEL.
|
||||
*
|
||||
* This variable specifies the level of the global logging domain and the level
|
||||
* of domains that haven't been set through EINA_LOG_LEVELS. Here's an example:
|
||||
*
|
||||
* @code
|
||||
*
|
||||
* EINA_LOG_LEVEL=3 EINA_LOG_LEVELS=module1:10,module3:2 ./myapp
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* Supposing you have modules named "module1", "module2" and "module3", this
|
||||
* line would result in module1 with level 10, module2 with level 3 and module3
|
||||
* with level 2. Note that module2's level wasn't specified, so it's level is
|
||||
* set to the global level. This way we can easily apply filters to multiple
|
||||
* domains with only one parameter (EINA_LOG_LEVEL=num).
|
||||
*
|
||||
* The global level (EINA_LOG_LEVEL) can also be set through code, using
|
||||
* eina_log_level_set() function.
|
||||
*
|
||||
* // TODO rewrite this section
|
||||
* @section tutorial_log_advanced_display Advanced usage of print callbacks
|
||||
*
|
||||
* The log module allows the user to change the way
|
||||
* eina_log_print() displays the messages. It suffices to pass to
|
||||
* eina_log_print_cb_set() the function used to display the
|
||||
* message. That function must be of type #Eina_log_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_LOG_ERR() 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_log.h>
|
||||
*
|
||||
* #define log(fmt, ...) \
|
||||
* eina_log_print(EINA_LOG_LEVEL_ERR, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
*
|
||||
* typedef struct _Data Data;
|
||||
*
|
||||
* struct _Data
|
||||
* {
|
||||
* int to_stderr;
|
||||
* };
|
||||
*
|
||||
* void print_cb(Eina_Log_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;
|
||||
*
|
||||
* log("log message...\n");
|
||||
* }
|
||||
*
|
||||
* int main(void)
|
||||
* {
|
||||
* Data *data;
|
||||
*
|
||||
* if (!eina_log_init())
|
||||
* {
|
||||
* printf ("log during the initialization of Eina_Log module\n");
|
||||
* return EXIT_FAILURE;
|
||||
* }
|
||||
*
|
||||
* data = (Data *)malloc(sizeof(Data));
|
||||
* if (!data)
|
||||
* {
|
||||
* printf ("log during memory allocation\n");
|
||||
* eina_log_shutdown();
|
||||
* return EXIT_FAILURE;
|
||||
* }
|
||||
*
|
||||
* eina_log_print_cb_set(print_cb, data);
|
||||
*
|
||||
* test(data, -1);
|
||||
* test(data, 0);
|
||||
*
|
||||
* eina_log_shutdown();
|
||||
*
|
||||
* return EXIT_SUCCESS;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* Of course, instead of printf(), eina_log_print() can be used to
|
||||
* have beautiful log messages.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_EVIL
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include "eina_log.h"
|
||||
#include "eina_inlist.h"
|
||||
#include "eina_private.h"
|
||||
#include "eina_safety_checks.h"
|
||||
|
||||
/* TODO
|
||||
* + printing logs to stdout or stderr can be implemented
|
||||
* using a queue, useful for multiple threads printing
|
||||
* + add a wrapper for assert?
|
||||
* + improve doc
|
||||
*/
|
||||
|
||||
/*============================================================================*
|
||||
* Local *
|
||||
*============================================================================*/
|
||||
|
||||
/**
|
||||
* @cond LOCAL
|
||||
*/
|
||||
|
||||
#define EINA_LOG_ENV_ABORT "EINA_LOG_ABORT"
|
||||
#define EINA_LOG_ENV_LEVEL "EINA_LOG_LEVEL"
|
||||
#define EINA_LOG_ENV_LEVELS "EINA_LOG_LEVELS"
|
||||
#define EINA_LOG_ENV_COLOR_DISABLE "EINA_LOG_COLOR_DISABLE"
|
||||
|
||||
|
||||
// Structure for storing domain level settings passed from the command line
|
||||
// that will be matched with application-defined domains.
|
||||
typedef struct _Eina_Log_Domain_Level_Pending Eina_Log_Domain_Level_Pending;
|
||||
struct _Eina_Log_Domain_Level_Pending
|
||||
{
|
||||
EINA_INLIST;
|
||||
unsigned int level;
|
||||
char name[];
|
||||
};
|
||||
|
||||
/*
|
||||
* List of levels for domains set by the user before the domains are registered,
|
||||
* updates the domain levels on the first log and clears itself.
|
||||
*/
|
||||
static Eina_Inlist *_pending_list = NULL;
|
||||
|
||||
// Initialization counter
|
||||
static int _eina_log_init_count = 0;
|
||||
|
||||
// Disable color flag (can be changed through the env var
|
||||
// EINA_LOG_ENV_COLOR_DISABLE).
|
||||
static Eina_Bool _disable_color = EINA_FALSE;
|
||||
|
||||
// List of domains registered
|
||||
static Eina_Log_Domain *_log_domains = NULL;
|
||||
static int _log_domains_count = 0;
|
||||
static int _log_domains_allocated = 0;
|
||||
|
||||
// Default function for printing on domains
|
||||
static Eina_Log_Print_Cb _print_cb = eina_log_print_cb_stdout;
|
||||
static void *_print_cb_data = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
static Eina_Log_Level _log_level = EINA_LOG_LEVEL_DBG;
|
||||
#elif DEBUG_CRITICAL
|
||||
static Eina_Log_Level _log_level = EINA_LOG_LEVEL_CRITICAL;
|
||||
#else
|
||||
static Eina_Log_Level _log_level = EINA_LOG_LEVEL_ERR;
|
||||
#endif
|
||||
|
||||
// Default colors and levels
|
||||
static const char *_colors[EINA_LOG_LEVELS + 1] = { // + 1 for higher than debug
|
||||
EINA_COLOR_LIGHTRED, // EINA_LOG_LEVEL_CRITICAL
|
||||
EINA_COLOR_RED, // EINA_LOG_LEVEL_ERR
|
||||
EINA_COLOR_YELLOW, // EINA_LOG_LEVEL_WARN
|
||||
EINA_COLOR_GREEN, // EINA_LOG_LEVEL_INFO
|
||||
EINA_COLOR_LIGHTBLUE, // EINA_LOG_LEVEL_DBG
|
||||
EINA_COLOR_BLUE, // Higher than DEBUG
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a colored domain name string.
|
||||
*/
|
||||
static const char *
|
||||
eina_log_domain_str_get(const char *name, const char *color)
|
||||
{
|
||||
const char *d;
|
||||
|
||||
if (color)
|
||||
{
|
||||
int name_len = strlen(name);
|
||||
int color_len = strlen(color);
|
||||
d = malloc(sizeof(char) * (color_len + name_len + strlen(EINA_COLOR_RESET) + 1));
|
||||
if (!d) return NULL;
|
||||
memcpy((char *)d, color, color_len);
|
||||
memcpy((char *)(d + color_len), name, name_len);
|
||||
memcpy((char *)(d + color_len + name_len), EINA_COLOR_RESET, strlen(EINA_COLOR_RESET));
|
||||
((char *)d)[color_len + name_len + strlen(EINA_COLOR_RESET)] = '\0';
|
||||
}
|
||||
else
|
||||
d = strdup(name);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setups a new logging domain to the name and color specified. Note that this
|
||||
* constructor acts upon an pre-allocated object.
|
||||
*/
|
||||
static Eina_Log_Domain *
|
||||
eina_log_domain_new(Eina_Log_Domain *d, const char *name, const char *color)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
|
||||
d->level = EINA_LOG_LEVEL_UNKNOWN;
|
||||
d->deleted = EINA_FALSE;
|
||||
|
||||
if (name)
|
||||
{
|
||||
if ((color) && (!_disable_color))
|
||||
d->domain_str = eina_log_domain_str_get(name, color);
|
||||
else
|
||||
d->domain_str = eina_log_domain_str_get(name, NULL);
|
||||
|
||||
d->name = strdup(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
d->domain_str = NULL;
|
||||
d->name = NULL;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees internal strings of a log domain, keeping the log domain itself as a
|
||||
* slot for next domain registers.
|
||||
*/
|
||||
static void
|
||||
eina_log_domain_free(Eina_Log_Domain *d)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(d);
|
||||
|
||||
if (d->domain_str)
|
||||
free((char *)d->domain_str);
|
||||
if (d->name)
|
||||
free((char *)d->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses domain levels passed through the env var.
|
||||
*/
|
||||
static void
|
||||
eina_log_domain_parse_pendings(void)
|
||||
{
|
||||
const char *start;
|
||||
|
||||
if (!(start = getenv(EINA_LOG_ENV_LEVELS))) return;
|
||||
|
||||
// name1:level1,name2:level2,name3:level3,...
|
||||
while (1)
|
||||
{
|
||||
Eina_Log_Domain_Level_Pending *p;
|
||||
char *end = NULL;
|
||||
char *tmp = NULL;
|
||||
int level;
|
||||
end = strchr(start, ':');
|
||||
if (!end) break;
|
||||
|
||||
// Parse level, keep going if failed
|
||||
level = strtol((char *)(end + 1), &tmp, 10);
|
||||
if (tmp == (end + 1)) goto parse_end;
|
||||
|
||||
// Parse name
|
||||
p = malloc(sizeof(Eina_Log_Domain_Level_Pending) + end - start + 1);
|
||||
if (!p) break;
|
||||
memcpy((char *)p->name, start, end - start);
|
||||
((char *)p->name)[end - start] = '\0';
|
||||
p->level = level;
|
||||
|
||||
_pending_list = eina_inlist_append(_pending_list, EINA_INLIST_GET(p));
|
||||
|
||||
parse_end:
|
||||
start = strchr(tmp, ',');
|
||||
if (start) start++;
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
|
||||
/*============================================================================*
|
||||
* Global *
|
||||
*============================================================================*/
|
||||
|
||||
/*============================================================================*
|
||||
* API *
|
||||
*============================================================================*/
|
||||
|
||||
/**
|
||||
* @addtogroup Eina_Log_Group log
|
||||
*
|
||||
* @brief These functions provide log management for projects.
|
||||
*
|
||||
* The log system must be initialized with eina_log_init() and
|
||||
* shut down with eina_log_shutdown(). The most generic way to print
|
||||
* logs is to use eina_log_print() but the helper macros
|
||||
* EINA_LOG_ERR(), EINA_LOG_INFO(), EINA_LOG_WARN() and
|
||||
* EINA_LOG_DBG() should be used instead.
|
||||
*
|
||||
* Here is a straightforward example:
|
||||
*
|
||||
* @code
|
||||
* #include <stdlib.h>
|
||||
* #include <stdio.h>
|
||||
*
|
||||
* #include <eina_log.h>
|
||||
*
|
||||
* void test_warn(void)
|
||||
* {
|
||||
* EINA_LOG_WARN("Here is a warning message\n");
|
||||
* }
|
||||
*
|
||||
* int main(void)
|
||||
* {
|
||||
* if (!eina_log_init())
|
||||
* {
|
||||
* printf ("log during the initialization of Eina_Log module\n");
|
||||
* return EXIT_FAILURE;
|
||||
* }
|
||||
*
|
||||
* test_warn();
|
||||
*
|
||||
* eina_log_shutdown();
|
||||
*
|
||||
* return EXIT_SUCCESS;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* Compile this code with the following command:
|
||||
*
|
||||
* @code
|
||||
* gcc -Wall -o test_Eina_Log 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 log level
|
||||
* is #EINA_LOG_LEVEL_ERR and we want to display a warning
|
||||
* message, which level is strictly greater than the log level (see
|
||||
* eina_log_print() for more informations). Now execute the program
|
||||
* with:
|
||||
*
|
||||
* @code
|
||||
* EINA_log_LEVEL=2 ./test_eina_log
|
||||
* @endcode
|
||||
*
|
||||
* You should see a message displayed in the terminal.
|
||||
*
|
||||
* For more information, you can look at the @ref tutorial_log_page.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @cond LOCAL
|
||||
*/
|
||||
|
||||
EAPI int EINA_LOG_DOMAIN_GLOBAL = 0;
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the log module.
|
||||
*
|
||||
* @return 1 or greater on success, 0 on log.
|
||||
*
|
||||
* This function sets up the log module of Eina. It is called by
|
||||
* eina_init() and by all modules initialization functions. It returns
|
||||
* @c 0 on failure, otherwise it returns the number of times it is
|
||||
* called.
|
||||
*
|
||||
* The default log level value is set by default to
|
||||
* #EINA_LOG_LEVEL_DBG if Eina is compiled with debug mode, or to
|
||||
* #EINA_LOG_LEVEL_ERR otherwise. That value can be overwritten by
|
||||
* setting the environment variable EINA_log_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
|
||||
* log levels #EINA_LOG_LEVEL_ERR, #EINA_LOG_LEVEL_WARN,
|
||||
* #EINA_LOG_LEVEL_INFO and #EINA_LOG_LEVEL_DBG. That value can
|
||||
* also be set later with eina_log_log_level_set().
|
||||
*
|
||||
* Once the log module is not used anymore, then
|
||||
* eina_log_shutdown() must be called to shut down the log
|
||||
* module.
|
||||
*
|
||||
* @see eina_init()
|
||||
*/
|
||||
EAPI int
|
||||
eina_log_init(void)
|
||||
{
|
||||
if (_eina_log_init_count) return ++_eina_log_init_count;
|
||||
|
||||
char *level;
|
||||
char *tmp;
|
||||
|
||||
// Check if color is disabled
|
||||
if ((tmp = getenv(EINA_LOG_ENV_COLOR_DISABLE)) && (atoi(tmp) == 1))
|
||||
_disable_color = EINA_TRUE;
|
||||
|
||||
// Global log level
|
||||
if ((level = getenv(EINA_LOG_ENV_LEVEL)))
|
||||
_log_level = atoi(level);
|
||||
else
|
||||
_log_level = EINA_LOG_LEVEL_ERR;
|
||||
|
||||
// Register UNKNOWN domain, the default logger
|
||||
EINA_LOG_DOMAIN_GLOBAL = eina_log_domain_register("", NULL);
|
||||
|
||||
if (EINA_LOG_DOMAIN_GLOBAL < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to create global logging domain.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse pending domains passed through EINA_LOG_LEVELS
|
||||
eina_log_domain_parse_pendings();
|
||||
|
||||
return ++_eina_log_init_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shut down the log module.
|
||||
*
|
||||
* @return 0 when the log module is completely shut down, 1 or
|
||||
* greater otherwise.
|
||||
*
|
||||
* This function shuts down the log module set up by
|
||||
* eina_log_init(). It is called by eina_shutdown() and by all
|
||||
* modules shutdown functions. It returns 0 when it is called the
|
||||
* same number of times than eina_log_init(). In that case it clears
|
||||
* the log list.
|
||||
*
|
||||
* @see eina_shutdown()
|
||||
*/
|
||||
EAPI int
|
||||
eina_log_shutdown(void)
|
||||
{
|
||||
if (_eina_log_init_count != 1) return --_eina_log_init_count;
|
||||
|
||||
Eina_Inlist *tmp;
|
||||
|
||||
while (_log_domains_count--)
|
||||
{
|
||||
if (_log_domains[_log_domains_count].deleted)
|
||||
continue;
|
||||
eina_log_domain_free(&_log_domains[_log_domains_count]);
|
||||
}
|
||||
|
||||
free(_log_domains);
|
||||
|
||||
_log_domains = NULL;
|
||||
|
||||
while (_pending_list)
|
||||
{
|
||||
tmp = _pending_list;
|
||||
_pending_list = _pending_list->next;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
return --_eina_log_init_count;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eina_log_print_cb_set(Eina_Log_Print_Cb cb, void *data)
|
||||
{
|
||||
_print_cb = cb;
|
||||
_print_cb_data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the default log log level.
|
||||
*
|
||||
* @param level The log level.
|
||||
*
|
||||
* This function sets the log log level @p level. It is used in
|
||||
* eina_log_print().
|
||||
*/
|
||||
EAPI void eina_log_level_set(Eina_Log_Level level)
|
||||
{
|
||||
_log_level = level;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param name Domain name
|
||||
* @param color Color of the domain name
|
||||
*
|
||||
* @return Domain index that will be used as the DOMAIN parameter on log
|
||||
* macros. A negative return value means an log ocurred.
|
||||
*/
|
||||
EAPI int
|
||||
eina_log_domain_register(const char *name, const char *color)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, -1);
|
||||
|
||||
Eina_Log_Domain_Level_Pending *pending = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _log_domains_count; i++)
|
||||
{
|
||||
if (_log_domains[i].deleted)
|
||||
{
|
||||
// Found a flagged slot, free domain_str and replace slot
|
||||
eina_log_domain_new(&_log_domains[i], name, color);
|
||||
goto finish_register;
|
||||
}
|
||||
}
|
||||
|
||||
if (_log_domains_count >= _log_domains_allocated)
|
||||
{
|
||||
// Did not found a slot, realloc 8 more slots. Also works on the first time
|
||||
// when the array doesn't exist yet.
|
||||
Eina_Log_Domain *tmp = NULL;
|
||||
|
||||
tmp = realloc(_log_domains, sizeof(Eina_Log_Domain)*(_log_domains_allocated + 8));
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
// Success!
|
||||
_log_domains = tmp;
|
||||
_log_domains_allocated += 8;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Use an allocated slot
|
||||
eina_log_domain_new(&_log_domains[i], name, color);
|
||||
_log_domains_count++;
|
||||
|
||||
finish_register:
|
||||
EINA_INLIST_FOREACH(_pending_list, pending)
|
||||
{
|
||||
if (!strcmp(pending->name, name))
|
||||
{
|
||||
_log_domains[i].level = pending->level;
|
||||
_pending_list = eina_inlist_remove(_pending_list, EINA_INLIST_GET(pending));
|
||||
free(pending);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if level is still UNKNOWN, set it to global
|
||||
if (_log_domains[i].level == EINA_LOG_LEVEL_UNKNOWN)
|
||||
_log_domains[i].level = _log_level;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eina_log_domain_unregister(int domain)
|
||||
{
|
||||
if (domain >= _log_domains_count) return;
|
||||
|
||||
Eina_Log_Domain *d = &_log_domains[domain];
|
||||
eina_log_domain_free(d);
|
||||
d->deleted = 1;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eina_log_print_cb_stdout(const Eina_Log_Domain *d, Eina_Log_Level level,
|
||||
const char *file, const char *fnc, int line, const char *fmt,
|
||||
__UNUSED__ void *data, va_list args)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(d);
|
||||
|
||||
// Normalize levels for printing. Negative leveled messages go will have
|
||||
// same color as CRITICAL and higher than debug will be regular blue.
|
||||
if (level < 0) level = 0;
|
||||
else if (level > 4) level = 5;
|
||||
|
||||
printf("%s %s%s:%d %s()%s ", d->domain_str,
|
||||
(!_disable_color) ? _colors[level] : "",
|
||||
file, line, fnc,
|
||||
(!_disable_color) ? EINA_COLOR_RESET: "");
|
||||
vprintf(fmt, args);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eina_log_print_cb_file(const Eina_Log_Domain *d, __UNUSED__ Eina_Log_Level level,
|
||||
const char *file, const char *fnc, int line, const char *fmt,
|
||||
void *data, va_list args)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(file);
|
||||
EINA_SAFETY_ON_NULL_RETURN(fnc);
|
||||
EINA_SAFETY_ON_NULL_RETURN(fmt);
|
||||
|
||||
FILE *f = data;
|
||||
fprintf(f, "%s %s:%d %s() ", d->name, file, line, fnc);
|
||||
vfprintf(f, fmt, args);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eina_log_print(int domain, Eina_Log_Level level, const char *file,
|
||||
const char *fnc, int line, const char *fmt, ...)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(file);
|
||||
EINA_SAFETY_ON_NULL_RETURN(fnc);
|
||||
EINA_SAFETY_ON_NULL_RETURN(fmt);
|
||||
|
||||
if (domain >= _log_domains_count) return;
|
||||
if (domain < 0) return;
|
||||
|
||||
Eina_Log_Domain *d = &_log_domains[domain];
|
||||
|
||||
if (level > d->level) return;
|
||||
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
_print_cb(d, level, file, fnc, line, fmt, _print_cb_data, args);
|
||||
va_end(args);
|
||||
|
||||
if ((getenv(EINA_LOG_ENV_ABORT) && level <= EINA_LOG_LEVEL_CRITICAL))
|
||||
abort();
|
||||
}
|
|
@ -48,7 +48,8 @@ eina_suite_SOURCES = \
|
|||
eina_suite.c \
|
||||
eina_test_stringshare.c \
|
||||
eina_test_array.c \
|
||||
eina_test_error.c \
|
||||
eina_test_error.c \
|
||||
eina_test_log.c \
|
||||
eina_test_magic.c \
|
||||
eina_test_inlist.c \
|
||||
eina_test_main.c \
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "eina_suite.h"
|
||||
#include "eina_mempool.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct _Eina_Test_Case Eina_Test_Case;
|
||||
struct _Eina_Test_Case
|
||||
|
@ -34,6 +35,7 @@ struct _Eina_Test_Case
|
|||
static const Eina_Test_Case etc[] = {
|
||||
{ "Array", eina_test_array },
|
||||
{ "String Share", eina_test_stringshare },
|
||||
{ "Log", eina_test_log },
|
||||
{ "Error", eina_test_error },
|
||||
{ "Magic", eina_test_magic },
|
||||
{ "Inlist", eina_test_inlist },
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
void eina_test_stringshare(TCase *tc);
|
||||
void eina_test_array(TCase *tc);
|
||||
void eina_test_log(TCase *tc);
|
||||
void eina_test_error(TCase *tc);
|
||||
void eina_test_magic(TCase *tc);
|
||||
void eina_test_inlist(TCase *tc);
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2008 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/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "eina_suite.h"
|
||||
#include "eina_log.h"
|
||||
|
||||
START_TEST(eina_log_init_shutdown)
|
||||
{
|
||||
int initial_level = eina_log_init() - 1;
|
||||
fail_if(!(initial_level+1));
|
||||
|
||||
fail_if(!eina_log_init());
|
||||
fail_if(!eina_log_shutdown());
|
||||
fail_if(!eina_log_init());
|
||||
fail_if(!eina_log_init());
|
||||
fail_if(!eina_log_shutdown());
|
||||
fail_if(!eina_log_shutdown());
|
||||
|
||||
fail_if(initial_level != eina_log_shutdown());
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eina_log_macro)
|
||||
{
|
||||
fail_if(!eina_log_init());
|
||||
|
||||
eina_log_level_set(EINA_LOG_LEVEL_DBG);
|
||||
eina_log_print_cb_set(eina_log_print_cb_file, stderr);
|
||||
|
||||
EINA_LOG_CRIT("Critical message\n");
|
||||
EINA_LOG_ERR("An error\n");
|
||||
EINA_LOG_INFO("An info\n");
|
||||
EINA_LOG_WARN("A warning\n");
|
||||
EINA_LOG_DBG("A debug\n");
|
||||
|
||||
eina_log_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eina_log_domains_macros)
|
||||
{
|
||||
fail_if(!eina_log_init());
|
||||
|
||||
int d = eina_log_domain_register("MyDomain", EINA_COLOR_GREEN);
|
||||
fail_if(d < 0);
|
||||
|
||||
EINA_LOG_DOM_CRIT(d, "A critical message\n");
|
||||
EINA_LOG_DOM_ERR(d, "An error\n");
|
||||
EINA_LOG_DOM_WARN(d, "A warning\n");
|
||||
EINA_LOG_DOM_DBG(d, "A debug\n");
|
||||
EINA_LOG_DOM_INFO(d, "An info\n");
|
||||
|
||||
eina_log_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eina_log_domains_registry)
|
||||
{
|
||||
fail_if(!eina_log_init());
|
||||
|
||||
int i;
|
||||
int d[50];
|
||||
|
||||
for (i = 0; i < 50; i++)
|
||||
{
|
||||
d[i] = eina_log_domain_register("Test", EINA_COLOR_GREEN);
|
||||
fail_if(d[i] < 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < 50; i++)
|
||||
eina_log_domain_unregister(d[i]);
|
||||
|
||||
eina_log_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eina_log_domains_slot_reuse)
|
||||
{
|
||||
fail_if(!eina_log_init());
|
||||
|
||||
// Create 9 domains
|
||||
int idx[9];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
idx[i] = eina_log_domain_register("Test1", EINA_COLOR_GREEN);
|
||||
fail_if(idx[i] < 0);
|
||||
}
|
||||
|
||||
// Slot 0 by default contains the global logger. The above code created
|
||||
// domains for slots indexes from 1 to 9.
|
||||
//
|
||||
// The global logger allocated the first 8 initial slots. The 8th domain
|
||||
// registered on the for loop will create 8 more slots.
|
||||
//
|
||||
// Test will just unregister a domain between 1 and 9 and assure that a new
|
||||
// domain register will be placed on the available slot and not at the end.
|
||||
|
||||
int removed = idx[5];
|
||||
eina_log_domain_unregister(removed);
|
||||
|
||||
int new = eina_log_domain_register("Test Slot", EINA_COLOR_GREEN);
|
||||
|
||||
// Check for slot reuse
|
||||
fail_if(new != removed);
|
||||
|
||||
eina_log_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eina_log_level_indexes)
|
||||
{
|
||||
fail_if(!eina_log_init());
|
||||
|
||||
int d = eina_log_domain_register("Levels", EINA_COLOR_GREEN);
|
||||
fail_if(d < 0);
|
||||
|
||||
// Displayed unless user sets level lower than -1
|
||||
EINA_LOG(d, -1, "Negative index message\n");
|
||||
|
||||
// Displayed only if user sets level 6 or higher
|
||||
EINA_LOG(d, 6, "Higher level debug\n");
|
||||
|
||||
eina_log_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
void
|
||||
eina_test_log(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, eina_log_init_shutdown);
|
||||
tcase_add_test(tc, eina_log_macro);
|
||||
tcase_add_test(tc, eina_log_domains_macros);
|
||||
tcase_add_test(tc, eina_log_domains_registry);
|
||||
tcase_add_test(tc, eina_log_domains_slot_reuse);
|
||||
tcase_add_test(tc, eina_log_level_indexes);
|
||||
}
|
Loading…
Reference in New Issue