From f7cd9786f16d04ab097e6e4e0f26e562c4a66b08 Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Tue, 9 Feb 2010 00:52:00 +0000 Subject: [PATCH] eina log parameters getters and setters. allow external users to check or set flags that are initialized based on environment variables such as EINA_LOG_COLOR_DISABLE. SVN revision: 45995 --- legacy/eina/src/include/eina_log.h | 24 +- legacy/eina/src/lib/eina_log.c | 327 +++++++++++++++++++++++++- legacy/eina/src/tests/eina_test_log.c | 53 +++++ 3 files changed, 399 insertions(+), 5 deletions(-) diff --git a/legacy/eina/src/include/eina_log.h b/legacy/eina/src/include/eina_log.h index 1cd4b2abd0..ccdafb6a82 100644 --- a/legacy/eina/src/include/eina_log.h +++ b/legacy/eina/src/include/eina_log.h @@ -200,8 +200,28 @@ typedef void (*Eina_Log_Print_Cb)(const Eina_Log_Domain *d, Eina_Log_Level level /* * 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); +EAPI void eina_log_print_cb_set(Eina_Log_Print_Cb cb, void *data) EINA_ARG_NONNULL(1); + +EAPI void eina_log_level_set(int level); +EAPI int eina_log_level_get(void) EINA_WARN_UNUSED_RESULT; + +EAPI Eina_Bool eina_log_main_thread_check(void) EINA_CONST EINA_WARN_UNUSED_RESULT; + +EAPI void eina_log_color_disable_set(Eina_Bool disabled); +EAPI Eina_Bool eina_log_color_disable_get(void) EINA_WARN_UNUSED_RESULT; +EAPI void eina_log_file_disable_set(Eina_Bool disabled); +EAPI Eina_Bool eina_log_file_disable_get(void) EINA_WARN_UNUSED_RESULT; +EAPI void eina_log_function_disable_set(Eina_Bool disabled); +EAPI Eina_Bool eina_log_function_disable_get(void) EINA_WARN_UNUSED_RESULT; +EAPI void eina_log_abort_on_critical_set(Eina_Bool abort_on_critical); +EAPI Eina_Bool eina_log_abort_on_critical_get(void) EINA_WARN_UNUSED_RESULT; +EAPI void eina_log_abort_on_critical_level_set(int critical_level); +EAPI int eina_log_abort_on_critical_level_get(void) EINA_WARN_UNUSED_RESULT; + +EAPI void eina_log_domain_level_set(const char *domain_name, int level) EINA_ARG_NONNULL(1); +EAPI int eina_log_domain_level_get(const char *domain_name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); +EAPI int eina_log_domain_registered_level_get(int domain) EINA_WARN_UNUSED_RESULT; + /* * Logging domains diff --git a/legacy/eina/src/lib/eina_log.c b/legacy/eina/src/lib/eina_log.c index 6d8e24243a..1c3c143b6c 100644 --- a/legacy/eina/src/lib/eina_log.c +++ b/legacy/eina/src/lib/eina_log.c @@ -1285,19 +1285,213 @@ eina_log_print_cb_set(Eina_Log_Print_Cb cb, void *data) } /** - * @brief Set the default log log level. + * @brief Set the default log level. * * @param level The log level. * - * This function sets the log log level @p level. It is used in + * This function sets the log level @p level. It is used in * eina_log_print(). + * + * @note this is initially set to envvar EINA_LOG_LEVEL by eina_init(). + * + * @see eina_log_level_get() */ EAPI void -eina_log_level_set(Eina_Log_Level level) +eina_log_level_set(int level) { _log_level = level; } +/** + * @brief Get the default log level. + * + * @return the log level that limits eina_log_print(). + * + * @see eina_log_level_set() + */ +EAPI int +eina_log_level_get(void) +{ + return _log_level; +} + +/** + * Checks if current thread is the main thread. + * + * @return #EINA_TRUE if threads were enabled and the current thread + * is the one that called eina_log_threads_init(). If there is + * no thread support (compiled with --disable-pthreads) or + * they were not enabled, then #EINA_TRUE is also + * returned. The only case where #EINA_FALSE is returned is + * when threads were successfully enabled but the current + * thread is not the main (one that called + * eina_log_threads_init()). + */ +EAPI Eina_Bool +eina_log_main_thread_check(void) +{ +#ifdef EFL_HAVE_PTHREAD + return ((!_threads_enabled) || pthread_equal(_main_thread, pthread_self())); +#else + return EINA_TRUE; +#endif +} + +/** + * @brief Set if color logging should be disabled. + * + * @param disabled if #EINA_TRUE, color logging should be disabled. + * + * @note this is initially set to envvar EINA_LOG_COLOR_DISABLE by eina_init(). + * + * @see eina_log_color_disable_get() + */ +EAPI void +eina_log_color_disable_set(Eina_Bool disabled) +{ + _disable_color = disabled; +} + +/** + * @brief Get if color logging should be disabled. + * + * @return if #EINA_TRUE, color logging should be disabled. + * + * @see eina_log_color_disable_set() + */ +EAPI Eina_Bool +eina_log_color_disable_get(void) +{ + return _disable_color; +} + +/** + * @brief Set if originating file name logging should be disabled. + * + * @param disabled if #EINA_TRUE, file name logging should be disabled. + * + * @note this is initially set to envvar EINA_LOG_FILE_DISABLE by eina_init(). + * + * @see eina_log_file_disable_get() + */ +EAPI void +eina_log_file_disable_set(Eina_Bool disabled) +{ + _disable_file = disabled; +} + +/** + * @brief Get if originating file name logging should be disabled. + * + * @return if #EINA_TRUE, file name logging should be disabled. + * + * @see eina_log_file_disable_set() + */ +EAPI Eina_Bool +eina_log_file_disable_get(void) +{ + return _disable_file; +} + +/** + * @brief Set if originating function name logging should be disabled. + * + * @param disabled if #EINA_TRUE, function name logging should be disabled. + * + * @note this is initially set to envvar EINA_LOG_FUNCTION_DISABLE by + * eina_init(). + * + * @see eina_log_function_disable_get() + */ +EAPI void +eina_log_function_disable_set(Eina_Bool disabled) +{ + _disable_function = disabled; +} + +/** + * @brief Get if originating function name logging should be disabled. + * + * @return if #EINA_TRUE, function name logging should be disabled. + * + * @see eina_log_function_disable_set() + */ +EAPI Eina_Bool +eina_log_function_disable_get(void) +{ + return _disable_function; +} + +/** + * @brief Set if critical messages should abort the program. + * + * @param abort_on_critical if #EINA_TRUE, messages with level equal + * or smaller than eina_log_abort_on_critical_level_get() will + * abort the program. + * + * @note this is initially set to envvar EINA_LOG_ABORT by + * eina_init(). + * + * @see eina_log_abort_on_critical_get() + * @see eina_log_abort_on_critical_level_set() + */ +EAPI void +eina_log_abort_on_critical_set(Eina_Bool abort_on_critical) +{ + _abort_on_critical = abort_on_critical; +} + +/** + * @brief Get if critical messages should abort the program. + * + * @return if #EINA_TRUE, any messages with level equal or smaller + * than eina_log_abort_on_critical_level_get() will abort the + * program. + * + * @see eina_log_abort_on_critical_set() + * @see eina_log_abort_on_critical_level_set() + */ +EAPI Eina_Bool +eina_log_abort_on_critical_get(void) +{ + return _abort_on_critical; +} + +/** + * @brief Set level that triggers abort if abort-on-critical is set. + * + * @param critical_level levels equal or smaller than the given value + * will trigger program abortion if + * eina_log_abort_on_critical_get() returns #EINA_TRUE. + * + * @note this is initially set to envvar EINA_LOG_ABORT_LEVEL by + * eina_init(). + * + * @see eina_log_abort_on_critical_level_get() + * @see eina_log_abort_on_critical_get() + */ +EAPI void +eina_log_abort_on_critical_level_set(int critical_level) +{ + _abort_level_on_critical = critical_level; +} + +/** + * @brief Get level that triggers abort if abort-on-critical is set. + * + * @return critical level equal or smaller than value will trigger + * program abortion if eina_log_abort_on_critical_get() returns + * #EINA_TRUE. + * + * @see eina_log_abort_on_critical_level_set() + * @see eina_log_abort_on_critical_get() + */ +EAPI int +eina_log_abort_on_critical_level_get(void) +{ + return _abort_level_on_critical; +} + /** * @param name Domain name * @param color Color of the domain name @@ -1350,6 +1544,133 @@ eina_log_domain_unregister(int domain) LOG_UNLOCK(); } +/** + * Set the domain level given its name. + * + * This call has the same effect as setting + * EINA_LOG_LEVELS=: + * + * @param domain_name domain name to change the level. It may be of a + * still not registered domain. If the domain is not registered + * yet, it will be saved as a pending set and applied upon + * registration. + * @param level level to use to limit eina_log_print() for given domain. + */ +EAPI void +eina_log_domain_level_set(const char *domain_name, int level) +{ + Eina_Log_Domain_Level_Pending *pending; + int i, namelen; + + EINA_SAFETY_ON_NULL_RETURN(domain_name); + + for (i = 0; i < _log_domains_count; i++) + { + if (_log_domains[i].deleted) + continue; + if (strcmp(_log_domains[i].name, domain_name) != 0) + continue; + + _log_domains[i].level = level; + return; + } + + EINA_INLIST_FOREACH(_pending_list, pending) + { + if (!strcmp(pending->name, domain_name)) + { + pending->level = level; + return; + } + } + + namelen = strlen(domain_name); + pending = malloc(sizeof(Eina_Log_Domain_Level_Pending) + namelen + 1); + if (!pending) + return; + pending->level = level; + memcpy(pending->name, domain_name, namelen + 1); + + _pending_list = eina_inlist_append(_pending_list, EINA_INLIST_GET(pending)); +} + +/** + * Get the domain level given its name. + * + * @param domain_name domain name to retrieve the level. It may be of + * a still not registered domain. If the domain is not + * registered yet, but there is a pending value, either from + * eina_log_domain_level_set(),EINA_LOG_LEVELS environment + * variable or from EINA_LOG_LEVELS_GLOB, these are + * returned. If nothing else was found, then the global/default + * level (eina_log_level_get()) is returned. + * + * @return level to use to limit eina_log_print() for given + * domain. On error (@p domain_name == NULL), + * EINA_LOG_LEVEL_UNKNOWN is returned. + * + * @see eina_log_domain_level_set() + * @see eina_log_domain_registered_level_get() + */ +EAPI int +eina_log_domain_level_get(const char *domain_name) +{ + Eina_Log_Domain_Level_Pending *pending; + int i; + + EINA_SAFETY_ON_NULL_RETURN_VAL(domain_name, EINA_LOG_LEVEL_UNKNOWN); + + for (i = 0; i < _log_domains_count; i++) + { + if (_log_domains[i].deleted) + continue; + if (strcmp(_log_domains[i].name, domain_name) != 0) + continue; + + return _log_domains[i].level; + } + + EINA_INLIST_FOREACH(_pending_list, pending) + { + if (!strcmp(pending->name, domain_name)) + { + return pending->level; + } + } + + EINA_INLIST_FOREACH(_glob_list, pending) + { + if (!fnmatch(pending->name, domain_name, 0)) + { + return pending->level; + } + } + + return _log_level; +} + +/** + * Get the domain level given its identifier. + * + * @param domain identifier, so it must be previously registered with + * eina_log_domain_register(). It's a much faster version of + * eina_log_domain_level_get(), but relies on domain being + * present. + * + * @return level to use to limit eina_log_print() for given domain. On + * error EINA_LOG_LEVEL_UNKNOWN is returned. + */ +EAPI int +eina_log_domain_registered_level_get(int domain) +{ + EINA_SAFETY_ON_FALSE_RETURN_VAL(domain >= 0, EINA_LOG_LEVEL_UNKNOWN); + EINA_SAFETY_ON_FALSE_RETURN_VAL(domain < _log_domains_count, + EINA_LOG_LEVEL_UNKNOWN); + EINA_SAFETY_ON_TRUE_RETURN_VAL(_log_domains[domain].deleted, + EINA_LOG_LEVEL_UNKNOWN); + return _log_domains[domain].level; +} + /** * Default logging method, this will output to standard error stream. * diff --git a/legacy/eina/src/tests/eina_test_log.c b/legacy/eina/src/tests/eina_test_log.c index 77fd9638e2..dce91b69b5 100644 --- a/legacy/eina/src/tests/eina_test_log.c +++ b/legacy/eina/src/tests/eina_test_log.c @@ -139,6 +139,58 @@ START_TEST(eina_log_level_indexes) } END_TEST +START_TEST(eina_log_customize) +{ + int d; + + /* please don't define EINA_LOG_LEVELS for it */ +#define TEST_DOM "_Test_Log_Dom" + + fail_if(!eina_init()); + +#define test_set_get(func, val) \ + eina_log_##func##_set(val); \ + fail_if(eina_log_##func##_get() != val) + + test_set_get(level, -1234); + test_set_get(level, 4567); + +#define test_set_get_bool(func) \ + test_set_get(func, EINA_FALSE); \ + test_set_get(func, EINA_TRUE) + + test_set_get_bool(color_disable); + test_set_get_bool(file_disable); + test_set_get_bool(function_disable); + test_set_get_bool(abort_on_critical); + + test_set_get(abort_on_critical_level, -1234); + test_set_get(abort_on_critical_level, 4567); + + fail_if(eina_log_domain_level_get(TEST_DOM) != eina_log_level_get()); + + eina_log_domain_level_set(TEST_DOM, -123); + fail_if(eina_log_domain_level_get(TEST_DOM) != -123); + + eina_log_domain_level_set(TEST_DOM, 890); + fail_if(eina_log_domain_level_get(TEST_DOM) != 890); + + d = eina_log_domain_register(TEST_DOM, EINA_COLOR_GREEN); + fail_if(d < 0); + + fail_if(eina_log_domain_level_get(TEST_DOM) != 890); + fail_if(eina_log_domain_registered_level_get(d) != 890); + + eina_log_domain_unregister(d); + fputs("NOTE: You should see a failed safety check or " + "a crash if compiled without safety checks support.\n", + stderr); + eina_log_abort_on_critical_set(EINA_FALSE); + fail_if(eina_log_domain_registered_level_get(d) != EINA_LOG_LEVEL_UNKNOWN); + + eina_shutdown(); +} +END_TEST void eina_test_log(TCase *tc) @@ -148,4 +200,5 @@ eina_test_log(TCase *tc) 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); + tcase_add_test(tc, eina_log_customize); }