/* Handle errors.
   Copyright (C) 2000-2021 Free Software Foundation, Inc.
   Contributed by Andy Vaught & Niels Kristian Bech Jensen

This file is part of GCC.

GCC 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 3, or (at your option) any later
version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* Handle the inevitable errors.  A major catch here is that things
   flagged as errors in one match subroutine can conceivably be legal
   elsewhere.  This means that error messages are recorded and saved
   for possible use later.  If a line does not match a legal
   construction, then the saved error message is reported.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "options.h"
#include "gfortran.h"

#include "diagnostic.h"
#include "diagnostic-color.h"
#include "tree-diagnostic.h" /* tree_diagnostics_defaults */

static int suppress_errors = 0;

static bool warnings_not_errors = false;

static int terminal_width;

/* True if the error/warnings should be buffered.  */
static bool buffered_p;

static gfc_error_buffer error_buffer;
/* These are always buffered buffers (.flush_p == false) to be used by
   the pretty-printer.  */
static output_buffer *pp_error_buffer, *pp_warning_buffer;
static int warningcount_buffered, werrorcount_buffered;

/* Return true if there output_buffer is empty.  */

static bool
gfc_output_buffer_empty_p (const output_buffer * buf)
{
  return output_buffer_last_position_in_text (buf) == NULL;
}

/* Go one level deeper suppressing errors.  */

void
gfc_push_suppress_errors (void)
{
  gcc_assert (suppress_errors >= 0);
  ++suppress_errors;
}

static void
gfc_error_opt (int opt, const char *gmsgid, va_list ap)  ATTRIBUTE_GCC_GFC(2,0);

static bool
gfc_warning (int opt, const char *gmsgid, va_list ap) ATTRIBUTE_GCC_GFC(2,0);


/* Leave one level of error suppressing.  */

void
gfc_pop_suppress_errors (void)
{
  gcc_assert (suppress_errors > 0);
  --suppress_errors;
}


/* Determine terminal width (for trimming source lines in output).  */

static int
gfc_get_terminal_width (void)
{
  return isatty (STDERR_FILENO) ? get_terminal_width () : INT_MAX;
}


/* Per-file error initialization.  */

void
gfc_error_init_1 (void)
{
  terminal_width = gfc_get_terminal_width ();
  gfc_buffer_error (false);
}


/* Set the flag for buffering errors or not.  */

void
gfc_buffer_error (bool flag)
{
  buffered_p = flag;
}


/* Add a single character to the error buffer or output depending on
   buffered_p.  */

static void
error_char (char)
{
  /* FIXME: Unused function to be removed in a subsequent patch.  */
}


/* Copy a string to wherever it needs to go.  */

static void
error_string (const char *p)
{
  while (*p)
    error_char (*p++);
}


/* Print a formatted integer to the error buffer or output.  */

#define IBUF_LEN 60

static void
error_uinteger (unsigned long long int i)
{
  char *p, int_buf[IBUF_LEN];

  p = int_buf + IBUF_LEN - 1;
  *p-- = '\0';

  if (i == 0)
    *p-- = '0';

  while (i > 0)
    {
      *p-- = i % 10 + '0';
      i = i / 10;
    }

  error_string (p + 1);
}

static void
error_integer (long long int i)
{
  unsigned long long int u;

  if (i < 0)
    {
      u = (unsigned long long int) -i;
      error_char ('-');
    }
  else
    u = i;

  error_uinteger (u);
}


static void
error_hwuint (unsigned HOST_WIDE_INT i)
{
  char *p, int_buf[IBUF_LEN];

  p = int_buf + IBUF_LEN - 1;
  *p-- = '\0';

  if (i == 0)
    *p-- = '0';

  while (i > 0)
    {
      *p-- = i % 10 + '0';
      i = i / 10;
    }

  error_string (p + 1);
}

static void
error_hwint (HOST_WIDE_INT i)
{
  unsigned HOST_WIDE_INT u;

  if (i < 0)
    {
      u = (unsigned HOST_WIDE_INT) -i;
      error_char ('-');
    }
  else
    u = i;

  error_uinteger (u);
}


static size_t
gfc_widechar_display_length (gfc_char_t c)
{
  if (gfc_wide_is_printable (c) || c == '\t')
    /* Printable ASCII character, or tabulation (output as a space).  */
    return 1;
  else if (c < ((gfc_char_t) 1 << 8))
    /* Displayed as \x??  */
    return 4;
  else if (c < ((gfc_char_t) 1 << 16))
    /* Displayed as \u????  */
    return 6;
  else
    /* Displayed as \U????????  */
    return 10;
}


/* Length of the ASCII representation of the wide string, escaping wide
   characters as print_wide_char_into_buffer() does.  */

static size_t
gfc_wide_display_length (const gfc_char_t *str)
{
  size_t i, len;

  for (i = 0, len = 0; str[i]; i++)
    len += gfc_widechar_display_length (str[i]);

  return len;
}

