Move command lines types/declarations to cli-script.h
[deliverable/binutils-gdb.git] / gdb / cli / cli-cmds.c
index d4dc53904cdcb7d385da9382bdb1ef549afa9c04..7d7e16a64a8fe7a214ae088615e7e8a390fb1031 100644 (file)
@@ -90,9 +90,11 @@ static void list_command (char *, int);
 
 /* Prototypes for local utility functions */
 
-static void ambiguous_line_spec (struct symtabs_and_lines *);
+static void ambiguous_line_spec (gdb::array_view<const symtab_and_line> sals,
+                                const char *format, ...)
+  ATTRIBUTE_PRINTF (2, 3);
 
-static void filter_sals (struct symtabs_and_lines *);
+static void filter_sals (std::vector<symtab_and_line> &);
 
 \f
 /* Limit the call depth of user-defined commands */
@@ -398,14 +400,14 @@ cd_command (char *dir, int from_tty)
   /* Found something other than leading repetitions of "/..".  */
   int found_real_path;
   char *p;
-  struct cleanup *cleanup;
 
   /* If the new directory is absolute, repeat is a no-op; if relative,
      repeat might be useful but is more likely to be a mistake.  */
   dont_repeat ();
 
-  dir = tilde_expand (dir != NULL ? dir : "~");
-  cleanup = make_cleanup (xfree, dir);
+  gdb::unique_xmalloc_ptr<char> dir_holder
+    (tilde_expand (dir != NULL ? dir : "~"));
+  dir = dir_holder.get ();
 
   if (chdir (dir) < 0)
     perror_with_name (dir);
@@ -430,17 +432,17 @@ cd_command (char *dir, int from_tty)
        len--;
     }
 
-  dir = savestring (dir, len);
-  if (IS_ABSOLUTE_PATH (dir))
-    current_directory = dir;
+  dir_holder.reset (savestring (dir, len));
+  if (IS_ABSOLUTE_PATH (dir_holder.get ()))
+    current_directory = dir_holder.release ();
   else
     {
       if (IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]))
-       current_directory = concat (current_directory, dir, (char *)NULL);
+       current_directory = concat (current_directory, dir_holder.get (),
+                                   (char *) NULL);
       else
        current_directory = concat (current_directory, SLASH_STRING,
-                                   dir, (char *)NULL);
-      xfree (dir);
+                                   dir_holder.get (), (char *) NULL);
     }
 
   /* Now simplify any occurrences of `.' and `..' in the pathname.  */
@@ -489,8 +491,6 @@ cd_command (char *dir, int from_tty)
 
   if (from_tty)
     pwd_command ((char *) 0, 1);
-
-  do_cleanups (cleanup);
 }
 \f
 /* Show the current value of the 'script-extension' option.  */
