Rename _const functions to use overloading instead
[binutils-gdb.git] / gdb / cli / cli-utils.c
index 34c368be9c58fe9c7a0a104d5e2dee0327e5351b..a00bc52daca198b5c014445ef527f2971d0996db 100644 (file)
@@ -1,6 +1,6 @@
 /* CLI utilities.
 
-   Copyright (c) 2011 Free Software Foundation, Inc.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
 #include "defs.h"
 #include "cli/cli-utils.h"
-#include "gdb_string.h"
 #include "value.h"
 
 #include <ctype.h>
 
-/* *PP is a string denoting a number.  Get the number of the.  Advance
-   *PP after the string and any trailing whitespace.
-
-   Currently the string can either be a number or "$" followed by the
-   name of a convenience variable.
-
-   TRAILER is a character which can be found after the number; most
-   commonly this is `-'.  If you don't want a trailer, use \0.  */
+/* See documentation in cli-utils.h.  */
 
-static int
-get_number_trailer (char **pp, int trailer)
+int
+get_number_trailer (const char **pp, int trailer)
 {
   int retval = 0;      /* default */
-  char *p = *pp;
+  const char *p = *pp;
 
   if (*p == '$')
     {
-      /* Make a copy of the name, so we can null-terminate it
-         to pass to lookup_internalvar().  */
-      char *varname;
-      char *start = ++p;
-      LONGEST val;
-
-      while (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), &val))
-       retval = (int) val;
-      else
+      struct value *val = value_from_history_ref (p, &p);
+
+      if (val) /* Value history reference */
        {
-         printf_filtered (_("Convenience variable must "
-                            "have integer value.\n"));
-         retval = 0;
+         if (TYPE_CODE (value_type (val)) == TYPE_CODE_INT)
+           retval = value_as_long (val);
+         else
+           {
+             printf_filtered (_("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 val;
+
+         while (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), &val))
+           retval = (int) val;
+         else
+           {
+             printf_filtered (_("Convenience variable must "
+                                "have integer value.\n"));
+             retval = 0;
+           }
        }
     }
   else
@@ -94,7 +101,7 @@ get_number_trailer (char **pp, int trailer)
 /* See documentation in cli-utils.h.  */
 
 int
-get_number (char **pp)
+get_number (const char **pp)
 {
   return get_number_trailer (pp, '\0');
 }
@@ -102,63 +109,104 @@ get_number (char **pp)
 /* See documentation in cli-utils.h.  */
 
 int
-get_number_or_range (char **pp)
+get_number (char **pp)
 {
-  static int last_retval, end_value;
-  static char *end_ptr;
-  static int in_range = 0;
+  int result;
+  const char *p = *pp;
+
+  result = get_number_trailer (&p, '\0');
+  *pp = (char *) p;
+  return result;
+}
 
-  if (**pp != '-')
+/* 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_finished = false;
+  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: pp is pointing either to a solo number, 
-        or to the first number of a range.  */
-      last_retval = get_number_trailer (pp, '-');
-      if (**pp == '-')
+      /* 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 (*m_cur_tok == '-')
        {
-         char **temp;
+         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 = &end_ptr; 
-         end_ptr = *pp + 1; 
-         while (isspace ((int) *end_ptr))
-           end_ptr++;  /* skip white space */
-         end_value = get_number (temp);
-         if (end_value < last_retval) 
+         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 (end_value == last_retval)
+         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.  */ 
-             *pp = end_ptr;
+                single number.  */
+             m_cur_tok = m_end_ptr;
            }
          else
-           in_range = 1;
+           m_in_range = true;
        }
     }
-  else if (! in_range)
-    error (_("negative value"));
   else
-    {
-      /* pp points to the '-' that betokens a 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 'pp' until the end of range
-        is reached.  */
+    error (_("negative value"));
+  m_finished = *m_cur_tok == '\0';
+  return m_last_retval;
+}
 
-      if (++last_retval == end_value)
-       {
-         /* End of range reached; advance token pointer.  */
-         *pp = end_ptr;
-         in_range = 0;
-       }
-    }
-  return 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;
 }
 
 /* Accept a number and a string-form list of numbers such as is 
@@ -170,14 +218,15 @@ get_number_or_range (char **pp)
    no arguments.  */
 
 int
-number_is_in_list (char *list, int number)
+number_is_in_list (const char *list, int number)
 {
   if (list == NULL || *list == '\0')
     return 1;
 
-  while (*list != '\0')
+  number_or_range_parser parser (list);
+  while (!parser.finished ())
     {
-      int gotnum = get_number_or_range (&list);
+      int gotnum = parser.get_number ();
 
       if (gotnum == 0)
        error (_("Args must be numbers or '$' variables."));
@@ -189,24 +238,63 @@ number_is_in_list (char *list, int number)
 
 /* See documentation in cli-utils.h.  */
 
+const char *
+remove_trailing_whitespace (const char *start, const char *s)
+{
+  while (s > start && isspace (*(s - 1)))
+    --s;
+
+  return s;
+}
+
+/* See documentation in cli-utils.h.  */
+
 char *
-skip_spaces (char *chp)
+extract_arg (const char **arg)
 {
-  if (chp == NULL)
+  const char *result;
+
+  if (!*arg)
+    return NULL;
+
+  /* Find the start of the argument.  */
+  *arg = skip_spaces (*arg);
+  if (!**arg)
+    return NULL;
+  result = *arg;
+
+  /* Find the end of the argument.  */
+  *arg = skip_to_space (*arg + 1);
+
+  if (result == *arg)
     return NULL;
-  while (*chp && isspace (*chp))
-    chp++;
-  return chp;
+
+  return savestring (result, *arg - result);
 }
 
 /* See documentation in cli-utils.h.  */
 
 char *
-skip_to_space (char *chp)
+extract_arg (char **arg)
 {
-  if (chp == NULL)
-    return NULL;
-  while (*chp && !isspace (*chp))
-    chp++;
-  return chp;
+  const char *arg_const = *arg;
+  char *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' || isspace ((*str)[arg_len])))
+    {
+      *str += arg_len;
+      return 1;
+    }
+  return 0;
 }