/* CLI utilities.

   Copyright (C) 2011-2025 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 "cli/cli-utils.h"
#include "value.h"


/* See documentation in cli-utils.h.  */

ULONGEST
get_ulongest (const char **pp, int trailer)
{
  LONGEST retval = 0;	/* default */
  const char *p = *pp;

  if (*p == '$')
    {
      value *val = value_from_history_ref (p, &p);

      if (val != NULL)	/* Value history reference */
	{
	  if (val->type ()->code () == TYPE_CODE_INT)
	    retval = value_as_long (val);
	  else
	    error (_("History value must have integer type."));
	}
      else	/* Convenience variable */
	{
	  /* Internal variable.  Make a copy of the name, so we can
	     null-terminate it to pass to lookup_internalvar().  */
	  const char *start = ++p;
	  while (c_isalnum (*p) || *p == '_')
	    p++;
	  std::string varname (start, p - start);
	  if (!get_internalvar_integer (lookup_internalvar (varname.c_str ()),
				       &retval))
	    error (_("Convenience variable $%s does not have integer value."),
		   varname.c_str ());
	}
    }
  else
    {
      const char *end = p;
      retval = strtoulst (p, &end, 0);
      if (p == end)
	{
	  /* There is no number here.  (e.g. "cond a == b").  */
	  error (_("Expected integer at: %s"), p);
	}
      p = end;
    }

  if (!(c_isspace (*p) || *p == '\0' || *p == trailer))
    error (_("Trailing junk at: %s"), p);
  p = skip_spaces (p);
  *pp = p;
  return retval;
}

/* See documentation in cli-utils.h.  */

int
get_number_trailer (const char **pp, int trailer)
{
  int retval = 0;	/* default */
  const char *p = *pp;
  bool negative = false;

  if (*p == '-')
    {
      ++p;
      negative = true;
    }

  if (*p == '$')
    {
      struct value *val = value_from_history_ref (p, &p);

      if (val)	/* Value history reference */
	{
	  if (val->type ()->code () == TYPE_CODE_INT)
	    retval = value_as_long (val);
	  else
	    {
	      gdb_printf (_("History value must have integer type.\n"));
	      retval = 0;
	    }
	}
      else	/* Convenience variable */
	{
	  /* Internal variable.  Make a copy of the name, so we can
	     null-terminate it to pass to lookup_internalvar().  */
	  char *varname;
	  const char *start = ++p;
	  LONGEST longest_val;

	  while (c_isalnum (*p) || *p == '_')
	    p++;
	  varname = (char *) alloca (p - start + 1);
	  strncpy (varname, start, p - start);
	  varname[p - start] = '\0';
	  if (get_internalvar_integer (lookup_internalvar (varname),
				       &longest_val))
	    retval = (int) longest_val;
	  else
	    {
	      gdb_printf (_("Convenience variable must "
			    "have integer value.\n"));
	      retval = 0;
	    }
	}
    }
  else
    {
      const char *p1 = p;
      while (*p >= '0' && *p <= '9')
	++p;
      if (p == p1)
	/* There is no number here.  (e.g. "cond a == b").  */
	{
	  /* Skip non-numeric token.  */
	  while (*p && !c_isspace((int) *p))
	    ++p;
	  /* Return zero, which caller must interpret as error.  */
	  retval = 0;
	}
      else
	retval = atoi (p1);
    }
  if (!(c_isspace (*p) || *p == '\0' || *p == trailer))
    {
      /* Trailing junk: return 0 and let caller print error msg.  */
      while (!(c_isspace (*p) || *p == '\0' || *p == trailer))
	++p;
      retval = 0;
    }
  p = skip_spaces (p);
  *pp = p;
  return negative ? -retval : retval;
}

/* See documentation in cli-utils.h.  */

int
get_number (const char **pp)
{
  return get_number_trailer (pp, '\0');
}

/* See documentation in cli-utils.h.  */

int
get_number (char **pp)
{
  int result;
  const char *p = *pp;

  result = get_number_trailer (&p, '\0');
  *pp = (char *) p;
  return result;
}

/* See documentation in cli-utils.h.  */

void
report_unrecognized_option_error (const char *command, const char *args)
{
  std::string option = extract_arg (&args);

  error (_("Unrecognized option '%s' to %s command.  "
	   "Try \"help %s\"."), option.c_str (),
	 command, command);
}

/* See documentation in cli-utils.h.  */

const char *
info_print_args_help (const char *prefix,
		      const char *entity_kind,
		      bool document_n_flag)
{
  return xstrprintf (_("\
%sIf NAMEREGEXP is provided, only prints the %s\n\
whose name matches NAMEREGEXP.\n\
If -t TYPEREGEXP is provided, only prints the %s\n\
whose type matches TYPEREGEXP.  Note that the matching is done with the type\n\
printed by the 'whatis' command.\n\
By default, the command might produce headers and/or messages indicating\n\
why no %s can be printed.\n\
The flag -q disables the production of these headers and messages.%s"),
		     prefix, entity_kind, entity_kind, entity_kind,
		     (document_n_flag ? _("\n\
By default, the command will include non-debug symbols in the output;\n\
these can be excluded using the -n flag.") : "")).release ();
}

/* See documentation in cli-utils.h.  */

number_or_range_parser::number_or_range_parser (const char *string)
{
  init (string);
}

/* See documentation in cli-utils.h.  */

void
number_or_range_parser::init (const char *string)
{
  m_cur_tok = string;
  m_last_retval = 0;
  m_end_value = 0;
  m_end_ptr = NULL;
  m_in_range = false;
}

