Change section_offsets to a std::vector
[deliverable/binutils-gdb.git] / gdb / cli / cli-utils.c
index 0fb68f2e1fe2996781544ee39e4542344e792b20..7d152a90f897b39891dad22ed81c8c603cddf116 100644 (file)
@@ -1,6 +1,6 @@
 /* CLI utilities.
 
-   Copyright (C) 2011-2016 Free Software Foundation, Inc.
+   Copyright (C) 2011-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
 /* 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 (TYPE_CODE (value_type (val)) == 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 (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 (!(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 == '$')
     {
@@ -51,15 +110,16 @@ get_number_trailer (const char **pp, int trailer)
             null-terminate it to pass to lookup_internalvar().  */
          char *varname;
          const char *start = ++p;
-         LONGEST val;
+         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 "
@@ -70,11 +130,10 @@ get_number_trailer (const 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.  */
@@ -84,7 +143,7 @@ get_number_trailer (const char **pp, int trailer)
          retval = 0;
        }
       else
-       retval = atoi (*pp);
+       retval = atoi (p1);
     }
   if (!(isspace (*p) || *p == '\0' || *p == trailer))
     {
@@ -93,15 +152,15 @@ get_number_trailer (const char **pp, int trailer)
        ++p;
       retval = 0;
     }
-  p = skip_spaces_const (p);
+  p = skip_spaces (p);
   *pp = p;
-  return retval;
+  return negative ? -retval : retval;
 }
 
 /* See documentation in cli-utils.h.  */
 
 int
-get_number_const (const char **pp)
+get_number (const char **pp)
 {
   return get_number_trailer (pp, '\0');
 }
@@ -121,6 +180,40 @@ get_number (char **pp)
 
 /* 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 whose name\n\
+matches NAMEREGEXP.\n\
+If -t TYPEREGEXP is provided, only prints the %s whose type\n\
+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.") : ""));
+}
+
+/* See documentation in cli-utils.h.  */
+
 number_or_range_parser::number_or_range_parser (const char *string)
 {
   init (string);
@@ -131,7 +224,6 @@ number_or_range_parser::number_or_range_parser (const char *string)
 void
 number_or_range_parser::init (const char *string)
 {
-  m_finished = false;
   m_cur_tok = string;
   m_last_retval = 0;
   m_end_value = 0;
@@ -163,7 +255,18 @@ number_or_range_parser::get_number ()
       /* 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 == '-')
+      /* 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] == '-'
+         && !(isspace (m_cur_tok[-1])
+              && (isalpha (m_cur_tok[1])
+                  || m_cur_tok[1] == '-'
+                  || m_cur_tok[1] == '\0')))
        {
          const char **temp;
 
@@ -172,8 +275,8 @@ number_or_range_parser::get_number ()
             and also remember the end of the final token.  */
 
          temp = &m_end_ptr;
-         m_end_ptr = skip_spaces_const (m_cur_tok + 1);
-         m_end_value = get_number_const (temp);
+         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"));
@@ -190,8 +293,17 @@ number_or_range_parser::get_number ()
        }
     }
   else
-    error (_("negative value"));
-  m_finished = *m_cur_tok == '\0';
+    {
+      if (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;
 }
 
@@ -209,6 +321,21 @@ number_or_range_parser::setup_range (int start_value, int end_value,
   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 
    accepted by get_number_or_range.  Return TRUE if the number is
    in the list.
@@ -224,12 +351,15 @@ number_is_in_list (const char *list, int number)
     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 (_("Args must be numbers or '$' variables."));
+       error (_("Arguments must be numbers or '$' variables."));
       if (gotnum == number)
        return 1;
     }
@@ -238,8 +368,8 @@ number_is_in_list (const char *list, int number)
 
 /* See documentation in cli-utils.h.  */
 
-char *
-remove_trailing_whitespace (const char *start, char *s)
+const char *
+remove_trailing_whitespace (const char *start, const char *s)
 {
   while (s > start && isspace (*(s - 1)))
     --s;
@@ -249,38 +379,38 @@ remove_trailing_whitespace (const char *start, char *s)
 
 /* See documentation in cli-utils.h.  */
 
-char *
-extract_arg_const (const char **arg)
+std::string
+extract_arg (const char **arg)
 {
   const char *result;
 
   if (!*arg)
-    return NULL;
+    return std::string ();
 
   /* Find the start of the argument.  */
-  *arg = skip_spaces_const (*arg);
+  *arg = skip_spaces (*arg);
   if (!**arg)
-    return NULL;
+    return std::string ();
   result = *arg;
 
   /* Find the end of the argument.  */
-  *arg = skip_to_space_const (*arg + 1);
+  *arg = skip_to_space (*arg + 1);
 
   if (result == *arg)
-    return NULL;
+    return std::string ();
 
-  return savestring (result, *arg - result);
+  return std::string (result, *arg - result);
 }
 
 /* See documentation in cli-utils.h.  */
 
-char *
+std::string
 extract_arg (char **arg)
 {
   const char *arg_const = *arg;
-  char *result;
+  std::string result;
 
-  result = extract_arg_const (&arg_const);
+  result = extract_arg (&arg_const);
   *arg += arg_const - *arg;
   return result;
 }
@@ -288,13 +418,24 @@ extract_arg (char **arg)
 /* 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])))
     {
       *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);
+}
+
This page took 0.032502 seconds and 4 git commands to generate.