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

   Copyright (C) 1986-2021 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/>.  */

#include "common-defs.h"
#include "print-utils.h"
/* Temporary storage using circular buffer.  */

/* Number of cells in the circular buffer.  */
#define NUMCELLS 16

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

char *
get_print_cell (void)
{
  static char buf[NUMCELLS][PRINT_CELL_SIZE];
  static int cell = 0;

  if (++cell >= NUMCELLS)
    cell = 0;
  return buf[cell];
}

static char *
decimal2str (const char *sign, ULONGEST addr, int width)
{
  /* Steal code from valprint.c:print_decimal().  Should this worry
     about the real size of addr as the above does?  */
  unsigned long temp[3];
  char *str = get_print_cell ();
  int i = 0;

  do
    {
      temp[i] = addr % (1000 * 1000 * 1000);
      addr /= (1000 * 1000 * 1000);
      i++;
      width -= 9;
    }
  while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));

  width += 9;
  if (width < 0)
    width = 0;

  switch (i)
    {
    case 1:
      xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu", sign, width, temp[0]);
      break;
    case 2:
      xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu", sign, width,
		 temp[1], temp[0]);
      break;
    case 3:
      xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu%09lu", sign, width,
		 temp[2], temp[1], temp[0]);
      break;
    default:
      internal_error (__FILE__, __LINE__,
		      _("failed internal consistency check"));
    }

  return str;
}

static char *
octal2str (ULONGEST addr, int width)
{
  unsigned long temp[3];
  char *str = get_print_cell ();
  int i = 0;

  do
    {
      temp[i] = addr % (0100000 * 0100000);
      addr /= (0100000 * 0100000);
      i++;
      width -= 10;
    }
  while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));

  width += 10;
  if (width < 0)
    width = 0;

  switch (i)
    {
    case 1:
      if (temp[0] == 0)
	xsnprintf (str, PRINT_CELL_SIZE, "%*o", width, 0);
      else
	xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo", width, temp[0]);
      break;
    case 2:
      xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo", width, temp[1], temp[0]);
      break;
    case 3:
      xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo%010lo", width,
		 temp[2], temp[1], temp[0]);
      break;
    default:
      internal_error (__FILE__, __LINE__,
		      _("failed internal consistency check"));
    }

  return str;
}

/* See print-utils.h.  */

char *
pulongest (ULONGEST u)
{
  return decimal2str ("", u, 0);
}

/* See print-utils.h.  */

char *
plongest (LONGEST l)
{
  if (l < 0)
    return decimal2str ("-", -l, 0);
  else
    return decimal2str ("", l, 0);
}

/* Eliminate warning from compiler on 32-bit systems.  */
static int thirty_two = 32;

/* See print-utils.h.  */

char *
phex (ULONGEST l, int sizeof_l)
{
  char *str;

  switch (sizeof_l)
    {
    case 8:
      str = get_print_cell ();
      xsnprintf (str, PRINT_CELL_SIZE, "%08lx%08lx",
		 (unsigned long) (l >> thirty_two),
		 (unsigned long) (l & 0xffffffff));
      break;
    case 4:
      str = get_print_cell ();
      xsnprintf (str, PRINT_CELL_SIZE, "%08lx", (unsigned long) l);
      break;
    case 2:
      str = get_print_cell ();
      xsnprintf (str, PRINT_CELL_SIZE, "%04x", (unsigned short) (l & 0xffff));
      break;
    default:
      str = phex (l, sizeof (l));
      break;
    }

  return str;
}

/* See print-utils.h.  */

char *
phex_nz (ULONGEST l, int sizeof_l)
{
  char *str;

  switch (sizeof_l)
    {
    case 8:
      {
	unsigned long high = (unsigned long) (l >> thirty_two);

	str = get_print_cell ();
	if (high == 0)
	  xsnprintf (str, PRINT_CELL_SIZE, "%lx",
		     (unsigned long) (l & 0xffffffff));
	else
	  xsnprintf (str, PRINT_CELL_SIZE, "%lx%08lx", high,
		     (unsigned long) (l & 0xffffffff));
	break;
      }
    case 4:
      str = get_print_cell ();
      xsnprintf (str, PRINT_CELL_SIZE, "%lx", (unsigned long) l);
      break;
    case 2:
      str = get_print_cell ();
      xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xffff));
      break;
    default:
      str = phex_nz (l, sizeof (l));
      break;
    }

  return str;
}

/* See print-utils.h.  */

char *
hex_string (LONGEST num)
{
  char *result = get_print_cell ();

  xsnprintf (result, PRINT_CELL_SIZE, "0x%s", phex_nz (num, sizeof (num)));
  return result;
}

/* See print-utils.h.  */

char *
hex_string_custom (LONGEST num, int width)
{
  char *result = get_print_cell ();
  char *result_end = result + PRINT_CELL_SIZE - 1;
  const char *hex = phex_nz (num, sizeof (num));
  int hex_len = strlen (hex);

  if (hex_len > width)
    width = hex_len;
  if (width + 2 >= PRINT_CELL_SIZE)
    internal_error (__FILE__, __LINE__, _("\
hex_string_custom: insufficient space to store result"));

  strcpy (result_end - width - 2, "0x");
  memset (result_end - width, '0', width);
  strcpy (result_end - hex_len, hex);
  return result_end - width - 2;
}

/* See print-utils.h.  */

char *
int_string (LONGEST val, int radix, int is_signed, int width,
	    int use_c_format)
{
  switch (radix)
    {
    case 16:
      {
	char *result;

	if (width == 0)
	  result = hex_string (val);
	else
	  result = hex_string_custom (val, width);
	if (! use_c_format)
	  result += 2;
	return result;
      }
    case 10:
      {
	if (is_signed && val < 0)
	  return decimal2str ("-", -val, width);
	else
	  return decimal2str ("", val, width);
      }
    case 8:
      {
	char *result = octal2str (val, width);

	if (use_c_format || val == 0)
	  return result;
	else
	  return result + 1;
      }
    default:
      internal_error (__FILE__, __LINE__,
		      _("failed internal consistency check"));
    }
}

/* See print-utils.h.  */

const char *
core_addr_to_string (const CORE_ADDR addr)
{
  char *str = get_print_cell ();

  strcpy (str, "0x");
  strcat (str, phex (addr, sizeof (addr)));
  return str;
}

/* See print-utils.h.  */

const char *
core_addr_to_string_nz (const CORE_ADDR addr)
{
  char *str = get_print_cell ();

  strcpy (str, "0x");
  strcat (str, phex_nz (addr, sizeof (addr)));
  return str;
}

/* See print-utils.h.  */

const char *
host_address_to_string_1 (const void *addr)
{
  char *str = get_print_cell ();

  xsnprintf (str, PRINT_CELL_SIZE, "0x%s",
	     phex_nz ((uintptr_t) addr, sizeof (addr)));
  return str;
}
