2008-05-03 Pedro Alves <pedro@codesourcery.com>
[binutils-gdb.git] / gdb / mi / mi-interp.c
index 96229a01d29a804d250a1751c3395f5459d3d075..8b0d9091c5b3db495eead22c99681675505510bd 100644 (file)
@@ -67,6 +67,7 @@ static void mi_insert_notify_hooks (void);
 static void mi_remove_notify_hooks (void);
 
 static void mi_new_thread (struct thread_info *t);
+static void mi_thread_exit (struct thread_info *t);
 
 static void *
 mi_interpreter_init (int top_level)
@@ -88,7 +89,10 @@ mi_interpreter_init (int top_level)
   mi->event_channel = mi_console_file_new (raw_stdout, "=", 0);
 
   if (top_level)
-    observer_attach_new_thread (mi_new_thread);
+    {
+      observer_attach_new_thread (mi_new_thread);
+      observer_attach_thread_exit (mi_thread_exit);
+    }
 
   return mi;
 }
@@ -168,9 +172,11 @@ mi_interpreter_prompt_p (void *data)
 }
 
 static void
-mi_interpreter_exec_continuation (struct continuation_arg *arg)
+mi_interpreter_exec_continuation (struct continuation_arg *arg, int error_p)
 {
   bpstat_do_actions (&stop_bpstat);
+  /* It's not clear what to do in the case of errror -- should we assume that
+     the target is stopped, or that it still runs?  */
   if (!target_executing)
     {
       fputs_unfiltered ("*stopped", raw_stdout);
@@ -178,7 +184,6 @@ mi_interpreter_exec_continuation (struct continuation_arg *arg)
       fputs_unfiltered ("\n", raw_stdout);
       fputs_unfiltered ("(gdb) \n", raw_stdout);
       gdb_flush (raw_stdout);
-      do_exec_cleanups (ALL_CLEANUPS);
     }
   else if (target_can_async_p ())
     {
@@ -190,29 +195,21 @@ enum mi_cmd_result
 mi_cmd_interpreter_exec (char *command, char **argv, int argc)
 {
   struct interp *interp_to_use;
-  enum mi_cmd_result result = MI_CMD_DONE;
   int i;
   struct interp_procs *procs;
+  char *mi_error_message = NULL;
+  struct cleanup *old_chain;
 
   if (argc < 2)
-    {
-      mi_error_message = xstrprintf ("mi_cmd_interpreter_exec: Usage: -interpreter-exec interp command");
-      return MI_CMD_ERROR;
-    }
+    error ("mi_cmd_interpreter_exec: Usage: -interpreter-exec interp command");
 
   interp_to_use = interp_lookup (argv[0]);
   if (interp_to_use == NULL)
-    {
-      mi_error_message = xstrprintf ("mi_cmd_interpreter_exec: could not find interpreter \"%s\"", argv[0]);
-      return MI_CMD_ERROR;
-    }
+    error ("mi_cmd_interpreter_exec: could not find interpreter \"%s\"", argv[0]);
 
   if (!interp_exec_p (interp_to_use))
-    {
-      mi_error_message = xstrprintf ("mi_cmd_interpreter_exec: interpreter \"%s\" does not support command execution",
-                                    argv[0]);
-      return MI_CMD_ERROR;
-    }
+    error ("mi_cmd_interpreter_exec: interpreter \"%s\" does not support command execution",
+             argv[0]);
 
   /* Insert the MI out hooks, making sure to also call the interpreter's hooks
      if it has any. */
@@ -222,25 +219,16 @@ mi_cmd_interpreter_exec (char *command, char **argv, int argc)
 
   /* Now run the code... */
 
+  old_chain = make_cleanup (null_cleanup, 0);
   for (i = 1; i < argc; i++)
     {
-      /* We had to set sync_execution = 0 for the mi (well really for Project
-         Builder's use of the mi - particularly so interrupting would work.
-         But for console commands to work, we need to initialize it to 1 -
-         since that is what the cli expects - before running the command,
-         and then set it back to 0 when we are done. */
-      sync_execution = 1;
-      {
-       struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
-       if (e.reason < 0)
-         {
-           mi_error_message = xstrdup (e.message);
-           result = MI_CMD_ERROR;
-           break;
-         }
-      }
-      do_exec_error_cleanups (ALL_CLEANUPS);
-      sync_execution = 0;
+      struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
+      if (e.reason < 0)
+       {
+         mi_error_message = xstrdup (e.message);
+         make_cleanup (xfree, mi_error_message);
+         break;
+       }
     }
 
   mi_remove_notify_hooks ();
@@ -256,7 +244,10 @@ mi_cmd_interpreter_exec (char *command, char **argv, int argc)
       add_continuation (mi_interpreter_exec_continuation, NULL);
     }
 
-  return result;
+  if (mi_error_message != NULL)
+    error ("%s", mi_error_message);
+  do_cleanups (old_chain);
+  return MI_CMD_DONE;
 }
 
 /*
@@ -326,7 +317,17 @@ mi_new_thread (struct thread_info *t)
 {
   struct mi_interp *mi = top_level_interpreter_data ();
 
-  fprintf_unfiltered (mi->event_channel, "thread-created,id=%d", t->num);
+  fprintf_unfiltered (mi->event_channel, "thread-created,id=\"%d\"", t->num);
+  gdb_flush (mi->event_channel);
+}
+
+static void
+mi_thread_exit (struct thread_info *t)
+{
+  struct mi_interp *mi = top_level_interpreter_data ();
+
+  target_terminal_ours ();
+  fprintf_unfiltered (mi->event_channel, "thread-exited,id=\"%d\"", t->num);
   gdb_flush (mi->event_channel);
 }