OSDN Git Service

2004-03-01 Paolo Bonzini <bonzini@gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / cpperror.c
index 969907b..d572380 100644 (file)
@@ -1,6 +1,6 @@
 /* Default error handlers for CPP Library.
 /* Default error handlers for CPP Library.
-   Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000
-   Free Software Foundation, Inc.
+   Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000,
+   2001, 2002, 2004 Free Software Foundation, Inc.
    Written by Per Bothner, 1994.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
    Written by Per Bothner, 1994.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -26,415 +26,158 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #include "config.h"
 #include "system.h"
 #include "cpplib.h"
 #include "config.h"
 #include "system.h"
 #include "cpplib.h"
+#include "cpphash.h"
 #include "intl.h"
 
 #include "intl.h"
 
-static void print_containing_files     PARAMS ((cpp_reader *, cpp_buffer *));
-static void print_file_and_line                PARAMS ((const char *, long, long));
-static void v_message                  PARAMS ((cpp_reader *, int,
-                                                const char *, long, long,
-                                                const char *, va_list));
-
-/* Print the file names and line numbers of the #include
-   commands which led to the current file.  */
+static void print_location (cpp_reader *, source_location, unsigned int);
 
 
+/* Print the logical file location (LINE, COL) in preparation for a
+   diagnostic.  Outputs the #include chain if it has changed.  A line
+   of zero suppresses the include stack, and outputs the program name
+   instead.  */
 static void
 static void
-print_containing_files (pfile, ip)
-     cpp_reader *pfile;
-     cpp_buffer *ip;
+print_location (cpp_reader *pfile, source_location line, unsigned int col)
 {
 {
-  int first = 1;
+  if (line == 0)
+    fprintf (stderr, "%s: ", progname);
+  else
+    {
+      const struct line_map *map;
+      unsigned int lin;
 
 
-  /* If stack of files hasn't changed since we last printed
-     this info, don't repeat it.  */
-  if (pfile->input_stack_listing_current)
-    return;
+      map = linemap_lookup (pfile->line_table, line);
+      linemap_print_containing_files (pfile->line_table, map);
 
 
-  /* Find the other, outer source files.  */
-  for (ip = CPP_PREV_BUFFER (ip); ip != NULL; ip = CPP_PREV_BUFFER (ip))
-    {
-      long line;
-      cpp_buf_line_and_col (ip, &line, NULL);
-      if (first)
+      lin = SOURCE_LINE (map, line);
+      if (col == 0)
        {
        {
-         first = 0;
-         fprintf (stderr,  _("In file included from %s:%ld"),
-                  ip->nominal_fname, line);
+         col = SOURCE_COLUMN (map, line);
+         if (col == 0)
+           col = 1;
        }
        }
-      else
-       /* Translators note: this message is used in conjunction
-          with "In file included from %s:%ld" and some other
-          tricks.  We want something like this:
 
 
-          In file included from sys/select.h:123,
-                           from sys/types.h:234,
-                           from userfile.c:31:
-          bits/select.h:45: <error message here>
+      if (lin == 0)
+       fprintf (stderr, "%s:", map->to_file);
+      else if (CPP_OPTION (pfile, show_column) == 0)
+       fprintf (stderr, "%s:%u:", map->to_file, lin);
+      else
+       fprintf (stderr, "%s:%u:%u:", map->to_file, lin, col);
 
 
-          The trailing comma is at the beginning of this message,
-          and the trailing colon is not translated.  */
-       fprintf (stderr, _(",\n                 from %s:%ld"),
-                ip->nominal_fname, line);
+      fputc (' ', stderr);
     }
     }
-  if (first == 0)
-    fputs (":\n", stderr);
-
-  /* Record we have printed the status as of this time.  */
-  pfile->input_stack_listing_current = 1;
 }
 
 }
 
