                      [Thanks to Louis W.  Erickson for contributing this file]
------------------------------------------------------------------------------

INTRODUCTION:

This is a quick overview of all the functions included in this
library, with all their inputs and return values listed and defined in
one place, so you don't need to refer to the header and/or the sources
as much.

------------------------------------------------------------------------------

USING THE LIBRARY:

Before calling the library, make and install it.  Include shhmsg.h in
every module that will make calls to the library.  You probably also
want to set the application name before using the output functions.
See msgSetName, below.

link with the library like so:

    cc foo.c -o foo -lshhmsg

or, include it directly, if it's not in the system path:

    cc bar.c -o bar libshhmsg.a

------------------------------------------------------------------------------

A word about streams:

This library uses three file streams.  One is used for error messages,
one for informational messages, and one for verbose messages.  These
normally default to stderr, stdout, and stderr, respectively.  They
can, however be easily changed, by calling the stream management
functions, and set to any stream the caller likes, including stdout,
stderr, opened pipes, open files, an open to /dev/console, whatever.
The documents refer to them as the "error stream", the "message
stream", and the "verbose stream".  These names have nothing to do
with what stream they may be actually pointing to.

------------------------------------------------------------------------------

Controlling the library:

There is one initialization function, and several control functions.

------------------------------------------------------------------------------

FUNCTION: void msgSetName(const char *s);

DESCRIPTION:

Call msgSetName with the name of the application as the parameter.
Note that argv[0] is a perfectly valid (perhaps encouraged) place to
get this, and all preceding path information to the program name will
be stripped off before it is displayed.

SAMPLE:

    msgSetName(argv[0]);

==========================

FUNCTION: void msgSetQuiet(int onoff);

DESCRIPTION:

This function sets an internal flag with whatever you pass in.  It
controls the behavior of msgMessage (see below).  A non-zero will
silence msgMessage, and a zero value will make it produce output.

You can use the constants MSG_QUIET and MSG_OUTPUT, defined in the
header file, if you want, or 0 or 1, or whatever.

SAMPLE:

    msgSetQuiet(MSG_OFF);

==========================

FUNCTION: void msgSetVerbose(int level);

DESCRIPTION:

This function controls what calls to the msgVerbose function occur.
If the first parameter to that function is greater than the currently
set level, the function produces output.  If you call this function
from code, the value of what you pass becomes the currently set level.

If you pass MSG_VERBOSE_NONE, all calls to msgVerbose will produce no
output, quieting your program a great deal.

