* cli/cli-cmds.c (_initialize_cli_cmds): New function.
[deliverable/binutils-gdb.git] / gdb / cli / cli-cmds.c
index d75a6c09f3e1abc1de9f475ace715fa94e8b2b99..6ee3e3c2e79102d242134933d98ba488926d2ef1 100644 (file)
@@ -1,7 +1,6 @@
 /* GDB CLI commands.
 
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010,
-   2011 Free Software Foundation, Inc.
+   Copyright (C) 2000-2005, 2007-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -92,9 +91,12 @@ void apropos_command (char *, int);
 /* Prototypes for local utility functions */
 
 static void ambiguous_line_spec (struct symtabs_and_lines *);
+
+static void filter_sals (struct symtabs_and_lines *);
+
 \f
 /* Limit the call depth of user-defined commands */
-int max_user_call_depth;
+unsigned int max_user_call_depth;
 
 /* Define all cmd_list_elements.  */
 
@@ -134,10 +136,6 @@ struct cmd_list_element *detachlist;
 
 struct cmd_list_element *killlist;
 
-/* Chain containing all defined "enable breakpoint" subcommands.  */
-
-struct cmd_list_element *enablebreaklist;
-
 /* Chain containing all defined set subcommands */
 
 struct cmd_list_element *setlist;
@@ -186,8 +184,6 @@ struct cmd_list_element *setchecklist;
 
 struct cmd_list_element *showchecklist;
 
-struct cmd_list_element *skiplist;
-
 /* Command tracing state.  */
 
 int source_verbose = 0;
@@ -199,7 +195,7 @@ static const char script_ext_off[] = "off";
 static const char script_ext_soft[] = "soft";
 static const char script_ext_strict[] = "strict";
 
