In contrast to many other libraries that use Erwin, the invocation
of this function is not needed. However, the error output is
improved if you invoke this (e.g., the program name is output).
If you do not invoke this, then the library also sets up a default
output stream to stderr. This is convenient for testing (simply
link -lerror and there you go).
Furthermore, if you do not invoke err_init(), you are only allowed
*printf functions, but no other functions from this library.
In total, it is highly advisable to invoke err_init() at the beginning
of your program.
If you want a progname different from the base name in argv[0] (under DOS
without .exe), then invoke err_set_progname with the desired name.
Important Note
If you invoke err_init, then by default, no output stream is
set, so no error messages are ever seen! So typically, you
will set a default error stream directly after the above
invocation. E.g.:
Please only give a non-NULL error style if you know what
you are doing. E.g. if you do set the style here,
the user cannot set it from the command line anymore.
Usually, plain style is the default, but can be set
differently. err_init() parses part of the command
line to check user settings.
Getting and setting the program name that is displayed
You are uncouraged to invoke err_set_progname before err_init,
but then you must ensure that the string you pass is not
deallocated.
(If you invoke the function after err_init, you may do so
even with temporary strings.)
Invoking err_set_progname before init makes the library
parse another environment variable ("ERR_OPTIONS_"
concatenated with the program name in upper case) specific to
the application.
Under Unix, the PID that is displayed defaults to the value
of getpid(). Under Windos, there is currently no PID
default. This can be overridden with this function.
Note that there is a command line option 'show-pid' that
decides whether the PID is displayed.
Getting and settings the prefix by which the error library is configured,
i.e., the prefix for the environment variables it reads from and the
command line options. By default, this is "err". It is converted
to upper case for the environment variables, thus "ERR" is the default
there. Further, if this is non-empty, a "-" is inserted
in the command line options and a "_" in the environment variables.
Therefore, the default environment variable is "ERR_OPTIONS" and the
default prefix for command line options is "--err-".
Setting this is NULL effectively resets the prefix to "msg".
Note
the default used to be "err" in older versions.
Using "msg" is recommended, since this refers to more than errors.
"err" is merely a historic misnomer.
The prefix must be set before an invocation to err_init(), otherwise,
it has no effect.
Sets a user-provided callback for resolving addresses, i.e.,
to look up to which source code location an address corresponds.
If you have several address spaces, you should use the number, subsystem or
group mechanism to pass through information about memory space to this
function.
An alternative to this look-up mechanism is to provide a resolve function
for an overloaded extended address (err_ext_address_t). This way, the
resolver is invoked depending on the type of extended address.
If this is invoked, the error location will be used in the
next eprintf command regardless of a possibly given location.
Note that only the last location set this way will have an
effect.
Further note that an eprintf with the C_TAG_PREFIX tag and
a given location also invokes this function if the next
location is not set. Therefore, calling this function is
equivalent to C_TAG_PREFIX with a location and an empty
format string when the next location is unset. However, use
this err_set_next_location() for clarity.
The function err_erase_prefix() deletes this location. If
you set a location whose file and address are invalid, this
is also equal to erasing the location.
If the stream already exists for the given file, the style will not
be changed. This is to allow the user to change the style explicitly
The streams stderr and stdout automatically get the names "stderr"
and "stdout".
Use err_stream_set_style for changing a stream style (remember to use
this AFTER err_stream_set_name since that function also likes to change
the error style if it has settings for that name, so it would again
reset the style.).
When you set this, command line options for styles are enabled for
the given stream. (E.g. print filtering (NYI), style settings)
Note
When a stream with this name exists and has a file pointer
of NULL or equal to the given file, then the current settings
will be copied from the named stream to the stream defined
by the file pointer. After that, the two streams will be
identified.
If a stream with the given name exists that has a different file
pointer, this routine returns false (= no success).
Note
when you erase a stream with a name, then the settings will be
erased, too, together with its name.
You can have only one style per FILE*. If you add a stream for
a FILE* that is already in use, the style is switched to the
new style before added the additional stream. Please note
the in this case, there are still two streams for this file,
although only one style. So if the filtering for both streams
is not mutually exclusive, some error messages are printed into
that stream twice per issue.
To change a style, first err_remove_stream() and then add it again.
Note that filtering rules are stored per file, so you cannot
reset a stream filter by removing the stream and adding it again.
If you want to reset a stream including its filtering rules, use
err_reset_stream().
You can set a group of tags by using bit operators for simple
filtering: E.g.
C_TAG_WARN | C_TAG_ERROR
~C_TAG_DEBUG
For all tags, use C_TAG_ALL.
The values 0 and -1 for tags are illegal.
By default, there is one stream for the messages, stderr,
used for all messages.
A stream may be NULL in which case err_style_default will
be used.
extern void err_clear_callback (int tags, int priority)
A function to call back for every message after filtering and formatting.
Like for err_(add/remove)_stream, you can specify groups of tags.
The callbacks are invoked in the following order:
Before the call to the print function, all priorities > 0
are invoked in rising order of the priority (1, 2, 3....)
and for the same priority, callbacks added later are invoked
later.
After the call to the print function, all priorities < 0
are invoked in RISING ORDER OF THE PRIORITY (... -3, -2, -1)
and for the same priority, callbacks added later are invoked
earlier.
For err_add_callback a callback may be NULL in which case nothing
is invoked. However, the error message is formatted with the
given style, so this may be used for a more complex call back
mechanism anyway (by providing your own style).
err_remove_callback removes a callback by its function pointer.
Note that on machines were code pointers have a different size that
data pointers, this currently does not work. We will have to implement
something else. This function is deprecated, please use the other
alternatives that receive a ErrFunctionPtr.
err_clear_callback() erases all callbacks for a given tag/priority.
(E.g. this can be used to remove the terminating exit(0) / abort()
invocations. However, this is sincerely deprecated!)
If the style is NULL, the pure text of the error message is passed
to the callback.
[For the behaviour of the old interface, use priority = 1.]
extern int err_declare_subsystem (char const * name)
Note that this function does not need to be invoked. You may
directly use err_subsystem() instead.
Generates a new, unique identifier of a new sub-system with the
given name. The returned value can be combined with the C_TAG_...
constants to generate errors in this sub-system. E.g.:
identification of an error message (the name of the
sub-system will be printed with the error message)
redirection of error messages.
b) was mainly introduced to keep old libraries compatible by
allowing them to set a default callback that prints all their
error messages into a vector. (liblisp and libtf14net work
like this).
Returns the identifier of a given group. You need not declare groups,
but may freely use them directly. Groups are a bit like subsystems,
but in contrast, the group is not shown, but instead meant to be
an additional level of classification of messages. They are used
mainly for filtering.
Start buffering all message into given buffer.
This locally makes error message issuing quiet.
Usage may be nested: this pushes an error buffer
which is then the innermost buffer.
If buffer is NULL, messages are hidden.
When buffering is active, only the innermost buffer
is filled with messages. The messages are already
filtered, but not formatted (apart from the mere
message).
Note that the buffer combines messages that have the
C_TAG_MORE with previous messages for convenience. This
is reflected in the typedef of err_message_t in
include/error/decls.h .
Note
Messages with the following tags cannot be gathered in buffers:
Re-issue buffered error messages that where gathered
using err_begin_buffer and err_end_buffer.
Note that this function does not filter the messages,
because filtering is done before already.
After re-issuing the mesages, the buffer is cleared.
Note that an err_buffer_t is not an Erwin vector.
Still, many functions are identical to Erwin vectors,
so you can easily filter it before unbuffering using e.g.
err_buffur_erase_if etc. You don't need to take care
of freeing messages, because this is done by Erwin.
Usually an application should stick to the ERR_DEFAULT_(YES,NO)
values, since this library will soon parse the command line
and configure itself at the users will.
The default is to use the setting for the given group.
If you set this, this overrides settings for the group.
Note
Messages with the following tags cannot be filtered,
since they have no numbers:
More specific selections override less specific ones.
The default is to hide debug messages (C_TAG_DEBUG) if NDEBUG is #defined
and to show all others. If NDEBUG is not #defined, all messages are
displayed by default. (Of course, this behaviour can be overriden using
this function, since that is only the default. It is even a weaker
default than can be defined with this function, so you can change it
with ERR_DEFAULT_YES and ERR_DEFAULT_NO.)
Note than currently, the library has only one table far the settings,
so the following sequence:
extern void err_print_message (FILE * stream, int number, err_decision_t print)
err-renumber
Define that the given error number shall be printed. See err_print()
for more details on the difference between printing and showing and
the filtering thereof.
You can set-up filtering rules without actually currently using
that FILE*. The next time you err_add_stream(), the filtering
will be active.
With this function, you can set-up filtering on streams, e.g.,
have all messages of group 'logfile' go into a special file only.
You can use NULL as a file pointer to set a default behaviour
for all possible files. This default behaviour can be reset
using err_reset_stream (NULL).
Any message returning YES using the given filtering will only be
printed once into the given stream.
To accomplish this, the text of every message is stored in
a hash table.
If 'table' is NULL, an internal global table is used. Otherwise,
the given symbol table is used for remembering messages. If
you want to, you can give a different table to the system.
Note
The library never deallocates tables that you give it.
To set a default behaviour for all possible files, use NULL as
a file pointer.
The only way to remove the filtering per stream is by using
err_reset_stream ().
You can reset the default values by using err_reset_stream(NULL).
extern ERR_ERWIN_BOOL err_is_printed (FILE *, int tag, int number)
err-renumber
checks the stream filtering for the given file.
Note
even if the FILE* is currently not in use, it's filtering
rules are still active.
If you want to reset a stream including its filtering rules, use
err_reset_stream().
Further Note
even if a FILE* was never seen by the library, it
does have filtering rules. So even without ever using err_add_stream()
on a new FILE*, this function will return ERR_ERWIN_TRUE if
the message is issued and shown.
extern ERR_ERWIN_BOOL err_is_seen (int tag, int number)
err-renumber
The functions consider all possible filters that prevent
messages from being printed in to a stream: issue filters,
show filters, and buffering. err_is_seen_in() also considers
stream filtering.
In short, this functions return whether the user will see
a message that is produced with an eprintf call in at least
one of the streams it is printed into.
An issued message is one that is counted. Those messages
whose issuing is prevented by a filter will not be seen by
error buffers and will not be distributed into streams and
user callbacks, and will also not be shown or printed.
So this a very hard filtering. The only counters that
are increased when a message is filtered from issuing are
the 'received' counters, which count the number of eprintf
invocations altogether.
See the ERR_STATUS_* enum for a list of filtering and
counting levels.
extern ERR_ERWIN_BOOL err_is_issued (int tag, int number)
err-renumber
The parameters are the same as for the show family, but
the effect is that the filtering is done such that the messages
are not even processed if they are filtered this way. In
contrast to only hiding them, this means:
they are not counted
the callbacks are not invoked
they are not stored in buffers.
Note
Messages with the following tags cannot be suppressed:
extern void err_do_count (int tag, int number, err_status_t)
err-renumber
Counts this error in the internal counters.
This is usually not very interesting to the user, since this
the function the library uses internally to count. If the
user wants to contribute, they can use this.
This function does not generate a fatal error if any of the fatal
counters is exceeded by the counting. This checking is only done in
eprintf functions.
In contrast to err_add_count, you cannot count groups of tags with
this function. (The result of trying to do so will be strange.)
extern void err_set_fatal_count (err_status_t, int tag, int cnt)
This function let's you define a maximal amount of errors
that leads to a fatal error. This is useful if you are
expecting a large number of errors when you'd start fixing
at the beginning anyway.
set/unset the amount of times a certain message may occur, that is
considered to be fatal. As with the normal message counters,
you may set/unset this for tags, groups, sub-systems, and messages.
cnt <= 0 is illegal.
As with counters, these functions work with groups of statuses, and
for ERR_COUNTER_TYPE_TAG, groups of tags.
Please note that these functions do not split the tag into tag,
subsystem and group. Instead, the fatal count may be specified
for any integer value. To check the fatal count, exactly this
value will be used to compare to the actual count. Therefore,
you can specify a fatal count for the sum of errors and
warnings, which in turn does not effect any fatal count for
errors and warnings alone. Or you could specify a fatal count
for C_TAG_ERROR of a given subsystem or group only.
This implies that you can only unset fatal counts exactly
for the tag you specified before. (So this behaves quite
differently from err_clear_count().)
Returns the name of the local environment variable for a
given prefix. This requires err_prognam() to return non-NULL.
E.g. for a prefix of "msg" and an err_progname() of "exec2crl",
this returns "MSG_OPTIONS_EXEC2CRL".
Parses the command line searching for options for the given library
(defined by the prefix) and calls the callback for each option found.
The processed options are removed from the command line.
Any dashes around the given prefix will be removed before being used.
First parses the environment variables for the given prefix,
then parses the command line args. This combines err_opt_parse_args()
and err_opt_parse_string() into one call.
The env.variables checked are derived from the prefix, which is
taken in upper case with _OPTIONS added, e.g. MSG_OPTIONS. This
is the first variable checked. The second variable, which may override
the settings, would be <PREFIX>OPTIONS<PROGNAME>, e.g.
MSG_OPTIONS_EXEC2CRL for a prefix of 'msg' and an err_progname() of
'exec2crl'.
Returns a symbol of a tag, e.g. "assertion" for C_TAG_ASSERTION.
In contrast to err_tag_description, these are not for humans but
for computers: a simple one word tag name. No spaces, to bells or
whistles.
fleprintf (tag, num, file, line, format, ...)
vofleprintf (tag, num, file, line, options, format, va)
"flp"
file, line and position (=column) are given:
flpeprintf (tag, num, file, line, pos, format, ...)
voflpeprintf (tag, num, file, line, pos, options, format, va)
"p"
an err_location_t const * argument is passed. This pointer
may always be a local reference even if the message is buffered.
The library copies the contents if needed.
leprintf (tag, num, loc, format, ...)
voleprintf (tag, num, loc, options, format, va)
This marks the message as a developer message by
adding C_TAG_DEBUG to the tag. Further, with
either -DNDEBUG or -DRELEASE, these functions will
not produce any message at all (it fact, the calls
will not even produce any code, so you can safely
use these without fearing that shipped code contains
debug code for generating the arguments).
The tag is a single bit C_TAG_xyz constant (see error/tags.h). You may
add a subsystem and/or group classification to it by using err_group()
and err_subsystem:
If num == 0, the number it is not printed.
You can use the errcodes script to insert the numbers automatically and
to check them into CVS.
Note
the error message will automatically be ensured to end in
\n. You, therefore, cannot issue one message using several
eprintf() calls. This is vital for the internal handling of
error messages anyway: one call = one message. However,
multi-line messages with additional lines that give additional
information can be implemented with the special error tag
C_TAG_MORE.
Options are Erwin vector options (e.g. ERR_FO_QUOTE_C_STRING etc.)
(The Erwin library of this error library has the prefix err_/ERR_/Err.)
The functions print the progname, PID, possible color tag, and a prefix
depending on the kind of message.
If tag == C_TAG_MORE and num == 0, the previous number is used. The same
holds for the tag in this case, which is replaced by the previous tag for
formatting. However, C_TAG_MORE may have a different number to allow
separate filtering etc.
The q-functions use the ERR_FO_QUOTE_C_STRING as options for printing (this is a
convenience abbreviation).
The fl types print a file and a line number in front of the message.
The flp types print a file, a line number and a line position.
The a types print an address or, if they can look up that address, the corresponding
file, a line number and possibly a line position.
Note that because of the compatibility with the fprintf family, these
routines return the number of characters that were printed, althought
this is really quite uninteresting information most of the time.
To be precise, the functions return the number of characters printed
without the automatic prefix (file, line, etc.), but the amount of
characters that resulted from formatting the user format string with
its arguments:
The de-variants (instead of e-variants) are for development and are not
compiled in when NDEBUG is defined. Messages issued using the de-family
never change the message counters, because counting would change in the
development version. Further, bodies of messages printed with de-variants
are colored using the C_TAG_DEBUG color.
Note that the de-family does not return a value. (This is due to some
compilers that do not support macro varargs.)
C_TAG_FATAL should be used with de-printf, since the call-back that
exits the program will not be invoked with NDEBUG.
Note
the tag C_TAG_DEBUG is a different message classification:
deprintf is thought to be for all kinds of messages that are
interesting to the developer, but not to users. E.g. a message
might indicate that some strange situation was encountered so that
an algorithm is not used, while in the production line of the
program, the algorithm is silently not used. C_TAG_DEBUG is more meant
to be for larger loads of messages that issue state information
about the algorithm during debugging, while deprintf is for messages
that are issued when unexpected things happend while you think that
an algorithm works.
extern int err_style_colon_format_flp (err_markup_t *, err_formatted_stream_t *, err_v_char_t *, int tag, int orig_tag, ERR_ERWIN_BOOL hide_file, ERR_ERWIN_BOOL hide_line, char const * file, int line, int pos)
This puts the string into double quotes and does the quotation
just like a (possibly interactive) shell would expect it. The
interactive shell is special wrt. to the