static int
print_wide_char_into_buffer (gfc_char_t c, char *buf)
{
  static const char xdigit[16] = { '0', '1', '2', '3', '4', '5', '6',
    '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

  if (gfc_wide_is_printable (c) || c == '\t')
    {
      buf[1] = '\0';
      /* Tabulation is output as a space.  */
      buf[0] = (unsigned char) (c == '\t' ? ' ' : c);
      return 1;
    }
  else if (c < ((gfc_char_t) 1 << 8))
    {
      buf[4] = '\0';
      buf[3] = xdigit[c & 0x0F];
      c = c >> 4;
      buf[2] = xdigit[c & 0x0F];

      buf[1] = 'x';
      buf[0] = '\\';
      return 4;
    }
  else if (c < ((gfc_char_t) 1 << 16))
    {
      buf[6] = '\0';
      buf[5] = xdigit[c & 0x0F];
      c = c >> 4;
      buf[4] = xdigit[c & 0x0F];
      c = c >> 4;
      buf[3] = xdigit[c & 0x0F];
      c = c >> 4;
      buf[2] = xdigit[c & 0x0F];

      buf[1] = 'u';
      buf[0] = '\\';
      return 6;
    }
  else
    {
      buf[10] = '\0';
      buf[9] = xdigit[c & 0x0F];
      c = c >> 4;
      buf[8] = xdigit[c & 0x0F];
      c = c >> 4;
      buf[7] = xdigit[c & 0x0F];
      c = c >> 4;
      buf[6] = xdigit[c & 0x0F];
      c = c >> 4;
      buf[5] = xdigit[c & 0x0F];
      c = c >> 4;
      buf[4] = xdigit[c & 0x0F];
      c = c >> 4;
      buf[3] = xdigit[c & 0x0F];
      c = c >> 4;
      buf[2] = xdigit[c & 0x0F];

      buf[1] = 'U';
      buf[0] = '\\';
      return 10;
    }
}

static char wide_char_print_buffer[11];

const char *
gfc_print_wide_char (gfc_char_t c)
{
  print_wide_char_into_buffer (c, wide_char_print_buffer);
  return wide_char_print_buffer;
}


/* Show the file, where it was included, and the source line, give a
   locus.  Calls error_printf() recursively, but the recursion is at
   most one level deep.  */

static void error_printf (const char *, ...) ATTRIBUTE_GCC_GFC(1,2);

static void
show_locus (locus *loc, int c1, int c2)
{
  gfc_linebuf *lb;
  gfc_file *f;
  gfc_char_t *p;
  int i, offset, cmax;

  /* TODO: Either limit the total length and number of included files
     displayed or add buffering of arbitrary number of characters in
     error messages.  */

  /* Write out the error header line, giving the source file and error
     location (in GNU standard "[file]:[line].[column]:" format),
     followed by an "included by" stack and a blank line.  This header
     format is matched by a testsuite parser defined in
     lib/gfortran-dg.exp.  */

  lb = loc->lb;
  f = lb->file;

  error_string (f->filename);
  error_char (':');

  error_integer (LOCATION_LINE (lb->location));

  if ((c1 > 0) || (c2 > 0))
    error_char ('.');

  if (c1 > 0)
    error_integer (c1);

  if ((c1 > 0) && (c2 > 0))
    error_char ('-');

  if (c2 > 0)
    error_integer (c2);

  error_char (':');
  error_char ('\n');

  for (;;)
    {
      i = f->inclusion_line;

      f = f->up;
      if (f == NULL) break;

      error_printf ("    Included at %s:%d:", f->filename, i);
    }

  error_char ('\n');

  /* Calculate an appropriate horizontal offset of the source line in
     order to get the error locus within the visible portion of the
     line.  Note that if the margin of 5 here is changed, the
     corresponding margin of 10 in show_loci should be changed.  */

  offset = 0;

  /* If the two loci would appear in the same column, we shift
     '2' one column to the right, so as to print '12' rather than
     just '1'.  We do this here so it will be accounted for in the
     margin calculations.  */

  if (c1 == c2)
    c2 += 1;

  cmax = (c1 < c2) ? c2 : c1;
  if (cmax > terminal_width - 5)
    offset = cmax - terminal_width + 5;

  /* Show the line itself, taking care not to print more than what can
     show up on the terminal.  Tabs are converted to spaces, and
     nonprintable characters are converted to a "\xNN" sequence.  */

  p = &(lb->line[offset]);
  i = gfc_wide_display_length (p);
  if (i > terminal_width)
    i = terminal_width - 1;

  while (i > 0)
    {
      static char buffer[11];
      i -= print_wide_char_into_buffer (*p++, buffer);
      error_string (buffer);
    }

  error_char ('\n');

  /* Show the '1' and/or '2' corresponding to the column of the error
     locus.  Note that a value of -1 for c1 or c2 will simply cause
     the relevant number not to be printed.  */

  c1 -= offset;
  c2 -= offset;
  cmax -= offset;

  p = &(lb->line[offset]);
  for (i = 0; i < cmax; i++)
    {
      int spaces, j;
      spaces = gfc_widechar_display_length (*p++);

      if (i == c1)
	error_char ('1'), spaces--;
      else if (i == c2)
	error_char ('2'), spaces--;

      for (j = 0; j < spaces; j++)
	error_char (' ');
    }

  if (i == c1)
    error_char ('1');
  else if (i == c2)
    error_char ('2');

  error_char ('\n');

}


/* As part of printing an error, we show the source lines that caused
   the problem.  We show at least one, and possibly two loci; the two
   loci may or may not be on the same source line.  */

static void
show_loci (locus *l1, locus *l2)
{
  int m, c1, c2;

  if (l1 == NULL || l1->lb == NULL)
    {
      error_printf ("<During initialization>\n");
      return;
    }

  /* While calculating parameters for printing the loci, we consider possible
     reasons for printing one per line.  If appropriate, print the loci
     individually; otherwise we print them both on the same line.  */

  c1 = l1->nextc - l1->lb->line;
  if (l2 == NULL)
    {
      show_locus (l1, c1, -1);
      return;
    }

  c2 = l2->nextc - l2->lb->line;

  if (c1 < c2)
    m = c2 - c1;
  else
    m = c1 - c2;

  /* Note that the margin value of 10 here needs to be less than the
     margin of 5 used in the calculation of offset in show_locus.  */

  if (l1->lb != l2->lb || m > terminal_width - 10)
    {
      show_locus (l1, c1, -1);
      show_locus (l2, -1, c2);
      return;
    }

  show_locus (l1, c1, c2);

  return;
}


/* Workhorse for the error printing subroutines.  This subroutine is
   inspired by g77's error handling and is similar to printf() with
   the following %-codes:

   %c Character, %d or %i Integer, %s String, %% Percent
   %L  Takes locus argument
   %C  Current locus (no argument)

   If a locus pointer is given, the actual source line is printed out
   and the column is indicated.  Since we want the error message at
   the bottom of any source file information, we must scan the
   argument list twice -- once to determine whether the loci are
   present and record this for printing, and once to print the error
   message after and loci have been printed.  A maximum of two locus
   arguments are permitted.

   This function is also called (recursively) by show_locus in the
   case of included files; however, as show_locus does not resupply
   any loci, the recursion is at most one level deep.  */

#define MAX_ARGS 10

static void ATTRIBUTE_GCC_GFC(2,0)
error_print (const char *type, const char *format0, va_list argp)
{
  enum { TYPE_CURRENTLOC, TYPE_LOCUS, TYPE_INTEGER, TYPE_UINTEGER,
	 TYPE_LONGINT, TYPE_ULONGINT, TYPE_LLONGINT, TYPE_ULLONGINT,
	 TYPE_HWINT, TYPE_HWUINT, TYPE_CHAR, TYPE_STRING, NOTYPE };
  struct
  {
    int type;
    int pos;
    union
    {
      int intval;
      unsigned int uintval;
      long int longintval;
      unsigned long int ulongintval;
      long long int llongintval;
      unsigned long long int ullongintval;
      HOST_WIDE_INT hwintval;
      unsigned HOST_WIDE_INT hwuintval;
      char charval;
      const char * stringval;
    } u;
  } arg[MAX_ARGS], spec[MAX_ARGS];
  /* spec is the array of specifiers, in the same order as they
     appear in the format string.  arg is the array of arguments,
     in the same order as they appear in the va_list.  */

  char c;
  int i, n, have_l1, pos, maxpos;
  locus *l1, *l2, *loc;
  const char *format;

  loc = l1 = l2 = NULL;

  have_l1 = 0;
  pos = -1;
  maxpos = -1;

  n = 0;
  format = format0;

  for (i = 0; i < MAX_ARGS; i++)
    {
      arg[i].type = NOTYPE;
      spec[i].pos = -1;
    }

  /* First parse the format string for position specifiers.  */
  while (*format)
    {
      c = *format++;
      if (c != '%')
	continue;

      if (*format == '%')
	{
	  format++;
	  continue;
	}

      if (ISDIGIT (*format))
	{
	  /* This is a position specifier.  For example, the number
	     12 in the format string "%12$d", which specifies the third
	     argument of the va_list, formatted in %d format.
	     For details, see "man 3 printf".  */
	  pos = atoi(format) - 1;
	  gcc_assert (pos >= 0);
	  while (ISDIGIT(*format))
	    format++;
	  gcc_assert (*format == '$');
	  format++;
	}
      else
	pos++;

      c = *format++;

      if (pos > maxpos)
	maxpos = pos;

      switch (c)
	{
	  case 'C':
	    arg[pos].type = TYPE_CURRENTLOC;
	    break;

	  case 'L':
	    arg[pos].type = TYPE_LOCUS;
	    break;

	  case 'd':
	  case 'i':
	    arg[pos].type = TYPE_INTEGER;
	    break;

	  case 'u':
	    arg[pos].type = TYPE_UINTEGER;
	    break;

	  case 'l':
	    c = *format++;
	    if (c == 'l')
	      {
		c = *format++;
		if (c == 'u')
		  arg[pos].type = TYPE_ULLONGINT;
		else if (c == 'i' || c == 'd')
		  arg[pos].type = TYPE_LLONGINT;
		else
		  gcc_unreachable ();
	      }
	    else if (c == 'u')
	      arg[pos].type = TYPE_ULONGINT;
	    else if (c == 'i' || c == 'd')
	      arg[pos].type = TYPE_LONGINT;
	    else
	      gcc_unreachable ();
	    break;

	  case 'w':
	    c = *format++;
	    if (c == 'u')
	      arg[pos].type = TYPE_HWUINT;
	    else if (c == 'i' || c == 'd')
	      arg[pos].type = TYPE_HWINT;
	    else
	      gcc_unreachable ();
	    break;

	  case 'c':
	    arg[pos].type = TYPE_CHAR;
	    break;

	  case 's':
	    arg[pos].type = TYPE_STRING;
	    break;

	  default:
	    gcc_unreachable ();
	}

      spec[n++].pos = pos;
    }

  /* Then convert the values for each %-style argument.  */
  for (pos = 0; pos <= maxpos; pos++)
    {
      gcc_assert (arg[pos].type != NOTYPE);
      switch (arg[pos].type)
	{
	  case TYPE_CURRENTLOC:
	    loc = &gfc_current_locus;
	    /* Fall through.  */

	  case TYPE_LOCUS:
	    if (arg[pos].type == TYPE_LOCUS)
	      loc = va_arg (argp, locus *);

	    if (have_l1)
	      {
		l2 = loc;
		arg[pos].u.stringval = "(2)";
		/* Point %C first offending character not the last good one. */
		if (arg[pos].type == TYPE_CURRENTLOC && *l2->nextc != '\0')
		  l2->nextc++;
	      }
	    else
	      {
		l1 = loc;
		have_l1 = 1;
		arg[pos].u.stringval = "(1)";
		/* Point %C first offending character not the last good one. */
		if (arg[pos].type == TYPE_CURRENTLOC && *l1->nextc != '\0')
		  l1->nextc++;
	      }
	    break;

	  case TYPE_INTEGER:
	    arg[pos].u.intval = va_arg (argp, int);
	    break;

	  case TYPE_UINTEGER:
	    arg[pos].u.uintval = va_arg (argp, unsigned int);
	    break;

	  case TYPE_LONGINT:
	    arg[pos].u.longintval = va_arg (argp, long int);
	    break;

	  case TYPE_ULONGINT:
	    arg[pos].u.ulongintval = va_arg (argp, unsigned long int);
	    break;

	  case TYPE_LLONGINT:
	    arg[pos].u.llongintval = va_arg (argp, long long int);
	    break;

	  case TYPE_ULLONGINT:
	    arg[pos].u.ullongintval = va_arg (argp, unsigned long long int);
	    break;

	  case TYPE_HWINT:
	    arg[pos].u.hwintval = va_arg (argp, HOST_WIDE_INT);
	    break;

	  case TYPE_HWUINT:
	    arg[pos].u.hwuintval = va_arg (argp, unsigned HOST_WIDE_INT);
	    break;

	  case TYPE_CHAR:
	    arg[pos].u.charval = (char) va_arg (argp, int);
	    break;

	  case TYPE_STRING:
	    arg[pos].u.stringval = (const char *) va_arg (argp, char *);
	    break;

	  default:
	    gcc_unreachable ();
	}
    }

  for (n = 0; spec[n].pos >= 0; n++)
    spec[n].u = arg[spec[n].pos].u;

  /* Show the current loci if we have to.  */
  if (have_l1)
    show_loci (l1, l2);

  if (*type)
    {
      error_string (type);
      error_char (' ');
    }

  have_l1 = 0;
  format = format0;
  n = 0;

  for (; *format; format++)
    {
      if (*format != '%')
	{
	  error_char (*format);
	  continue;
	}

      format++;
      if (ISDIGIT (*format))
	{
	  /* This is a position specifier.  See comment above.  */
	  while (ISDIGIT (*format))
	    format++;

	  /* Skip over the dollar sign.  */
	  format++;
	}

      switch (*format)
	{
	case '%':
	  error_char ('%');
	  break;

	case 'c':
	  error_char (spec[n++].u.charval);
	  break;

	case 's':
	case 'C':		/* Current locus */
	case 'L':		/* Specified locus */
	  error_string (spec[n++].u.stringval);
	  break;

	case 'd':
	case 'i':
	  error_integer (spec[n++].u.intval);
	  break;

	case 'u':
	  error_uinteger (spec[n++].u.uintval);
	  break;

	case 'l':
	  format++;
	  if (*format == 'l')
	    {
	      format++;
	      if (*format == 'u')
		error_uinteger (spec[n++].u.ullongintval);
	      else
		error_integer (spec[n++].u.llongintval);
	    }
	  if (*format == 'u')
	    error_uinteger (spec[n++].u.ulongintval);
	  else
	    error_integer (spec[n++].u.longintval);
	  break;

	case 'w':
	  format++;
	  if (*format == 'u')
	    error_hwuint (spec[n++].u.hwintval);
	  else
	    error_hwint (spec[n++].u.hwuintval);
	  break;
	}
    }

  error_char ('\n');
}


/* Wrapper for error_print().  */

static void
error_printf (const char *gmsgid, ...)
{
  va_list argp;

  va_start (argp, gmsgid);
  error_print ("", _(gmsgid), argp);
  va_end (argp);
}


/* Clear any output buffered in a pretty-print output_buffer.  */

static void
gfc_clear_pp_buffer (output_buffer *this_buffer)
{
  pretty_printer *pp = global_dc->printer;
  output_buffer *tmp_buffer = pp->buffer;
  pp->buffer = this_buffer;
  pp_clear_output_area (pp);
  pp->buffer = tmp_buffer;
  /* We need to reset last_location, otherwise we may skip caret lines
     when we actually give a diagnostic.  */
  global_dc->last_location = UNKNOWN_LOCATION;
}

/* The currently-printing diagnostic, for use by gfc_format_decoder,
   for colorizing %C and %L.  */

static diagnostic_info *curr_diagnostic;

/* A helper function to call diagnostic_report_diagnostic, while setting
   curr_diagnostic for the duration of the call.  */

static bool
gfc_report_diagnostic (diagnostic_info *diagnostic)
{
  gcc_assert (diagnostic != NULL);
  curr_diagnostic = diagnostic;
  bool ret = diagnostic_report_diagnostic (global_dc, diagnostic);
  curr_diagnostic = NULL;
  return ret;
}

/* This is just a helper function to avoid duplicating the logic of
   gfc_warning.  */

static bool
gfc_warning (int opt, const char *gmsgid, va_list ap)
{
  va_list argp;
  va_copy (argp, ap);

  diagnostic_info diagnostic;
  rich_location rich_loc (line_table, UNKNOWN_LOCATION);
  bool fatal_errors = global_dc->fatal_errors;
  pretty_printer *pp = global_dc->printer;
  output_buffer *tmp_buffer = pp->buffer;

  gfc_clear_pp_buffer (pp_warning_buffer);

  if (buffered_p)
    {
      pp->buffer = pp_warning_buffer;
      global_dc->fatal_errors = false;
      /* To prevent -fmax-errors= triggering.  */
      --werrorcount;
    }

  diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc,
		       DK_WARNING);
  diagnostic.option_index = opt;
  bool ret = gfc_report_diagnostic (&diagnostic);

  if (buffered_p)
    {
      pp->buffer = tmp_buffer;
      global_dc->fatal_errors = fatal_errors;

      warningcount_buffered = 0;
      werrorcount_buffered = 0;
      /* Undo the above --werrorcount if not Werror, otherwise
	 werrorcount is correct already.  */
      if (!ret)
	++werrorcount;
      else if (diagnostic.kind == DK_ERROR)
	++werrorcount_buffered;
      else
	++werrorcount, --warningcount, ++warningcount_buffered;
    }

  va_end (argp);
  return ret;
}

