1 /* strings -- print the strings of printable characters in files
2 Copyright (C) 1993-2024 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
19 /* Usage: strings [options] file...
24 - Scan each file in its entirety.
27 -d Scan only the initialized data section(s) of object files.
30 -f Print the name of the file before each string.
34 -min-len Print graphic char sequences, MIN-LEN or more bytes long,
35 that are followed by a NUL or a non-displayable character.
39 -t {o,x,d} Print the offset within the file before each string,
42 --include-all-whitespace
43 -w By default tab and space are the only whitepace included in graphic
44 char sequences. This option considers all of isspace() valid.
46 -o Like -to. (Some other implementations have -o like -to,
47 others like -td. We chose one arbitrarily.)
49 --encoding={s,S,b,l,B,L}
51 Select character encoding: 7-bit-character, 8-bit-character,
52 bigendian 16-bit, littleendian 16-bit, bigendian 32-bit,
57 Specify a non-default object file format.
59 --unicode={default|locale|invalid|hex|escape|highlight}
61 Determine how to handle UTF-8 unicode characters. The default
62 is no special treatment. All other versions of this option
63 only apply if the encoding is valid and enabling the option
65 The 'locale' option displays the characters according to the
66 current locale. The 'invalid' option treats them as
67 non-string characters. The 'hex' option displays them as hex
68 byte sequences. The 'escape' option displays them as escape
69 sequences and the 'highlight' option displays them as
70 coloured escape sequences.
72 --output-separator=sep_string
73 -s sep_string String used to separate parsed strings in output.
77 -h Print the usage message on the standard output.
81 -v Print the program version number.
83 Written by Richard Stallman <rms@gnu.ai.mit.edu>
84 and David MacKenzie <djm@gnu.ai.mit.edu>. */
89 #include "libiberty.h"
90 #include "safe-ctype.h"
94 #define streq(a,b) (strcmp ((a),(b)) == 0)
97 typedef enum unicode_display_type
105 } unicode_display_type
;
107 static unicode_display_type unicode_display
= unicode_default
;
109 #define STRING_ISGRAPHIC(c) \
112 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127) \
113 || (include_all_whitespace && ISSPACE (c))) \
120 /* The BFD section flags that identify an initialized data section. */
121 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
123 /* Radix for printing addresses (must be 8, 10 or 16). */
124 static int address_radix
;
126 /* Minimum length of sequence of graphic chars to trigger output. */
127 static unsigned int string_min
;
129 /* Whether or not we include all whitespace as a graphic char. */
130 static bool include_all_whitespace
;
132 /* TRUE means print address within file for each string. */
133 static bool print_addresses
;
135 /* TRUE means print filename for each string. */
136 static bool print_filenames
;
138 /* TRUE means for object files scan only the data section. */
139 static bool datasection_only
;
141 /* The BFD object file format. */
144 /* The character encoding format. */
145 static char encoding
;
146 static int encoding_bytes
;
148 /* Output string used to separate parsed strings */
149 static char *output_separator
;
151 static struct option long_options
[] =
153 {"all", no_argument
, NULL
, 'a'},
154 {"bytes", required_argument
, NULL
, 'n'},
155 {"data", no_argument
, NULL
, 'd'},
156 {"encoding", required_argument
, NULL
, 'e'},
157 {"help", no_argument
, NULL
, 'h'},
158 {"include-all-whitespace", no_argument
, NULL
, 'w'},
159 {"output-separator", required_argument
, NULL
, 's'},
160 {"print-file-name", no_argument
, NULL
, 'f'},
161 {"radix", required_argument
, NULL
, 't'},
162 {"target", required_argument
, NULL
, 'T'},
163 {"unicode", required_argument
, NULL
, 'U'},
164 {"version", no_argument
, NULL
, 'v'},
168 static bool strings_file (char *);
169 static void print_strings (const char *, FILE *, file_ptr
, int, char *);
170 static void usage (FILE *, int) ATTRIBUTE_NORETURN
;
172 int main (int, char **);
175 set_string_min (const char * arg
)
178 unsigned long l
= strtoul (arg
, &s
, 0);
180 if (s
!= NULL
&& *s
!= 0)
181 fatal (_("invalid integer argument %s"), arg
);
183 string_min
= (unsigned int) l
;
185 if (l
!= (unsigned long) string_min
)
186 fatal (_("minimum string length is too big: %s"), arg
);
189 fatal (_("minimum string length is too small: %s"), arg
);
191 /* PR 30595: Look for minimum string lengths that overflow an 'int'. */
192 if (string_min
+ 1 == 0)
193 fatal (_("minimum string length %s is too big"), arg
);
195 /* FIXME: Should we warn for unreasonably large minimum
196 string lengths, even if technically they will work ? */
200 main (int argc
, char **argv
)
204 bool files_given
= false;
207 setlocale (LC_ALL
, "");
208 bindtextdomain (PACKAGE
, LOCALEDIR
);
209 textdomain (PACKAGE
);
211 program_name
= argv
[0];
212 xmalloc_set_program_name (program_name
);
213 bfd_set_error_program_name (program_name
);
215 expandargv (&argc
, &argv
);
218 include_all_whitespace
= false;
219 print_addresses
= false;
220 print_filenames
= false;
221 if (DEFAULT_STRINGS_ALL
)
222 datasection_only
= false;
224 datasection_only
= true;
227 output_separator
= NULL
;
229 while ((optc
= getopt_long (argc
, argv
, "adfhHn:wot:e:T:s:U:Vv0123456789",
230 long_options
, (int *) 0)) != EOF
)
235 datasection_only
= false;
239 datasection_only
= true;
243 print_filenames
= true;
251 set_string_min (optarg
);
255 include_all_whitespace
= true;
259 print_addresses
= true;
264 print_addresses
= true;
265 if (optarg
[1] != '\0')
291 if (optarg
[1] != '\0')
293 encoding
= optarg
[0];
297 output_separator
= optarg
;
301 if (streq (optarg
, "default") || streq (optarg
, "d"))
302 unicode_display
= unicode_default
;
303 else if (streq (optarg
, "locale") || streq (optarg
, "l"))
304 unicode_display
= unicode_locale
;
305 else if (streq (optarg
, "escape") || streq (optarg
, "e"))
306 unicode_display
= unicode_escape
;
307 else if (streq (optarg
, "invalid") || streq (optarg
, "i"))
308 unicode_display
= unicode_invalid
;
309 else if (streq (optarg
, "hex") || streq (optarg
, "x"))
310 unicode_display
= unicode_hex
;
311 else if (streq (optarg
, "highlight") || streq (optarg
, "h"))
312 unicode_display
= unicode_highlight
;
314 fatal (_("invalid argument to -U/--unicode: %s"), optarg
);
319 print_version ("strings");
326 numeric_opt
= optind
;
331 if (unicode_display
!= unicode_default
)
334 if (numeric_opt
!= 0)
335 set_string_min (argv
[numeric_opt
- 1] + 1);
355 if (bfd_init () != BFD_INIT_MAGIC
)
356 fatal (_("fatal error: libbfd ABI mismatch"));
357 set_default_bfd_target ();
361 datasection_only
= false;
362 SET_BINARY (fileno (stdin
));
363 print_strings ("{standard input}", stdin
, 0, 0, (char *) NULL
);
368 for (; optind
< argc
; ++optind
)
370 if (streq (argv
[optind
], "-"))
371 datasection_only
= false;
375 exit_status
|= !strings_file (argv
[optind
]);
383 return (exit_status
);
386 /* Scan section SECT of the file ABFD, whose printable name is
387 FILENAME. If it contains initialized data set GOT_A_SECTION and
388 print the strings in it. */
391 strings_a_section (bfd
*abfd
, asection
*sect
, const char *filename
,
394 bfd_size_type sectsize
;
397 if ((sect
->flags
& DATA_FLAGS
) != DATA_FLAGS
)
400 sectsize
= bfd_section_size (sect
);
404 if (!bfd_malloc_and_get_section (abfd
, sect
, &mem
))
406 non_fatal (_("%s: Reading section %s failed: %s"),
407 filename
, sect
->name
, bfd_errmsg (bfd_get_error ()));
411 *got_a_section
= true;
412 print_strings (filename
, NULL
, sect
->filepos
, sectsize
, (char *) mem
);
416 /* Scan all of the sections in FILE, and print the strings
417 in the initialized data section(s).
419 Return TRUE if successful,
420 FALSE if not (such as if FILE is not an object file). */
423 strings_object_file (const char *file
)
429 abfd
= bfd_openr (file
, target
);
432 /* Treat the file as a non-object file. */
435 /* This call is mainly for its side effect of reading in the sections.
436 We follow the traditional behavior of `strings' in that we don't
437 complain if we don't recognize a file to be an object file. */
438 if (!bfd_check_format (abfd
, bfd_object
))
444 got_a_section
= false;
445 for (s
= abfd
->sections
; s
!= NULL
; s
= s
->next
)
446 strings_a_section (abfd
, s
, file
, &got_a_section
);
448 if (!bfd_close (abfd
))
454 return got_a_section
;
457 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
460 strings_file (char *file
)
464 /* get_file_size does not support non-S_ISREG files. */
466 if (stat (file
, &st
) < 0)
469 non_fatal (_("'%s': No such file"), file
);
471 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
472 file
, strerror (errno
));
475 else if (S_ISDIR (st
.st_mode
))
477 non_fatal (_("Warning: '%s' is a directory"), file
);
481 /* If we weren't told to scan the whole file,
482 try to open it as an object file and only look at
483 initialized data sections. If that fails, fall back to the
485 if (!datasection_only
|| !strings_object_file (file
))
489 stream
= fopen (file
, FOPEN_RB
);
492 fprintf (stderr
, "%s: ", program_name
);
497 print_strings (file
, stream
, (file_ptr
) 0, 0, (char *) NULL
);
499 if (fclose (stream
) == EOF
)
501 fprintf (stderr
, "%s: ", program_name
);
510 /* Read the next character, return EOF if none available.
511 Assume that STREAM is positioned so that the next byte read
512 is at address ADDRESS in the file.
514 If STREAM is NULL, do not read from it.
515 The caller can supply a buffer of characters
516 to be processed before the data in STREAM.
517 MAGIC is the address of the buffer and
518 MAGICCOUNT is how many characters are in it. */
521 get_char (FILE *stream
, file_ptr
*address
, int *magiccount
, char **magic
)
526 for (i
= 0; i
< encoding_bytes
; i
++)
538 /* Only use getc_unlocked if we found a declaration for it.
539 Otherwise, libc is not thread safe by default, and we
540 should not use it. */
542 #if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
543 c
= getc_unlocked (stream
);
552 r
= (r
<< 8) | (c
& 0xff);
560 r
= ((r
& 0xff) << 8) | ((r
& 0xff00) >> 8);
563 r
= (((r
& 0xff) << 24) | ((r
& 0xff00) << 8)
564 | ((r
& 0xff0000) >> 8) | ((r
& 0xff000000) >> 24));
571 /* Throw away one byte of a (possibly) multi-byte char C, updating
572 address and buffer to suit. */
575 unget_part_char (long c
, file_ptr
*address
, int *magiccount
, char **magic
)
579 if (encoding_bytes
> 1)
581 *address
-= encoding_bytes
- 1;
583 if (*magiccount
== 0)
585 /* If no magic buffer exists, use temp buffer. */
595 tmp
[0] = (c
>> 8) & 0xff;
599 tmp
[0] = (c
>> 16) & 0xff;
600 tmp
[1] = (c
>> 8) & 0xff;
605 tmp
[0] = (c
>> 8) & 0xff;
606 tmp
[1] = (c
>> 16) & 0xff;
607 tmp
[2] = (c
>> 24) & 0xff;
615 /* If magic buffer exists, rewind. */
616 *magic
-= encoding_bytes
- 1;
617 *magiccount
+= encoding_bytes
- 1;
623 print_filename_and_address (const char * filename
, file_ptr address
)
626 printf ("%s: ", filename
);
628 if (! print_addresses
)
631 switch (address_radix
)
634 if (sizeof (address
) > sizeof (long))
637 printf ("%7llo ", (unsigned long long) address
);
639 printf ("%7I64o ", (unsigned long long) address
);
643 printf ("%7lo ", (unsigned long) address
);
647 if (sizeof (address
) > sizeof (long))
650 printf ("%7llu ", (unsigned long long) address
);
652 printf ("%7I64d ", (unsigned long long) address
);
656 printf ("%7ld ", (long) address
);
660 if (sizeof (address
) > sizeof (long))
663 printf ("%7llx ", (unsigned long long) address
);
665 printf ("%7I64x ", (unsigned long long) address
);
669 printf ("%7lx ", (unsigned long) address
);
674 /* Return non-zero if the bytes starting at BUFFER form a valid UTF-8 encoding.
675 If the encoding is valid then returns the number of bytes it uses. */
678 is_valid_utf8 (const unsigned char * buffer
, unsigned long buflen
)
680 if (buffer
[0] < 0xc0)
686 if ((buffer
[1] & 0xc0) != 0x80)
689 if ((buffer
[0] & 0x20) == 0)
695 if ((buffer
[2] & 0xc0) != 0x80)
698 if ((buffer
[0] & 0x10) == 0)
704 if ((buffer
[3] & 0xc0) != 0x80)
710 /* Display a UTF-8 encoded character in BUFFER according to the setting
711 of unicode_display. The character is known to be valid.
712 Returns the number of bytes consumed. */
715 display_utf8_char (const unsigned char * buffer
)
718 unsigned int utf8_len
;
720 switch (buffer
[0] & 0x30)
733 switch (unicode_display
)
736 fprintf (stderr
, "ICE: unexpected unicode display type\n");
740 case unicode_highlight
:
741 if (unicode_display
== unicode_highlight
&& isatty (1))
742 printf ("\x1B[31;47m"); /* Red. */
747 printf ("\\u%02x%02x",
748 ((buffer
[0] & 0x1c) >> 2),
749 ((buffer
[0] & 0x03) << 6) | (buffer
[1] & 0x3f));
753 printf ("\\u%02x%02x",
754 ((buffer
[0] & 0x0f) << 4) | ((buffer
[1] & 0x3c) >> 2),
755 ((buffer
[1] & 0x03) << 6) | ((buffer
[2] & 0x3f)));
759 printf ("\\u%02x%02x%02x",
760 ((buffer
[0] & 0x07) << 6) | ((buffer
[1] & 0x3c) >> 2),
761 ((buffer
[1] & 0x03) << 6) | ((buffer
[2] & 0x3c) >> 2),
762 ((buffer
[2] & 0x03) << 6) | ((buffer
[3] & 0x3f)));
769 if (unicode_display
== unicode_highlight
&& isatty (1))
770 printf ("\033[0m"); /* Default colour. */
776 for (j
= 0; j
< utf8_len
; j
++)
777 printf ("%02x", buffer
[j
]);
782 printf ("%.1s", buffer
);
789 /* Display strings in BUFFER. Treat any UTF-8 encoded characters encountered
790 according to the setting of the unicode_display variable. The buffer
791 contains BUFLEN bytes.
793 Display the characters as if they started at ADDRESS and are contained in
797 print_unicode_buffer (const char * filename
,
799 const unsigned char * buffer
,
800 unsigned long buflen
)
802 /* Paranoia checks... */
805 || unicode_display
== unicode_default
807 || encoding_bytes
!= 1)
809 fprintf (stderr
, "ICE: bad arguments to print_unicode_buffer\n");
816 /* We must only display strings that are at least string_min *characters*
817 long. So we scan the buffer in two stages. First we locate the start
818 of a potential string. Then we walk along it until we have found
819 string_min characters. Then we go back to the start point and start
820 displaying characters according to the unicode_display setting. */
822 unsigned long start_point
= 0;
824 unsigned int char_len
= 1;
825 unsigned int num_found
= 0;
827 for (i
= 0; i
< buflen
; i
+= char_len
)
833 /* Find the first potential character of a string. */
834 if (! STRING_ISGRAPHIC (c
))
848 if ((char_len
= is_valid_utf8 (buffer
+ i
, buflen
- i
)) == 0)
855 if (unicode_display
== unicode_invalid
)
857 /* We have found a valid UTF-8 character, but we treat it as non-graphic. */
864 /* We have found a potential starting point for a string. */
869 if (num_found
>= string_min
)
873 if (num_found
< string_min
)
876 print_filename_and_address (filename
, address
+ start_point
);
878 /* We have found string_min characters. Display them and any
880 for (i
= start_point
; i
< buflen
; i
+= char_len
)
886 if (! STRING_ISGRAPHIC (c
))
890 else if (! is_valid_utf8 (buffer
+ i
, buflen
- i
))
892 else if (unicode_display
== unicode_invalid
)
895 char_len
= display_utf8_char (buffer
+ i
);
898 if (output_separator
)
899 fputs (output_separator
, stdout
);
903 /* FIXME: Using tail recursion here is lazy programming... */
904 print_unicode_buffer (filename
, address
+ i
, buffer
+ i
, buflen
- i
);
908 get_unicode_byte (FILE * stream
,
909 unsigned char * putback
,
910 unsigned int * num_putback
,
911 unsigned int * num_read
)
913 if (* num_putback
> 0)
915 * num_putback
= * num_putback
- 1;
916 return putback
[* num_putback
];
919 * num_read
= * num_read
+ 1;
921 #if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
922 return getc_unlocked (stream
);
924 return getc (stream
);
928 /* Helper function for print_unicode_stream. */
931 print_unicode_stream_body (const char * filename
,
934 unsigned char * putback_buf
,
935 unsigned int num_putback
,
936 unsigned char * print_buf
)
938 /* It would be nice if we could just read the stream into a buffer
939 and then process if with print_unicode_buffer. But the input
940 might be huge or it might time-locked (eg stdin). So instead
941 we go one byte at a time... */
943 file_ptr start_point
= 0;
944 unsigned int num_read
= 0;
945 unsigned int num_chars
= 0;
946 unsigned int num_print
= 0;
949 /* Find a series of string_min characters. Put them into print_buf. */
952 if (num_chars
>= string_min
)
955 c
= get_unicode_byte (stream
, putback_buf
, & num_putback
, & num_read
);
959 if (! STRING_ISGRAPHIC (c
))
961 num_chars
= num_print
= 0;
966 start_point
= num_read
- 1;
970 print_buf
[num_print
] = c
;
978 num_chars
= num_print
= 0;
982 /* We *might* have a UTF-8 sequence. Time to start peeking. */
986 c
= get_unicode_byte (stream
, putback_buf
, & num_putback
, & num_read
);
991 if ((utf8
[1] & 0xc0) != 0x80)
994 putback_buf
[num_putback
++] = utf8
[1];
995 num_chars
= num_print
= 0;
998 else if ((utf8
[0] & 0x20) == 0)
1000 /* A valid 2-byte UTF-8 encoding. */
1001 if (unicode_display
== unicode_invalid
)
1003 putback_buf
[num_putback
++] = utf8
[1];
1004 num_chars
= num_print
= 0;
1008 print_buf
[num_print
++] = utf8
[0];
1009 print_buf
[num_print
++] = utf8
[1];
1015 c
= get_unicode_byte (stream
, putback_buf
, & num_putback
, & num_read
);
1020 if ((utf8
[2] & 0xc0) != 0x80)
1022 /* Invalid UTF-8. */
1023 putback_buf
[num_putback
++] = utf8
[2];
1024 putback_buf
[num_putback
++] = utf8
[1];
1025 num_chars
= num_print
= 0;
1028 else if ((utf8
[0] & 0x10) == 0)
1030 /* A valid 3-byte UTF-8 encoding. */
1031 if (unicode_display
== unicode_invalid
)
1033 putback_buf
[num_putback
++] = utf8
[2];
1034 putback_buf
[num_putback
++] = utf8
[1];
1035 num_chars
= num_print
= 0;
1039 print_buf
[num_print
++] = utf8
[0];
1040 print_buf
[num_print
++] = utf8
[1];
1041 print_buf
[num_print
++] = utf8
[2];
1047 c
= get_unicode_byte (stream
, putback_buf
, & num_putback
, & num_read
);
1052 if ((utf8
[3] & 0xc0) != 0x80)
1054 /* Invalid UTF-8. */
1055 putback_buf
[num_putback
++] = utf8
[3];
1056 putback_buf
[num_putback
++] = utf8
[2];
1057 putback_buf
[num_putback
++] = utf8
[1];
1058 num_chars
= num_print
= 0;
1060 /* We have a valid 4-byte UTF-8 encoding. */
1061 else if (unicode_display
== unicode_invalid
)
1063 putback_buf
[num_putback
++] = utf8
[3];
1064 putback_buf
[num_putback
++] = utf8
[1];
1065 putback_buf
[num_putback
++] = utf8
[2];
1066 num_chars
= num_print
= 0;
1070 print_buf
[num_print
++] = utf8
[0];
1071 print_buf
[num_print
++] = utf8
[1];
1072 print_buf
[num_print
++] = utf8
[2];
1073 print_buf
[num_print
++] = utf8
[3];
1079 if (num_chars
>= string_min
)
1081 /* We know that we have string_min valid characters in print_buf,
1082 and there may be more to come in the stream. Start displaying
1085 print_filename_and_address (filename
, address
+ start_point
);
1088 for (i
= 0; i
< num_print
;)
1090 if (print_buf
[i
] < 127)
1091 putchar (print_buf
[i
++]);
1093 i
+= display_utf8_char (print_buf
+ i
);
1096 /* OK so now we have to start read unchecked bytes. */
1098 /* Find a series of string_min characters. Put them into print_buf. */
1101 c
= get_unicode_byte (stream
, putback_buf
, & num_putback
, & num_read
);
1105 if (! STRING_ISGRAPHIC (c
))
1117 /* We *might* have a UTF-8 sequence. Time to start peeking. */
1118 unsigned char utf8
[4];
1121 c
= get_unicode_byte (stream
, putback_buf
, & num_putback
, & num_read
);
1126 if ((utf8
[1] & 0xc0) != 0x80)
1128 /* Invalid UTF-8. */
1129 putback_buf
[num_putback
++] = utf8
[1];
1132 else if ((utf8
[0] & 0x20) == 0)
1134 /* Valid 2-byte UTF-8. */
1135 if (unicode_display
== unicode_invalid
)
1137 putback_buf
[num_putback
++] = utf8
[1];
1142 (void) display_utf8_char (utf8
);
1147 c
= get_unicode_byte (stream
, putback_buf
, & num_putback
, & num_read
);
1152 if ((utf8
[2] & 0xc0) != 0x80)
1154 /* Invalid UTF-8. */
1155 putback_buf
[num_putback
++] = utf8
[2];
1156 putback_buf
[num_putback
++] = utf8
[1];
1159 else if ((utf8
[0] & 0x10) == 0)
1161 /* Valid 3-byte UTF-8. */
1162 if (unicode_display
== unicode_invalid
)
1164 putback_buf
[num_putback
++] = utf8
[2];
1165 putback_buf
[num_putback
++] = utf8
[1];
1170 (void) display_utf8_char (utf8
);
1175 c
= get_unicode_byte (stream
, putback_buf
, & num_putback
, & num_read
);
1180 if ((utf8
[3] & 0xc0) != 0x80)
1182 /* Invalid UTF-8. */
1183 putback_buf
[num_putback
++] = utf8
[3];
1184 putback_buf
[num_putback
++] = utf8
[2];
1185 putback_buf
[num_putback
++] = utf8
[1];
1188 else if (unicode_display
== unicode_invalid
)
1190 putback_buf
[num_putback
++] = utf8
[3];
1191 putback_buf
[num_putback
++] = utf8
[2];
1192 putback_buf
[num_putback
++] = utf8
[1];
1196 /* A valid 4-byte UTF-8 encoding. */
1197 (void) display_utf8_char (utf8
);
1201 if (output_separator
)
1202 fputs (output_separator
, stdout
);
1208 /* FIXME: Using tail recursion here is lazy, but it works. */
1209 print_unicode_stream_body (filename
, address
+ num_read
, stream
, putback_buf
, num_putback
, print_buf
);
1212 /* Display strings read in from STREAM. Treat any UTF-8 encoded characters
1213 encountered according to the setting of the unicode_display variable.
1214 The stream is positioned at ADDRESS and is attached to FILENAME. */
1217 print_unicode_stream (const char * filename
,
1221 /* Paranoia checks... */
1222 if (filename
== NULL
1224 || unicode_display
== unicode_default
1226 || encoding_bytes
!= 1)
1228 fprintf (stderr
, "ICE: bad arguments to print_unicode_stream\n");
1232 /* Allocate space for string_min 4-byte utf-8 characters. */
1233 size_t amt
= string_min
;
1234 amt
= (4 * amt
) + 1;
1235 unsigned char * print_buf
= xmalloc (amt
);
1236 /* We should never have to put back more than 4 bytes. */
1237 unsigned char putback_buf
[5];
1238 unsigned int num_putback
= 0;
1240 print_unicode_stream_body (filename
, address
, stream
, putback_buf
, num_putback
, print_buf
);
1244 /* Find the strings in file FILENAME, read from STREAM.
1245 Assume that STREAM is positioned so that the next byte read
1246 is at address ADDRESS in the file.
1248 If STREAM is NULL, do not read from it.
1249 The caller can supply a buffer of characters
1250 to be processed before the data in STREAM.
1251 MAGIC is the address of the buffer and
1252 MAGICCOUNT is how many characters are in it.
1253 Those characters come at address ADDRESS and the data in STREAM follow. */
1256 print_strings (const char *filename
, FILE *stream
, file_ptr address
,
1257 int magiccount
, char *magic
)
1259 if (unicode_display
!= unicode_default
)
1262 print_unicode_buffer (filename
, address
,
1263 (const unsigned char *) magic
, magiccount
);
1266 print_unicode_stream (filename
, address
, stream
);
1270 char *buf
= (char *) xmalloc (sizeof (char) * (string_min
+ 1));
1278 /* See if the next `string_min' chars are all graphic chars. */
1281 for (i
= 0; i
< string_min
; i
++)
1283 c
= get_char (stream
, &address
, &magiccount
, &magic
);
1290 if (! STRING_ISGRAPHIC (c
))
1292 /* Found a non-graphic. Try again starting with next byte. */
1293 unget_part_char (c
, &address
, &magiccount
, &magic
);
1299 /* We found a run of `string_min' graphic characters. Print up
1300 to the next non-graphic character. */
1301 print_filename_and_address (filename
, start
);
1304 fputs (buf
, stdout
);
1308 c
= get_char (stream
, &address
, &magiccount
, &magic
);
1311 if (! STRING_ISGRAPHIC (c
))
1313 unget_part_char (c
, &address
, &magiccount
, &magic
);
1319 if (output_separator
)
1320 fputs (output_separator
, stdout
);
1328 usage (FILE *stream
, int status
)
1330 fprintf (stream
, _("Usage: %s [option(s)] [file(s)]\n"), program_name
);
1331 fprintf (stream
, _(" Display printable strings in [file(s)] (stdin by default)\n"));
1332 fprintf (stream
, _(" The options are:\n"));
1334 if (DEFAULT_STRINGS_ALL
)
1335 fprintf (stream
, _("\
1336 -a - --all Scan the entire file, not just the data section [default]\n\
1337 -d --data Only scan the data sections in the file\n"));
1339 fprintf (stream
, _("\
1340 -a - --all Scan the entire file, not just the data section\n\
1341 -d --data Only scan the data sections in the file [default]\n"));
1343 fprintf (stream
, _("\
1344 -f --print-file-name Print the name of the file before each string\n\
1345 -n <number> Locate & print any sequence of at least <number>\n\
1346 --bytes=<number> displayable characters. (The default is 4).\n\
1347 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
1348 -w --include-all-whitespace Include all whitespace as valid string characters\n\
1349 -o An alias for --radix=o\n\
1350 -T --target=<BFDNAME> Specify the binary file format\n\
1351 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
1352 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
1353 --unicode={default|locale|invalid|hex|escape|highlight}\n\
1354 -U {d|l|i|x|e|h} Specify how to treat UTF-8 encoded unicode characters\n\
1355 -s --output-separator=<string> String used to separate strings in output.\n\
1356 @<file> Read options from <file>\n\
1357 -h --help Display this information\n\
1358 -v -V --version Print the program's version number\n"));
1359 list_supported_targets (program_name
, stream
);
1360 if (REPORT_BUGS_TO
[0] && status
== 0)
1361 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);