* gdbserver/{remote-gutils.c remote-server.c Makefile.in
[deliverable/binutils-gdb.git] / gdb / command.c
index f39600ee0298d6ed1ea1f3334a59773b8519e03d..dc5a92f571280d6141007a6a438e12bc150b86f0 100644 (file)
@@ -45,7 +45,9 @@ parse_binary_operation PARAMS ((char *));
 static void
 print_doc_line PARAMS ((FILE *, char *));
 
-/* Add element named NAME to command list *LIST.
+/* Add element named NAME.
+   CLASS is the top level category into which commands are broken down
+   for "help" purposes.
    FUN should be the function to execute the command;
    it will get a character string as argument, with leading
    and trailing blanks already eliminated.
@@ -53,7 +55,9 @@ print_doc_line PARAMS ((FILE *, char *));
    DOC is a documentation string for the command.
    Its first line should be a complete sentence.
    It should start with ? for a command that is an abbreviation
-   or with * for a command that most users don't need to know about.  */
+   or with * for a command that most users don't need to know about.
+
+   Add this command to command list *LIST.  */
 
 struct cmd_list_element *
 add_cmd (name, class, fun, doc, list)
@@ -75,8 +79,10 @@ add_cmd (name, class, fun, doc, list)
   c->prefixlist = 0;
   c->prefixname = (char *)NULL;
   c->allow_unknown = 0;
+  c->hook = 0;
+  c->hookee = 0;
+  c->cmd_pointer = 0;
   c->abbrev_flag = 0;
-  c->aux = 0;
   c->type = not_set_cmd;
   c->completer = make_symbol_completion_list;
   c->var = 0;
@@ -134,7 +140,7 @@ add_alias_cmd (name, oldname, class, abbrev_flag, list)
   c->prefixname = old->prefixname;
   c->allow_unknown = old->allow_unknown;
   c->abbrev_flag = abbrev_flag;
-  c->aux = old->aux;
+  c->cmd_pointer = old;
   return c;
 }
 
@@ -162,7 +168,7 @@ add_prefix_cmd (name, class, fun, doc, prefixlist, prefixname,
   return c;
 }
 
