2004-04-21 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / cli / cli-script.c
index 69fc4fb31aefdbaf7ac7212693be611d0acc37ad..165702db3f5ed92ca9727eaf3157d3e3606634da 100644 (file)
@@ -1,6 +1,8 @@
 /* GDB CLI command scripting.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+   Foundation, Inc.
 
    This file is part of GDB.
 
 #include "language.h"          /* For value_true */
 #include <ctype.h>
 
-#ifdef UI_OUT
 #include "ui-out.h"
-#endif
+#include "gdb_string.h"
 
 #include "top.h"
 #include "cli/cli-cmds.h"
 #include "cli/cli-decode.h"
 #include "cli/cli-script.h"
 
-/* From gdb/top.c */
-
-extern void dont_repeat (void);
-
-extern void do_restore_instream_cleanup (void *stream);
-
 /* Prototypes for local functions */
 
-static struct cleanup *
-       make_cleanup_free_command_lines (struct command_line **arg);
-
 static enum command_control_type
        recurse_read_control_structure (struct command_line *current_cmd);
 
@@ -126,7 +118,7 @@ get_command_line (enum command_control_type type, char *arg)
 }
 
 /* Recursively print a command (including full control structures).  */
-#ifdef UI_OUT
+
 void
 print_command_lines (struct ui_out *uiout, struct command_line *cmd,
                     unsigned int depth)
@@ -171,14 +163,13 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd,
       /* A while command.  Recursively print its subcommands and continue.  */
       if (list->control_type == while_control)
        {
-         ui_out_text (uiout, "while ");
          ui_out_field_fmt (uiout, NULL, "while %s", list->line);
          ui_out_text (uiout, "\n");
          print_command_lines (uiout, *list->body_list, depth + 1);
-         ui_out_field_string (uiout, NULL, "end");
          if (depth)
            ui_out_spaces (uiout, 2 * depth);
-         ui_out_text (uiout, "end\n");
+         ui_out_field_string (uiout, NULL, "end");
+         ui_out_text (uiout, "\n");
          list = list->next;
          continue;
        }
@@ -186,7 +177,6 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd,
       /* An if command.  Recursively print both arms before continueing.  */
       if (list->control_type == if_control)
        {
-         ui_out_text (uiout, "if ");
          ui_out_field_fmt (uiout, NULL, "if %s", list->line);
          ui_out_text (uiout, "\n");
          /* The true arm. */
@@ -198,14 +188,14 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd,
              if (depth)
                ui_out_spaces (uiout, 2 * depth);
              ui_out_field_string (uiout, NULL, "else");
-             ui_out_text (uiout, "else\n");
+             ui_out_text (uiout, "\n");
              print_command_lines (uiout, list->body_list[1], depth + 1);
            }
 
-         ui_out_field_string (uiout, NULL, "end");
          if (depth)
            ui_out_spaces (uiout, 2 * depth);
-         ui_out_text (uiout, "end\n");
+         ui_out_field_string (uiout, NULL, "end");
+         ui_out_text (uiout, "\n");
          list = list->next;
          continue;
        }
@@ -214,95 +204,59 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd,
       list = list->next;
     }                          /* while (list) */
 }
