[net.sources] Source for UNIX errmt program

swatt (08/10/82)

Several people have requested this; it's quite short so I'm posting it
here (it's also amazingly cheap; "_doprnt" does all the work!).

The function names "error" and "remark" are, of course, gleaned from
Software Tools.  They work in a similar manner, appending a newline at
the end.  Thus:

	error ("Too many files (%d); max is %d", nfiles, MAXFILES);

is all you need.  The format string accepted by error and remark (and
fperror, and fpremark) is the same as for printf.  Variable number of
arguments works the same way as well.

fperror, is just like error, except that it appends the standard system
error message (like perror).  fpremark is just like remark with the
same addition.

I don't believe it depends on 4.1bsd stdio internals, but I could be
wrong.  I seem to recall moving this stuff to an ONYX but if so it was
a long time ago and I may be fooling myself.  It just occurred to me
people on system III **might** have a different formatted print
function; I've made this stuff work under IS/1 (derivative of PWB), and
there were minor differences.  If anyone has trouble, I can dig up the
differences and post them as well.

	- Alan S. Watt
======================================================================
sed 's/^	//' >error.c <<!EOF
	/*********************************************************************
	function:	error
	description:	Error message routines
	programmer:	Alan S. Watt
	
	history:
		11/04/81	original version
		07/17/82	fixes for lint
		08/10/82	modest cleanup before posting.
	*********************************************************************/
	
	#ifndef lint
	 static char Sccsid[] = "@(#)error.c	1.1";
	#endif !lint
	
	#include <stdio.h>
	#define NOTOK	(-1)
	
	/* VARARGS1 */
	error (mesg, args)
	char *mesg;
	{
		_doprnt (mesg, &args, stderr);
		putc ('\n', stderr);
		exit (NOTOK);
	}
	
	extern	errno;
	extern	sys_nerr;
	extern	char *sys_errlist[];
	#ifdef lint
	 int	errno;
	 int	sys_nerr;
	 char *sys_errlist[1];
	#endif lint
	static	char ehuh[]	= "Unknown System Error";
	
	/* VARARGS1 */
	fperror (mesg, args)
	char *mesg;
	{
		char *err = ((unsigned)errno >= sys_nerr ? ehuh : sys_errlist[errno]);
	
		_doprnt (mesg, &args, stderr);
		fprintf (stderr, ": %s\n", err);
		exit (NOTOK);
	}
	
	/*VARARGS1*/
	remark (mesg, args)
	char *mesg;
	{
		_doprnt (mesg, &args, stderr);
		putc ('\n',stderr);
	}
	
	/*VARARGS1*/
	fpremark (mesg, args)
	char *mesg;
	{
		char *err = ((unsigned)errno >= sys_nerr ? ehuh : sys_errlist[errno]);
	
		_doprnt (mesg, &args, stderr);
		fprintf (stderr, ":%s\n", err);
	}
!EOF
sed 's/^	//' >error.3a <<!EOF
	.\"	Manual page for error(3a)
	.\"	author:	Alan S. Watt
	.\"
	.\"	Sccsid=@(#)error.3a	1.1
	.\"
	.\"	To format this page:
	.\"	nroff -man
	.\"
	.\"	history:
	.\"	08/10/82   original version
	.TH "error" 3a "Advanced Technology"
	.ED "8/10/82"
	.SH NAME
	error \- formatted print diagnostic functions
	.SH SYNOPSIS
	.nf
	.B error (format, arg, ...)
	.sp
	.B fperror (format, arg, ...)
	.sp
	.B remark (format, arg, ...)
	.sp
	.B fpremark (format, arg, ...)
	.sp
	.B char *format
	.B int arg
	.fi
	.SH DESCRIPTION
	All these functions directed a formatted message to the 
	.I standard error
	channel (normally the user's terminal).
	Both
	.I error
	and
	.I fperror
	force an exit with a status of -1 as well.
	The
	.I format
	argument to all functions is exactly like the format
	argument to
	.IR printf .
	The number of
	arguments is variable, as with
	.IR printf .
	.PP
	.I fperror
	is like
	.IR error ,
	except that it also appends the standard
	system error message (like
	.IR perror (3)).
	.I fpremark
	is like
	.IR remark ,
	with the same addition.
	If for any reason the external system error number
	.RI ( errno )
	is not valid, the message "Unknown System Error" is substituted.
	.PP
	.I format
	need not contain a final newline character;
	one is appended automatically.
	The operating spirit for these functions is from
	.I Software
	.IR Tools .
	.SH EXAMPLES
	.IP ""
	.nf
	error ("Too many files (%d); max is %d", nfiles, MAXFILES);
	
	if ((fd = fopen (file, "r")) == NULL)
		fperror ("Cannot open %s for reading", file);
	
	if (!exists (file))
		remark ("Warning: %s does not exist, creating it", file);
	.fi
	.PP
	The first example prints an error message and exits.
	The second prints a diagnostic including the standard system
	error message and exits.
	The final example prints a diagnostic (advisory), but does not
	exit.
	.SH DIAGNOSTICS
	.I error
	and
	.I fperror
	both exit with the status -1.
	.SH BUGS
	.SH SEE ALSO
	exit(2),
	perror(3)
	.SH AUTHOR
	Alan S. Watt
	.br
	ittvax!swatt
!EOF