// go-diagnostics.cc -- Go error/warning diagnostics utilities.

// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go-diagnostics.h"

static std::string
mformat_value()
{
  return std::string(xstrerror(errno));
}

// Rewrite a format string to expand any extensions not
// supported by sprintf(). See comments in go-diagnostics.h
// for list of supported format specifiers.

static std::string
expand_format(const char* fmt)
{
  std::stringstream ss;
  for (const char* c = fmt; *c; ++c)
    {
      if (*c != '%')
        {
          ss << *c;
          continue;
        }
      c++;
      switch (*c)
        {
          case '\0':
            {
              // malformed format string
              go_unreachable();
            }
          case '%':
            {
              ss << "%";
              break;
            }
          case 'm':
            {
              ss << mformat_value();
              break;
            }
          case '<':
            {
              ss << go_open_quote();
              break;
            }
          case '>':
            {
              ss << go_close_quote();
              break;
            }
          case 'q':
            {
              ss << go_open_quote();
              c++;
              if (*c == 'm')
                {
                  ss << mformat_value();
                }
              else
                {
                  ss << "%" << *c;
                }
              ss << go_close_quote();
              break;
            }
          default:
            {
              ss << "%" << *c;
            }
        }
    }
  return ss.str();
}

// Expand message format specifiers, using a combination of
// expand_format above to handle extensions (ex: %m, %q) and vasprintf()
// to handle regular printf-style formatting. A pragma is being used here to
// suppress this warning:
//
//   warning: function ‘std::__cxx11::string expand_message(const char*, __va_list_tag*)’ might be a candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format]
//
// What appears to be happening here is that the checker is deciding that
// because of the call to vasprintf() (which has attribute gnu_printf), the
// calling function must need to have attribute gnu_printf as well, even
// though there is already an attribute declaration for it.

static std::string
expand_message(const char* fmt, va_list ap) GO_ATTRIBUTE_GCC_DIAG(1,0);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"

static std::string
expand_message(const char* fmt, va_list ap)
{
  char* mbuf = 0;
  std::string expanded_fmt = expand_format(fmt);
  int nwr = vasprintf(&mbuf, expanded_fmt.c_str(), ap);
  if (nwr == -1)
    {
      // memory allocation failed
      go_be_error_at(Linemap::unknown_location(),
                     "memory allocation failed in vasprintf");
      go_assert(0);
    }
  std::string rval = std::string(mbuf);
  free(mbuf);
  return rval;
}

#pragma GCC diagnostic pop

static const char* cached_open_quote = NULL;
static const char* cached_close_quote = NULL;

const char*
go_open_quote()
{
  if (cached_open_quote == NULL)
    go_be_get_quotechars(&cached_open_quote, &cached_close_quote);
  return cached_open_quote;
}

const char*
go_close_quote()
{
  if (cached_close_quote == NULL)
    go_be_get_quotechars(&cached_open_quote, &cached_close_quote);
  return cached_close_quote;
}

void
go_error_at(const Location location, const char* fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  go_be_error_at(location, expand_message(fmt, ap));
  va_end(ap);
}

void
go_warning_at(const Location location, int opt, const char* fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  go_be_warning_at(location, opt, expand_message(fmt, ap));
  va_end(ap);
}

void
go_fatal_error(const Location location, const char* fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  go_be_fatal_error(location, expand_message(fmt, ap));
  va_end(ap);
}

void
go_inform(const Location location, const char* fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  go_be_inform(location, expand_message(fmt, ap));
  va_end(ap);
}

// go_debug uses normal printf formatting, not GCC diagnostic formatting.

void
go_debug(const Location location, const char* fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  char* mbuf = NULL;
  int nwr = vasprintf(&mbuf, fmt, ap);
  va_end(ap);
  if (nwr == -1)
    {
      go_be_error_at(Linemap::unknown_location(),
		     "memory allocation failed in vasprintf");
      go_assert(0);
    }
  std::string rval = std::string(mbuf);
  free(mbuf);
  go_be_inform(location, rval);
}
