OSDN Git Service

75th Cygnus<->FSF merge
[pf3gnuchains/gcc-fork.git] / gcc / cp / errfn.c
1 /* Provide a call-back mechanism for handling error output.
2    Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
3    Contributed by Jason Merrill (jason@cygnus.com)
4
5    This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21    
22 #include "config.h"
23 #include "tree.h"
24 #include <ctype.h>
25
26 /* cp_printer is the type of a function which converts an argument into
27    a string for digestion by printf.  The cp_printer function should deal
28    with all memory management; the functions in this file will not free
29    the char*s returned.  See error.c for an example use of this code.  */
30
31 typedef char* cp_printer PROTO((HOST_WIDE_INT, int));
32 extern cp_printer * cp_printers[256];
33
34 /* Whether or not we should try to be quiet for errors and warnings; this is
35    used to avoid being too talkative about problems with tentative choices
36    when we're computing the conversion costs for a method call.  */
37 int cp_silent = 0;
38
39 typedef void errorfn ();        /* deliberately vague */
40
41 extern char* cp_file_of PROTO((tree));
42 extern int   cp_line_of PROTO((tree));
43
44 #define STRDUP(f) (ap = (char *) alloca (strlen (f) +1), strcpy (ap, (f)), ap)
45
46 #define NARGS 4
47 #define arglist a1, a2, a3, a4
48 #define arglist_dcl HOST_WIDE_INT a1, a2, a3, a4;
49 #define ARGSINIT args[0] = a1; args[1] = a2; args[2] = a3; args[3] = a4;
50 #define ARGSLIST args[0], args[1], args[2], args[3]
51
52 static void
53 cp_thing (errfn, atarg1, format, arglist)
54      errorfn *errfn;
55      int atarg1;
56      char *format;
57      arglist_dcl
58 {
59   char *fmt;
60   char *f;
61   char *ap;
62   int arg;
63   HOST_WIDE_INT atarg = atarg1 ? a1 : 0;
64   HOST_WIDE_INT args[NARGS];
65   ARGSINIT
66
67   fmt = STRDUP(format);
68   
69   for (f = fmt, arg = 0; *f; ++f)
70     {
71       cp_printer * function;
72       int alternate;
73       int maybe_here;
74       
75       /* ignore text */
76       if (*f != '%') continue;
77
78       ++f;
79
80       alternate = 0;
81       maybe_here = 0;
82
83       /* ignore most flags */
84       while (*f == ' ' || *f == '-' || *f == '+' || *f == '#')
85         {
86           if (*f == '+')
87             maybe_here = 1;
88           else if (*f == '#')
89             alternate = 1;
90           ++f;
91         }
92
93       /* ignore field width */
94       if (*f == '*')
95         {
96           ++f;
97           ++arg;
98         }
99       else
100         while (isdigit (*f))
101           ++f;
102
103       /* ignore precision */
104       if (*f == '.')
105         {
106           ++f;
107           if (*f == '*')
108             {
109               ++f;
110               ++arg;
111             }
112           else
113             while (isdigit (*f))
114               ++f;
115         }
116
117       /* ignore "long" */
118       if (*f == 'l')
119         ++f;
120
121       function = cp_printers[(int)*f];
122
123       if (function)
124         {
125           char *p;
126
127           if (arg >= NARGS) abort ();
128           
129           if (maybe_here && atarg1)
130             atarg = args[arg];
131
132           /* Must use a temporary to avoid calling *function twice */
133           p = (*function) (args[arg], alternate);
134           args[arg] = (HOST_WIDE_INT) STRDUP(p);
135           *f = 's';
136         }
137
138       ++arg;                    /* Assume valid format string */
139
140     }
141
142   if (atarg)
143     {
144       char *file = cp_file_of ((tree) atarg);
145       int   line = cp_line_of ((tree) atarg);
146       (*errfn) (file, line, fmt, ARGSLIST);
147     }
148   else
149     (*errfn) (fmt, ARGSLIST);
150
151 }
152
153 void
154 cp_error (format, arglist)
155      char *format;
156      arglist_dcl
157 {
158   extern errorfn error;
159   if (! cp_silent)
160     cp_thing (error, 0, format, arglist);
161 }
162
163 void
164 cp_warning (format, arglist)
165      char *format;
166      arglist_dcl
167 {
168   extern errorfn warning;
169   if (! cp_silent)
170     cp_thing (warning, 0, format, arglist);
171 }
172
173 void
174 cp_pedwarn (format, arglist)
175      char *format;
176      arglist_dcl
177 {
178   extern errorfn pedwarn;
179   if (! cp_silent)
180     cp_thing (pedwarn, 0, format, arglist);
181 }
182
183 void
184 cp_compiler_error (format, arglist)
185      char *format;
186      arglist_dcl
187 {
188   extern errorfn compiler_error;
189   if (! cp_silent)
190     cp_thing (compiler_error, 0, format, arglist);
191 }
192
193 void
194 cp_sprintf (format, arglist)
195      char *format;
196      arglist_dcl
197 {
198   extern errorfn sprintf;
199   cp_thing (sprintf, 0, format, arglist);
200 }
201
202 void
203 cp_error_at (format, arglist)
204      char *format;
205      arglist_dcl
206 {
207   extern errorfn error_with_file_and_line;
208   if (! cp_silent)
209     cp_thing (error_with_file_and_line, 1, format, arglist);
210 }
211
212 void
213 cp_warning_at (format, arglist)
214      char *format;
215      arglist_dcl
216 {
217   extern errorfn warning_with_file_and_line;
218   if (! cp_silent)
219     cp_thing (warning_with_file_and_line, 1, format, arglist);
220 }
221
222 void
223 cp_pedwarn_at (format, arglist)
224      char *format;
225      arglist_dcl
226 {
227   extern errorfn pedwarn_with_file_and_line;
228   if (! cp_silent)
229     cp_thing (pedwarn_with_file_and_line, 1, format, arglist);
230 }