Introduction
Introduction Statistics Contact Development Disclaimer Help
expand.c - sbase - suckless unix tools
git clone git://git.suckless.org/sbase
Log
Files
Refs
README
LICENSE
---
expand.c (2300B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include "utf.h"
7 #include "util.h"
8
9 static int iflag = 0;
10 static size_t *tablist = NULL;
11 static size_t tablistlen = 0;
12
13 static size_t
14 parselist(const char *s)
15 {
16 size_t i;
17 char *p, *tmp;
18
19 tmp = estrdup(s);
20 for (i = 0; (p = strsep(&tmp, " ,")); i++) {
21 if (*p == '\0')
22 eprintf("empty field in tablist\n");
23 tablist = ereallocarray(tablist, i + 1, sizeof(*tablist)…
24 tablist[i] = estrtonum(p, 1, MIN(LLONG_MAX, SIZE_MAX));
25 if (i > 0 && tablist[i - 1] >= tablist[i])
26 eprintf("tablist must be ascending\n");
27 }
28 tablist = ereallocarray(tablist, i + 1, sizeof(*tablist));
29 /* tab length = 1 for the overflowing case later in the matcher …
30 tablist[i] = 1;
31
32 return i;
33 }
34
35 static int
36 expand(const char *file, FILE *fp)
37 {
38 size_t bol = 1, col = 0, i;
39 Rune r;
40
41 while (efgetrune(&r, fp, file)) {
42 switch (r) {
43 case '\t':
44 if (tablistlen == 1)
45 i = 0;
46 else for (i = 0; i < tablistlen; i++)
47 if (col < tablist[i])
48 break;
49 if (bol || !iflag) {
50 do {
51 col++;
52 putchar(' ');
53 } while (col % tablist[i]);
54 } else {
55 putchar('\t');
56 col = tablist[i];
57 }
58 break;
59 case '\b':
60 bol = 0;
61 if (col)
62 col--;
63 putchar('\b');
64 break;
65 case '\n':
66 bol = 1;
67 col = 0;
68 putchar('\n');
69 break;
70 default:
71 col++;
72 if (r != ' ')
73 bol = 0;
74 efputrune(&r, stdout, "<stdout>");
75 break;
76 }
77 }
78
79 return 0;
80 }
81
82 static void
83 usage(void)
84 {
85 eprintf("usage: %s [-i] [-t tablist] [file ...]\n", argv0);
86 }
87
88 int
89 main(int argc, char *argv[])
90 {
91 FILE *fp;
92 int ret = 0;
93 char *tl = "8";
94
95 ARGBEGIN {
96 case 'i':
97 iflag = 1;
98 break;
99 case 't':
100 tl = EARGF(usage());
101 if (!*tl)
102 eprintf("tablist cannot be empty\n");
103 break;
104 default:
105 usage();
106 } ARGEND
107
108 tablistlen = parselist(tl);
109
110 if (!argc) {
111 expand("<stdin>", stdin);
112 } else {
113 for (; *argv; argc--, argv++) {
114 if (!strcmp(*argv, "-")) {
115 *argv = "<stdin>";
116 fp = stdin;
117 } else if (!(fp = fopen(*argv, "r"))) {
118 weprintf("fopen %s:", *argv);
119 ret = 1;
120 continue;
121 }
122 expand(*argv, fp);
123 if (fp != stdin && fshut(fp, *argv))
124 ret = 1;
125 }
126 }
127
128 ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>");
129
130 return ret;
131 }
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.