#define FFEBAD_MAX_ 6
#include "proj.h"
#include "bad.h"
#include "flags.h"
#include "com.h"
#include "toplev.h"
#include "where.h"
#include "intl.h"
#include "diagnostic.h"
bool ffebad_is_inhibited_ = FALSE;
#define FFEBAD_LONG_MSGS_ 1
struct _ffebad_message_
{
const ffebadSeverity severity;
const char *const message;
};
static const struct _ffebad_message_ ffebad_messages_[]
=
{
#define FFEBAD_MSG(kwd,sev,msgid) { sev, msgid },
#if FFEBAD_LONG_MSGS_ == 0
#define LONG(m)
#define SHORT(m) m
#else
#define LONG(m) m
#define SHORT(m)
#endif
#include "bad.def"
#undef FFEBAD_MSG
#undef LONG
#undef SHORT
};
static struct
{
ffewhereLine line;
ffewhereColumn col;
ffebadIndex tag;
}
ffebad_here_[FFEBAD_MAX_];
static const char *ffebad_string_[FFEBAD_MAX_];
static ffebadIndex ffebad_order_[FFEBAD_MAX_];
static ffebad ffebad_errnum_;
static ffebadSeverity ffebad_severity_;
static const char *ffebad_message_;
static unsigned char ffebad_index_;
static ffebadIndex ffebad_places_;
static bool ffebad_is_temp_inhibited_;
static int ffebad_bufputs_ (char buf[], int bufi, const char *s);
#define ffebad_bufflush_(buf, bufi) \
(((buf)[bufi] = '\0'), fputs ((buf), stderr), 0)
#define ffebad_bufputc_(buf, bufi, c) \
(((bufi) == ARRAY_SIZE (buf)) \
? (ffebad_bufflush_ ((buf), (bufi)), ((buf)[0] = (c)), 1) \
: (((buf)[bufi] = (c)), (bufi) + 1))
static int
ffebad_bufputs_ (char buf[], int bufi, const char *s)
{
for (; *s != '\0'; ++s)
bufi = ffebad_bufputc_ (buf, bufi, *s);
return bufi;
}
void
ffebad_init_0 ()
{
assert (FFEBAD == ARRAY_SIZE (ffebad_messages_));
}
ffebadSeverity
ffebad_severity (ffebad errnum)
{
return ffebad_messages_[errnum].severity;
}
bool
ffebad_start_ (bool lex_override, ffebad errnum, ffebadSeverity sev,
const char *msgid)
{
unsigned char i;
if (ffebad_is_inhibited_ && !lex_override)
{
ffebad_is_temp_inhibited_ = TRUE;
return FALSE;
}
if (errnum != FFEBAD)
{
ffebad_severity_ = ffebad_messages_[errnum].severity;
ffebad_message_ = gettext (ffebad_messages_[errnum].message);
}
else
{
ffebad_severity_ = sev;
ffebad_message_ = gettext (msgid);
}
switch (ffebad_severity_)
{
case FFEBAD_severityINFORMATIONAL:
case FFEBAD_severityTRIVIAL:
if (inhibit_warnings)
{
ffebad_is_temp_inhibited_ = TRUE;
return FALSE;
}
case FFEBAD_severityWARNING:
case FFEBAD_severityPECULIAR:
case FFEBAD_severityPEDANTIC:
if ((ffebad_severity_ != FFEBAD_severityPEDANTIC)
|| !flag_pedantic_errors)
{
if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
{
ffebad_is_temp_inhibited_ = TRUE;
return FALSE;
}
break;
}
case FFEBAD_severityFATAL:
case FFEBAD_severityWEIRD:
case FFEBAD_severitySEVERE:
case FFEBAD_severityDISASTER:
diagnostic_count_diagnostic (global_dc, DK_ERROR);
break;
default:
break;
}
ffebad_is_temp_inhibited_ = FALSE;
ffebad_errnum_ = errnum;
ffebad_index_ = 0;
ffebad_places_ = 0;
for (i = 0; i < FFEBAD_MAX_; ++i)
{
ffebad_string_[i] = NULL;
ffebad_here_[i].line = ffewhere_line_unknown ();
ffebad_here_[i].col = ffewhere_column_unknown ();
}
return TRUE;
}
void
ffebad_here (ffebadIndex index, ffewhereLine line, ffewhereColumn col)
{
ffewhereLineNumber line_num;
ffewhereLineNumber ln;
ffewhereColumnNumber col_num;
ffewhereColumnNumber cn;
ffebadIndex i;
ffebadIndex j;
if (ffebad_is_temp_inhibited_)
return;
assert (index < FFEBAD_MAX_);
ffebad_here_[index].line = ffewhere_line_use (line);
ffebad_here_[index].col = ffewhere_column_use (col);
if (ffewhere_line_is_unknown (line)
|| ffewhere_column_is_unknown (col))
{
ffebad_here_[index].tag = FFEBAD_MAX_;
return;
}
ffebad_here_[index].tag = 0;
line_num = ffewhere_line_number (line);
col_num = ffewhere_column_number (col);
for (i = 0; i < ffebad_places_; ++i)
{
ln = ffewhere_line_number (ffebad_here_[ffebad_order_[i]].line);
cn = ffewhere_column_number (ffebad_here_[ffebad_order_[i]].col);
if (line_num < ln)
break;
if (line_num == ln)
{
if (col_num == cn)
{
ffebad_here_[index].tag = i;
return;
}
else if (col_num < cn)
break;
}
}
if (i != ffebad_places_)
{
for (j = 0; j < FFEBAD_MAX_; ++j)
{
if (ffebad_here_[j].tag >= i)
++ffebad_here_[j].tag;
}
}
for (j = ffebad_places_; j > i; --j)
ffebad_order_[j] = ffebad_order_[j - 1];
ffebad_order_[i] = index;
ffebad_here_[index].tag = i;
++ffebad_places_;
}
void
ffebad_string (const char *string)
{
if (ffebad_is_temp_inhibited_)
return;
assert (ffebad_index_ != FFEBAD_MAX_);
ffebad_string_[ffebad_index_++] = string;
}
void
ffebad_finish ()
{
#define MAX_SPACES 132
static const char *const spaces
= "...>\
\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
\040\040\040";
ffewhereLineNumber last_line_num;
ffewhereLineNumber ln;
ffewhereLineNumber rn;
ffewhereColumnNumber last_col_num;
ffewhereColumnNumber cn;
ffewhereColumnNumber cnt;
ffewhereLine l;
ffebadIndex bi;
unsigned short i;
char pointer;
unsigned char c;
unsigned const char *s;
const char *fn;
static char buf[1024];
int bufi;
int index;
if (ffebad_is_temp_inhibited_)
return;
switch (ffebad_severity_)
{
case FFEBAD_severityINFORMATIONAL:
s = _("note:");
break;
case FFEBAD_severityWARNING:
s = _("warning:");
break;
case FFEBAD_severitySEVERE:
s = _("fatal:");
break;
default:
s = "";
break;
}
last_line_num = 0;
last_col_num = 0;
for (bi = 0; bi < ffebad_places_; ++bi)
{
if (ffebad_places_ == 1)
pointer = '^';
else
pointer = '1' + bi;
l = ffebad_here_[ffebad_order_[bi]].line;
ln = ffewhere_line_number (l);
rn = ffewhere_line_filelinenum (l);
cn = ffewhere_column_number (ffebad_here_[ffebad_order_[bi]].col);
fn = ffewhere_line_filename (l);
if (ln != last_line_num)
{
if (bi != 0)
fputc ('\n', stderr);
diagnostic_report_current_function (global_dc);
fprintf (stderr,
"%s:%" ffewhereLineNumber_f "u: %s\n %s\n %s%c",
fn, rn,
s,
ffewhere_line_content (l),
&spaces[cn > MAX_SPACES ? 0 : MAX_SPACES - cn + 4],
pointer);
last_line_num = ln;
last_col_num = cn;
s = _("(continued):");
}
else
{
cnt = cn - last_col_num;
fprintf (stderr,
"%s%c", &spaces[cnt > MAX_SPACES
? 0 : MAX_SPACES - cnt + 4],
pointer);
last_col_num = cn;
}
}
if (ffebad_places_ == 0)
{
if (s[0] != '\0')
{
char c;
c = TOUPPER (s[0]);
fprintf (stderr, "%c%s ", c, &s[1]);
}
else if (s[0] != '\0')
fprintf (stderr, "%s ", s);
}
else
fputc ('\n', stderr);
for (bi = 0; bi < FFEBAD_MAX_; ++bi)
{
ffewhere_line_kill (ffebad_here_[bi].line);
ffewhere_column_kill (ffebad_here_[bi].col);
}
bufi = 0;
for (i = 0; (c = ffebad_message_[i]) != '\0'; ++i)
{
if (c == '%')
{
c = ffebad_message_[++i];
if (ISUPPER (c))
{
index = c - 'A';
if ((index < 0) || (index >= FFEBAD_MAX_))
{
bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!] %"));
bufi = ffebad_bufputc_ (buf, bufi, c);
}
else
{
s = ffebad_string_[index];
if (s == NULL)
bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!]"));
else
bufi = ffebad_bufputs_ (buf, bufi, s);
}
}
else if (ISDIGIT (c))
{
index = c - '0';
if ((index < 0) || (index >= FFEBAD_MAX_))
{
bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!] %"));
bufi = ffebad_bufputc_ (buf, bufi, c);
}
else
{
pointer = ffebad_here_[index].tag + '1';
if (pointer == FFEBAD_MAX_ + '1')
pointer = '?';
else if (ffebad_places_ == 1)
pointer = '^';
bufi = ffebad_bufputc_ (buf, bufi, '(');
bufi = ffebad_bufputc_ (buf, bufi, pointer);
bufi = ffebad_bufputc_ (buf, bufi, ')');
}
}
else if (c == '\0')
break;
else if (c == '%')
bufi = ffebad_bufputc_ (buf, bufi, '%');
else
{
bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!]"));
bufi = ffebad_bufputc_ (buf, bufi, '%');
bufi = ffebad_bufputc_ (buf, bufi, c);
}
}
else
bufi = ffebad_bufputc_ (buf, bufi, c);
}
bufi = ffebad_bufputc_ (buf, bufi, '\n');
bufi = ffebad_bufflush_ (buf, bufi);
}