#include <stdio.h>
#include <stdarg.h>
#include <errno.h>

int Num_Errors;
int Num_Warnings;

static void
prefix(file, line, msg)
	char *file, *msg;
	int line;
{
	fflush(stdout);

	if (file) {
		fprintf(stderr, "%s, ", file);
	}

	if (line) {
		fprintf(stderr, "line %d, ", line);
	}

	if (msg) {
		fprintf(stderr, "%s: ", msg);
	}
}

static void
endmsg()
{
	fputc('\n', stderr);
	fflush(stderr);
}

void
fatal(char *f, int l, char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);

	prefix(f,l,"Internal error");
	vfprintf(stderr, fmt, ap);
	endmsg();

	va_end(ap);

	exit(1);
}

void
error(char *f, int l, char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);

	Num_Errors++;
	prefix(f,l,"Error");
	vfprintf(stderr, fmt, ap);
	endmsg();

	va_end(ap);
}

void
warning(char *f, int l, char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);

	Num_Warnings++;
	prefix(f,l,"Warning");
	vfprintf(stderr, fmt, ap);
	endmsg();

	va_end(ap);
}

void
inform(char *f, int l, char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);

	prefix(f,l,"Info");
	vfprintf(stderr, fmt, ap);
	endmsg();

	va_end(ap);
}

void
assert_failed(f, l, msg)
	char *f, *msg;
	int l;
{
	prefix(f,l,"Assertion Failed");
	fputs(msg, stderr);
	endmsg();
	exit(1);
}

static void
unix_error()
{
	if (errno != 0) {
		if (errno > 0 && errno < sys_nerr) {
			fputs(sys_errlist[errno], stderr);
		}
		else {
			fprintf(stderr, "errno = %d", errno);
		}
	}
}

void
syserr(file, line)
	char *file;
	int line;
{
	Num_Errors++;
	prefix(file,line,"Error");
	unix_error();
	endmsg();
}


syntax highlighted by Code2HTML, v. 0.9.1