Automatic date update in version.in
[platform/upstream/binutils.git] / gas / messages.c
index 005cd22..2865c9d 100644 (file)
@@ -1,11 +1,10 @@
 /* messages.c - error reporter -
 /* messages.c - error reporter -
-   Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2003
-   Free Software Foundation, Inc.
+   Copyright (C) 1987-2014 Free Software Foundation, Inc.
    This file is part of GAS, the GNU Assembler.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    This file is part of GAS, the GNU Assembler.
 
    GAS 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, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    GAS is distributed in the hope that it will be useful,
    any later version.
 
    GAS is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to the Free
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to the Free
-   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 #include "as.h"
 
 
 #include "as.h"
 
-#include <stdio.h>
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#ifdef USE_STDARG
-#include <stdarg.h>
-#endif
-
-#ifdef USE_VARARGS
-#include <varargs.h>
-#endif
-
-#if !defined (USE_STDARG) && !defined (USE_VARARGS)
-/* Roll our own.  */
-#define va_alist REST
-#define va_dcl
-typedef int * va_list;
-#define va_start(ARGS) ARGS = &REST
-#define va_end(ARGS)
-#endif
-
 static void identify (char *);
 static void as_show_where (void);
 static void as_warn_internal (char *, unsigned int, char *);
 static void identify (char *);
 static void as_show_where (void);
 static void as_warn_internal (char *, unsigned int, char *);
@@ -134,31 +111,12 @@ as_show_where (void)
   as_where (&file, &line);
   identify (file);
   if (file)
   as_where (&file, &line);
   identify (file);
   if (file)
-    fprintf (stderr, "%s:%u: ", file, line);
-}
-
-/* Like perror(3), but with more info.  */
-
-void
-as_perror (const char *gripe,          /* Unpunctuated error theme.  */
-          const char *filename)
-{
-  const char *errtxt;
-  int saved_errno = errno;
-
-  as_show_where ();
-  fprintf (stderr, gripe, filename);
-  errno = saved_errno;
-#ifdef BFD_ASSEMBLER
-  errtxt = bfd_errmsg (bfd_get_error ());
-#else
-  errtxt = xstrerror (errno);
-#endif
-  fprintf (stderr, ": %s\n", errtxt);
-  errno = 0;
-#ifdef BFD_ASSEMBLER
-  bfd_set_error (bfd_error_no_error);
-#endif
+    {
+      if (line != 0)
+       fprintf (stderr, "%s:%u: ", file, line);
+      else
+       fprintf (stderr, "%s: ", file);
+    }
 }
 
 /* Send to stderr a string as a warning, and locate warning
 }
 
 /* Send to stderr a string as a warning, and locate warning
@@ -167,7 +125,6 @@ as_perror (const char *gripe,               /* Unpunctuated error theme.  */
    Please explain in string (which may have '\n's) what recovery was
    done.  */
 
    Please explain in string (which may have '\n's) what recovery was
    done.  */
 
-#ifdef USE_STDARG
 void
 as_tsktsk (const char *format, ...)
 {
 void
 as_tsktsk (const char *format, ...)
 {
@@ -179,21 +136,6 @@ as_tsktsk (const char *format, ...)
   va_end (args);
   (void) putc ('\n', stderr);
 }
   va_end (args);
   (void) putc ('\n', stderr);
 }
-#else
-void
-as_tsktsk (format, va_alist)
-     const char *format;
-     va_dcl
-{
-  va_list args;
-
-  as_show_where ();
-  va_start (args);
-  vfprintf (stderr, format, args);
-  va_end (args);
-  (void) putc ('\n', stderr);
-}
-#endif /* not NO_STDARG */
 
 /* The common portion of as_warn and as_warn_where.  */
 
 
 /* The common portion of as_warn and as_warn_where.  */
 
@@ -207,10 +149,14 @@ as_warn_internal (char *file, unsigned int line, char *buffer)
 
   identify (file);
   if (file)
 
   identify (file);
   if (file)