/* See documentation in cli-utils.h.  */

int
number_or_range_parser::get_number ()
{
  if (m_in_range)
    {
      /* All number-parsing has already been done.  Return the next
	 integer value (one greater than the saved previous value).
	 Do not advance the token pointer until the end of range is
	 reached.  */

      if (++m_last_retval == m_end_value)
	{
	  /* End of range reached; advance token pointer.  */
	  m_cur_tok = m_end_ptr;
	  m_in_range = false;
	}
    }
  else if (*m_cur_tok != '-')
    {
      /* Default case: state->m_cur_tok is pointing either to a solo
	 number, or to the first number of a range.  */
      m_last_retval = get_number_trailer (&m_cur_tok, '-');
      /* If get_number_trailer has found a '-' preceded by a space, it
	 might be the start of a command option.  So, do not parse a
	 range if the '-' is followed by an alpha or another '-'.  We
	 might also be completing something like
	 "frame apply level 0 -" and we prefer treating that "-" as an
	 option rather than an incomplete range, so check for end of
	 string as well.  */
      if (m_cur_tok[0] == '-'
	  && !(c_isspace (m_cur_tok[-1])
	       && (c_isalpha (m_cur_tok[1])
		   || m_cur_tok[1] == '-'
		   || m_cur_tok[1] == '\0')))
	{
	  const char **temp;

	  /* This is the start of a range (<number1> - <number2>).
	     Skip the '-', parse and remember the second number,
	     and also remember the end of the final token.  */

	  temp = &m_end_ptr;
	  m_end_ptr = skip_spaces (m_cur_tok + 1);
	  m_end_value = ::get_number (temp);
	  if (m_end_value < m_last_retval)
	    {
	      error (_("inverted range"));
	    }
	  else if (m_end_value == m_last_retval)
	    {
	      /* Degenerate range (number1 == number2).  Advance the
		 token pointer so that the range will be treated as a
		 single number.  */
	      m_cur_tok = m_end_ptr;
	    }
	  else
	    m_in_range = true;
	}
    }
  else
    {
      if (c_isdigit (*(m_cur_tok + 1)))
	error (_("negative value"));
      if (*(m_cur_tok + 1) == '$')
	{
	  /* Convenience variable.  */
	  m_last_retval = ::get_number (&m_cur_tok);
	  if (m_last_retval < 0)
	    error (_("negative value"));
	}
    }
  return m_last_retval;
}

/* See documentation in cli-utils.h.  */

void
number_or_range_parser::setup_range (int start_value, int end_value,
				     const char *end_ptr)
{
  gdb_assert (start_value > 0);

  m_in_range = true;
  m_end_ptr = end_ptr;
  m_last_retval = start_value - 1;
  m_end_value = end_value;
}

/* See documentation in cli-utils.h.  */

bool
number_or_range_parser::finished () const
{
  /* Parsing is finished when at end of string or null string,
     or we are not in a range and not in front of an integer, negative
     integer, convenience var or negative convenience var.  */
  return (m_cur_tok == NULL || *m_cur_tok == '\0'
	  || (!m_in_range
	      && !(c_isdigit (*m_cur_tok) || *m_cur_tok == '$')
	      && !(*m_cur_tok == '-'
		   && (c_isdigit (m_cur_tok[1]) || m_cur_tok[1] == '$'))));
}

/* Accept a number and a string-form list of numbers such as is 
   accepted by get_number_or_range.  Return TRUE if the number is
   in the list.

   By definition, an empty list includes all numbers.  This is to 
   be interpreted as typing a command such as "delete break" with 
   no arguments.  */

int
number_is_in_list (const char *list, int number)
{
  if (list == NULL || *list == '\0')
    return 1;

  number_or_range_parser parser (list);

  if (parser.finished ())
    error (_("Arguments must be numbers or '$' variables."));
  while (!parser.finished ())
    {
      int gotnum = parser.get_number ();

      if (gotnum == 0)
	error (_("Arguments must be numbers or '$' variables."));
      if (gotnum == number)
	return 1;
    }
  return 0;
}

/* See documentation in cli-utils.h.  */

const char *
remove_trailing_whitespace (const char *start, const char *s)
{
  while (s > start && c_isspace (*(s - 1)))
    --s;

  return s;
}

/* See documentation in cli-utils.h.  */

std::string
extract_arg (const char **arg)
{
  const char *result;

  if (!*arg)
    return std::string ();

  /* Find the start of the argument.  */
  *arg = skip_spaces (*arg);
  if (!**arg)
    return std::string ();
  result = *arg;

  /* Find the end of the argument.  */
  *arg = skip_to_space (*arg + 1);

  if (result == *arg)
    return std::string ();

  return std::string (result, *arg - result);
}

/* See documentation in cli-utils.h.  */

std::string
extract_arg (char **arg)
{
  const char *arg_const = *arg;
  std::string result;

  result = extract_arg (&arg_const);
  *arg += arg_const - *arg;
  return result;
}

/* See documentation in cli-utils.h.  */

int
check_for_argument (const char **str, const char *arg, int arg_len)
{
  if (strncmp (*str, arg, arg_len) == 0
      && ((*str)[arg_len] == '\0' || c_isspace ((*str)[arg_len])))
    {
      *str += arg_len;
      *str = skip_spaces (*str);
      return 1;
    }
  return 0;
}

/* See documentation in cli-utils.h.  */

void
validate_flags_qcs (const char *which_command, qcs_flags *flags)
{
  if (flags->cont && flags->silent)
    error (_("%s: -c and -s are mutually exclusive"), which_command);
}

