* cli/cli-decode.c (do_cfunc, set_cmd_cfunc): New functions.
[deliverable/binutils-gdb.git] / gdb / cli / cli-decode.c
index a09da91a77ef7c8fcb4db6d5408392d7f4810ab5..d64b2f642905e9d0838b39487354e353685e8e84 100644 (file)
@@ -1,5 +1,7 @@
 /* Handle lists of commands, their decoding and documentation, for GDB.
-   Copyright 1986, 1989, 1990, 1991, 1998, 2000 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 "defs.h"
 #include "symtab.h"
 #include <ctype.h>
-#include "gnu-regex.h"
+#include "gdb_regex.h"
 
-#ifdef UI_OUT
 #include "ui-out.h"
-#endif
 
 #include "cli/cli-cmds.h"
 #include "cli/cli-decode.h"
@@ -40,6 +40,46 @@ 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,
+              void (*cfunc) (char *args, int from_tty))
+{
+  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,
+              void (*sfunc) (char *args, int from_tty,
+                             struct cmd_list_element * c))
+{
+  if (sfunc == NULL)
+    cmd->func = NULL;
+  else
+    cmd->func = do_sfunc;
+  cmd->function.sfunc = sfunc; /* Ok.  */
+}
+
+
 /* Add element named NAME.
    CLASS is the top level category into which commands are broken down
    for "help" purposes.
@@ -67,7 +107,7 @@ add_cmd (char *name, enum command_class class, void (*fun) (char *, int),
 
   delete_cmd (name, list);
 
-  if (*list == NULL || STRCMP ((*list)->name, name) >= 0)
+  if (*list == NULL || strcmp ((*list)->name, name) >= 0)
     {
       c->next = *list;
       *list = c;
@@ -75,7 +115,7 @@ add_cmd (char *name, enum command_class class, void (*fun) (char *, int),
   else
     {
       p = *list;
-      while (p->next && STRCMP (p->next->name, name) <= 0)
+      while (p->next && strcmp (p->next->name, name) <= 0)
        {
          p = p->next;
        }
@@ -85,10 +125,11 @@ 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);
   c->doc = doc;
   c->flags = 0;
   c->replacement = NULL;
+  c->pre_show_hook = NULL;
   c->hook_pre  = NULL;
   c->hook_post = NULL;
   c->hook_in = 0;
@@ -109,6 +150,19 @@ 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
@@ -133,24 +187,6 @@ deprecate_cmd (struct cmd_list_element *cmd, char *replacement)
   return cmd;
 }
 
-
-/* Same as above, except that the abbrev_flag is set. */
-
-#if 0                          /* Currently unused */
-
-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;
-}
-
-#endif
-
 struct cmd_list_element *
 add_alias_cmd (char *name, char *oldname, enum command_class class,
               int abbrev_flag, struct cmd_list_element **list)
@@ -169,7 +205,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;
@@ -241,15 +280,14 @@ 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);
+  struct cmd_list_element *c = add_cmd (name, class, NULL, 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
+  /* This needs to be something besides NULL so that this isn't
      treated as a help class.  */
-  c->function.sfunc = empty_sfunc;
+  set_cmd_sfunc (c, empty_sfunc);
   return c;
 }
 
@@ -295,6 +333,25 @@ add_set_auto_boolean_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_boolean_cmd (char *name,
+                    enum command_class class,
+                    int *var,
+                    char *doc,
+                    struct cmd_list_element **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);
+  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 
    necessarily the head of LIST).  */
@@ -317,7 +374,7 @@ add_show_from_set (struct cmd_list_element *setcmd,
   else
     fprintf_unfiltered (gdb_stderr, "GDB internal error: Bad docstring for set command\n");
 
-  if (*list == NULL || STRCMP ((*list)->name, showcmd->name) >= 0)
+  if (*list == NULL || strcmp ((*list)->name, showcmd->name) >= 0)
     {
       showcmd->next = *list;
       *list = showcmd;
@@ -325,7 +382,7 @@ add_show_from_set (struct cmd_list_element *setcmd,
   else
     {
       p = *list;
-      while (p->next && STRCMP (p->next->name, showcmd->name) <= 0)
+      while (p->next && strcmp (p->next->name, showcmd->name) <= 0)
        {
          p = p->next;
        }
@@ -351,7 +408,7 @@ delete_cmd (char *name, struct cmd_list_element **list)
       if ((*list)->hookee_post)
       (*list)->hookee_post->hook_post = 0; /* Hook slips out of its bottom  */
       p = (*list)->next;
-      free ((PTR) * list);
+      xfree (* list);
       *list = p;
     }
 
@@ -366,7 +423,7 @@ delete_cmd (char *name, struct cmd_list_element **list)
             c->next->hookee_post->hook_post = 0; /* remove post hook */
                                                /* :( no fishing metaphore */
            p = c->next->next;
-           free ((PTR) c->next);
+           xfree (c->next);
            c->next = p;
          }
        else
@@ -502,18 +559,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");
 
@@ -522,7 +579,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)
@@ -606,7 +663,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);
     }
 }
@@ -631,18 +688,14 @@ print_doc_line (struct ui_file *stream, char *str)
   if (p - str > line_size - 1)
     {
       line_size = p - str + 1;
-      free ((PTR) line_buffer);
+      xfree (line_buffer);
       line_buffer = (char *) xmalloc (line_size);
     }
   strncpy (line_buffer, str, p - 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
 }
 
 /*
@@ -671,8 +724,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);
@@ -700,7 +753,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)++;
@@ -914,15 +967,9 @@ lookup_cmd (char **line, struct cmd_list_element *list, char *cmdtype,
   struct cmd_list_element *last_list = 0;
   struct cmd_list_element *c =
   lookup_cmd_1 (line, list, &last_list, ignore_help_classes);
-#if 0
-  /* This is wrong for complete_command.  */
-  char *ptr = (*line) + strlen (*line) - 1;
 
