aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-05-21 17:43:06 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-05-21 17:43:06 +0200
commit5c10fa5c241b116b8c623189a42673754b21dc8c (patch)
treea373490b460d40c02073b6f1f04450af281ea842 /coreutils
parent232ebaa5681790291154cf8e8203a02eec04f6d8 (diff)
downloadbusybox-w32-5c10fa5c241b116b8c623189a42673754b21dc8c.tar.gz
busybox-w32-5c10fa5c241b116b8c623189a42673754b21dc8c.tar.bz2
busybox-w32-5c10fa5c241b116b8c623189a42673754b21dc8c.zip
od: code shrink, fix "od --traditional FILE"
function old new delta parse_old_offset 107 125 +18 packed_usage 28715 28691 -24 od_main 2312 2275 -37 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/od.c7
-rw-r--r--coreutils/od_bloaty.c213
2 files changed, 100 insertions, 120 deletions
diff --git a/coreutils/od.c b/coreutils/od.c
index 31ebde210..fb11fcfe3 100644
--- a/coreutils/od.c
+++ b/coreutils/od.c
@@ -11,11 +11,12 @@
11 * Original copyright notice is retained at the end of this file. 11 * Original copyright notice is retained at the end of this file.
12 */ 12 */
13 13
14//usage:#if !ENABLE_DESKTOP
14//usage:#define od_trivial_usage 15//usage:#define od_trivial_usage
15//usage: "[-aBbcDdeFfHhIiLlOovXx] " IF_DESKTOP("[-t TYPE] ") "[FILE]" 16//usage: "[-aBbcDdeFfHhIiLlOovXx] [FILE]"
16//usage:#define od_full_usage "\n\n" 17//usage:#define od_full_usage "\n\n"
17//usage: "Write an unambiguous representation, octal bytes by default, of FILE\n" 18//usage: "Print FILE (or stdin) unambiguously, as octal bytes by default"
18//usage: "(or stdin) to stdout" 19//usage:#endif
19 20
20#include "libbb.h" 21#include "libbb.h"
21#if ENABLE_DESKTOP 22#if ENABLE_DESKTOP
diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c
index a9a45c8d3..fcd9f60d6 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -13,43 +13,24 @@
13 13
14 You should have received a copy of the GNU General Public License 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 Foundation, 15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 17 */
18/* Written by Jim Meyering. */ 18/* Written by Jim Meyering. */
19/* Busyboxed by Denys Vlasenko, based on od.c from coreutils-5.2.1 */
19 20
20/* Busyboxed by Denys Vlasenko 21//usage:#if ENABLE_DESKTOP
21 22//usage:#define od_trivial_usage
22Based on od.c from coreutils-5.2.1 23//usage: "[-abcdfhilovxs] [-t TYPE] [-A RADIX] [-N SIZE] [-j SKIP] [-S MINSTR] [-w WIDTH] [FILE...]"
23Top bloat sources: 24// We don't support:
24 25// ... [FILE] [[+]OFFSET[.][b]]
2500000073 t parse_old_offset 26// Support is buggy for:
260000007b t get_lcm 27// od --traditional [OPTION]... [FILE] [[+]OFFSET[.][b] [+][LABEL][.][b]]
2700000090 r long_options
2800000092 t print_named_ascii
29000000bf t print_ascii
3000000168 t write_block
3100000366 t decode_format_string
3200000a71 T od_main
33 28
34Tested for compat with coreutils 6.3 29//usage:#define od_full_usage "\n\n"
35using this script. Minor differences fixed. 30//usage: "Print FILEs (or stdin) unambiguously, as octal bytes by default"
31//usage:#endif
36 32
37#!/bin/sh 33/* #include "libbb.h" - done in od.c */
38echo STD
39time /path/to/coreutils/od \
40...params... \
41>std
42echo Exit code $?
43echo BBOX
44time ./busybox od \
45...params... \
46>bbox
47echo Exit code $?
48diff -u -a std bbox >bbox.diff || { echo Different!; sleep 1; }
49
50*/
51
52#include "libbb.h"
53 34
54#define assert(a) ((void)0) 35#define assert(a) ((void)0)
55 36
@@ -214,7 +195,7 @@ static const unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] ALIGN1
214 195
215#define MAX_FP_TYPE_SIZE sizeof(longdouble_t) 196#define MAX_FP_TYPE_SIZE sizeof(longdouble_t)
216static const unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] ALIGN1 = { 197static const unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] ALIGN1 = {
217 /* gcc seems to allow repeated indexes. Last one stays */ 198 /* gcc seems to allow repeated indexes. Last one wins */
218 [sizeof(longdouble_t)] = FLOAT_LONG_DOUBLE, 199 [sizeof(longdouble_t)] = FLOAT_LONG_DOUBLE,
219 [sizeof(double)] = FLOAT_DOUBLE, 200 [sizeof(double)] = FLOAT_DOUBLE,
220 [sizeof(float)] = FLOAT_SINGLE 201 [sizeof(float)] = FLOAT_SINGLE
@@ -376,7 +357,7 @@ print_named_ascii(size_t n_bytes, const char *block,
376 }; 357 };
377 // buf[N] pos: 01234 56789 358 // buf[N] pos: 01234 56789
378 char buf[12] = " x\0 0xx\0"; 359 char buf[12] = " x\0 0xx\0";
379 // actually " x\0 xxx\0", but I want to share the string with below. 360 // actually " x\0 xxx\0", but want to share string with print_ascii.
380 // [12] because we take three 32bit stack slots anyway, and 361 // [12] because we take three 32bit stack slots anyway, and
381 // gcc is too dumb to initialize with constant stores, 362 // gcc is too dumb to initialize with constant stores,
382 // it copies initializer from rodata. Oh well. 363 // it copies initializer from rodata. Oh well.
@@ -954,42 +935,6 @@ get_lcm(void)
954 return l_c_m; 935 return l_c_m;
955} 936}
956 937
957#if ENABLE_LONG_OPTS
958/* If S is a valid traditional offset specification with an optional
959 leading '+' return nonzero and set *OFFSET to the offset it denotes. */
960
961static int
962parse_old_offset(const char *s, off_t *offset)
963{
964 static const struct suffix_mult Bb[] = {
965 { "B", 1024 },
966 { "b", 512 },
967 { "", 0 }
968 };
969 char *p;
970 int radix;
971
972 /* Skip over any leading '+'. */
973 if (s[0] == '+') ++s;
974
975 /* Determine the radix we'll use to interpret S. If there is a '.',
976 * it's decimal, otherwise, if the string begins with '0X'or '0x',
977 * it's hexadecimal, else octal. */
978 p = strchr(s, '.');
979 radix = 8;
980 if (p) {
981 p[0] = '\0'; /* cheating */
982 radix = 10;
983 } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
984 radix = 16;
985
986 *offset = xstrtooff_sfx(s, radix, Bb);
987 if (p) p[0] = '.';
988
989 return (*offset >= 0);
990}
991#endif
992
993/* Read a chunk of size BYTES_PER_BLOCK from the input files, write the 938/* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
994 formatted block to standard output, and repeat until the specified 939 formatted block to standard output, and repeat until the specified
995 maximum number of bytes has been read or until all input has been 940 maximum number of bytes has been read or until all input has been
@@ -1172,8 +1117,45 @@ dump_strings(off_t address, off_t end_offset)
1172 check_and_close(); 1117 check_and_close();
1173} 1118}
1174 1119
1120#if ENABLE_LONG_OPTS
1121/* If S is a valid traditional offset specification with an optional
1122 leading '+' return nonzero and set *OFFSET to the offset it denotes. */
1123
1124static int
1125parse_old_offset(const char *s, off_t *offset)
1126{
1127 static const struct suffix_mult Bb[] = {
1128 { "B", 1024 },
1129 { "b", 512 },
1130 { "", 0 }
1131 };
1132 char *p;
1133 int radix;
1134
1135 /* Skip over any leading '+'. */
1136 if (s[0] == '+') ++s;
1137 if (!isdigit(s[0])) return 0; /* not a number */
1138
1139 /* Determine the radix we'll use to interpret S. If there is a '.',
1140 * it's decimal, otherwise, if the string begins with '0X'or '0x',
1141 * it's hexadecimal, else octal. */
1142 p = strchr(s, '.');
1143 radix = 8;
1144 if (p) {
1145 p[0] = '\0'; /* cheating */
1146 radix = 10;
1147 } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
1148 radix = 16;
1149
1150 *offset = xstrtooff_sfx(s, radix, Bb);
1151 if (p) p[0] = '.';
1152
1153 return (*offset >= 0);
1154}
1155#endif
1156
1175int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1157int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1176int od_main(int argc, char **argv) 1158int od_main(int argc UNUSED_PARAM, char **argv)
1177{ 1159{
1178 static const struct suffix_mult bkm[] = { 1160 static const struct suffix_mult bkm[] = {
1179 { "b", 512 }, 1161 { "b", 512 },
@@ -1245,7 +1227,6 @@ int od_main(int argc, char **argv)
1245 // but in coreutils 6.3 it was renamed and now has 1227 // but in coreutils 6.3 it was renamed and now has
1246 // _mandatory_ parameter 1228 // _mandatory_ parameter
1247 &str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block); 1229 &str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block);
1248 argc -= optind;
1249 argv += optind; 1230 argv += optind;
1250 if (opt & OPT_A) { 1231 if (opt & OPT_A) {
1251 static const char doxn[] ALIGN1 = "doxn"; 1232 static const char doxn[] ALIGN1 = "doxn";
@@ -1288,7 +1269,6 @@ int od_main(int argc, char **argv)
1288 if (opt & OPT_x) decode_format_string("x2"); 1269 if (opt & OPT_x) decode_format_string("x2");
1289 if (opt & OPT_s) decode_format_string("d2"); 1270 if (opt & OPT_s) decode_format_string("d2");
1290 if (opt & OPT_S) { 1271 if (opt & OPT_S) {
1291 string_min = 3;
1292 string_min = xstrtou_sfx(str_S, 0, bkm); 1272 string_min = xstrtou_sfx(str_S, 0, bkm);
1293 flag_dump_strings = 1; 1273 flag_dump_strings = 1;
1294 } 1274 }
@@ -1301,7 +1281,7 @@ int od_main(int argc, char **argv)
1301 /* If the --traditional option is used, there may be from 1281 /* If the --traditional option is used, there may be from
1302 * 0 to 3 remaining command line arguments; handle each case 1282 * 0 to 3 remaining command line arguments; handle each case
1303 * separately. 1283 * separately.
1304 * od [file] [[+]offset[.][b] [[+]label[.][b]]] 1284 * od [FILE] [[+]OFFSET[.][b] [[+]LABEL[.][b]]]
1305 * The offset and pseudo_start have the same syntax. 1285 * The offset and pseudo_start have the same syntax.
1306 * 1286 *
1307 * FIXME: POSIX 1003.1-2001 with XSI requires support for the 1287 * FIXME: POSIX 1003.1-2001 with XSI requires support for the
@@ -1311,48 +1291,47 @@ int od_main(int argc, char **argv)
1311 if (opt & OPT_traditional) { 1291 if (opt & OPT_traditional) {
1312 off_t o1, o2; 1292 off_t o1, o2;
1313 1293
1314 if (argc == 1) { 1294 if (argv[0]) {
1315 if (parse_old_offset(argv[0], &o1)) { 1295 if (!argv[1]) { /* one arg */
1316 n_bytes_to_skip = o1; 1296 if (parse_old_offset(argv[0], &o1)) {
1317 --argc; 1297 /* od --traditional OFFSET */
1318 ++argv; 1298 n_bytes_to_skip = o1;
1319 } 1299 argv++;
1320 } else if (argc == 2) { 1300 }
1321 if (parse_old_offset(argv[0], &o1) 1301 /* od --traditional FILE */
1322 && parse_old_offset(argv[1], &o2) 1302 } else if (!argv[2]) { /* two args */
1323 ) { 1303 if (parse_old_offset(argv[0], &o1)
1324 n_bytes_to_skip = o1; 1304 && parse_old_offset(argv[1], &o2)
1325 flag_pseudo_start = 1; 1305 ) {
1326 pseudo_start = o2; 1306 /* od --traditional OFFSET LABEL */
1327 argv += 2; 1307 n_bytes_to_skip = o1;
1328 argc -= 2; 1308 flag_pseudo_start = 1;
1329 } else if (parse_old_offset(argv[1], &o2)) { 1309 pseudo_start = o2;
1330 n_bytes_to_skip = o2; 1310 argv += 2;
1331 --argc; 1311 } else if (parse_old_offset(argv[1], &o2)) {
1332 argv[1] = argv[0]; 1312 /* od --traditional FILE OFFSET */
1333 ++argv; 1313 n_bytes_to_skip = o2;
1334 } else { 1314 argv[1] = NULL;
1335 bb_error_msg_and_die("invalid second operand " 1315 } else {
1336 "in compatibility mode '%s'", argv[1]); 1316 bb_error_msg_and_die("invalid second argument '%s'", argv[1]);
1337 } 1317 }
1338 } else if (argc == 3) { 1318 } else if (!argv[3]) { /* three args */
1339 if (parse_old_offset(argv[1], &o1) 1319 if (parse_old_offset(argv[1], &o1)
1340 && parse_old_offset(argv[2], &o2) 1320 && parse_old_offset(argv[2], &o2)
1341 ) { 1321 ) {
1342 n_bytes_to_skip = o1; 1322 /* od --traditional FILE OFFSET LABEL */
1343 flag_pseudo_start = 1; 1323 n_bytes_to_skip = o1;
1344 pseudo_start = o2; 1324 flag_pseudo_start = 1;
1345 argv[2] = argv[0]; 1325 pseudo_start = o2;
1346 argv += 2; 1326 argv[1] = NULL;
1347 argc -= 2; 1327 } else {
1348 } else { 1328 bb_error_msg_and_die("the last two arguments must be offsets");
1349 bb_error_msg_and_die("in compatibility mode " 1329 }
1350 "the last two arguments must be offsets"); 1330 } else { /* >3 args */
1331 bb_error_msg_and_die("too many arguments");
1351 } 1332 }
1352 } else if (argc > 3) {
1353 bb_error_msg_and_die("compatibility mode supports "
1354 "at most three arguments");
1355 } 1333 }
1334 /* else: od --traditional (without args) */
1356 1335
1357 if (flag_pseudo_start) { 1336 if (flag_pseudo_start) {
1358 if (format_address == format_address_none) { 1337 if (format_address == format_address_none) {
@@ -1368,7 +1347,7 @@ int od_main(int argc, char **argv)
1368 if (limit_bytes_to_format) { 1347 if (limit_bytes_to_format) {
1369 end_offset = n_bytes_to_skip + max_bytes_to_format; 1348 end_offset = n_bytes_to_skip + max_bytes_to_format;
1370 if (end_offset < n_bytes_to_skip) 1349 if (end_offset < n_bytes_to_skip)
1371 bb_error_msg_and_die("skip-bytes + read-bytes is too large"); 1350 bb_error_msg_and_die("SKIP + SIZE is too large");
1372 } 1351 }
1373 1352
1374 if (n_specs == 0) { 1353 if (n_specs == 0) {
@@ -1380,7 +1359,7 @@ int od_main(int argc, char **argv)
1380 set the global pointer FILE_LIST so that it 1359 set the global pointer FILE_LIST so that it
1381 references the null-terminated list of one name: "-". */ 1360 references the null-terminated list of one name: "-". */
1382 file_list = bb_argv_dash; 1361 file_list = bb_argv_dash;
1383 if (argc > 0) { 1362 if (argv[0]) {
1384 /* Set the global pointer FILE_LIST so that it 1363 /* Set the global pointer FILE_LIST so that it
1385 references the first file-argument on the command-line. */ 1364 references the first file-argument on the command-line. */
1386 file_list = (char const *const *) argv; 1365 file_list = (char const *const *) argv;