/* Issue a warning.  */

bool
gfc_warning (int opt, const char *gmsgid, ...)
{
  va_list argp;

  va_start (argp, gmsgid);
  bool ret = gfc_warning (opt, gmsgid, argp);
  va_end (argp);
  return ret;
}


/* Whether, for a feature included in a given standard set (GFC_STD_*),
   we should issue an error or a warning, or be quiet.  */

notification
gfc_notification_std (int std)
{
  bool warning;

  warning = ((gfc_option.warn_std & std) != 0) && !inhibit_warnings;
  if ((gfc_option.allow_std & std) != 0 && !warning)
    return SILENT;

  return warning ? WARNING : ERROR;
}


/* Return a string describing the nature of a standard violation
 * and/or the relevant version of the standard.  */

char const*
notify_std_msg(int std)
{

  if (std & GFC_STD_F2018_DEL)
    return _("Fortran 2018 deleted feature:");
  else if (std & GFC_STD_F2018_OBS)
    return _("Fortran 2018 obsolescent feature:");
  else if (std & GFC_STD_F2018)
    return _("Fortran 2018:");
  else if (std & GFC_STD_F2008_OBS)
    return _("Fortran 2008 obsolescent feature:");
  else if (std & GFC_STD_F2008)
    return "Fortran 2008:";
  else if (std & GFC_STD_F2003)
    return "Fortran 2003:";
  else if (std & GFC_STD_GNU)
    return _("GNU Extension:");
  else if (std & GFC_STD_LEGACY)
    return _("Legacy Extension:");
  else if (std & GFC_STD_F95_OBS)
    return _("Obsolescent feature:");
  else if (std & GFC_STD_F95_DEL)
    return _("Deleted feature:");
  else
    gcc_unreachable ();
}


