#include	<stdarg.h>
#include	"global.h"

// errorCount maintains the number of errors reported.

int errorCount = 0;

// errorsFound() merely returns the value of errorCount.

int errorsFound()
{
	return errorCount;
}

// The function error() receives a variable number of parameters
// depending on the specification of the format string.  It thus relies
// on the va_start() and va_arg() functions as defined in <stdarg.h>

void error(errorKind mode, char* format, ...)
{
	static char *prefix[] = {
		"warning: ",
		"",
		"abort: ",
		"internal error: "
	};
	va_list ap;

	va_start(ap, format);
	fprintf(stderr, "%s", prefix[mode]);
	if (mode == ERROR) errorCount++;
	while (*format)
		if (*format == '%') {
			switch (*++format) {
			case 's': {
				char *p = va_arg(ap, char *);
				fprintf(stderr, "%s", p);
				break;
				}
			case 'd': {
				int p = va_arg(ap, int);
				fprintf(stderr, "%d", (int) p);
				break;
				}
			case '^': {
				int count = va_arg(ap, int);
				for (int i = 1; i<count; i++) putc(' ', stderr);
				fprintf(stderr, "          ^");
				break;
				}
			default: fprintf(stderr, "%%c", *format);
			}
			format++;
		} else
			putc(*format++, stderr);
	if (mode == ABORT || mode == INTERNAL)
		exit(-1);
}

// allocate() returns the address of the memory block returned by
// malloc().  Insufficient memory is indicated by a 0 malloc()
// result.  This condition is fatal since recovery is typically slim.

char *allocate(int n)
{
	char *p = (char *) malloc(n);

	if (p) return p;
	error(ABORT, "cannot allocate sufficient heap space\n");
	return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1