Updated Finnish translation
[binutils.git] / binutils / bucomm.c
blob26cb09efb42b22ced5f49084d786301462c2d01e
1 /* bucomm.c -- Bin Utils COMmon code.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
3 2003, 2006, 2007
4 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
23 /* We might put this in a library someday so it could be dynamically
24 loaded, but for now it's not necessary. */
26 #include "sysdep.h"
27 #include "bfd.h"
28 #include "libiberty.h"
29 #include "filenames.h"
30 #include "libbfd.h"
32 #include <sys/stat.h>
33 #include <time.h> /* ctime, maybe time_t */
34 #include <assert.h>
35 #include "bucomm.h"
37 #ifndef HAVE_TIME_T_IN_TIME_H
38 #ifndef HAVE_TIME_T_IN_TYPES_H
39 typedef long time_t;
40 #endif
41 #endif
43 static const char * endian_string (enum bfd_endian);
44 static int display_target_list (void);
45 static int display_info_table (int, int);
46 static int display_target_tables (void);
48 /* Error reporting. */
50 char *program_name;
52 void
53 bfd_nonfatal (const char *string)
55 const char *errmsg = bfd_errmsg (bfd_get_error ());
57 if (string)
58 fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
59 else
60 fprintf (stderr, "%s: %s\n", program_name, errmsg);
63 /* Issue a non fatal error message. FILENAME, or if NULL then BFD,
64 are used to indicate the problematic file. SECTION, if non NULL,
65 is used to provide a section name. If FORMAT is non-null, then it
66 is used to print additional information via vfprintf. Finally the
67 bfd error message is printed. In summary, error messages are of
68 one of the following forms:
70 PROGRAM:file: bfd-error-message
71 PROGRAM:file[section]: bfd-error-message
72 PROGRAM:file: printf-message: bfd-error-message
73 PROGRAM:file[section]: printf-message: bfd-error-message
76 void
77 bfd_nonfatal_message (const char *filename,
78 const bfd *bfd, const asection *section,
79 const char *format, ...)
81 const char *errmsg = bfd_errmsg (bfd_get_error ());
82 const char *section_name = NULL;
83 va_list args;
85 va_start (args, format);
86 fprintf (stderr, "%s", program_name);
88 if (bfd)
90 if (!filename)
91 filename = bfd_get_filename (bfd);
92 if (section)
93 section_name = bfd_get_section_name (bfd, section);
95 if (section_name)
96 fprintf (stderr, ":%s[%s]", filename, section_name);
97 else
98 fprintf (stderr, ":%s", filename);
100 if (format)
102 fprintf (stderr, ": ");
103 vfprintf (stderr, format, args);
105 fprintf (stderr, ": %s\n", errmsg);
106 va_end (args);
109 void
110 bfd_fatal (const char *string)
112 bfd_nonfatal (string);
113 xexit (1);
116 void
117 report (const char * format, va_list args)
119 fprintf (stderr, "%s: ", program_name);
120 vfprintf (stderr, format, args);
121 putc ('\n', stderr);
124 void
125 fatal VPARAMS ((const char *format, ...))
127 VA_OPEN (args, format);
128 VA_FIXEDARG (args, const char *, format);
130 report (format, args);
131 VA_CLOSE (args);
132 xexit (1);
135 void
136 non_fatal VPARAMS ((const char *format, ...))
138 VA_OPEN (args, format);
139 VA_FIXEDARG (args, const char *, format);
141 report (format, args);
142 VA_CLOSE (args);
145 /* Set the default BFD target based on the configured target. Doing
146 this permits the binutils to be configured for a particular target,
147 and linked against a shared BFD library which was configured for a
148 different target. */
150 void
151 set_default_bfd_target (void)
153 /* The macro TARGET is defined by Makefile. */
154 const char *target = TARGET;
156 if (! bfd_set_default_target (target))
157 fatal (_("can't set BFD default target to `%s': %s"),
158 target, bfd_errmsg (bfd_get_error ()));
161 /* After a FALSE return from bfd_check_format_matches with
162 bfd_get_error () == bfd_error_file_ambiguously_recognized, print
163 the possible matching targets. */
165 void
166 list_matching_formats (char **p)
168 fprintf (stderr, _("%s: Matching formats:"), program_name);
169 while (*p)
170 fprintf (stderr, " %s", *p++);
171 fputc ('\n', stderr);
174 /* List the supported targets. */
176 void
177 list_supported_targets (const char *name, FILE *f)
179 int t;
180 const char **targ_names = bfd_target_list ();
182 if (name == NULL)
183 fprintf (f, _("Supported targets:"));
184 else
185 fprintf (f, _("%s: supported targets:"), name);
187 for (t = 0; targ_names[t] != NULL; t++)
188 fprintf (f, " %s", targ_names[t]);
189 fprintf (f, "\n");
190 free (targ_names);
193 /* List the supported architectures. */
195 void
196 list_supported_architectures (const char *name, FILE *f)
198 const char **arch;
200 if (name == NULL)
201 fprintf (f, _("Supported architectures:"));
202 else
203 fprintf (f, _("%s: supported architectures:"), name);
205 for (arch = bfd_arch_list (); *arch; arch++)
206 fprintf (f, " %s", *arch);
207 fprintf (f, "\n");
210 /* The length of the longest architecture name + 1. */
211 #define LONGEST_ARCH sizeof ("powerpc:common")
213 static const char *
214 endian_string (enum bfd_endian endian)
216 switch (endian)
218 case BFD_ENDIAN_BIG: return "big endian";
219 case BFD_ENDIAN_LITTLE: return "little endian";
220 default: return "endianness unknown";
224 /* List the targets that BFD is configured to support, each followed
225 by its endianness and the architectures it supports. */
227 static int
228 display_target_list (void)
230 char *dummy_name;
231 int t;
232 int ret = 1;
234 dummy_name = make_temp_file (NULL);
235 for (t = 0; bfd_target_vector[t]; t++)
237 const bfd_target *p = bfd_target_vector[t];
238 bfd *abfd = bfd_openw (dummy_name, p->name);
239 enum bfd_architecture a;
241 printf ("%s\n (header %s, data %s)\n", p->name,
242 endian_string (p->header_byteorder),
243 endian_string (p->byteorder));
245 if (abfd == NULL)
247 bfd_nonfatal (dummy_name);
248 ret = 0;
249 continue;
252 if (! bfd_set_format (abfd, bfd_object))
254 if (bfd_get_error () != bfd_error_invalid_operation)
256 bfd_nonfatal (p->name);
257 ret = 0;
259 bfd_close_all_done (abfd);
260 continue;
263 for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
264 if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
265 printf (" %s\n",
266 bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
267 bfd_close_all_done (abfd);
269 unlink (dummy_name);
270 free (dummy_name);
272 return ret;
275 /* Print a table showing which architectures are supported for entries
276 FIRST through LAST-1 of bfd_target_vector (targets across,
277 architectures down). */
279 static int
280 display_info_table (int first, int last)
282 int t;
283 int ret = 1;
284 char *dummy_name;
285 enum bfd_architecture a;
287 /* Print heading of target names. */
288 printf ("\n%*s", (int) LONGEST_ARCH, " ");
289 for (t = first; t < last && bfd_target_vector[t]; t++)
290 printf ("%s ", bfd_target_vector[t]->name);
291 putchar ('\n');
293 dummy_name = make_temp_file (NULL);
294 for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
295 if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
297 printf ("%*s ", (int) LONGEST_ARCH - 1,
298 bfd_printable_arch_mach (a, 0));
299 for (t = first; t < last && bfd_target_vector[t]; t++)
301 const bfd_target *p = bfd_target_vector[t];
302 bfd_boolean ok = TRUE;
303 bfd *abfd = bfd_openw (dummy_name, p->name);
305 if (abfd == NULL)
307 bfd_nonfatal (p->name);
308 ret = 0;
309 ok = FALSE;
312 if (ok)
314 if (! bfd_set_format (abfd, bfd_object))
316 if (bfd_get_error () != bfd_error_invalid_operation)
318 bfd_nonfatal (p->name);
319 ret = 0;
321 ok = FALSE;
325 if (ok)
327 if (! bfd_set_arch_mach (abfd, a, 0))
328 ok = FALSE;
331 if (ok)
332 printf ("%s ", p->name);
333 else
335 int l = strlen (p->name);
336 while (l--)
337 putchar ('-');
338 putchar (' ');
340 if (abfd != NULL)
341 bfd_close_all_done (abfd);
343 putchar ('\n');
345 unlink (dummy_name);
346 free (dummy_name);
348 return ret;
351 /* Print tables of all the target-architecture combinations that
352 BFD has been configured to support. */
354 static int
355 display_target_tables (void)
357 int t;
358 int columns;
359 int ret = 1;
360 char *colum;
362 columns = 0;
363 colum = getenv ("COLUMNS");
364 if (colum != NULL)
365 columns = atoi (colum);
366 if (columns == 0)
367 columns = 80;
369 t = 0;
370 while (bfd_target_vector[t] != NULL)
372 int oldt = t, wid;
374 wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
375 ++t;
376 while (wid < columns && bfd_target_vector[t] != NULL)
378 int newwid;
380 newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
381 if (newwid >= columns)
382 break;
383 wid = newwid;
384 ++t;
386 if (! display_info_table (oldt, t))
387 ret = 0;
390 return ret;
394 display_info (void)
396 printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
397 if (! display_target_list () || ! display_target_tables ())
398 return 1;
399 else
400 return 0;
403 /* Display the archive header for an element as if it were an ls -l listing:
405 Mode User\tGroup\tSize\tDate Name */
407 void
408 print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
410 struct stat buf;
412 if (verbose)
414 if (bfd_stat_arch_elt (abfd, &buf) == 0)
416 char modebuf[11];
417 char timebuf[40];
418 time_t when = buf.st_mtime;
419 const char *ctime_result = (const char *) ctime (&when);
421 /* POSIX format: skip weekday and seconds from ctime output. */
422 sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
424 mode_string (buf.st_mode, modebuf);
425 modebuf[10] = '\0';
426 /* POSIX 1003.2/D11 says to skip first character (entry type). */
427 fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
428 (long) buf.st_uid, (long) buf.st_gid,
429 (long) buf.st_size, timebuf);
433 fprintf (file, "%s\n", bfd_get_filename (abfd));
436 /* Return a path for a new temporary file in the same directory
437 as file PATH. */
439 static char *
440 template_in_dir (const char *path)
442 #define template "stXXXXXX"
443 const char *slash = strrchr (path, '/');
444 char *tmpname;
445 size_t len;
447 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
449 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
450 char *bslash = strrchr (path, '\\');
452 if (slash == NULL || (bslash != NULL && bslash > slash))
453 slash = bslash;
454 if (slash == NULL && path[0] != '\0' && path[1] == ':')
455 slash = path + 1;
457 #endif
459 if (slash != (char *) NULL)
461 len = slash - path;
462 tmpname = xmalloc (len + sizeof (template) + 2);
463 memcpy (tmpname, path, len);
465 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
466 /* If tmpname is "X:", appending a slash will make it a root
467 directory on drive X, which is NOT the same as the current
468 directory on drive X. */
469 if (len == 2 && tmpname[1] == ':')
470 tmpname[len++] = '.';
471 #endif
472 tmpname[len++] = '/';
474 else
476 tmpname = xmalloc (sizeof (template));
477 len = 0;
480 memcpy (tmpname + len, template, sizeof (template));
481 return tmpname;
482 #undef template
485 /* Return the name of a created temporary file in the same directory
486 as FILENAME. */
488 char *
489 make_tempname (char *filename)
491 char *tmpname = template_in_dir (filename);
492 int fd;
494 #ifdef HAVE_MKSTEMP
495 fd = mkstemp (tmpname);
496 #else
497 tmpname = mktemp (tmpname);
498 if (tmpname == NULL)
499 return NULL;
500 fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
501 #endif
502 if (fd == -1)
503 return NULL;
504 close (fd);
505 return tmpname;
508 /* Return the name of a created temporary directory inside the
509 directory containing FILENAME. */
511 char *
512 make_tempdir (char *filename)
514 char *tmpname = template_in_dir (filename);
516 #ifdef HAVE_MKDTEMP
517 return mkdtemp (tmpname);
518 #else
519 tmpname = mktemp (tmpname);
520 if (tmpname == NULL)
521 return NULL;
522 #if defined (_WIN32) && !defined (__CYGWIN32__)
523 if (mkdir (tmpname) != 0)
524 return NULL;
525 #else
526 if (mkdir (tmpname, 0700) != 0)
527 return NULL;
528 #endif
529 return tmpname;
530 #endif
533 /* Parse a string into a VMA, with a fatal error if it can't be
534 parsed. */
536 bfd_vma
537 parse_vma (const char *s, const char *arg)
539 bfd_vma ret;
540 const char *end;
542 ret = bfd_scan_vma (s, &end, 0);
544 if (*end != '\0')
545 fatal (_("%s: bad number: %s"), arg, s);
547 return ret;
550 /* Returns the size of the named file. If the file does not
551 exist, or if it is not a real file, then a suitable non-fatal
552 error message is printed and zero is returned. */
554 off_t
555 get_file_size (const char * file_name)
557 struct stat statbuf;
559 if (stat (file_name, &statbuf) < 0)
561 if (errno == ENOENT)
562 non_fatal (_("'%s': No such file"), file_name);
563 else
564 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
565 file_name, strerror (errno));
567 else if (! S_ISREG (statbuf.st_mode))
568 non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
569 else
570 return statbuf.st_size;
572 return 0;
575 /* Return the filename in a static buffer. */
577 const char *
578 bfd_get_archive_filename (bfd *abfd)
580 static size_t curr = 0;
581 static char *buf;
582 size_t needed;
584 assert (abfd != NULL);
586 if (!abfd->my_archive)
587 return bfd_get_filename (abfd);
589 needed = (strlen (bfd_get_filename (abfd->my_archive))
590 + strlen (bfd_get_filename (abfd)) + 3);
591 if (needed > curr)
593 if (curr)
594 free (buf);
595 curr = needed + (needed >> 1);
596 buf = bfd_malloc (curr);
597 /* If we can't malloc, fail safe by returning just the file name.
598 This function is only used when building error messages. */
599 if (!buf)
601 curr = 0;
602 return bfd_get_filename (abfd);
605 sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
606 bfd_get_filename (abfd));
607 return buf;