/* Possibly issue a warning/error about use of a nonstandard (or deleted)
   feature.  An error/warning will be issued if the currently selected
   standard does not contain the requested bits.  Return false if
   an error is generated.  */

bool
gfc_notify_std (int std, const char *gmsgid, ...)
{
  va_list argp;
  const char *msg, *msg2;
  char *buffer;

  /* Determine whether an error or a warning is needed.  */
  const int wstd = std & gfc_option.warn_std;    /* Standard to warn about.  */
  const int estd = std & ~gfc_option.allow_std;  /* Standard to error about.  */
  const bool warning = (wstd != 0) && !inhibit_warnings;
  const bool error = (estd != 0);

  if (!error && !warning)
    return true;
  if (suppress_errors)
    return !error;

  if (error)
    msg = notify_std_msg (estd);
  else
    msg = notify_std_msg (wstd);

  msg2 = _(gmsgid);
  buffer = (char *) alloca (strlen (msg) + strlen (msg2) + 2);
  strcpy (buffer, msg);
  strcat (buffer, " ");
  strcat (buffer, msg2);

  va_start (argp, gmsgid);
  if (error)
    gfc_error_opt (0, buffer, argp);
  else
    gfc_warning (0, buffer, argp);
  va_end (argp);

  if (error)
    return false;
  else
    return (warning && !warnings_are_errors);
}