-#else
-void
-print_command_line (struct command_line *cmd, unsigned int depth,
-                   struct ui_file *stream)
-{
-  unsigned int i;
 
-  if (depth)
-    {
-      for (i = 0; i < depth; i++)
-       fputs_filtered ("  ", stream);
-    }
-
-  /* A simple command, print it and return.  */
-  if (cmd->control_type == simple_control)
-    {
-      fputs_filtered (cmd->line, stream);
-      fputs_filtered ("\n", stream);
-      return;
-    }
+/* Handle pre-post hooks.  */
 
-  /* loop_continue to jump to the start of a while loop, print it
-     and return. */
-  if (cmd->control_type == continue_control)
-    {
-      fputs_filtered ("loop_continue\n", stream);
-      return;
-    }
+static void
+clear_hook_in_cleanup (void *data)
+{
+  struct cmd_list_element *c = data;
+  c->hook_in = 0; /* Allow hook to work again once it is complete */
+}
 
-  /* loop_break to break out of a while loop, print it and return.  */
-  if (cmd->control_type == break_control)
+void
+execute_cmd_pre_hook (struct cmd_list_element *c)
+{
+  if ((c->hook_pre) && (!c->hook_in))
     {
-      fputs_filtered ("loop_break\n", stream);
-      return;
+      struct cleanup *cleanups = make_cleanup (clear_hook_in_cleanup, c);
+      c->hook_in = 1; /* Prevent recursive hooking */
+      execute_user_command (c->hook_pre, (char *) 0);
+      do_cleanups (cleanups);
     }
+}
 
-  /* A while command.  Recursively print its subcommands before returning.  */
-  if (cmd->control_type == while_control)
+void
+execute_cmd_post_hook (struct cmd_list_element *c)
+{
+  if ((c->hook_post) && (!c->hook_in))
     {
-      struct command_line *list;
-      fputs_filtered ("while ", stream);
-      fputs_filtered (cmd->line, stream);
-      fputs_filtered ("\n", stream);
-      list = *cmd->body_list;
-      while (list)
-       {
-         print_command_line (list, depth + 1, stream);
-         list = list->next;
-       }
-    }
-
-  /* An if command.  Recursively print both arms before returning.  */
-  if (cmd->control_type == if_control)
-    {
-      fputs_filtered ("if ", stream);
-      fputs_filtered (cmd->line, stream);
-      fputs_filtered ("\n", stream);
-      /* The true arm. */
-      print_command_line (cmd->body_list[0], depth + 1, stream);
-
-      /* Show the false arm if it exists.  */
-      if (cmd->body_count == 2)
-       {
-         if (depth)
-           {
-             for (i = 0; i < depth; i++)
-               fputs_filtered ("  ", stream);
-           }
-         fputs_filtered ("else\n", stream);
-         print_command_line (cmd->body_list[1], depth + 1, stream);
-       }
-      if (depth)
-       {
-         for (i = 0; i < depth; i++)
-           fputs_filtered ("  ", stream);
-       }
-      fputs_filtered ("end\n", stream);
+      struct cleanup *cleanups = make_cleanup (clear_hook_in_cleanup, c);
+      c->hook_in = 1; /* Prevent recursive hooking */
+      execute_user_command (c->hook_post, (char *) 0);
+      do_cleanups (cleanups);
     }
 }
-#endif
 
 /* Execute the command in CMD.  */
+static void
+do_restore_user_call_depth (void * call_depth)
+{      
+  int * depth = call_depth;
+  /* We will be returning_to_top_level() at this point, so we want to
+     reset our depth. */
+  (*depth) = 0;
+}
+
 
 void
 execute_user_command (struct cmd_list_element *c, char *args)
 {
-  register struct command_line *cmdlines;
+  struct command_line *cmdlines;
   struct cleanup *old_chain;
   enum command_control_type ret;
+  static int user_call_depth = 0;
+  extern int max_user_call_depth;
 
   old_chain = setup_user_args (args);
 
@@ -311,6 +265,11 @@ execute_user_command (struct cmd_list_element *c, char *args)
     /* Null command */
     return;
 
+  if (++user_call_depth > max_user_call_depth)
+    error ("Max user call depth exceeded -- command aborted\n");
+
+  old_chain = make_cleanup (do_restore_user_call_depth, &user_call_depth);
+
   /* Set the instream to 0, indicating execution of a
      user-defined function.  */
   old_chain = make_cleanup (do_restore_instream_cleanup, instream);
@@ -326,6 +285,8 @@ execute_user_command (struct cmd_list_element *c, char *args)
       cmdlines = cmdlines->next;
     }
   do_cleanups (old_chain);
+
+  user_call_depth--;
 }
 
 enum command_control_type
