/* Declarations for error-reporting facilities.

   Copyright (C) 1986-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   This program 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 of the License, or
   (at your option) any later version.

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GDBSUPPORT_ERRORS_H
#define GDBSUPPORT_ERRORS_H

/* A problem was detected, but the requested operation can still
   proceed.  A warning message is constructed using a printf- or
   vprintf-style argument list.  The function "vwarning" must be
   provided by the client.  */

extern void warning (const char *fmt, ...)
     ATTRIBUTE_PRINTF (1, 2);

extern void vwarning (const char *fmt, va_list args)
     ATTRIBUTE_PRINTF (1, 0);

/* A non-predictable, non-fatal error was detected.  The requested
   operation cannot proceed.  An error message is constructed using
   a printf- or vprintf-style argument list.  These functions do not
   return.  The function "verror" must be provided by the client.  */

[[noreturn]] extern void error (const char *fmt, ...) ATTRIBUTE_PRINTF (1, 2);

[[noreturn]] extern void verror (const char *fmt, va_list args)
  ATTRIBUTE_PRINTF (1, 0);

/* An internal error was detected.  Internal errors indicate
   programming errors such as assertion failures, as opposed to
   more general errors beyond the application's control.  These
   functions do not return.  An error message is constructed using
   a printf- or vprintf-style argument list.  FILE and LINE
   indicate the file and line number where the programming error
   was detected.  Most client code should call the internal_error
   wrapper macro instead, which expands the source location
   automatically.  The function "internal_verror" must be provided
   by the client.  */

[[noreturn]] extern void internal_error_loc (const char *file, int line,
					     const char *fmt, ...)
  ATTRIBUTE_PRINTF (3, 4);

#define internal_error(fmt, ...)				\
  internal_error_loc (__FILE__, __LINE__, fmt, ##__VA_ARGS__)

[[noreturn]] extern void internal_verror (const char *file, int line,
					  const char *fmt, va_list args)
  ATTRIBUTE_PRINTF (3, 0);

/* An internal problem was detected, but the requested operation can
   still proceed.  Internal warnings indicate programming errors as
   opposed to more general issues beyond the application's control.
   A warning message is constructed using a printf- or vprintf-style
   argument list.  The function "internal_vwarning" must be provided
   by the client.  */

extern void internal_warning_loc (const char *file, int line,
				  const char *fmt, ...)
     ATTRIBUTE_PRINTF (3, 4);

#define internal_warning(fmt, ...)				\
  internal_warning_loc (__FILE__, __LINE__, fmt, ##__VA_ARGS__)

extern void internal_vwarning (const char *file, int line,
			       const char *fmt, va_list args)
     ATTRIBUTE_PRINTF (3, 0);


/* Return a newly allocated string, containing the PREFIX followed
   by the system error message for errno (separated by a colon).
   If ERRNUM is given, then use it in place of errno.  */

extern std::string perror_string (const char *prefix, int errnum = 0);

/* Like "error", but the error message is constructed by combining
   STRING with the system error message for errno.  If ERRNUM is given,
   then use it in place of errno.  This function does not return.  */

[[noreturn]] extern void perror_with_name (const char *string, int errnum = 0);

/* Call this function to handle memory allocation failures.  This
   function does not return.  This function must be provided by the
   client.  */

[[noreturn]] extern void malloc_failure (long size);

/* Flush stdout and stderr.  Must be provided by the client.  */

extern void flush_streams ();

#if defined(USE_WIN32API) || defined(__CYGWIN__)

/* Map the Windows error number in ERROR to a locale-dependent error
   message string and return a pointer to it.  Typically, the values
   for ERROR come from GetLastError.

   The string pointed to shall not be modified by the application,
   but may be overwritten by a subsequent call to strwinerror

   The strwinerror function does not change the current setting
   of GetLastError.  */

extern const char *strwinerror (ULONGEST error);

/* Like perror_with_name, but for Windows errors.  Throw an exception
   including STRING and the system text for the given error
   number.  */

[[noreturn]] extern void throw_winerror_with_name (const char *string,
						   ULONGEST err);

#endif /* USE_WIN32API */

#endif /* GDBSUPPORT_ERRORS_H */
