import gdb-1999-07-07 post reformat
[deliverable/binutils-gdb.git] / gdb / top.c
index 2aff8d429e0cfb4e593e24faf47d166d7664844c..12b63754b8b3d90e1e0b23b7f60e77635fceb998 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1,5 +1,5 @@
 /* Top level stuff for GDB, the GNU debugger.
-   Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+   Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
    Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -32,7 +32,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "language.h"
 #include "terminal.h" /* For job_control.  */
 #include "annotate.h"
-#include <setjmp.h>
 #include "top.h"
 
 /* readline include files */
@@ -47,12 +46,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include <unistd.h>
 #endif
 
+#include "event-loop.h"
 #include "gdb_string.h"
 #include "gdb_stat.h"
 #include <ctype.h>
 
-extern void initialize_utils PARAMS ((void));
-
 /* Prototypes for local functions */
 
 static void dont_repeat_command PARAMS ((char *, int));
@@ -71,7 +69,10 @@ static char * line_completion_function PARAMS ((char *, int, char *, int));
 
 static char * readline_line_completion_function PARAMS ((char *, int));
 
-static void command_loop_marker PARAMS ((int));
+/* NOTE 1999-04-29: this function will be static again, after we make the
+   event loop be the default command loop for gdb, and we merge
+   event-top.c into this file, top.c */
+/* static */ void command_loop_marker PARAMS ((int));
 
 static void while_command PARAMS ((char *, int));
 
@@ -140,7 +141,10 @@ static void complete_command PARAMS ((char *, int));
 static void do_nothing PARAMS ((int));
 
 #ifdef SIGHUP
-static int quit_cover PARAMS ((PTR));
+/* NOTE 1999-04-29: This function will be static again, once we modify
+   gdb to use the event loop as the default command loop and we merge
+   event-top.c into this file, top.c */
+/* static */ int quit_cover PARAMS ((PTR));
 
 static void disconnect PARAMS ((int));
 #endif
@@ -245,21 +249,15 @@ struct cmd_list_element *unsethistlist;
 
 /* Chain containing all defined maintenance subcommands. */
 
-#if MAINTENANCE_CMDS
 struct cmd_list_element *maintenancelist;
-#endif
 
 /* Chain containing all defined "maintenance info" subcommands. */
 
-#if MAINTENANCE_CMDS
 struct cmd_list_element *maintenanceinfolist;
-#endif
 
 /* Chain containing all defined "maintenance print" subcommands. */
 
-#if MAINTENANCE_CMDS
 struct cmd_list_element *maintenanceprintlist;
-#endif
 
 struct cmd_list_element *setprintlist;
 
@@ -292,7 +290,8 @@ int epoch_interface;
 int xgdb_verbose;
 
 /* gdb prints this when reading a command interactively */
-static char *prompt;
+static char *gdb_prompt_string;                /* the global prompt string */
+extern char *get_prompt PARAMS((void));        /* access function for prompt string */
 
 /* Buffer used for reading command lines, and the size
    allocated for it so far.  */
@@ -323,6 +322,12 @@ int remote_timeout = 20;   /* Set default to 20 */
 
 int remote_debug = 0;
 
+/* Non-zero means the target is running. Note: this is different from
+   saying that there is an active target and we are stopped at a
+   breakpoint, for instance. This is a real indicator whether the
+   target is off and running, which gdb is doing something else. */
+int target_executing = 0;
+
 /* Level of control structure.  */
 static int control_level;
 
@@ -367,9 +372,12 @@ static void stop_sig PARAMS ((int));
    command file.  */
 
 void (*init_ui_hook) PARAMS ((char *argv0));
-#ifdef __CYGWIN__
-void (*ui_loop_hook) PARAMS ((int));
-#endif
+
+/* This hook is called from within gdb's many mini-event loops which could
+   steal control from a real user interface's event loop. It returns
+   non-zero if the user is requesting a detach, zero otherwise. */
+
+int (*ui_loop_hook) PARAMS ((int));
 
 /* Called instead of command_loop at top level.  Can be invoked via
    return_to_top_level.  */
@@ -381,11 +389,6 @@ void (*command_loop_hook) PARAMS ((void));
 
 void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, GDB_FILE *stream));
 