/* Called from output_format -- during diagnostic message processing
   to handle Fortran specific format specifiers with the following meanings:

   %C  Current locus (no argument)
   %L  Takes locus argument
*/
static bool
gfc_format_decoder (pretty_printer *pp, text_info *text, const char *spec,
		    int precision, bool wide, bool set_locus, bool hash,
		    bool *quoted, const char **buffer_ptr)
{
  switch (*spec)
    {
    case 'C':
    case 'L':
      {
	static const char *result[2] = { "(1)", "(2)" };
	locus *loc;
	if (*spec == 'C')
	  loc = &gfc_current_locus;
	else
	  loc = va_arg (*text->args_ptr, locus *);
	gcc_assert (loc->nextc - loc->lb->line >= 0);
	unsigned int offset = loc->nextc - loc->lb->line;
	if (*spec == 'C' && *loc->nextc != '\0')
	  /* Point %C first offending character not the last good one. */
	  offset++;
	/* If location[0] != UNKNOWN_LOCATION means that we already
	   processed one of %C/%L.  */
	int loc_num = text->get_location (0) == UNKNOWN_LOCATION ? 0 : 1;
	location_t src_loc
	  = linemap_position_for_loc_and_offset (line_table,
						 loc->lb->location,
						 offset);
	text->set_location (loc_num, src_loc, SHOW_RANGE_WITH_CARET);
	/* Colorize the markers to match the color choices of
	   diagnostic_show_locus (the initial location has a color given
	   by the "kind" of the diagnostic, the secondary location has
	   color "range1").  */
	gcc_assert (curr_diagnostic != NULL);
	const char *color
	  = (loc_num
	     ? "range1"
	     : diagnostic_get_color_for_kind (curr_diagnostic->kind));
	pp_string (pp, colorize_start (pp_show_color (pp), color));
	pp_string (pp, result[loc_num]);
	pp_string (pp, colorize_stop (pp_show_color (pp)));
	return true;
      }
    default:
      /* Fall through info the middle-end decoder, as e.g. stor-layout.c
	 etc. diagnostics can use the FE printer while the FE is still
	 active.  */
      return default_tree_printer (pp, text, spec, precision, wide,
				   set_locus, hash, quoted, buffer_ptr);
    }
}

