X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fstrings.c;h=5d3aa6d4fa7f8dab802360c8aadd3619ea45413c;hb=198ce79b6b8e11c56a270eb3686574b87b0e7c75;hp=02ef67ba37ac890bb5d1cdfdf41a74b4ae461825;hpb=cef35d488209227385e0aa9ab92ebf5a861c3780;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/strings.c b/binutils/strings.c index 02ef67ba37..5d3aa6d4fa 100644 --- a/binutils/strings.c +++ b/binutils/strings.c @@ -1,5 +1,6 @@ /* strings -- print the strings of printable characters in files - Copyright (C) 1993, 94 Free Software Foundation, Inc. + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 + Free Software Foundation, Inc. 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 @@ -13,7 +14,8 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ /* Usage: strings [options] file... @@ -49,17 +51,38 @@ Written by Richard Stallman and David MacKenzie . */ +#include "bfd.h" #include #include #include #include -#include "bfd.h" #include "bucomm.h" +#include "libiberty.h" + +/* Some platforms need to put stdin into binary mode, to read + binary files. */ +#ifdef HAVE_SETMODE +#ifndef O_BINARY +#ifdef _O_BINARY +#define O_BINARY _O_BINARY +#define setmode _setmode +#else +#define O_BINARY 0 +#endif +#endif +#if O_BINARY +#include +#define SET_BINARY(f) do { if (!isatty(f)) setmode(f,O_BINARY); } while (0) +#endif +#endif -#ifdef isascii -#define isgraphic(c) (isascii (c) && isprint (c)) +/* Not all printable characters have ASCII codes (depending upon the + LOCALE set) but on some older systems it is not safe to test isprint + without first testing isascii... */ +#if defined isascii && !defined HAVE_LOCALE_H +#define isgraphic(c) (isascii (c) && (isprint (c) || (c) == '\t')) #else -#define isgraphic(c) (isprint (c)) +#define isgraphic(c) (isprint (c) || (c) == '\t') #endif #ifndef errno @@ -67,7 +90,7 @@ extern int errno; #endif /* The BFD section flags that identify an initialized data section. */ -#define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS) +#define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS) /* Radix for printing addresses (must be 8, 10 or 16). */ static int address_radix; @@ -90,8 +113,6 @@ static boolean got_a_section; /* The BFD object file format. */ static char *target; -extern char *program_version; - static struct option long_options[] = { {"all", no_argument, NULL, 'a'}, @@ -104,14 +125,16 @@ static struct option long_options[] = {NULL, 0, NULL, 0} }; +static void strings_a_section PARAMS ((bfd *, asection *, PTR)); +static boolean strings_object_file PARAMS ((const char *)); static boolean strings_file PARAMS ((char *file)); static int integer_arg PARAMS ((char *s)); -static void print_strings PARAMS ((char *filename, FILE *stream, +static void print_strings PARAMS ((const char *filename, FILE *stream, file_ptr address, int stop_point, int magiccount, char *magic)); static void usage PARAMS ((FILE *stream, int status)); -void +int main (argc, argv) int argc; char **argv; @@ -120,7 +143,14 @@ main (argc, argv) int exit_status = 0; boolean files_given = false; +#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) + setlocale (LC_ALL, ""); +#endif + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + program_name = argv[0]; + xmalloc_set_program_name (program_name); string_min = -1; print_addresses = false; print_filenames = false; @@ -147,9 +177,7 @@ main (argc, argv) string_min = integer_arg (optarg); if (string_min < 1) { - fprintf (stderr, "%s: invalid number %s\n", - program_name, optarg); - exit (1); + fatal (_("invalid number %s"), optarg); } break; @@ -186,15 +214,15 @@ main (argc, argv) break; case 'v': - printf ("GNU %s version %s\n", program_name, program_version); - exit (0); + print_version ("strings"); + break; case '?': usage (stderr, 1); default: if (string_min < 0) - string_min = optc; + string_min = optc - '0'; else string_min = string_min * 10 + optc - '0'; break; @@ -205,22 +233,35 @@ main (argc, argv) string_min = 4; bfd_init (); + set_default_bfd_target (); - for (; optind < argc; ++optind) + if (optind >= argc) { - if (!strcmp (argv[optind], "-")) - datasection_only = false; - else + datasection_only = false; +#ifdef SET_BINARY + SET_BINARY (fileno (stdin)); +#endif + print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL); + files_given = true; + } + else + { + for (; optind < argc; ++optind) { - files_given = true; - exit_status |= (strings_file (argv[optind]) == false); + if (strcmp (argv[optind], "-") == 0) + datasection_only = false; + else + { + files_given = true; + exit_status |= (strings_file (argv[optind]) == false); + } } } if (files_given == false) usage (stderr, 1); - exit (exit_status); + return (exit_status); } /* Scan section SECT of the file ABFD, whose printable name is FILE. @@ -228,11 +269,13 @@ main (argc, argv) set `got_a_section' and print the strings in it. */ static void -strings_a_section (abfd, sect, file) +strings_a_section (abfd, sect, filearg) bfd *abfd; asection *sect; - PTR file; + PTR filearg; { + const char *file = (const char *) filearg; + if ((sect->flags & DATA_FLAGS) == DATA_FLAGS) { bfd_size_type sz = bfd_get_section_size_before_reloc (sect); @@ -254,7 +297,7 @@ strings_a_section (abfd, sect, file) static boolean strings_object_file (file) - char *file; + const char *file; { bfd *abfd = bfd_openr (file, target); @@ -274,7 +317,7 @@ strings_object_file (file) } got_a_section = false; - bfd_map_over_sections (abfd, strings_a_section, file); + bfd_map_over_sections (abfd, strings_a_section, (PTR) file); if (!bfd_close (abfd)) { @@ -299,7 +342,10 @@ strings_file (file) { FILE *stream; - stream = fopen (file, "r"); + stream = fopen (file, "rb"); + /* Not all systems permit "rb", so try "r" if it failed. */ + if (stream == NULL) + stream = fopen (file, "r"); if (stream == NULL) { fprintf (stderr, "%s: ", program_name); @@ -334,18 +380,18 @@ strings_file (file) static void print_strings (filename, stream, address, stop_point, magiccount, magic) - char *filename; + const char *filename; FILE *stream; file_ptr address; int stop_point; int magiccount; char *magic; { - int bufsize = 100; - char *buf = (char *) xmalloc (bufsize); + char *buf = (char *) xmalloc (string_min + 1); while (1) { + file_ptr start; int i; int c; @@ -353,6 +399,7 @@ print_strings (filename, stream, address, stop_point, magiccount, magic) tryline: if (stop_point && address >= stop_point) break; + start = address; for (i = 0; i < string_min; i++) { if (magiccount) @@ -365,7 +412,7 @@ print_strings (filename, stream, address, stop_point, magiccount, magic) if (stream == NULL) return; c = getc (stream); - if (c < 0) + if (c == EOF) return; } address++; @@ -375,78 +422,51 @@ print_strings (filename, stream, address, stop_point, magiccount, magic) buf[i] = c; } - /* We found a run of `string_min' graphic characters. - Now see if it is terminated with a NUL byte or a newline. */ - while (1) - { - if (i == bufsize) - { - bufsize *= 2; - buf = (char *) xrealloc (buf, bufsize); - } - if (magiccount) - { - magiccount--; - c = *magic++; - } - else - { - if (stream == NULL) - return; - c = getc (stream); - if (c < 0) - return; - } - address++; - if (c == '\0' || c == '\n') - break; /* It is; print this string. */ - if (!isgraphic (c)) - goto tryline; /* It isn't; give up on this string. */ - buf[i++] = c; /* The string continues; store it all. */ - } + /* We found a run of `string_min' graphic characters. Print up + to the next non-graphic character. */ - /* If we get here, the string is all graphics and properly terminated, - so print it. It is all in `buf' and `i' is its length. */ - buf[i] = '\0'; if (print_filenames) printf ("%s: ", filename); if (print_addresses) switch (address_radix) { case 8: - printf ("%7lo ", (unsigned long) (address - i - 1)); + printf ("%7lo ", (unsigned long) start); break; case 10: - printf ("%7ld ", (long) (address - i - 1)); + printf ("%7ld ", (long) start); break; case 16: - printf ("%7lx ", (unsigned long) (address - i - 1)); + printf ("%7lx ", (unsigned long) start); break; } - for (i = 0; (c = buf[i]) != '\0'; i++) - switch (c) - { - case '\n': - printf ("\\n"); - break; - case '\t': - printf ("\\t"); - break; - case '\f': - printf ("\\f"); - break; - case '\b': - printf ("\\b"); - break; - case '\r': - printf ("\\r"); + buf[i] = '\0'; + fputs (buf, stdout); + + while (1) + { + if (magiccount) + { + magiccount--; + c = *magic++; + } + else + { + if (stream == NULL) + break; + c = getc (stream); + if (c == EOF) + break; + } + address++; + if (! isgraphic (c)) break; - default: - putchar (c); - } + putchar (c); + } + putchar ('\n'); } } @@ -493,8 +513,7 @@ integer_arg (s) if (*p) { - fprintf (stderr, "%s: invalid integer argument %s\n", program_name, s); - exit (1); + fatal (_("invalid integer argument %s"), s); } return value; } @@ -504,10 +523,13 @@ usage (stream, status) FILE *stream; int status; { - fprintf (stream, "\ + fprintf (stream, _("\ Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\ [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\ - [--target=bfdname] [--help] [--version] file...\n", + [--target=bfdname] [--help] [--version] file...\n"), program_name); + list_supported_targets (program_name, stream); + if (status == 0) + fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); exit (status); }