2003-06-08 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / mi / mi-main.c
index 41775922def89bbdb06c8a8c355b1b2a60a4f490..7ac56509dcf5d78a152f7a5b77e685e038b2b2b4 100644 (file)
@@ -1,5 +1,5 @@
 /* MI Command Set.
-   Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
    Contributed by Cygnus Solutions (a Red Hat company).
 
    This file is part of GDB.
 #include "mi-console.h"
 #include "ui-out.h"
 #include "mi-out.h"
+#include "interps.h"
 #include "event-loop.h"
 #include "event-top.h"
 #include "gdbcore.h"           /* for write_memory() */
-#include "value.h"             /* for write_register_bytes() */
+#include "value.h"             /* for deprecated_write_register_bytes() */
 #include "regcache.h"
 #include "gdb.h"
 #include "frame.h"
+#include "mi-main.h"
 
 #include <ctype.h>
 #include <sys/time.h>
@@ -79,27 +81,29 @@ struct ui_file *raw_stdout;
 /* The token of the last asynchronous command */
 static char *last_async_command;
 static char *previous_async_command;
-static char *mi_error_message;
+char *mi_error_message;
 static char *old_regs;
 
 extern void _initialize_mi_main (void);
-static char *mi_input (char *);
-static void mi_execute_command (char *cmd, int from_tty);
 static enum mi_cmd_result mi_cmd_execute (struct mi_parse *parse);
 
 static void mi_execute_cli_command (const char *cli, char *args);
 static enum mi_cmd_result mi_execute_async_cli_command (char *mi, char *args, int from_tty);
-static void mi_execute_command_wrapper (char *cmd);
 
-void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg);
+static void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg);
 
 static int register_changed_p (int regnum);
 static int get_register (int regnum, int format);
-static void mi_load_progress (const char *section_name,
-                             unsigned long sent_so_far,
-                             unsigned long total_section,
-                             unsigned long total_sent,
-                             unsigned long grand_total);
+
+/* A helper function which will set mi_error_message to
+   error_last_message.  */
+void
+mi_error_last_message (void)
+{
+  char *s = error_last_message ();
+  xasprintf (&mi_error_message, s);
+  xfree (s);
+}
 
 /* Command implementations. FIXME: Is this libgdb? No.  This is the MI
    layer that calls libgdb.  Any operation used in the below should be
@@ -183,9 +187,9 @@ mi_cmd_exec_return (char *args, int from_tty)
 
   /* Because we have called return_command with from_tty = 0, we need
      to print the frame here. */
-  show_and_print_stack_frame (selected_frame,
-                             frame_relative_level (selected_frame),
-                             LOC_AND_ADDRESS);
+  print_stack_frame (deprecated_selected_frame,
+                    frame_relative_level (deprecated_selected_frame),
+                    LOC_AND_ADDRESS);
 
   return MI_CMD_DONE;
 }
@@ -240,8 +244,12 @@ mi_cmd_thread_select (char *command, char **argv, int argc)
   else
     rc = gdb_thread_select (uiout, argv[0]);
 
-  if (rc == GDB_RC_FAIL)
+  /* RC is enum gdb_rc if it is successful (>=0)
+     enum return_reason if not (<0). */
+  if ((int) rc < 0 && (enum return_reason) rc == RETURN_ERROR)
     return MI_CMD_CAUGHT_ERROR;
+  else if ((int) rc >= 0 && rc == GDB_RC_FAIL)
+    return MI_CMD_ERROR;
   else
     return MI_CMD_DONE;
 }