-static void
-print_file_and_line (filename, line, column)
-     const char *filename;
-     long line, column;
+/* Set up for a diagnostic: print the file and line, bump the error
+   counter, etc.  SRC_LOC is the logical line number; zero means to print
+   at the location of the previously lexed token, which tends to be
+   the correct place by default.  The column number can be specified either
+   using COLUMN or (if COLUMN==0) extracting SOURCE_COLUMN from SRC_LOC.
+   (This may seem redundant, but is useful when pre-scanning (cleaning) a line,
+   when we haven't yet verified whether the current line_map has a
+   big enough max_column_hint.)
+
+   Returns 0 if the error has been suppressed.  */
+int
+_cpp_begin_message (cpp_reader *pfile, int code,
+                   source_location src_loc, unsigned int column)
 {
 {
-  if (filename == 0 || *filename == '\0')
-    filename = "<stdin>";
-  if (line <= 0)
-    fputs (_("<command line>: "), stderr);
-  else if (column > 0)
-    fprintf (stderr, "%s:%ld:%ld: ", filename, line, column);
-  else
-    fprintf (stderr, "%s:%ld: ", filename, line);
-}
+  int level = CPP_DL_EXTRACT (code);
 
 
-/* IS_ERROR is 3 for ICE, 2 for merely "fatal" error,
-   1 for error, 0 for warning.  */
-
-static void
-v_message (pfile, is_error, file, line, col, msg, ap)
-     cpp_reader *pfile;
-     int is_error;
-     const char *file;
-     long line;
-     long col;
-     const char *msg;
-     va_list ap;
-{
-  cpp_buffer *ip = cpp_file_buffer (pfile);
-
-  if (ip)
-    {
-      if (file == NULL)
-       file = ip->nominal_fname;
-      if (line == -1)
-       cpp_buf_line_and_col (ip, &line, &col);
-
-      print_containing_files (pfile, ip);
-      print_file_and_line (file, line, col);
-    }
-  else
-    fprintf (stderr, "%s: ", progname);
-
-  switch (is_error)
+  switch (level)
     {
     {
-    case 0:
-      fprintf (stderr, _("warning: "));
-      break;
-    case 1:
-      if (pfile->errors < CPP_FATAL_LIMIT)
-       pfile->errors++;
-      break;
-    case 2:
-      pfile->errors = CPP_FATAL_LIMIT;
+    case CPP_DL_WARNING:
+    case CPP_DL_PEDWARN:
+      if (cpp_in_system_header (pfile)
+         && ! CPP_OPTION (pfile, warn_system_headers))
+       return 0;
+      /* Fall through.  */
+
+    case CPP_DL_WARNING_SYSHDR:
+      if (CPP_OPTION (pfile, warnings_are_errors)
+         || (level == CPP_DL_PEDWARN && CPP_OPTION (pfile, pedantic_errors)))
+       {
+         if (CPP_OPTION (pfile, inhibit_errors))
+           return 0;
+         level = CPP_DL_ERROR;
+         pfile->errors++;
+       }
+      else if (CPP_OPTION (pfile, inhibit_warnings))
+       return 0;
       break;
       break;
-    case 3:
-      fprintf (stderr, _("internal error: "));
-      pfile->errors = CPP_FATAL_LIMIT;
+
+    case CPP_DL_ERROR:
+      if (CPP_OPTION (pfile, inhibit_errors))
+       return 0;
+      /* ICEs cannot be inhibited.  */
+    case CPP_DL_ICE:
+      pfile->errors++;
       break;
       break;
-    default:
-      cpp_ice (pfile, "bad is_error(%d) in v_message", is_error);
     }
 
     }
 
-  vfprintf (stderr, _(msg), ap);
-  putc ('\n', stderr);
-}
-
-/* Exported interface.  */
-
-/* For reporting internal errors.  Prints "internal error: " for you,
-   otherwise identical to cpp_fatal.  */
-
-void
-cpp_ice VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
-{  
-#ifndef ANSI_PROTOTYPES
-  cpp_reader *pfile;
-  const char *msgid;
-#endif
-  va_list ap;
-  
-  VA_START (ap, msgid);
-  
-#ifndef ANSI_PROTOTYPES
-  pfile = va_arg (ap, cpp_reader *);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  v_message (pfile, 3, NULL, -1, -1, msgid, ap);
-  va_end(ap);
-}
-
-/* Same as cpp_error, except we consider the error to be "fatal",
-   such as inconsistent options.  I.e. there is little point in continuing.
-   (We do not exit, to support use of cpplib as a library.
-   Instead, it is the caller's responsibility to check
-   CPP_FATAL_ERRORS.  */
-
-void
-cpp_fatal VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
-{  
-#ifndef ANSI_PROTOTYPES
-  cpp_reader *pfile;
-  const char *msgid;
-#endif
-  va_list ap;
-  
-  VA_START (ap, msgid);
-  
-#ifndef ANSI_PROTOTYPES
-  pfile = va_arg (ap, cpp_reader *);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  v_message (pfile, 2, NULL, -1, -1, msgid, ap);
-  va_end(ap);
-}
-
-void
-cpp_error VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  cpp_reader *pfile;
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START(ap, msgid);
-  
-#ifndef ANSI_PROTOTYPES
-  pfile = va_arg (ap, cpp_reader *);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  if (CPP_OPTIONS (pfile)->inhibit_errors)
-    return;
-
-  v_message (pfile, 1, NULL, -1, -1, msgid, ap);
-  va_end(ap);
-}
-
-void
-cpp_error_with_line VPARAMS ((cpp_reader *pfile, int line, int column,
-                            const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  cpp_reader *pfile;
-  int line;
-  int column;
-  const char *msgid;
-#endif
-  va_list ap;
-  
-  VA_START (ap, msgid);
-  
-#ifndef ANSI_PROTOTYPES
-  pfile = va_arg (ap, cpp_reader *);
-  line = va_arg (ap, int);
-  column = va_arg (ap, int);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  if (CPP_OPTIONS (pfile)->inhibit_errors)
-    return;
+  print_location (pfile, src_loc, column);
+  if (CPP_DL_WARNING_P (level))
+    fputs (_("warning: "), stderr);
+  else if (level == CPP_DL_ICE)
+    fputs (_("internal error: "), stderr);
 
 
-  v_message (pfile, 1, NULL, line, column, msgid, ap);
-  va_end(ap);
+  return 1;
 }
 
 }
 
