* h8300-tdep.c (E_PSEUDO_CCR_REGNUM): New define.
[deliverable/binutils-gdb.git] / gdb / cli / cli-decode.c
index 1d51c6b6b7eed96c3c43d1dacd6ed2e5d0530f53..be516c9a6f39d2942de0fa85f2c2330e1ea890c0 100644 (file)
@@ -1,6 +1,7 @@
 /* Handle lists of commands, their decoding and documentation, for GDB.
-   Copyright 1986, 1989, 1990, 1991, 1998, 2000, 2001
-   Free Software Foundation, Inc.
+
+   Copyright 1986, 1989, 1990, 1991, 1998, 2000, 2001, 2002 Free
+   Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include "symtab.h"
 #include <ctype.h>
 #include "gdb_regex.h"
+#include "gdb_string.h"
 
-#ifdef UI_OUT
 #include "ui-out.h"
-#endif
 
 #include "cli/cli-cmds.h"
 #include "cli/cli-decode.h"
 
+#include "gdb_assert.h"
+
 /* Prototypes for local functions */
 
 static void undef_cmd_error (char *, char *);
@@ -41,6 +43,75 @@ static struct cmd_list_element *find_cmd (char *command,
 
 static void help_all (struct ui_file *stream);
 \f
+/* Set the callback function for the specified command.  For each both
+   the commands callback and func() are set.  The latter set to a
+   bounce function (unless cfunc / sfunc is NULL that is).  */
+
+static void
+do_cfunc (struct cmd_list_element *c, char *args, int from_tty)
+{
+  c->function.cfunc (args, from_tty); /* Ok.  */
+}
+
+void
+set_cmd_cfunc (struct cmd_list_element *cmd, cmd_cfunc_ftype *cfunc)
+{
+  if (cfunc == NULL)
+    cmd->func = NULL;
+  else
+    cmd->func = do_cfunc;
+  cmd->function.cfunc = cfunc; /* Ok.  */
+}
+
+static void
+do_sfunc (struct cmd_list_element *c, char *args, int from_tty)
+{
+  c->function.sfunc (args, from_tty, c); /* Ok.  */
+}
+
+void
+set_cmd_sfunc (struct cmd_list_element *cmd, cmd_sfunc_ftype *sfunc)
+{
+  if (sfunc == NULL)
+    cmd->func = NULL;
+  else
+    cmd->func = do_sfunc;
+  cmd->function.sfunc = sfunc; /* Ok.  */
+}
+
+int
+cmd_cfunc_eq (struct cmd_list_element *cmd,
+             void (*cfunc) (char *args, int from_tty))
+{
+  return cmd->func == do_cfunc && cmd->function.cfunc == cfunc;
+}
+
+void
+set_cmd_context (struct cmd_list_element *cmd, void *context)
+{
+  cmd->context = context;
+}
+
+void *
+get_cmd_context (struct cmd_list_element *cmd)
+{
+  return cmd->context;
+}
+
+enum cmd_types
+cmd_type (struct cmd_list_element *cmd)
+{
+  return cmd->type;
+}
+
+void
+set_cmd_completer (struct cmd_list_element *cmd,
+                  char **(*completer) (char *text, char *word))
+{
+  cmd->completer = completer; /* Ok.  */
+}
+
+
 /* Add element named NAME.
    CLASS is the top level category into which commands are broken down
    for "help" purposes.
@@ -86,7 +157,8 @@ add_cmd (char *name, enum command_class class, void (*fun) (char *, int),
 
   c->name = name;
   c->class = class;
-  c->function.cfunc = fun;
+  set_cmd_cfunc (c, fun);
+  set_cmd_context (c, NULL);
   c->doc = doc;
   c->flags = 0;
   c->replacement = NULL;
@@ -98,7 +170,7 @@ add_cmd (char *name, enum command_class class, void (*fun) (char *, int),
   c->prefixname = NULL;
   c->allow_unknown = 0;
   c->abbrev_flag = 0;
-  c->completer = make_symbol_completion_list;
+  set_cmd_completer (c, make_symbol_completion_list);
   c->type = not_set_cmd;
   c->var = NULL;
   c->var_type = var_boolean;
@@ -111,20 +183,6 @@ add_cmd (char *name, enum command_class class, void (*fun) (char *, int),
   return c;
 }
 
-/* Same as above, except that the abbrev_flag is set. */
-/* Note: Doesn't seem to be used anywhere currently. */
-
-struct cmd_list_element *
-add_abbrev_cmd (char *name, enum command_class class, void (*fun) (char *, int),
-               char *doc, struct cmd_list_element **list)
-{
-  register struct cmd_list_element *c
-  = add_cmd (name, class, fun, doc, list);
-
-  c->abbrev_flag = 1;
-  return c;
-}
-
 /* Deprecates a command CMD.
    REPLACEMENT is the name of the command which should be used in place
    of this command, or NULL if no such command exists.
@@ -166,7 +224,10 @@ add_alias_cmd (char *name, char *oldname, enum command_class class,
       return 0;
     }
 
-  c = add_cmd (name, class, old->function.cfunc, old->doc, list);
+  c = add_cmd (name, class, NULL, old->doc, list);
+  /* NOTE: Both FUNC and all the FUNCTIONs need to be copied.  */
+  c->func = old->func;
+  c->function = old->function;
   c->prefixlist = old->prefixlist;
   c->prefixname = old->prefixname;
   c->allow_unknown = old->allow_unknown;
@@ -223,13 +284,90 @@ empty_sfunc (char *args, int from_tty, struct cmd_list_element *c)
 {
 }
 
-/* Add element named NAME to command list LIST (the list for set
+/* Add element named NAME to command list LIST (the list for set/show
    or some sublist thereof).
+   TYPE is set_cmd or show_cmd.
    CLASS is as in add_cmd.
    VAR_TYPE is the kind of thing we are setting.
    VAR is address of the variable being controlled by this command.
    DOC is the documentation string.  */
 
+static struct cmd_list_element *
+add_set_or_show_cmd (char *name,
+                    enum cmd_types type,
+                    enum command_class class,
+                    var_types var_type,
+                    void *var,
+                    char *doc,
+                    struct cmd_list_element **list)
+{
+  struct cmd_list_element *c = add_cmd (name, class, NULL, doc, list);
+  gdb_assert (type == set_cmd || type == show_cmd);
+  c->type = type;
+  c->var_type = var_type;
+  c->var = var;
+  /* This needs to be something besides NULL so that this isn't
+     treated as a help class.  */
+  set_cmd_sfunc (c, empty_sfunc);
+  return c;
+}
+
+/* Add element named NAME to both the command SET_LIST and SHOW_LIST.
+   CLASS is as in add_cmd.  VAR_TYPE is the kind of thing we are
+   setting.  VAR is address of the variable being controlled by this
+   command.  SET_FUNC and SHOW_FUNC are the callback functions (if
+   non-NULL).  SET_DOC and SHOW_DOC are the documentation strings.
+   SET_RESULT and SHOW_RESULT, if not NULL, are set to the resulting
+   command structures.  */
+
+void
+add_setshow_cmd_full (char *name,
+                     enum command_class class,
+                     var_types var_type, void *var,
+                     char *set_doc, char *show_doc,
+                     cmd_sfunc_ftype *set_func, cmd_sfunc_ftype *show_func,
+                     struct cmd_list_element **set_list,
+                     struct cmd_list_element **show_list,
+                     struct cmd_list_element **set_result,
+                     struct cmd_list_element **show_result)
+{
+  struct cmd_list_element *set;
+  struct cmd_list_element *show;
+  set = add_set_or_show_cmd (name, set_cmd, class, var_type, var,
+                            set_doc, set_list);
+  if (set_func != NULL)
+    set_cmd_sfunc (set, set_func);
+  show = add_set_or_show_cmd (name, show_cmd, class, var_type, var,
+                             show_doc, show_list);
+  if (show_func != NULL)
+    set_cmd_sfunc (show, show_func);
+
+  if (set_result != NULL)
+    *set_result = set;
+  if (show_result != NULL)
+    *show_result = show;
+}
+
+/* Add element named NAME to both the command SET_LIST and SHOW_LIST.
+   CLASS is as in add_cmd.  VAR_TYPE is the kind of thing we are
+   setting.  VAR is address of the variable being controlled by this
+   command.  SET_FUNC and SHOW_FUNC are the callback functions (if
+   non-NULL).  SET_DOC and SHOW_DOC are the documentation strings.  */
+
+void
+add_setshow_cmd (char *name,
+                enum command_class class,
+                var_types var_type, void *var,
+                char *set_doc, char *show_doc,
+                cmd_sfunc_ftype *set_func, cmd_sfunc_ftype *show_func,
+                struct cmd_list_element **set_list,
+                struct cmd_list_element **show_list)
+{
+  add_setshow_cmd_full (name, class, var_type, var, set_doc, show_doc,
+                       set_func, show_func, set_list, show_list,
+                       NULL, NULL);
+}
+
 struct cmd_list_element *
 add_set_cmd (char *name,
             enum command_class class,
@@ -238,16 +376,7 @@ add_set_cmd (char *name,
             char *doc,
             struct cmd_list_element **list)
 {
-  struct cmd_list_element *c
-  = add_cmd (name, class, NO_FUNCTION, doc, list);
-
-  c->type = set_cmd;
-  c->var_type = var_type;
-  c->var = var;
-  /* This needs to be something besides NO_FUNCTION so that this isn't
-     treated as a help class.  */
-  c->function.sfunc = empty_sfunc;
-  return c;
+  return add_set_or_show_cmd (name, set_cmd, class, var_type, var, doc, list);
 }
 
 /* Add element named NAME to command list LIST (the list for set
@@ -273,83 +402,77 @@ add_set_enum_cmd (char *name,
   return c;
 }
 
-/* Add element named NAME to command list LIST (the list for set
-   or some sublist thereof).
-   CLASS is as in add_cmd.
-   VAR is address of the variable which will contain the value.
-   DOC is the documentation string.  */
-struct cmd_list_element *
-add_set_auto_boolean_cmd (char *name,
-                         enum command_class class,
-                         enum cmd_auto_boolean *var,
-                         char *doc,
-                         struct cmd_list_element **list)
+/* Add an auto-boolean command named NAME to both the set and show
+   command list lists.  CLASS is as in add_cmd.  VAR is address of the
+   variable which will contain the value.  DOC is the documentation
+   string.  FUNC is the corresponding callback.  */
+void
+add_setshow_auto_boolean_cmd (char *name,
+                             enum command_class class,
+                             enum auto_boolean *var,
+                             char *set_doc, char *show_doc,
+                             cmd_sfunc_ftype *set_func,
+                             cmd_sfunc_ftype *show_func,
+                             struct cmd_list_element **set_list,
+                             struct cmd_list_element **show_list)
 {
   static const char *auto_boolean_enums[] = { "on", "off", "auto", NULL };
   struct cmd_list_element *c;
-  c = add_set_cmd (name, class, var_auto_boolean, var, doc, list);
+  add_setshow_cmd_full (name, class, var_auto_boolean, var,
+                       set_doc, show_doc, set_func, show_func,
+                       set_list, show_list,
+                       &c, NULL);
   c->enums = auto_boolean_enums;
-  return c;
 }
 
-/* Add element named NAME to command list LIST (the list for set
-   or some sublist thereof).
-   CLASS is as in add_cmd.
-   VAR is address of the variable which will contain the value.
-   DOC is the documentation string.  */
-struct cmd_list_element *
-add_set_boolean_cmd (char *name,
-                    enum command_class class,
-                    int *var,
-                    char *doc,
-                    struct cmd_list_element **list)
+/* Add element named NAME to both the set and show command LISTs (the
+   list for set/show or some sublist thereof).  CLASS is as in
+   add_cmd.  VAR is address of the variable which will contain the
+   value.  SET_DOC and SHOW_DOR are the documentation strings.  */
+void
+add_setshow_boolean_cmd (char *name,
+                        enum command_class class,
+                        int *var, char *set_doc, char *show_doc,
+                        cmd_sfunc_ftype *set_func,
+                        cmd_sfunc_ftype *show_func,
+                        struct cmd_list_element **set_list,
+                        struct cmd_list_element **show_list)
 {
   static const char *boolean_enums[] = { "on", "off", NULL };
   struct cmd_list_element *c;
-  c = add_set_cmd (name, class, var_boolean, var, doc, list);
+  add_setshow_cmd_full (name, class, var_boolean, var,
+                       set_doc, show_doc,
+                       set_func, show_func,
+                       set_list, show_list,
+                       &c, NULL);
   c->enums = boolean_enums;
-  return c;
 }
 
 /* Where SETCMD has already been added, add the corresponding show
-   command to LIST and return a pointer to the added command (not 
+   command to LIST and return a pointer to the added command (not
    necessarily the head of LIST).  */
+/* NOTE: cagney/2002-03-17: The original version of add_show_from_set
+   used memcpy() to clone `set' into `show'.  This meant that in
+   addition to all the needed fields (var, name, et.al.) some
+   unnecessary fields were copied (namely the callback function).  The
+   function explictly copies relevant fields.  For a `set' and `show'
+   command to share the same callback, the caller must set both
+   explicitly.  */
 struct cmd_list_element *
 add_show_from_set (struct cmd_list_element *setcmd,
                   struct cmd_list_element **list)
 {
-  struct cmd_list_element *showcmd =
-  (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
-  struct cmd_list_element *p;
-
-  memcpy (showcmd, setcmd, sizeof (struct cmd_list_element));
-  delete_cmd (showcmd->name, list);
-  showcmd->type = show_cmd;
-
-  /* Replace "set " at start of docstring with "show ".  */
-  if (setcmd->doc[0] == 'S' && setcmd->doc[1] == 'e'
-      && setcmd->doc[2] == 't' && setcmd->doc[3] == ' ')
-    showcmd->doc = concat ("Show ", setcmd->doc + 4, NULL);
-  else
-    fprintf_unfiltered (gdb_stderr, "GDB internal error: Bad docstring for set command\n");
+  char *doc;
+  const static char setstring[] = "Set ";
 
-  if (*list == NULL || strcmp ((*list)->name, showcmd->name) >= 0)
-    {
-      showcmd->next = *list;
-      *list = showcmd;
-    }
-  else
-    {
-      p = *list;
-      while (p->next && strcmp (p->next->name, showcmd->name) <= 0)
-       {
-         p = p->next;
-       }
-      showcmd->next = p->next;
-      p->next = showcmd;
-    }
+  /* Create a doc string by replacing "Set " at the start of the
+     `set'' command's doco with "Show ".  */
+  gdb_assert (strncmp (setcmd->doc, setstring, sizeof (setstring) - 1) == 0);
+  doc = concat ("Show ", setcmd->doc + sizeof (setstring) - 1, NULL);
 
-  return showcmd;
+  /* Insert the basic command.  */
+  return add_set_or_show_cmd (setcmd->name, show_cmd, setcmd->class,
+                             setcmd->var_type, setcmd->var, doc, list);
 }
 
 /* Remove the command named NAME from the command list.  */
@@ -518,18 +641,18 @@ help_cmd (char *command, struct ui_file *stream)
      If c->prefixlist is nonzero, we have a prefix command.
      Print its documentation, then list its subcommands.
 
-     If c->function is nonzero, we really have a command.
-     Print its documentation and return.
+     If c->func is non NULL, we really have a command.  Print its
+     documentation and return.
 
-     If c->function is zero, we have a class name.
-     Print its documentation (as if it were a command)
-     and then set class to the number of this class
-     so that the commands in the class will be listed.  */
+     If c->func is NULL, we have a class name.  Print its
+     documentation (as if it were a command) and then set class to the
+     number of this class so that the commands in the class will be
+     listed.  */
 
   fputs_filtered (c->doc, stream);
   fputs_filtered ("\n", stream);
 
-  if (c->prefixlist == 0 && c->function.cfunc != NULL)
+  if (c->prefixlist == 0 && c->func != NULL)
     return;
   fprintf_filtered (stream, "\n");
 
@@ -538,7 +661,7 @@ help_cmd (char *command, struct ui_file *stream)
     help_list (*c->prefixlist, c->prefixname, all_commands, stream);
 
   /* If this is a class name, print all of the commands in the class */
-  if (c->function.cfunc == NULL)
+  if (c->func == NULL)
     help_list (cmdlist, "", c->class, stream);
 
   if (c->hook_pre || c->hook_post)
@@ -597,14 +720,24 @@ help_list (struct cmd_list_element *list, char *cmdtype,
   help_cmd_list (list, class, cmdtype, (int) class >= 0, stream);
 
   if (class == all_classes)
-    fprintf_filtered (stream, "\n\
-Type \"help%s\" followed by a class name for a list of commands in that class.",
-                     cmdtype1);
+    {
+      fprintf_filtered (stream, "\n\
+Type \"help%s\" followed by a class name for a list of commands in ",
+                       cmdtype1);
+      wrap_here ("");
+      fprintf_filtered (stream, "that class.");
+    }
 
-  fprintf_filtered (stream, "\n\
-Type \"help%s\" followed by %scommand name for full documentation.\n\
-Command name abbreviations are allowed if unambiguous.\n",
+  fprintf_filtered (stream, "\nType \"help%s\" followed by %scommand name ",
                    cmdtype1, cmdtype2);
+  wrap_here ("");
+  fputs_filtered ("for ", stream);
+  wrap_here ("");
+  fputs_filtered ("full ", stream);
+  wrap_here ("");
+  fputs_filtered ("documentation.\n", stream);
+  fputs_filtered ("Command name abbreviations are allowed if unambiguous.\n",
+                 stream);
 }
 
 static void
@@ -622,7 +755,7 @@ help_all (struct ui_file *stream)
         help_cmd_list (*c->prefixlist, all_commands, c->prefixname, 0, stream);
     
       /* If this is a class name, print all of the commands in the class */
-      else if (c->function.cfunc == NULL)
+      else if (c->func == NULL)
         help_cmd_list (cmdlist, c->class, "", 0, stream);
     }
 }
@@ -654,11 +787,7 @@ print_doc_line (struct ui_file *stream, char *str)
   line_buffer[p - str] = '\0';
   if (islower (line_buffer[0]))
     line_buffer[0] = toupper (line_buffer[0]);
-#ifdef UI_OUT
   ui_out_text (uiout, line_buffer);
-#else
-  fputs_filtered (line_buffer, stream);
-#endif
 }
 
 /*
@@ -687,8 +816,8 @@ help_cmd_list (struct cmd_list_element *list, enum command_class class,
     {
       if (c->abbrev_flag == 0 &&
          (class == all_commands
-          || (class == all_classes && c->function.cfunc == NULL)
-          || (class == c->class && c->function.cfunc != NULL)))
+          || (class == all_classes && c->func == NULL)
+          || (class == c->class && c->func != NULL)))
        {
          fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
          print_doc_line (stream, c->doc);
@@ -716,7 +845,7 @@ find_cmd (char *command, int len, struct cmd_list_element *clist,
   *nfound = 0;
   for (c = clist; c; c = c->next)
     if (!strncmp (command, c->name, len)
-       && (!ignore_help_classes || c->function.cfunc))
+       && (!ignore_help_classes || c->func))
       {
        found = c;
        (*nfound)++;
@@ -780,10 +909,14 @@ lookup_cmd_1 (char **text, struct cmd_list_element *clist,
   /* Treating underscores as part of command words is important
      so that "set args_foo()" doesn't get interpreted as
      "set args _foo()".  */
+  /* NOTE: cagney/2003-02-13 The `tui_active' was previously
+     `tui_version'.  */
   for (p = *text;
        *p && (isalnum (*p) || *p == '-' || *p == '_' ||
-             (tui_version &&
+#if defined(TUI)
+             (tui_active &&
               (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
+#endif
              (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
        p++)
     ;
@@ -905,7 +1038,7 @@ undef_cmd_error (char *cmdtype, char *q)
         cmdtype,
         q,
         *cmdtype ? " " : "",
-        strlen (cmdtype) - 1,
+        (int) strlen (cmdtype) - 1,
         cmdtype);
 }
 
@@ -1150,10 +1283,14 @@ lookup_cmd_composition (char *text,
       /* Treating underscores as part of command words is important
        so that "set args_foo()" doesn't get interpreted as
        "set args _foo()".  */
+      /* NOTE: cagney/2003-02-13 The `tui_active' was previously
+        `tui_version'.  */
       for (p = text;
          *p && (isalnum (*p) || *p == '-' || *p == '_' ||
-                (tui_version &&
+#if defined(TUI)
+                (tui_active &&
                  (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
+#endif
                 (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
          p++)
       ;
@@ -1247,7 +1384,7 @@ complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
   for (ptr = list; ptr; ptr = ptr->next)
     if (!strncmp (ptr->name, text, textlen)
        && !ptr->abbrev_flag
-       && (ptr->function.cfunc
+       && (ptr->func
            || ptr->prefixlist))
       {
        if (matches == sizeof_matchlist)
@@ -1363,3 +1500,23 @@ complete_on_enum (const char *enumlist[],
   return matchlist;
 }
 
+
+/* check function pointer */
+int
+cmd_func_p (struct cmd_list_element *cmd)
+{
+  return (cmd->func != NULL);
+}
+
+
+/* call the command function */
+void
+cmd_func (struct cmd_list_element *cmd, char *args, int from_tty)
+{
+  if (cmd_func_p (cmd))
+    (*cmd->func) (cmd, args, from_tty);
+  else
+    error ("Invalid command");
+}
+
+
This page took 0.032876 seconds and 4 git commands to generate.