Simple -Wshadow=local fixes
[deliverable/binutils-gdb.git] / gdb / cli / cli-utils.c
index f74e6b1f3f4266940a123dd4d879d789a316d9f0..30ee4450f93fcef967bdcb6f107c844dde4f6f29 100644 (file)
@@ -1,6 +1,6 @@
 /* CLI utilities.
 
-   Copyright (C) 2011-2013 Free Software Foundation, Inc.
+   Copyright (C) 2011-2018 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 "gdb_assert.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, or ("$" or "$$") followed by digits.
-
-   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;
+  bool negative = false;
+
+  if (*p == '-')
+    {
+      ++p;
+      negative = true;
+    }
 
   if (*p == '$')
     {
@@ -50,7 +48,7 @@ get_number_trailer (char **pp, int trailer)
            retval = value_as_long (val);
          else
            {
-             printf_filtered (_("History value must have integer type."));
+             printf_filtered (_("History value must have integer type.\n"));
              retval = 0;
            }
        }
@@ -59,16 +57,17 @@ get_number_trailer (char **pp, int trailer)
          /* Internal variable.  Make a copy of the name, so we can
             null-terminate it to pass to lookup_internalvar().  */
          char *varname;
-         char *start = ++p;
-         LONGEST val;
+         const char *start = ++p;
+         LONGEST 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;
+         if (get_internalvar_integer (lookup_internalvar (varname),
+                                      &longest_val))
+           retval = (int) longest_val;
          else
            {
              printf_filtered (_("Convenience variable must "
@@ -79,11 +78,10 @@ get_number_trailer (char **pp, int trailer)
     }
   else
     {
-      if (*p == '-')
-       ++p;
+      const char *p1 = p;
       while (*p >= '0' && *p <= '9')
        ++p;
-      if (p == *pp)
+      if (p == p1)
        /* There is no number here.  (e.g. "cond a == b").  */
        {
          /* Skip non-numeric token.  */
@@ -93,7 +91,7 @@ get_number_trailer (char **pp, int trailer)
          retval = 0;
        }
       else
-       retval = atoi (*pp);
+       retval = atoi (p1);
     }
   if (!(isspace (*p) || *p == '\0' || *p == trailer))
     {
@@ -104,82 +102,144 @@ get_number_trailer (char **pp, int trailer)
     }
   p = skip_spaces (p);
   *pp = p;
-  return retval;
+  return negative ? -retval : retval;
 }
 
 /* See documentation in cli-utils.h.  */
 
 int
-get_number (char **pp)
+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.  */
+
+number_or_range_parser::number_or_range_parser (const char *string)
+{
+  init (string);
+}
+
+/* See documentation in cli-utils.h.  */
+
 void
-init_number_or_range (struct get_number_or_range_state *state,
-                     char *string)
+number_or_range_parser::init (const char *string)
 {
-  memset (state, 0, sizeof (*state));
-  state->string = 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
-get_number_or_range (struct get_number_or_range_state *state)
+number_or_range_parser::get_number ()
 {
-  if (*state->string != '-')
+  if (m_in_range)
     {
-      /* Default case: state->string is pointing either to a solo
+      /* 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.  */
-      state->last_retval = get_number_trailer (&state->string, '-');
-      if (*state->string == '-')
+      m_last_retval = get_number_trailer (&m_cur_tok, '-');
+      /* If get_number_trailer has found a -, it might be the start
+        of a command option.  So, do not parse a range if the - is
+        followed by an alpha.  */
+      if (*m_cur_tok == '-' && !isalpha (*(m_cur_tok + 1)))
        {
-         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 = &state->end_ptr; 
-         state->end_ptr = skip_spaces (state->string + 1);
-         state->end_value = get_number (temp);
-         if (state->end_value < state->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 (state->end_value == state->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.  */ 
-             state->string = state->end_ptr;
+                single number.  */
+             m_cur_tok = m_end_ptr;
            }
          else
-           state->in_range = 1;
+           m_in_range = true;
        }
     }
-  else if (! state->in_range)
-    error (_("negative value"));
   else
     {
-      /* state->string 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 until the end of range
-        is reached.  */
-
-      if (++state->last_retval == state->end_value)
+      if (isdigit (*(m_cur_tok + 1)))
+       error (_("negative value"));
+      if (*(m_cur_tok + 1) == '$')
        {
-         /* End of range reached; advance token pointer.  */
-         state->string = state->end_ptr;
-         state->in_range = 0;
+         /* Convenience variable.  */
+         m_last_retval = ::get_number (&m_cur_tok);
+         if (m_last_retval < 0)
+           error (_("negative value"));
        }
     }
-  state->finished = *state->string == '\0';
-  return state->last_retval;
+  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
+             && !(isdigit (*m_cur_tok) || *m_cur_tok == '$')
+             && !(*m_cur_tok == '-'
+                  && (isdigit (m_cur_tok[1]) || m_cur_tok[1] == '$'))));
 }
 
 /* Accept a number and a string-form list of numbers such as is 
@@ -191,20 +251,21 @@ get_number_or_range (struct get_number_or_range_state *state)
    no arguments.  */
 
 int
-number_is_in_list (char *list, int number)
+number_is_in_list (const char *list, int number)
 {
-  struct get_number_or_range_state state;
-
   if (list == NULL || *list == '\0')
     return 1;
 
-  init_number_or_range (&state, list);
-  while (!state.finished)
+  number_or_range_parser parser (list);
+
+  if (parser.finished ())
+    error (_("Arguments must be numbers or '$' variables."));
+  while (!parser.finished ())
     {
-      int gotnum = get_number_or_range (&state);
+      int gotnum = parser.get_number ();
 
       if (gotnum == 0)
-       error (_("Args must be numbers or '$' variables."));
+       error (_("Arguments must be numbers or '$' variables."));
       if (gotnum == number)
        return 1;
     }
@@ -213,44 +274,8 @@ number_is_in_list (char *list, int number)
 
 /* See documentation in cli-utils.h.  */
 
-char *
-skip_spaces (char *chp)
-{
-  if (chp == NULL)
-    return NULL;
-  while (*chp && isspace (*chp))
-    chp++;
-  return chp;
-}
-
-/* A const-correct version of the above.  */
-
-const char *
-skip_spaces_const (const char *chp)
-{
-  if (chp == NULL)
-    return NULL;
-  while (*chp && isspace (*chp))
-    chp++;
-  return chp;
-}
-
-/* See documentation in cli-utils.h.  */
-
 const char *
-skip_to_space_const (const char *chp)
-{
-  if (chp == NULL)
-    return NULL;
-  while (*chp && !isspace (*chp))
-    chp++;
-  return chp;
-}
-
-/* See documentation in cli-utils.h.  */
-
-char *
-remove_trailing_whitespace (const char *start, char *s)
+remove_trailing_whitespace (const char *start, const char *s)
 {
   while (s > start && isspace (*(s - 1)))
     --s;
@@ -260,37 +285,46 @@ remove_trailing_whitespace (const char *start, char *s)
 
 /* See documentation in cli-utils.h.  */
 
-char *
-extract_arg (char **arg)
+std::string
+extract_arg (const char **arg)
 {
-  char *result, *copy;
+  const char *result;
 
   if (!*arg)
-    return NULL;
+    return std::string ();
 
   /* Find the start of the argument.  */
   *arg = skip_spaces (*arg);
   if (!**arg)
-    return NULL;
+    return std::string ();
   result = *arg;
 
   /* Find the end of the argument.  */
   *arg = skip_to_space (*arg + 1);
 
   if (result == *arg)
-    return NULL;
+    return std::string ();
 
-  copy = xmalloc (*arg - result + 1);
-  memcpy (copy, result, *arg - result);
-  copy[*arg - result] = '\0';
+  return std::string (result, *arg - result);
+}
+
+/* See documentation in cli-utils.h.  */
 
-  return copy;
+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 (char **str, char *arg, int arg_len)
+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])))
@@ -300,3 +334,60 @@ check_for_argument (char **str, char *arg, int arg_len)
     }
   return 0;
 }
