aboutsummaryrefslogtreecommitdiff
path: root/lib/internals.h
blob: 8cc79911091de3fdb616b68b2a02a29017c6fc86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#ifndef  LOCAL_INTERNALS_H
# define LOCAL_INTERNALS_H 20180710
# include <libtio.h>
# include <string.h>

# ifndef min
#  define min(TIO__A, TIO__B) \
	((TIO__A) > (TIO__B) ? (TIO__B) : (TIO__A))
# endif

typedef TIO_HOOK_TYPE(void) tio_exit_t
	OF((void *));

TIO_EXTERN(int) tio_add_exit
	OF((tio_exit_t func, void *cookie));

/* ---
 * Logging system.
 * --- */

/* These definitions used to be public, but they went private in order to
 * not have numbers *and* strings in the public interface.
 * Strings allow an easier future compatibility. */

typedef int tio_loglevel_t;

# define tio_loglevel_info   0
# define tio_loglevel_warn  10
# define tio_loglevel_error 20
# define tio_loglevel_fatal 30
# define tio_loglevel_none  40

/* Cross-compiler and cross-standard `__func__` variable to display
 * the function on logging. */

# if defined(__cplusplus) ? TIO_GNUC_PREREQ(2, 6) \
   : !defined(__STRICT_ANSI__) && TIO_GNUC_PREREQ(2, 4)
#  define TIO_LOGFUNC __PRETTY_FUNCTION__
# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#  define TIO_LOGFUNC __func__
# elif !defined(__STRICT_ANSI__) && TIO_GNUC_PREREQ(2, 0)
#  define TIO_LOGFUNC __FUNCTION__
# else
#  define TIO_LOGFUNC NULL
# endif

/* Log levels. */

# define ll_info  tio_loglevel_info,  TIO_LOGFUNC
# define ll_warn  tio_loglevel_warn,  TIO_LOGFUNC
# define ll_error tio_loglevel_error, TIO_LOGFUNC
# define ll_fatal tio_loglevel_fatal, TIO_LOGFUNC
# define ll_none  tio_loglevel_none,  TIO_LOGFUNC

/* Check if we can log. */

# if defined(LIBTIO_DISABLED_FILE) && !defined(LIBTIO_DISABLED_LOG)
#  define LIBTIO_DISABLED_LOG
# endif

/* Main functions. */

# if defined(LIBTIO_DISABLED_LOG)

#  define msg(TIO__ARGS)
#  define mem(TIO__ARGS)
#  define islog(TIO__LOGLEVEL) 0

#  define   ifmsg(TIO__COND, TIO__ARGS)
#  define   ifmem(TIO__COND, TIO__ARGS)
#  define elifmsg(TIO__COND, TIO__ARGS)
#  define elifmem(TIO__COND, TIO__ARGS)
#  define elsemsg(             TIO__ARGS)
#  define elsemem(             TIO__ARGS)

# else

/* Main macros, which redirect to whether the logging functions if logging
 * is enabled, or nothing if it is not (`LIBTIO_DISABLED_LOG` defined).
 * Use double parenthesis to transmit args, e.g.:
 *
 *		msg((ll_info, "my %sformat string number %d", "wonderful", 1));
 *		mem((ll_info, my_data_buffer, the_size_of_my_data_buffer));
 *
 * This is some kind of "variadic macro", but for K&R/ANSI C. */

#  define msg(TIO__ARGS) \
	tio_log_msg TIO__ARGS
#  define mem(TIO__ARGS) \
	tio_log_mem TIO__ARGS
#  define islog(TIO__LOGLEVEL) \
	tio_islog(TIO__LOGLEVEL)

/* Here are the linked to conditional kind of macros. */

#  define   ifmsg(TIO__COND, TIO__ARGS) \
	if (TIO__COND) { msg(TIO__ARGS); }
#  define   ifmem(TIO__COND, TIO__ARGS) \
	if (TIO__COND) { mem(TIO__ARGS); }
#  define elifmsg(TIO__COND, TIO__ARGS) \
	else if (TIO__COND) { msg(TIO__ARGS); }
#  define elifmem(TIO__COND, TIO__ARGS) \
	else if (TIO__COND) { mem(TIO__ARGS); }
#  define elsemsg(             TIO__ARGS) \
	else { msg(TIO__ARGS); }
#  define elsemem(             TIO__ARGS) \
	else { mem(TIO__ARGS); }

/* Conversion functions between strings and numbers.
 * Strings are for the external API, numbers for the internal one. */

TIO_EXTERN(char const *)   tio_loglevel_tostring
	OF((tio_loglevel_t tio__level));
TIO_EXTERN(tio_loglevel_t) tio_loglevel_fromstring
	OF((const char *tio__string));

/* Here are the main functions. Don't use them directly, prefer the
 * `msg` and `mem` macros as they are sensible to the fact that logging
 * is enabled or not. */

TIO_EXTERN(int)  tio_islog
	OF((tio_loglevel_t tio__level, char const *tio__func));
TIO_EXTERN(void) tio_log_prefix
	OF((tio_loglevel_t tio__loglevel, char const *tio__func));

#  if defined(__STDC__) && __STDC__

TIO_EXTERN(void) tio_log_msg
	(tio_loglevel_t tio__loglevel, char const *tio__func,
	char const *tio__format, ...);
TIO_EXTERN(void) tio_log_mem
	(tio_loglevel_t tio__loglevel, char const *tio__func,
	void const *tio__m, size_t tio__n);

#  else

TIO_EXTERN(void) tio_log_msg();
TIO_EXTERN(void) tio_log_mem();

#  endif
# endif

#endif /* LOCAL_INTERNALS_H */