-    fprintf (stderr, "%s:%u: ", file, line);
-  fprintf (stderr, _("Warning: "));
-  fputs (buffer, stderr);
-  (void) putc ('\n', stderr);
+    {
+      if (line != 0)
+       fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Warning: "), buffer);
+      else
+       fprintf (stderr, "%s: %s%s\n", file, _("Warning: "), buffer);
+    }
+  else
+    fprintf (stderr, "%s%s\n", _("Warning: "), buffer);
 #ifndef NO_LISTING
   listing_warning (buffer);
 #endif
 #ifndef NO_LISTING
   listing_warning (buffer);
 #endif
@@ -222,7 +168,6 @@ as_warn_internal (char *file, unsigned int line, char *buffer)
    Please explain in string (which may have '\n's) what recovery was
    done.  */
 
    Please explain in string (which may have '\n's) what recovery was
    done.  */
 
-#ifdef USE_STDARG
 void
 as_warn (const char *format, ...)
 {
 void
 as_warn (const char *format, ...)
 {
@@ -232,35 +177,16 @@ as_warn (const char *format, ...)
   if (!flag_no_warnings)
     {
       va_start (args, format);
   if (!flag_no_warnings)
     {
       va_start (args, format);
-      vsprintf (buffer, format, args);
+      vsnprintf (buffer, sizeof (buffer), format, args);
       va_end (args);
       as_warn_internal ((char *) NULL, 0, buffer);
     }
 }
       va_end (args);
       as_warn_internal ((char *) NULL, 0, buffer);
     }
 }
-#else
-void
-as_warn (format, va_alist)
-     const char *format;
-     va_dcl
-{
-  va_list args;
-  char buffer[2000];
-
-  if (!flag_no_warnings)
-    {
-      va_start (args);
-      vsprintf (buffer, format, args);
-      va_end (args);
-      as_warn_internal ((char *) NULL, 0, buffer);
-    }
-}
-#endif /* not NO_STDARG */
 
 /* Like as_bad but the file name and line number are passed in.
    Unfortunately, we have to repeat the function in order to handle
    the varargs correctly and portably.  */
 
 
 /* Like as_bad but the file name and line number are passed in.
    Unfortunately, we have to repeat the function in order to handle
    the varargs correctly and portably.  */
 
-#ifdef USE_STDARG
 void
 as_warn_where (char *file, unsigned int line, const char *format, ...)
 {
 void
 as_warn_where (char *file, unsigned int line, const char *format, ...)
 {
@@ -270,31 +196,11 @@ as_warn_where (char *file, unsigned int line, const char *format, ...)
   if (!flag_no_warnings)
     {
       va_start (args, format);
   if (!flag_no_warnings)
     {
       va_start (args, format);
-      vsprintf (buffer, format, args);
-      va_end (args);
-      as_warn_internal (file, line, buffer);
-    }
-}
-#else
-void
-as_warn_where (file, line, format, va_alist)
-     char *file;
-     unsigned int line;
-     const char *format;
-     va_dcl
-{
-  va_list args;
-  char buffer[2000];
-
-  if (!flag_no_warnings)
-    {
-      va_start (args);
-      vsprintf (buffer, format, args);
+      vsnprintf (buffer, sizeof (buffer), format, args);
       va_end (args);
       as_warn_internal (file, line, buffer);
     }
 }
       va_end (args);
       as_warn_internal (file, line, buffer);
     }
 }
-#endif /* not NO_STDARG */
 
 /* The common portion of as_bad and as_bad_where.  */
 
 
 /* The common portion of as_bad and as_bad_where.  */
 
@@ -308,10 +214,14 @@ as_bad_internal (char *file, unsigned int line, char *buffer)
 
   identify (file);
   if (file)
 
   identify (file);
   if (file)
-    fprintf (stderr, "%s:%u: ", file, line);
-  fprintf (stderr, _("Error: "));
-  fputs (buffer, stderr);
-  (void) putc ('\n', stderr);
+    {
+      if (line != 0)
+       fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Error: "), buffer);
+      else
+       fprintf (stderr, "%s: %s%s\n", file, _("Error: "), buffer);
+    }
+  else
+    fprintf (stderr, "%s%s\n", _("Error: "), buffer);
 #ifndef NO_LISTING
   listing_error (buffer);
 #endif
 #ifndef NO_LISTING
   listing_error (buffer);
 #endif
@@ -323,7 +233,6 @@ as_bad_internal (char *file, unsigned int line, char *buffer)
    Please explain in string (which may have '\n's) what recovery was
    done.  */
 
    Please explain in string (which may have '\n's) what recovery was
    done.  */
 