-/* Called when the target says something to the host, which may
-   want to appear in a different window. */
-
-void (*target_output_hook) PARAMS ((char *));
-
 /* Called from print_frame_info to list the line we stopped in.  */
 
 void (*print_frame_info_listing_hook) PARAMS ((struct symtab *s, int line,
@@ -434,8 +437,13 @@ void (*interactive_hook) PARAMS ((void));
 
 void (*registers_changed_hook) PARAMS ((void));
 
-/* tell the GUI someone changed the PC */
-void (*pc_changed_hook) PARAMS ((void));
+/* Tell the GUI someone changed the register REGNO. -1 means
+   that the caller does not know which register changed or
+   that several registers have changed (see value_assign).*/
+void (*register_changed_hook) PARAMS ((int regno));
+
+/* Tell the GUI someone changed LEN bytes of memory at ADDR */
+void (*memory_changed_hook) PARAMS ((CORE_ADDR addr, int len));
 
 /* Called when going to wait for the target.  Usually allows the GUI to run
    while waiting for target events.  */
@@ -479,6 +487,8 @@ return_to_top_level (reason)
 
   disable_current_display ();
   do_cleanups (ALL_CLEANUPS);
+  if (async_p && target_has_async)
+    do_exec_cleanups (ALL_CLEANUPS);
 
   if (annotation_level > 1)
     switch (reason)
@@ -585,7 +595,10 @@ int signo;
 
 /* Just a little helper function for disconnect().  */
 
-static int
+/* NOTE 1999-04-29: This function will be static again, once we modify
+   gdb to use the event loop as the default command loop and we merge
+   event-top.c into this file, top.c */
+/* static */ int
 quit_cover (s)
      PTR s;
 {
@@ -597,19 +610,31 @@ quit_cover (s)
 #endif /* defined SIGHUP */
 \f
 /* Line number we are currently in in a file which is being sourced.  */
-static int source_line_number;
+/* NOTE 1999-04-29: This variable will be static again, once we modify
+   gdb to use the event loop as the default command loop and we merge
+   event-top.c into this file, top.c */
+/* static */ int source_line_number;
 
 /* Name of the file we are sourcing.  */
-static char *source_file_name;
+/* NOTE 1999-04-29: This variable will be static again, once we modify
+   gdb to use the event loop as the default command loop and we merge
+   event-top.c into this file, top.c */
+/* static */ char *source_file_name;
 
 /* Buffer containing the error_pre_print used by the source stuff.
    Malloc'd.  */
-static char *source_error;
+/* NOTE 1999-04-29: This variable will be static again, once we modify
+   gdb to use the event loop as the default command loop and we merge
+   event-top.c into this file, top.c */
+/* static */ char *source_error;
 static int source_error_allocated;
 
 /* Something to glom on to the start of error_pre_print if source_file_name
    is set.  */
-static char *source_pre_error;
+/* NOTE 1999-04-29: This variable will be static again, once we modify
+   gdb to use the event loop as the default command loop and we merge
+   event-top.c into this file, top.c */
+/* static */ char *source_pre_error;
 
 /* Clean up on error during a "source" command (or execution of a
    user-defined command).  */
@@ -631,7 +656,7 @@ read_command_file (stream)
 
   cleanups = make_cleanup ((make_cleanup_func) source_cleanup, instream);
   instream = stream;
-  command_loop ();
+  command_loop (); 
   do_cleanups (cleanups);
 }
 \f
@@ -656,9 +681,15 @@ gdb_init (argv0)
   initialize_utils (); /* Make errors and warnings possible */
   initialize_all_files ();
   init_main ();                /* But that omits this file!  Do it now */
-  init_signals ();
 
-  init_proc ();
+  /* The signal handling mechanism is different depending whether or
+     not the async version is run. NOTE: in the future we plan to make
+     the event loop be the default engine of gdb, and this difference
+     will disappear. */
+  if (async_p)
+    async_init_signals ();
+  else
+    init_signals (); 
 
   /* We need a default language for parsing expressions, so simple things like
      "set width 0" won't fail if no language is explicitly set in a config file
@@ -666,6 +697,8 @@ gdb_init (argv0)
   set_language (language_c);
   expected_language = current_language;        /* don't warn about the change.  */
 
+  /* All the interpreters should have had a look at things by now.
+     Initialize the selected interpreter. */
   if (init_ui_hook)
     init_ui_hook (argv0);
 }
@@ -726,23 +759,24 @@ get_command_line (type, arg)
 
 /* Recursively print a command (including full control structures).  */
 void
-print_command_line (cmd, depth)
+print_command_line (cmd, depth, stream)
      struct command_line *cmd;
      unsigned int depth;
+     GDB_FILE *stream;
 {
   unsigned int i;
 
   if (depth)
     {
       for (i = 0; i < depth; i++)
-       fputs_filtered ("  ", gdb_stdout);
+       fputs_filtered ("  ", stream);
     }
 
   /* A simple command, print it and return.  */
   if (cmd->control_type == simple_control)
     {
-      fputs_filtered (cmd->line, gdb_stdout);
-      fputs_filtered ("\n", gdb_stdout);
+      fputs_filtered (cmd->line, stream);
+      fputs_filtered ("\n", stream);
       return;
     }
 
@@ -750,14 +784,14 @@ print_command_line (cmd, depth)
      and return. */
   if (cmd->control_type == continue_control)
     {
-      fputs_filtered ("loop_continue\n", gdb_stdout);
+      fputs_filtered ("loop_continue\n", stream);
       return;
     }
 
   /* loop_break to break out of a while loop, print it and return.  */
   if (cmd->control_type == break_control)
     {
-      fputs_filtered ("loop_break\n", gdb_stdout);
+      fputs_filtered ("loop_break\n", stream);
       return;
     }
 
@@ -765,13 +799,13 @@ print_command_line (cmd, depth)
   if (cmd->control_type == while_control)
     {
       struct command_line *list;
-      fputs_filtered ("while ", gdb_stdout);
-      fputs_filtered (cmd->line, gdb_stdout);
-      fputs_filtered ("\n", gdb_stdout);
+      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);
+         print_command_line (list, depth + 1, stream);
          list = list->next;
        }
     }