/* Return a malloc'd string describing the kind of diagnostic.  The
   caller is responsible for freeing the memory.  */
static char *
gfc_diagnostic_build_kind_prefix (diagnostic_context *context,
				  const diagnostic_info *diagnostic)
{
  static const char *const diagnostic_kind_text[] = {
#define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
#include "gfc-diagnostic.def"
#undef DEFINE_DIAGNOSTIC_KIND
    "must-not-happen"
  };
  static const char *const diagnostic_kind_color[] = {
#define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
#include "gfc-diagnostic.def"
#undef DEFINE_DIAGNOSTIC_KIND
    NULL
  };
  gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
  const char *text = _(diagnostic_kind_text[diagnostic->kind]);
  const char *text_cs = "", *text_ce = "";
  pretty_printer *pp = context->printer;

  if (diagnostic_kind_color[diagnostic->kind])
    {
      text_cs = colorize_start (pp_show_color (pp),
				diagnostic_kind_color[diagnostic->kind]);
      text_ce = colorize_stop (pp_show_color (pp));
    }
  return build_message_string ("%s%s:%s ", text_cs, text, text_ce);
}

/* Return a malloc'd string describing a location.  The caller is
   responsible for freeing the memory.  */
static char *
gfc_diagnostic_build_locus_prefix (diagnostic_context *context,
				   expanded_location s)
{
  pretty_printer *pp = context->printer;
  const char *locus_cs = colorize_start (pp_show_color (pp), "locus");
  const char *locus_ce = colorize_stop (pp_show_color (pp));
  return (s.file == NULL
	  ? build_message_string ("%s%s:%s", locus_cs, progname, locus_ce )
	  : !strcmp (s.file, N_("<built-in>"))
	  ? build_message_string ("%s%s:%s", locus_cs, s.file, locus_ce)
	  : context->show_column
	  ? build_message_string ("%s%s:%d:%d:%s", locus_cs, s.file, s.line,
				  s.column, locus_ce)
	  : build_message_string ("%s%s:%d:%s", locus_cs, s.file, s.line, locus_ce));
}

/* Return a malloc'd string describing two locations.  The caller is
   responsible for freeing the memory.  */
static char *
gfc_diagnostic_build_locus_prefix (diagnostic_context *context,
				   expanded_location s, expanded_location s2)
{
  pretty_printer *pp = context->printer;
  const char *locus_cs = colorize_start (pp_show_color (pp), "locus");
  const char *locus_ce = colorize_stop (pp_show_color (pp));

  return (s.file == NULL
	  ? build_message_string ("%s%s:%s", locus_cs, progname, locus_ce )
	  : !strcmp (s.file, N_("<built-in>"))
	  ? build_message_string ("%s%s:%s", locus_cs, s.file, locus_ce)
	  : context->show_column
	  ? build_message_string ("%s%s:%d:%d-%d:%s", locus_cs, s.file, s.line,
				  MIN (s.column, s2.column),
				  MAX (s.column, s2.column), locus_ce)
	  : build_message_string ("%s%s:%d:%s", locus_cs, s.file, s.line,
				  locus_ce));
}

/* This function prints the locus (file:line:column), the diagnostic kind
   (Error, Warning) and (optionally) the relevant lines of code with
   annotation lines with '1' and/or '2' below them.

   With -fdiagnostic-show-caret (the default) it prints:

       [locus of primary range]:

          some code
                 1
       Error: Some error at (1)

  With -fno-diagnostic-show-caret or if the primary range is not
  valid, it prints:

       [locus of primary range]: Error: Some error at (1) and (2)
*/
static void
gfc_diagnostic_starter (diagnostic_context *context,
			diagnostic_info *diagnostic)
{
  char * kind_prefix = gfc_diagnostic_build_kind_prefix (context, diagnostic);

  expanded_location s1 = diagnostic_expand_location (diagnostic);
  expanded_location s2;
  bool one_locus = diagnostic->richloc->get_num_locations () < 2;
  bool same_locus = false;

  if (!one_locus)
    {
      s2 = diagnostic_expand_location (diagnostic, 1);
      same_locus = diagnostic_same_line (context, s1, s2);
    }

  char * locus_prefix = (one_locus || !same_locus)
    ? gfc_diagnostic_build_locus_prefix (context, s1)
    : gfc_diagnostic_build_locus_prefix (context, s1, s2);

  if (!context->show_caret
      || diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION
      || diagnostic_location (diagnostic, 0) == context->last_location)
    {
      pp_set_prefix (context->printer,
		     concat (locus_prefix, " ", kind_prefix, NULL));
      free (locus_prefix);

      if (one_locus || same_locus)
	{
	  free (kind_prefix);
	  return;
	}
      /* In this case, we print the previous locus and prefix as:

	  [locus]:[prefix]: (1)

	 and we flush with a new line before setting the new prefix.  */
      pp_string (context->printer, "(1)");
      pp_newline (context->printer);
      locus_prefix = gfc_diagnostic_build_locus_prefix (context, s2);
      pp_set_prefix (context->printer,
		     concat (locus_prefix, " ", kind_prefix, NULL));
      free (kind_prefix);
      free (locus_prefix);
    }
  else
    {
      pp_verbatim (context->printer, "%s", locus_prefix);
      free (locus_prefix);
      /* Fortran uses an empty line between locus and caret line.  */
      pp_newline (context->printer);
      pp_set_prefix (context->printer, NULL);
      pp_newline (context->printer);
      diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
      /* If the caret line was shown, the prefix does not contain the
	 locus.  */
      pp_set_prefix (context->printer, kind_prefix);
    }
}