-#ifdef USE_STDARG
 void
 as_bad (const char *format, ...)
 {
 void
 as_bad (const char *format, ...)
 {
@@ -331,34 +240,16 @@ as_bad (const char *format, ...)
   char buffer[2000];
 
   va_start (args, format);
   char buffer[2000];
 
   va_start (args, format);
-  vsprintf (buffer, format, args);
-  va_end (args);
-
-  as_bad_internal ((char *) NULL, 0, buffer);
-}
-
-#else
-void
-as_bad (format, va_alist)
-     const char *format;
-     va_dcl
-{
-  va_list args;
-  char buffer[2000];
-
-  va_start (args);
-  vsprintf (buffer, format, args);
+  vsnprintf (buffer, sizeof (buffer), format, args);
   va_end (args);
 
   as_bad_internal ((char *) NULL, 0, buffer);
 }
   va_end (args);
 
   as_bad_internal ((char *) NULL, 0, buffer);
 }
-#endif /* not NO_STDARG */
 
 /* Like as_bad but the file name and line number are passed in.
    Unfortunately, we have to repeat the function in order to handle
    the varargs correctly and portably.  */
 
 
 /* Like as_bad but the file name and line number are passed in.
    Unfortunately, we have to repeat the function in order to handle
    the varargs correctly and portably.  */
 
-#ifdef USE_STDARG
 void
 as_bad_where (char *file, unsigned int line, const char *format, ...)
 {
 void
 as_bad_where (char *file, unsigned int line, const char *format, ...)
 {
@@ -366,37 +257,17 @@ as_bad_where (char *file, unsigned int line, const char *format, ...)
   char buffer[2000];
 
   va_start (args, format);
   char buffer[2000];
 
   va_start (args, format);
-  vsprintf (buffer, format, args);
+  vsnprintf (buffer, sizeof (buffer), format, args);
   va_end (args);
 
   as_bad_internal (file, line, buffer);
 }
 
   va_end (args);
 
   as_bad_internal (file, line, buffer);
 }
 
-#else
-void
-as_bad_where (file, line, format, va_alist)
-     char *file;
-     unsigned int line;
-     const char *format;
-     va_dcl
-{
-  va_list args;
-  char buffer[2000];
-
-  va_start (args);
-  vsprintf (buffer, format, args);
-  va_end (args);
-
-  as_bad_internal (file, line, buffer);
-}
-#endif /* not NO_STDARG */
-
 /* Send to stderr a string as a fatal message, and print location of
    error in input file(s).
    Please only use this for when we DON'T have some recovery action.
    It xexit()s with a warning status.  */
 
 /* Send to stderr a string as a fatal message, and print location of
    error in input file(s).
    Please only use this for when we DON'T have some recovery action.
    It xexit()s with a warning status.  */
 
-#ifdef USE_STDARG
 void
 as_fatal (const char *format, ...)
 {
 void
 as_fatal (const char *format, ...)
 {
@@ -411,26 +282,9 @@ as_fatal (const char *format, ...)
   /* Delete the output file, if it exists.  This will prevent make from
      thinking that a file was created and hence does not need rebuilding.  */
   if (out_file_name != NULL)
   /* Delete the output file, if it exists.  This will prevent make from
      thinking that a file was created and hence does not need rebuilding.  */
   if (out_file_name != NULL)
-    unlink (out_file_name);
+    unlink_if_ordinary (out_file_name);
   xexit (EXIT_FAILURE);
 }
   xexit (EXIT_FAILURE);
 }
-#else
-void
-as_fatal (format, va_alist)
-     char *format;
-     va_dcl
-{
-  va_list args;
-
-  as_show_where ();
-  va_start (args);
-  fprintf (stderr, _("Fatal error: "));
-  vfprintf (stderr, format, args);
-  (void) putc ('\n', stderr);
-  va_end (args);
-  xexit (EXIT_FAILURE);
-}
-#endif /* not NO_STDARG */
 
 /* Indicate assertion failure.
    Arguments: Filename, line number, optional function name.  */
 
 /* Indicate assertion failure.
    Arguments: Filename, line number, optional function name.  */
@@ -469,37 +323,114 @@ as_abort (const char *file, int line, const char *fn)
 /* Support routines.  */
 
 void
 /* Support routines.  */
 
 void
