Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/coreutils/od_bloaty.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/coreutils/od_bloaty.c
r1765 r2725 18 18 /* Written by Jim Meyering. */ 19 19 20 /* Busyboxed by Den is Vlasenko20 /* Busyboxed by Denys Vlasenko 21 21 22 22 Based on od.c from coreutils-5.2.1 … … 51 51 52 52 #include "libbb.h" 53 #include <getopt.h>54 53 55 54 #define assert(a) ((void)0) … … 182 181 the number of bytes to skip. */ 183 182 static off_t pseudo_offset; 184 /* The number of input bytes to skip before formatting and writing. */185 static off_t n_bytes_to_skip;186 183 /* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all 187 184 input is formatted. */ 188 /* The maximum number of bytes that will be formatted. */189 static off_t max_bytes_to_format;190 /* The offset of the first byte after the last byte to be formatted. */191 static off_t end_offset;192 185 193 186 /* The number of input bytes formatted per output line. It must be … … 195 188 the specified output types. It should be as large as possible, but 196 189 no larger than 16 -- unless specified with the -w option. */ 197 static size_t bytes_per_block; 198 199 /* Human-readable representation of *file_list (for error messages). 200 It differs from *file_list only when *file_list is "-". */ 201 static char const *input_filename; 190 static unsigned bytes_per_block = 32; /* have to use unsigned, not size_t */ 202 191 203 192 /* A NULL-terminated list of the file-arguments from the command line. */ 204 static char const *const *file_list; 205 206 /* Initializer for file_list if no file-arguments 207 were specified on the command line. */ 208 static char const *const default_file_list[] = { "-", NULL }; 193 static const char *const *file_list; 209 194 210 195 /* The input stream associated with the current file. */ … … 212 197 213 198 #define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t) 214 static unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] ALIGN1 = {199 static const unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] ALIGN1 = { 215 200 [sizeof(char)] = CHAR, 216 201 #if USHRT_MAX != UCHAR_MAX … … 229 214 230 215 #define MAX_FP_TYPE_SIZE sizeof(longdouble_t) 231 static unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] ALIGN1 = {216 static const unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] ALIGN1 = { 232 217 /* gcc seems to allow repeated indexes. Last one stays */ 233 218 [sizeof(longdouble_t)] = FLOAT_LONG_DOUBLE, … … 375 360 376 361 /* print_[named]_ascii are optimized for speed. 377 * Remember, someday you may want to pump gigabytes thr uthis thing.362 * Remember, someday you may want to pump gigabytes through this thing. 378 363 * Saving a dozen of .text bytes here is counter-productive */ 379 364 380 365 static void 381 366 print_named_ascii(size_t n_bytes, const char *block, 382 const char *unused_fmt_string ATTRIBUTE_UNUSED)367 const char *unused_fmt_string UNUSED_PARAM) 383 368 { 384 369 /* Names for some non-printing characters. */ … … 420 405 static void 421 406 print_ascii(size_t n_bytes, const char *block, 422 const char *unused_fmt_string ATTRIBUTE_UNUSED)407 const char *unused_fmt_string UNUSED_PARAM) 423 408 { 424 409 // buf[N] pos: 01234 56789 … … 482 467 { 483 468 while (1) { 484 input_filename = *file_list; 485 if (!input_filename) 469 if (!*file_list) 486 470 return; 487 file_list++; 488 in_stream = fopen_or_warn_stdin(input_filename); 471 in_stream = fopen_or_warn_stdin(*file_list++); 489 472 if (in_stream) { 490 if (in_stream == stdin)491 input_filename = bb_msg_standard_input;492 473 break; 493 474 } … … 511 492 if (in_stream) { 512 493 if (ferror(in_stream)) { 513 bb_error_msg("%s: read error", input_filename); 494 bb_error_msg("%s: read error", (in_stream == stdin) 495 ? bb_msg_standard_input 496 : file_list[-1] 497 ); 514 498 ioerror = 1; 515 499 } … … 519 503 520 504 if (ferror(stdout)) { 521 bb_error_msg( "write error");505 bb_error_msg(bb_msg_write_error); 522 506 ioerror = 1; 523 507 } … … 525 509 526 510 /* If S points to a single valid modern od format string, put 527 a description of that format in *TSPEC, make *NEXT point at the528 character following the just-decoded format (if *NEXT is non-NULL),529 and return zero. For example, if S were "d4afL"530 *NEXT would be set to "afL"and *TSPEC would be511 a description of that format in *TSPEC, return pointer to 512 character following the just-decoded format. 513 For example, if S were "d4afL", we will return a rtp to "afL" 514 and *TSPEC would be 531 515 { 532 516 fmt = SIGNED_DECIMAL; … … 538 522 string argument. */ 539 523 540 static void 541 decode_one_format(const char *s_orig, const char *s, const char **next, 542 struct tspec *tspec) 524 static NOINLINE const char * 525 decode_one_format(const char *s_orig, const char *s, struct tspec *tspec) 543 526 { 544 527 enum size_spec size_spec; … … 553 536 int pos; 554 537 555 assert(tspec != NULL);556 538 557 539 switch (*s) { … … 564 546 c = *s++; 565 547 p = strchr(CSIL, *s); 566 if (!p) { 548 /* if *s == NUL, p != NULL! Testcase: "od -tx" */ 549 if (!p || *p == '\0') { 567 550 size = sizeof(int); 568 551 if (isdigit(s[0])) { … … 579 562 } 580 563 } else { 581 static const uint8_t CSIL_sizeof[ ] = {564 static const uint8_t CSIL_sizeof[4] = { 582 565 sizeof(char), 583 566 sizeof(short), … … 586 569 }; 587 570 size = CSIL_sizeof[p - CSIL]; 571 s++; /* skip C/S/I/L */ 588 572 } 589 573 … … 733 717 s++; 734 718 735 if (next != NULL) 736 *next = s; 719 return s; 737 720 } 738 721 739 722 /* Decode the modern od format string S. Append the decoded 740 723 representation to the global array SPEC, reallocating SPEC if 741 necessary. Return zero if S is valid, nonzero otherwise.*/724 necessary. */ 742 725 743 726 static void … … 750 733 const char *next; 751 734 752 decode_one_format(s_orig, s, &next, &tspec);735 next = decode_one_format(s_orig, s, &tspec); 753 736 754 737 assert(s != next); 755 738 s = next; 739 spec = xrealloc_vector(spec, 4, n_specs); 740 memcpy(&spec[n_specs], &tspec, sizeof(spec[0])); 756 741 n_specs++; 757 spec = xrealloc(spec, n_specs * sizeof(*spec));758 memcpy(&spec[n_specs-1], &tspec, sizeof *spec);759 742 } 760 743 } … … 792 775 decrement n_skip and go on to the next file. */ 793 776 if (fstat(fileno(in_stream), &file_stats) == 0 794 && S_ISREG(file_stats.st_mode) && file_stats.st_size > =0777 && S_ISREG(file_stats.st_mode) && file_stats.st_size > 0 795 778 ) { 796 779 if (file_stats.st_size < n_skip) { 797 780 n_skip -= file_stats.st_size; 798 /* take check&close / open_nextroute */781 /* take "check & close / open_next" route */ 799 782 } else { 800 783 if (fseeko(in_stream, n_skip, SEEK_CUR) != 0) … … 803 786 } 804 787 } else { 805 /* If it's not a regular file with nonnegative size,788 /* If it's not a regular file with positive size, 806 789 position the file pointer by reading. */ 807 char buf[BUFSIZ]; 808 size_t n_bytes_read, n_bytes_to_read = BUFSIZ; 790 char buf[1024]; 791 size_t n_bytes_to_read = 1024; 792 size_t n_bytes_read; 809 793 810 794 while (n_skip > 0) { … … 825 809 826 810 if (n_skip) 827 bb_error_msg_and_die("can not skip past end of combined input");811 bb_error_msg_and_die("can't skip past end of combined input"); 828 812 } 829 813 … … 832 816 833 817 static void 834 format_address_none(off_t address ATTRIBUTE_UNUSED, char c ATTRIBUTE_UNUSED)818 format_address_none(off_t address UNUSED_PARAM, char c UNUSED_PARAM) 835 819 { 836 820 } … … 850 834 } 851 835 852 #if ENABLE_ GETOPT_LONG836 #if ENABLE_LONG_OPTS 853 837 /* only used with --traditional */ 854 838 static void … … 971 955 } 972 956 973 #if ENABLE_ GETOPT_LONG957 #if ENABLE_LONG_OPTS 974 958 /* If S is a valid traditional offset specification with an optional 975 959 leading '+' return nonzero and set *OFFSET to the offset it denotes. */ … … 981 965 { "B", 1024 }, 982 966 { "b", 512 }, 983 { }967 { "", 0 } 984 968 }; 985 969 char *p; … … 1015 999 multiple of all format spec sizes. Write the final block. Finally, 1016 1000 write on a line by itself the offset of the byte after the last byte 1017 read. Accumulate return values from calls to read_block and 1018 check_and_close, and if any was nonzero, return nonzero. 1019 Otherwise, return zero. */ 1020 1021 static void 1022 dump(void) 1001 read. */ 1002 1003 static void 1004 dump(off_t current_offset, off_t end_offset) 1023 1005 { 1024 1006 char *block[2]; 1025 off_t current_offset;1026 1007 int idx; 1027 1008 size_t n_bytes_read; … … 1029 1010 block[0] = xmalloc(2*bytes_per_block); 1030 1011 block[1] = block[0] + bytes_per_block; 1031 1032 current_offset = n_bytes_to_skip;1033 1012 1034 1013 idx = 0; … … 1096 1075 Then try to read a byte from the newly opened file. Repeat if 1097 1076 necessary until EOF is reached for the last file in FILE_LIST, then 1098 set *C to EOF and return. Subsequent calls do likewise. The return 1099 value is nonzero if any errors occured, zero otherwise. */ 1077 set *C to EOF and return. Subsequent calls do likewise. */ 1100 1078 1101 1079 static void … … 1130 1108 graphic (or formatting) characters terminated by a null. 1131 1109 Based on a function written by Richard Stallman for a 1132 traditional version of od. Return nonzero if an error 1133 occurs. Otherwise, return zero. */ 1134 1135 static void 1136 dump_strings(void) 1110 traditional version of od. */ 1111 1112 static void 1113 dump_strings(off_t address, off_t end_offset) 1137 1114 { 1138 1115 size_t bufsize = MAX(100, string_min); 1139 1116 char *buf = xmalloc(bufsize); 1140 off_t address = n_bytes_to_skip;1141 1117 1142 1118 while (1) { … … 1170 1146 goto tryline; 1171 1147 1172 /* If we get here, the string is all printable and null-terminated,1148 /* If we get here, the string is all printable and NUL-terminated, 1173 1149 * so print it. It is all in 'buf' and 'i' is its length. */ 1174 1150 buf[i] = 0; … … 1184 1160 case '\t': fputs("\\t", stdout); break; 1185 1161 case '\v': fputs("\\v", stdout); break; 1186 default: putc (c, stdout);1162 default: putchar(c); 1187 1163 } 1188 1164 } … … 1197 1173 } 1198 1174 1199 int od_main(int argc, char **argv) ;1175 int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1200 1176 int od_main(int argc, char **argv) 1201 1177 { … … 1204 1180 { "k", 1024 }, 1205 1181 { "m", 1024*1024 }, 1206 { }1182 { "", 0 } 1207 1183 }; 1208 unsigned opt;1209 int l_c_m;1210 /* The old-style 'pseudo starting address' to be printed in parentheses1211 after any true address. */1212 off_t pseudo_start = 0; // only for gcc1213 1184 enum { 1214 1185 OPT_A = 1 << 0, … … 1230 1201 OPT_S = 1 << 16, 1231 1202 OPT_w = 1 << 17, 1232 OPT_traditional = (1 << 18) * ENABLE_ GETOPT_LONG,1203 OPT_traditional = (1 << 18) * ENABLE_LONG_OPTS, 1233 1204 }; 1234 #if ENABLE_ GETOPT_LONG1205 #if ENABLE_LONG_OPTS 1235 1206 static const char od_longopts[] ALIGN1 = 1236 1207 "skip-bytes\0" Required_argument "j" … … 1245 1216 #endif 1246 1217 char *str_A, *str_N, *str_j, *str_S; 1247 char *str_w = NULL;1248 1218 llist_t *lst_t = NULL; 1219 unsigned opt; 1220 int l_c_m; 1221 /* The old-style 'pseudo starting address' to be printed in parentheses 1222 after any true address. */ 1223 off_t pseudo_start = pseudo_start; // for gcc 1224 /* The number of input bytes to skip before formatting and writing. */ 1225 off_t n_bytes_to_skip = 0; 1226 /* The offset of the first byte after the last byte to be formatted. */ 1227 off_t end_offset = 0; 1228 /* The maximum number of bytes that will be formatted. */ 1229 off_t max_bytes_to_format = 0; 1249 1230 1250 1231 spec = NULL; … … 1255 1236 1256 1237 /* Parse command line */ 1257 opt_complementary = " t::"; // list1258 #if ENABLE_ GETOPT_LONG1238 opt_complementary = "w+:t::"; /* -w N, -t is a list */ 1239 #if ENABLE_LONG_OPTS 1259 1240 applet_long_options = od_longopts; 1260 1241 #endif … … 1264 1245 // but in coreutils 6.3 it was renamed and now has 1265 1246 // _mandatory_ parameter 1266 &str_A, &str_N, &str_j, &lst_t, &str_S, & str_w);1247 &str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block); 1267 1248 argc -= optind; 1268 1249 argv += optind; … … 1302 1283 //if (opt & OPT_t)... 1303 1284 while (lst_t) { 1304 decode_format_string(lst_t->data); 1305 lst_t = lst_t->link; 1285 decode_format_string(llist_pop(&lst_t)); 1306 1286 } 1307 1287 if (opt & OPT_v) verbose = 1; … … 1328 1308 * traditional syntax even if --traditional is not given. */ 1329 1309 1330 #if ENABLE_ GETOPT_LONG1310 #if ENABLE_LONG_OPTS 1331 1311 if (opt & OPT_traditional) { 1332 1312 off_t o1, o2; … … 1400 1380 set the global pointer FILE_LIST so that it 1401 1381 references the null-terminated list of one name: "-". */ 1402 file_list = default_file_list;1382 file_list = bb_argv_dash; 1403 1383 if (argc > 0) { 1404 1384 /* Set the global pointer FILE_LIST so that it … … 1412 1392 skip(n_bytes_to_skip); 1413 1393 if (!in_stream) 1414 return 1;1394 return EXIT_FAILURE; 1415 1395 1416 1396 pseudo_offset = (flag_pseudo_start ? pseudo_start - n_bytes_to_skip : 0); … … 1420 1400 1421 1401 if (opt & OPT_w) { /* -w: width */ 1422 bytes_per_block = 32;1423 if (str_w)1424 bytes_per_block = xatou(str_w);1425 1402 if (!bytes_per_block || bytes_per_block % l_c_m != 0) { 1426 bb_error_msg("warning: invalid width % zu; using %d instead",1427 bytes_per_block, l_c_m);1403 bb_error_msg("warning: invalid width %u; using %d instead", 1404 (unsigned)bytes_per_block, l_c_m); 1428 1405 bytes_per_block = l_c_m; 1429 1406 } … … 1442 1419 1443 1420 if (flag_dump_strings) 1444 dump_strings( );1421 dump_strings(n_bytes_to_skip, end_offset); 1445 1422 else 1446 dump( );1423 dump(n_bytes_to_skip, end_offset); 1447 1424 1448 1425 if (fclose(stdin) == EOF)
Note:
See TracChangeset
for help on using the changeset viewer.