static void
gfc_diagnostic_start_span (diagnostic_context *context,
			   expanded_location exploc)
{
  char *locus_prefix;
  locus_prefix = gfc_diagnostic_build_locus_prefix (context, exploc);
  pp_verbatim (context->printer, "%s", locus_prefix);
  free (locus_prefix);
  pp_newline (context->printer);
  /* Fortran uses an empty line between locus and caret line.  */
  pp_newline (context->printer);
}


static void
gfc_diagnostic_finalizer (diagnostic_context *context,
			  diagnostic_info *diagnostic ATTRIBUTE_UNUSED,
			  diagnostic_t orig_diag_kind ATTRIBUTE_UNUSED)
{
  pp_destroy_prefix (context->printer);
  pp_newline_and_flush (context->printer);
}

/* Immediate warning (i.e. do not buffer the warning) with an explicit
   location.  */

bool
gfc_warning_now_at (location_t loc, int opt, const char *gmsgid, ...)
{
  va_list argp;
  diagnostic_info diagnostic;
  rich_location rich_loc (line_table, loc);
  bool ret;

  va_start (argp, gmsgid);
  diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_WARNING);
  diagnostic.option_index = opt;
  ret = gfc_report_diagnostic (&diagnostic);
  va_end (argp);
  return ret;
}

/* Immediate warning (i.e. do not buffer the warning).  */

bool
gfc_warning_now (int opt, const char *gmsgid, ...)
{
  va_list argp;
  diagnostic_info diagnostic;
  rich_location rich_loc (line_table, UNKNOWN_LOCATION);
  bool ret;

  va_start (argp, gmsgid);
  diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc,
		       DK_WARNING);
  diagnostic.option_index = opt;
  ret = gfc_report_diagnostic (&diagnostic);
  va_end (argp);
  return ret;
}

/* Internal warning, do not buffer.  */

bool
gfc_warning_internal (int opt, const char *gmsgid, ...)
{
  va_list argp;
  diagnostic_info diagnostic;
  rich_location rich_loc (line_table, UNKNOWN_LOCATION);
  bool ret;

  va_start (argp, gmsgid);
  diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc,
		       DK_WARNING);
  diagnostic.option_index = opt;
  ret = gfc_report_diagnostic (&diagnostic);
  va_end (argp);
  return ret;
}

/* Immediate error (i.e. do not buffer).  */

void
gfc_error_now (const char *gmsgid, ...)
{
  va_list argp;
  diagnostic_info diagnostic;
  rich_location rich_loc (line_table, UNKNOWN_LOCATION);

  error_buffer.flag = true;

  va_start (argp, gmsgid);
  diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ERROR);
  gfc_report_diagnostic (&diagnostic);
  va_end (argp);
}


/* Fatal error, never returns.  */

void
gfc_fatal_error (const char *gmsgid, ...)
{
  va_list argp;
  diagnostic_info diagnostic;
  rich_location rich_loc (line_table, UNKNOWN_LOCATION);

  va_start (argp, gmsgid);
  diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_FATAL);
  gfc_report_diagnostic (&diagnostic);
  va_end (argp);

  gcc_unreachable ();
}

/* Clear the warning flag.  */

void
gfc_clear_warning (void)
{
  gfc_clear_pp_buffer (pp_warning_buffer);
  warningcount_buffered = 0;
  werrorcount_buffered = 0;
}


/* Check to see if any warnings have been saved.
   If so, print the warning.  */

void
gfc_warning_check (void)
{
  if (! gfc_output_buffer_empty_p (pp_warning_buffer))
    {
      pretty_printer *pp = global_dc->printer;
      output_buffer *tmp_buffer = pp->buffer;
      pp->buffer = pp_warning_buffer;
      pp_really_flush (pp);
      warningcount += warningcount_buffered;
      werrorcount += werrorcount_buffered;
      gcc_assert (warningcount_buffered + werrorcount_buffered == 1);
      pp->buffer = tmp_buffer;
      diagnostic_action_after_output (global_dc,
				      warningcount_buffered
				      ? DK_WARNING : DK_ERROR);
      diagnostic_check_max_errors (global_dc, true);
    }
}


/* Issue an error.  */

static void
gfc_error_opt (int opt, const char *gmsgid, va_list ap)
{
  va_list argp;
  va_copy (argp, ap);
  bool saved_abort_on_error = false;

  if (warnings_not_errors)
    {
      gfc_warning (opt, gmsgid, argp);
      va_end (argp);
      return;
    }

  if (suppress_errors)
    {
      va_end (argp);
      return;
    }

  diagnostic_info diagnostic;
  rich_location richloc (line_table, UNKNOWN_LOCATION);
  bool fatal_errors = global_dc->fatal_errors;
  pretty_printer *pp = global_dc->printer;
  output_buffer *tmp_buffer = pp->buffer;

  gfc_clear_pp_buffer (pp_error_buffer);

  if (buffered_p)
    {
      /* To prevent -dH from triggering an abort on a buffered error,
	 save abort_on_error and restore it below.  */
      saved_abort_on_error = global_dc->abort_on_error;
      global_dc->abort_on_error = false;
      pp->buffer = pp_error_buffer;
      global_dc->fatal_errors = false;
      /* To prevent -fmax-errors= triggering, we decrease it before
	 report_diagnostic increases it.  */
      --errorcount;
    }

  diagnostic_set_info (&diagnostic, gmsgid, &argp, &richloc, DK_ERROR);
  gfc_report_diagnostic (&diagnostic);

  if (buffered_p)
    {
      pp->buffer = tmp_buffer;
      global_dc->fatal_errors = fatal_errors;
      global_dc->abort_on_error = saved_abort_on_error;

    }

  va_end (argp);
}