-/* Error including a message from `errno'.  */
-void
-cpp_error_from_errno (pfile, name)
-     cpp_reader *pfile;
-     const char *name;
-{
-  cpp_error (pfile, "%s: %s", name, xstrerror (errno));
-}
+/* Don't remove the blank before do, as otherwise the exgettext
+   script will mistake this as a function definition */
+#define v_message(msgid, ap) \
+ do { vfprintf (stderr, _(msgid), ap); putc ('\n', stderr); } while (0)
 
 
-void
-cpp_warning VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  cpp_reader *pfile;
-  const char *msgid;
-#endif
-  va_list ap;
-  
-  VA_START (ap, msgid);
-  
-#ifndef ANSI_PROTOTYPES
-  pfile = va_arg (ap, cpp_reader *);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  if (CPP_OPTIONS (pfile)->inhibit_warnings)
-    return;
-
-  v_message (pfile, 0, NULL, -1, -1, msgid, ap);
-  va_end(ap);
-}
-
-void
-cpp_warning_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
-                              const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  cpp_reader *pfile;
-  int line;
-  int column;
-  const char *msgid;
-#endif
-  va_list ap;
-  
-  VA_START (ap, msgid);
-  
-#ifndef ANSI_PROTOTYPES
-  pfile = va_arg (ap, cpp_reader *);
-  line = va_arg (ap, int);
-  column = va_arg (ap, int);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  if (CPP_OPTIONS (pfile)->inhibit_warnings)
-    return;
-
-  v_message (pfile, 0, NULL, line, column, msgid, ap);
-  va_end(ap);
-}
+/* Exported interface.  */
 
 
+/* Print an error at the location of the previously lexed token.  */
 void
 void
