source: trunk/src/emx/include/InnoTekLIBC/logstrict.h@ 1315

Last change on this file since 1315 was 1315, checked in by bird, 22 years ago

More logging.

  • Property cvs2svn:cvs-rev set to 1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 19.4 KB
Line 
1/* $Id: logstrict.h 1315 2004-03-17 03:59:28Z bird $ */
2/** @file
3 *
4 * InnoTek LIBC - Debug Logging and Strict Checking Features.
5 *
6 * InnoTek Systemberatung GmbH confidential
7 *
8 * Copyright (c) 2004 InnoTek Systemberatung GmbH
9 * Author: knut st. osmundsen <[email protected]>
10 *
11 * All Rights Reserved
12 *
13 */
14
15#ifndef __InnoTekLIBC_LOG_H__
16#define __InnoTekLIBC_LOG_H__
17
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#include <sys/cdefs.h>
22#include <sys/types.h> /* size_t */
23#include <sys/param.h> /* NULL */
24
25/** @defgroup __libc_log Debug Logging and Strict Checking Features
26 *
27 * The logging feature is not accessible unless DEBUG_LOGGING is #defined.
28 *
29 * The strict checking feature is not accessible unless __LIBC_STRICT is #defined.
30 *
31 * The user of this feature must #define __LIBC_LOG_GROUP to a valid group
32 * number before including this file.
33 *
34 * The user may also #define __LIBC_LOG_INSTANCE if it doesn't want to use
35 * the default logging device.
36 *
37 * Note that all everything but the main logger & strict macros are using the
38 * default prefix to avoid too much namespace pollution. The main logger and
39 * strict macros are not prefixed with the double underscore because that
40 * would make the code less readable (and mean more typing which is painful).
41 *
42 * @{
43 */
44
45
46/*******************************************************************************
47* Defined Constants And Macros *
48*******************************************************************************/
49/**
50 * The user may also #define __LIBC_LOG_INSTANCE if it doesn't want to use
51 * the default logging device.
52 */
53#ifdef DEBUG_LOGGING
54#ifndef __LIBC_LOG_INSTANCE
55#define __LIBC_LOG_INSTANCE NULL
56#endif
57#endif
58
59/**
60 * The user of this feature must #define __LIBC_LOG_GROUP to a valid group
61 * number before including this file.
62 */
63#ifdef DEBUG_LOGGING
64#ifndef __LIBC_LOG_GROUP
65#define __LIBC_LOG_GROUP 0
66#error "__LIBC_LOG_GROUP must be defined before including InnoTekLIBC/log.h"
67#endif
68#endif
69
70/** Macro to log a function entry. */
71#ifdef DEBUG_LOGGING
72#define LIBCLOG_ENTER(...) \
73 unsigned __libclog_uEnterTS__ = __libc_LogEnter(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __VA_ARGS__)
74#else
75#define LIBCLOG_ENTER(...) //hmm
76#endif
77
78/** Macro to log a generic message within a function entered by LIBCLOG_ENTER(). */
79#ifdef DEBUG_LOGGING
80#define LIBCLOG_MSG(...) \
81 __libc_LogMsg(__libclog_uEnterTS__, __LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __VA_ARGS__)
82#else
83#define LIBCLOG_MSG(...) do {} while (0)
84#endif
85
86/** Macro to log a generic message within a functionw. */
87#ifdef DEBUG_LOGGING
88#define LIBCLOG_MSG2(...) \
89 __libc_LogMsg(~0, __LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __VA_ARGS__)
90#else
91#define LIBCLOG_MSG2(...) do {} while (0)
92#endif
93
94/** Macro to log a raw message. */
95#ifdef DEBUG_LOGGING
96#define LIBCLOG_RAW(string, maxlen) \
97 __libc_LogRaw(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, string, maxlen)
98#else
99#define LIBCLOG_RAW(...) do {} while (0)
100#endif
101
102/** Macro to log a function exit. */
103#ifdef DEBUG_LOGGING
104#define LIBCLOG_LEAVE(...) \
105 __libc_LogLeave(__libclog_uEnterTS__, __LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __VA_ARGS__)
106#else
107#define LIBCLOG_LEAVE(...) do {} while (0)
108#endif
109
110/** Macro to log a custom message and return. */
111#define LIBCLOG_RETURN_MSG(rc,...) do { LIBCLOG_LEAVE(__VA_ARGS__); return (rc); } while (0)
112/** Macro to log a custom message and return. */
113#define LIBCLOG_RETURN_MSG_VOID(...) do { LIBCLOG_LEAVE(__VA_ARGS__); return; } while (0)
114
115/** Macro to log a void return and do the return. */
116#define LIBCLOG_RETURN_VOID() LIBCLOG_RETURN_MSG_VOID( "ret void\n")
117/** Macro to log an int return and do the return. */
118#define LIBCLOG_RETURN_INT(rc) LIBCLOG_RETURN_MSG((rc), "ret %d (%#x)\n", (rc), (rc))
119/** Macro to log an unsigned int return and do the return. */
120#define LIBCLOG_RETURN_UINT(rc) LIBCLOG_RETURN_MSG((rc), "ret %u (%#x)\n", (rc), (rc));
121/** Macro to log an long int return and do the return. */
122#define LIBCLOG_RETURN_LONG(rc) LIBCLOG_RETURN_MSG((rc), "ret %ld (%#lx)\n", (rc), (rc));
123/** Macro to log an unsigned long int return and do the return. */
124#define LIBCLOG_RETURN_ULONG(rc) LIBCLOG_RETURN_MSG((rc), "ret %lu (%#lx)\n", (rc), (rc));
125/** Macro to log a pointer return and do the return. */
126#define LIBCLOG_RETURN_P(rc) LIBCLOG_RETURN_MSG((rc), "ret %p\n", (void*)(rc));
127
128/** @defgroup __libc_log_flags Message Flags (to be combined with group)
129 *
130 * In source files which uses the logger you can or these flags together
131 * with a group specification in the __LIBC_LOG_GROUP #define.
132 * @{
133 */
134/** Forces a flush of the output file after the message have been written. */
135#define __LIBC_LOG_MSGF_FLUSH 0x00010000
136/** @} */
137
138
139/** @defgroup __libc_log_groups Default Logging Groups
140*
141 * In source files which uses the default logger you must #define
142 * __LIBC_LOG_GROUP to one of these defines.
143 *
144 * @{
145 */
146/** whatever. */
147#define __LIBC_LOG_GRP_NOGROUP 0
148
149/*-- LIBC --*/
150/** Process APIs. */
151#define __LIBC_LOG_GRP_PROCESS 1
152/** Heap APIs. */
153#define __LIBC_LOG_GRP_HEAP 2
154/** File stream APIs. */
155#define __LIBC_LOG_GRP_STREAM 3
156/** Other I/O APIs. */
157#define __LIBC_LOG_GRP_IO 4
158/** String APIs. */
159#define __LIBC_LOG_GRP_STRING 5
160/** Locale APIs. */
161#define __LIBC_LOG_GRP_LOCALE 6
162/** Regular expression APIs. */
163#define __LIBC_LOG_GRP_REGEX 7
164/** Math APIs. */
165#define __LIBC_LOG_GRP_MATH 8
166/** Time APIs. */
167#define __LIBC_LOG_GRP_TIME 9
168/** BSD DB APIs. */
169#define __LIBC_LOG_GRP_BSD_DB 10
170/** GLIBC POSIX APIs. */
171#define __LIBC_LOG_GRP_GLIBC_POSIX 11
172/** Thread APIs. */
173#define __LIBC_LOG_GRP_THREAD 12
174/** Mutex Semaphores. */
175#define __LIBC_LOG_GRP_MUTEX 13
176/** Signal APIs and events. */
177#define __LIBC_LOG_GRP_SIGNAL 14
178/** Environment APIs. */
179#define __LIBC_LOG_GRP_ENV 15
180
181/** Init/Term APIs and Events. */
182#define __LIBC_LOG_GRP_INITTERM 27
183/** Backend APIs. */
184#define __LIBC_LOG_GRP_BACKEND 28
185/** Misc APIs. */
186#define __LIBC_LOG_GRP_MISC 29
187/** BSD Gen APIs. */
188#define __LIBC_LOG_GRP_BSD_GEN 30
189/** GLIBC Misc APIs. */
190#define __LIBC_LOG_GRP_GLIBC_MISC 31
191
192/*-- other libraries/APIs --*/
193/** Socket APIs. */
194#define __LIBC_LOG_GRP_SOCKET 32
195/** Other TCP/IP APIs. */
196#define __LIBC_LOG_GRP_TCPIP 33
197/** iconv APIs. */
198#define __LIBC_LOG_GRP_ICONV 34
199/** Dynamic Library (libdl) APIs. */
200#define __LIBC_LOG_GRP_DLFCN 35
201/** Posix thread APIs. */
202#define __LIBC_LOG_GRP_PTHREAD 36
203
204/** @todo complete this */
205#define __LIBC_LOG_GRP_MAX 36
206/** @} */
207
208
209/** @defgroup __libc_log_strict Strict Assertions
210 * @{ */
211
212/** Generic assertion.
213 * @param expr Boolean expression,
214 */
215#ifdef __LIBC_STRICT
216#define LIBC_ASSERT(expr) ((expr) ? (void)0 \
217 : __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, #expr, NULL))
218#else
219#define LIBC_ASSERT(expr) ((void)0)
220#endif
221
222/** Generic assertion failed.
223 * (Yeah, this always fails.)
224 */
225#ifdef __LIBC_STRICT
226#define LIBC_ASSERT_FAILED() __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, "0", NULL)
227#else
228#define LIBC_ASSERT_FAILED() ((void)0)
229#endif
230
231/** Assert that a memory buffer is readable.
232 * @param pv Pointer to buffer.
233 * @param cb Size of buffer.
234 */
235#ifdef __LIBC_STRICT
236#define LIBC_ASSERT_MEM_R(pv, cb) (__libc_StrictMemoryR((pv), (cb)) ? (void)0 \
237 : __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, #pv "; " #cb, \
238 "Memory buffer at %p of %d bytes isn't readable!\n", (pv), (cb)))
239#else
240#define LIBC_ASSERT_MEM_R(pv, cb) ((void)0)
241#endif
242
243/** Assert that a memory buffer is readable and writable.
244 * @param pv Pointer to buffer.
245 * @param cb Size of buffer.
246 */
247#ifdef __LIBC_STRICT
248#define LIBC_ASSERT_MEM_RW(pv, cb) (__libc_StrictMemoryRW((pv), (cb)) ? (void)0 \
249 : __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, #pv "; " #cb, \
250 "Memory buffer at %p of %d bytes isn't readable and writable!\n", (pv), (cb)))
251#else
252#define LIBC_ASSERT_MEM_RW(pv, cb) ((void)0)
253#endif
254
255/** Assert that a zero terminated string is readable.
256 * @param psz Pointer to buffer.
257 */
258#ifdef __LIBC_STRICT
259#define LIBC_ASSERT_STR(psz) (__libc_StrictStringR((psz), ~0) ? (void)0 \
260 : __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, #psz, \
261 "String at %p isn't readable!\n", (psz)))
262#else
263#define LIBC_ASSERT_STR(psz) ((void)0)
264#endif
265
266/** Assert that a zero terminated string with a maximum lenght is readable.
267 * @param psz Pointer to buffer.
268 * @param cchMax Max string length.
269 */
270#ifdef __LIBC_STRICT
271#define LIBC_ASSERT_NSTR(psz, cchMax) (__libc_StrictStringR((psz), cchMax) ? (void)0 \
272 : __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, #psz " " #cchMax, \
273 "String at %p of maximum %d bytes isn't readable!\n", (psz), (cchMax)))
274#else
275#define LIBC_ASSERT_NSTR(psz, cchMax) ((void)0)
276#endif
277
278
279/** Generic assertion, custom message.
280 * @param expr Boolean expression,
281 * @param ... Custom error message.
282 */
283#ifdef __LIBC_STRICT
284#define LIBC_ASSERTM(expr, ...) ((expr) ? (void)0 \
285 : __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, #expr, \
286 __VA_ARGS__))
287#else
288#define LIBC_ASSERTM(expr, ...) ((void)0)
289#endif
290
291/** Generic assertion failed, custom message.
292 * (Yeah, this always fails.)
293 * @param ... Custom error message.
294 */
295#ifdef __LIBC_STRICT
296#define LIBC_ASSERTM_FAILED(...) __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, "0", __VA_ARGS__)
297#else
298#define LIBC_ASSERTM_FAILED(...) ((void)0)
299#endif
300
301/** Assert that a memory buffer is readable, custom message
302 * @param pv Pointer to buffer.
303 * @param cb Size of buffer.
304 */
305#ifdef __LIBC_STRICT
306#define LIBC_ASSERTM_MEM_R(pv, cb, ...) (__libc_StrictMemoryR((pv), (cb)) ? (void)0 \
307 : __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, #pv "; " #cb, \
308 __VA_ARGS__))
309#else
310#define LIBC_ASSERTM_MEM_R(pv, cb, ...) ((void)0)
311#endif
312
313/** Assert that a memory buffer is readable and writable, custom message
314 * @param pv Pointer to buffer.
315 * @param cb Size of buffer.
316 */
317#ifdef __LIBC_STRICT
318#define LIBC_ASSERTM_MEM_RW(pv, cb, ...) (__libc_StrictMemoryRW((pv), (cb)) ? (void)0 \
319 : __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, #pv "; " #cb, \
320 __VA_ARGS__))
321#else
322#define LIBC_ASSERTM_MEM_RW(pv, cb, ...) ((void)0)
323#endif
324
325/** Assert that a zero terminated string is readable, custom message
326 * @param psz Pointer to buffer.
327 */
328#ifdef __LIBC_STRICT
329#define LIBC_ASSERTM_STR(psz, ...) (__libc_StrictStringR((psz), ~0) ? (void)0 \
330 : __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, #psz, \
331 __VA_ARGS__))
332#else
333#define LIBC_ASSERTM_STR(psz, ...) ((void)0)
334#endif
335
336/** Assert that a zero terminated string with a maximum lenght is readable, custom message
337 * @param psz Pointer to buffer.
338 * @param cchMax Max string length.
339 */
340#ifdef __LIBC_STRICT
341#define LIBC_ASSERTM_NSTR(psz, cchMax, ...) (__libc_StrictStringR((psz), cchMax) ? (void)0 \
342 : __libc_LogAssert(__LIBC_LOG_INSTANCE, __LIBC_LOG_GROUP, __PRETTY_FUNCTION__, __FILE__, __LINE__, #psz " " #cchMax, \
343 __VA_ARGS__))
344#else
345#define LIBC_ASSERTM_NSTR(psz, cchMax, ...) ((void)0)
346#endif
347
348/** Extracts the group from the fGroupAndFlags argument. */
349#define __LIBC_LOG_GETGROUP(fGroupAndFlags) ((fGroupAndFlags) & 0xffff)
350
351/** @} */
352
353
354/*******************************************************************************
355* Structures and Typedefs *
356*******************************************************************************/
357/** Logging group. */
358typedef struct __libc_log_group
359{
360 /** Set if logging for the group is enabled, clear if it's disabled. */
361 int fEnabled;
362 /** Group name */
363 const char * pszGroupName;
364} __LIBC_LOGGROUP, *__LIBC_PLOGGROUP;
365
366/** Ordered collection of logging groups. */
367typedef struct __libc_log_groups
368{
369 /** Group index base. This value is subtracted from the group part of the
370 * fFlagsAndGroups arguments to make an index into paGroups. */
371 unsigned uBase;
372 /** Number of groups in the array. */
373 unsigned cGroups;
374 /** Array of log groups. */
375 __LIBC_PLOGGROUP paGroups;
376} __LIBC_LOGGROUPS, *__LIBC_PLOGGROUPS;
377
378
379/*******************************************************************************
380* External Functions *
381*******************************************************************************/
382__BEGIN_DECLS
383/**
384 * Create a logger.
385 *
386 * @returns Pointer to a logger instance on success.
387 * @returns NULL on failure. errno is set.
388 * @param fFlags Flags reserved for future use. Set to zero.
389 * @param pGroups Pointer to a table of logging groups used for this
390 * logger instance.
391 * @param pszFilenameFormat Format string for making up the log filename.
392 * @param ... Arguments to the format string.
393 */
394extern void *__libc_LogInit(unsigned fFlags, __LIBC_PLOGGROUPS pGroups, const char *pszFilenameFormat, ...) __printflike(3, 4);
395
396/**
397 * Parses the given environment variable and sets the group
398 * flags accordingly.
399 *
400 * The environment variable is a sequence of group idendifiers with
401 * a prefix which determins whether or not that group is enabled.
402 * A special group 'all' can be used to address all groups.
403 *
404 * If the environment variable is not present no changes will be
405 * performed.
406 *
407 * @param pGroups Pointer to groups to init.
408 * @param pszEnvVar Name of the environment variable.
409 * This is taken from the initial environment of the process
410 * and not from the current!!
411 */
412extern void __libc_LogGroupInit(__LIBC_PLOGGROUPS pGroups, const char *pszEnvVar);
413
414/**
415 * Terminate (or close if you like) a logger instance.
416 * This means flushing any buffered messages and writing a termination
417 * message before closing the log file.
418 *
419 * @returns 0 on succes.
420 * @returns -1 on failure, error is set.
421 * @param pvInstance Logger instance.
422 */
423extern int __libc_LogTerm(void *pvInstance);
424
425/**
426 * Output an enter function log message.
427 * An enter message is considered to be one line and is appended a newline if
428 * none was given.
429 *
430 * @returns Current timestamp.
431 * @param pvInstance Logger instance. If NULL the message goes to the
432 * default log instance.
433 * @param fGroupAndFlags Logging group and logging flags.
434 * @param pszFunction Name of the function which was entered.
435 * @param pszFormat Format string to display arguments.
436 * @param ... Arguments to the format string.
437 */
438extern unsigned __libc_LogEnter(void *pvInstance, unsigned fGroupAndFlags, const char *pszFunction, const char *pszFormat, ...) __printflike(4, 5);
439
440/**
441 * Output a leave function log message.
442 * A leave message is considered to be one line and is appended a newline if
443 * none was given.
444 *
445 * @param uEnterTS The timestamp returned by LogEnter.
446 * @param pvInstance Logger instance. If NULL the message goes to the
447 * default log instance.
448 * @param fGroupAndFlags Logging group and logging flags.
449 * @param pszFunction Name of the function which was entered.
450 * @param pszFormat Format string to display the result.
451 * @param ... Arguments to the format string.
452 */
453extern void __libc_LogLeave(unsigned uEnterTS, void *pvInstance, unsigned fGroupAndFlags, const char *pszFunction, const char *pszFormat, ...) __printflike(5, 6);
454
455/**
456 * Output a log message.
457 * A log message is considered to be one line and is appended a newline if
458 * none was given.
459 *
460 * @param uEnterTS The timestamp returned by LogEnter.
461 * @param pvInstance Logger instance. If NULL the message goes to the
462 * default log instance.
463 * @param fGroupAndFlags Logging group and logging flags.
464 * @param pszFunction Name of the function which was entered.
465 * @param pszFormat Format string for the message to log.
466 * @param ... Arguments to the format string.
467 */
468extern void __libc_LogMsg(unsigned uEnterTS, void *pvInstance, unsigned fGroupAndFlags, const char *pszFunction, const char *pszFormat, ...) __printflike(5, 6);
469
470/**
471 * Output a raw log message.
472 * Nothing is prepended. No newline is appended.
473 *
474 * @param uEnterTS The timestamp returned by LogEnter.
475 * @param pvInstance Logger instance. If NULL the message goes to the
476 * default log instance.
477 * @param fGroupAndFlags Logging group and logging flags.
478 * @param pszFunction Name of the function which was entered.
479 * @param pszString Pointer to raw log message.
480 * @param cchMax Maximum number of bytes to write.
481 */
482extern void __libc_LogRaw(void *pvInstance, unsigned fGroupAndFlags, const char *pszString, unsigned cchMax);
483
484/**
485 * Assertion helper.
486 * Logs and displays (stderr) an assertion failed message.
487 *
488 * @param pvInstance Logger instance. If NULL the message goes to the
489 * default log instance.
490 * @param pszFunction Name of the function which was entered.
491 * @param pszFile Source filename.
492 * @param uLine Line number.
493 * @param pszExpression Expression.
494 * @param pszFormat Format string for the message to log.
495 * @param ... Arguments to the format string.
496 */
497extern void __libc_LogAssert(void *pvInstance, unsigned fGroupAndFlags,
498 const char *pszFunction, const char *pszFile, unsigned uLine, const char *pszExpression,
499 const char *pszFormat, ...) __printflike(7, 8);
500
501/**
502 * Validate a memory area for read access.
503 * @returns 1 if readable.
504 * @returns 0 if not entirely readable.
505 * @param pv Pointer to memory area.
506 * @param cb Size of memory area.
507 */
508extern int __libc_StrictMemoryR(const void *pv, size_t cb);
509
510/**
511 * Validate a memory area for read & write access.
512 * @returns 1 if readable and writable.
513 * @returns 0 if not entirely readable and writable.
514 * @param pv Pointer to memory area.
515 * @param cb Size of memory area.
516 */
517extern int __libc_StrictMemoryRW(void *pv, size_t cb);
518
519/**
520 * Validate a zero terminated string for read access.
521 * @returns 1 if readable.
522 * @returns 0 if not entirely readable.
523 * @param psz Pointer to string.
524 * @param cchMax Max string length. Use ~0 if to very all the
525 * way to the terminator.
526 */
527extern int __libc_StrictStringR(const char *psz, size_t cchMax);
528
529__END_DECLS
530
531/** @} */
532
533#endif
Note: See TracBrowser for help on using the repository browser.