Soletta™ Framework
Framework for making IoT devices

Full online documentation | C API Index
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sol-log.h
Go to the documentation of this file.
1 /*
2  * This file is part of the Soletta (TM) Project
3  *
4  * Copyright (C) 2015 Intel Corporation. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #pragma once
20 
21 #include "sol-common-buildopts.h"
22 
23 #include "sol-macros.h"
24 #include <inttypes.h>
25 #include <stdint.h>
26 #include <stdarg.h>
27 #include <stdbool.h>
28 #include <stdio.h>
29 #include <sys/types.h>
30 
31 #ifdef __cplusplus
32 
33 template <typename T> inline const char *sol_int_format(T) { return NULL; }
34 template <> inline const char *sol_int_format<int>(int) { return "%d"; }
35 template <> inline const char *sol_int_format<long>(long) { return "%ld"; }
36 template <> inline const char *sol_int_format<long long>(long long) { return "%lld"; }
37 template <> inline const char *sol_int_format<short>(short) { return "%hd"; }
38 template <> inline const char *sol_int_format<signed char>(signed char) { return "%hhd"; }
39 template <> inline const char *sol_int_format<unsigned>(unsigned) { return "%u"; }
40 template <> inline const char *sol_int_format<unsigned long>(unsigned long) { return "%lu"; }
41 template <> inline const char *sol_int_format<unsigned long long>(unsigned long long) { return "%llu"; }
42 template <> inline const char *sol_int_format<unsigned short>(unsigned short) { return "%hu"; }
43 template <> inline const char *sol_int_format<unsigned char>(unsigned char) { return "%hhu"; }
44 
45 #define SOL_INT_CHECK_IMPL(var, exp, ...) \
46  do { \
47  if (SOL_UNLIKELY((var)exp)) { \
48  char *str = (char *)alloca(snprintf(NULL, 0, "%s (%s) %s", #var, sol_int_format(var), #exp) + 1); \
49  sprintf(str, "%s (%s) %s", #var, sol_int_format(var), #exp); \
50  SOL_WRN(str, var); \
51  return __VA_ARGS__; \
52  } \
53  } while (0)
54 
55 #define SOL_INT_CHECK_GOTO_IMPL(var, exp, label) \
56  do { \
57  if (SOL_UNLIKELY((var)exp)) { \
58  char *str = (char *)alloca(snprintf(NULL, 0, "%s (%s) %s", #var, sol_int_format(var), #exp) + 1); \
59  sprintf(str, "%s (%s) %s", #var, sol_int_format(var), #exp); \
60  SOL_WRN(str, var); \
61  goto label; \
62  } \
63  } while (0)
64 
65 #define SOL_INT_CHECK_GOTO_IMPL_ERRNO(var, exp, err, label) \
66  do { \
67  if (SOL_UNLIKELY((var)exp)) { \
68  char *str = (char *)alloca(snprintf(NULL, 0, "%s (%s) %s", \
69  # var, sol_int_format(var), # exp) + 1); \
70  sprintf(str, "%s (%s) %s", # var, sol_int_format(var), # exp); \
71  SOL_WRN(str, var); \
72  errno = err; \
73  goto label; \
74  } \
75  } while (0)
76 
77 #define SOL_INT_CHECK_IMPL_ERRNO(var, exp, err, ...) \
78  do { \
79  if (SOL_UNLIKELY((var)exp)) { \
80  char *str = (char *)alloca(snprintf(NULL, 0, "%s (%s) %s", \
81  # var, sol_int_format(var), # exp) + 1); \
82  sprintf(str, "%s (%s) %s", # var, sol_int_format(var), # exp); \
83  SOL_WRN(str, var); \
84  errno = err; \
85  return __VA_ARGS__; \
86  } \
87  } while (0)
88 
89 #else
90 
96 #define _SOL_INT_CHECK_FMT(var) \
97  __builtin_choose_expr( \
98  __builtin_types_compatible_p(__typeof__(var), int), \
99  "" # var " (%d) %s", \
100  __builtin_choose_expr( \
101  __builtin_types_compatible_p(__typeof__(var), long), \
102  "" # var " (%ld) %s", \
103  __builtin_choose_expr( \
104  __builtin_types_compatible_p(__typeof__(var), size_t), \
105  "" # var " (%zu) %s", \
106  __builtin_choose_expr( \
107  __builtin_types_compatible_p(__typeof__(var), unsigned), \
108  "" # var " (%u) %s", \
109  __builtin_choose_expr( \
110  __builtin_types_compatible_p(__typeof__(var), uint64_t), \
111  "" # var " (%" PRIu64 ") %s", \
112  __builtin_choose_expr( \
113  __builtin_types_compatible_p(__typeof__(var), uint32_t), \
114  "" # var " (%" PRIu32 ") %s", \
115  __builtin_choose_expr( \
116  __builtin_types_compatible_p(__typeof__(var), uint16_t), \
117  "" # var " (%" PRIu16 ") %s", \
118  __builtin_choose_expr( \
119  __builtin_types_compatible_p(__typeof__(var), uint8_t), \
120  "" # var " (%" PRIu8 ") %s", \
121  __builtin_choose_expr( \
122  __builtin_types_compatible_p(__typeof__(var), int64_t), \
123  "" # var " (%" PRId64 ") %s", \
124  __builtin_choose_expr( \
125  __builtin_types_compatible_p(__typeof__(var), int32_t), \
126  "" # var " (%" PRId32 ") %s", \
127  __builtin_choose_expr( \
128  __builtin_types_compatible_p(__typeof__(var), int16_t), \
129  "" # var " (%" PRId16 ") %s", \
130  __builtin_choose_expr( \
131  __builtin_types_compatible_p(__typeof__(var), int8_t), \
132  "" # var " (%" PRId8 ") %s", \
133  __builtin_choose_expr( \
134  __builtin_types_compatible_p(__typeof__(var), ssize_t), \
135  "" # var " (%zd) %s", \
136  (void)0)))))))))))))
137 
138 #define SOL_INT_CHECK_IMPL(var, exp, ...) \
139  do { \
140  if (SOL_UNLIKELY((var)exp)) { \
141  SOL_WRN(_SOL_INT_CHECK_FMT(var), var, # exp); \
142  return __VA_ARGS__; \
143  } \
144  } while (0)
145 
146 #define SOL_INT_CHECK_GOTO_IMPL(var, exp, label) \
147  do { \
148  if (SOL_UNLIKELY((var)exp)) { \
149  SOL_WRN(_SOL_INT_CHECK_FMT(var), var, # exp); \
150  goto label; \
151  } \
152  } while (0)
153 
154 #define SOL_INT_CHECK_GOTO_IMPL_ERRNO(var, exp, err, label) \
155  do { \
156  if (SOL_UNLIKELY((var)exp)) { \
157  SOL_WRN(_SOL_INT_CHECK_FMT(var), var, # exp); \
158  errno = err; \
159  goto label; \
160  } \
161  } while (0)
162 
163 #define SOL_INT_CHECK_IMPL_ERRNO(var, exp, err, ...) \
164  do { \
165  if (SOL_UNLIKELY((var)exp)) { \
166  SOL_WRN(_SOL_INT_CHECK_FMT(var), var, # exp); \
167  errno = err; \
168  return __VA_ARGS__; \
169  } \
170  } while (0)
171 
172 #endif
173 
174 #ifdef __cplusplus
175 extern "C" {
176 #endif
177 
196 #define SOL_LOG_COLOR_LIGHTRED "\033[31;1m"
197 #define SOL_LOG_COLOR_RED "\033[31m"
198 #define SOL_LOG_COLOR_LIGHTBLUE "\033[34;1m"
199 #define SOL_LOG_COLOR_BLUE "\033[34m"
200 #define SOL_LOG_COLOR_GREEN "\033[32;1m"
201 #define SOL_LOG_COLOR_YELLOW "\033[33;1m"
202 #define SOL_LOG_COLOR_ORANGE "\033[0;33m"
203 #define SOL_LOG_COLOR_WHITE "\033[37;1m"
204 #define SOL_LOG_COLOR_LIGHTMAGENTA "\033[35;1m"
205 #define SOL_LOG_COLOR_MAGENTA "\033[35m"
206 #define SOL_LOG_COLOR_LIGHTCYAN "\033[36;1m"
207 #define SOL_LOG_COLOR_CYAN "\033[36m"
208 #define SOL_LOG_COLOR_RESET "\033[0m"
209 #define SOL_LOG_COLOR_HIGH "\033[1m"
223 #define SOL_NULL_CHECK(ptr, ...) \
224  do { \
225  if (SOL_UNLIKELY(!(ptr))) { \
226  SOL_WRN("%s == NULL", # ptr); \
227  return __VA_ARGS__; \
228  } \
229  } while (0)
230 
243 #define SOL_NULL_CHECK_ERRNO(ptr, err, ...) \
244  do { \
245  if (SOL_UNLIKELY(!(ptr))) { \
246  SOL_WRN("%s == NULL", # ptr); \
247  errno = err; \
248  return __VA_ARGS__; \
249  } \
250  } while (0)
251 
262 #define SOL_NULL_CHECK_GOTO(ptr, label) \
263  do { \
264  if (SOL_UNLIKELY(!(ptr))) { \
265  SOL_WRN("%s == NULL", # ptr); \
266  goto label; \
267  } \
268  } while (0)
269 
280 #define SOL_NULL_CHECK_MSG(ptr, ret, fmt, ...) \
281  do { \
282  if (SOL_UNLIKELY(!(ptr))) { \
283  SOL_WRN(fmt, ## __VA_ARGS__); \
284  return ret; \
285  } \
286  } while (0)
287 
298 #define SOL_NULL_CHECK_MSG_GOTO(ptr, label, fmt, ...) \
299  do { \
300  if (SOL_UNLIKELY(!(ptr))) { \
301  SOL_WRN(fmt, ## __VA_ARGS__); \
302  goto label; \
303  } \
304  } while (0)
305 
316 #define SOL_INT_CHECK(var, exp, ...) \
317  SOL_INT_CHECK_IMPL(var, exp, __VA_ARGS__)
318 
332 #define SOL_INT_CHECK_ERRNO(var, exp, err, ...) \
333  SOL_INT_CHECK_IMPL_ERRNO(var, exp, err, __VA_ARGS__)
334 
345 #define SOL_INT_CHECK_GOTO(var, exp, label) \
346  SOL_INT_CHECK_GOTO_IMPL(var, exp, label)
347 
361 #define SOL_INT_CHECK_GOTO_ERRNO(var, exp, err, label) \
362  SOL_INT_CHECK_GOTO_IMPL_ERRNO(var, exp, label)
363 
373 #define SOL_EXP_CHECK(exp, ...) \
374  do { \
375  if (SOL_UNLIKELY((exp))) { \
376  SOL_WRN("(%s) is true", # exp); \
377  return __VA_ARGS__; \
378  } \
379  } while (0)
380 
390 #define SOL_EXP_CHECK_GOTO(exp, label) \
391  do { \
392  if (SOL_UNLIKELY((exp))) { \
393  SOL_WRN("(%s) is true", # exp); \
394  goto label; \
395  } \
396  } while (0)
397 
409 };
410 
414 typedef struct sol_log_domain {
415  const char *color;
416  const char *name;
417  uint8_t level;
419 
427 
463 #ifdef SOL_LOG_ENABLED
464 void sol_log_domain_init_level(struct sol_log_domain *domain);
465 void sol_log_init_level_global(const char *str, size_t length);
466 void sol_log_init_levels(const char *str, size_t length);
467 
468 #ifdef SOL_LOG_LEVEL
469 #define SOL_LOG_LEVEL_INIT() \
470  sol_log_init_level_global(SOL_LOG_LEVEL, sizeof(SOL_LOG_LEVEL) - 1)
471 #else
472 #define SOL_LOG_LEVEL_INIT()
473 #endif
474 
475 #ifdef SOL_LOG_LEVELS
476 #define SOL_LOG_LEVELS_INIT() \
477  sol_log_init_levels(SOL_LOG_LEVELS, sizeof(SOL_LOG_LEVELS) - 1)
478 #else
479 #define SOL_LOG_LEVELS_INIT()
480 #endif
481 
482 #else
483 static inline void
485 {
486 }
487 
488 #define SOL_LOG_LEVEL_INIT()
489 #define SOL_LOG_LEVELS_INIT()
490 
491 #endif
492 
493 #ifndef SOL_LOG_DOMAIN
494 
505 #define SOL_LOG_DOMAIN sol_log_global_domain
506 #endif
507 
529 #if 0
530 #define SOL_LOG_LEVEL_MAXIMUM SOL_LOG_LEVEL_WARNING
531 #endif
532 
541 #ifdef SOL_LOG_ENABLED
542 #ifdef SOL_LOG_LEVEL_MAXIMUM
543 #define SOL_LOG_LEVEL_POSSIBLE(level) (level <= SOL_LOG_LEVEL_MAXIMUM)
544 #else
545 #define SOL_LOG_LEVEL_POSSIBLE(level) (1)
546 #endif
547 #else
548 #ifdef SOL_LOG_LEVEL_MAXIMUM
549 #undef SOL_LOG_LEVEL_MAXIMUM
550 #endif
551 #define SOL_LOG_LEVEL_MAXIMUM -1
552 #define SOL_LOG_LEVEL_POSSIBLE(level) (0)
553 #endif
554 
566 #ifdef SOL_LOG_FILES
567 #define SOL_LOG_FILE __FILE__
568 #else
569 #define SOL_LOG_FILE ""
570 #endif
571 
583 #ifdef SOL_LOG_FUNCTIONS
584 #define SOL_LOG_FUNCTION __PRETTY_FUNCTION__
585 #else
586 #define SOL_LOG_FUNCTION ""
587 #endif
588 
599 #define SOL_LOG(level, fmt, ...) \
600  do { \
601  if (SOL_LOG_LEVEL_POSSIBLE(level)) { \
602  sol_log_print(SOL_LOG_DOMAIN, level, \
603  SOL_LOG_FILE, SOL_LOG_FUNCTION, __LINE__, \
604  fmt, ## __VA_ARGS__); \
605  } \
606  } while (0)
607 
619 #define SOL_CRI(fmt, ...) SOL_LOG(SOL_LOG_LEVEL_CRITICAL, fmt, ## __VA_ARGS__)
620 
632 #define SOL_ERR(fmt, ...) SOL_LOG(SOL_LOG_LEVEL_ERROR, fmt, ## __VA_ARGS__)
633 
645 #define SOL_WRN(fmt, ...) SOL_LOG(SOL_LOG_LEVEL_WARNING, fmt, ## __VA_ARGS__)
646 
658 #define SOL_INF(fmt, ...) SOL_LOG(SOL_LOG_LEVEL_INFO, fmt, ## __VA_ARGS__)
659 
671 #define SOL_DBG(fmt, ...) SOL_LOG(SOL_LOG_LEVEL_DEBUG, fmt, ## __VA_ARGS__)
672 
732 #ifdef SOL_LOG_ENABLED
733 void sol_log_print(const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, ...) SOL_ATTR_PRINTF(6, 7) SOL_ATTR_NO_INSTRUMENT;
734 
735 void sol_log_vprint(const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, va_list args) SOL_ATTR_PRINTF(6, 0) SOL_ATTR_NO_INSTRUMENT;
736 #else
737 static inline void
738 sol_log_print(const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, ...)
739 {
740 }
741 static inline void
742 sol_log_vprint(const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, va_list args)
743 {
744 }
745 #endif
746 
764 #ifdef SOL_LOG_ENABLED
765 void sol_log_set_print_function(void (*print)(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, va_list args), const void *data);
766 #else
767 static inline void
768 sol_log_set_print_function(void (*print)(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, va_list args), const void *data)
769 {
770 }
771 #endif
772 
781 #ifdef SOL_LOG_ENABLED
782 void sol_log_print_function_stderr(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, va_list args) SOL_ATTR_PRINTF(7, 0);
783 #else
784 static inline void
785 sol_log_print_function_stderr(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, va_list args)
786 {
787 }
788 #endif
789 
790 #ifdef SOL_PLATFORM_LINUX
791 
804 #ifdef SOL_LOG_ENABLED
805 void sol_log_print_function_file(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, va_list args) SOL_ATTR_PRINTF(7, 0);
806 #else
807 static inline void
808 sol_log_print_function_file(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, va_list args)
809 {
810 }
811 #endif
812 #endif
813 
814 #ifdef SOL_PLATFORM_LINUX
815 
831 #ifdef SOL_LOG_ENABLED
832 void sol_log_print_function_syslog(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *syslog, const char *function, int line, const char *format, va_list args) SOL_ATTR_PRINTF(7, 0);
833 #else
834 static inline void
835 sol_log_print_function_syslog(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *syslog, const char *function, int line, const char *format, va_list args)
836 {
837 }
838 #endif
839 #endif
840 
841 #ifdef SOL_PLATFORM_LINUX
842 
863 #ifdef SOL_LOG_ENABLED
864 void sol_log_print_function_journal(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *journal, const char *function, int line, const char *format, va_list args) SOL_ATTR_PRINTF(7, 0);
865 #else
866 static inline void
867 sol_log_print_function_journal(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *journal, const char *function, int line, const char *format, va_list args)
868 {
869 }
870 #endif
871 #endif
872 
989 #ifdef SOL_LOG_ENABLED
990 /*
991  * Those implementing custom logging functions may use the following getters
992  */
993 void sol_log_level_to_str(uint8_t level, char *buf, size_t buflen);
994 const char *sol_log_get_level_color(uint8_t level);
995 uint8_t sol_log_get_abort_level(void);
996 uint8_t sol_log_get_level(void);
997 bool sol_log_get_show_colors(void);
998 bool sol_log_get_show_file(void);
999 bool sol_log_get_show_function(void);
1000 bool sol_log_get_show_line(void);
1001 
1002 /*
1003  * To force some logging setting independent of platform initializations,
1004  * use the following setters
1005  */
1006 void sol_log_set_abort_level(uint8_t level);
1007 void sol_log_set_level(uint8_t level);
1008 void sol_log_set_show_colors(bool enabled);
1009 void sol_log_set_show_file(bool enabled);
1011 void sol_log_set_show_line(bool enabled);
1012 #else
1013 static inline void
1014 sol_log_level_to_str(uint8_t level, char *buf, size_t buflen)
1015 {
1016 }
1017 static inline const char *
1019 {
1020  return "";
1021 }
1022 static inline uint8_t
1024 {
1025  return 0;
1026 }
1027 static inline uint8_t
1029 {
1030  return 0;
1031 }
1032 static inline bool
1034 {
1035  return false;
1036 }
1037 static inline bool
1039 {
1040  return false;
1041 }
1042 static inline bool
1044 {
1045  return false;
1046 }
1047 static inline bool
1049 {
1050  return false;
1051 }
1052 static inline void
1054 {
1055 }
1056 static inline void
1058 {
1059 }
1060 static inline void
1062 {
1063 }
1064 static inline void
1066 {
1067 }
1068 static inline void
1070 {
1071 }
1072 static inline void
1074 {
1075 }
1076 #endif
1077 
1082 #ifdef __cplusplus
1083 }
1084 #endif
static void sol_log_set_print_function(void(*print)(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, va_list args), const void *data)
Set the function to print out log messages.
Definition: sol-log.h:768
#define SOL_ATTR_NO_INSTRUMENT
Used to tell that this functions shouldn't be instrumented.
Definition: sol-macros.h:192
static void sol_log_set_show_function(bool enabled)
Enable/Disables the output of function's name containing the logging messages.
Definition: sol-log.h:1069
#define SOL_ATTR_PRINTF(fmt, arg)
Specifies that a function takes printf style arguments which should be type-checked against a format ...
Definition: sol-macros.h:189
static void sol_log_print(const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format,...)
Print out a message in a given domain and level.
Definition: sol-log.h:738
Debug.
Definition: sol-log.h:408
static void sol_log_level_to_str(uint8_t level, char *buf, size_t buflen)
Convenience function to convert the logging level to string.
Definition: sol-log.h:1014
static const char * sol_log_get_level_color(uint8_t level)
Get the color code used for the given logging level level.
Definition: sol-log.h:1018
static bool sol_log_get_show_colors(void)
Get if color output is enabled or not.
Definition: sol-log.h:1033
static uint8_t sol_log_get_abort_level(void)
Get the logging level that triggers the program to abort.
Definition: sol-log.h:1023
static void sol_log_vprint(const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, va_list args)
Similar to sol_log_print, but called with va_list instead of a variable number of arguments...
Definition: sol-log.h:742
static void enabled(void *data, bool powered)
Definition: browse.c:155
static bool sol_log_get_show_function(void)
Get if showing function's name is enabled or not.
Definition: sol-log.h:1043
These are common Soletta macros.
Structure containing the attributes of the domain used for logging.
Definition: sol-log.h:414
struct sol_log_domain * sol_log_global_domain
Global logging domain.
static void sol_log_print_function_stderr(void *data, const struct sol_log_domain *domain, uint8_t message_level, const char *file, const char *function, int line, const char *format, va_list args)
Standard logging function that send to standard error output.
Definition: sol-log.h:785
static void sol_log_domain_init_level(struct sol_log_domain *domain)
Initialize domain log level based on system configuration.
Definition: sol-log.h:484
static void sol_log_set_level(uint8_t level)
Set the global domain maximum level to level.
Definition: sol-log.h:1057
struct sol_log_domain sol_log_domain
Structure containing the attributes of the domain used for logging.
static void sol_log_set_abort_level(uint8_t level)
Set the logging level that should trigger the program to abort.
Definition: sol-log.h:1053
const char * color
Color to be used.
Definition: sol-log.h:415
sol_log_level
Available logging levels.
Definition: sol-log.h:403
static bool sol_log_get_show_file(void)
Get if showing source file's name is enabled or not.
Definition: sol-log.h:1038
Informational.
Definition: sol-log.h:407
static void sol_log_set_show_colors(bool enabled)
Enable/Disables the use of colors in logging messages.
Definition: sol-log.h:1061
static bool sol_log_get_show_line(void)
Get if showing the line number is enabled or not.
Definition: sol-log.h:1048
const char * name
Domain name.
Definition: sol-log.h:416
static uint8_t sol_log_get_level(void)
Get the maximum log level allowed.
Definition: sol-log.h:1028
Warning.
Definition: sol-log.h:406
Error.
Definition: sol-log.h:405
Critical.
Definition: sol-log.h:404
static void sol_log_set_show_line(bool enabled)
Enable/Disables the output of the line number in logging messages.
Definition: sol-log.h:1073
uint8_t level
Maximum level to log for this domain.
Definition: sol-log.h:417
static void sol_log_set_show_file(bool enabled)
Enable/Disables the output of source file's name in logging messages.
Definition: sol-log.h:1065