// Copyright 2006-2008 the V8 project 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 "src/base/logging.h"

#include <cctype>
#if !V8_OS_STARBOARD
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#endif

#include "src/base/debug/stack_trace.h"
#include "src/base/platform/platform.h"

namespace v8 {
namespace base {

namespace {

void DefaultDcheckHandler(const char* file, int line, const char* message);

void (*g_print_stack_trace)() = nullptr;

void (*g_dcheck_function)(const char*, int, const char*) = DefaultDcheckHandler;

void PrettyPrintChar(std::ostream& os, int ch) {
  switch (ch) {
#define CHAR_PRINT_CASE(ch) \
  case ch:                  \
    os << #ch;              \
    break;

    CHAR_PRINT_CASE('\0')
    CHAR_PRINT_CASE('\'')
    CHAR_PRINT_CASE('\\')
    CHAR_PRINT_CASE('\a')
    CHAR_PRINT_CASE('\b')
    CHAR_PRINT_CASE('\f')
    CHAR_PRINT_CASE('\n')
    CHAR_PRINT_CASE('\r')
    CHAR_PRINT_CASE('\t')
    CHAR_PRINT_CASE('\v')
#undef CHAR_PRINT_CASE
    default:
      if (std::isprint(ch)) {
        os << '\'' << ch << '\'';
      } else {
        auto flags = os.flags(std::ios_base::hex);
        os << "\\x" << static_cast<unsigned int>(ch);
        os.flags(flags);
      }
  }
}

void DefaultDcheckHandler(const char* file, int line, const char* message) {
  V8_Fatal(file, line, "Debug check failed: %s.", message);
}

}  // namespace

void SetPrintStackTrace(void (*print_stack_trace)()) {
  g_print_stack_trace = print_stack_trace;
}

void SetDcheckFunction(void (*dcheck_function)(const char*, int, const char*)) {
  g_dcheck_function = dcheck_function ? dcheck_function : &DefaultDcheckHandler;
}

// Define specialization to pretty print characters (escaping non-printable
// characters) and to print c strings as pointers instead of strings.
#define DEFINE_PRINT_CHECK_OPERAND_CHAR(type)                                \
  template <>                                                                \
  void PrintCheckOperand<type>(std::ostream & os, type ch) {                 \
    PrettyPrintChar(os, ch);                                                 \
  }                                                                          \
  template <>                                                                \
  void PrintCheckOperand<type*>(std::ostream & os, type * cstr) {            \
    os << static_cast<void*>(cstr);                                          \
  }                                                                          \
  template <>                                                                \
  void PrintCheckOperand<const type*>(std::ostream & os, const type* cstr) { \
    os << static_cast<const void*>(cstr);                                    \
  }

DEFINE_PRINT_CHECK_OPERAND_CHAR(char)
DEFINE_PRINT_CHECK_OPERAND_CHAR(signed char)
DEFINE_PRINT_CHECK_OPERAND_CHAR(unsigned char)
#undef DEFINE_PRINT_CHECK_OPERAND_CHAR

// Explicit instantiations for commonly used comparisons.
#define DEFINE_MAKE_CHECK_OP_STRING(type)                           \
  template std::string* MakeCheckOpString<type, type>(type, type,   \
                                                      char const*); \
  template void PrintCheckOperand<type>(std::ostream&, type);
DEFINE_MAKE_CHECK_OP_STRING(int)
DEFINE_MAKE_CHECK_OP_STRING(long)       // NOLINT(runtime/int)
DEFINE_MAKE_CHECK_OP_STRING(long long)  // NOLINT(runtime/int)
DEFINE_MAKE_CHECK_OP_STRING(unsigned int)
DEFINE_MAKE_CHECK_OP_STRING(unsigned long)       // NOLINT(runtime/int)
DEFINE_MAKE_CHECK_OP_STRING(unsigned long long)  // NOLINT(runtime/int)
DEFINE_MAKE_CHECK_OP_STRING(void const*)
#undef DEFINE_MAKE_CHECK_OP_STRING


// Explicit instantiations for floating point checks.
#define DEFINE_CHECK_OP_IMPL(NAME)                                            \
  template std::string* Check##NAME##Impl<float, float>(float lhs, float rhs, \
                                                        char const* msg);     \
  template std::string* Check##NAME##Impl<double, double>(                    \
      double lhs, double rhs, char const* msg);
DEFINE_CHECK_OP_IMPL(EQ)
DEFINE_CHECK_OP_IMPL(NE)
DEFINE_CHECK_OP_IMPL(LE)
DEFINE_CHECK_OP_IMPL(LT)
DEFINE_CHECK_OP_IMPL(GE)
DEFINE_CHECK_OP_IMPL(GT)
#undef DEFINE_CHECK_OP_IMPL

}  // namespace base
}  // namespace v8

void V8_Fatal(const char* file, int line, const char* format, ...) {
#if !V8_OS_STARBOARD
  fflush(stdout);
  fflush(stderr);
#endif
  v8::base::OS::PrintError("\n\n#\n# Fatal error in %s, line %d\n# ", file,
                           line);
  va_list arguments;
  va_start(arguments, format);
  v8::base::OS::VPrintError(format, arguments);
  va_end(arguments);
  v8::base::OS::PrintError("\n#\n");

  if (v8::base::g_print_stack_trace) v8::base::g_print_stack_trace();

#if !V8_OS_STARBOARD
  fflush(stderr);
#endif
  v8::base::OS::Abort();
}

void V8_Dcheck(const char* file, int line, const char* message) {
  v8::base::g_dcheck_function(file, line, message);
}
