/*
    SUPPL - a supplemental library for common useage
    Copyright (C) 1995,1996  Steffen Kaiser

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    See: COPYING.LB
*/
/* $Id: MSGLIB.H 1.1 1998/08/19 06:33:33 ska Exp $
   $Locker:  $	$Name:  $	$State: Exp $

	Global message handling definitions.

*/

#ifndef __MSGLIB_H
#define __MSGLIB_H

#include <stdio.h>
#include <portable.h>

#define GLOBAL_GROUP 8
#define LOCAL_GROUP 0

#ifdef MSG_METHOD2
#undef MSG_METHOD1
#else	/* !defined(MSG_METHOD2) */

#ifndef MSG_METHOD1
#define MSG_METHOD1			/* default to method #1 */
#endif	/* defined(MSG_METHOD1) */

#endif	/* defined(MSG_METHOD2) */


/*
 *	MSGID is the black-box type to hold the identifier of a message
 */
#ifdef MSG_METHOD1
#ifdef _MICROC_	/* does not support typedef's */
#define MSGID unsigned char*
#else
typedef const unsigned char *MSGID;
#endif

/*
 *	DCL_MSG declares one MeSsaGe IDentifier;
 */
#define DCL_MSG(msg,group,id) extern const unsigned char msg[];

#define msgLock(msg) ((char*)msg)
#define msgRetreive(msg) ((char*)msg)
#define msgUnlock(msg)
#define msgUnlockString(msg)
/* this needs the one-byte alignment within the error definition files */
#define msgErrorNumber(msg) ((msg)[-1]) 
#endif	/* !defined(MSG_METHOD1) */

#define iFailure(nr) fatal(E_internalFailure, nr)
/* msgInit() is a function */

#define ANSI_TEST 0		/* check if output stream is connected to a CON device */
#define ANSI_DENY 1		/* do no send ANSI sequences into the output stream */
#define ANSI_ALLOW 2	/* do not check for CON device, send sequences */

#define NOISE_TEST 2	/* check if stdin is redirected, before emitting interactive messages.
						   skip if not interactive message */
#define NOISE_DENY 1	/* skip messages ‘t all */
#define NOISE_ALLOW 0	/* emit mess‘ges */
#define NOISE_ERR (-1)	/* error, returned by getNoiseLevel() on error */

#define ENoise_interactive 0	/* must be number zero !!! */
#define ENoise_informative 1
#define ENoise_fatal 2
#define ENoise_error 3
#define ENoise_warning 4
#define ENoise_none 5
#define ENoise_screen 6
#define	ENoise_Nr 7				/* number of noise levels */



void msgInit(void);
/* Initialize the message system.

   Currently:
   	+ Check for ANSI and set the ANSI test flag to ANSI_TEST or ANSI_DENY.
   	+ Check for redirected stdin and set the interactive test flag to
   	  NOISE_ALLOW or NOISE_DENY.
   	+ Determine the application's name.
*/

#ifdef _MICROC_
#define msgErrFct(fct) _msgErrFct(&(fct))
void _msgErrFct(int fct);
#else
void msgErrFct(void (*fct)(void));
#endif
/* Set a function, which will be executed right before the exit()-call,
   after an error() or fatal() message has been emittedú
*/

char *appName(void);
/* Return the name of the current process. This name is upper-cased
   and without drive, path, and extension.
*/


int fputmc(int c, int rep, FILE *fout);
/* Dump the character rep times into the stream fout.

	Return:		 0: OK
				!0: failure
*/


int skprintf(unsigned char *poi, unsigned len, char *fmt, const unsigned *args);
/* input:	poi: output stream; must not be NULL!
   			len: length of the output buffer:
   				== 0 => output buffer is stream (poi is FILE*)
   				else => output buffer is memory (terminating NUL is added)
   					the buffer is filled with up to (len-1) bytes
   					is used to indicate, how much space is left in the buffer
   			fmt: enhanced format string
   			args: pointer to the first argument

   output: number of written characters or EOF on failure

   This function uses the isatty() function on the stream fout to
   determine, if to emit the ANSI enclosures or not. That behaviour is
   controlled by the ANSI test flag. When (len != 0) ANSI is always
   disabled.

*/

