Add xsnprintf() and remove some unnecessary strlen(3) calls

This commit is contained in:
Craig Barnes 2021-01-14 21:30:06 +00:00
parent b25b8a78a9
commit 3f4cfa338b
8 changed files with 86 additions and 36 deletions

37
csi.c
View file

@ -23,6 +23,7 @@
#include "version.h" #include "version.h"
#include "vt.h" #include "vt.h"
#include "xmalloc.h" #include "xmalloc.h"
#include "xsnprintf.h"
#define UNHANDLED() LOG_DBG("unhandled: %s", csi_as_string(term, final, -1)) #define UNHANDLED() LOG_DBG("unhandled: %s", csi_as_string(term, final, -1))
#define UNHANDLED_SGR(idx) LOG_DBG("unhandled: %s", csi_as_string(term, 'm', idx)) #define UNHANDLED_SGR(idx) LOG_DBG("unhandled: %s", csi_as_string(term, 'm', idx))
@ -1204,9 +1205,9 @@ csi_dispatch(struct terminal *term, uint8_t final)
if (x >= 0 && y >= 0) { if (x >= 0 && y >= 0) {
char reply[64]; char reply[64];
snprintf(reply, sizeof(reply), "\033[3;%d;%dt", size_t n = xsnprintf(reply, sizeof(reply), "\033[3;%d;%dt",
x / term->scale, y / term->scale); x / term->scale, y / term->scale);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
} }
break; break;
} }
@ -1235,9 +1236,9 @@ csi_dispatch(struct terminal *term, uint8_t final)
if (width >= 0 && height >= 0) { if (width >= 0 && height >= 0) {
char reply[64]; char reply[64];
snprintf(reply, sizeof(reply), "\033[4;%d;%dt", size_t n = xsnprintf(reply, sizeof(reply), "\033[4;%d;%dt",
height / term->scale, width / term->scale); height / term->scale, width / term->scale);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
} }
break; break;
} }
@ -1245,10 +1246,10 @@ csi_dispatch(struct terminal *term, uint8_t final)
case 15: /* report screen size in pixels */ case 15: /* report screen size in pixels */
tll_foreach(term->window->on_outputs, it) { tll_foreach(term->window->on_outputs, it) {
char reply[64]; char reply[64];
snprintf(reply, sizeof(reply), "\033[5;%d;%dt", size_t n = xsnprintf(reply, sizeof(reply), "\033[5;%d;%dt",
it->item->dim.px_scaled.height, it->item->dim.px_scaled.height,
it->item->dim.px_scaled.width); it->item->dim.px_scaled.width);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
break; break;
} }
@ -1258,28 +1259,28 @@ csi_dispatch(struct terminal *term, uint8_t final)
case 16: { /* report cell size in pixels */ case 16: { /* report cell size in pixels */
char reply[64]; char reply[64];
snprintf(reply, sizeof(reply), "\033[6;%d;%dt", size_t n = xsnprintf(reply, sizeof(reply), "\033[6;%d;%dt",
term->cell_height / term->scale, term->cell_height / term->scale,
term->cell_width / term->scale); term->cell_width / term->scale);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
break; break;
} }
case 18: { /* text area size in chars */ case 18: { /* text area size in chars */
char reply[64]; char reply[64];
snprintf(reply, sizeof(reply), "\033[8;%d;%dt", size_t n = xsnprintf(reply, sizeof(reply), "\033[8;%d;%dt",
term->rows, term->cols); term->rows, term->cols);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
break; break;
} }
case 19: { /* report screen size in chars */ case 19: { /* report screen size in chars */
tll_foreach(term->window->on_outputs, it) { tll_foreach(term->window->on_outputs, it) {
char reply[64]; char reply[64];
snprintf(reply, sizeof(reply), "\033[9;%d;%dt", size_t n = xsnprintf(reply, sizeof(reply), "\033[9;%d;%dt",
it->item->dim.px_real.height / term->cell_height / term->scale, it->item->dim.px_real.height / term->cell_height / term->scale,
it->item->dim.px_real.width / term->cell_width / term->scale); it->item->dim.px_real.width / term->cell_width / term->scale);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
break; break;
} }
@ -1341,9 +1342,9 @@ csi_dispatch(struct terminal *term, uint8_t final)
* terminfo says the receiver of the reply should * terminfo says the receiver of the reply should
* decrement, hence we must add 1 */ * decrement, hence we must add 1 */
char reply[64]; char reply[64];
snprintf(reply, sizeof(reply), "\x1b[%d;%dR", size_t n = xsnprintf(reply, sizeof(reply), "\x1b[%d;%dR",
row + 1, term->grid->cursor.point.col + 1); row + 1, term->grid->cursor.point.col + 1);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
break; break;
} }
@ -1468,10 +1469,10 @@ csi_dispatch(struct terminal *term, uint8_t final)
static_assert(FOOT_PATCH < 100, "Patch version must not exceed 99"); static_assert(FOOT_PATCH < 100, "Patch version must not exceed 99");
char reply[64]; char reply[64];
snprintf(reply, sizeof(reply), "\033[>1;%02u%02u%02u;0c", size_t n = xsnprintf(reply, sizeof(reply), "\033[>1;%02u%02u%02u;0c",
FOOT_MAJOR, FOOT_MINOR, FOOT_PATCH); FOOT_MAJOR, FOOT_MINOR, FOOT_PATCH);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
break; break;
case 'm': case 'm':
@ -1625,8 +1626,8 @@ csi_dispatch(struct terminal *term, uint8_t final)
value = 0; value = 0;
char reply[32]; char reply[32];
snprintf(reply, sizeof(reply), "\033[?%u;%u$y", param, value); size_t n = xsnprintf(reply, sizeof(reply), "\033[?%u;%u$y", param, value);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
break; break;
} }