-/* Like add_prefix_cmd butsets the abbrev_flag on the new command. */
+/* Like add_prefix_cmd but sets the abbrev_flag on the new command. */
    
 struct cmd_list_element *
 add_abbrev_prefix_cmd (name, class, fun, doc, prefixlist, prefixname,
@@ -186,10 +192,9 @@ add_abbrev_prefix_cmd (name, class, fun, doc, prefixlist, prefixname,
 
 /* ARGSUSED */
 void
-not_just_help_class_command (args, from_tty, c)
+not_just_help_class_command (args, from_tty)
      char *args;
      int from_tty;
-     struct cmd_list_element *c;
 {
 }
 
@@ -233,7 +238,7 @@ add_show_from_set (setcmd, list)
   struct cmd_list_element *showcmd =
     (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
 
-  bcopy (setcmd, showcmd, sizeof (struct cmd_list_element));
+  memcpy (showcmd, setcmd, sizeof (struct cmd_list_element));
   delete_cmd (showcmd->name, list);
   showcmd->type = show_cmd;
   
@@ -259,20 +264,24 @@ delete_cmd (name, list)
   register struct cmd_list_element *c;
   struct cmd_list_element *p;
 
-  while (*list && !strcmp ((*list)->name, name))
+  while (*list && STREQ ((*list)->name, name))
     {
+      if ((*list)->hookee)
+       (*list)->hookee->hook = 0;      /* Hook slips out of its mouth */
       p = (*list)->next;
-      free (*list);
+      free ((PTR)*list);
       *list = p;
     }
 
   if (*list)
     for (c = *list; c->next;)
       {
-       if (!strcmp (c->next->name, name))
+       if (STREQ (c->next->name, name))
          {
+           if (c->next->hookee)
+             c->next->hookee->hook = 0;  /* hooked cmd gets away.  */
            p = c->next->next;
-           free (c->next);
+           free ((PTR)c->next);
            c->next = p;
          }
        else
@@ -336,6 +345,10 @@ help_cmd (command, stream)
   /* If this is a class name, print all of the commands in the class */
   if (c->function.cfunc == NULL)
     help_list (cmdlist, "", c->class, stream);
+
+  if (c->hook)
+    fprintf_filtered (stream, "\nThis command has a hook defined: %s\n",
+                     c->hook->name);
 }
 
 /*
@@ -415,7 +428,7 @@ print_doc_line (stream, str)
   if (p - str > line_size - 1)
     {
       line_size = p - str + 1;
-      free (line_buffer);
+      free ((PTR)line_buffer);
       line_buffer = (char *) xmalloc (line_size);
     }
   strncpy (line_buffer, str, p - str);
@@ -469,36 +482,38 @@ help_cmd_list (list, class, prefix, recurse, stream)
     }
 }
 \f
-/* This routine takes a line of TEXT and a CLIST in which to
-   start the lookup.  When it returns it will have incremented the text
-   pointer past the section of text it matched, set *RESULT_LIST to
-   the list in which the last word was matched, and will return the
-   cmd list element which the text matches.  It will return 0 if no
-   match at all was possible.  It will return -1 if ambigous matches are
-   possible; in this case *RESULT_LIST will be set to the list in which
-   there are ambiguous choices (and text will be set to the ambiguous
-   text string).
+/* This routine takes a line of TEXT and a CLIST in which to start the
+   lookup.  When it returns it will have incremented the text pointer past
+   the section of text it matched, set *RESULT_LIST to point to the list in
+   which the last word was matched, and will return a pointer to the cmd
+   list element which the text matches.  It will return NULL if no match at
+   all was possible.  It will return -1 (cast appropriately, ick) if ambigous
+   matches are possible; in this case *RESULT_LIST will be set to point to
+   the list in which there are ambiguous choices (and *TEXT will be set to
+   the ambiguous text string).
+
+   If the located command was an abbreviation, this routine returns the base
+   command of the abbreviation.
 
    It does no error reporting whatsoever; control will always return
    to the superior routine.
 
-   In the case of an ambiguous return (-1), *RESULT_LIST will be set to
-   point at the prefix_command (ie. the best match) *or* (special
-   case) will be 0 if no prefix command was ever found.  For example,
-   in the case of "info a", "info" matches without ambiguity, but "a"
-   could be "args" or "address", so *RESULT_LIST is set to
-   the cmd_list_element for "info".  So in this case
-   result list should not be interpeted as a pointer to the beginning
-   of a list; it simply points to a specific command.
+   In the case of an ambiguous return (-1), *RESULT_LIST will be set to point
+   at the prefix_command (ie. the best match) *or* (special case) will be NULL
+   if no prefix command was ever found.  For example, in the case of "info a",
+   "info" matches without ambiguity, but "a" could be "args" or "address", so
+   *RESULT_LIST is set to the cmd_list_element for "info".  So in this case
+   RESULT_LIST should not be interpeted as a pointer to the beginning of a
+   list; it simply points to a specific command.
 
    If RESULT_LIST is NULL, don't set *RESULT_LIST (but don't otherwise
    affect the operation).
 
    This routine does *not* modify the text pointed to by TEXT.
    
-   If IGNORE_HELP_CLASSES is nonzero, ignore any command list
-   elements which are actually help classes rather than commands (i.e.
-   the function field of the struct cmd_list_element is 0).  */
+   If IGNORE_HELP_CLASSES is nonzero, ignore any command list elements which
+   are actually help classes rather than commands (i.e. the function field of
+   the struct cmd_list_element is NULL).  */
 
 struct cmd_list_element *
 lookup_cmd_1 (text, clist, result_list, ignore_help_classes)
@@ -571,6 +586,14 @@ lookup_cmd_1 (text, clist, result_list, ignore_help_classes)
   /* We've matched something on this list.  Move text pointer forward. */
 
   *text = p;
+
+  /* If this was an abbreviation, use the base command instead.  */
+
+  if (found->cmd_pointer)
+    found = found->cmd_pointer;
+
+  /* If we found a prefix command, keep looking.  */
+
   if (found->prefixlist)
     {
       c = lookup_cmd_1 (text, *found->prefixlist, result_list,
@@ -921,7 +944,7 @@ complete_on_cmdlist (list, text)
 
   if (matches == 0)
     {
-      free (matchlist);
+      free ((PTR)matchlist);
       matchlist = 0;
     }
   else
@@ -1035,10 +1058,24 @@ do_setshow_command (arg, from_tty, c)
        case var_uinteger:
          if (arg == NULL)
            error_no_arg ("integer to set it to.");
-         *(int *) c->var = parse_and_eval_address (arg);
-         if (*(int *) c->var == 0)
-           *(int *) c->var = UINT_MAX;
+         *(unsigned int *) c->var = parse_and_eval_address (arg);
+         if (*(unsigned int *) c->var == 0)
+           *(unsigned int *) c->var = UINT_MAX;
          break;
+       case var_integer:
+         {
+           unsigned int val;
+           if (arg == NULL)
+             error_no_arg ("integer to set it to.");
+           val = parse_and_eval_address (arg);
+           if (val == 0)
+             *(int *) c->var = INT_MAX;
+           else if (val >= INT_MAX)
+             error ("integer %u out of range", val);
+           else
+             *(int *) c->var = val;
+           break;
+         }
        case var_zinteger:
          if (arg == NULL)
            error_no_arg ("integer to set it to.");
@@ -1062,7 +1099,7 @@ do_setshow_command (arg, from_tty, c)
          unsigned char *p;
          fputs_filtered ("\"", stdout);
          for (p = *(unsigned char **) c->var; *p != '\0'; p++)
-           printchar (*p, stdout, '"');
+           gdb_printchar (*p, stdout, '"');
          fputs_filtered ("\"", stdout);
        }
        break;
@@ -1082,8 +1119,17 @@ do_setshow_command (arg, from_tty, c)
        }
        /* else fall through */
       case var_zinteger:
-       fprintf_filtered (stdout, "%d", *(unsigned int *) c->var);
+       fprintf_filtered (stdout, "%u", *(unsigned int *) c->var);
+       break;
+      case var_integer:
+       if (*(int *) c->var == INT_MAX)
+         {
+           fputs_filtered ("unlimited", stdout);
+         }
+       else
+         fprintf_filtered (stdout, "%d", *(int *) c->var);
        break;
+           
       default:
        error ("gdb internal error: bad var_type in do_setshow_command");
       }
@@ -1123,6 +1169,11 @@ shell_escape (arg, from_tty)
      char *arg;
      int from_tty;
 {
+#ifdef CANT_FORK
+  /* FIXME: what about errors (I don't know how GO32 system() handles
+     them)?  */
+  system (arg);
+#else /* Can fork.  */
   int rc, status, pid;
   char *p, *user_shell;
 
@@ -1151,6 +1202,7 @@ shell_escape (arg, from_tty)
       ;
   else
     error ("Fork failed");
+#endif /* Can fork.  */
 }
 
 static void
@@ -1182,10 +1234,13 @@ show_user_1 (c, stream)
   cmdlines = c->user_commands;
   if (!cmdlines)
     return;
-  fprintf_filtered (stream, "User command %s:\n", c->name);
+  fputs_filtered ("User command ", stream);
+  fputs_filtered (c->name, stream);
+  fputs_filtered (":\n", stream);
   while (cmdlines)
     {
-      fprintf_filtered (stream, "%s\n", cmdlines->line); 
+      fputs_filtered (cmdlines->line, stream); 
+      fputs_filtered ("\n", stream); 
       cmdlines = cmdlines->next;
     }
   fputs_filtered ("\n", stream);
@@ -1223,10 +1278,8 @@ _initialize_command ()
   add_com ("shell", class_support, shell_escape,
           "Execute the rest of the line as a shell command.  \n\
 With no arguments, run an inferior shell.");
-
   add_com ("make", class_support, make_command,
           "Run the ``make'' program using the rest of the line as arguments.");
-
   add_cmd ("user", no_class, show_user, 
           "Show definitions of user defined commands.\n\
 Argument is the name of the user defined command.\n\
This page took 0.026564 seconds and 4 git commands to generate.