C/Tcl Interface: Message Handling

This page describes the message handling services of Janus 3.

Creating Messages from C

There are a few macroes defined in error.h which faciliate the generation of warnings and error messages. These are the following:
INFO (Information)
Used for informing the user about what is going on. This message kind should be used when you think the user might want to know somethind, but you don't expect this to be a problem (e.g. the number of items read from a file, or the acknowledment that some procedure has finished successfully, etc.).

WARN (Warning)
This message kind should be used when you expect that the user might have done a mistake. The programm could still continue running and the user might just have wanted to do exactly what is happening, but usually this could cause problems (e.g. mismatching sizes and numbers of items, undefined items, attempted access to non-existing items, etc.).

SWARN (Silent Warning)
This is the same severity level as a regular warning, only this time the message is not printed immediately. Instead it is accumulated in a message buffer, such that the calling function can decide itself whether it considers the message important enough to notify the user (e.g. when a function wants to check if a word is existing, it is actually expecting a possible negative answer, then the produced silent warning can be ignored using MSGCLEAR).

ERROR (Error)
This is a regular error, something after which a function can't continue (e.g. undefined objects or commands, type mismatches, NULL-pointers, out of memory cases, etc.).

SERROR (Silent Error)
This is the same as a regular error, only this time the message is not printed immediately. Instead it is accumulated in a message buffer, such that the calling function can decide itself whether it considers the message important enough to notify the user.

FATAL (Fatal Error)
This message kind is used for errors which are likely to have destroyed vital data of the recognizer, or when the user asks impossible things, or for errors that should be impossible but happened anyway, i.e. errors after which it seems rather undefined how the process will continue running (e.g. too many items for a static array, unimplemented functions, corrupt pointers or data structures, etc.).

MSGCLEAR (Clear Message Accumulator)
This macro is used to empty the message accumulator, all the silent warnings and erros residing in the accumulator will be removed (e.g. hundreds of undefined item messages, or messages produced by the previous command).

MSGPRINT (Print Message Accumulator)
This macro is used to empty the message accumulator and print its contents before removing all the messages.

All of the above macroes are used exactly like the standard printf() function of C. They all expect a format string followed by a variable number of items. The macroes will automatically add the name of the file and the number of the line from where they are invoked to the parameter list of the msgHandler() function. If the format string starts with an error code (i.e. two comma-separated not-comma-containing not-right-angle-containing strings enclosed in angle brackes) then the error code will be stripped off the format and treated separately. If no error code is provided the two strings will be treated as empty strings. The first of the two strings is referred to as the major code of the error, the second string is the minor code of the error. For example, you could have a line like:
    ERROR("<Foo,Bar>Can't snafu %d times!\n",7)
Then the error message will be "Can't snafu 7 times!\n", the major code of the message is Foo and the minor code is Bar. You can use these codes to determine what has gone wrong when a command returns simply TCL_ERROR. E.g. you would like to know why the Viterbi algorithm couldn't do his job then you don't have to parse the error message to find out what has happened, instead you can decide depending on the error code (see below for details).

Handling Messages from Tcl

The actual output is not done from C but by the Tcl procedure itfOutput. You can have a look at the procedure with info body itfOutput and you can redefine it. For example like this:
proc itfOutput { cmd mode text file line major minor } {
 puts "Macro    = $cmd"
 puts "Mode     = $mode (0=regular, 1=silent, 2=clear, 3=print)"
 puts "Message  = $text"
 puts "File     = $file"
 puts "Line     = $line"
 puts "Code     = Major: $major   minor: $minor"
}
The global variables itfErrorMajor and itfErrorMinor, are set by the default version of itfOutput. If you chose to redefine this procedure then keep in mind that some of your scripts might examine the global variables itfErrorMajor and itfErrorMinor. Also keep in mind that the global variables only contain the code of the last error.