#ifndef _MICROC_
int fd_fprintf(FILE *fp, char *fmt, ...);
int fd_sprintf(char *buf, char *fmt, ...);
#else
register int fd_fprintf(FILE *fp, char *fmt);
register int fd_sprintf(char *buf, char *fmt);
#endif
/* Wrapper for skprintf().

	These functions allow to call skprintf() with the same 
	calling interface than standard fprintf() and sprintf().
*/


void msgSetAnsiFlag(int flag);
/* Function to set the ANSI test flag. 

   Should be called before msgInit() to skip the check, if an ANSI
   driver is present. This test will set the flag to ANSI_TEST if a
   driver is present and to ANSI_DENY if none is found.

   In the functions using this flag, ANSI_TEST means, that ANSI will
   be used, if the file stream is connected to a console (CON:).

   May be called anytime the application wants to alter the ANSI test
   behaviour of skprintf(). To retrieve the current state of the fl‘g
   use getAnsiTest().

   flag should be one of ANSI_????, otherwise the behaviour of all
   functions using this flag is undefined.

   Initial setting of the flag: ANSI_TEST.

*/

int msgGetAnsiFlag(void);
/* Function retrieves the current state of the ANSI test flag
*/

int checkANSI(void);
/* Return whether or not an ANSI driver is loaded.
*/


void setNoiseLevel(unsigned noiseLevel, int flag);
/* Function to set the allow/disallow flag for each noise level.

   May be called anytime the application wants to alter the interactive
   test behaviour of the interactive() function. To retrieve the current
   state of the flag use getNoiseLevel().

   flag should be one of NOISE_???, otherwise the behaviour of all
   functions using this flag is undefined.

   Initial setting is NOISE_ALLOW.

	For ENoise_interactive only:

   Should be called after msgInit() to ensure, that the test is
   performed anytime an interactive message is emitted.

   Initial setting of the ENoise_interactive flag: NOISE_TEST, but is
   altered to either NOISE_DENY or NOISE_ALLOW by the msgInit()
   function.

*/

int getNoiseLevel(unsigned noiseLevel);
/* Function retrieves the current state of the allow/disallow flag
   of the specified noise level.
*/



/* Message emitting functions:

   hlpScreen:
   	Emit the message E_hlpScreen onto stdout and exit with errorlevel.
   error:
   	Emit the supplied message onto stderr and exit with errorlevel.
   	Preceed the message with the application name and E_error.
   fatal:
   	Equals to error, but preceed with the application name and
   	E_fatal.
   warning:
   	Emit the supplied message onto stderr and preceed the message
   	with the application name and E_warning.
   informative:
   	Emit the supplied message onto stderr and preceed the message
   	with the application name.
   interactive:
   	Emit the supplied message onto stdout. If redirection test is 
   	enabled, the message is not emitted, if stdin is redirected to
   	a non-CON: device (or, by switch, to a file).
   smessage (screen):
   	Emit the supplied message onto stdout.
   message (none):
   	Emit the supplied message onto the supplied file stream.
*/

#ifdef _MICROC_
register void error(MSGID msg);
register void warning(MSGID msg); 
register void fatal(MSGID msg);
register void informative(MSGID msg);
register void interactive(MSGID msg);
register void smessage(MSGID msg);
register void message(FILE *fp, MSGID msg);

#else /* no Micro-C */
void error(MSGID msg,...); 
void warning(MSGID msg,...); 
void fatal(MSGID msg,...);
void informative(MSGID msg,...);
void interactive(MSGID msg,...);
void smessage(MSGID msg,...);
void message(FILE *fp, MSGID msg,...);

#endif

void hlpScreen(void);
	//DCL_MSG(E_hlpScreen);

/* no format string error reporting
#define Nr_E_hlpFmtStr 20
    DCL_MSG(E_hlpFmtStr);
*/

#endif
