/*++
/* NAME
/* error 3
/* SUMMARY
/* diagnostics handlers
/* SYNOPSIS
/* #include <error.h>
/*
/* void error(format, ...)
/* char *format;
/*
/* void remark(format, ...)
/* char *format;
/*
/* void panic(format, ...)
/* char *format;
/*
/* char *progname;
/* int verbose;
/* DESCRIPTION
/* This module reports diagnostics. Each routine produces a one-line
/* record with the program name and a caller-provided informative
/* message. In the format string, %m is replaced by the text that
/* corresponds to the present \fBerrno\fR value.
/*
/* error() writes a message to the standard error stream and
/* terminates the process with a non-zero exit status.
/*
/* remark() writes a message to the standard error stream.
/*
/* panic() writes a message to the standard error stream and
/* forces a core dump.
/*
/* progname is a global variable that the application should
/* assign the program name. The initial value is a pointer to
/* the string \fB"unknown"\fR.
/*
/* verbose is a global variable (initially, zero), that exists
/* solely for the convenience of the application. Typical usage
/* is like:
/*
/* .ti +5
/* if (verbose) remark(...);
/* SEE ALSO
/* errno(2) error numbers
/* HISTORY
/* error() and remark() appear in "Software Tools" by B.W. Kernighan
/* and P.J. Plaugher.
/* LICENSE
/* This software is distributed under the IBM Public License.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#ifdef __STDC__
#include <stdarg.h>
#define VARARGS(func,type,arg) func(type arg, ...)
#define VASTART(ap,type,name) va_start(ap,name)
#define VAEND(ap) va_end(ap)
#else
#include <varargs.h>
#define VARARGS(func,type,arg) func(va_alist) va_dcl
#define VASTART(ap,type,name) {type name; va_start(ap); name = va_arg(ap, type)
#define VAEND(ap) va_end(ap);}
#endif
/* Utility library. */
#include "error.h"
char *progname = "unknown";
int verbose = 0;
/* percentm - replace %m by error message associated with value in err */
char *percentm(buf, str, err)
char *buf;
char *str;
int err;
{
char *ip = str;
char *op = buf;
while (*ip) {
switch (*ip) {
case '%':
switch (ip[1]) {
case '\0': /* don't fall off end */
*op++ = *ip++;
break;
case 'm': /* replace %m */
strcpy(op, strerror(err));
op += strlen(op);
ip += 2;
break;
default: /* leave %<any> alone */
*op++ = *ip++, *op++ = *ip++;
break;
}
default:
*op++ = *ip++;
}
}
*op = 0;
return (buf);
}
/* error - print warning on stderr and terminate */
void VARARGS(error, char *, fmt)
{
va_list ap;
int err = errno;
char buf[BUFSIZ];
VASTART(ap, char *, fmt);
fprintf(stderr, "%s: ", progname);
vfprintf(stderr, percentm(buf, fmt, err), ap);
fprintf(stderr, "\n");
VAEND(ap);
exit(1);
}
/* remark - print warning on stderr and continue */
void VARARGS(remark, char *, fmt)
{
va_list ap;
int err = errno;
char buf[BUFSIZ];
VASTART(ap, char *, fmt);
fprintf(stderr, "%s: ", progname);
vfprintf(stderr, percentm(buf, fmt, err), ap);
fprintf(stderr, "\n");
VAEND(ap);
}
/* panic - print warning on stderr and dump core */
void VARARGS(panic, char *, fmt)
{
va_list ap;
int err = errno;
char buf[BUFSIZ];
VASTART(ap, char *, fmt);
fprintf(stderr, "%s: ", progname);
vfprintf(stderr, percentm(buf, fmt, err), ap);
fprintf(stderr, "\n");
VAEND(ap);
abort();
}
syntax highlighted by Code2HTML, v. 0.9.1