]> git.lizzy.rs Git - center.git/blob - center.c
Add new target clean
[center.git] / center.c
1 #define _POSIX_C_SOURCE 200809L
2 #define _XOPEN_SOURCE
3 #include <fcntl.h>
4 #include <locale.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <sys/ioctl.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 #include <termios.h>
11 #include <unistd.h>
12 #include <wchar.h>
13
14 #define ERR(str) { perror(str); err = EXIT_FAILURE; goto end; }
15
16 int main()
17 {
18         if (setlocale(LC_ALL, "") == NULL) {
19                 perror("setlocale");
20                 exit(EXIT_FAILURE);
21         }
22
23         char *buf = NULL;
24         size_t siz = 0;
25         ssize_t len;
26         int err = EXIT_SUCCESS;
27
28         int tty_fd = open("/dev/tty", O_RDWR);
29         if (tty_fd < 0) {
30                 perror("open");
31                 return EXIT_FAILURE;
32         }
33
34         while ((len = getline(&buf, &siz, stdin)) > 0) {
35                 struct winsize ws;
36                 if (ioctl(tty_fd, TIOCGWINSZ, &ws) < 0) ERR("ioctl")
37
38                 int term_width = ws.ws_col;
39
40                 char *ptr = buf;
41                 char *last = ptr;
42                 int str_width = 0;
43                 mbstate_t mbs = {0};
44
45                 while (len > 0) {
46                         wchar_t wc;
47
48                         size_t adv = mbrtowc(&wc, ptr, len, &mbs);
49                         if (adv == (size_t) -1 || adv == (size_t) -2) ERR("mbrtowc")
50
51                         int width = wcwidth(wc);
52                         if (width > 0)
53                                 str_width += width;
54
55                         if (*ptr == '\n' || str_width >= term_width - 12) {
56                                 for (int i = (term_width - str_width) / 2; i > 0; i--)
57                                         putchar(' ');
58                                 fwrite(last, 1, ptr - last + 1, stdout);
59
60                                 if (*ptr != '\n')
61                                         putchar('\n');
62
63                                 last = ptr + adv;
64                                 str_width = 0;
65                         }
66
67                         ptr += adv;
68                         len -= adv;
69                 }
70         }
71
72         end:
73         close(tty_fd);
74
75         if (buf)
76                 free(buf);
77
78         return err;
79 }