1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
/* fold.c - fold text
*
* Copyright 2014 Samuel Holland <samuel@sholland.net>
*
* See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/fold.html
USE_FOLD(NEWTOY(fold, "bsw#", TOYFLAG_USR|TOYFLAG_BIN))
config FOLD
bool "fold"
default n
help
usage: fold [-bs] [-w WIDTH] [FILE...]
Folds/wraps FILE or stdin at 80 columns.
-b Wrap based on bytes instead of columns
-s Wrap at farthest right whitespace
-w Wrap at WIDTH columns instead of 80
*/
#define FOR_fold
#include "toys.h"
GLOBALS(
int w_number;
)
void do_fold(int fd, char *name)
{
int buflen, i, len = 0, split;
int max = (toys.optflags & FLAG_w) ? TT.w_number : 80;
char tmp, *buf;
if (max > sizeof(toybuf)) {
error_exit("width (%ld) too big", max);
}
while (read(fd, toybuf, sizeof(toybuf))) {
split = -1;
buf = toybuf;
buflen = strlen(buf);
for (i = 0; i < buflen; i++) {
switch (buf[i]) {
case '\n':
//reset len, FLAG_b or not; just print multiple lines at once
len = 0;
continue;
case '\b':
//len cannot be negative; not allowed to wrap after backspace
if (toys.optflags & FLAG_b) len++;
else if (len > 0) len--;
continue;
case '\r':
//not allowed to wrap after carriage return
if (toys.optflags & FLAG_b) len++;
else len = 0;
continue;
case '\t':
//round to 8, but we add one after falling through
//(because of whitespace, but it also takes care of FLAG_b)
if (!(toys.optflags & FLAG_b)) len = (len & -8) + 7;
case ' ':
split = i;
default:
len++;
}
//we don't want to double up \n; not allowed to wrap before \b
if (len >= max && buf[i+1] != '\n' && buf[i+1] != '\b') {
if (!(toys.optflags & FLAG_s)) split = i; //we split right here
tmp = buf[split+1];
buf[split+1] = 0;
xprintf("%s\n", buf);
buf[split+1] = tmp;
len = 0;
if (split < buflen - 1) {
buf += split + 1;
i = 0;
buflen = strlen(buf);
}
}
}
xputs(buf);
}
}
void fold_main(void)
{
loopfiles(toys.optargs, do_fold);
}
|