Introduction
Introduction Statistics Contact Development Disclaimer Help
fold.c - sbase - suckless unix tools
git clone git://git.suckless.org/sbase
Log
Files
Refs
README
LICENSE
---
fold.c (2616B)
---
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 "text.h"
9 #include "util.h"
10 #include "utf.h"
11
12 static int bflag = 0;
13 static int sflag = 0;
14 static size_t width = 80;
15
16 static void
17 foldline(struct line *l, const char *fname) {
18 size_t i, col, last, spacesect, len;
19 Rune r;
20 int runelen;
21
22 for (i = 0, last = 0, col = 0, spacesect = 0; i < l->len; i += r…
23 if (col >= width && ((l->data[i] != '\r' && l->data[i] !…
24 if (bflag && col > width)
25 i -= runelen; /* never split a ch…
26 len = ((sflag && spacesect) ? spacesect : i) - l…
27 if (fwrite(l->data + last, 1, len, stdout) != le…
28 eprintf("fwrite <stdout>:");
29 if (l->data[i] != '\n')
30 putchar('\n');
31 if (sflag && spacesect)
32 i = spacesect;
33 last = i;
34 col = 0;
35 spacesect = 0;
36 }
37 runelen = charntorune(&r, l->data + i, l->len - i);
38 if (!runelen || r == Runeerror)
39 eprintf("charntorune: %s: invalid utf\n", fname);
40 if (sflag && isblankrune(r))
41 spacesect = i + runelen;
42 if (!bflag && iscntrl(l->data[i])) {
43 switch(l->data[i]) {
44 case '\b':
45 col -= (col > 0);
46 break;
47 case '\r':
48 col = 0;
49 break;
50 case '\t':
51 col += (8 - (col % 8));
52 if (col >= width)
53 i--;
54 break;
55 }
56 } else {
57 col += bflag ? runelen : 1;
58 }
59 }
60 if (l->len - last)
61 fwrite(l->data + last, 1, l->len - last, stdout);
62 }
63
64 static void
65 fold(FILE *fp, const char *fname)
66 {
67 static struct line line;
68 static size_t size = 0;
69 ssize_t len;
70
71 while ((len = getline(&line.data, &size, fp)) > 0) {
72 line.len = len;
73 foldline(&line, fname);
74 }
75 if (ferror(fp))
76 eprintf("getline %s:", fname);
77 }
78
79 static void
80 usage(void)
81 {
82 eprintf("usage: %s [-bs] [-w num | -num] [FILE ...]\n", argv0);
83 }
84
85 int
86 main(int argc, char *argv[])
87 {
88 FILE *fp;
89 int ret = 0;
90
91 ARGBEGIN {
92 case 'b':
93 bflag = 1;
94 break;
95 case 's':
96 sflag = 1;
97 break;
98 case 'w':
99 width = estrtonum(EARGF(usage()), 1, MIN(LLONG_MAX, SIZE…
100 break;
101 ARGNUM:
102 if (!(width = ARGNUMF()))
103 eprintf("illegal width value, too small\n");
104 break;
105 default:
106 usage();
107 } ARGEND
108
109 if (!argc) {
110 fold(stdin, "<stdin>");
111 } else {
112 for (; *argv; argc--, argv++) {
113 if (!strcmp(*argv, "-")) {
114 *argv = "<stdin>";
115 fp = stdin;
116 } else if (!(fp = fopen(*argv, "r"))) {
117 weprintf("fopen %s:", *argv);
118 ret = 1;
119 continue;
120 }
121 fold(fp, *argv);
122 if (fp != stdin && fshut(fp, *argv))
123 ret = 1;
124 }
125 }
126
127 ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>");
128
129 return ret;
130 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.