@@ -779,11 +813,11 @@ print_command_line (cmd, depth)
   /* An if command.  Recursively print both arms before returning.  */
   if (cmd->control_type == if_control)
     {
-      fputs_filtered ("if ", gdb_stdout);
-      fputs_filtered (cmd->line, gdb_stdout);
-      fputs_filtered ("\n", gdb_stdout);
+      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);
+      print_command_line (cmd->body_list[0], depth + 1, stream);
 
       /* Show the false arm if it exists.  */
       if (cmd->body_count == 2)
@@ -791,17 +825,17 @@ print_command_line (cmd, depth)
            if (depth)
              {
                for (i = 0; i < depth; i++)
-                 fputs_filtered ("  ", gdb_stdout);
+                 fputs_filtered ("  ", stream);
              }
-           fputs_filtered ("else\n", gdb_stdout);
-           print_command_line (cmd->body_list[1], depth + 1);
+           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 ("  ", gdb_stdout);
+           fputs_filtered ("  ", stream);
        }
-      fputs_filtered ("end\n", gdb_stdout);
+      fputs_filtered ("end\n", stream);
     }
 }
 
@@ -1235,6 +1269,16 @@ execute_command (p, from_tty)
       char *arg;
 
       c = lookup_cmd (&p, cmdlist, "", 0, 1);
+
+      /* If the target is running, we allow only a limited set of
+         commands. */
+      if (async_p && target_has_async && target_executing)
+       if (!strcmp (c->name, "help")
+           && !strcmp (c->name, "pwd")
+           && !strcmp (c->name, "show")
+           && !strcmp (c->name, "stop"))
+         error ("Cannot execute this command while the target is running.");
+
       /* Pass null arg rather than an empty one.  */
       arg = *p ? p : 0;
 
@@ -1292,7 +1336,10 @@ execute_command (p, from_tty)
 }
 
 /* ARGSUSED */
-static void
+/* NOTE 1999-04-29: This function will be static again, once we modify
+   gdb to use the event loop as the default command loop and we merge
+   event-top.c into this file, top.c */
+/* static */ void
 command_loop_marker (foo)
      int foo;
 {
@@ -1320,7 +1367,7 @@ command_loop ()
       extern int insert_mode;
 #endif
       if (window_hook && instream == stdin)
-       (*window_hook) (instream, prompt);
+       (*window_hook) (instream, get_prompt ());
 
       quit_flag = 0;
       if (instream == stdin && stdin_is_tty)
@@ -1337,7 +1384,8 @@ command_loop ()
       insert_mode = 0;
 #endif
       /* Get a command-line. This calls the readline package. */
-      command = command_line_input (instream == stdin ? prompt : (char *) NULL,
+      command = command_line_input (instream == stdin ? 
+                                   get_prompt () : (char *) NULL,
                                    instream == stdin, "prompt");
 #if defined(TUI)
       insert_mode = 0;
@@ -1386,6 +1434,7 @@ command_loop ()
        }
     }
 }
