diff options
Diffstat (limited to 'src/translators/btparse/error.c')
-rw-r--r-- | src/translators/btparse/error.c | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/src/translators/btparse/error.c b/src/translators/btparse/error.c new file mode 100644 index 0000000..26f2fb2 --- /dev/null +++ b/src/translators/btparse/error.c @@ -0,0 +1,348 @@ +/* ------------------------------------------------------------------------ +@NAME : error.c +@DESCRIPTION: Anything relating to reporting or recording errors and + warnings. +@GLOBALS : errclass_names + err_actions + err_handlers + errclass_counts + error_buf +@CALLS : +@CREATED : 1996/08/28, Greg Ward +@MODIFIED : +@VERSION : $Id: error.c,v 2.5 1999/11/29 01:13:10 greg Rel $ +@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved. + + This file is part of the btparse library. This library is + free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. +-------------------------------------------------------------------------- */ + +/*#include "bt_config.h"*/ +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include "btparse.h" +#include "error.h" +/*#include "my_dmalloc.h"*/ + + +#define NUM_ERRCLASSES ((int) BTERR_INTERNAL + 1) + + +static const char *errclass_names[NUM_ERRCLASSES] = +{ + NULL, /* BTERR_NOTIFY */ + "warning", /* BTERR_CONTENT */ + "warning", /* BTERR_LEXWARN */ + "warning", /* BTERR_USAGEWARN */ + "error", /* BTERR_LEXERR */ + "syntax error", /* BTERR_SYNTAX */ + "fatal error", /* BTERR_USAGEERR */ + "internal error" /* BTERR_INTERNAL */ +}; + +static const bt_erraction err_actions[NUM_ERRCLASSES] = +{ + BTACT_NONE, /* BTERR_NOTIFY */ + BTACT_NONE, /* BTERR_CONTENT */ + BTACT_NONE, /* BTERR_LEXWARN */ + BTACT_NONE, /* BTERR_USAGEWARN */ + BTACT_NONE, /* BTERR_LEXERR */ + BTACT_NONE, /* BTERR_SYNTAX */ + BTACT_CRASH, /* BTERR_USAGEERR */ + BTACT_ABORT /* BTERR_INTERNAL */ +}; + +void print_error (bt_error *err); + +static bt_err_handler err_handlers[NUM_ERRCLASSES] = +{ + print_error, + print_error, + print_error, + print_error, + print_error, + print_error, + print_error, + print_error +}; + +static int errclass_counts[NUM_ERRCLASSES] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +static char error_buf[MAX_ERROR+1]; + + +/* ---------------------------------------------------------------------- + * Error-handling functions. + */ + +void print_error (bt_error *err) +{ + const char * name; + boolean something_printed; + + something_printed = FALSE; + + if (err->filename) + { + fprintf (stderr, err->filename); + something_printed = TRUE; + } + if (err->line > 0) /* going to print a line number? */ + { + if (something_printed) + fprintf (stderr, ", "); + fprintf (stderr, "line %d", err->line); + something_printed = TRUE; + } + if (err->item_desc && err->item > 0) /* going to print an item number? */ + { + if (something_printed) + fprintf (stderr, ", "); + fprintf (stderr, "%s %d", err->item_desc, err->item); + something_printed = TRUE; + } + + name = errclass_names[(int) err->errclass]; + if (name) + { + if (something_printed) + fprintf (stderr, ", "); + fprintf (stderr, name); + something_printed = TRUE; + } + + if (something_printed) + fprintf (stderr, ": "); + + fprintf (stderr, "%s\n", err->message); + +} /* print_error() */ + + + +/* ---------------------------------------------------------------------- + * Error-reporting functions: these are called anywhere in the library + * when we encounter an error. + */ + +void +report_error (bt_errclass errclass, + char * filename, + int line, + const char * item_desc, + int item, + const char * fmt, + va_list arglist) +{ + bt_error err; +#if !HAVE_VSNPRINTF + int msg_len; +#endif + + err.errclass = errclass; + err.filename = filename; + err.line = line; + err.item_desc = item_desc; + err.item = item; + + errclass_counts[(int) errclass]++; + + + /* + * Blech -- we're writing to a static buffer because there's no easy + * way to know how long the error message is going to be. (Short of + * reimplementing printf(), or maybe printf()'ing to a dummy file + * and using the return value -- ugh!) The GNU C library conveniently + * supplies vsnprintf(), which neatly solves this problem by truncating + * the output string if it gets too long. (I could check for this + * truncation if I wanted to, but I don't think it's necessary given the + * ample size of the message buffer.) For non-GNU systems, though, + * we're stuck with using vsprintf()'s return value. This can't be + * trusted on all systems -- thus there's a check for it in configure. + * Also, this won't necessarily trigger the internal_error() if we + * do overflow; it's conceivable that vsprintf() itself would crash. + * At least doing it this way we avoid the possibility of vsprintf() + * silently corrupting some memory, and crashing unpredictably at some + * later point. + */ + +#if HAVE_VSNPRINTF + vsnprintf (error_buf, MAX_ERROR, fmt, arglist); +#else + msg_len = vsprintf (error_buf, fmt, arglist); + if (msg_len > MAX_ERROR) + internal_error ("static error message buffer overflowed"); +#endif + + err.message = error_buf; + if (err_handlers[errclass]) + (*err_handlers[errclass]) (&err); + + switch (err_actions[errclass]) + { + case BTACT_NONE: return; + case BTACT_CRASH: exit (1); + case BTACT_ABORT: abort (); + default: internal_error ("invalid error action %d for class %d (%s)", + (int) err_actions[errclass], + (int) errclass, errclass_names[errclass]); + } + +} /* report_error() */ + + +GEN_ERRFUNC (general_error, + (bt_errclass errclass, + char * filename, + int line, + const char * item_desc, + int item, + char * fmt, + ...), + errclass, filename, line, item_desc, item, fmt) + +GEN_ERRFUNC (error, + (bt_errclass errclass, + char * filename, + int line, + char * fmt, + ...), + errclass, filename, line, NULL, -1, fmt) + +GEN_ERRFUNC (ast_error, + (bt_errclass errclass, + AST * ast, + char * fmt, + ...), + errclass, ast->filename, ast->line, NULL, -1, fmt) + +GEN_ERRFUNC (notify, + (const char * fmt, ...), + BTERR_NOTIFY, NULL, -1, NULL, -1, fmt) + +GEN_ERRFUNC (usage_warning, + (const char * fmt, ...), + BTERR_USAGEWARN, NULL, -1, NULL, -1, fmt) + +GEN_ERRFUNC (usage_error, + (const char * fmt, ...), + BTERR_USAGEERR, NULL, -1, NULL, -1, fmt) + +GEN_ERRFUNC (internal_error, + (const char * fmt, ...), + BTERR_INTERNAL, NULL, -1, NULL, -1, fmt) + + +/* ====================================================================== + * Functions to be used outside of the library + */ + +/* ------------------------------------------------------------------------ +@NAME : bt_reset_error_counts() +@INPUT : +@OUTPUT : +@RETURNS : +@DESCRIPTION: Resets all the error counters to zero. +@GLOBALS : +@CALLS : +@CREATED : 1997/01/08, GPW +@MODIFIED : +-------------------------------------------------------------------------- */ +void bt_reset_error_counts (void) +{ + int i; + + for (i = 0; i < NUM_ERRCLASSES; i++) + errclass_counts[i] = 0; +} + + +/* ------------------------------------------------------------------------ +@NAME : bt_get_error_count() +@INPUT : errclass +@OUTPUT : +@RETURNS : +@DESCRIPTION: Returns number of errors seen in the specified class. +@GLOBALS : errclass_counts +@CALLS : +@CREATED : +@MODIFIED : +-------------------------------------------------------------------------- */ +int bt_get_error_count (bt_errclass errclass) +{ + return errclass_counts[errclass]; +} + + +/* ------------------------------------------------------------------------ +@NAME : bt_get_error_counts() +@INPUT : counts - pointer to an array big enough to hold all the counts + if NULL, the array will be allocated for you (and you + must free() it when done with it) +@OUTPUT : +@RETURNS : counts - either the passed-in pointer, or the newly- + allocated array if you pass in NULL +@DESCRIPTION: Returns a newly-allocated array with the number of errors + in each error class, indexed by the members of the + eclass_t enum. +@GLOBALS : errclass_counts +@CALLS : +@CREATED : 1997/01/06, GPW +@MODIFIED : +-------------------------------------------------------------------------- */ +int *bt_get_error_counts (int *counts) +{ + int i; + + if (counts == NULL) + counts = (int *) malloc (sizeof (int) * NUM_ERRCLASSES); + for (i = 0; i < NUM_ERRCLASSES; i++) + counts[i] = errclass_counts[i]; + + return counts; +} + + +/* ------------------------------------------------------------------------ +@NAME : bt_error_status +@INPUT : saved_counts - an array of error counts as returned by + bt_get_error_counts, or NULL not to compare + to a previous checkpoint +@OUTPUT : +@RETURNS : +@DESCRIPTION: Computes a bitmap where a bit is set for each error class + that has more errors now than it used to have (or, if + saved_counts is NULL, the bit is set of there are have been + any errors in the corresponding error class). + + Eg. "x & (1<<E_SYNTAX)" (where x is returned by bt_error_status) + is true if there have been any syntax errors. +@GLOBALS : +@CALLS : +@CREATED : +@MODIFIED : +-------------------------------------------------------------------------- */ +ushort bt_error_status (int *saved_counts) +{ + int i; + ushort status; + + status = 0; + + if (saved_counts) + { + for (i = 0; i < NUM_ERRCLASSES; i++) + status |= ( (errclass_counts[i] > saved_counts[i]) << i); + } + else + { + for (i = 0; i < NUM_ERRCLASSES; i++) + status |= ( (errclass_counts[i] > 0) << i); + } + + return status; +} /* bt_error_status () */ |