1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#define FOR_paste
24#include "toys.h"
25
26GLOBALS(
27 char *d;
28
29 int files;
30)
31
32
33
34static void paste_files(void)
35{
36 FILE **fps = (void *)toybuf;
37 char *dpos, *dstr, *buf, c;
38 int i, any, dcount, dlen, len, seq = toys.optflags&FLAG_s;
39
40
41 for (;;) {
42
43
44 dpos = TT.d;
45
46 for (i = any = dcount = dlen = 0; seq || i<TT.files; i++) {
47 size_t blen;
48 wchar_t wc;
49 FILE *ff = seq ? *fps : fps[i];
50
51
52
53 buf = 0;
54 len = 0;
55 if (!ff || 0>=(len = getline(&buf, &blen, ff))) {
56 if (ff && ff!=stdin) fclose(ff);
57 if (seq) return;
58 fps[i] = 0;
59 if (!any) continue;
60 }
61 dcount = any ? 1 : i;
62 any = 1;
63
64
65
66
67
68 while (dcount) {
69
70
71 dstr = dpos;
72 dlen = 0;
73 dcount--;
74
75 if (!*TT.d) {;}
76 else if (*dpos == '\\') {
77 if (*++dpos=='0') dpos++;
78 else {
79 dlen = 1;
80 if ((c = unescape(*dpos))) {
81 dstr = &c;
82 dpos++;
83 }
84 }
85 } else {
86 while (0<(dlen = utf8towc(&wc, dpos, 99))) {
87 dpos += dlen;
88 if (!(dlen = wcwidth(wc))) continue;
89 if (dlen<0) dpos = dstr+1;
90 break;
91 }
92 dlen = dpos-dstr;
93 }
94 if (!*dpos) dpos = TT.d;
95
96 if (dlen) fwrite(dstr, dlen, 1, stdout);
97 }
98
99 if (0<len) {
100 fwrite(buf, len-(buf[len-1]=='\n'), 1, stdout);
101 free(buf);
102 }
103 }
104
105
106 if (any) xputc('\n');
107 else break;
108 }
109}
110
111static void do_paste(int fd, char *name)
112{
113 FILE **fps = (void *)toybuf;
114
115 if (!(fps[TT.files++] = (fd ? fdopen(fd, "r") : stdin))) perror_exit(0);
116 if (TT.files >= sizeof(toybuf)/sizeof(FILE *)) perror_exit("tilt");
117 if (toys.optflags&FLAG_s) {
118 paste_files();
119 xputc('\n');
120 TT.files = 0;
121 }
122}
123
124void paste_main(void)
125{
126 if (!(toys.optflags&FLAG_d)) TT.d = "\t";
127
128 loopfiles_rw(toys.optargs, O_RDONLY, 0, do_paste);
129 if (!(toys.optflags&FLAG_s)) paste_files();
130}
131