NAME
ulog.h - standardized I/O routines with many features
SYNOPSIS
Because of this module, there is not a single plain printf() in all of NODElib. All screen I/O is passed through the ULOG package, which means that you can arbitrarily set how verbose the messages are and where they should go (i.e., log files, error message window, etc.).
#include <ulog.h>
void ulog(int type, char *fmt, ...);
void ulog_redirect_fp(int type, FILE * fp);
void ulog_redirect_hook(int type,
void (*func) (char *msg));
void ulog_add_shutdown_hook(void (*func) (void));
void ulog_remove_shutdown_hook(void (*func) (void));
void ulog_mutex_init();
DESCRIPTION
The user log system (ulog) provides a method for controlling all tty type output in a user program. The philosophy behind this package is that modular routines should never directly call printf(3), but should instead direct output to ulog. When appropriately used, it becomes possible to selectively redirect output messages based on type. This feature is tremendously useful when existing code is used as a back-end to a GUI, for example. Thus, instead of rewriting printf() statements so that output is sent to a window, one only needs to select a new output hook.
There are seven different types of messages distinguished by ulog. Normally you will only use the ulog() function which is used in a manner similar to printf(), except that a message type must be specified. The message types are described below. Since each message type can be sent to a different destination, the default destination is also listed, along with any other peculiarities of the message type.
- ULOG_DEBUG
Messages that contain information normally only of use
while debugging. Default destination is to stderr. All
message are preceded by the string "(FILE, LINE): "
to indicate where the call was made. Any instance of
"%m" in the format string is replaced with the string
which corresponds to errno.
- ULOG_INFO
This message type is provided just in case none of the
other types fit your needs. It behaves just like ULOG_PRINT
but defaults to standard error instead. Use this for
debugging and error messages when it doesn't make sense
for a (FILE, LINE) prefix to be printed.
- ULOG_PRINT
Messages that you would normally consider
the standard output of your program. Default destination
is to stdout. Only the standard printf() type
formats are supported.
- ULOG_WARN
Warning messages denote a fully recoverable condition.
Warning conditions usually denote a problem with the user's
input, or a problem with the environment. For example,
failure to open a file with a supplied name would be a
typical warning condition. Default destination is to stderr.
Any instance of "%m" in the format string is replaced with
the string which corresponds to errno.
- ULOG_ERROR
Error messages denote serious problems that may be
recoverable. Error conditions are usually indicative
of a programmer's error. For example, an attempt to pop
an item off of an empty stack would be an error. Default
destination is to stderr. All message are preceded by
the string "(FILE, LINE): " to indicate where the call
was made. Any instance of "%m" in the format string is
replaced with the string which corresponds to errno.
- ULOG_FATAL
Fatal errors are similar to normal errors except that they
are considered unrecoverable. An example would be a NULL
being returned from malloc() or a failed assertion.
The result of a ULOG_FATAL message is identical to a
ULOG_ERROR message except that each shutdown hook is called
prior to exit(1). See below for more information
on shutdown hooks.
- ULOG_ABORT An abort message is identical to a fatal message except that the shutdown hooks are not called and abort() is called. This allows you to dump core at a time of your choosing.
Since each use of ULOG_DEBUG, ULOG_ERROR, ULOG_FATAL, and ULOG_ABORT prints out the prefix "(FILE, LINE): " any instance of "%t" in the format string will print a newline followed spaces, followed by " : " such that the the ":" characters of the two lines will match up. For example,
ulog(ULOG_ERROR, "func: failed to write \\"%s\\".%t%m.", fname);
will print:
(foo.c, 128): func: failed to write "afile". : No space left on device.
Notice also that newlines are appended to any line without one.
Function Definitions
The following function prototypes are given in the header file ulog.h.
void ulog(int type, char *fmt, ...);
The ulog() function is not really function, but a special type of macro that evaluates to a function. This distinction is probably not needed for most users, however we give the warning just in case. Given a message type as described in the beginning of this section ulog() prints the appropriate message as determined by the format string fmt and the rest of the arguments.
void ulog_redirect_fp(int type, FILE * fp);
If fp is non-NULL then all messages of type type will be written to the file pointed to by fp.
void ulog_redirect_hook(int type,
void (*func) (char *msg));
If func is non-NULL then all messages of type type will be passed to the function pointed to by func.
void ulog_add_shutdown_hook(void (*func) (void));
This function adds func to the central list of shutdown hooks, which are called in the event of a ULOG_FATAL message being issued. You can use this to gracefully exit the program (write out buffers, free memory on DOS machines, etc.).
void ulog_remove_shutdown_hook(void (*func) (void));
This function will remove func from the central list of shutdown hooks.
Miscellaneous Items
There are two global variables that you can use to tune the behavior of ulog:
- int ulog_threshold ; The order of the message types listed
in the beginning of this section is in increasing order of severity. Only
messages which have a severity greater than ulog_threshold will be
printed. By default it is set to 0 or ULOG_PRINT.
- int ulog_never_dump ; If set to non-zero, then ULOG_ABORT
messages will behave as normal but call exit(2) instead of
abort().
- int ulog_no_prefix ; If set to non-zero, then messages of
type ULOG_DEBUG, ULOG_ERROR, ULOG_FATAL, and ULOG_ABORT will not print the
(FILE, LINE) prefix string before a message.
BUGS
Right now ulog has a fixed size output buffer determined by ULOG_BUFF_SZ. There is no easy way around this since ulog uses vsprintf() to do the bulk of the string processing.
AUTHOR
Gary William Flake (gary.flake@usa.net).
SEE ALSO
syslog(3), printf(3), errno(2), perror(3)