aboutsummaryrefslogtreecommitdiff
path: root/coreutils/split.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-03-26 20:15:40 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-03-26 20:15:40 +0000
commit91dd275f058500dc703d46c6114f6b037007129d (patch)
tree59bf4e2ed9546cb3a672b921eabfd234fd0de501 /coreutils/split.c
parent576de34d1c2bfe61dac872148406368ba1d1522a (diff)
downloadbusybox-w32-91dd275f058500dc703d46c6114f6b037007129d.tar.gz
busybox-w32-91dd275f058500dc703d46c6114f6b037007129d.tar.bz2
busybox-w32-91dd275f058500dc703d46c6114f6b037007129d.zip
split: let me join bikeshed painting frenzy :)
this one should be able to handle huge files. text data bss dec hex filename 664 4 0 668 29c busybox.t0/coreutils/split.o 628 0 0 628 274 busybox.t1/coreutils/split.o split_main 488 525 +37 suffix_len 4 - -4 next_file 77 - -77 (add/remove: 0/2 grow/shrink: 1/0 up/down: 37/-81) Total: -44 bytes
Diffstat (limited to 'coreutils/split.c')
-rw-r--r--coreutils/split.c139
1 files changed, 71 insertions, 68 deletions
diff --git a/coreutils/split.c b/coreutils/split.c
index ca546986e..07eb97e0c 100644
--- a/coreutils/split.c
+++ b/coreutils/split.c
@@ -10,44 +10,43 @@
10 * http://www.opengroup.org/onlinepubs/009695399/utilities/split.html 10 * http://www.opengroup.org/onlinepubs/009695399/utilities/split.html
11 */ 11 */
12#include "busybox.h" 12#include "busybox.h"
13static unsigned suffix_len = 2; 13
14static const struct suffix_mult split_suffices[] = { 14static const struct suffix_mult split_suffices[] = {
15#if ENABLE_FEATURE_SPLIT_FANCY
16 { "b", 512 }, 15 { "b", 512 },
17#endif
18 { "k", 1024 }, 16 { "k", 1024 },
19 { "m", 1024*1024 }, 17 { "m", 1024*1024 },
20#if ENABLE_FEATURE_SPLIT_FANCY
21 { "g", 1024*1024*1024 }, 18 { "g", 1024*1024*1024 },
22#endif
23 { NULL, 0 } 19 { NULL, 0 }
24}; 20};
25 21
26/* Increment the suffix part of the filename. 22/* Increment the suffix part of the filename.
27 * Returns 0 on success and 1 on error (if we are out of files) 23 * Returns NULL if we are out of filenames.
28 */ 24 */
29static bool next_file(char **old) 25static char *next_file(char *old, unsigned suffix_len)
30{ 26{
31 size_t end = strlen(*old); 27 size_t end = strlen(old);
32 unsigned i = 1; 28 unsigned i = 1;
33 char *curr; 29 char *curr;
34 30
35 do { 31 do {
36 curr = *old + end - i; 32 curr = old + end - i;
37 if (*curr < 'z') { 33 if (*curr < 'z') {
38 *curr += 1; 34 *curr += 1;
39 break; 35 break;
40 } 36 }
41 i++; 37 i++;
42 if (i > suffix_len) { 38 if (i > suffix_len) {
43 bb_error_msg("Suffices exhausted"); 39 return NULL;
44 return 1;
45 } 40 }
46 *curr = 'a'; 41 *curr = 'a';
47 } while (1); 42 } while (1);
48 return 0; 43
44 return old;
49} 45}
50 46
47#define read_buffer bb_common_bufsiz1
48enum { READ_BUFFER_SIZE = sizeof(bb_common_bufsiz1) - 1 };
49
51#define SPLIT_OPT_l (1<<0) 50#define SPLIT_OPT_l (1<<0)
52#define SPLIT_OPT_b (1<<1) 51#define SPLIT_OPT_b (1<<1)
53#define SPLIT_OPT_a (1<<2) 52#define SPLIT_OPT_a (1<<2)
@@ -55,79 +54,83 @@ static bool next_file(char **old)
55int split_main(int argc, char **argv); 54int split_main(int argc, char **argv);
56int split_main(int argc, char **argv) 55int split_main(int argc, char **argv)
57{ 56{
58 char *pfx, *buf, *input_file; 57 unsigned suffix_len = 2;
59 unsigned cnt = 1000, opt; 58 char *pfx;
60 bool ret = EXIT_SUCCESS; 59 char *count_p;
61 FILE *fp; 60 const char *sfx;
62 char *count_p, *sfx; 61 unsigned long cnt = 1000;
63//XXX: FIXME opt_complementary = "+2"; /* at most 2 non-option arguments */ 62 unsigned long remaining = 0;
63 unsigned opt;
64 int bytes_read, to_write;
65 char *src;
66
67 opt_complementary = "?2";
64 opt = getopt32(argc, argv, "l:b:a:", &count_p, &count_p, &sfx); 68 opt = getopt32(argc, argv, "l:b:a:", &count_p, &count_p, &sfx);
65 69
66 if (opt & SPLIT_OPT_l) 70 if (opt & SPLIT_OPT_l)
67 cnt = xatoi(count_p); 71 cnt = xatoul(count_p);
68 if (opt & SPLIT_OPT_b) 72 if (opt & SPLIT_OPT_b)
69 cnt = xatoul_sfx(count_p, split_suffices); 73 cnt = xatoul_sfx(count_p, split_suffices);
70 if (opt & SPLIT_OPT_a) 74 if (opt & SPLIT_OPT_a)
71 suffix_len = xatoi(sfx); 75 suffix_len = xatou(sfx);
72 argv += optind; 76 argv += optind;
73 if (!*argv) 77 sfx = "x";
74 *--argv = (char*) "-"; 78 if (argv[0]) {
75 input_file = *argv; 79 if (argv[1])
76 sfx = *++argv; 80 sfx = argv[1];
81 xmove_fd(xopen(argv[0], O_RDONLY), 0);
82 } else {
83 argv[0] = (char *) bb_msg_standard_input;
84 }
77 85
78 if (sfx && (NAME_MAX < strlen(sfx) + suffix_len)) 86 if (NAME_MAX < strlen(sfx) + suffix_len)
79 bb_error_msg_and_die("Suffix too long"); 87 bb_error_msg_and_die("suffix too long");
80 88
81 { 89 {
82 char *char_p = xzalloc(suffix_len); 90 char *char_p = xzalloc(suffix_len + 1);
83 memset(char_p, 'a', suffix_len); 91 memset(char_p, 'a', suffix_len);
84 pfx = xasprintf("%s%s", sfx ? sfx : "x", char_p); 92 pfx = xasprintf("%s%s", sfx, char_p);
85 if (ENABLE_FEATURE_CLEAN_UP) 93 if (ENABLE_FEATURE_CLEAN_UP)
86 free(char_p); 94 free(char_p);
87 } 95 }
88 fp = fopen_or_warn_stdin(input_file);
89//XXX:FIXME: unify those two file-handling schemata below (FILE vs fd) !
90 if (opt & SPLIT_OPT_b) {
91 ssize_t i;
92 ssize_t bytes = 0;
93 int inp = fileno(fp);
94 96
97 while (1) {
98 bytes_read = safe_read(0, read_buffer, READ_BUFFER_SIZE);
99 if (!bytes_read)
100 break;
101 if (bytes_read < 0)
102 bb_perror_msg_and_die("%s", argv[0]);
103 src = read_buffer;
95 do { 104 do {
96 int out = xopen(pfx, O_WRONLY | O_CREAT | O_TRUNC); 105 if (!remaining) {
97 lseek(inp, bytes, SEEK_SET); 106 if (!pfx)
98 buf = xzalloc(cnt); 107 bb_error_msg_and_die("suffices exhausted");
99 bytes += i = full_read(inp, buf, cnt); 108 xmove_fd(xopen(pfx, O_WRONLY | O_CREAT | O_TRUNC), 1);
100 xwrite(out, buf, i); 109 pfx = next_file(pfx, suffix_len);
101 free(buf); 110 remaining = cnt;
102 close(out);
103 if (next_file(&pfx)) {
104 ret++;
105 goto bail;
106 } 111 }
107 } while (i == cnt); /* if we read less than cnt, then nothing is left */ 112
108 } else { /* -l */ 113 if (opt & SPLIT_OPT_b) {
109 do { 114 /* split by bytes */
110 unsigned i = cnt; 115 to_write = (bytes_read < remaining) ? bytes_read : remaining;
111 int out = xopen(pfx, O_WRONLY | O_CREAT | O_TRUNC); 116 remaining -= to_write;
112 buf = NULL; 117 } else {
113 while (i--) { 118 /* split by lines */
114 buf = xmalloc_fgets(fp); 119 /* can be sped up by using _memrchr_
115 if (buf == NULL) 120 * and writing many lines at once... */
116 break; 121 char *end = memchr(src, '\n', bytes_read);
117 xwrite(out, buf, strlen(buf)); 122 if (end) {
118 free(buf); 123 --remaining;
119 }; 124 to_write = end - src + 1;
120 close(out); 125 } else {
121 if (next_file(&pfx)) { 126 to_write = bytes_read;
122 ret++; 127 }
123 goto bail;
124 } 128 }
125 } while (buf); 129
126 } 130 xwrite(1, src, to_write);
127bail: 131 bytes_read -= to_write;
128 if (ENABLE_FEATURE_CLEAN_UP) { 132 src += to_write;
129 free(pfx); 133 } while (bytes_read);
130 fclose_if_not_stdin(fp);
131 } 134 }
132 return ret; 135 return 0;
133} 136}