sum: 40% size reduction (-300 bytes) find: one_char -> LONE_CHAR
No binary (build failed)
—
(log yok)
| @@ -15,139 +15,80 @@ | |
| #include "busybox.h" | |
| - | /* 1 if any of the files read were the standard input */ |
| - | static int have_read_stdin; |
| + | enum { sysv_sum, bsd_sum }; |
| - | /* Calculate and print the rotated checksum and the size in 1K blocks |
| - | of file FILE, or of the standard input if FILE is "-". |
| - | If PRINT_NAME is >1, print FILE next to the checksum and size. |
| - | The checksum varies depending on sizeof (int). |
| - | Return 1 if successful. */ |
| - | static int bsd_sum_file(const char *file, int print_name) |
| + | /* BSD: calculate and print the rotated checksum and the size in 1K blocks |
| + | The checksum varies depending on sizeof (int). */ |
| + | /* SYSV: calculate and print the checksum and the size in 512-byte blocks */ |
| + | /* Return 1 if successful. */ |
| + | static int sum_file(const char *file, int type, int print_name) |
| { | |
| - | FILE *fp; |
| - | int checksum = 0; /* The checksum mod 2^16. */ |
| - | uintmax_t total_bytes = 0; /* The number of bytes. */ |
| - | int ch; /* Each character read. */ |
| - | int ret = 0; |
| - | |
| - | if (LONE_DASH(file)) { |
| - | fp = stdin; |
| - | have_read_stdin++; |
| - | } else { |
| - | fp = fopen_or_warn(file, "r"); |
| - | if (fp == NULL) |
| - | goto out; |
| - | } |
| - | |
| - | while ((ch = getc(fp)) != EOF) { |
| - | ++total_bytes; |
| - | checksum = (checksum >> 1) + ((checksum & 1) << 15); |
| - | checksum += ch; |
| - | checksum &= 0xffff; /* Keep it within bounds. */ |
| - | } |
| - | |
| - | if (ferror(fp)) { |
| - | bb_perror_msg(file); |
| - | fclose_if_not_stdin(fp); |
| - | goto out; |
| - | } |
| - | |
| - | if (fclose_if_not_stdin(fp) == EOF) { |
| - | bb_perror_msg(file); |
| - | goto out; |
| - | } |
| - | ret++; |
| - | printf("%05d %5ju ", checksum, (total_bytes+1023)/1024); |
| - | if (print_name > 1) |
| - | puts(file); |
| - | else |
| - | puts(""); |
| - | out: |
| - | return ret; |
| - | } |
| - | |
| - | /* Calculate and print the checksum and the size in 512-byte blocks |
| - | of file FILE, or of the standard input if FILE is "-". |
| - | If PRINT_NAME is >0, print FILE next to the checksum and size. |
| - | Return 1 if successful. */ |
| - | #define MY_BUF_SIZE 8192 |
| - | static int sysv_sum_file(const char *file, int print_name) |
| - | { |
| - | RESERVE_CONFIG_BUFFER(buf, MY_BUF_SIZE); |
| - | int fd; |
| + | #define buf bb_common_bufsiz1 |
| + | int r, fd; |
| uintmax_t total_bytes = 0; | |
| /* The sum of all the input bytes, modulo (UINT_MAX + 1). */ | |
| - | unsigned int s = 0; |
| + | unsigned s = 0; |
| - | if (LONE_DASH(file)) { |
| - | fd = 0; |
| - | have_read_stdin = 1; |
| - | } else { |
| + | fd = 0; |
| + | if (NOT_LONE_DASH(file)) { |
| fd = open(file, O_RDONLY); | |
| if (fd == -1) | |
| - | goto release_and_ret; |
| + | goto ret_bad; |
| } | |
| while (1) { | |
| - | size_t bytes_read = safe_read(fd, buf, MY_BUF_SIZE); |
| - | |
| - | if (bytes_read == 0) |
| - | break; |
| - | |
| - | if (bytes_read == -1) { |
| - | release_and_ret: |
| + | size_t bytes_read = safe_read(fd, buf, BUFSIZ); |
| + | |
| + | if ((ssize_t)bytes_read <= 0) { |
| + | r = (fd && close(fd) != 0); |
| + | if (!bytes_read && !r) |
| + | /* no error */ |
| + | break; |
| + | ret_bad: |
| bb_perror_msg(file); | |
| - | RELEASE_CONFIG_BUFFER(buf); |
| - | if (NOT_LONE_DASH(file)) |
| - | close(fd); |
| return 0; | |
| } | |
| total_bytes += bytes_read; | |
| - | while (bytes_read--) |
| - | s += buf[bytes_read]; |
| + | if (type == sysv_sum) { |
| + | do s += buf[--bytes_read]; while (bytes_read); |
| + | } else { |
| + | r = 0; |
| + | do { |
| + | s = (s >> 1) + ((s & 1) << 15); |
| + | s += buf[r++]; |
| + | s &= 0xffff; /* Keep it within bounds. */ |
| + | } while (--bytes_read); |
| + | } |
| } | |
| - | if (NOT_LONE_DASH(file) && close(fd) == -1) |
| - | goto release_and_ret; |
| - | else |
| - | RELEASE_CONFIG_BUFFER(buf); |
| - | |
| - | { |
| - | int r = (s & 0xffff) + ((s & 0xffffffff) >> 16); |
| + | if (!print_name) file = ""; |
| + | if (type == sysv_sum) { |
| + | r = (s & 0xffff) + ((s & 0xffffffff) >> 16); |
| s = (r & 0xffff) + (r >> 16); | |
| - | |
| - | printf("%d %ju ", s, (total_bytes+511)/512); |
| - | } |
| - | puts(print_name ? file : ""); |
| - | |
| + | printf("%d %ju %s\n", s, (total_bytes+511)/512, file); |
| + | } else |
| + | printf("%05d %5ju %s\n", s, (total_bytes+1023)/1024, file); |
| return 1; | |
| + | #undef buf |
| } | |
| int sum_main(int argc, char **argv) | |
| { | |
| - | int flags; |
| - | int ok; |
| - | int (*sum_func)(const char *, int) = bsd_sum_file; |
| + | int n; |
| + | int type = bsd_sum; |
| - | /* give the bsd func priority over sysv func */ |
| - | flags = getopt32(argc, argv, "sr"); |
| - | if (flags & 1) |
| - | sum_func = sysv_sum_file; |
| - | if (flags & 2) |
| - | sum_func = bsd_sum_file; |
| + | n = getopt32(argc, argv, "sr"); |
| + | if (n & 1) type = sysv_sum; |
| + | /* give the bsd priority over sysv func */ |
| + | if (n & 2) type = bsd_sum; |
| - | have_read_stdin = 0; |
| - | if ((argc - optind) == 0) |
| - | ok = sum_func("-", 0); |
| + | if (argc == optind) |
| + | n = sum_file("-", type, 0); |
| else | |
| - | for (ok = 1; optind < argc; optind++) |
| - | ok &= sum_func(argv[optind], 1); |
| - | |
| - | if (have_read_stdin && fclose(stdin) == EOF) |
| - | bb_perror_msg_and_die("-"); |
| + | for (n = 1; optind < argc; optind++) |
| + | n &= sum_file(argv[optind], type, 1); |
| - | exit(ok ? EXIT_SUCCESS : EXIT_FAILURE); |
| + | return !n; |
| } | |
| @@ -75,11 +75,6 @@ USE_DESKTOP( ACTS(prune)) | |
| static action ***actions; | |
| static int need_print = 1; | |
| - | static inline int one_char(const char* str, char c) |
| - | { |
| - | return (str[0] == c && str[1] == '\0'); |
| - | } |
| - | |
| static int count_subst(const char *str) | |
| { | |
| @@ -455,7 +450,7 @@ action*** parse_params(char **argv) | |
| while (1) { | |
| if (!*argv) /* did not see ';' till end */ | |
| bb_error_msg_and_die(bb_msg_requires_arg, arg); | |
| - | if (one_char(argv[0], ';')) |
| + | if (LONE_CHAR(argv[0], ';')) |
| break; | |
| argv++; | |
| ap->exec_argc++; | |
| @@ -469,7 +464,7 @@ action*** parse_params(char **argv) | |
| } | |
| #endif | |
| #if ENABLE_DESKTOP | |
| - | else if (one_char(arg, '(')) { |
| + | else if (LONE_CHAR(arg, '(')) { |
| action_paren *ap; | |
| char **endarg; | |
| int nested = 1; | |
| @@ -478,9 +473,9 @@ action*** parse_params(char **argv) | |
| while (1) { | |
| if (!*++endarg) | |
| bb_error_msg_and_die("unpaired '('"); | |
| - | if (one_char(*endarg, '(')) |
| + | if (LONE_CHAR(*endarg, '(')) |
| nested++; | |
| - | else if (one_char(*endarg, ')') && !--nested) { |
| + | else if (LONE_CHAR(*endarg, ')') && !--nested) { |
| *endarg = NULL; | |
| break; | |
| } | |
| @@ -522,7 +517,7 @@ int find_main(int argc, char **argv) | |
| if (argv[firstopt][0] == '-') | |
| break; | |
| #if ENABLE_DESKTOP | |
| - | if (one_char(argv[firstopt], '(')) |
| + | if (LONE_CHAR(argv[firstopt], '(')) |
| break; | |
| #endif | |
| } | |