2011-05-23 Pedro Alves <pedro@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / complaints.c
index 95ded4c4a8a982c1e5599cb47635c3cf86e4dba0..9129b98a6e05b6747e75258079d6998fe199b158 100644 (file)
@@ -1,13 +1,13 @@
 /* Support for complaint handling during symbol reading in GDB.
 
-   Copyright 1990, 1991, 1992, 1993, 1995, 1998, 1999, 2000, 2002 Free
-   Software Foundation, Inc.
+   Copyright (C) 1990, 1991, 1992, 1993, 1995, 1998, 1999, 2000, 2002, 2004,
+   2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -16,9 +16,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "complaints.h"
@@ -28,8 +26,8 @@
 
 extern void _initialize_complaints (void);
 
-/* Should each complaint message be self explanatory, or should we assume that
-   a series of complaints is being produced?  */
+/* Should each complaint message be self explanatory, or should we
+   assume that a series of complaints is being produced?  */
 
 /* case 1: First message of a series that must
    start off with explanation.  case 2: Subsequent message of a series
@@ -60,6 +58,15 @@ struct complain
   struct complain *next;
 };
 
+/* The explanatory message that should accompany the complaint.  The
+   message is in two parts - pre and post - that are printed around
+   the complaint text.  */
+struct explanation
+{
+  const char *prefix;
+  const char *postfix;
+};
+
 struct complaints
 {
   struct complain *root;
@@ -75,20 +82,21 @@ struct complaints
   /* The explanatory messages that should accompany the complaint.
      NOTE: cagney/2002-08-14: In a desperate attempt at being vaguely
      i18n friendly, this is an array of two messages.  When present,
-     EXPLANATION[SERIES] is used to wrap the message.  */
-  const char **explanation;
+     the PRE and POST EXPLANATION[SERIES] are used to wrap the
+     message.  */
+  const struct explanation *explanation;
 };
 
 static struct complain complaint_sentinel;
 
 /* The symbol table complaint table.  */
 