void
gfc_error_opt (int opt, const char *gmsgid, ...)
{
  va_list argp;
  va_start (argp, gmsgid);
  gfc_error_opt (opt, gmsgid, argp);
  va_end (argp);
}


void
gfc_error (const char *gmsgid, ...)
{
  va_list argp;
  va_start (argp, gmsgid);
  gfc_error_opt (0, gmsgid, argp);
  va_end (argp);
}


/* This shouldn't happen... but sometimes does.  */

void
gfc_internal_error (const char *gmsgid, ...)
{
  int e, w;
  va_list argp;
  diagnostic_info diagnostic;
  rich_location rich_loc (line_table, UNKNOWN_LOCATION);

  gfc_get_errors (&w, &e);
  if (e > 0)
    exit(EXIT_FAILURE);

  va_start (argp, gmsgid);
  diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ICE);
  gfc_report_diagnostic (&diagnostic);
  va_end (argp);

  gcc_unreachable ();
}


/* Clear the error flag when we start to compile a source line.  */

void
gfc_clear_error (void)
{
  error_buffer.flag = false;
  warnings_not_errors = false;
  gfc_clear_pp_buffer (pp_error_buffer);
}


/* Tests the state of error_flag.  */

bool
gfc_error_flag_test (void)
{
  return error_buffer.flag
    || !gfc_output_buffer_empty_p (pp_error_buffer);
}


/* Check to see if any errors have been saved.
   If so, print the error.  Returns the state of error_flag.  */

bool
gfc_error_check (void)
{
  if (error_buffer.flag
      || ! gfc_output_buffer_empty_p (pp_error_buffer))
    {
      error_buffer.flag = false;
      pretty_printer *pp = global_dc->printer;
      output_buffer *tmp_buffer = pp->buffer;
      pp->buffer = pp_error_buffer;
      pp_really_flush (pp);
      ++errorcount;
      gcc_assert (gfc_output_buffer_empty_p (pp_error_buffer));
      pp->buffer = tmp_buffer;
      diagnostic_action_after_output (global_dc, DK_ERROR);
      diagnostic_check_max_errors (global_dc, true);
      return true;
    }

  return false;
}

/* Move the text buffered from FROM to TO, then clear
   FROM. Independently if there was text in FROM, TO is also
   cleared. */

static void
gfc_move_error_buffer_from_to (gfc_error_buffer * buffer_from,
			       gfc_error_buffer * buffer_to)
{
  output_buffer * from = &(buffer_from->buffer);
  output_buffer * to =  &(buffer_to->buffer);

  buffer_to->flag = buffer_from->flag;
  buffer_from->flag = false;

  gfc_clear_pp_buffer (to);
  /* We make sure this is always buffered.  */
  to->flush_p = false;

  if (! gfc_output_buffer_empty_p (from))
    {
      const char *str = output_buffer_formatted_text (from);
      output_buffer_append_r (to, str, strlen (str));
      gfc_clear_pp_buffer (from);
    }
}

/* Save the existing error state.  */

void
gfc_push_error (gfc_error_buffer *err)
{
  gfc_move_error_buffer_from_to (&error_buffer, err);
}


/* Restore a previous pushed error state.  */

void
gfc_pop_error (gfc_error_buffer *err)
{
  gfc_move_error_buffer_from_to (err, &error_buffer);
}


/* Free a pushed error state, but keep the current error state.  */

void
gfc_free_error (gfc_error_buffer *err)
{
  gfc_clear_pp_buffer (&(err->buffer));
}


/* Report the number of warnings and errors that occurred to the caller.  */

void
gfc_get_errors (int *w, int *e)
{
  if (w != NULL)
    *w = warningcount + werrorcount;
  if (e != NULL)
    *e = errorcount + sorrycount + werrorcount;
}


/* Switch errors into warnings.  */

void
gfc_errors_to_warnings (bool f)
{
  warnings_not_errors = f;
}

void
gfc_diagnostics_init (void)
{
  diagnostic_starter (global_dc) = gfc_diagnostic_starter;
  global_dc->start_span = gfc_diagnostic_start_span;
  diagnostic_finalizer (global_dc) = gfc_diagnostic_finalizer;
  diagnostic_format_decoder (global_dc) = gfc_format_decoder;
  global_dc->caret_chars[0] = '1';
  global_dc->caret_chars[1] = '2';
  pp_warning_buffer = new (XNEW (output_buffer)) output_buffer ();
  pp_warning_buffer->flush_p = false;
  /* pp_error_buffer is statically allocated.  This simplifies memory
     management when using gfc_push/pop_error. */
  pp_error_buffer = &(error_buffer.buffer);
  pp_error_buffer->flush_p = false;
}

void
gfc_diagnostics_finish (void)
{
  tree_diagnostics_defaults (global_dc);
  /* We still want to use the gfc starter and finalizer, not the tree
     defaults.  */
  diagnostic_starter (global_dc) = gfc_diagnostic_starter;
  diagnostic_finalizer (global_dc) = gfc_diagnostic_finalizer;
  global_dc->caret_chars[0] = '^';
  global_dc->caret_chars[1] = '^';
}
