strings.c - sbase - suckless unix tools | |
git clone git://git.suckless.org/sbase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
strings.c (1708B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include <limits.h> | |
3 #include <stdio.h> | |
4 #include <stdlib.h> | |
5 #include <string.h> | |
6 | |
7 #include "utf.h" | |
8 #include "util.h" | |
9 | |
10 static char *format = ""; | |
11 | |
12 static void | |
13 strings(FILE *fp, const char *fname, size_t min) | |
14 { | |
15 Rune r, *rbuf; | |
16 size_t i, bread; | |
17 off_t off; | |
18 | |
19 rbuf = ereallocarray(NULL, min, sizeof(*rbuf)); | |
20 | |
21 for (off = 0, i = 0; (bread = efgetrune(&r, fp, fname)); ) { | |
22 off += bread; | |
23 if (r == Runeerror) | |
24 continue; | |
25 if (!isprintrune(r)) { | |
26 if (i == min) | |
27 putchar('\n'); | |
28 i = 0; | |
29 continue; | |
30 } | |
31 if (i == min) { | |
32 efputrune(&r, stdout, "<stdout>"); | |
33 continue; | |
34 } | |
35 rbuf[i++] = r; | |
36 if (i < min) | |
37 continue; | |
38 printf(format, (long)off - i); | |
39 for (i = 0; i < min; i++) | |
40 efputrune(rbuf + i, stdout, "<stdout>"); | |
41 } | |
42 free(rbuf); | |
43 } | |
44 | |
45 static void | |
46 usage(void) | |
47 { | |
48 eprintf("usage: %s [-a] [-n num] [-t format] [file ...]\n", argv… | |
49 } | |
50 | |
51 int | |
52 main(int argc, char *argv[]) | |
53 { | |
54 FILE *fp; | |
55 size_t min = 4; | |
56 int ret = 0; | |
57 char f; | |
58 | |
59 ARGBEGIN { | |
60 case 'a': | |
61 break; | |
62 case 'n': | |
63 min = estrtonum(EARGF(usage()), 1, LLONG_MAX); | |
64 break; | |
65 case 't': | |
66 format = estrdup("%8l#: "); | |
67 f = *EARGF(usage()); | |
68 if (f == 'd' || f == 'o' || f == 'x') | |
69 format[3] = f; | |
70 else | |
71 usage(); | |
72 break; | |
73 default: | |
74 usage(); | |
75 } ARGEND | |
76 | |
77 if (!argc) { | |
78 strings(stdin, "<stdin>", min); | |
79 } else { | |
80 for (; *argv; argc--, argv++) { | |
81 if (!strcmp(*argv, "-")) { | |
82 *argv = "<stdin>"; | |
83 fp = stdin; | |
84 } else if (!(fp = fopen(*argv, "r"))) { | |
85 weprintf("fopen %s:", *argv); | |
86 ret = 1; | |
87 continue; | |
88 } | |
89 strings(fp, *argv, min); | |
90 if (fp != stdin && fshut(fp, *argv)) | |
91 ret = 1; | |
92 } | |
93 } | |
94 | |
95 ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>"); | |
96 | |
97 return ret; | |
98 } |