/* Shared general utility routines for GDB, the GNU debugger.

   Copyright (C) 1986-2020 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 COMMON_COMMON_UTILS_H
#define COMMON_COMMON_UTILS_H

#include <string>
#include <vector>

#include "poison.h"

/* If possible, define FUNCTION_NAME, a macro containing the name of
   the function being defined.  Since this macro may not always be
   defined, all uses must be protected by appropriate macro definition
   checks (Eg: "#ifdef FUNCTION_NAME").

   Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
   which contains the name of the function currently being defined.
   This is broken in G++ before version 2.6.
   C9x has a similar variable called __func__, but prefer the GCC one since
   it demangles C++ function names.  */
#if (GCC_VERSION >= 2004)
#define FUNCTION_NAME		__PRETTY_FUNCTION__
#else
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#define FUNCTION_NAME		__func__  /* ARI: func */
#endif
#endif

#include "gdb_string_view.h"

/* xmalloc(), xrealloc() and xcalloc() have already been declared in
   "libiberty.h". */

/* Like xmalloc, but zero the memory.  */
void *xzalloc (size_t);

template <typename T>
static void
xfree (T *ptr)
{
  static_assert (IsFreeable<T>::value, "Trying to use xfree with a non-POD \
data type.  Use operator delete instead.");

  if (ptr != NULL)
    free (ptr);		/* ARI: free */
}


/* Like asprintf and vasprintf, but return the string, throw an error
   if no memory.  */
char *xstrprintf (const char *format, ...) ATTRIBUTE_PRINTF (1, 2);
char *xstrvprintf (const char *format, va_list ap)
     ATTRIBUTE_PRINTF (1, 0);

/* Like snprintf, but throw an error if the output buffer is too small.  */
int xsnprintf (char *str, size_t size, const char *format, ...)
     ATTRIBUTE_PRINTF (3, 4);

/* Returns a std::string built from a printf-style format string.  */
std::string string_printf (const char* fmt, ...)
  ATTRIBUTE_PRINTF (1, 2);

/* Like string_printf, but takes a va_list.  */
std::string string_vprintf (const char* fmt, va_list args)
  ATTRIBUTE_PRINTF (1, 0);

/* Like string_printf, but appends to DEST instead of returning a new
   std::string.  */
void string_appendf (std::string &dest, const char* fmt, ...)
  ATTRIBUTE_PRINTF (2, 3);

/* Like string_appendf, but takes a va_list.  */
void string_vappendf (std::string &dest, const char* fmt, va_list args)
  ATTRIBUTE_PRINTF (2, 0);

/* Make a copy of the string at PTR with LEN characters
   (and add a null character at the end in the copy).
   Uses malloc to get the space.  Returns the address of the copy.  */

char *savestring (const char *ptr, size_t len);

/* Extract the next word from ARG.  The next word is defined as either,
   everything up to the next space, or, if the next word starts with either
   a single or double quote, then everything up to the closing quote.  The
   enclosing quotes are not returned in the result string.  The pointer in
   ARG is updated to point to the first character after the end of the
   word, or, for quoted words, the first character after the closing
   quote.  */

std::string extract_string_maybe_quoted (const char **arg);

/* The strerror() function can return NULL for errno values that are
   out of range.  Provide a "safe" version that always returns a
   printable string.  This version is also thread-safe.  */

extern const char *safe_strerror (int);

/* Return true if the start of STRING matches PATTERN, false otherwise.  */

static inline bool
startswith (const char *string, const char *pattern)
{
  return strncmp (string, pattern, strlen (pattern)) == 0;
}

/* Version of startswith that takes string_view arguments.  See comment
   above.  */

static inline bool
startswith (gdb::string_view string, gdb::string_view pattern)
{
  return (string.length () >= pattern.length ()
	  && strncmp (string.data (), pattern.data (), pattern.length ()) == 0);
}

ULONGEST strtoulst (const char *num, const char **trailer, int base);

/* Skip leading whitespace characters in INP, returning an updated
   pointer.  If INP is NULL, return NULL.  */

extern char *skip_spaces (char *inp);

/* A const-correct version of the above.  */

extern const char *skip_spaces (const char *inp);

/* Skip leading non-whitespace characters in INP, returning an updated
   pointer.  If INP is NULL, return NULL.  */

extern char *skip_to_space (char *inp);

/* A const-correct version of the above.  */

extern const char *skip_to_space (const char *inp);

/* Assumes that V is an argv for a program, and iterates through
   freeing all the elements.  */
extern void free_vector_argv (std::vector<char *> &v);

/* Given a vector of arguments ARGV, return a string equivalent to
   joining all the arguments with a whitespace separating them.  */
extern std::string stringify_argv (const std::vector<char *> &argv);

/* Return true if VALUE is in [LOW, HIGH].  */

template <typename T>
static bool
in_inclusive_range (T value, T low, T high)
{
  return value >= low && value <= high;
}

/* Ensure that V is aligned to an N byte boundary (B's assumed to be a
   power of 2).  Round up/down when necessary.  Examples of correct
   use include:

    addr = align_up (addr, 8); -- VALUE needs 8 byte alignment
    write_memory (addr, value, len);
    addr += len;

   and:

    sp = align_down (sp - len, 16); -- Keep SP 16 byte aligned
    write_memory (sp, value, len);

   Note that uses such as:

    write_memory (addr, value, len);
    addr += align_up (len, 8);

   and:

    sp -= align_up (len, 8);
    write_memory (sp, value, len);

   are typically not correct as they don't ensure that the address (SP
   or ADDR) is correctly aligned (relying on previous alignment to
   keep things right).  This is also why the methods are called
   "align_..." instead of "round_..." as the latter reads better with
   this incorrect coding style.  */

extern ULONGEST align_up (ULONGEST v, int n);
extern ULONGEST align_down (ULONGEST v, int n);

#endif /* COMMON_COMMON_UTILS_H */