View file

@ -37,6 +37,7 @@
#include "util.h" #include "util.h"
#include "vt.h" #include "vt.h"
#include "xmalloc.h" #include "xmalloc.h"
#include "xsnprintf.h"
struct pipe_context { struct pipe_context {
char *text; char *text;
@ -974,8 +975,8 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
assert(modify_param != 0); assert(modify_param != 0);
char reply[1024]; char reply[1024];
snprintf(reply, sizeof(reply), "\x1b[27;%d;%d~", modify_param, sym); size_t n = xsnprintf(reply, sizeof(reply), "\x1b[27;%d;%d~", modify_param, sym);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
} }
else { else {

5
main.c
View file

@ -31,6 +31,7 @@
#include "util.h" #include "util.h"
#include "version.h" #include "version.h"
#include "xmalloc.h" #include "xmalloc.h"
#include "xsnprintf.h"
static volatile sig_atomic_t aborted = 0; static volatile sig_atomic_t aborted = 0;
@ -127,9 +128,9 @@ print_pid(const char *pid_file, bool *unlink_at_exit)
if (pid_fd >= 0) { if (pid_fd >= 0) {
char pid[32]; char pid[32];
snprintf(pid, sizeof(pid), "%u\n", getpid()); size_t n = xsnprintf(pid, sizeof(pid), "%u\n", getpid());
ssize_t bytes = write(pid_fd, pid, strlen(pid)); ssize_t bytes = write(pid_fd, pid, n);
close(pid_fd); close(pid_fd);
if (bytes < 0) { if (bytes < 0) {

View file

@ -112,6 +112,7 @@ misc = static_library(
'misc.c', 'misc.h', 'misc.c', 'misc.h',
'uri.c', 'uri.h', 'uri.c', 'uri.h',
'xmalloc.c', 'xmalloc.h', 'xmalloc.c', 'xmalloc.h',
'xsnprintf.c', 'xsnprintf.h',
) )
vtlib = static_library( vtlib = static_library(

13
osc.c
View file

@ -17,6 +17,7 @@
#include "uri.h" #include "uri.h"
#include "vt.h" #include "vt.h"
#include "xmalloc.h" #include "xmalloc.h"
#include "xsnprintf.h"
#define UNHANDLED() LOG_DBG("unhandled: OSC: %.*s", (int)term->vt.osc.idx, term->vt.osc.data) #define UNHANDLED() LOG_DBG("unhandled: OSC: %.*s", (int)term->vt.osc.idx, term->vt.osc.data)
@ -522,9 +523,9 @@ osc_dispatch(struct terminal *term)
uint8_t b = (color >> 0) & 0xff; uint8_t b = (color >> 0) & 0xff;
char reply[32]; char reply[32];
snprintf(reply, sizeof(reply), "\033]4;%u;rgb:%02x/%02x/%02x\033\\", size_t n = xsnprintf(reply, sizeof(reply), "\033]4;%u;rgb:%02x/%02x/%02x\033\\",
idx, r, g, b); idx, r, g, b);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
} }
else { else {
@ -568,11 +569,11 @@ osc_dispatch(struct terminal *term)
* E.g. for color 0xdcdccc we reply "\033]10;rgb:dc/dc/cc\033\\" * E.g. for color 0xdcdccc we reply "\033]10;rgb:dc/dc/cc\033\\"
*/ */
char reply[32]; char reply[32];
snprintf( size_t n = xsnprintf(
reply, sizeof(reply), "\033]%u;rgb:%02x/%02x/%02x\033\\", reply, sizeof(reply), "\033]%u;rgb:%02x/%02x/%02x\033\\",
param, r, g, b); param, r, g, b);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
break; break;
} }
@ -602,8 +603,8 @@ osc_dispatch(struct terminal *term)
uint8_t b = (term->cursor_color.cursor >> 0) & 0xff; uint8_t b = (term->cursor_color.cursor >> 0) & 0xff;
char reply[32]; char reply[32];
snprintf(reply, sizeof(reply), "\033]12;rgb:%02x/%02x/%02x\033\\", r, g, b); size_t n = xsnprintf(reply, sizeof(reply), "\033]12;rgb:%02x/%02x/%02x\033\\", r, g, b);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
break; break;
} }

17
sixel.c
View file

@ -10,6 +10,7 @@
#include "hsl.h" #include "hsl.h"
#include "util.h" #include "util.h"
#include "xmalloc.h" #include "xmalloc.h"
#include "xsnprintf.h"
static size_t count; static size_t count;
@ -1101,8 +1102,8 @@ void
sixel_colors_report_current(struct terminal *term) sixel_colors_report_current(struct terminal *term)
{ {
char reply[24]; char reply[24];
snprintf(reply, sizeof(reply), "\033[?1;0;%uS", term->sixel.palette_size); size_t n = xsnprintf(reply, sizeof(reply), "\033[?1;0;%uS", term->sixel.palette_size);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
LOG_DBG("query response for current color count: %u", term->sixel.palette_size); LOG_DBG("query response for current color count: %u", term->sixel.palette_size);
} }
@ -1135,8 +1136,8 @@ void
sixel_colors_report_max(struct terminal *term) sixel_colors_report_max(struct terminal *term)
{ {
char reply[24]; char reply[24];
snprintf(reply, sizeof(reply), "\033[?1;0;%uS", SIXEL_MAX_COLORS); size_t n = xsnprintf(reply, sizeof(reply), "\033[?1;0;%uS", SIXEL_MAX_COLORS);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
LOG_DBG("query response for max color count: %u", SIXEL_MAX_COLORS); LOG_DBG("query response for max color count: %u", SIXEL_MAX_COLORS);
} }
@ -1144,10 +1145,10 @@ void
sixel_geometry_report_current(struct terminal *term) sixel_geometry_report_current(struct terminal *term)
{ {
char reply[64]; char reply[64];
snprintf(reply, sizeof(reply), "\033[?2;0;%u;%uS", size_t n = xsnprintf(reply, sizeof(reply), "\033[?2;0;%u;%uS",
min(term->cols * term->cell_width, term->sixel.max_width), min(term->cols * term->cell_width, term->sixel.max_width),
min(term->rows * term->cell_height, term->sixel.max_height)); min(term->rows * term->cell_height, term->sixel.max_height));
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
LOG_DBG("query response for current sixel geometry: %ux%u", LOG_DBG("query response for current sixel geometry: %ux%u",
term->sixel.max_width, term->sixel.max_height); term->sixel.max_width, term->sixel.max_height);
@ -1178,8 +1179,8 @@ sixel_geometry_report_max(struct terminal *term)
unsigned max_height = term->rows * term->cell_height; unsigned max_height = term->rows * term->cell_height;
char reply[64]; char reply[64];
snprintf(reply, sizeof(reply), "\033[?2;0;%u;%uS", max_width, max_height); size_t n = xsnprintf(reply, sizeof(reply), "\033[?2;0;%u;%uS", max_width, max_height);
term_to_slave(term, reply, strlen(reply)); term_to_slave(term, reply, n);
LOG_DBG("query response for max sixel geometry: %ux%u", LOG_DBG("query response for max sixel geometry: %ux%u",
max_width, max_height); max_width, max_height);

36
xsnprintf.c Normal file
View file

@ -0,0 +1,36 @@
#include "xsnprintf.h"
#include <assert.h>
#include <limits.h>
#include <stdio.h>
size_t
xvsnprintf(char *buf, size_t n, const char *format, va_list ap)
{
assert(n <= INT_MAX);
int len = vsnprintf(buf, n, format, ap);
/*
* ISO C11 §7.21.6.5 states:
* "The snprintf function returns the number of characters that
* would have been written had n been sufficiently large, not
* counting the terminating null character, or a negative value
* if an encoding error occurred. Thus, the null-terminated output
* has been completely written if and only if the returned value
* is nonnegative and less than n."
*/
assert(len >= 0);
assert(len < (int)n);
return (size_t)len;
}
size_t
xsnprintf(char *buf, size_t n, const char *format, ...)
{
va_list ap;
va_start(ap, format);
size_t len = xvsnprintf(buf, n, format, ap);
va_end(ap);
return len;
}

8
xsnprintf.h Normal file
View file

@ -0,0 +1,8 @@
#pragma once
#include <stdarg.h>
#include <stddef.h>
#include "macros.h"
size_t xsnprintf(char *buf, size_t len, const char *fmt, ...) PRINTF(3) NONNULL_ARGS;
size_t xvsnprintf(char *buf, size_t len, const char *fmt, va_list ap) VPRINTF(3) NONNULL_ARGS;