-static const char *script_ext_enums[] = {
+static const char *const script_ext_enums[] = {
   script_ext_off,
   script_ext_soft,
   script_ext_strict,
@@ -246,23 +242,14 @@ help_command (char *command, int from_tty)
   help_cmd (command, gdb_stdout);
 }
 \f
-/* String compare function for qsort.  */
-static int
-compare_strings (const void *arg1, const void *arg2)
-{
-  const char **s1 = (const char **) arg1;
-  const char **s2 = (const char **) arg2;
-
-  return strcmp (*s1, *s2);
-}
-
 /* The "complete" command is used by Emacs to implement completion.  */
 
 static void
 complete_command (char *arg, int from_tty)
 {
   int argpoint;
-  char **completions, *point, *arg_prefix;
+  char *point, *arg_prefix;
+  VEC (char_ptr) *completions;
 
   dont_repeat ();
 
@@ -290,33 +277,30 @@ complete_command (char *arg, int from_tty)
 
   if (completions)
     {
-      int item, size;
+      int ix, size = VEC_length (char_ptr, completions);
+      char *item, *prev = NULL;
 
-      for (size = 0; completions[size]; ++size)
-       ;
-      qsort (completions, size, sizeof (char *), compare_strings);
+      qsort (VEC_address (char_ptr, completions), size,
+            sizeof (char *), compare_strings);
 
       /* We do extra processing here since we only want to print each
         unique item once.  */
-      item = 0;
-      while (item < size)
+      for (ix = 0; VEC_iterate (char_ptr, completions, ix, item); ++ix)
        {
          int next_item;
 
-         printf_unfiltered ("%s%s\n", arg_prefix, completions[item]);
-         next_item = item + 1;
-         while (next_item < size
-                && ! strcmp (completions[item], completions[next_item]))
+         if (prev == NULL || strcmp (item, prev) != 0)
            {
-             xfree (completions[next_item]);
-             ++next_item;
+             printf_unfiltered ("%s%s\n", arg_prefix, item);
+             xfree (prev);
+             prev = item;
            }
-
-         xfree (completions[item]);
-         item = next_item;
+         else
+           xfree (item);
        }
 
-      xfree (completions);
+      xfree (prev);
+      VEC_free (char_ptr, completions);
     }
 }
 
@@ -329,10 +313,8 @@ is_complete_command (struct cmd_list_element *c)
 static void
 show_version (char *args, int from_tty)
 {
-  immediate_quit++;
   print_gdb_version (gdb_stdout);
   printf_filtered ("\n");
-  immediate_quit--;
 }
 
 /* Handle the quit command.  */
@@ -377,7 +359,7 @@ cd_command (char *dir, int from_tty)
   dont_repeat ();
 
   if (dir == 0)
-    error_no_arg (_("new working directory"));
+    dir = "~";
 
   dir = tilde_expand (dir);
   make_cleanup (xfree, dir);
@@ -425,7 +407,7 @@ cd_command (char *dir, int from_tty)
     {
       if (IS_DIR_SEPARATOR (p[0]) && p[1] == '.'
          && (p[2] == 0 || IS_DIR_SEPARATOR (p[2])))
-       strcpy (p, p + 2);
+       memmove (p, p + 2, strlen (p + 2) + 1);
       else if (IS_DIR_SEPARATOR (p[0]) && p[1] == '.' && p[2] == '.'
               && (p[3] == 0 || IS_DIR_SEPARATOR (p[3])))
        {
@@ -444,7 +426,7 @@ cd_command (char *dir, int from_tty)
                ++p;
              else
                {
-                 strcpy (q - 1, p + 3);
+                 memmove (q - 1, p + 3, strlen (p + 3) + 1);
                  p = q - 1;
                }
            }
@@ -521,11 +503,21 @@ find_and_open_script (const char *script_file, int search_path,
   do_cleanups (old_cleanups);
 
   *streamp = fdopen (fd, FOPEN_RT);
+  if (*streamp == NULL)
+    {
+      int save_errno = errno;
+
+      close (fd);
+      if (full_pathp)
+       xfree (*full_pathp);
+      errno = save_errno;
+      return 0;
+    }
+
   return 1;
 }
 
-/* Load script FILE, which has already been opened as STREAM.
-   STREAM is closed before we return.  */
+/* Load script FILE, which has already been opened as STREAM.  */
 
 static void
 source_script_from_stream (FILE *stream, const char *file)
@@ -537,9 +529,7 @@ source_script_from_stream (FILE *stream, const char *file)
 
       TRY_CATCH (e, RETURN_MASK_ERROR)
        {
-          /* The python support reopens the file using python functions,
-             so there's no point in passing STREAM here.  */
-         source_python_script (file);
+         source_python_script (stream, file);
        }
       if (e.reason < 0)
        {
@@ -553,12 +543,9 @@ source_script_from_stream (FILE *stream, const char *file)
          else
            {
              /* Nope, just punt.  */
-             fclose (stream);
              throw_exception (e);
            }
        }
-      else
-       fclose (stream);
     }
   else
     script_from_file (stream, file);
@@ -592,6 +579,7 @@ source_script_with_search (const char *file, int from_tty, int search_path)
     }
 
   old_cleanups = make_cleanup (xfree, full_path);
+  make_cleanup_fclose (stream);
   /* The python support reopens the file, so we need to pass full_path here
      in case the file was found on the search path.  It's useful to do this
      anyway so that error messages show the actual file used.  But only do
@@ -774,7 +762,8 @@ edit_command (char *arg, int from_tty)
   struct symbol *sym;
   char *arg1;
   char *editor;
-  char *p, *fn;
+  char *p;
+  const char *fn;
 
   /* Pull in the current default source line if necessary.  */
   if (arg == 0)
@@ -796,8 +785,9 @@ edit_command (char *arg, int from_tty)
       /* Now should only be one argument -- decode it in SAL.  */
 
       arg1 = arg;
-      sals = decode_line_1 (&arg1, 0, 0, 0, 0);
+      sals = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
 
