gdb/doc/
[binutils-gdb.git] / binutils / bucomm.c
index 03a4d2873e2a325771c4f0fd82bf3c9c96ac3b65..e568b031ab953e0de0ded5ee195dff970a7cddcf 100644 (file)
@@ -1,12 +1,13 @@
 /* bucomm.c -- Bin Utils COMmon code.
-   Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003
+   Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
+   2003, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
    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,
 /* We might put this in a library someday so it could be dynamically
    loaded, but for now it's not necessary.  */
 
+#include "sysdep.h"
 #include "bfd.h"
-#include "bfdver.h"
 #include "libiberty.h"
-#include "bucomm.h"
 #include "filenames.h"
 #include "libbfd.h"
 
 #include <sys/stat.h>
 #include <time.h>              /* ctime, maybe time_t */
 #include <assert.h>
+#include "bucomm.h"
 
 #ifndef HAVE_TIME_T_IN_TIME_H
 #ifndef HAVE_TIME_T_IN_TYPES_H
@@ -59,6 +60,52 @@ bfd_nonfatal (const char *string)
     fprintf (stderr, "%s: %s\n", program_name, errmsg);
 }
 
+/* Issue a non fatal error message.  FILENAME, or if NULL then BFD,
+   are used to indicate the problematic file.  SECTION, if non NULL,
+   is used to provide a section name.  If FORMAT is non-null, then it
+   is used to print additional information via vfprintf.  Finally the
+   bfd error message is printed.  In summary, error messages are of
+   one of the following forms:
+
+   PROGRAM:file: bfd-error-message
+   PROGRAM:file[section]: bfd-error-message
+   PROGRAM:file: printf-message: bfd-error-message
+   PROGRAM:file[section]: printf-message: bfd-error-message.  */
+
+void
+bfd_nonfatal_message (const char *filename,
+                     const bfd *abfd,
+                     const asection *section,
+                     const char *format, ...)
+{
+  const char *errmsg = bfd_errmsg (bfd_get_error ());
+  const char *section_name = NULL;
+  va_list args;
+
+  va_start (args, format);
+  fprintf (stderr, "%s", program_name);
+  
+  if (abfd)
+    {
+      if (!filename)
+       filename = bfd_get_archive_filename (abfd);
+      if (section)
+       section_name = bfd_get_section_name (abfd, section);
+    }
+  if (section_name)
+    fprintf (stderr, ":%s[%s]", filename, section_name);
+  else
+    fprintf (stderr, ":%s", filename);
+
+  if (format)
+    {
+      fprintf (stderr, ": ");
+      vfprintf (stderr, format, args);
+    }
+  fprintf (stderr, ": %s\n", errmsg);
+  va_end (args);
+}
+
 void
 bfd_fatal (const char *string)
 {
@@ -148,16 +195,18 @@ list_supported_targets (const char *name, FILE *f)
 void
 list_supported_architectures (const char *name, FILE *f)
 {
-  const char **arch;
+  const char ** arch;
+  const char ** arches;
 
   if (name == NULL)
     fprintf (f, _("Supported architectures:"));
   else
     fprintf (f, _("%s: supported architectures:"), name);
 
-  for (arch = bfd_arch_list (); *arch; arch++)
+  for (arch = arches = bfd_arch_list (); *arch; arch++)
     fprintf (f, " %s", *arch);
   fprintf (f, "\n");
+  free (arches);
 }
 \f
 /* The length of the longest architecture name + 1.  */
@@ -189,7 +238,7 @@ display_target_list (void)
     {
       const bfd_target *p = bfd_target_vector[t];
       bfd *abfd = bfd_openw (dummy_name, p->name);
-      enum bfd_architecture a;
+      int a;
 
       printf ("%s\n (header %s, data %s)\n", p->name,
              endian_string (p->header_byteorder),
@@ -235,7 +284,7 @@ display_info_table (int first, int last)
   int t;
   int ret = 1;
   char *dummy_name;
-  enum bfd_architecture a;
+  int a;
 
   /* Print heading of target names.  */
   printf ("\n%*s", (int) LONGEST_ARCH, " ");
@@ -245,10 +294,11 @@ display_info_table (int first, int last)
 
   dummy_name = make_temp_file (NULL);
   for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
-    if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
+    if (strcmp (bfd_printable_arch_mach ((enum bfd_architecture) a, 0),
+                "UNKNOWN!") != 0)
       {
        printf ("%*s ", (int) LONGEST_ARCH - 1,
-               bfd_printable_arch_mach (a, 0));
+               bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
        for (t = first; t < last && bfd_target_vector[t]; t++)
          {
            const bfd_target *p = bfd_target_vector[t];
@@ -277,7 +327,7 @@ display_info_table (int first, int last)
 
            if (ok)
              {
-               if (! bfd_set_arch_mach (abfd, a, 0))
+               if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
                  ok = FALSE;
              }
 
@@ -386,55 +436,103 @@ print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
   fprintf (file, "%s\n", bfd_get_filename (abfd));
 }
 
-/* Return the name of a temporary file in the same directory as FILENAME.  */
+/* Return a path for a new temporary file in the same directory
+   as file PATH.  */
 
-char *
-make_tempname (char *filename)
+static char *
+template_in_dir (const char *path)
 {
-  static char template[] = "stXXXXXX";
+#define template "stXXXXXX"
+  const char *slash = strrchr (path, '/');
   char *tmpname;
-  char *slash = strrchr (filename, '/');
+  size_t len;
 
 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
   {
     /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
-    char *bslash = strrchr (filename, '\\');
+    char *bslash = strrchr (path, '\\');
+
     if (slash == NULL || (bslash != NULL && bslash > slash))
       slash = bslash;
-    if (slash == NULL && filename[0] != '\0' && filename[1] == ':')
-      slash = filename + 1;
+    if (slash == NULL && path[0] != '\0' && path[1] == ':')
+      slash = path + 1;
   }
 #endif
 
   if (slash != (char *) NULL)
     {
-      char c;
+      len = slash - path;
+      tmpname = (char *) xmalloc (len + sizeof (template) + 2);
+      memcpy (tmpname, path, len);
 
-      c = *slash;
-      *slash = 0;
-      tmpname = xmalloc (strlen (filename) + sizeof (template) + 2);
-      strcpy (tmpname, filename);
 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
       /* If tmpname is "X:", appending a slash will make it a root
         directory on drive X, which is NOT the same as the current
         directory on drive X.  */
-      if (tmpname[1] == ':' && tmpname[2] == '\0')
-       strcat (tmpname, ".");
+      if (len == 2 && tmpname[1] == ':')
+       tmpname[len++] = '.';
 #endif
-      strcat (tmpname, "/");
-      strcat (tmpname, template);
-      mktemp (tmpname);
-      *slash = c;
+      tmpname[len++] = '/';
     }
   else
     {
-      tmpname = xmalloc (sizeof (template));
-      strcpy (tmpname, template);
-      mktemp (tmpname);
+      tmpname = (char *) xmalloc (sizeof (template));
+      len = 0;
     }
+
+  memcpy (tmpname + len, template, sizeof (template));
+  return tmpname;
+#undef template
+}
+
+/* Return the name of a created temporary file in the same directory
+   as FILENAME.  */
+
+char *
+make_tempname (char *filename)
+{
+  char *tmpname = template_in_dir (filename);
+  int fd;
+
+#ifdef HAVE_MKSTEMP
+  fd = mkstemp (tmpname);
+#else
+  tmpname = mktemp (tmpname);
+  if (tmpname == NULL)
+    return NULL;
+  fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
+#endif
+  if (fd == -1)
+    return NULL;
+  close (fd);
   return tmpname;
 }
 
+/* Return the name of a created temporary directory inside the
+   directory containing FILENAME.  */
+
+char *
+make_tempdir (char *filename)
+{
+  char *tmpname = template_in_dir (filename);
+
+#ifdef HAVE_MKDTEMP
+  return mkdtemp (tmpname);
+#else
+  tmpname = mktemp (tmpname);
+  if (tmpname == NULL)
+    return NULL;
+#if defined (_WIN32) && !defined (__CYGWIN32__)
+  if (mkdir (tmpname) != 0)
+    return NULL;
+#else
+  if (mkdir (tmpname, 0700) != 0)
+    return NULL;
+#endif
+  return tmpname;
+#endif
+}
+
 /* Parse a string into a VMA, with a fatal error if it can't be
    parsed.  */
 
@@ -454,7 +552,7 @@ parse_vma (const char *s, const char *arg)
 
 /* Returns the size of the named file.  If the file does not
    exist, or if it is not a real file, then a suitable non-fatal
-   error message is printed and zero is returned.  */
+   error message is printed and (off_t) -1 is returned.  */
 
 off_t
 get_file_size (const char * file_name)
@@ -474,13 +572,13 @@ get_file_size (const char * file_name)
   else
     return statbuf.st_size;
 
-  return 0;
+  return (off_t) -1;
 }
 
 /* Return the filename in a static buffer.  */
 
 const char *
-bfd_get_archive_filename (bfd *abfd)
+bfd_get_archive_filename (const bfd *abfd)
 {
   static size_t curr = 0;
   static char *buf;
@@ -498,7 +596,7 @@ bfd_get_archive_filename (bfd *abfd)
       if (curr)
        free (buf);
       curr = needed + (needed >> 1);
-      buf = bfd_malloc (curr);
+      buf = (char *) bfd_malloc (curr);
       /* If we can't malloc, fail safe by returning just the file name.
         This function is only used when building error messages.  */
       if (!buf)