-fprint_value (FILE *file, valueT val)
+sprint_value (char *buf, valueT val)
 {
   if (sizeof (val) <= sizeof (long))
     {
 {
   if (sizeof (val) <= sizeof (long))
     {
-      fprintf (file, "%ld", (long) val);
+      sprintf (buf, "%ld", (long) val);
       return;
     }
       return;
     }
-#ifdef BFD_ASSEMBLER
   if (sizeof (val) <= sizeof (bfd_vma))
     {
   if (sizeof (val) <= sizeof (bfd_vma))
     {
-      fprintf_vma (file, val);
+      sprintf_vma (buf, val);
       return;
     }
       return;
     }
-#endif
   abort ();
 }
 
   abort ();
 }
 
-void
-sprint_value (char *buf, valueT val)
+#define HEX_MAX_THRESHOLD      1024
+#define HEX_MIN_THRESHOLD      -(HEX_MAX_THRESHOLD)
+
+static void
+as_internal_value_out_of_range (char *    prefix,
+                               offsetT   val,
+                               offsetT   min,
+                               offsetT   max,
+                               char *    file,
+                               unsigned  line,
+                               int       bad)
 {
 {
-  if (sizeof (val) <= sizeof (long))
+  const char * err;
+
+  if (prefix == NULL)
+    prefix = "";
+
+  if (val >= min && val <= max)
     {
     {
-      sprintf (buf, "%ld", (long) val);
+      addressT right = max & -max;
+
+      if (max <= 1)
+       abort ();
+
+      /* xgettext:c-format  */
+      err = _("%s out of domain (%d is not a multiple of %d)");
+      if (bad)
+       as_bad_where (file, line, err,
+                     prefix, (int) val, (int) right);
+      else
+       as_warn_where (file, line, err,
+                      prefix, (int) val, (int) right);
       return;
     }
       return;
     }
-#ifdef BFD_ASSEMBLER
-  if (sizeof (val) <= sizeof (bfd_vma))
+
+  if (   val < HEX_MAX_THRESHOLD
+      && min < HEX_MAX_THRESHOLD
+      && max < HEX_MAX_THRESHOLD
+      && val > HEX_MIN_THRESHOLD
+      && min > HEX_MIN_THRESHOLD
+      && max > HEX_MIN_THRESHOLD)
     {
     {
-      sprintf_vma (buf, val);
-      return;
+      /* xgettext:c-format  */
+      err = _("%s out of range (%d is not between %d and %d)");
+
+      if (bad)
+       as_bad_where (file, line, err,
+                     prefix, (int) val, (int) min, (int) max);
+      else
+       as_warn_where (file, line, err,
+                      prefix, (int) val, (int) min, (int) max);
     }
     }
-#endif
-  abort ();
+  else
+    {
+      char val_buf [sizeof (val) * 3 + 2];
+      char min_buf [sizeof (val) * 3 + 2];
+      char max_buf [sizeof (val) * 3 + 2];
+
+      if (sizeof (val) > sizeof (bfd_vma))
+       abort ();
+
+      sprintf_vma (val_buf, (bfd_vma) val);
+      sprintf_vma (min_buf, (bfd_vma) min);
+      sprintf_vma (max_buf, (bfd_vma) max);
+
+      /* xgettext:c-format.  */
+      err = _("%s out of range (0x%s is not between 0x%s and 0x%s)");
+
+      if (bad)
+       as_bad_where (file, line, err, prefix, val_buf, min_buf, max_buf);
+      else
+       as_warn_where (file, line, err, prefix, val_buf, min_buf, max_buf);
+    }
+}
+
+void
+as_warn_value_out_of_range (char *   prefix,
+                          offsetT  value,
+                          offsetT  min,
+                          offsetT  max,
+                          char *   file,
+                          unsigned line)
+{
+  as_internal_value_out_of_range (prefix, value, min, max, file, line, 0);
+}
+
+void
+as_bad_value_out_of_range (char *   prefix,
+                          offsetT  value,
+                          offsetT  min,
+                          offsetT  max,
+                          char *   file,
+                          unsigned line)
+{
+  as_internal_value_out_of_range (prefix, value, min, max, file, line, 1);
 }
 }