1
0
vt100-games/2048/uz80as/err.c

197 lines
3.5 KiB
C

/* ===========================================================================
* uz80as, an assembler for the Zilog Z80 and several other microprocessors.
*
* Error reporting.
* ===========================================================================
*/
#include "config.h"
#include "err.h"
#include "incl.h"
#ifndef ASSERT_H
#include <assert.h>
#endif
#ifndef CTYPE_H
#include <ctype.h>
#endif
#ifndef STDARG_H
#include <stdarg.h>
#endif
#ifndef STDIO_H
#include <stdio.h>
#endif
#ifndef STDLIB_H
#include <stdlib.h>
#endif
#ifndef STRING_H
#include <string.h>
#endif
/* Max number of errors before halt. */
#define MAXERR 64
int s_nerrors;
static void eprfl(void)
{
fprintf(stderr, "%s:%d: ", curfile()->name, curfile()->linenum);
}
static void eprwarn(void)
{
fputs(_("warning:"), stderr);
fputc(' ', stderr);
}
/* Print the characters in [p, q[ to stderr. */
void echars(const char *p, const char *q)
{
while (*p != '\0' && p != q) {
fputc(*p, stderr);
p++;
}
}
/*
* Print a space, an opening parenthesis, the characters in [p, q[,
* and a closing parenthesis to stderr.
*/
void epchars(const char *p, const char *q)
{
fputs(" (", stderr);
echars(p, q);
fputs(")", stderr);
}
/*
* Increments the number of errors, and exit with failure if
* maximum number of errors allowed is reached.
*/
void newerr(void)
{
s_nerrors++;
if (s_nerrors >= MAXERR) {
eprogname();
fprintf(stderr, _("exiting: too many errors"));
enl();
exit(EXIT_FAILURE);
}
}
static void evprint(int warn, const char *ecode, va_list args)
{
if (nfiles() > 0)
eprfl();
else
eprogname();
if (warn)
eprwarn();
assert(ecode != NULL);
vfprintf(stderr, ecode, args);
}
/* Prints only the printable characters, the rst as space. */
static void eprint_printable(const char *p)
{
for (; *p != '\0'; p++) {
if (isprint(*p))
putc(*p, stderr);
else
putc(' ', stderr);
}
}
/* Prints the line and a marker pointing to the charcater q inside line. */
void eprcol(const char *line, const char *q)
{
putc(' ', stderr);
eprint_printable(line);
fputs("\n ", stderr);
while (line != q) {
putc(' ', stderr);
line++;
}
fputs("^\n", stderr);
}
/*
* Like fprintf but prints to stderr.
* If we are parsing any file (incl.c), print first the file and the line.
* If not, print first the program name.
*/
void eprint(const char *ecode, ...)
{
va_list args;
va_start(args, ecode);
evprint(0, ecode, args);
va_end(args);
}
/* Same as eprint, but print "warning: " before ecode str. */
void wprint(const char *ecode, ...)
{
va_list args;
va_start(args, ecode);
evprint(1, ecode, args);
va_end(args);
}
/* Print \n on stderr. */
void enl(void)
{
fputc('\n', stderr);
}
/* Print the program name on stderr. */
void eprogname(void)
{
fprintf(stderr, PACKAGE": ");
}
/* Call malloc, but if no memory, print that error and exit with failure. */
void *emalloc(size_t n)
{
void *p;
if ((p = malloc(n)) == NULL) {
eprint(_("malloc fail\n"));
exit(EXIT_FAILURE);
}
// printf("emalloc: %d = %x\n", n, p);
return p;
}
/* Call realloc, but if no memory, print that error and exit with failure. */
void *erealloc(void *p, size_t n)
{
// void *q = p;
if ((p = realloc(p, n)) == NULL) {
eprint(_("realloc fail\n"));
exit(EXIT_FAILURE);
}
// printf("erealloc: %x %d = %x\n", q, n, p);
return p;
}
/* Call fopen, but if any error, print it and exit with failure. */
FILE *efopen(const char *fname, const char *ops)
{
FILE *fp;
if ((fp = fopen(fname, ops)) == NULL) {
eprint(_("cannot open file %s\n"), fname);
exit(EXIT_FAILURE);
}
return fp;
}