@@ -391,9 +399,9 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
 static int
 register_changed_p (int regnum)
 {
-  char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+  char raw_buffer[MAX_REGISTER_SIZE];
 
-  if (! frame_register_read (selected_frame, regnum, raw_buffer))
+  if (! frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
     return -1;
 
   if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
@@ -504,9 +512,12 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc)
 static int
 get_register (int regnum, int format)
 {
-  char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
-  char *virtual_buffer = alloca (MAX_REGISTER_VIRTUAL_SIZE);
+  char raw_buffer[MAX_REGISTER_SIZE];
+  char virtual_buffer[MAX_REGISTER_SIZE];
   int optim;
+  int realnum;
+  CORE_ADDR addr;
+  enum lval_type lval;
   static struct ui_stream *stb = NULL;
 
   stb = ui_out_stream_new (uiout);
@@ -514,8 +525,9 @@ get_register (int regnum, int format)
   if (format == 'N')
     format = 0;
 
-  get_saved_register (raw_buffer, &optim, (CORE_ADDR *) NULL, selected_frame,
-                     regnum, (enum lval_type *) NULL);
+  frame_register (deprecated_selected_frame, regnum, &optim, &lval, &addr,
+                 &realnum, raw_buffer);
+
   if (optim)
     {
       xasprintf (&mi_error_message, "Optimized out");
@@ -526,7 +538,8 @@ get_register (int regnum, int format)
 
   if (REGISTER_CONVERTIBLE (regnum))
     {
-      REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
+      REGISTER_CONVERT_TO_VIRTUAL (regnum,
+                                  register_type (current_gdbarch, regnum),
                                   raw_buffer, virtual_buffer);
     }
   else
@@ -551,7 +564,7 @@ get_register (int regnum, int format)
     }
   else
     {
-      val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0, 0,
+      val_print (register_type (current_gdbarch, regnum), virtual_buffer, 0, 0,
                 stb->stream, format, 1, 0, Val_pretty_default);
       ui_out_field_stream (uiout, "value", stb);
       ui_out_stream_delete (stb);
@@ -624,11 +637,11 @@ mi_cmd_data_write_register_values (char *command, char **argv, int argc)
          /* Get the value as a number */
          value = parse_and_eval_address (argv[i + 1]);
          /* Get the value into an array */
-         buffer = xmalloc (REGISTER_SIZE);
+         buffer = xmalloc (DEPRECATED_REGISTER_SIZE);
          old_chain = make_cleanup (xfree, buffer);
-         store_signed_integer (buffer, REGISTER_SIZE, value);
+         store_signed_integer (buffer, DEPRECATED_REGISTER_SIZE, value);
          /* Write it down */
-         write_register_bytes (REGISTER_BYTE (regnum), buffer, REGISTER_RAW_SIZE (regnum));
+         deprecated_write_register_bytes (REGISTER_BYTE (regnum), buffer, REGISTER_RAW_SIZE (regnum));
          /* Free the buffer.  */
          do_cleanups (old_chain);
        }
@@ -911,19 +924,22 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc)
   /* Build the result as a two dimentional table. */
   {
     struct ui_stream *stream = ui_out_stream_new (uiout);
+    struct cleanup *cleanup_list_memory;
     int row;
     int row_byte;
-    ui_out_list_begin (uiout, "memory");
+    cleanup_list_memory = make_cleanup_ui_out_list_begin_end (uiout, "memory");
     for (row = 0, row_byte = 0;
         row < nr_rows;
         row++, row_byte += nr_cols * word_size)
       {
        int col;
        int col_byte;
-       ui_out_tuple_begin (uiout, NULL);
+       struct cleanup *cleanup_tuple;
+       struct cleanup *cleanup_list_data;
+       cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
        ui_out_field_core_addr (uiout, "addr", addr + row_byte);
        /* ui_out_field_core_addr_symbolic (uiout, "saddr", addr + row_byte); */
-       ui_out_list_begin (uiout, "data");
+       cleanup_list_data = make_cleanup_ui_out_list_begin_end (uiout, "data");
        for (col = 0, col_byte = row_byte;
             col < nr_cols;
             col++, col_byte += word_size)
@@ -940,7 +956,7 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc)
                ui_out_field_stream (uiout, NULL, stream);
              }
          }
-       ui_out_list_end (uiout);
+       do_cleanups (cleanup_list_data);
        if (aschar)
          {
            int byte;
@@ -960,10 +976,10 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc)
              }
            ui_out_field_stream (uiout, "ascii", stream);
          }
-       ui_out_tuple_end (uiout);
+       do_cleanups (cleanup_tuple);
       }
     ui_out_stream_delete (stream);
-    ui_out_list_end (uiout);
+    do_cleanups (cleanup_list_memory);
   }
   do_cleanups (cleanups);
   return MI_CMD_DONE;
