00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define FFEBAD_MAX_ 6
00036
00037
00038
00039 #include "proj.h"
00040 #include "bad.h"
00041 #include "flags.h"
00042 #include "com.h"
00043 #include "toplev.h"
00044 #include "where.h"
00045 #include "intl.h"
00046
00047
00048
00049 bool ffebad_is_inhibited_ = FALSE;
00050
00051
00052
00053 #define FFEBAD_LONG_MSGS_ 1
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 struct _ffebad_message_
00064 {
00065 const ffebadSeverity severity;
00066 const char *const message;
00067 };
00068
00069
00070
00071 static const struct _ffebad_message_ ffebad_messages_[]
00072 =
00073 {
00074 #define FFEBAD_MSG(kwd,sev,msgid) { sev, msgid },
00075 #if FFEBAD_LONG_MSGS_ == 0
00076 #define LONG(m)
00077 #define SHORT(m) m
00078 #else
00079 #define LONG(m) m
00080 #define SHORT(m)
00081 #endif
00082 #include "bad.def"
00083 #undef FFEBAD_MSG
00084 #undef LONG
00085 #undef SHORT
00086 };
00087
00088 static struct
00089 {
00090 ffewhereLine line;
00091 ffewhereColumn col;
00092 ffebadIndex tag;
00093 }
00094
00095 ffebad_here_[FFEBAD_MAX_];
00096 static const char *ffebad_string_[FFEBAD_MAX_];
00097 static ffebadIndex ffebad_order_[FFEBAD_MAX_];
00098 static ffebad ffebad_errnum_;
00099 static ffebadSeverity ffebad_severity_;
00100 static const char *ffebad_message_;
00101 static unsigned char ffebad_index_;
00102 static ffebadIndex ffebad_places_;
00103 static bool ffebad_is_temp_inhibited_;
00104
00105
00106
00107
00108
00109 static int ffebad_bufputs_ (char buf[], int bufi, const char *s);
00110
00111
00112
00113 #define ffebad_bufflush_(buf, bufi) \
00114 (((buf)[bufi] = '\0'), fputs ((buf), stderr), 0)
00115 #define ffebad_bufputc_(buf, bufi, c) \
00116 (((bufi) == ARRAY_SIZE (buf)) \
00117 ? (ffebad_bufflush_ ((buf), (bufi)), ((buf)[0] = (c)), 1) \
00118 : (((buf)[bufi] = (c)), (bufi) + 1))
00119
00120
00121 static int
00122 ffebad_bufputs_ (char buf[], int bufi, const char *s)
00123 {
00124 for (; *s != '\0'; ++s)
00125 bufi = ffebad_bufputc_ (buf, bufi, *s);
00126 return bufi;
00127 }
00128
00129
00130
00131
00132
00133 void
00134 ffebad_init_0 ()
00135 {
00136 assert (FFEBAD == ARRAY_SIZE (ffebad_messages_));
00137 }
00138
00139 ffebadSeverity
00140 ffebad_severity (ffebad errnum)
00141 {
00142 return ffebad_messages_[errnum].severity;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 bool
00167 ffebad_start_ (bool lex_override, ffebad errnum, ffebadSeverity sev,
00168 const char *msgid)
00169 {
00170 unsigned char i;
00171
00172 if (ffebad_is_inhibited_ && !lex_override)
00173 {
00174 ffebad_is_temp_inhibited_ = TRUE;
00175 return FALSE;
00176 }
00177
00178 if (errnum != FFEBAD)
00179 {
00180 ffebad_severity_ = ffebad_messages_[errnum].severity;
00181 ffebad_message_ = gettext (ffebad_messages_[errnum].message);
00182 }
00183 else
00184 {
00185 ffebad_severity_ = sev;
00186 ffebad_message_ = gettext (msgid);
00187 }
00188
00189 switch (ffebad_severity_)
00190 {
00191 case FFEBAD_severityINFORMATIONAL:
00192 case FFEBAD_severityTRIVIAL:
00193 if (inhibit_warnings)
00194 {
00195 ffebad_is_temp_inhibited_ = TRUE;
00196 return FALSE;
00197 }
00198
00199 case FFEBAD_severityWARNING:
00200 case FFEBAD_severityPECULIAR:
00201 case FFEBAD_severityPEDANTIC:
00202 if ((ffebad_severity_ != FFEBAD_severityPEDANTIC)
00203 || !flag_pedantic_errors)
00204 {
00205 if (count_error (1) == 0)
00206 {
00207 ffebad_is_temp_inhibited_ = TRUE;
00208 return FALSE;
00209 }
00210 break;
00211 }
00212
00213 case FFEBAD_severityFATAL:
00214 case FFEBAD_severityWEIRD:
00215 case FFEBAD_severitySEVERE:
00216 case FFEBAD_severityDISASTER:
00217 count_error (0);
00218 break;
00219
00220 default:
00221 break;
00222 }
00223
00224 ffebad_is_temp_inhibited_ = FALSE;
00225 ffebad_errnum_ = errnum;
00226 ffebad_index_ = 0;
00227 ffebad_places_ = 0;
00228 for (i = 0; i < FFEBAD_MAX_; ++i)
00229 {
00230 ffebad_string_[i] = NULL;
00231 ffebad_here_[i].line = ffewhere_line_unknown ();
00232 ffebad_here_[i].col = ffewhere_column_unknown ();
00233 }
00234
00235 return TRUE;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 void
00247 ffebad_here (ffebadIndex index, ffewhereLine line, ffewhereColumn col)
00248 {
00249 ffewhereLineNumber line_num;
00250 ffewhereLineNumber ln;
00251 ffewhereColumnNumber col_num;
00252 ffewhereColumnNumber cn;
00253 ffebadIndex i;
00254 ffebadIndex j;
00255
00256 if (ffebad_is_temp_inhibited_)
00257 return;
00258
00259 assert (index < FFEBAD_MAX_);
00260 ffebad_here_[index].line = ffewhere_line_use (line);
00261 ffebad_here_[index].col = ffewhere_column_use (col);
00262 if (ffewhere_line_is_unknown (line)
00263 || ffewhere_column_is_unknown (col))
00264 {
00265 ffebad_here_[index].tag = FFEBAD_MAX_;
00266 return;
00267 }
00268 ffebad_here_[index].tag = 0;
00269
00270
00271
00272
00273 line_num = ffewhere_line_number (line);
00274 col_num = ffewhere_column_number (col);
00275
00276
00277
00278 for (i = 0; i < ffebad_places_; ++i)
00279 {
00280 ln = ffewhere_line_number (ffebad_here_[ffebad_order_[i]].line);
00281 cn = ffewhere_column_number (ffebad_here_[ffebad_order_[i]].col);
00282 if (line_num < ln)
00283 break;
00284 if (line_num == ln)
00285 {
00286 if (col_num == cn)
00287 {
00288 ffebad_here_[index].tag = i;
00289 return;
00290 }
00291 else if (col_num < cn)
00292 break;
00293 }
00294 }
00295
00296
00297
00298
00299 if (i != ffebad_places_)
00300 {
00301 for (j = 0; j < FFEBAD_MAX_; ++j)
00302 {
00303 if (ffebad_here_[j].tag >= i)
00304 ++ffebad_here_[j].tag;
00305 }
00306 }
00307
00308
00309
00310 for (j = ffebad_places_; j > i; --j)
00311 ffebad_order_[j] = ffebad_order_[j - 1];
00312
00313
00314
00315 ffebad_order_[i] = index;
00316 ffebad_here_[index].tag = i;
00317 ++ffebad_places_;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 void
00331 ffebad_string (const char *string)
00332 {
00333 if (ffebad_is_temp_inhibited_)
00334 return;
00335
00336 assert (ffebad_index_ != FFEBAD_MAX_);
00337 ffebad_string_[ffebad_index_++] = string;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 void
00349 ffebad_finish ()
00350 {
00351 #define MAX_SPACES 132
00352 static const char *const spaces
00353 = "...>\
00354 \040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
00355 \040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
00356 \040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
00357 \040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
00358 \040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
00359 \040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
00360 \040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
00361 \040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
00362 \040\040\040";
00363 ffewhereLineNumber last_line_num;
00364 ffewhereLineNumber ln;
00365 ffewhereLineNumber rn;
00366 ffewhereColumnNumber last_col_num;
00367 ffewhereColumnNumber cn;
00368 ffewhereColumnNumber cnt;
00369 ffewhereLine l;
00370 ffebadIndex bi;
00371 unsigned short i;
00372 char pointer;
00373 unsigned char c;
00374 unsigned const char *s;
00375 const char *fn;
00376 static char buf[1024];
00377 int bufi;
00378 int index;
00379
00380 if (ffebad_is_temp_inhibited_)
00381 return;
00382
00383 switch (ffebad_severity_)
00384 {
00385 case FFEBAD_severityINFORMATIONAL:
00386 s = _("note:");
00387 break;
00388
00389 case FFEBAD_severityWARNING:
00390 s = _("warning:");
00391 break;
00392
00393 case FFEBAD_severitySEVERE:
00394 s = _("fatal:");
00395 break;
00396
00397 default:
00398 s = "";
00399 break;
00400 }
00401
00402
00403
00404 last_line_num = 0;
00405 last_col_num = 0;
00406
00407 for (bi = 0; bi < ffebad_places_; ++bi)
00408 {
00409 if (ffebad_places_ == 1)
00410 pointer = '^';
00411 else
00412 pointer = '1' + bi;
00413
00414 l = ffebad_here_[ffebad_order_[bi]].line;
00415 ln = ffewhere_line_number (l);
00416 rn = ffewhere_line_filelinenum (l);
00417 cn = ffewhere_column_number (ffebad_here_[ffebad_order_[bi]].col);
00418 fn = ffewhere_line_filename (l);
00419 if (ln != last_line_num)
00420 {
00421 if (bi != 0)
00422 fputc ('\n', stderr);
00423 report_error_function (fn);
00424 fprintf (stderr,
00425
00426
00427
00428 "%s:%" ffewhereLineNumber_f "u: %s\n %s\n %s%c",
00429 fn, rn,
00430 s,
00431 ffewhere_line_content (l),
00432 &spaces[cn > MAX_SPACES ? 0 : MAX_SPACES - cn + 4],
00433 pointer);
00434 last_line_num = ln;
00435 last_col_num = cn;
00436 s = _("(continued):");
00437 }
00438 else
00439 {
00440 cnt = cn - last_col_num;
00441 fprintf (stderr,
00442 "%s%c", &spaces[cnt > MAX_SPACES
00443 ? 0 : MAX_SPACES - cnt + 4],
00444 pointer);
00445 last_col_num = cn;
00446 }
00447 }
00448 if (ffebad_places_ == 0)
00449 {
00450
00451 if (s[0] != '\0')
00452 {
00453 char c;
00454
00455 c = TOUPPER (s[0]);
00456 fprintf (stderr, "%c%s ", c, &s[1]);
00457 }
00458 else if (s[0] != '\0')
00459 fprintf (stderr, "%s ", s);
00460 }
00461 else
00462 fputc ('\n', stderr);
00463
00464
00465
00466 for (bi = 0; bi < FFEBAD_MAX_; ++bi)
00467 {
00468 ffewhere_line_kill (ffebad_here_[bi].line);
00469 ffewhere_column_kill (ffebad_here_[bi].col);
00470 }
00471
00472
00473
00474 bufi = 0;
00475 for (i = 0; (c = ffebad_message_[i]) != '\0'; ++i)
00476 {
00477 if (c == '%')
00478 {
00479 c = ffebad_message_[++i];
00480 if (ISUPPER (c))
00481 {
00482 index = c - 'A';
00483
00484 if ((index < 0) || (index >= FFEBAD_MAX_))
00485 {
00486 bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!] %"));
00487 bufi = ffebad_bufputc_ (buf, bufi, c);
00488 }
00489 else
00490 {
00491 s = ffebad_string_[index];
00492 if (s == NULL)
00493 bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!]"));
00494 else
00495 bufi = ffebad_bufputs_ (buf, bufi, s);
00496 }
00497 }
00498 else if (ISDIGIT (c))
00499 {
00500 index = c - '0';
00501
00502 if ((index < 0) || (index >= FFEBAD_MAX_))
00503 {
00504 bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!] %"));
00505 bufi = ffebad_bufputc_ (buf, bufi, c);
00506 }
00507 else
00508 {
00509 pointer = ffebad_here_[index].tag + '1';
00510 if (pointer == FFEBAD_MAX_ + '1')
00511 pointer = '?';
00512 else if (ffebad_places_ == 1)
00513 pointer = '^';
00514 bufi = ffebad_bufputc_ (buf, bufi, '(');
00515 bufi = ffebad_bufputc_ (buf, bufi, pointer);
00516 bufi = ffebad_bufputc_ (buf, bufi, ')');
00517 }
00518 }
00519 else if (c == '\0')
00520 break;
00521 else if (c == '%')
00522 bufi = ffebad_bufputc_ (buf, bufi, '%');
00523 else
00524 {
00525 bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!]"));
00526 bufi = ffebad_bufputc_ (buf, bufi, '%');
00527 bufi = ffebad_bufputc_ (buf, bufi, c);
00528 }
00529 }
00530 else
00531 bufi = ffebad_bufputc_ (buf, bufi, c);
00532 }
00533 bufi = ffebad_bufputc_ (buf, bufi, '\n');
00534 bufi = ffebad_bufflush_ (buf, bufi);
00535 }