@@ -333,21 +294,25 @@ execute_control_command (struct command_line *cmd)
 {
   struct expression *expr;
   struct command_line *current;
-  struct cleanup *old_chain = 0;
-  value_ptr val;
-  value_ptr val_mark;
+  struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
+  struct value *val;
+  struct value *val_mark;
   int loop;
   enum command_control_type ret;
   char *new_line;
 
+  /* Start by assuming failure, if a problem is detected, the code
+     below will simply "break" out of the switch.  */
+  ret = invalid_control;
+
   switch (cmd->control_type)
     {
     case simple_control:
       /* A simple command, execute it and return.  */
       new_line = insert_args (cmd->line);
       if (!new_line)
-       return invalid_control;
-      old_chain = make_cleanup (free_current_contents, &new_line);
+       break;
+      make_cleanup (free_current_contents, &new_line);
       execute_command (new_line, 0);
       ret = cmd->control_type;
       break;
@@ -364,8 +329,8 @@ execute_control_command (struct command_line *cmd)
        /* Parse the loop control expression for the while statement.  */
        new_line = insert_args (cmd->line);
        if (!new_line)
-         return invalid_control;
-       old_chain = make_cleanup (free_current_contents, &new_line);
+         break;
+       make_cleanup (free_current_contents, &new_line);
        expr = parse_expression (new_line);
        make_cleanup (free_current_contents, &expr);
 
@@ -424,8 +389,8 @@ execute_control_command (struct command_line *cmd)
       {
        new_line = insert_args (cmd->line);
        if (!new_line)
-         return invalid_control;
-       old_chain = make_cleanup (free_current_contents, &new_line);
+         break;
+       make_cleanup (free_current_contents, &new_line);
        /* Parse the conditional for the if statement.  */
        expr = parse_expression (new_line);
        make_cleanup (free_current_contents, &expr);
@@ -463,11 +428,10 @@ execute_control_command (struct command_line *cmd)
 
     default:
       warning ("Invalid control type in command structure.");
-      return invalid_control;
+      break;
     }
 
-  if (old_chain)
-    do_cleanups (old_chain);
+  do_cleanups (old_chain);
 
   return ret;
 }
@@ -721,7 +685,7 @@ read_next_line (struct command_line **command)
     error ("Control nesting too deep!\n");
 
   /* Set a prompt based on the nesting of the control commands.  */
-  if (instream == stdin || (instream == 0 && readline_hook != NULL))
+  if (instream == stdin || (instream == 0 && deprecated_readline_hook != NULL))
     {
       for (i = 0; i < control_level; i++)
        control_prompt[i] = ' ';
@@ -929,10 +893,10 @@ read_command_lines (char *prompt_arg, int from_tty)
   enum misc_command_type val;
 
   control_level = 0;
-  if (readline_begin_hook)
+  if (deprecated_readline_begin_hook)
     {
       /* Note - intentional to merge messages with no newline */
-      (*readline_begin_hook) ("%s  %s\n", prompt_arg, END_MESSAGE);
+      (*deprecated_readline_begin_hook) ("%s  %s\n", prompt_arg, END_MESSAGE);
     }
   else if (from_tty && input_from_terminal_p ())
     {
@@ -998,9 +962,9 @@ read_command_lines (char *prompt_arg, int from_tty)
        do_cleanups (old_chain);
     }
 
-  if (readline_end_hook)
+  if (deprecated_readline_end_hook)
     {
-      (*readline_end_hook) ();
+      (*deprecated_readline_end_hook) ();
     }
   return (head);
 }
@@ -1010,8 +974,8 @@ read_command_lines (char *prompt_arg, int from_tty)
 void
 free_command_lines (struct command_line **lptr)
 {
-  register struct command_line *l = *lptr;
-  register struct command_line *next;
+  struct command_line *l = *lptr;
+  struct command_line *next;
   struct command_line **blist;
   int i;
 
@@ -1037,16 +1001,46 @@ do_free_command_lines_cleanup (void *arg)
   free_command_lines (arg);
 }
 
-static struct cleanup *
+struct cleanup *
 make_cleanup_free_command_lines (struct command_line **arg)
 {
   return make_cleanup (do_free_command_lines_cleanup, arg);
 }
+
+struct command_line *
+copy_command_lines (struct command_line *cmds)
+{
+  struct command_line *result = NULL;
+
+  if (cmds)
+    {
+      result = (struct command_line *) xmalloc (sizeof (struct command_line));
+
+      result->next = copy_command_lines (cmds->next);
+      result->line = xstrdup (cmds->line);
+      result->control_type = cmds->control_type;
+      result->body_count = cmds->body_count;
+      if (cmds->body_count > 0)
+        {
+          int i;
+
+          result->body_list = (struct command_line **)
+            xmalloc (sizeof (struct command_line *) * cmds->body_count);
+
+          for (i = 0; i < cmds->body_count; i++)
+            result->body_list[i] = copy_command_lines (cmds->body_list[i]);
+        }
+      else
+        result->body_list = NULL;
+    }
+
+  return result;
+}
 \f
 static void
 validate_comname (char *comname)
 {
-  register char *p;
+  char *p;
 
   if (comname == 0)
     error_no_arg ("name of command to define");
@@ -1076,8 +1070,8 @@ define_command (char *comname, int from_tty)
       CMD_PRE_HOOK,
       CMD_POST_HOOK
     };
-  register struct command_line *cmds;
-  register struct cmd_list_element *c, *newc, *oldc, *hookc = 0;
+  struct command_line *cmds;
+  struct cmd_list_element *c, *newc, *oldc, *hookc = 0;
   char *tem = comname;
   char *tem2; 
   char tmpbuf[MAX_TMPBUF];
@@ -1093,16 +1087,17 @@ define_command (char *comname, int from_tty)
 
   /* Look it up, and verify that we got an exact match.  */
   c = lookup_cmd (&tem, cmdlist, "", -1, 1);
-  if (c && !STREQ (comname, c->name))
+  if (c && strcmp (comname, c->name) != 0)
     c = 0;
 
   if (c)
     {
+      int q;
       if (c->class == class_user || c->class == class_alias)
-       tem = "Redefine command \"%s\"? ";
+       q = query ("Redefine command \"%s\"? ", c->name);
       else
-       tem = "Really redefine built-in command \"%s\"? ";
-      if (!query (tem, c->name))
+       q = query ("Really redefine built-in command \"%s\"? ", c->name);
+      if (!q)
        error ("Command \"%s\" not redefined.", c->name);
     }
 
@@ -1126,7 +1121,7 @@ define_command (char *comname, int from_tty)
       /* Look up cmd it hooks, and verify that we got an exact match.  */
       tem = comname + hook_name_size;
       hookc = lookup_cmd (&tem, cmdlist, "", -1, 0);
-      if (hookc && !STREQ (comname + hook_name_size, hookc->name))
+      if (hookc && strcmp (comname + hook_name_size, hookc->name) != 0)
        hookc = 0;
       if (!hookc)
        {
@@ -1181,7 +1176,7 @@ void
 document_command (char *comname, int from_tty)
 {
   struct command_line *doclines;
-  register struct cmd_list_element *c;
+  struct cmd_list_element *c;
   char *tem = comname;
   char tmpbuf[128];
 
@@ -1199,8 +1194,8 @@ document_command (char *comname, int from_tty)
     xfree (c->doc);
 
   {
-    register struct command_line *cl1;
-    register int len = 0;
+    struct command_line *cl1;
+    int len = 0;
 
     for (cl1 = doclines; cl1; cl1 = cl1->next)
       len += strlen (cl1->line) + 1;
@@ -1228,7 +1223,7 @@ struct source_cleanup_lines_args
 };
 
 static void
-source_cleanup_lines (PTR args)
+source_cleanup_lines (void *args)
 {
   struct source_cleanup_lines_args *p =
   (struct source_cleanup_lines_args *) args;
@@ -1238,7 +1233,6 @@ source_cleanup_lines (PTR args)
   error_pre_print = p->old_error_pre_print;
 }
 
-/* ARGSUSED */
 static void
 do_fclose_cleanup (void *stream)
 {
@@ -1295,7 +1289,7 @@ script_from_file (FILE *stream, char *file)
 void
 show_user_1 (struct cmd_list_element *c, struct ui_file *stream)
 {
-  register struct command_line *cmdlines;
+  struct command_line *cmdlines;
 
   cmdlines = c->user_commands;
   if (!cmdlines)
@@ -1304,16 +1298,7 @@ show_user_1 (struct cmd_list_element *c, struct ui_file *stream)
   fputs_filtered (c->name, stream);
   fputs_filtered (":\n", stream);
 
-#ifdef UI_OUT
   print_command_lines (uiout, cmdlines, 1);
   fputs_filtered ("\n", stream);
-#else
-  while (cmdlines)
-    {
-      print_command_line (cmdlines, 4, stream);
-      cmdlines = cmdlines->next;
-    }
-  fputs_filtered ("\n", stream);
-#endif
 }
 
This page took 0.030291 seconds and 4 git commands to generate.