aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElias Fleckenstein <eliasfleckenstein@web.de>2022-05-24 11:34:52 +0200
committerElias Fleckenstein <eliasfleckenstein@web.de>2022-05-24 11:34:52 +0200
commitf52ab2a8648bb3f63b5d930474e4c3b85134d6ca (patch)
treeba8a08cf29efaa2fbe5014b5e28c489dd4009b53
parent512239c77a63779649ee4a996e83f52f7f3b7a46 (diff)
downloadcenter-f52ab2a8648bb3f63b5d930474e4c3b85134d6ca.tar.xz
Split output to multiple lines if necessary
-rw-r--r--center.c57
1 files changed, 36 insertions, 21 deletions
diff --git a/center.c b/center.c
index e6f13b6..e8097d2 100644
--- a/center.c
+++ b/center.c
@@ -8,7 +8,7 @@
#include <sys/ioctl.h>
#include <locale.h>
-#define ERR(str) { perror(str); err = EXIT_FAILURE; break; }
+#define ERR(str) { perror(str); err = EXIT_FAILURE; goto end; }
int main()
{
@@ -17,37 +17,52 @@ int main()
exit(EXIT_FAILURE);
}
- char *ptr = NULL;
+ char *buf = NULL;
size_t siz = 0;
- ssize_t slen;
+ ssize_t len;
int err = EXIT_SUCCESS;
- while ((slen = getline(&ptr, &siz, stdin)) > 0) {
- ptr[slen - 1] = '\0';
-
- size_t len = mbstowcs(NULL, ptr, 0);
- if (len == (size_t) -1) ERR("msbtowcs")
+ while ((len = getline(&buf, &siz, stdin)) > 0) {
+ struct winsize ws;
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) ERR("ioctl")
- wchar_t *wcs = calloc(len + 1, sizeof *wcs);
- if (!wcs) ERR("calloc")
+ int term_width = ws.ws_col;
- if (mbstowcs(wcs, ptr, len + 1) == (size_t) -1) ERR("msbtowcs")
+ char *ptr = buf;
+ char *last = ptr;
+ int str_width = 0;
+ mbstate_t mbs = {0};
- struct winsize ws;
- if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) ERR("ioctl")
+ while (len > 0) {
+ wchar_t wc;
+
+ size_t adv = mbrtowc(&wc, ptr, len, &mbs);
+ if (adv == (size_t) -1 || adv == (size_t) -2) ERR("mbrtowc")
+
+ ptr += adv;
+ len -= adv;
+
+ int width = wcwidth(wc);
+ if (width > 0)
+ str_width += width;
- int trm_width = ws.ws_col;
- int str_width = wcswidth(wcs, len);
+ if (*ptr == '\n' || str_width >= term_width - 12) {
+ for (int i = (term_width - str_width) / 2; i > 0; i--)
+ putchar(' ');
+ fwrite(last, 1, ptr - last + 1, stdout);
- free(wcs);
+ if (*ptr != '\n')
+ putchar('\n');
- for (int i = (trm_width - str_width) / 2; i > 0; i--)
- putchar(' ');
- puts(ptr);
+ last = ptr + 1;
+ str_width = 0;
+ }
+ }
}
- if (ptr)
- free(ptr);
+ end:
+ if (buf)
+ free(buf);
return err;
}