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

   Copyright (C) 1986-2022 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 "gdbsupport/byte-vector.h"
#include "gdbsupport/gdb_unique_ptr.h"
#include "poison.h"
#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);

/* Like asprintf and vasprintf, but return the string, throw an error
   if no memory.  */
gdb::unique_xmalloc_ptr<char> xstrprintf (const char *format, ...)
     ATTRIBUTE_PRINTF (1, 2);
gdb::unique_xmalloc_ptr<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.  */
std::string &string_appendf (std::string &dest, const char* fmt, ...)
  ATTRIBUTE_PRINTF (2, 3);

/* Like string_appendf, but takes a va_list.  */
std::string &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);

/* Version of startswith that takes string_view arguments.  Return
   true if the start of STRING matches PATTERN, false otherwise.  */

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);

/* 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 (N'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);

/* Convert hex digit A to a number, or throw an exception.  */
extern int fromhex (int a);

/* HEX is a string of characters representing hexadecimal digits.
   Convert pairs of hex digits to bytes and store sequentially into
   BIN.  COUNT is the maximum number of characters to convert.  This
   will convert fewer characters if the number of hex characters
   actually seen is odd, or if HEX terminates before COUNT characters.
   Returns the number of characters actually converted.  */
extern int hex2bin (const char *hex, gdb_byte *bin, int count);

/* Like the above, but return a gdb::byte_vector.  */
gdb::byte_vector hex2bin (const char *hex);

#endif /* COMMON_COMMON_UTILS_H */
