split.c - sbase - suckless unix tools | |
git clone git://git.suckless.org/sbase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
split.c (2086B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include <ctype.h> | |
3 #include <stdint.h> | |
4 #include <stdio.h> | |
5 #include <stdlib.h> | |
6 #include <string.h> | |
7 | |
8 #include "util.h" | |
9 | |
10 static int base = 26, start = 'a'; | |
11 | |
12 static int | |
13 itostr(char *str, int x, int n) | |
14 { | |
15 str[n] = '\0'; | |
16 while (n-- > 0) { | |
17 str[n] = start + (x % base); | |
18 x /= base; | |
19 } | |
20 | |
21 return x ? -1 : 0; | |
22 } | |
23 | |
24 static FILE * | |
25 nextfile(FILE *f, char *buf, int plen, int slen) | |
26 { | |
27 static int filecount = 0; | |
28 | |
29 if (f) | |
30 fshut(f, "<file>"); | |
31 if (itostr(buf + plen, filecount++, slen) < 0) | |
32 return NULL; | |
33 | |
34 if (!(f = fopen(buf, "w"))) | |
35 eprintf("'%s':", buf); | |
36 | |
37 return f; | |
38 } | |
39 | |
40 static void | |
41 usage(void) | |
42 { | |
43 eprintf("usage: %s [-a num] [-b num[k|m|g] | -l num] [-d] " | |
44 "[file [prefix]]\n", argv0); | |
45 } | |
46 | |
47 int | |
48 main(int argc, char *argv[]) | |
49 { | |
50 FILE *in = stdin, *out = NULL; | |
51 off_t size = 1000, n; | |
52 int ret = 0, ch, plen, slen = 2, always = 0; | |
53 char name[NAME_MAX + 1], *prefix = "x", *file = NULL; | |
54 | |
55 ARGBEGIN { | |
56 case 'a': | |
57 slen = estrtonum(EARGF(usage()), 0, INT_MAX); | |
58 break; | |
59 case 'b': | |
60 always = 1; | |
61 if ((size = parseoffset(EARGF(usage()))) < 0) | |
62 return 1; | |
63 if (!size) | |
64 eprintf("size needs to be positive\n"); | |
65 break; | |
66 case 'd': | |
67 base = 10; | |
68 start = '0'; | |
69 break; | |
70 case 'l': | |
71 always = 0; | |
72 size = estrtonum(EARGF(usage()), 1, MIN(LLONG_MAX, SSIZE… | |
73 break; | |
74 default: | |
75 usage(); | |
76 } ARGEND | |
77 | |
78 if (*argv) | |
79 file = *argv++; | |
80 if (*argv) | |
81 prefix = *argv++; | |
82 if (*argv) | |
83 usage(); | |
84 | |
85 plen = strlen(prefix); | |
86 if (plen + slen > NAME_MAX) | |
87 eprintf("names cannot exceed %d bytes\n", NAME_MAX); | |
88 estrlcpy(name, prefix, sizeof(name)); | |
89 | |
90 if (file && strcmp(file, "-")) { | |
91 if (!(in = fopen(file, "r"))) | |
92 eprintf("fopen %s:", file); | |
93 } | |
94 | |
95 n = 0; | |
96 while ((ch = getc(in)) != EOF) { | |
97 if (!out || n >= size) { | |
98 if (!(out = nextfile(out, name, plen, slen))) | |
99 eprintf("fopen: %s:", name); | |
100 n = 0; | |
101 } | |
102 n += (always || ch == '\n'); | |
103 putc(ch, out); | |
104 } | |
105 | |
106 ret |= (in != stdin) && fshut(in, "<infile>"); | |
107 ret |= out && (out != stdout) && fshut(out, "<outfile>"); | |
108 ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>"); | |
109 | |
110 return ret; | |
111 } |