-static const char *symfile_explanations[] = {
-  "During symbol reading, %s.\n",
-  "During symbol reading...%s...",
-  "%s...",
-  "%s...",
-  NULL
+static struct explanation symfile_explanations[] = {
+  { "During symbol reading, ", "." },
+  { "During symbol reading...", "..."},
+  { "", "..."},
+  { "", "..."},
+  { NULL, NULL }
 };
 
 static struct complaints symfile_complaint_book = {
@@ -112,7 +120,7 @@ get_complaints (struct complaints **c)
   return (*c);
 }
 
-static struct complain *
+static struct complain * ATTRIBUTE_PRINTF (4, 0)
 find_complaint (struct complaints *complaints, const char *file,
                int line, const char *fmt)
 {
@@ -151,18 +159,21 @@ find_complaint (struct complaints *complaints, const char *file,
    before we stop whining about it?  Default is no whining at all,
    since so many systems have ill-constructed symbol files.  */
 
-static unsigned int stop_whining = 0;
+static int stop_whining = 0;
 
 /* Print a complaint, and link the complaint block into a chain for
    later handling.  */
 
-static void
-vcomplaint (struct complaints **c, const char *file, int line, const char *fmt,
+static void ATTRIBUTE_PRINTF (4, 0)
+vcomplaint (struct complaints **c, const char *file, 
+           int line, const char *fmt,
            va_list args)
 {
   struct complaints *complaints = get_complaints (c);
-  struct complain *complaint = find_complaint (complaints, file, line, fmt);
+  struct complain *complaint = find_complaint (complaints, file, 
+                                              line, fmt);
   enum complaint_series series;
+
   gdb_assert (complaints != NULL);
 
   complaint->counter++;
@@ -175,26 +186,39 @@ vcomplaint (struct complaints **c, const char *file, int line, const char *fmt,
     series = complaints->series;
 
   if (complaint->file != NULL)
-    internal_vwarning (complaint->file, complaint->line, complaint->fmt, args);
-  else if (warning_hook)
-    (*warning_hook) (complaint->fmt, args);
+    internal_vwarning (complaint->file, complaint->line, 
+                      complaint->fmt, args);
+  else if (deprecated_warning_hook)
+    (*deprecated_warning_hook) (complaint->fmt, args);
   else
     {
       if (complaints->explanation == NULL)
+       /* A [v]warning() call always appends a newline.  */
        vwarning (complaint->fmt, args);
       else
        {
          char *msg;
          struct cleanup *cleanups;
-         xvasprintf (&msg, complaint->fmt, args);
+         msg = xstrvprintf (complaint->fmt, args);
          cleanups = make_cleanup (xfree, msg);
          wrap_here ("");
          if (series != SUBSEQUENT_MESSAGE)
            begin_line ();
-         fprintf_filtered (gdb_stderr,
-                           complaints->explanation[series],
-                           msg);
-         wrap_here ("");
+         /* XXX: i18n */
+         fprintf_filtered (gdb_stderr, "%s%s%s",
+                           complaints->explanation[series].prefix, msg,
+                           complaints->explanation[series].postfix);
+         /* Force a line-break after any isolated message.  For the
+             other cases, clear_complaints() takes care of any missing
+             trailing newline, the wrap_here() is just a hint.  */
+         if (series == ISOLATED_MESSAGE)
+           /* It would be really nice to use begin_line() here.
+              Unfortunately that function doesn't track GDB_STDERR and
+              consequently will sometimes supress a line when it
+              shouldn't.  */
+           fputs_filtered ("\n", gdb_stderr);
+         else
+           wrap_here ("");
          do_cleanups (cleanups);
        }
     }
@@ -223,6 +247,7 @@ void
 complaint (struct complaints **complaints, const char *fmt, ...)
 {
   va_list args;
+
   va_start (args, fmt);
   vcomplaint (complaints, NULL/*file*/, 0/*line*/, fmt, args);
   va_end (args);
@@ -238,16 +263,6 @@ internal_complaint (struct complaints **complaints, const char *file,
   va_end (args);
 }
 
-void
-complain (struct complaint *complaint, ...)
-{
-  va_list args;
-  va_start (args, complaint);
-  vcomplaint (&symfile_complaints, NULL/*file*/, 0/*line*/,
-             complaint->message, args);
-  va_end (args);
-}
-
 /* Clear out / initialize all complaint counters that have ever been
    incremented.  If LESS_VERBOSE is 1, be less verbose about
    successive complaints, since the messages are appearing all
@@ -267,10 +282,27 @@ clear_complaints (struct complaints **c, int less_verbose, int noisy)
       p->counter = 0;
     }
 
-  if (complaints->series > 1 && !warning_hook)
+  switch (complaints->series)
     {
-      /* Terminate previous series, since caller won't.  */
-      puts_filtered ("\n");
+    case FIRST_MESSAGE:
+      /* Haven't yet printed anything.  */
+      break;
+    case SHORT_FIRST_MESSAGE:
+      /* Haven't yet printed anything.  */
+      break;
+    case ISOLATED_MESSAGE:
+      /* The code above, always forces a line-break.  No need to do it
+         here.  */
+      break;
+    case SUBSEQUENT_MESSAGE:
+      /* It would be really nice to use begin_line() here.
+         Unfortunately that function doesn't track GDB_STDERR and
+         consequently will sometimes supress a line when it
+         shouldn't.  */
+      fputs_unfiltered ("\n", gdb_stderr);
+      break;
+    default:
+      internal_error (__FILE__, __LINE__, _("bad switch"));
     }
 
   if (!less_verbose)
@@ -281,14 +313,22 @@ clear_complaints (struct complaints **c, int less_verbose, int noisy)
     complaints->series = SHORT_FIRST_MESSAGE;
 }
 
+static void
+complaints_show_value (struct ui_file *file, int from_tty,
+                      struct cmd_list_element *cmd, const char *value)
+{
+  fprintf_filtered (file, _("Max number of complaints about incorrect"
+                           " symbols is %s.\n"),
+                   value);
+}
+
 void
 _initialize_complaints (void)
 {
-  add_setshow_cmd ("complaints", class_support, var_zinteger,
-                  &stop_whining,
-                  "Set max number of complaints about incorrect symbols.",
-                  "Show max number of complaints about incorrect symbols.",
-                  NULL, NULL,
-                  &setlist, &showlist);
-
+  add_setshow_zinteger_cmd ("complaints", class_support, 
+                           &stop_whining, _("\
+Set max number of complaints about incorrect symbols."), _("\
+Show max number of complaints about incorrect symbols."), NULL,
+                           NULL, complaints_show_value,
+                           &setlist, &showlist);
 }
This page took 0.027937 seconds and 4 git commands to generate.