@@ -1090,7 +1106,12 @@ captured_mi_execute_command (struct ui_out *uiout, void *data)
 
       if (!target_can_async_p () || !target_executing)
        {
-         /* print the result if there were no errors */
+         /* print the result if there were no errors
+
+            Remember that on the way out of executing a command, you have
+            to directly use the mi_interp's uiout, since the command could 
+            have reset the interpreter, in which case the current uiout 
+            will most likely crash in the mi_out_* routines.  */
          if (args->rc == MI_CMD_DONE)
            {
              fputs_unfiltered (context->token, raw_stdout);
@@ -1138,15 +1159,21 @@ captured_mi_execute_command (struct ui_out *uiout, void *data)
       /* FIXME: If the command string has something that looks like 
          a format spec (e.g. %s) we will get a core dump */
       mi_execute_cli_command ("%s", context->command);
-      /* print the result */
-      /* FIXME: Check for errors here. */
-      fputs_unfiltered (context->token, raw_stdout);
-      fputs_unfiltered ("^done", raw_stdout);
-      mi_out_put (uiout, raw_stdout);
-      mi_out_rewind (uiout);
-      fputs_unfiltered ("\n", raw_stdout);
-      args->action = EXECUTE_COMMAND_DISPLAY_PROMPT;
-      args->rc = MI_CMD_DONE;
+
+      /* If we changed interpreters, DON'T print out anything. */
+      if (current_interp_named_p (INTERP_MI)
+         || current_interp_named_p (INTERP_MI1))
+       {
+         /* print the result */
+         /* FIXME: Check for errors here. */
+         fputs_unfiltered (context->token, raw_stdout);
+         fputs_unfiltered ("^done", raw_stdout);
+         mi_out_put (uiout, raw_stdout);
+         mi_out_rewind (uiout);
+         fputs_unfiltered ("\n", raw_stdout);
+         args->action = EXECUTE_COMMAND_DISPLAY_PROMPT;
+         args->rc = MI_CMD_DONE;
+       }
       break;
 
     }
@@ -1161,7 +1188,7 @@ mi_execute_command (char *cmd, int from_tty)
   struct mi_parse *command;
   struct captured_mi_execute_command_args args;
   struct ui_out *saved_uiout = uiout;
-  int result, rc;
+  int result;
 
   /* This is to handle EOF (^D). We just quit gdb. */
   /* FIXME: we should call some API function here. */
@@ -1269,12 +1296,6 @@ mi_cmd_execute (struct mi_parse *parse)
     }
 }
 
-static void
-mi_execute_command_wrapper (char *cmd)
-{
-  mi_execute_command (cmd, stdin == instream);
-}
-
 /* FIXME: This is just a hack so we can get some extra commands going.
    We don't want to channel things through the CLI, but call libgdb directly */
 /* Use only for synchronous commands */
@@ -1377,13 +1398,7 @@ mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg)
   do_exec_cleanups (ALL_CLEANUPS);
 }
 
