friendly messages

Jim Prescott jgp at moscom.UUCP
Wed Mar 29 16:23:02 AEST 1989


In article <3314 at ficc.uu.net> peter at ficc.uu.net (Peter da Silva) writes:
>Perhaps we (the usenet community) should spec a better interface:

A nice quick 90% solution is a printf-like function that writes to stderr,
prepends the program name to the message, and can append the system error
message.  Something like:
	if (open(fname, O_RDRW, 0) == -1)
		errmsg("Cannot open \"%s\" for read/write -- ", fname);
would output:
	prog: Cannot open "somefile" for read/write -- Read-only file system

This makes it fairly painless for the programmer to come up with an
informative message without worrying about the little details.  Trying
to use perror to get a nice message is too much work, which is probably
why it isn't used as often as it should be.

The problems in implementing this are:
	- finding the program name; most likely needs to be stashed away
		while in main().  (It would have been nice if the ANSI-C
		folks had invented some globals to hold copies of main's
		arguments.  (I know it isn't their job to invent :-).)
	- deciding where to put the system error.  The code below tacks it
		on the end of the message iff it doesn't end in a newline.
		Not a great solution but certainly much simpler than doing
		a new % escape.

An enhancement would be introduce error levels (we use FATAL, ERROR, INFO
and DEBUG) and provide some way to specify which you want to see (we default
to FATAL & ERROR).

I've even enclosed a function to implement it below (about 99% of which is
from an article on varargs by Chris Torek).  I'm not sure how portable
vsprintf is, its on our sun but wasn't in V7 so it probably isn't universal.
If anyone can tell me where to get a pd vsprintf I'd be grateful.

While we're on the subject, Guy mentioned TECO error messages but not how
nifty they actually are.  You can tell it to print just the 3 letter code
(eg. ?FNF), to print the 1 line error (eg. ?FNF File not found.) or to print
the 1 line message followed by a couple of likely paragraphs out of the manual
(this is called "war and peace" mode).  Its flexible even if not overly
useful (I can't imagine using anything other than 1 line messages.  Maybe
the 3 letter only would be good on 110 baud ttys).

========= varargs version
#include <varargs.h>

int
errmsg(va_alist)
	va_dcl		/* N.B.: no semicolon */
{
	int	ret;
	char	*fmt;
	va_list	ap;
	char	buf[1024];		/* shouldn't be fixed size */

	va_start(ap);
	fmt = va_arg(ap, char *);
	ret = vsprintf(buf, fmt, ap);
	va_end(ap);

	fprintf(stderr, "%s: %s", Progname, buf);
	if (*(buf + strlen(buf) - 1) != '\n')
		perror("");
	return ret;
}
#endif

========= stdarg version
#include <stdarg.h>

int
errmsg(char *fmt, ...) 	/* the `...'s are part of the syntax */
{
	int	ret;
	va_list	ap;
	char	buf[1024];		/* shouldn't be fixed size */

	va_start(ap, fmt);
	ret = vsprintf(buf, fmt, ap);
	va_end(ap);

	fprintf(stderr, "%s: %s", Progname, buf);
	if (*(buf + strlen(buf) - 1) != '\n')
		perror("");
	return ret;
}
-- 
Jim Prescott	moscom!jgp at cs.rochester.edu
		{rutgers,ames,harvard}!rochester!moscom!jgp



More information about the Comp.unix.wizards mailing list