Truncate output to the terminal size - sacc - sacc(omys), simple console gopher… | |
git clone git://bitreich.org/sacc/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65… | |
Log | |
Files | |
Refs | |
Tags | |
LICENSE | |
--- | |
commit 2e31e44ffa614c5202edfe2abcc05a7880902640 | |
parent d90036de3c72730ae2797844b36eb5ae9fd3843f | |
Author: Quentin Rameau <[email protected]> | |
Date: Fri, 29 Dec 2017 10:52:39 +0100 | |
Truncate output to the terminal size | |
Thanks to Hiltjo for his input, making this patch a little better. | |
Diffstat: | |
M ui_ti.c | 71 +++++++++++++++++++++--------… | |
M ui_txt.c | 58 +++++++++++++++++++++++------… | |
2 files changed, 92 insertions(+), 37 deletions(-) | |
--- | |
diff --git a/ui_ti.c b/ui_ti.c | |
@@ -13,6 +13,7 @@ | |
#define C(c) #c | |
#define S(c) C(c) | |
+static char bufout[256]; | |
static struct termios tsave; | |
static struct termios tsacc; | |
#if defined(__NetBSD__) | |
@@ -50,8 +51,8 @@ uiprompt(char *fmt, ...) | |
{ | |
va_list ap; | |
char *input = NULL; | |
- size_t n = 0; | |
- ssize_t r = 0; | |
+ size_t n; | |
+ ssize_t r; | |
putp(tparm(save_cursor)); | |
@@ -60,19 +61,23 @@ uiprompt(char *fmt, ...) | |
putp(tparm(enter_standout_mode)); | |
va_start(ap, fmt); | |
- r += vprintf(fmt, ap); | |
+ if (vsnprintf(bufout, sizeof(bufout), fmt, ap) >= sizeof(bufout)) | |
+ bufout[sizeof(bufout)-1] = '\0'; | |
va_end(ap); | |
+ printf("%.*s", columns, bufout); | |
putp(tparm(exit_standout_mode)); | |
- printf("%*s", columns-r, " "); | |
+ if ((n = strlen(bufout)) < columns) | |
+ printf("%*s", columns - n, " "); | |
- putp(tparm(cursor_address, lines-1, r)); | |
+ putp(tparm(cursor_address, lines-1, n)); | |
tsacc.c_lflag |= (ECHO|ICANON); | |
tcsetattr(0, TCSANOW, &tsacc); | |
fflush(stdout); | |
+ n = 0; | |
r = getline(&input, &n, stdin); | |
tsacc.c_lflag &= ~(ECHO|ICANON); | |
@@ -93,7 +98,10 @@ uiprompt(char *fmt, ...) | |
static void | |
printitem(Item *item) | |
{ | |
- printf("%s %s\r", typedisplay(item->type), item->username); | |
+ if (snprintf(bufout, sizeof(bufout), "%s %s", typedisplay(item->type), | |
+ item->username) >= sizeof(bufout)) | |
+ bufout[sizeof(bufout)-1] = '\0'; | |
+ printf("%.*s\r", columns, bufout); | |
} | |
static Item * | |
@@ -127,7 +135,7 @@ void | |
uistatus(char *fmt, ...) | |
{ | |
va_list ap; | |
- int n = 0; | |
+ size_t n; | |
putp(tparm(save_cursor)); | |
@@ -135,12 +143,20 @@ uistatus(char *fmt, ...) | |
putp(tparm(enter_standout_mode)); | |
va_start(ap, fmt); | |
- n += vprintf(fmt, ap); | |
+ n = vsnprintf(bufout + n, sizeof(bufout) - n, fmt, ap); | |
va_end(ap); | |
- n += printf(" [Press a key to continue ☃]"); | |
+ if (n < sizeof(bufout)-1) { | |
+ n += snprintf(bufout + n, sizeof(bufout) - n, | |
+ " [Press a key to continue ☃]"); | |
+ } | |
+ if (n >= sizeof(bufout)) | |
+ bufout[sizeof(bufout)-1] = '\0'; | |
+ | |
+ printf("%.*s", columns, bufout); | |
putp(tparm(exit_standout_mode)); | |
- printf("%*s", columns-n, " "); | |
+ if ((n = strlen(bufout)) < columns) | |
+ printf("%*s", columns - n, " "); | |
putp(tparm(restore_cursor)); | |
fflush(stdout); | |
@@ -153,9 +169,8 @@ displaystatus(Item *item) | |
{ | |
Dir *dir = item->dat; | |
char *fmt; | |
- size_t nitems = dir ? dir->nitems : 0; | |
+ size_t n, nitems = dir ? dir->nitems : 0; | |
unsigned long long printoff = dir ? dir->printoff : 0; | |
- int n; | |
putp(tparm(save_cursor)); | |
@@ -163,12 +178,16 @@ displaystatus(Item *item) | |
putp(tparm(enter_standout_mode)); | |
fmt = (strcmp(item->port, "70") && strcmp(item->port, "gopher")) ? | |
"%1$3lld%%| %2$s:%5$s/%3$c%4$s" : "%3lld%%| %s/%c%s"; | |
- n = printf(fmt, | |
- (printoff + lines-1 >= nitems) ? 100 : | |
- (printoff + lines-1) * 100 / nitems, | |
- item->host, item->type, item->selector, item->port); | |
+ if (snprintf(bufout, sizeof(bufout), fmt, | |
+ (printoff + lines-1 >= nitems) ? 100 : | |
+ (printoff + lines-1) * 100 / nitems, | |
+ item->host, item->type, item->selector, item->port) | |
+ >= sizeof(bufout)) | |
+ bufout[sizeof(bufout)-1] = '\0'; | |
+ printf("%.*s", columns, bufout); | |
putp(tparm(exit_standout_mode)); | |
- printf("%*s", columns-n, " "); | |
+ if ((n = strlen(bufout)) < columns) | |
+ printf("%*s", columns - n, " "); | |
putp(tparm(restore_cursor)); | |
fflush(stdout); | |
@@ -178,7 +197,7 @@ static void | |
displayuri(Item *item) | |
{ | |
char *fmt; | |
- int n; | |
+ size_t n; | |
if (item->type == 0 || item->type == 'i') | |
return; | |
@@ -189,18 +208,26 @@ displayuri(Item *item) | |
putp(tparm(enter_standout_mode)); | |
switch (item->type) { | |
case 'h': | |
- n = printf("%s: %s", item->username, item->selector); | |
+ n = snprintf(bufout, sizeof(bufout), "%s: %s", | |
+ item->username, item->selector); | |
break; | |
default: | |
fmt = strcmp(item->port, "70") ? | |
"%1$s: gopher://%2$s:%5$s/%3$c%4$s" : | |
"%s: gopher://%s/%c%s"; | |
- n = printf(fmt, item->username, | |
- item->host, item->type, item->selector, item->port); | |
+ n = snprintf(bufout, sizeof(bufout), fmt, | |
+ item->username, item->host, item->type, | |
+ item->selector, item->port); | |
break; | |
} | |
+ | |
+ if (n >= sizeof(bufout)) | |
+ bufout[sizeof(bufout)-1] = '\0'; | |
+ | |
+ printf("%.*s", columns, bufout); | |
putp(tparm(exit_standout_mode)); | |
- printf("%*s", columns-n, " "); | |
+ if ((n = strlen(bufout)) < columns) | |
+ printf("%*s", columns - n, " "); | |
putp(tparm(restore_cursor)); | |
fflush(stdout); | |
diff --git a/ui_txt.c b/ui_txt.c | |
@@ -10,6 +10,7 @@ | |
#include "common.h" | |
+static char bufout[256]; | |
int lines, columns; | |
static void | |
@@ -67,12 +68,20 @@ void | |
uistatus(char *fmt, ...) | |
{ | |
va_list arg; | |
+ int n; | |
va_start(arg, fmt); | |
- vprintf(fmt, arg); | |
+ n = vsnprintf(bufout, sizeof(bufout), fmt, arg); | |
va_end(arg); | |
- printf(" [Press Enter to continue ☃]"); | |
+ if (n < sizeof(bufout)-1) { | |
+ n += snprintf(bufout + n, sizeof(bufout) - n, | |
+ " [Press Enter to continue ☃]"); | |
+ } | |
+ if (n >= sizeof(bufout)) | |
+ bufout[sizeof(bufout)-1] = '\0'; | |
+ | |
+ printf("%.*s", columns, bufout); | |
fflush(stdout); | |
getchar(); | |
@@ -89,9 +98,13 @@ printstatus(Item *item, char c) | |
fmt = (strcmp(item->port, "70") && strcmp(item->port, "gopher")) ? | |
"%1$3lld%%%*2$3$c %4$s:%8$s/%5$c%6$s [%7$c]: " : | |
"%3lld%%%*c %s/%c%s [%c]: "; | |
- printf(fmt, (printoff + lines-1 >= nitems) ? 100 : | |
- (printoff + lines) * 100 / nitems, ndigits(nitems)+2, '|', | |
- item->host, item->type, item->selector, c, item->port); | |
+ if (snprintf(bufout, sizeof(bufout), fmt, | |
+ (printoff + lines-1 >= nitems) ? 100 : | |
+ (printoff + lines) * 100 / nitems, ndigits(nitems)+2, '|', | |
+ item->host, item->type, item->selector, c, item->port) | |
+ >= sizeof(bufout)) | |
+ bufout[sizeof(bufout)-1] = '\0'; | |
+ printf("%.*s", columns, bufout); | |
} | |
char * | |
@@ -103,9 +116,12 @@ uiprompt(char *fmt, ...) | |
ssize_t r; | |
va_start(ap, fmt); | |
- vprintf(fmt, ap); | |
+ if (vsnprintf(bufout, sizeof(bufout), fmt, ap) >= sizeof(bufout)) | |
+ bufout[sizeof(bufout)-1] = '\0'; | |
va_end(ap); | |
+ printf("%.*s", columns, bufout); | |
+ | |
fflush(stdout); | |
if ((r = getline(&input, &n, stdin)) < 0) { | |
@@ -138,8 +154,12 @@ uidisplay(Item *entry) | |
nd = ndigits(nitems); | |
for (i = dir->printoff; i < nitems && i < nlines; ++i) { | |
- printf("%*zu %s %s\n", | |
- nd, i+1, typedisplay(items[i].type), items[i].username); | |
+ if (snprintf(bufout, sizeof(bufout), "%*zu %s %s", | |
+ nd, i+1, typedisplay(items[i].type), | |
+ items[i].username) | |
+ >= sizeof(bufout)) | |
+ bufout[sizeof(bufout)-1] = '\0'; | |
+ printf("%.*s\n", columns, bufout); | |
} | |
fflush(stdout); | |
@@ -149,27 +169,35 @@ void | |
printuri(Item *item, size_t i) | |
{ | |
char *fmt; | |
+ int n; | |
if (!item) | |
return; | |
switch (item->type) { | |
case 0: | |
- break; | |
+ return; | |
case 'i': | |
- printf("%zu: %s\n", i, item->username); | |
+ n = snprintf(bufout, sizeof(bufout), "%zu: %s", | |
+ i, item->username); | |
break; | |
case 'h': | |
- printf("%zu: %s: %s\n", i, item->username, item->selector); | |
+ n = snprintf(bufout, sizeof(bufout), "%zu: %s: %s", | |
+ i, item->username, item->selector); | |
break; | |
default: | |
fmt = strcmp(item->port, "70") ? | |
- "%1$zu: %2$s: gopher://%3$s:%6$s/%4$c%5$s\n" : | |
- "%zu: %s: gopher://%s/%c%s\n"; | |
- printf(fmt, i, item->username, | |
- item->host, item->type, item->selector, item->port); | |
+ "%1$zu: %2$s: gopher://%3$s:%6$s/%4$c%5$s" : | |
+ "%zu: %s: gopher://%s/%c%s"; | |
+ n = snprintf(bufout, sizeof(bufout), fmt, i, item->username, | |
+ item->host, item->type, item->selector, item->por… | |
break; | |
} | |
+ | |
+ if (n >= sizeof(bufout)) | |
+ bufout[sizeof(bufout)-1] = '\0'; | |
+ | |
+ printf("%.*s\n", columns, bufout); | |
} | |
void |