+
 \f
 /* Commands call this if they do not want to be repeated by null lines.  */
 
@@ -1404,26 +1453,26 @@ dont_repeat ()
 \f
 /* Read a line from the stream "instream" without command line editing.
 
-   It prints PRROMPT once at the start.
+   It prints PROMPT_ARG once at the start.
    Action is compatible with "readline", e.g. space for the result is
    malloc'd and should be freed by the caller.
 
    A NULL return means end of file.  */
 char *
-gdb_readline (prrompt)
-     char *prrompt;
+gdb_readline (prompt_arg)
+     char *prompt_arg;
 {
   int c;
   char *result;
   int input_index = 0;
   int result_size = 80;
 
-  if (prrompt)
+  if (prompt_arg)
     {
       /* Don't use a _filtered function here.  It causes the assumed
         character position to be off, since the newline we read from
         the user is not accounted for.  */
-      fputs_unfiltered (prrompt, gdb_stdout);
+      fputs_unfiltered (prompt_arg, gdb_stdout);
 #ifdef MPW
       /* Move to a new line so the entered line doesn't have a prompt
         on the front of it. */
@@ -1478,7 +1527,10 @@ gdb_readline (prrompt)
    substitution.  These variables are given default values at the end
    of this file.  */
 static int command_editing_p;
-static int history_expansion_p;
+/* NOTE 1999-04-29: This variable will be static again, once we modify
+   gdb to use the event loop as the default command loop and we merge
+   event-top.c into this file, top.c */
+/* static */ int history_expansion_p;
 static int write_history_p;
 static int history_size;
 static char *history_filename;
@@ -1930,7 +1982,7 @@ int signo;
 #else
   signal (STOP_SIGNAL, stop_sig);
 #endif
-  printf_unfiltered ("%s", prompt);
+  printf_unfiltered ("%s", get_prompt ());
   gdb_flush (gdb_stdout);
 
   /* Forget about any previous command -- null line now will do nothing.  */
@@ -1999,8 +2051,8 @@ init_signals ()
    simple input as the user has requested.  */
 
 char *
-command_line_input (prrompt, repeat, annotation_suffix)
-     char *prrompt;
+command_line_input (prompt_arg, repeat, annotation_suffix)
+     char *prompt_arg;
      int repeat;
      char *annotation_suffix;
 {
@@ -2009,7 +2061,7 @@ command_line_input (prrompt, repeat, annotation_suffix)
   register char *p;
   char *p1;
   char *rl;
-  char *local_prompt = prrompt;
+  char *local_prompt = prompt_arg;
   char *nline;
   char got_eof = 0;
 
@@ -2019,12 +2071,12 @@ command_line_input (prrompt, repeat, annotation_suffix)
 
   if (annotation_level > 1 && instream == stdin)
     {
-      local_prompt = alloca ((prrompt == NULL ? 0 : strlen (prrompt))
+      local_prompt = alloca ((prompt_arg == NULL ? 0 : strlen (prompt_arg))
                             + strlen (annotation_suffix) + 40);
-      if (prrompt == NULL)
+      if (prompt_arg == NULL)
        local_prompt[0] = '\0';
       else
-       strcpy (local_prompt, prrompt);
+       strcpy (local_prompt, prompt_arg);
       strcat (local_prompt, "\n\032\032");
       strcat (local_prompt, annotation_suffix);
       strcat (local_prompt, "\n");
@@ -2043,7 +2095,12 @@ command_line_input (prrompt, repeat, annotation_suffix)
   immediate_quit++;
 #ifdef STOP_SIGNAL
   if (job_control)
-    signal (STOP_SIGNAL, stop_sig);
+    {
+      if (async_p)
+       signal (STOP_SIGNAL, handle_stop_sig);
+      else
+       signal (STOP_SIGNAL, stop_sig);
+    }
 #endif
 
   while (1)
@@ -2160,7 +2217,7 @@ command_line_input (prrompt, repeat, annotation_suffix)
          if (expanded < 0)
            {
              free (history_value);
-             return command_line_input (prrompt, repeat, annotation_suffix);
+             return command_line_input (prompt_arg, repeat, annotation_suffix);
            }
          if (strlen (history_value) > linelength)
            {
@@ -2457,23 +2514,24 @@ recurse_read_control_structure (current_cmd)
 #define END_MESSAGE "End with a line saying just \"end\"."
 
 struct command_line *
-read_command_lines (prompt, from_tty)
-char *prompt;
-int from_tty;
+read_command_lines (prompt_arg, from_tty)
+     char *prompt_arg;
+     int from_tty;
 {
   struct command_line *head, *tail, *next;
   struct cleanup *old_chain;
   enum command_control_type ret;
   enum misc_command_type val;
 
+  control_level = 0; 
   if (readline_begin_hook)
     {
       /* Note - intentional to merge messages with no newline */
-      (*readline_begin_hook) ("%s  %s\n", prompt, END_MESSAGE);
+      (*readline_begin_hook) ("%s  %s\n", prompt_arg, END_MESSAGE);
     }
   else if (from_tty && input_from_terminal_p ())
     {
-      printf_unfiltered ("%s\n%s\n", prompt, END_MESSAGE);
+      printf_unfiltered ("%s\n%s\n", prompt_arg, END_MESSAGE);
       gdb_flush (gdb_stdout);
     }
 
@@ -2764,7 +2822,6 @@ define_command (comname, from_tty)
   for (tem = comname; *tem; tem++)
     if (isupper(*tem)) *tem = tolower(*tem);
 
-  control_level = 0;
   sprintf (tmpbuf, "Type commands for definition of \"%s\".", comname);
   cmds = read_command_lines (tmpbuf, from_tty);
 
@@ -2880,22 +2937,266 @@ show_version (args, from_tty)
   immediate_quit--;
 }
 \f
-/* xgdb calls this to reprint the usual GDB prompt.  Obsolete now that xgdb
-   is obsolete.  */
+/* get_prompt: access method for the GDB prompt string.  */
 
-void
-print_prompt ()
+#define MAX_PROMPT_SIZE 256
+
+/*
+ * int get_prompt_1 (char * buf);
+ *
+ * Work-horse for get_prompt (called via catch_errors).
+ * Argument is buffer to hold the formatted prompt.
+ *
+ * Returns: 1 for success (use formatted prompt)
+ *          0 for failure (use gdb_prompt_string).
+ */ 
+
+static int gdb_prompt_escape;
+
+static int
+get_prompt_1 (formatted_prompt)
+     char *formatted_prompt;
 {
-  printf_unfiltered ("%s", prompt);
-  gdb_flush (gdb_stdout);
+  char *local_prompt;
+
+  if (async_p)
+    local_prompt = PROMPT (0);
+  else
+    local_prompt = gdb_prompt_string;
+
+
+  if (gdb_prompt_escape == 0)
+    {
+      return 0;                /* do no formatting */
+    }
+  else /* formatted prompt */
+    {
+      char   fmt[40], *promptp, *outp, *tmp;
+      value_ptr arg_val;
+      DOUBLEST  doubleval;
+      LONGEST   longval;
+      CORE_ADDR addrval;
+
+      int i, len;
+      struct type *arg_type, *elt_type;
+
+      promptp = local_prompt;
+      outp    = formatted_prompt;
+
+      while (*promptp != '\0')
+       {
+         int available = MAX_PROMPT_SIZE - (outp - formatted_prompt) - 1;
+
+         if (*promptp != gdb_prompt_escape)
+           {
+             if (available >= 1)                       /* overflow protect */
+               *outp++ = *promptp++;
+           }
+         else
+           {
+             /* GDB prompt string contains escape char.  Parse for arg.
+                Two consecutive escape chars followed by arg followed by
+                a comma means to insert the arg using a default format.
+                Otherwise a printf format string may be included between
+                the two escape chars.  eg:
+                  %%foo,       insert foo using default format
+                  %2.2f%foo,   insert foo using "%2.2f" format
+                A mismatch between the format string and the data type
+                of "foo" is an error (which we don't know how to protect
+                against).  */
+
+             fmt[0] = '\0';    /* assume null format string */
+             if (promptp[1] == gdb_prompt_escape)      /* double esc char */
+               {
+                 promptp += 2; /* skip past two escape chars. */
+               }
+             else
+               {
+                 /* extract format string from between two esc chars */
+                 i = 0;
+                 do {
+                   fmt[i++] = *promptp++;      /* copy format string */
+                 } while (i < sizeof (fmt) - 1 && 
+                          *promptp != gdb_prompt_escape &&
+                          *promptp != '\0');
+
+                 if (*promptp != gdb_prompt_escape)
+                   error ("Syntax error at prompt position %d",
+                          promptp - local_prompt);
+                 else
+                   {
+                     promptp++;        /* skip second escape char */
+                     fmt[i++] = '\0';  /* terminate the format string */
+                   }
+               }
+
+             arg_val = parse_to_comma_and_eval (&promptp);
+             if (*promptp == ',')
+               promptp++;              /* skip past the comma */
+             arg_type = check_typedef (VALUE_TYPE (arg_val));
+             switch (TYPE_CODE (arg_type)) 
+               {
+               case TYPE_CODE_ARRAY:
+                 elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
+                 if (TYPE_LENGTH (arg_type) > 0  &&
+                     TYPE_LENGTH (elt_type) == 1 &&
+                     TYPE_CODE (elt_type) == TYPE_CODE_INT)
+                   {
+                     int len = TYPE_LENGTH (arg_type);
+
+                     if (VALUE_LAZY (arg_val))
+                       value_fetch_lazy (arg_val);
+                     tmp = VALUE_CONTENTS (arg_val);
+
+                     if (len > available)
+                       len = available;                /* overflow protect */
+
+                     /* FIXME: how to protect GDB from crashing
+                        from bad user-supplied format string? */
+                     if (fmt[0] != 0)
+                       sprintf (outp, fmt, tmp);
+                     else
+                       strncpy (outp, tmp, len);
+                     outp[len] = '\0';
+                   }
+                 break;
+               case TYPE_CODE_PTR:
+                 elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
+                 addrval = value_as_pointer (arg_val);
+
+                 if (TYPE_LENGTH (elt_type) == 1 &&
+                     TYPE_CODE   (elt_type) == TYPE_CODE_INT &&
+                     addrval != 0)
+                   {
+                     /* display it as a string */
+                     char *default_fmt = "%s";
+                     char *tmp;
+                     int err = 0;
+
+                     /* Limiting the number of bytes that the following call
+                        will read protects us from sprintf overflow later. */
+                     i = target_read_string (addrval,               /* src */
+                                             &tmp,                  /* dest */
+                                             available,             /* len */
+                                             &err);
+                     if (err)  /* read failed */
+                       error ("%s on target_read", safe_strerror (err));
+
+                     tmp[i] = '\0';    /* force-terminate string */
+                     /* FIXME: how to protect GDB from crashing
+                        from bad user-supplied format string? */
+                     sprintf (outp, fmt[0] == 0 ? default_fmt : fmt, 
+                              tmp);
+                     free (tmp);
+                   }
+                 else
+                   {
+                     /* display it as a pointer */
+                     char *default_fmt = "0x%x";
+
+                     /* FIXME: how to protect GDB from crashing
+                        from bad user-supplied format string? */
+                     if (available >= 16 /*?*/)        /* overflow protect */
+                       sprintf (outp, fmt[0] == 0 ? default_fmt : fmt,
+                                (long) addrval);
+                   }
+                 break;
+               case TYPE_CODE_FLT:
+                 {
+                   char *default_fmt = "%g";
+
+                   doubleval = value_as_double (arg_val);
+                   /* FIXME: how to protect GDB from crashing
+                      from bad user-supplied format string? */
+                   if (available >= 16 /*?*/)          /* overflow protect */
+                     sprintf (outp, fmt[0] == 0 ? default_fmt : fmt,
+                              (double) doubleval);
+                   break;
+                 }
+               case TYPE_CODE_INT:
+                 {
+                   char *default_fmt = "%d";
+
+                   longval = value_as_long (arg_val);
+                   /* FIXME: how to protect GDB from crashing
+                      from bad user-supplied format string? */
+                   if (available >= 16 /*?*/)          /* overflow protect */
+                     sprintf (outp, fmt[0] == 0 ? default_fmt : fmt,
+                              (long) longval);
+                   break;
+                 }
+               case TYPE_CODE_BOOL:
+                 {
+                   /* no default format for bool */
+                   longval = value_as_long (arg_val);
+                   if (available >= 8 /*?*/)           /* overflow protect */
+                     {
+                       if (longval)
+                         strcpy (outp, "<true>");
+                       else
+                         strcpy (outp, "<false>");
+                     }
+                   break;
+                 }
+               case TYPE_CODE_ENUM:
+                 {
+                   /* no default format for enum */
+                   longval = value_as_long (arg_val);
+                   len = TYPE_NFIELDS (arg_type);
+                   /* find enum name if possible */
+                   for (i = 0; i < len; i++)
+                     if (TYPE_FIELD_BITPOS (arg_type, i) == longval)
+                       break;          /* match -- end loop */
+
+                   if (i < len)        /* enum name found */
+                     {
+                       char *name = TYPE_FIELD_NAME (arg_type, i);
+
+                       strncpy (outp, name, available);
+                       /* in casel available < strlen (name), */
+                       outp[available] = '\0';
+                     }
+                   else
+                     {
+                       if (available >= 16 /*?*/)      /* overflow protect */
+                         sprintf (outp, "%d", (long) longval);
+                     }
+                   break;
+                 }
+               case TYPE_CODE_VOID:
+                 *outp = '\0';
+                 break;        /* void type -- no output */
+               default:
+                 error ("bad data type at prompt position %d",
+                        promptp - local_prompt);
+                 break;
+               }
+             outp += strlen (outp);
+           }
+       }
+      *outp++ = '\0';          /* terminate prompt string */
+      return 1;
+    }
 }
 
-/* This replaces the above for the frontends: it returns a pointer
-   to the prompt. */
 char *
 get_prompt ()
 {
-  return prompt;
+  static char buf[MAX_PROMPT_SIZE];
+
+  if (catch_errors (get_prompt_1, buf, "bad formatted prompt: ", 
+                   RETURN_MASK_ALL))
+    {
+      return &buf[0];  /* successful formatted prompt */
+    }
+  else
+    {
+      /* Prompt could not be formatted.  */
+      if (async_p)
+       return PROMPT (0);
+      else
+       return gdb_prompt_string;
+    }
 }
 
 void
@@ -2907,7 +3208,10 @@ set_prompt (s)
   if (prompt != NULL)
     free (prompt);
 */
-  prompt = savestring (s, strlen (s));
+  if (async_p)
+    PROMPT (0) = savestring (s, strlen (s));
+  else
+    gdb_prompt_string = savestring (s, strlen (s));
 }
 
 \f
@@ -3146,10 +3450,12 @@ source_command (args, from_tty)
 
   stream = fopen (file, FOPEN_RT);
   if (!stream)
-    if (from_tty)
-      perror_with_name (file);
-    else
-      return;
+    {
+      if (from_tty)
+       perror_with_name (file);
+      else
+       return;
+    }
 
   make_cleanup ((make_cleanup_func) fclose, stream);
 
@@ -3400,11 +3706,9 @@ init_cmd_lists ()
   sethistlist = NULL;
   showhistlist = NULL;
   unsethistlist = NULL;
-#if MAINTENANCE_CMDS
   maintenancelist = NULL;
   maintenanceinfolist = NULL;
   maintenanceprintlist = NULL;
-#endif
   setprintlist = NULL;
   showprintlist = NULL;
   setchecklist = NULL;
@@ -3447,11 +3751,35 @@ init_main ()
 {
   struct cmd_list_element *c;
 
+  /* If we are running the asynchronous version,
+     we initialize the prompts differently. */
+  if (!async_p)
+    {
+#ifdef DEFAULT_PROMPT
+      gdb_prompt_string = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT));
+#else
+      gdb_prompt_string = savestring ("(gdb) ", 6);
+#endif
+    }
+  else
+    {
+      /* initialize the prompt stack to a simple "(gdb) " prompt or to
+        whatever the DEFULAT_PROMPT is. */
+      the_prompts.top = 0;
+      PREFIX(0) = "";
 #ifdef DEFAULT_PROMPT
-  prompt = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT));
+      PROMPT(0) = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT));
 #else
-  prompt = savestring ("(gdb) ", 6);
+      PROMPT(0) = savestring ("(gdb) ", 6);
 #endif
+      SUFFIX(0) = "";
+      /* Set things up for annotation_level > 1, if the user ever decides
+        to use it. */
+      async_annotation_suffix = "prompt";
+      /* Set the variable associated with the setshow prompt command. */
+      new_async_prompt = savestring (PROMPT (0), strlen (PROMPT (0)));
+    }
+  gdb_prompt_escape = 0;       /* default to none.  */
 
   /* Set the important stuff up for command editing.  */
   command_editing_p = 1;