+      filter_sals (&sals);
       if (! sals.nelts)
        {
          /*  C++  */
@@ -926,8 +916,9 @@ list_command (char *arg, int from_tty)
     dummy_beg = 1;
   else
     {
-      sals = decode_line_1 (&arg1, 0, 0, 0, 0);
+      sals = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
 
+      filter_sals (&sals);
       if (!sals.nelts)
        return;                 /*  C++  */
       if (sals.nelts > 1)
@@ -959,9 +950,11 @@ list_command (char *arg, int from_tty)
       else
        {
          if (dummy_beg)
-           sals_end = decode_line_1 (&arg1, 0, 0, 0, 0);
+           sals_end = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
          else
-           sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0);
+           sals_end = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE,
+                                     sal.symtab, sal.line);
+         filter_sals (&sals_end);
          if (sals_end.nelts == 0)
            return;
          if (sals_end.nelts > 1)
@@ -1095,11 +1088,11 @@ disassemble_current_function (int flags)
   struct frame_info *frame;
   struct gdbarch *gdbarch;
   CORE_ADDR low, high, pc;
-  char *name;
+  const char *name;
 
   frame = get_selected_frame (_("No frame selected."));
   gdbarch = get_frame_arch (frame);
-  pc = get_frame_pc (frame);
+  pc = get_frame_address_in_block (frame);
   if (find_pc_partial_function (pc, &name, &low, &high) == 0)
     error (_("No function contains program counter for selected frame."));
 #if defined(TUI)
@@ -1133,7 +1126,7 @@ disassemble_command (char *arg, int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
   CORE_ADDR low, high;
-  char *name;
+  const char *name;
   CORE_ADDR pc;
   int flags;
 
@@ -1239,7 +1232,8 @@ show_user (char *args, int from_tty)
       char *comname = args;
 
       c = lookup_cmd (&comname, cmdlist, "", 0, 1);
-      if (c->class != class_user)
+      /* c->user_commands would be NULL if it's a python command.  */
+      if (c->class != class_user || !c->user_commands)
        error (_("Not a user command."));
       show_user_1 (c, "", args, gdb_stdout);
     }
@@ -1422,7 +1416,6 @@ alias_command (char *args, int from_tty)
     }
   else
     {
-      int i;
       dyn_string_t alias_prefix_dyn_string, command_prefix_dyn_string;
       char *alias_prefix, *command_prefix;
       struct cmd_list_element *c_alias, *c_command;
@@ -1472,6 +1465,86 @@ ambiguous_line_spec (struct symtabs_and_lines *sals)
                     sals->sals[i].symtab->filename, sals->sals[i].line);
 }
 
+/* Sort function for filter_sals.  */
+
+static int
+compare_symtabs (const void *a, const void *b)
+{
+  const struct symtab_and_line *sala = a;
+  const struct symtab_and_line *salb = b;
+  int r;
+
+  if (!sala->symtab->dirname)
+    {
+      if (salb->symtab->dirname)
+       return -1;
+    }
+  else if (!salb->symtab->dirname)
+    {
+      if (sala->symtab->dirname)
+       return 1;
+    }
+  else
+    {
+      r = filename_cmp (sala->symtab->dirname, salb->symtab->dirname);
+      if (r)
+       return r;
+    }
+
+  r = filename_cmp (sala->symtab->filename, salb->symtab->filename);
+  if (r)
+    return r;
+
+  if (sala->line < salb->line)
+    return -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)
+{
+  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;
+}
+
 static void
 set_debug (char *arg, int from_tty)
 {
@@ -1499,7 +1572,6 @@ init_cmd_lists (void)
   stoplist = NULL;
   deletelist = NULL;
   detachlist = NULL;
-  enablebreaklist = NULL;
   setlist = NULL;
   unsetlist = NULL;
   showlist = NULL;
@@ -1513,7 +1585,6 @@ init_cmd_lists (void)
   showprintlist = NULL;
   setchecklist = NULL;
   showchecklist = NULL;
-  skiplist = NULL;
 }
 
 static void
@@ -1572,11 +1643,13 @@ show_max_user_call_depth (struct ui_file *file, int from_tty,
 }
 
 \f
+
+initialize_file_ftype _initialize_cli_cmds;
+
 void
-init_cli_cmds (void)
+_initialize_cli_cmds (void)
 {
   struct cmd_list_element *c;
-  char *source_help_text;
 
   /* Define the classes of commands.
      They will appear in the help list in alphabetical order.  */
@@ -1643,20 +1716,6 @@ End with a line of just \"end\".\n\
 Use the \"document\" command to give documentation for the new command.\n\
 Commands defined in this way may have up to ten arguments."));
 
