Introduction
Introduction Statistics Contact Development Disclaimer Help
paste.c - sbase - suckless unix tools
git clone git://git.suckless.org/sbase
Log
Files
Refs
README
LICENSE
---
paste.c (2734B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "utf.h"
6 #include "util.h"
7
8 struct fdescr {
9 FILE *fp;
10 const char *name;
11 };
12
13 static void
14 sequential(struct fdescr *dsc, int fdescrlen, Rune *delim, size_t deliml…
15 {
16 Rune c, last;
17 size_t i, d;
18
19 for (i = 0; i < fdescrlen; i++) {
20 d = 0;
21 last = 0;
22
23 while (efgetrune(&c, dsc[i].fp, dsc[i].name)) {
24 if (last == '\n') {
25 if (delim[d] != '\0')
26 efputrune(&delim[d], stdout, "<s…
27 d = (d + 1) % delimlen;
28 }
29
30 if (c != '\n')
31 efputrune(&c, stdout, "<stdout>");
32 last = c;
33 }
34
35 if (last == '\n')
36 efputrune(&last, stdout, "<stdout>");
37 }
38 }
39
40 static void
41 parallel(struct fdescr *dsc, int fdescrlen, Rune *delim, size_t delimlen)
42 {
43 Rune c, d;
44 size_t i, m;
45 ssize_t last;
46
47 nextline:
48 last = -1;
49
50 for (i = 0; i < fdescrlen; i++) {
51 d = delim[i % delimlen];
52 c = 0;
53
54 while (efgetrune(&c, dsc[i].fp, dsc[i].name)) {
55 for (m = last + 1; m < i; m++) {
56 if (delim[m % delimlen] != '\0')
57 efputrune(&delim[m % delimlen], …
58 }
59 last = i;
60 if (c == '\n') {
61 if (i != fdescrlen - 1)
62 c = d;
63 efputrune(&c, stdout, "<stdout>");
64 break;
65 }
66 efputrune(&c, stdout, "<stdout>");
67 }
68
69 if (c == 0 && last != -1) {
70 if (i == fdescrlen - 1)
71 putchar('\n');
72 else if (d != '\0')
73 efputrune(&d, stdout, "<stdout>");
74 last++;
75 }
76 }
77 if (last != -1)
78 goto nextline;
79 }
80
81 static void
82 usage(void)
83 {
84 eprintf("usage: %s [-s] [-d list] file ...\n", argv0);
85 }
86
87 int
88 main(int argc, char *argv[])
89 {
90 struct fdescr *dsc;
91 Rune *delim_rune = NULL;
92 size_t delim_runelen, i, delim_bytelen = 1;
93 int seq = 0, ret = 0;
94 char *delim = "\t";
95
96 ARGBEGIN {
97 case 's':
98 seq = 1;
99 break;
100 case 'd':
101 delim = EARGF(usage());
102 delim_bytelen = unescape(delim);
103 break;
104 default:
105 usage();
106 } ARGEND
107
108 if (!argc)
109 usage();
110
111 /* populate delimiters */
112 delim_rune = ereallocarray(NULL,
113 utfmemlen(delim, delim_bytelen) + 1, sizeof(*delim_rune)…
114 if (!(delim_runelen = utfntorunestr(delim, delim_bytelen, delim_…
115 usage();
116 }
117
118 /* populate file list */
119 dsc = ereallocarray(NULL, argc, sizeof(*dsc));
120
121 for (i = 0; i < argc; i++) {
122 if (!strcmp(argv[i], "-")) {
123 argv[i] = "<stdin>";
124 dsc[i].fp = stdin;
125 } else if (!(dsc[i].fp = fopen(argv[i], "r"))) {
126 eprintf("fopen %s:", argv[i]);
127 }
128 dsc[i].name = argv[i];
129 }
130
131 if (seq) {
132 sequential(dsc, argc, delim_rune, delim_runelen);
133 } else {
134 parallel(dsc, argc, delim_rune, delim_runelen);
135 }
136
137 for (i = 0; i < argc; i++)
138 if (dsc[i].fp != stdin && fshut(dsc[i].fp, argv[i]))
139 ret |= fshut(dsc[i].fp, argv[i]);
140
141 ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>");
142
143 return ret;
144 }
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.