ARPA2 Common Libraries  2.6.2
except.h
1 
23 /* This file is part of ARPA2 Common Libraries, version 2.0.2 and later.
24  * https://gitlab.com/arpa2/arpa2common
25  *
26  * Before, it was kept in ARPA2CM, where it was taken from commit
27  * 6c995b1a28190c1c5f477edca642999ebf45e243
28  * https://gitlab.com/arpa2/arpa2cm
29  *
30  * Redistribution and use is allowed according to the terms of the two-clause BSD license.
31  * SPDX-License-Identifier: BSD-2-Clause
32  * SPDX-FileCopyrightText: Copyright 2020, Rick van Rein <rick@openfortress.nl>
33  *
34  */
35 
36 
37 #ifndef _ARPA2_EXCEPT_H
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 #ifdef __clang__
44 /* This file uses ## __VA_ARGS__ all the time, which is a GNU extension;
45  * tell Clang not to complain about it for this one header.
46  */
47 #pragma clang diagnostic push
48 #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
49 #endif
50 
51 #ifdef DEBUG
52 
65 #define except_if(lab,nok) do if (nok) { log_error ("Exceptional outcome for %s at %s:%d", #nok, __FILE__, __LINE__); goto lab; } while (0)
66 
79 #define except_ifnot(lab,ok) do if (!(ok)) { log_error ("Exceptional outcome for %s at %s:%d", #ok , __FILE__, __LINE__); goto lab; } while (0)
80 
88 #define assertxt(test,fmt,...) do if (!(test)) { log_critical ("\nAssertion Failed on %s at %s:%d (" fmt ")\n", #test, __FILE__, __LINE__ , ##__VA_ARGS__); exit (-6); } while (0)
89 
90 #else /* DEBUG */
91 
96 #define except_if(lab,nok) while ( nok ) goto lab
97 
102 #define except_ifnot(lab,ok) while (!(ok)) goto lab
103 
104 /* assertxt(test,fmt,...)
105  *
106  * With DEBUG undefined, assertxt() ascertains that test is valid, and it will
107  * exit on error, logging a more limited error message.
108  */
109 #define assertxt(test,fmt,...) do if (!(test)) { log_critical ("\nAssertion Failed (" fmt ")\n" , ##__VA_ARGS__); exit (-6); } while (0)
110 
111 #endif /* DEBUG */
112 
113 
114 /* The platform-sensible default value for LOG_STYLE.
115  * This is only used when LOG_STYLE is undefined.
116  * POSIX systems normally default to syslog() style,
117  * but POSIX will DEBUG to stderr by default.
118  */
119 #ifdef _WIN32
120 #define LOG_STYLE_DEFAULT LOG_STYLE_STDERR
121 #else /* POSIX */
122 #ifdef DEBUG
123 #define LOG_STYLE_DEFAULT LOG_STYLE_STDERR
124 #else
125 #define LOG_STYLE_DEFAULT LOG_STYLE_SYSLOG
126 #endif /* DEBUG */
127 #endif /* POSIX or WIN32 */
128 
129 /* Configuration option: LOG_STYLE may be set to one of:
130  * - LOG_STYLE_NULL -- log information will be suppressed
131  * - LOG_STYLE_STDOUT -- log information is printed to stdout
132  * - LOG_STYLE_STDERR -- log information is printed to stderr
133  * - LOG_STYLE_SYSLOG -- log information
134  */
135 #define LOG_STYLE_NULL 0
136 #define LOG_STYLE_STDOUT 1
137 #define LOG_STYLE_STDERR 2
138 #define LOG_STYLE_SYSLOG 3
139 
140 #ifndef LOG_STYLE
141 #define LOG_STYLE LOG_STYLE_DEFAULT
142 #endif
143 
144 #ifdef DEBUG_DETAIL
145 /* Turn on DEBUG if it wasn't already */
146 #ifndef DEBUG
147 #define DEBUG
148 #endif
149 #endif
150 
151 
152 #if LOG_STYLE == LOG_STYLE_NULL
153 
154 /* LOG_STYLE_NULL allows the inclusion of log_xxx statements but
155  * none of the produced output is actually used.
156  */
157 
158 #define log_critical(fmt,...) do { ; } while (0)
159 #define log_warning(fmt,...) do { ; } while (0)
160 #define log_error(fmt,...) do { ; } while (0)
161 #define log_info(fmt,...) do { ; } while (0)
162 #define log_notice(fmt,...) do { ; } while (0)
163 #define log_debug(fmt,...) do { ; } while (0)
164 
165 #elif LOG_STYLE == LOG_STYLE_STDOUT
166 
167 /* LOG_STYLE_STDOUT sends logging output to stdout, with preceding
168  * text labels for easy recognition.
169  */
170 
171 #include <stdio.h>
172 
173 #define log_critical(fmt,...) do { fprintf (stdout, "##\n## CRITICAL: " fmt "\n##\n" , ##__VA_ARGS__); fflush (stdout); } while (0)
174 #define log_error(fmt,...) do { fprintf (stdout, "Error: " fmt "\n" , ##__VA_ARGS__); fflush (stdout); } while (0)
175 #define log_warning(fmt,...) do { fprintf (stdout, "Warning: " fmt "\n" , ##__VA_ARGS__); fflush (stdout); } while (0)
176 #define log_info(fmt,...) do { fprintf (stdout, fmt "\n" , ##__VA_ARGS__); fflush (stdout); } while (0)
177 #define log_notice(fmt,...) do { fprintf (stdout, fmt "\n" , ##__VA_ARGS__); fflush (stdout); } while (0)
178 #define log_debug(fmt,...) do { fprintf (stdout, "DEBUG: " fmt "\n" , ##__VA_ARGS__); fflush (stdout); } while (0)
179 
180 #elif LOG_STYLE == LOG_STYLE_STDERR
181 
182 /* LOG_STYLE_STDOUT sends logging output to stderr, with preceding
183  * text labels for easy recognition.
184  */
185 
186 #include <stdio.h>
187 
188 #define log_critical(fmt,...) do { fprintf (stderr, "##\n## CRITICAL: " fmt "\n##\n" , ##__VA_ARGS__); fflush (stderr); } while (0)
189 #define log_error(fmt,...) do { fprintf (stderr, "Error: " fmt "\n" , ##__VA_ARGS__); fflush (stderr); } while (0)
190 #define log_warning(fmt,...) do { fprintf (stderr, "Warning: " fmt "\n" , ##__VA_ARGS__); fflush (stderr); } while (0)
191 #define log_info(fmt,...) do { fprintf (stderr, fmt "\n" , ##__VA_ARGS__); fflush (stderr); } while (0)
192 #define log_notice(fmt,...) do { fprintf (stderr, fmt "\n" , ##__VA_ARGS__); fflush (stderr); } while (0)
193 #define log_debug(fmt,...) do { fprintf (stderr, "DEBUG: " fmt "\n" , ##__VA_ARGS__); fflush (stderr); } while (0)
194 
195 #elif LOG_STYLE == LOG_STYLE_SYSLOG
196 
197 /* LOG_STYLE_SYSLOG sends logging output to the system logging service.
198  */
199 
200 #include <syslog.h>
201 
202 #ifdef _WIN32
203 
204 #error "No Windows syslogging yet"
205 
206 #else /* POSIX */
207 
208 #define log_critical(fmt,...) syslog (LOG_CRIT, fmt , ##__VA_ARGS__)
209 #define log_error(fmt,...) syslog (LOG_ERR, fmt , ##__VA_ARGS__)
210 #define log_warning(fmt,...) syslog (LOG_WARNING, fmt , ##__VA_ARGS__)
211 #define log_info(fmt,...) syslog (LOG_INFO, fmt , ##__VA_ARGS__)
212 #define log_notice(fmt,...) syslog (LOG_NOTICE, fmt , ##__VA_ARGS__)
213 #define log_debug(fmt,...) syslog (LOG_DEBUG, fmt , ##__VA_ARGS__)
214 
215 #endif /* WIN32 / POSIX */
216 
217 #else /* LOG_STYLE */
218 
219 #error "No recognised LOG_STYLE setting"
220 
221 #endif /* LOG_STYLE */
222 
223 #include <errno.h>
224 
235 #if defined(__COM_ERR_H) || defined (__COM_ERR_H__)
236 #define log_errno(fmt,...) log_error ("%s: " fmt, error_message (errno) , ##__VA_ARGS__)
237 #else
238 #define log_errno(fmt,...) log_error ("%s: " fmt, strerror (errno) , ##__VA_ARGS__)
239 #endif
240 
287 #ifdef DEBUG_DETAIL
288 #define log_detail(fmt,...) log_debug (fmt , ##__VA_ARGS__)
289 #else
290 #define log_detail(fmt,...) do { ; } while (0)
291 #endif
292 
302 #ifdef DEBUG_DETAIL
303 
304 #include <stdlib.h>
305 #include <stdbool.h>
306 #include <stdint.h>
307 #include <stdio.h>
308 #include <string.h>
309 
310 static inline void log_data (const char *descr, const void *blk, uint32_t blklen, uint32_t maxsz) {
311  uint32_t size = blklen;
312  if ((maxsz > 0) && (size > maxsz)) {
313  size = maxsz;
314  }
315  char buf [strlen (descr) + 3 * size + 50];
316  int count = snprintf (buf, sizeof(buf), "%s =", descr);
317  if (blk == NULL) {
318  snprintf (buf + count, sizeof(buf) - count, "NULL");
319  log_debug ("%s", buf);
320  return;
321  }
322  for (uint32_t i=0; i < blklen; i++) {
323  count += snprintf (buf + count, sizeof(buf) - count, " %02x", ((uint8_t *) blk) [i]);
324  if ((size < blklen) && (i > 5) && (i == size - 5)) {
325  count += snprintf (buf + count, sizeof(buf) - count, " ...");
326  i = blklen - 5;
327  }
328  }
329  count += snprintf (buf + count, sizeof(buf) - count, " -> #%d", blklen);
330  log_debug ("%s", buf);
331 }
332 
333 #else
334 #define log_data(descr,blk,blklen,skip) do { ; } while (0)
335 #endif
336 
337 
338 #ifdef __UNREALISED_WISH__
339 
363 #if LOG_STYLE == LOG_STYLE_NULL
364 
365 #define nok_critical(test,fmt,...) (test)
366 #define nok_warning(test,fmt,...) (test)
367 #define nok_error(test,fmt,...) (test)
368 #define nok_info(test,fmt,...) (test)
369 #define nok_notice(test,fmt,...) (test)
370 #define nok_debug(test,fmt,...) (test)
371 #define nok_detail(test,fmt,...) (test)
372 
373 #else /* if not LOG_STYLE == LOG_STYLE_NULL */
374 
375 #include <stdbool.h>
376 
377 #define nok_critical(test,fmt,...) (test || (log_critical (fmt, ##__VA_ARGS__), false))
378 #define nok_warning(test,fmt,...) (test || (log_warning (fmt, ##__VA_ARGS__), false))
379 #define nok_error(test,fmt,...) (test || (log_error (fmt, ##__VA_ARGS__), false))
380 #define nok_info(test,fmt,...) (test || (log_info (fmt, ##__VA_ARGS__), false))
381 #define nok_notice(test,fmt,...) (test || (log_notice (fmt, ##__VA_ARGS__), false))
382 #define nok_debug(test,fmt,...) (test || (log_debug (fmt, ##__VA_ARGS__), false))
383 #define nok_detail(test,fmt,...) (test || (log_detail (fmt, ##__VA_ARGS__), false))
384 
385 #endif /* LOG_STYLE == LOG_STYLE_NULL */
386 
387 #endif /* __UNRELIASED_WISH__ */
388 
389 #ifdef __clang__
390 #pragma clang diagnostic pop
391 #endif
392 
393 #ifdef __cplusplus
394 }
395 #endif
396 
397 #define _ARPA2_EXCEPT_H
398 #endif
399 
#define log_debug(fmt,...)
static void log_data(const char *descr, const void *blk, uint32_t blklen, uint32_t maxsz)
log_data(descr,ptr,len,maxsz)
Definition: except.h:310