+
+/* See documentation in cli-utils.h.  */
+
+int
+parse_flags (const char **str, const char *flags)
+{
+  const char *p = skip_spaces (*str);
+
+  if (p[0] == '-'
+      && isalpha (p[1])
+      && (p[2] == '\0' || isspace (p[2])))
+    {
+      const char pf = p[1];
+      const char *f = flags;
+
+      while (*f != '\0')
+       {
+         if (*f == pf)
+           {
+             *str = skip_spaces (p + 2);
+             return f - flags + 1;
+           }
+         f++;
+       }
+    }
+
+  return 0;
+}
+
+/* See documentation in cli-utils.h.  */
+
+bool
+parse_flags_qcs (const char *which_command, const char **str,
+                qcs_flags *flags)
+{
+  switch (parse_flags (str, "qcs"))
+    {
+    case 0:
+      return false;
+    case 1:
+      flags->quiet = true;
+      break;
+    case 2:
+      flags->cont = true;
+      break;
+    case 3:
+      flags->silent = true;
+      break;
+    default:
+      gdb_assert_not_reached ("int qcs flag out of bound");
+    }
+
+  if (flags->cont && flags->silent)
+    error (_("%s: -c and -s are mutually exclusive"), which_command);
+
+  return true;
+}
This page took 0.031825 seconds and 4 git commands to generate.