commit 2e31e44ffa614c5202edfe2abcc05a7880902640
parent d90036de3c72730ae2797844b36eb5ae9fd3843f
Author: Quentin Rameau <quinq@fifth.space>
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->port);
break;
}
+
+ if (n >= sizeof(bufout))
+ bufout[sizeof(bufout)-1] = '\0';
+
+ printf("%.*s\n", columns, bufout);
}
void