The default value is MSG_VERBOSE_DEFAULT.  It has special behavior.
If you do not call msgSetVerbose, or you call it with
MSG_VERBOSE_DEFAULT, then the current verbosity level is read from an
environmental variable.  The variable is based on the name set with
msgSetName.  The program takes the first ten bytes, forces everything
to upper case, and appends "_LEVEL" to it to make the name.  You can
set this variable (export it if you're using bash or sh) and then the
program will produce that much output.  Notice that this is a numeric
value of -1, so all prompts will be suppressed if there is none set.
Spaces in the name are NOT affected, and must be part of the
environmental variable's name.

NOTE: Because the special values used to control the extended behavior
are negative numbers, the user of negative levels is not recommended.
Levels from 0 to MAX_INT should be ok.

SAMPLE:

    msgSetVerbose(2);

-or-

    msgSetVerbose(MSG_VERBOSE_DEFAULT);

==========================

FUNCTION: void msgSetShowNameAlways(int onoff)

DESCRIPTION:

Some of the functions in the library prepend the name of the
application set with msgSetName to the strings they output.  Some
functions do this SOMETIMES.  Calling this with a non-zero parameter
will make ALL of the functions in the library do this.  Calling it
with a 0 will return the default behavior.  When using this as a debug
engine, having the name prepended is useful.  The default value is
"off".

There are predefined constants, MSG_ON and MSG_OFF in the header file,
if you want to use them.

SAMPLE:

    msgSetShowNameAlways(MSG_ON);

==========================

FUNCTION: FILE *msgSetErrorStream(FILE *f)

DESCRIPTION:

This function sets the file stream that the error functions (msgError,
msgFatal, msgPerror, and msgFatalPerror) output to.  The return value
is the old stream that was in use (to be closed, if needed).  No
opening or closing of these streams is performed by the library.

Passing in NULL will return the library to it's default value (stderr)
and return you the steam currently in use.

SAMPLE:

    FILE *fl;
    fl = fopen("/dev/console", "w");
    msgSetErrorStream(fl);
    ...
    fclose(msgSetErrorStream(NULL));

==========================

FUNCTION: FILE *msgSetMessageStream(FILE *f);

DESCRIPTION:

This function controls the stream that msgMessage outputs to.  It
normally uses stdout, but this can be changed to anything you want.
The library does no opening or closing of this stream, the application
must do this.

Passing in a NULL returns the library to the default of stdout, and
returns the current stream in use.

SAMPLE:

    FILE *fl;
    fl = fopen("output", "w");
    msgSetMessageStream(fl);
    ...
    fclose(msgSetMessageStream(NULL));

==========================

FUNCTION: FILE *msgSetVerboseStream(FILE *f);

DESCRIPTION:

This function controls what stream the msgVerbose function outputs to.
The default value is stderr.  The library does no opening or closing
of this file.

Passing in a NULL restores the library to the default of stderr, and
returns the value currently in use.

SAMPLE:

    FILE *fl;
    fl = fopen("output", "w");
    msgSetVerboseStream(fl);
    ...
    fclose(msgSetVerboseStream(NULL));

------------------------------------------------------------------------------

Using the library to report errors:

FUNCTION: void msgError(const char *format, ...)

DESCRIPTION:

Pass msgError printf-like arguments, and it will print the name of the
program, followed by ": ", then your passed in arguments to whatever
the error stream is set to.

SAMPLE:

    msgError("you need to have more than %d things!\n", iThings);

==========================

FUNCTION: void msgFatal(const char *fmt, ...)

DESCRIPTION:

This function, called with printf-like arguments, will print the name
of the program, a ": ", then your output, to whatever the error stream
is set to.  It will then exit the running program, with an exit code
of 99.

SAMPLE:

    msgFatal("cannot open: %s\n", szFileName);

==========================

FUNCTION: void msgPerror(const char *fmt, ...)

DESCRIPTION:

msgPerror, named for the C library call perror, will print out your
passed in, printf-like arguments, then a ": ", then the textual error
code represented by the system global errno.  All output goes to the
stream set as the current error stream.

If errno represents "no error", then the function returns, doing
nothing.

The program name is not output, unless the msgSetShowNameAlways
function has forced it to do so.

SAMPLE:

    msgPerror("can't open %s", filename);

==========================

FUNCTION: void msgFatalPerror(const char *fmt, ...)

DESCRIPTION:

Like msgPerror, this function accepts printf-like arguments, and
displays those to the stream set as the error stream, followed by a
": ", then the textual error string that the global errno indicates.

If errno is not reporting an error, the call returns, having done
nothing.

The call normally does not output the program name, but a call to
msgSetShowNameAlways can force this.

If an error is set, the function will not return, exiting with a
return code of 99.

SAMPLE:

    msgFatalPerror("can't continue: %s file missing!", filename);

==========================

FUNCTION: void msgMessage(const char *format, ...)

DESCRIPTION:

msgMessage will take your output, format is as printf would, and
output it to the message stream.  If quiet mode has been set with
msgSetQuiet, nothing is output.  Normally, the program name is not
output, but if msgSetShowNameAlways has been called, the name of the
program, then a ": " will be prepended to the message.

SAMPLE:

    msgMessage("something went wrong!\n");

==========================

FUNCTION: msgVerbose(int level, const char *fmt, ...)

DESCRIPTION:

msgVerbose accepts a "verbosity level", followed by printf-like
arguments.  If the current verbosity level is greater than or equal to
the passed in value, the output will be formatted, and sent to the
verbose stream.  See above, in the msgSetVerbose description, for the
different fixed values, and methods of getting them.

The program name is not automatically output, unless
msgSetShowNameAlways has been called with a non-zero parameter.

Note that this can be quite useful to track program flow, if these are
used liberally at function entry and exit points, with a high
verbosity level.

SAMPLE:

    msgVerbose(5, "entering the CalcFooBar function!\n");