-cpp_pedwarn VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
+cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
 {
 {
-#ifndef ANSI_PROTOTYPES
-  cpp_reader *pfile;
-  const char *msgid;
-#endif
+  source_location src_loc;
   va_list ap;
   
   va_list ap;
   
-  VA_START (ap, msgid);
-  
-#ifndef ANSI_PROTOTYPES
-  pfile = va_arg (ap, cpp_reader *);
-  msgid = va_arg (ap, const char *);
-#endif
+  va_start (ap, msgid);
 
 
-  if (CPP_OPTIONS (pfile)->pedantic_errors
-      ? CPP_OPTIONS (pfile)->inhibit_errors
-      : CPP_OPTIONS (pfile)->inhibit_warnings)
-    return;
-
-  v_message (pfile, CPP_OPTIONS (pfile)->pedantic_errors,
-                NULL, -1, -1, msgid, ap);
-  va_end(ap);
-}
-
-void
-cpp_pedwarn_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
-                              const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  cpp_reader *pfile;
-  int line;
-  int column;
-  const char *msgid;
-#endif
-  va_list ap;
-  
-  VA_START (ap, msgid);
-  
-#ifndef ANSI_PROTOTYPES
-  pfile = va_arg (ap, cpp_reader *);
-  line = va_arg (ap, int);
-  column = va_arg (ap, int);
-  msgid = va_arg (ap, const char *);
-#endif
+  if (CPP_OPTION (pfile, traditional))
+    {
+      if (pfile->state.in_directive)
+       src_loc = pfile->directive_line;
+      else
+       src_loc = pfile->line;
+    }
+  else
+    {
+      src_loc = pfile->cur_token[-1].src_loc;
+    }
 
 
-  if (CPP_OPTIONS (pfile)->pedantic_errors
-      ? CPP_OPTIONS (pfile)->inhibit_errors
-      : CPP_OPTIONS (pfile)->inhibit_warnings)
-    return;
+  if (_cpp_begin_message (pfile, level, src_loc, 0))
+    v_message (msgid, ap);
 
 
-  v_message (pfile, CPP_OPTIONS (pfile)->pedantic_errors,
-                NULL, line, column, msgid, ap);
-  va_end(ap);
+  va_end (ap);
 }
 
 }
 
-/* Report a warning (or an error if pedantic_errors)
-   giving specified file name and line number, not current.  */
-
+/* Print an error at a specific location.  */
 void
 void
-cpp_pedwarn_with_file_and_line VPARAMS ((cpp_reader *pfile,
-                                        const char *file, int line, int col,
-                                        const char *msgid, ...))
+cpp_error_with_line (cpp_reader *pfile, int level,
+                    source_location src_loc, unsigned int column,
+                    const char *msgid, ...)
 {
 {
-#ifndef ANSI_PROTOTYPES
-  cpp_reader *pfile;
-  const char *file;
-  int line;
-  int col;
-  const char *msgid;
-#endif
   va_list ap;
   
   va_list ap;
   
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  pfile = va_arg (ap, cpp_reader *);
-  file = va_arg (ap, const char *);
-  line = va_arg (ap, int);
-  col = va_arg (ap, int);
-  msgid = va_arg (ap, const char *);
-#endif
+  va_start (ap, msgid);
 
 
-  if (CPP_OPTIONS (pfile)->pedantic_errors
-      ? CPP_OPTIONS (pfile)->inhibit_errors
-      : CPP_OPTIONS (pfile)->inhibit_warnings)
-    return;
+  if (_cpp_begin_message (pfile, level, src_loc, column))
+    v_message (msgid, ap);
 
 
-  v_message (pfile, CPP_OPTIONS (pfile)->pedantic_errors,
-                file, line, col, msgid, ap);
-  va_end(ap);
+  va_end (ap);
 }
 
 }
 
-/* Print an error message not associated with a file.  */
 void
 void
-cpp_notice VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
+cpp_errno (cpp_reader *pfile, int level, const char *msgid)
 {
 {
-#ifndef ANSI_PROTOTYPES
-  cpp_reader *pfile;
-  const char *msgid;
-#endif
-  va_list ap;
-  
-  VA_START (ap, msgid);
-  
-#ifndef ANSI_PROTOTYPES
-  pfile = va_arg (ap, cpp_reader *);
-  msgid = va_arg (ap, const char *);
-#endif
+  if (msgid[0] == '\0')
+    msgid = _("stdout");
 
 
-  if (pfile->errors < CPP_FATAL_LIMIT)
-    pfile->errors++;
-
-  vfprintf (stderr, _(msgid), ap);
-  putc('\n', stderr);
-
-  va_end(ap);
-}
-
-void
-cpp_notice_from_errno (pfile, name)
-     cpp_reader *pfile;
-     const char *name;
-{
-  cpp_notice (pfile, "%s: %s", name, xstrerror (errno));
+  cpp_error (pfile, level, "%s: %s", msgid, xstrerror (errno));
 }
 }