diff options
author | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 1994-02-24 01:02:37 +0000 |
---|---|---|
committer | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 1994-02-24 01:02:37 +0000 |
commit | 471086d69c5e0021d6e82e30a8fe36c4b300488c (patch) | |
tree | c9a38e97d26c8dcc0a3aab71de38da5f8fdcc3bc /gcc/cp/errfn.c | |
parent | ef5b53740dedca45c23707087f7d6d6596400751 (diff) | |
download | gcc-471086d69c5e0021d6e82e30a8fe36c4b300488c.tar.gz |
Initial revision
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@6613 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/errfn.c')
-rw-r--r-- | gcc/cp/errfn.c | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/gcc/cp/errfn.c b/gcc/cp/errfn.c new file mode 100644 index 00000000000..21feb772b47 --- /dev/null +++ b/gcc/cp/errfn.c @@ -0,0 +1,217 @@ +/* Provide a call-back mechanism for handling error output. + Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Jason Merrill (jason@cygnus.com) + + This file is part of GNU CC. + +GNU CC 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, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "config.h" +#include "tree.h" +#include <ctype.h> + +/* cp_printer is the type of a function which converts an argument into + a string for digestion by printf. The cp_printer function should deal + with all memory management; the functions in this file will not free + the char*s returned. See cp-error.c for an example use of this code. */ + +typedef char* cp_printer PROTO((HOST_WIDE_INT, int)); +extern cp_printer * cp_printers[256]; + +typedef void errorfn (); /* deliberately vague */ + +extern char* cp_file_of PROTO((tree)); +extern int cp_line_of PROTO((tree)); + +#define STRDUP(f) (ap = (char *) alloca (strlen (f) +1), strcpy (ap, (f)), ap) + +#define NARGS 3 +#define arglist a1, a2, a3 +#define arglist_dcl HOST_WIDE_INT a1, a2, a3; +#define ARGSINIT args[0] = a1; args[1] = a2; args[2] = a3; +#define ARGSLIST args[0], args[1], args[2] + +static void +cp_thing (errfn, atarg1, format, arglist) + errorfn *errfn; + int atarg1; + char *format; + arglist_dcl +{ + char *fmt; + char *f; + char *ap; + int arg; + HOST_WIDE_INT atarg = atarg1 ? a1 : 0; + HOST_WIDE_INT args[NARGS]; + ARGSINIT + + fmt = STRDUP(format); + + for (f = fmt, arg = 0; *f; ++f) + { + cp_printer * function; + int alternate; + int maybe_here; + + /* ignore text */ + if (*f != '%') continue; + + ++f; + + alternate = 0; + maybe_here = 0; + + /* ignore most flags */ + while (*f == ' ' || *f == '-' || *f == '+' || *f == '#') + { + if (*f == '+') + maybe_here = 1; + else if (*f == '#') + alternate = 1; + ++f; + } + + /* ignore field width */ + if (*f == '*') + { + ++f; + ++arg; + } + else + while (isdigit (*f)) + ++f; + + /* ignore precision */ + if (*f == '.') + { + ++f; + if (*f == '*') + { + ++f; + ++arg; + } + else + while (isdigit (*f)) + ++f; + } + + /* ignore "long" */ + if (*f == 'l') + ++f; + + function = cp_printers[*f]; + + if (function) + { + char *p; + + if (arg >= NARGS) abort (); + + if (maybe_here && atarg) + atarg = args[arg]; + + /* Must use a temporary to avoid calling *function twice */ + p = (*function) (args[arg], alternate); + args[arg] = (HOST_WIDE_INT) STRDUP(p); + *f = 's'; + } + + ++arg; /* Assume valid format string */ + + } + + if (atarg) + { + char *file = cp_file_of ((tree) atarg); + int line = cp_line_of ((tree) atarg); + (*errfn) (file, line, fmt, ARGSLIST); + } + else + (*errfn) (fmt, ARGSLIST); + +} + +void +cp_error (format, arglist) + char *format; + arglist_dcl +{ + extern errorfn error; + cp_thing (error, 0, format, arglist); +} + +void +cp_warning (format, arglist) + char *format; + arglist_dcl +{ + extern errorfn warning; + cp_thing (warning, 0, format, arglist); +} + +void +cp_pedwarn (format, arglist) + char *format; + arglist_dcl +{ + extern errorfn pedwarn; + cp_thing (pedwarn, 0, format, arglist); +} + +void +cp_compiler_error (format, arglist) + char *format; + arglist_dcl +{ + extern errorfn compiler_error; + cp_thing (compiler_error, 0, format, arglist); +} + +void +cp_sprintf (format, arglist) + char *format; + arglist_dcl +{ + extern errorfn sprintf; + cp_thing (sprintf, 0, format, arglist); +} + +void +cp_error_at (format, arglist) + char *format; + arglist_dcl +{ + extern errorfn error_with_file_and_line; + cp_thing (error_with_file_and_line, 1, format, arglist); +} + +void +cp_warning_at (format, arglist) + char *format; + arglist_dcl +{ + extern errorfn warning_with_file_and_line; + cp_thing (warning_with_file_and_line, 1, format, arglist); +} + +void +cp_pedwarn_at (format, arglist) + char *format; + arglist_dcl +{ + extern errorfn pedwarn_with_file_and_line; + cp_thing (pedwarn_with_file_and_line, 1, format, arglist); +} |