1 #ifndef SIEVE_RUNTIME_TRACE_H
2 #define SIEVE_RUNTIME_TRACE_H
3 
4 #include "sieve-common.h"
5 #include "sieve-runtime.h"
6 
7 /*
8  * Runtime trace
9  */
10 
11 struct sieve_runtime_trace {
12 	struct sieve_trace_config config;
13 	struct sieve_trace_log *log;
14 	unsigned int indent;
15 };
16 
17 /* Trace configuration */
18 
sieve_runtime_trace_active(const struct sieve_runtime_env * renv,sieve_trace_level_t trace_level)19 static inline bool sieve_runtime_trace_active
20 (const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level)
21 {
22 	return ( renv->trace != NULL && trace_level <= renv->trace->config.level );
23 }
24 
sieve_runtime_trace_hasflag(const struct sieve_runtime_env * renv,unsigned int flag)25 static inline bool sieve_runtime_trace_hasflag
26 (const struct sieve_runtime_env *renv, unsigned int flag)
27 {
28 	return ( renv->trace != NULL && (renv->trace->config.flags & flag) != 0 );
29 }
30 
31 /* Trace indent */
32 
sieve_runtime_trace_descend(const struct sieve_runtime_env * renv)33 static inline void sieve_runtime_trace_descend
34 (const struct sieve_runtime_env *renv)
35 {
36 	if ( renv->trace != NULL ) renv->trace->indent++;
37 }
38 
sieve_runtime_trace_ascend(const struct sieve_runtime_env * renv)39 static inline void sieve_runtime_trace_ascend
40 (const struct sieve_runtime_env *renv)
41 {
42 	if ( renv->trace != NULL ) renv->trace->indent--;
43 }
44 
sieve_runtime_trace_toplevel(const struct sieve_runtime_env * renv)45 static inline void sieve_runtime_trace_toplevel
46 (const struct sieve_runtime_env *renv)
47 {
48 	if ( renv->trace != NULL ) renv->trace->indent = 0;
49 }
50 
51 /* Trace errors */
52 
53 void _sieve_runtime_trace_error
54 	(const struct sieve_runtime_env *renv, const char *fmt, va_list args)
55 		ATTR_FORMAT(2, 0);
56 
57 void _sieve_runtime_trace_operand_error
58 	(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd,
59 		const char *fmt, va_list args) ATTR_FORMAT(3, 0);
60 
61 static inline void sieve_runtime_trace_error
62 	(const struct sieve_runtime_env *renv, const char *fmt, ...)
63 		ATTR_FORMAT(2, 3);
64 
65 static inline void sieve_runtime_trace_operand_error
66 	(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd,
67 		const char *fmt, ...) ATTR_FORMAT(3, 4);
68 
sieve_runtime_trace_error(const struct sieve_runtime_env * renv,const char * fmt,...)69 static inline void ATTR_FORMAT(2, 3) sieve_runtime_trace_error
70 	(const struct sieve_runtime_env *renv, const char *fmt, ...)
71 {
72 	va_list args;
73 
74 	va_start(args, fmt);
75 	if ( renv->trace != NULL )
76 		_sieve_runtime_trace_error(renv, fmt, args);
77 	va_end(args);
78 }
79 
sieve_runtime_trace_operand_error(const struct sieve_runtime_env * renv,const struct sieve_operand * oprnd,const char * fmt,...)80 static inline void ATTR_FORMAT(3, 4) sieve_runtime_trace_operand_error
81 	(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd,
82 		const char *fmt, ...)
83 {
84 	va_list args;
85 
86 	va_start(args, fmt);
87 	if ( renv->trace != NULL )
88 		_sieve_runtime_trace_operand_error(renv, oprnd, fmt, args);
89 	va_end(args);
90 }
91 
92 /* Trace info */
93 
94 void _sieve_runtime_trace
95 	(const struct sieve_runtime_env *renv, const char *fmt, va_list args)
96 		ATTR_FORMAT(2, 0);
97 
98 static inline void sieve_runtime_trace
99 	(const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level,
100 		const char *fmt, ...) ATTR_FORMAT(3, 4);
101 
sieve_runtime_trace(const struct sieve_runtime_env * renv,sieve_trace_level_t trace_level,const char * fmt,...)102 static inline void ATTR_FORMAT(3, 4) sieve_runtime_trace
103 (const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level,
104 	const char *fmt, ...)
105 {
106 	va_list args;
107 
108 	va_start(args, fmt);
109 
110 	if ( renv->trace != NULL && trace_level <= renv->trace->config.level ) {
111 		_sieve_runtime_trace(renv, fmt, args);
112 	}
113 
114 	va_end(args);
115 }
116 
117 void _sieve_runtime_trace_address
118 	(const struct sieve_runtime_env *renv, sieve_size_t address,
119 		const char *fmt, va_list args) ATTR_FORMAT(3, 0);
120 
121 static inline void sieve_runtime_trace_address
122 	(const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level,
123 		sieve_size_t address, const char *fmt, ...) ATTR_FORMAT(4, 5);
124 
sieve_runtime_trace_address(const struct sieve_runtime_env * renv,sieve_trace_level_t trace_level,sieve_size_t address,const char * fmt,...)125 static inline void ATTR_FORMAT(4, 5) sieve_runtime_trace_address
126 (const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level,
127 	sieve_size_t address, const char *fmt, ...)
128 {
129 	va_list args;
130 
131 	va_start(args, fmt);
132 
133 	if ( renv->trace != NULL && trace_level <= renv->trace->config.level ) {
134 		_sieve_runtime_trace_address(renv, address, fmt, args);
135 	}
136 
137 	va_end(args);
138 }
139 
sieve_runtime_trace_here(const struct sieve_runtime_env * renv,sieve_trace_level_t trace_level,const char * fmt,...)140 static inline void ATTR_FORMAT(3, 4) sieve_runtime_trace_here
141 (const struct sieve_runtime_env *renv, sieve_trace_level_t trace_level,
142 	const char *fmt, ...)
143 {
144 	va_list args;
145 
146 	va_start(args, fmt);
147 
148 	if ( renv->trace != NULL && trace_level <= renv->trace->config.level ) {
149 		_sieve_runtime_trace_address(renv, renv->pc, fmt, args);
150 	}
151 
152 	va_end(args);
153 }
154 
155 /* Trace boundaries */
156 
157 void _sieve_runtime_trace_begin(const struct sieve_runtime_env *renv);
158 void _sieve_runtime_trace_end(const struct sieve_runtime_env *renv);
159 void _sieve_runtime_trace_sep(const struct sieve_runtime_env *renv);
160 
sieve_runtime_trace_begin(const struct sieve_runtime_env * renv)161 static inline void sieve_runtime_trace_begin
162 (const struct sieve_runtime_env *renv)
163 {
164 	if ( renv->trace != NULL )
165 		_sieve_runtime_trace_begin(renv);
166 }
167 
sieve_runtime_trace_end(const struct sieve_runtime_env * renv)168 static inline void sieve_runtime_trace_end
169 (const struct sieve_runtime_env *renv)
170 {
171 	if ( renv->trace != NULL )
172 		_sieve_runtime_trace_end(renv);
173 }
174 
sieve_runtime_trace_sep(const struct sieve_runtime_env * renv)175 static inline void sieve_runtime_trace_sep
176 (const struct sieve_runtime_env *renv)
177 {
178 	if ( renv->trace != NULL )
179 		_sieve_runtime_trace_sep(renv);
180 }
181 
182 #endif
183