SPRAAK
|
Message and error processing. More...
Macros | |
#define | SPR_MSG_ID(var, name) |
#define | SPR_SET_THREAD_ID(thread_name) |
#define | spr_error(routine,...) |
Send an error message. More... | |
#define | spr_warning(routine,...) |
Send a warning message. More... | |
#define | spr_info(routine,...) |
Send an info message. More... | |
#define | spr_msg_long_start(lvl, routine,...) |
Send a long debug message at a given level lvl. More... | |
#define | spr_msg_async_start(lvl, routine,...) |
#define | spr_assert1(routine__, tst__) |
#define | spr_assert2(routine__, tst__) |
#define | spr_assert3(routine__, tst__) |
Typedefs | |
typedef void(* | SprMsgCatchFunc )(int lvl, const char *thread, const char *routine, const char *format, va_list *list) |
Enumerations | |
enum | { SPR_ERROR, SPR_WARNING, SPR_INFO } |
Predefined message levels for error, warning and info messages. More... | |
enum | { SPR_MSG_SET, SPR_MSG_RM, SPR_MSG_ADD } |
Functions | |
int | spr_msg (int lvl, SprMsgId *routine, const char *fmt,...) |
int | spr_msg_check (int lvl, SprMsgId *routine) |
int | spr_set_thread_id (const char *name) |
void | spr_msg_modif_lvl (int lvl) |
Set the global message filter level to lvl, i.e. only messages with a level equal to or lower than lvl will be output (unless routine or thread specific levels are defined. More... | |
int | spr_msg_get_lvl (void) |
int | spr_msg_modif_in (const char *filter_desc, int action) |
int | spr_msg_modif_from (const char *filter_desc, int action) |
SprDynStr | spr_msg_get_in (void) |
SprDynStr | spr_msg_get_from (void) |
int | spr_msg_modif_stream (SprStream *restrict stream, const char *restrict fname) |
void | spr_msg_set_timeout (int sec) |
void | spr_msg_modif_catch_func (SprMsgCatchFunc handler) |
int | spr_msg_ini_time (SprMsgId *prog) |
Variables | |
SprStream * | spr_msg_stream |
Message and error processing.
This module provides a system for message and error reporting/accounting.
The main properties of the system are:
On the program level, configuration of the message system is done by means of the following global options:
When just using the library, the same effect can be obtained using the environment variables 'SPR_DEBUG_STREAM', 'SPR_DEBUG_LVL', 'SPR_DEBUG_IN', and 'SPR_DEBUG_FROM'.
The message system is used to signal errors, warnings, info messages and even debug information. The severity of the message is indicated by a level. The following levels are predefined:
The remaining positive levels are used for debugging. The level is typically proportional to the amount of output generated. Some rules of thumb about which level to use where are:
Messages (error, warning, info or debug) can be either short or long.\ Short messages are sent as a single printf() command, are no longer than 1023 characters, and if they consist of multiple lines, all extra lines must start with a tab ('\t'). Multiple short messages can be sent concurrently. Long messages are not concurrent (although short messages can still be sent concurrently). Sending a long message consist of a message start and stop command pair with in between a set of writes to the stream 'spr_msg_stream'. The intermediate output can be free formatted, but must end with a new-line ('\n') character.
Warnings and errors must inform the user on both the problem at hand and the cause of the problem. Errors should, as a rule of thumb, only be reported in the routine where they occur. Rehashing the same error message in the calling routine(s) should be avoided.
Example: if a file fails to open, the spr_fopen() routine will give detailed information. If the main purpuse of the calling routine was opening that file, nothing more needs to be reported. If opening that file was only one step in a more complex operation, a short message indicating that the complex operation failed can be given (but details on the cause are not needed since spr_fopen() already gave the details).
Errors and warnings cannot be blocked. Info and debug messages can be filtered either by a global threshold level or by routine and thread specific threshold levels. Info and debug messages can also be suppressed until a certain trigger is activated. See the routines spr_msg_modif_lvl(), spr_msg_modif_in() and spr_msg_modif_from() for more information.
In order to use the debug system in your code, each routine (or group of routines) must be tagged with a unique id as follows:
The name of the current function is (in C99) also available using the macro __func__
.
Threads must also be tagged with an unique id as follows:
It is allowed to make dynamic names for threads (e.g. aux_thread00 ... aux_thread99), but this will leak memory (a few bytes per thread started) and is fairly slow, so use this only for coarse grained threading. This can be done as follows:
SPR_DEBUG_STREAM
identical to the option –debug_stream
SPR_DEBUG_LVL
identical to the option –debug_lvl
SPR_DEBUG_IN
identical to the option –debug_in
SPR_DEBUG_FROM
identical to the option –debug_drom
The message system assumes that names are static strings. See the examples on how to assure this.
Changing the filters (spr_msg_modif_in()) or triggers (spr_msg_modif_from()) while there are multiple threads running may result in some transitional abnormalities (no crashes, just too many or too less messages).
The amount of concurrency the msg-system can handle is limited. Typically 16 threads can send simultanious messages in a non blocking fashion if the destination stream can keep up.
Unamed threads may result in undefined behaviour in combination with nested messages.