-static char *
-mi_input (char *buf)
-{
-  return gdb_readline (NULL);
-}
-
-static void
+void
 mi_load_progress (const char *section_name,
                  unsigned long sent_so_far,
                  unsigned long total_section,
@@ -1395,7 +1410,8 @@ mi_load_progress (const char *section_name,
   static char *previous_sect_name = NULL;
   int new_section;
 
-  if (!interpreter_p || strncmp (interpreter_p, "mi", 2) != 0)
+  if (!current_interp_named_p (INTERP_MI)
+      && !current_interp_named_p (INTERP_MI1))
     return;
 
   update_threshold.tv_sec = 0;
@@ -1415,17 +1431,18 @@ mi_load_progress (const char *section_name,
                 strcmp (previous_sect_name, section_name) : 1);
   if (new_section)
     {
+      struct cleanup *cleanup_tuple;
       xfree (previous_sect_name);
       previous_sect_name = xstrdup (section_name);
 
       if (last_async_command)
        fputs_unfiltered (last_async_command, raw_stdout);
       fputs_unfiltered ("+download", raw_stdout);
-      ui_out_tuple_begin (uiout, NULL);
+      cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
       ui_out_field_string (uiout, "section", section_name);
       ui_out_field_int (uiout, "section-size", total_section);
       ui_out_field_int (uiout, "total-size", grand_total);
-      ui_out_tuple_end (uiout);
+      do_cleanups (cleanup_tuple);
       mi_out_put (uiout, raw_stdout);
       fputs_unfiltered ("\n", raw_stdout);
       gdb_flush (raw_stdout);
@@ -1434,137 +1451,36 @@ mi_load_progress (const char *section_name,
   if (delta.tv_sec >= update_threshold.tv_sec &&
       delta.tv_usec >= update_threshold.tv_usec)
     {
+      struct cleanup *cleanup_tuple;
       last_update.tv_sec = time_now.tv_sec;
       last_update.tv_usec = time_now.tv_usec;
       if (last_async_command)
        fputs_unfiltered (last_async_command, raw_stdout);
       fputs_unfiltered ("+download", raw_stdout);
-      ui_out_tuple_begin (uiout, NULL);
+      cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
       ui_out_field_string (uiout, "section", section_name);
       ui_out_field_int (uiout, "section-sent", sent_so_far);
       ui_out_field_int (uiout, "section-size", total_section);
       ui_out_field_int (uiout, "total-sent", total_sent);
       ui_out_field_int (uiout, "total-size", grand_total);
-      ui_out_tuple_end (uiout);
+      do_cleanups (cleanup_tuple);
       mi_out_put (uiout, raw_stdout);
       fputs_unfiltered ("\n", raw_stdout);
       gdb_flush (raw_stdout);
     }
 }
 
-static void
-mi_command_loop (int mi_version)
-{
-  /* HACK: Force stdout/stderr to point at the console.  This avoids
-     any potential side effects caused by legacy code that is still
-     using the TUI / fputs_unfiltered_hook */
-  raw_stdout = stdio_fileopen (stdout);
-  /* Route normal output through the MIx */
-  gdb_stdout = mi_console_file_new (raw_stdout, "~");
-  /* Route error and log output through the MI */
-  gdb_stderr = mi_console_file_new (raw_stdout, "&");
-  gdb_stdlog = gdb_stderr;
-  /* Route target output through the MI. */
-  gdb_stdtarg = mi_console_file_new (raw_stdout, "@");
-
-  /* HACK: Poke the ui_out table directly.  Should we be creating a
-     mi_out object wired up to the above gdb_stdout / gdb_stderr? */
-  uiout = mi_out_new (mi_version);
-
-  /* HACK: Override any other interpreter hooks.  We need to create a
-     real event table and pass in that. */
-  init_ui_hook = 0;
-  /* command_loop_hook = 0; */
-  print_frame_info_listing_hook = 0;
-  query_hook = 0;
-  warning_hook = 0;
-  create_breakpoint_hook = 0;
-  delete_breakpoint_hook = 0;
-  modify_breakpoint_hook = 0;
-  interactive_hook = 0;
-  registers_changed_hook = 0;
-  readline_begin_hook = 0;
-  readline_hook = 0;
-  readline_end_hook = 0;
-  register_changed_hook = 0;
-  memory_changed_hook = 0;
-  context_hook = 0;
-  target_wait_hook = 0;
-  call_command_hook = 0;
-  error_hook = 0;
-  error_begin_hook = 0;
-  show_load_progress = mi_load_progress;
-
-  /* Turn off 8 bit strings in quoted output.  Any character with the
-     high bit set is printed using C's octal format. */
-  sevenbit_strings = 1;
-
-  /* Tell the world that we're alive */
-  fputs_unfiltered ("(gdb) \n", raw_stdout);
-  gdb_flush (raw_stdout);
-
-  if (!event_loop_p)
-    simplified_command_loop (mi_input, mi_execute_command);
-  else
-    start_event_loop ();
-}
-
-static void
-mi1_command_loop (void)
-{
-  mi_command_loop (1);
-}
-
-static void
-mi2_command_loop (void)
-{
-  mi_command_loop (2);
-}
-
-static void
-setup_architecture_data (void)
-{
-  /* don't trust REGISTER_BYTES to be zero. */
-  old_regs = xmalloc (REGISTER_BYTES + 1);
-  memset (old_regs, 0, REGISTER_BYTES + 1);
-}
-
-static void
-mi_init_ui (char *arg0)
+void
+mi_setup_architecture_data (void)
 {
-  /* Eventually this will contain code that takes control of the
-     console. */
+  /* don't trust DEPRECATED_REGISTER_BYTES to be zero. */
+  old_regs = xmalloc (DEPRECATED_REGISTER_BYTES + 1);
+  memset (old_regs, 0, DEPRECATED_REGISTER_BYTES + 1);
 }
 
 void
 _initialize_mi_main (void)
 {
-  if (interpreter_p == NULL)
-    return;
-
-  /* If we're _the_ interpreter, take control. */
-  if (strcmp (interpreter_p, "mi") == 0)
-    command_loop_hook = mi2_command_loop;
-  else if (strcmp (interpreter_p, "mi1") == 0)
-    command_loop_hook = mi1_command_loop;
-  else if (strcmp (interpreter_p, "mi2") == 0)
-    command_loop_hook = mi2_command_loop;
-  else
-    return;
-
-  init_ui_hook = mi_init_ui;
-  setup_architecture_data ();
   register_gdbarch_swap (&old_regs, sizeof (old_regs), NULL);
-  register_gdbarch_swap (NULL, 0, setup_architecture_data);
-  if (event_loop_p)
-    {
-      /* These overwrite some of the initialization done in
-        _intialize_event_loop. */
-      call_readline = gdb_readline2;
-      input_handler = mi_execute_command_wrapper;
-      add_file_handler (input_fd, stdin_event_handler, 0);
-      async_command_editing_p = 0;
-    }
-  /* FIXME: Should we notify main that we are here as a possible
-     interpreter? */
+  register_gdbarch_swap (NULL, 0, mi_setup_architecture_data);
 }
This page took 0.032353 seconds and 4 git commands to generate.