-  /* Clear off trailing whitespace.  */
-  while (ptr >= *line && (*ptr == ' ' || *ptr == '\t'))
-    ptr--;
-  *(ptr + 1) = '\0';
-#endif
+  /* Note: Do not remove trailing whitespace here because this
+     would be wrong for complete_command.  Jim Kingdon  */
 
   if (!c)
     {
@@ -1211,143 +1258,6 @@ lookup_cmd_composition (char *text,
     }
 }
 
-
-
-
-#if 0
-/* Look up the contents of *LINE as a command in the command list LIST.
-   LIST is a chain of struct cmd_list_element's.
-   If it is found, return the struct cmd_list_element for that command
-   and update *LINE to point after the command name, at the first argument.
-   If not found, call error if ALLOW_UNKNOWN is zero
-   otherwise (or if error returns) return zero.
-   Call error if specified command is ambiguous,
-   unless ALLOW_UNKNOWN is negative.
-   CMDTYPE precedes the word "command" in the error message.  */
-
-struct cmd_list_element *
-lookup_cmd (char **line, struct cmd_list_element *list, char *cmdtype,
-           int allow_unknown)
-{
-  register char *p;
-  register struct cmd_list_element *c, *found;
-  int nfound;
-  char ambbuf[100];
-  char *processed_cmd;
-  int i, cmd_len;
-
-  /* Skip leading whitespace.  */
-
-  while (**line == ' ' || **line == '\t')
-    (*line)++;
-
-  /* Clear out trailing whitespace.  */
-
-  p = *line + strlen (*line);
-  while (p != *line && (p[-1] == ' ' || p[-1] == '\t'))
-    p--;
-  *p = 0;
-
-  /* Find end of command name.  */
-
-  p = *line;
-  while (*p == '-' || isalnum (*p))
-    p++;
-
-  /* Look up the command name.
-     If exact match, keep that.
-     Otherwise, take command abbreviated, if unique.  Note that (in my
-     opinion) a null string does *not* indicate ambiguity; simply the
-     end of the argument.  */
-
-  if (p == *line)
-    {
-      if (!allow_unknown)
-       error ("Lack of needed %scommand", cmdtype);
-      return 0;
-    }
-
-  /* Copy over to a local buffer, converting to lowercase on the way.
-     This is in case the command being parsed is a subcommand which
-     doesn't match anything, and that's ok.  We want the original
-     untouched for the routine of the original command.  */
-
-  processed_cmd = (char *) alloca (p - *line + 1);
-  for (cmd_len = 0; cmd_len < p - *line; cmd_len++)
-    {
-      char x = (*line)[cmd_len];
-      if (isupper (x))
-       processed_cmd[cmd_len] = tolower (x);
-      else
-       processed_cmd[cmd_len] = x;
-    }
-  processed_cmd[cmd_len] = '\0';
-
-  /* Check all possibilities in the current command list.  */
-  found = 0;
-  nfound = 0;
-  for (c = list; c; c = c->next)
-    {
-      if (!strncmp (processed_cmd, c->name, cmd_len))
-       {
-         found = c;
-         nfound++;
-         if (c->name[cmd_len] == 0)
-           {
-             nfound = 1;
-             break;
-           }
-       }
-    }
-
-  /* Report error for undefined command name.  */
-
-  if (nfound != 1)
-    {
-      if (nfound > 1 && allow_unknown >= 0)
-       {
-         ambbuf[0] = 0;
-         for (c = list; c; c = c->next)
-           if (!strncmp (processed_cmd, c->name, cmd_len))
-             {
-               if (strlen (ambbuf) + strlen (c->name) + 6 < sizeof ambbuf)
-                 {
-                   if (strlen (ambbuf))
-                     strcat (ambbuf, ", ");
-                   strcat (ambbuf, c->name);
-                 }
-               else
-                 {
-                   strcat (ambbuf, "..");
-                   break;
-                 }
-             }
-         error ("Ambiguous %scommand \"%s\": %s.", cmdtype,
-                processed_cmd, ambbuf);
-       }
-      else if (!allow_unknown)
-       error ("Undefined %scommand: \"%s\".", cmdtype, processed_cmd);
-      return 0;
-    }
-
-  /* Skip whitespace before the argument.  */
-
-  while (*p == ' ' || *p == '\t')
-    p++;
-  *line = p;
-
-  if (found->prefixlist && *p)
-    {
-      c = lookup_cmd (line, *found->prefixlist, found->prefixname,
-                     found->allow_unknown);
-      if (c)
-       return c;
-    }
-
-  return found;
-}
-#endif
-
 /* Helper function for SYMBOL_COMPLETION_FUNCTION.  */
 
 /* Return a vector of char pointers which point to the different
@@ -1374,7 +1284,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)
@@ -1406,7 +1316,7 @@ complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
 
   if (matches == 0)
     {
-      free ((PTR) matchlist);
+      xfree (matchlist);
       matchlist = 0;
     }
   else
@@ -1477,7 +1387,7 @@ complete_on_enum (const char *enumlist[],
 
   if (matches == 0)
     {
-      free ((PTR) matchlist);
+      xfree (matchlist);
       matchlist = 0;
     }
   else
This page took 0.033912 seconds and 4 git commands to generate.