@@ -3502,10 +3830,32 @@ The change does not take effect for the program being debugged\n\
 until the next time it is started.", &cmdlist);
   c->completer = filename_completer;
 
+  /* The set prompt command is different depending whether or not the
+     async version is run. NOTE: this difference is going to
+     disappear as we make the event loop be the default engine of
+     gdb. */
+  if (!async_p)
+    {
+      add_show_from_set
+       (add_set_cmd ("prompt", class_support, var_string, 
+                     (char *) &gdb_prompt_string, "Set gdb's prompt",
+                     &setlist),
+        &showlist);
+    }
+  else
+    {
+      c = add_set_cmd ("prompt", class_support, var_string, 
+                     (char *)&new_async_prompt, "Set gdb's prompt",
+                      &setlist);
+      add_show_from_set (c, &showlist);
+      c->function.sfunc = set_async_prompt;
+    }
+
   add_show_from_set
-    (add_set_cmd ("prompt", class_support, var_string, (char *)&prompt,
-          "Set gdb's prompt",
-          &setlist),
+    (add_set_cmd ("prompt-escape-char", class_support, var_zinteger, 
+                 (char *) &gdb_prompt_escape,
+                 "Set escape character for formatting of gdb's prompt",
+                 &setlist),
      &showlist);
 
   add_com ("echo", class_support, echo_command,
@@ -3557,13 +3907,30 @@ hitting return.");
   c->function.sfunc = set_verbose;
   set_verbose (NULL, 0, c);
 
-  add_show_from_set
-    (add_set_cmd ("editing", class_support, var_boolean, (char *)&command_editing_p,
-          "Set editing of command lines as they are typed.\n\
+  /* The set editing command is different depending whether or not the
+     async version is run. NOTE: this difference is going to disappear
+     as we make the event loop be the default engine of gdb. */
+  if (!async_p)
+    {
+      add_show_from_set
+       (add_set_cmd ("editing", class_support, var_boolean, (char *)&command_editing_p,
+                     "Set editing of command lines as they are typed.\n\
 Use \"on\" to enable the editing, and \"off\" to disable it.\n\
 Without an argument, command line editing is enabled.  To edit, use\n\
 EMACS-like or VI-like commands like control-P or ESC.", &setlist),
-     &showlist);
+        &showlist);
+    }
+  else
+    {
+      c = add_set_cmd ("editing", class_support, var_boolean, (char *)&async_command_editing_p,
+                      "Set editing of command lines as they are typed.\n\
+Use \"on\" to enable the editing, and \"off\" to disable it.\n\
+Without an argument, command line editing is enabled.  To edit, use\n\
+EMACS-like or VI-like commands like control-P or ESC.", &setlist);
+
+      add_show_from_set (c, &showlist);
+      c->function.sfunc = set_async_editing_command;
+    }
 
   add_prefix_cmd ("history", class_support, set_history,
                  "Generic command for setting command history parameters.",
@@ -3660,13 +4027,30 @@ is displayed.", &setlist),
     add_set_cmd ("remotetimeout", no_class, var_integer, (char *)&remote_timeout,
                   "Set timeout limit to wait for target to respond.\n\
 This value is used to set the time limit for gdb to wait for a response\n\
-from he target.", &setlist),
+from the target.", &setlist),
                     &showlist);
 
-  c = add_set_cmd ("annotate", class_obscure, var_zinteger, 
-                  (char *)&annotation_level, "Set annotation_level.\n\
+  /* The set annotate command is different depending whether or not
+     the async version is run. NOTE: this difference is going to
+     disappear as we make the event loop be the default engine of
+     gdb. */
+  if (!async_p)
+    {
+      c = add_set_cmd ("annotate", class_obscure, var_zinteger, 
+                      (char *)&annotation_level, "Set annotation_level.\n\
+0 == normal;     1 == fullname (for use when running under emacs)\n\
+2 == output annotated suitably for use by programs that control GDB.",
+                      &setlist);
+      c = add_show_from_set (c, &showlist);
+    }
+  else
+    {
+      c = add_set_cmd ("annotate", class_obscure, var_zinteger, 
+                      (char *)&annotation_level, "Set annotation_level.\n\
 0 == normal;     1 == fullname (for use when running under emacs)\n\
 2 == output annotated suitably for use by programs that control GDB.",
-                &setlist);
-  c = add_show_from_set (c, &showlist);
+                      &setlist);     
+      add_show_from_set (c, &showlist);
+      c->function.sfunc = set_async_annotation_level;
+    }
 }
This page took 0.038234 seconds and 4 git commands to generate.