@@ -786,7 +786,6 @@ shell_command (char *arg, int from_tty)
 static void
 edit_command (char *arg, int from_tty)
 {
-  struct symtabs_and_lines sals;
   struct symtab_and_line sal;
   struct symbol *sym;
   const char *editor;
@@ -816,24 +815,24 @@ edit_command (char *arg, int from_tty)
       arg1 = arg;
       event_location_up location = string_to_event_location (&arg1,
                                                             current_language);
-      sals = decode_line_1 (location.get (), DECODE_LINE_LIST_MODE,
-                           NULL, NULL, 0);
+      std::vector<symtab_and_line> sals = decode_line_1 (location.get (),
+                                                        DECODE_LINE_LIST_MODE,
+                                                        NULL, NULL, 0);
 
-      filter_sals (&sals);
-      if (! sals.nelts)
+      filter_sals (sals);
+      if (sals.empty ())
        {
          /*  C++  */
          return;
        }
-      if (sals.nelts > 1)
+      if (sals.size () > 1)
        {
-         ambiguous_line_spec (&sals);
-         xfree (sals.sals);
+         ambiguous_line_spec (sals,
+                              _("Specified line is ambiguous:\n"));
          return;
        }
 
-      sal = sals.sals[0];
-      xfree (sals.sals);
+      sal = sals[0];
 
       if (*arg1)
         error (_("Junk at end of line specification."));
@@ -887,10 +886,6 @@ edit_command (char *arg, int from_tty)
 static void
 list_command (char *arg, int from_tty)
 {
-  struct symtabs_and_lines sals, sals_end;
-  struct symtab_and_line sal = { 0 };
-  struct symtab_and_line sal_end = { 0 };
-  struct symtab_and_line cursal = { 0 };
   struct symbol *sym;
   char *arg1;
   int no_end = 1;
@@ -903,7 +898,7 @@ list_command (char *arg, int from_tty)
   if (arg == NULL || ((arg[0] == '+' || arg[0] == '-') && arg[1] == '\0'))
     {
       set_default_source_symtab_and_line ();
-      cursal = get_current_source_symtab_and_line ();
+      symtab_and_line cursal = get_current_source_symtab_and_line ();
 
       /* If this is the first "list" since we've set the current
         source line, center the listing around that line.  */
@@ -955,8 +950,9 @@ list_command (char *arg, int from_tty)
   if (!have_full_symbols () && !have_partial_symbols ())
     error (_("No symbol table is loaded.  Use the \"file\" command."));
 
-  sals.nelts = 0;
-  sals.sals = NULL;
+  std::vector<symtab_and_line> sals;
+  symtab_and_line sal, sal_end;
+
   arg1 = arg;
   if (*arg1 == ',')
     dummy_beg = 1;
@@ -966,15 +962,14 @@ list_command (char *arg, int from_tty)
                                                             current_language);
       sals = decode_line_1 (location.get (), DECODE_LINE_LIST_MODE,
                            NULL, NULL, 0);
-
-      filter_sals (&sals);
-      if (!sals.nelts)
+      filter_sals (sals);
+      if (sals.empty ())
        {
          /*  C++  */
          return;
        }
 
-      sal = sals.sals[0];
+      sal = sals[0];
     }
 
   /* Record whether the BEG arg is all digits.  */
@@ -982,15 +977,21 @@ list_command (char *arg, int from_tty)
   for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
   linenum_beg = (p == arg1);
 
+  /* Save the range of the first argument, in case we need to let the
+     user know it was ambiguous.  */
+  const char *beg = arg;
+  size_t beg_len = arg1 - beg;
+
   while (*arg1 == ' ' || *arg1 == '\t')
     arg1++;
   if (*arg1 == ',')
     {
       no_end = 0;
-      if (sals.nelts > 1)
+      if (sals.size () > 1)
        {
-         ambiguous_line_spec (&sals);
-         xfree (sals.sals);
+         ambiguous_line_spec (sals,
+                              _("Specified first line '%.*s' is ambiguous:\n"),
+                              (int) beg_len, beg);
          return;
        }
       arg1++;
@@ -1000,30 +1001,31 @@ list_command (char *arg, int from_tty)
        dummy_end = 1;
       else
        {
+         /* Save the last argument, in case we need to let the user
+            know it was ambiguous.  */
+         const char *end_arg = arg1;
+
          event_location_up location
            = string_to_event_location (&arg1, current_language);
-         if (dummy_beg)
-           sals_end = decode_line_1 (location.get (),
-                                     DECODE_LINE_LIST_MODE, NULL, NULL, 0);
-         else
-           sals_end = decode_line_1 (location.get (), DECODE_LINE_LIST_MODE,
-                                     NULL, sal.symtab, sal.line);
 
-         filter_sals (&sals_end);
-         if (sals_end.nelts == 0)
-           {
-             xfree (sals.sals);
-             return;
-           }
-         if (sals_end.nelts > 1)
+         std::vector<symtab_and_line> sals_end
+           = (dummy_beg
+              ? decode_line_1 (location.get (), DECODE_LINE_LIST_MODE,
+                               NULL, NULL, 0)
+              : decode_line_1 (location.get (), DECODE_LINE_LIST_MODE,
+                               NULL, sal.symtab, sal.line));
+
+         filter_sals (sals_end);
+         if (sals_end.empty ())
+           return;
+         if (sals_end.size () > 1)
            {
-             ambiguous_line_spec (&sals_end);
-             xfree (sals_end.sals);
-             xfree (sals.sals);
+             ambiguous_line_spec (sals_end,
+                                  _("Specified last line '%s' is ambiguous:\n"),
+                                  end_arg);
              return;
            }
-         sal_end = sals_end.sals[0];
-         xfree (sals_end.sals);
+         sal_end = sals_end[0];
        }
     }
 
@@ -1032,7 +1034,7 @@ list_command (char *arg, int from_tty)
 
   if (!no_end && !dummy_beg && !dummy_end
       && sal.symtab != sal_end.symtab)
-    error (_("Specified start and end are in different files."));
+    error (_("Specified first and last lines are in different files."));
   if (dummy_beg && dummy_end)
     error (_("Two empty args do not say what lines to list."));
 
@@ -1085,13 +1087,13 @@ list_command (char *arg, int from_tty)
     error (_("No default source file yet.  Do \"help list\"."));
   else if (no_end)
     {
-      for (int i = 0; i < sals.nelts; i++)
+      for (int i = 0; i < sals.size (); i++)
        {
-         sal = sals.sals[i];
+         sal = sals[i];
          int first_line = sal.line - get_lines_to_list () / 2;
          if (first_line < 1)
            first_line = 1;
-         if (sals.nelts > 1)
+         if (sals.size () > 1)
            {
              printf_filtered (_("file: \"%s\", line number: %d\n"),
                               symtab_to_filename_for_display (sal.symtab),
@@ -1109,7 +1111,6 @@ list_command (char *arg, int from_tty)
                         ? sal.line + get_lines_to_list ()
                         : sal_end.line + 1),
                        0);
-  xfree (sals.sals);
 }
 
 /* Subroutine of disassemble_command to simplify it.
@@ -1516,29 +1517,34 @@ alias_command (char *args, int from_tty)
 \f
 /* Print a list of files and line numbers which a user may choose from
    in order to list a function which was specified ambiguously (as
-   with `list classname::overloadedfuncname', for example).  The
-   vector in SALS provides the filenames and line numbers.  */
+   with `list classname::overloadedfuncname', for example).  The SALS
+   array provides the filenames and line numbers.  FORMAT is a
+   printf-style format string used to tell the user what was
+   ambiguous.  */
 
 static void
-ambiguous_line_spec (struct symtabs_and_lines *sals)
+ambiguous_line_spec (gdb::array_view<const symtab_and_line> sals,
+                    const char *format, ...)
 {
-  int i;
+  va_list ap;
+  va_start (ap, format);
+  vprintf_filtered (format, ap);
+  va_end (ap);
 
-  for (i = 0; i < sals->nelts; ++i)
+  for (const auto &sal : sals)
     printf_filtered (_("file: \"%s\", line number: %d\n"),
-                    symtab_to_filename_for_display (sals->sals[i].symtab),
-                    sals->sals[i].line);
+                    symtab_to_filename_for_display (sal.symtab),
+                    sal.line);
 }
 
-/* Sort function for filter_sals.  */
+/* Comparison function for filter_sals.  Returns a qsort-style
+   result.  */
 
 static int
-compare_symtabs (const void *a, const void *b)
+cmp_symtabs (const symtab_and_line &sala, const symtab_and_line &salb)
 {
-  const struct symtab_and_line *sala = (const struct symtab_and_line *) a;
-  const struct symtab_and_line *salb = (const struct symtab_and_line *) b;
-  const char *dira = SYMTAB_DIRNAME (sala->symtab);
-  const char *dirb = SYMTAB_DIRNAME (salb->symtab);
+  const char *dira = SYMTAB_DIRNAME (sala.symtab);
+  const char *dirb = SYMTAB_DIRNAME (salb.symtab);
   int r;
 
   if (dira == NULL)
@@ -1558,58 +1564,37 @@ compare_symtabs (const void *a, const void *b)
        return r;
     }
 
-  r = filename_cmp (sala->symtab->filename, salb->symtab->filename);
+  r = filename_cmp (sala.symtab->filename, salb.symtab->filename);
   if (r)
     return r;
 
-  if (sala->line < salb->line)
+  if (sala.line < salb.line)
     return -1;
-  return sala->line == salb->line ? 0 : 1;
+  return sala.line == salb.line ? 0 : 1;
 }
 
 /* Remove any SALs that do not match the current program space, or
    which appear to be "file:line" duplicates.  */
 
 static void
-filter_sals (struct symtabs_and_lines *sals)
+filter_sals (std::vector<symtab_and_line> &sals)
 {
-  int i, out, prev;
-
-  out = 0;
-  for (i = 0; i < sals->nelts; ++i)
-    {
-      if (sals->sals[i].pspace == current_program_space
-         && sals->sals[i].symtab != NULL)
-       {
-         sals->sals[out] = sals->sals[i];
-         ++out;
-       }
-    }
-  sals->nelts = out;
-
-  qsort (sals->sals, sals->nelts, sizeof (struct symtab_and_line),
-        compare_symtabs);
-
-  out = 1;
-  prev = 0;
-  for (i = 1; i < sals->nelts; ++i)
-    {
-      if (compare_symtabs (&sals->sals[prev], &sals->sals[i]))
-       {
-         /* Symtabs differ.  */
-         sals->sals[out] = sals->sals[i];
-         prev = out;
-         ++out;
-       }
-    }
-
-  if (sals->nelts == 0)
-    {
-      xfree (sals->sals);
-      sals->sals = NULL;
-    }
-  else
-    sals->nelts = out;
+  /* Remove SALs that do not match.  */
+  auto from = std::remove_if (sals.begin (), sals.end (),
+                             [&] (const symtab_and_line &sal)
+    { return (sal.pspace != current_program_space || sal.symtab == NULL); });
+
+  /* Remove dups.  */
+  std::sort (sals.begin (), from,
+            [] (const symtab_and_line &sala, const symtab_and_line &salb)
+   { return cmp_symtabs (sala, salb) < 0; });
+
+  from = std::unique (sals.begin (), from,
+                     [&] (const symtab_and_line &sala,
+                          const symtab_and_line &salb)
+    { return cmp_symtabs (sala, salb) == 0; });
+
+  sals.erase (from, sals.end ());
 }
 
 static void
This page took 0.02939 seconds and 4 git commands to generate.