-  source_help_text = xstrprintf (_("\
-Read commands from a file named FILE.\n\
-\n\
-Usage: source [-s] [-v] FILE\n\
--s: search for the script in the source search path,\n\
-    even if FILE contains directories.\n\
--v: each command in FILE is echoed as it is executed.\n\
-\n\
-Note that the file \"%s\" is read automatically in this way\n\
-when GDB is started."), gdbinit);
-  c = add_cmd ("source", class_support, source_command,
-              source_help_text, &cmdlist);
-  set_cmd_completer (c, filename_completer);
-
   add_setshow_enum_cmd ("script-extension", class_support,
                        script_ext_enums, &script_ext_mode, _("\
 Set mode for script filename extension recognition."), _("\
@@ -1756,14 +1815,15 @@ is displayed."),
                            show_remote_debug,
                            &setdebuglist, &showdebuglist);
 
-  add_setshow_integer_cmd ("remotetimeout", no_class, &remote_timeout, _("\
+  add_setshow_zuinteger_unlimited_cmd ("remotetimeout", no_class,
+                                      &remote_timeout, _("\
 Set timeout limit to wait for target to respond."), _("\
 Show timeout limit to wait for target to respond."), _("\
 This value is used to set the time limit for gdb to wait for a response\n\
 from the target."),
-                          NULL,
-                          show_remote_timeout,
-                          &setlist, &showlist);
+                                      NULL,
+                                      show_remote_timeout,
+                                      &setlist, &showlist);
 
   add_prefix_cmd ("debug", no_class, set_debug,
                  _("Generic command for setting gdb debugging flags"),
@@ -1831,19 +1891,19 @@ Two arguments (separated by a comma) are taken as a range of memory to dump,\n\
 Run the ``make'' program using the rest of the line as arguments."));
   set_cmd_completer (c, filename_completer);
   add_cmd ("user", no_class, show_user, _("\
-Show definitions of user defined commands.\n\
+Show definitions of non-python user defined commands.\n\
 Argument is the name of the user defined command.\n\
 With no argument, show definitions of all user defined commands."), &showlist);
   add_com ("apropos", class_support, apropos_command,
           _("Search for commands matching a REGEXP"));
 
-  add_setshow_integer_cmd ("max-user-call-depth", no_class,
+  add_setshow_uinteger_cmd ("max-user-call-depth", no_class,
                           &max_user_call_depth, _("\
-Set the max call depth for user-defined commands."), _("\
-Show the max call depth for user-defined commands."), NULL,
-                          NULL,
-                          show_max_user_call_depth,
-                          &setlist, &showlist);
+Set the max call depth for non-python user-defined commands."), _("\
+Show the max call depth for non-python user-defined commands."), NULL,
+                           NULL,
+                           show_max_user_call_depth,
+                           &setlist, &showlist);
 
   add_setshow_boolean_cmd ("trace-commands", no_class, &trace_commands, _("\
 Set tracing of GDB CLI commands."), _("\
@@ -1867,3 +1927,24 @@ Make \"spe\" an alias of \"set print elements\":\n\
 Make \"elms\" an alias of \"elements\" in the \"set print\" command:\n\
   alias -a set print elms = set print elements"));
 }
+
+void
+init_cli_cmds (void)
+{
+  struct cmd_list_element *c;
+  char *source_help_text;
+
+  source_help_text = xstrprintf (_("\
+Read commands from a file named FILE.\n\
+\n\
+Usage: source [-s] [-v] FILE\n\
+-s: search for the script in the source search path,\n\
+    even if FILE contains directories.\n\
+-v: each command in FILE is echoed as it is executed.\n\
+\n\
+Note that the file \"%s\" is read automatically in this way\n\
+when GDB is started."), gdbinit);
+  c = add_cmd ("source", class_support, source_command,
+              source_help_text, &cmdlist);
+  set_cmd_completer (c, filename_completer);
+}
This page took 0.031052 seconds and 4 git commands to generate.