/* Cell-based print utility routines for GDB, the GNU debugger.

   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_PRINT_UTILS_H
#define GDBSUPPORT_PRINT_UTILS_H

/* How many characters (including the terminating null byte) fit in a
   cell.  */
#define PRINT_CELL_SIZE 50

/* %u for ULONGEST.  The result is stored in a circular static buffer,
   NUMCELLS deep.  */

extern const char *pulongest (ULONGEST u);

/* %d for LONGEST.  The result is stored in a circular static buffer,
   NUMCELLS deep.  */

extern const char *plongest (LONGEST l);

/* Convert a ULONGEST into a HEX string, like %lx, with leading zeros.
   The result is stored in a circular static buffer, NUMCELLS deep.  */

extern const char *phex (ULONGEST l, int sizeof_l);

/* Convert a ULONGEST into a HEX string, like %lx, without leading zeros.
   The result is  stored in a circular static buffer, NUMCELLS deep.  */

extern const char *phex_nz (ULONGEST l, int sizeof_l);

/* Converts a LONGEST to a C-format hexadecimal literal and stores it
   in a static string.  Returns a pointer to this string.  */

extern const char *hex_string (LONGEST num);

/* Converts a LONGEST number to a C-format hexadecimal literal and
   stores it in a static string.  Returns a pointer to this string
   that is valid until the next call.  The number is padded on the
   left with 0s to at least WIDTH characters.  */

extern const char *hex_string_custom (LONGEST num, int width);

/* Convert VAL to a numeral in the given radix.  For
 * radix 10, IS_SIGNED may be true, indicating a signed quantity;
 * otherwise VAL is interpreted as unsigned.  If WIDTH is supplied, 
 * it is the minimum width (0-padded if needed).  USE_C_FORMAT means
 * to use C format in all cases.  If it is false, then 'x' 
 * and 'o' formats do not include a prefix (0x or leading 0).  */

extern const char *int_string (LONGEST val, int radix, int is_signed, int width,
			       int use_c_format);

/* Convert a CORE_ADDR into a string.  */

extern const char *core_addr_to_string (const CORE_ADDR addr);

extern const char *core_addr_to_string_nz (const CORE_ADDR addr);

extern const char *host_address_to_string_1 (const void *addr);

/* Wrapper that avoids adding a pointless cast to all callers.  */
#define host_address_to_string(ADDR) \
  host_address_to_string_1 ((const void *) (ADDR))

/* Return the next entry in the circular print buffer.  */

extern char *get_print_cell (void);

#endif /* GDBSUPPORT_PRINT_UTILS_H */
