diff options
author | Elias Fleckenstein <eliasfleckenstein@web.de> | 2022-05-24 11:34:52 +0200 |
---|---|---|
committer | Elias Fleckenstein <eliasfleckenstein@web.de> | 2022-05-24 11:34:52 +0200 |
commit | f52ab2a8648bb3f63b5d930474e4c3b85134d6ca (patch) | |
tree | ba8a08cf29efaa2fbe5014b5e28c489dd4009b53 | |
parent | 512239c77a63779649ee4a996e83f52f7f3b7a46 (diff) | |
download | center-f52ab2a8648bb3f63b5d930474e4c3b85134d6ca.tar.xz |
Split output to multiple lines if necessary
-rw-r--r-- | center.c | 57 |
1 files changed, 36 insertions, 21 deletions
@@ -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; } |